Compare commits

..

1270 Commits

Author SHA1 Message Date
epenet a76c3a6864 Adjust patch 2025-10-03 07:36:32 +00:00
epenet 3ae8f5d955 Use lazy formatting
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-03 09:19:37 +02:00
epenet bbd21876e6 Add workaround for partial local_strategy in Tuya 2025-10-03 07:13:19 +00:00
Ståle Storø Hauknes 7355799030 Fix typo in Airthings BLE config flow (#153512) 2025-10-03 08:20:17 +02:00
Erik Montnemery 982166df3c Remove module recorder.history.modern (#153502) 2025-10-03 01:00:09 +02:00
puddly c7d3512ad2 Bump universal-silabs-flasher to 0.0.35 (#153500) 2025-10-03 00:18:05 +02:00
Aidan Timson ada6f7b3fb Update ovoenergy to 3.0.2 (#153488) 2025-10-02 22:44:28 +01:00
Erik Montnemery 78e16495bd Remove runtime support for recorder DB without States.last_reported_ts (#153495) 2025-10-02 23:15:15 +02:00
starkillerOG 12085e6152 Improve Reolink docstrings (#153498) 2025-10-02 23:10:27 +02:00
starkillerOG 6764463689 Use new Reolink rec_enable flag (#153496) 2025-10-02 23:09:43 +02:00
starkillerOG 7055276665 Allign naming of Reolink host switch entities (#153494) 2025-10-02 23:09:17 +02:00
starkillerOG 71b3ebd15a Cleanup reolink update entity migration (#153492) 2025-10-02 22:49:55 +02:00
starkillerOG b87910e596 Bump reolink-aio to 0.16.1 (#153489) 2025-10-02 22:49:39 +02:00
Erik Montnemery e19bfd670b Bump recorder live schema migration to schema version 48 (#153404) 2025-10-02 22:47:01 +02:00
dollaransh17 7b3c96e80b Remove deprication code for reolink Hub switches (#153483)
Thank you, good work!
2025-10-02 22:37:08 +02:00
Erik Montnemery 01ff3cf9d9 Start recorder data migration after schema migration (#153471) 2025-10-02 22:21:49 +02:00
Erik Montnemery d66da0c10d Respect filtering of WS subscribe_entities when there are unserializalizable states (#153262) 2025-10-02 22:20:45 +02:00
Josef Zweck 3491bb1b40 Fix missing parameter pass in onedrive (#153478) 2025-10-02 22:17:56 +02:00
G Johansson 3bf995eb71 Fix next event in workday calendar (#153465) 2025-10-02 22:17:11 +02:00
Joost Lekkerkerker 2169ce1722 Remove state attributes from Firefly 3 (#153285) 2025-10-02 22:14:51 +02:00
Joost Lekkerkerker 275e9485e9 Fix missing powerconsumptionreport in Smartthings (#153438) 2025-10-02 22:08:48 +02:00
Daniel Hjelseth Høyer 95198ae540 Bump pyTibber to 0.32.2 (#153484) 2025-10-02 21:04:32 +02:00
Aidan Timson aed2d3899d Update OVOEnergy to 3.0.1 (#153476) 2025-10-02 21:04:16 +02:00
Erik Montnemery 4011d62ac7 Improve enable_migrate_event_ids recorder test fixture (#153470)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-10-02 21:03:26 +02:00
Björn Ebbinghaus d2aa0573de Add relative humidity to matter climate entities (#152554)
OK after talking with Marcel.
2025-10-02 20:44:19 +02:00
Ståle Storø Hauknes 571b2e3ab6 Fix Airthings config flow description (#153452) 2025-10-02 20:38:27 +02:00
peteS-UK a7f48360b7 Add PARALLEL_UPDATES to Squeezebox switch platform (#153477) 2025-10-02 20:32:37 +02:00
Erik Montnemery 22f2f8680a Improve recorder migration tests dropping indices (#153456) 2025-10-02 20:16:24 +02:00
Aidan Timson d92004a9e7 Add missing translation for media browser default title (#153430)
Co-authored-by: Erwin Douna <e.douna@gmail.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-10-02 19:33:57 +02:00
Norbert Rittel 64875894d6 Fix sentence-casing in user-facing strings of slack (#153427) 2025-10-02 19:27:28 +02:00
Ståle Storø Hauknes 3f7a288526 Add data_description field for Airthings BLE (#153442) 2025-10-02 19:25:59 +02:00
Ståle Storø Hauknes a2a067a81c Add serial number to the list of discovered devices (#153448) 2025-10-02 19:25:19 +02:00
Erwin Douna f9f61b8da7 Portainer add configuration URL's (#153466) 2025-10-02 19:22:34 +02:00
Paul Bottein cd69b82fc9 Add light, security and climate panel (#153261) 2025-10-02 13:06:53 -04:00
Shay Levy d20631598e Bump aioshelly 13.11.0 (#153458) 2025-10-02 19:44:24 +03:00
puddly 229ebe16f3 Disable baudrate bootloader reset for ZBT-2 (#153443) 2025-10-02 17:36:10 +01:00
G Johansson a172f67d37 Fix Nord Pool 15 minute interval (#153350) 2025-10-02 18:26:33 +02:00
Joost Lekkerkerker ee4a1de566 Add translation for turbo fan mode in SmartThings (#153445)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-02 18:45:37 +03:00
epenet 7ab99c028c Add new test fixture for Tuya wk category (#153457) 2025-10-02 17:29:14 +02:00
TheJulianJES 0e1d12b1ae Fix Z-Wave RGB light turn on causing rare ZeroDivisionError (#153422) 2025-10-02 17:26:49 +02:00
Artur Pragacz e090ddd761 Move entities to the end of devices in analytics payload (#153449) 2025-10-02 16:36:38 +02:00
Stefan Agner 9721ce6877 Update Home Assistant base image to 2025.10.0 (#153441) 2025-10-02 15:17:59 +02:00
MoonDevLT 8dde94f421 Add Lunatone gateway integration (#149182)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-02 12:55:17 +01:00
dollaransh17 f5f6b22af1 Fix spelling error in logbook tests (#153417)
Co-authored-by: dollaransh17 <dollaransh17@users.noreply.github.com>
2025-10-02 12:49:22 +02:00
Tom Matheussen f8a93b6561 Add Quality Scale to Satel Integra (#153122) 2025-10-02 12:48:34 +02:00
epenet 840a03f048 Add new dehumidifier fixture for Tuya (#153407) 2025-10-02 12:15:28 +02:00
Erwin Douna 85f3b5ce78 Firefly III add re-auth flow (#153303)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-10-02 12:15:10 +02:00
Michael f4284fec2f Explicit pass in the config entry to coordinator in airtouch4 (#153361)
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-10-02 11:54:20 +02:00
Abílio Costa 3a89b3152f Move common Uptime Robot new device check logic to helper (#153094)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-02 10:52:22 +01:00
epenet a0356328c3 Use walrus and combine conditions in Tuya alarm control panel (#153426) 2025-10-02 11:52:08 +02:00
Michael J. Kidd 4b6f37b1d7 Pushover: Handle empty data section properly (#153397) 2025-10-02 11:48:03 +02:00
johanzander 716705fb5a Adds token authentication and usage of official API for Growatt MIN/TLX inverters (#149783) 2025-10-02 11:40:53 +02:00
J. Nick Koston d246836480 Bump aiohomekit to 3.2.19 (#153423) 2025-10-02 11:17:17 +02:00
Guido Schmitz 6ee2b82d15 Cleanup sync_callback in devolo Home Control (#153321) 2025-10-02 11:11:19 +02:00
Luke Lashley 73ff8d36a5 Bump python-roborock to 2.49.1 (#153396) 2025-10-02 11:09:44 +02:00
Manu 1397def3b8 Add last check-in sensor to Habitica integration (#153293) 2025-10-02 11:03:21 +02:00
epenet d443529041 Add more sensors to Tuya weather monitor (#153420) 2025-10-02 10:58:24 +02:00
G Johansson 373bb20f1b Remove deprecated entity feature constants in vacuum (#153364) 2025-10-02 10:46:34 +02:00
Erik Montnemery 3b44cce6dc Improve recorder migration test (#153405) 2025-10-02 10:45:04 +02:00
Joakim Plate 46056fe45b Correct blocking update in ToGrill with lack of notifications (#153387) 2025-10-02 10:44:42 +02:00
epenet 1816c190b2 Add test fixture for new Tuya cjkg category (#153411) 2025-10-02 10:43:54 +02:00
Josef Zweck 00abaee6b3 Increase onedrive upload chunk size (#153406) 2025-10-02 10:43:10 +02:00
Manu 3a301f54e0 Update markdown field description in ntfy integration (#153421) 2025-10-02 10:40:33 +02:00
Denis Shulyaka 762accbd6d Disable thinking for unsupported gemini models (#153415) 2025-10-02 10:38:31 +02:00
Tom Matheussen e0422d7d34 Fix Satel Integra creating new binary sensors on YAML import (#153419) 2025-10-02 10:37:41 +02:00
Erwin Douna 6ba2057a88 Bump pyportainer 1.0.3 (#153413) 2025-10-02 10:34:11 +02:00
epenet 752969bce5 Add test fixture for new Tuya jsq category (#153412) 2025-10-02 10:33:02 +02:00
Franck Nijhof efbdfd2954 Merge branch 'master' into dev 2025-10-02 07:06:58 +00:00
Erik Montnemery bb7a177a5d Improve recorder migration tests (#153388) 2025-10-02 07:45:04 +02:00
Kinachi249 9b56ca8cde Bump PyCync to 0.4.1 (#153401) 2025-10-02 07:11:34 +02:00
starkillerOG b0a08782e0 Add Roborock mop intensity translations (#153380) 2025-10-01 22:51:26 +02:00
G Johansson 6c9955f220 Remove deprecated constants in camera (#153363) 2025-10-01 22:20:34 +02:00
G Johansson f56b94c0f9 Remove deprecated constants from media_player (#153366) 2025-10-01 22:20:07 +02:00
G Johansson 3cf035820b Remove deprecated state constants from lock (#153367) 2025-10-01 22:16:52 +02:00
Erik Montnemery 99a796d066 Remove legacy history queries from recorder (#153324) 2025-10-01 22:06:56 +02:00
Erik Montnemery 1cd1b1aba8 Remove to_native method from recorder database schemas (#153334) 2025-10-01 21:25:05 +02:00
Ståle Storø Hauknes 4131c14629 Add parallel updates to airthings_ble (#153315) 2025-10-01 20:14:23 +02:00
Tom c2acda5796 Bump airOS module for alternative login url (#153317) 2025-10-01 20:11:35 +02:00
Marc Mueller 4806e7e9d9 Update cryptography to 46.0.2 (#153327) 2025-10-01 19:52:57 +02:00
Marc Mueller 76606fd44f Update types packages (#153330) 2025-10-01 19:51:37 +02:00
Andre Lengwenus 2983f1a3b6 Explicitly check for None in raw value processing of modbus (#153352) 2025-10-01 19:48:35 +02:00
Michael 8019779b3a Set config entry to None in ProxmoxVE (#153357) 2025-10-01 19:45:34 +02:00
Marc Mueller 62cdcbf422 Misc typing improvements (#153322) 2025-10-01 19:30:41 +02:00
Marc Mueller b12a5a36e1 Update bcrpyt to 5.0.0 (#153325) 2025-10-01 20:07:45 +03:00
epenet e32763e464 Add water heater fixture for Tuya tests (#153336) 2025-10-01 20:02:54 +03:00
Stefan Agner b85cf3f9d2 Bump aiohasupervisor to 0.3.3 (#153344) 2025-10-01 20:01:53 +03:00
puddly 3777bcc2af Do not reset the adapter twice during ZHA options flow migration (#153345) 2025-10-01 18:22:41 +02:00
Franck Nijhof 9a29cc53ef 2025.10.0 (#152881) 2025-10-01 18:17:36 +02:00
Maciej Bieniek 52cde48ff0 Add missing test for Shelly config flow (#153346) 2025-10-01 18:32:57 +03:00
Marc Mueller bf1da35303 Update pyOpenSSL to 25.3.0 (#153329) 2025-10-01 17:32:08 +02:00
Franck Nijhof 55d5e769b2 Bump version to 2025.10.0 2025-10-01 15:19:48 +00:00
Erwin Douna c1bf11da34 Bump pyportainer 1.0.2 (#153326) 2025-10-01 17:07:21 +02:00
Erwin Douna 3c20325b37 Bump pyfirefly 0.1.6 (#153335) 2025-10-01 17:06:31 +02:00
Franck Nijhof 6cd1283b00 Bump version to 2025.10.0b7 2025-10-01 14:51:37 +00:00
Maciej Bieniek dde60cdecb Improve mac_address_from_name() function to avoid double discovery of Shelly devices (#153343) 2025-10-01 14:51:09 +00:00
Michael Hansen f03b16bdf8 Bump intents to 2025.10.1 (#153340) 2025-10-01 14:51:07 +00:00
Maciej Bieniek fd8ccb8d8f Improve mac_address_from_name() function to avoid double discovery of Shelly devices (#153343) 2025-10-01 16:49:27 +02:00
Michael Hansen d76e947021 Bump intents to 2025.10.1 (#153340) 2025-10-01 09:39:08 -05:00
Erik Montnemery c91ed96543 Use pytest.mark.usefixtures in history tests (#153306) 2025-10-01 15:53:55 +02:00
HarvsG b164531ba8 Bayesian - add config entry tests (#153316) 2025-10-01 15:46:16 +02:00
Erik Montnemery 7c623a8704 Use pytest.mark.usefixtures in some recorder tests (#153313) 2025-10-01 15:38:51 +02:00
Maciej Bieniek 7ae3340336 Add test for full device snapshot for Shelly Wall Display XL (#153305) 2025-10-01 16:00:15 +03:00
Marc Mueller 653b73c601 Fix device_automation RuntimeWarning in tests (#153319) 2025-10-01 14:26:09 +02:00
Franck Nijhof f616e5a4e3 Bump version to 2025.10.0b6 2025-10-01 10:41:01 +00:00
Artur Pragacz c0317f60cc Add analytics platform to esphome (#153311) 2025-10-01 10:40:41 +00:00
Bram Kragten 8abfe424e1 Update frontend to 20251001.0 (#153300) 2025-10-01 10:40:40 +00:00
HarvsG 8de200de0b Fix Bayesian ConfigFlow templates in 2025.10 (#153289)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-10-01 10:40:38 +00:00
Joost Lekkerkerker f242e294be Add Konnected brand (#153280) 2025-10-01 10:40:36 +00:00
Joost Lekkerkerker 58cc7c8f84 Add Level brand (#153279) 2025-10-01 10:40:35 +00:00
Joost Lekkerkerker bd10f6ec08 Require cloud for Aladdin Connect (#153278)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-01 10:40:33 +00:00
puddly ed9cfb4c4b Use hardware bootloader reset methods for firmware config flows (#153277) 2025-10-01 10:40:32 +00:00
Joost Lekkerkerker a6b6e4c4b8 Add Eltako brand (#153276) 2025-10-01 10:40:31 +00:00
Robert Resch 36ff5c0d45 Bump aioecowitt to 2025.9.2 (#153273) 2025-10-01 10:40:29 +00:00
Artur Pragacz de6d34fec5 Filter out service type devices in extended analytics (#153271) 2025-10-01 10:40:28 +00:00
Erwin Douna 38f9067970 Portainer fix CONF_VERIFY_SSL (#153269)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-10-01 10:40:27 +00:00
Norbert Rittel 53a8a250d0 Replace "Climate name" with "Climate program" in ecobee action (#153264) 2025-10-01 10:40:25 +00:00
Artur Pragacz 00f6d26ede Add analytics platform to wled (#153258) 2025-10-01 10:40:24 +00:00
andreimoraru 6d09411c07 Bump yt-dlp to 2025.09.26 (#153252) 2025-10-01 10:40:22 +00:00
TheJulianJES 037e2bfd31 Fix ZHA unable to select "none" flow control (#153235) 2025-10-01 10:40:21 +00:00
TheJulianJES c893552d4a Replace remaining ZHA "radio" strings with "adapter" (#153234) 2025-10-01 10:40:20 +00:00
TheJulianJES 4fd10162c9 Improve ZHA multi-pan firmware repair text (#153232) 2025-10-01 10:40:18 +00:00
Joris Pelgröm 392ee5ae7e Use UnitOfTime.DAYS instead of custom unit for LetPot number entity (#153054) 2025-10-01 10:40:17 +00:00
puddly bf190609a0 Reduce Connect firmware install times by removing unnecessary firmware probing (#153012) 2025-10-01 10:40:15 +00:00
Samuel Xiao e982ac1e53 Switchbot Cloud: Fix Roller Shade not work issue (#152528) 2025-10-01 10:40:14 +00:00
Pete Sage b4747ea87b Fix Sonos Dialog Select type conversion part II (#152491)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-10-01 10:40:12 +00:00
HarvsG df69bcecb7 Pihole better logging of update errors (#152077) 2025-10-01 10:40:11 +00:00
Artur Pragacz 7c93d91bae Filter out service type devices in extended analytics (#153271) 2025-10-01 12:38:50 +02:00
Abílio Costa 07da0cfb2b Stop writing to config dir log file on supervised install (#146675)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-10-01 11:11:00 +01:00
Artur Pragacz b411a11c2c Add analytics platform to esphome (#153311) 2025-10-01 12:08:50 +02:00
epenet 0555b84d05 Add new cover fixture for Tuya (#153310) 2025-10-01 12:01:37 +02:00
TheJulianJES 790bddef63 Improve ZHA multi-pan firmware repair text (#153232) 2025-10-01 11:50:01 +02:00
TheJulianJES a3089b8aa7 Replace remaining ZHA "radio" strings with "adapter" (#153234) 2025-10-01 11:46:08 +02:00
puddly 77c8426d63 Use hardware bootloader reset methods for firmware config flows (#153277) 2025-10-01 11:43:28 +02:00
TheJulianJES faf226f6c2 Fix ZHA unable to select "none" flow control (#153235) 2025-10-01 11:42:50 +02:00
HarvsG 06d143b81a Fix Bayesian ConfigFlow templates in 2025.10 (#153289)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-10-01 11:39:23 +02:00
Erik Montnemery 08b6a0a702 Add device class filter to switcher_kis services (#153248) 2025-10-01 12:27:17 +03:00
Bram Kragten a20d1e3656 Update frontend to 20251001.0 (#153300) 2025-10-01 09:50:30 +02:00
Erwin Douna 36cc3682ca Add Firefly III integration (#147062)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-30 23:34:33 +02:00
Aviad Levy 1b495ecafa Add support for errored torrents in qBittorrent sensor (#153120)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-30 23:34:15 +02:00
puddly 7d1a0be07e Reduce Connect firmware install times by removing unnecessary firmware probing (#153012) 2025-09-30 22:41:51 +02:00
Geoffrey 327f65c991 Add switch domain to VegeHub integration (#148436)
Co-authored-by: GhoweVege <85890024+GhoweVege@users.noreply.github.com>
2025-09-30 22:38:05 +02:00
Manu 4ac89f6849 Add notify platform to Habitica (#150553) 2025-09-30 22:35:55 +02:00
Nojus db3b070ed0 Add meteo_lt integration (#152948)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-30 22:17:36 +02:00
anishsane 6d940f476a Add support for Media player Mute/Unmute intents (#150508) 2025-09-30 14:37:19 -05:00
Erwin Douna 1ca701dda4 Portainer fix CONF_VERIFY_SSL (#153269)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-09-30 21:36:04 +02:00
Joost Lekkerkerker 291c44100c Add Eltako brand (#153276) 2025-09-30 21:29:58 +02:00
Joost Lekkerkerker c8d676e06b Add Konnected brand (#153280) 2025-09-30 21:27:43 +02:00
Joost Lekkerkerker 4c1ae0eddc Add Level brand (#153279) 2025-09-30 21:21:21 +02:00
Norbert Rittel 39eadc814f Replace "Climate name" with "Climate program" in ecobee action (#153264) 2025-09-30 21:16:37 +02:00
Robert Resch f7ecad61ba Bump aioecowitt to 2025.9.2 (#153273) 2025-09-30 20:58:34 +02:00
Norbert Rittel fa4cb54549 Fix sentence-casing in two title strings of roomba (#153281) 2025-09-30 20:51:44 +02:00
Manu 2be33c5e0a Update quality scale of ntfy integration to platinum 🏆️ (#151785) 2025-09-30 20:36:18 +02:00
LG-ThinQ-Integration 904d7e5d5a Add air/water filter state in percent to LG ThinQ (#152150)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-30 20:26:47 +02:00
Pete Sage dbc4a65d48 Fix Sonos Dialog Select type conversion part II (#152491)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-30 20:25:19 +02:00
Pete Sage b93f4aabf1 Add tests for Sonos media metadata (#152622) 2025-09-30 20:24:57 +02:00
Joost Lekkerkerker 9eaa40c7a4 Require cloud for Aladdin Connect (#153278)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-30 19:57:24 +02:00
Lucas Mindêllo de Andrade b308a882fb Add Roomba J9 compatibility to the roomba integration (#145913)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-30 19:10:22 +02:00
Erik Montnemery 7f63ba2087 Improve saved state of RestoreSensor when using freezegun (#152740) 2025-09-30 18:27:56 +02:00
Erik Montnemery d7269cfcc6 Use pytest_unordered in additional service helper tests (#153255) 2025-09-30 18:26:32 +02:00
starkillerOG 2850a574f6 Add Reolink floodlight event entities (#152564) 2025-09-30 17:59:12 +02:00
Samuel Xiao dcb8d4f702 Add support model [relay switch 2pm] for switchbot cloud (#148381) 2025-09-30 17:49:32 +02:00
Samuel Xiao aeadc0c4b0 Add lock support to Switchbot Cloud (#148310) 2025-09-30 17:48:38 +02:00
Nathan Spencer 683c6b17be Add release url to Litter-Robot 4 update entity (#152504) 2025-09-30 17:47:27 +02:00
Samuel Xiao 69dd5c91b7 Switchbot Cloud: Fix Roller Shade not work issue (#152528) 2025-09-30 17:05:23 +02:00
HarvsG 5cf7dfca8f Pihole better logging of update errors (#152077) 2025-09-30 16:59:03 +02:00
Marc Mueller 62a49d4244 Update pandas to 2.3.3 (#153251) 2025-09-30 16:58:41 +02:00
falconindy 93ee6322f2 snoo: add button entity for calling start_snoo (#151052)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-30 16:57:58 +02:00
Artur Pragacz 914990b58a Add analytics platform to wled (#153258) 2025-09-30 10:39:32 -04:00
Joakim Sørensen f78bb5adb6 Bump hass-nabucasa from 1.1.2 to 1.2.0 (#153250) 2025-09-30 15:29:04 +02:00
Erik Montnemery 905f5e7289 Add device class filter to entity services (#153247) 2025-09-30 14:28:04 +01:00
Erik Montnemery ec503618c3 Handle errors in WS manifest/list (#153256) 2025-09-30 15:12:41 +02:00
Erik Montnemery 7a41cbc314 Skip unserializable flows in WS config_entries/flow/subscribe (#153259) 2025-09-30 15:12:19 +02:00
Erik Montnemery c58ba734e7 Correct target filter in osoenergy services (#153244) 2025-09-30 14:06:14 +02:00
Erik Montnemery 68f63be62f Correct target filter in litterrobot services (#153243) 2025-09-30 14:05:46 +02:00
Erik Montnemery 2aa4ca1351 Correct homekit service definition (#153242) 2025-09-30 14:04:09 +02:00
Imeon-Energy fbabb27787 Add forecast energy sensor to Imeon inverter integration (#152176)
Co-authored-by: TheBushBoy <theodavid@icloud.com>
2025-09-30 13:35:18 +02:00
Markus Jacobsen 0960d78eb5 Use initial received WebSocket state in Bang & Olufsen (#152432) 2025-09-30 13:34:43 +02:00
andreimoraru 474b40511f Bump yt-dlp to 2025.09.26 (#153252) 2025-09-30 13:19:06 +02:00
Jan-Philipp Benecke 18b80aced3 Record current quality scale of Electricity Maps (#149241) 2025-09-30 11:38:16 +02:00
Franck Nijhof c75dca743a Bump version to 2025.10.0b5 2025-09-30 09:21:25 +00:00
Jan Bouwhuis 00d667ed51 Add missing translation strings for added sensor device classes pm4 and reactive energy (#153215) 2025-09-30 09:21:19 +00:00
c0ffeeca7 51e098e807 ZHA: rename radio to adapter (#153206) 2025-09-30 09:21:17 +00:00
RogerSelwyn 5e2b27699e Handle return result from ebusd being "empty" (#153199) 2025-09-30 09:21:16 +00:00
Erik Montnemery be942c2888 Revert "Add mg/m³ as a valid UOM for sensor/number Carbon Monoxide device class" (#153196) 2025-09-30 09:21:14 +00:00
Erik Montnemery 584c1fbd97 Revert "Add comment on conversion factor for Carbon monoxide on dependency molecular weight" (#153195) 2025-09-30 09:21:13 +00:00
Joost Lekkerkerker abc5c6e2b4 Mark Konnected as Legacy (#153193) 2025-09-30 09:21:11 +00:00
Martin Hjelmare d9de964035 Add hardware Zigbee flow strategy (#153190) 2025-09-30 09:21:10 +00:00
Artur Pragacz bb02158d1a Filter out empty integration type in extended analytics (#153188) 2025-09-30 09:21:08 +00:00
Simone Chemelli be10f097c7 Bump aioamazondevices to 6.2.7 (#153185) 2025-09-30 09:21:07 +00:00
cdnninja 7084bca783 Correct vesync water tank lifted key (#153173) 2025-09-30 09:21:05 +00:00
Michael cd6f3a0fe5 Add newly added cpu temperatures to diagnostics in FRITZ!Tools (#153168) 2025-09-30 09:21:03 +00:00
starkillerOG af2888331d Bump reolink-aio to 0.16.0 (#153161) 2025-09-30 09:21:02 +00:00
Allen Porter b92e5d7131 Add missing translations for Model Context Protocol integration (#153147) 2025-09-30 09:21:00 +00:00
Tom Matheussen f7265c85d0 Fix entities not being created when adding subentries for Satel Integra (#153139) 2025-09-30 09:20:58 +00:00
G Johansson 8466dbf69f Fix event range in workday calendar (#153128) 2025-09-30 09:20:57 +00:00
Robert Resch 2dd0d69bcd Bump deebot-client to 15.0.0 (#153125) 2025-09-30 09:20:56 +00:00
Luca Graf 6783c4ad83 Ignore gateway device in ViCare integration (#153097) 2025-09-30 09:20:54 +00:00
G Johansson 07d7f4e18d Add timeout to dnsip (to handle stale connections) (#153086) 2025-09-30 09:20:53 +00:00
Simone Chemelli 54b1749986 Remove redundant code for Alexa Devices (#153083) 2025-09-30 09:20:51 +00:00
G Johansson eaf264361f Fix can exclude optional holidays in workday (#153082) 2025-09-30 09:20:50 +00:00
Kyle Worrall d8f6f17a4f Fix for Hue Integration motion aware areas (#153079)
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-30 09:20:48 +00:00
Joakim Plate 9a969cea63 Ensure togrill detects disconnected devices (#153067) 2025-09-30 09:20:47 +00:00
Maciej Bieniek ef16327b2b Add consumed energy sensor for Shelly pm1 and switch components (#153053) 2025-09-30 09:20:46 +00:00
Martin Hjelmare a6a6261168 Improve hardware flow strings (#153034) 2025-09-30 09:20:44 +00:00
Erwin Douna a01eb48db8 Portainer switch terminology to API token (#152958)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-30 09:20:43 +00:00
Christian McHugh eb103a8d9a Fix: Set EPH climate heating as on only when boiler is actively heating (#152914) 2025-09-30 09:20:41 +00:00
Shay Levy 2b5f989855 Add Shelly EV charger sensors (#152722) 2025-09-30 09:20:40 +00:00
Thomas D 4e247a6ebe Prevent duplicate entities for Volvo integration (#151779) 2025-09-30 09:20:38 +00:00
dependabot[bot] b964d362b7 Bump docker/login-action from 3.5.0 to 3.6.0 (#153239)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-30 11:14:17 +02:00
G Johansson 3914e41f3c Rename resolver to nameserver in dnsip (#153223) 2025-09-30 10:46:59 +02:00
Erik Montnemery 82bdfcb99b Correct target filter in ecovacs services (#153241) 2025-09-30 10:39:18 +03:00
Marc Mueller 976cea600f Use attribute names for match class (#153191) 2025-09-29 23:12:54 +02:00
Tom 8c8713c3f7 Rework test split for airOS reauthentication flow (#153221) 2025-09-29 22:07:18 +02:00
G Johansson 2359ae6ce7 Bump pysmhi to 1.1.0 (#153222) 2025-09-29 22:04:59 +02:00
Paul Bottein b570fd35c8 Replace legacy hass icons to mdi icons (#153204) 2025-09-29 20:04:21 +01:00
starkillerOG 9d94e6b3b4 Add Reolink bicycle sensitivity and delay (#153217) 2025-09-29 20:44:13 +02:00
Martin Hjelmare cfab789823 Add hardware Zigbee flow strategy (#153190) 2025-09-29 20:08:43 +02:00
Erik Montnemery 81917425dc Add test which fails on duplicated statistics units (#153202)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: jbouwh <jan@jbsoft.nl>
2025-09-29 20:07:59 +02:00
Jan Bouwhuis bfb62709d4 Add missing translation strings for added sensor device classes pm4 and reactive energy (#153215) 2025-09-29 19:55:09 +02:00
Joost Lekkerkerker ca3f2ee782 Mark Konnected as Legacy (#153193) 2025-09-29 18:22:29 +01:00
Ludovic BOUÉ fc8703a40f Matter DoorLock attributes (#151418)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-09-29 18:20:22 +01:00
c0ffeeca7 80517c7ac1 ZHA: rename radio to adapter (#153206) 2025-09-29 18:17:44 +01:00
Erik Montnemery 2b4b46eaf8 Add async_iterator util (#153194) 2025-09-29 18:54:23 +02:00
Martin Hjelmare 40b9dae608 Improve hardware flow strings (#153034) 2025-09-29 18:29:58 +02:00
Erik Montnemery 5975cd6e09 Revert "Add mg/m³ as a valid UOM for sensor/number Carbon Monoxide device class" (#153196) 2025-09-29 15:43:13 +01:00
RogerSelwyn 258c9ff52b Handle return result from ebusd being "empty" (#153199) 2025-09-29 16:08:42 +02:00
starkillerOG 89c5d498a4 Add Reolink Ai person type, vehicle type and animal type (#153170) 2025-09-29 15:39:29 +02:00
Artur Pragacz 76cb4d123a Filter out empty integration type in extended analytics (#153188) 2025-09-29 15:18:15 +02:00
Erik Montnemery f0c29c7699 Revert "Add comment on conversion factor for Carbon monoxide on dependency molecular weight" (#153195) 2025-09-29 14:56:42 +02:00
Kyle Worrall aa4151ced7 Fix for Hue Integration motion aware areas (#153079)
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-29 14:50:36 +02:00
G Johansson 0a6fa978fa Add timeout to dnsip (to handle stale connections) (#153086) 2025-09-29 14:49:38 +02:00
Simone Chemelli dc02002b9d Bump aioamazondevices to 6.2.7 (#153185) 2025-09-29 14:30:42 +02:00
cdnninja f071a3f38b Correct vesync water tank lifted key (#153173) 2025-09-29 14:29:25 +02:00
dependabot[bot] b935231e47 Bump actions/dependency-review-action from 4.7.3 to 4.8.0 (#153180)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-29 13:17:20 +02:00
dependabot[bot] b9f7613567 Bump github/codeql-action from 3.30.4 to 3.30.5 (#153179)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-29 13:15:53 +02:00
Maciej Bieniek 1289a031ab Add consumed energy sensor for Shelly pm1 and switch components (#153053) 2025-09-29 13:06:07 +03:00
Andrew Jackson 289546ef6d Bump aiomealie to 0.11.0 adding times to recipes (#153183) 2025-09-29 11:58:40 +02:00
Guido Schmitz aacff4db5d Rework devolo Home Control config flow tests (#147083)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-29 09:47:07 +02:00
starkillerOG f833b56122 Add Reolink siren state (#153169) 2025-09-29 08:42:38 +02:00
Tom Matheussen 7eb0f2993f Fix entities not being created when adding subentries for Satel Integra (#153139) 2025-09-28 21:37:35 -04:00
Michael abb341abfe Add newly added cpu temperatures to diagnostics in FRITZ!Tools (#153168) 2025-09-28 22:40:10 +02:00
starkillerOG 0d90614369 Bump reolink-aio to 0.16.0 (#153161) 2025-09-28 21:55:39 +02:00
starkillerOG ec84bebeea Add Reolink AI bicycle detection entity (#153163) 2025-09-28 21:54:59 +02:00
Shay Levy 9176867d6b Add Shelly EV charger sensors (#152722) 2025-09-28 22:45:11 +03:00
Allen Porter 281a137ff5 Add missing translations for Model Context Protocol integration (#153147) 2025-09-28 20:05:15 +02:00
tronikos d6543480ac Refactor SQL integration (#153135) 2025-09-28 19:03:13 +02:00
Luca Graf ae6391b866 Ignore gateway device in ViCare integration (#153097) 2025-09-28 16:04:22 +02:00
Joakim Plate 10b56e4258 Ensure togrill detects disconnected devices (#153067) 2025-09-28 15:34:56 +02:00
Erwin Douna 0ff2597957 Portainer add re-auth flow (#153077) 2025-09-28 15:31:50 +02:00
Artur Pragacz 026b28e962 Improve interview logging in Onkyo (#153095) 2025-09-28 15:26:40 +02:00
peteS-UK 9a1e67294a Extend timeout test in test_config_flow for Squeezebox to completion (#153080) 2025-09-28 15:20:47 +02:00
G Johansson cdb448a5cc Use automatic reload options flow in random (#153103) 2025-09-28 01:02:33 +01:00
G Johansson ab80e726e2 Use automatic reload options flow in filter (#153104) 2025-09-28 01:02:14 +01:00
G Johansson 2d5d0f67b2 Use automatic reload options flow in history_stats (#153115) 2025-09-28 01:01:33 +01:00
G Johansson d4100b6096 Use automatic reload options flow in mold_indicator (#153106) 2025-09-28 01:00:48 +01:00
G Johansson 955e854d77 Use automatic reload options flow in utility_meter (#153111) 2025-09-28 01:00:07 +01:00
G Johansson 0c37f88c49 Use automatic reload options flow in derivative (#153112) 2025-09-28 00:59:07 +01:00
G Johansson 48167eeb9c Use automatic reload options flow in worldclock (#153105) 2025-09-28 00:58:20 +01:00
G Johansson 24177197f7 Use automatic reload options flow in generic_thermostat (#153108) 2025-09-28 00:57:12 +01:00
G Johansson 863fc0ba97 Use automatic reload options flow in switch_as_x (#153109) 2025-09-28 00:52:26 +01:00
G Johansson 9f7b229d02 Use automatic reload options flow in template (#153110) 2025-09-28 00:50:00 +01:00
G Johansson ffd909f3d9 Use automatic reload options flow in group (#153116) 2025-09-28 00:48:44 +01:00
Tom 1ebf096a33 Add reauthentication flow to airOS (#153076)
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2025-09-27 23:28:14 +02:00
Robert Resch 96d51965e5 Bump deebot-client to 15.0.0 (#153125) 2025-09-27 23:24:39 +02:00
G Johansson 04b510b020 Fix event range in workday calendar (#153128) 2025-09-27 23:22:39 +02:00
G Johansson c9a301d50e Use automatic reload options flow in systemmonitor (#153107) 2025-09-27 20:50:14 +02:00
G Johansson b304bd1a8b Use automatic reload options flow in local_file (#153114) 2025-09-27 20:49:39 +02:00
G Johansson b99525b231 Use automatic reload options flow in tod (#153113) 2025-09-27 20:45:40 +02:00
G Johansson 634db13990 Use automatic reload options flow in trend (#153117) 2025-09-27 20:44:53 +02:00
peteS-UK ad51a77989 Extend squeezebox config_flow test to completion (#153000)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-09-27 20:36:38 +02:00
G Johansson 3348a39e8a Use automatic reload options flow in generic_hygrostat (#153102) 2025-09-27 20:33:57 +02:00
Christian McHugh 81c2e356ec Fix: Set EPH climate heating as on only when boiler is actively heating (#152914) 2025-09-27 20:19:57 +02:00
Jan Bouwhuis de6c3512d2 Add IMAP fetch message part feature (#152845) 2025-09-27 14:49:26 +02:00
G Johansson 36dc1e938a Fix can exclude optional holidays in workday (#153082) 2025-09-27 14:40:29 +02:00
Sören Beye 07a78cf6f7 Squeezebox: Proxy all the thumbnails (#147199)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-27 14:39:15 +02:00
Erwin Douna eaa673e0c3 Portainer switch terminology to API token (#152958)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-27 14:32:25 +02:00
Simone Chemelli f2c4ca081f Remove redundant code for Alexa Devices (#153083) 2025-09-27 13:05:07 +02:00
Thomas D e3d707f0b4 Prevent duplicate entities for Volvo integration (#151779) 2025-09-27 12:29:11 +02:00
Tom fb93fed2e5 Bump airOS dependency (#153065) 2025-09-27 01:20:51 +02:00
Björn Dalfors 95dfc2f23d Bump nibe dependency to 2.19.0 (#153062) 2025-09-26 23:49:40 +01:00
Franck Nijhof 77f897a768 Bump version to 2025.10.0b4 2025-09-26 21:30:19 +00:00
Franck Nijhof 4f0a6ef9a1 Update Home Assistant base image to 2025.09.3 (#153064) 2025-09-26 21:30:12 +00:00
Franck Nijhof 408df2093a Update Home Assistant base image to 2025.09.3 (#153064) 2025-09-26 23:28:43 +02:00
Franck Nijhof 66c6b0f5fc Bump version to 2025.10.0b3 2025-09-26 20:37:41 +00:00
Josef Zweck dd01243391 Ensure token validity in lamarzocco (#153058) 2025-09-26 20:36:47 +00:00
SapuSeven 66c17e250a Add None-check for VeSync fan device.state.display_status (#153055) 2025-09-26 20:36:46 +00:00
DeerMaximum 723902e233 NINA Use better wording for filters (#153050) 2025-09-26 20:36:45 +00:00
Paul Bottein 59fdb9f3b5 Update frontend to 20250926.0 (#153049) 2025-09-26 20:36:44 +00:00
Martin Hjelmare d83502514a Fix Thread flow abort on multiple flows (#153048) 2025-09-26 20:36:43 +00:00
Stefan Agner 08e81b2ba6 Update Home Assistant base image to 2025.09.2 (#153035) 2025-09-26 20:36:41 +00:00
Josef Zweck 1e808c965d Bump pylamarzocco to 2.1.1 (#153027) 2025-09-26 20:36:40 +00:00
Stefan Agner 563b58c9aa Bump to home-assistant/wheels@2025.09.1 (#153025) 2025-09-26 20:36:39 +00:00
Artur Pragacz cf223880e8 Use satellite entity area in the assist pipeline (#153017) 2025-09-26 20:36:37 +00:00
J. Nick Koston 4058ca59ed Bump aioesphomeapi to 41.11.0 (#153014) 2025-09-26 20:36:36 +00:00
puddly 1386c01733 Allow ZHA discovery if discovery unique_id conflicts with config entry (#153009)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-26 20:36:35 +00:00
puddly 46504947f7 Bump ZHA to 0.0.73 (#153007) 2025-09-26 20:36:34 +00:00
Paulus Schoutsen 0a44682014 Push ESPHome discovery to ZJS addon (#153004) 2025-09-26 20:36:33 +00:00
Brandon Harvey 06a57473a9 Rename service to action in ESPHome (#152997) 2025-09-26 20:36:32 +00:00
Noah Husby fbed66ef1f Bump aiorussound to 4.8.2 (#152988) 2025-09-26 20:36:30 +00:00
puddly 99a0380ec5 Ignore discovery for existing ZHA entries (#152984) 2025-09-26 20:36:29 +00:00
Simone Chemelli 68c51dc7aa Fix PIN failure if starting with 0 for Comelit SimpleHome (#152983) 2025-09-26 20:36:28 +00:00
lliwog 3d945b0fc5 Fix EZVIZ devices merging due to empty MAC addr (#152939) (#152981)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-26 20:36:27 +00:00
Erwin Douna 7b26a93d38 Portainer add ability to skip SSL verification (#152955) 2025-09-26 20:36:25 +00:00
Tom 1b2eab00be Add SSL options during config_flow for airOS (#150325)
Co-authored-by: Åke Strandberg <ake@strandberg.eu>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-26 20:36:24 +00:00
RogerSelwyn 750e849f09 Protect against last_comms being None (#149366)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-26 20:36:22 +00:00
Eskander Bejaoui f32bf0cc3e nmap_tracker: Optimize default scan options (#153047) 2025-09-26 22:31:49 +02:00
peteS-UK dbbe3145b6 Replace patch of entity_registry in test_config_flow for Squeezebox (#153039) 2025-09-26 22:17:47 +02:00
Erik Montnemery f8bf3ea2ef Correct filter of target selector in motioneye services (#152971) 2025-09-26 22:08:19 +02:00
Bouwe Westerdijk 053bd31d43 Snapshot testing for Plugwise Switch platform (#153030) 2025-09-26 22:07:42 +02:00
DeerMaximum 1aefc3f37a NINA Use better wording for filters (#153050) 2025-09-26 22:05:10 +02:00
Joris Pelgröm 3de955d9ce Use UnitOfTime.DAYS instead of custom unit for LetPot number entity (#153054) 2025-09-26 21:58:17 +02:00
SapuSeven 0ff88fd366 Add None-check for VeSync fan device.state.display_status (#153055) 2025-09-26 21:57:01 +02:00
peteS-UK eb84020773 Replace platform setup functions with fixtures with autouse in Squeezebox tests (#153057) 2025-09-26 21:49:58 +02:00
Tom 4bbfea3c7c Add SSL options during config_flow for airOS (#150325)
Co-authored-by: Åke Strandberg <ake@strandberg.eu>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-26 21:38:27 +02:00
Josef Zweck 63d4fb7558 Ensure token validity in lamarzocco (#153058) 2025-09-26 21:36:03 +02:00
Artur Pragacz 953895cd81 Use satellite entity area in the assist pipeline (#153017) 2025-09-26 21:34:45 +02:00
Erwin Douna a6c3f4efc0 Portainer add ability to skip SSL verification (#152955) 2025-09-26 21:32:49 +02:00
Paul Bottein 11e880d034 Update frontend to 20250926.0 (#153049) 2025-09-26 21:31:47 +02:00
Martin Hjelmare e4d6bdb398 Fix Thread flow abort on multiple flows (#153048) 2025-09-26 18:48:51 +01:00
Andrew Jackson 6ced1783e3 Add discovery to Mealie (#151773)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-26 18:48:19 +02:00
Paulus Schoutsen 8051f78d10 Push ESPHome discovery to ZJS addon (#153004) 2025-09-26 10:12:56 -04:00
Josef Zweck b724176b23 Bump pylamarzocco to 2.1.1 (#153027) 2025-09-26 15:46:24 +02:00
Erik Montnemery fdca16ea92 Fix typing in ObjectSelectorConfig (#153043) 2025-09-26 15:18:18 +02:00
Stefan Agner f8fd8b432a Update Home Assistant base image to 2025.09.2 (#153035) 2025-09-26 13:03:39 +02:00
lliwog 9148ae70ce Fix EZVIZ devices merging due to empty MAC addr (#152939) (#152981)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-26 12:47:11 +02:00
RogerSelwyn 447cb26d28 Protect against last_comms being None (#149366)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-26 12:35:04 +02:00
J. Nick Koston 2af36465f6 Bump aioesphomeapi to 41.11.0 (#153014) 2025-09-26 12:31:59 +02:00
dependabot[bot] d5f7265424 Bump github/codeql-action from 3.30.3 to 3.30.4 (#153015)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-26 12:31:15 +02:00
Simone Chemelli cc16af7f2d Code optimization for Uptime Robot (#153031) 2025-09-26 12:29:02 +02:00
Retha Runolfsson 7a4d75bc44 Add garage door opener for switchbot integration (#148460) 2025-09-26 12:11:59 +02:00
Bouwe Westerdijk ec0380fd3b Snapshot testing for Plugwise Sensor platform (#153021) 2025-09-26 11:22:14 +02:00
Stefan Agner b17cc71dfb Bump to home-assistant/wheels@2025.09.1 (#153025) 2025-09-26 11:04:02 +02:00
Erik Montnemery 89b327ed7b Remove device filter from target selector in bang_olufsen services (#152957) 2025-09-26 09:02:14 +02:00
Simone Chemelli 9bf361a1b8 Fix PIN failure if starting with 0 for Comelit SimpleHome (#152983) 2025-09-26 08:59:03 +02:00
J. Diego Rodríguez Royo d11c171c75 Bump aiohomeconnect to version 0.20.0 (#153003) 2025-09-26 07:49:38 +02:00
puddly c523c45d17 Allow ZHA discovery if discovery unique_id conflicts with config entry (#153009)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-26 07:39:00 +02:00
puddly c1b9c0e1b6 Ignore discovery for existing ZHA entries (#152984) 2025-09-26 07:17:01 +02:00
puddly 487b9ff03e Bump ZHA to 0.0.73 (#153007) 2025-09-25 23:44:25 -04:00
Simone Chemelli ec62b0cdfb Code optimization for Uptime Robot (#152993) 2025-09-26 00:34:09 +01:00
Brandon Harvey 6d0470064f Rename service to action in ESPHome (#152997) 2025-09-25 14:54:06 -05:00
Simone Chemelli 7450b3fd1a Improve tests for Alexa Devices (#152995) 2025-09-25 21:39:44 +02:00
Noah Husby 5b70910d77 Bump aiorussound to 4.8.2 (#152988) 2025-09-25 20:34:29 +02:00
Franck Nijhof 6aaddad56b Bump version to 2025.10.0b2 2025-09-25 18:19:29 +00:00
Paul Bottein a5af974209 Update frontend to 20250925.1 (#152985) 2025-09-25 18:18:47 +00:00
Luke Lashley 09e45f6f54 Fix incorrect Roborock test (#152980) 2025-09-25 18:18:46 +00:00
Joost Lekkerkerker d857d8850c Bump pySmartThings to 3.3.0 (#152977) 2025-09-25 18:18:45 +00:00
J. Nick Koston ccc50f2412 Bump aioesphomeapi to 41.10.0 (#152975)
Co-authored-by: Michael Hansen <mike@rhasspy.org>
2025-09-25 18:18:43 +00:00
Maciej Bieniek 3905723900 Bump accuweather to version 4.2.2 (#152965) 2025-09-25 18:18:42 +00:00
Simone Chemelli cee88473a2 Remove deprecated sensors and update remaning for Alexa Devices (#151230) 2025-09-25 18:18:40 +00:00
Daniel Potthast cdf613d3f8 Update mvglive component (#146479)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-25 18:18:39 +00:00
Abílio Costa 52de5ff5ff Remove deprecated zone and event condition keys (#152986) 2025-09-25 19:23:40 +02:00
J. Nick Koston c4389a1679 Bump aioesphomeapi to 41.10.0 (#152975)
Co-authored-by: Michael Hansen <mike@rhasspy.org>
2025-09-25 19:21:17 +02:00
Norbert Rittel 35faaa6cae Add missing square brackets to references in fully_kiosk actions (#152987) 2025-09-25 19:19:27 +02:00
Paul Bottein 3c0b13975a Update frontend to 20250925.1 (#152985) 2025-09-25 19:05:12 +02:00
Simone Chemelli bc88696339 Remove deprecated sensors and update remaning for Alexa Devices (#151230) 2025-09-25 18:59:53 +02:00
Erik Montnemery 8f99c3f64a Remove device filter from target selector in lyric services (#152970) 2025-09-25 18:45:32 +02:00
Erik Montnemery 88016d96d4 Remove device and entity filter from target selector in homeassistant services (#152969) 2025-09-25 17:41:54 +01:00
Erik Montnemery 47df73b18f Remove device filter from target selector in google_mail services (#152968) 2025-09-25 18:32:12 +02:00
Maciej Bieniek 1c12d2b8cd Bump accuweather to version 4.2.2 (#152965) 2025-09-25 18:30:47 +02:00
Erik Montnemery eb38837a8c Replace target selector with device selector in fully_kiosk services (#152959)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-25 18:30:05 +02:00
Erik Montnemery 159c7fbfd1 Correct filter of target selector in sonos services (#152972) 2025-09-25 18:29:26 +02:00
Joost Lekkerkerker 7ee31f0884 Bump pySmartThings to 3.3.0 (#152977) 2025-09-25 17:57:30 +02:00
Daniel Potthast 0c5e12571a Update mvglive component (#146479)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-25 17:20:43 +02:00
Luke Lashley 9db973217f Fix incorrect Roborock test (#152980) 2025-09-25 17:18:24 +02:00
Artur Pragacz cf1a745283 Move condition-specific fields into options (#152635) 2025-09-25 15:55:50 +02:00
peteS-UK 834e3f1963 Add HassKey for hass.data in Squeezebox (#149129) 2025-09-25 14:05:40 +02:00
Joakim Sørensen 3f8f7573c9 Bump hass-nabucasa from 1.1.1 to 1.1.2 (#152950) 2025-09-25 11:34:14 +01:00
Franck Nijhof 156a0f1a3d Bump version to 2025.10.0b1 2025-09-25 09:37:33 +00:00
Paul Bottein cc2a5b43dd Update frontend to 20250925.0 (#152945) 2025-09-25 09:37:03 +00:00
Karsten Bade 0ae272f1f6 Add return types and docstring to sonos component (#152946) 2025-09-25 11:34:38 +02:00
Paul Bottein 8774295e2e Update frontend to 20250925.0 (#152945) 2025-09-25 11:33:01 +02:00
Erwin Douna 731064f7e9 Portainer fix unique entity (#152941)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-25 08:19:21 +00:00
Sab44 2f75661c20 Bump librehardwaremonitor-api to version 1.4.0 (#152938) 2025-09-25 08:19:20 +00:00
Paulus Schoutsen be6f056f30 Prevent common control calling async methods from thread (#152931)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-25 08:19:18 +00:00
Franck Nijhof 79599e1284 Add block Spook < 4.0.0 as breaking Home Assistant (#152930) 2025-09-25 08:19:17 +00:00
Paulus Schoutsen a255585ab6 Remove some more domains from common controls (#152927) 2025-09-25 08:19:15 +00:00
J. Nick Koston e9bde225fe Bump aioesphomeapi to 41.9.4 (#152923) 2025-09-25 08:19:14 +00:00
Franck Nijhof d9521ac2a0 Bump to home-assistant/wheels@2025.09.0 (#152920) 2025-09-25 08:19:13 +00:00
J. Nick Koston d8b24ccccd Bump aioesphomeapi to 41.9.3 to fix segfault (#152912) 2025-09-25 08:19:12 +00:00
J. Nick Koston b4417a76d5 Fix ESPHome reauth not being triggered on incorrect password (#152911) 2025-09-25 08:19:10 +00:00
Simone Chemelli 274f6eb54a Update IQS to platinum for Comelit SimpleHome (#152906) 2025-09-25 08:19:09 +00:00
Simone Chemelli 21a5aaf35c Update IQS to platinum for Alexa Devices (#152905) 2025-09-25 08:19:07 +00:00
Luke Lashley 05820a49d0 Fix logical error when user has no Roborock maps (#152752) 2025-09-25 08:19:06 +00:00
Erwin Douna 0c8d2594ef Portainer fix unique entity (#152941)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-25 09:49:22 +02:00
Simone Chemelli 205bd2676b Update IQS to platinum for Alexa Devices (#152905) 2025-09-25 09:45:50 +02:00
dependabot[bot] 25849fd9cc Bump actions/cache from 4.2.4 to 4.3.0 (#152934)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-25 09:43:03 +02:00
Sab44 7d6eac9ff7 Bump librehardwaremonitor-api to version 1.4.0 (#152938) 2025-09-25 09:42:31 +02:00
Luke Lashley 31017ebc98 Fix logical error when user has no Roborock maps (#152752) 2025-09-25 09:39:52 +02:00
Jimmy Zhening Luo 724a7b0ecc Quality: mark installation param doc as done (#152909) 2025-09-25 09:06:13 +02:00
Paulus Schoutsen 91e13d447a Prevent common control calling async methods from thread (#152931)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-24 23:09:54 -04:00
J. Nick Koston 7c8ad9d535 Fix ESPHome reauth not being triggered on incorrect password (#152911) 2025-09-24 22:27:40 -04:00
Franck Nijhof 9cd3ab853d Add block Spook < 4.0.0 as breaking Home Assistant (#152930) 2025-09-24 22:18:06 -04:00
Paulus Schoutsen 0b0f8c5829 Remove some more domains from common controls (#152927) 2025-09-24 22:15:29 -04:00
J. Nick Koston ae7bc7fb1b Bump aioesphomeapi to 41.9.4 (#152923) 2025-09-24 19:16:48 -05:00
Franck Nijhof 09750872b5 Bump version to 2025.11.0dev0 (#152915) 2025-09-24 23:55:32 +02:00
Franck Nijhof 076e51017b Bump to home-assistant/wheels@2025.09.0 (#152920) 2025-09-24 23:12:20 +02:00
Simone Chemelli 95e7b00996 Update IQS to platinum for Comelit SimpleHome (#152906) 2025-09-24 22:03:31 +01:00
J. Nick Koston ddecf1ac21 Bump aioesphomeapi to 41.9.3 to fix segfault (#152912) 2025-09-24 22:00:45 +01:00
Franck Nijhof 17b12d29af Bump version to 2025.10.0b0 2025-09-24 18:57:19 +00:00
Marc Mueller 9cc78680d6 Fix lg_thinq test RuntimeWarning (#152910) 2025-09-24 21:28:49 +03:00
Simone Chemelli 14d42e43bf Add dynamic devices management for Alexa Devices (#151975) 2025-09-24 19:00:35 +02:00
Simone Chemelli ed5f5d4b33 Add dynamic devices management for Comelit SimpleHome (#152137) 2025-09-24 18:57:56 +02:00
Kinachi249 c3ba086fad Add new Cync by GE integration (#149848)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-24 18:43:50 +02:00
Abílio Costa 7b5314605c Revert "Rename function arguments in modbus (#152814)" (#152904) 2025-09-24 17:25:01 +01:00
Karsten Bade 3a806d6603 Add dc:title support for Sonos sharelinks (#152774)
Co-authored-by: Pete Sage <76050312+PeteRager@users.noreply.github.com>
2025-09-24 17:23:58 +01:00
starkillerOG 6dd33f900d Add support for Reolink chime connected to Home Hub (#151199) 2025-09-24 18:07:23 +02:00
Paul Bottein 2844bd474a Update frontend to 20250924.0 (#152901) 2025-09-24 18:05:13 +02:00
Artur Pragacz d865fcf999 Do not include capabilities in extended analytics (#152900)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-09-24 11:58:44 -04:00
Bouwe Westerdijk 79a2fc5a01 Snapshot testing for Plugwise Select platform (#152827) 2025-09-24 17:51:04 +02:00
alorente 19d87abb8a Add Q-Adapt to Airzone integration (#151945) 2025-09-24 17:43:32 +02:00
Joris Pelgröm c4de46a85b Add number platform to LetPot integration (#151092) 2025-09-24 17:41:36 +02:00
epenet e79a434d9b Use DeviceCategory in Tuya remaining platforms (#152890) 2025-09-24 17:39:46 +02:00
Manu 9a801424c7 Fix deleting message filters in ntfy integration (#152783) 2025-09-24 17:38:40 +02:00
Paulus Schoutsen 5cb186980a Mark MQTT as service (#152899) 2025-09-24 11:35:23 -04:00
Ravaka Razafimanantsoa 1629ade97f Add Smart Meter B Route integration (#123446)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-24 17:31:30 +02:00
puddly ccf0011ac2 Skip ignored discovery entries when showing migrate/setup config flow steps for ZHA and Hardware (#152895) 2025-09-24 17:31:04 +02:00
puddly 70077511a3 Unload ZHA integration before adapter migration (#152896) 2025-09-24 17:28:55 +02:00
Petar Petrov dfbaf66021 Add progress step decorator for easier config flows (#152739)
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-09-24 18:18:42 +03:00
Richard Polzer 62cea48a58 Fix typo in ekeybionyx strings.json (#152889) 2025-09-24 15:46:22 +01:00
Michael Hansen c493c7dd67 Bump intents and fix tests (#152893) 2025-09-24 09:24:42 -05:00
Maciej Bieniek fdaceaddfd Add new virtual integration Neo (#152886) 2025-09-24 14:57:22 +02:00
epenet a2f4073d54 Use DeviceCategory in Tuya more platforms (#152885) 2025-09-24 14:40:25 +02:00
epenet 2d01a99ec2 Bump renault-api to 0.4.1 (#152883) 2025-09-24 12:44:33 +01:00
epenet 311d4c4262 Use DeviceCategory in Tuya binary sensor (#152882) 2025-09-24 13:31:44 +02:00
Erik Montnemery e14f5ba44d Fix misleading + unclear comment in homeassistant.const (#152878) 2025-09-24 13:22:32 +02:00
Artur Pragacz 9babc85517 Add analytics to core files (#152877) 2025-09-24 13:21:40 +02:00
Marc Mueller 332a3fad3c Fix mypy errors (#152879) 2025-09-24 13:09:32 +02:00
Michael 8782aa4f60 Hide asserts behind TYPE_CHECKING in Synology DSM (#152880) 2025-09-24 12:49:44 +02:00
jan iversen 475b84cc5f Remove codeowner. (#152869) 2025-09-24 12:43:22 +02:00
Artur Pragacz 0f904d418b Filter out integration types in extended analytics (#152874) 2025-09-24 12:32:30 +02:00
Artur Pragacz 4ea4eec2d8 Remove analytics platform in template (#152876) 2025-09-24 12:32:14 +02:00
Artur Pragacz afefa16615 Remove analytics platform in automation (#152875) 2025-09-24 12:29:33 +02:00
Martin Hjelmare 1dccbee45c Remove hardware flow thread confirm step after install (#152868) 2025-09-24 11:28:10 +01:00
Simone Chemelli 711a56db2f Add dynamic devices management for UptimeRobot (#152139) 2025-09-24 10:56:56 +01:00
Joost Lekkerkerker 9d1c7dadff Make SmartThings AC preset modes translatable (#152833) 2025-09-24 10:55:28 +01:00
Richard Polzer 7d1953e387 Add Ekey Bionyx integration (#139132)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-24 11:54:27 +02:00
Martin Hjelmare 023ecf2a64 Patch async_setup_entry in hardware integration flow tests (#152871) 2025-09-24 11:49:01 +02:00
epenet 934db458a3 Simplify access to Tuya device manager in async_setup_entry (#152859) 2025-09-24 11:47:28 +02:00
epenet 0a6ae3b52a Add enum for Tuya device categories (#152858) 2025-09-24 11:46:33 +02:00
Patrick bdd0b74d51 Enhance Synology DSM handling of external USB drives (#145943)
Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>
2025-09-24 11:26:22 +02:00
Norbert Rittel 8837f2aca7 Capitalize "Auto Cycle Link" as feature name in smartthings (#152864) 2025-09-24 11:11:35 +02:00
Artur Pragacz 403cd2d8ef Filter out custom integrations in extended analytics (#152820) 2025-09-24 10:24:42 +02:00
Erik Montnemery ddfc528d63 Fix apparent copy-paste error in tests of trigger helper (#152855) 2025-09-24 08:38:32 +02:00
Nick Kuiper ddea2206c3 Add start charge session action for blue current integration. (#145446) 2025-09-24 08:11:33 +02:00
J. Nick Koston 32aacac550 Fix async_get_scanner return type for BleakScanner compatibility (#152840) 2025-09-23 23:14:08 -05:00
Luke Lashley dadba274aa Bump python-roborock to 2.47.1 (#152844) 2025-09-23 22:16:32 -04:00
TheJulianJES 14b5b9742c Bump ZHA to 0.0.72 (#152850) 2025-09-23 22:15:00 -04:00
Michael Hansen a0be737925 Auto select first active wake word (#152562) 2025-09-23 17:19:04 -04:00
Marcel van der Veldt ff47839c61 Fix support for new Hue bulbs with very wide color temperature support (#152834) 2025-09-23 16:56:16 -04:00
Copilot 9ba7dda864 Rename logbook integration to "Activity" in user-facing strings (#150950) 2025-09-23 22:55:11 +02:00
J. Nick Koston 911f901d9d Bump aioesphomeapi to 41.9.0 (#152841) 2025-09-23 22:54:31 +02:00
Marcel van der Veldt 2008a73657 Add support for Hue MotionAware sensors (#152811)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-09-23 16:52:09 -04:00
Pete Sage 60bf298ca6 File add read_file action with Response (#139216) 2025-09-23 22:25:56 +02:00
jan iversen 3bc2ea7b5f Use DOMAIN not MODBUS_DOMAIN (#152823) 2025-09-23 22:07:24 +02:00
Kevin Stillhammer 3bac6b86df Fix multiple_here_travel_time_entries issue description (#152839) 2025-09-23 22:06:06 +02:00
Stefan Agner 20293e2a11 Bump aiohasupervisor to 0.3.3b0 (#152835)
Co-authored-by: Claude <noreply@anthropic.com>
2025-09-23 22:05:38 +02:00
Martin Hjelmare 15cc28e6c1 Move first probe firmware to firmware progress in hardware flow (#152819) 2025-09-23 22:03:04 +02:00
puddly 874ca1323b Simplified ZHA adapter migration and setup flow (#152389) 2025-09-23 22:00:31 +02:00
Ludovic BOUÉ ca186925af Add Matter Thermostat OutdoorTemperature sensor (#152632) 2025-09-23 21:28:24 +02:00
andreimoraru 2ab051b716 Bump yt-dlp to 2025.09.23 (#152818) 2025-09-23 20:03:53 +01:00
epenet a2a726de34 Rename function arguments in modbus (#152814) 2025-09-23 20:54:52 +02:00
Sarah Seidman 5d543d2185 Bump pydroplet version to 2.3.3 (#152832) 2025-09-23 19:36:06 +01:00
epenet a78c909b34 Rename cover property in tuya (#152822) 2025-09-23 19:35:47 +01:00
Artur Pragacz f00ab80d17 Add analytics platform to template (#152824) 2025-09-23 13:53:53 -04:00
Joakim Sørensen 014881d985 Fix error handling in subscription info retrieval and update tests (#148397)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-23 19:53:12 +02:00
Artur Pragacz 29a42a8e58 Add analytics platform to automation (#152828) 2025-09-23 13:52:58 -04:00
Rohan Kapoor 3f70084d7f Handle ignored and disabled entries correctly in zeroconf discovery for Music Assistant (#152792)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-23 10:15:52 -07:00
Felipe Santos b1ae9c95c9 Add a switch entity for add-ons (#151431)
Co-authored-by: Stefan Agner <stefan@agner.ch>
2025-09-23 17:27:35 +02:00
Artur Pragacz 8be79ecdb0 Move conversation trigger registration to manager (#152749) 2025-09-23 10:01:46 -05:00
Jan Bouwhuis f6b8aa893b Add mqtt image subentry support (#151586) 2025-09-23 16:31:40 +02:00
jan iversen c867026bdd Add test to validate multiple host/port for modbus. (#152658)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-09-23 16:03:42 +02:00
Kevin Stillhammer da3a164e66 Change here_travel_time update interval to 30min (#147222) 2025-09-23 15:56:13 +02:00
Josef Zweck 32688e1108 Bump aioacaia to 0.1.17 (#152815) 2025-09-23 15:29:16 +02:00
Artur Pragacz 4305ea9b4c Create analytics platform (#151974) 2025-09-23 09:16:37 -04:00
epenet 61153ec456 Deduplicate code in modbus service call (#152808)
Co-authored-by: jan iversen <jancasacondor@gmail.com>
2025-09-23 13:44:28 +02:00
Marcel van der Veldt 9e4a2d5fa9 Bump aiohue to 4.8.0 (#152807) 2025-09-23 13:39:58 +02:00
Marcel van der Veldt 72e608918b Handle toggling of the 'expose_to_ha' setting in Music Assistant integration (#152779) 2025-09-23 13:22:16 +02:00
Erik Montnemery 86db60c442 Freeze time in irm_kmi tests (#152810) 2025-09-23 13:21:59 +02:00
cdnninja 25806615a9 Bump pyvesync to 3.0.0 (#152726) 2025-09-23 13:00:59 +02:00
Paulus Schoutsen a0f67381e5 Allow configuring Z-Wave JS to talk via ESPHome (#152590)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-23 12:58:36 +02:00
Jan Čermák 90bfadda9b Support all reported preset modes in Smartthings climate (#148056)
Co-authored-by: abmantis <amfcalt@gmail.com>
2025-09-23 12:56:27 +02:00
Maciej Bieniek 0f8e700965 Add a cable unplugged sensor for Shelly Flood Gen4 (#152559) 2025-09-23 12:55:44 +02:00
Jan Čermák 21d4ed2837 Add profiler service for dumping sockets used by HA (#152440)
Co-authored-by: Stefan Agner <stefan@agner.ch>
2025-09-23 12:55:29 +02:00
Luke Lashley ce363b3835 Make Roborock load_multi_map always cloud dependent. (#152698) 2025-09-23 12:55:07 +02:00
G Johansson dd3e6b8df5 Only load selected processes in systemmonitor (#152777) 2025-09-23 12:41:31 +02:00
epenet abbf8390ac Move switch to valve for Tuya sfkzq category (#152478) 2025-09-23 12:39:37 +02:00
epenet 689039959c Improve current_state support in Tuya curtains (#152801) 2025-09-23 12:38:47 +02:00
epenet 52c25cfc88 Rename modbus internal variable (#152805) 2025-09-23 12:14:05 +02:00
G Johansson 00b2017767 Fix resource and payload template in scrape (#152670) 2025-09-23 11:59:00 +02:00
Martin Hjelmare dd7f7be6ad Move hardware thread add-on install after firmware install (#152800) 2025-09-23 11:47:30 +02:00
Robert Resch 22709506c6 Add Ecovacs custom water amount entity (#152782)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-23 11:21:11 +02:00
Lukas f0c0492375 Add MAC address to Pooldose device (#152760)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-23 11:11:08 +02:00
Robert Resch 58459cb80f Bump deebot-client to 14.0.0 (#152448) 2025-09-23 10:47:37 +02:00
epenet a19e378447 Add Tuya test fixture files (#152795) 2025-09-23 10:44:36 +02:00
J. Nick Koston 38a5a3ed4b Handle wrong ESPHome device without encryption appearing at the configured IP (#152758) 2025-09-23 10:27:13 +02:00
Matthias Lohr e76bed4a83 Add reconfigure flow to tolo (#137609)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-09-23 10:21:06 +02:00
Karsten Bade d73309ba60 Bump SoCo to 0.30.12 (#152797) 2025-09-23 09:49:33 +02:00
Przemko92 19fdea024c Bump compit-inext-api to 0.3.1 (#152781) 2025-09-23 09:48:53 +02:00
Manu a3cfd7f707 Fix coordinator data handling in Bring integration (#152786) 2025-09-23 09:03:01 +02:00
Petro31 3dd941eff7 Fix section and entity variable resolution for template platforms (#149660)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-23 08:12:24 +02:00
J. Nick Koston d389141aee Bump aioesphomeapi to 41.6.0 (#152787) 2025-09-22 21:43:20 -05:00
Rohan Kapoor 3c542b8d43 Only update Music Assistant URL on zeroconf discovery when current URL is unreachable (#152030) 2025-09-22 13:49:41 -07:00
starkillerOG 2367df89d9 Bump reolink-aio to 0.15.2 (#152775) 2025-09-22 21:39:06 +01:00
Manu 7bfdfb3fc7 Bump pynecil to v4.2.0 (#152776) 2025-09-22 21:35:19 +01:00
G Johansson 485916265a Fix manual updating of Nord Pool sensors (#152773) 2025-09-22 22:04:17 +02:00
Stefan Agner 1bb3c96fc1 Drop Windows compatibility code from systemmonitor integration (#152545) 2025-09-22 21:26:26 +02:00
Artur Pragacz 4eaf6784af Use satellite entity area in the default agent (#152762) 2025-09-22 13:34:31 -05:00
Abílio Costa 7b7265a6b0 Revert "Add EZVIZ battery camera power status and online status sensor (#146822)" (#152767) 2025-09-22 19:03:32 +02:00
Thomas D 9059e3dadc Prepare Volvo integration for new platforms (#152042) 2025-09-22 18:41:44 +02:00
J. Nick Koston d9d42b3ad5 Pass timezone to aioesphomeapi to ensure HA timezone takes precedence (#152756) 2025-09-22 09:54:15 -06:00
epenet d565fb3cb4 Bump mcp to 1.14.1 (#152737) 2025-09-22 17:33:48 +02:00
G Johansson 6e93e480d1 Use automatic reload options flow in integration (#152686) 2025-09-22 15:27:19 +01:00
Maciej Bieniek 5a3570702d Add re-auth flow to AccuWeather integration (#152755) 2025-09-22 16:27:09 +02:00
Abílio Costa b26b1df143 Fix unitless converter missing valid units (#152665) 2025-09-22 15:19:31 +01:00
Manu fdbff76733 Add collapse checklist field to Habitica create/update task actions (#150988) 2025-09-22 16:16:47 +02:00
epenet 018d59a892 Drop hass argument from service extraction helpers (#152738) 2025-09-22 16:08:07 +02:00
Andrew Jackson 4b6dd0eb8f Add optional language to Mastodon post action (#151072) 2025-09-22 16:01:09 +02:00
Wendelin b7db87bd3d Update regex for core logs path to include latest logs (#152747) 2025-09-22 14:07:49 +01:00
Jules Dejaeghere 86dc453c55 Add integration for Belgian weather provider meteo.be (#144689)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-22 13:28:41 +02:00
Abílio Costa a4f2c88c7f Add TriggerConfig to reduce ambiguity (#152563) 2025-09-22 12:24:47 +01:00
Erik Montnemery 3cdb894e61 Small improvement of exposed_entities test (#152744) 2025-09-22 13:16:02 +02:00
Bouwe Westerdijk cb837aaae5 Number snapshot testing for Plugwise (#152673) 2025-09-22 11:55:57 +02:00
G Johansson 82443ded34 Use already cached data in Nord Pool if valid (#152664) 2025-09-22 11:55:00 +02:00
Retha Runolfsson 71cc3b7fcd Add K11+ Vacuum for switchbot integration (#152643) 2025-09-22 11:51:39 +02:00
G Johansson e5658f9747 Use automatic reload options flow in statistics (#152682) 2025-09-22 11:48:58 +02:00
G Johansson 868ded141f Use automatic reload options flow in threshold (#152684) 2025-09-22 11:48:37 +02:00
LG-ThinQ-Integration 1151fa698d Add energy usage sensors of ThinQ devices. (#152141)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
2025-09-22 11:47:18 +02:00
Paulus Schoutsen 2796d6110a Split up media source integration (#152721)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-22 11:46:24 +02:00
Tom Matheussen 844b97bd32 Add Satel Integra diagnostics (#152621)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-22 11:38:26 +02:00
Lukas 286b2500bd Pooldose: Add Dhcp discovery (#152253)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-22 11:31:40 +02:00
Joshua Leaper 4b7746ab51 Bump nessclient to 1.3.1 (#152700) 2025-09-22 11:01:04 +03:00
Abílio Costa ca1c366f4f Remove unused var from llm helper (#152724) 2025-09-22 09:57:16 +02:00
epenet de42ac14ac Drop unused hass argument from internal helper (#152733) 2025-09-22 09:56:52 +02:00
J. Nick Koston 7f7bd5a97f Bump aioesphomeapi to 41.5.0 (#152730) 2025-09-22 09:56:20 +02:00
epenet 8a70a1badb Drop hass argument from verify_domain_control (#147946) 2025-09-22 08:15:41 +02:00
Shay Levy 181741cab6 Use component role in Shelly sensor platform (#152710)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-22 01:03:29 +03:00
Maciej Bieniek 1e14fb6dab Use the common unique_id schema in the Shelly button platform (#152707) 2025-09-21 19:34:50 +02:00
Maciej Bieniek 2b6a125927 Support Shelly presencezone component (#152393)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
2025-09-21 19:27:40 +02:00
Abílio Costa e61ad10708 Split sensor unit long condition (#152668) 2025-09-21 16:49:13 +01:00
Shay Levy 5177f9e8c2 Add support for Shelly object based entities (#152046)
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
2025-09-21 17:08:43 +03:00
Luke Lashley 850aeeb5eb Explicitly connect to the Roborock API before sending messages (#152697) 2025-09-21 12:37:15 +02:00
J. Nick Koston a1b9061060 Bump aiohomekit to 3.2.18 (#152694) 2025-09-21 12:14:21 +02:00
Maciej Bieniek 0ec1f27489 Use DeviceClass.PM4 in NAM integration (#152703) 2025-09-21 11:59:09 +02:00
J. Diego Rodríguez Royo befc93bc73 Delete Home Connect alarm clock entity from time platform (#152188) 2025-09-21 10:23:51 +01:00
Luke Lashley 1526d953bf Make Roborock A01 initilization threadsafe (#152699) 2025-09-21 07:52:26 +02:00
G Johansson d38082a5c8 Use automatic reload options flow in Scrape (#152681) 2025-09-20 22:02:23 +01:00
G Johansson 42850421d2 Use automatic reload options flow in wake_on_lan (#152683) 2025-09-20 22:01:11 +01:00
avee87 21a835c4b4 Expose pressure as a separate sensor for metoffice (#152685) 2025-09-20 21:59:14 +01:00
Manu e9294dbf72 Bump pyecotrend-ista to v3.4.0 (#152678) 2025-09-20 21:52:51 +01:00
Daniel Hjelseth Høyer 5c4dfbff1b Update Tibber lib 0.32.1 (#152677) 2025-09-20 20:52:24 +02:00
G Johansson abe628506d Use OptionsFlowWithReload in pvpc_hourly_pricing (#151255) 2025-09-20 18:45:06 +02:00
Franck Nijhof 12cc0ed18d Refactor template engine: Extract raise_no_default() into helper module (#152661)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-20 17:20:05 +01:00
Franck Nijhof 8ca7562390 Merge branch 'master' into dev 2025-09-20 14:28:37 +00:00
GSzabados 942f7eebb1 Add PM4 device class for Ecowitt (#152568) 2025-09-20 14:40:21 +02:00
Franck Nijhof 1a167e6aee Refactor template engine: Extract context and render info (#152630) 2025-09-20 14:15:24 +02:00
Stephan van Rooij 9531ae10f2 Remove volvooncall (#150725)
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2025-09-20 14:08:53 +02:00
tronikos bfc9616abf Deprecate google_generative_ai_conversation.generate_content (#152644) 2025-09-20 07:50:31 -04:00
Jan Bouwhuis 054a5d751a Organize order MQTT subentry (test) globals and translation strings (#152576) 2025-09-20 13:24:30 +02:00
Andrea Turri a43ba4f966 Miele add new program phase mapping (#152647) 2025-09-20 11:33:12 +02:00
J. Nick Koston 1a5cae125f Handle unparsable responses during HomeKit Controller initial polling (#152636) 2025-09-19 22:51:21 -05:00
Franck Nijhof f3b9bda876 2025.9.4 (#152634) 2025-09-19 23:08:58 +02:00
Yevhenii Vaskivskyi 3f3aaa2815 Bump asusrouter to 1.21.0 (#151607) 2025-09-19 20:38:05 +00:00
Franck Nijhof 6dc7870779 Bump version to 2025.9.4 2025-09-19 20:07:56 +00:00
G Johansson be83416c72 Bump holidays to 0.81 (#152569) 2025-09-19 20:07:27 +00:00
G Johansson c745ee18eb Bump holidays to 0.80 (#152306) 2025-09-19 20:07:25 +00:00
tronikos cf907ae196 Bump opower to 0.15.5 (#152531) 2025-09-19 20:05:04 +00:00
Pete Sage 8eee53036a Fix Sonos set_volume float precision issue (#152493) 2025-09-19 20:00:42 +00:00
Alexandre CUER b37237d24b Bump pyemoncms to 0.1.3 (#152436) 2025-09-19 20:00:41 +00:00
Matthias Alphart 950e758b62 Fix KNX UI schema missing DPT (#152430) 2025-09-19 20:00:40 +00:00
Josef Zweck 9cd940b7df Add La Marzocco specific client headers (#152419) 2025-09-19 20:00:38 +00:00
Josef Zweck 10b186a20d Bump pylamarzocco to 2.1.0 (#152364) 2025-09-19 20:00:37 +00:00
Imeon-Energy 757aec1c6b Bump imeon_inverter_api to 0.4.0 (#152351)
Co-authored-by: TheBushBoy <theodavid@icloud.com>
2025-09-19 20:00:36 +00:00
Allen Porter 0b159bdb9c Update authorization server to prefer absolute urls (#152313)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-19 20:00:34 +00:00
J. Nick Koston 8728312e87 Bump aiohomekit to 3.2.17 (#152297) 2025-09-19 20:00:33 +00:00
Åke Strandberg bbb67db354 Add proper error handling for /actions endpoint for miele (#152290) 2025-09-19 20:00:31 +00:00
J. Nick Koston 265f5da21a Bump bluetooth-auto-recovery to 1.5.3 (#152256) 2025-09-19 20:00:30 +00:00
J. Nick Koston 54859e8a83 Bump aiohomekit to 3.2.16 (#152255) 2025-09-19 20:00:28 +00:00
Sean Dague c87dba878d Upgrade waterfurnace to 1.2.0 (#152241) 2025-09-19 20:00:27 +00:00
J. Nick Koston 8d8e008123 Fix HomeKit Controller overwhelming resource-limited devices by batching characteristic polling (#152209) 2025-09-19 20:00:25 +00:00
Yevhenii Vaskivskyi b30667a469 Fix bug with the hardcoded configuration_url (asuswrt) (#151858) 2025-09-19 20:00:23 +00:00
Manu 8920c548d5 Bump habiticalib to v0.4.5 (#151720) 2025-09-19 20:00:22 +00:00
Manu eac719f9af Bump habiticalib to v0.4.4 (#151332) 2025-09-19 20:00:20 +00:00
Aidan Timson 71c274cb91 Add power usage sensor to System Bridge (#152625) 2025-09-19 21:16:30 +02:00
Retha Runolfsson d4902361e6 Bump pySwitchbot to 0.71.0 (#152597) 2025-09-19 22:04:42 +03:00
Norbert Rittel f63eee3889 Fix typo and sentence-casing in honeywell exception string (#152619) 2025-09-19 17:07:46 +02:00
Aidan Timson 21bfe610d1 Update systembridgeconnector to 5.1.0 (#152623) 2025-09-19 17:07:15 +02:00
J. Nick Koston 21c174e895 Bump aioesphomeapi to 41.4.0 (#152618)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-09-19 08:20:00 -06:00
Simon Roberts ec148e0459 Add PM4 (particulates < 4μm) sensor and number device classes (#112867)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-19 08:12:09 -06:00
Maciej Bieniek 286763b998 Fix KeyError for Shelly Duo Bulb Gen3 (#152612) 2025-09-19 07:22:48 -06:00
Shay Levy 5f88122a2b Fix Shelly Wall Display virtual button platform (#152582) 2025-09-19 11:44:08 +03:00
Åke Strandberg 31968d16ab Refactor miele program phase codes part 2(3) (#144180) 2025-09-19 09:54:24 +02:00
epenet c125554817 Rename modbus base entities (#152595) 2025-09-19 09:17:31 +02:00
Abílio Costa 10f2955d34 Update Whirlpool quality scale to silver (#152505) 2025-09-19 08:30:10 +02:00
Paulus Schoutsen 55712b784c Bump aioesphomeapi to 41.3.0 (#152588) 2025-09-18 22:49:03 -04:00
Paulus Schoutsen fe3a929556 Fix reolink test (#152587) 2025-09-18 21:03:13 -04:00
J. Nick Koston 534801e80d Migrate yale and august integrations to use new lock API (#152579) 2025-09-18 17:20:38 -05:00
J. Nick Koston 8aeda5a0c0 Bump aioesphomeapi to 41.2.0 (#152578) 2025-09-19 01:03:59 +03:00
Ville Skyttä eb1cbbc75c Upgrade upcloud-api to 2.8.0 (#152577) 2025-09-19 01:03:31 +03:00
Przemko92 fa8a4d7098 Add Compit integration (#132164)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-18 21:53:49 +01:00
Andre Lengwenus 2623ebac4d Bump pypck to 0.8.12 (#152573) 2025-09-18 23:34:37 +03:00
Michael Hansen 1746c51ce4 Fix error with pipeline device removal due to multiple selects (#152560) 2025-09-18 14:34:03 -05:00
Joakim Sørensen 8b984a2105 Remove ludeeus as a codeowner for analytics (#152558) 2025-09-18 22:08:22 +03:00
Allen Porter ebee370a56 Bump python roborock to 2.44.1 (#152557) 2025-09-18 21:51:16 +03:00
starkillerOG dabd096587 Add color temperature support to Reolink light entity (#152546) 2025-09-18 21:48:18 +03:00
Simone Chemelli 21399818af Remove stale devices for Comelit SimpleHome (#151519) 2025-09-18 19:43:38 +01:00
G Johansson 4354214fbf Bump holidays to 0.81 (#152569) 2025-09-18 20:35:21 +02:00
Erik Montnemery 5bd39804f1 Remove EntityComponent.async_register_legacy_entity_service (#152539) 2025-09-18 20:34:25 +02:00
Norbert Rittel 6d3ad3ab9c Replace "iCloud account" with "Apple Account" (#152561) 2025-09-18 18:39:54 +02:00
Petar Petrov 4c212bdcd4 Enable thread migration for ZBT integration (#152550) 2025-09-18 18:33:06 +03:00
Petar Petrov b91b39580f Add migrate options to ZBT protocol picker (#152532) 2025-09-18 11:13:58 -04:00
Jan Bouwhuis 472d70b6c9 Add comment on conversion factor for Carbon monoxide on dependency molecular weight (#152535) 2025-09-18 15:36:12 +02:00
tronikos 017a84a859 Bump opower to 0.15.5 (#152531) 2025-09-18 14:29:27 +03:00
starkillerOG d184540967 Bump reolink-aio to 0.15.1 (#152533) 2025-09-18 14:28:16 +03:00
Erik Montnemery 1740984b3b Improve comments in SelectedEntities (#152540) 2025-09-18 14:12:33 +03:00
droans 4db8592c61 Add support for overriding entity_picture to universal (#149387) 2025-09-18 11:59:29 +02:00
Stefan Agner 27e630c107 Make systemmonitor tests timezone independent (#152537) 2025-09-18 12:58:09 +03:00
Åke Strandberg ea8833342d Bump dependency pymiele to v0.5.5 and subsequent code changes (#152534) 2025-09-18 10:33:55 +02:00
epenet 87be2ba823 Use compat UOM in _is_valid_suggested_unit (#152350)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-18 08:38:15 +02:00
Artur Pragacz 51c35eb631 Move default conversation agent to manager (#152479) 2025-09-18 08:22:56 +02:00
Samuel Xiao 24a86d042f Bumb switchbot api to v2.8.0 (#152506) 2025-09-18 07:46:51 +02:00
Manu cd6f653123 Bump aiontfy to v0.6.0 (#152520) 2025-09-18 07:45:22 +02:00
J. Nick Koston fd05ddca28 Bump yalexs to 9.2.0 (#152527) 2025-09-18 07:43:54 +02:00
Artur Pragacz a1f2eb44ae Move trigger-specific fields into options in new-style triggers (#151314) 2025-09-18 07:35:39 +02:00
Samuel Xiao c4ddc03dbc Update codeowner for switchbot cloud Integration (#152526) 2025-09-17 22:54:22 -05:00
J. Nick Koston 9db5aafb71 Bump yalexs to 9.1.0 (#152457) 2025-09-17 22:11:35 -05:00
Ivan Lopez Hernandez 64cdcfb613 Bump google-genai to 1.38.0 (#152523) 2025-09-17 22:14:04 -04:00
Paulus Schoutsen c761ce699c Tweak usage prediction common control algorithm (#152490) 2025-09-17 19:04:25 -04:00
Martin Hjelmare 40ebce4ae8 Improve Home Assistant Hardware flow (#152451)
Co-authored-by: puddly <32534428+puddly@users.noreply.github.com>
2025-09-17 18:23:38 -04:00
puddly 29914d6722 Bump ZHA to 0.0.71 (#152511) 2025-09-17 18:23:08 -04:00
Jan Bouwhuis 5eef6edded Add mg/m³ as a valid UOM for sensor/number Carbon Monoxide device class (#152456) 2025-09-17 22:04:23 +01:00
epenet db729273a5 Add pymodbus to PACKAGE_CHECK_VERSION_RANGE (#152494) 2025-09-17 17:22:45 +02:00
Abílio Costa 946d75d651 Merge similar Whirlpool init tests (#152497) 2025-09-17 17:18:54 +02:00
Abílio Costa 093f779edb Remove target humidity methods from Whirlpool climate (#152498) 2025-09-17 17:18:20 +02:00
Paulus Schoutsen 87658e77a7 Clean up stale comment in AI Task test (#152492) 2025-09-17 17:17:20 +02:00
dontinelli 38f65cda98 Bump solarlog_cli to 0.6.0 (#152500) 2025-09-17 16:02:51 +01:00
Jan Čermák 797c6ddedd Fix APT cache restore failures in CI (#152481)
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2025-09-17 16:52:09 +02:00
NANI fe8a53407a Add Victron Remote Monitoring integration (#143687)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-17 16:38:04 +02:00
Abílio Costa ae5f57fd99 Add unique_id to Whirlpool config entry mock (#152496) 2025-09-17 14:38:53 +01:00
Abílio Costa a93c3cc23c Make Whirlpool log when entity goes unavailable (#152064) 2025-09-17 15:00:23 +02:00
Pete Sage 804b42e1fb Fix Sonos set_volume float precision issue (#152493) 2025-09-17 14:39:28 +02:00
karwosts a4f15e4840 Add debug logging to derivative (#152489) 2025-09-17 14:19:48 +02:00
Pete Sage 2471177c84 Set Sonos quality scale to bronze (#152487) 2025-09-17 14:16:08 +02:00
Yuxin Wang a494d3ec69 Sort the resources for deterministic sensor addition order in APCUPSD (#152467) 2025-09-17 10:41:19 +02:00
Paulus Schoutsen b10a9721a7 Add async_get_image helper to Image integration (#152465) 2025-09-17 10:35:55 +02:00
Paulus Schoutsen 04c0bb20d6 AI Task to store generated images in media dir (#152463) 2025-09-17 10:30:15 +02:00
Paulus Schoutsen 1598c4ebe8 Bump aioesphomeapi to 41.1.0 (#152461)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-16 20:18:54 -04:00
karwosts d67ec7593a Add diagnostics to history_stats (#152460) 2025-09-17 00:02:35 +01:00
Franck Nijhof 4a4c124181 Refactor template engine: Extract collection & data structure functions into CollectionExtension (#152446) 2025-09-16 18:48:50 -04:00
Franck Nijhof c34af4be86 Add active built-in and custom integrations to Cloud support package (#152452) 2025-09-16 18:47:00 -04:00
GSzabados 823071b722 Add LDS01 support (#151820)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-09-16 21:33:47 +02:00
Daniel Jansen 462fa77ba1 Improve waze_travel_time tests (#146495)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-16 21:24:51 +02:00
Yevhenii Vaskivskyi 24fc8b9297 Fix bug with the hardcoded configuration_url (asuswrt) (#151858) 2025-09-16 21:18:29 +02:00
Paulus Schoutsen 2596ab2940 OpenAI to use provided mimetype when available (#152407) 2025-09-16 22:11:46 +03:00
Robert Resch 23fa84e20e Verify that Ecovacs integration is setup without any errors in the tests (#152447) 2025-09-16 20:55:44 +02:00
Shay Levy 7f13141297 Bump aioshelly 13.10.0 (#152442) 2025-09-16 21:25:09 +03:00
karwosts 770f41d079 Diagnostics for derivative sensor (#152445) 2025-09-16 14:24:05 -04:00
Shay Levy df16e85359 Fix typo in update_not_available key in Shelly strings (#152444) 2025-09-16 14:23:10 -04:00
Nathan Spencer 3c6db923a3 Deprecate Litter-Robot 4 night light mode switch (#152249) 2025-09-16 20:18:26 +02:00
Thomas D 450c47f932 Use new method to get the access token in the Volvo integration (#151625)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-16 20:17:43 +02:00
Norbert Rittel 048f64eccf Improve two unsupported_xxx issue descriptions in hassio (#152387)
Co-authored-by: Stefan Agner <stefan@agner.ch>
2025-09-16 19:52:12 +02:00
Maciej Bieniek c4c523e8b7 Open a repair issue if Shelly Wall Display firmware is older than 2.3.0 (#152399) 2025-09-16 19:48:47 +02:00
Matthias Alphart 87e30e0907 Fix KNX UI schema missing DPT (#152430) 2025-09-16 19:39:39 +02:00
Alexandre CUER 74660da2d2 Bump pyemoncms to 0.1.3 (#152436) 2025-09-16 18:32:13 +02:00
Maciej Bieniek 6b8c180509 Bump imgw_pib to version 1.5.6 (#152435) 2025-09-16 18:30:22 +02:00
Alessandro Manighetti eb4a873c43 Add m/min of speed sensors (#146441) 2025-09-16 18:02:22 +02:00
G Johansson 6aafa666d6 Add calendar to Workday (#150596) 2025-09-16 17:29:04 +02:00
Mike Degatano 9ee9bb368d Move Supervisor created persistent notifications into repairs (#152066) 2025-09-16 11:24:48 -04:00
Tom Matheussen 6e4258c8a9 Add Satel Integra config flow (#138946)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-09-16 17:24:15 +02:00
Paulus Schoutsen d65e704823 Add usage_prediction integration (#151206)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-16 10:33:46 -04:00
Retha Runolfsson aadaf87c16 Add switchbot relayswitch 2PM (#146140) 2025-09-16 15:59:13 +02:00
Timothy e70b147c0c Add missing content type to backup http endpoint (#152433) 2025-09-16 09:45:21 -04:00
yufeng 031b12752f Add sensors for Tuya energy storage systems (xnyjcn) (#149237)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-09-16 15:34:21 +02:00
Samuel Xiao df0cfd69a9 Add Climate Panel support to Switchbot Cloud (#152427) 2025-09-16 14:14:09 +02:00
marc7s b2c53f2d78 Add geocaching cache sensors (#145453) 2025-09-16 14:13:54 +02:00
Rafael López Diez 3649e949b1 Add support for sending chat actions in Telegram bot integration (#151378) 2025-09-16 14:06:15 +02:00
Rafael López Diez de7e2303a7 Add support for multi-tap action in Lutron Caseta integration (#150551) 2025-09-16 13:32:10 +02:00
onsmam 892f3f267b Added rain_start and lightningstrike event to publish on the event bus (#146652)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-16 13:31:43 +02:00
Marc Mueller 0254285285 Fix warning in template extensions tests (#152425) 2025-09-16 13:30:36 +02:00
Chris Oldfield 44a95242dc Add downloading and seeding counts to Deluge (#150623) 2025-09-16 13:06:14 +02:00
Marc Mueller f9b1c52d65 Fix warning in prowl tests (#152424) 2025-09-16 12:42:37 +02:00
Josef Zweck aa8d78622c Add La Marzocco specific client headers (#152419) 2025-09-16 13:15:57 +03:00
Franck Nijhof ca6289a576 Refactor template engine: Extract string functions into StringExtension (#152420) 2025-09-16 13:15:43 +03:00
Erik Montnemery 0f372f4b47 Improve condition schema validation (#144793) 2025-09-16 10:44:26 +02:00
Franck Nijhof 4bba167ab3 Refactor template engine: Extract regex functions into RegexExtension (#152417) 2025-09-16 10:38:01 +02:00
Jan-Philipp Benecke 962c0c443d Improve setup completion message of Improv BLE (#152412) 2025-09-16 10:37:47 +02:00
Duco Sebel c6b4cac28a Remember HomeWizard uptime sensor value as timestamp to prevent it spamming the state (#150680)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-16 10:29:37 +02:00
dependabot[bot] 3c7e3a5e30 Bump home-assistant/builder from 2025.03.0 to 2025.09.0 (#152413)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-16 10:28:49 +02:00
Maciej Bieniek fa698956c3 Fix the illuminance level entity name in Shelly integration (#152400)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-09-16 10:16:43 +02:00
Klaas Schoute 32f136b12f Update P1 Monitor integration to use settings method during config flow (#152391) 2025-09-16 10:11:29 +02:00
Josef Zweck e1f617df25 Bump pylamarzocco to 2.1.0 (#152364) 2025-09-16 10:08:08 +02:00
Tomeroeni 84f1b8a5cc Bump aiounifi version to 87 (#152395) 2025-09-16 10:04:06 +02:00
kylehakala e9cedf4852 Bump aioridwell to 2025.09.0 (#152405) 2025-09-16 10:01:50 +02:00
kingy444 9c72b40ab4 Bump HunterDouglas_Powerview dependency to aiopvapi 3.2.1 (#152409) 2025-09-16 09:58:41 +02:00
Marcus Gustavsson 65f655e5f5 Change Prowl to use the prowlpy library and add tests for the Prowl component (#149034)
Co-authored-by: Joostlek <joostlek@outlook.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-16 09:23:08 +02:00
Erik Montnemery af28573894 Refactor zwave js event trigger (#144885) 2025-09-16 07:49:09 +02:00
Jan-Philipp Benecke c5fc1de3df Update url in success message of Improv BLE to use markdown (#152388) 2025-09-15 19:50:19 +01:00
karwosts 1df1144eb9 Add 'stations near me' to radio browser (#150907) 2025-09-15 14:47:16 -04:00
Artur Pragacz d51c0e3752 Revert "Add Matter service actions for vacuum area (#151467)" (#152386) 2025-09-15 20:14:09 +02:00
Ernst Klamer f5157878c2 Bthome encryption fix (#152384) 2025-09-15 20:46:43 +03:00
Lennard Beers fb723571b6 Bump eq3btsmart to 2.3.0 (#152383) 2025-09-15 18:36:12 +01:00
puddly dbf80c3ce3 Bump universal-silabs-flasher to 0.0.32 (#152381) 2025-09-15 19:10:52 +02:00
Joost Lekkerkerker e0a774b598 Add sensor test to Nederlandse Spoorwegen (#152375) 2025-09-15 18:03:14 +01:00
Manu 168afc5f0e Bump pyrate-limiter to v3.9.0 (#152370) 2025-09-15 18:54:26 +02:00
Paulus Schoutsen af23670854 Add quality-scale-verifier Claude agent (#152333) 2025-09-15 17:40:15 +01:00
Jan Bouwhuis 935ce421df Remove unused const in MQTT JSON Light component (#152377) 2025-09-15 11:36:19 -05:00
Klaas Schoute c60ad8179d Bump p1-monitor to v3.2.0 (#152378) 2025-09-15 18:12:04 +02:00
Nc Hodges 14ad3364e3 Add Re-Configure workflow to the Elk M1 Integration (#146368)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-15 11:02:00 -05:00
J. Nick Koston e229f36648 Clarify contributor responsibility when using AI-generated code (#152379) 2025-09-15 17:59:06 +02:00
Norbert Rittel f4f99e015c Clarify "discovery_requires_supervisor" message in zwave_js (#152345) 2025-09-15 17:14:41 +02:00
Joost Lekkerkerker 5dc509cba0 Add typing to Nederlandse Spoorwegen (#152367) 2025-09-15 16:19:39 +02:00
Shay Levy 75597ac98d Add Shelly removal condition for virtual components (#152312) 2025-09-15 16:15:15 +03:00
Heindrich Paul b503f792b5 Add config flow to NS (#151567)
Signed-off-by: Heindrich Paul <heindrich.paul@gmail.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-15 15:13:43 +02:00
Ludovic BOUÉ 410c3df6dd Add Matter service actions for vacuum area (#151467)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-15 13:52:26 +02:00
virtualbitzz f1bf28df18 Add Matter climate running state heat fan and cool fan (#151535)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-09-15 13:28:40 +02:00
Patrick 99fb64af9b Add new USB drives to Synology DSM without reloading integration (#146829)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-15 13:12:57 +02:00
Shay Levy c0af0159e3 Use Entity Description in Shelly light platform (#137118) 2025-09-15 14:10:25 +03:00
Jan Bouwhuis 71749da3a3 Rename MQTT tag and device_automation setup helpers (#152344) 2025-09-15 11:52:24 +02:00
Norbert Rittel b01be94034 Update "Find my iPhone" to "Find My" in icloud (#152354) 2025-09-15 11:52:08 +02:00
Jan Gutowski 47ec8b7f12 Bump nibe to 2.18.0 (#152353) 2025-09-15 11:41:44 +02:00
dependabot[bot] 93ec9e448e Bump sigstore/cosign-installer from 3.9.2 to 3.10.0 (#152343)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-15 11:20:21 +02:00
Lennard Beers 90bc41dd02 Bump eq3btsmart to 2.2.0 (#152334) 2025-09-15 11:16:39 +02:00
epenet 410d869f3d Improve type hints in zha tests (#152347) 2025-09-15 11:16:10 +02:00
Imeon-Energy d75d9f2589 Bump imeon_inverter_api to 0.4.0 (#152351)
Co-authored-by: TheBushBoy <theodavid@icloud.com>
2025-09-15 11:14:31 +02:00
Christopher Fenner afbb832a57 Improve config flow for openweathermap integration (#152319) 2025-09-15 11:13:39 +02:00
epenet bdc881c87a Handle missing argument in hass_enforce_type_hints (#152342) 2025-09-15 09:45:27 +02:00
J. Nick Koston 22ea269ed8 Bump aioesphomeapi to 41.0.0 (#152332) 2025-09-14 23:22:10 -04:00
tronikos 10fecbaf4d Mark Opower as bronze (#148103)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-09-14 23:21:05 -04:00
Franck Nijhof cbdc1dc5b6 Refactor template engine: Extract math & statistical functions into MathExtension (#152266) 2025-09-14 20:48:29 -04:00
J. Nick Koston b203a831c9 Bump aioesphomeapi to 40.2.1 (#152327) 2025-09-14 19:31:55 -05:00
G Johansson 5ccbee4c9a Break long strings in entity platform/component tests (#152320) 2025-09-14 23:27:04 +02:00
Allen Porter 1483c9488f Update authorization server to prefer absolute urls (#152313)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-14 14:07:31 -07:00
Paulus Schoutsen f5535db24c Automatically generate entity platform enum (#152193)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-14 22:44:48 +02:00
Shay Levy e40ecdfb00 Remove Shelly empty sub-devices (#152251) 2025-09-14 22:43:37 +02:00
Norbert Rittel 2f4c69bbd5 Simplify description of direction_command_topic in mqtt (#150617) 2025-09-14 22:05:05 +02:00
Norbert Rittel dd0f6a702b Small fixes of user-facing strings in esphome (#152311) 2025-09-14 21:36:05 +03:00
Norbert Rittel 5ba580bc25 Capitalize "Supervisor" in two issues strings of hassio (#152303)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2025-09-14 21:35:47 +03:00
Samuel Xiao c13002bdd5 Add supported device[Plug-Mini-EU] for switchbot cloud (#151019) 2025-09-14 20:00:15 +02:00
Niklas Wagner 75d22191a0 Fix local_todo capitalization to preserve user input (#150814) 2025-09-14 19:53:41 +02:00
GSzabados 58d6549f1c Add display precision for rain rate and rain count (#151822) 2025-09-14 19:49:59 +02:00
Åke Strandberg 1fcc6df1fd Add proper error handling for /actions endpoint for miele (#152290) 2025-09-14 19:47:01 +02:00
J. Nick Koston 9bf467e6d1 Bump aioesphomeapi to 40.2.0 (#152272) 2025-09-14 19:39:44 +02:00
J. Nick Koston d877d6d93f Fix Lutron Caseta shade stuttering and improve stop functionality (#152207)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-14 19:35:18 +02:00
Lukas Waslowski d2b255ba92 nitpick: Add parameter types to _test_selector function signature (#152226) 2025-09-14 19:33:43 +02:00
Christopher Fenner 1509c429d6 Improve husqvarna_automower_ble config flow (#144877) 2025-09-14 19:32:10 +02:00
G Johansson af9717c1cd Raise error for entity services without a correct schema (#151165) 2025-09-14 19:17:26 +02:00
karwosts 49e75c9cf8 Fix browse by language in radio browser (#152296) 2025-09-14 19:04:59 +02:00
J. Nick Koston c97f16a96d Bump aiohomekit to 3.2.17 (#152297) 2025-09-14 19:02:11 +02:00
Bram Gerritsen a3a4433d62 Add missing unit conversion for BTU/h (#152300) 2025-09-14 19:00:44 +02:00
G Johansson f832002afd Bump holidays to 0.80 (#152306) 2025-09-14 17:51:47 +02:00
J. Diego Rodríguez Royo dbc7f2b43c Remove Home Connect stale code (#152307) 2025-09-14 17:51:11 +02:00
Galorhallen 1cd3a1eede Updated govee local api to 2.2.0 (#152289) 2025-09-14 16:16:26 +02:00
Norbert Rittel 7d6e0d44b0 Capitalize "Core" and "Supervisor" in backup issue strings (#152292) 2025-09-14 16:14:08 +02:00
jan iversen 2bb6d745ca Flexit: Fix wrong import from modbus. (#152225) 2025-09-14 12:04:07 +02:00
Todd Fast beb9d7856c Reduce PurpleAir sensor polling rate from every 2m to every 5m (#152271) 2025-09-14 11:59:48 +02:00
PaulCavill 6a4c8a550a Fix login issue with pyicloud (#129059)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-14 11:34:14 +02:00
Simon Lamon 7d23752a3f Unpin home-assistant/builder action (#152279) 2025-09-14 11:11:59 +02:00
Adam Goode c2b2a78db5 Change prusalink update cooldown to 1.0 seconds (#151060) 2025-09-14 10:58:00 +02:00
Manu 0fb6bbee59 Improve error logging for protected topic subscription in ntfy integration (#152244) 2025-09-14 10:02:48 +03:00
Denis Shulyaka d93e0a105a Save AI generated images to files (#152231) 2025-09-13 17:37:39 -04:00
karwosts ab1619c0b4 Adjust logbook filtering rules (#149349)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-13 16:34:55 -05:00
Franck Nijhof 70df7b8503 Restructure template engine, add crypto & base64 Jinja extension (#152261) 2025-09-13 22:21:29 +02:00
Denis Shulyaka 0e2c2ad355 Create dir on media upload if not exists (#152254) 2025-09-13 15:34:12 -04:00
J. Nick Koston 4c26718739 Bump bluetooth-auto-recovery to 1.5.3 (#152256) 2025-09-13 20:19:37 +02:00
J. Nick Koston 96034e1525 Bump aiohomekit to 3.2.16 (#152255) 2025-09-13 12:44:34 -05:00
Marc Mueller df1302fc1c Update mypy-dev to 1.19.0a2 (#152250) 2025-09-13 19:28:02 +02:00
Marc Mueller 5a5b639aa4 Update pytest-asyncio to 1.2.0 (#152156) 2025-09-13 19:27:47 +02:00
J. Nick Koston e9fbe2227f Fix HomeKit Controller overwhelming resource-limited devices by batching characteristic polling (#152209) 2025-09-13 19:24:05 +02:00
Yuxin Wang 82b57568a0 Set diagnostic entity category for "mode" in APCUPSD (#152246) 2025-09-13 18:38:47 +02:00
Simon Lamon be692ab2fd Reapply "Pin SHA for all github actions" (#152233) 2025-09-13 16:47:33 +02:00
Tor André Roland 24c04cceee Reflect Verisure lock, alarm control panel and switch state immediately without cloud pull (#149479)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-13 15:41:51 +01:00
w531t4 97077898bb Add Twitch entity for self (#150525)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-13 15:39:11 +01:00
Sean Dague 08485f4e09 Upgrade waterfurnace to 1.2.0 (#152241) 2025-09-13 15:36:15 +01:00
Marc Mueller b64d60fce4 Fix lg_thinq RuntimeWarning in tests (#152221) 2025-09-13 16:30:17 +02:00
Marc Mueller 3690497e1f Update pydantic to 2.11.9 (#152213) 2025-09-13 15:17:49 +01:00
Paulus Schoutsen b87e581cde Drop use of aiofiles in TTS (#152208) 2025-09-13 07:29:09 -04:00
J. Nick Koston f1c55ee7e2 Bump habluetooth to 5.6.4 (#152227) 2025-09-13 07:04:58 -04:00
J. Nick Koston 9f17a82acf Revert "Pin SHA for all github actions" (#152229) 2025-09-13 05:50:31 -05:00
Shay Levy 3955391cda Fix Shelly orphaned entity removal logic to handle sub-devices (#152195) 2025-09-13 12:11:47 +03:00
karwosts d9a757c7e6 Play url_resolved for radio browser instead of url (#150888) 2025-09-12 22:14:19 -04:00
Michael Hansen aa1ec944c0 Add secondary wake word and pipeline to ESPHome voice satellites (#151710) 2025-09-12 22:11:09 -04:00
Beat 88c3b6a9f5 Remove myself from enocean code owners (#151149) 2025-09-12 21:28:20 -04:00
skbeh ada73953f6 Use ephemeral port for SSDP server (#152049) 2025-09-12 23:56:53 +01:00
epenet 42e9b9a0bc Refactor _is_valid_suggested_unit in sensor (#151956) 2025-09-12 23:48:30 +01:00
Brandon Rothweiler ec6a052ff5 Add Hot Water+ Level select entity to A. O. Smith integration (#151548) 2025-09-13 00:46:26 +02:00
WardZhou c91d64e04d Add support for Thread Integration to Display Icons for GLiNet TBRs (#151386) 2025-09-12 23:45:43 +01:00
hbludworth 0ac7cb311d Fix Aladdin Connect state not updating (#151652)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-12 22:16:37 +02:00
Shay Levy 3472020812 Add icons for volume flow rate (#152196) 2025-09-12 22:09:01 +02:00
RoboMagus dcd09523a6 Webhook trigger: Enable templated webhook_id (#151193) 2025-09-12 15:48:52 -04:00
Jozef Lačný a5bfdc697b Add MEASUREMENT state_class to temperature sensors of flexit_bacnet (#152120) 2025-09-12 15:16:26 -04:00
Petar Petrov dbb29a7c7d Add attributes.entity_id to min_max sensors similar to groups (#151480) 2025-09-12 15:16:06 -04:00
Nathan Spencer 124a63d846 Add globe light settings for Litter-Robot 4 (#152190) 2025-09-12 14:55:50 -04:00
Michael Hansen 3de701a9ab Acknowledge if targets in same area (#150655)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2025-09-12 13:40:16 -05:00
Nc Hodges bfe1dd65b3 Add device and state class to Temp and Voltage entities. (#145613)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-12 12:57:58 -05:00
AdrianEddy 71bf5e14cc Add On/Off switch for DiscreteHeatingSystem in Overkiz (#151778)
Co-authored-by: Mick Vleeshouwer <mick@imick.nl>
2025-09-12 19:24:59 +02:00
Daniel Hjelseth Høyer 6d231c2c99 Tibber 15min prices (#151881)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-12 19:23:34 +02:00
Artur Pragacz b93072865b Clean up unused partial action response in intent helper (#151908) 2025-09-12 19:21:41 +02:00
Simon Lamon 14ebb6cd74 Pin SHA for all github actions (#151939) 2025-09-12 19:20:20 +02:00
Shay Levy 2ddbcd560e Add Shelly support for virtual buttons (#151940) 2025-09-12 19:16:54 +02:00
jan iversen c5ff7ed1c9 Remove self._lock in modbus. (#151997)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2025-09-12 19:15:15 +02:00
Yuxin Wang c4bea5616c Upgrade aioapcaccess to 1.0.0 (#151844) 2025-09-12 19:09:46 +02:00
epenet 17fe147726 Add support for Tuya szjcy category (water quality sensors) (#152020) 2025-09-12 19:08:29 +02:00
epenet 9fae4e7e1f Add support for Tuya bzyd category (white noise machine) (#152025) 2025-09-12 19:00:54 +02:00
Thijs W. 0cebca498c Bump pymodbus to 3.11.2 (#152097)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2025-09-12 18:55:22 +02:00
Luke Lashley 521ff62aae Make Roborock map transparent by default (#152092) 2025-09-12 18:50:42 +02:00
Marcos Alano fd1df5ad88 Add select for up/down/stop to electric desk (#152166) 2025-09-12 18:39:05 +02:00
Nathan Spencer 91e7a35a07 Add gravity mode switch for Feeder-Robot (#152175) 2025-09-12 18:36:58 +02:00
Maciej Bieniek 09381abf46 Add hourly forecast for AccuWeather integration (#152178) 2025-09-12 18:34:56 +02:00
laiho-vogels 3713c03c07 Drop index from preset name in MotionMount (#151301)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-12 17:33:26 +01:00
Erik Montnemery bd8ddd7cd8 Register androidtv entity services in async_setup (#152172) 2025-09-12 18:29:47 +02:00
Jan Bouwhuis f0dc1f927b Fix ai_task generate image service test (#152184) 2025-09-12 18:19:03 +02:00
Simone Chemelli 984590c6d1 Fix Pylance errors in UptimeRobot tests (#152185) 2025-09-12 18:18:27 +02:00
Iskra kranj d324021a3f Bump pyiskra to 0.1.27 (#152160) 2025-09-12 18:05:37 +02:00
jan iversen 1f4c0b3e9b Add codeowner for Modbus (#152163) 2025-09-12 18:04:01 +02:00
Bram Kragten 69893aba4b Update frontend to 20250903.5 (#152170) 2025-09-12 18:01:16 +02:00
Paulus Schoutsen b9dcf89b37 Fix hassfest error for internal integrations (#152173)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-12 17:53:08 +02:00
Artur Pragacz 54fd55a1c6 Remove unused ATTR_STEP_VALIDATION from number (#152179) 2025-09-12 16:46:42 +02:00
Matthias Alphart cc64fa639d Add KNX UI entity config to diagnostics (#151620) 2025-09-12 15:41:17 +02:00
Benjamin Pearce 84140ba414 Add remote codes which can be used with remote.send_command to diagnostics (#152017)
Co-authored-by: Maciej Bieniek <bieniu@users.noreply.github.com>
2025-09-12 14:41:15 +02:00
Marc Mueller d1726b84c8 Update pytest-cov to 7.0.0 (#152157) 2025-09-12 13:34:20 +02:00
Jan Bouwhuis 4724ecbc38 Suppress warning if object_id is still added when default_entity_id is used in MQTT discovery (#151996) 2025-09-12 13:11:10 +02:00
Marc Mueller 85afe87b5e Update coverage to 7.10.6 (#152158) 2025-09-12 13:02:01 +02:00
Nathan Spencer 5960179844 Add food dispensed today and next feeding sensors to litterrobot (#152016)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-12 11:17:45 +01:00
Thomas55555 9f8f7d2fde Add event entity on websocket ready in Husqvarna Automower (#151428) 2025-09-12 11:52:29 +02:00
ekobres 4c22264b13 Add support for inH₂O pressure unit (#148289)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-12 11:24:45 +02:00
Andrea Turri baf4382724 Miele consumption sensors consistent behavior with RestoreSensor (#151098) 2025-09-12 11:17:10 +02:00
Manu 8263ea4a4a Don't try to connect after exiting loop in ntfy (#152011) 2025-09-12 11:14:01 +02:00
Bouwe Westerdijk 8412581be4 Implement snapshot-testing for Plugwise climate platform (#151070) 2025-09-12 11:10:49 +02:00
J. Nick Koston 207c848438 Improve SwitchBot device discovery when Bluetooth adapter is in passive mode (#152074) 2025-09-12 11:08:51 +02:00
Paulus Schoutsen 2b61601fd7 Remove the host from the AI Task generated image URL (#151887) 2025-09-12 11:03:01 +02:00
Denis Shulyaka ee506e6c14 Implement thinking content for Gemini (#150347)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-12 05:02:39 -04:00
Brett Adams 8003a49571 Add guest mode switch to Teslemetry (#151550) 2025-09-12 10:44:38 +02:00
Maciej Bieniek e438b11afb Use native_visibility property instead of visibility for OpenWeatherMap weather entity (#151867) 2025-09-12 10:44:22 +02:00
Matthias Alphart 64ba43703c Fix KNX Light - individual color initialisation from UI config (#151815) 2025-09-12 10:43:45 +02:00
Jeremy Cook 1d214ae120 For the met integration Increase the hourly forecast limit to 48 hours in coordinator. (#150486) 2025-09-12 10:19:29 +02:00
Joakim Sørensen 68d987f866 Bump hass-nabucasa from 1.1.0 to 1.1.1 (#152147) 2025-09-12 10:18:58 +02:00
Norbert Rittel 299cc5e40c Fix sentence-casing of "CPU temperature" in fritz (#152149) 2025-09-12 10:18:12 +02:00
Retha Runolfsson 2c3456177e Add humidifier support for switchbot cloud integration (#149039) 2025-09-12 10:08:01 +02:00
Retha Runolfsson 1ef90180cc Add plug mini eu for switchbot integration (#151130) 2025-09-12 10:05:15 +02:00
Erik Montnemery 4c1364dfd1 Fix wrong type annotation in exposed_entities (#152142) 2025-09-12 09:32:17 +02:00
Norbert Rittel 09a44a6a30 Fix spelling of "H.265" encoding standard in reolink (#152130) 2025-09-12 08:05:01 +02:00
Maciej Bieniek 63303bdcde Allow port and SNMP community configuration for Brother printer (#151506) 2025-09-12 00:21:05 +02:00
Markus Adrario 59cd24f54b Add dynamic devices to Homee (#151934) 2025-09-12 00:19:37 +02:00
Duco Sebel 82b9fead39 Add support for controlling LED brightness on HomeWizard Plug-In Battery and P1 Meter (#151186) 2025-09-11 23:46:00 +02:00
karwosts a879e36e9b Designate helpers as internal quality (#149021) 2025-09-11 23:41:06 +02:00
HarvsG b12c458188 Log bayesian sensor name for unavailable observations (#152039) 2025-09-11 22:14:51 +01:00
Simone Chemelli 4985f9a5a1 Fix reauth for Alexa Devices (#152128) 2025-09-11 22:26:47 +02:00
Maciej Bieniek ae70ca7cba Add sw_version to Shelly BLU TRV device info (#152129) 2025-09-11 21:50:03 +02:00
Norbert Rittel 66d1cf8af7 Add missing period in "H.264" standard name in onvif (#152132) 2025-09-11 22:12:02 +03:00
Roland Moers 27c0df3da8 Add CPU temperature sensor to AVM FRITZ!Box Tools (#151328) 2025-09-11 21:05:59 +02:00
Norbert Rittel 5413131885 Replace "cook time" with correct "cooking time" in matter (#152110) 2025-09-11 20:49:13 +03:00
Michael Hansen 0acd77e60a Only use media path for TTS stream override (#152084) 2025-09-11 19:46:36 +02:00
epenet c5d552dc4a Use translation_key in Tuya dr category (electric blanket) (#152099) 2025-09-11 19:45:21 +02:00
Jan Bouwhuis 4f045b45ac Fix supported _color_modes attribute not set for on/off MQTT JSON light (#152126) 2025-09-11 19:43:44 +02:00
markhannon 4ad29161bd Bump zcc-helper to 3.7 (#151807) 2025-09-11 19:42:24 +02:00
LG-ThinQ-Integration fea7f537a8 Bump thinqconnect to 1.0.8 (#152100)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
2025-09-11 19:39:01 +02:00
epenet 442b6e9cca Add initial support for Tuya sjz category (electric desk) (#152036) 2025-09-11 19:35:24 +02:00
wollew 531b67101d fix rain sensor for Velux GPU windows (#151857) 2025-09-11 19:14:59 +02:00
J. Nick Koston 596a3fc879 Add async_current_scanners API to Bluetooth integration (#152122) 2025-09-11 13:06:51 -04:00
Joost Lekkerkerker 0e8295604e Fail hassfest if translation key is obsolete (#151924)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-11 18:56:56 +02:00
Manu 9cfdb99e76 Add repair to unsubscribe protected topic in ntfy integration (#152009) 2025-09-11 18:52:12 +02:00
Marc Mueller b1a6e403fb Cache apt install [ci] (#152113) 2025-09-11 18:44:43 +02:00
Samuel Xiao 937d3e4a96 Add more light models to SwitchBot Cloud (#150986) 2025-09-11 18:39:29 +02:00
Manu a368ad4ab5 Set sensors to unknown when no next alarm is set in Sleep as Android (#150558) 2025-09-11 18:38:33 +02:00
peteS-UK 254694b024 Fix track icons for Apps and Radios in Squeezebox (#151001) 2025-09-11 18:37:21 +02:00
Sam Reed bcfa7a7383 squeezebox: Improve update notification string (#151003) 2025-09-11 18:36:22 +02:00
Abílio Costa ab7081d26a Include non-primary entities targeted directly by label (#149309) 2025-09-11 17:34:15 +01:00
epenet 4762c64c25 Add initial support for Tuya msp category (cat toilet) (#152035) 2025-09-11 18:22:39 +02:00
Artur Pragacz 1b99ffe61b Pass satellite id through assist pipeline (#151992) 2025-09-11 11:13:23 -05:00
Imeon-Energy d5132e8ea9 Add select to Imeon inverter integration (#150889)
Co-authored-by: TheBushBoy <theodavid@icloud.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-11 17:55:55 +02:00
J. Nick Koston 1bcf3cfbb2 Fix DoorBird being updated with wrong IP addresses during discovery (#152088)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-11 10:58:59 -04:00
Norbert Rittel d4d912ef55 Add missing "to" in invalid_auth exception of portainer (#152116) 2025-09-11 16:40:39 +02:00
Martin Hjelmare 393826635b Add next_flow to config flow result (#151998) 2025-09-11 15:48:59 +02:00
Abílio Costa 9edd5c35e0 Fix duplicated IP port usage in Govee Light Local (#152087) 2025-09-11 14:47:59 +01:00
J. Nick Koston e8c1d3dc3c Add repair issue for Bluetooth adapter passive mode fallback (#152076) 2025-09-11 08:52:57 -04:00
Paulus Schoutsen 46463ea4f8 Rename Google Gen AI to Google Gemini (#151653) 2025-09-11 08:35:50 -04:00
Paulus Schoutsen 88e6b0c8d9 Make LocalSource reusable (#151886) 2025-09-11 08:35:10 -04:00
Maciej Bieniek 2ed92c720f Add entities for Shelly presence component (#151816) 2025-09-11 14:23:27 +02:00
Åke Strandberg 7389f23d9a Bump miele quality scale to platinum (#149736) 2025-09-11 13:18:55 +02:00
Retha Runolfsson a0cef80cf2 Add sensors for switchbot cloud integration (#147663) 2025-09-11 12:58:36 +02:00
Marc Hörsken 343b17788f Add support for valance shades / volants to WMS WebControl pro (#150882) 2025-09-11 12:57:53 +02:00
Erik Montnemery 50349e49f1 Register sonos entity services in async_setup (#152047) 2025-09-11 12:52:58 +02:00
Shay Levy 42d0415a86 Update Shelly Neo water valve device class and units (#152080) 2025-09-11 13:36:11 +03:00
G Johansson 1428b41a25 Improve sql config flow (#150757)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-11 12:27:48 +02:00
Foscam-wangzhengyu e65b4292b2 Add volume control to Foscam Upgrade dependencies (#150618)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-11 11:59:05 +02:00
Marc Mueller 2fc2bb97fc Update PyNaCl to 1.6.0 (#152107) 2025-09-11 10:30:33 +02:00
epenet 40da606177 Add support for Tuya swtz category (cooking thermometer) (#152022) 2025-09-11 10:28:20 +02:00
epenet d613b69e4e Fix typo in Tuya strings (#152103) 2025-09-11 10:27:25 +02:00
Erik Montnemery 3c5d09e114 Fix stale docstring in alarm_control_panel (#152026) 2025-09-11 10:26:34 +02:00
dependabot[bot] 9c54cc369b Bump github/codeql-action from 3.30.1 to 3.30.3 (#152098)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-11 09:11:22 +02:00
Paulus Schoutsen f91e4090f9 Add path to resolved media in image_upload (#152093) 2025-09-10 22:55:59 -04:00
Paulus Schoutsen 2cdf0b74d5 Gemini: Reuse attachment mime type if known (#152094) 2025-09-10 19:49:10 -07:00
J. Nick Koston 86750ae5c3 Fix HomeKit Controller stale values at startup (#152086)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-09-10 19:45:22 -05:00
J. Nick Koston c1eb492616 Fix Bluetooth mock to prevent degraded mode repair issues in tests (#152081) 2025-09-10 17:19:15 -05:00
karwosts ac154c020c Use a state selector for history_stats (#150445)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-10 23:52:50 +02:00
Manu 0e23eb9ebd Update Sleep as Android quality scale to platinum 🏆️ (#150449) 2025-09-10 23:37:12 +02:00
Tsvi Mostovicz 8367930f42 Jewish Calendar quality scale (#143763) 2025-09-10 23:25:16 +02:00
Joost Lekkerkerker d71b1246cf Add DHCP discovery to Aladdin Connect (#151532) 2025-09-10 22:57:46 +02:00
Ville Skyttä 4ad664a652 Add huawei_lte quality scale YAML (#143347)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-10 22:32:21 +02:00
Whitney Young 002493c3e1 Openuv protection window internal update (#146409) 2025-09-10 22:18:50 +02:00
Ludovic BOUÉ 720ecde568 Support for Matter MountedDimmableLoadControl device type (#151330)
Support for Matter MountedDimmableLoadControl device type:
Matter MountedDimmableLoadControl device was wrongly reco
gnized as Switch entity.
This PR fix thte behavior and makes it recognized as Light entity as expected.
There is no Matter MountedDimmableLoadControl device in the market yet so it doesn't really breaks anything.
2025-09-10 22:16:43 +02:00
Paul Bottein 4c548830b4 Use state selector for select option service (#148960) 2025-09-10 22:15:23 +02:00
Raphael Hehl 214925e10a Refactor unifiprotect RTSP repair flow to use publicapi create_rtsps_streams method (#149542) 2025-09-10 22:13:14 +02:00
Joost Lekkerkerker 885256299f Enable PYI059 and fix violations (#152069) 2025-09-10 21:52:21 +02:00
Joost Lekkerkerker e73c670025 Enable PYI061 and fix violations (#152070) 2025-09-10 21:17:59 +02:00
Joost Lekkerkerker e3c0cfd1e2 Enable RUF059 and fix violations (#152071) 2025-09-10 21:16:09 +02:00
Maciej Bieniek 46c38f185c Adapt AccuWeather to new paid API plans (#152056)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-10 21:15:48 +02:00
Abílio Costa 9082637133 Raise on service calls in Whirlpool (#152057)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-10 21:13:12 +02:00
Simone Chemelli 0a35fd0ea4 Add key reconfigure to UptimeRobot config flow (#151562) 2025-09-10 21:12:57 +02:00
Simone Chemelli c4649fc068 Avoid cleanup/recreate of device_trackers not linked to a device for Vodafone Station (#151904) 2025-09-10 21:09:44 +02:00
Erwin Douna b496637bdd Add Portainer integration (#142875)
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-10 21:01:41 +02:00
Retha Runolfsson 7d471f9624 Add rgbicww light for switchbot integration (#151129) 2025-09-10 13:52:47 -05:00
Joost Lekkerkerker 83f3b3e3eb Bump ruff to 0.13.0 (#152067) 2025-09-10 20:48:31 +02:00
J. Nick Koston 4592d6370a Bump PySwitchBot to 0.70.0 (#152072) 2025-09-10 13:39:52 -05:00
Abílio Costa ccef31a37a Set PARALLEL_UPDATES in Whirlpool integration (#152065) 2025-09-10 19:47:31 +02:00
Simone Chemelli 6a482b1a3e Remove stale devices for Alexa Devices (#151909) 2025-09-10 19:20:40 +02:00
Marc Mueller 6f00f8a920 Update feedreader to 6.0.12 (#152054) 2025-09-10 11:09:11 -05:00
Sarah Seidman ceeeb22040 Add integration for Droplet (#149989)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-10 17:38:49 +02:00
Simone Chemelli 2cda0817b2 Add illuminance sensor for Shelly Plug US Gen4 (#150681) 2025-09-10 17:31:56 +02:00
epenet 881a0bd1fa Add missing Tuya translation string (#152051) 2025-09-10 15:59:21 +02:00
epenet dba6f419c9 Remove unneeded Tuya translation key (#152052) 2025-09-10 15:59:03 +02:00
Abílio Costa fad8d4fca2 Remove uneeded check for fan mode in Whirlpool (#152053) 2025-09-10 15:47:05 +02:00
Ludovic BOUÉ 1663ad1adb Remove device class for Matter NitrogenDioxideSensor (#151782)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-10 15:34:32 +02:00
Marc Mueller 6a8152bc7f Update isal to 1.8.0 (#152043) 2025-09-10 08:25:19 -05:00
Felipe Santos e5edccd56f Fix Supervisor Ingress WebSocket not handling Connection and Timeout Error (#151951)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-10 13:59:42 +02:00
Erik Montnemery 480527eb68 Call DeviceRegistry._async_update_device from device registry (#151295) 2025-09-10 13:14:03 +02:00
Maciej Bieniek 1475108f1c Bump accuweather to version 4.2.1 (#152029) 2025-09-10 12:25:20 +02:00
Erik Montnemery a1e68336fc Add service helper for registering platform services (#151965)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-09-10 11:21:31 +01:00
Erik Montnemery 07392e3ff7 Fix lifx tests opening sockets (#152037) 2025-09-10 12:18:58 +02:00
Erik Montnemery 3e39f77e92 Remove duplicated call to time.time in device registry (#152024) 2025-09-10 11:15:59 +02:00
anishsane a12617645b Add support for Tasmota camera (#144067)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-10 08:13:48 +02:00
Manu 723476457e Add subentry reconfigure flow to ntfy integration (#143718) 2025-09-10 07:57:55 +02:00
Megamind 7053727426 Feature - add Time-to-Live (ttl) parameter support to Pushover integration (#143791) 2025-09-10 07:56:36 +02:00
Denis Shulyaka 0f4ce58f28 Raise repair issue when organization verification is required by OpenAI (#151878)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-09 23:35:29 -04:00
J. Nick Koston 2c72cd3832 Add repair issue for Bluetooth adapters in degraded mode due to missing container permissions (#151947)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-09 23:34:19 -04:00
Michael Hansen e8d5615e54 Allow overriding TTS result stream with media id (#151718) 2025-09-09 23:30:00 -04:00
Nathan Spencer 7a332d489d Bump pylitterbot to 2024.2.4 (#152015) 2025-09-09 22:28:54 -05:00
J. Nick Koston 504421e257 Fix ESPHome lock showing as unlocked when state is unknown (#152012) 2025-09-09 21:52:48 -04:00
Joost Lekkerkerker a0ace3b082 Bump yt-dlp to 2025.09.05 (#152006) 2025-09-09 18:28:49 -05:00
J. Nick Koston aea055b444 Bump aioesphomeapi to 40.1.0 (#152005) 2025-09-09 16:07:53 -05:00
Keith Burzinski 5b107349a1 Patch ESPHome client to handle climate UI correctly (#151897)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-09 15:55:38 -05:00
RogerSelwyn 46fa98e0b2 Fix Private Groups in Hue integration cause delay in startup (#151896) 2025-09-09 22:30:36 +02:00
peteS-UK 96e66009e5 Fix playlist media_class_filter in search_media for squeezebox (#151973) 2025-09-09 22:22:28 +02:00
GSzabados ad14a66187 WH46 missing PM1.0 and PM4.0 sensors (#151821)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-09 22:17:13 +02:00
Manu 777ac97acb Add state attribute translations to ntfy integration (#152004) 2025-09-09 22:12:50 +02:00
Paulus Schoutsen af07ab4752 Allow passing an LLM API to AI Task generate data (#151081) 2025-09-09 15:12:20 -04:00
Simone Chemelli 74b731528d Improve config entry migration for edge cases in Alexa Devices (#151788) 2025-09-09 21:08:04 +02:00
Erik Montnemery c361c32407 Bump hatasmota to 0.10.1 (#151988)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-09 20:55:01 +03:00
Álvaro Fernández Rojas 75c1eddaf9 Update aioairzone to v1.0.1 (#151990)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-09-09 20:43:50 +03:00
Manu 715aba3aca Bump aiontfy to v0.5.5 (#151869) 2025-09-09 20:42:49 +03:00
Paulus Schoutsen 285619e913 Allow storing AI Task generate image preferred entity (#151938) 2025-09-09 18:29:14 +01:00
Manu eaf400f3b7 Add ntfy.publish action to ntfy integration (#143560)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-09-09 19:08:49 +02:00
J. Nick Koston 3d79a73110 Bump habluetooth to 5.6.2 (#151985) 2025-09-09 11:38:45 -05:00
Manu 6271765eaf Add event platform to ntfy integration (#143529) 2025-09-09 17:53:19 +02:00
skbeh 9e73ff06d2 Prevent socket leak on SSDP when finding available port (#150999)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-09 16:50:52 +01:00
tronikos 36edfd8c04 Mark Android TV Remote as platinum (#148047) 2025-09-09 17:33:09 +02:00
tronikos a750cfcac6 Make "Add new" translatable in Android TV Remote options (#151749) 2025-09-09 17:32:32 +02:00
Joost Lekkerkerker 026f20932a Remove manually adding domain in android TV remote (#151983) 2025-09-09 08:12:18 -07:00
GSzabados 07d4e11c30 Add VPD - Vapour Pressure Deficit support to Ecowitt (#141727)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-09 17:08:23 +02:00
epenet 9c80d75588 Add charge_state to Tuya siren alarm (#151220) 2025-09-09 17:02:31 +02:00
epenet 1818a103b6 Use motor rotation mode in Tuya clkg covers (curtain) (#151767) 2025-09-09 17:02:04 +02:00
epenet 3e4bb4eb7e Add PM10 to Tuya air quality monitor (co2bj category) (#151980) 2025-09-09 16:54:47 +02:00
Bob Igo 1117b92dde Fix XMPP not working with non-TLS servers (#150957) 2025-09-09 15:18:48 +02:00
Stefan Agner f5a1523068 Update Home Assistant base image to 2025.09.1 (#151960) 2025-09-09 08:17:30 -05:00
peteS-UK 7005a70a4e Fix for squeezebox track content_type (#151963) 2025-09-09 15:16:19 +02:00
Joost Lekkerkerker 9b862a8e4e Set otbr config entry title to ZBT-1 with a SkyConnect (#151911) 2025-09-09 15:03:17 +02:00
epenet f5dba77636 Fix invalid logger in Tuya (#151957) 2025-09-09 14:44:31 +02:00
Joost Lekkerkerker da7f9f6154 Remove obsolete Ecobee strings (#151970) 2025-09-09 15:37:48 +03:00
Joost Lekkerkerker 9a92d58613 Remove obsolete LCN strings (#151969) 2025-09-09 15:36:47 +03:00
epenet 9ea438024d Add Tuya test fixtures (#151972) 2025-09-09 14:28:25 +02:00
Joost Lekkerkerker 58edc3742a Remove obsolete alexa devices strings (#151971) 2025-09-09 13:47:30 +02:00
epenet 3c0580880d Add Tuya test fixtures (#151953) 2025-09-09 13:44:32 +02:00
J. Nick Koston 04b5eb7d53 Bump habluetooth to 5.6.0 (#151942) 2025-09-08 16:45:11 -05:00
Shay Levy cecae10a15 Bump aioshelly to 13.9.0 (#151943) 2025-09-09 00:23:26 +03:00
HarvsG 2e2b9483df Improve efficiency of config_entries _async_abort_entries_match() (#148344)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-09-08 15:17:29 -05:00
Paulus Schoutsen 0444467858 Gemini: add support for AI Task generate image (#151880) 2025-09-08 16:11:06 -04:00
michnovka d990c2bee2 Fix timestamps exposed to LLM to be in local timezone (#139825)
Co-authored-by: Michael Hansen <mike@rhasspy.org>
2025-09-08 14:51:17 -05:00
Nathan Spencer 03a7052151 Add last feeding sensor for Feeder-Robots (#151871) 2025-09-08 21:40:18 +02:00
Manu 4025e23c67 Remove unused translation string in Bring! integration (#151927) 2025-09-08 21:37:47 +02:00
Abílio Costa 82c3fcccc9 Update whirlpool-sixth-sense to 0.21.3 (#151929)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-08 21:37:18 +02:00
J. Nick Koston 7ee7a3c0b5 Bump bleak-esphome to 3.3.0 (#151922)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-08 14:32:31 -05:00
Abílio Costa e7cb0173b0 Increase timeout of install os dependencies step (#151931) 2025-09-08 13:41:38 -05:00
J. Nick Koston dbdbf1cf16 Bump habluetooth to 5.5.1 (#151921) 2025-09-08 13:37:50 -05:00
Markus Adrario b5704f3e8b Bump pyHomee to 1.3.8 (#151874) 2025-09-08 18:53:13 +01:00
Artur Pragacz df3d4b5db1 Clean up unused intent category (#151917) 2025-09-08 19:42:23 +02:00
Jan Bouwhuis 0ab232b904 Fix typo in MQTT strings (#151907) 2025-09-08 18:43:15 +02:00
Joost Lekkerkerker acc75e4419 Remove image filename parameter from Google Generative AI (#151914) 2025-09-08 09:01:41 -07:00
Norbert Rittel 8aa672882a Replace "STT" with "Speech-to-Text" in google_cloud UI (#151918) 2025-09-08 08:59:18 -07:00
Artur Pragacz 3cbf3bdf4c Remove Kodi media player platform yaml support (#151786) 2025-09-08 17:16:23 +02:00
epenet 56c865dcfe Fix _is_valid_suggested_unit in sensor platform (#151912) 2025-09-08 16:35:33 +02:00
karwosts b7360dfad8 Allow deleting kitchen_sink devices (#151826) 2025-09-08 15:01:08 +01:00
dependabot[bot] f2204e97ab Bump github/codeql-action from 3.30.0 to 3.30.1 (#151890)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-08 14:49:05 +02:00
Artur Pragacz 98df5f5f0c Validate selectors in the condition helper (#151884) 2025-09-08 14:20:11 +02:00
Simone Chemelli 064d43480d Bump aiovodafone to 1.2.1 (#151901) 2025-09-08 12:58:26 +02:00
Jan Bouwhuis 1536375e82 Fix update of the entity ID does not clean up an old restored state (#151696)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-08 12:48:23 +02:00
Avi Miller 39e9ffff29 Bump aiolifx-themes to 1.0.2 to support newer LIFX devices (#151898)
Signed-off-by: Avi Miller <me@dje.li>
2025-09-08 13:45:42 +03:00
puddly 12f152d6e4 Home Assistant Connect ZBT-2 integration (#151015)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-09-08 11:18:31 +02:00
Jan Bouwhuis c7f0560208 Deprecate object_id and instead suggest to use default_entity_id to set the suggested entity_id in MQTT entity configurations (#151775) 2025-09-08 09:22:12 +02:00
Denis Shulyaka 65603a3829 Add signature to ai_task generated images URL (#151882) 2025-09-07 16:58:51 -04:00
Robert Resch 38ea5c6813 Bump aioecowitt to 2025.9.1 (#151859) 2025-09-07 19:52:05 +02:00
Norbert Rittel 5b1fd8f58b Fix sentence-casing in volvooncall (#151863) 2025-09-07 19:51:16 +02:00
Maciej Bieniek e5f99a617f Mark Tractive switches as unavailable when tacker is in the enegy saving zone (#151817) 2025-09-07 13:34:31 +02:00
Martins Sipenko 7f8b5f2288 Update pysmarty2 to 0.10.3 (#151855) 2025-09-07 09:36:45 +02:00
J. Nick Koston 75f69cd5b6 Bump aioharmony to 0.5.3 (#151853) 2025-09-06 23:55:27 -04:00
Paulus Schoutsen d7fab27351 Remove myself as code owner of integrations (#151851) 2025-09-06 20:42:25 -05:00
David Knowles 6c6ec7534f Bump pydrawise to 2025.9.0 (#151842) 2025-09-06 23:07:56 +03:00
Norbert Rittel 8e3780264a Capitalize "AC" in nut (#151831) 2025-09-06 20:25:42 +02:00
jan iversen 78b009dd8f Allow delay > 1 in modbus. (#151832) 2025-09-06 21:21:12 +03:00
jan iversen 76d72ad280 max_temp / min_temp in modbus light could only be int, otherwise an assert was provoked. (#151833) 2025-09-06 21:20:49 +03:00
jan iversen e5be9426a4 removed assert fron entity in modbus. (#151834) 2025-09-06 21:20:21 +03:00
Norbert Rittel 0922f12ec0 Use "credentials" only for username and password in overkiz (#151837) 2025-09-06 21:19:52 +03:00
Norbert Rittel 89f424e1d3 Fix sentence-casing of "Application credentials" in common strings (#151828) 2025-09-06 19:21:33 +02:00
Norbert Rittel 143eb20d99 Fix sentence-casing of two tesla_fleet user-facing strings (#151829) 2025-09-06 17:56:54 +02:00
Artur Pragacz 3187506eb9 Ignore incorrect themes (#151794) 2025-09-06 13:49:03 +02:00
Matthias Alphart a328b23437 Fix KNX BinarySensor config_store data (#151808) 2025-09-06 13:02:35 +02:00
Norbert Rittel 7e6a949559 Fix exceptions of climate.set_temperature action to use friendly names (#151811) 2025-09-06 14:00:15 +03:00
J. Nick Koston da7db5e22b Bump habluetooth to 5.3.1 (#151803) 2025-09-06 13:57:44 +03:00
Jan-Philipp Benecke ec58943c8c Bump zeroconf to 0.147.2 (#151809) 2025-09-06 13:56:52 +03:00
Norbert Rittel 61a05490e9 Fix missing sentence-casing of "temperature" in bsblan (#151810) 2025-09-06 13:55:13 +03:00
Joakim Plate 6a1629d2ed Update philips_js to 3.2.4 (#151796) 2025-09-06 08:16:06 +02:00
Paulus Schoutsen 106e1ce224 Gen translations in script/bootstrap (#151806) 2025-09-06 07:22:47 +02:00
Abílio Costa 601d63e3b7 Add top-level target support to condition schema (#149634)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2025-09-05 22:55:28 +01:00
Jan Bouwhuis 6a5f5b9adc Mock discovery in lifx sensor tests to avoid socket access in tests (#151787) 2025-09-05 21:46:07 +02:00
karwosts 8ecf5a98a5 Catch more invalid themes in validation (#151719) 2025-09-05 20:09:33 +02:00
Tsvi Mostovicz 1728c577f7 Revert "Jewish Calendar add coordinator " (#151780) 2025-09-05 17:47:29 +02:00
wollew 1006d5e0ba Use position percentage for closed status in Velux (#151679)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-05 16:45:29 +01:00
Artur Pragacz 6c29d5dc49 Add entity info to device database analytics (#151670) 2025-09-05 16:12:35 +02:00
Carlos Morán a4e086f0d9 Add manual mode to the map of Overkiz to HVAC modes (#151438) 2025-09-05 15:43:54 +02:00
Marko Todorić 0fecf012e6 SFTP/SSH as remote Backup location (#135844)
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-05 15:43:26 +02:00
blotus 63c8bfaa9b Fix support for Ecowitt soil moisture sensors (#151685) 2025-09-05 14:40:14 +02:00
Mark Adkins 435926fd41 Update SharkIQ authentication method (#151046) 2025-09-05 13:14:28 +02:00
Ludovic BOUÉ c621f0c139 Matter RVC ServiceArea EstimatedEndTime attribute (#151384) 2025-09-05 12:49:32 +02:00
Artur Pragacz fa9007777d Add myself as codeowner to Voice components (#151764) 2025-09-05 12:45:17 +02:00
jan iversen e1afadb28c Fix enable/disable entity in modbus (#151626) 2025-09-05 12:31:33 +02:00
tronikos 34c45eae56 Translate exceptions in Android TV Remote media player (#151744) 2025-09-05 12:29:06 +02:00
tronikos 71b8da6497 Limit the scope of try except blocks in Android TV Remote (#151746) 2025-09-05 12:28:46 +02:00
tronikos caa0e357ee Improve Android TV Remote tests by testing we can recover from errors (#151752) 2025-09-05 12:26:31 +02:00
Imeon-Energy 0721ac6c73 Fix, entities stay unavailable after timeout error, Imeon inverter integration (#151671)
Co-authored-by: TheBushBoy <theodavid@icloud.com>
2025-09-05 12:11:44 +02:00
Marcel van der Veldt 783c742e09 Add support for migrated Hue bridge (#151411)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-05 12:09:37 +02:00
tronikos d2324086af Remove unused class variables in Android TV Remote entity (#151743) 2025-09-05 12:04:14 +02:00
Marc Mueller 2ffd5f4c97 Update types packages (#151760) 2025-09-05 11:54:14 +02:00
Norbert Rittel aa4a110923 Improve action descriptions in homematic (#151751) 2025-09-05 11:46:28 +02:00
Artur Pragacz 0a3032e766 Fix recognition of entity names in default agent with interpunction (#151759) 2025-09-05 11:42:56 +02:00
Richard Kroegel c4db422355 Bump bimmer_connected to 0.17.3 (#151756) 2025-09-05 11:37:51 +02:00
Michael Hansen f4e0b9ba15 Handle match failures in intent HTTP API (#151726) 2025-09-05 10:28:37 +02:00
dependabot[bot] f3b997720d Bump actions/github-script from 7 to 8 (#151747)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-05 10:18:31 +02:00
dependabot[bot] f5d3a89f90 Bump codecov/codecov-action from 5.5.0 to 5.5.1 (#151748)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-05 10:17:12 +02:00
Norbert Rittel b90296d853 Remove trailing periods from title strings in sia (#151754) 2025-09-05 10:07:37 +02:00
tronikos c6d6349908 Remove extra whitespace in Android TV Remote strings (#151741) 2025-09-05 09:25:00 +02:00
J. Nick Koston 2be6f17505 Bump aioesphomeapi to 40.0.1 (#151737) 2025-09-05 09:24:28 +02:00
epenet 4c953f36c8 Bump tuya-device-sharing-sdk to 0.2.4 (#151742) 2025-09-05 09:21:34 +02:00
Dan Raper ec2fa202e9 Require OhmeAdvancedSettingsCoordinator to run regardless of entities (#151701) 2025-09-05 07:37:40 +02:00
G Johansson 1a970e6c88 Make sensor startup code more dry in System monitor (#151164) 2025-09-05 07:36:37 +02:00
Dan Raper b9db828df3 Bump ohmepy version to 1.5.2 (#151707) 2025-09-05 04:23:57 +02:00
Daniel Hjelseth Høyer 50c0f41e8f Update Mill library 0.13.1 (#151712) 2025-09-05 04:23:08 +02:00
David Knowles 8cc66ee96c Bump pyschlage to 2025.9.0 (#151731) 2025-09-05 04:21:09 +02:00
Louis Christ 71981975a4 Update pyblu to 2.0.5 and fix code (#151728) 2025-09-04 23:34:59 +01:00
Manu b875af9667 Bump pyotp to v2.9.0 (#151721) 2025-09-05 00:09:23 +02:00
Manu 89cd55c878 Bump habiticalib to v0.4.5 (#151720) 2025-09-04 22:58:28 +01:00
Daniel Hjelseth Høyer b25708cec2 Update Tibber library 0.31.7 (#151711)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2025-09-05 00:21:26 +03:00
Franck Nijhof bb9c65bc4b Update debugpy to v1.8.16 (#151716) 2025-09-05 00:17:58 +03:00
Franck Nijhof 447c7b64a9 Update cryptography to 45.0.7 (#151715) 2025-09-04 23:40:08 +03:00
Marc Mueller b111a33b8c Update ciso8601 to 2.3.3 (#151704) 2025-09-04 13:54:49 -05:00
Marc Mueller 4fcd02bc5d Update requests to 2.32.5 (#151705) 2025-09-04 20:53:16 +02:00
Marc Mueller 80d26b8d2e Update pytest to 8.4.2 (#151706) 2025-09-04 20:52:48 +02:00
flonou a475ecb342 Shelly cover position update when moving (#139008)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-09-04 20:22:07 +03:00
Simone Chemelli 42aec9cd91 Remove attributes from all Shelly entities (#140386) 2025-09-04 20:21:32 +03:00
karwosts 5409181b79 Add missing device trigger duration localizations (#151578)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-04 17:25:25 +02:00
Marc Mueller c1945211fa [ci] Add timeout to install os dependencies step (#151682) 2025-09-04 17:20:17 +02:00
Abílio Costa 29537dc87d Add tests for hassfest conditions module (#151646)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-04 17:18:51 +02:00
Bram Kragten 72e1a8f912 Update frontend to 20250903.3 (#151694) 2025-09-04 17:04:49 +02:00
epenet b742e4898c Ensure Tuya fixtures are correctly referenced (#151691) 2025-09-04 16:53:48 +02:00
Marcel van der Veldt e5565c75f6 Bump aiohue to 4.7.5 (#151684) 2025-09-04 14:44:10 +02:00
epenet a7ca618327 Check badly formatted dhcp addresses in tests (#147814) 2025-09-04 13:43:51 +01:00
epenet 6cbb881647 Drop Tuya compatibility code for mqtt (#151666) 2025-09-04 12:10:58 +02:00
Kevin McCormack eae1fe4a56 Add strict typing, shared constants, and fix OPNsense name casing (#151599) 2025-09-04 11:20:16 +02:00
epenet 8d945d89de Bump tuya-device-sharing-sdk to 0.2.3 (#151659) 2025-09-04 10:37:25 +02:00
dependabot[bot] 86e7f3713f Bump actions/stale from 9.1.0 to 10.0.0 (#151660)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 10:11:50 +02:00
Pete Sage 3bc772a196 Fix Sonos Dialog Select type conversion (#151649) 2025-09-04 09:33:43 +02:00
Felipe Santos c2290d6edb Fix WebSocket proxy for add-ons not forwarding ping/pong frame data (#151654) 2025-09-04 09:30:23 +02:00
dependabot[bot] 2a458dcec9 Bump actions/setup-python from 5.6.0 to 6.0.0 (#151662)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 09:22:28 +02:00
dependabot[bot] ab5ef3674f Bump pypa/gh-action-pypi-publish from 1.12.4 to 1.13.0 (#151661)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 09:22:22 +02:00
Norbert Rittel f28251bc76 Small fixes of user-facing strings in fritz (#151663) 2025-09-04 09:20:15 +02:00
Mike Kelly 1cca65b5c5 Add MCF (1000 Cubic Feet) as an alternate unit of measure for volume (#150015) 2025-09-04 09:29:37 +03:00
karwosts ed134e22f9 Allow defining the start weekday for statistic_during_period (#149033) 2025-09-04 09:27:12 +03:00
Paulus Schoutsen 300c582ea0 Devcontainer fixes for Debian 13 (#151655) 2025-09-04 06:23:45 +02:00
Franck Nijhof 52f7e20b5c Merge branch 'master' into dev 2025-09-03 21:32:40 +00:00
epenet 813098cb1a Use correctly formatted MAC in esphome tests (#151622) 2025-09-03 15:07:03 -05:00
Manu 000df08bca Correct capitalization of "FRITZ!Box" in FRITZ!Box Tools integration (#151637) 2025-09-03 21:23:48 +02:00
J. Nick Koston 9b80cf7d94 Prevent multiple Home Assistant instances from running with the same config directory (#151631) 2025-09-03 13:13:02 -05:00
karwosts 3385151c26 Test for async_show_menu sort (#151630) 2025-09-03 18:46:57 +02:00
Michael Hansen 111fa78c57 Bump intents (#151627) 2025-09-03 18:11:37 +02:00
Erik Montnemery e67df73c4e Clarify behavior of ConfigEntry.async_on_state_change (#151628) 2025-09-03 17:21:28 +02:00
Bram Kragten b9f24bbb2a Update frontend to 20250903.2 (#151629) 2025-09-03 16:54:37 +02:00
karwosts 18ca9590f0 Sort template config menu step by user language (#151596) 2025-09-03 17:02:45 +03:00
Paulus Schoutsen eccadd4a11 script/bootstrap to update core deps (#151624) 2025-09-03 09:58:29 -04:00
BenJewell aeff62faea Correct critical notification variable name in Flo (#151523)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-03 14:15:13 +01:00
Norbert Rittel e5a44e5966 Fix naming of "State of charge" sensor in growatt_server (#151619) 2025-09-03 15:13:04 +02:00
mattreim 1369a98fa3 Fix for deCONZ issue - Detected that integration 'deconz' calls device_registry.async_get_or_create referencing a non existing via_device - #134539 (#150355) 2025-09-03 14:28:52 +02:00
jan iversen 0e1dd04083 Simplify Modbus update methods (#151494) 2025-09-03 14:23:36 +02:00
G Johansson df46816b2f Add reload support to schema options flow handler (#151260) 2025-09-03 12:55:21 +01:00
Jack 955ef3b5e7 Remove deprecated target position attributes from ZHA covers (#142534)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-03 13:43:29 +02:00
Bram Kragten 5fc6fb9cf3 Update frontend to 20250903.1 (#151617) 2025-09-03 13:31:33 +02:00
Erik Montnemery 9ee9e1775d Bump device registry version to 1.12 (#151616) 2025-09-03 13:12:49 +02:00
jan iversen 712c9b9edc Fix racing bug in slave entities in Modbus (#151522) 2025-09-03 13:09:42 +02:00
Erik Montnemery d571857770 Handle colliding aliases for floors (#151614) 2025-09-03 12:43:03 +02:00
Bram Kragten de90922297 Update frontend to 20250903.0 (#151612) 2025-09-03 12:42:27 +02:00
Erik Montnemery e0b3a5337c Handle colliding aliases for areas (#151613) 2025-09-03 12:39:03 +02:00
Yevhenii Vaskivskyi 215603fae1 Bump asusrouter to 1.21.0 (#151607) 2025-09-03 12:16:00 +02:00
Krisjanis Lejejs 1a12c619e9 Bump hass-nabucasa from 1.0.0 to 1.1.0 (#151606) 2025-09-03 12:12:29 +02:00
yufeng 34c061df19 Add energy consumption/production for Tuya kg category (smart switches) (#149234) 2025-09-03 11:47:23 +02:00
yufeng c12b638b3d Adds initial support for tuya category xnyjcn (solar inverter) (#151549)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-09-03 11:39:54 +02:00
Robert Resch b9427deed2 Bump aioecowitt to 2025.9.0 (#151608) 2025-09-03 11:34:45 +02:00
yufeng d66016588b Add support for new energy sensor entities for DLQ (circuit breaker) devices in the Tuya integration (#151551)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-09-03 11:34:08 +02:00
Stefan Agner 229d0bdc77 Update Home Assistant base image to 2025.09.0 (#151582) 2025-09-03 11:12:18 +02:00
Erik Montnemery 078425918e Improve migration to device registry version 1.10 (#151571) 2025-09-03 10:22:29 +02:00
Erik Montnemery da2f154111 Improve migration to entity registry version 1.18 (#151570) 2025-09-03 10:08:59 +02:00
yufeng 270a9a5a98 Add support for new power sensor entities for ZNDB (smart energy meter) devices in the Tuya integration (#151554) 2025-09-03 09:22:20 +02:00
Lucas Mindêllo de Andrade 9f953c2e35 Tuya add missing sensors for Metering_3PN_ZB (dlq) device (#151601) 2025-09-03 09:13:24 +02:00
Artur Pragacz 8f16b09751 Accept None directly in the selector schemas (#151510)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-03 08:37:43 +02:00
dependabot[bot] 73ab041051 Bump github/codeql-action from 3.29.11 to 3.30.0 (#151600)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-03 08:10:07 +02:00
Paul Bottein 4bb76c6d94 Update frontend to 20250902.1 (#151593) 2025-09-02 22:55:03 -03:00
Brandon Rothweiler 7378d3607c Update py-aosmith to 1.0.14 (#151597) 2025-09-02 22:34:37 +01:00
Florian von Garrel 7d1e36af7f Raise paperless to platinum (#151588) 2025-09-02 22:27:56 +01:00
Petar Petrov 8b03a23ed8 Add option descriptions to Z-Wave reconfigure flow (#151558)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-09-02 22:06:07 +01:00
Michael Hansen a023dfc013 Add required features to vacuum intents (#151581) 2025-09-02 14:10:31 -05:00
J. Nick Koston fa0f707872 Add bluetooth websocket_api to subscribe to scanner state (#151452)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-02 15:17:27 -03:00
Joost Lekkerkerker a8f56e4b96 Fix Slide local tests (#151569)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-02 18:21:38 +02:00
Marc Mueller 61c904d225 Update pytest-rerunfailures to 16.0.1 (#151573) 2025-09-02 17:11:15 +01:00
Thomas D a8ff14ecb8 Bump volvocarsapi to v0.4.2 (#151579) 2025-09-02 17:09:21 +01:00
Michael Hansen 3909906823 Add required features for mowing intents (#151580) 2025-09-02 11:02:38 -05:00
Blear e0bf7749e6 Adjust Zhong_Hong climate set_fan_mode to lowercase (#151559) 2025-09-02 17:00:05 +02:00
Paul Bottein 72128e9708 Add start mowing and dock intents for lawn mower (#140525) 2025-09-02 09:49:24 -05:00
cdnninja 1b9acdc233 Convert Vesync to 3.X version of library (#148239)
Co-authored-by: SapuSeven <sapuseven@gmail.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-02 15:31:38 +02:00
Maciej Bieniek 0f530485d1 Record current IQS for NextDNS (#146895)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-02 15:07:25 +02:00
Christopher Fenner 0928e9a6ee Add sensor for DHW storage temperature in ViCare integration (#151128) 2025-09-02 13:24:42 +02:00
Marc Mueller 75d792207a Add missing pychromecast imports (#151544) 2025-09-02 13:24:00 +02:00
yufeng ceda62f6ea Add support for new energy sensor entities for TDQ (socket/outlet) devices in the Tuya integration (#151553) 2025-09-02 13:10:36 +02:00
Avi Miller 12ab84a5d9 Expose the transition field to the UI config of effect_colorloop (#151124)
Signed-off-by: Avi Miller <me@dje.li>
2025-09-02 13:07:48 +02:00
Simone Chemelli 8e85faf997 Update SamsungTV quality scale (#151552) 2025-09-02 13:06:33 +02:00
Simone Chemelli b514a14c10 Remove config entry from device instead of deleting in Uptime robot (#151557) 2025-09-02 13:06:07 +02:00
Erik Montnemery 6b609b019e Exclude non mowers from husqvarna_automower_ble discovery (#151507) 2025-09-02 12:57:39 +02:00
Erik Montnemery 10baae92a0 Revert "Improve migration to device registry version 1.11" (#151563) 2025-09-02 11:58:27 +02:00
Erik Montnemery 8e1ee32190 Revert "Improve migration to entity registry version 1.18" (#151561) 2025-09-02 11:54:37 +02:00
Abílio Costa 814b98c2a3 Add tests for hassfest triggers module (#151318) 2025-09-02 10:45:55 +02:00
Abílio Costa 243569f6b8 Add back missing controller cleanup to Govee Light Local (#151541) 2025-09-02 10:37:43 +02:00
Abílio Costa 4b7817f1df Filter out IPv6 addresses in Govee Light Local (#151540) 2025-09-02 10:27:38 +02:00
Antoni Czaplicki 180f898bfa Remove the vulcan integration (#151504) 2025-09-02 01:10:07 +02:00
Mathis Dirksen-Thedens e9dcde1bb5 Allow overriding default recipient in Signal messenger (#145654)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-09-01 23:20:26 +01:00
Bram Kragten f44b6a3a39 Update frontend to 20250901.0 (#151529) 2025-09-01 23:37:49 +02:00
Lukas 9b6b8003ec Remove mac address from Pooldose device (#151536)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2025-09-01 23:19:24 +02:00
Jan-Philipp Benecke 2503157282 Deprecate LANnouncer integration (#151531) 2025-09-01 22:31:25 +02:00
Sab44 7b2b3e9e33 Add Libre Hardware Monitor integration (#140449) 2025-09-01 22:12:12 +02:00
Abílio Costa 2d5f228308 Use MockConfigEntry.start_reauth_flow in Roborock's tests (#151528) 2025-09-01 21:28:42 +02:00
Nolan Stover 19f36fc630 Bump zabbix-utils to 2.0.3 (#149450)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-01 20:07:11 +01:00
Andrea Turri 6b6553dae3 Miele time sensors 2/3 - Provide consistent behavior with appliance status (#146053)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-09-01 20:20:24 +02:00
Robert Resch 0865d3f749 Add support for stream orientation in go2rtc (#148832) 2025-09-01 19:06:01 +01:00
Ravaka Razafimanantsoa 095f73d84f Add Switchbot Cloud AC Off (#138648)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-01 19:52:43 +02:00
Andrea Turri 3b60961f02 Miele refrigerators cause index out of range errors when offline (#151299) 2025-09-01 19:28:08 +02:00
Yevhenii Vaskivskyi 0d9079ea72 Add model_id and serial_number to the device description (asuswrt) (#151516) 2025-09-01 18:08:53 +02:00
Andrew Jackson f17db80428 Bump aiomealie to 0.10.2 (#151514) 2025-09-01 18:07:36 +02:00
Imeon-Energy 2d4b2e822a Fix typo in const.py for Imeon inverter integration (#151515)
Co-authored-by: TheBushBoy <theodavid@icloud.com>
2025-09-01 17:54:16 +02:00
Yuxin Wang b08a72a53d Move APC UPS Daemon integration to platinum (#151335) 2025-09-01 17:26:31 +02:00
dontinelli 1e4fa40a77 Extend effect of invert_position to cover status for slide_local (#150418) 2025-09-01 17:25:59 +02:00
Jan Bouwhuis ac0ff96f26 Sort MQTT test cases for subentry config flow (#151426) 2025-09-01 17:23:27 +02:00
Jan Bouwhuis 2e50cee555 Sort globals and helpers in MQTT config flow (#151419) 2025-09-01 17:22:58 +02:00
Artur Pragacz 51c6c1b0d2 Allow ignored Onkyo devices to be set up from the user flow (#150921) 2025-09-01 17:04:06 +02:00
Artur Pragacz c4fce1c793 Improve unpair schema in homekit (#150235) 2025-09-01 09:57:24 -05:00
Willem-Jan van Rootselaar 581f8a9378 Fix add checks for None values and check if DHW is available (#151376) 2025-09-01 16:47:59 +02:00
Artur Pragacz d7e6f84d28 Fix empty selector validation (#151340) 2025-09-01 16:22:41 +02:00
Artur Pragacz 5e22533fc0 Code quality improvements of the selector helper (#151505) 2025-09-01 16:18:17 +02:00
Fabian Leutgeb ecae074dd7 Homekit valve duration properties (#150273)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-09-01 08:24:50 -05:00
Joost Lekkerkerker 55b0406960 Update Pooldose quality scale (#151499) 2025-09-01 15:15:21 +02:00
Phil Male 36483dd785 Use average color for Hue light group state (#149499) 2025-09-01 15:14:50 +02:00
Ludovic BOUÉ ad154dce40 Add Matter occupancy sensing hold time (#150745) 2025-09-01 15:14:08 +02:00
G Johansson 3abf91af3a Use OptionsFlowWithReload in google (#151257) 2025-09-01 15:13:19 +02:00
Jozef Kruszynski 579d217c6b Fix sort order in media browser for music assistant integration (#150910) 2025-09-01 14:27:48 +02:00
Joakim Plate 7322bee4dd Add select entity to ToGrill (#151114)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-01 14:24:43 +02:00
Joost Lekkerkerker 8a36ec88f4 Add AC fixture to smartthings (#150891)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2025-09-01 14:24:33 +02:00
Michel van de Wetering 864f908257 Remove Hue Bridge v1 image in config flow (#151112) 2025-09-01 14:14:43 +02:00
alexqzd 5d86d8b380 SmartThings: Expose the entity to control the AC display light (#151404)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-09-01 14:12:18 +02:00
Iskra kranj 15245707a5 Bump pyiskra to 0.1.26 (#151489) 2025-09-01 14:09:19 +02:00
Martin Hjelmare 80e4451a3f Freeze development of alert integration (#151486) 2025-09-01 13:50:22 +02:00
Yuxin Wang f051f4ea99 Add more test logic to APCUPSD (#151336) 2025-09-01 13:15:11 +02:00
starkillerOG 7717b5aca6 Add Reolink Home Hub siren (#151196) 2025-09-01 12:46:46 +02:00
Imeon-Energy 81d2bcdeb9 Missing state for inverter state sensor in Imeon inverter (#151493)
Co-authored-by: TheBushBoy <theodavid@icloud.com>
2025-09-01 12:34:27 +02:00
Marc Mueller 9934de18ae Remove unused code in bayesian binary_sensor (#151492) 2025-09-01 12:33:53 +02:00
Marc Mueller aac015e822 Fix backup manager delete backup error filter (#151490) 2025-09-01 12:22:23 +02:00
Denis Shulyaka 1f584f011e Allow structure field of ai_task.generate_data for non-advanced users (#151481) 2025-09-01 07:06:09 -03:00
Joost Lekkerkerker 2106c4cfb9 Set Aladdin Connect integration type to hub (#151491) 2025-09-01 11:59:25 +02:00
jan iversen a053142601 modbus: Do not modify registers (return wrong data). (#151131) 2025-09-01 11:48:19 +02:00
starkillerOG dd0dce7968 Add Reolink encoding select entity (#151195) 2025-09-01 11:20:20 +02:00
Tom bdfff6df2d Bump airOS to 0.5.1 (#151458) 2025-09-01 10:40:09 +02:00
J. Nick Koston 671c4e1eab Reduce log spam from unauthenticated websocket connections (#151388) 2025-09-01 10:35:22 +02:00
ChristianKuehnel 8aae2a935a Replace string literal in lacrosse (#151484) 2025-09-01 10:32:05 +02:00
Yevhenii Vaskivskyi 9e64f18439 Fix bug with the wrong temperature scale on new router firmware (asuswrt) (#151011) 2025-09-01 10:30:41 +02:00
Paul Bottein e8a6f2f098 Update frontend to 20250829.0 (#151390) 2025-09-01 10:20:03 +02:00
Russell VanderMey 8faeb1fe98 Avoid blocking IO in TRIGGERcmd (#151396) 2025-09-01 10:19:35 +02:00
J. Nick Koston edc48e0604 Fix Yale Access Bluetooth key discovery timing issues (#151433)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-01 10:18:53 +02:00
Manu eab77f11b0 Rename brand Fritz!Box to FRITZ! (#151389) 2025-09-01 10:15:09 +02:00
Simone Chemelli edb79b0337 Change sounds list source for Alexa Devices (#151317) 2025-09-01 09:50:57 +02:00
Brett Adams 41f33a106f Fix history startup failures (#151439) 2025-09-01 09:48:49 +02:00
Arjan cf31401cc2 Fix typo in Meteo France mappings (#151344) 2025-09-01 09:46:21 +02:00
Niccolò Maggioni 8679c8e40c Expose MAC address in SNMP device_tracker entity attributes (#139941)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-01 09:40:50 +02:00
David Rapan e675d0e8ed Starlink's Energy, Download and Upload accumulation after restart fix (#137855)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-09-01 09:00:09 +02:00
J. Nick Koston c73289aed9 Bump bluetooth-adapters to 2.1.0 and habluetooth to 5.3.0 (#151465) 2025-08-31 17:13:03 -05:00
Marc Mueller 4420776977 Update anyio to 4.10.0 (#151455) 2025-08-31 21:14:37 +02:00
jan iversen b77d6e7b59 Modbus: Ignore unknown parameters. (#151451) 2025-08-31 16:48:12 +02:00
Thomas55555 8f074e5724 Bump aioautomower to 2.2.1 (#151427) 2025-08-31 15:16:19 +02:00
tronikos b1e46bcde4 Bump opower to 0.15.4 (#151443) 2025-08-31 12:14:14 +02:00
stephan-carstens fc4b5f66ff Extend UnitOfApparentPower with 'kVA' (#151420) 2025-08-31 00:05:07 +01:00
Maciej Bieniek 55978f2827 Allow integration to initialize when BraviaTV is offline (#151415) 2025-08-30 23:06:01 +03:00
Yuxin Wang 010a8cc693 Attach serial_number to devices in APC UPS Daemon (#151421) 2025-08-30 18:20:46 +02:00
Joakim Plate d31eadc8cd feat: bump fjaraskupan to 2.3.3 (#151408) 2025-08-30 10:35:30 +02:00
Manu 3190a523aa Remove device class from Habitica binary sensor quest status (#151338) 2025-08-30 09:40:36 +02:00
karwosts 8f82e451cd Fix play media example data (#151394) 2025-08-30 09:37:41 +02:00
Joakim Plate 5bbd71e594 Add icons to different temperatures for the ToGrill integration (#151392) 2025-08-30 07:11:33 +02:00
Aaron Bach 33257b8422 Bump aiopurpleair to 2025.08.1 (#151398) 2025-08-29 23:38:34 +02:00
Michael Hansen b3a4cd5b76 Bump intents to 2025.8.29 (#151397) 2025-08-29 16:17:42 -05:00
J. Nick Koston dcfa466dd4 Bump habluetooth to 5.2.1 (#151391) 2025-08-29 12:14:22 -05:00
Joakim Plate 846e6d96a4 Add minimum and maximum targets (#151387) 2025-08-29 17:42:28 +02:00
Erik Montnemery d72b35a0cd Improve comment on disabled_by + hidden_by flag in registries (#151290)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-08-29 17:27:39 +02:00
Foscam-wangzhengyu 5e003627b2 Update Foscam codeowners (#150972) 2025-08-29 16:59:46 +02:00
Manu a4f71f37f6 Use subentry title as display name in ntfy integration (#151370) 2025-08-29 16:56:37 +02:00
Manu c37b2f86b1 Change manufacturer name AVM to FRITZ! in FRITZ!Box Tools integration (#151371) 2025-08-29 16:54:53 +02:00
Manu 926aeef156 Change manufacturer name AVM to FRITZ! in FRITZ!Box Call Monitor integration (#151374) 2025-08-29 16:53:57 +02:00
Maciej Bieniek ee86671d39 Bump brother to version 5.1.0 (#151368)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-08-29 16:53:26 +02:00
Manu dc371cf46d Ignore errors when PlayStation Network group fetch is blocked by parental controls (#150364) 2025-08-29 16:53:13 +02:00
J. Nick Koston c76e26508d Bump aioesphomeapi to 39.0.1 (#151385) 2025-08-29 16:52:27 +02:00
J. Nick Koston a5cd316fa3 Bump bleak-esphome to 3.2.0 (#151380) 2025-08-29 16:51:56 +02:00
starkillerOG 736cc8a17d Bump reolink-aio to 0.15.0 (#151367)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-08-29 16:51:20 +02:00
J. Nick Koston 5278fce218 Bump nexia to 2.11.1 (#151379) 2025-08-29 16:49:57 +02:00
Erik Montnemery 8f04f22c65 Improve migration to device registry version 1.11 (#151315)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-08-29 16:48:29 +02:00
Manu a01f638fc6 Change manufacturer name AVM to FRITZ! in FRITZ!SmartHome integration (#151373) 2025-08-29 16:17:32 +02:00
Marc Mueller 22005dd48a Pin pytest-rerunfailures to 15.1 (#151383) 2025-08-29 16:03:32 +02:00
Thomas55555 fff60b3863 Use _async_setup in Huqvarna Automower (#151325) 2025-08-29 13:16:24 +02:00
Manu 5cb5fe5b67 Fix direct message notifiers in PlayStation Network (#150548) 2025-08-29 11:37:01 +02:00
J. Nick Koston 24ea5eb9b5 Bump habluetooth to 5.2.0 (#151333) 2025-08-29 11:23:50 +02:00
dependabot[bot] 673c2a77e0 Bump actions/attest-build-provenance from 2.4.0 to 3.0.0 (#151347)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-29 11:21:42 +02:00
Yevhenii Vaskivskyi ad3014e711 Bump asusrouter to 1.20.1 (#151311) 2025-08-29 11:21:18 +02:00
Tom c19ae81cbc Bump airOS to 0.4.4 (#151345) 2025-08-29 11:20:20 +02:00
J. Nick Koston 959d99f333 Bump bleak-retry-connector to 4.4.3 (#151341) 2025-08-29 11:19:44 +02:00
Manu 7cfe6bf427 Add sensors for boss rage to Habitica (#151334) 2025-08-29 00:01:23 +01:00
Manu 765e2c1b6c Bump habiticalib to v0.4.4 (#151332) 2025-08-29 00:04:37 +02:00
Paul Bottein 0fd63df123 Update frontend to 20250828.0 (#151321) 2025-08-28 22:27:46 +02:00
Robert Resch 862fbd551a Bump deebot-client to 13.7.0 (#151327) 2025-08-28 22:23:46 +02:00
J. Nick Koston 6e79b76d15 Bump nexia to 2.11.0 (#151319) 2025-08-28 21:48:41 +02:00
Martin Hjelmare f85307d86c Fix Z-Wave duplicate notification binary sensors (#151304) 2025-08-28 20:46:43 +02:00
Erik Montnemery b01f93119f Fix restoring disabled_by flag of deleted devices (#151313) 2025-08-28 20:10:10 +02:00
Erik Montnemery 4130f3db2f Improve migration to entity registry version 1.18 (#151308)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-08-28 18:52:51 +02:00
Yuxin Wang ffcd5167b5 Use fixtures instead of helper functions for APCUPSD tests (#151172)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2025-08-28 16:11:31 +02:00
Ludovic BOUÉ e94a7b2ec1 Add product_id support to Matter discovery schemas (#151307) 2025-08-28 15:57:40 +02:00
Ludovic BOUÉ 6b3f2e9b7b Aqara door window p2 fixture (#151294) 2025-08-28 15:04:23 +02:00
Roland Moers 56545dacb0 Bump fritzconnection to 1.15.0 (#151252) 2025-08-28 14:26:07 +02:00
Norbert Rittel cbf061183e Fix wrong description for numeric_state observation in bayesian (#151291) 2025-08-28 15:24:24 +03:00
Jamie Magee 5dcb5f4926 Remove uv.lock (#151282) 2025-08-28 12:33:30 +02:00
Andrew Jackson 5fbb99a79a Fix endpoint deprecation warning in Mastodon (#151275) 2025-08-28 11:59:37 +02:00
Felipe Santos da65c52f2d Fix ONVIF not displaying sensor and binary_sensor entity names (#151285) 2025-08-28 11:58:13 +02:00
Simone Chemelli 08a850cfc7 Fix exception countries migration for Alexa Devices (#151292) 2025-08-28 11:57:32 +02:00
Simone Chemelli 12978092f7 Add missing state class to Alexa Devices sensors (#151296) 2025-08-28 11:53:46 +02:00
starkillerOG 210a9ad2de Fix Reolink duplicates due to wrong merge (#151298) 2025-08-28 11:38:08 +02:00
Artur Pragacz 61328129fc Remove is_new from device entry (#149835)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-08-28 08:07:54 +02:00
Ian Tewksbury f4673f44ee Add multiple NICs in govee_light_local (#128123) 2025-08-28 08:04:50 +02:00
Arjan 3bdd532dcd Adding missing: Averses de grèle (#151288) 2025-08-28 07:50:48 +02:00
G Johansson e23d3c8ab4 Use OptionsFlowWithReload in google_cloud (#151259) 2025-08-27 22:19:44 -07:00
Florent Thoumie a7cb66c592 Iaqualink: create parent device manually and link entities (#151215) 2025-08-27 23:05:15 +01:00
Norbert Rittel 8544d1ebec Fix broken translation key for "update_percentage" in template (#151272) 2025-08-27 22:57:32 +01:00
G Johansson 240afd80c1 Fix spelling in bayesian strings (#151265) 2025-08-28 00:08:39 +03:00
Franck Nijhof ccb1da3a97 Bump version to 2025.10.0dev0 (#151262) 2025-08-27 21:53:39 +02:00
Denis Shulyaka de62991e5b OpenAI ai_task image generation support (#151238) 2025-08-27 14:43:27 -04:00
G Johansson bad75222ed Use OptionsFlowWithReload in yalexs_ble (#151256) 2025-08-27 13:14:31 -05:00
2208 changed files with 150759 additions and 28588 deletions
@@ -0,0 +1,77 @@
---
name: quality-scale-rule-verifier
description: |
Use this agent when you need to verify that a Home Assistant integration follows a specific quality scale rule. This includes checking if the integration implements required patterns, configurations, or code structures defined by the quality scale system.
<example>
Context: The user wants to verify if an integration follows a specific quality scale rule.
user: "Check if the peblar integration follows the config-flow rule"
assistant: "I'll use the quality scale rule verifier to check if the peblar integration properly implements the config-flow rule."
<commentary>
Since the user is asking to verify a quality scale rule implementation, use the quality-scale-rule-verifier agent.
</commentary>
</example>
<example>
Context: The user is reviewing if an integration reaches a specific quality scale level.
user: "Verify that this integration reaches the bronze quality scale"
assistant: "Let me use the quality scale rule verifier to check the bronze quality scale implementation."
<commentary>
The user wants to verify the integration has reached a certain quality level, so use multiple quality-scale-rule-verifier agents to verify each bronze rule.
</commentary>
</example>
model: inherit
color: yellow
tools: Read, Bash, Grep, Glob, WebFetch
---
You are an expert Home Assistant integration quality scale auditor specializing in verifying compliance with specific quality scale rules. You have deep knowledge of Home Assistant's architecture, best practices, and the quality scale system that ensures integration consistency and reliability.
You will verify if an integration follows a specific quality scale rule by:
1. **Fetching Rule Documentation**: Retrieve the official rule documentation from:
`https://raw.githubusercontent.com/home-assistant/developers.home-assistant/refs/heads/master/docs/core/integration-quality-scale/rules/{rule_name}.md`
where `{rule_name}` is the rule identifier (e.g., 'config-flow', 'entity-unique-id', 'parallel-updates')
2. **Understanding Rule Requirements**: Parse the rule documentation to identify:
- Core requirements and mandatory implementations
- Specific code patterns or configurations required
- Common violations and anti-patterns
- Exemption criteria (when a rule might not apply)
- The quality tier this rule belongs to (Bronze, Silver, Gold, Platinum)
3. **Analyzing Integration Code**: Examine the integration's codebase at `homeassistant/components/<integration domain>` focusing on:
- `manifest.json` for quality scale declaration and configuration
- `quality_scale.yaml` for rule status (done, todo, exempt)
- Relevant Python modules based on the rule requirements
- Configuration files and service definitions as needed
4. **Verification Process**:
- Check if the rule is marked as 'done', 'todo', or 'exempt' in quality_scale.yaml
- If marked 'exempt', verify the exemption reason is valid
- If marked 'done', verify the actual implementation matches requirements
- Identify specific files and code sections that demonstrate compliance or violations
- Consider the integration's declared quality tier when applying rules
- To fetch the integration docs, use WebFetch to fetch from `https://raw.githubusercontent.com/home-assistant/home-assistant.io/refs/heads/current/source/_integrations/<integration domain>.markdown`
- To fetch information about a PyPI package, use the URL `https://pypi.org/pypi/<package>/json`
5. **Reporting Findings**: Provide a comprehensive verification report that includes:
- **Rule Summary**: Brief description of what the rule requires
- **Compliance Status**: Clear pass/fail/exempt determination
- **Evidence**: Specific code examples showing compliance or violations
- **Issues Found**: Detailed list of any non-compliance issues with file locations
- **Recommendations**: Actionable steps to achieve compliance if needed
- **Exemption Analysis**: If applicable, whether the exemption is justified
When examining code, you will:
- Look for exact implementation patterns specified in the rule
- Verify all required components are present and properly configured
- Check for common mistakes and anti-patterns
- Consider edge cases and error handling requirements
- Validate that implementations follow Home Assistant conventions
You will be thorough but focused, examining only the aspects relevant to the specific rule being verified. You will provide clear, actionable feedback that helps developers understand both what needs to be fixed and why it matters for integration quality.
If you cannot access the rule documentation or find the integration code, clearly state what information is missing and what you would need to complete the verification.
Remember that quality scale rules are cumulative - Bronze rules apply to all integrations with a quality scale, Silver rules apply to Silver+ integrations, and so on. Always consider the integration's target quality level when determining which rules should be enforced.
+1
View File
@@ -58,6 +58,7 @@ base_platforms: &base_platforms
# Extra components that trigger the full suite
components: &components
- homeassistant/components/alexa/**
- homeassistant/components/analytics/**
- homeassistant/components/application_credentials/**
- homeassistant/components/assist_pipeline/**
- homeassistant/components/auth/**
+2
View File
@@ -8,6 +8,8 @@
"PYTHONASYNCIODEBUG": "1"
},
"features": {
// Node feature required for Claude Code until fixed https://github.com/anthropics/devcontainer-features/issues/28
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
},
+5
View File
@@ -55,8 +55,12 @@
creating the PR. If you're unsure about any of them, don't hesitate to ask.
We're here to help! This is simply a reminder of what we are going to look
for before merging your code.
AI tools are welcome, but contributors are responsible for *fully*
understanding the code before submitting a PR.
-->
- [ ] I understand the code I am submitting and can explain how it works.
- [ ] The code change is tested and works locally.
- [ ] Local tests pass. **Your PR cannot be merged unless tests pass**
- [ ] There is no commented out code in this PR.
@@ -64,6 +68,7 @@
- [ ] I have followed the [perfect PR recommendations][perfect-pr]
- [ ] The code has been formatted using Ruff (`ruff format homeassistant tests`)
- [ ] Tests have been added to verify that the new code works.
- [ ] Any generated code has been carefully reviewed for correctness and compliance with project standards.
If user exposed functionality or configuration variables are added/changed:
+26 -24
View File
@@ -27,12 +27,12 @@ jobs:
publish: ${{ steps.version.outputs.publish }}
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -69,7 +69,7 @@ jobs:
run: find ./homeassistant/components/*/translations -name "*.json" | tar zcvf translations.tar.gz -T -
- name: Upload translations
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: translations
path: translations.tar.gz
@@ -90,11 +90,11 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@v11
uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/frontend
@@ -105,7 +105,7 @@ jobs:
- name: Download nightly wheels of intents
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@v11
uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: OHF-Voice/intents-package
@@ -116,7 +116,7 @@ jobs:
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
if: needs.init.outputs.channel == 'dev'
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -175,7 +175,7 @@ jobs:
sed -i "s|pykrakenapi|# pykrakenapi|g" requirements_all.txt
- name: Download translations
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: translations
@@ -190,14 +190,15 @@ jobs:
echo "${{ github.sha }};${{ github.ref }};${{ github.event_name }};${{ github.actor }}" > rootfs/OFFICIAL_IMAGE
- name: Login to GitHub Container Registry
uses: docker/login-action@v3.5.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# home-assistant/builder doesn't support sha pinning
- name: Build base image
uses: home-assistant/builder@2025.03.0
uses: home-assistant/builder@2025.09.0
with:
args: |
$BUILD_ARGS \
@@ -242,7 +243,7 @@ jobs:
- green
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set build additional args
run: |
@@ -256,14 +257,15 @@ jobs:
fi
- name: Login to GitHub Container Registry
uses: docker/login-action@v3.5.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# home-assistant/builder doesn't support sha pinning
- name: Build base image
uses: home-assistant/builder@2025.03.0
uses: home-assistant/builder@2025.09.0
with:
args: |
$BUILD_ARGS \
@@ -279,7 +281,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Initialize git
uses: home-assistant/actions/helpers/git-init@master
@@ -321,23 +323,23 @@ jobs:
registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"]
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install Cosign
uses: sigstore/cosign-installer@v3.9.2
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
with:
cosign-release: "v2.2.3"
- name: Login to DockerHub
if: matrix.registry == 'docker.io/homeassistant'
uses: docker/login-action@v3.5.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
if: matrix.registry == 'ghcr.io/home-assistant'
uses: docker/login-action@v3.5.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -454,15 +456,15 @@ jobs:
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Download translations
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: translations
@@ -480,7 +482,7 @@ jobs:
python -m build
- name: Upload package to PyPI
uses: pypa/gh-action-pypi-publish@v1.12.4
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
with:
skip-existing: true
@@ -502,7 +504,7 @@ jobs:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Login to GitHub Container Registry
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -531,7 +533,7 @@ jobs:
- name: Generate artifact attestation
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
with:
subject-name: ${{ env.HASSFEST_IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }}
+222 -94
View File
@@ -37,10 +37,10 @@ on:
type: boolean
env:
CACHE_VERSION: 7
CACHE_VERSION: 8
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 1
HA_SHORT_VERSION: "2025.9"
HA_SHORT_VERSION: "2025.11"
DEFAULT_PYTHON: "3.13"
ALL_PYTHON_VERSIONS: "['3.13']"
# 10.3 is the oldest supported version
@@ -61,6 +61,9 @@ env:
POSTGRESQL_VERSIONS: "['postgres:12.14','postgres:15.2']"
PRE_COMMIT_CACHE: ~/.cache/pre-commit
UV_CACHE_DIR: /tmp/uv-cache
APT_CACHE_BASE: /home/runner/work/apt
APT_CACHE_DIR: /home/runner/work/apt/cache
APT_LIST_CACHE_DIR: /home/runner/work/apt/lists
SQLALCHEMY_WARN_20: 1
PYTHONASYNCIODEBUG: 1
HASS_CI: 1
@@ -78,6 +81,7 @@ jobs:
core: ${{ steps.core.outputs.changes }}
integrations_glob: ${{ steps.info.outputs.integrations_glob }}
integrations: ${{ steps.integrations.outputs.changes }}
apt_cache_key: ${{ steps.generate_apt_cache_key.outputs.key }}
pre-commit_cache_key: ${{ steps.generate_pre-commit_cache_key.outputs.key }}
python_cache_key: ${{ steps.generate_python_cache_key.outputs.key }}
requirements: ${{ steps.core.outputs.requirements }}
@@ -94,7 +98,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Generate partial Python venv restore key
id: generate_python_cache_key
run: |
@@ -111,8 +115,12 @@ jobs:
run: >-
echo "key=pre-commit-${{ env.CACHE_VERSION }}-${{
hashFiles('.pre-commit-config.yaml') }}" >> $GITHUB_OUTPUT
- name: Generate partial apt restore key
id: generate_apt_cache_key
run: |
echo "key=$(lsb_release -rs)-apt-${{ env.CACHE_VERSION }}-${{ env.HA_SHORT_VERSION }}" >> $GITHUB_OUTPUT
- name: Filter for core changes
uses: dorny/paths-filter@v3.0.2
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: core
with:
filters: .core_files.yaml
@@ -127,7 +135,7 @@ jobs:
echo "Result:"
cat .integration_paths.yaml
- name: Filter for integration changes
uses: dorny/paths-filter@v3.0.2
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: integrations
with:
filters: .integration_paths.yaml
@@ -246,16 +254,16 @@ jobs:
- info
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v4.2.4
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
key: >-
@@ -271,7 +279,7 @@ jobs:
uv pip install "$(cat requirements_test.txt | grep pre-commit)"
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v4.2.4
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ env.PRE_COMMIT_CACHE }}
lookup-only: true
@@ -292,16 +300,16 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -310,7 +318,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -332,16 +340,16 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -350,7 +358,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -372,16 +380,16 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -390,7 +398,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -462,7 +470,7 @@ jobs:
- script/hassfest/docker/Dockerfile
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Register hadolint problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/hadolint.json"
@@ -481,10 +489,10 @@ jobs:
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
@@ -497,7 +505,7 @@ jobs:
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v4.2.4
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
key: >-
@@ -505,7 +513,7 @@ jobs:
needs.info.outputs.python_cache_key }}
- name: Restore uv wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v4.2.4
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ env.UV_CACHE_DIR }}
key: >-
@@ -515,15 +523,38 @@ jobs:
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-uv-${{
env.UV_CACHE_VERSION }}-${{ steps.generate-uv-key.outputs.version }}-${{
env.HA_SHORT_VERSION }}-
- name: Check if apt cache exists
id: cache-apt-check
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
lookup-only: ${{ steps.cache-venv.outputs.cache-hit == 'true' }}
path: |
${{ env.APT_CACHE_DIR }}
${{ env.APT_LIST_CACHE_DIR }}
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
- name: Install additional OS dependencies
if: steps.cache-venv.outputs.cache-hit != 'true'
if: |
steps.cache-venv.outputs.cache-hit != 'true'
|| steps.cache-apt-check.outputs.cache-hit != 'true'
timeout-minutes: 10
run: |
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update
if [[ "${{ steps.cache-apt-check.outputs.cache-hit }}" != 'true' ]]; then
mkdir -p ${{ env.APT_CACHE_DIR }}
mkdir -p ${{ env.APT_LIST_CACHE_DIR }}
fi
sudo apt-get update \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }}
sudo apt-get -y install \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }} \
bluez \
ffmpeg \
libturbojpeg \
libxml2-utils \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
@@ -533,6 +564,19 @@ jobs:
libswresample-dev \
libswscale-dev \
libudev-dev
if [[ "${{ steps.cache-apt-check.outputs.cache-hit }}" != 'true' ]]; then
sudo chmod -R 755 ${{ env.APT_CACHE_BASE }}
fi
- name: Save apt cache
if: steps.cache-apt-check.outputs.cache-hit != 'true'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
${{ env.APT_CACHE_DIR }}
${{ env.APT_LIST_CACHE_DIR }}
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
- name: Create Python virtual environment
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
@@ -552,7 +596,7 @@ jobs:
python --version
uv pip freeze >> pip_freeze.txt
- name: Upload pip_freeze artifact
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pip-freeze-${{ matrix.python-version }}
path: pip_freeze.txt
@@ -577,23 +621,37 @@ jobs:
- info
- base
steps:
- name: Restore apt cache
uses: actions/cache/restore@v4.3.0
with:
path: |
${{ env.APT_CACHE_DIR }}
${{ env.APT_LIST_CACHE_DIR }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
- name: Install additional OS dependencies
timeout-minutes: 10
run: |
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update
sudo apt-get update \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }}
sudo apt-get -y install \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }} \
libturbojpeg
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -617,16 +675,16 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -651,9 +709,9 @@ jobs:
&& github.event_name == 'pull_request'
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Dependency review
uses: actions/dependency-review-action@v4.7.3
uses: actions/dependency-review-action@56339e523c0409420f6c2c9a2f4292bbb3c07dd3 # v4.8.0
with:
license-check: false # We use our own license audit checks
@@ -674,16 +732,16 @@ jobs:
python-version: ${{ fromJson(needs.info.outputs.python_versions) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -695,7 +753,7 @@ jobs:
. venv/bin/activate
python -m script.licenses extract --output-file=licenses-${{ matrix.python-version }}.json
- name: Upload licenses
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: licenses-${{ github.run_number }}-${{ matrix.python-version }}
path: licenses-${{ matrix.python-version }}.json
@@ -717,16 +775,16 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -764,16 +822,16 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -809,10 +867,10 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -825,7 +883,7 @@ jobs:
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -833,7 +891,7 @@ jobs:
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Restore mypy cache
uses: actions/cache@v4.2.4
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .mypy_cache
key: >-
@@ -876,26 +934,40 @@ jobs:
- mypy
name: Split tests for full run
steps:
- name: Restore apt cache
uses: actions/cache/restore@v4.3.0
with:
path: |
${{ env.APT_CACHE_DIR }}
${{ env.APT_LIST_CACHE_DIR }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
- name: Install additional OS dependencies
timeout-minutes: 10
run: |
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update
sudo apt-get update \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }}
sudo apt-get -y install \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }} \
bluez \
ffmpeg \
libturbojpeg \
libgammu-dev
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -907,7 +979,7 @@ jobs:
. venv/bin/activate
python -m script.split_tests ${{ needs.info.outputs.test_group_count }} tests
- name: Upload pytest_buckets
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pytest_buckets
path: pytest_buckets.txt
@@ -936,27 +1008,41 @@ jobs:
name: >-
Run tests Python ${{ matrix.python-version }} (${{ matrix.group }})
steps:
- name: Restore apt cache
uses: actions/cache/restore@v4.3.0
with:
path: |
${{ env.APT_CACHE_DIR }}
${{ env.APT_LIST_CACHE_DIR }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
- name: Install additional OS dependencies
timeout-minutes: 10
run: |
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update
sudo apt-get update \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }}
sudo apt-get -y install \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }} \
bluez \
ffmpeg \
libturbojpeg \
libgammu-dev \
libxml2-utils
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -970,7 +1056,7 @@ jobs:
run: |
echo "::add-matcher::.github/workflows/matchers/pytest-slow.json"
- name: Download pytest_buckets
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: pytest_buckets
- name: Compile English translations
@@ -1009,14 +1095,14 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${{ matrix.group }}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-full.conclusion == 'failure'
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{ matrix.group }}
path: pytest-*.txt
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
path: coverage.xml
@@ -1029,7 +1115,7 @@ jobs:
mv "junit.xml-tmp" "junit.xml"
- name: Upload test results artifact
if: needs.info.outputs.skip_coverage != 'true' && !cancelled()
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: test-results-full-${{ matrix.python-version }}-${{ matrix.group }}
path: junit.xml
@@ -1069,27 +1155,41 @@ jobs:
name: >-
Run ${{ matrix.mariadb-group }} tests Python ${{ matrix.python-version }}
steps:
- name: Restore apt cache
uses: actions/cache/restore@v4.3.0
with:
path: |
${{ env.APT_CACHE_DIR }}
${{ env.APT_LIST_CACHE_DIR }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
- name: Install additional OS dependencies
timeout-minutes: 10
run: |
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update
sudo apt-get update \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }}
sudo apt-get -y install \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }} \
bluez \
ffmpeg \
libturbojpeg \
libmariadb-dev-compat \
libxml2-utils
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -1148,7 +1248,7 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${mariadb}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.mariadb }}
@@ -1156,7 +1256,7 @@ jobs:
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: coverage-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.mariadb }}
@@ -1170,7 +1270,7 @@ jobs:
mv "junit.xml-tmp" "junit.xml"
- name: Upload test results artifact
if: needs.info.outputs.skip_coverage != 'true' && !cancelled()
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: test-results-mariadb-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.mariadb }}
@@ -1209,11 +1309,25 @@ jobs:
name: >-
Run ${{ matrix.postgresql-group }} tests Python ${{ matrix.python-version }}
steps:
- name: Restore apt cache
uses: actions/cache/restore@v4.3.0
with:
path: |
${{ env.APT_CACHE_DIR }}
${{ env.APT_LIST_CACHE_DIR }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
- name: Install additional OS dependencies
timeout-minutes: 10
run: |
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update
sudo apt-get update \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }}
sudo apt-get -y install \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }} \
bluez \
ffmpeg \
libturbojpeg \
@@ -1222,16 +1336,16 @@ jobs:
sudo apt-get -y install \
postgresql-server-dev-14
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -1291,7 +1405,7 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${postgresql}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.postgresql }}
@@ -1299,7 +1413,7 @@ jobs:
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: coverage-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.postgresql }}
@@ -1313,7 +1427,7 @@ jobs:
mv "junit.xml-tmp" "junit.xml"
- name: Upload test results artifact
if: needs.info.outputs.skip_coverage != 'true' && !cancelled()
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: test-results-postgres-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.postgresql }}
@@ -1334,14 +1448,14 @@ jobs:
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Download all coverage artifacts
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
pattern: coverage-*
- name: Upload coverage to Codecov
if: needs.info.outputs.test_full_suite == 'true'
uses: codecov/codecov-action@v5.5.0
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
with:
fail_ci_if_error: true
flags: full-suite
@@ -1370,27 +1484,41 @@ jobs:
name: >-
Run tests Python ${{ matrix.python-version }} (${{ matrix.group }})
steps:
- name: Restore apt cache
uses: actions/cache/restore@v4.3.0
with:
path: |
${{ env.APT_CACHE_DIR }}
${{ env.APT_LIST_CACHE_DIR }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
- name: Install additional OS dependencies
timeout-minutes: 10
run: |
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update
sudo apt-get update \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }}
sudo apt-get -y install \
-o Dir::Cache=${{ env.APT_CACHE_DIR }} \
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }} \
bluez \
ffmpeg \
libturbojpeg \
libgammu-dev \
libxml2-utils
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: venv
fail-on-cache-miss: true
@@ -1446,14 +1574,14 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${{ matrix.group }}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{ matrix.group }}
path: pytest-*.txt
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
path: coverage.xml
@@ -1466,7 +1594,7 @@ jobs:
mv "junit.xml-tmp" "junit.xml"
- name: Upload test results artifact
if: needs.info.outputs.skip_coverage != 'true' && !cancelled()
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: test-results-partial-${{ matrix.python-version }}-${{ matrix.group }}
path: junit.xml
@@ -1484,14 +1612,14 @@ jobs:
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Download all coverage artifacts
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
pattern: coverage-*
- name: Upload coverage to Codecov
if: needs.info.outputs.test_full_suite == 'false'
uses: codecov/codecov-action@v5.5.0
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
@@ -1511,11 +1639,11 @@ jobs:
timeout-minutes: 10
steps:
- name: Download all coverage artifacts
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
pattern: test-results-*
- name: Upload test results to Codecov
uses: codecov/test-results-action@v1
uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1
with:
fail_ci_if_error: true
verbose: true
+3 -3
View File
@@ -21,14 +21,14 @@ jobs:
steps:
- name: Check out code from GitHub
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.29.11
uses: github/codeql-action/init@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.29.11
uses: github/codeql-action/analyze@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
with:
category: "/language:python"
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Check if integration label was added and extract details
id: extract
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
// Debug: Log the event payload
@@ -113,7 +113,7 @@ jobs:
- name: Fetch similar issues
id: fetch_similar
if: steps.extract.outputs.should_continue == 'true'
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
INTEGRATION_LABELS: ${{ steps.extract.outputs.integration_labels }}
CURRENT_NUMBER: ${{ steps.extract.outputs.current_number }}
@@ -231,7 +231,7 @@ jobs:
- name: Detect duplicates using AI
id: ai_detection
if: steps.extract.outputs.should_continue == 'true' && steps.fetch_similar.outputs.has_similar == 'true'
uses: actions/ai-inference@v2.0.1
uses: actions/ai-inference@a1c11829223a786afe3b5663db904a3aa1eac3a2 # v2.0.1
with:
model: openai/gpt-4o
system-prompt: |
@@ -280,7 +280,7 @@ jobs:
- name: Post duplicate detection results
id: post_results
if: steps.extract.outputs.should_continue == 'true' && steps.fetch_similar.outputs.has_similar == 'true'
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
AI_RESPONSE: ${{ steps.ai_detection.outputs.response }}
SIMILAR_ISSUES: ${{ steps.fetch_similar.outputs.similar_issues }}
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Check issue language
id: detect_language
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
@@ -57,7 +57,7 @@ jobs:
- name: Detect language using AI
id: ai_language_detection
if: steps.detect_language.outputs.should_continue == 'true'
uses: actions/ai-inference@v2.0.1
uses: actions/ai-inference@a1c11829223a786afe3b5663db904a3aa1eac3a2 # v2.0.1
with:
model: openai/gpt-4o-mini
system-prompt: |
@@ -90,7 +90,7 @@ jobs:
- name: Process non-English issues
if: steps.detect_language.outputs.should_continue == 'true'
uses: actions/github-script@v7.0.1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
AI_RESPONSE: ${{ steps.ai_language_detection.outputs.response }}
ISSUE_NUMBER: ${{ steps.detect_language.outputs.issue_number }}
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
if: github.repository_owner == 'home-assistant'
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5.0.1
- uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1
with:
github-token: ${{ github.token }}
issue-inactive-days: "30"
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
if: github.event.issue.type.name == 'Task'
steps:
- name: Check if user is authorized
uses: actions/github-script@v7
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const issueAuthor = context.payload.issue.user.login;
+3 -3
View File
@@ -17,7 +17,7 @@ jobs:
# - No PRs marked as no-stale
# - No issues (-1)
- name: 60 days stale PRs policy
uses: actions/stale@v9.1.0
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 60
@@ -57,7 +57,7 @@ jobs:
# - No issues marked as no-stale or help-wanted
# - No PRs (-1)
- name: 90 days stale issues
uses: actions/stale@v9.1.0
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
with:
repo-token: ${{ steps.token.outputs.token }}
days-before-stale: 90
@@ -87,7 +87,7 @@ jobs:
# - No Issues marked as no-stale or help-wanted
# - No PRs (-1)
- name: Needs more information stale issues policy
uses: actions/stale@v9.1.0
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
with:
repo-token: ${{ steps.token.outputs.token }}
only-labels: "needs-more-information"
+2 -2
View File
@@ -19,10 +19,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
+19 -17
View File
@@ -32,11 +32,11 @@ jobs:
architectures: ${{ steps.info.outputs.architectures }}
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.6.0
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -91,7 +91,7 @@ jobs:
) > build_constraints.txt
- name: Upload env_file
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: env_file
path: ./.env_file
@@ -99,14 +99,14 @@ jobs:
overwrite: true
- name: Upload build_constraints
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: build_constraints
path: ./build_constraints.txt
overwrite: true
- name: Upload requirements_diff
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: requirements_diff
path: ./requirements_diff.txt
@@ -118,7 +118,7 @@ jobs:
python -m script.gen_requirements_all ci
- name: Upload requirements_all_wheels
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: requirements_all_wheels
path: ./requirements_all_wheels_*.txt
@@ -135,20 +135,20 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Download env_file
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: env_file
- name: Download build_constraints
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: build_constraints
- name: Download requirements_diff
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: requirements_diff
@@ -158,8 +158,9 @@ jobs:
sed -i "/uv/d" requirements.txt
sed -i "/uv/d" requirements_diff.txt
# home-assistant/wheels doesn't support sha pinning
- name: Build wheels
uses: home-assistant/wheels@2025.07.0
uses: home-assistant/wheels@2025.09.1
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
@@ -184,25 +185,25 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v5.0.0
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Download env_file
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: env_file
- name: Download build_constraints
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: build_constraints
- name: Download requirements_diff
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: requirements_diff
- name: Download requirements_all_wheels
uses: actions/download-artifact@v5.0.0
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: requirements_all_wheels
@@ -218,8 +219,9 @@ jobs:
sed -i "/uv/d" requirements.txt
sed -i "/uv/d" requirements_diff.txt
# home-assistant/wheels doesn't support sha pinning
- name: Build wheels
uses: home-assistant/wheels@2025.07.0
uses: home-assistant/wheels@2025.09.1
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
+1 -1
View File
@@ -140,5 +140,5 @@ tmp_cache
pytest_buckets.txt
# AI tooling
.claude
.claude/settings.local.json
+1 -1
View File
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.1
rev: v0.13.0
hooks:
- id: ruff-check
args:
+9
View File
@@ -142,6 +142,7 @@ homeassistant.components.cloud.*
homeassistant.components.co2signal.*
homeassistant.components.comelit.*
homeassistant.components.command_line.*
homeassistant.components.compit.*
homeassistant.components.config.*
homeassistant.components.configurator.*
homeassistant.components.cookidoo.*
@@ -169,6 +170,7 @@ homeassistant.components.dnsip.*
homeassistant.components.doorbird.*
homeassistant.components.dormakaba_dkey.*
homeassistant.components.downloader.*
homeassistant.components.droplet.*
homeassistant.components.dsmr.*
homeassistant.components.duckdns.*
homeassistant.components.dunehd.*
@@ -201,6 +203,7 @@ homeassistant.components.feedreader.*
homeassistant.components.file_upload.*
homeassistant.components.filesize.*
homeassistant.components.filter.*
homeassistant.components.firefly_iii.*
homeassistant.components.fitbit.*
homeassistant.components.flexit_bacnet.*
homeassistant.components.flux_led.*
@@ -307,6 +310,7 @@ homeassistant.components.ld2410_ble.*
homeassistant.components.led_ble.*
homeassistant.components.lektrico.*
homeassistant.components.letpot.*
homeassistant.components.libre_hardware_monitor.*
homeassistant.components.lidarr.*
homeassistant.components.lifx.*
homeassistant.components.light.*
@@ -322,6 +326,7 @@ homeassistant.components.london_underground.*
homeassistant.components.lookin.*
homeassistant.components.lovelace.*
homeassistant.components.luftdaten.*
homeassistant.components.lunatone.*
homeassistant.components.madvr.*
homeassistant.components.manual.*
homeassistant.components.mastodon.*
@@ -382,6 +387,7 @@ homeassistant.components.openai_conversation.*
homeassistant.components.openexchangerates.*
homeassistant.components.opensky.*
homeassistant.components.openuv.*
homeassistant.components.opnsense.*
homeassistant.components.opower.*
homeassistant.components.oralb.*
homeassistant.components.otbr.*
@@ -399,6 +405,7 @@ homeassistant.components.person.*
homeassistant.components.pi_hole.*
homeassistant.components.ping.*
homeassistant.components.plugwise.*
homeassistant.components.portainer.*
homeassistant.components.powerfox.*
homeassistant.components.powerwall.*
homeassistant.components.private_ble_device.*
@@ -438,6 +445,7 @@ homeassistant.components.rituals_perfume_genie.*
homeassistant.components.roborock.*
homeassistant.components.roku.*
homeassistant.components.romy.*
homeassistant.components.route_b_smart_meter.*
homeassistant.components.rpi_power.*
homeassistant.components.rss_feed_template.*
homeassistant.components.russound_rio.*
@@ -458,6 +466,7 @@ homeassistant.components.sensorpush_cloud.*
homeassistant.components.sensoterra.*
homeassistant.components.senz.*
homeassistant.components.sfr_box.*
homeassistant.components.sftp_storage.*
homeassistant.components.shell_command.*
homeassistant.components.shelly.*
homeassistant.components.shopping_list.*
Generated
+64 -39
View File
@@ -107,8 +107,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/ambient_station/ @bachya
/tests/components/ambient_station/ @bachya
/homeassistant/components/amcrest/ @flacjacket
/homeassistant/components/analytics/ @home-assistant/core @ludeeus
/tests/components/analytics/ @home-assistant/core @ludeeus
/homeassistant/components/analytics/ @home-assistant/core
/tests/components/analytics/ @home-assistant/core
/homeassistant/components/analytics_insights/ @joostlek
/tests/components/analytics_insights/ @joostlek
/homeassistant/components/android_ip_webcam/ @engrbm87
@@ -154,10 +154,10 @@ build.json @home-assistant/supervisor
/tests/components/arve/ @ikalnyi
/homeassistant/components/aseko_pool_live/ @milanmeu
/tests/components/aseko_pool_live/ @milanmeu
/homeassistant/components/assist_pipeline/ @balloob @synesthesiam
/tests/components/assist_pipeline/ @balloob @synesthesiam
/homeassistant/components/assist_satellite/ @home-assistant/core @synesthesiam
/tests/components/assist_satellite/ @home-assistant/core @synesthesiam
/homeassistant/components/assist_pipeline/ @synesthesiam @arturpragacz
/tests/components/assist_pipeline/ @synesthesiam @arturpragacz
/homeassistant/components/assist_satellite/ @home-assistant/core @synesthesiam @arturpragacz
/tests/components/assist_satellite/ @home-assistant/core @synesthesiam @arturpragacz
/homeassistant/components/asuswrt/ @kennedyshead @ollo69 @Vaskivskyi
/tests/components/asuswrt/ @kennedyshead @ollo69 @Vaskivskyi
/homeassistant/components/atag/ @MatsNL
@@ -292,14 +292,16 @@ build.json @home-assistant/supervisor
/tests/components/command_line/ @gjohansson-ST
/homeassistant/components/compensation/ @Petro31
/tests/components/compensation/ @Petro31
/homeassistant/components/compit/ @Przemko92
/tests/components/compit/ @Przemko92
/homeassistant/components/config/ @home-assistant/core
/tests/components/config/ @home-assistant/core
/homeassistant/components/configurator/ @home-assistant/core
/tests/components/configurator/ @home-assistant/core
/homeassistant/components/control4/ @lawtancool
/tests/components/control4/ @lawtancool
/homeassistant/components/conversation/ @home-assistant/core @synesthesiam
/tests/components/conversation/ @home-assistant/core @synesthesiam
/homeassistant/components/conversation/ @home-assistant/core @synesthesiam @arturpragacz
/tests/components/conversation/ @home-assistant/core @synesthesiam @arturpragacz
/homeassistant/components/cookidoo/ @miaucl
/tests/components/cookidoo/ @miaucl
/homeassistant/components/coolmaster/ @OnFreund
@@ -314,6 +316,8 @@ build.json @home-assistant/supervisor
/tests/components/crownstone/ @Crownstone @RicArch97
/homeassistant/components/cups/ @fabaff
/tests/components/cups/ @fabaff
/homeassistant/components/cync/ @Kinachi249
/tests/components/cync/ @Kinachi249
/homeassistant/components/daikin/ @fredrike
/tests/components/daikin/ @fredrike
/homeassistant/components/date/ @home-assistant/core
@@ -377,6 +381,8 @@ build.json @home-assistant/supervisor
/tests/components/dremel_3d_printer/ @tkdrob
/homeassistant/components/drop_connect/ @ChandlerSystems @pfrazer
/tests/components/drop_connect/ @ChandlerSystems @pfrazer
/homeassistant/components/droplet/ @sarahseidman
/tests/components/droplet/ @sarahseidman
/homeassistant/components/dsmr/ @Robbie1221
/tests/components/dsmr/ @Robbie1221
/homeassistant/components/dsmr_reader/ @sorted-bits @glodenox @erwindouna
@@ -406,6 +412,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/egardia/ @jeroenterheerdt
/homeassistant/components/eheimdigital/ @autinerd
/tests/components/eheimdigital/ @autinerd
/homeassistant/components/ekeybionyx/ @richardpolzer
/tests/components/ekeybionyx/ @richardpolzer
/homeassistant/components/electrasmart/ @jafar-atili
/tests/components/electrasmart/ @jafar-atili
/homeassistant/components/electric_kiwi/ @mikey0000
@@ -440,8 +448,6 @@ build.json @home-assistant/supervisor
/tests/components/energyzero/ @klaasnicolaas
/homeassistant/components/enigma2/ @autinerd
/tests/components/enigma2/ @autinerd
/homeassistant/components/enocean/ @bdurrer
/tests/components/enocean/ @bdurrer
/homeassistant/components/enphase_envoy/ @bdraco @cgarwood @catsmanac
/tests/components/enphase_envoy/ @bdraco @cgarwood @catsmanac
/homeassistant/components/entur_public_transport/ @hfurubotten
@@ -464,8 +470,6 @@ build.json @home-assistant/supervisor
/tests/components/eufylife_ble/ @bdr99
/homeassistant/components/event/ @home-assistant/core
/tests/components/event/ @home-assistant/core
/homeassistant/components/evil_genius_labs/ @balloob
/tests/components/evil_genius_labs/ @balloob
/homeassistant/components/evohome/ @zxdavb
/tests/components/evohome/ @zxdavb
/homeassistant/components/ezviz/ @RenierM26
@@ -488,6 +492,8 @@ build.json @home-assistant/supervisor
/tests/components/filesize/ @gjohansson-ST
/homeassistant/components/filter/ @dgomes
/tests/components/filter/ @dgomes
/homeassistant/components/firefly_iii/ @erwindouna
/tests/components/firefly_iii/ @erwindouna
/homeassistant/components/fireservicerota/ @cyberjunky
/tests/components/fireservicerota/ @cyberjunky
/homeassistant/components/firmata/ @DaAwesomeP
@@ -515,8 +521,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/forked_daapd/ @uvjustin
/tests/components/forked_daapd/ @uvjustin
/homeassistant/components/fortios/ @kimfrellsen
/homeassistant/components/foscam/ @krmarien
/tests/components/foscam/ @krmarien
/homeassistant/components/foscam/ @Foscam-wangzhengyu
/tests/components/foscam/ @Foscam-wangzhengyu
/homeassistant/components/freebox/ @hacf-fr @Quentame
/tests/components/freebox/ @hacf-fr @Quentame
/homeassistant/components/freedompro/ @stefano055415
@@ -650,6 +656,8 @@ build.json @home-assistant/supervisor
/tests/components/homeassistant/ @home-assistant/core
/homeassistant/components/homeassistant_alerts/ @home-assistant/core
/tests/components/homeassistant_alerts/ @home-assistant/core
/homeassistant/components/homeassistant_connect_zbt2/ @home-assistant/core
/tests/components/homeassistant_connect_zbt2/ @home-assistant/core
/homeassistant/components/homeassistant_green/ @home-assistant/core
/tests/components/homeassistant_green/ @home-assistant/core
/homeassistant/components/homeassistant_hardware/ @home-assistant/core
@@ -678,8 +686,8 @@ build.json @home-assistant/supervisor
/tests/components/http/ @home-assistant/core
/homeassistant/components/huawei_lte/ @scop @fphammerle
/tests/components/huawei_lte/ @scop @fphammerle
/homeassistant/components/hue/ @balloob @marcelveldt
/tests/components/hue/ @balloob @marcelveldt
/homeassistant/components/hue/ @marcelveldt
/tests/components/hue/ @marcelveldt
/homeassistant/components/huisbaasje/ @dennisschroer
/tests/components/huisbaasje/ @dennisschroer
/homeassistant/components/humidifier/ @home-assistant/core @Shulyaka
@@ -751,8 +759,8 @@ build.json @home-assistant/supervisor
/tests/components/integration/ @dgomes
/homeassistant/components/intellifire/ @jeeftor
/tests/components/intellifire/ @jeeftor
/homeassistant/components/intent/ @home-assistant/core @synesthesiam
/tests/components/intent/ @home-assistant/core @synesthesiam
/homeassistant/components/intent/ @home-assistant/core @synesthesiam @arturpragacz
/tests/components/intent/ @home-assistant/core @synesthesiam @arturpragacz
/homeassistant/components/intesishome/ @jnimmo
/homeassistant/components/iometer/ @MaestroOnICe
/tests/components/iometer/ @MaestroOnICe
@@ -770,6 +778,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/iqvia/ @bachya
/tests/components/iqvia/ @bachya
/homeassistant/components/irish_rail_transport/ @ttroy50
/homeassistant/components/irm_kmi/ @jdejaegh
/tests/components/irm_kmi/ @jdejaegh
/homeassistant/components/iron_os/ @tr4nt0r
/tests/components/iron_os/ @tr4nt0r
/homeassistant/components/isal/ @bdraco
@@ -860,6 +870,8 @@ build.json @home-assistant/supervisor
/tests/components/lg_netcast/ @Drafteed @splinter98
/homeassistant/components/lg_thinq/ @LG-ThinQ-Integration
/tests/components/lg_thinq/ @LG-ThinQ-Integration
/homeassistant/components/libre_hardware_monitor/ @Sab44
/tests/components/libre_hardware_monitor/ @Sab44
/homeassistant/components/lidarr/ @tkdrob
/tests/components/lidarr/ @tkdrob
/homeassistant/components/lifx/ @Djelibeybi
@@ -898,6 +910,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/luci/ @mzdrale
/homeassistant/components/luftdaten/ @fabaff @frenck
/tests/components/luftdaten/ @fabaff @frenck
/homeassistant/components/lunatone/ @MoonDevLT
/tests/components/lunatone/ @MoonDevLT
/homeassistant/components/lupusec/ @majuss @suaveolent
/tests/components/lupusec/ @majuss @suaveolent
/homeassistant/components/lutron/ @cdheiser @wilburCForce
@@ -943,6 +957,8 @@ build.json @home-assistant/supervisor
/tests/components/met_eireann/ @DylanGore
/homeassistant/components/meteo_france/ @hacf-fr @oncleben31 @Quentame
/tests/components/meteo_france/ @hacf-fr @oncleben31 @Quentame
/homeassistant/components/meteo_lt/ @xE1H
/tests/components/meteo_lt/ @xE1H
/homeassistant/components/meteoalarm/ @rolfberkenbosch
/homeassistant/components/meteoclimatic/ @adrianmo
/tests/components/meteoclimatic/ @adrianmo
@@ -1013,7 +1029,8 @@ build.json @home-assistant/supervisor
/tests/components/nanoleaf/ @milanmeu @joostlek
/homeassistant/components/nasweb/ @nasWebio
/tests/components/nasweb/ @nasWebio
/homeassistant/components/nederlandse_spoorwegen/ @YarmoM
/homeassistant/components/nederlandse_spoorwegen/ @YarmoM @heindrichpaul
/tests/components/nederlandse_spoorwegen/ @YarmoM @heindrichpaul
/homeassistant/components/ness_alarm/ @nickw444
/tests/components/ness_alarm/ @nickw444
/homeassistant/components/nest/ @allenporter
@@ -1108,8 +1125,6 @@ build.json @home-assistant/supervisor
/tests/components/open_meteo/ @frenck
/homeassistant/components/open_router/ @joostlek
/tests/components/open_router/ @joostlek
/homeassistant/components/openai_conversation/ @balloob
/tests/components/openai_conversation/ @balloob
/homeassistant/components/openerz/ @misialq
/tests/components/openerz/ @misialq
/homeassistant/components/openexchangerates/ @MartinHjelmare
@@ -1189,6 +1204,8 @@ build.json @home-assistant/supervisor
/tests/components/pooldose/ @lmaertin
/homeassistant/components/poolsense/ @haemishkyd
/tests/components/poolsense/ @haemishkyd
/homeassistant/components/portainer/ @erwindouna
/tests/components/portainer/ @erwindouna
/homeassistant/components/powerfox/ @klaasnicolaas
/tests/components/powerfox/ @klaasnicolaas
/homeassistant/components/powerwall/ @bdraco @jrester @daniel-simpson
@@ -1208,8 +1225,6 @@ build.json @home-assistant/supervisor
/homeassistant/components/proximity/ @mib1185
/tests/components/proximity/ @mib1185
/homeassistant/components/proxmoxve/ @jhollowe @Corbeno
/homeassistant/components/prusalink/ @balloob
/tests/components/prusalink/ @balloob
/homeassistant/components/ps4/ @ktnrg45
/tests/components/ps4/ @ktnrg45
/homeassistant/components/pterodactyl/ @elmurato
@@ -1303,8 +1318,8 @@ build.json @home-assistant/supervisor
/tests/components/rflink/ @javicalle
/homeassistant/components/rfxtrx/ @danielhiversen @elupus @RobBie1221
/tests/components/rfxtrx/ @danielhiversen @elupus @RobBie1221
/homeassistant/components/rhasspy/ @balloob @synesthesiam
/tests/components/rhasspy/ @balloob @synesthesiam
/homeassistant/components/rhasspy/ @synesthesiam
/tests/components/rhasspy/ @synesthesiam
/homeassistant/components/ridwell/ @bachya
/tests/components/ridwell/ @bachya
/homeassistant/components/ring/ @sdb9696
@@ -1325,6 +1340,8 @@ build.json @home-assistant/supervisor
/tests/components/roomba/ @pschmitt @cyr-ius @shenxn @Orhideous
/homeassistant/components/roon/ @pavoni
/tests/components/roon/ @pavoni
/homeassistant/components/route_b_smart_meter/ @SeraphicRav
/tests/components/route_b_smart_meter/ @SeraphicRav
/homeassistant/components/rpi_power/ @shenxn @swetoast
/tests/components/rpi_power/ @shenxn @swetoast
/homeassistant/components/rss_feed_template/ @home-assistant/core
@@ -1347,6 +1364,8 @@ build.json @home-assistant/supervisor
/tests/components/samsungtv/ @chemelli74 @epenet
/homeassistant/components/sanix/ @tomaszsluszniak
/tests/components/sanix/ @tomaszsluszniak
/homeassistant/components/satel_integra/ @Tommatheussen
/tests/components/satel_integra/ @Tommatheussen
/homeassistant/components/scene/ @home-assistant/core
/tests/components/scene/ @home-assistant/core
/homeassistant/components/schedule/ @home-assistant/core
@@ -1392,12 +1411,14 @@ build.json @home-assistant/supervisor
/tests/components/seventeentrack/ @shaiu
/homeassistant/components/sfr_box/ @epenet
/tests/components/sfr_box/ @epenet
/homeassistant/components/sftp_storage/ @maretodoric
/tests/components/sftp_storage/ @maretodoric
/homeassistant/components/sharkiq/ @JeffResc @funkybunch
/tests/components/sharkiq/ @JeffResc @funkybunch
/homeassistant/components/shell_command/ @home-assistant/core
/tests/components/shell_command/ @home-assistant/core
/homeassistant/components/shelly/ @balloob @bieniu @thecode @chemelli74 @bdraco
/tests/components/shelly/ @balloob @bieniu @thecode @chemelli74 @bdraco
/homeassistant/components/shelly/ @bieniu @thecode @chemelli74 @bdraco
/tests/components/shelly/ @bieniu @thecode @chemelli74 @bdraco
/homeassistant/components/shodan/ @fabaff
/homeassistant/components/sia/ @eavanvalkenburg
/tests/components/sia/ @eavanvalkenburg
@@ -1526,8 +1547,8 @@ build.json @home-assistant/supervisor
/tests/components/switchbee/ @jafar-atili
/homeassistant/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski @zerzhang
/tests/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski @zerzhang
/homeassistant/components/switchbot_cloud/ @SeraphicRav @laurence-presland @Gigatrappeur
/tests/components/switchbot_cloud/ @SeraphicRav @laurence-presland @Gigatrappeur
/homeassistant/components/switchbot_cloud/ @SeraphicRav @laurence-presland @Gigatrappeur @XiaoLing-git
/tests/components/switchbot_cloud/ @SeraphicRav @laurence-presland @Gigatrappeur @XiaoLing-git
/homeassistant/components/switcher_kis/ @thecode @YogevBokobza
/tests/components/switcher_kis/ @thecode @YogevBokobza
/homeassistant/components/switchmate/ @danielhiversen @qiz-li
@@ -1544,8 +1565,8 @@ build.json @home-assistant/supervisor
/tests/components/systemmonitor/ @gjohansson-ST
/homeassistant/components/tado/ @erwindouna
/tests/components/tado/ @erwindouna
/homeassistant/components/tag/ @balloob @dmulcahey
/tests/components/tag/ @balloob @dmulcahey
/homeassistant/components/tag/ @home-assistant/core
/tests/components/tag/ @home-assistant/core
/homeassistant/components/tailscale/ @frenck
/tests/components/tailscale/ @frenck
/homeassistant/components/tailwind/ @frenck
@@ -1672,6 +1693,8 @@ build.json @home-assistant/supervisor
/tests/components/uptime_kuma/ @tr4nt0r
/homeassistant/components/uptimerobot/ @ludeeus @chemelli74
/tests/components/uptimerobot/ @ludeeus @chemelli74
/homeassistant/components/usage_prediction/ @home-assistant/core
/tests/components/usage_prediction/ @home-assistant/core
/homeassistant/components/usb/ @bdraco
/tests/components/usb/ @bdraco
/homeassistant/components/usgs_earthquakes_feed/ @exxamalte
@@ -1697,10 +1720,12 @@ build.json @home-assistant/supervisor
/homeassistant/components/versasense/ @imstevenxyz
/homeassistant/components/version/ @ludeeus
/tests/components/version/ @ludeeus
/homeassistant/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja @iprak
/tests/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja @iprak
/homeassistant/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja @iprak @sapuseven
/tests/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja @iprak @sapuseven
/homeassistant/components/vicare/ @CFenner
/tests/components/vicare/ @CFenner
/homeassistant/components/victron_remote_monitoring/ @AndyTempel
/tests/components/victron_remote_monitoring/ @AndyTempel
/homeassistant/components/vilfo/ @ManneW
/tests/components/vilfo/ @ManneW
/homeassistant/components/vivotek/ @HarlemSquirrel
@@ -1710,14 +1735,14 @@ build.json @home-assistant/supervisor
/tests/components/vlc_telnet/ @rodripf @MartinHjelmare
/homeassistant/components/vodafone_station/ @paoloantinori @chemelli74
/tests/components/vodafone_station/ @paoloantinori @chemelli74
/homeassistant/components/voip/ @balloob @synesthesiam @jaminh
/tests/components/voip/ @balloob @synesthesiam @jaminh
/homeassistant/components/voip/ @synesthesiam @jaminh
/tests/components/voip/ @synesthesiam @jaminh
/homeassistant/components/volumio/ @OnFreund
/tests/components/volumio/ @OnFreund
/homeassistant/components/volvo/ @thomasddn
/tests/components/volvo/ @thomasddn
/homeassistant/components/volvooncall/ @molobrakos
/tests/components/volvooncall/ @molobrakos
/homeassistant/components/volvooncall/ @molobrakos @svrooij
/tests/components/volvooncall/ @molobrakos @svrooij
/homeassistant/components/wake_on_lan/ @ntilley905
/tests/components/wake_on_lan/ @ntilley905
/homeassistant/components/wake_word/ @home-assistant/core @synesthesiam
@@ -1782,8 +1807,8 @@ build.json @home-assistant/supervisor
/tests/components/worldclock/ @fabaff
/homeassistant/components/ws66i/ @ssaenger
/tests/components/ws66i/ @ssaenger
/homeassistant/components/wyoming/ @balloob @synesthesiam
/tests/components/wyoming/ @balloob @synesthesiam
/homeassistant/components/wyoming/ @synesthesiam
/tests/components/wyoming/ @synesthesiam
/homeassistant/components/xbox/ @hunterjm
/tests/components/xbox/ @hunterjm
/homeassistant/components/xiaomi_aqara/ @danielhiversen @syssi
+1 -2
View File
@@ -3,8 +3,7 @@ FROM mcr.microsoft.com/vscode/devcontainers/base:debian
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& apt-get update \
apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
# Additional library needed by some tests and accordingly by VScode Tests Discovery
bluez \
+5 -5
View File
@@ -1,10 +1,10 @@
image: ghcr.io/home-assistant/{arch}-homeassistant
build_from:
aarch64: ghcr.io/home-assistant/aarch64-homeassistant-base:2025.09.0
armhf: ghcr.io/home-assistant/armhf-homeassistant-base:2025.09.0
armv7: ghcr.io/home-assistant/armv7-homeassistant-base:2025.09.0
amd64: ghcr.io/home-assistant/amd64-homeassistant-base:2025.09.0
i386: ghcr.io/home-assistant/i386-homeassistant-base:2025.09.0
aarch64: ghcr.io/home-assistant/aarch64-homeassistant-base:2025.10.0
armhf: ghcr.io/home-assistant/armhf-homeassistant-base:2025.10.0
armv7: ghcr.io/home-assistant/armv7-homeassistant-base:2025.10.0
amd64: ghcr.io/home-assistant/amd64-homeassistant-base:2025.10.0
i386: ghcr.io/home-assistant/i386-homeassistant-base:2025.10.0
codenotary:
signer: notary@home-assistant.io
base_image: notary@home-assistant.io
+31 -25
View File
@@ -187,36 +187,42 @@ def main() -> int:
from . import config, runner # noqa: PLC0415
safe_mode = config.safe_mode_enabled(config_dir)
# Ensure only one instance runs per config directory
with runner.ensure_single_execution(config_dir) as single_execution_lock:
# Check if another instance is already running
if single_execution_lock.exit_code is not None:
return single_execution_lock.exit_code
runtime_conf = runner.RuntimeConfig(
config_dir=config_dir,
verbose=args.verbose,
log_rotate_days=args.log_rotate_days,
log_file=args.log_file,
log_no_color=args.log_no_color,
skip_pip=args.skip_pip,
skip_pip_packages=args.skip_pip_packages,
recovery_mode=args.recovery_mode,
debug=args.debug,
open_ui=args.open_ui,
safe_mode=safe_mode,
)
safe_mode = config.safe_mode_enabled(config_dir)
fault_file_name = os.path.join(config_dir, FAULT_LOG_FILENAME)
with open(fault_file_name, mode="a", encoding="utf8") as fault_file:
faulthandler.enable(fault_file)
exit_code = runner.run(runtime_conf)
faulthandler.disable()
runtime_conf = runner.RuntimeConfig(
config_dir=config_dir,
verbose=args.verbose,
log_rotate_days=args.log_rotate_days,
log_file=args.log_file,
log_no_color=args.log_no_color,
skip_pip=args.skip_pip,
skip_pip_packages=args.skip_pip_packages,
recovery_mode=args.recovery_mode,
debug=args.debug,
open_ui=args.open_ui,
safe_mode=safe_mode,
)
# It's possible for the fault file to disappear, so suppress obvious errors
with suppress(FileNotFoundError):
if os.path.getsize(fault_file_name) == 0:
os.remove(fault_file_name)
fault_file_name = os.path.join(config_dir, FAULT_LOG_FILENAME)
with open(fault_file_name, mode="a", encoding="utf8") as fault_file:
faulthandler.enable(fault_file)
exit_code = runner.run(runtime_conf)
faulthandler.disable()
check_threads()
# It's possible for the fault file to disappear, so suppress obvious errors
with suppress(FileNotFoundError):
if os.path.getsize(fault_file_name) == 0:
os.remove(fault_file_name)
return exit_code
check_threads()
return exit_code
if __name__ == "__main__":
+1 -1
View File
@@ -27,7 +27,7 @@ from . import (
SetupFlow,
)
REQUIREMENTS = ["pyotp==2.8.0"]
REQUIREMENTS = ["pyotp==2.9.0"]
CONF_MESSAGE = "message"
+1 -1
View File
@@ -20,7 +20,7 @@ from . import (
SetupFlow,
)
REQUIREMENTS = ["pyotp==2.8.0", "PyQRCode==1.2.1"]
REQUIREMENTS = ["pyotp==2.9.0", "PyQRCode==1.2.1"]
CONFIG_SCHEMA = MULTI_FACTOR_AUTH_MODULE_SCHEMA.extend({}, extra=vol.PREVENT_EXTRA)
+31 -21
View File
@@ -616,34 +616,44 @@ async def async_enable_logging(
),
)
# Log errors to a file if we have write access to file or config dir
logger = logging.getLogger()
logger.setLevel(logging.INFO if verbose else logging.WARNING)
if log_file is None:
err_log_path = hass.config.path(ERROR_LOG_FILENAME)
default_log_path = hass.config.path(ERROR_LOG_FILENAME)
if "SUPERVISOR" in os.environ:
_LOGGER.info("Running in Supervisor, not logging to file")
# Rename the default log file if it exists, since previous versions created
# it even on Supervisor
if os.path.isfile(default_log_path):
with contextlib.suppress(OSError):
os.rename(default_log_path, f"{default_log_path}.old")
err_log_path = None
else:
err_log_path = default_log_path
else:
err_log_path = os.path.abspath(log_file)
err_path_exists = os.path.isfile(err_log_path)
err_dir = os.path.dirname(err_log_path)
if err_log_path:
err_path_exists = os.path.isfile(err_log_path)
err_dir = os.path.dirname(err_log_path)
# Check if we can write to the error log if it exists or that
# we can create files in the containing directory if not.
if (err_path_exists and os.access(err_log_path, os.W_OK)) or (
not err_path_exists and os.access(err_dir, os.W_OK)
):
err_handler = await hass.async_add_executor_job(
_create_log_file, err_log_path, log_rotate_days
)
# Check if we can write to the error log if it exists or that
# we can create files in the containing directory if not.
if (err_path_exists and os.access(err_log_path, os.W_OK)) or (
not err_path_exists and os.access(err_dir, os.W_OK)
):
err_handler = await hass.async_add_executor_job(
_create_log_file, err_log_path, log_rotate_days
)
err_handler.setFormatter(logging.Formatter(fmt, datefmt=FORMAT_DATETIME))
err_handler.setFormatter(logging.Formatter(fmt, datefmt=FORMAT_DATETIME))
logger.addHandler(err_handler)
logger = logging.getLogger()
logger.addHandler(err_handler)
logger.setLevel(logging.INFO if verbose else logging.WARNING)
# Save the log file location for access by other components.
hass.data[DATA_LOGGING] = err_log_path
else:
_LOGGER.error("Unable to set up error log %s (access denied)", err_log_path)
# Save the log file location for access by other components.
hass.data[DATA_LOGGING] = err_log_path
else:
_LOGGER.error("Unable to set up error log %s (access denied)", err_log_path)
async_activate_log_queue_handler(hass)
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "eltako",
"name": "Eltako",
"iot_standards": ["matter"]
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
"domain": "fritzbox",
"name": "FRITZ!Box",
"name": "FRITZ!",
"integrations": ["fritz", "fritzbox", "fritzbox_callmonitor"]
}
-1
View File
@@ -6,7 +6,6 @@
"google_assistant_sdk",
"google_cloud",
"google_drive",
"google_gemini",
"google_generative_ai_conversation",
"google_mail",
"google_maps",
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "konnected",
"name": "Konnected",
"integrations": ["konnected", "konnected_esphome"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "level",
"name": "Level",
"iot_standards": ["matter"]
}
@@ -8,6 +8,7 @@ import logging
from aioacaia.acaiascale import AcaiaScale
from aioacaia.exceptions import AcaiaDeviceNotFound, AcaiaError
from homeassistant.components.bluetooth import async_get_scanner
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ADDRESS
from homeassistant.core import HomeAssistant
@@ -42,6 +43,7 @@ class AcaiaCoordinator(DataUpdateCoordinator[None]):
name=entry.title,
is_new_style_scale=entry.data[CONF_IS_NEW_STYLE_SCALE],
notify_callback=self.async_update_listeners,
scanner=async_get_scanner(hass),
)
@property
+1 -1
View File
@@ -26,5 +26,5 @@
"iot_class": "local_push",
"loggers": ["aioacaia"],
"quality_scale": "platinum",
"requirements": ["aioacaia==0.1.14"]
"requirements": ["aioacaia==0.1.17"]
}
@@ -2,21 +2,23 @@
from __future__ import annotations
import asyncio
import logging
from accuweather import AccuWeather
from homeassistant.components.sensor import DOMAIN as SENSOR_PLATFORM
from homeassistant.const import CONF_API_KEY, CONF_NAME, Platform
from homeassistant.const import CONF_API_KEY, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN, UPDATE_INTERVAL_DAILY_FORECAST, UPDATE_INTERVAL_OBSERVATION
from .const import DOMAIN
from .coordinator import (
AccuWeatherConfigEntry,
AccuWeatherDailyForecastDataUpdateCoordinator,
AccuWeatherData,
AccuWeatherHourlyForecastDataUpdateCoordinator,
AccuWeatherObservationDataUpdateCoordinator,
)
@@ -28,7 +30,6 @@ PLATFORMS = [Platform.SENSOR, Platform.WEATHER]
async def async_setup_entry(hass: HomeAssistant, entry: AccuWeatherConfigEntry) -> bool:
"""Set up AccuWeather as config entry."""
api_key: str = entry.data[CONF_API_KEY]
name: str = entry.data[CONF_NAME]
location_key = entry.unique_id
@@ -41,26 +42,28 @@ async def async_setup_entry(hass: HomeAssistant, entry: AccuWeatherConfigEntry)
hass,
entry,
accuweather,
name,
"observation",
UPDATE_INTERVAL_OBSERVATION,
)
coordinator_daily_forecast = AccuWeatherDailyForecastDataUpdateCoordinator(
hass,
entry,
accuweather,
name,
"daily forecast",
UPDATE_INTERVAL_DAILY_FORECAST,
)
coordinator_hourly_forecast = AccuWeatherHourlyForecastDataUpdateCoordinator(
hass,
entry,
accuweather,
)
await coordinator_observation.async_config_entry_first_refresh()
await coordinator_daily_forecast.async_config_entry_first_refresh()
await asyncio.gather(
coordinator_observation.async_config_entry_first_refresh(),
coordinator_daily_forecast.async_config_entry_first_refresh(),
coordinator_hourly_forecast.async_config_entry_first_refresh(),
)
entry.runtime_data = AccuWeatherData(
coordinator_observation=coordinator_observation,
coordinator_daily_forecast=coordinator_daily_forecast,
coordinator_hourly_forecast=coordinator_hourly_forecast,
)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@@ -3,6 +3,7 @@
from __future__ import annotations
from asyncio import timeout
from collections.abc import Mapping
from typing import Any
from accuweather import AccuWeather, ApiError, InvalidApiKeyError, RequestsExceededError
@@ -22,6 +23,8 @@ class AccuWeatherFlowHandler(ConfigFlow, domain=DOMAIN):
"""Config flow for AccuWeather."""
VERSION = 1
_latitude: float | None = None
_longitude: float | None = None
async def async_step_user(
self, user_input: dict[str, Any] | None = None
@@ -50,6 +53,7 @@ class AccuWeatherFlowHandler(ConfigFlow, domain=DOMAIN):
await self.async_set_unique_id(
accuweather.location_key, raise_on_progress=False
)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=user_input[CONF_NAME], data=user_input
@@ -73,3 +77,46 @@ class AccuWeatherFlowHandler(ConfigFlow, domain=DOMAIN):
),
errors=errors,
)
async def async_step_reauth(
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle configuration by re-auth."""
self._latitude = entry_data[CONF_LATITUDE]
self._longitude = entry_data[CONF_LONGITUDE]
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Dialog that informs the user that reauth is required."""
errors: dict[str, str] = {}
if user_input is not None:
websession = async_get_clientsession(self.hass)
try:
async with timeout(10):
accuweather = AccuWeather(
user_input[CONF_API_KEY],
websession,
latitude=self._latitude,
longitude=self._longitude,
)
await accuweather.async_get_location()
except (ApiError, ClientConnectorError, TimeoutError, ClientError):
errors["base"] = "cannot_connect"
except InvalidApiKeyError:
errors["base"] = "invalid_api_key"
except RequestsExceededError:
errors["base"] = "requests_exceeded"
else:
return self.async_update_reload_and_abort(
self._get_reauth_entry(), data_updates=user_input
)
return self.async_show_form(
step_id="reauth_confirm",
data_schema=vol.Schema({vol.Required(CONF_API_KEY): str}),
errors=errors,
)
@@ -69,5 +69,6 @@ POLLEN_CATEGORY_MAP = {
4: "very_high",
5: "extreme",
}
UPDATE_INTERVAL_OBSERVATION = timedelta(minutes=40)
UPDATE_INTERVAL_OBSERVATION = timedelta(minutes=10)
UPDATE_INTERVAL_DAILY_FORECAST = timedelta(hours=6)
UPDATE_INTERVAL_HOURLY_FORECAST = timedelta(hours=30)
@@ -3,6 +3,7 @@
from __future__ import annotations
from asyncio import timeout
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from datetime import timedelta
import logging
@@ -12,7 +13,9 @@ from accuweather import AccuWeather, ApiError, InvalidApiKeyError, RequestsExcee
from aiohttp.client_exceptions import ClientConnectorError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.update_coordinator import (
DataUpdateCoordinator,
@@ -20,9 +23,15 @@ from homeassistant.helpers.update_coordinator import (
UpdateFailed,
)
from .const import DOMAIN, MANUFACTURER
from .const import (
DOMAIN,
MANUFACTURER,
UPDATE_INTERVAL_DAILY_FORECAST,
UPDATE_INTERVAL_HOURLY_FORECAST,
UPDATE_INTERVAL_OBSERVATION,
)
EXCEPTIONS = (ApiError, ClientConnectorError, InvalidApiKeyError, RequestsExceededError)
EXCEPTIONS = (ApiError, ClientConnectorError, RequestsExceededError)
_LOGGER = logging.getLogger(__name__)
@@ -33,6 +42,7 @@ class AccuWeatherData:
coordinator_observation: AccuWeatherObservationDataUpdateCoordinator
coordinator_daily_forecast: AccuWeatherDailyForecastDataUpdateCoordinator
coordinator_hourly_forecast: AccuWeatherHourlyForecastDataUpdateCoordinator
type AccuWeatherConfigEntry = ConfigEntry[AccuWeatherData]
@@ -43,18 +53,18 @@ class AccuWeatherObservationDataUpdateCoordinator(
):
"""Class to manage fetching AccuWeather data API."""
config_entry: AccuWeatherConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AccuWeatherConfigEntry,
accuweather: AccuWeather,
name: str,
coordinator_type: str,
update_interval: timedelta,
) -> None:
"""Initialize."""
self.accuweather = accuweather
self.location_key = accuweather.location_key
name = config_entry.data[CONF_NAME]
if TYPE_CHECKING:
assert self.location_key is not None
@@ -65,8 +75,8 @@ class AccuWeatherObservationDataUpdateCoordinator(
hass,
_LOGGER,
config_entry=config_entry,
name=f"{name} ({coordinator_type})",
update_interval=update_interval,
name=f"{name} (observation)",
update_interval=UPDATE_INTERVAL_OBSERVATION,
)
async def _async_update_data(self) -> dict[str, Any]:
@@ -80,29 +90,39 @@ class AccuWeatherObservationDataUpdateCoordinator(
translation_key="current_conditions_update_error",
translation_placeholders={"error": repr(error)},
) from error
except InvalidApiKeyError as err:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN,
translation_key="auth_error",
translation_placeholders={"entry": self.config_entry.title},
) from err
_LOGGER.debug("Requests remaining: %d", self.accuweather.requests_remaining)
return result
class AccuWeatherDailyForecastDataUpdateCoordinator(
class AccuWeatherForecastDataUpdateCoordinator(
TimestampDataUpdateCoordinator[list[dict[str, Any]]]
):
"""Class to manage fetching AccuWeather data API."""
"""Base class for AccuWeather forecast."""
config_entry: AccuWeatherConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: AccuWeatherConfigEntry,
accuweather: AccuWeather,
name: str,
coordinator_type: str,
update_interval: timedelta,
fetch_method: Callable[..., Awaitable[list[dict[str, Any]]]],
) -> None:
"""Initialize."""
self.accuweather = accuweather
self.location_key = accuweather.location_key
self._fetch_method = fetch_method
name = config_entry.data[CONF_NAME]
if TYPE_CHECKING:
assert self.location_key is not None
@@ -118,24 +138,71 @@ class AccuWeatherDailyForecastDataUpdateCoordinator(
)
async def _async_update_data(self) -> list[dict[str, Any]]:
"""Update data via library."""
"""Update forecast data via library."""
try:
async with timeout(10):
result = await self.accuweather.async_get_daily_forecast(
language=self.hass.config.language
)
result = await self._fetch_method(language=self.hass.config.language)
except EXCEPTIONS as error:
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="forecast_update_error",
translation_placeholders={"error": repr(error)},
) from error
except InvalidApiKeyError as err:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN,
translation_key="auth_error",
translation_placeholders={"entry": self.config_entry.title},
) from err
_LOGGER.debug("Requests remaining: %d", self.accuweather.requests_remaining)
return result
class AccuWeatherDailyForecastDataUpdateCoordinator(
AccuWeatherForecastDataUpdateCoordinator
):
"""Coordinator for daily forecast."""
def __init__(
self,
hass: HomeAssistant,
config_entry: AccuWeatherConfigEntry,
accuweather: AccuWeather,
) -> None:
"""Initialize."""
super().__init__(
hass,
config_entry,
accuweather,
"daily forecast",
UPDATE_INTERVAL_DAILY_FORECAST,
fetch_method=accuweather.async_get_daily_forecast,
)
class AccuWeatherHourlyForecastDataUpdateCoordinator(
AccuWeatherForecastDataUpdateCoordinator
):
"""Coordinator for hourly forecast."""
def __init__(
self,
hass: HomeAssistant,
config_entry: AccuWeatherConfigEntry,
accuweather: AccuWeather,
) -> None:
"""Initialize."""
super().__init__(
hass,
config_entry,
accuweather,
"hourly forecast",
UPDATE_INTERVAL_HOURLY_FORECAST,
fetch_method=accuweather.async_get_hourly_forecast,
)
def _get_device_info(location_key: str, name: str) -> DeviceInfo:
"""Get device info."""
return DeviceInfo(
@@ -7,6 +7,5 @@
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["accuweather"],
"requirements": ["accuweather==4.2.1"],
"single_config_entry": true
"requirements": ["accuweather==4.2.2"]
}
@@ -7,6 +7,17 @@
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]"
},
"data_description": {
"api_key": "API key generated in the AccuWeather APIs portal."
}
},
"reauth_confirm": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]"
},
"data_description": {
"api_key": "[%key:component::accuweather::config::step::user::data_description::api_key%]"
}
}
},
@@ -17,6 +28,10 @@
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]",
"requests_exceeded": "The allowed number of requests to the AccuWeather API has been exceeded. You have to wait or change the API key."
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
},
"entity": {
@@ -236,6 +251,9 @@
}
},
"exceptions": {
"auth_error": {
"message": "Authentication failed for {entry}, please update your API key"
},
"current_conditions_update_error": {
"message": "An error occurred while retrieving weather current conditions data from the AccuWeather API: {error}"
},
@@ -45,6 +45,7 @@ from .coordinator import (
AccuWeatherConfigEntry,
AccuWeatherDailyForecastDataUpdateCoordinator,
AccuWeatherData,
AccuWeatherHourlyForecastDataUpdateCoordinator,
AccuWeatherObservationDataUpdateCoordinator,
)
@@ -64,6 +65,7 @@ class AccuWeatherEntity(
CoordinatorWeatherEntity[
AccuWeatherObservationDataUpdateCoordinator,
AccuWeatherDailyForecastDataUpdateCoordinator,
AccuWeatherHourlyForecastDataUpdateCoordinator,
]
):
"""Define an AccuWeather entity."""
@@ -76,6 +78,7 @@ class AccuWeatherEntity(
super().__init__(
observation_coordinator=accuweather_data.coordinator_observation,
daily_coordinator=accuweather_data.coordinator_daily_forecast,
hourly_coordinator=accuweather_data.coordinator_hourly_forecast,
)
self._attr_native_precipitation_unit = UnitOfPrecipitationDepth.MILLIMETERS
@@ -86,10 +89,13 @@ class AccuWeatherEntity(
self._attr_unique_id = accuweather_data.coordinator_observation.location_key
self._attr_attribution = ATTRIBUTION
self._attr_device_info = accuweather_data.coordinator_observation.device_info
self._attr_supported_features = WeatherEntityFeature.FORECAST_DAILY
self._attr_supported_features = (
WeatherEntityFeature.FORECAST_DAILY | WeatherEntityFeature.FORECAST_HOURLY
)
self.observation_coordinator = accuweather_data.coordinator_observation
self.daily_coordinator = accuweather_data.coordinator_daily_forecast
self.hourly_coordinator = accuweather_data.coordinator_hourly_forecast
@property
def condition(self) -> str | None:
@@ -207,3 +213,32 @@ class AccuWeatherEntity(
}
for item in self.daily_coordinator.data
]
@callback
def _async_forecast_hourly(self) -> list[Forecast] | None:
"""Return the hourly forecast in native units."""
return [
{
ATTR_FORECAST_TIME: utc_from_timestamp(
item["EpochDateTime"]
).isoformat(),
ATTR_FORECAST_CLOUD_COVERAGE: item["CloudCover"],
ATTR_FORECAST_HUMIDITY: item["RelativeHumidity"],
ATTR_FORECAST_NATIVE_TEMP: item["Temperature"][ATTR_VALUE],
ATTR_FORECAST_NATIVE_APPARENT_TEMP: item["RealFeelTemperature"][
ATTR_VALUE
],
ATTR_FORECAST_NATIVE_PRECIPITATION: item["TotalLiquid"][ATTR_VALUE],
ATTR_FORECAST_PRECIPITATION_PROBABILITY: item[
"PrecipitationProbability"
],
ATTR_FORECAST_NATIVE_WIND_SPEED: item["Wind"][ATTR_SPEED][ATTR_VALUE],
ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: item["WindGust"][ATTR_SPEED][
ATTR_VALUE
],
ATTR_FORECAST_UV_INDEX: item["UVIndex"],
ATTR_FORECAST_WIND_BEARING: item["Wind"][ATTR_DIRECTION]["Degrees"],
ATTR_FORECAST_CONDITION: CONDITION_MAP.get(item["WeatherIcon"]),
}
for item in self.hourly_coordinator.data
]
+9 -37
View File
@@ -3,10 +3,8 @@
import logging
from typing import Any
from aiohttp import web
import voluptuous as vol
from homeassistant.components.http import KEY_HASS, HomeAssistantView
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ENTITY_ID, CONF_DESCRIPTION, CONF_SELECTOR
from homeassistant.core import (
@@ -28,7 +26,6 @@ from .const import (
ATTR_STRUCTURE,
ATTR_TASK_NAME,
DATA_COMPONENT,
DATA_IMAGES,
DATA_PREFERENCES,
DOMAIN,
SERVICE_GENERATE_DATA,
@@ -42,7 +39,6 @@ from .task import (
GenDataTaskResult,
GenImageTask,
GenImageTaskResult,
ImageData,
async_generate_data,
async_generate_image,
)
@@ -55,7 +51,6 @@ __all__ = [
"GenDataTaskResult",
"GenImageTask",
"GenImageTaskResult",
"ImageData",
"async_generate_data",
"async_generate_image",
"async_setup",
@@ -94,10 +89,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
entity_component = EntityComponent[AITaskEntity](_LOGGER, DOMAIN, hass)
hass.data[DATA_COMPONENT] = entity_component
hass.data[DATA_PREFERENCES] = AITaskPreferences(hass)
hass.data[DATA_IMAGES] = {}
await hass.data[DATA_PREFERENCES].async_load()
async_setup_http(hass)
hass.http.register_view(ImageView)
hass.services.async_register(
DOMAIN,
SERVICE_GENERATE_DATA,
@@ -126,7 +119,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
schema=vol.Schema(
{
vol.Required(ATTR_TASK_NAME): cv.string,
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
vol.Optional(ATTR_ENTITY_ID): cv.entity_id,
vol.Required(ATTR_INSTRUCTIONS): cv.string,
vol.Optional(ATTR_ATTACHMENTS): vol.All(
cv.ensure_list, [selector.MediaSelector({"accept": ["*/*"]})]
@@ -163,9 +156,10 @@ async def async_service_generate_image(call: ServiceCall) -> ServiceResponse:
class AITaskPreferences:
"""AI Task preferences."""
KEYS = ("gen_data_entity_id",)
KEYS = ("gen_data_entity_id", "gen_image_entity_id")
gen_data_entity_id: str | None = None
gen_image_entity_id: str | None = None
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the preferences."""
@@ -179,17 +173,21 @@ class AITaskPreferences:
if data is None:
return
for key in self.KEYS:
setattr(self, key, data[key])
setattr(self, key, data.get(key))
@callback
def async_set_preferences(
self,
*,
gen_data_entity_id: str | None | UndefinedType = UNDEFINED,
gen_image_entity_id: str | None | UndefinedType = UNDEFINED,
) -> None:
"""Set the preferences."""
changed = False
for key, value in (("gen_data_entity_id", gen_data_entity_id),):
for key, value in (
("gen_data_entity_id", gen_data_entity_id),
("gen_image_entity_id", gen_image_entity_id),
):
if value is not UNDEFINED:
if getattr(self, key) != value:
setattr(self, key, value)
@@ -204,29 +202,3 @@ class AITaskPreferences:
def as_dict(self) -> dict[str, str | None]:
"""Get the current preferences."""
return {key: getattr(self, key) for key in self.KEYS}
class ImageView(HomeAssistantView):
"""View to generated images."""
url = f"/api/{DOMAIN}/images/{{filename}}"
name = f"api:{DOMAIN}/images"
requires_auth = False
async def get(
self,
request: web.Request,
filename: str,
) -> web.Response:
"""Serve image."""
hass = request.app[KEY_HASS]
image_storage = hass.data[DATA_IMAGES]
image_data = image_storage.get(filename)
if image_data is None:
raise web.HTTPNotFound
return web.Response(
body=image_data.data,
content_type=image_data.mime_type,
)
+3 -3
View File
@@ -8,19 +8,19 @@ from typing import TYPE_CHECKING, Final
from homeassistant.util.hass_dict import HassKey
if TYPE_CHECKING:
from homeassistant.components.media_source import local_source
from homeassistant.helpers.entity_component import EntityComponent
from . import AITaskPreferences
from .entity import AITaskEntity
from .task import ImageData
DOMAIN = "ai_task"
DATA_COMPONENT: HassKey[EntityComponent[AITaskEntity]] = HassKey(DOMAIN)
DATA_PREFERENCES: HassKey[AITaskPreferences] = HassKey(f"{DOMAIN}_preferences")
DATA_IMAGES: HassKey[dict[str, ImageData]] = HassKey(f"{DOMAIN}_images")
DATA_MEDIA_SOURCE: HassKey[local_source.LocalSource] = HassKey(f"{DOMAIN}_media_source")
IMAGE_DIR: Final = "image"
IMAGE_EXPIRY_TIME = 60 * 60 # 1 hour
MAX_IMAGES = 20
SERVICE_GENERATE_DATA = "generate_data"
SERVICE_GENERATE_IMAGE = "generate_image"
@@ -60,6 +60,10 @@ class AITaskEntity(RestoreEntity):
task: GenDataTask | GenImageTask,
) -> AsyncGenerator[ChatLog]:
"""Context manager used to manage the ChatLog used during an AI Task."""
user_llm_hass_api: llm.API | None = None
if isinstance(task, GenDataTask):
user_llm_hass_api = task.llm_api
# pylint: disable-next=contextmanager-generator-missing-cleanup
with (
async_get_chat_log(
@@ -77,6 +81,7 @@ class AITaskEntity(RestoreEntity):
device_id=None,
),
user_llm_prompt=DEFAULT_SYSTEM_PROMPT,
user_llm_hass_api=user_llm_hass_api,
)
chat_log.async_add_user_content(
+1
View File
@@ -37,6 +37,7 @@ def websocket_get_preferences(
{
vol.Required("type"): "ai_task/preferences/set",
vol.Optional("gen_data_entity_id"): vol.Any(str, None),
vol.Optional("gen_image_entity_id"): vol.Any(str, None),
}
)
@websocket_api.require_admin
@@ -1,7 +1,7 @@
{
"domain": "ai_task",
"name": "AI Task",
"after_dependencies": ["camera", "http"],
"after_dependencies": ["camera"],
"codeowners": ["@home-assistant/core"],
"dependencies": ["conversation", "media_source"],
"documentation": "https://www.home-assistant.io/integrations/ai_task",
@@ -2,80 +2,31 @@
from __future__ import annotations
import logging
from pathlib import Path
from homeassistant.components.media_player import BrowseError, MediaClass
from homeassistant.components.media_source import (
BrowseMediaSource,
MediaSource,
MediaSourceItem,
PlayMedia,
Unresolvable,
)
from homeassistant.components.media_source import MediaSource, local_source
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from .const import DATA_IMAGES, DOMAIN
_LOGGER = logging.getLogger(__name__)
from .const import DATA_MEDIA_SOURCE, DOMAIN, IMAGE_DIR
async def async_get_media_source(hass: HomeAssistant) -> ImageMediaSource:
"""Set up image media source."""
_LOGGER.debug("Setting up image media source")
return ImageMediaSource(hass)
async def async_get_media_source(hass: HomeAssistant) -> MediaSource:
"""Set up local media source."""
media_dirs = list(hass.config.media_dirs.values())
class ImageMediaSource(MediaSource):
"""Provide images as media sources."""
name: str = "AI Generated Images"
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize ImageMediaSource."""
super().__init__(DOMAIN)
self.hass = hass
async def async_resolve_media(self, item: MediaSourceItem) -> PlayMedia:
"""Resolve media to a url."""
image_storage = self.hass.data[DATA_IMAGES]
image = image_storage.get(item.identifier)
if image is None:
raise Unresolvable(f"Could not resolve media item: {item.identifier}")
return PlayMedia(f"/api/{DOMAIN}/images/{item.identifier}", image.mime_type)
async def async_browse_media(
self,
item: MediaSourceItem,
) -> BrowseMediaSource:
"""Return media."""
if item.identifier:
raise BrowseError("Unknown item")
image_storage = self.hass.data[DATA_IMAGES]
children = [
BrowseMediaSource(
domain=DOMAIN,
identifier=filename,
media_class=MediaClass.IMAGE,
media_content_type=image.mime_type,
title=image.title or filename,
can_play=True,
can_expand=False,
)
for filename, image in image_storage.items()
]
return BrowseMediaSource(
domain=DOMAIN,
identifier=None,
media_class=MediaClass.APP,
media_content_type="",
title="AI Generated Images",
can_play=False,
can_expand=True,
children_media_class=MediaClass.IMAGE,
children=children,
if not media_dirs:
raise HomeAssistantError(
"AI Task media source requires at least one media directory configured"
)
media_dir = Path(media_dirs[0]) / DOMAIN / IMAGE_DIR
hass.data[DATA_MEDIA_SOURCE] = source = local_source.LocalSource(
hass,
DOMAIN,
"AI Generated Images",
{IMAGE_DIR: str(media_dir)},
f"/{DOMAIN}",
)
return source
+58 -70
View File
@@ -3,8 +3,8 @@
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime
from functools import partial
from datetime import datetime, timedelta
import io
import mimetypes
from pathlib import Path
import tempfile
@@ -12,33 +12,33 @@ from typing import Any
import voluptuous as vol
from homeassistant.components import camera, conversation, media_source
from homeassistant.components import camera, conversation, image, media_source
from homeassistant.components.http.auth import async_sign_path
from homeassistant.core import HomeAssistant, ServiceResponse, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import llm
from homeassistant.helpers.chat_session import ChatSession, async_get_chat_session
from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.network import get_url
from homeassistant.util import RE_SANITIZE_FILENAME, slugify
from .const import (
DATA_COMPONENT,
DATA_IMAGES,
DATA_MEDIA_SOURCE,
DATA_PREFERENCES,
DOMAIN,
IMAGE_DIR,
IMAGE_EXPIRY_TIME,
MAX_IMAGES,
AITaskEntityFeature,
)
def _save_camera_snapshot(image: camera.Image) -> Path:
def _save_camera_snapshot(image_data: camera.Image | image.Image) -> Path:
"""Save camera snapshot to temp file."""
with tempfile.NamedTemporaryFile(
mode="wb",
suffix=mimetypes.guess_extension(image.content_type, False),
suffix=mimetypes.guess_extension(image_data.content_type, False),
delete=False,
) as temp_file:
temp_file.write(image.content)
temp_file.write(image_data.content)
return Path(temp_file.name)
@@ -54,26 +54,31 @@ async def _resolve_attachments(
for attachment in attachments or []:
media_content_id = attachment["media_content_id"]
# Special case for camera media sources
if media_content_id.startswith("media-source://camera/"):
# Extract entity_id from the media content ID
entity_id = media_content_id.removeprefix("media-source://camera/")
# Special case for certain media sources
for integration in camera, image:
media_source_prefix = f"media-source://{integration.DOMAIN}/"
if not media_content_id.startswith(media_source_prefix):
continue
# Get snapshot from camera
image = await camera.async_get_image(hass, entity_id)
# Extract entity_id from the media content ID
entity_id = media_content_id.removeprefix(media_source_prefix)
# Get snapshot from entity
image_data = await integration.async_get_image(hass, entity_id)
temp_filename = await hass.async_add_executor_job(
_save_camera_snapshot, image
_save_camera_snapshot, image_data
)
created_files.append(temp_filename)
resolved_attachments.append(
conversation.Attachment(
media_content_id=media_content_id,
mime_type=image.content_type,
mime_type=image_data.content_type,
path=temp_filename,
)
)
break
else:
# Handle regular media sources
media = await media_source.async_resolve_media(hass, media_content_id, None)
@@ -115,6 +120,7 @@ async def async_generate_data(
instructions: str,
structure: vol.Schema | None = None,
attachments: list[dict] | None = None,
llm_api: llm.API | None = None,
) -> GenDataTaskResult:
"""Run a data generation task in the AI Task integration."""
if entity_id is None:
@@ -150,37 +156,26 @@ async def async_generate_data(
instructions=instructions,
structure=structure,
attachments=resolved_attachments or None,
llm_api=llm_api,
),
)
def _cleanup_images(image_storage: dict[str, ImageData], num_to_remove: int) -> None:
"""Remove old images to keep the storage size under the limit."""
if num_to_remove <= 0:
return
if num_to_remove >= len(image_storage):
image_storage.clear()
return
sorted_images = sorted(
image_storage.items(),
key=lambda item: item[1].timestamp,
)
for filename, _ in sorted_images[:num_to_remove]:
image_storage.pop(filename, None)
async def async_generate_image(
hass: HomeAssistant,
*,
task_name: str,
entity_id: str,
entity_id: str | None = None,
instructions: str,
attachments: list[dict] | None = None,
) -> ServiceResponse:
"""Run an image generation task in the AI Task integration."""
if entity_id is None:
entity_id = hass.data[DATA_PREFERENCES].gen_image_entity_id
if entity_id is None:
raise HomeAssistantError("No entity_id provided and no preferred entity set")
entity = hass.data[DATA_COMPONENT].get_entity(entity_id)
if entity is None:
raise HomeAssistantError(f"AI Task entity {entity_id} not found")
@@ -215,32 +210,34 @@ async def async_generate_image(
if service_result.get("revised_prompt") is None:
service_result["revised_prompt"] = instructions
image_storage = hass.data[DATA_IMAGES]
if len(image_storage) + 1 > MAX_IMAGES:
_cleanup_images(image_storage, len(image_storage) + 1 - MAX_IMAGES)
source = hass.data[DATA_MEDIA_SOURCE]
current_time = datetime.now()
ext = mimetypes.guess_extension(task_result.mime_type, False) or ".png"
sanitized_task_name = RE_SANITIZE_FILENAME.sub("", slugify(task_name))
filename = f"{current_time.strftime('%Y-%m-%d_%H%M%S')}_{sanitized_task_name}{ext}"
image_storage[filename] = ImageData(
data=image_data,
timestamp=int(current_time.timestamp()),
mime_type=task_result.mime_type,
title=service_result["revised_prompt"],
image_file = ImageData(
filename=f"{current_time.strftime('%Y-%m-%d_%H%M%S')}_{sanitized_task_name}{ext}",
file=io.BytesIO(image_data),
content_type=task_result.mime_type,
)
def _purge_image(filename: str, now: datetime) -> None:
"""Remove image from storage."""
image_storage.pop(filename, None)
target_folder = media_source.MediaSourceItem.from_uri(
hass, f"media-source://{DOMAIN}/{IMAGE_DIR}", None
)
if IMAGE_EXPIRY_TIME > 0:
async_call_later(hass, IMAGE_EXPIRY_TIME, partial(_purge_image, filename))
service_result["media_source_id"] = await source.async_upload_media(
target_folder, image_file
)
service_result["url"] = get_url(hass) + f"/api/{DOMAIN}/images/{filename}"
service_result["media_source_id"] = f"media-source://{DOMAIN}/images/{filename}"
item = media_source.MediaSourceItem.from_uri(
hass, service_result["media_source_id"], None
)
service_result["url"] = async_sign_path(
hass,
(await source.async_resolve_media(item)).url,
timedelta(seconds=IMAGE_EXPIRY_TIME),
)
return service_result
@@ -261,6 +258,9 @@ class GenDataTask:
attachments: list[conversation.Attachment] | None = None
"""List of attachments to go along the instructions."""
llm_api: llm.API | None = None
"""API to provide to the LLM."""
def __str__(self) -> str:
"""Return task as a string."""
return f"<GenDataTask {self.name}: {id(self)}>"
@@ -342,20 +342,8 @@ class GenImageTaskResult:
@dataclass(slots=True)
class ImageData:
"""Image data for stored generated images."""
"""Implementation of media_source.local_source.UploadedFile protocol."""
data: bytes
"""Raw image data."""
timestamp: int
"""Timestamp when the image was generated, as a Unix timestamp."""
mime_type: str
"""MIME type of the image."""
title: str
"""Title of the image, usually the prompt used to generate it."""
def __str__(self) -> str:
"""Return image data as a string."""
return f"<ImageData {self.title}: {id(self)}>"
filename: str
file: io.IOBase
content_type: str
+39 -4
View File
@@ -2,12 +2,20 @@
from __future__ import annotations
from airos.airos8 import AirOS
from airos.airos8 import AirOS8
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
CONF_SSL,
CONF_USERNAME,
CONF_VERIFY_SSL,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DEFAULT_SSL, DEFAULT_VERIFY_SSL, SECTION_ADVANCED_SETTINGS
from .coordinator import AirOSConfigEntry, AirOSDataUpdateCoordinator
_PLATFORMS: list[Platform] = [
@@ -21,13 +29,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirOSConfigEntry) -> boo
# By default airOS 8 comes with self-signed SSL certificates,
# with no option in the web UI to change or upload a custom certificate.
session = async_get_clientsession(hass, verify_ssl=False)
session = async_get_clientsession(
hass, verify_ssl=entry.data[SECTION_ADVANCED_SETTINGS][CONF_VERIFY_SSL]
)
airos_device = AirOS(
airos_device = AirOS8(
host=entry.data[CONF_HOST],
username=entry.data[CONF_USERNAME],
password=entry.data[CONF_PASSWORD],
session=session,
use_ssl=entry.data[SECTION_ADVANCED_SETTINGS][CONF_SSL],
)
coordinator = AirOSDataUpdateCoordinator(hass, entry, airos_device)
@@ -40,6 +51,30 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirOSConfigEntry) -> boo
return True
async def async_migrate_entry(hass: HomeAssistant, entry: AirOSConfigEntry) -> bool:
"""Migrate old config entry."""
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}
advanced_data = {
CONF_SSL: DEFAULT_SSL,
CONF_VERIFY_SSL: DEFAULT_VERIFY_SSL,
}
new_data[SECTION_ADVANCED_SETTINGS] = advanced_data
hass.config_entries.async_update_entry(
entry,
data=new_data,
minor_version=2,
)
return True
async def async_unload_entry(hass: HomeAssistant, entry: AirOSConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, _PLATFORMS)
@@ -15,7 +15,7 @@ from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import AirOSConfigEntry, AirOSData, AirOSDataUpdateCoordinator
from .coordinator import AirOS8Data, AirOSConfigEntry, AirOSDataUpdateCoordinator
from .entity import AirOSEntity
_LOGGER = logging.getLogger(__name__)
@@ -27,7 +27,7 @@ PARALLEL_UPDATES = 0
class AirOSBinarySensorEntityDescription(BinarySensorEntityDescription):
"""Describe an AirOS binary sensor."""
value_fn: Callable[[AirOSData], bool]
value_fn: Callable[[AirOS8Data], bool]
BINARY_SENSORS: tuple[AirOSBinarySensorEntityDescription, ...] = (
+123 -39
View File
@@ -2,6 +2,7 @@
from __future__ import annotations
from collections.abc import Mapping
import logging
from typing import Any
@@ -14,12 +15,24 @@ from airos.exceptions import (
)
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlow, ConfigFlowResult
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
CONF_SSL,
CONF_USERNAME,
CONF_VERIFY_SSL,
)
from homeassistant.data_entry_flow import section
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.selector import (
TextSelector,
TextSelectorConfig,
TextSelectorType,
)
from .const import DOMAIN
from .coordinator import AirOS
from .const import DEFAULT_SSL, DEFAULT_VERIFY_SSL, DOMAIN, SECTION_ADVANCED_SETTINGS
from .coordinator import AirOS8
_LOGGER = logging.getLogger(__name__)
@@ -28,6 +41,15 @@ STEP_USER_DATA_SCHEMA = vol.Schema(
vol.Required(CONF_HOST): str,
vol.Required(CONF_USERNAME, default="ubnt"): str,
vol.Required(CONF_PASSWORD): str,
vol.Required(SECTION_ADVANCED_SETTINGS): section(
vol.Schema(
{
vol.Required(CONF_SSL, default=DEFAULT_SSL): bool,
vol.Required(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): bool,
}
),
{"collapsed": True},
),
}
)
@@ -36,47 +58,109 @@ class AirOSConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Ubiquiti airOS."""
VERSION = 1
MINOR_VERSION = 2
def __init__(self) -> None:
"""Initialize the config flow."""
super().__init__()
self.airos_device: AirOS8
self.errors: dict[str, str] = {}
async def async_step_user(
self,
user_input: dict[str, Any] | None = None,
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}
"""Handle the manual input of host and credentials."""
self.errors = {}
if user_input is not None:
# By default airOS 8 comes with self-signed SSL certificates,
# with no option in the web UI to change or upload a custom certificate.
session = async_get_clientsession(self.hass, verify_ssl=False)
airos_device = AirOS(
host=user_input[CONF_HOST],
username=user_input[CONF_USERNAME],
password=user_input[CONF_PASSWORD],
session=session,
)
try:
await airos_device.login()
airos_data = await airos_device.status()
except (
AirOSConnectionSetupError,
AirOSDeviceConnectionError,
):
errors["base"] = "cannot_connect"
except (AirOSConnectionAuthenticationError, AirOSDataMissingError):
errors["base"] = "invalid_auth"
except AirOSKeyDataMissingError:
errors["base"] = "key_data_missing"
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
await self.async_set_unique_id(airos_data.derived.mac)
self._abort_if_unique_id_configured()
validated_info = await self._validate_and_get_device_info(user_input)
if validated_info:
return self.async_create_entry(
title=airos_data.host.hostname, data=user_input
title=validated_info["title"],
data=validated_info["data"],
)
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=self.errors
)
async def _validate_and_get_device_info(
self, config_data: dict[str, Any]
) -> dict[str, Any] | None:
"""Validate user input with the device API."""
# By default airOS 8 comes with self-signed SSL certificates,
# with no option in the web UI to change or upload a custom certificate.
session = async_get_clientsession(
self.hass,
verify_ssl=config_data[SECTION_ADVANCED_SETTINGS][CONF_VERIFY_SSL],
)
airos_device = AirOS8(
host=config_data[CONF_HOST],
username=config_data[CONF_USERNAME],
password=config_data[CONF_PASSWORD],
session=session,
use_ssl=config_data[SECTION_ADVANCED_SETTINGS][CONF_SSL],
)
try:
await airos_device.login()
airos_data = await airos_device.status()
except (
AirOSConnectionSetupError,
AirOSDeviceConnectionError,
):
self.errors["base"] = "cannot_connect"
except (AirOSConnectionAuthenticationError, AirOSDataMissingError):
self.errors["base"] = "invalid_auth"
except AirOSKeyDataMissingError:
self.errors["base"] = "key_data_missing"
except Exception:
_LOGGER.exception("Unexpected exception during credential validation")
self.errors["base"] = "unknown"
else:
await self.async_set_unique_id(airos_data.derived.mac)
if self.source == SOURCE_REAUTH:
self._abort_if_unique_id_mismatch()
else:
self._abort_if_unique_id_configured()
return {"title": airos_data.host.hostname, "data": config_data}
return None
async def async_step_reauth(
self,
user_input: Mapping[str, Any],
) -> ConfigFlowResult:
"""Perform reauthentication upon an API authentication error."""
return await self.async_step_reauth_confirm(user_input)
async def async_step_reauth_confirm(
self,
user_input: Mapping[str, Any],
) -> ConfigFlowResult:
"""Perform reauthentication upon an API authentication error."""
self.errors = {}
if user_input:
validate_data = {**self._get_reauth_entry().data, **user_input}
if await self._validate_and_get_device_info(config_data=validate_data):
return self.async_update_reload_and_abort(
self._get_reauth_entry(),
data_updates=validate_data,
)
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
step_id="reauth_confirm",
data_schema=vol.Schema(
{
vol.Required(CONF_PASSWORD): TextSelector(
TextSelectorConfig(
type=TextSelectorType.PASSWORD,
autocomplete="current-password",
)
),
}
),
errors=self.errors,
)
+5
View File
@@ -7,3 +7,8 @@ DOMAIN = "airos"
SCAN_INTERVAL = timedelta(minutes=1)
MANUFACTURER = "Ubiquiti"
DEFAULT_VERIFY_SSL = False
DEFAULT_SSL = True
SECTION_ADVANCED_SETTINGS = "advanced_settings"
@@ -4,7 +4,7 @@ from __future__ import annotations
import logging
from airos.airos8 import AirOS, AirOSData
from airos.airos8 import AirOS8, AirOS8Data
from airos.exceptions import (
AirOSConnectionAuthenticationError,
AirOSConnectionSetupError,
@@ -14,7 +14,7 @@ from airos.exceptions import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryError
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN, SCAN_INTERVAL
@@ -24,13 +24,13 @@ _LOGGER = logging.getLogger(__name__)
type AirOSConfigEntry = ConfigEntry[AirOSDataUpdateCoordinator]
class AirOSDataUpdateCoordinator(DataUpdateCoordinator[AirOSData]):
class AirOSDataUpdateCoordinator(DataUpdateCoordinator[AirOS8Data]):
"""Class to manage fetching AirOS data from single endpoint."""
config_entry: AirOSConfigEntry
def __init__(
self, hass: HomeAssistant, config_entry: AirOSConfigEntry, airos_device: AirOS
self, hass: HomeAssistant, config_entry: AirOSConfigEntry, airos_device: AirOS8
) -> None:
"""Initialize the coordinator."""
self.airos_device = airos_device
@@ -42,14 +42,14 @@ class AirOSDataUpdateCoordinator(DataUpdateCoordinator[AirOSData]):
update_interval=SCAN_INTERVAL,
)
async def _async_update_data(self) -> AirOSData:
async def _async_update_data(self) -> AirOS8Data:
"""Fetch data from AirOS."""
try:
await self.airos_device.login()
return await self.airos_device.status()
except (AirOSConnectionAuthenticationError,) as err:
except AirOSConnectionAuthenticationError as err:
_LOGGER.exception("Error authenticating with airOS device")
raise ConfigEntryError(
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN, translation_key="invalid_auth"
) from err
except (
+8 -3
View File
@@ -2,11 +2,11 @@
from __future__ import annotations
from homeassistant.const import CONF_HOST
from homeassistant.const import CONF_HOST, CONF_SSL
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, MANUFACTURER
from .const import DOMAIN, MANUFACTURER, SECTION_ADVANCED_SETTINGS
from .coordinator import AirOSDataUpdateCoordinator
@@ -20,9 +20,14 @@ class AirOSEntity(CoordinatorEntity[AirOSDataUpdateCoordinator]):
super().__init__(coordinator)
airos_data = self.coordinator.data
url_schema = (
"https"
if coordinator.config_entry.data[SECTION_ADVANCED_SETTINGS][CONF_SSL]
else "http"
)
configuration_url: str | None = (
f"https://{coordinator.config_entry.data[CONF_HOST]}"
f"{url_schema}://{coordinator.config_entry.data[CONF_HOST]}"
)
self._attr_device_info = DeviceInfo(
+1 -1
View File
@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/airos",
"iot_class": "local_polling",
"quality_scale": "bronze",
"requirements": ["airos==0.4.4"]
"requirements": ["airos==0.5.4"]
}
+2 -2
View File
@@ -26,7 +26,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
from .coordinator import AirOSConfigEntry, AirOSData, AirOSDataUpdateCoordinator
from .coordinator import AirOS8Data, AirOSConfigEntry, AirOSDataUpdateCoordinator
from .entity import AirOSEntity
_LOGGER = logging.getLogger(__name__)
@@ -42,7 +42,7 @@ PARALLEL_UPDATES = 0
class AirOSSensorEntityDescription(SensorEntityDescription):
"""Describe an AirOS sensor."""
value_fn: Callable[[AirOSData], StateType]
value_fn: Callable[[AirOS8Data], StateType]
SENSORS: tuple[AirOSSensorEntityDescription, ...] = (
+23 -1
View File
@@ -2,6 +2,14 @@
"config": {
"flow_title": "Ubiquiti airOS device",
"step": {
"reauth_confirm": {
"data": {
"password": "[%key:common::config_flow::data::password%]"
},
"data_description": {
"password": "[%key:component::airos::config::step::user::data_description::password%]"
}
},
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
@@ -12,6 +20,18 @@
"host": "IP address or hostname of the airOS device",
"username": "Administrator username for the airOS device, normally 'ubnt'",
"password": "Password configured through the UISP app or web interface"
},
"sections": {
"advanced_settings": {
"data": {
"ssl": "Use HTTPS",
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
},
"data_description": {
"ssl": "Whether the connection should be encrypted (required for most devices)",
"verify_ssl": "Whether the certificate should be verified when using HTTPS. This should be off for self-signed certificates"
}
}
}
}
},
@@ -22,7 +42,9 @@
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"unique_id_mismatch": "Re-authentication should be used for the same device not a new one"
}
},
"entity": {
@@ -23,6 +23,10 @@ STEP_USER_DATA_SCHEMA = vol.Schema(
}
)
URL_API_INTEGRATION = {
"url": "https://dashboard.airthings.com/integrations/api-integration"
}
class AirthingsConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Airthings."""
@@ -37,11 +41,7 @@ class AirthingsConfigFlow(ConfigFlow, domain=DOMAIN):
return self.async_show_form(
step_id="user",
data_schema=STEP_USER_DATA_SCHEMA,
description_placeholders={
"url": (
"https://dashboard.airthings.com/integrations/api-integration"
),
},
description_placeholders=URL_API_INTEGRATION,
)
errors = {}
@@ -65,5 +65,8 @@ class AirthingsConfigFlow(ConfigFlow, domain=DOMAIN):
return self.async_create_entry(title="Airthings", data=user_input)
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
step_id="user",
data_schema=STEP_USER_DATA_SCHEMA,
errors=errors,
description_placeholders=URL_API_INTEGRATION,
)
@@ -4,9 +4,9 @@
"user": {
"data": {
"id": "ID",
"secret": "Secret",
"description": "Login at {url} to find your credentials"
}
"secret": "Secret"
},
"description": "Log in at {url} to find your credentials"
}
},
"error": {
@@ -171,7 +171,7 @@ class AirthingsConfigFlow(ConfigFlow, domain=DOMAIN):
return self.async_abort(reason="no_devices_found")
titles = {
address: discovery.device.name
address: get_name(discovery.device)
for (address, discovery) in self._discovered_devices.items()
}
return self.async_show_form(
@@ -114,6 +114,8 @@ SENSORS_MAPPING_TEMPLATE: dict[str, SensorEntityDescription] = {
),
}
PARALLEL_UPDATES = 0
@callback
def async_migrate(hass: HomeAssistant, address: str, sensor_name: str) -> None:
@@ -6,6 +6,9 @@
"description": "[%key:component::bluetooth::config::step::user::description%]",
"data": {
"address": "[%key:common::config_flow::data::device%]"
},
"data_description": {
"address": "The Airthings devices discovered via Bluetooth."
}
},
"bluetooth_confirm": {
@@ -2,17 +2,14 @@
from airtouch4pyapi import AirTouch
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from .coordinator import AirtouchDataUpdateCoordinator
from .coordinator import AirTouch4ConfigEntry, AirtouchDataUpdateCoordinator
PLATFORMS = [Platform.CLIMATE]
type AirTouch4ConfigEntry = ConfigEntry[AirtouchDataUpdateCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: AirTouch4ConfigEntry) -> bool:
"""Set up AirTouch4 from a config entry."""
@@ -22,7 +19,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirTouch4ConfigEntry) ->
info = airtouch.GetAcs()
if not info:
raise ConfigEntryNotReady
coordinator = AirtouchDataUpdateCoordinator(hass, airtouch)
coordinator = AirtouchDataUpdateCoordinator(hass, entry, airtouch)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
@@ -2,26 +2,34 @@
import logging
from airtouch4pyapi import AirTouch
from airtouch4pyapi.airtouch import AirTouchStatus
from homeassistant.components.climate import SCAN_INTERVAL
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
type AirTouch4ConfigEntry = ConfigEntry[AirtouchDataUpdateCoordinator]
class AirtouchDataUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching Airtouch data."""
def __init__(self, hass, airtouch):
def __init__(
self, hass: HomeAssistant, entry: AirTouch4ConfigEntry, airtouch: AirTouch
) -> None:
"""Initialize global Airtouch data updater."""
self.airtouch = airtouch
super().__init__(
hass,
_LOGGER,
config_entry=entry,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)
@@ -11,5 +11,5 @@
"documentation": "https://www.home-assistant.io/integrations/airzone",
"iot_class": "local_polling",
"loggers": ["aioairzone"],
"requirements": ["aioairzone==1.0.0"]
"requirements": ["aioairzone==1.0.1"]
}
+19 -1
View File
@@ -6,17 +6,19 @@ from collections.abc import Callable
from dataclasses import dataclass
from typing import Any, Final
from aioairzone.common import GrilleAngle, OperationMode, SleepTimeout
from aioairzone.common import GrilleAngle, OperationMode, QAdapt, SleepTimeout
from aioairzone.const import (
API_COLD_ANGLE,
API_HEAT_ANGLE,
API_MODE,
API_Q_ADAPT,
API_SLEEP,
AZD_COLD_ANGLE,
AZD_HEAT_ANGLE,
AZD_MASTER,
AZD_MODE,
AZD_MODES,
AZD_Q_ADAPT,
AZD_SLEEP,
AZD_ZONES,
)
@@ -65,6 +67,14 @@ SLEEP_DICT: Final[dict[str, int]] = {
"90m": SleepTimeout.SLEEP_90,
}
Q_ADAPT_DICT: Final[dict[str, int]] = {
"standard": QAdapt.STANDARD,
"power": QAdapt.POWER,
"silence": QAdapt.SILENCE,
"minimum": QAdapt.MINIMUM,
"maximum": QAdapt.MAXIMUM,
}
def main_zone_options(
zone_data: dict[str, Any],
@@ -83,6 +93,14 @@ MAIN_ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
options_fn=main_zone_options,
translation_key="modes",
),
AirzoneSelectDescription(
api_param=API_Q_ADAPT,
entity_category=EntityCategory.CONFIG,
key=AZD_Q_ADAPT,
options=list(Q_ADAPT_DICT),
options_dict=Q_ADAPT_DICT,
translation_key="q_adapt",
),
)
@@ -63,6 +63,16 @@
"stop": "Stop"
}
},
"q_adapt": {
"name": "Q-Adapt",
"state": {
"standard": "Standard",
"power": "Power",
"silence": "Silence",
"minimum": "Minimum",
"maximum": "Maximum"
}
},
"sleep_times": {
"name": "Sleep",
"state": {
@@ -22,6 +22,17 @@ class OAuth2FlowHandler(
VERSION = CONFIG_FLOW_VERSION
MINOR_VERSION = CONFIG_FLOW_MINOR_VERSION
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Check we have the cloud integration set up."""
if "cloud" not in self.hass.config.components:
return self.async_abort(
reason="cloud_not_enabled",
description_placeholders={"default_config": "default_config"},
)
return await super().async_step_user(user_input)
async def async_step_reauth(
self, user_input: Mapping[str, Any]
) -> ConfigFlowResult:
@@ -4,6 +4,11 @@
"codeowners": ["@swcloudgenie"],
"config_flow": true,
"dependencies": ["application_credentials"],
"dhcp": [
{
"hostname": "gdocntl-*"
}
],
"documentation": "https://www.home-assistant.io/integrations/aladdin_connect",
"integration_type": "hub",
"iot_class": "cloud_polling",
@@ -7,6 +7,9 @@
"reauth_confirm": {
"title": "[%key:common::config_flow::title::reauth%]",
"description": "Aladdin Connect needs to re-authenticate your account"
},
"oauth_discovery": {
"description": "Home Assistant has found an Aladdin Connect device on your network. Press **Submit** to continue setting up Aladdin Connect."
}
},
"abort": {
@@ -21,7 +24,8 @@
"no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]",
"user_rejected_authorize": "[%key:common::config_flow::abort::oauth2_user_rejected_authorize%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"wrong_account": "You are authenticated with a different account than the one set up. Please authenticate with the configured account."
"wrong_account": "You are authenticated with a different account than the one set up. Please authenticate with the configured account.",
"cloud_not_enabled": "Please make sure you run Home Assistant with `{default_config}` enabled in your configuration.yaml."
},
"create_entry": {
"default": "[%key:common::config_flow::create_entry::authenticated%]"
@@ -61,7 +61,7 @@ ALARM_SERVICE_SCHEMA: Final = make_entity_service_schema(
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Track states and offer events for sensors."""
"""Set up the alarm control panel component."""
component = hass.data[DATA_COMPONENT] = EntityComponent[AlarmControlPanelEntity](
_LOGGER, DOMAIN, hass, SCAN_INTERVAL
)
+8 -2
View File
@@ -1,4 +1,7 @@
"""Support for repeating alerts when conditions are met."""
"""Support for repeating alerts when conditions are met.
DEVELOPMENT OF THE ALERT INTEGRATION IS FROZEN.
"""
from __future__ import annotations
@@ -63,7 +66,10 @@ CONFIG_SCHEMA = vol.Schema(
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Alert component."""
"""Set up the Alert component.
DEVELOPMENT OF THE ALERT INTEGRATION IS FROZEN.
"""
component = EntityComponent[AlertEntity](LOGGER, DOMAIN, hass)
entities: list[AlertEntity] = []
+8 -2
View File
@@ -1,4 +1,7 @@
"""Support for repeating alerts when conditions are met."""
"""Support for repeating alerts when conditions are met.
DEVELOPMENT OF THE ALERT INTEGRATION IS FROZEN.
"""
from __future__ import annotations
@@ -27,7 +30,10 @@ from .const import DOMAIN, LOGGER
class AlertEntity(Entity):
"""Representation of an alert."""
"""Representation of an alert.
DEVELOPMENT OF THE ALERT INTEGRATION IS FROZEN.
"""
_attr_should_poll = False
@@ -1,4 +1,7 @@
"""Reproduce an Alert state."""
"""Reproduce an Alert state.
DEVELOPMENT OF THE ALERT INTEGRATION IS FROZEN.
"""
from __future__ import annotations
@@ -10,6 +10,7 @@ from aioamazondevices.api import AmazonDevice
from aioamazondevices.const import SENSOR_STATE_OFF
from homeassistant.components.binary_sensor import (
DOMAIN as BINARY_SENSOR_DOMAIN,
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
@@ -20,6 +21,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import AmazonConfigEntry
from .entity import AmazonEntity
from .utils import async_update_unique_id
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
@@ -31,6 +33,7 @@ class AmazonBinarySensorEntityDescription(BinarySensorEntityDescription):
is_on_fn: Callable[[AmazonDevice, str], bool]
is_supported: Callable[[AmazonDevice, str], bool] = lambda device, key: True
is_available_fn: Callable[[AmazonDevice, str], bool] = lambda device, key: True
BINARY_SENSORS: Final = (
@@ -41,46 +44,15 @@ BINARY_SENSORS: Final = (
is_on_fn=lambda device, _: device.online,
),
AmazonBinarySensorEntityDescription(
key="bluetooth",
entity_category=EntityCategory.DIAGNOSTIC,
translation_key="bluetooth",
is_on_fn=lambda device, _: device.bluetooth_state,
),
AmazonBinarySensorEntityDescription(
key="babyCryDetectionState",
translation_key="baby_cry_detection",
is_on_fn=lambda device, key: (device.sensors[key].value != SENSOR_STATE_OFF),
is_supported=lambda device, key: device.sensors.get(key) is not None,
),
AmazonBinarySensorEntityDescription(
key="beepingApplianceDetectionState",
translation_key="beeping_appliance_detection",
is_on_fn=lambda device, key: (device.sensors[key].value != SENSOR_STATE_OFF),
is_supported=lambda device, key: device.sensors.get(key) is not None,
),
AmazonBinarySensorEntityDescription(
key="coughDetectionState",
translation_key="cough_detection",
is_on_fn=lambda device, key: (device.sensors[key].value != SENSOR_STATE_OFF),
is_supported=lambda device, key: device.sensors.get(key) is not None,
),
AmazonBinarySensorEntityDescription(
key="dogBarkDetectionState",
translation_key="dog_bark_detection",
is_on_fn=lambda device, key: (device.sensors[key].value != SENSOR_STATE_OFF),
is_supported=lambda device, key: device.sensors.get(key) is not None,
),
AmazonBinarySensorEntityDescription(
key="humanPresenceDetectionState",
key="detectionState",
device_class=BinarySensorDeviceClass.MOTION,
is_on_fn=lambda device, key: (device.sensors[key].value != SENSOR_STATE_OFF),
is_supported=lambda device, key: device.sensors.get(key) is not None,
),
AmazonBinarySensorEntityDescription(
key="waterSoundsDetectionState",
translation_key="water_sounds_detection",
is_on_fn=lambda device, key: (device.sensors[key].value != SENSOR_STATE_OFF),
is_on_fn=lambda device, key: bool(
device.sensors[key].value != SENSOR_STATE_OFF
),
is_supported=lambda device, key: device.sensors.get(key) is not None,
is_available_fn=lambda device, key: (
device.online and device.sensors[key].error is False
),
),
)
@@ -94,13 +66,34 @@ async def async_setup_entry(
coordinator = entry.runtime_data
async_add_entities(
AmazonBinarySensorEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in BINARY_SENSORS
for serial_num in coordinator.data
if sensor_desc.is_supported(coordinator.data[serial_num], sensor_desc.key)
# Replace unique id for "detectionState" binary sensor
await async_update_unique_id(
hass,
coordinator,
BINARY_SENSOR_DOMAIN,
"humanPresenceDetectionState",
"detectionState",
)
known_devices: set[str] = set()
def _check_device() -> None:
current_devices = set(coordinator.data)
new_devices = current_devices - known_devices
if new_devices:
known_devices.update(new_devices)
async_add_entities(
AmazonBinarySensorEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in BINARY_SENSORS
for serial_num in new_devices
if sensor_desc.is_supported(
coordinator.data[serial_num], sensor_desc.key
)
)
_check_device()
entry.async_on_unload(coordinator.async_add_listener(_check_device))
class AmazonBinarySensorEntity(AmazonEntity, BinarySensorEntity):
"""Binary sensor device."""
@@ -113,3 +106,13 @@ class AmazonBinarySensorEntity(AmazonEntity, BinarySensorEntity):
return self.entity_description.is_on_fn(
self.device, self.entity_description.key
)
@property
def available(self) -> bool:
"""Return if entity is available."""
return (
self.entity_description.is_available_fn(
self.device, self.entity_description.key
)
and super().available
)
@@ -64,7 +64,7 @@ class AmazonDevicesConfigFlow(ConfigFlow, domain=DOMAIN):
data = await validate_input(self.hass, user_input)
except CannotConnect:
errors["base"] = "cannot_connect"
except (CannotAuthenticate, TypeError):
except CannotAuthenticate:
errors["base"] = "invalid_auth"
except CannotRetrieveData:
errors["base"] = "cannot_retrieve_data"
@@ -112,7 +112,7 @@ class AmazonDevicesConfigFlow(ConfigFlow, domain=DOMAIN):
)
except CannotConnect:
errors["base"] = "cannot_connect"
except (CannotAuthenticate, TypeError):
except CannotAuthenticate:
errors["base"] = "invalid_auth"
except CannotRetrieveData:
errors["base"] = "cannot_retrieve_data"
@@ -14,6 +14,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import _LOGGER, CONF_LOGIN_DATA, DOMAIN
@@ -48,12 +49,13 @@ class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
entry.data[CONF_PASSWORD],
entry.data[CONF_LOGIN_DATA],
)
self.previous_devices: set[str] = set()
async def _async_update_data(self) -> dict[str, AmazonDevice]:
"""Update device data."""
try:
await self.api.login_mode_stored_data()
return await self.api.get_devices_data()
data = await self.api.get_devices_data()
except CannotConnect as err:
raise UpdateFailed(
translation_domain=DOMAIN,
@@ -66,9 +68,37 @@ class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
translation_key="cannot_retrieve_data_with_error",
translation_placeholders={"error": repr(err)},
) from err
except (CannotAuthenticate, TypeError) as err:
except CannotAuthenticate as err:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN,
translation_key="invalid_auth",
translation_placeholders={"error": repr(err)},
) from err
else:
current_devices = set(data.keys())
if stale_devices := self.previous_devices - current_devices:
await self._async_remove_device_stale(stale_devices)
self.previous_devices = current_devices
return data
async def _async_remove_device_stale(
self,
stale_devices: set[str],
) -> None:
"""Remove stale device."""
device_registry = dr.async_get(self.hass)
for serial_num in stale_devices:
_LOGGER.debug(
"Detected change in devices: serial %s removed",
serial_num,
)
device = device_registry.async_get_device(
identifiers={(DOMAIN, serial_num)}
)
if device:
device_registry.async_update_device(
device_id=device.id,
remove_config_entry_id=self.config_entry.entry_id,
)
@@ -60,7 +60,5 @@ def build_device_data(device: AmazonDevice) -> dict[str, Any]:
"online": device.online,
"serial number": device.serial_number,
"software version": device.software_version,
"do not disturb": device.do_not_disturb,
"response style": device.response_style,
"bluetooth state": device.bluetooth_state,
"sensors": device.sensors,
}
@@ -1,44 +1,4 @@
{
"entity": {
"binary_sensor": {
"bluetooth": {
"default": "mdi:bluetooth-off",
"state": {
"on": "mdi:bluetooth"
}
},
"baby_cry_detection": {
"default": "mdi:account-voice-off",
"state": {
"on": "mdi:account-voice"
}
},
"beeping_appliance_detection": {
"default": "mdi:bell-off",
"state": {
"on": "mdi:bell-ring"
}
},
"cough_detection": {
"default": "mdi:blur-off",
"state": {
"on": "mdi:blur"
}
},
"dog_bark_detection": {
"default": "mdi:dog-side-off",
"state": {
"on": "mdi:dog-side"
}
},
"water_sounds_detection": {
"default": "mdi:water-pump-off",
"state": {
"on": "mdi:water-pump"
}
}
}
},
"services": {
"send_sound": {
"service": "mdi:cast-audio"
@@ -7,6 +7,6 @@
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["aioamazondevices"],
"quality_scale": "silver",
"requirements": ["aioamazondevices==6.0.0"]
"quality_scale": "platinum",
"requirements": ["aioamazondevices==6.2.7"]
}
@@ -57,13 +57,23 @@ async def async_setup_entry(
coordinator = entry.runtime_data
async_add_entities(
AmazonNotifyEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in NOTIFY
for serial_num in coordinator.data
if sensor_desc.subkey in coordinator.data[serial_num].capabilities
and sensor_desc.is_supported(coordinator.data[serial_num])
)
known_devices: set[str] = set()
def _check_device() -> None:
current_devices = set(coordinator.data)
new_devices = current_devices - known_devices
if new_devices:
known_devices.update(new_devices)
async_add_entities(
AmazonNotifyEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in NOTIFY
for serial_num in new_devices
if sensor_desc.subkey in coordinator.data[serial_num].capabilities
and sensor_desc.is_supported(coordinator.data[serial_num])
)
_check_device()
entry.async_on_unload(coordinator.async_add_listener(_check_device))
class AmazonNotifyEntity(AmazonEntity, NotifyEntity):
@@ -53,7 +53,7 @@ rules:
docs-supported-functions: done
docs-troubleshooting: done
docs-use-cases: done
dynamic-devices: todo
dynamic-devices: done
entity-category: done
entity-device-class: done
entity-disabled-by-default: done
@@ -64,9 +64,7 @@ rules:
repair-issues:
status: exempt
comment: no known use cases for repair issues or flows, yet
stale-devices:
status: todo
comment: automate the cleanup process
stale-devices: done
# Platinum
async-dependency: done
@@ -31,6 +31,9 @@ class AmazonSensorEntityDescription(SensorEntityDescription):
"""Amazon Devices sensor entity description."""
native_unit_of_measurement_fn: Callable[[AmazonDevice, str], str] | None = None
is_available_fn: Callable[[AmazonDevice, str], bool] = lambda device, key: (
device.online and device.sensors[key].error is False
)
SENSORS: Final = (
@@ -62,12 +65,22 @@ async def async_setup_entry(
coordinator = entry.runtime_data
async_add_entities(
AmazonSensorEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in SENSORS
for serial_num in coordinator.data
if coordinator.data[serial_num].sensors.get(sensor_desc.key) is not None
)
known_devices: set[str] = set()
def _check_device() -> None:
current_devices = set(coordinator.data)
new_devices = current_devices - known_devices
if new_devices:
known_devices.update(new_devices)
async_add_entities(
AmazonSensorEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in SENSORS
for serial_num in new_devices
if coordinator.data[serial_num].sensors.get(sensor_desc.key) is not None
)
_check_device()
entry.async_on_unload(coordinator.async_add_listener(_check_device))
class AmazonSensorEntity(AmazonEntity, SensorEntity):
@@ -89,3 +102,13 @@ class AmazonSensorEntity(AmazonEntity, SensorEntity):
def native_value(self) -> StateType:
"""Return the state of the sensor."""
return self.device.sensors[self.entity_description.key].value
@property
def available(self) -> bool:
"""Return if entity is available."""
return (
self.entity_description.is_available_fn(
self.device, self.entity_description.key
)
and super().available
)
@@ -58,26 +58,6 @@
}
},
"entity": {
"binary_sensor": {
"bluetooth": {
"name": "Bluetooth"
},
"baby_cry_detection": {
"name": "Baby crying"
},
"beeping_appliance_detection": {
"name": "Beeping appliance"
},
"cough_detection": {
"name": "Coughing"
},
"dog_bark_detection": {
"name": "Dog barking"
},
"water_sounds_detection": {
"name": "Water sounds"
}
},
"notify": {
"speak": {
"name": "Speak"
@@ -104,10 +84,6 @@
"sound": {
"name": "Alexa Skill sound file",
"description": "The sound file to play."
},
"sound_variant": {
"name": "Sound variant",
"description": "The variant of the sound to play."
}
}
},
@@ -8,13 +8,17 @@ from typing import TYPE_CHECKING, Any, Final
from aioamazondevices.api import AmazonDevice
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.components.switch import (
DOMAIN as SWITCH_DOMAIN,
SwitchEntity,
SwitchEntityDescription,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import AmazonConfigEntry
from .entity import AmazonEntity
from .utils import alexa_api_call
from .utils import alexa_api_call, async_update_unique_id
PARALLEL_UPDATES = 1
@@ -24,16 +28,17 @@ class AmazonSwitchEntityDescription(SwitchEntityDescription):
"""Alexa Devices switch entity description."""
is_on_fn: Callable[[AmazonDevice], bool]
subkey: str
is_available_fn: Callable[[AmazonDevice, str], bool] = lambda device, key: (
device.online and device.sensors[key].error is False
)
method: str
SWITCHES: Final = (
AmazonSwitchEntityDescription(
key="do_not_disturb",
subkey="AUDIO_PLAYER",
key="dnd",
translation_key="do_not_disturb",
is_on_fn=lambda _device: _device.do_not_disturb,
is_on_fn=lambda device: bool(device.sensors["dnd"].value),
method="set_do_not_disturb",
),
)
@@ -48,13 +53,28 @@ async def async_setup_entry(
coordinator = entry.runtime_data
async_add_entities(
AmazonSwitchEntity(coordinator, serial_num, switch_desc)
for switch_desc in SWITCHES
for serial_num in coordinator.data
if switch_desc.subkey in coordinator.data[serial_num].capabilities
# Replace unique id for "DND" switch and remove from Speaker Group
await async_update_unique_id(
hass, coordinator, SWITCH_DOMAIN, "do_not_disturb", "dnd"
)
known_devices: set[str] = set()
def _check_device() -> None:
current_devices = set(coordinator.data)
new_devices = current_devices - known_devices
if new_devices:
known_devices.update(new_devices)
async_add_entities(
AmazonSwitchEntity(coordinator, serial_num, switch_desc)
for switch_desc in SWITCHES
for serial_num in new_devices
if switch_desc.key in coordinator.data[serial_num].sensors
)
_check_device()
entry.async_on_unload(coordinator.async_add_listener(_check_device))
class AmazonSwitchEntity(AmazonEntity, SwitchEntity):
"""Switch device."""
@@ -84,3 +104,13 @@ class AmazonSwitchEntity(AmazonEntity, SwitchEntity):
def is_on(self) -> bool:
"""Return True if switch is on."""
return self.entity_description.is_on_fn(self.device)
@property
def available(self) -> bool:
"""Return if entity is available."""
return (
self.entity_description.is_available_fn(
self.device, self.entity_description.key
)
and super().available
)
@@ -6,9 +6,12 @@ from typing import Any, Concatenate
from aioamazondevices.exceptions import CannotConnect, CannotRetrieveData
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.entity_registry as er
from .const import DOMAIN
from .const import _LOGGER, DOMAIN
from .coordinator import AmazonDevicesCoordinator
from .entity import AmazonEntity
@@ -38,3 +41,23 @@ def alexa_api_call[_T: AmazonEntity, **_P](
) from err
return cmd_wrapper
async def async_update_unique_id(
hass: HomeAssistant,
coordinator: AmazonDevicesCoordinator,
domain: str,
old_key: str,
new_key: str,
) -> None:
"""Update unique id for entities created with old format."""
entity_registry = er.async_get(hass)
for serial_num in coordinator.data:
unique_id = f"{serial_num}-{old_key}"
if entity_id := entity_registry.async_get_entity_id(domain, DOMAIN, unique_id):
_LOGGER.debug("Updating unique_id for %s", entity_id)
new_unique_id = unique_id.replace(old_key, new_key)
# Update the registry with the new unique_id
entity_registry.async_update_entity(entity_id, new_unique_id=new_unique_id)
+1 -1
View File
@@ -41,7 +41,7 @@ def async_setup_services(hass: HomeAssistant) -> None:
if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_NONE:
return []
call_ids = await async_extract_entity_ids(hass, call)
call_ids = await async_extract_entity_ids(call)
entity_ids = []
for entity_id in hass.data[DATA_AMCREST][CAMERAS]:
if entity_id not in call_ids:
+16 -1
View File
@@ -12,10 +12,25 @@ from homeassistant.helpers.event import async_call_later, async_track_time_inter
from homeassistant.helpers.typing import ConfigType
from homeassistant.util.hass_dict import HassKey
from .analytics import Analytics
from .analytics import (
Analytics,
AnalyticsInput,
AnalyticsModifications,
DeviceAnalyticsModifications,
EntityAnalyticsModifications,
async_devices_payload,
)
from .const import ATTR_ONBOARDED, ATTR_PREFERENCES, DOMAIN, INTERVAL, PREFERENCE_SCHEMA
from .http import AnalyticsDevicesView
__all__ = [
"AnalyticsInput",
"AnalyticsModifications",
"DeviceAnalyticsModifications",
"EntityAnalyticsModifications",
"async_devices_payload",
]
CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN)
DATA_COMPONENT: HassKey[Analytics] = HassKey(DOMAIN)
+308 -44
View File
@@ -4,9 +4,10 @@ from __future__ import annotations
import asyncio
from asyncio import timeout
from dataclasses import asdict as dataclass_asdict, dataclass
from collections.abc import Awaitable, Callable, Iterable, Mapping
from dataclasses import asdict as dataclass_asdict, dataclass, field
from datetime import datetime
from typing import Any
from typing import Any, Protocol
import uuid
import aiohttp
@@ -24,17 +25,25 @@ from homeassistant.components.recorder import (
get_instance as get_recorder_instance,
)
from homeassistant.config_entries import SOURCE_IGNORE
from homeassistant.const import ATTR_DOMAIN, BASE_PLATFORMS, __version__ as HA_VERSION
from homeassistant.const import (
ATTR_ASSUMED_STATE,
ATTR_DOMAIN,
BASE_PLATFORMS,
__version__ as HA_VERSION,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.hassio import is_hassio
from homeassistant.helpers.singleton import singleton
from homeassistant.helpers.storage import Store
from homeassistant.helpers.system_info import async_get_system_info
from homeassistant.helpers.typing import UNDEFINED
from homeassistant.loader import (
Integration,
IntegrationNotFound,
async_get_integration,
async_get_integrations,
)
from homeassistant.setup import async_get_loaded_integrations
@@ -70,12 +79,115 @@ from .const import (
ATTR_USER_COUNT,
ATTR_UUID,
ATTR_VERSION,
DOMAIN,
LOGGER,
PREFERENCE_SCHEMA,
STORAGE_KEY,
STORAGE_VERSION,
)
DATA_ANALYTICS_MODIFIERS = "analytics_modifiers"
type AnalyticsModifier = Callable[
[HomeAssistant, AnalyticsInput], Awaitable[AnalyticsModifications]
]
@singleton(DATA_ANALYTICS_MODIFIERS)
def _async_get_modifiers(
hass: HomeAssistant,
) -> dict[str, AnalyticsModifier | None]:
"""Return the analytics modifiers."""
return {}
@dataclass
class AnalyticsInput:
"""Analytics input for a single integration.
This is sent to integrations that implement the platform.
"""
device_ids: Iterable[str] = field(default_factory=list)
entity_ids: Iterable[str] = field(default_factory=list)
@dataclass
class AnalyticsModifications:
"""Analytics config for a single integration.
This is used by integrations that implement the platform.
"""
remove: bool = False
devices: Mapping[str, DeviceAnalyticsModifications] | None = None
entities: Mapping[str, EntityAnalyticsModifications] | None = None
@dataclass
class DeviceAnalyticsModifications:
"""Analytics config for a single device.
This is used by integrations that implement the platform.
"""
remove: bool = False
@dataclass
class EntityAnalyticsModifications:
"""Analytics config for a single entity.
This is used by integrations that implement the platform.
"""
remove: bool = False
class AnalyticsPlatformProtocol(Protocol):
"""Define the format of analytics platforms."""
async def async_modify_analytics(
self,
hass: HomeAssistant,
analytics_input: AnalyticsInput,
) -> AnalyticsModifications:
"""Modify the analytics."""
async def _async_get_analytics_platform(
hass: HomeAssistant, domain: str
) -> AnalyticsPlatformProtocol | None:
"""Get analytics platform."""
try:
integration = await async_get_integration(hass, domain)
except IntegrationNotFound:
return None
try:
return await integration.async_get_platform(DOMAIN)
except ImportError:
return None
async def _async_get_modifier(
hass: HomeAssistant, domain: str
) -> AnalyticsModifier | None:
"""Get analytics modifier."""
modifiers = _async_get_modifiers(hass)
modifier = modifiers.get(domain, UNDEFINED)
if modifier is not UNDEFINED:
return modifier
platform = await _async_get_analytics_platform(hass, domain)
if platform is None:
modifiers[domain] = None
return None
modifier = getattr(platform, "async_modify_analytics", None)
modifiers[domain] = modifier
return modifier
def gen_uuid() -> str:
"""Generate a new UUID."""
@@ -388,67 +500,219 @@ def _domains_from_yaml_config(yaml_configuration: dict[str, Any]) -> set[str]:
return domains
async def async_devices_payload(hass: HomeAssistant) -> dict:
"""Return the devices payload."""
devices: list[dict[str, Any]] = []
DEFAULT_ANALYTICS_CONFIG = AnalyticsModifications()
DEFAULT_DEVICE_ANALYTICS_CONFIG = DeviceAnalyticsModifications()
DEFAULT_ENTITY_ANALYTICS_CONFIG = EntityAnalyticsModifications()
async def async_devices_payload(hass: HomeAssistant) -> dict: # noqa: C901
"""Return detailed information about entities and devices."""
dev_reg = dr.async_get(hass)
# Devices that need via device info set
new_indexes: dict[str, int] = {}
via_devices: dict[str, str] = {}
ent_reg = er.async_get(hass)
seen_integrations = set()
integration_inputs: dict[str, tuple[list[str], list[str]]] = {}
integration_configs: dict[str, AnalyticsModifications] = {}
for device in dev_reg.devices.values():
if not device.primary_config_entry:
removed_devices: set[str] = set()
# Get device list
for device_entry in dev_reg.devices.values():
if not device_entry.primary_config_entry:
continue
config_entry = hass.config_entries.async_get_entry(device.primary_config_entry)
config_entry = hass.config_entries.async_get_entry(
device_entry.primary_config_entry
)
if config_entry is None:
continue
seen_integrations.add(config_entry.domain)
new_indexes[device.id] = len(devices)
devices.append(
{
"integration": config_entry.domain,
"manufacturer": device.manufacturer,
"model_id": device.model_id,
"model": device.model,
"sw_version": device.sw_version,
"hw_version": device.hw_version,
"has_configuration_url": device.configuration_url is not None,
"via_device": None,
"entry_type": device.entry_type.value if device.entry_type else None,
}
)
if device.via_device_id:
via_devices[device.id] = device.via_device_id
for from_device, via_device in via_devices.items():
if via_device not in new_indexes:
if device_entry.entry_type is dr.DeviceEntryType.SERVICE:
removed_devices.add(device_entry.id)
continue
devices[new_indexes[from_device]]["via_device"] = new_indexes[via_device]
integration_domain = config_entry.domain
integration_input = integration_inputs.setdefault(integration_domain, ([], []))
integration_input[0].append(device_entry.id)
# Get entity list
for entity_entry in ent_reg.entities.values():
integration_domain = entity_entry.platform
integration_input = integration_inputs.setdefault(integration_domain, ([], []))
integration_input[1].append(entity_entry.entity_id)
integrations = {
domain: integration
for domain, integration in (
await async_get_integrations(hass, seen_integrations)
await async_get_integrations(hass, integration_inputs.keys())
).items()
if isinstance(integration, Integration)
}
for device_info in devices:
if integration := integrations.get(device_info["integration"]):
device_info["is_custom_integration"] = not integration.is_built_in
# Include version for custom integrations
if not integration.is_built_in and integration.version:
device_info["custom_integration_version"] = str(integration.version)
# Filter out custom integrations and integrations that are not device or hub type
integration_inputs = {
domain: integration_info
for domain, integration_info in integration_inputs.items()
if (integration := integrations.get(domain)) is not None
and integration.is_built_in
and integration.manifest.get("integration_type") in ("device", "hub")
}
# Call integrations that implement the analytics platform
for integration_domain, integration_input in integration_inputs.items():
if (
modifier := await _async_get_modifier(hass, integration_domain)
) is not None:
try:
integration_config = await modifier(
hass, AnalyticsInput(*integration_input)
)
except Exception as err: # noqa: BLE001
LOGGER.exception(
"Calling async_modify_analytics for integration '%s' failed: %s",
integration_domain,
err,
)
integration_configs[integration_domain] = AnalyticsModifications(
remove=True
)
continue
if not isinstance(integration_config, AnalyticsModifications):
LOGGER.error( # type: ignore[unreachable]
"Calling async_modify_analytics for integration '%s' did not return an AnalyticsConfig",
integration_domain,
)
integration_configs[integration_domain] = AnalyticsModifications(
remove=True
)
continue
integration_configs[integration_domain] = integration_config
integrations_info: dict[str, dict[str, Any]] = {}
# We need to refer to other devices, for example in `via_device` field.
# We don't however send the original device ids outside of Home Assistant,
# instead we refer to devices by (integration_domain, index_in_integration_device_list).
device_id_mapping: dict[str, tuple[str, int]] = {}
# Fill out information about devices
for integration_domain, integration_input in integration_inputs.items():
integration_config = integration_configs.get(
integration_domain, DEFAULT_ANALYTICS_CONFIG
)
if integration_config.remove:
continue
integration_info = integrations_info.setdefault(
integration_domain, {"devices": [], "entities": []}
)
devices_info = integration_info["devices"]
for device_id in integration_input[0]:
device_config = DEFAULT_DEVICE_ANALYTICS_CONFIG
if integration_config.devices is not None:
device_config = integration_config.devices.get(device_id, device_config)
if device_config.remove:
removed_devices.add(device_id)
continue
device_entry = dev_reg.devices[device_id]
device_id_mapping[device_id] = (integration_domain, len(devices_info))
devices_info.append(
{
"entry_type": device_entry.entry_type,
"has_configuration_url": device_entry.configuration_url is not None,
"hw_version": device_entry.hw_version,
"manufacturer": device_entry.manufacturer,
"model": device_entry.model,
"model_id": device_entry.model_id,
"sw_version": device_entry.sw_version,
"via_device": device_entry.via_device_id,
"entities": [],
}
)
# Fill out via_device with new device ids
for integration_info in integrations_info.values():
for device_info in integration_info["devices"]:
if device_info["via_device"] is None:
continue
device_info["via_device"] = device_id_mapping.get(device_info["via_device"])
# Fill out information about entities
for integration_domain, integration_input in integration_inputs.items():
integration_config = integration_configs.get(
integration_domain, DEFAULT_ANALYTICS_CONFIG
)
if integration_config.remove:
continue
integration_info = integrations_info.setdefault(
integration_domain, {"devices": [], "entities": []}
)
devices_info = integration_info["devices"]
entities_info = integration_info["entities"]
for entity_id in integration_input[1]:
entity_config = DEFAULT_ENTITY_ANALYTICS_CONFIG
if integration_config.entities is not None:
entity_config = integration_config.entities.get(
entity_id, entity_config
)
if entity_config.remove:
continue
entity_entry = ent_reg.entities[entity_id]
entity_state = hass.states.get(entity_id)
entity_info = {
# LIMITATION: `assumed_state` can be overridden by users;
# we should replace it with the original value in the future.
# It is also not present, if entity is not in the state machine,
# which can happen for disabled entities.
"assumed_state": (
entity_state.attributes.get(ATTR_ASSUMED_STATE, False)
if entity_state is not None
else None
),
"domain": entity_entry.domain,
"entity_category": entity_entry.entity_category,
"has_entity_name": entity_entry.has_entity_name,
"original_device_class": entity_entry.original_device_class,
# LIMITATION: `unit_of_measurement` can be overridden by users;
# we should replace it with the original value in the future.
"unit_of_measurement": entity_entry.unit_of_measurement,
}
if (device_id_ := entity_entry.device_id) is not None:
if device_id_ in removed_devices:
# The device was removed, so we remove the entity too
continue
if (
new_device_id := device_id_mapping.get(device_id_)
) is not None and (new_device_id[0] == integration_domain):
device_info = devices_info[new_device_id[1]]
device_info["entities"].append(entity_info)
continue
entities_info.append(entity_info)
return {
"version": "home-assistant:1",
"home_assistant": HA_VERSION,
"devices": devices,
"integrations": integrations_info,
}
@@ -2,7 +2,7 @@
"domain": "analytics",
"name": "Analytics",
"after_dependencies": ["energy", "hassio", "recorder"],
"codeowners": ["@home-assistant/core", "@ludeeus"],
"codeowners": ["@home-assistant/core"],
"dependencies": ["api", "websocket_api", "http"],
"documentation": "https://www.home-assistant.io/integrations/analytics",
"integration_type": "system",
@@ -33,9 +33,11 @@ from homeassistant.const import (
)
from homeassistant.core import Event, HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.device_registry import format_mac
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.storage import STORAGE_DIR
from homeassistant.helpers.typing import ConfigType
from .const import (
CONF_ADB_SERVER_IP,
@@ -46,10 +48,12 @@ from .const import (
DEFAULT_ADB_SERVER_PORT,
DEVICE_ANDROIDTV,
DEVICE_FIRETV,
DOMAIN,
PROP_ETHMAC,
PROP_WIFIMAC,
SIGNAL_CONFIG_ENTITY,
)
from .services import async_setup_services
ADB_PYTHON_EXCEPTIONS: tuple = (
AdbTimeoutError,
@@ -63,6 +67,8 @@ ADB_PYTHON_EXCEPTIONS: tuple = (
)
ADB_TCP_EXCEPTIONS: tuple = (ConnectionResetError, RuntimeError)
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
PLATFORMS = [Platform.MEDIA_PLAYER, Platform.REMOTE]
RELOAD_OPTIONS = [CONF_STATE_DETECTION_RULES]
@@ -188,6 +194,12 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Android TV / Fire TV integration."""
async_setup_services(hass)
return True
async def async_setup_entry(hass: HomeAssistant, entry: AndroidTVConfigEntry) -> bool:
"""Set up Android Debug Bridge platform."""
@@ -8,7 +8,6 @@ import logging
from androidtv.constants import APPS, KEYS
from androidtv.setup_async import AndroidTVAsync, FireTVAsync
import voluptuous as vol
from homeassistant.components import persistent_notification
from homeassistant.components.media_player import (
@@ -17,9 +16,7 @@ from homeassistant.components.media_player import (
MediaPlayerEntityFeature,
MediaPlayerState,
)
from homeassistant.const import ATTR_COMMAND
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 AddConfigEntryEntitiesCallback
from homeassistant.util.dt import utcnow
@@ -39,19 +36,10 @@ from .const import (
SIGNAL_CONFIG_ENTITY,
)
from .entity import AndroidTVEntity, adb_decorator
from .services import ATTR_ADB_RESPONSE, ATTR_HDMI_INPUT, SERVICE_LEARN_SENDEVENT
_LOGGER = logging.getLogger(__name__)
ATTR_ADB_RESPONSE = "adb_response"
ATTR_DEVICE_PATH = "device_path"
ATTR_HDMI_INPUT = "hdmi_input"
ATTR_LOCAL_PATH = "local_path"
SERVICE_ADB_COMMAND = "adb_command"
SERVICE_DOWNLOAD = "download"
SERVICE_LEARN_SENDEVENT = "learn_sendevent"
SERVICE_UPLOAD = "upload"
# Translate from `AndroidTV` / `FireTV` reported state to HA state.
ANDROIDTV_STATES = {
"off": MediaPlayerState.OFF,
@@ -77,32 +65,6 @@ async def async_setup_entry(
]
)
platform = entity_platform.async_get_current_platform()
platform.async_register_entity_service(
SERVICE_ADB_COMMAND,
{vol.Required(ATTR_COMMAND): cv.string},
"adb_command",
)
platform.async_register_entity_service(
SERVICE_LEARN_SENDEVENT, None, "learn_sendevent"
)
platform.async_register_entity_service(
SERVICE_DOWNLOAD,
{
vol.Required(ATTR_DEVICE_PATH): cv.string,
vol.Required(ATTR_LOCAL_PATH): cv.string,
},
"service_download",
)
platform.async_register_entity_service(
SERVICE_UPLOAD,
{
vol.Required(ATTR_DEVICE_PATH): cv.string,
vol.Required(ATTR_LOCAL_PATH): cv.string,
},
"service_upload",
)
class ADBDevice(AndroidTVEntity, MediaPlayerEntity):
"""Representation of an Android or Fire TV device."""
@@ -0,0 +1,66 @@
"""Services for Android/Fire TV devices."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.components.media_player import DOMAIN as MEDIA_PLAYER_DOMAIN
from homeassistant.const import ATTR_COMMAND
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv, service
from .const import DOMAIN
ATTR_ADB_RESPONSE = "adb_response"
ATTR_DEVICE_PATH = "device_path"
ATTR_HDMI_INPUT = "hdmi_input"
ATTR_LOCAL_PATH = "local_path"
SERVICE_ADB_COMMAND = "adb_command"
SERVICE_DOWNLOAD = "download"
SERVICE_LEARN_SENDEVENT = "learn_sendevent"
SERVICE_UPLOAD = "upload"
@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Register the Android TV / Fire TV services."""
service.async_register_platform_entity_service(
hass,
DOMAIN,
SERVICE_ADB_COMMAND,
entity_domain=MEDIA_PLAYER_DOMAIN,
schema={vol.Required(ATTR_COMMAND): cv.string},
func="adb_command",
)
service.async_register_platform_entity_service(
hass,
DOMAIN,
SERVICE_LEARN_SENDEVENT,
entity_domain=MEDIA_PLAYER_DOMAIN,
schema=None,
func="learn_sendevent",
)
service.async_register_platform_entity_service(
hass,
DOMAIN,
SERVICE_DOWNLOAD,
entity_domain=MEDIA_PLAYER_DOMAIN,
schema={
vol.Required(ATTR_DEVICE_PATH): cv.string,
vol.Required(ATTR_LOCAL_PATH): cv.string,
},
func="service_download",
)
service.async_register_platform_entity_service(
hass,
DOMAIN,
SERVICE_UPLOAD,
entity_domain=MEDIA_PLAYER_DOMAIN,
schema={
vol.Required(ATTR_DEVICE_PATH): cv.string,
vol.Required(ATTR_LOCAL_PATH): cv.string,
},
func="service_upload",
)
@@ -37,7 +37,7 @@ from .helpers import AndroidTVRemoteConfigEntry, create_api, get_enable_ime
_LOGGER = logging.getLogger(__name__)
APPS_NEW_ID = "NewApp"
APPS_NEW_ID = "add_new"
CONF_APP_DELETE = "app_delete"
CONF_APP_ID = "app_id"
@@ -66,9 +66,14 @@ class AndroidTVRemoteConfigFlow(ConfigFlow, domain=DOMAIN):
if user_input is not None:
self.host = user_input[CONF_HOST]
api = create_api(self.hass, self.host, enable_ime=False)
await api.async_generate_cert_if_missing()
try:
await api.async_generate_cert_if_missing()
self.name, self.mac = await api.async_get_name_and_mac()
except CannotConnect:
# Likely invalid IP address or device is network unreachable. Stay
# in the user step allowing the user to enter a different host.
errors["base"] = "cannot_connect"
else:
await self.async_set_unique_id(format_mac(self.mac))
if self.source == SOURCE_RECONFIGURE:
self._abort_if_unique_id_mismatch()
@@ -81,11 +86,10 @@ class AndroidTVRemoteConfigFlow(ConfigFlow, domain=DOMAIN):
},
)
self._abort_if_unique_id_configured(updates={CONF_HOST: self.host})
return await self._async_start_pair()
except (CannotConnect, ConnectionClosed):
# Likely invalid IP address or device is network unreachable. Stay
# in the user step allowing the user to enter a different host.
errors["base"] = "cannot_connect"
try:
return await self._async_start_pair()
except (CannotConnect, ConnectionClosed):
errors["base"] = "cannot_connect"
else:
user_input = {}
default_host = user_input.get(CONF_HOST, vol.UNDEFINED)
@@ -112,22 +116,9 @@ class AndroidTVRemoteConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle the pair step."""
errors: dict[str, str] = {}
if user_input is not None:
pin = user_input["pin"]
try:
pin = user_input["pin"]
await self.api.async_finish_pairing(pin)
if self.source == SOURCE_REAUTH:
return self.async_update_reload_and_abort(
self._get_reauth_entry(), reload_even_if_entry_is_unchanged=True
)
return self.async_create_entry(
title=self.name,
data={
CONF_HOST: self.host,
CONF_NAME: self.name,
CONF_MAC: self.mac,
},
)
except InvalidAuth:
# Invalid PIN. Stay in the pair step allowing the user to enter
# a different PIN.
@@ -145,6 +136,20 @@ class AndroidTVRemoteConfigFlow(ConfigFlow, domain=DOMAIN):
# them to enter a new IP address but we cannot do that for the zeroconf
# flow. Simpler to abort for both flows.
return self.async_abort(reason="cannot_connect")
else:
if self.source == SOURCE_REAUTH:
return self.async_update_reload_and_abort(
self._get_reauth_entry(), reload_even_if_entry_is_unchanged=True
)
return self.async_create_entry(
title=self.name,
data={
CONF_HOST: self.host,
CONF_NAME: self.name,
CONF_MAC: self.mac,
},
)
return self.async_show_form(
step_id="pair",
data_schema=STEP_PAIR_DATA_SCHEMA,
@@ -282,7 +287,9 @@ class AndroidTVRemoteOptionsFlowHandler(OptionsFlowWithReload):
{
vol.Optional(CONF_APPS): SelectSelector(
SelectSelectorConfig(
options=apps, mode=SelectSelectorMode.DROPDOWN
options=apps,
mode=SelectSelectorMode.DROPDOWN,
translation_key="apps",
)
),
vol.Required(
@@ -6,7 +6,7 @@ from typing import Any
from androidtvremote2 import AndroidTVRemote, ConnectionClosed
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME
from homeassistant.const import CONF_MAC, CONF_NAME
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
@@ -28,8 +28,6 @@ class AndroidTVRemoteBaseEntity(Entity):
) -> None:
"""Initialize the entity."""
self._api = api
self._host = config_entry.data[CONF_HOST]
self._name = config_entry.data[CONF_NAME]
self._apps: dict[str, Any] = config_entry.options.get(CONF_APPS, {})
self._attr_unique_id = config_entry.unique_id
self._attr_is_on = api.is_on
@@ -39,7 +37,7 @@ class AndroidTVRemoteBaseEntity(Entity):
self._attr_device_info = DeviceInfo(
connections={(CONNECTION_NETWORK_MAC, config_entry.data[CONF_MAC])},
identifiers={(DOMAIN, config_entry.unique_id)},
name=self._name,
name=config_entry.data[CONF_NAME],
manufacturer=device_info["manufacturer"],
model=device_info["model"],
)
@@ -7,6 +7,7 @@
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["androidtvremote2"],
"quality_scale": "platinum",
"requirements": ["androidtvremote2==0.2.3"],
"zeroconf": ["_androidtvremote2._tcp.local."]
}
@@ -175,7 +175,11 @@ class AndroidTVRemoteMediaPlayerEntity(AndroidTVRemoteBaseEntity, MediaPlayerEnt
"""Play a piece of media."""
if media_type == MediaType.CHANNEL:
if not media_id.isnumeric():
raise ValueError(f"Channel must be numeric: {media_id}")
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="invalid_channel",
translation_placeholders={"media_id": media_id},
)
if self._channel_set_task:
self._channel_set_task.cancel()
self._channel_set_task = asyncio.create_task(
@@ -188,7 +192,11 @@ class AndroidTVRemoteMediaPlayerEntity(AndroidTVRemoteBaseEntity, MediaPlayerEnt
self._send_launch_app_command(media_id)
return
raise ValueError(f"Invalid media type: {media_type}")
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="invalid_media_type",
translation_placeholders={"media_type": media_type},
)
async def async_browse_media(
self,
@@ -0,0 +1,78 @@
rules:
# Bronze
action-setup:
status: exempt
comment: No integration-specific service actions are defined.
appropriate-polling:
status: exempt
comment: This is a push-based integration.
brands: done
common-modules: done
config-flow-test-coverage: done
config-flow: done
dependency-transparency: done
docs-actions: done
docs-high-level-description: done
docs-installation-instructions: done
docs-removal-instructions: done
entity-event-setup: done
entity-unique-id: done
has-entity-name: done
runtime-data: done
test-before-configure: done
test-before-setup: done
unique-config-entry: done
# Silver
action-exceptions: done
config-entry-unloading: done
docs-configuration-parameters: done
docs-installation-parameters: done
entity-unavailable: done
integration-owner: done
log-when-unavailable: done
parallel-updates: done
reauthentication-flow: done
test-coverage: done
# Gold
devices: done
diagnostics: done
discovery-update-info: done
discovery: done
docs-data-update: done
docs-examples: done
docs-known-limitations: done
docs-supported-devices: done
docs-supported-functions: done
docs-troubleshooting: done
docs-use-cases: done
dynamic-devices:
status: exempt
comment: The integration is configured on a per-device basis, so there are no dynamic devices to add.
entity-category:
status: exempt
comment: All entities are primary and do not require a specific category.
entity-device-class: done
entity-disabled-by-default:
status: exempt
comment: The integration provides only primary entities that should be enabled.
entity-translations: done
exception-translations: done
icon-translations:
status: exempt
comment: Icons are provided by the entity's device class, and no state-based icons are needed.
reconfiguration-flow: done
repair-issues:
status: exempt
comment: The integration uses the reauth flow for authentication issues, and no other repairable issues have been identified.
stale-devices:
status: exempt
comment: The integration manages a single device per config entry. Stale device removal is handled by removing the config entry.
# Platinum
async-dependency: done
inject-websession:
status: exempt
comment: The underlying library does not use HTTP for communication.
strict-typing: done
@@ -22,7 +22,7 @@
},
"zeroconf_confirm": {
"title": "Discovered Android TV",
"description": "Do you want to add the Android TV ({name}) to Home Assistant? It will turn on and a pairing code will be displayed on it that you will need to enter in the next screen."
"description": "Do you want to add the Android TV ({name}) to Home Assistant? It will turn on and a pairing code will be displayed on it that you will need to enter in the next screen."
},
"pair": {
"description": "Enter the pairing code displayed on the Android TV ({name}).",
@@ -85,6 +85,19 @@
"exceptions": {
"connection_closed": {
"message": "Connection to the Android TV device is closed"
},
"invalid_channel": {
"message": "Channel must be numeric: {media_id}"
},
"invalid_media_type": {
"message": "Invalid media type: {media_type}"
}
},
"selector": {
"apps": {
"options": {
"add_new": "Add new"
}
}
}
}
+1 -1
View File
@@ -16,7 +16,7 @@ from .coordinator import (
AOSmithStatusCoordinator,
)
PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.WATER_HEATER]
PLATFORMS: list[Platform] = [Platform.SELECT, Platform.SENSOR, Platform.WATER_HEATER]
async def async_setup_entry(hass: HomeAssistant, entry: AOSmithConfigEntry) -> bool:
@@ -1,5 +1,10 @@
{
"entity": {
"select": {
"hot_water_plus_level": {
"default": "mdi:water-plus"
}
},
"sensor": {
"hot_water_availability": {
"default": "mdi:water-thermometer"
@@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aosmith",
"iot_class": "cloud_polling",
"requirements": ["py-aosmith==1.0.12"]
"requirements": ["py-aosmith==1.0.14"]
}
@@ -0,0 +1,70 @@
"""The select platform for the A. O. Smith integration."""
from homeassistant.components.select import SelectEntity
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AOSmithConfigEntry
from .coordinator import AOSmithStatusCoordinator
from .entity import AOSmithStatusEntity
HWP_LEVEL_HA_TO_AOSMITH = {
"off": 0,
"level1": 1,
"level2": 2,
"level3": 3,
}
HWP_LEVEL_AOSMITH_TO_HA = {value: key for key, value in HWP_LEVEL_HA_TO_AOSMITH.items()}
async def async_setup_entry(
hass: HomeAssistant,
entry: AOSmithConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up A. O. Smith select platform."""
data = entry.runtime_data
async_add_entities(
AOSmithHotWaterPlusSelectEntity(data.status_coordinator, device.junction_id)
for device in data.status_coordinator.data.values()
if device.supports_hot_water_plus
)
class AOSmithHotWaterPlusSelectEntity(AOSmithStatusEntity, SelectEntity):
"""Class for the Hot Water+ select entity."""
_attr_translation_key = "hot_water_plus_level"
_attr_options = list(HWP_LEVEL_HA_TO_AOSMITH)
def __init__(self, coordinator: AOSmithStatusCoordinator, junction_id: str) -> None:
"""Initialize the entity."""
super().__init__(coordinator, junction_id)
self._attr_unique_id = f"hot_water_plus_level_{junction_id}"
@property
def suggested_object_id(self) -> str | None:
"""Override the suggested object id to make '+' get converted to 'plus' in the entity id."""
return "hot_water_plus_level"
@property
def current_option(self) -> str | None:
"""Return the current Hot Water+ mode."""
hot_water_plus_level = self.device.status.hot_water_plus_level
return (
None
if hot_water_plus_level is None
else HWP_LEVEL_AOSMITH_TO_HA.get(hot_water_plus_level)
)
async def async_select_option(self, option: str) -> None:
"""Set the Hot Water+ mode."""
aosmith_hwp_level = HWP_LEVEL_HA_TO_AOSMITH[option]
await self.client.update_mode(
junction_id=self.junction_id,
mode=self.device.status.current_mode,
hot_water_plus_level=aosmith_hwp_level,
)
await self.coordinator.async_request_refresh()

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