Compare commits

...

1348 Commits

Author SHA1 Message Date
mib1185
53b81c5bbd improve tests 2025-12-14 11:44:54 +00:00
mib1185
37a61427de fix test name 2025-12-14 11:14:42 +00:00
mib1185
f8fd4b99fe use specific trigger mock 2025-12-14 11:12:30 +00:00
Michael
8785867c16 Merge branch 'dev' into fritzbox/add-support-for-routines 2025-12-14 11:28:05 +01:00
Michael
78af3acf35 Bump pyfritzhome to 0.6.18 (#158877) 2025-12-14 08:12:25 +01:00
Joost Lekkerkerker
b72f04d44e Add integration_type hub to electrasmart (#158942) 2025-12-14 07:17:50 +01:00
Joost Lekkerkerker
35f287e330 Add integration_type hub to ekeybionyx (#158941) 2025-12-14 07:16:40 +01:00
Joost Lekkerkerker
0a55f83b46 Add integration_type hub to econet (#158940) 2025-12-14 07:14:44 +01:00
Joost Lekkerkerker
5030d0ba90 Add integration_type device to ecoforest (#158939) 2025-12-14 07:13:44 +01:00
Joost Lekkerkerker
f582f06ee4 Add integration_type service to eafm (#158937) 2025-12-14 06:59:46 +01:00
Joost Lekkerkerker
662bada5d8 Add integration_type hub to duotecno (#158936) 2025-12-14 06:59:13 +01:00
Joost Lekkerkerker
3ca338dd25 Add integration_type device to dunehd (#158935) 2025-12-14 06:58:03 +01:00
Joost Lekkerkerker
9337a0e71b Add integration_type device to droplet (#158933) 2025-12-14 06:56:08 +01:00
Joost Lekkerkerker
ccbb00197d Add integration_type hub to drop_connect (#158932) 2025-12-14 06:55:22 +01:00
Joost Lekkerkerker
0f59c17e61 Add integration_type service to dexcom (#158928) 2025-12-14 06:42:34 +01:00
Joost Lekkerkerker
6253ade3e2 Add integration_type service to datadog (#158927) 2025-12-14 06:40:48 +01:00
Joost Lekkerkerker
e5890378a1 Add integration_type device to daikin (#158926) 2025-12-14 06:40:29 +01:00
Joost Lekkerkerker
b8ab0bcadf Add integration_type service to dnsip (#158930) 2025-12-13 16:25:51 -06:00
Joost Lekkerkerker
19cb827577 Add integration_type device to doorbird (#158931) 2025-12-13 16:23:37 -06:00
Joost Lekkerkerker
03676d7e5a Add integration_type hub to ecobee (#158938) 2025-12-13 16:23:15 -06:00
Magnus
13f3b49b96 Bump aioasuswrt 1.5.3 (#158882) 2025-12-13 22:43:21 +01:00
Allen Porter
90c8c56a06 Suppress roborock failures under some unavailability threshold (#158673)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 22:30:21 +01:00
Josef Zweck
afb9e18a7d Add brew by weight controls to lamarzocco (#158169) 2025-12-13 22:28:11 +01:00
Andrew Jackson
2c2934065f Bump aiomealie to 1.1.1 and statically define mealplan entry types (#158907) 2025-12-13 22:26:31 +01:00
mettolen
0bead67df9 Add device uptime to Airobot integration (#158516) 2025-12-13 22:20:52 +01:00
James Cole
2895849203 Update strings for Firefly III integration (#158911) 2025-12-13 22:20:30 +01:00
David Recordon
b2400708ac Add myself as a maintainer for Control4 (#158948) 2025-12-13 22:15:35 +01:00
mib1185
b5addcfc81 add tests 2025-12-13 18:37:44 +00:00
Anthony Garera
0bed9c20b3 Bump python-overseerr to 0.8.0 (#158924) 2025-12-13 19:31:21 +01:00
Brett Adams
d3fb7a7b87 Bump tesla-fleet-api to 1.2.7 (#158904) 2025-12-13 15:02:19 +01:00
mib1185
90e103beb9 add support to activte/deactivate routines/triggers 2025-12-13 11:30:59 +00:00
Bouwe Westerdijk
60dcca4143 Show Plugwise configuration-link on gateway only (#158094) 2025-12-13 11:38:23 +01:00
Paul Tarjan
01f498f239 Clarify previous state in total_increasing warning message (#158805) 2025-12-13 11:15:37 +01:00
Andre Lengwenus
15055b8e8e Fix race condition in LCN climate and cover entites (#158894) 2025-12-13 11:12:20 +01:00
Bouwe Westerdijk
6826619e12 Revert adding entity_category to Plugwise thermostat schedule select (#158901) 2025-12-13 11:08:17 +01:00
Joost Lekkerkerker
b50a8e04a8 Add integration_type hub to airtouch5 (#158834)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:47:27 +01:00
Joost Lekkerkerker
c6c67c5357 Add integration_type hub to blue_current (#158863) 2025-12-13 10:46:12 +01:00
Joost Lekkerkerker
c82803d1e2 Add integration_type hub to agent_dvr (#158829)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:45:09 +01:00
Joost Lekkerkerker
732b30f181 Add integration_type hub to airzone (#158835)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:44:05 +01:00
Joost Lekkerkerker
0e2e57a657 Add integration_type device to android_ip_webcam (#158838)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:42:39 +01:00
Joost Lekkerkerker
f00b0080a9 Add integration_type device to advantage_air (#158826)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:39:58 +01:00
Joost Lekkerkerker
ad970c1234 Add integration_type hub to cert_expiry (#158897) 2025-12-13 10:39:14 +01:00
Joost Lekkerkerker
02ec56bffa Add integration_type device to ccm15 (#158896)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:37:36 +01:00
Joost Lekkerkerker
8388c290bf Add integration_type hub to canary (#158895) 2025-12-13 09:41:01 +01:00
Joost Lekkerkerker
576ee99faf Add integration_type hub to control4 (#158900) 2025-12-13 09:36:36 +01:00
Joost Lekkerkerker
8a3534c345 Add integration_type service to coinbase (#158899) 2025-12-13 09:31:54 +01:00
Joost Lekkerkerker
e1e91c5568 Add integration_type service to cloudflare (#158898) 2025-12-13 09:31:25 +01:00
epenet
1e09bddb1d Cleanup deprecated alias in core (#158799) 2025-12-13 09:29:15 +01:00
Joost Lekkerkerker
90e4340595 Add integration_type hub to brunt (#158870)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-12-13 09:04:05 +01:00
Joost Lekkerkerker
120b17349c Add integration_type service to aussie_broadband (#158853) 2025-12-13 08:56:35 +01:00
Joost Lekkerkerker
8a26961304 Add integration_type service to aurora (#158852) 2025-12-13 08:56:01 +01:00
Joost Lekkerkerker
407b675080 Add integration_type device to atag (#158850) 2025-12-13 08:55:35 +01:00
Joost Lekkerkerker
274844271b Add integration_type hub to aseko_pool_live (#158849) 2025-12-13 08:54:46 +01:00
Joost Lekkerkerker
f11e4e7bda Add integration_type hub to aosmith (#158843) 2025-12-13 08:52:45 +01:00
Joost Lekkerkerker
96f8c39c6f Add integration_type device to anthemav (#158841) 2025-12-13 08:51:25 +01:00
Joost Lekkerkerker
77b79fef8d Add integration_type hub to anova (#158840) 2025-12-13 08:50:24 +01:00
mkmer
a0d2f285f3 blink: Remove mkmer as codeowner (#158884) 2025-12-13 08:45:13 +01:00
Joost Lekkerkerker
3aef05d1ec Add integration_type hub to airzone_cloud (#158836) 2025-12-13 08:43:57 +01:00
Joost Lekkerkerker
510e391ee4 Add integration_type device to airtouch4 (#158833) 2025-12-13 08:41:17 +01:00
Joost Lekkerkerker
54adfdd694 Add integration_type device to bluesound (#158865) 2025-12-13 08:38:48 +01:00
Joost Lekkerkerker
d45f920b4a Add integration_type service to amberelectric (#158837) 2025-12-13 08:37:16 +01:00
Joost Lekkerkerker
3080ef9a4a Add integration_type device to airthings_ble (#158832) 2025-12-13 08:36:06 +01:00
Joost Lekkerkerker
51cebb52f3 Add integration_type hub to airthings (#158831) 2025-12-13 08:34:28 +01:00
Joost Lekkerkerker
7b0d4c47b7 Add integration_type service to airnow (#158830) 2025-12-13 08:33:53 +01:00
Joost Lekkerkerker
a660ab3f97 Add integration_type service to aftership (#158828) 2025-12-13 08:32:31 +01:00
Joost Lekkerkerker
dd8fc16788 Add integration_type service to aemet (#158827) 2025-12-13 08:32:01 +01:00
Joost Lekkerkerker
2b0fab0468 Add integration_type service to brottsplatskartan (#158869) 2025-12-13 08:30:59 +01:00
Joost Lekkerkerker
3bb88ed433 Add integration_type hub to bosch_shc (#158868) 2025-12-13 08:30:04 +01:00
Joost Lekkerkerker
984385cd98 Add integration_type service to buienradar (#158871) 2025-12-13 08:27:55 +01:00
Joost Lekkerkerker
09de108676 Add integration_type service to caldav (#158872) 2025-12-13 08:26:40 +01:00
Joost Lekkerkerker
ebc7581718 Add integration_type hub to bmw_connected_drive (#158866) 2025-12-13 08:26:16 +01:00
Joost Lekkerkerker
e55162812d Add integration_type hub to blink (#158862) 2025-12-13 08:22:22 +01:00
Joost Lekkerkerker
aa6ccaa024 Add integration_type device to blebox (#158860) 2025-12-13 08:21:25 +01:00
Joost Lekkerkerker
e1b009a6de Add integration_type device to balboa (#158859) 2025-12-13 08:20:12 +01:00
Joost Lekkerkerker
91ddc525b0 Add integration_type service to azure_event_hub (#158857) 2025-12-13 08:18:56 +01:00
Joost Lekkerkerker
d7d7954ac2 Add integration_type service to azure_devops (#158856) 2025-12-13 08:18:35 +01:00
Joost Lekkerkerker
e87c260df7 Add integration_type service to azure_data_explorer (#158855) 2025-12-13 08:18:13 +01:00
Joost Lekkerkerker
5185c6cd68 Add integration_type hub to arve (#158848) 2025-12-13 08:17:37 +01:00
Joost Lekkerkerker
7599c918e2 Add integration_type hub to august (#158851) 2025-12-12 23:00:06 +01:00
Joost Lekkerkerker
fa7e22ec91 Add integration_type device to arcam_fmj (#158846) 2025-12-12 22:59:47 +01:00
Joost Lekkerkerker
606519e51b Add integration_type device to baf (#158858) 2025-12-12 22:59:28 +01:00
Joost Lekkerkerker
8e39e010f7 Add integration_type device to bluemaestro (#158864) 2025-12-12 22:59:13 +01:00
Joost Lekkerkerker
dc01cf49a0 Add integration_type hub to bond (#158867) 2025-12-12 22:58:57 +01:00
Joost Lekkerkerker
1f3ad382f1 Set Denon AVR integration type to device (#158815) 2025-12-12 20:33:56 +01:00
Joost Lekkerkerker
2595c7dcb2 Set Actron Air integration type to hub (#158816) 2025-12-12 20:33:25 +01:00
Kamil Breguła
d445b320de Accept URLs in WLED Host input (#157793)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-12-12 18:55:03 +01:00
epenet
7b6df1a8a0 Cleanup deprecated typing helpers (#158806) 2025-12-12 17:04:41 +01:00
Manu
2a151dcd19 Add tests for discovery to Xbox integration (#158808) 2025-12-12 17:02:32 +01:00
epenet
adbab150af Move blue_current services to separate module (#158389) 2025-12-12 16:50:34 +01:00
Allen Porter
d20edf7928 Improve Roborock exception logging behavior for Zeo/Dyad devices (#158465)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-12 16:43:45 +01:00
Ludovic BOUÉ
7d6d37fe76 Fix Matter Door Lock Operating Mode select entity (#158468) 2025-12-12 16:30:48 +01:00
Ludovic BOUÉ
228e0453a7 Add Matter Thermostat remote sensing status (#157650) 2025-12-12 16:26:27 +01:00
Raphael Hehl
1da31c0530 Move icons to icons.json for unifiprotect (#158800)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2025-12-12 16:23:11 +01:00
Joost Lekkerkerker
41ad15e577 Bump pySmartThings to 3.5.1 (#158795) 2025-12-12 15:45:08 +01:00
Markus Jacobsen
421af881fe Add video source reporting to Bang & Olufsen (#158675) 2025-12-12 15:40:12 +01:00
Klaas Schoute
715a484f7e Add AutarcoSensorBase class for Autarco sensors (#158691)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-12 15:39:18 +01:00
Samuel Xiao
0a789f51b8 Switchbot Cloud: Fixed binary sensors didn't update automatically (#158434)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-12 15:39:08 +01:00
epenet
fa25d45123 Remove incorrect bring test (#158797) 2025-12-12 15:32:27 +01:00
johanzander
6d255b2521 Add state_class to Growatt power and energy sensors (#158705)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-12 15:27:47 +01:00
peteS-UK
5ffb39f064 Trap for missing UUID in config_flow for Squeezebox (#158721)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-12 15:15:04 +01:00
Zoltán Farkasdi
d642109436 Netatmo NOCamera on/off fix (#158741) 2025-12-12 14:57:57 +01:00
Heindrich Paul
10f6d8d14f Add diagnostics support for Nederlandse Spoorwegen integration (#158722)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-12 14:36:35 +01:00
Thomas55555
a94678cb06 Bump google air quality api to 2.0.2 (#158742) 2025-12-12 14:35:07 +01:00
Manu
0d8d466003 Increase Xbox update interval to 15 seconds and refactor title data handling (#158780) 2025-12-12 14:04:25 +01:00
Marc Mueller
8ddf3e1734 Update pytest warnings filter (#158790) 2025-12-12 13:54:00 +01:00
cdutr
d88047a750 Migrate Blink component to use hardware_id instead of device_id (#158765) 2025-12-12 13:49:19 +01:00
Jordan Harvey
61c7ac81d6 Bump pynintendoparental to 2.1.1 (#158779) 2025-12-12 13:45:48 +01:00
Josef Zweck
bbe07bddb0 Bump pylamarzocco to 2.2.4 (#158774) 2025-12-12 13:45:14 +01:00
Denis Shulyaka
a3afc2beb1 Bump openai to 2.11.0 (#158785) 2025-12-12 13:40:43 +01:00
epenet
374cd93d3d Replace Tuya remap methods with helper class (#158718) 2025-12-12 13:37:29 +01:00
Maciej Bieniek
6e99411084 Add get_kvs_value and set_kvs_value actions for Shelly RPC devices (#157349) 2025-12-12 13:15:25 +01:00
dependabot[bot]
41d5415c86 Bump actions/cache from 4.3.0 to 5.0.0 (#158771) 2025-12-12 10:39:58 +01:00
Allen Porter
052d56f358 Bump ical to 12.1.1 (#158770) 2025-12-12 08:34:22 +01:00
Abílio Costa
0a676b5812 Remove alarm panel test from text tests (#158743) 2025-12-12 02:18:40 +01:00
Michael
1f4cf67daa Add turned off and turned on triggers to switch platform (#158688)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-11 22:02:22 +00:00
Maikel Punie
bb4ec229ce Add Velbus VLP file loading (#154883) 2025-12-11 22:53:01 +01:00
ndrwrbgs
ff62b460d5 Update advanced_options display text for MQTT (#158728) 2025-12-11 22:16:35 +01:00
Willem-Jan van Rootselaar
9b48e92940 Bump python-bsblan to 3.1.4 (#158725)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-12-11 18:04:57 +00:00
Magnus
c03b9d1f87 Bump aioasuswrt to 1.5.2 (#158727) 2025-12-11 17:31:46 +00:00
Koknico
3f30df203c Add support for AtlanticDomesticHotWaterProductionV2_CETHI_V4_IOComponent to Overkiz (#157872) 2025-12-11 13:10:37 +01:00
epenet
7fe0d96c88 Remove unnecessary wrapper base method in Tuya (#158708) 2025-12-11 10:13:24 +01:00
Joost Lekkerkerker
cdc2192bba Clean up Homelink tests (#158685)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-11 09:10:02 +01:00
Matt Zimmerman
74b1c1f6fd Bump python-smarttub to 0.0.46 (#158702) 2025-12-11 09:07:46 +01:00
J. Nick Koston
69c7a7b0ab Pin pycares to 4.11.0 (#158695) 2025-12-10 22:00:59 -05:00
Norbert Rittel
ef302215cc Add two common config flow strings in energyid (#158680) 2025-12-10 21:23:18 +01:00
Norbert Rittel
6378f5f02a Use common reauth_successful string in rituals_perfume_genie (#158684) 2025-12-10 21:14:25 +01:00
Bouwe Westerdijk
79245195cd Bump Plugwise to v1.11.0 (#158067) 2025-12-10 21:03:27 +01:00
epenet
d0e33a6e04 Use process_raw_value in Tuya JsonTypeInformation (#158517) 2025-12-10 20:13:16 +01:00
Joost Lekkerkerker
f55fc788db Cleanup homelink config flow (#158479) 2025-12-10 18:39:44 +01:00
epenet
6152e0fa27 Split action and state wrapper in Tuya alarm control panel (#158532) 2025-12-10 18:37:04 +01:00
Matthias Alphart
f1a89741c0 Add counter for KNX DataSecure undecodable telegrams (#157844) 2025-12-10 17:59:00 +01:00
Paul Tarjan
7629c9f280 Fix flaky test_stream_source timeout in generic camera tests (#158506) 2025-12-10 17:49:27 +01:00
Abílio Costa
6b8650c6d9 Remove uneeded check in whirlpool oven temperature sensors (#157997) 2025-12-10 17:45:34 +01:00
Paul Tarjan
48f186368a Fix flaky playstation_network test_image_platform test (#158296) 2025-12-10 17:07:58 +01:00
Allen Porter
d65baac8d4 Bump python-roborock to 3.12.2 (#158572) 2025-12-10 17:05:57 +01:00
Paul Tarjan
d57801407b Fix flaky test_calls_not_allowed by using thread-safe event signaling (#158504) 2025-12-10 16:38:34 +01:00
Markus Jacobsen
4495a76557 Change Bang & Olufsen "stopped" state translation (#158534) 2025-12-10 16:37:48 +01:00
Paul Tarjan
99dfb93ac0 Fix flaky test_rename_entity_collision test (#158297) 2025-12-10 16:36:52 +01:00
Abílio Costa
7c7c0aad25 Rename trigger helper state checkers (#158537)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-10 14:56:56 +00:00
Andrew Jackson
5992898340 Add measurement state class to ohme sensors (#158541) 2025-12-10 15:35:24 +01:00
Sander Blomvågnes
4f2ff9a4f4 Add codeowner and integration_type to Entur manifest (#158543) 2025-12-10 15:26:24 +01:00
bestycame
a8a135c2ca Bump hanna-cloud to version 0.0.7 (#158536)
Co-authored-by: Olivier d'Otreppe <odotreppe@abbove.com>
2025-12-10 14:50:05 +01:00
epenet
43e241ee39 Use process_raw_value in Tuya RawTypeInformation (#158521) 2025-12-10 10:44:49 +01:00
Kinachi249
6af7052b9d Bump PyCync to 0.5.0 (#158509) 2025-12-10 08:15:47 +01:00
dependabot[bot]
c0aa35ff6d Bump codecov/codecov-action from 5.5.1 to 5.5.2 (#158515) 2025-12-10 07:27:42 +01:00
Ludovic BOUÉ
2c7763e350 Fix Matter epoch timestamp sensors (#157600) 2025-12-10 07:13:21 +01:00
Joost Lekkerkerker
95e344ea44 Cleanup homelink (#158477) 2025-12-10 01:09:23 +01:00
Yevhenii Vaskivskyi
7ed8613411 Bump asusrouter to 1.21.3 (#158492) 2025-12-09 22:56:11 +01:00
Anton Dalgren
4ac0567ccc Add AirPatrol integration (#149247)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-09 21:26:21 +01:00
epenet
bc031e7a81 Improve Tuya HVACMode handling (#158042)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-09 21:17:57 +01:00
Raphael Hehl
ad1ba629c5 Fix typos in UniFi Protect integration (#158478) 2025-12-09 21:13:38 +01:00
Paul Tarjan
0c2cb460cb Fix flaky laundrify coordinator test (#158460) 2025-12-09 21:12:55 +01:00
Kira
5388740c83 Bump blinkpy to 0.25.1 (#158135)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-09 20:53:59 +01:00
Raphael Hehl
2a54d4c3a9 Add model_id to NVR device info in UniFi Protect (#158481)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2025-12-09 20:18:04 +01:00
Steve Easley
2008972215 Bump kaleidescape requirement version to v1.0.2 (#158068) 2025-12-09 20:12:55 +01:00
Jordan Harvey
39004bd0a2 Update pynintendoparental to 2.1.0 (#158487) 2025-12-09 20:11:28 +01:00
Michael Hansen
bb847ce3ff Bump pysilero-vad to 3.0.1 (#158486) 2025-12-09 13:08:34 -06:00
Denis Shulyaka
05920a9c73 Bump openai to 2.9.0 (#158476) 2025-12-09 12:30:57 -05:00
epenet
61499a5ad4 Fix Tuya BitmapTypeInformation parsing (#158474) 2025-12-09 17:39:54 +01:00
epenet
0076aafa6e Move color_extractor services to separate module (#158341) 2025-12-09 17:32:03 +01:00
epenet
c50f4d6d2d Add Tuya local_strategy to Tuya diagnostic (#158450) 2025-12-09 17:29:11 +01:00
hanwg
68036099a2 Remove timeout parameter for Telegram bot actions (#155198)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-12-09 16:53:02 +01:00
Willem-Jan van Rootselaar
180053fe98 Bump python-bsblan to v3.1.3 (#157626) 2025-12-09 15:33:04 +01:00
Thomas D
280c25cb85 Enable volvo engine status for all engine types (#158437) 2025-12-09 14:35:02 +01:00
Petro31
4064b6d28c Sort weather platform keys (#158106)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-12-09 14:29:01 +01:00
epenet
ff25809a3e Do not unregister google_mail services (#158431) 2025-12-09 13:52:37 +01:00
mettolen
245f47c7fb Add diagnostics to Airobot integration (#158247) 2025-12-09 12:55:37 +01:00
Andre Lengwenus
86135a19d1 Bump pypck to 0.9.7 (#158089) 2025-12-09 12:43:21 +01:00
Simon Lamon
2e038250a9 Bump doorbirdpy to v3.0.11 (#151178)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-12-09 10:37:18 +01:00
Jordan Harvey
88c7c6fc8a Update pynintendoparental to 2.0.0 (#158285) 2025-12-09 08:47:52 +01:00
epenet
d691862d0d Bump heatmiserV3 to 2.0.4 (#158304) 2025-12-09 08:47:16 +01:00
Allen Porter
cceaff7bc6 Fix roborock off peak electricity timer (#158292) 2025-12-09 08:24:04 +01:00
Michael Hansen
079c6daa63 Replace microVAD with Silero VAD (ggml) (#158282) 2025-12-08 20:02:14 -06:00
Michel D'Astous
b120ae827f Fix webhook exception when empty json data is sent (#158254) 2025-12-08 23:44:59 +01:00
Tsvi Mostovicz
c1227aaf1f Jewish Calendar coordinator (#152434) 2025-12-08 22:41:58 +01:00
Artur Pragacz
c0365dfe99 Query state after turn on in Onkyo (#158093) 2025-12-08 21:49:00 +01:00
Petro31
02aa3fc906 Fix legacy template entity_id field in migration (#158105)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-12-08 21:07:40 +01:00
Marcel van der Veldt
42e55491cc Skip check for onboarding done in Music Assistant integration (#158270) 2025-12-08 20:28:02 +01:00
Harvey
33e09c4967 Bump HueBLE to 2.1.0 (#158197) 2025-12-08 19:55:55 +01:00
Petro31
6f5507670f Fix multiple top-level support for template integration (#158244) 2025-12-08 19:19:52 +01:00
Paul Bottein
765be3f047 Update frontend to 20251203.2 (#158259) 2025-12-08 18:08:03 +01:00
omrishiv
12bc9e9f68 fix Lutron Caseta smart away subscription (#158082)
Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-12-08 17:45:36 +01:00
Nic Eggert
2617c4a453 Add eGauge integration (#155279)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-08 17:33:11 +01:00
andreimoraru
0e6d9ecbdc Bump yt-dlp to 2025.12.08 (#158253) 2025-12-08 16:45:23 +01:00
Sander Blomvågnes
5cdbbe999d Move Entur constants to separate module (#158256) 2025-12-08 16:40:54 +01:00
Yevhenii Vaskivskyi
5ca61386f8 Bump asusrouter to 1.21.1 (#158192) 2025-12-08 16:16:25 +01:00
Thomas55555
6d6ee866a6 Remove stale fixture in Google Air Quality (#158235) 2025-12-08 15:44:05 +01:00
Paul Bottein
eeb2b2febc Be more specific about winter mode in the description (#158230)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-12-08 15:28:17 +01:00
Thomas55555
a6c7bd76eb Bump google air quality api to 2.0.0 (#158234) 2025-12-08 13:41:28 +01:00
epenet
470f5a2396 Validate action translation placeholders (#158225)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2025-12-08 13:40:53 +01:00
Marc Mueller
d934fd974d Update Python to 3.13.11 and 3.14.2 in CI (#158238) 2025-12-08 13:30:45 +01:00
epenet
edc81b706d Fix teslemetry service description placeholders (#158240) 2025-12-08 12:50:23 +01:00
epenet
03aaebe718 Fix zwave_js service description placeholders (#158236) 2025-12-08 12:47:35 +01:00
epenet
98d61aa5b2 Fix yeelight service description placeholders (#158239) 2025-12-08 12:46:33 +01:00
Jan Bouwhuis
fe5d411856 Fix description placeholders for system_bridge (#158232) 2025-12-08 12:26:46 +01:00
Petar Petrov
efa5a773eb Add query params handling for requests in Supervisor API (#157832)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-12-08 12:09:59 +01:00
Jordan Harvey
32399de5f1 Bump pyanglianwater to 3.0.0 (#158121) 2025-12-08 11:01:41 +01:00
Klaas Schoute
a1ad28c066 Update powerfox to v2.0.0 (#158223) 2025-12-08 10:59:59 +01:00
Álvaro Fernández Rojas
6faccf4327 Update aioairzone to v1.0.4 (#158208)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-12-08 10:28:26 +01:00
Allen Porter
2ac15ab67d Ensure Roborock disconnects mqtt on unload/stop (#158144)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 09:36:34 +01:00
dependabot[bot]
d599bb9553 Bump github/codeql-action from 4.31.6 to 4.31.7 (#158218)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-08 08:51:12 +01:00
Klaas Schoute
92ee37017d Update energyzero to v4.0.1 (#158211) 2025-12-08 08:50:14 +01:00
Allen Porter
adf698d570 Bump python-roborock to 3.10.10 (#158212) 2025-12-07 20:06:50 -08:00
taltenbach
6ce9a13816 Add Roborock attach/detach mop status translations (#158184) 2025-12-07 16:33:24 -08:00
epenet
9cb9efeb88 Make Tuya find_dpcode a class method (#158028) 2025-12-07 22:32:14 +01:00
J. Nick Koston
ca31134caa Keep persistent BLE connection during Shelly WiFi provisioning (#158145)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-07 14:28:53 -06:00
Raphael Hehl
769578dc51 UnifiProtect: Create NVR device before loading platforms to fix via_device references (#158191) 2025-12-07 21:22:39 +01:00
Thomas55555
9dcabfe804 Use SectionConfig in Google Air Quality (#158188) 2025-12-07 19:49:44 +01:00
Åke Strandberg
dc6c23a58c Add program id codes for Miele WQ1000 (#158175) 2025-12-07 19:34:35 +01:00
Álvaro Fernández Rojas
6ec7efc2b8 Update aioairzone to v1.0.3 (#158181) 2025-12-07 11:54:04 -06:00
Åke Strandberg
97e5b7954e Bump pymiele dependency to 0.6.1 (#158177) 2025-12-07 18:35:28 +01:00
J. Nick Koston
25505752b7 Use "Output" for Shelly RPC switch sub-device names (#158139) 2025-12-07 11:33:00 -06:00
J. Nick Koston
95a347dcf8 Bump aioshelly to 13.23.0 (#158183) 2025-12-07 11:18:53 -06:00
Manu
8c0f3014f7 Fix secure URLs for promotional game media in Xbox integration (#158162) 2025-12-07 11:34:18 +01:00
Josef Zweck
bb3cd3ebd3 Bump pylamarzocco to 2.2.3 (#158104) 2025-12-07 08:57:02 +01:00
Philip Cheong
319d6711c4 Add support for LockStatus.JAMMED to yalexs_ble (#157551)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-06 13:17:09 -06:00
J. Nick Koston
ea3f76c315 Bump yalexs-ble to 3.2.2 (#158124) 2025-12-06 12:16:52 -06:00
Shay Levy
b892cc1cad Revert "Remove Shelly redundant device entry check for sleepy devices" (#158108) 2025-12-06 19:40:05 +02:00
Marc Mueller
3046c7afd8 Fix shelly RuntimeWarnings in tests (#158101) 2025-12-06 11:34:24 -06:00
Raphael Hehl
73dc81034e Implement reconfiguration flow for UniFi Protect integration (#157532)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-06 11:32:43 -06:00
Jesse Hills
f306cde3b6 Add response support to esphome custom actions (#157393)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-12-06 09:48:20 -06:00
Kevin Stillhammer
38c5e483a8 add entity_picture to fressnapf_tracker (#158099) 2025-12-06 13:28:53 +01:00
Michael
ce14544ec1 Add packet loss sensor to Ping integration (#158081) 2025-12-06 10:57:31 +01:00
mettolen
87b9c3193e Add sensor entities to Airobot integration (#157938) 2025-12-06 07:57:03 +01:00
Adam Goode
061c38d2a7 Make unifi LEDs EntityCategory.CONFIG (#158088) 2025-12-06 07:51:09 +01:00
Allen Porter
e1720be5a4 Update roborock quality scale (#158024) 2025-12-05 22:52:38 +01:00
Paul Bottein
2d13a92496 Update frontend to 20251203.1 (#158069) 2025-12-05 21:25:01 +01:00
Artur Pragacz
b06bffa815 Add ai_task to core files (#158058) 2025-12-05 21:14:49 +01:00
Joost Lekkerkerker
b8f4b9515b Prevent entsoe from loading (#158036)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-12-05 21:08:57 +01:00
Petro31
3c10e9f1c0 Fix inverted kelvin issue (#158054) 2025-12-05 19:12:12 +00:00
Artur Pragacz
2dec3befcd Assign hass in Condition init (#158062) 2025-12-05 19:04:11 +00:00
J. Nick Koston
7d065bf314 Bump aiodns to 3.6.0 (#158063) 2025-12-05 20:00:09 +01:00
Raphael Hehl
3315680d0b Bump uiprotect to 7.33.2 (#158057) 2025-12-05 19:43:44 +01:00
Markus Jacobsen
ce48c89a26 Fix button event entity creation in Bang & Olufsen (#157982)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-12-05 18:39:58 +00:00
Jan Bouwhuis
f67a926f56 Move lametric URLs out of strings.json (#158051) 2025-12-05 19:35:07 +01:00
Paulus Schoutsen
e0a9d305b2 Use multiple selector for validation in AI task (#158056) 2025-12-05 18:51:18 +01:00
Jan Bouwhuis
4ff141d35e Move example image path out of translatable strings (#158053) 2025-12-05 18:05:09 +01:00
Artur Pragacz
f12a43b2b7 Mark reauthentication in music assistant quality scale (#158055) 2025-12-05 18:02:16 +01:00
Paul Tarjan
35e6f504a3 Fix doorbird duplicate unique ID generation (#158013)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-12-05 10:17:43 -06:00
Denis Shulyaka
1f68809cf9 Replace deprecated preview image model (#158048) 2025-12-05 07:55:05 -08:00
Paul Bottein
66bddebca1 Add subscribe preview feature endpoint to labs (#157976) 2025-12-05 16:36:56 +01:00
TheJulianJES
2280d779a8 Change ZHA strings for incorrect adapter state (#158021)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-12-05 16:35:34 +01:00
Maciej Bieniek
ebc608845c Do not create restart button for sleeping gen2+ Shelly devices (#158047) 2025-12-05 16:33:11 +01:00
Max Michels
5d13a41926 Move telegram-bot URLs out of strings.json (#155130)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
Co-authored-by: jbouwh <jan@jbsoft.nl>
2025-12-05 16:33:01 +01:00
Quentin Ulmer
630b40fbba Fix Rituals Perfume Genie (#151537)
Co-authored-by: Joostlek <joostlek@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-05 16:16:51 +01:00
Manu
7fd440c4a0 Add coordinator to Duck DNS integration (#158041) 2025-12-05 15:49:48 +01:00
Petro31
2a116a2a11 Fix missing template key in deprecation repair (#158033) 2025-12-05 15:30:39 +01:00
David Bonnes
f189e3b5ca Bump evohome-async to 1.0.6 (#158005) 2025-12-05 13:27:38 +01:00
wollew
4cd460351d Add Squeezebox binary sensors for player alarm status (#154491)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-12-05 11:43:19 +01:00
Johnny Willemsen
afea571c2c Enhance migration logging for home_connect (#158027) 2025-12-05 11:30:10 +01:00
Manu
e4aadd675e Add reconfigure flow to Duck DNS (#157948) 2025-12-05 10:19:05 +01:00
Abílio Costa
a47255c233 Bump whirlpool-sixth-sense to 1.0.3 (#157996) 2025-12-05 08:27:31 +01:00
hanwg
c1e7492743 Improve action descriptions for Telegram bot (#158022) 2025-12-05 08:26:42 +01:00
Kevin Stillhammer
63e8cf582f Set PARALLEL_UPDATES in fressnapf_tracker (#158008) 2025-12-05 08:21:48 +01:00
Allen Porter
73f23168a2 Bump python-roborock to 3.10.2 (#158020) 2025-12-05 08:20:41 +01:00
Mark Adkins
20d8176515 SharkIQ dep upgrade v1.5.0 (#158015) 2025-12-04 22:00:47 -05:00
Ezra Freedman
c9351a022e Add HassStopMoving intent for covers and valves (#155267)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2025-12-04 22:23:49 +01:00
epenet
4e8a31a4e2 Improve Tuya data validation (#157968)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-04 22:20:05 +01:00
johanzander
2beb551db3 Replace bare Exception with specific exceptions in Growatt (#157790) 2025-12-04 20:44:41 +01:00
Markus Jacobsen
90cea0325f Bump mozart_api to 5.3.1.108.0 (#157983) 2025-12-04 19:29:35 +00:00
dontinelli
f5dd9d83ac Bump solarlog_cli to 0.6.1 (#157845) 2025-12-04 19:24:33 +00:00
Alsatian67
e0484ba1ff Improve dev error message for YAML platform setup missing method (#155505)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-04 20:06:37 +01:00
Kevin Stillhammer
62f758f695 mark quality_scale rules done for fressnapf_tracker (#157990) 2025-12-04 20:03:53 +01:00
Abílio Costa
20d2115122 Bump oralb-ble to 1.0.2 (#157992) 2025-12-04 18:51:16 +01:00
Jan Bouwhuis
2bed7afe0e Move out example URL and IP of strings.json for reolink (#157970) 2025-12-04 18:37:30 +01:00
Petro31
2eeac5f9c9 Update template deprecation to be more explicit (#157965) 2025-12-04 18:34:01 +01:00
Abílio Costa
a35af9097b Remove uneeded async_setup_component from trigger/condition tests (#157873) 2025-12-04 17:21:30 +00:00
Luke Lashley
710b7c2b41 Bump python-Roborock to 3.10.0 (#157980) 2025-12-04 17:26:41 +01:00
Abílio Costa
c058810461 Cache flattened service descriptions in websocket api (#157510)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-12-04 16:05:49 +00:00
Kevin Stillhammer
0ccfd77fef add switch platform to fressnapf_tracker (#157971) 2025-12-04 16:44:53 +01:00
epenet
4805b33a27 Fix unit parsing in Tuya climate entities (#157964) 2025-12-04 16:17:39 +01:00
Hem Bhagat
c333036959 Move translatable URL out of strings.json for ntfy integration (#155859) 2025-12-04 16:17:16 +01:00
Petro31
002eed24f1 Fix template migration errors (#157949) 2025-12-04 16:16:58 +01:00
Jan Bouwhuis
9a9f8271b3 Move pilight URL out of strings.json (#157967) 2025-12-04 16:02:28 +01:00
Paulus Schoutsen
855d7c6e16 Extract WebRTC integration (#157648) 2025-12-04 09:44:24 -05:00
Jordan Harvey
837de55ce6 Set account number as required for Anglian Water config entry (#157939) 2025-12-04 15:39:52 +01:00
epenet
81ed259c59 Move Tuya type information classes to separate module (#157958)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-04 15:34:04 +01:00
Manu
5f00452c96 Convert image URLs to secure URLs in Xbox integration (#157945) 2025-12-04 15:12:33 +01:00
Jan Bouwhuis
06a44de3fb Move Yeelight URLs out of translatable strings for action descriptions (#157957) 2025-12-04 15:10:50 +01:00
Jan Bouwhuis
11b4d75cfb Move out zwave_js api docs url from strings.json (#157959) 2025-12-04 15:10:26 +01:00
David Rapan
845c9ee05f Fix Starlink's ever updating uptime (#155574)
Signed-off-by: David Rapan <david@rapan.cz>
2025-12-04 14:44:23 +01:00
Jordan Harvey
dedf6b1223 Add pyanglianwater to Anglian Water loggers (#157947) 2025-12-04 13:55:24 +01:00
Felipe Santos
c1b631d049 Remove Intellicode extension from devcontainer (#157894) 2025-12-04 13:43:01 +01:00
milanhin
6cc645bc6c Remove deprecation warning of step_id in ConfigFlow class (#157925) 2025-12-04 13:41:52 +01:00
Jan Bouwhuis
f10866395d Move out URL of Xiaomy_aquara from strings.json (#157937)
Co-authored-by: Michelle "MishManners®™" Duke <36594527+mishmanners@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-04 12:59:55 +01:00
Jan Bouwhuis
df68448b27 Move translatable URL from rainmachine push_weather_data action description (#157941)
Co-authored-by: Michelle "MishManners®™" Duke <36594527+mishmanners@users.noreply.github.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-12-04 12:59:15 +01:00
Abílio Costa
bf7b96622c Correct websocket commands test name (#157870) 2025-12-04 11:14:34 +00:00
Kevin Stillhammer
53c644ac5b add light platform to fressnapf_tracker (#157865) 2025-12-04 11:09:53 +01:00
starkillerOG
5e9107e52b Bump reolink_aio to 0.17.1 (#157929) 2025-12-04 10:58:25 +01:00
Jan Bouwhuis
ca9ea267c7 Move teslemetry time-of-use URL out of strings.json (#157874) 2025-12-04 10:34:51 +01:00
ryanjones-gentex
f1bfe2f11e Add HomeLink integration (#136460)
Co-authored-by: Nicholas Aelick <niaexa@syntronic.com>
2025-12-04 10:32:02 +01:00
Franck Nijhof
34cc6036b9 Merge branch 'master' into dev 2025-12-04 09:12:55 +00:00
cdnninja
2facfbadaa Add VeSync type hints and returns (#157900)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-12-04 09:19:48 +01:00
cdnninja
1b1dface35 Fix VeSync binary sensor discovery (#157898) 2025-12-04 09:14:35 +01:00
TheJulianJES
3c0cfd5e0c Display error when forming new ZHA network fails (#157863) 2025-12-03 22:37:52 -05:00
Luke Lashley
69f66ffef4 Correctly pass MopParserConfig for Roborock (#157891) 2025-12-03 17:35:51 -08:00
Norbert Rittel
d2c3543b6c Consistently use "Labs" as name in kitchen_sink (#157875) 2025-12-04 00:19:24 +01:00
Franck Nijhof
ca4a2d441e 2025.12.0 (#157330) 2025-12-03 19:06:27 +01:00
Joost Lekkerkerker
f42fe9cee3 Add button to reset hood filter to SmartThings (#157847) 2025-12-03 18:38:23 +01:00
Kevin Stillhammer
b67873f40c bump fressnapftracker to 0.2.0 (#157868) 2025-12-03 18:29:20 +01:00
Markus Jacobsen
ecc08fce0f Reduce naming verbosity in Bang & Olufsen (#157825) 2025-12-03 17:46:18 +01:00
Ludovic BOUÉ
375f536b15 Add Matter DoorPositionSensor open/closed count sensors (#155809) 2025-12-03 17:35:47 +01:00
Kevin Stillhammer
5cff813eac remove deep_sleep binary_sensor from fressnapf_tracker (#157857) 2025-12-03 17:28:59 +01:00
Franck Nijhof
c2ce322af1 Bump version to 2025.12.0 2025-12-03 16:28:33 +00:00
Thomas55555
079f306a65 Fix strings in Google Air Quality (#157862) 2025-12-03 16:28:06 +00:00
Thomas55555
9129665c64 Fix strings in Google Air Quality (#157862) 2025-12-03 17:26:21 +01:00
Franck Nijhof
7bf60f9d15 Bump version to 2025.12.0b9 2025-12-03 15:57:15 +00:00
Robert Resch
7dddd89ac2 Add retry logic to docker.io image push step (#157859) 2025-12-03 15:57:03 +00:00
Luke Lashley
a2322ef3c7 Bump Roborock to 3.9.3 (#157852) 2025-12-03 15:57:01 +00:00
Bram Kragten
5f6ef2109a Update frontend to 20251203.0 (#157851) 2025-12-03 15:57:00 +00:00
starkillerOG
44f0a8899a Bump reolink_aio to 0.17.0 (#157850) 2025-12-03 15:56:58 +00:00
Robert Resch
78fa29b41f Bump deebot-client to 17.0.0 (#157836) 2025-12-03 15:56:57 +00:00
Manu
06d4f085c0 Prevent startup blocking when a friend’s trophy summary is private on PlayStation Network (#157597)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2025-12-03 15:56:55 +00:00
Robert Resch
f4e11da1a6 Add retry logic to docker.io image push step (#157859) 2025-12-03 16:53:45 +01:00
Bram Kragten
e0238b5ab2 Update frontend to 20251203.0 (#157851) 2025-12-03 10:40:05 -05:00
Luke Lashley
352f3813e2 Bump Roborock to 3.9.3 (#157852) 2025-12-03 16:37:59 +01:00
Manu
b1399a5541 Prevent startup blocking when a friend’s trophy summary is private on PlayStation Network (#157597)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2025-12-03 16:29:51 +01:00
J. Nick Koston
316cddec86 Bump bleak to 2.0.0 (#157766) 2025-12-03 15:25:42 +00:00
starkillerOG
2f71aec26f Bump reolink_aio to 0.17.0 (#157850) 2025-12-03 16:22:02 +01:00
Joost Lekkerkerker
aa72b76ee7 Add cooktop fixture to SmartThings (#157842) 2025-12-03 15:36:29 +01:00
Erik Montnemery
e009898107 Remove template config entry from source device (#157814)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-12-03 15:24:48 +01:00
Artur Pragacz
ceb13e70b9 Add integration type to wake_on_lan (#157726)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-03 15:14:57 +01:00
Robert Resch
498a80ac7f Bump deebot-client to 17.0.0 (#157836) 2025-12-03 15:12:31 +01:00
victorigualada
a9deb2a08a Bump hass-nabucasa from 1.6.2 to 1.7.0 (#157834) 2025-12-03 13:56:01 +00:00
victorigualada
0d26d22986 Allow non strict response_format structures for Cloud LLM generation (#157822) 2025-12-03 13:55:09 +00:00
Erik Montnemery
062366966b Pin Python point release used in CI (#157819) 2025-12-03 13:53:30 +00:00
Artur Pragacz
1a60c46d67 Bump aioonkyo to 0.4.0 (#157838) 2025-12-03 14:46:52 +01:00
Matthias Alphart
62fba5ca20 Update xknx to 3.12.0 (#157835) 2025-12-03 14:40:40 +01:00
victorigualada
b54cde795c Bump hass-nabucasa from 1.6.2 to 1.7.0 (#157834) 2025-12-03 14:37:45 +01:00
victorigualada
0f456373bf Allow non strict response_format structures for Cloud LLM generation (#157822) 2025-12-03 14:31:09 +01:00
IAmStiven
a5042027b8 Add support for new ElevenLabs model Scribe v2 (#156961) 2025-12-03 14:29:25 +01:00
Franck Nijhof
1b8a50e80a Bump version to 2025.12.0b8 2025-12-03 12:16:30 +00:00
Franck Nijhof
59761385f0 Add final learn more and feedback links for purpose-specific triggers and conditions preview feature (#157830) 2025-12-03 12:16:21 +00:00
Robert Resch
6536d348e5 Prioritize default stun port over alternative (#157829) 2025-12-03 12:16:20 +00:00
Michael
c157c83d54 Add integration_type to Oralb (#157828) 2025-12-03 12:16:18 +00:00
torben-iometer
77425cc40f bump iometer to v0.3.0 (#157826) 2025-12-03 12:16:16 +00:00
Franck Nijhof
b15b5ba95c Add final learn more and feedback links for purpose-specific triggers and conditions preview feature (#157830) 2025-12-03 13:14:37 +01:00
Robert Resch
cd6e72798e Prioritize default stun port over alternative (#157829) 2025-12-03 13:14:28 +01:00
Kamil Breguła
739157e59f Simplify availability property in WLED (#157800)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-12-03 13:00:21 +01:00
torben-iometer
267aa1af42 bump iometer to v0.3.0 (#157826) 2025-12-03 12:47:05 +01:00
Michael
7328b61a69 Add integration_type to Oralb (#157828) 2025-12-03 12:46:50 +01:00
Franck Nijhof
c4b67329c3 Bump version to 2025.12.0b7 2025-12-03 10:42:56 +00:00
Allen Porter
c1f8c89bd0 Bump python-roborock to 3.9.2 (#157815)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-12-03 10:42:32 +00:00
Allen Porter
b1bf6f5678 Bump google-nest-sdm to 9.1.2 (#157812)
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Robert Resch <robert@resch.dev>
2025-12-03 10:42:30 +00:00
Josef Zweck
d347136188 Mark nordpool as service integration_type (#157810) 2025-12-03 10:42:29 +00:00
Kamil Breguła
a4319f3bf8 Update release URL in WLED (#157801) 2025-12-03 10:42:27 +00:00
Marc Mueller
db27aee62a Fix ping TypeError when killing the process (#157794) 2025-12-03 10:42:26 +00:00
Joost Lekkerkerker
a7446b3da9 Make occupancy trigger check occupancy instead of presence (#157791) 2025-12-03 10:42:24 +00:00
Stefan Agner
7fc5464621 Add storage link to low disk space repair issue (#157786)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-12-03 10:42:23 +00:00
hanwg
a00b50c195 Fix bug in group notify entities when title is missing (#157171)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-12-03 10:42:21 +00:00
Allen Porter
203f2fb364 Bump google-nest-sdm to 9.1.2 (#157812)
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Robert Resch <robert@resch.dev>
2025-12-03 11:23:00 +01:00
Josef Zweck
b956c17ce4 Mark nordpool as service integration_type (#157810) 2025-12-03 11:22:42 +01:00
Marc Mueller
5163dc0567 Fix ping TypeError when killing the process (#157794) 2025-12-03 11:22:14 +01:00
Allen Porter
31a0478717 Bump python-roborock to 3.9.2 (#157815)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-12-03 10:56:56 +01:00
dependabot[bot]
24da3f0db8 Bump actions/checkout from 6.0.0 to 6.0.1 (#157806)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 10:38:45 +01:00
dependabot[bot]
786922fc5d Bump actions/stale from 10.1.0 to 10.1.1 (#157807)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 10:36:44 +01:00
Erik Montnemery
c2f8b6986b Pin Python point release used in CI (#157819) 2025-12-03 10:26:15 +01:00
hanwg
0a0832671f Fix bug in group notify entities when title is missing (#157171)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-12-03 09:44:01 +01:00
Aidan Timson
7b353d7ad4 Add levoit virtual integration (#157618) 2025-12-03 09:38:01 +01:00
epenet
99de73a729 Update SFR Box unit of measurement (#157813) 2025-12-03 08:46:59 +01:00
Joost Lekkerkerker
1995fbd252 Make occupancy trigger check occupancy instead of presence (#157791) 2025-12-03 08:15:31 +01:00
Kamil Breguła
315ea9dc76 Update release URL in WLED (#157801) 2025-12-03 05:55:03 +01:00
Josef Zweck
639a96f8cb La Marzocco add Bluetooth offline mode (#157011) 2025-12-03 05:53:27 +01:00
Stefan Agner
b6786c5a42 Add storage link to low disk space repair issue (#157786)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-12-02 22:14:24 -05:00
Kamil Breguła
6f6e9b8057 Add quality scale for WLED (#155482)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-12-03 01:19:02 +01:00
johanzander
e0c687e415 Remove extra logging in Growatt (#157788) 2025-12-03 00:38:03 +01:00
Abestanis
982362110c Allow to configure KNX time, date & datetime entities via UI (#157603) 2025-12-02 23:45:43 +01:00
Lukas
90dc3a8fdf Pooldose: add number platform (#157787) 2025-12-02 23:31:44 +01:00
J. Nick Koston
5112742b71 Bump habluetooth to 5.8.0 (#157771) 2025-12-02 15:55:37 -06:00
johanzander
8899bc01bd Add bronze quality scale to Growatt Server integration (#154649)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-12-02 22:36:51 +01:00
Franck Nijhof
738fb59efa Bump version to 2025.12.0b6 2025-12-02 21:23:23 +00:00
Joris Pelgröm
04e512a48e Bump letpot to 0.6.4 (#157781) 2025-12-02 21:23:12 +00:00
Michael Hansen
c63aca2d9b Bump hassil to 3.5.0 (#157780) 2025-12-02 21:23:11 +00:00
Kamil Breguła
c95203e095 Handle unsupported version in WLED (#157778)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-12-02 21:23:09 +00:00
Josef Zweck
259235ceeb Add integration_type for tedee (#157776) 2025-12-02 21:23:08 +00:00
Paulus Schoutsen
c7f1729300 Allow fetching the Cloud ICE servers (#157774) 2025-12-02 21:23:06 +00:00
puddly
065329e668 Fix ZHA network formation (#157769) 2025-12-02 21:23:05 +00:00
Marcel van der Veldt
a93ed69fe4 Let AuthenticationRequired also trigger the reauth flow in MusicAssistant (#157580) 2025-12-02 21:23:04 +00:00
Sab44
189497622d Fix orphaned devices not being removed during integration startup (#155900) 2025-12-02 21:23:02 +00:00
Joris Pelgröm
ed8f9105ff Bump letpot to 0.6.4 (#157781) 2025-12-02 22:12:41 +01:00
Michael Hansen
185de98f5e Bump hassil to 3.5.0 (#157780) 2025-12-02 22:11:00 +01:00
Paulus Schoutsen
e857abb43f Allow fetching the Cloud ICE servers (#157774) 2025-12-02 16:02:30 -05:00
Joost Lekkerkerker
5b1829f3a1 Add hood filter usage entity to SmartThings (#157775) 2025-12-02 21:45:17 +01:00
Kamil Breguła
520156a33a Handle unsupported version in WLED (#157778)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-12-02 21:20:36 +01:00
Kevin Stillhammer
e3b5342b76 use sentence casing in binary_sensor for fressnapf_tracker (#157772) 2025-12-02 21:06:18 +01:00
Josef Zweck
951b19e80c Add integration_type for tedee (#157776) 2025-12-02 21:04:51 +01:00
Sab44
e2351ecec2 Fix orphaned devices not being removed during integration startup (#155900) 2025-12-02 21:03:37 +01:00
Joost Lekkerkerker
d75e5498c6 Add health concern entities to SmartThings (#157773) 2025-12-02 21:00:50 +01:00
puddly
2dd58dbe39 Fix ZHA network formation (#157769) 2025-12-02 14:59:55 -05:00
Joost Lekkerkerker
4ef17799db Add snapshot test to Vivotek (#157767) 2025-12-02 20:47:02 +01:00
Joost Lekkerkerker
9373378350 Add fixture for hood to SmartThings (#157770) 2025-12-02 20:46:06 +01:00
Marcel van der Veldt
18833a194b Let AuthenticationRequired also trigger the reauth flow in MusicAssistant (#157580) 2025-12-02 14:22:40 -05:00
Kevin Stillhammer
2631c77bee add platform binary_sensor to fressnapf_tracker (#157753) 2025-12-02 20:05:34 +01:00
Kevin McCormack
c67247bf32 Add config flow for Vivotek integration (#154801)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-12-02 19:47:22 +01:00
Joost Lekkerkerker
18b5ffd365 Add SmartThings walloven fixtures (#157748) 2025-12-02 19:32:28 +01:00
Franck Nijhof
a466fc4a01 Bump version to 2025.12.0b5 2025-12-02 18:19:42 +00:00
Matthias Alphart
8a968b5d0e Add integration_type for Fronius (#157760) 2025-12-02 18:19:13 +00:00
Michael Hansen
3baee5c4ac Bump intents to 2025.12.2 (#157758) 2025-12-02 18:17:57 +00:00
Bram Kragten
f624a43770 Update frontend to 20251202.0 (#157755)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-12-02 18:16:17 +00:00
Artur Pragacz
242935774b Add integration type to ping (#157730)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 18:14:17 +00:00
Artur Pragacz
051ad5878f Add integration type to rest (#157728)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 18:14:16 +00:00
Artur Pragacz
b2156c1d4c Add integration type to speedtestdotnet (#157727)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 18:14:15 +00:00
Artur Pragacz
7d4394f7ed Add integration type to google_translate (#157718)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 18:14:14 +00:00
Brett Adams
4df172374c Add integration_type to Tesla Fleet manifest (#157679) 2025-12-02 18:14:13 +00:00
Brett Adams
c97755472e Add integration_type to Teslemetry manifest (#157677) 2025-12-02 18:14:11 +00:00
Erik Montnemery
ebc9060b01 Improve trigger descriptions (#157643)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-12-02 18:14:10 +00:00
Erik Montnemery
bbcc2a94b3 Add occupancy binary sensor triggers (#157631) 2025-12-02 18:14:09 +00:00
victorigualada
692188fa85 Don't register Home Assistant Cloud LLM platforms if not logged in (#157630) 2025-12-02 18:14:08 +00:00
Jordan Harvey
2c993ea5a2 Fix Anglian Water sensor setup (#157457) 2025-12-02 18:14:06 +00:00
Bram Kragten
c4e3a4d65e Update frontend to 20251202.0 (#157755)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-12-02 17:50:13 +01:00
victorigualada
84d2686517 Don't register Home Assistant Cloud LLM platforms if not logged in (#157630) 2025-12-02 17:47:08 +01:00
Michael Hansen
ae8980ce5b Bump intents to 2025.12.2 (#157758) 2025-12-02 17:43:21 +01:00
epenet
b2d4c9ecb4 Add exception translation to SFR box (#157756) 2025-12-02 17:42:16 +01:00
Matthias Alphart
f5b046ee7d Add integration_type for Fronius (#157760) 2025-12-02 17:31:05 +01:00
epenet
55c5fb7374 Migrate Tuya climate (swing) to use wrapper class (#157646) 2025-12-02 17:24:36 +01:00
Erik Montnemery
5d78cd328a Remove explicit templating of velbus service data (#157749) 2025-12-02 17:00:10 +01:00
epenet
bc36578ada Add mac address to SFR Box device registry entries (#157752) 2025-12-02 16:52:09 +01:00
Erik Montnemery
e63242e465 Add occupancy binary sensor triggers (#157631) 2025-12-02 16:37:02 +01:00
epenet
e84c09745d Bump SFR box IQS to silver (#157754) 2025-12-02 16:32:38 +01:00
Julian Meier
f07991d0ba Add boot and energy sensor to MyStrom Switch (#155132) 2025-12-02 15:42:04 +01:00
epenet
872fef1f6f Add reconfigure flow to SFR Box (#157711) 2025-12-02 15:35:25 +01:00
Kevin Stillhammer
c866dc973c Add sensor platform to fressnapf_tracker (#157658)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-02 15:33:57 +01:00
Zoltán Farkasdi
e2acf30637 Add Netatmo outdoor camera test (#156740) 2025-12-02 15:01:47 +01:00
epenet
29631a2c5a Cleanup SFR Box sensors (#157708) 2025-12-02 14:52:52 +01:00
Heindrich Paul
1d31e6d0ea Create more sensors for Nederlandse Spoorwegen (#154466)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-12-02 14:39:05 +01:00
Franck Nijhof
c765776726 Bump version to 2025.12.0b4 2025-12-02 12:42:32 +00:00
Robert Resch
723365d8e6 Create the go2rtc unix socket inside a temporary folder (#157742) 2025-12-02 12:42:13 +00:00
Artur Pragacz
3d8e136049 Add integration type to xiaomi_ble (#157740)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:11 +00:00
Artur Pragacz
2fe9fc7ee3 Add integration type to broadlink (#157739)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:10 +00:00
Artur Pragacz
e11e31a1a0 Add integration type to ring (#157738)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:09 +00:00
Artur Pragacz
989407047d Add integration type to roborock (#157737)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:08 +00:00
Artur Pragacz
6d3087c5a4 Add integration type to webostv (#157736)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:06 +00:00
Artur Pragacz
9bd3c35231 Add integration type to tplink (#157735)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:05 +00:00
Artur Pragacz
b7e97971cf Add integration type to ibeacon (#157734)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:04 +00:00
Artur Pragacz
4d232c63f8 Add integration type to dlna_dmr (#157733)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:03 +00:00
Artur Pragacz
6fc000ee2a Add integration type to google (#157729)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:02 +00:00
Artur Pragacz
623d3ecde5 Add integration type to music_assistant (#157725)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:00 +00:00
Artur Pragacz
0fbb3215b4 Add integration type to dlna_dms (#157723)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:59 +00:00
Artur Pragacz
c82ce1ff89 Add integration type to met (#157720)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:58 +00:00
Franck Nijhof
8c891a20e5 Rename preview feature to purpose-specific triggers and conditions (#157717) 2025-12-02 12:41:57 +00:00
Erik Montnemery
97c50b2d86 Improve helpers.condition.async_subscribe_platform_events (#157710) 2025-12-02 12:41:55 +00:00
Erik Montnemery
ef4062a565 Improve helpers.trigger.async_subscribe_platform_events (#157709) 2025-12-02 12:41:54 +00:00
cdnninja
e31cce5d9b Bump pyvesync to 3.3.3 (#157697) 2025-12-02 12:41:53 +00:00
Paulus Schoutsen
21f6b9a53a Add integration_type to Nuki Bridge manifest (#157683)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:52 +00:00
Paulus Schoutsen
047e549112 Add integration_type to Motionblinds manifest (#157682)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:51 +00:00
Paulus Schoutsen
4c4aecd9a7 Add integration_type to Konnected.io manifest (#157681) 2025-12-02 12:41:50 +00:00
Paulus Schoutsen
733496ff3f Add integration_type to HomeWizard Energy manifest (#157680)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:49 +00:00
Paulus Schoutsen
f682e93243 Add integration_type to Tessie manifest (#157676)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:48 +00:00
Paulus Schoutsen
c8fa5b0290 Add integration_type to SwitchBot Bluetooth manifest (#157675)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:46 +00:00
Paulus Schoutsen
8ff2a22664 Add integration_type to Sonos manifest (#157674)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:45 +00:00
Paulus Schoutsen
c174ab2d96 Add integration_type to SmartThings manifest (#157673) 2025-12-02 12:41:44 +00:00
Paulus Schoutsen
10f0ff7bd7 Add integration_type to Reolink manifest (#157672)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:43 +00:00
Paulus Schoutsen
4a4eb33bf7 Add integration_type to HomeKit Device manifest (#157671)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:42 +00:00
Paulus Schoutsen
8199c4e5de Add integration_type to Home Connect manifest (#157668)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:40 +00:00
Paulus Schoutsen
0bfa8318a7 Add integration_type to Ecowitt manifest (#157666) 2025-12-02 12:41:39 +00:00
Paulus Schoutsen
ed66a4920c Add integration_type to Apple TV manifest (#157664)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:41:38 +00:00
Åke Strandberg
f51007c448 Add program id:s and phases to new Miele WQ1000 (#157660) 2025-12-02 12:41:37 +00:00
TheJulianJES
bd44402b04 Set Matter integration type to "hub" (#157657) 2025-12-02 12:41:36 +00:00
TheJulianJES
99fa92d966 Set ZHA integration type to "hub" (#157656) 2025-12-02 12:41:35 +00:00
Arjan
1cb8f19020 Meteo France: add new mapping "Brouillard dense givrant" (#157627) 2025-12-02 12:41:33 +00:00
Copilot
81cdbdd4df Add labs_updated event to subscription allowlist (#157552)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: balloob <1444314+balloob@users.noreply.github.com>
2025-12-02 12:41:32 +00:00
Artur Pragacz
8109d9a39c Add integration type to music_assistant (#157725)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 13:38:08 +01:00
Artur Pragacz
e1abd451b8 Add integration type to google (#157729)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 13:37:37 +01:00
Robert Resch
2c72cd94f2 Create the go2rtc unix socket inside a temporary folder (#157742) 2025-12-02 13:35:39 +01:00
Franck Nijhof
3bccb4b89c Rename preview feature to purpose-specific triggers and conditions (#157717) 2025-12-02 13:34:52 +01:00
Artur Pragacz
6d4fb30630 Add integration type to tplink (#157735)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 13:24:21 +01:00
Artur Pragacz
c04411f1bc Add integration type to dlna_dmr (#157733)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:48:59 +01:00
Artur Pragacz
753ea023de Add integration type to ibeacon (#157734)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:48:33 +01:00
Artur Pragacz
1ca1cf59eb Add integration type to ring (#157738)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:44:09 +01:00
Artur Pragacz
5b01bb1a29 Add integration type to broadlink (#157739)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:43:19 +01:00
Artur Pragacz
15c89d24eb Add integration type to xiaomi_ble (#157740)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:21 +01:00
Artur Pragacz
b26b2347e6 Add integration type to roborock (#157737)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:42:10 +01:00
Artur Pragacz
7d54103c09 Add integration type to speedtestdotnet (#157727)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:27:25 +01:00
Artur Pragacz
c705a1dc4b Add integration type to rest (#157728)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:26:02 +01:00
Artur Pragacz
998bd23446 Add integration type to webostv (#157736)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:25:37 +01:00
Artur Pragacz
3a1a58d6ad Add integration type to ping (#157730)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:23:19 +01:00
Artur Pragacz
f9219dd841 Add integration type to dlna_dms (#157723)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 12:04:17 +01:00
Artur Pragacz
402ed7e0f3 Add integration type to met (#157720)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 11:51:51 +01:00
epenet
7a1a5df89e Use _async_send_commands in Tuya base entity (#157716) 2025-12-02 11:50:07 +01:00
Artur Pragacz
df558fc1e7 Add integration type to google_translate (#157718)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 11:47:30 +01:00
Erik Montnemery
ec66407ef1 Improve helpers.condition.async_subscribe_platform_events (#157710) 2025-12-02 11:32:14 +01:00
Paulus Schoutsen
6b99234a43 Add integration_type to SwitchBot Bluetooth manifest (#157675)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 11:31:04 +01:00
Erik Montnemery
393be71009 Improve trigger descriptions (#157643)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-12-02 11:08:39 +01:00
epenet
12bc1687ec Use _async_send_commands in Tuya vacuum (#157704) 2025-12-02 11:01:51 +01:00
epenet
c59b322c0a Use _async_send_commands in Tuya light (#157703) 2025-12-02 11:01:38 +01:00
Arjan
e00266463d Meteo France: add new mapping "Brouillard dense givrant" (#157627) 2025-12-02 10:55:51 +01:00
dependabot[bot]
cbc8a33553 Bump github/codeql-action from 4.31.5 to 4.31.6 (#157700)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 10:52:13 +01:00
Paulus Schoutsen
28582f75d4 Add integration_type to Ecowitt manifest (#157666) 2025-12-02 10:49:58 +01:00
J. Diego Rodríguez Royo
39cccd212d Bump aiohomeconnect to version 0.24.0 (#157670) 2025-12-02 10:46:37 +01:00
Brett Adams
329ea33337 Add integration_type to Teslemetry manifest (#157677) 2025-12-02 10:45:41 +01:00
Brett Adams
521733c420 Revert integration type in Tessie (#157713) 2025-12-02 10:45:21 +01:00
Brett Adams
33e9f9a0ff Add integration_type to Tesla Fleet manifest (#157679) 2025-12-02 10:44:49 +01:00
Erik Montnemery
5fda2bccbe Improve helpers.trigger.async_subscribe_platform_events (#157709) 2025-12-02 10:37:19 +01:00
Åke Strandberg
ae75332656 Add program id:s and phases to new Miele WQ1000 (#157660) 2025-12-02 09:25:47 +01:00
Paulus Schoutsen
b171785f96 Add integration_type to SmartThings manifest (#157673) 2025-12-02 09:17:49 +01:00
Paulus Schoutsen
ff3d6783c6 Add integration_type to Konnected.io manifest (#157681) 2025-12-02 09:15:18 +01:00
cdnninja
b1e579bea0 Bump pyvesync to 3.3.3 (#157697) 2025-12-02 09:14:41 +01:00
Jan Bouwhuis
87241ea051 Add read support for MQTT config entry version to 2.1 (#157623) 2025-12-02 08:02:06 +01:00
dependabot[bot]
a871ec0bdf Bump home-assistant/wheels from 2025.11.0 to 2025.12.0 (#157699) 2025-12-02 07:41:44 +01:00
Copilot
b8829b645a Add labs_updated event to subscription allowlist (#157552)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: balloob <1444314+balloob@users.noreply.github.com>
2025-12-02 07:35:29 +01:00
Paulus Schoutsen
5b056a83d4 Add integration_type to Motionblinds manifest (#157682)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 07:15:11 +01:00
Paulus Schoutsen
02a70123c1 Add integration_type to HomeWizard Energy manifest (#157680)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 00:04:08 -05:00
Paulus Schoutsen
5f6d2f537a Add integration_type to Tessie manifest (#157676)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 23:50:35 -05:00
Paulus Schoutsen
5e04e9f04d Add integration_type to Home Connect manifest (#157668)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 23:49:39 -05:00
Paulus Schoutsen
56515ad7b5 Add integration_type to Sonos manifest (#157674)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 05:03:53 +01:00
Paulus Schoutsen
a1fe2bf4fa Add integration_type to HomeKit Device manifest (#157671)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 05:02:59 +01:00
Paulus Schoutsen
b8fa8efd91 Add integration_type to Apple TV manifest (#157664)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 05:01:56 +01:00
Jesse Hills
03557b5ef2 Bump aioesphomeapi to 42.10.0 (#157678) 2025-12-01 20:59:35 -05:00
Paulus Schoutsen
dafec8ce58 Add integration_type to Reolink manifest (#157672)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 20:58:51 -05:00
Paulus Schoutsen
6ff3f74347 Add integration_type to Nuki Bridge manifest (#157683)
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 20:58:03 -05:00
karwosts
ddd8cf7fde Fix a bad script error message (#157654) 2025-12-01 15:19:30 -05:00
TheJulianJES
1356eea52f Set Matter integration type to "hub" (#157657) 2025-12-01 15:18:55 -05:00
TheJulianJES
6188e0e39b Set ZHA integration type to "hub" (#157656) 2025-12-01 15:18:49 -05:00
Franck Nijhof
c82706eaf5 Bump version to 2025.12.0b3 2025-12-01 19:26:30 +00:00
andreimoraru
07f9bec8b6 bump yt-dlp to 2025.11.12 (#157645) 2025-12-01 19:26:14 +00:00
Åke Strandberg
33d576234b Add code mappings for Miele WQ1000 (#157642) 2025-12-01 19:26:13 +00:00
Bram Kragten
9e2b4615f1 Update frontend to 20251201.0 (#157638) 2025-12-01 19:26:11 +00:00
Petro31
a46dc7e05f Reload config entry templates when labs flag automation.new_triggers_conditions is set (#157637)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-12-01 19:26:09 +00:00
Erik Montnemery
7dd9953345 Bump area registry to version 1.9 and sort areas (#157634) 2025-12-01 19:26:08 +00:00
Maciej Bieniek
1145026190 Bump aioshelly to version 13.22.0 (#157629) 2025-12-01 19:26:06 +00:00
Erik Montnemery
d8f9574bc3 Remove cover triggers (#157621) 2025-12-01 19:26:05 +00:00
Erik Montnemery
e91f8d3a81 Remove description_configured from condition and trigger translations (#157620) 2025-12-01 19:26:04 +00:00
Aidan Timson
8c0fd0565e Default area icons for new instances (#157619) 2025-12-01 19:26:02 +00:00
Paul Bottein
cc620fc0f8 Fix user store not loaded on restart (#157616) 2025-12-01 19:26:00 +00:00
Erik Montnemery
5a89332680 Bump floor registry to version 1.3 and sort floors (#157614)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-12-01 19:25:59 +00:00
LG-ThinQ-Integration
1831c5e249 Bump thinqconnect to 1.0.9 (#157607) 2025-12-01 19:25:57 +00:00
cdnninja
dddd2503ea Bump pyvesync to 3.3.2 (#157605) 2025-12-01 19:25:56 +00:00
Norbert Rittel
91ba510a1e Fix spelling of "to log in" in anglian_water (#157594) 2025-12-01 19:25:54 +00:00
Norbert Rittel
6e5e739496 Fix spelling of "to set up" in hue_ble (#157593) 2025-12-01 19:25:53 +00:00
Sanjay Govind
6b39eb069c Bump bosch-alarm-mode2 to v0.4.10 (#157564) 2025-12-01 19:25:51 +00:00
Allen Porter
847c332c70 Bump google-nest-sdm to 9.1.1 (#157562) 2025-12-01 19:25:50 +00:00
J. Nick Koston
1a19f3b527 Bump aioesphomeapi to 42.9.0 (#157558) 2025-12-01 19:25:49 +00:00
Thomas55555
8110935d2d Bump google air quality api to 1.1.3 (#157555) 2025-12-01 19:25:47 +00:00
Raphael Hehl
af69da94f5 Bump uiprotect to 7.31.0 (#157543) 2025-12-01 19:25:46 +00:00
Jan Bouwhuis
c1cf17d4db Fix MQTT entity cannot be renamed (#157540) 2025-12-01 19:25:44 +00:00
Allen Porter
6079637909 Bump python-roborock to 3.8.4 (#157538) 2025-12-01 19:25:43 +00:00
Jordan Harvey
9268e12b20 Disable cookie quotes for Anglian Water (#157518) 2025-12-01 19:25:41 +00:00
Raphael Hehl
d07993f4a4 Fix UniFi Protect RTSP repair warnings when globally disabled (#157516) 2025-12-01 19:25:40 +00:00
Allen Porter
441cb4197c Bump python-roborock to 3.8.3 (#157512) 2025-12-01 19:25:38 +00:00
J. Nick Koston
d2a095588d Bump ESPHome stable BLE version to 2025.11.0 (#157511) 2025-12-01 19:25:37 +00:00
Arie Catsman
f2578da7db Bump pyenphase to 2.4.2 (#157500) 2025-12-01 19:25:35 +00:00
Jan Bouwhuis
22200d6804 Fix subentry ID is not updated when renaming the entity ID (#157498) 2025-12-01 19:25:34 +00:00
Maciej Bieniek
8a4e5c3a28 Remove name from Shelly RGBCCT sensors (#157492) 2025-12-01 19:25:32 +00:00
Maciej Bieniek
30f31c7d8c Remove name for Shelly gas valve (gen1) entity (#157490) 2025-12-01 19:25:30 +00:00
Maciej Bieniek
232c4255a1 Add missing string for Shelly away mode switch (#157488) 2025-12-01 19:25:28 +00:00
Petro31
236f7cd22c Ensure platform template does not appear in repair (#157486) 2025-12-01 19:25:27 +00:00
Åke Strandberg
5948ff2e31 Add loggers to senz manifest (#157479) 2025-12-01 19:25:25 +00:00
epenet
380127bc70 Fix blocking call in Tuya initialisation (#157477) 2025-12-01 19:25:23 +00:00
epenet
b6a1e8251a Remove unnecessary instanciating in Tuya find_dpcode (#157473) 2025-12-01 19:25:22 +00:00
David Woodhouse
c20236717c Clarify percentage_command_topic and percentage_state_topic for MQTT fan (#157460)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2025-12-01 19:25:21 +00:00
Artur Pragacz
1fd9feaace Provide log info for discovered flows in logger (#157454) 2025-12-01 19:25:19 +00:00
ElectricSteve
7ce072b4dc bump: youtubeaio to 2.1.1 (#157452) 2025-12-01 19:25:17 +00:00
Artur Pragacz
45aa0399c7 Add tools in default agent also in fallback pipeline (#157441) 2025-12-01 19:25:16 +00:00
Hem Bhagat
d82b3871c1 Move translatable URLs out of strings.json for opentherm_gw integration (#157437) 2025-12-01 19:25:14 +00:00
Thomas55555
8f6d1162e5 Fix strings in Google Air Quality (#157297) 2025-12-01 19:21:28 +00:00
puddly
dafce97341 Disable owning integrations for the entire firmware interaction process (#157082) 2025-12-01 19:21:26 +00:00
Sebastian Schneider
ffd5d33bbc Support UniFi LED control for devices without RGB (#156812) 2025-12-01 19:21:24 +00:00
Aidan Timson
699fa1617d Default area icons for new instances (#157619) 2025-12-01 20:02:38 +01:00
Erik Montnemery
449f0fa5a5 Bump floor registry to version 1.3 and sort floors (#157614)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-12-01 19:54:43 +01:00
andreimoraru
2e008d2bb7 bump yt-dlp to 2025.11.12 (#157645) 2025-12-01 19:44:54 +01:00
Petro31
05dec2619d Ensure platform template does not appear in repair (#157486) 2025-12-01 19:38:49 +01:00
Paul Bottein
25a6778ba8 Fix user store not loaded on restart (#157616) 2025-12-01 19:37:27 +01:00
epenet
f564b8cb44 Remove unnecessary instanciating in Tuya find_dpcode (#157473) 2025-12-01 19:37:06 +01:00
Erik Montnemery
ce6bfdebfc Improve typing of floor registry events (#157624) 2025-12-01 19:36:50 +01:00
Bram Kragten
f00a944ac1 Update frontend to 20251201.0 (#157638) 2025-12-01 19:28:18 +01:00
Petro31
3073a99ce6 Reload config entry templates when labs flag automation.new_triggers_conditions is set (#157637)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-12-01 19:27:30 +01:00
Erik Montnemery
8b04ce1328 Bump area registry to version 1.9 and sort areas (#157634) 2025-12-01 19:26:17 +01:00
Andrew Jackson
39f76787ab Allow multiline post in Mastodon (#157647) 2025-12-01 18:35:59 +01:00
puddly
e8acced335 Disable owning integrations for the entire firmware interaction process (#157082) 2025-12-01 18:18:32 +01:00
Åke Strandberg
758a30eebc Add code mappings for Miele WQ1000 (#157642) 2025-12-01 17:28:02 +01:00
epenet
faf94bea24 Use read_wrapper entity helper in Tuya (#157632) 2025-12-01 17:00:08 +01:00
epenet
ff91c57228 Adjust Tuya wrapper to return a command list (#157622) 2025-12-01 16:59:26 +01:00
epenet
3d2b506997 Rename Tuya method (#157640) 2025-12-01 16:56:46 +01:00
Kevin Stillhammer
d3c1c28605 Add integration fressnapf_tracker (#157480)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-01 16:48:30 +01:00
mettolen
d4e1f7741d Add sensor entities to Saunum integration (#157342)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-01 16:47:00 +01:00
mettolen
e713632eed Add reauth flow to Airobot integration (#157501) 2025-12-01 16:28:10 +01:00
Maciej Bieniek
060ad35ddc Bump aioshelly to version 13.22.0 (#157629) 2025-12-01 15:47:53 +01:00
Erik Montnemery
6c5dba40cd Remove cover triggers (#157621) 2025-12-01 14:09:29 +01:00
Erik Montnemery
a04d595424 Remove description_configured from condition and trigger translations (#157620) 2025-12-01 12:57:07 +01:00
Lukas
fe85eaf2a2 Pooldose: Add sensors for water meter (#157382) 2025-12-01 11:43:50 +01:00
Raphael Hehl
3551c4b01f Fix UniFi Protect G6 Instant speaker volume control (#157549) 2025-12-01 11:38:34 +01:00
Shay Levy
e7edd51a65 Refactor Shelly number platform to use upstream set_thermostat_state (#157527)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-01 12:37:12 +02:00
Raphael Hehl
0c4f2326ef Use public API for UniFi Protect light brightness control (#157550) 2025-12-01 11:32:03 +01:00
dependabot[bot]
81f4456d7c Bump actions/ai-inference from 2.0.3 to 2.0.4 (#157608)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 11:04:04 +01:00
Maciej Bieniek
2b608bf15c Remove name from Shelly RGBCCT sensors (#157492) 2025-12-01 10:54:19 +01:00
karwosts
972ed4b27f Finish removal of sensor.sun_solar_rising (#157606) 2025-12-01 09:26:54 +01:00
LG-ThinQ-Integration
23c167da1b Bump thinqconnect to 1.0.9 (#157607) 2025-12-01 09:26:01 +01:00
Jan Bouwhuis
34d6938171 Fix subentry ID is not updated when renaming the entity ID (#157498) 2025-12-01 07:55:13 +01:00
Kevin Stillhammer
4bb8590076 Revert "Force httpx client to use IPv4 for waze_travel_time" (#157596) 2025-12-01 06:35:26 +01:00
Norbert Rittel
5e0923b60d Fix spelling of "to set up" in hue_ble (#157593) 2025-12-01 06:33:18 +01:00
Norbert Rittel
ad48f3c634 Fix spelling of "to log in" in anglian_water (#157594) 2025-12-01 06:32:54 +01:00
cdnninja
2bdd6854eb Bump pyvesync to 3.3.2 (#157605) 2025-11-30 23:41:46 -05:00
Lukas
0bf906911c pooldose bump to api 0.8.1 (#157591) 2025-11-30 23:49:40 +01:00
Ludovic BOUÉ
874d6f5613 Add Matter fixture for Eufy vacuum Omni E28 (#157590) 2025-11-30 21:47:31 +01:00
Raphael Hehl
43ba10eebd Add missing translations for UniFi Protect integration (#157570) 2025-11-30 17:05:05 +01:00
Sanjay Govind
64bed19805 Bump bosch-alarm-mode2 to v0.4.10 (#157564) 2025-11-30 16:02:43 +01:00
Shay Levy
6357067f0f Rename Shelly SENSORS to BLOCK_SENSORS to match naming in other platforms (#157553) 2025-11-30 12:48:35 +02:00
Thomas55555
e328ba4045 Bump google air quality api to 1.1.3 (#157555) 2025-11-30 07:17:36 +01:00
Allen Porter
332dbddce6 Bump google-nest-sdm to 9.1.1 (#157562) 2025-11-29 23:19:44 -05:00
J. Nick Koston
82d935a819 Bump aioesphomeapi to 42.9.0 (#157558) 2025-11-29 18:04:55 -06:00
Raphael Hehl
4b84998c0c Fix UFPConfigEntry type consistency in unifiprotect (#157548) 2025-11-29 17:07:44 -06:00
Raphael Hehl
e10c1ebcf6 Fix UniFi Protect RTSP repair warnings when globally disabled (#157516) 2025-11-29 22:53:34 +02:00
Raphael Hehl
0174bad182 Add PARALLEL_UPDATES to UniFi Protect platforms (#157504) 2025-11-29 19:48:43 +01:00
Allen Porter
d5be623684 Bump python-roborock to 3.8.4 (#157538) 2025-11-29 20:34:27 +02:00
Raphael Hehl
d006b044c8 Bump uiprotect to 7.31.0 (#157543) 2025-11-29 20:33:09 +02:00
Jan Bouwhuis
fdd9571623 Fix MQTT entity cannot be renamed (#157540) 2025-11-29 19:29:54 +01:00
Shay Levy
4f4c5152b9 Refactor Shelly setup to use async_setup_entry_block for block entities (#157517) 2025-11-29 18:08:12 +02:00
Denis Shulyaka
b031a082cd Bump anthropic to 0.75.0 (#157491) 2025-11-29 14:35:30 +01:00
Shay Levy
a1132195fd Refactor Shelly RPC event platform to use base class (#157499) 2025-11-29 13:09:32 +02:00
Jordan Harvey
708b3dc8b2 Disable cookie quotes for Anglian Water (#157518) 2025-11-29 11:52:55 +01:00
J. Nick Koston
8ae0216135 Bump ESPHome stable BLE version to 2025.11.0 (#157511) 2025-11-29 03:40:22 -06:00
David Woodhouse
1472281cd5 Clarify percentage_command_topic and percentage_state_topic for MQTT fan (#157460)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2025-11-29 02:47:34 -06:00
Allen Porter
ceaa71d198 Bump python-roborock to 3.8.3 (#157512) 2025-11-29 09:34:22 +01:00
Arie Catsman
7f0d0c555a Bump pyenphase to 2.4.2 (#157500) 2025-11-28 21:58:57 +01:00
steaura
3b94b2491a Update bootstrap.py for grammar in slow startup error log (#157458) 2025-11-28 19:34:30 +01:00
Sebastian Schneider
8c8708d5bc Support UniFi LED control for devices without RGB (#156812) 2025-11-28 17:33:15 +01:00
Maciej Bieniek
ca35102138 Remove name for Shelly gas valve (gen1) entity (#157490) 2025-11-28 15:26:17 +01:00
Maciej Bieniek
1a1b50ef1a Add missing string for Shelly away mode switch (#157488) 2025-11-28 16:07:40 +02:00
epenet
5a4d51e57a Mark config-flow-test-coverage as done in SFR Box IQS (#157485) 2025-11-28 12:46:01 +01:00
epenet
9e1bc637e2 Improve diagnostics tests in SFR Box API (#157483) 2025-11-28 11:58:33 +01:00
Joakim Plate
ab879c07ca Add logbook support for args same as params for zha (#154997) 2025-11-28 11:15:49 +01:00
Hem Bhagat
488c97531e Move translatable URLs out of strings.json for opentherm_gw integration (#157437) 2025-11-28 10:45:45 +01:00
epenet
3b52c5df79 Use snapshot_platform helper in SFR Box tests (#157481) 2025-11-28 10:44:39 +01:00
Shay Levy
7f4b56104d Update Shelly utils coverage to 100% (#157478) 2025-11-28 11:32:41 +02:00
Åke Strandberg
ab8135ba1a Add loggers to senz manifest (#157479) 2025-11-28 10:19:28 +01:00
epenet
a88599bc09 Improve tests in SFR Box (#157444)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-28 10:10:38 +01:00
Manuel Stahl
45034279c8 Update pystiebeleltron to 0.2.5 (#157450) 2025-11-28 09:48:51 +01:00
Artur Pragacz
9f3dae6254 Add tools in default agent also in fallback pipeline (#157441) 2025-11-28 09:47:52 +01:00
epenet
ef36d7b1e5 Fix blocking call in Tuya initialisation (#157477) 2025-11-28 09:45:28 +01:00
dependabot[bot]
e5346ba017 Bump home-assistant/builder from 2025.09.0 to 2025.11.0 (#157468)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-28 09:30:37 +01:00
dependabot[bot]
68d41d2a48 Bump docker/metadata-action from 5.9.0 to 5.10.0 (#157467)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-28 09:30:22 +01:00
dependabot[bot]
00a882c20a Bump actions/ai-inference from 2.0.2 to 2.0.3 (#157466)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-28 09:28:59 +01:00
Jordan Harvey
44a6772947 Fix Anglian Water sensor setup (#157457) 2025-11-28 07:25:04 +01:00
cdnninja
f874ba1355 Move device_info to attribute in vesync (#157462) 2025-11-28 07:20:50 +01:00
Allen Porter
4fc125c49a Improve Nest error message wording in test before setup (#157465) 2025-11-28 07:19:54 +01:00
Artur Pragacz
8c59196e19 Provide log info for discovered flows in logger (#157454) 2025-11-28 02:13:10 +01:00
Shay Levy
326f7f0559 Add coverage to Shelly utils (#157455) 2025-11-28 00:29:47 +02:00
ElectricSteve
11afda8c22 bump: youtubeaio to 2.1.1 (#157452) 2025-11-27 22:42:57 +01:00
StaleLoafOfBread
f1ee0e4ac9 Add support for gallons per day as a unit of volume flow rate (#157394) 2025-11-27 20:42:16 +01:00
Joakim Plate
5f522e5afa Fix cancel propagation in update coordinator and config entry (#153504) 2025-11-27 19:48:45 +01:00
Thomas55555
4f6624d0aa Fix strings in Google Air Quality (#157297) 2025-11-27 19:26:33 +01:00
epenet
70990645a7 Mark config-flow as done in SFR Box IQS (#157439) 2025-11-27 19:14:13 +01:00
Andrew Jackson
2f7d74ff62 Add icons to transmission entities (#157436) 2025-11-27 18:38:32 +01:00
epenet
885667832b Add initial IQS to sfr_box (#155419) 2025-11-27 18:36:51 +01:00
Franck Nijhof
bac32bc379 Bump version to 2025.12.0b2 2025-11-27 17:13:26 +00:00
Allen Porter
6344837009 Fix regression in roborock image entity naming (#157432) 2025-11-27 17:12:08 +00:00
Allen Porter
9079ff5ea8 Update roborock test typing (#157370) 2025-11-27 17:12:06 +00:00
Bram Kragten
cd646aea11 Update frontend to 20251127.0 (#157431) 2025-11-27 17:09:23 +00:00
Shay Levy
b3a93d9fab Fix Shelly support for button5 trigger (#157422) 2025-11-27 17:09:22 +00:00
Denis Shulyaka
db98fb138b Fix Anthropic init with incorrect model (#157421) 2025-11-27 17:09:21 +00:00
Petro31
348c8bca7c Avoid custom template platform deprecations (#157415) 2025-11-27 17:09:20 +00:00
Allen Porter
e30707ad5e Bump python-roborock to 3.8.1 (#157376) 2025-11-27 17:09:18 +00:00
Petro31
3fa4dcb980 Reload templates when labs flag automation.new_triggers_conditions is set (#157368) 2025-11-27 17:09:17 +00:00
Kamil Breguła
57835efc9d Fix MAC address mix-ups between WLED devices (#155491)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-27 17:09:16 +00:00
Petro31
4646929987 Avoid custom template platform deprecations (#157415) 2025-11-27 18:06:29 +01:00
Petro31
010aea952c Reload templates when labs flag automation.new_triggers_conditions is set (#157368) 2025-11-27 18:05:33 +01:00
Bram Kragten
563678dc47 Update frontend to 20251127.0 (#157431) 2025-11-27 18:05:18 +01:00
epenet
a48f01f213 Raise UpdateFailed if API returns None in sfr_box (#157434) 2025-11-27 18:01:56 +01:00
Andrew Jackson
08b758b0d2 Add device info and parallel_updates to Transmission (#157423) 2025-11-27 17:37:27 +01:00
Allen Porter
4306fbea52 Fix regression in roborock image entity naming (#157432) 2025-11-27 17:36:18 +01:00
Robert Resch
6f4c479f8f Use same cosign version in build workflow (#157365) 2025-11-27 17:13:04 +01:00
Shay Levy
1d9c06264e Fix Shelly support for button5 trigger (#157422) 2025-11-27 16:38:45 +01:00
epenet
d045ecaf13 Add parallel_updates to SFR Box (#157426) 2025-11-27 16:04:25 +01:00
Markus Jacobsen
f7c41e694c Add media content id attribute to Bang & Olufsen (#156597) 2025-11-27 15:53:43 +01:00
Kamil Breguła
9ee7ed5cdb Fix MAC address mix-ups between WLED devices (#155491)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-27 15:10:32 +01:00
Denis Shulyaka
83c4e2abc9 Fix Anthropic init with incorrect model (#157421) 2025-11-27 14:16:46 +01:00
Franck Nijhof
f8d5a8bc58 Bump version to 2025.12.0b1 2025-11-27 11:49:46 +00:00
epenet
3f1f8da6f5 Bump renault-api to 0.5.1 (#157411) 2025-11-27 11:48:09 +00:00
Jan Čermák
55613f56b6 Fix state classes of Ecowitt rain sensors (#157409) 2025-11-27 11:48:08 +00:00
victorigualada
3ee2a78663 Bump hass-nabucasa from 1.6.1 to 1.6.2 (#157405) 2025-11-27 11:48:06 +00:00
victorigualada
814a0c4cc9 Return early when setting cloud ai_task and conversation and not logged in to cloud (#157402) 2025-11-27 11:48:04 +00:00
starkillerOG
71b674d8f1 Bump reolink-aio to 0.16.6 (#157399) 2025-11-27 11:48:03 +00:00
Erik Montnemery
c952fc5e31 Minor polish of cover trigger tests (#157397) 2025-11-27 11:48:02 +00:00
Allen Porter
8c3d40a348 Remove old roborock map storage (#157379) 2025-11-27 11:48:01 +00:00
Paulus Schoutsen
2451dfb63d Default conversation agent to store tool calls in chat log (#157377) 2025-11-27 11:48:00 +00:00
Sarah Seidman
8e5921eab6 Normalize input for Droplet pairing code (#157361) 2025-11-27 11:47:59 +00:00
Jaap Pieroen
bc730da9b1 Bugfix: Essent remove average gas price today (#157317) 2025-11-27 11:47:57 +00:00
abelyliu
28b7ebea6e Fix parsing of Tuya electricity RAW values (#157039) 2025-11-27 11:47:56 +00:00
Erik Montnemery
cfa447c7a9 Add climate started_cooling and started_drying triggers (#156945) 2025-11-27 11:47:55 +00:00
Erik Montnemery
a7dbf551a3 Add climate started_cooling and started_drying triggers (#156945) 2025-11-27 12:41:08 +01:00
Petro31
0b2bb9f6bf Modernize template binary sensor (#157279) 2025-11-27 12:28:16 +01:00
tan-lawrence
0769163b67 Use "medium" instead of "med" for the medium fan mode in Coolmaster (#157253) 2025-11-27 12:27:49 +01:00
Robert Resch
2bb51e1146 Reduce Devcontainer docker layers (#157412) 2025-11-27 12:27:18 +01:00
Paulus Schoutsen
d2248d282c Default conversation agent to store tool calls in chat log (#157377) 2025-11-27 12:27:03 +01:00
Jan Čermák
8fe79a88ca Fix state classes of Ecowitt rain sensors (#157409) 2025-11-27 12:24:28 +01:00
Jaap Pieroen
7a328539b2 Bugfix: Essent remove average gas price today (#157317) 2025-11-27 12:24:07 +01:00
abelyliu
ec69efee4d Fix parsing of Tuya electricity RAW values (#157039) 2025-11-27 12:23:33 +01:00
Shay Levy
dbcde549d4 Update Shelly coordinator coverage to 100% (#157380) 2025-11-27 12:22:19 +01:00
Michael
988355e138 Add tests for the switch platform to the AdGuard Home integration (#157105) 2025-11-27 12:21:23 +01:00
victorigualada
7711eac607 Return early when setting cloud ai_task and conversation and not logged in to cloud (#157402) 2025-11-27 12:20:42 +01:00
Denis Shulyaka
32fe53cceb Add anthropic model to the device info (#157413) 2025-11-27 12:16:05 +01:00
Andrew Jackson
3a65d3c0dc Add tests to Transmission (#157355) 2025-11-27 12:15:10 +01:00
epenet
7fe26223ac Bump renault-api to 0.5.1 (#157411) 2025-11-27 12:06:57 +01:00
victorigualada
7e8496afb2 Bump hass-nabucasa from 1.6.1 to 1.6.2 (#157405) 2025-11-27 11:40:50 +01:00
Paulus Schoutsen
2ec5190243 Install requirements_test_all in dev (#157392) 2025-11-27 10:30:50 +01:00
Erik Montnemery
a706db8fdb Minor polish of cover trigger tests (#157397) 2025-11-27 09:57:03 +01:00
starkillerOG
a00923c48b Bump reolink-aio to 0.16.6 (#157399) 2025-11-27 09:53:25 +01:00
Sarah Seidman
7480d59f0f Normalize input for Droplet pairing code (#157361) 2025-11-27 08:36:30 +01:00
Erik Montnemery
4c8d9ed401 Adjust type hints in sensor group (#157373) 2025-11-27 08:34:16 +01:00
Lukas
eef10c59db Pooldose bump api 0.8.0 (new) (#157381) 2025-11-27 08:33:32 +01:00
dependabot[bot]
a1a1f8dd77 Bump docker/metadata-action from 5.5.1 to 5.9.0 (#157395) 2025-11-27 07:26:58 +01:00
dependabot[bot]
c75a5c5151 Bump docker/setup-buildx-action from 3.5.0 to 3.11.1 (#157396) 2025-11-27 07:25:16 +01:00
Allen Porter
cdaaa2bd8f Update fitbit to use new asyncio client library for device list (#157308)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-27 00:23:49 -05:00
Allen Porter
bd84dac8fb Update roborock test typing (#157370) 2025-11-27 00:21:48 -05:00
Allen Porter
42cbeca5b0 Remove old roborock map storage (#157379) 2025-11-27 00:21:04 -05:00
Allen Porter
ad0a498d10 Bump python-roborock to 3.8.1 (#157376) 2025-11-26 16:12:19 -08:00
Jan Bouwhuis
973405822b Move translatable URL out of strings.json for knx integration (#155244) 2025-11-26 23:09:59 +01:00
Franck Nijhof
b883d2f519 Bump version to 2026.1.0dev0 2025-11-26 17:15:29 +00:00
Franck Nijhof
f64c870e42 Bump version to 2025.12.0b0 2025-11-26 17:13:42 +00:00
Christopher Fenner
4654d6de87 Filter devices based on online status in ViCare integration (#157287) 2025-11-26 18:00:52 +01:00
Ludovic BOUÉ
990c8cd4e6 Add Matter Window covering operational status (#156066)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-26 18:00:13 +01:00
Raphael Hehl
f8c76f42e3 Add session clearing on config entry removal for UniFi Protect integration (#157360)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-26 17:59:49 +01:00
Erik Montnemery
21d914c8ca Disable experimental conditions according to labs flag setting (#157345) 2025-11-26 17:59:12 +01:00
Erik Montnemery
ec77add1a6 Reload scripts when labs flag automation.new_triggers_conditions is set (#157348) 2025-11-26 17:53:38 +01:00
Erik Montnemery
ef3b7dfd1d Reload automations when labs flag automation.new_triggers_conditions is set (#157347) 2025-11-26 17:45:25 +01:00
Robert Resch
51241d963d Bump deebot-client to 16.4.0 (#157358) 2025-11-26 17:28:41 +01:00
Joost Lekkerkerker
7c48e6e046 Delete leftover SmartThings smartapps (#157188) 2025-11-26 17:14:36 +01:00
Bram Kragten
38d8da4279 Update frontend to 20251126.0 (#157352) 2025-11-26 17:13:25 +01:00
Raphael Hehl
3396a72fa8 Bump uiprotect to version 7.29.0 (#157354) 2025-11-26 17:04:38 +01:00
Erik Montnemery
2d26ab390e Save device registry store in worker thread (#157351) 2025-11-26 17:02:10 +01:00
Thomas55555
1bf5bc9323 Bump google air quality api to 1.1.2 (#157337) 2025-11-26 16:04:01 +01:00
Erik Montnemery
87ea96a3e0 Save entity registry store in worker thread (#157274) 2025-11-26 16:03:14 +01:00
Jan Čermák
e3cf65510b Update Home Assistant base image to 2025.11.3 (#157346) 2025-11-26 15:15:08 +01:00
Robert Resch
f69fce68d6 Use buildx imagetools to copy base image to docker.io and enable provenance (#157341)
Co-authored-by: Stefan Agner <stefan@agner.ch>
2025-11-26 15:12:32 +01:00
Abílio Costa
f758cfa82f Add get_conditions_for_target websocket command (#157344)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-26 14:08:56 +00:00
Artur Pragacz
9c7a928b29 Add get encryption key websocket to esphome (#154058) 2025-11-26 14:41:19 +01:00
Petro31
405a9948a2 Deprecate legacy and undocumented template entity configurations (#155355) 2025-11-26 14:30:06 +01:00
Oscar
0e3bab3ce4 Energyid bugfix (#157343) 2025-11-26 14:29:28 +01:00
Erik Montnemery
4900d25ac8 Disable experimental triggers according to labs flag setting (#157320) 2025-11-26 14:27:05 +01:00
Shay Levy
ea10cdb4b0 Remove Shelly redundant device entry check for sleepy devices (#157333) 2025-11-26 14:54:51 +02:00
Oscar
6baf77d256 Energyid integration (#138206)
Co-authored-by: Jan Pecinovsky <jan.pecinovsky@energieid.be>
Co-authored-by: Jan Pecinovsky <janpecinovsky@gmail.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-26 13:38:57 +01:00
Artur Pragacz
13bc0ebed8 Remove incorrect after dependency in music assistant (#157339) 2025-11-26 13:38:18 +01:00
Marcel van der Veldt
611af9c832 Add support for authentication to the Music Assistant integration (#157257)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
Co-authored-by: Artur Pragacz <artur@pragacz.com>
2025-11-26 13:34:26 +01:00
Abílio Costa
c2b7a63dd9 Add get_services_for_target websocket command (#157334) 2025-11-26 12:30:51 +00:00
Robert Resch
550716a753 Optimize docker container publish job (#157076)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-26 13:24:45 +01:00
TheJulianJES
56a71e6798 Add missing ZHA button strings (#157335) 2025-11-26 13:21:17 +01:00
Simone Chemelli
80ec51c56b Bump aioamazondevices to 10.0.0 (#157331) 2025-11-26 13:01:40 +01:00
Allen Porter
ea651c4a22 Overhaul Roborock integration to use new devices based API (#154837) 2025-11-26 12:52:09 +01:00
Bram Kragten
ff40ce419e Add context support for triggers.yaml (#156531) 2025-11-26 12:50:17 +01:00
OzGav
d95308719c Qualify Music Assistant to Bronze Quality Level (#155260)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2025-11-26 12:42:21 +01:00
Petro31
f4fb95ee43 Modernize template light (#156469) 2025-11-26 12:13:27 +01:00
Simone Chemelli
14d95cc86b Temporary raise scan interval for Alexa Devices (#157326) 2025-11-26 11:29:57 +01:00
Joost Lekkerkerker
4257435975 Add Matter info to SmartThings Device (#157321) 2025-11-26 11:28:49 +01:00
Abílio Costa
a6aab088fb Add get_triggers_for_target websocket command (#156778) 2025-11-26 11:05:03 +01:00
Aarni Koskela
655a63c104 Add clamp/wrap/remap to template math functions (#154537) 2025-11-26 11:00:12 +01:00
Robert Resch
a2ade413c2 Fix aarch64 image download by specifing the platform (#157316)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-26 10:02:35 +01:00
Jan Bouwhuis
10299b2ef4 Add description placeholders to service translation strings (#154984)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-26 09:54:22 +01:00
David Rapan
26444d8d34 Move Shelly sensor translation logic to base class (#157129)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-26 10:43:16 +02:00
Lukas
554c122a37 Add switch platform to PoolDose integration (#157296) 2025-11-26 09:09:35 +01:00
puddly
1c0dd02a7c Abort USB discovery flows on device unplug (#156303) 2025-11-26 09:00:41 +01:00
puddly
c41493860d Bump ZHA to 0.0.80 (#157311)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-26 08:43:14 +01:00
Erik Montnemery
f5b8ede5f9 Add models and websocket_api modules to labs integration (#157313) 2025-11-26 08:42:18 +01:00
dependabot[bot]
474a60511b Bump docker/setup-buildx-action from 3.10.0 to 3.11.1 (#157310) 2025-11-26 07:56:04 +01:00
TheJulianJES
9657f3f832 Fix ZHA custom quirks friendly name priority (#156751)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-26 05:15:42 +01:00
TheJulianJES
59f4bc1908 Raise user-friendly error for locked ports when flashing ZBT (#157272) 2025-11-26 04:37:09 +01:00
Bram Kragten
9ebc6cbb23 Add target to condition description (#157298) 2025-11-26 01:22:48 +01:00
Paul Bottein
f433ca7455 Let Home Assistant generate the entity id for esphome entities (#154097)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-25 18:09:35 -06:00
Shay Levy
f77629d0f8 Add coverage for Shelly repairs (#157277) 2025-11-26 00:06:48 +02:00
Joost Lekkerkerker
0ac1b22e03 Bump pySmartThings to 3.5.0 (#157290) 2025-11-25 23:36:50 +02:00
Thomas55555
1069233851 Add Google Air Quality integration (#145237)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-11-25 21:18:44 +01:00
Harvey
d2fd200469 New integration: Hue BLE (#118635)
Co-authored-by: Mr. Bubbles <manni@zapto.de>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-25 21:15:34 +01:00
Petro31
20cdd9386e Modernize template sensor (#157251) 2025-11-25 21:15:17 +01:00
Jordan Harvey
1be2e4f90c Add anglian_water integration (#156225)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-25 20:48:24 +01:00
Raphael Hehl
839f647396 Unifiprotect Prevent duplicate vehicle detection events from firing (#157278)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-11-25 13:41:53 -06:00
victorigualada
7c2741bd36 Add home assistant cloud conversation (#157090) 2025-11-25 14:04:19 -05:00
dotlambda
d6fb268119 Bump xmltodict to 1.0.2 (#156670) 2025-11-25 12:54:25 -06:00
Erik Montnemery
521a6784b4 Add opt-in to Store for serializing in an executor (#157263) 2025-11-25 19:10:39 +01:00
Raphael Hehl
d2ba7e8e3e UnifiProtect add vehicle detection event entity with license plate recognition support (#157203)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2025-11-25 11:30:06 -06:00
Andrew Jackson
405c2f96fd Add bronze quality scale to transmission (#156388)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-25 18:13:15 +01:00
Jaap Pieroen
90ef5b1c25 Add Essent dynamic price integration (#157010)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-25 18:00:34 +01:00
dotlambda
562f72f321 Bump panasonic-viera to 0.4.4 (#157268) 2025-11-25 17:59:13 +01:00
Tom Wilkie
f5ee3bd872 Refactor Prometheus metrics handling (#157159) 2025-11-25 17:53:08 +01:00
Erik Montnemery
8dd35cb129 Add entity triggers and conditions (#156852)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
Co-authored-by: abmantis <amfcalt@gmail.com>
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-25 17:52:20 +01:00
Manu
6fa971d393 Refactor media player browse media in Xbox integration (#156672) 2025-11-25 17:49:29 +01:00
Samuel Xiao
6deff1c78f Add smart radiator thermostat support to Switchbot Cloud (#154445)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-25 17:46:55 +01:00
Manu
f96996b27f Detect image type from magic numbers in image component (#157190) 2025-11-25 17:38:16 +01:00
J. Nick Koston
eb9fc66ca9 Bump yalexs-ble to 3.2.1 (#157265) 2025-11-25 17:32:47 +01:00
Petar Petrov
43e4fe4526 Add support for downstream water meters in energy dashboard (#155927) 2025-11-25 17:18:39 +01:00
Denis Shulyaka
252dbb706f Anthropic: consolidate recommended values in a dict (#156787) 2025-11-25 17:08:55 +01:00
Petro31
d7ad0cba94 Modernize template image (#157255) 2025-11-25 17:05:32 +01:00
Robert Resch
159a8d39d6 Optimize build_base build job (#157231)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-25 17:04:15 +01:00
victorigualada
8f1abb6dbb Add HomeAssistant Cloud ai_task (#157015) 2025-11-25 11:01:32 -05:00
Joost Lekkerkerker
242c02890f Add snapshot tests to Awair (#157266) 2025-11-25 16:58:59 +01:00
Erik Montnemery
eb793a3942 Disable Ruff rule D417 (#157264) 2025-11-25 16:48:37 +01:00
Rico Hageman
e65c47ba0f Add quality scale definition to Awair (#150234)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-25 16:25:34 +01:00
Marcel van der Veldt
24dba24571 Bump music assistant client to version 1.3.2 (#157261) 2025-11-25 16:25:07 +01:00
Erik Montnemery
4c04dc00dd Respect callback decorator in store helper async_delay_save (#157158) 2025-11-25 16:08:09 +01:00
Joakim Sørensen
0c366506c5 Bump hass-nabucasa from 1.6.0 to 1.6.1 (#157256) 2025-11-25 15:49:37 +01:00
Lukas Malkmus
a0323e80f5 Add support for switchbot presence sensor (#156314)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-25 15:15:57 +01:00
mettolen
e496fb2227 Add reconfigure flow to Saunum integration (#157128)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-25 15:10:10 +01:00
Franck Nijhof
c2219aadb1 Handle invalid IP addresses in ip_bans.yaml gracefully (#157232)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Robert Resch <robert@resch.dev>
2025-11-25 14:49:05 +01:00
DeerMaximum
2cd0637324 Fix NINA flow tests to end a final state (#156664) 2025-11-25 14:36:45 +01:00
Robert Resch
293f8f7c87 Remove bluetooth_tracker integration (#157246) 2025-11-25 14:09:08 +01:00
Robert Resch
1af569ae17 Bump wheels to 2025.11.0 (#157247) 2025-11-25 14:05:46 +01:00
Erik Montnemery
d4db5ec0cc Fix use of storage helper in the labs integration (#157249)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-25 13:52:02 +01:00
Paul Bottein
4be1fa9a3a Provide icon and title for lovelace panel (#156955) 2025-11-25 13:48:28 +01:00
Robert Resch
149c1e6772 Remove rpi_camera (#157245) 2025-11-25 13:44:00 +01:00
Franck Nijhof
e37e7574a4 Bump debugpy to 1.8.17 (#157248)
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-25 13:34:56 +01:00
epenet
37152a27ba Remove old migration from Tuya (#157237) 2025-11-25 13:34:01 +01:00
Josef Zweck
5025af8334 Add steam temperature number to lamarzocco (#157167) 2025-11-25 13:33:13 +01:00
mettolen
ec9fb9837a Add current humidity to Airobot climate entity (#157209) 2025-11-25 13:15:41 +01:00
Franck Nijhof
30451e3aaa Register preview labs feature for the new intuitive triggers and conditions (#157189)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-25 12:54:28 +01:00
Kevin Stillhammer
c66c3497c1 Bump pywaze to 1.1.1 (#157240) 2025-11-25 12:18:41 +01:00
Robert Resch
1063e71318 Don't fetch everything on builder init job (#157243) 2025-11-25 12:00:19 +01:00
Maciej Bieniek
1a875b021a Bump imgw-pib to version 1.6.0 (#157239) 2025-11-25 11:57:45 +01:00
epenet
15328a4aff Cleanup unused function in Tuya util (#157227) 2025-11-25 10:58:40 +01:00
Paul Bottein
083cfb89af Add winter mode to front-end integration under lab preview feature (#157181) 2025-11-25 09:34:11 +01:00
epenet
bd129c2085 Bump tuya-device-sharing-sdk to 0.2.6 (#157223) 2025-11-25 09:18:02 +01:00
Petro31
f73bc9242b Modernize template fan (#156470) 2025-11-25 08:08:19 +01:00
wollew
4506be5065 Complete test coverage for velux light and cover entities (#156770)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-11-25 08:07:36 +01:00
Manu
80c611e562 Add support for additional remote commands to Xbox integration (#157206) 2025-11-25 07:49:13 +01:00
Will Moss
b44aafc294 Improved error handling for oauth2 configuration in neato integration (#156300) 2025-11-25 07:28:04 +01:00
Petro31
af1e3205b8 Modernize template lock (#156402) 2025-11-25 07:26:42 +01:00
dependabot[bot]
1360fe7f23 Bump actions/setup-python from 6.0.0 to 6.1.0 (#157219)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-25 07:22:24 +01:00
dependabot[bot]
b5bb8583f8 Bump github/codeql-action from 4.31.4 to 4.31.5 (#157220)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-25 07:21:59 +01:00
Andre Lengwenus
9b62c212ce Bump LCN quality scale to Silver (#157151) 2025-11-25 06:45:26 +01:00
Simone Chemelli
8fa56ad92e Bump aioamazondevices to 9.0.3 (#157205)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-25 06:09:20 +01:00
ndrwrbgs
f82f0a1862 Correctcurrent_temp local variable name in homekit _get_current_temperature (#157202) 2025-11-25 06:04:13 +01:00
J. Nick Koston
878881b100 Fix elkm1 connection cleanup on setup failure (#157208) 2025-11-24 23:12:04 -05:00
J. Nick Koston
743583d9bd Bump aioesphomeapi to 42.8.0 (#157214) 2025-11-24 22:49:57 -05:00
Jan Bouwhuis
f537204d22 Fix websocket_api timeout test (#157204) 2025-11-24 20:12:32 -06:00
Glenn Waters
ec74be7922 Bump elkm1-lib to 2.2.13 (#157212)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-24 18:27:53 -06:00
David Rapan
3574f647d0 Move Shelly binary sensor translation logic to base class (#157127)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-25 00:31:25 +02:00
David Rapan
6c4296a0de Remove Shelly binary sensor name removal (#157065)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-24 22:35:25 +01:00
Paulus Schoutsen
e780e3db8c Add chat log subscription endpoint (#155287)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-24 22:31:19 +01:00
David Rapan
4ed2efa4e8 Remove Shelly switch name removal (#157072)
Signed-off-by: David Rapan <david@rapan.cz>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-24 22:24:24 +01:00
David Rapan
abef6f7b3e Remove Shelly sensor name removal (#157071)
Signed-off-by: David Rapan <david@rapan.cz>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-24 22:09:42 +01:00
David Rapan
5556fb99e6 Remove Shelly event name removal (#157067)
Signed-off-by: David Rapan <david@rapan.cz>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-24 22:01:58 +01:00
J. Nick Koston
16669e39bd Filter devices with active discovery flows from Shelly user step (#157201) 2025-11-24 14:52:05 -06:00
Raphael Hehl
ca088d81c3 Bump uiprotect to version 7.28.0 (#157198)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-24 14:44:39 -06:00
Michael Hansen
12847fb0a4 Bump intents (#157200) 2025-11-24 21:39:24 +01:00
J. Nick Koston
8b758c46f4 Combine Shelly BLE WiFi provisioning SSID and password steps (#157199) 2025-11-24 14:34:59 -06:00
J. Nick Koston
f439471dc1 Add BLE IP fallback for Shelly provisioning when zeroconf fails (#157144) 2025-11-24 13:55:09 -06:00
Raphael Hehl
5ff3233b09 Remove license plate event sensor (#157196) 2025-11-24 13:48:38 -06:00
Jan Bouwhuis
22daed083f Fix MQTT link text to be sentence cased (#157191) 2025-11-24 20:27:22 +01:00
Peter Norlander
13384de464 Extend Matter lock to support selecting OperatingMode (#157132)
Co-authored-by: Ludovic BOUÉ <lboue@users.noreply.github.com>
2025-11-24 20:16:56 +01:00
J. Nick Koston
f5e5183190 Show available shelly devices in user config flow (#157138) 2025-11-24 13:16:42 -06:00
Jan Bouwhuis
e18668b8f9 Add MQTT water heater subentry support (#157182) 2025-11-24 19:54:42 +01:00
Åke Strandberg
15647f2720 Add miele select platform to support sabbath mode (#156866) 2025-11-24 19:29:13 +01:00
victorigualada
c961126ee5 Bump hass-nabucasa from 1.5.1 to 1.6.0 (#157177) 2025-11-24 16:43:10 +00:00
Joost Lekkerkerker
5142c5f418 Use SmartThings modelCode as model_id (#157179) 2025-11-24 17:07:22 +01:00
David Rapan
3d459704e1 Remove Shelly update name removal (#157073)
Signed-off-by: David Rapan <david@rapan.cz>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-24 18:02:23 +02:00
Joost Lekkerkerker
5a8ddcd0b3 Bump pySmartThings to 3.4.0 (#157178) 2025-11-24 16:55:18 +01:00
David Rapan
2667a40b92 Remove Shelly number name removal (#157069)
Signed-off-by: David Rapan <david@rapan.cz>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-24 17:08:13 +02:00
David Rapan
08baa99691 Remove Shelly button name removal (#157066)
Signed-off-by: David Rapan <david@rapan.cz>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-24 14:28:38 +02:00
David Rapan
d84cf26f40 Fix Shelly Self-test sensor name (#157169) 2025-11-24 14:03:56 +02:00
Robert Resch
ba5472da90 Pin go2rtc version to sha hash (#157166)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-24 12:52:58 +01:00
Jan Bouwhuis
e20b88a54f Revert MQTT subscribe on_subscribe arg (#157168) 2025-11-24 12:32:55 +01:00
TimL
ac69712a51 update firmware handling in SMLIGHT integration (#157145) 2025-11-24 12:13:28 +01:00
Jan Bouwhuis
f0e75ba0ed Add MQTT valve subentry support (#157124)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-11-24 12:04:38 +01:00
mettolen
e64598e7f5 Add light entity to Saunum integration (#157081)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-11-24 12:02:46 +01:00
vexofp
e6f9a8e7d6 Assign icons for more Octoprint sensors (#157150) 2025-11-24 11:51:58 +01:00
Josef Zweck
1e8b42f843 Bump pylamarzocco to 2.2.2 (#157165) 2025-11-24 11:50:11 +01:00
Franck Nijhof
430eee0b28 Address Home Assistant Labs review comments (#157075)
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 11:34:38 +01:00
Paulus Schoutsen
b4799aa7ea Abort Z-Wave JS discovery from ESPHome if add-on umanaged (#157013)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-24 11:09:20 +01:00
Markus Jacobsen
ab45460069 Add Beoremote One support to Bang & Olufsen (#155082)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-24 08:17:04 +01:00
dependabot[bot]
c8fd6db3ff Bump actions/ai-inference from 2.0.1 to 2.0.2 (#157153) 2025-11-24 07:54:24 +01:00
Jan Bouwhuis
0a9f200ca4 Bump incomfort-client to v0.6.10 (#157136) 2025-11-24 06:31:50 +01:00
J. Nick Koston
8591335660 Bump dbus-fast to 3.1.2 (#157147) 2025-11-23 23:03:26 -05:00
TimL
c01089e994 Bump pysmlight to 0.2.11 (#157146) 2025-11-23 21:05:41 -06:00
Kamil Breguła
79a7daf89d Fix fixture for da_ks_oven_0107x (#157122)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-11-23 22:30:03 +01:00
David Rapan
d22867b852 Remove Shelly select name removal (#157070)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-23 21:24:55 +01:00
Amit Finkelstein
ddb74c5af4 Refresh HassOS coordinator when mount repair is received (#155969) 2025-11-23 20:51:18 +01:00
David Rapan
9aec7b12c2 Refactor Shelly entity to remove name assignments (#157018)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-23 20:10:46 +01:00
J. Nick Koston
bf42e3769a Bump aioshelly to 13.21.0 (#157123) 2025-11-23 20:10:09 +01:00
Franck Nijhof
43f40c6f0e Extract issue template functions into an issues Jinja2 extension (#157116) 2025-11-23 19:14:46 +01:00
Manu
03ac634e6d Add aiofiles to requirements of matrix and slack integration (#157117) 2025-11-23 18:16:15 +01:00
Manu
a204e85d84 Fix typos in Duck DNS integration (#157118) 2025-11-23 18:05:08 +01:00
hahn-th
79c7ad7646 Handle variable number of channels for HmIPW-DRI16 and HmIPW-DRI32 in homematicip_cloud integration (#151201) 2025-11-23 17:53:05 +01:00
J. Diego Rodríguez Royo
704d4c896d Add air conditioner and microwave features to Home Connect (#151184)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-11-23 17:20:24 +01:00
Franck Nijhof
5b6a4b0fea Merge branch 'master' into dev 2025-11-23 16:08:46 +00:00
Jan Bouwhuis
ef5573c693 Allow to callback for MQTT subscription status (#152994) 2025-11-23 16:53:44 +01:00
J. Nick Koston
45aecd525a Fix Shelly BLE rediscovery after factory reset (#157113)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-23 16:50:41 +01:00
omrishiv
ce1146492e Enable Pylutron Caseta Smart Away (#156711) 2025-11-23 16:41:14 +01:00
J. Nick Koston
1ce890b105 Add repair issue for Shelly devices with open WiFi access point (#157086) 2025-11-23 07:40:38 -08:00
Janez Urevc
3e7bef77e5 Add total active power sensor to Tesla Wall Connector integration. (#151028)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-23 16:37:47 +01:00
puddly
1222828852 Show Z2M docs link in final step of hardware config flow (#155736) 2025-11-23 16:35:40 +01:00
skye-harris
1ef64582eb Bugfix Ollama Integration - Unable to reconfigure LLM Agents when an LLM Tooling API is removed (#156344) 2025-11-23 16:34:36 +01:00
w531t4
d363bd63eb Always expose Twitch channel_picture attr regardless of channel status (#150300) 2025-11-23 16:29:06 +01:00
Manu
5916af1115 Add config flow to Duck DNS integration (#147693)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-23 15:54:51 +01:00
tronikos
f8bf7ec1ff Add Google Weather sensors (#147141)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-23 15:43:08 +01:00
Jeremiah
41e42b9581 Fix Thermopro 'Device not available' on Restart (#155929) 2025-11-23 15:36:51 +01:00
Kevin Stillhammer
51f68f2776 Force httpx client to use IPv4 for waze_travel_time (#156526) 2025-11-23 15:05:02 +01:00
steinmn
773cb7424c Translatable error msg to frontend if new dashboard url already in use (#153501) 2025-11-23 14:43:44 +01:00
Artur Pragacz
eefab75ef0 Correct color mode when effect active in Wiz (#156742) 2025-11-23 14:13:22 +01:00
Markus Jacobsen
81b4122b73 Add proper Beosound Premiere support to Bang & Olufsen (#156954) 2025-11-23 13:58:26 +01:00
Artur Pragacz
bd0ab4d1fe Add snapshot device analytics url config option (#156984) 2025-11-23 13:47:33 +01:00
Robert Resch
80151b205d Use basic auth in go2rtc (#157008)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-23 13:39:14 +01:00
hanwg
4488fdd2d6 Remove yaml in tests for Telegram webhook bot (#157091) 2025-11-23 13:38:29 +01:00
David Rapan
a6e0bea805 Increase Shelly code coverage for Gen2+ (input w/ custom name) (#157079) 2025-11-23 13:11:35 +01:00
Josef Zweck
994619e179 Don't manually update dashboard data in lamarzocco (#156864) 2025-11-23 13:07:43 +01:00
Allen Porter
4db5be73a7 Update Nest config flow tests to fix quality scale item (#156716) 2025-11-23 13:05:15 +01:00
Tom Wilkie
3cfedd1721 Add Prometheus metrics support for water_heater domain (#152963)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-23 13:00:56 +01:00
Michael
2f1301abaf Improve test coverage of adguard (#156839) 2025-11-23 13:00:27 +01:00
Arjan
21d61ef401 Add new mapping "Averses de pluie et neige" (#157093) 2025-11-23 12:59:34 +01:00
Maciej Bieniek
6850f9622a Bump pysnmp and brother libraries (#157098) 2025-11-23 12:48:48 +01:00
Andre Lengwenus
2b2bb79505 Add missing availability change (#157096) 2025-11-23 12:33:28 +01:00
Franck Nijhof
d97998e2e1 Extract date/time template functions into an datetime Jinja2 extension (#157042) 2025-11-23 11:47:49 +01:00
cdnninja
3ef62c97ca Correct vesync tests to reflect new method (#157080) 2025-11-23 09:08:56 +01:00
Allen Porter
5cca95ab2f Bump google-nest-sdm to 9.1.0 (#157083) 2025-11-23 09:08:22 +01:00
Simone Chemelli
a4f0a21c8e Bump aioamazondevices to 9.0.2 (#156963) 2025-11-22 20:11:04 -08:00
Matthias Alphart
11a2b5df6a Update xknx to 3.11.0 (#157077) 2025-11-23 00:03:34 +01:00
Manu
07e2c8a610 Add PARALLEL_UPDATES to Xbox integration (#157074) 2025-11-22 23:17:53 +01:00
Matthias Alphart
43783ed896 Fix KNX lights Hue DPT (#157068) 2025-11-22 21:55:31 +01:00
Tim Messerschmidt
a206604df5 Fix tado via_device warnings (#156884) 2025-11-22 21:54:54 +01:00
David Rapan
2e82ac81b2 Refactor Shelly switch name construction (#157027) 2025-11-22 21:28:47 +01:00
David Rapan
5139e9e566 Refactor Shelly light to reuse RPC key split (#157003)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-22 22:19:42 +02:00
mettolen
c53674531c Add Airobot integration (#156712) 2025-11-22 21:14:41 +01:00
mettolen
a04244ad25 Add fan support to Saunum climate entity (#156683)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-22 20:44:20 +01:00
karwosts
b27b357b91 Add hot reload for derivative (#156898)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-22 20:23:29 +01:00
Maciej Bieniek
01e38853c0 Add IQS to the Brother integration (#155818) 2025-11-22 20:21:52 +01:00
Avi Miller
06158fc9a1 Simplify how light entities register with LIFX Manager (#156993)
Signed-off-by: Avi Miller <me@dje.li>
2025-11-22 20:04:49 +01:00
David Rapan
e5968084a2 Refactor Shelly event name construction (#157025)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-22 21:02:20 +02:00
karwosts
263839a6c0 Add unique_id for derivative (#157055) 2025-11-22 19:25:46 +01:00
Marc Mueller
931b2c2db0 Update av to 16.0.1 (#157044)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-22 18:25:12 +01:00
David Rapan
8e26112db1 Refactor Shelly cover name construction (#157024) 2025-11-22 18:23:33 +01:00
David Rapan
b1286af423 Refactor Shelly text name construction (#157028) 2025-11-22 18:23:25 +01:00
David Rapan
bd02e279cf Refactor Shelly logbook name construction (#157026) 2025-11-22 18:23:17 +01:00
David Rapan
6e5be843d6 Refactor Shelly climate name construction (#157054) 2025-11-22 18:22:59 +01:00
Etienne C.
5b1d86a04b Remove rounding on Google Travel Time sensor (#156658) 2025-11-22 17:50:05 +01:00
Andrew Jackson
1514013c3b Add optional idempotency key to Mastodon post action (#156688) 2025-11-22 17:44:53 +01:00
Manu
54ed290cc1 Add reauthentication flow to Xbox integration (#156624) 2025-11-22 17:43:12 +01:00
Jan Bouwhuis
1106f4f0e2 Fix typo in mqtt text subentry translations and improve advanced settings translations (#157052) 2025-11-22 15:40:36 +01:00
Andre Lengwenus
f73e92a34a Mark entity unavailable if data can't be fetched (#156928) 2025-11-22 15:36:47 +01:00
hanwg
74ad5066e2 Fix Telegram bot bug where messages are sent to wrong recipient (#156978) 2025-11-22 15:25:35 +01:00
David Rapan
4202a665af Refactor Shelly climate to reuse RPC key split (#157002) 2025-11-22 15:20:31 +01:00
David Rapan
c9ddbe39ce Refactor Shelly button to reuse RPC key split (#156990) 2025-11-22 15:20:02 +01:00
Ville Skyttä
8a2e8d2c61 Add internal util.snakecase, use instead of stringcase (#156775)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-22 15:19:15 +01:00
epenet
ca2e8bfb56 Add support for tuya doorbell events (#156540)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-22 15:17:37 +01:00
epenet
c0772f3957 Log warning for incorrect Tuya enum values (#156541) 2025-11-22 15:04:01 +01:00
epenet
0b96da3b24 Add more fixtures for Tuya tests (#156855) 2025-11-22 15:03:19 +01:00
Franck Nijhof
4c07b2b290 Remove template engine dependency in EmonCMS (#157045) 2025-11-22 14:48:44 +01:00
Paulus Schoutsen
f699d95ea0 Do not require admin for instance URLs (#157012) 2025-11-22 13:09:38 +01:00
Artur Pragacz
f6b9a0eb29 Ensure backwards compatibility for new-style configs in old triggers and conditions (#156446) 2025-11-22 12:37:48 +01:00
epenet
71c665ed49 Fix fallback to local system unit in Tuya climate (#156999) 2025-11-22 10:24:03 +01:00
Thomas D
85a1afb174 Add lock reduced guard button to Volvo integration (#157004) 2025-11-22 10:05:01 +01:00
Manu
9668a68c28 Bump python-xbox to v0.1.2 (#157030) 2025-11-22 00:09:42 +01:00
J. Nick Koston
a06aa8edfe Bump inkbird-ble to 1.1.1 (#157016) 2025-11-21 15:08:03 -08:00
Kurt Chrisford
4e30a5d930 Add support for actron air que air conditioners (#156675) 2025-11-21 23:59:02 +01:00
Manu
696550a7f2 Add diagnostics platform to Xbox integration (#156662) 2025-11-21 23:56:07 +01:00
Raphael Hehl
c064d23a99 Bump uiprotect to version 7.26.0 (#157022) 2025-11-21 23:54:50 +01:00
Lukas
ac7b063c2c Add binary_sensor platform to pooldose integration (#156894) 2025-11-21 23:50:30 +01:00
J. Nick Koston
e0778c8e2e Add security options to disable AP and BLE RPC after Shelly WiFi provisioning (#156970) 2025-11-21 14:27:26 -08:00
David Rapan
2ba5a96d5b Refactor Shelly binary sensor name removal (#157023)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-21 23:41:19 +02:00
Manu
13c9fb6e37 Remove Domino's Pizza integration (#156879) 2025-11-21 19:47:04 +01:00
Robert Resch
102bb1f694 Remove deprecated archs (#156414) 2025-11-21 19:17:41 +01:00
Franck Nijhof
fc8f8b39b4 2025.11.3 (#157006) 2025-11-21 18:02:26 +01:00
Franck Nijhof
e5b2d44e8e Extract area template functions into an areas Jinja2 extension (#156629) 2025-11-21 17:56:16 +01:00
Franck Nijhof
ec0918027e Bump version to 2025.11.3 2025-11-21 16:27:45 +00:00
Joost Lekkerkerker
8a54f8d4e2 Throttle Decora wifi updates (#156994) 2025-11-21 16:26:49 +00:00
Bram Kragten
5c27126b6d Update frontend to 20251105.1 (#156992) 2025-11-21 16:26:47 +00:00
Robert Resch
e069aff0e2 Bump go2rtc to 1.9.12 and go2rtc-client to 0.3.0 (#156948) 2025-11-21 16:26:46 +00:00
Timothy
733526fae3 Rework CloudhookURL setup for mobile app (#156940) 2025-11-21 16:26:45 +00:00
Sebastian Schneider
1ef001f8e9 Bump aiounifi to 88 (#156867) 2025-11-21 16:26:43 +00:00
Josef Zweck
7732377fde Bump onedrive-personal-sdk to 0.0.17 (#156865) 2025-11-21 16:26:42 +00:00
puddly
b7786e589b Bump universal-silabs-flasher to 0.1.2 (#156849) 2025-11-21 16:26:41 +00:00
Joost Lekkerkerker
4f60970a91 Bump pySmartThings to 3.3.4 (#156830) 2025-11-21 16:26:40 +00:00
Thomas55555
1c1286dd57 Bump aioautomower to 2.7.1 (#156826) 2025-11-21 16:26:39 +00:00
Copilot
41c9f08f60 Fix hvv_departures to pass config_entry explicitly to DataUpdateCoordinator (#156794)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: joostlek <7083755+joostlek@users.noreply.github.com>
2025-11-21 16:26:37 +00:00
Josef Zweck
fc4bfab0f7 Lamarzocco fix websocket reconnect issue (#156786)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2025-11-21 16:26:36 +00:00
epenet
769a12f74e Fix blocking call in cync (#156782) 2025-11-21 16:26:35 +00:00
Dan Raper
dabaa2bc5e Bump ohmepy and remove advanced_settings_coordinator (#156764) 2025-11-21 16:26:34 +00:00
Jan Bouwhuis
b674828a91 Fix missing temperature_delta device class translations (#156685) 2025-11-21 16:26:32 +00:00
Jan Bouwhuis
761da66658 Fix missing description placeholders in MQTT subentry flow (#156684) 2025-11-21 16:26:31 +00:00
MarkGodwin
c8aba62301 Bump tplink-omada-api to 1.5.3 (#156645) 2025-11-21 16:26:30 +00:00
Robert Resch
07ab2e6805 Bump async-upnp-client to 0.46.0 (#156622) 2025-11-21 16:26:28 +00:00
Fredrik Mårtensson
f62e0c8c08 Fix is_matching in samsungtv config flow (#156594)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-21 16:26:27 +00:00
PaulCavill
6ca00f9dbb Bump pyiCloud to 2.2.0 (#156485) 2025-11-21 16:26:25 +00:00
Jamin
0fba80e30f Reset state on error during VOIP announcement (#156384) 2025-11-21 16:26:24 +00:00
puddly
7073c40385 Bump universal-silabs-flasher to v0.1.0 (#156291)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-21 16:26:23 +00:00
Charlie Rusbridger
8fb9d92daf Fix wrong BrowseError module in Kode (#155971) 2025-11-21 16:26:22 +00:00
cdnninja
2d81665f99 update methods to non deprecated methods in vesync (#155887) 2025-11-21 16:26:20 +00:00
Tom Monck JR
b398935539 Fix args passed to check_config script (#155885) 2025-11-21 16:26:19 +00:00
averybiteydinosaur
95f588aae1 Bump version of python_awair to 0.2.5 (#155798)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-21 16:26:18 +00:00
Hessel
ffe524d95a Cache token info in Wallbox (#154147)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-21 16:26:17 +00:00
epenet
4d4ad900b1 Add Tuya climate tests for US unit_system (#156989) 2025-11-21 17:20:03 +01:00
Joost Lekkerkerker
acc136af19 Add entities for Smartthings flexwash (#156997) 2025-11-21 16:58:50 +01:00
Abílio Costa
0f12a40eb2 Fix typing in websocket_api test (#156964) 2025-11-21 16:29:19 +01:00
Joost Lekkerkerker
bf124daf72 Add SmartThings dustfilter threshold (#153909) 2025-11-21 16:28:35 +01:00
Josef Zweck
1682ced5cc Bump pylamarzocco to 2.2.0 (#156667) 2025-11-21 16:26:38 +01:00
averybiteydinosaur
80b316bc70 Bump version of python_awair to 0.2.5 (#155798)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-21 16:25:18 +01:00
karwosts
00d2340d4b Fix usage_prediction incorrectly accessing target fields (#156937) 2025-11-21 15:56:58 +01:00
Timothy
514a329580 Rework CloudhookURL setup for mobile app (#156940) 2025-11-21 15:23:23 +01:00
Petro31
f2b8bb01bf Modernize template cover (#156475) 2025-11-21 15:20:30 +01:00
Manu
30153ab059 Fix spelling mistake in IronOS integration (#156996) 2025-11-21 15:19:33 +01:00
Bram Kragten
2957b15ede Update frontend to 20251105.1 (#156992) 2025-11-21 15:18:23 +01:00
Glenn Vandeuren (aka Iondependent)
12ace95f3e Improve error handling in Niko Home Control config flow (#154565)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-21 14:34:59 +01:00
Joost Lekkerkerker
babe19767d Add diagnostic support to WAQI (#156811) 2025-11-21 14:20:47 +01:00
Robert Resch
d01843e1ab Use unix socket for HA managed go2rtc instance (#156968) 2025-11-21 14:19:03 +01:00
Joost Lekkerkerker
9964cb512a Throttle Decora wifi updates (#156994) 2025-11-21 14:16:03 +01:00
Joost Lekkerkerker
ae38214b7c Bump pySmartThings to 3.3.4 (#156830) 2025-11-21 14:10:38 +01:00
Kamil Breguła
9812286801 Add fixtures for Samsung oven and dishwasher (#156655)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-21 13:53:10 +01:00
J. Nick Koston
32a40e5919 Bump PySwichBot to 0.74.0 (#156986) 2025-11-21 13:22:55 +01:00
Kamil Breguła
97de944a14 Add Washer Water Temperature to SmartThings (#156980)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-11-21 13:19:08 +01:00
Artur Pragacz
c9bd87f4b3 Classify identify button as diagnostic in Matter (#156943) 2025-11-21 13:17:26 +01:00
Neal
ac46568996 Add tests to concord232 component (#156070)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-21 13:13:08 +01:00
J. Nick Koston
7c1b8ee02c Bump aioshelly to 13.20.0 (#156988) 2025-11-21 06:11:03 -06:00
dependabot[bot]
aa6901265d Bump actions/checkout from 5.0.1 to 6.0.0 (#156973)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-21 12:56:33 +01:00
epenet
b76e9ad1c0 Migrate Tuya light (color_data) to use wrapper class (#156816) 2025-11-21 13:05:12 +02:00
epenet
edb8007c65 Migrate Tuya climate (temperature) to use wrapper class (#156977) 2025-11-21 13:03:58 +02:00
epenet
956a29411f Migrate Tuya fan (oscillate) to use wrapper class (#156946) 2025-11-21 11:56:24 +01:00
Brett Adams
1a2361050b Add update platform to Tesla Fleet (#156908) 2025-11-21 11:54:20 +01:00
Jan Bouwhuis
0c9e92f6f9 Add MQTT text subentry support (#156686) 2025-11-21 11:46:19 +01:00
epenet
bfdff46859 Migrate Tuya fan (speed) to use wrapper class (#156976) 2025-11-21 11:45:42 +01:00
epenet
9a22808499 Migrate Tuya fan (direction) to use wrapper class (#156944) 2025-11-21 11:44:16 +01:00
epenet
88b373af41 Migrate Tuya climate (swing) to use wrapper class (#156938) 2025-11-21 11:41:01 +01:00
epenet
dea2f37e8f Migrate Tuya cover (state) to use wrapper class (#156941) 2025-11-21 11:38:05 +01:00
David Rapan
30cce68e0b Update Shelly's quality scale to platinum 🏆️ (#156982) 2025-11-21 12:36:58 +02:00
Shay Levy
985eff972a Mark Shelly entity translations as done (#155683) 2025-11-21 12:10:46 +02:00
David Rapan
31ca332158 Increase Shelly code coverage for Gen1 EM3 (#156752)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-21 11:02:53 +01:00
David Rapan
bf76c1601d Align Shelly event naming paradigm (#156774)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-21 09:15:26 +01:00
J. Nick Koston
e572f8d48f Fix Shelly Bluetooth discovery for Gen3/Gen4 devices without advertised names (#156883) 2025-11-20 15:11:17 -06:00
Franck Nijhof
482b5d49a3 Introduce Home Assistant Labs (#156840) 2025-11-20 21:22:37 +01:00
Robert Resch
126fd217e7 Bump go2rtc to 1.9.12 and go2rtc-client to 0.3.0 (#156948) 2025-11-20 19:41:40 +01:00
Manu
0327b0e1ec Fix next alarm sensor showing wrong time in Sleep as Android (#156939) 2025-11-20 18:56:58 +01:00
epenet
3d5a7b4813 Migrate Tuya vacuum (pause) to use wrapper class (#156947) 2025-11-20 18:55:03 +01:00
epenet
e0bb30f63b Migrate Tuya fan (switch) to use wrapper class (#156936) 2025-11-20 15:04:36 +01:00
epenet
e5ae58c5df Migrate Tuya cover (open/close/stop) to use wrapper class (#156726) 2025-11-20 15:24:58 +02:00
epenet
13e4bb4b93 Migrate Tuya climate (hvac_mode/presets) to use wrapper class (#156933) 2025-11-20 14:23:28 +01:00
epenet
d5fd27d2a2 Add tests for Tuya climate actions (#156935) 2025-11-20 15:23:04 +02:00
bestycame
0a034b9984 Add Hanna integration (#147085)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Olivier d'Otreppe <odotreppe@abbove.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-20 14:20:14 +01:00
epenet
6a8106c0eb Add tests for Tuya fan actions (#156919) 2025-11-20 14:25:05 +02:00
epenet
2cacfc7413 Migrate Tuya fan (preset) to use wrapper class (#156922) 2025-11-20 13:19:37 +01:00
epenet
388ab5c16c Migrate Tuya climate (fan_mode) to use wrapper class (#156721) 2025-11-20 13:02:33 +01:00
epenet
81ea6f8c25 Migrate Tuya vacuum (status) to use wrapper class (#156744) 2025-11-20 14:01:18 +02:00
Joost Lekkerkerker
4f885994b7 Remove deprecation for SmartThings binary sensor (#156924) 2025-11-20 11:53:50 +01:00
Hessel
25e2c9ee80 Cache token info in Wallbox (#154147)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-20 11:12:11 +01:00
epenet
12c04f5571 Use pytest.parametrize in Tuya siren/switch/valve tests (#156920) 2025-11-20 10:46:57 +01:00
epenet
3ad1c6a47a Use pytest.parametrize in Tuya cover tests (#156921) 2025-11-20 11:38:14 +02:00
Åke Strandberg
e7e13ecc74 Refactor miele program id codes part 3(3) (#144196)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-20 09:59:28 +01:00
J. Nick Koston
991b8d2040 Bump aioshelly to 13.19.0 (#156902) 2025-11-19 17:52:55 -06:00
J. Nick Koston
43fadbf6b4 Bump aioshelly to 13.18.0 (#156887) 2025-11-19 19:00:10 +02:00
Maciej Bieniek
ca79d37135 Use native_value property instead of _attr_native_value in the Brother integration (#156878) 2025-11-19 16:06:11 +01:00
Paul Bottein
df8ef15535 Add reorder floors and areas websocket command (#156802)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-19 09:58:07 -05:00
Maciej Bieniek
249c1530d0 Address comments for Brother tests (#156877) 2025-11-19 15:06:27 +01:00
Maciej Bieniek
081b769abc Use Brother printer model as model_id (#156876) 2025-11-19 14:44:22 +01:00
Josef Zweck
b8b101d747 Lamarzocco fix websocket reconnect issue (#156786)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2025-11-19 13:06:29 +01:00
Sebastian Schneider
a19be192e0 Bump aiounifi to 88 (#156867) 2025-11-19 13:04:20 +01:00
Josef Zweck
92da82a200 Bump onedrive-personal-sdk to 0.0.17 (#156865) 2025-11-19 13:03:37 +01:00
Paul Bottein
820ba1dfba Add system-level frontend data storage (#155945) 2025-11-19 06:59:34 -05:00
Ludovic BOUÉ
63c8962f09 Add Matter mock lock fixture (#156862) 2025-11-19 12:50:58 +01:00
dependabot[bot]
c1a6996549 Bump github/codeql-action from 4.31.3 to 4.31.4 (#156850)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 12:46:32 +01:00
epenet
05253841af Auto-generate fixture list in Tuya tests (#156858) 2025-11-19 12:38:11 +01:00
Heindrich Paul
f2ef0503a0 Adding new sensors to the cat litter box (#156054)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-19 12:32:54 +01:00
puddly
938da38fc3 Bump universal-silabs-flasher to 0.1.2 (#156849) 2025-11-19 10:46:56 +01:00
Niracler
9311a87bf5 Refactor Sunricher DALI integration to use direct device callbacks (#155315) 2025-11-19 09:47:45 +01:00
Louis
b45294ded3 unifi: Add wired client link speed sensor and related tests (#155086)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Robert Svensson <Kane610@users.noreply.github.com>
2025-11-19 09:26:26 +01:00
Andre Lengwenus
82d3190016 Bump pypck to 0.9.5 (#156847) 2025-11-19 06:52:29 +01:00
omrishiv
d8cbcc1977 Bump pylutron-caseta to 0.26.0 (#156825)
Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com>
2025-11-18 23:01:34 +01:00
Raj Laud
4b69543515 Add support for Victron bluetooth low energy devices (#148043)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-18 21:12:48 +01:00
Thomas55555
97ef4a35b9 Bump aioautomower to 2.7.1 (#156826) 2025-11-18 20:32:47 +01:00
Dan Raper
f782c78650 Bump ohmepy and remove advanced_settings_coordinator (#156764) 2025-11-18 19:52:17 +01:00
Abílio Costa
139ed34c74 Properly mock integrations' file_path (#156813) 2025-11-18 18:42:35 +01:00
Andre Lengwenus
7f14d013ac Strict typing for lcn integration (#156800) 2025-11-18 18:26:24 +01:00
Artur Pragacz
963e27dda4 Send snapshot analytics for device database in dev (#155717) 2025-11-18 16:15:27 +00:00
Yuxin Wang
b8e3d57fea Deprecate useless sensors in APCUPSD integration (#151525) 2025-11-18 17:09:38 +01:00
Heindrich Paul
0de2a16d0f Add binary sensor support and refactor NS sensor integration (#154589)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-18 16:29:09 +01:00
David Rapan
c8c2413a09 Fix Shelly sleeping sensor with channel name (#156708)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-18 16:28:21 +01:00
Fredrik Mårtensson
291331f878 Fix is_matching in samsungtv config flow (#156594)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-18 16:12:21 +01:00
David
a13cdbdf3d Add new Tuya dehumidifier test fixture (#156799)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-18 16:07:37 +01:00
epenet
1bf713f279 Set kw_only in Tuya TypeInformation (#156804)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-11-18 15:58:46 +01:00
Heindrich Paul
10c8ee417b Refactor Nederlandse Spoorwegen integration (#154616)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Erwin Douna <e.douna@gmail.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-18 15:53:49 +01:00
Jamin
b23134f4f1 Reset state on error during VOIP announcement (#156384) 2025-11-18 15:36:41 +01:00
Joost Lekkerkerker
f45a6f806b Add Cosori virtual integration (#156792) 2025-11-18 13:38:32 +01:00
Ludovic BOUÉ
d3857a00d5 Rename Matter thermostat fixture (#156795) 2025-11-18 13:25:08 +01:00
Copilot
8c9b90a9f9 Fix hvv_departures to pass config_entry explicitly to DataUpdateCoordinator (#156794)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: joostlek <7083755+joostlek@users.noreply.github.com>
2025-11-18 12:32:55 +01:00
Timothy
4eedc88935 Store Mobile app pending updates when enabling back an entity (#156026)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-18 12:26:13 +01:00
Abílio Costa
343ea1b82d Return target in trigger description command (#156766)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2025-11-18 12:16:28 +01:00
Lukas
36e13653d2 New virtual integration Vagner Pool supported by pooldose (#156678)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-18 11:46:46 +01:00
dependabot[bot]
80444b2165 Bump actions/checkout from 5.0.0 to 5.0.1 (#156780)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 11:43:52 +01:00
epenet
262f06dd2b Migrate Tuya light (color_temp) to use wrapper class (#156743)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-18 11:43:32 +01:00
epenet
bd87119c2e Fix blocking call in cync (#156782) 2025-11-18 11:41:54 +01:00
Andre Lengwenus
0dfa037aa8 Refactor device classes for LCN (#156791) 2025-11-18 11:39:23 +01:00
Artur Pragacz
c32a471573 Register music assistant services in async setup (#155963) 2025-11-18 11:38:58 +01:00
valexi7
97b7e51171 Add fixture for Tuya Wifi Knob Thermostat wk_t94pit6zjbask9qo (#156781)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-18 08:34:21 +01:00
David Rapan
433712b407 Add Shelly binary sensor translation (#154116)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-17 22:39:14 +02:00
Luca Angemi
5d87e0f429 Make Google sheets datetime column optional (#155861)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-11-17 19:48:17 +00:00
tronikos
acb087f1e5 Mark Google Assistant SDK as gold (#148077) 2025-11-17 17:37:41 +01:00
Andre Lengwenus
10c12623bf Switch LCN integration to local polling (#152601) 2025-11-17 15:50:26 +01:00
stegm
2fe20553b3 Add new settings option to kostal plenticore (#153162) 2025-11-17 15:45:50 +01:00
Tom Matheussen
b431bb197a Sync quality scale tracking with codebase (#156440) 2025-11-17 15:41:30 +01:00
Manu
eb9d625926 Fix return type annotations and enable strict typing in Xbox integration (#156746) 2025-11-17 14:38:02 +01:00
PaulCavill
3a69534b09 Bump pyiCloud to 2.2.0 (#156485) 2025-11-17 14:32:01 +01:00
Erik Montnemery
8f2cedcb73 Run hassfest if conditions.yaml or triggers.yaml is changed (#156738) 2025-11-17 12:26:50 +01:00
epenet
3658953ff3 Migrate Tuya light (brightness) to use wrapper class (#156735) 2025-11-17 11:58:16 +01:00
dotlambda
0be5893e37 sonos requires defusedxml (#156718) 2025-11-17 08:21:55 +01:00
Allen Porter
c87e38c4cf Add Nest config flow data_description fields to fix quality scale item (#156713) 2025-11-17 08:13:15 +01:00
Allen Porter
4874610ad6 Bump google-nest-sdm to 9.0.1 (#156707) 2025-11-16 23:13:40 +01:00
Michael
9180282fc6 Add update entity to AdGUard Home (#156682)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-16 22:52:38 +01:00
J. Nick Koston
118f30f32e Bump dbus to 3.0.0 (#156704) 2025-11-16 22:34:31 +01:00
Bouwe Westerdijk
bd10da126f Revisit diagnostic-category assignments for Plugwise (#156279) 2025-11-16 21:29:24 +01:00
starkillerOG
b73a7928ca Enable Reolink RTSP and ONVIF port when supported (#156700) 2025-11-16 21:24:25 +01:00
Jan Bouwhuis
3e20c2ea93 Fix missing description placeholders in MQTT subentry flow (#156684) 2025-11-16 21:21:22 +01:00
andreipoenaru
60130d3d68 Add support for encoded URLs to RESTful Command (#154957)
Co-authored-by: Jan-Philipp Benecke <jan-philipp@bnck.me>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-16 21:04:18 +01:00
Denis Shulyaka
c45ede2e5d Bump anthropic to 0.73.0 (#156692) 2025-11-16 21:02:55 +01:00
J. Nick Koston
e167061f53 Bump dbus-fast to 2.46.4 (#156703) 2025-11-16 20:52:05 +01:00
Kamil Breguła
5560fb6c9e Refactor tests in GIOS (#155756)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-11-16 20:21:46 +01:00
J. Nick Koston
9808b6c961 Bump dbus-fast to 2.46.1 (#156695) 2025-11-16 19:34:29 +01:00
J. Nick Koston
e8cfde579e Bump dbus-fast to 2.46.0 (#156693) 2025-11-16 09:46:53 -06:00
J. Nick Koston
f695fb4d51 Bump dbus-fast to 2.45.1 (#156691) 2025-11-16 09:12:44 -06:00
Jan Bouwhuis
a0e0549d90 Fix missing temperature_delta device class translations (#156685) 2025-11-16 15:00:51 +01:00
epenet
ba034c6c8c Add alarm_state to Tuya siren alarm (#151221) 2025-11-16 12:26:33 +01:00
Åke Strandberg
008bb85c59 Mock arguments in senz tests (#156677) 2025-11-16 12:25:28 +01:00
Michael
cf1c1294d3 Bump adguardhome to 0.8.1 (#156679) 2025-11-16 12:16:17 +01:00
Åke Strandberg
11d5d314cc Fix type hints in miele tests (#156657) 2025-11-16 12:12:45 +01:00
Joost Lekkerkerker
6f0de3071a Add fixture for dual washing machine to SmartThings (#156646) 2025-11-16 11:43:25 +01:00
mettolen
87d2597292 Add diagnostics to Saunum integration (#156623) 2025-11-16 11:40:49 +01:00
Manu
437bc04fe8 Remove Live-TV support from Xbox integration (#156669) 2025-11-16 11:30:04 +01:00
Åke Strandberg
67a0d6a187 Mock arguments to ClientResponseError() in miele tests (#156676) 2025-11-16 10:03:32 +01:00
Lukas
abb52bca81 Add more sensors to Pooldose (#156002)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-15 23:02:27 +01:00
J. Nick Koston
d2d6889278 Bump thermopro-ble to 1.1.2 (#156652) 2025-11-15 14:10:59 -06:00
David Rapan
bdca592219 Add Shelly event translation (#156162)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-15 20:52:13 +02:00
Michael
5c0c7b9ec3 Bump adguardhome to 0.8.0 (#156651) 2025-11-15 16:26:05 +01:00
TheDK
9717599fb9 Use SensorDeviceClass.PRESSURE in Withings (#156648)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-15 16:08:34 +01:00
MarkGodwin
4d7de2f814 Bump tplink-omada-api to 1.5.3 (#156645) 2025-11-15 15:39:56 +01:00
epenet
779590ce1c Migrate Tuya climate (humidity) to use wrapper class (#156575) 2025-11-15 15:05:52 +01:00
epenet
f3a185ff9c Migrate Tuya cover to use wrapper class (#156558)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-15 15:04:54 +01:00
epenet
5a5a106984 Migrate Tuya humidifier to use wrapper class (#156572)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-15 15:03:30 +01:00
epenet
796b421d99 Migrate Tuya vacuum to use wrapper class (#156569) 2025-11-15 15:02:49 +01:00
epenet
0c03e8dbe9 Migrate Tuya light (color_mode) to use wrapper class (#156582) 2025-11-15 15:02:40 +01:00
epenet
47cf4e3ffe Ensure Tuya scale and step are integers (#156555) 2025-11-15 14:30:44 +02:00
epenet
0ea0fc151d Use parametrize in tuya climate tests (#156577) 2025-11-15 14:28:57 +02:00
Åke Strandberg
b7e5afec9f Fix typing in miele tests (#156637) 2025-11-15 12:19:34 +01:00
cdnninja
7a2bb67e82 Refactor vesync test (#156625) 2025-11-15 09:24:48 +01:00
Manu
e0612bec07 Bump pythonkuma to v0.3.2 (#156626) 2025-11-15 03:43:16 +01:00
Denis Shulyaka
a06f4b6776 Anthropic model selection from list (#156261) 2025-11-14 21:16:52 -05:00
Denis Shulyaka
275670a526 Add support for gpt-5.1 (#156612) 2025-11-14 18:39:05 -05:00
Robert Resch
d0d62526dd Bump async-upnp-client to 0.46.0 (#156622) 2025-11-14 18:30:18 -05:00
Franck Nijhof
aefdf412b0 Extract device template functions into a devices Jinja2 extension (#156619) 2025-11-15 00:23:38 +01:00
Franck Nijhof
ee05adfca1 2025.11.2 (#156620) 2025-11-14 23:09:51 +01:00
Franck Nijhof
168c915b5f Update snapshots 2025-11-14 21:43:53 +00:00
Franck Nijhof
6c80be52af Bump version to 2025.11.2 2025-11-14 21:15:12 +00:00
Simone Chemelli
ead92cdf82 Add debounce to Alexa Devices coordinator (#156609) 2025-11-14 21:14:11 +00:00
Thomas55555
c0f0cfef59 Fix model_id in Husqvarna Automower (#156608) 2025-11-14 21:14:09 +00:00
epenet
cefc0ba96e Fix sfr_box entry reload (#156593) 2025-11-14 21:14:08 +00:00
TheJulianJES
ad091b1062 Bump ZHA to 0.0.79 (#156571) 2025-11-14 21:14:07 +00:00
TheJulianJES
876bc6d8c4 Bump ZHA to 0.0.78 (#155937) 2025-11-14 21:14:05 +00:00
Joost Lekkerkerker
9f206d4363 Bump python-open-router to 0.3.3 (#156563) 2025-11-14 21:12:17 +00:00
starkillerOG
a2d11e6d98 Bump reolink-aio to 0.16.5 (#156553) 2025-11-14 21:12:16 +00:00
Willem-Jan van Rootselaar
3b38af3984 Update bsblan to python-bsblan version 3.1.1 (#156536)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-11-14 21:12:14 +00:00
Joost Lekkerkerker
3875f91bb9 Bump pySmartThings to 3.3.3 (#156528) 2025-11-14 21:12:13 +00:00
Jan Čermák
c813776b0c Update Home Assistant base image to 2025.11.0 (#156517) 2025-11-14 21:12:12 +00:00
Foscam-wangzhengyu
3afb421cba URL-encode the RTSP URL in the Foscam integration (#156488)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-14 21:12:10 +00:00
puddly
c16633568b Add firmware flashing debug loggers to hardware integrations (#156480)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-14 21:12:09 +00:00
Josef Zweck
87f8ff2bb4 Fix lamarzocco update status (#156442) 2025-11-14 21:12:08 +00:00
cdnninja
b423303f1e Bump pyvesync to 3.2.2 (#156423)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-11-14 21:12:06 +00:00
Brett Adams
f6ff222679 Fix update progress in Teslemetry (#156422) 2025-11-14 21:12:05 +00:00
Manu
0152fa0c03 Prevent sensor updates caused by fluctuating “last seen” timestamps in Xbox integration (#156419) 2025-11-14 21:12:03 +00:00
Daniel Hjelseth Høyer
37ebbe83bc Update pyMill to 0.14.1 (#156396) 2025-11-14 21:12:02 +00:00
antoniocifu
63e036d39e Fix support for Hyperion 2.1.1 (#156343)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-14 21:12:01 +00:00
Erik Montnemery
f0cbf34a78 Check collation of statistics_meta DB table (#156327) 2025-11-14 21:11:59 +00:00
Teemu R.
596bc89ee6 tplink: handle repeated, unknown thermostat modes gracefully (#156310) 2025-11-14 21:11:58 +00:00
Assaf Inbal
b8c877e1d2 Ituran: Don't cache properties (#156281) 2025-11-14 21:11:56 +00:00
Åke Strandberg
197d9781cb Improve logging of failing miele action commands (#156275) 2025-11-14 21:11:55 +00:00
Erik Montnemery
f3f323637e Correct migration to recorder schema 51 (#156267)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-14 21:11:54 +00:00
Joost Lekkerkerker
9748abc103 Bump pySmartThings to 3.3.2 (#156250) 2025-11-14 21:11:52 +00:00
dotvav
596f049971 Bump pypalazzetti lib from 0.1.19 to 0.1.20 (#156249) 2025-11-14 21:11:51 +00:00
Foscam-wangzhengyu
dee80cb6f5 Foscam Integration with Legacy Model Compatibility (#156226)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-14 21:11:50 +00:00
Michael
b4ab73468b Fix Climate state reproduction when target temperature is None (#156220) 2025-11-14 21:11:48 +00:00
cdnninja
a300199a97 Bump pyvesync to 3.2.1 (#156195) 2025-11-14 21:11:47 +00:00
Simone Chemelli
09dd765583 Fix config flow reconfigure for Comelit (#156193) 2025-11-14 21:11:46 +00:00
starkillerOG
0c8b765415 Fix set_absolute_position angle (#156185) 2025-11-14 21:11:44 +00:00
Paul Annekov
0824ec502f Forbid to choose state in Ukraine Alarm integration (#156183) 2025-11-14 21:11:43 +00:00
Matthias Alphart
9e0e353a5f Update xknx to 3.10.1 (#156177) 2025-11-14 21:11:42 +00:00
Abílio Costa
e934b006e2 Fix MFA Notify setup flow schema (#156158) 2025-11-14 21:11:40 +00:00
Jan Rieger
05479bb8fd Bump aio-ownet to 0.0.5 (#156157) 2025-11-14 21:11:39 +00:00
TheJulianJES
d07247566d Log HomeAssistantErrors in ZHA config flow (#156075) 2025-11-14 21:11:38 +00:00
Erwin Douna
19e6097df6 Bump pyportainter 1.0.14 (#156072) 2025-11-14 21:11:36 +00:00
Erwin Douna
2cff3cf29c Bump pyportainer 1.0.13 (#155783) 2025-11-14 21:11:35 +00:00
Timothy
5cac9b8e5e Make sure to clean register callbacks when mobile_app reloads (#156028) 2025-11-14 21:09:04 +00:00
Erik Montnemery
c2a516ea32 Fix progress step bugs (#155923) 2025-11-14 21:09:03 +00:00
Nojus
192b38d3e2 Remove arbitrary forecast limit for meteo_lt (#155877) 2025-11-14 21:09:01 +00:00
puddly
bb018e3546 Avoid firing discovery events when flows immediately create a config entry (#155753) 2025-11-14 21:09:00 +00:00
Diogo Gomes
4919d73cc5 Bump cronsim to 2.7 (#155648) 2025-11-14 21:08:58 +00:00
Manu
56ab6b2512 Prevent sensor updates caused by fluctuating “last seen” timestamps in Xbox integration (#156419) 2025-11-14 22:07:13 +01:00
mettolen
d1dea85cf5 Add Saunum integration (#155099)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-14 19:55:55 +01:00
wollew
84b0d39763 clean up velux test fixtures (#156554) 2025-11-14 19:53:17 +01:00
tronikos
3aff225bc3 Add Google Weather integration (#147015)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-14 19:46:56 +01:00
Ludovic BOUÉ
04458e01be Fix spelling of 'Auto-relock time' in Matter integration strings (#156607) 2025-11-14 19:10:57 +01:00
Thomas55555
ae51cfb8c0 Fix model_id in Husqvarna Automower (#156608) 2025-11-14 19:10:16 +01:00
Simone Chemelli
c116a9c037 Add debounce to Alexa Devices coordinator (#156609) 2025-11-14 19:09:19 +01:00
Allen Porter
fb58758684 Add completed timestamp support in Google tasks (#156564) 2025-11-14 12:07:23 -05:00
Franck Nijhof
25fbcbc68c Extract floor template functions into a floors Jinja2 extension (#156589)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-14 12:06:55 -05:00
Denis Shulyaka
a670286b45 Bump openai to 2.8.0 (#156602) 2025-11-14 12:06:21 -05:00
ElectricSteve
52ba55b17f Bump youtubeaio to 2.1.0 (#156595) 2025-11-14 16:01:00 +01:00
epenet
ff0fc98c36 Fix sfr_box entry reload (#156593) 2025-11-14 15:03:43 +01:00
David Rapan
9f78a2263d Move Shelly sensor get_entity_translation_attributes to utils (#156590)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-14 15:44:48 +02:00
Kamil Breguła
9b4696a80b Add quality_scale to mvglive manifest (#155474) 2025-11-14 13:20:10 +01:00
wollew
70fe8cae39 Fix velux scenes (naming and unique ids) (#156436) 2025-11-14 13:18:08 +01:00
wollew
95eb45ab08 cleanup registered callbacks before removing velux config entry (#156525) 2025-11-14 13:06:45 +01:00
Erwin Douna
84f8e57141 Add retry_after to UpdateFailed in update coordinator (#153550)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-14 12:19:02 +01:00
Franck Nijhof
f484b6df0d Extract label template functions into a label Jinja2 extension (#156439)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-14 11:04:31 +01:00
J. Diego Rodríguez Royo
34c1d45ee0 Ensure that Home Connect program update value event is a string when updating options (#156416)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-14 10:51:52 +01:00
epenet
09a105d9ad Migrate Tuya light (switch) to use wrapper class (#156580) 2025-11-14 10:33:58 +01:00
epenet
6bd1787d0a Improve parametrize in tuya light tests (#156581) 2025-11-14 10:19:48 +01:00
David Rapan
37040f5064 Add Shelly switch translation (#156146)
Signed-off-by: David Rapan <david@rapan.cz>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-14 11:16:04 +02:00
puddly
531397ec07 Avoid firing discovery events when flows immediately create a config entry (#155753) 2025-11-14 09:40:46 +01:00
epenet
d6cc0f81de Remove pointless super.async_added_to_hass in Tuya climate (#156573) 2025-11-14 09:31:03 +01:00
TheJulianJES
f8ef8a466a Bump ZHA to 0.0.79 (#156571) 2025-11-14 09:30:38 +01:00
Åke Strandberg
713015e26a Improve logging of failing miele action commands (#156275) 2025-11-14 09:10:24 +01:00
Åke Strandberg
f9c1e81c5e Improve error handling and add tests to senz climate (#156544) 2025-11-14 09:06:56 +01:00
Joost Lekkerkerker
0549d113e6 Bump python-open-router to 0.3.3 (#156563) 2025-11-14 08:48:47 +01:00
dependabot[bot]
0d842978ec Bump github/codeql-action from 4.31.2 to 4.31.3 (#156565) 2025-11-13 23:05:52 -08:00
Nojus
55476ef6ea Remove arbitrary forecast limit for meteo_lt (#155877) 2025-11-14 00:14:48 +01:00
starkillerOG
0e130d8fdd Bump reolink-aio to 0.16.5 (#156553) 2025-11-14 00:12:03 +01:00
slickm0nty
20bcb84956 Set suggested display precision in modbus integration (#155467) 2025-11-13 22:47:40 +00:00
jlanchares
bbb1d57081 Goodwe port502ftp support with PORT stored on config data. (#148628)
Co-authored-by: starkillerOG <starkiller.og@gmail.com>
2025-11-13 21:12:47 +01:00
hanwg
121406569b Upgrade Telegram bot quality scale to Silver (#155352) 2025-11-13 21:08:35 +01:00
Joost Lekkerkerker
4866c775ce Fix CI (#156549) 2025-11-13 21:08:08 +01:00
Willem-Jan van Rootselaar
7c5ab12270 Update bsblan to python-bsblan version 3.1.1 (#156536)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-11-13 20:44:12 +01:00
Erik Montnemery
099edfac20 Fix flux_led tests opening sockets (#156458) 2025-11-13 20:39:56 +01:00
epenet
aa31df0fd5 Migrate Tuya camera to use wrapper class (#156542) 2025-11-13 20:38:44 +01:00
Bram Kragten
13fbeb6cdb Add support for trigger and condition category icons (#156533) 2025-11-13 14:36:34 -05:00
karwosts
8d557447df Add completed timestamp to TodoItem (#156547)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-11-13 14:35:33 -05:00
Joakim Sørensen
e6e3f2455f Add discovery_service_actions configuration option (#156537) 2025-11-13 14:35:22 -05:00
epenet
c9c518ee84 Improve IntegerTypeData scaling in Tuya (#156507) 2025-11-13 20:29:07 +01:00
Magnus
214731e964 Component asuswrt: Type check is redundant for this value (#154535) 2025-11-13 20:24:24 +01:00
Jan Čermák
c4b09c9a0a Update Home Assistant base image to 2025.11.0 (#156517) 2025-11-13 20:01:22 +01:00
epenet
f5b5b2fb70 Remove unused/absent property from Tuya (#156508) 2025-11-13 19:32:08 +01:00
Manu
bb3cdd382b Add media_content_id to media player in Xbox integration (#156519) 2025-11-13 19:25:43 +01:00
starkillerOG
8d09b5c273 Relax Reolink update interval and timeout for big installs (#156509) 2025-11-13 19:25:03 +01:00
epenet
d92fa7fa72 Move more logic from entity to wrapper in Tuya alarm (#156450) 2025-11-13 18:37:47 +01:00
Åke Strandberg
0c45b7f615 Add reconfiguration flow to senz (#156539) 2025-11-13 16:49:16 +01:00
Alexandre CUER
bfa1116115 Add quality scale to Emoncms (#149727)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-13 16:10:29 +01:00
Arie Catsman
4984237987 Add alternative ct meter source to enphase_envoy diagnostics (#154468) 2025-11-13 15:37:36 +01:00
Joost Lekkerkerker
3839573151 Bump pySmartThings to 3.3.3 (#156528) 2025-11-13 15:31:03 +01:00
Åke Strandberg
e02dc53df3 Add reauthentication flow and tests to senz (#156534) 2025-11-13 15:28:45 +01:00
Arie Catsman
bedae1e12c Optimize Enphase_Envoy CT sensor entity code (#153859) 2025-11-13 14:59:24 +01:00
epenet
b4eb73be98 Improve tests for Tuya alarm control panel (#156481) 2025-11-13 14:44:38 +01:00
wollew
0ac3f776fa set shorthand atrributes for supported_features in velux cover (#156524) 2025-11-13 14:18:20 +01:00
Petar Petrov
8e8a4fff11 Extract grid, gas, and water source validation into separate functions (#156515) 2025-11-13 13:28:25 +01:00
Åke Strandberg
579ffcc64d Add unique_id to senz config_entry (#156472) 2025-11-13 12:26:33 +01:00
Foscam-wangzhengyu
81943fb31d URL-encode the RTSP URL in the Foscam integration (#156488)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-13 12:23:28 +01:00
Petro31
70dd0bf12e Modernize template alarm control panel (#156476) 2025-11-13 12:21:03 +01:00
Tom Matheussen
c2d462c1e7 Refactor Satel Integra platforms to use shared base entity (#156499) 2025-11-13 12:20:32 +01:00
epenet
49e050cc60 Redact more DP codes in tuya diagnostics (#156497) 2025-11-13 12:18:43 +01:00
Josef Zweck
f6d829a2f3 Bump pylamarzocco to 2.1.3 (#156501) 2025-11-13 11:54:15 +01:00
Aarni Koskela
e44e3b6f25 Rename RuuviTag BLE to Ruuvi BLE (#156504) 2025-11-13 11:36:50 +01:00
Christopher Fenner
af603661c0 Fix spelling in ViCare integration (#156500) 2025-11-13 10:54:55 +01:00
puddly
35c6113777 Add firmware flashing debug loggers to hardware integrations (#156480)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-13 09:25:00 +01:00
TheJulianJES
3c2f729ddc Fix Z-Wave generating name before setting entity description (#156494) 2025-11-13 08:18:22 +01:00
Erik Montnemery
0d63cb765f Fix lg_netcast tests opening sockets (#156459)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-13 07:44:56 +01:00
TheJulianJES
3cb414511b Migrate Z-Wave event entity to new discovery schema (#156320) 2025-11-13 07:22:37 +01:00
karwosts
f55c36d42d Update ical to 11.1.0 (#156487) 2025-11-12 20:24:04 -08:00
Erik Montnemery
26bb301cc0 Fix lifx tests opening sockets (#156460) 2025-11-12 21:51:54 +02:00
Erik Montnemery
4159e483ee Fix wiz tests opening sockets (#156468) 2025-11-12 20:11:15 +01:00
Erik Montnemery
7eb6f7cc07 Fix romy tests opening sockets (#156466) 2025-11-12 20:10:46 +01:00
epenet
a7d01b0b03 Use json_loads_object in tuya models (#156455) 2025-11-12 20:08:28 +01:00
epenet
1e5cfddf83 Use json_loads_object in Tuya light (#156452) 2025-11-12 19:34:17 +01:00
epenet
006fc5b10a Remove JSON parsing from tuya diagnostics (#156451) 2025-11-12 19:32:40 +01:00
Erik Montnemery
35a4b685b3 Fix steamist tests opening sockets (#156467) 2025-11-12 12:01:21 -06:00
Janez Urevc
b166818ef4 Bump tesla-wall-connector to 1.1.0 (#156438) 2025-11-12 17:45:08 +01:00
Erik Montnemery
34cd9f11d0 Fix onkyo tests opening sockets (#156461) 2025-11-12 17:32:58 +01:00
Erik Montnemery
0711d62085 Change collation to utf8mb4_bin for MySQL and MariaDB databases (#156297)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-12 16:54:58 +01:00
J. Diego Rodríguez Royo
f70aeafb5f Bump aiohomeconnect to version 0.23.1 (#156454) 2025-11-12 15:59:20 +01:00
MoonDevLT
e2279b3589 Bump lunatone-rest-api-client to 0.5.7 (#156356) 2025-11-12 14:44:52 +01:00
Christopher Fenner
87b68e99ec Add compressor, condensor and evaporator sensors in ViCare integration (#156411) 2025-11-12 14:42:26 +01:00
Manu
b6c8b787e8 Add device storage sensor entities to Xbox (#155657) 2025-11-12 13:53:42 +01:00
Franck Nijhof
78f26edc29 Extend base jinja2 extension with limited template errors (#156431) 2025-11-12 13:52:15 +01:00
ehendrix23
5e6a72de90 Bump pyecobee to 0.3.2 (#156421)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-11-12 13:40:08 +01:00
Erik Montnemery
dcc559f8b6 Fix progress step bugs (#155923) 2025-11-12 13:14:53 +01:00
Manu
eda49cced0 Code quality improvements for Xbox integration (#156395) 2025-11-12 14:09:53 +02:00
Josef Zweck
14e41ab119 Fix lamarzocco update status (#156442) 2025-11-12 13:10:23 +02:00
Timothy
46151456d8 Make sure to clean register callbacks when mobile_app reloads (#156028) 2025-11-12 12:03:05 +01:00
cdnninja
39773a022a Bump pyvesync to 3.2.2 (#156423)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-11-12 11:59:45 +01:00
Christopher Fenner
5f49a6450f Add air quality sensors in ViCare integration (#156417) 2025-11-12 11:45:04 +01:00
Christopher Fenner
dc8425c580 Add icon for pm4 sensor (#156432) 2025-11-12 11:38:33 +01:00
Josef Zweck
910bd371e4 Remove wsproto from exceptions (#156434) 2025-11-12 11:16:36 +01:00
Tom Matheussen
802a225e11 Clean alarm control panel platform for Satel Integra (#156357) 2025-11-12 11:09:48 +01:00
Josef Zweck
84f66fa689 Fix aussie-broadband tests (#156441) 2025-11-12 10:54:23 +01:00
wollew
0b7e88d0e0 add parallel_updates for button entity (#156437) 2025-11-12 11:49:32 +02:00
puddly
1fcaf95df5 Bump universal-silabs-flasher to v0.1.0 (#156291)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-12 10:44:33 +01:00
Erik Montnemery
6c7434531f Fix tado tests opening sockets (#156386) 2025-11-12 10:08:15 +01:00
Åke Strandberg
5ec1c2b68b Use runtime_data in Senz (#156408) 2025-11-12 10:06:45 +01:00
Christopher Fenner
d8636d8346 Bump PyViCare to 2.55.0 (#156426) 2025-11-12 09:57:49 +01:00
Brett Adams
434763c74d Fix update progress in Teslemetry (#156422) 2025-11-12 09:55:09 +01:00
Petar Petrov
8cd2c1b43b Add power configuration to Energy dashboard (#153809)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 09:21:33 +01:00
Daniel Hjelseth Høyer
44711787a4 Update pyMill to 0.14.1 (#156396) 2025-11-12 09:15:59 +01:00
TheJulianJES
98fd0ee683 Exempt wsproto from license check (#156418) 2025-11-12 08:45:11 +01:00
Joost Lekkerkerker
303e4ce961 Add mac address to Velux device (#156376) 2025-11-12 09:45:02 +02:00
Paul Bottein
76f29298cd Add home panel (#156269) 2025-11-12 09:09:39 +02:00
Will Moss
17f5d0a69f Use common string for the remaining oauth2 error messages (#156407) 2025-11-12 04:43:12 +01:00
johanzander
90561de438 Refactor Growatt Server integration tests (#156413)
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-12 00:32:25 +01:00
Will Moss
aedd48c298 Improved error handling for oauth2 configuration in toon integration (#156218) 2025-11-11 22:38:46 +01:00
Will Moss
febbb85532 Improved error handling for oauth2 configuration in netatmo integration (#156207) 2025-11-11 22:37:56 +01:00
Franck Nijhof
af67a35b75 Extend base jinja2 extension with hass requirement and tests (#156403) 2025-11-11 22:34:08 +01:00
Will Moss
dd34d458f5 Improved error handling for oauth2 configuration in tesla_fleet integration (#156219) 2025-11-11 22:33:20 +01:00
Will Moss
603d4bcf87 Improved error handling for oauth2 configuration in weheat integration (#156217) 2025-11-11 22:23:56 +01:00
Erik Montnemery
2dadc1f2b3 Fix iskra tests opening sockets (#156374) 2025-11-11 21:18:14 +01:00
epenet
936151fae5 Use dpcode_wrapper in tuya sensor platform (#156277) 2025-11-11 21:16:41 +01:00
wollew
9760eb7f2b Deprecate velux reboot action (#155549)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-11 20:23:07 +01:00
Erik Montnemery
7851bed00c Fix zimi tests opening sockets (#156382) 2025-11-11 11:48:30 -06:00
wollew
6aba0b20c6 Add Velux initial quality scale assessment (#154615) 2025-11-11 18:46:24 +01:00
Åke Strandberg
cadfed2348 Add diagnostics to SENZ (#156383) 2025-11-11 18:19:37 +01:00
Åke Strandberg
44e2fa6996 Improve handling of OAuth2 implementation unavailable in SENZ (#156381) 2025-11-11 17:42:19 +01:00
Andrew Jackson
d0ff617e17 Transmission Service validation and fixes (#155554) 2025-11-11 17:29:42 +01:00
wollew
8e499569a4 Add reboot button to velux gateway device (#155547)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-11 17:10:20 +01:00
Åke Strandberg
5e0ebddd6f Add temperature sensor to SENZ integration (#156181) 2025-11-11 16:33:49 +01:00
Artur Pragacz
c0f61f6c2b Improve code quality of music assistant config flow (#156263) 2025-11-11 16:06:54 +01:00
Manu
df60de38b0 Add In party sensor to Xbox integration (#155967) 2025-11-11 16:05:38 +01:00
Manu
cb086bb8e9 Refactor media source platform in Xbox integration (#155925) 2025-11-11 15:01:53 +01:00
Erik Montnemery
ee2e9dc7d6 Fix homewizard tests opening sockets (#156370) 2025-11-11 15:00:18 +01:00
TheJulianJES
85cd3c68b7 Remove redundant Z-Wave binary sensor entity_description arg (#156323) 2025-11-11 15:00:07 +01:00
Erik Montnemery
1b0b6e63f2 Fix squeezebox tests opening sockets (#156373) 2025-11-11 15:50:56 +02:00
Erik Montnemery
12fc79e8d3 Fix google_generative_ai_conversation tests opening sockets (#156371) 2025-11-11 14:33:36 +01:00
Ludovic BOUÉ
ca2e7b9509 Add Matter Eve Shutter device with corresponding fixtures and snapshots (#156296) 2025-11-11 14:07:08 +01:00
Teemu R.
8e8becc43e tplink: handle repeated, unknown thermostat modes gracefully (#156310) 2025-11-11 14:06:29 +01:00
Paul Annekov
dcec6c3dc8 Forbid to choose state in Ukraine Alarm integration (#156183) 2025-11-11 14:05:14 +01:00
Retha Runolfsson
c0e59c4508 Add support for switchbot s20 (#156368) 2025-11-11 13:55:50 +01:00
Erik Montnemery
cd379aadbf Use pytest.mark.freeze_time in sensibo tests (#156348) 2025-11-11 13:52:19 +01:00
antoniocifu
ccdd54b187 Fix support for Hyperion 2.1.1 (#156343)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-11 13:18:35 +01:00
Marc Mueller
3f22dbaa2e Update pytest to 9.0.0 (#156365) 2025-11-11 13:18:09 +01:00
Retha Runolfsson
c18dc0a9ab Add support for Switchbot Smart thermostat radiator (#155123) 2025-11-11 13:12:39 +01:00
Erik Montnemery
f0e4296d93 Use pytest.mark.freeze_time in sensor tests (#156349) 2025-11-11 13:05:52 +01:00
Erik Montnemery
b3750109c6 Use pytest.mark.freeze_time in playstation_network tests (#156347) 2025-11-11 13:05:38 +01:00
Erik Montnemery
93025c9845 Use pytest.mark.freeze_time in pglab tests (#156346) 2025-11-11 13:05:17 +01:00
Erik Montnemery
df348644b1 Use pytest.mark.freeze_time in openai_conversation tests (#156345) 2025-11-11 13:05:02 +01:00
Erik Montnemery
8749b0d750 Use pytest.mark.freeze_time in smhi tests (#156352) 2025-11-11 13:02:21 +01:00
Erik Montnemery
a6a1519c06 Use pytest.mark.freeze_time in snoo tests (#156353) 2025-11-11 13:02:01 +01:00
Erik Montnemery
3068e19843 Use pytest.mark.freeze_time in telegram_bot tests (#156354) 2025-11-11 13:01:34 +01:00
Erik Montnemery
55feb1e735 Use pytest.mark.freeze_time in tomorrowio tests (#156355) 2025-11-11 13:01:29 +01:00
Erik Montnemery
bb7dc69131 Use pytest.mark.freeze_time in yale_smart_alarm tests (#156359) 2025-11-11 12:06:22 +01:00
Erik Montnemery
aa9003a524 Use pytest.mark.freeze_time in wake_word tests (#156360) 2025-11-11 12:06:12 +01:00
Erik Montnemery
4e9da5249d Use pytest.mark.freeze_time in utility_meter tests (#156361) 2025-11-11 12:05:58 +01:00
Erik Montnemery
f502739df2 Use pytest.mark.freeze_time in zha tests (#156358) 2025-11-11 12:04:59 +01:00
Erik Montnemery
0f2ff29378 Use pytest.mark.freeze_time in sleep_as_android tests (#156351) 2025-11-11 12:04:40 +01:00
Erik Montnemery
2921e7ed3c Use pytest.mark.freeze_time in plaato tests (#156362) 2025-11-11 12:04:31 +01:00
Christopher Fenner
25d44e8d37 Enhance compressor phase with state translations in ViCare integration (#156238) 2025-11-11 11:20:27 +01:00
Will Moss
0a480a26a3 Remove import of config_entry_oauth2_flow in scaffold in favor of direct imports (#156302) 2025-11-11 11:17:31 +01:00
Khole
d5da64dd8d Bump pyhive to 1.0.7 (#156309) 2025-11-11 11:16:11 +01:00
wollew
92adcd8635 add the velux KLF 200 gateway as device (#155434)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-11 11:13:18 +01:00
Franck Nijhof
f3ddffb5ff 2025.11.1 (#156076) 2025-11-07 13:29:37 -08:00
Franck Nijhof
9bdfa77fa0 Merge branch 'master' into rc 2025-11-07 12:41:56 -08:00
Franck Nijhof
c65003009f Bump version to 2025.11.1 2025-11-07 20:36:12 +00:00
Michael Hansen
0f722109b7 Bump intents to 2025.11.7 (#156063) 2025-11-07 20:35:56 +00:00
Foscam-wangzhengyu
f7d86dec3c Fix the exception caused by the missing Foscam integration key (#156022) 2025-11-07 20:35:55 +00:00
Josef Zweck
6b49c8a70c Bump onedrive-personal-sdk to 0.0.16 (#156021) 2025-11-07 20:35:54 +00:00
epenet
ab9a8f3e53 Bump tuya-device-sharing-sdk to 0.2.5 (#156014) 2025-11-07 20:35:53 +00:00
johanzander
4e12628266 Fix Growatt integration authentication error for legacy config entries (#155993)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-07 20:35:51 +00:00
Simone Chemelli
e6d8d4de42 Bump aioamazondevices to 8.0.1 (#155989) 2025-11-07 20:35:50 +00:00
tronikos
6620b90eb4 Fix SolarEdge unload failing when there are no sensors (#155979) 2025-11-07 20:35:49 +00:00
tronikos
6fd3af8891 Handle empty fields in SolarEdge config flow (#155978) 2025-11-07 20:35:48 +00:00
Åke Strandberg
46979b8418 Fix for corrupt restored state in miele consumption sensors (#155966) 2025-11-07 20:35:47 +00:00
Marc Mueller
1718a11de2 Truncate password before sending it to bcrypt (#155950) 2025-11-07 20:35:45 +00:00
Matthias Alphart
2016b1d8c7 Fix KNX Climate humidity DPT (#155942) 2025-11-07 20:35:44 +00:00
puddly
4b72e45fc2 Remove @progress_step decorator from ZHA and Hardware integration (#155867)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-07 20:35:43 +00:00
Ståle Storø Hauknes
ead5ce905b Improve scan interval for Airthings Corentium Home 2 (#155694)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-07 20:35:42 +00:00
Franck Nijhof
f233f2da3f Bump version to 2025.11.0 2025-11-05 19:21:40 +00:00
2104 changed files with 176725 additions and 35714 deletions

View File

@@ -13,6 +13,7 @@ core: &core
# Our base platforms, that are used by other integrations
base_platforms: &base_platforms
- homeassistant/components/ai_task/**
- homeassistant/components/air_quality/**
- homeassistant/components/alarm_control_panel/**
- homeassistant/components/assist_satellite/**

View File

@@ -27,7 +27,6 @@
"charliermarsh.ruff",
"ms-python.pylint",
"ms-python.vscode-pylance",
"visualstudioexptteam.vscodeintellicode",
"redhat.vscode-yaml",
"esbenp.prettier-vscode",
"GitHub.vscode-pull-request-github",

View File

@@ -14,6 +14,9 @@ env:
PIP_TIMEOUT: 60
UV_HTTP_TIMEOUT: 60
UV_SYSTEM_PYTHON: "true"
# Base image version from https://github.com/home-assistant/docker
BASE_IMAGE_VERSION: "2025.11.3"
ARCHITECTURES: '["amd64", "aarch64"]'
jobs:
init:
@@ -21,18 +24,16 @@ jobs:
if: github.repository_owner == 'home-assistant'
runs-on: ubuntu-latest
outputs:
architectures: ${{ steps.info.outputs.architectures }}
version: ${{ steps.version.outputs.version }}
channel: ${{ steps.version.outputs.channel }}
publish: ${{ steps.version.outputs.publish }}
architectures: ${{ env.ARCHITECTURES }}
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -79,7 +80,7 @@ jobs:
name: Build ${{ matrix.arch }} base core image
if: github.repository_owner == 'home-assistant'
needs: init
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
@@ -88,13 +89,14 @@ jobs:
fail-fast: false
matrix:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
exclude:
- arch: armv7
- arch: armhf
- arch: i386
include:
- arch: amd64
os: ubuntu-latest
- arch: aarch64
os: ubuntu-24.04-arm
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
@@ -120,7 +122,7 @@ jobs:
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
if: needs.init.outputs.channel == 'dev'
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -188,16 +190,60 @@ jobs:
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.09.0
- &install_cosign
name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
with:
args: |
$BUILD_ARGS \
--${{ matrix.arch }} \
--cosign \
--target /data \
--generic ${{ needs.init.outputs.version }}
cosign-release: "v2.5.3"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Build variables
id: vars
shell: bash
run: |
echo "base_image=ghcr.io/home-assistant/${{ matrix.arch }}-homeassistant-base:${{ env.BASE_IMAGE_VERSION }}" >> "$GITHUB_OUTPUT"
echo "cache_image=ghcr.io/home-assistant/${{ matrix.arch }}-homeassistant:latest" >> "$GITHUB_OUTPUT"
echo "created=$(date --rfc-3339=seconds --utc)" >> "$GITHUB_OUTPUT"
- name: Verify base image signature
run: |
cosign verify \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp "https://github.com/home-assistant/docker/.*" \
"${{ steps.vars.outputs.base_image }}"
- name: Verify cache image signature
id: cache
continue-on-error: true
run: |
cosign verify \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp "https://github.com/home-assistant/core/.*" \
"${{ steps.vars.outputs.cache_image }}"
- name: Build base image
id: build
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
file: ./Dockerfile
platforms: ${{ steps.vars.outputs.platform }}
push: true
cache-from: ${{ steps.cache.outcome == 'success' && steps.vars.outputs.cache_image || '' }}
build-args: |
BUILD_FROM=${{ steps.vars.outputs.base_image }}
tags: ghcr.io/home-assistant/${{ matrix.arch }}-homeassistant:${{ needs.init.outputs.version }}
labels: |
io.hass.arch=${{ matrix.arch }}
io.hass.version=${{ needs.init.outputs.version }}
org.opencontainers.image.created=${{ steps.vars.outputs.created }}
org.opencontainers.image.version=${{ needs.init.outputs.version }}
- name: Sign image
run: |
cosign sign --yes "ghcr.io/home-assistant/${{ matrix.arch }}-homeassistant:${{ needs.init.outputs.version }}@${{ steps.build.outputs.digest }}"
build_machine:
name: Build ${{ matrix.machine }} machine core image
@@ -227,7 +273,7 @@ jobs:
- green
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set build additional args
run: |
@@ -249,7 +295,7 @@ jobs:
# home-assistant/builder doesn't support sha pinning
- name: Build base image
uses: home-assistant/builder@2025.09.0
uses: home-assistant/builder@2025.11.0
with:
args: |
$BUILD_ARGS \
@@ -265,7 +311,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Initialize git
uses: home-assistant/actions/helpers/git-init@master
@@ -308,13 +354,7 @@ jobs:
matrix:
registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"]
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
with:
cosign-release: "v2.2.3"
- *install_cosign
- name: Login to DockerHub
if: matrix.registry == 'docker.io/homeassistant'
@@ -324,88 +364,104 @@ jobs:
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
if: matrix.registry == 'ghcr.io/home-assistant'
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Meta Image
- name: Verify architecture image signatures
shell: bash
run: |
export DOCKER_CLI_EXPERIMENTAL=enabled
ARCHS=$(echo '${{ needs.init.outputs.architectures }}' | jq -r '.[]')
for arch in $ARCHS; do
echo "Verifying ${arch} image signature..."
cosign verify \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp https://github.com/home-assistant/core/.* \
"ghcr.io/home-assistant/${arch}-homeassistant:${{ needs.init.outputs.version }}"
done
echo "✓ All images verified successfully"
function create_manifest() {
local tag_l=${1}
local tag_r=${2}
local registry=${{ matrix.registry }}
# Generate all Docker tags based on version string
# Version format: YYYY.MM.PATCH, YYYY.MM.PATCHbN (beta), or YYYY.MM.PATCH.devYYYYMMDDHHMM (dev)
# Examples:
# 2025.12.1 (stable) -> tags: 2025.12.1, 2025.12, stable, latest, beta, rc
# 2025.12.0b3 (beta) -> tags: 2025.12.0b3, beta, rc
# 2025.12.0.dev202511250240 -> tags: 2025.12.0.dev202511250240, dev
- name: Generate Docker metadata
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
with:
images: ${{ matrix.registry }}/home-assistant
sep-tags: ","
tags: |
type=raw,value=${{ needs.init.outputs.version }},priority=9999
type=raw,value=dev,enable=${{ contains(needs.init.outputs.version, 'd') }}
type=raw,value=beta,enable=${{ !contains(needs.init.outputs.version, 'd') }}
type=raw,value=rc,enable=${{ !contains(needs.init.outputs.version, 'd') }}
type=raw,value=stable,enable=${{ !contains(needs.init.outputs.version, 'd') && !contains(needs.init.outputs.version, 'b') }}
type=raw,value=latest,enable=${{ !contains(needs.init.outputs.version, 'd') && !contains(needs.init.outputs.version, 'b') }}
type=semver,pattern={{major}}.{{minor}},value=${{ needs.init.outputs.version }},enable=${{ !contains(needs.init.outputs.version, 'd') && !contains(needs.init.outputs.version, 'b') }}
docker manifest create "${registry}/home-assistant:${tag_l}" \
"${registry}/amd64-homeassistant:${tag_r}" \
"${registry}/aarch64-homeassistant:${tag_r}"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.7.1
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/amd64-homeassistant:${tag_r}" \
--os linux --arch amd64
- name: Copy architecture images to DockerHub
if: matrix.registry == 'docker.io/homeassistant'
shell: bash
run: |
# Use imagetools to copy image blobs directly between registries
# This preserves provenance/attestations and seems to be much faster than pull/push
ARCHS=$(echo '${{ needs.init.outputs.architectures }}' | jq -r '.[]')
for arch in $ARCHS; do
echo "Copying ${arch} image to DockerHub..."
for attempt in 1 2 3; do
if docker buildx imagetools create \
--tag "docker.io/homeassistant/${arch}-homeassistant:${{ needs.init.outputs.version }}" \
"ghcr.io/home-assistant/${arch}-homeassistant:${{ needs.init.outputs.version }}"; then
break
fi
echo "Attempt ${attempt} failed, retrying in 10 seconds..."
sleep 10
if [ "${attempt}" -eq 3 ]; then
echo "Failed after 3 attempts"
exit 1
fi
done
cosign sign --yes "docker.io/homeassistant/${arch}-homeassistant:${{ needs.init.outputs.version }}"
done
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/aarch64-homeassistant:${tag_r}" \
--os linux --arch arm64 --variant=v8
- name: Create and push multi-arch manifests
shell: bash
run: |
# Build list of architecture images dynamically
ARCHS=$(echo '${{ needs.init.outputs.architectures }}' | jq -r '.[]')
ARCH_IMAGES=()
for arch in $ARCHS; do
ARCH_IMAGES+=("${{ matrix.registry }}/${arch}-homeassistant:${{ needs.init.outputs.version }}")
done
docker manifest push --purge "${registry}/home-assistant:${tag_l}"
cosign sign --yes "${registry}/home-assistant:${tag_l}"
}
# Build list of all tags for single manifest creation
# Note: Using sep-tags=',' in metadata-action for easier parsing
TAG_ARGS=()
IFS=',' read -ra TAGS <<< "${{ steps.meta.outputs.tags }}"
for tag in "${TAGS[@]}"; do
TAG_ARGS+=("--tag" "${tag}")
done
function validate_image() {
local image=${1}
if ! cosign verify --certificate-oidc-issuer https://token.actions.githubusercontent.com --certificate-identity-regexp https://github.com/home-assistant/core/.* "${image}"; then
echo "Invalid signature!"
exit 1
fi
}
# Create manifest with ALL tags in a single operation (much faster!)
echo "Creating multi-arch manifest with tags: ${TAGS[*]}"
docker buildx imagetools create "${TAG_ARGS[@]}" "${ARCH_IMAGES[@]}"
function push_dockerhub() {
local image=${1}
local tag=${2}
# Sign each tag separately (signing requires individual tag names)
echo "Signing all tags..."
for tag in "${TAGS[@]}"; do
echo "Signing ${tag}"
cosign sign --yes "${tag}"
done
docker tag "ghcr.io/home-assistant/${image}:${tag}" "docker.io/homeassistant/${image}:${tag}"
docker push "docker.io/homeassistant/${image}:${tag}"
cosign sign --yes "docker.io/homeassistant/${image}:${tag}"
}
# Pull images from github container registry and verify signature
docker pull "ghcr.io/home-assistant/amd64-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/home-assistant/aarch64-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/amd64-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/aarch64-homeassistant:${{ needs.init.outputs.version }}"
if [[ "${{ matrix.registry }}" == "docker.io/homeassistant" ]]; then
# Upload images to dockerhub
push_dockerhub "amd64-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "aarch64-homeassistant" "${{ needs.init.outputs.version }}"
fi
# Create version tag
create_manifest "${{ needs.init.outputs.version }}" "${{ needs.init.outputs.version }}"
# Create general tags
if [[ "${{ needs.init.outputs.version }}" =~ d ]]; then
create_manifest "dev" "${{ needs.init.outputs.version }}"
elif [[ "${{ needs.init.outputs.version }}" =~ b ]]; then
create_manifest "beta" "${{ needs.init.outputs.version }}"
create_manifest "rc" "${{ needs.init.outputs.version }}"
else
create_manifest "stable" "${{ needs.init.outputs.version }}"
create_manifest "latest" "${{ needs.init.outputs.version }}"
create_manifest "beta" "${{ needs.init.outputs.version }}"
create_manifest "rc" "${{ needs.init.outputs.version }}"
# Create series version tag (e.g. 2021.6)
v="${{ needs.init.outputs.version }}"
create_manifest "${v%.*}" "${{ needs.init.outputs.version }}"
fi
echo "All manifests created and signed successfully"
build_python:
name: Build PyPi package
@@ -418,10 +474,10 @@ jobs:
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -463,7 +519,7 @@ jobs:
HASSFEST_IMAGE_TAG: ghcr.io/home-assistant/hassfest:${{ needs.init.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0

View File

@@ -37,12 +37,12 @@ on:
type: boolean
env:
CACHE_VERSION: 1
CACHE_VERSION: 2
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 1
HA_SHORT_VERSION: "2025.12"
DEFAULT_PYTHON: "3.13"
ALL_PYTHON_VERSIONS: "['3.13', '3.14']"
HA_SHORT_VERSION: "2026.1"
DEFAULT_PYTHON: "3.13.11"
ALL_PYTHON_VERSIONS: "['3.13.11', '3.14.2']"
# 10.3 is the oldest supported version
# - 10.3.32 is the version currently shipped with Synology (as of 17 Feb 2022)
# 10.6 is the current long-term-support
@@ -99,7 +99,7 @@ jobs:
steps:
- &checkout
name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Generate partial Python venv restore key
id: generate_python_cache_key
run: |
@@ -257,13 +257,13 @@ jobs:
- &setup-python-default
name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: &actions-setup-python actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: &actions-setup-python actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: &actions-cache actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: &actions-cache actions/cache@a7833574556fa59680c1b7cb190c1735db73ebf0 # v5.0.0
with:
path: venv
key: &key-pre-commit-venv >-
@@ -304,7 +304,7 @@ jobs:
- &cache-restore-pre-commit-venv
name: Restore base Python virtual environment
id: cache-venv
uses: &actions-cache-restore actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: &actions-cache-restore actions/cache/restore@a7833574556fa59680c1b7cb190c1735db73ebf0 # v5.0.0
with:
path: venv
fail-on-cache-miss: true
@@ -511,7 +511,7 @@ jobs:
fi
- name: Save apt cache
if: steps.cache-apt-check.outputs.cache-hit != 'true'
uses: &actions-cache-save actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: &actions-cache-save actions/cache/save@a7833574556fa59680c1b7cb190c1735db73ebf0 # v5.0.0
with:
path: *path-apt-cache
key: *key-apt-cache
@@ -1188,7 +1188,7 @@ jobs:
pattern: coverage-*
- name: Upload coverage to Codecov
if: needs.info.outputs.test_full_suite == 'true'
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
fail_ci_if_error: true
flags: full-suite
@@ -1313,7 +1313,7 @@ jobs:
pattern: coverage-*
- name: Upload coverage to Codecov
if: needs.info.outputs.test_full_suite == 'false'
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -21,14 +21,14 @@ jobs:
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Initialize CodeQL
uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
uses: github/codeql-action/init@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
uses: github/codeql-action/analyze@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7
with:
category: "/language:python"

View File

@@ -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@a1c11829223a786afe3b5663db904a3aa1eac3a2 # v2.0.1
uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4
with:
model: openai/gpt-4o
system-prompt: |

View File

@@ -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@a1c11829223a786afe3b5663db904a3aa1eac3a2 # v2.0.1
uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4
with:
model: openai/gpt-4o-mini
system-prompt: |

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@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
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@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
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@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
with:
repo-token: ${{ steps.token.outputs.token }}
only-labels: "needs-more-information"

View File

@@ -19,10 +19,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}

View File

@@ -28,16 +28,14 @@ jobs:
name: Initialize wheels builder
if: github.repository_owner == 'home-assistant'
runs-on: ubuntu-latest
outputs:
architectures: ${{ steps.info.outputs.architectures }}
steps:
- &checkout
name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -50,10 +48,6 @@ jobs:
pip install "$(grep '^uv' < requirements.txt)"
uv pip install -r requirements.txt
- name: Get information
id: info
uses: home-assistant/actions/helpers/info@master
- name: Create requirements_diff file
run: |
if [[ ${{ github.event_name }} =~ (schedule|workflow_dispatch) ]]; then
@@ -77,20 +71,8 @@ jobs:
# Use C-Extension for SQLAlchemy
echo "REQUIRE_SQLALCHEMY_CEXT=1"
# Add additional pip wheel build constraints
echo "PIP_CONSTRAINT=build_constraints.txt"
) > .env_file
- name: Write pip wheel build constraints
run: |
(
# ninja 1.11.1.2 + 1.11.1.3 seem to be broken on at least armhf
# this caused the numpy builds to fail
# https://github.com/scikit-build/ninja-python-distributions/issues/274
echo "ninja==1.11.1.1"
) > build_constraints.txt
- name: Upload env_file
uses: &actions-upload-artifact actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
@@ -99,13 +81,6 @@ jobs:
include-hidden-files: true
overwrite: true
- name: Upload build_constraints
uses: *actions-upload-artifact
with:
name: build_constraints
path: ./build_constraints.txt
overwrite: true
- name: Upload requirements_diff
uses: *actions-upload-artifact
with:
@@ -133,18 +108,12 @@ jobs:
fail-fast: false
matrix: &matrix-build
abi: ["cp313", "cp314"]
arch: ${{ fromJson(needs.init.outputs.architectures) }}
arch: ["amd64", "aarch64"]
include:
- os: ubuntu-latest
- arch: amd64
os: ubuntu-latest
- arch: aarch64
os: ubuntu-24.04-arm
exclude:
- abi: cp314
arch: armv7
- abi: cp314
arch: armhf
- abi: cp314
arch: i386
steps:
- *checkout
@@ -154,12 +123,6 @@ jobs:
with:
name: env_file
- &download-build-constraints
name: Download build_constraints
uses: *actions-download-artifact
with:
name: build_constraints
- &download-requirements-diff
name: Download requirements_diff
uses: *actions-download-artifact
@@ -172,9 +135,8 @@ 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 home-assistant/wheels@2025.10.0
uses: &home-assistant-wheels home-assistant/wheels@e5742a69d69f0e274e2689c998900c7d19652c21 # 2025.12.0
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
@@ -199,7 +161,7 @@ jobs:
- *checkout
- *download-env-file
- *download-build-constraints
- *download-requirements-diff
- name: Download requirements_all_wheels
@@ -209,17 +171,12 @@ jobs:
- name: Adjust build env
run: |
if [ "${{ matrix.arch }}" = "i386" ]; then
echo "NPY_DISABLE_SVML=1" >> .env_file
fi
# Do not pin numpy in wheels building
sed -i "/numpy/d" homeassistant/package_constraints.txt
# Don't build wheels for uv as uv requires a greater version of rust as currently available on alpine
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
with:

View File

@@ -87,14 +87,14 @@ repos:
pass_filenames: false
language: script
types: [text]
files: ^(homeassistant/.+/(icons|manifest|strings)\.json|homeassistant/.+/(quality_scale)\.yaml|homeassistant/brands/.*\.json|homeassistant/.+/services\.yaml|script/hassfest/(?!metadata|mypy_config).+\.py|requirements.+\.txt)$
files: ^(homeassistant/.+/(icons|manifest|strings)\.json|homeassistant/.+/(conditions|quality_scale|services|triggers)\.yaml|homeassistant/brands/.*\.json|script/hassfest/(?!metadata|mypy_config).+\.py|requirements.+\.txt)$
- id: hassfest-metadata
name: hassfest-metadata
entry: script/run-in-env.sh python3 -m script.hassfest -p metadata,docker
pass_filenames: false
language: script
types: [text]
files: ^(script/hassfest/metadata\.py|homeassistant/const\.py$|pyproject\.toml|homeassistant/components/go2rtc/const\.py)$
files: ^(script/hassfest/(metadata|docker)\.py|homeassistant/const\.py$|pyproject\.toml)$
- id: hassfest-mypy-config
name: hassfest-mypy-config
entry: script/run-in-env.sh python3 -m script.hassfest -p mypy_config

View File

@@ -120,7 +120,6 @@ homeassistant.components.blueprint.*
homeassistant.components.bluesound.*
homeassistant.components.bluetooth.*
homeassistant.components.bluetooth_adapters.*
homeassistant.components.bluetooth_tracker.*
homeassistant.components.bmw_connected_drive.*
homeassistant.components.bond.*
homeassistant.components.bosch_alarm.*
@@ -188,6 +187,7 @@ homeassistant.components.elkm1.*
homeassistant.components.emulated_hue.*
homeassistant.components.energenie_power_sockets.*
homeassistant.components.energy.*
homeassistant.components.energyid.*
homeassistant.components.energyzero.*
homeassistant.components.enigma2.*
homeassistant.components.enphase_envoy.*
@@ -231,6 +231,7 @@ homeassistant.components.google_cloud.*
homeassistant.components.google_drive.*
homeassistant.components.google_photos.*
homeassistant.components.google_sheets.*
homeassistant.components.google_weather.*
homeassistant.components.govee_ble.*
homeassistant.components.gpsd.*
homeassistant.components.greeneye_monitor.*
@@ -578,6 +579,7 @@ homeassistant.components.wiz.*
homeassistant.components.wled.*
homeassistant.components.workday.*
homeassistant.components.worldclock.*
homeassistant.components.xbox.*
homeassistant.components.xiaomi_ble.*
homeassistant.components.yale_smart_alarm.*
homeassistant.components.yalexs_ble.*

53
CODEOWNERS generated
View File

@@ -69,8 +69,12 @@ build.json @home-assistant/supervisor
/tests/components/airly/ @bieniu
/homeassistant/components/airnow/ @asymworks
/tests/components/airnow/ @asymworks
/homeassistant/components/airobot/ @mettolen
/tests/components/airobot/ @mettolen
/homeassistant/components/airos/ @CoMPaTech
/tests/components/airos/ @CoMPaTech
/homeassistant/components/airpatrol/ @antondalgren
/tests/components/airpatrol/ @antondalgren
/homeassistant/components/airq/ @Sibgatulin @dl2080
/tests/components/airq/ @Sibgatulin @dl2080
/homeassistant/components/airthings/ @danielhiversen @LaStrada
@@ -119,6 +123,8 @@ build.json @home-assistant/supervisor
/tests/components/androidtv/ @JeffLIrion @ollo69
/homeassistant/components/androidtv_remote/ @tronikos @Drafteed
/tests/components/androidtv_remote/ @tronikos @Drafteed
/homeassistant/components/anglian_water/ @pantherale0
/tests/components/anglian_water/ @pantherale0
/homeassistant/components/anova/ @Lash-L
/tests/components/anova/ @Lash-L
/homeassistant/components/anthemav/ @hyralex
@@ -181,8 +187,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/automation/ @home-assistant/core
/tests/components/automation/ @home-assistant/core
/homeassistant/components/avea/ @pattyland
/homeassistant/components/awair/ @ahayworth @danielsjf
/tests/components/awair/ @ahayworth @danielsjf
/homeassistant/components/awair/ @ahayworth @ricohageman
/tests/components/awair/ @ahayworth @ricohageman
/homeassistant/components/aws_s3/ @tomasbedrich
/tests/components/aws_s3/ @tomasbedrich
/homeassistant/components/axis/ @Kane610
@@ -214,8 +220,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/bizkaibus/ @UgaitzEtxebarria
/homeassistant/components/blebox/ @bbx-a @swistakm
/tests/components/blebox/ @bbx-a @swistakm
/homeassistant/components/blink/ @fronzbot @mkmer
/tests/components/blink/ @fronzbot @mkmer
/homeassistant/components/blink/ @fronzbot
/tests/components/blink/ @fronzbot
/homeassistant/components/blue_current/ @gleeuwen @NickKoepr @jtodorova23
/tests/components/blue_current/ @gleeuwen @NickKoepr @jtodorova23
/homeassistant/components/bluemaestro/ @bdraco
@@ -302,8 +308,8 @@ build.json @home-assistant/supervisor
/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/control4/ @lawtancool @davidrecordon
/tests/components/control4/ @lawtancool @davidrecordon
/homeassistant/components/conversation/ @home-assistant/core @synesthesiam @arturpragacz
/tests/components/conversation/ @home-assistant/core @synesthesiam @arturpragacz
/homeassistant/components/cookidoo/ @miaucl
@@ -389,6 +395,8 @@ build.json @home-assistant/supervisor
/tests/components/dsmr/ @Robbie1221
/homeassistant/components/dsmr_reader/ @sorted-bits @glodenox @erwindouna
/tests/components/dsmr_reader/ @sorted-bits @glodenox @erwindouna
/homeassistant/components/duckdns/ @tr4nt0r
/tests/components/duckdns/ @tr4nt0r
/homeassistant/components/duke_energy/ @hunterjm
/tests/components/duke_energy/ @hunterjm
/homeassistant/components/duotecno/ @cereal2nd
@@ -412,6 +420,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/efergy/ @tkdrob
/tests/components/efergy/ @tkdrob
/homeassistant/components/egardia/ @jeroenterheerdt
/homeassistant/components/egauge/ @neggert
/tests/components/egauge/ @neggert
/homeassistant/components/eheimdigital/ @autinerd
/tests/components/eheimdigital/ @autinerd
/homeassistant/components/ekeybionyx/ @richardpolzer
@@ -446,13 +456,15 @@ build.json @home-assistant/supervisor
/tests/components/energenie_power_sockets/ @gnumpi
/homeassistant/components/energy/ @home-assistant/core
/tests/components/energy/ @home-assistant/core
/homeassistant/components/energyid/ @JrtPec @Molier
/tests/components/energyid/ @JrtPec @Molier
/homeassistant/components/energyzero/ @klaasnicolaas
/tests/components/energyzero/ @klaasnicolaas
/homeassistant/components/enigma2/ @autinerd
/tests/components/enigma2/ @autinerd
/homeassistant/components/enphase_envoy/ @bdraco @cgarwood @catsmanac
/tests/components/enphase_envoy/ @bdraco @cgarwood @catsmanac
/homeassistant/components/entur_public_transport/ @hfurubotten
/homeassistant/components/entur_public_transport/ @hfurubotten @SanderBlom
/homeassistant/components/environment_canada/ @gwww @michaeldavie
/tests/components/environment_canada/ @gwww @michaeldavie
/homeassistant/components/ephember/ @ttroy50 @roberty99
@@ -468,6 +480,8 @@ build.json @home-assistant/supervisor
/tests/components/escea/ @lazdavila
/homeassistant/components/esphome/ @jesserockz @kbx81 @bdraco
/tests/components/esphome/ @jesserockz @kbx81 @bdraco
/homeassistant/components/essent/ @jaapp
/tests/components/essent/ @jaapp
/homeassistant/components/eufylife_ble/ @bdr99
/tests/components/eufylife_ble/ @bdr99
/homeassistant/components/event/ @home-assistant/core
@@ -529,6 +543,8 @@ build.json @home-assistant/supervisor
/tests/components/freebox/ @hacf-fr @Quentame
/homeassistant/components/freedompro/ @stefano055415
/tests/components/freedompro/ @stefano055415
/homeassistant/components/fressnapf_tracker/ @eifinger
/tests/components/fressnapf_tracker/ @eifinger
/homeassistant/components/fritz/ @AaronDavidSchneider @chemelli74 @mib1185
/tests/components/fritz/ @AaronDavidSchneider @chemelli74 @mib1185
/homeassistant/components/fritzbox/ @mib1185 @flabbamann
@@ -559,6 +575,8 @@ build.json @home-assistant/supervisor
/tests/components/generic_hygrostat/ @Shulyaka
/homeassistant/components/geniushub/ @manzanotti
/tests/components/geniushub/ @manzanotti
/homeassistant/components/gentex_homelink/ @niaexa @ryanjones-gentex
/tests/components/gentex_homelink/ @niaexa @ryanjones-gentex
/homeassistant/components/geo_json_events/ @exxamalte
/tests/components/geo_json_events/ @exxamalte
/homeassistant/components/geo_location/ @home-assistant/core
@@ -587,6 +605,8 @@ build.json @home-assistant/supervisor
/tests/components/goodwe/ @mletenay @starkillerOG
/homeassistant/components/google/ @allenporter
/tests/components/google/ @allenporter
/homeassistant/components/google_air_quality/ @Thomas55555
/tests/components/google_air_quality/ @Thomas55555
/homeassistant/components/google_assistant/ @home-assistant/cloud
/tests/components/google_assistant/ @home-assistant/cloud
/homeassistant/components/google_assistant_sdk/ @tronikos
@@ -607,6 +627,8 @@ build.json @home-assistant/supervisor
/tests/components/google_tasks/ @allenporter
/homeassistant/components/google_travel_time/ @eifinger
/tests/components/google_travel_time/ @eifinger
/homeassistant/components/google_weather/ @tronikos
/tests/components/google_weather/ @tronikos
/homeassistant/components/govee_ble/ @bdraco
/tests/components/govee_ble/ @bdraco
/homeassistant/components/govee_light_local/ @Galorhallen
@@ -625,6 +647,8 @@ build.json @home-assistant/supervisor
/tests/components/guardian/ @bachya
/homeassistant/components/habitica/ @tr4nt0r
/tests/components/habitica/ @tr4nt0r
/homeassistant/components/hanna/ @bestycame
/tests/components/hanna/ @bestycame
/homeassistant/components/hardkernel/ @home-assistant/core
/tests/components/hardkernel/ @home-assistant/core
/homeassistant/components/hardware/ @home-assistant/core
@@ -692,6 +716,8 @@ build.json @home-assistant/supervisor
/tests/components/huawei_lte/ @scop @fphammerle
/homeassistant/components/hue/ @marcelveldt
/tests/components/hue/ @marcelveldt
/homeassistant/components/hue_ble/ @flip-dots
/tests/components/hue_ble/ @flip-dots
/homeassistant/components/huisbaasje/ @dennisschroer
/tests/components/huisbaasje/ @dennisschroer
/homeassistant/components/humidifier/ @home-assistant/core @Shulyaka
@@ -844,6 +870,8 @@ build.json @home-assistant/supervisor
/tests/components/kraken/ @eifinger
/homeassistant/components/kulersky/ @emlove
/tests/components/kulersky/ @emlove
/homeassistant/components/labs/ @home-assistant/core
/tests/components/labs/ @home-assistant/core
/homeassistant/components/lacrosse_view/ @IceBotYT
/tests/components/lacrosse_view/ @IceBotYT
/homeassistant/components/lamarzocco/ @zweckj
@@ -1334,8 +1362,8 @@ build.json @home-assistant/supervisor
/tests/components/ring/ @sdb9696
/homeassistant/components/risco/ @OnFreund
/tests/components/risco/ @OnFreund
/homeassistant/components/rituals_perfume_genie/ @milanmeu @frenck
/tests/components/rituals_perfume_genie/ @milanmeu @frenck
/homeassistant/components/rituals_perfume_genie/ @milanmeu @frenck @quebulm
/tests/components/rituals_perfume_genie/ @milanmeu @frenck @quebulm
/homeassistant/components/rmvtransport/ @cgtobi
/tests/components/rmvtransport/ @cgtobi
/homeassistant/components/roborock/ @Lash-L @allenporter
@@ -1374,6 +1402,8 @@ build.json @home-assistant/supervisor
/tests/components/sanix/ @tomaszsluszniak
/homeassistant/components/satel_integra/ @Tommatheussen
/tests/components/satel_integra/ @Tommatheussen
/homeassistant/components/saunum/ @mettolen
/tests/components/saunum/ @mettolen
/homeassistant/components/scene/ @home-assistant/core
/tests/components/scene/ @home-assistant/core
/homeassistant/components/schedule/ @home-assistant/core
@@ -1732,11 +1762,14 @@ build.json @home-assistant/supervisor
/tests/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja @iprak @sapuseven
/homeassistant/components/vicare/ @CFenner
/tests/components/vicare/ @CFenner
/homeassistant/components/victron_ble/ @rajlaud
/tests/components/victron_ble/ @rajlaud
/homeassistant/components/victron_remote_monitoring/ @AndyTempel
/tests/components/victron_remote_monitoring/ @AndyTempel
/homeassistant/components/vilfo/ @ManneW
/tests/components/vilfo/ @ManneW
/homeassistant/components/vivotek/ @HarlemSquirrel
/tests/components/vivotek/ @HarlemSquirrel
/homeassistant/components/vizio/ @raman325
/tests/components/vizio/ @raman325
/homeassistant/components/vlc_telnet/ @rodripf @MartinHjelmare
@@ -1776,6 +1809,8 @@ build.json @home-assistant/supervisor
/tests/components/weatherflow_cloud/ @jeeftor
/homeassistant/components/weatherkit/ @tjhorner
/tests/components/weatherkit/ @tjhorner
/homeassistant/components/web_rtc/ @home-assistant/core
/tests/components/web_rtc/ @home-assistant/core
/homeassistant/components/webdav/ @jpbede
/tests/components/webdav/ @jpbede
/homeassistant/components/webhook/ @home-assistant/core

35
Dockerfile generated
View File

@@ -4,34 +4,33 @@
ARG BUILD_FROM
FROM ${BUILD_FROM}
LABEL \
io.hass.type="core" \
org.opencontainers.image.authors="The Home Assistant Authors" \
org.opencontainers.image.description="Open-source home automation platform running on Python 3" \
org.opencontainers.image.documentation="https://www.home-assistant.io/docs/" \
org.opencontainers.image.licenses="Apache-2.0" \
org.opencontainers.image.source="https://github.com/home-assistant/core" \
org.opencontainers.image.title="Home Assistant" \
org.opencontainers.image.url="https://www.home-assistant.io/"
# Synchronize with homeassistant/core.py:async_stop
ENV \
S6_SERVICES_GRACETIME=240000 \
UV_SYSTEM_PYTHON=true \
UV_NO_CACHE=true
ARG QEMU_CPU
# Home Assistant S6-Overlay
COPY rootfs /
# Needs to be redefined inside the FROM statement to be set for RUN commands
ARG BUILD_ARCH
# Get go2rtc binary
RUN \
case "${BUILD_ARCH}" in \
"aarch64") go2rtc_suffix='arm64' ;; \
"armhf") go2rtc_suffix='armv6' ;; \
"armv7") go2rtc_suffix='arm' ;; \
*) go2rtc_suffix=${BUILD_ARCH} ;; \
esac \
&& curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.11/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
&& chmod +x /bin/go2rtc \
# Verify go2rtc can be executed
&& go2rtc --version
# Add go2rtc binary
COPY --from=ghcr.io/alexxit/go2rtc@sha256:baef0aa19d759fcfd31607b34ce8eaf039d496282bba57731e6ae326896d7640 /usr/local/bin/go2rtc /bin/go2rtc
# Install uv
RUN pip3 install uv==0.9.6
RUN \
# Verify go2rtc can be executed
go2rtc --version \
# Install uv
&& pip3 install uv==0.9.6
WORKDIR /usr/src

View File

@@ -35,25 +35,22 @@ COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
USER vscode
COPY .python-version ./
RUN uv python install
ENV VIRTUAL_ENV="/home/vscode/.local/ha-venv"
RUN uv venv $VIRTUAL_ENV
RUN --mount=type=bind,source=.python-version,target=.python-version \
uv python install \
&& uv venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
WORKDIR /tmp
# Setup hass-release
RUN git clone --depth 1 https://github.com/home-assistant/hass-release ~/hass-release \
&& uv pip install -e ~/hass-release/
# Install Python dependencies from requirements
COPY requirements.txt ./
COPY homeassistant/package_constraints.txt homeassistant/package_constraints.txt
RUN uv pip install -r requirements.txt
COPY requirements_test.txt requirements_test_pre_commit.txt ./
RUN uv pip install -r requirements_test.txt
RUN --mount=type=bind,source=requirements.txt,target=requirements.txt \
--mount=type=bind,source=homeassistant/package_constraints.txt,target=homeassistant/package_constraints.txt \
--mount=type=bind,source=requirements_test.txt,target=requirements_test.txt \
--mount=type=bind,source=requirements_test_pre_commit.txt,target=requirements_test_pre_commit.txt \
uv pip install -r requirements.txt -r requirements_test.txt
WORKDIR /workspaces

View File

@@ -1,19 +0,0 @@
image: ghcr.io/home-assistant/{arch}-homeassistant
build_from:
aarch64: ghcr.io/home-assistant/aarch64-homeassistant-base:2025.10.1
armhf: ghcr.io/home-assistant/armhf-homeassistant-base:2025.10.1
armv7: ghcr.io/home-assistant/armv7-homeassistant-base:2025.10.1
amd64: ghcr.io/home-assistant/amd64-homeassistant-base:2025.10.1
i386: ghcr.io/home-assistant/i386-homeassistant-base:2025.10.1
cosign:
base_identity: https://github.com/home-assistant/docker/.*
identity: https://github.com/home-assistant/core/.*
labels:
io.hass.type: core
org.opencontainers.image.title: Home Assistant
org.opencontainers.image.description: Open-source home automation platform running on Python 3
org.opencontainers.image.source: https://github.com/home-assistant/core
org.opencontainers.image.authors: The Home Assistant Authors
org.opencontainers.image.url: https://www.home-assistant.io/
org.opencontainers.image.documentation: https://www.home-assistant.io/docs/
org.opencontainers.image.licenses: Apache-2.0

View File

@@ -7,6 +7,7 @@ from typing import Any, Final
from homeassistant.const import (
EVENT_COMPONENT_LOADED,
EVENT_CORE_CONFIG_UPDATE,
EVENT_LABS_UPDATED,
EVENT_LOVELACE_UPDATED,
EVENT_PANELS_UPDATED,
EVENT_RECORDER_5MIN_STATISTICS_GENERATED,
@@ -45,6 +46,7 @@ SUBSCRIBE_ALLOWLIST: Final[set[EventType[Any] | str]] = {
EVENT_STATE_CHANGED,
EVENT_THEMES_UPDATED,
EVENT_LABEL_REGISTRY_UPDATED,
EVENT_LABS_UPDATED,
EVENT_CATEGORY_REGISTRY_UPDATED,
EVENT_FLOOR_REGISTRY_UPDATED,
}

View File

@@ -176,6 +176,8 @@ FRONTEND_INTEGRATIONS = {
STAGE_0_INTEGRATIONS = (
# Load logging and http deps as soon as possible
("logging, http deps", LOGGING_AND_HTTP_DEPS_INTEGRATIONS, None),
# Setup labs for preview features
("labs", {"labs"}, STAGE_0_SUBSTAGE_TIMEOUT),
# Setup frontend
("frontend", FRONTEND_INTEGRATIONS, None),
# Setup recorder
@@ -212,6 +214,7 @@ DEFAULT_INTEGRATIONS = {
"backup",
"frontend",
"hardware",
"labs",
"logger",
"network",
"system_health",
@@ -997,7 +1000,7 @@ class _WatchPendingSetups:
# We log every LOG_SLOW_STARTUP_INTERVAL until all integrations are done
# once we take over LOG_SLOW_STARTUP_INTERVAL (60s) to start up
_LOGGER.warning(
"Waiting on integrations to complete setup: %s",
"Waiting for integrations to complete setup: %s",
self._setup_started,
)

View File

@@ -2,6 +2,7 @@
"domain": "google",
"name": "Google",
"integrations": [
"google_air_quality",
"google_assistant",
"google_assistant_sdk",
"google_cloud",
@@ -15,6 +16,7 @@
"google_tasks",
"google_translate",
"google_travel_time",
"google_weather",
"google_wifi",
"google",
"nest",

View File

@@ -1,5 +1,5 @@
{
"domain": "philips",
"name": "Philips",
"integrations": ["dynalite", "hue", "philips_js"]
"integrations": ["dynalite", "hue", "hue_ble", "philips_js"]
}

View File

@@ -1,5 +1,5 @@
{
"domain": "raspberry_pi",
"name": "Raspberry Pi",
"integrations": ["raspberry_pi", "rpi_camera", "rpi_power", "remote_rpi_gpio"]
"integrations": ["raspberry_pi", "rpi_power", "remote_rpi_gpio"]
}

View File

@@ -0,0 +1,5 @@
{
"domain": "victron",
"name": "Victron",
"integrations": ["victron_ble", "victron_remote_monitoring"]
}

View File

@@ -1,10 +1,10 @@
"""The Actron Air integration."""
from actron_neo_api import (
ActronAirNeoACSystem,
ActronNeoAPI,
ActronNeoAPIError,
ActronNeoAuthError,
ActronAirACSystem,
ActronAirAPI,
ActronAirAPIError,
ActronAirAuthError,
)
from homeassistant.const import CONF_API_TOKEN, Platform
@@ -23,16 +23,16 @@ PLATFORM = [Platform.CLIMATE]
async def async_setup_entry(hass: HomeAssistant, entry: ActronAirConfigEntry) -> bool:
"""Set up Actron Air integration from a config entry."""
api = ActronNeoAPI(refresh_token=entry.data[CONF_API_TOKEN])
systems: list[ActronAirNeoACSystem] = []
api = ActronAirAPI(refresh_token=entry.data[CONF_API_TOKEN])
systems: list[ActronAirACSystem] = []
try:
systems = await api.get_ac_systems()
await api.update_status()
except ActronNeoAuthError:
except ActronAirAuthError:
_LOGGER.error("Authentication error while setting up Actron Air integration")
raise
except ActronNeoAPIError as err:
except ActronAirAPIError as err:
_LOGGER.error("API error while setting up Actron Air integration: %s", err)
raise

View File

@@ -2,7 +2,7 @@
from typing import Any
from actron_neo_api import ActronAirNeoStatus, ActronAirNeoZone
from actron_neo_api import ActronAirStatus, ActronAirZone
from homeassistant.components.climate import (
FAN_AUTO,
@@ -132,7 +132,7 @@ class ActronSystemClimate(BaseClimateEntity):
return self._status.max_temp
@property
def _status(self) -> ActronAirNeoStatus:
def _status(self) -> ActronAirStatus:
"""Get the current status from the coordinator."""
return self.coordinator.data
@@ -194,7 +194,7 @@ class ActronZoneClimate(BaseClimateEntity):
def __init__(
self,
coordinator: ActronAirSystemCoordinator,
zone: ActronAirNeoZone,
zone: ActronAirZone,
) -> None:
"""Initialize an Actron Air unit."""
super().__init__(coordinator, zone.title)
@@ -221,7 +221,7 @@ class ActronZoneClimate(BaseClimateEntity):
return self._zone.max_temp
@property
def _zone(self) -> ActronAirNeoZone:
def _zone(self) -> ActronAirZone:
"""Get the current zone data from the coordinator."""
status = self.coordinator.data
return status.zones[self._zone_id]

View File

@@ -3,7 +3,7 @@
import asyncio
from typing import Any
from actron_neo_api import ActronNeoAPI, ActronNeoAuthError
from actron_neo_api import ActronAirAPI, ActronAirAuthError
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_API_TOKEN
@@ -17,7 +17,7 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
def __init__(self) -> None:
"""Initialize the config flow."""
self._api: ActronNeoAPI | None = None
self._api: ActronAirAPI | None = None
self._device_code: str | None = None
self._user_code: str = ""
self._verification_uri: str = ""
@@ -30,10 +30,10 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle the initial step."""
if self._api is None:
_LOGGER.debug("Initiating device authorization")
self._api = ActronNeoAPI()
self._api = ActronAirAPI()
try:
device_code_response = await self._api.request_device_code()
except ActronNeoAuthError as err:
except ActronAirAuthError as err:
_LOGGER.error("OAuth2 flow failed: %s", err)
return self.async_abort(reason="oauth2_error")
@@ -50,7 +50,7 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
try:
await self._api.poll_for_token(self._device_code)
_LOGGER.debug("Authorization successful")
except ActronNeoAuthError as ex:
except ActronAirAuthError as ex:
_LOGGER.exception("Error while waiting for device authorization")
raise CannotConnect from ex
@@ -89,7 +89,7 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
try:
user_data = await self._api.get_user_info()
except ActronNeoAuthError as err:
except ActronAirAuthError as err:
_LOGGER.error("Error getting user info: %s", err)
return self.async_abort(reason="oauth2_error")

View File

@@ -5,7 +5,7 @@ from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
from actron_neo_api import ActronAirNeoACSystem, ActronAirNeoStatus, ActronNeoAPI
from actron_neo_api import ActronAirACSystem, ActronAirAPI, ActronAirStatus
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
@@ -23,7 +23,7 @@ ERROR_UNKNOWN = "unknown_error"
class ActronAirRuntimeData:
"""Runtime data for the Actron Air integration."""
api: ActronNeoAPI
api: ActronAirAPI
system_coordinators: dict[str, ActronAirSystemCoordinator]
@@ -33,15 +33,15 @@ AUTH_ERROR_THRESHOLD = 3
SCAN_INTERVAL = timedelta(seconds=30)
class ActronAirSystemCoordinator(DataUpdateCoordinator[ActronAirNeoACSystem]):
class ActronAirSystemCoordinator(DataUpdateCoordinator[ActronAirACSystem]):
"""System coordinator for Actron Air integration."""
def __init__(
self,
hass: HomeAssistant,
entry: ActronAirConfigEntry,
api: ActronNeoAPI,
system: ActronAirNeoACSystem,
api: ActronAirAPI,
system: ActronAirACSystem,
) -> None:
"""Initialize the coordinator."""
super().__init__(
@@ -57,7 +57,7 @@ class ActronAirSystemCoordinator(DataUpdateCoordinator[ActronAirNeoACSystem]):
self.status = self.api.state_manager.get_status(self.serial_number)
self.last_seen = dt_util.utcnow()
async def _async_update_data(self) -> ActronAirNeoStatus:
async def _async_update_data(self) -> ActronAirStatus:
"""Fetch updates and merge incremental changes into the full state."""
await self.api.update_status()
self.status = self.api.state_manager.get_status(self.serial_number)

View File

@@ -10,7 +10,8 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/actron_air",
"integration_type": "hub",
"iot_class": "cloud_polling",
"quality_scale": "bronze",
"requirements": ["actron-neo-api==0.1.84"]
"requirements": ["actron-neo-api==0.1.87"]
}

View File

@@ -45,7 +45,7 @@ SERVICE_REFRESH_SCHEMA = vol.Schema(
{vol.Optional(CONF_FORCE, default=False): cv.boolean}
)
PLATFORMS = [Platform.SENSOR, Platform.SWITCH]
PLATFORMS = [Platform.SENSOR, Platform.SWITCH, Platform.UPDATE]
type AdGuardConfigEntry = ConfigEntry[AdGuardData]

View File

@@ -7,5 +7,5 @@
"integration_type": "service",
"iot_class": "local_polling",
"loggers": ["adguardhome"],
"requirements": ["adguardhome==0.7.0"]
"requirements": ["adguardhome==0.8.1"]
}

View File

@@ -0,0 +1,71 @@
"""AdGuard Home Update platform."""
from __future__ import annotations
from datetime import timedelta
from typing import Any
from adguardhome import AdGuardHomeError
from homeassistant.components.update import UpdateEntity, UpdateEntityFeature
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AdGuardConfigEntry, AdGuardData
from .const import DOMAIN
from .entity import AdGuardHomeEntity
SCAN_INTERVAL = timedelta(seconds=300)
PARALLEL_UPDATES = 1
async def async_setup_entry(
hass: HomeAssistant,
entry: AdGuardConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up AdGuard Home update entity based on a config entry."""
data = entry.runtime_data
if (await data.client.update.update_available()).disabled:
return
async_add_entities([AdGuardHomeUpdate(data, entry)], True)
class AdGuardHomeUpdate(AdGuardHomeEntity, UpdateEntity):
"""Defines an AdGuard Home update."""
_attr_supported_features = UpdateEntityFeature.INSTALL
_attr_name = None
def __init__(
self,
data: AdGuardData,
entry: AdGuardConfigEntry,
) -> None:
"""Initialize AdGuard Home update."""
super().__init__(data, entry)
self._attr_unique_id = "_".join(
[DOMAIN, self.adguard.host, str(self.adguard.port), "update"]
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
value = await self.adguard.update.update_available()
self._attr_installed_version = self.data.version
self._attr_latest_version = value.new_version
self._attr_release_summary = value.announcement
self._attr_release_url = value.announcement_url
async def async_install(
self, version: str | None, backup: bool, **kwargs: Any
) -> None:
"""Install latest update."""
try:
await self.adguard.update.begin_update()
except AdGuardHomeError as err:
raise HomeAssistantError(f"Failed to install update: {err}") from err
self.hass.config_entries.async_schedule_reload(self._entry.entry_id)

View File

@@ -4,6 +4,7 @@
"codeowners": ["@Bre77"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/advantage_air",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["advantage_air"],
"requirements": ["advantage-air==0.4.4"]

View File

@@ -4,6 +4,7 @@
"codeowners": ["@Noltari"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aemet",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["aemet_opendata"],
"requirements": ["AEMET-OpenData==0.6.4"]

View File

@@ -4,6 +4,7 @@
"codeowners": [],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aftership",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["pyaftership==21.11.0"]
}

View File

@@ -4,6 +4,7 @@
"codeowners": ["@ispysoftware"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/agent_dvr",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["agent"],
"requirements": ["agent-py==0.0.24"]

View File

@@ -101,8 +101,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
vol.Schema({str: STRUCTURE_FIELD_SCHEMA}),
_validate_structure_fields,
),
vol.Optional(ATTR_ATTACHMENTS): vol.All(
cv.ensure_list, [selector.MediaSelector({"accept": ["*/*"]})]
vol.Optional(ATTR_ATTACHMENTS): selector.MediaSelector(
{"accept": ["*/*"], "multiple": True}
),
}
),
@@ -118,8 +118,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
vol.Required(ATTR_TASK_NAME): cv.string,
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": ["*/*"]})]
vol.Optional(ATTR_ATTACHMENTS): selector.MediaSelector(
{"accept": ["*/*"], "multiple": True}
),
}
),

View File

@@ -4,6 +4,7 @@
"codeowners": ["@asymworks"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airnow",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["pyairnow"],
"requirements": ["pyairnow==1.3.1"]

View File

@@ -0,0 +1,29 @@
"""The Airobot integration."""
from __future__ import annotations
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from .coordinator import AirobotConfigEntry, AirobotDataUpdateCoordinator
PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.SENSOR]
async def async_setup_entry(hass: HomeAssistant, entry: AirobotConfigEntry) -> bool:
"""Set up Airobot from a config entry."""
coordinator = AirobotDataUpdateCoordinator(hass, entry)
# Fetch initial data so we have data when entities subscribe
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: AirobotConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@@ -0,0 +1,168 @@
"""Climate platform for Airobot thermostat."""
from __future__ import annotations
from typing import Any
from pyairobotrest.const import (
MODE_AWAY,
MODE_HOME,
SETPOINT_TEMP_MAX,
SETPOINT_TEMP_MIN,
)
from pyairobotrest.exceptions import AirobotError
from pyairobotrest.models import ThermostatSettings, ThermostatStatus
from homeassistant.components.climate import (
PRESET_AWAY,
PRESET_BOOST,
PRESET_HOME,
ClimateEntity,
ClimateEntityFeature,
HVACAction,
HVACMode,
)
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AirobotConfigEntry
from .const import DOMAIN
from .entity import AirobotEntity
PARALLEL_UPDATES = 1
_PRESET_MODE_2_MODE = {
PRESET_AWAY: MODE_AWAY,
PRESET_HOME: MODE_HOME,
}
async def async_setup_entry(
hass: HomeAssistant,
entry: AirobotConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Airobot climate platform."""
coordinator = entry.runtime_data
async_add_entities([AirobotClimate(coordinator)])
class AirobotClimate(AirobotEntity, ClimateEntity):
"""Representation of an Airobot thermostat."""
_attr_name = None
_attr_translation_key = "thermostat"
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_hvac_modes = [HVACMode.HEAT]
_attr_preset_modes = [PRESET_HOME, PRESET_AWAY, PRESET_BOOST]
_attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE
)
_attr_min_temp = SETPOINT_TEMP_MIN
_attr_max_temp = SETPOINT_TEMP_MAX
@property
def _status(self) -> ThermostatStatus:
"""Get status from coordinator data."""
return self.coordinator.data.status
@property
def _settings(self) -> ThermostatSettings:
"""Get settings from coordinator data."""
return self.coordinator.data.settings
@property
def current_temperature(self) -> float | None:
"""Return the current temperature.
If floor temperature is available, thermostat is set up for floor heating.
"""
if self._status.temp_floor is not None:
return self._status.temp_floor
return self._status.temp_air
@property
def current_humidity(self) -> float | None:
"""Return the current humidity."""
return self._status.hum_air
@property
def target_temperature(self) -> float | None:
"""Return the target temperature."""
if self._settings.is_home_mode:
return self._settings.setpoint_temp
return self._settings.setpoint_temp_away
@property
def hvac_mode(self) -> HVACMode:
"""Return current HVAC mode."""
if self._status.is_heating:
return HVACMode.HEAT
return HVACMode.OFF
@property
def hvac_action(self) -> HVACAction:
"""Return current HVAC action."""
if self._status.is_heating:
return HVACAction.HEATING
return HVACAction.IDLE
@property
def preset_mode(self) -> str | None:
"""Return current preset mode."""
if self._settings.setting_flags.boost_enabled:
return PRESET_BOOST
if self._settings.is_home_mode:
return PRESET_HOME
return PRESET_AWAY
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
temperature = kwargs[ATTR_TEMPERATURE]
try:
if self._settings.is_home_mode:
await self.coordinator.client.set_home_temperature(float(temperature))
else:
await self.coordinator.client.set_away_temperature(float(temperature))
except AirobotError as err:
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="set_temperature_failed",
translation_placeholders={"temperature": str(temperature)},
) from err
await self.coordinator.async_request_refresh()
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set HVAC mode.
This thermostat only supports HEAT mode. The climate platform validates
that only supported modes are passed, so this method is a no-op.
"""
async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new preset mode."""
try:
if preset_mode == PRESET_BOOST:
# Enable boost mode
if not self._settings.setting_flags.boost_enabled:
await self.coordinator.client.set_boost_mode(True)
else:
# Disable boost mode if it's enabled
if self._settings.setting_flags.boost_enabled:
await self.coordinator.client.set_boost_mode(False)
# Set the mode (HOME or AWAY)
await self.coordinator.client.set_mode(_PRESET_MODE_2_MODE[preset_mode])
except AirobotError as err:
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="set_preset_mode_failed",
translation_placeholders={"preset_mode": preset_mode},
) from err
await self.coordinator.async_request_refresh()

View File

@@ -0,0 +1,234 @@
"""Config flow for the Airobot integration."""
from __future__ import annotations
from collections.abc import Mapping
from dataclasses import dataclass
import logging
from typing import Any
from pyairobotrest import AirobotClient
from pyairobotrest.exceptions import (
AirobotAuthError,
AirobotConnectionError,
AirobotError,
AirobotTimeoutError,
)
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow as BaseConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): str,
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
}
)
@dataclass
class DeviceInfo:
"""Device information."""
title: str
device_id: str
async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> DeviceInfo:
"""Validate the user input allows us to connect.
Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user.
"""
session = async_get_clientsession(hass)
client = AirobotClient(
host=data[CONF_HOST],
username=data[CONF_USERNAME],
password=data[CONF_PASSWORD],
session=session,
)
try:
# Try to fetch data to validate connection and authentication
status = await client.get_statuses()
settings = await client.get_settings()
except AirobotAuthError as err:
raise InvalidAuth from err
except (AirobotConnectionError, AirobotTimeoutError, AirobotError) as err:
raise CannotConnect from err
# Use device name or device ID as title
title = settings.device_name or status.device_id
return DeviceInfo(title=title, device_id=status.device_id)
class AirobotConfigFlow(BaseConfigFlow, domain=DOMAIN):
"""Handle a config flow for Airobot."""
VERSION = 1
MINOR_VERSION = 1
def __init__(self) -> None:
"""Initialize the config flow."""
self._discovered_host: str | None = None
self._discovered_mac: str | None = None
self._discovered_device_id: str | None = None
async def async_step_dhcp(
self, discovery_info: DhcpServiceInfo
) -> ConfigFlowResult:
"""Handle DHCP discovery."""
# Store the discovered IP address and MAC
self._discovered_host = discovery_info.ip
self._discovered_mac = discovery_info.macaddress
# Extract device_id from hostname (format: airobot-thermostat-t01xxxxxx)
hostname = discovery_info.hostname.lower()
device_id = hostname.replace("airobot-thermostat-", "").upper()
self._discovered_device_id = device_id
# Set unique_id to device_id for duplicate detection
await self.async_set_unique_id(device_id)
self._abort_if_unique_id_configured(updates={CONF_HOST: discovery_info.ip})
# Show the confirmation form
return await self.async_step_dhcp_confirm()
async def async_step_dhcp_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle DHCP discovery confirmation - ask for credentials only."""
errors: dict[str, str] = {}
if user_input is not None:
# Combine discovered host and device_id with user-provided password
data = {
CONF_HOST: self._discovered_host,
CONF_USERNAME: self._discovered_device_id,
CONF_PASSWORD: user_input[CONF_PASSWORD],
}
try:
info = await validate_input(self.hass, data)
except CannotConnect:
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
# Store MAC address in config entry data
if self._discovered_mac:
data[CONF_MAC] = self._discovered_mac
return self.async_create_entry(title=info.title, data=data)
# Only ask for password since we already have the device_id from discovery
return self.async_show_form(
step_id="dhcp_confirm",
data_schema=vol.Schema(
{
vol.Required(CONF_PASSWORD): str,
}
),
description_placeholders={
"host": self._discovered_host or "",
"device_id": self._discovered_device_id or "",
},
errors=errors,
)
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}
if user_input is not None:
try:
info = await validate_input(self.hass, user_input)
except CannotConnect:
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
# Use device ID as unique ID to prevent duplicates
await self.async_set_unique_id(info.device_id)
self._abort_if_unique_id_configured()
return self.async_create_entry(title=info.title, data=user_input)
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
)
async def async_step_reauth(
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle reauthentication upon an API authentication error."""
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm reauthentication dialog."""
errors: dict[str, str] = {}
reauth_entry = self._get_reauth_entry()
if user_input is not None:
# Combine existing data with new password
data = {
CONF_HOST: reauth_entry.data[CONF_HOST],
CONF_USERNAME: reauth_entry.data[CONF_USERNAME],
CONF_PASSWORD: user_input[CONF_PASSWORD],
}
try:
await validate_input(self.hass, data)
except CannotConnect:
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
return self.async_update_reload_and_abort(
reauth_entry,
data_updates={CONF_PASSWORD: user_input[CONF_PASSWORD]},
)
return self.async_show_form(
step_id="reauth_confirm",
data_schema=vol.Schema(
{
vol.Required(CONF_PASSWORD): str,
}
),
description_placeholders={
"username": reauth_entry.data[CONF_USERNAME],
"host": reauth_entry.data[CONF_HOST],
},
errors=errors,
)
class CannotConnect(HomeAssistantError):
"""Error to indicate we cannot connect."""
class InvalidAuth(HomeAssistantError):
"""Error to indicate there is invalid auth."""

View File

@@ -0,0 +1,5 @@
"""Constants for the Airobot integration."""
from typing import Final
DOMAIN: Final = "airobot"

View File

@@ -0,0 +1,68 @@
"""Coordinator for the Airobot integration."""
from __future__ import annotations
from datetime import timedelta
import logging
from pyairobotrest import AirobotClient
from pyairobotrest.exceptions import AirobotAuthError, AirobotConnectionError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN
from .models import AirobotData
_LOGGER = logging.getLogger(__name__)
# Update interval - thermostat measures air every 30 seconds
UPDATE_INTERVAL = timedelta(seconds=30)
type AirobotConfigEntry = ConfigEntry[AirobotDataUpdateCoordinator]
class AirobotDataUpdateCoordinator(DataUpdateCoordinator[AirobotData]):
"""Class to manage fetching Airobot data."""
config_entry: AirobotConfigEntry
def __init__(self, hass: HomeAssistant, entry: AirobotConfigEntry) -> None:
"""Initialize the coordinator."""
super().__init__(
hass,
_LOGGER,
name=DOMAIN,
update_interval=UPDATE_INTERVAL,
config_entry=entry,
)
session = async_get_clientsession(hass)
self.client = AirobotClient(
host=entry.data[CONF_HOST],
username=entry.data[CONF_USERNAME],
password=entry.data[CONF_PASSWORD],
session=session,
)
async def _async_update_data(self) -> AirobotData:
"""Fetch data from API endpoint."""
try:
status = await self.client.get_statuses()
settings = await self.client.get_settings()
except AirobotAuthError as err:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN,
translation_key="authentication_failed",
) from err
except AirobotConnectionError as err:
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="connection_failed",
) from err
return AirobotData(status=status, settings=settings)

View File

@@ -0,0 +1,38 @@
"""Diagnostics support for Airobot."""
from __future__ import annotations
from dataclasses import asdict
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from .coordinator import AirobotConfigEntry
TO_REDACT_CONFIG = [CONF_HOST, CONF_MAC, CONF_PASSWORD, CONF_USERNAME]
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: AirobotConfigEntry
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
coordinator = entry.runtime_data
# Build device capabilities info
device_capabilities = None
if coordinator.data:
device_capabilities = {
"has_floor_sensor": coordinator.data.status.has_floor_sensor,
"has_co2_sensor": coordinator.data.status.has_co2_sensor,
"hw_version": coordinator.data.status.hw_version,
"fw_version": coordinator.data.status.fw_version,
}
return {
"entry_data": async_redact_data(entry.data, TO_REDACT_CONFIG),
"device_capabilities": device_capabilities,
"status": asdict(coordinator.data.status) if coordinator.data else None,
"settings": asdict(coordinator.data.settings) if coordinator.data else None,
}

View File

@@ -0,0 +1,42 @@
"""Base entity for Airobot integration."""
from __future__ import annotations
from homeassistant.const import CONF_MAC
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import AirobotDataUpdateCoordinator
class AirobotEntity(CoordinatorEntity[AirobotDataUpdateCoordinator]):
"""Base class for Airobot entities."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: AirobotDataUpdateCoordinator,
) -> None:
"""Initialize the entity."""
super().__init__(coordinator)
status = coordinator.data.status
settings = coordinator.data.settings
self._attr_unique_id = status.device_id
connections = set()
if (mac := coordinator.config_entry.data.get(CONF_MAC)) is not None:
connections.add((CONNECTION_NETWORK_MAC, mac))
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, status.device_id)},
connections=connections,
name=settings.device_name or status.device_id,
manufacturer="Airobot",
model="Thermostat",
model_id="TE1",
sw_version=str(status.fw_version),
hw_version=str(status.hw_version),
)

View File

@@ -0,0 +1,17 @@
{
"domain": "airobot",
"name": "Airobot",
"codeowners": ["@mettolen"],
"config_flow": true,
"dhcp": [
{
"hostname": "airobot-thermostat-*"
}
],
"documentation": "https://www.home-assistant.io/integrations/airobot",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["pyairobotrest"],
"quality_scale": "silver",
"requirements": ["pyairobotrest==0.1.0"]
}

View File

@@ -0,0 +1,15 @@
"""Models for the Airobot integration."""
from __future__ import annotations
from dataclasses import dataclass
from pyairobotrest.models import ThermostatSettings, ThermostatStatus
@dataclass
class AirobotData:
"""Data from the Airobot coordinator."""
status: ThermostatStatus
settings: ThermostatSettings

View File

@@ -0,0 +1,72 @@
rules:
# Bronze
action-setup:
status: exempt
comment: Integration does not register custom actions.
appropriate-polling: done
brands: done
common-modules: done
config-flow-test-coverage: done
config-flow: done
dependency-transparency: done
docs-actions:
status: exempt
comment: Integration does not register custom actions.
docs-high-level-description: done
docs-installation-instructions: done
docs-removal-instructions: done
entity-event-setup:
status: exempt
comment: Integration does not use event subscriptions.
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: todo
docs-known-limitations: done
docs-supported-devices: done
docs-supported-functions: done
docs-troubleshooting: done
docs-use-cases: todo
dynamic-devices:
status: exempt
comment: Single device integration, no dynamic device discovery needed.
entity-category: done
entity-device-class: done
entity-disabled-by-default: done
entity-translations: done
exception-translations: done
icon-translations: todo
reconfiguration-flow: todo
repair-issues:
status: exempt
comment: This integration doesn't have any cases where raising an issue is needed.
stale-devices:
status: exempt
comment: Single device integration, no stale device handling needed.
# Platinum
async-dependency: done
inject-websession: done
strict-typing: todo

View File

@@ -0,0 +1,150 @@
"""Sensor platform for Airobot thermostat."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime, timedelta
from pyairobotrest.models import ThermostatStatus
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import (
CONCENTRATION_PARTS_PER_MILLION,
PERCENTAGE,
EntityCategory,
UnitOfTemperature,
UnitOfTime,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.util.dt import utcnow
from homeassistant.util.variance import ignore_variance
from . import AirobotConfigEntry
from .entity import AirobotEntity
PARALLEL_UPDATES = 0
@dataclass(frozen=True, kw_only=True)
class AirobotSensorEntityDescription(SensorEntityDescription):
"""Describes Airobot sensor entity."""
value_fn: Callable[[ThermostatStatus], StateType | datetime]
supported_fn: Callable[[ThermostatStatus], bool] = lambda _: True
uptime_to_stable_datetime = ignore_variance(
lambda value: utcnow().replace(microsecond=0) - timedelta(seconds=value),
timedelta(minutes=2),
)
SENSOR_TYPES: tuple[AirobotSensorEntityDescription, ...] = (
AirobotSensorEntityDescription(
key="air_temperature",
translation_key="air_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.temp_air,
),
AirobotSensorEntityDescription(
key="humidity",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.hum_air,
),
AirobotSensorEntityDescription(
key="floor_temperature",
translation_key="floor_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.temp_floor,
supported_fn=lambda status: status.has_floor_sensor,
),
AirobotSensorEntityDescription(
key="co2",
device_class=SensorDeviceClass.CO2,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.co2,
supported_fn=lambda status: status.has_co2_sensor,
),
AirobotSensorEntityDescription(
key="air_quality_index",
device_class=SensorDeviceClass.AQI,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.aqi,
supported_fn=lambda status: status.has_co2_sensor,
),
AirobotSensorEntityDescription(
key="heating_uptime",
translation_key="heating_uptime",
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.SECONDS,
suggested_unit_of_measurement=UnitOfTime.HOURS,
state_class=SensorStateClass.TOTAL_INCREASING,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda status: status.heating_uptime,
entity_registry_enabled_default=False,
),
AirobotSensorEntityDescription(
key="errors",
translation_key="errors",
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda status: status.errors,
),
AirobotSensorEntityDescription(
key="device_uptime",
translation_key="device_uptime",
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda status: uptime_to_stable_datetime(status.device_uptime),
entity_registry_enabled_default=False,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AirobotConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Airobot sensor platform."""
coordinator = entry.runtime_data
async_add_entities(
AirobotSensor(coordinator, description)
for description in SENSOR_TYPES
if description.supported_fn(coordinator.data.status)
)
class AirobotSensor(AirobotEntity, SensorEntity):
"""Representation of an Airobot sensor."""
entity_description: AirobotSensorEntityDescription
def __init__(
self,
coordinator,
description: AirobotSensorEntityDescription,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.data.status.device_id}_{description.key}"
@property
def native_value(self) -> StateType | datetime:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self.coordinator.data.status)

View File

@@ -0,0 +1,79 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"step": {
"dhcp_confirm": {
"data": {
"password": "[%key:common::config_flow::data::password%]"
},
"data_description": {
"password": "[%key:component::airobot::config::step::user::data_description::password%]"
},
"description": "Airobot thermostat {device_id} discovered at {host}. Enter the password to complete setup. Find the password in the thermostat settings menu under Connectivity → Mobile app."
},
"reauth_confirm": {
"data": {
"password": "[%key:common::config_flow::data::password%]"
},
"data_description": {
"password": "[%key:component::airobot::config::step::user::data_description::password%]"
},
"description": "The authentication for Airobot thermostat at {host} (Device ID: {username}) has expired. Please enter the password to reauthenticate. Find the password in the thermostat settings menu under Connectivity → Mobile app."
},
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
"password": "[%key:common::config_flow::data::password%]",
"username": "Device ID"
},
"data_description": {
"host": "The hostname or IP address of your Airobot thermostat.",
"password": "The thermostat password.",
"username": "The thermostat Device ID (e.g., T01XXXXXX)."
},
"description": "Enter your Airobot thermostat connection details. Find the Device ID and password in the thermostat settings menu under Connectivity → Mobile app."
}
}
},
"entity": {
"sensor": {
"air_temperature": {
"name": "Air temperature"
},
"device_uptime": {
"name": "Device uptime"
},
"errors": {
"name": "Error count"
},
"floor_temperature": {
"name": "Floor temperature"
},
"heating_uptime": {
"name": "Heating uptime"
}
}
},
"exceptions": {
"authentication_failed": {
"message": "Authentication failed, please reauthenticate."
},
"connection_failed": {
"message": "Failed to communicate with device."
},
"set_preset_mode_failed": {
"message": "Failed to set preset mode to {preset_mode}."
},
"set_temperature_failed": {
"message": "Failed to set temperature to {temperature}."
}
}
}

View File

@@ -0,0 +1,24 @@
"""The AirPatrol integration."""
from __future__ import annotations
from homeassistant.core import HomeAssistant
from .const import PLATFORMS
from .coordinator import AirPatrolConfigEntry, AirPatrolDataUpdateCoordinator
async def async_setup_entry(hass: HomeAssistant, entry: AirPatrolConfigEntry) -> bool:
"""Set up AirPatrol from a config entry."""
coordinator = AirPatrolDataUpdateCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: AirPatrolConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@@ -0,0 +1,208 @@
"""Climate platform for AirPatrol integration."""
from __future__ import annotations
from typing import Any
from homeassistant.components.climate import (
FAN_AUTO,
FAN_HIGH,
FAN_LOW,
SWING_OFF,
SWING_ON,
ClimateEntity,
ClimateEntityFeature,
HVACMode,
)
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AirPatrolConfigEntry
from .coordinator import AirPatrolDataUpdateCoordinator
from .entity import AirPatrolEntity
PARALLEL_UPDATES = 0
AP_TO_HA_HVAC_MODES = {
"heat": HVACMode.HEAT,
"cool": HVACMode.COOL,
"off": HVACMode.OFF,
}
HA_TO_AP_HVAC_MODES = {value: key for key, value in AP_TO_HA_HVAC_MODES.items()}
AP_TO_HA_FAN_MODES = {
"min": FAN_LOW,
"max": FAN_HIGH,
"auto": FAN_AUTO,
}
HA_TO_AP_FAN_MODES = {value: key for key, value in AP_TO_HA_FAN_MODES.items()}
AP_TO_HA_SWING_MODES = {
"on": SWING_ON,
"off": SWING_OFF,
}
HA_TO_AP_SWING_MODES = {value: key for key, value in AP_TO_HA_SWING_MODES.items()}
async def async_setup_entry(
hass: HomeAssistant,
config_entry: AirPatrolConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up AirPatrol climate entities."""
coordinator = config_entry.runtime_data
units = coordinator.data
async_add_entities(
AirPatrolClimate(coordinator, unit_id)
for unit_id, unit in units.items()
if "climate" in unit
)
class AirPatrolClimate(AirPatrolEntity, ClimateEntity):
"""AirPatrol climate entity."""
_attr_name = None
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.FAN_MODE
| ClimateEntityFeature.SWING_MODE
| ClimateEntityFeature.TURN_OFF
| ClimateEntityFeature.TURN_ON
)
_attr_hvac_modes = [HVACMode.HEAT, HVACMode.COOL, HVACMode.OFF]
_attr_fan_modes = [FAN_LOW, FAN_HIGH, FAN_AUTO]
_attr_swing_modes = [SWING_ON, SWING_OFF]
_attr_min_temp = 16.0
_attr_max_temp = 30.0
def __init__(
self,
coordinator: AirPatrolDataUpdateCoordinator,
unit_id: str,
) -> None:
"""Initialize the climate entity."""
super().__init__(coordinator, unit_id)
self._attr_unique_id = f"{coordinator.config_entry.unique_id}-{unit_id}"
@property
def climate_data(self) -> dict[str, Any]:
"""Return the climate data."""
return self.device_data.get("climate") or {}
@property
def params(self) -> dict[str, Any]:
"""Return the current parameters for the climate entity."""
return self.climate_data.get("ParametersData") or {}
@property
def available(self) -> bool:
"""Return if entity is available."""
return super().available and bool(self.climate_data)
@property
def current_humidity(self) -> float | None:
"""Return the current humidity."""
if humidity := self.climate_data.get("RoomHumidity"):
return float(humidity)
return None
@property
def current_temperature(self) -> float | None:
"""Return the current temperature."""
if temp := self.climate_data.get("RoomTemp"):
return float(temp)
return None
@property
def target_temperature(self) -> float | None:
"""Return the target temperature."""
if temp := self.params.get("PumpTemp"):
return float(temp)
return None
@property
def hvac_mode(self) -> HVACMode | None:
"""Return the current HVAC mode."""
pump_power = self.params.get("PumpPower")
pump_mode = self.params.get("PumpMode")
if pump_power and pump_power == "on" and pump_mode:
return AP_TO_HA_HVAC_MODES.get(pump_mode)
return HVACMode.OFF
@property
def fan_mode(self) -> str | None:
"""Return the current fan mode."""
fan_speed = self.params.get("FanSpeed")
if fan_speed:
return AP_TO_HA_FAN_MODES.get(fan_speed)
return None
@property
def swing_mode(self) -> str | None:
"""Return the current swing mode."""
swing = self.params.get("Swing")
if swing:
return AP_TO_HA_SWING_MODES.get(swing)
return None
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
params = self.params.copy()
if ATTR_TEMPERATURE in kwargs:
temp = kwargs[ATTR_TEMPERATURE]
params["PumpTemp"] = f"{temp:.3f}"
await self._async_set_params(params)
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set new target hvac mode."""
params = self.params.copy()
if hvac_mode == HVACMode.OFF:
params["PumpPower"] = "off"
else:
params["PumpPower"] = "on"
params["PumpMode"] = HA_TO_AP_HVAC_MODES.get(hvac_mode)
await self._async_set_params(params)
async def async_set_fan_mode(self, fan_mode: str) -> None:
"""Set new target fan mode."""
params = self.params.copy()
params["FanSpeed"] = HA_TO_AP_FAN_MODES.get(fan_mode)
await self._async_set_params(params)
async def async_set_swing_mode(self, swing_mode: str) -> None:
"""Set new target swing mode."""
params = self.params.copy()
params["Swing"] = HA_TO_AP_SWING_MODES.get(swing_mode)
await self._async_set_params(params)
async def async_turn_on(self) -> None:
"""Turn the entity on."""
params = self.params.copy()
if mode := AP_TO_HA_HVAC_MODES.get(params["PumpMode"]):
await self.async_set_hvac_mode(mode)
async def async_turn_off(self) -> None:
"""Turn the entity off."""
await self.async_set_hvac_mode(HVACMode.OFF)
async def _async_set_params(self, params: dict[str, Any]) -> None:
"""Set the unit to dry mode."""
new_climate_data = self.climate_data.copy()
new_climate_data["ParametersData"] = params
await self.coordinator.api.set_unit_climate_data(
self._unit_id, new_climate_data
)
await self.coordinator.async_request_refresh()

View File

@@ -0,0 +1,111 @@
"""Config flow for the AirPatrol integration."""
from __future__ import annotations
from collections.abc import Mapping
from typing import Any
from airpatrol.api import AirPatrolAPI, AirPatrolAuthenticationError, AirPatrolError
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_EMAIL, CONF_PASSWORD
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.selector import (
TextSelector,
TextSelectorConfig,
TextSelectorType,
)
from .const import DOMAIN
DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_EMAIL): TextSelector(
TextSelectorConfig(
type=TextSelectorType.EMAIL,
autocomplete="email",
)
),
vol.Required(CONF_PASSWORD): TextSelector(
TextSelectorConfig(
type=TextSelectorType.PASSWORD,
autocomplete="current-password",
)
),
}
)
async def validate_api(
hass: HomeAssistant, user_input: dict[str, str]
) -> tuple[str | None, str | None, dict[str, str]]:
"""Validate the API connection."""
errors: dict[str, str] = {}
session = async_get_clientsession(hass)
access_token = None
unique_id = None
try:
api = await AirPatrolAPI.authenticate(
session, user_input[CONF_EMAIL], user_input[CONF_PASSWORD]
)
except AirPatrolAuthenticationError:
errors["base"] = "invalid_auth"
except AirPatrolError:
errors["base"] = "cannot_connect"
else:
access_token = api.get_access_token()
unique_id = api.get_unique_id()
return (access_token, unique_id, errors)
class AirPatrolConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for AirPatrol."""
VERSION = 1
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}
if user_input is not None:
access_token, unique_id, errors = await validate_api(self.hass, user_input)
if access_token and unique_id:
user_input[CONF_ACCESS_TOKEN] = access_token
await self.async_set_unique_id(unique_id)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=user_input[CONF_EMAIL], data=user_input
)
return self.async_show_form(
step_id="user", data_schema=DATA_SCHEMA, errors=errors
)
async def async_step_reauth(
self, user_input: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle reauthentication with new credentials."""
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle reauthentication confirmation."""
errors: dict[str, str] = {}
if user_input:
access_token, unique_id, errors = await validate_api(self.hass, user_input)
if access_token and unique_id:
await self.async_set_unique_id(unique_id)
self._abort_if_unique_id_mismatch()
user_input[CONF_ACCESS_TOKEN] = access_token
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=DATA_SCHEMA, errors=errors
)

View File

@@ -0,0 +1,16 @@
"""Constants for the AirPatrol integration."""
from datetime import timedelta
import logging
from airpatrol.api import AirPatrolAuthenticationError, AirPatrolError
from homeassistant.const import Platform
DOMAIN = "airpatrol"
LOGGER = logging.getLogger(__package__)
PLATFORMS = [Platform.CLIMATE]
SCAN_INTERVAL = timedelta(minutes=1)
AIRPATROL_ERRORS = (AirPatrolAuthenticationError, AirPatrolError)

View File

@@ -0,0 +1,100 @@
"""Data update coordinator for AirPatrol."""
from __future__ import annotations
from typing import Any
from airpatrol.api import AirPatrolAPI, AirPatrolAuthenticationError, AirPatrolError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_EMAIL, CONF_PASSWORD
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN, LOGGER, SCAN_INTERVAL
type AirPatrolConfigEntry = ConfigEntry[AirPatrolDataUpdateCoordinator]
class AirPatrolDataUpdateCoordinator(DataUpdateCoordinator[dict[str, dict[str, Any]]]):
"""Class to manage fetching AirPatrol data."""
config_entry: AirPatrolConfigEntry
api: AirPatrolAPI
def __init__(self, hass: HomeAssistant, config_entry: AirPatrolConfigEntry) -> None:
"""Initialize."""
super().__init__(
hass,
LOGGER,
name=f"{DOMAIN.capitalize()} {config_entry.title}",
update_interval=SCAN_INTERVAL,
config_entry=config_entry,
)
async def _async_setup(self) -> None:
try:
await self._setup_client()
except AirPatrolError as api_err:
raise UpdateFailed(
f"Error communicating with AirPatrol API: {api_err}"
) from api_err
async def _async_update_data(self) -> dict[str, dict[str, Any]]:
"""Update unit data from AirPatrol API."""
return {unit_data["unit_id"]: unit_data for unit_data in await self._get_data()}
async def _get_data(self, retry: bool = False) -> list[dict[str, Any]]:
"""Fetch data from API."""
try:
return await self.api.get_data()
except AirPatrolAuthenticationError as auth_err:
if retry:
raise ConfigEntryAuthFailed(
"Authentication with AirPatrol failed"
) from auth_err
await self._update_token()
return await self._get_data(retry=True)
except AirPatrolError as err:
raise UpdateFailed(
f"Error communicating with AirPatrol API: {err}"
) from err
async def _update_token(self) -> None:
"""Refresh the AirPatrol API client and update the access token."""
session = async_get_clientsession(self.hass)
try:
self.api = await AirPatrolAPI.authenticate(
session,
self.config_entry.data[CONF_EMAIL],
self.config_entry.data[CONF_PASSWORD],
)
except AirPatrolAuthenticationError as auth_err:
raise ConfigEntryAuthFailed(
"Authentication with AirPatrol failed"
) from auth_err
self.hass.config_entries.async_update_entry(
self.config_entry,
data={
**self.config_entry.data,
CONF_ACCESS_TOKEN: self.api.get_access_token(),
},
)
async def _setup_client(self) -> None:
"""Set up the AirPatrol API client from stored access_token."""
session = async_get_clientsession(self.hass)
api = AirPatrolAPI(
session,
self.config_entry.data[CONF_ACCESS_TOKEN],
self.config_entry.unique_id,
)
try:
await api.get_data()
except AirPatrolAuthenticationError:
await self._update_token()
self.api = api

View File

@@ -0,0 +1,44 @@
"""Base entity for AirPatrol integration."""
from __future__ import annotations
from typing import Any
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import AirPatrolDataUpdateCoordinator
class AirPatrolEntity(CoordinatorEntity[AirPatrolDataUpdateCoordinator]):
"""Base entity for AirPatrol devices."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: AirPatrolDataUpdateCoordinator,
unit_id: str,
) -> None:
"""Initialize the AirPatrol entity."""
super().__init__(coordinator)
self._unit_id = unit_id
device = coordinator.data[unit_id]
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, unit_id)},
name=device["name"],
manufacturer=device["manufacturer"],
model=device["model"],
serial_number=device["hwid"],
)
@property
def device_data(self) -> dict[str, Any]:
"""Return the device data."""
return self.coordinator.data[self._unit_id]
@property
def available(self) -> bool:
"""Return if entity is available."""
return super().available and self._unit_id in self.coordinator.data

View File

@@ -0,0 +1,11 @@
{
"domain": "airpatrol",
"name": "AirPatrol",
"codeowners": ["@antondalgren"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airpatrol",
"integration_type": "device",
"iot_class": "cloud_polling",
"quality_scale": "bronze",
"requirements": ["airpatrol==0.1.0"]
}

View File

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

View File

@@ -0,0 +1,38 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"unique_id_mismatch": "Login credentials do not match the configured account"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"step": {
"reauth_confirm": {
"data": {
"email": "[%key:common::config_flow::data::email%]",
"password": "[%key:common::config_flow::data::password%]"
},
"data_description": {
"email": "[%key:component::airpatrol::config::step::user::data_description::email%]",
"password": "[%key:component::airpatrol::config::step::user::data_description::password%]"
},
"description": "Reauthenticate with AirPatrol"
},
"user": {
"data": {
"email": "[%key:common::config_flow::data::email%]",
"password": "[%key:common::config_flow::data::password%]"
},
"data_description": {
"email": "Your AirPatrol email address",
"password": "Your AirPatrol password"
},
"description": "Connect to AirPatrol"
}
}
}
}

View File

@@ -17,6 +17,7 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/airthings",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["airthings"],
"requirements": ["airthings-cloud==0.2.0"]

View File

@@ -27,6 +27,7 @@
"config_flow": true,
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",
"integration_type": "device",
"iot_class": "local_polling",
"requirements": ["airthings-ble==1.2.0"]
}

View File

@@ -4,6 +4,7 @@
"codeowners": ["@samsinnamon"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airtouch4",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["airtouch4pyapi"],
"requirements": ["airtouch4pyapi==1.0.5"]

View File

@@ -4,6 +4,7 @@
"codeowners": ["@danzel"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airtouch5",
"integration_type": "hub",
"iot_class": "local_push",
"loggers": ["airtouch5py"],
"requirements": ["airtouch5py==0.3.0"]

View File

@@ -9,7 +9,8 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/airzone",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["aioairzone"],
"requirements": ["aioairzone==1.0.2"]
"requirements": ["aioairzone==1.0.4"]
}

View File

@@ -4,6 +4,7 @@
"codeowners": ["@Noltari"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airzone_cloud",
"integration_type": "hub",
"iot_class": "cloud_push",
"loggers": ["aioairzone_cloud"],
"requirements": ["aioairzone-cloud==0.7.2"]

View File

@@ -36,5 +36,28 @@
"alarm_trigger": {
"service": "mdi:bell-ring"
}
},
"triggers": {
"armed": {
"trigger": "mdi:shield"
},
"armed_away": {
"trigger": "mdi:shield-lock"
},
"armed_home": {
"trigger": "mdi:shield-home"
},
"armed_night": {
"trigger": "mdi:shield-moon"
},
"armed_vacation": {
"trigger": "mdi:shield-airplane"
},
"disarmed": {
"trigger": "mdi:shield-off"
},
"triggered": {
"trigger": "mdi:bell-ring"
}
}
}

View File

@@ -1,4 +1,8 @@
{
"common": {
"trigger_behavior_description": "The behavior of the targeted alarms to trigger on.",
"trigger_behavior_name": "Behavior"
},
"device_automation": {
"action_type": {
"arm_away": "Arm {entity_name} away",
@@ -71,6 +75,15 @@
"message": "Arming requires a code but none was given for {entity_id}."
}
},
"selector": {
"trigger_behavior": {
"options": {
"any": "Any",
"first": "First",
"last": "Last"
}
}
},
"services": {
"alarm_arm_away": {
"description": "Arms the alarm in the away mode.",
@@ -143,5 +156,77 @@
"name": "Trigger"
}
},
"title": "Alarm control panel"
"title": "Alarm control panel",
"triggers": {
"armed": {
"description": "Triggers after one or more alarms become armed, regardless of the mode.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::trigger_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::trigger_behavior_name%]"
}
},
"name": "Alarm armed"
},
"armed_away": {
"description": "Triggers after one or more alarms become armed in away mode.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::trigger_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::trigger_behavior_name%]"
}
},
"name": "Alarm armed away"
},
"armed_home": {
"description": "Triggers after one or more alarms become armed in home mode.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::trigger_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::trigger_behavior_name%]"
}
},
"name": "Alarm armed home"
},
"armed_night": {
"description": "Triggers after one or more alarms become armed in night mode.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::trigger_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::trigger_behavior_name%]"
}
},
"name": "Alarm armed night"
},
"armed_vacation": {
"description": "Triggers after one or more alarms become armed in vacation mode.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::trigger_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::trigger_behavior_name%]"
}
},
"name": "Alarm armed vacation"
},
"disarmed": {
"description": "Triggers after one or more alarms become disarmed.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::trigger_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::trigger_behavior_name%]"
}
},
"name": "Alarm disarmed"
},
"triggered": {
"description": "Triggers after one or more alarms become triggered.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::trigger_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::trigger_behavior_name%]"
}
},
"name": "Alarm triggered"
}
}
}

View File

@@ -0,0 +1,99 @@
"""Provides triggers for alarm control panels."""
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity import get_supported_features
from homeassistant.helpers.trigger import (
EntityStateTriggerBase,
Trigger,
make_conditional_entity_state_trigger,
make_entity_state_trigger,
)
from .const import DOMAIN, AlarmControlPanelEntityFeature, AlarmControlPanelState
def supports_feature(hass: HomeAssistant, entity_id: str, features: int) -> bool:
"""Get the device class of an entity or UNDEFINED if not found."""
try:
return bool(get_supported_features(hass, entity_id) & features)
except HomeAssistantError:
return False
class EntityStateTriggerRequiredFeatures(EntityStateTriggerBase):
"""Trigger for entity state changes."""
_required_features: int
def entity_filter(self, entities: set[str]) -> set[str]:
"""Filter entities of this domain."""
entities = super().entity_filter(entities)
return {
entity_id
for entity_id in entities
if supports_feature(self._hass, entity_id, self._required_features)
}
def make_entity_state_trigger_required_features(
domain: str, to_state: str, required_features: int
) -> type[EntityStateTriggerBase]:
"""Create an entity state trigger class."""
class CustomTrigger(EntityStateTriggerRequiredFeatures):
"""Trigger for entity state changes."""
_domain = domain
_to_state = to_state
_required_features = required_features
return CustomTrigger
TRIGGERS: dict[str, type[Trigger]] = {
"armed": make_conditional_entity_state_trigger(
DOMAIN,
from_states={
AlarmControlPanelState.ARMING,
AlarmControlPanelState.DISARMED,
AlarmControlPanelState.DISARMING,
AlarmControlPanelState.PENDING,
AlarmControlPanelState.TRIGGERED,
},
to_states={
AlarmControlPanelState.ARMED_AWAY,
AlarmControlPanelState.ARMED_CUSTOM_BYPASS,
AlarmControlPanelState.ARMED_HOME,
AlarmControlPanelState.ARMED_NIGHT,
AlarmControlPanelState.ARMED_VACATION,
},
),
"armed_away": make_entity_state_trigger_required_features(
DOMAIN,
AlarmControlPanelState.ARMED_AWAY,
AlarmControlPanelEntityFeature.ARM_AWAY,
),
"armed_home": make_entity_state_trigger_required_features(
DOMAIN,
AlarmControlPanelState.ARMED_HOME,
AlarmControlPanelEntityFeature.ARM_HOME,
),
"armed_night": make_entity_state_trigger_required_features(
DOMAIN,
AlarmControlPanelState.ARMED_NIGHT,
AlarmControlPanelEntityFeature.ARM_NIGHT,
),
"armed_vacation": make_entity_state_trigger_required_features(
DOMAIN,
AlarmControlPanelState.ARMED_VACATION,
AlarmControlPanelEntityFeature.ARM_VACATION,
),
"disarmed": make_entity_state_trigger(DOMAIN, AlarmControlPanelState.DISARMED),
"triggered": make_entity_state_trigger(DOMAIN, AlarmControlPanelState.TRIGGERED),
}
async def async_get_triggers(hass: HomeAssistant) -> dict[str, type[Trigger]]:
"""Return the triggers for alarm control panels."""
return TRIGGERS

View File

@@ -0,0 +1,53 @@
.trigger_common: &trigger_common
target:
entity:
domain: alarm_control_panel
fields: &trigger_common_fields
behavior:
required: true
default: any
selector:
select:
options:
- first
- last
- any
translation_key: trigger_behavior
armed: *trigger_common
armed_away:
fields: *trigger_common_fields
target:
entity:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_AWAY
armed_home:
fields: *trigger_common_fields
target:
entity:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_HOME
armed_night:
fields: *trigger_common_fields
target:
entity:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_NIGHT
armed_vacation:
fields: *trigger_common_fields
target:
entity:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_VACATION
disarmed: *trigger_common
triggered: *trigger_common

View File

@@ -45,7 +45,7 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
data[CONF_PASSWORD],
)
return await api.login_mode_interactive(data[CONF_CODE])
return await api.login.login_mode_interactive(data[CONF_CODE])
class AmazonDevicesConfigFlow(ConfigFlow, domain=DOMAIN):

View File

@@ -16,11 +16,12 @@ 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.debounce import Debouncer
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import _LOGGER, CONF_LOGIN_DATA, DOMAIN
SCAN_INTERVAL = 30
SCAN_INTERVAL = 300
type AmazonConfigEntry = ConfigEntry[AmazonDevicesCoordinator]
@@ -43,6 +44,9 @@ class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
name=entry.title,
config_entry=entry,
update_interval=timedelta(seconds=SCAN_INTERVAL),
request_refresh_debouncer=Debouncer(
hass, _LOGGER, cooldown=SCAN_INTERVAL, immediate=False
),
)
self.api = AmazonEchoApi(
session,
@@ -55,7 +59,7 @@ class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
async def _async_update_data(self) -> dict[str, AmazonDevice]:
"""Update device data."""
try:
await self.api.login_mode_stored_data()
await self.api.login.login_mode_stored_data()
data = await self.api.get_devices_data()
except CannotConnect as err:
raise UpdateFailed(

View File

@@ -8,5 +8,5 @@
"iot_class": "cloud_polling",
"loggers": ["aioamazondevices"],
"quality_scale": "platinum",
"requirements": ["aioamazondevices==8.0.1"]
"requirements": ["aioamazondevices==10.0.0"]
}

View File

@@ -4,6 +4,7 @@
"codeowners": ["@madpilot"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/amberelectric",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["amberelectric"],
"requirements": ["amberelectric==2.0.12"]

View File

@@ -6,9 +6,7 @@ import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED
from homeassistant.core import Event, HassJob, HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.event import async_call_later, async_track_time_interval
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.helpers.typing import ConfigType
from homeassistant.util.hass_dict import HassKey
@@ -20,7 +18,7 @@ from .analytics import (
EntityAnalyticsModifications,
async_devices_payload,
)
from .const import ATTR_ONBOARDED, ATTR_PREFERENCES, DOMAIN, INTERVAL, PREFERENCE_SCHEMA
from .const import ATTR_ONBOARDED, ATTR_PREFERENCES, DOMAIN, PREFERENCE_SCHEMA
from .http import AnalyticsDevicesView
__all__ = [
@@ -31,40 +29,43 @@ __all__ = [
"async_devices_payload",
]
CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN)
CONF_SNAPSHOTS_URL = "snapshots_url"
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Optional(CONF_SNAPSHOTS_URL): vol.Any(str, None),
}
)
},
extra=vol.ALLOW_EXTRA,
)
DATA_COMPONENT: HassKey[Analytics] = HassKey(DOMAIN)
async def async_setup(hass: HomeAssistant, _: ConfigType) -> bool:
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the analytics integration."""
analytics = Analytics(hass)
analytics_config = config.get(DOMAIN, {})
# For now we want to enable device analytics only if the url option
# is explicitly listed in YAML.
if CONF_SNAPSHOTS_URL in analytics_config:
disable_snapshots = False
snapshots_url = analytics_config[CONF_SNAPSHOTS_URL]
else:
disable_snapshots = True
snapshots_url = None
analytics = Analytics(hass, snapshots_url, disable_snapshots)
# Load stored data
await analytics.load()
@callback
def start_schedule(_event: Event) -> None:
async def start_schedule(_event: Event) -> None:
"""Start the send schedule after the started event."""
# Wait 15 min after started
async_call_later(
hass,
900,
HassJob(
analytics.send_analytics,
name="analytics schedule",
cancel_on_shutdown=True,
),
)
# Send every day
async_track_time_interval(
hass,
analytics.send_analytics,
INTERVAL,
name="analytics daily",
cancel_on_shutdown=True,
)
await analytics.async_schedule()
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, start_schedule)
@@ -111,7 +112,7 @@ async def websocket_analytics_preferences(
analytics = hass.data[DATA_COMPONENT]
await analytics.save_preferences(preferences)
await analytics.send_analytics()
await analytics.async_schedule()
connection.send_result(
msg["id"],

View File

@@ -7,6 +7,8 @@ from asyncio import timeout
from collections.abc import Awaitable, Callable, Iterable, Mapping
from dataclasses import asdict as dataclass_asdict, dataclass, field
from datetime import datetime
import random
import time
from typing import Any, Protocol
import uuid
@@ -31,10 +33,18 @@ from homeassistant.const import (
BASE_PLATFORMS,
__version__ as HA_VERSION,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.core import (
CALLBACK_TYPE,
HassJob,
HomeAssistant,
ReleaseChannel,
callback,
get_release_channel,
)
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.event import async_call_later, async_track_time_interval
from homeassistant.helpers.hassio import is_hassio
from homeassistant.helpers.singleton import singleton
from homeassistant.helpers.storage import Store
@@ -49,8 +59,6 @@ from homeassistant.loader import (
from homeassistant.setup import async_get_loaded_integrations
from .const import (
ANALYTICS_ENDPOINT_URL,
ANALYTICS_ENDPOINT_URL_DEV,
ATTR_ADDON_COUNT,
ATTR_ADDONS,
ATTR_ARCH,
@@ -71,6 +79,7 @@ from .const import (
ATTR_PROTECTED,
ATTR_RECORDER,
ATTR_SLUG,
ATTR_SNAPSHOTS,
ATTR_STATE_COUNT,
ATTR_STATISTICS,
ATTR_SUPERVISOR,
@@ -79,9 +88,15 @@ from .const import (
ATTR_USER_COUNT,
ATTR_UUID,
ATTR_VERSION,
BASIC_ENDPOINT_URL,
BASIC_ENDPOINT_URL_DEV,
DOMAIN,
INTERVAL,
LOGGER,
PREFERENCE_SCHEMA,
SNAPSHOT_DEFAULT_URL,
SNAPSHOT_URL_PATH,
SNAPSHOT_VERSION,
STORAGE_KEY,
STORAGE_VERSION,
)
@@ -194,13 +209,18 @@ def gen_uuid() -> str:
return uuid.uuid4().hex
RELEASE_CHANNEL = get_release_channel()
@dataclass
class AnalyticsData:
"""Analytics data."""
onboarded: bool
preferences: dict[str, bool]
uuid: str | None
uuid: str | None = None
submission_identifier: str | None = None
snapshot_submission_time: float | None = None
@classmethod
def from_dict(cls, data: dict[str, Any]) -> AnalyticsData:
@@ -209,29 +229,44 @@ class AnalyticsData:
data["onboarded"],
data["preferences"],
data["uuid"],
data.get("submission_identifier"),
data.get("snapshot_submission_time"),
)
class Analytics:
"""Analytics helper class for the analytics integration."""
def __init__(self, hass: HomeAssistant) -> None:
def __init__(
self,
hass: HomeAssistant,
snapshots_url: str | None = None,
disable_snapshots: bool = False,
) -> None:
"""Initialize the Analytics class."""
self.hass: HomeAssistant = hass
self.session = async_get_clientsession(hass)
self._data = AnalyticsData(False, {}, None)
self._hass: HomeAssistant = hass
self._snapshots_url = snapshots_url
self._disable_snapshots = disable_snapshots
self._session = async_get_clientsession(hass)
self._data = AnalyticsData(False, {})
self._store = Store[dict[str, Any]](hass, STORAGE_VERSION, STORAGE_KEY)
self._basic_scheduled: CALLBACK_TYPE | None = None
self._snapshot_scheduled: CALLBACK_TYPE | None = None
@property
def preferences(self) -> dict:
"""Return the current active preferences."""
preferences = self._data.preferences
return {
result = {
ATTR_BASE: preferences.get(ATTR_BASE, False),
ATTR_DIAGNOSTICS: preferences.get(ATTR_DIAGNOSTICS, False),
ATTR_USAGE: preferences.get(ATTR_USAGE, False),
ATTR_STATISTICS: preferences.get(ATTR_STATISTICS, False),
}
if not self._disable_snapshots:
result[ATTR_SNAPSHOTS] = preferences.get(ATTR_SNAPSHOTS, False)
return result
@property
def onboarded(self) -> bool:
@@ -244,17 +279,17 @@ class Analytics:
return self._data.uuid
@property
def endpoint(self) -> str:
def endpoint_basic(self) -> str:
"""Return the endpoint that will receive the payload."""
if HA_VERSION.endswith("0.dev0"):
if RELEASE_CHANNEL is ReleaseChannel.DEV:
# dev installations will contact the dev analytics environment
return ANALYTICS_ENDPOINT_URL_DEV
return ANALYTICS_ENDPOINT_URL
return BASIC_ENDPOINT_URL_DEV
return BASIC_ENDPOINT_URL
@property
def supervisor(self) -> bool:
"""Return bool if a supervisor is present."""
return is_hassio(self.hass)
return is_hassio(self._hass)
async def load(self) -> None:
"""Load preferences."""
@@ -264,7 +299,7 @@ class Analytics:
if (
self.supervisor
and (supervisor_info := hassio.get_supervisor_info(self.hass)) is not None
and (supervisor_info := hassio.get_supervisor_info(self._hass)) is not None
):
if not self.onboarded:
# User have not configured analytics, get this setting from the supervisor
@@ -277,32 +312,35 @@ class Analytics:
):
self._data.preferences[ATTR_DIAGNOSTICS] = False
async def _save(self) -> None:
"""Save data."""
await self._store.async_save(dataclass_asdict(self._data))
async def save_preferences(self, preferences: dict) -> None:
"""Save preferences."""
preferences = PREFERENCE_SCHEMA(preferences)
self._data.preferences.update(preferences)
self._data.onboarded = True
await self._store.async_save(dataclass_asdict(self._data))
await self._save()
if self.supervisor:
await hassio.async_update_diagnostics(
self.hass, self.preferences.get(ATTR_DIAGNOSTICS, False)
self._hass, self.preferences.get(ATTR_DIAGNOSTICS, False)
)
async def send_analytics(self, _: datetime | None = None) -> None:
"""Send analytics."""
hass = self.hass
if not self.onboarded or not self.preferences.get(ATTR_BASE, False):
return
hass = self._hass
supervisor_info = None
operating_system_info: dict[str, Any] = {}
if not self.onboarded or not self.preferences.get(ATTR_BASE, False):
LOGGER.debug("Nothing to submit")
return
if self._data.uuid is None:
self._data.uuid = gen_uuid()
await self._store.async_save(dataclass_asdict(self._data))
await self._save()
if self.supervisor:
supervisor_info = hassio.get_supervisor_info(hass)
@@ -436,7 +474,7 @@ class Analytics:
try:
async with timeout(30):
response = await self.session.post(self.endpoint, json=payload)
response = await self._session.post(self.endpoint_basic, json=payload)
if response.status == 200:
LOGGER.info(
(
@@ -449,14 +487,12 @@ class Analytics:
LOGGER.warning(
"Sending analytics failed with statuscode %s from %s",
response.status,
self.endpoint,
self.endpoint_basic,
)
except TimeoutError:
LOGGER.error("Timeout sending analytics to %s", ANALYTICS_ENDPOINT_URL)
LOGGER.error("Timeout sending analytics to %s", BASIC_ENDPOINT_URL)
except aiohttp.ClientError as err:
LOGGER.error(
"Error sending analytics to %s: %r", ANALYTICS_ENDPOINT_URL, err
)
LOGGER.error("Error sending analytics to %s: %r", BASIC_ENDPOINT_URL, err)
@callback
def _async_should_report_integration(
@@ -480,7 +516,7 @@ class Analytics:
if not integration.config_flow:
return False
entries = self.hass.config_entries.async_entries(integration.domain)
entries = self._hass.config_entries.async_entries(integration.domain)
# Filter out ignored and disabled entries
return any(
@@ -489,6 +525,186 @@ class Analytics:
if entry.source != SOURCE_IGNORE and entry.disabled_by is None
)
async def send_snapshot(self, _: datetime | None = None) -> None:
"""Send a snapshot."""
if not self.onboarded or not self.preferences.get(ATTR_SNAPSHOTS, False):
return
payload = await _async_snapshot_payload(self._hass)
headers = {
"Content-Type": "application/json",
"User-Agent": f"home-assistant/{HA_VERSION}",
}
if self._data.submission_identifier is not None:
headers["X-Device-Database-Submission-Identifier"] = (
self._data.submission_identifier
)
url = (
self._snapshots_url
if self._snapshots_url is not None
else SNAPSHOT_DEFAULT_URL
)
url += SNAPSHOT_URL_PATH
try:
async with timeout(30):
response = await self._session.post(url, json=payload, headers=headers)
if response.status == 200: # OK
response_data = await response.json()
new_identifier = response_data.get("submission_identifier")
if (
new_identifier is not None
and new_identifier != self._data.submission_identifier
):
self._data.submission_identifier = new_identifier
await self._save()
LOGGER.info(
"Submitted snapshot analytics to Home Assistant servers"
)
elif response.status == 400: # Bad Request
response_data = await response.json()
error_kind = response_data.get("kind", "unknown")
error_message = response_data.get("message", "Unknown error")
if error_kind == "invalid-submission-identifier":
# Clear the invalid identifier and retry on next cycle
LOGGER.warning(
"Invalid submission identifier to %s, clearing: %s",
url,
error_message,
)
self._data.submission_identifier = None
await self._save()
else:
LOGGER.warning(
"Malformed snapshot analytics submission (%s) to %s: %s",
error_kind,
url,
error_message,
)
elif response.status == 503: # Service Unavailable
response_text = await response.text()
LOGGER.warning(
"Snapshot analytics service %s unavailable: %s",
url,
response_text,
)
else:
LOGGER.warning(
"Unexpected status code %s when submitting snapshot analytics to %s",
response.status,
url,
)
except TimeoutError:
LOGGER.error(
"Timeout sending snapshot analytics to %s",
url,
)
except aiohttp.ClientError as err:
LOGGER.error(
"Error sending snapshot analytics to %s: %r",
url,
err,
)
async def async_schedule(self) -> None:
"""Schedule analytics."""
if not self.onboarded:
LOGGER.debug("Analytics not scheduled")
if self._basic_scheduled is not None:
self._basic_scheduled()
self._basic_scheduled = None
if self._snapshot_scheduled:
self._snapshot_scheduled()
self._snapshot_scheduled = None
return
if not self.preferences.get(ATTR_BASE, False):
LOGGER.debug("Basic analytics not scheduled")
if self._basic_scheduled is not None:
self._basic_scheduled()
self._basic_scheduled = None
elif self._basic_scheduled is None:
# Wait 15 min after started for basic analytics
self._basic_scheduled = async_call_later(
self._hass,
900,
HassJob(
self._async_schedule_basic,
name="basic analytics schedule",
cancel_on_shutdown=True,
),
)
if not self.preferences.get(ATTR_SNAPSHOTS, False) or self._disable_snapshots:
LOGGER.debug("Snapshot analytics not scheduled")
if self._snapshot_scheduled:
self._snapshot_scheduled()
self._snapshot_scheduled = None
elif self._snapshot_scheduled is None:
snapshot_submission_time = self._data.snapshot_submission_time
interval_seconds = INTERVAL.total_seconds()
if snapshot_submission_time is None:
# Randomize the submission time within the 24 hours
snapshot_submission_time = random.uniform(0, interval_seconds)
self._data.snapshot_submission_time = snapshot_submission_time
await self._save()
LOGGER.debug(
"Initialized snapshot submission time to %s",
snapshot_submission_time,
)
# Calculate delay until next submission
current_time = time.time()
delay = (snapshot_submission_time - current_time) % interval_seconds
self._snapshot_scheduled = async_call_later(
self._hass,
delay,
HassJob(
self._async_schedule_snapshots,
name="snapshot analytics schedule",
cancel_on_shutdown=True,
),
)
async def _async_schedule_basic(self, _: datetime | None = None) -> None:
"""Schedule basic analytics."""
await self.send_analytics()
# Send basic analytics every day
self._basic_scheduled = async_track_time_interval(
self._hass,
self.send_analytics,
INTERVAL,
name="basic analytics daily",
cancel_on_shutdown=True,
)
async def _async_schedule_snapshots(self, _: datetime | None = None) -> None:
"""Schedule snapshot analytics."""
await self.send_snapshot()
# Send snapshot analytics every day
self._snapshot_scheduled = async_track_time_interval(
self._hass,
self.send_snapshot,
INTERVAL,
name="snapshot analytics daily",
cancel_on_shutdown=True,
)
def _domains_from_yaml_config(yaml_configuration: dict[str, Any]) -> set[str]:
"""Extract domains from the YAML configuration."""
@@ -505,8 +721,8 @@ 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."""
async def _async_snapshot_payload(hass: HomeAssistant) -> dict: # noqa: C901
"""Return detailed information about entities and devices for a snapshot."""
dev_reg = dr.async_get(hass)
ent_reg = er.async_get(hass)
@@ -711,8 +927,13 @@ async def async_devices_payload(hass: HomeAssistant) -> dict: # noqa: C901
entities_info.append(entity_info)
return integrations_info
async def async_devices_payload(hass: HomeAssistant) -> dict:
"""Return detailed information about entities and devices for a direct download."""
return {
"version": "home-assistant:1",
"version": f"home-assistant:{SNAPSHOT_VERSION}",
"home_assistant": HA_VERSION,
"integrations": integrations_info,
"integrations": await _async_snapshot_payload(hass),
}

View File

@@ -5,13 +5,17 @@ import logging
import voluptuous as vol
ANALYTICS_ENDPOINT_URL = "https://analytics-api.home-assistant.io/v1"
ANALYTICS_ENDPOINT_URL_DEV = "https://analytics-api-dev.home-assistant.io/v1"
DOMAIN = "analytics"
INTERVAL = timedelta(days=1)
STORAGE_KEY = "core.analytics"
STORAGE_VERSION = 1
BASIC_ENDPOINT_URL = "https://analytics-api.home-assistant.io/v1"
BASIC_ENDPOINT_URL_DEV = "https://analytics-api-dev.home-assistant.io/v1"
SNAPSHOT_VERSION = 1
SNAPSHOT_DEFAULT_URL = "https://device-database.eco-dev-aws.openhomefoundation.com"
SNAPSHOT_URL_PATH = f"/api/v1/snapshot/{SNAPSHOT_VERSION}"
LOGGER: logging.Logger = logging.getLogger(__package__)
@@ -38,6 +42,7 @@ ATTR_PREFERENCES = "preferences"
ATTR_PROTECTED = "protected"
ATTR_RECORDER = "recorder"
ATTR_SLUG = "slug"
ATTR_SNAPSHOTS = "snapshots"
ATTR_STATE_COUNT = "state_count"
ATTR_STATISTICS = "statistics"
ATTR_SUPERVISOR = "supervisor"
@@ -51,6 +56,7 @@ ATTR_VERSION = "version"
PREFERENCE_SCHEMA = vol.Schema(
{
vol.Optional(ATTR_BASE): bool,
vol.Optional(ATTR_SNAPSHOTS): bool,
vol.Optional(ATTR_DIAGNOSTICS): bool,
vol.Optional(ATTR_STATISTICS): bool,
vol.Optional(ATTR_USAGE): bool,

View File

@@ -4,6 +4,7 @@
"codeowners": ["@engrbm87"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/android_ip_webcam",
"integration_type": "device",
"iot_class": "local_polling",
"requirements": ["pydroid-ipcam==3.0.0"]
}

View File

@@ -0,0 +1,73 @@
"""The Anglian Water integration."""
from __future__ import annotations
from aiohttp import CookieJar
from pyanglianwater import AnglianWater
from pyanglianwater.auth import MSOB2CAuth
from pyanglianwater.exceptions import (
ExpiredAccessTokenError,
SelfAssertedError,
SmartMeterUnavailableError,
)
from homeassistant.const import (
CONF_ACCESS_TOKEN,
CONF_PASSWORD,
CONF_USERNAME,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryError
from homeassistant.helpers.aiohttp_client import async_create_clientsession
from .const import CONF_ACCOUNT_NUMBER, DOMAIN
from .coordinator import AnglianWaterConfigEntry, AnglianWaterUpdateCoordinator
_PLATFORMS: list[Platform] = [Platform.SENSOR]
async def async_setup_entry(
hass: HomeAssistant, entry: AnglianWaterConfigEntry
) -> bool:
"""Set up Anglian Water from a config entry."""
auth = MSOB2CAuth(
username=entry.data[CONF_USERNAME],
password=entry.data[CONF_PASSWORD],
session=async_create_clientsession(
hass,
cookie_jar=CookieJar(quote_cookie=False),
),
refresh_token=entry.data[CONF_ACCESS_TOKEN],
)
try:
await auth.send_refresh_request()
except (ExpiredAccessTokenError, SelfAssertedError) as err:
raise ConfigEntryAuthFailed from err
_aw = AnglianWater(authenticator=auth)
try:
await _aw.validate_smart_meter(entry.data[CONF_ACCOUNT_NUMBER])
except SmartMeterUnavailableError as err:
raise ConfigEntryError(
translation_domain=DOMAIN, translation_key="smart_meter_unavailable"
) from err
hass.config_entries.async_update_entry(
entry, data={**entry.data, CONF_ACCESS_TOKEN: auth.refresh_token}
)
entry.runtime_data = coordinator = AnglianWaterUpdateCoordinator(
hass=hass, api=_aw, config_entry=entry
)
await coordinator.async_config_entry_first_refresh()
await hass.config_entries.async_forward_entry_setups(entry, _PLATFORMS)
return True
async def async_unload_entry(
hass: HomeAssistant, entry: AnglianWaterConfigEntry
) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, _PLATFORMS)

View File

@@ -0,0 +1,92 @@
"""Config flow for the Anglian Water integration."""
from __future__ import annotations
import logging
from typing import Any
from aiohttp import CookieJar
from pyanglianwater import AnglianWater
from pyanglianwater.auth import MSOB2CAuth
from pyanglianwater.exceptions import (
InvalidAccountIdError,
SelfAssertedError,
SmartMeterUnavailableError,
)
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_PASSWORD, CONF_USERNAME
from homeassistant.helpers import selector
from homeassistant.helpers.aiohttp_client import async_create_clientsession
from .const import CONF_ACCOUNT_NUMBER, DOMAIN
_LOGGER = logging.getLogger(__name__)
STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_USERNAME): selector.TextSelector(),
vol.Required(CONF_PASSWORD): selector.TextSelector(
selector.TextSelectorConfig(type=selector.TextSelectorType.PASSWORD)
),
vol.Required(CONF_ACCOUNT_NUMBER): selector.TextSelector(),
}
)
async def validate_credentials(
auth: MSOB2CAuth, account_number: str
) -> str | MSOB2CAuth:
"""Validate the provided credentials."""
try:
await auth.send_login_request()
except SelfAssertedError:
return "invalid_auth"
except Exception:
_LOGGER.exception("Unexpected exception")
return "unknown"
_aw = AnglianWater(authenticator=auth)
try:
await _aw.validate_smart_meter(account_number)
except (InvalidAccountIdError, SmartMeterUnavailableError):
return "smart_meter_unavailable"
return auth
class AnglianWaterConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Anglian Water."""
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}
if user_input is not None:
validation_response = await validate_credentials(
MSOB2CAuth(
username=user_input[CONF_USERNAME],
password=user_input[CONF_PASSWORD],
session=async_create_clientsession(
self.hass,
cookie_jar=CookieJar(quote_cookie=False),
),
),
user_input[CONF_ACCOUNT_NUMBER],
)
if isinstance(validation_response, str):
errors["base"] = validation_response
else:
await self.async_set_unique_id(user_input[CONF_ACCOUNT_NUMBER])
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=user_input[CONF_ACCOUNT_NUMBER],
data={
**user_input,
CONF_ACCESS_TOKEN: validation_response.refresh_token,
},
)
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
)

View File

@@ -0,0 +1,4 @@
"""Constants for the Anglian Water integration."""
DOMAIN = "anglian_water"
CONF_ACCOUNT_NUMBER = "account_number"

View File

@@ -0,0 +1,49 @@
"""Anglian Water data coordinator."""
from __future__ import annotations
from datetime import timedelta
import logging
from pyanglianwater import AnglianWater
from pyanglianwater.exceptions import ExpiredAccessTokenError, UnknownEndpointError
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import CONF_ACCOUNT_NUMBER, DOMAIN
type AnglianWaterConfigEntry = ConfigEntry[AnglianWaterUpdateCoordinator]
_LOGGER = logging.getLogger(__name__)
UPDATE_INTERVAL = timedelta(minutes=60)
class AnglianWaterUpdateCoordinator(DataUpdateCoordinator[None]):
"""Anglian Water data update coordinator."""
config_entry: AnglianWaterConfigEntry
def __init__(
self,
hass: HomeAssistant,
api: AnglianWater,
config_entry: AnglianWaterConfigEntry,
) -> None:
"""Initialize update coordinator."""
super().__init__(
hass=hass,
logger=_LOGGER,
name=DOMAIN,
update_interval=UPDATE_INTERVAL,
config_entry=config_entry,
)
self.api = api
async def _async_update_data(self) -> None:
"""Update data from Anglian Water's API."""
try:
return await self.api.update(self.config_entry.data[CONF_ACCOUNT_NUMBER])
except (ExpiredAccessTokenError, UnknownEndpointError) as err:
raise UpdateFailed from err

View File

@@ -0,0 +1,48 @@
"""Anglian Water entity."""
from __future__ import annotations
import logging
from pyanglianwater.meter import SmartMeter
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import AnglianWaterUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
class AnglianWaterEntity(CoordinatorEntity[AnglianWaterUpdateCoordinator]):
"""Defines a Anglian Water entity."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: AnglianWaterUpdateCoordinator,
smart_meter: SmartMeter,
key: str,
) -> None:
"""Initialize Anglian Water entity."""
super().__init__(coordinator)
self.smart_meter = smart_meter
self._attr_unique_id = f"{smart_meter.serial_number}_{key}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, smart_meter.serial_number)},
name=smart_meter.serial_number,
manufacturer="Anglian Water",
serial_number=smart_meter.serial_number,
)
async def async_added_to_hass(self) -> None:
"""When entity is loaded."""
self.coordinator.api.updated_data_callbacks.append(self.async_write_ha_state)
await super().async_added_to_hass()
async def async_will_remove_from_hass(self) -> None:
"""When will be removed from HASS."""
self.coordinator.api.updated_data_callbacks.remove(self.async_write_ha_state)
await super().async_will_remove_from_hass()

View File

@@ -0,0 +1,11 @@
{
"domain": "anglian_water",
"name": "Anglian Water",
"codeowners": ["@pantherale0"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/anglian_water",
"iot_class": "cloud_polling",
"loggers": ["pyanglianwater"],
"quality_scale": "bronze",
"requirements": ["pyanglianwater==3.0.0"]
}

View File

@@ -0,0 +1,83 @@
rules:
# Bronze
action-setup:
status: exempt
comment: |
No custom actions are defined.
appropriate-polling: done
brands: done
common-modules: done
config-flow-test-coverage: done
config-flow: done
dependency-transparency: done
docs-actions:
status: exempt
comment: |
No custom actions are defined.
docs-high-level-description: done
docs-installation-instructions: done
docs-removal-instructions: done
entity-event-setup: done
entity-unique-id: done
has-entity-name: done
runtime-data: done
test-before-configure: done
test-before-setup: done
unique-config-entry: done
# Silver
action-exceptions:
status: exempt
comment: |
No custom actions are defined.
config-entry-unloading: done
docs-configuration-parameters: done
docs-installation-parameters: done
entity-unavailable: done
integration-owner: done
log-when-unavailable: done
parallel-updates: done
reauthentication-flow: todo
test-coverage: todo
# Gold
devices: done
diagnostics: todo
discovery-update-info:
status: exempt
comment: |
Unable to discover meters.
discovery:
status: exempt
comment: |
Unable to discover meters.
docs-data-update: done
docs-examples: todo
docs-known-limitations: done
docs-supported-devices: done
docs-supported-functions: done
docs-troubleshooting: done
docs-use-cases: todo
dynamic-devices: todo
entity-category: done
entity-device-class: done
entity-disabled-by-default:
status: exempt
comment: |
No entities are disabled by default.
entity-translations: done
exception-translations: done
icon-translations:
status: exempt
comment: |
Entities do not require different icons.
reconfiguration-flow: todo
repair-issues:
status: exempt
comment: |
Read-only integration and no repairs are possible.
stale-devices: todo
# Platinum
async-dependency: done
inject-websession: done
strict-typing: todo

View File

@@ -0,0 +1,117 @@
"""Anglian Water sensor platform."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from enum import StrEnum
from pyanglianwater.meter import SmartMeter
from homeassistant.components.sensor import (
EntityCategory,
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import UnitOfVolume
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import AnglianWaterConfigEntry, AnglianWaterUpdateCoordinator
from .entity import AnglianWaterEntity
PARALLEL_UPDATES = 0
class AnglianWaterSensor(StrEnum):
"""Store keys for Anglian Water sensors."""
YESTERDAY_CONSUMPTION = "yesterday_consumption"
YESTERDAY_WATER_COST = "yesterday_water_cost"
YESTERDAY_SEWERAGE_COST = "yesterday_sewerage_cost"
LATEST_READING = "latest_reading"
@dataclass(frozen=True, kw_only=True)
class AnglianWaterSensorEntityDescription(SensorEntityDescription):
"""Describes AnglianWater sensor entity."""
value_fn: Callable[[SmartMeter], float]
ENTITY_DESCRIPTIONS: tuple[AnglianWaterSensorEntityDescription, ...] = (
AnglianWaterSensorEntityDescription(
key=AnglianWaterSensor.YESTERDAY_CONSUMPTION,
native_unit_of_measurement=UnitOfVolume.LITERS,
device_class=SensorDeviceClass.WATER,
value_fn=lambda entity: entity.get_yesterday_consumption,
state_class=SensorStateClass.TOTAL,
translation_key=AnglianWaterSensor.YESTERDAY_CONSUMPTION,
entity_category=EntityCategory.DIAGNOSTIC,
),
AnglianWaterSensorEntityDescription(
key=AnglianWaterSensor.LATEST_READING,
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
device_class=SensorDeviceClass.WATER,
value_fn=lambda entity: entity.latest_read,
state_class=SensorStateClass.TOTAL_INCREASING,
translation_key=AnglianWaterSensor.LATEST_READING,
entity_category=EntityCategory.DIAGNOSTIC,
),
AnglianWaterSensorEntityDescription(
key=AnglianWaterSensor.YESTERDAY_WATER_COST,
native_unit_of_measurement="GBP",
device_class=SensorDeviceClass.MONETARY,
value_fn=lambda entity: entity.yesterday_water_cost,
translation_key=AnglianWaterSensor.YESTERDAY_WATER_COST,
entity_category=EntityCategory.DIAGNOSTIC,
),
AnglianWaterSensorEntityDescription(
key=AnglianWaterSensor.YESTERDAY_SEWERAGE_COST,
native_unit_of_measurement="GBP",
device_class=SensorDeviceClass.MONETARY,
value_fn=lambda entity: entity.yesterday_sewerage_cost,
translation_key=AnglianWaterSensor.YESTERDAY_SEWERAGE_COST,
entity_category=EntityCategory.DIAGNOSTIC,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AnglianWaterConfigEntry,
async_add_devices: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the sensor platform."""
async_add_devices(
AnglianWaterSensorEntity(
coordinator=entry.runtime_data,
description=entity_description,
smart_meter=smart_meter,
)
for entity_description in ENTITY_DESCRIPTIONS
for smart_meter in entry.runtime_data.api.meters.values()
)
class AnglianWaterSensorEntity(AnglianWaterEntity, SensorEntity):
"""Defines a Anglian Water sensor."""
entity_description: AnglianWaterSensorEntityDescription
def __init__(
self,
coordinator: AnglianWaterUpdateCoordinator,
smart_meter: SmartMeter,
description: AnglianWaterSensorEntityDescription,
) -> None:
"""Initialize Anglian Water sensor."""
super().__init__(coordinator, smart_meter, description.key)
self.entity_description = description
@property
def native_value(self) -> float | None:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self.smart_meter)

View File

@@ -0,0 +1,55 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"smart_meter_unavailable": "This account does not have any smart meters associated with it. If this is unexpected, enter your Billing Account Number found at the top of your latest bill.",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"step": {
"user": {
"data": {
"account_number": "Billing Account Number",
"password": "[%key:common::config_flow::data::password%]",
"username": "[%key:common::config_flow::data::username%]"
},
"data_description": {
"account_number": "Your account number found on your latest bill.",
"password": "Your password",
"username": "Username or email used to log in to the Anglian Water website."
},
"description": "Enter your Anglian Water account credentials to connect to Home Assistant."
}
}
},
"entity": {
"sensor": {
"latest_reading": {
"name": "Latest reading"
},
"yesterday_consumption": {
"name": "Yesterday's usage"
},
"yesterday_sewerage_cost": {
"name": "Yesterday's sewerage cost"
},
"yesterday_water_cost": {
"name": "Yesterday's water cost"
}
}
},
"exceptions": {
"auth_expired": {
"message": "Authentication token expired"
},
"service_unavailable": {
"message": "Anglian Water services are currently unavailable for maintenance."
},
"smart_meter_unavailable": {
"message": "This account no longer has a smart meter associated with it."
}
}
}

View File

@@ -4,6 +4,7 @@
"codeowners": ["@Lash-L"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/anova",
"integration_type": "hub",
"iot_class": "cloud_push",
"loggers": ["anova_wifi"],
"requirements": ["anova-wifi==0.17.0"]

View File

@@ -4,6 +4,7 @@
"codeowners": ["@hyralex"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/anthemav",
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["anthemav"],
"requirements": ["anthemav==1.4.1"]

View File

@@ -17,13 +17,7 @@ from homeassistant.helpers import (
)
from homeassistant.helpers.typing import ConfigType
from .const import (
CONF_CHAT_MODEL,
DEFAULT_CONVERSATION_NAME,
DOMAIN,
LOGGER,
RECOMMENDED_CHAT_MODEL,
)
from .const import DEFAULT_CONVERSATION_NAME, DOMAIN, LOGGER
PLATFORMS = (Platform.AI_TASK, Platform.CONVERSATION)
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
@@ -43,14 +37,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AnthropicConfigEntry) ->
partial(anthropic.AsyncAnthropic, api_key=entry.data[CONF_API_KEY])
)
try:
# Use model from first conversation subentry for validation
subentries = list(entry.subentries.values())
if subentries:
model_id = subentries[0].data.get(CONF_CHAT_MODEL, RECOMMENDED_CHAT_MODEL)
else:
model_id = RECOMMENDED_CHAT_MODEL
model = await client.models.retrieve(model_id=model_id, timeout=10.0)
LOGGER.debug("Anthropic model: %s", model.display_name)
await client.models.list(timeout=10.0)
except anthropic.AuthenticationError as err:
LOGGER.error("Invalid API key: %s", err)
return False

View File

@@ -5,7 +5,8 @@ from __future__ import annotations
from functools import partial
import json
import logging
from typing import Any
import re
from typing import Any, cast
import anthropic
import voluptuous as vol
@@ -53,17 +54,11 @@ from .const import (
CONF_WEB_SEARCH_REGION,
CONF_WEB_SEARCH_TIMEZONE,
CONF_WEB_SEARCH_USER_LOCATION,
DEFAULT,
DEFAULT_AI_TASK_NAME,
DEFAULT_CONVERSATION_NAME,
DOMAIN,
NON_THINKING_MODELS,
RECOMMENDED_CHAT_MODEL,
RECOMMENDED_MAX_TOKENS,
RECOMMENDED_TEMPERATURE,
RECOMMENDED_THINKING_BUDGET,
RECOMMENDED_WEB_SEARCH,
RECOMMENDED_WEB_SEARCH_MAX_USES,
RECOMMENDED_WEB_SEARCH_USER_LOCATION,
WEB_SEARCH_UNSUPPORTED_MODELS,
)
@@ -75,13 +70,13 @@ STEP_USER_DATA_SCHEMA = vol.Schema(
}
)
RECOMMENDED_CONVERSATION_OPTIONS = {
DEFAULT_CONVERSATION_OPTIONS = {
CONF_RECOMMENDED: True,
CONF_LLM_HASS_API: [llm.LLM_API_ASSIST],
CONF_PROMPT: llm.DEFAULT_INSTRUCTIONS_PROMPT,
}
RECOMMENDED_AI_TASK_OPTIONS = {
DEFAULT_AI_TASK_OPTIONS = {
CONF_RECOMMENDED: True,
}
@@ -135,13 +130,13 @@ class AnthropicConfigFlow(ConfigFlow, domain=DOMAIN):
subentries=[
{
"subentry_type": "conversation",
"data": RECOMMENDED_CONVERSATION_OPTIONS,
"data": DEFAULT_CONVERSATION_OPTIONS,
"title": DEFAULT_CONVERSATION_NAME,
"unique_id": None,
},
{
"subentry_type": "ai_task_data",
"data": RECOMMENDED_AI_TASK_OPTIONS,
"data": DEFAULT_AI_TASK_OPTIONS,
"title": DEFAULT_AI_TASK_NAME,
"unique_id": None,
},
@@ -179,9 +174,9 @@ class ConversationSubentryFlowHandler(ConfigSubentryFlow):
) -> SubentryFlowResult:
"""Add a subentry."""
if self._subentry_type == "ai_task_data":
self.options = RECOMMENDED_AI_TASK_OPTIONS.copy()
self.options = DEFAULT_AI_TASK_OPTIONS.copy()
else:
self.options = RECOMMENDED_CONVERSATION_OPTIONS.copy()
self.options = DEFAULT_CONVERSATION_OPTIONS.copy()
return await self.async_step_init()
async def async_step_reconfigure(
@@ -282,15 +277,19 @@ class ConversationSubentryFlowHandler(ConfigSubentryFlow):
step_schema: VolDictType = {
vol.Optional(
CONF_CHAT_MODEL,
default=RECOMMENDED_CHAT_MODEL,
): str,
default=DEFAULT[CONF_CHAT_MODEL],
): SelectSelector(
SelectSelectorConfig(
options=await self._get_model_list(), custom_value=True
)
),
vol.Optional(
CONF_MAX_TOKENS,
default=RECOMMENDED_MAX_TOKENS,
default=DEFAULT[CONF_MAX_TOKENS],
): int,
vol.Optional(
CONF_TEMPERATURE,
default=RECOMMENDED_TEMPERATURE,
default=DEFAULT[CONF_TEMPERATURE],
): NumberSelector(NumberSelectorConfig(min=0, max=1, step=0.05)),
}
@@ -320,12 +319,14 @@ class ConversationSubentryFlowHandler(ConfigSubentryFlow):
if not model.startswith(tuple(NON_THINKING_MODELS)):
step_schema[
vol.Optional(CONF_THINKING_BUDGET, default=RECOMMENDED_THINKING_BUDGET)
vol.Optional(
CONF_THINKING_BUDGET, default=DEFAULT[CONF_THINKING_BUDGET]
)
] = vol.All(
NumberSelector(
NumberSelectorConfig(
min=0,
max=self.options.get(CONF_MAX_TOKENS, RECOMMENDED_MAX_TOKENS),
max=self.options.get(CONF_MAX_TOKENS, DEFAULT[CONF_MAX_TOKENS]),
)
),
vol.Coerce(int),
@@ -338,15 +339,15 @@ class ConversationSubentryFlowHandler(ConfigSubentryFlow):
{
vol.Optional(
CONF_WEB_SEARCH,
default=RECOMMENDED_WEB_SEARCH,
default=DEFAULT[CONF_WEB_SEARCH],
): bool,
vol.Optional(
CONF_WEB_SEARCH_MAX_USES,
default=RECOMMENDED_WEB_SEARCH_MAX_USES,
default=DEFAULT[CONF_WEB_SEARCH_MAX_USES],
): int,
vol.Optional(
CONF_WEB_SEARCH_USER_LOCATION,
default=RECOMMENDED_WEB_SEARCH_USER_LOCATION,
default=DEFAULT[CONF_WEB_SEARCH_USER_LOCATION],
): bool,
}
)
@@ -364,9 +365,10 @@ class ConversationSubentryFlowHandler(ConfigSubentryFlow):
user_input = {}
if user_input is not None:
if user_input.get(CONF_WEB_SEARCH, RECOMMENDED_WEB_SEARCH) and not errors:
if user_input.get(CONF_WEB_SEARCH, DEFAULT[CONF_WEB_SEARCH]) and not errors:
if user_input.get(
CONF_WEB_SEARCH_USER_LOCATION, RECOMMENDED_WEB_SEARCH_USER_LOCATION
CONF_WEB_SEARCH_USER_LOCATION,
DEFAULT[CONF_WEB_SEARCH_USER_LOCATION],
):
user_input.update(await self._get_location_data())
@@ -394,6 +396,41 @@ class ConversationSubentryFlowHandler(ConfigSubentryFlow):
last_step=True,
)
async def _get_model_list(self) -> list[SelectOptionDict]:
"""Get list of available models."""
try:
client = await self.hass.async_add_executor_job(
partial(
anthropic.AsyncAnthropic,
api_key=self._get_entry().data[CONF_API_KEY],
)
)
models = (await client.models.list()).data
except anthropic.AnthropicError:
models = []
_LOGGER.debug("Available models: %s", models)
model_options: list[SelectOptionDict] = []
short_form = re.compile(r"[^\d]-\d$")
for model_info in models:
# Resolve alias from versioned model name:
model_alias = (
model_info.id[:-9]
if model_info.id
not in ("claude-3-haiku-20240307", "claude-3-opus-20240229")
else model_info.id
)
if short_form.search(model_alias):
model_alias += "-0"
if model_alias.endswith(("haiku", "opus", "sonnet")):
model_alias += "-latest"
model_options.append(
SelectOptionDict(
label=model_info.display_name,
value=model_alias,
)
)
return model_options
async def _get_location_data(self) -> dict[str, str]:
"""Get approximate location data of the user."""
location_data: dict[str, str] = {}
@@ -418,7 +455,7 @@ class ConversationSubentryFlowHandler(ConfigSubentryFlow):
}
)
response = await client.messages.create(
model=RECOMMENDED_CHAT_MODEL,
model=cast(str, DEFAULT[CONF_CHAT_MODEL]),
messages=[
{
"role": "user",
@@ -433,7 +470,7 @@ class ConversationSubentryFlowHandler(ConfigSubentryFlow):
"content": "{", # hints the model to skip any preamble
},
],
max_tokens=RECOMMENDED_MAX_TOKENS,
max_tokens=cast(int, DEFAULT[CONF_MAX_TOKENS]),
)
_LOGGER.debug("Model response: %s", response.content)
location_data = location_schema(

View File

@@ -11,25 +11,29 @@ DEFAULT_AI_TASK_NAME = "Claude AI Task"
CONF_RECOMMENDED = "recommended"
CONF_PROMPT = "prompt"
CONF_CHAT_MODEL = "chat_model"
RECOMMENDED_CHAT_MODEL = "claude-3-5-haiku-latest"
CONF_MAX_TOKENS = "max_tokens"
RECOMMENDED_MAX_TOKENS = 3000
CONF_TEMPERATURE = "temperature"
RECOMMENDED_TEMPERATURE = 1.0
CONF_THINKING_BUDGET = "thinking_budget"
RECOMMENDED_THINKING_BUDGET = 0
MIN_THINKING_BUDGET = 1024
CONF_WEB_SEARCH = "web_search"
RECOMMENDED_WEB_SEARCH = False
CONF_WEB_SEARCH_USER_LOCATION = "user_location"
RECOMMENDED_WEB_SEARCH_USER_LOCATION = False
CONF_WEB_SEARCH_MAX_USES = "web_search_max_uses"
RECOMMENDED_WEB_SEARCH_MAX_USES = 5
CONF_WEB_SEARCH_CITY = "city"
CONF_WEB_SEARCH_REGION = "region"
CONF_WEB_SEARCH_COUNTRY = "country"
CONF_WEB_SEARCH_TIMEZONE = "timezone"
DEFAULT = {
CONF_CHAT_MODEL: "claude-3-5-haiku-latest",
CONF_MAX_TOKENS: 3000,
CONF_TEMPERATURE: 1.0,
CONF_THINKING_BUDGET: 0,
CONF_WEB_SEARCH: False,
CONF_WEB_SEARCH_USER_LOCATION: False,
CONF_WEB_SEARCH_MAX_USES: 5,
}
MIN_THINKING_BUDGET = 1024
NON_THINKING_MODELS = [
"claude-3-5", # Both sonnet and haiku
"claude-3-opus",

View File

@@ -84,14 +84,11 @@ from .const import (
CONF_WEB_SEARCH_REGION,
CONF_WEB_SEARCH_TIMEZONE,
CONF_WEB_SEARCH_USER_LOCATION,
DEFAULT,
DOMAIN,
LOGGER,
MIN_THINKING_BUDGET,
NON_THINKING_MODELS,
RECOMMENDED_CHAT_MODEL,
RECOMMENDED_MAX_TOKENS,
RECOMMENDED_TEMPERATURE,
RECOMMENDED_THINKING_BUDGET,
)
# Max number of back and forth with the LLM to generate a response
@@ -392,7 +389,7 @@ async def _transform_stream( # noqa: C901 - This is complex, but better to have
type="tool_use",
id=response.content_block.id,
name=response.content_block.name,
input="",
input={},
)
current_tool_args = ""
if response.content_block.name == output_tool:
@@ -459,7 +456,7 @@ async def _transform_stream( # noqa: C901 - This is complex, but better to have
type="server_tool_use",
id=response.content_block.id,
name=response.content_block.name,
input="",
input={},
)
current_tool_args = ""
elif isinstance(response.content_block, WebSearchToolResultBlock):
@@ -586,7 +583,7 @@ class AnthropicBaseLLMEntity(Entity):
identifiers={(DOMAIN, subentry.subentry_id)},
name=subentry.title,
manufacturer="Anthropic",
model="Claude",
model=subentry.data.get(CONF_CHAT_MODEL, DEFAULT[CONF_CHAT_MODEL]),
entry_type=dr.DeviceEntryType.SERVICE,
)
@@ -604,17 +601,19 @@ class AnthropicBaseLLMEntity(Entity):
raise TypeError("First message must be a system message")
messages = _convert_content(chat_log.content[1:])
model = options.get(CONF_CHAT_MODEL, RECOMMENDED_CHAT_MODEL)
model = options.get(CONF_CHAT_MODEL, DEFAULT[CONF_CHAT_MODEL])
model_args = MessageCreateParamsStreaming(
model=model,
messages=messages,
max_tokens=options.get(CONF_MAX_TOKENS, RECOMMENDED_MAX_TOKENS),
max_tokens=options.get(CONF_MAX_TOKENS, DEFAULT[CONF_MAX_TOKENS]),
system=system.content,
stream=True,
)
thinking_budget = options.get(CONF_THINKING_BUDGET, RECOMMENDED_THINKING_BUDGET)
thinking_budget = options.get(
CONF_THINKING_BUDGET, DEFAULT[CONF_THINKING_BUDGET]
)
if (
not model.startswith(tuple(NON_THINKING_MODELS))
and thinking_budget >= MIN_THINKING_BUDGET
@@ -625,7 +624,7 @@ class AnthropicBaseLLMEntity(Entity):
else:
model_args["thinking"] = ThinkingConfigDisabledParam(type="disabled")
model_args["temperature"] = options.get(
CONF_TEMPERATURE, RECOMMENDED_TEMPERATURE
CONF_TEMPERATURE, DEFAULT[CONF_TEMPERATURE]
)
tools: list[ToolUnionParam] = []

View File

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

View File

@@ -4,6 +4,7 @@
"codeowners": ["@bdr99"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aosmith",
"integration_type": "hub",
"iot_class": "cloud_polling",
"requirements": ["py-aosmith==1.0.15"]
}

View File

@@ -7,3 +7,26 @@ CONNECTION_TIMEOUT: int = 10
# Field name of last self test retrieved from apcupsd.
LAST_S_TEST: Final = "laststest"
# Mapping of deprecated sensor keys (as reported by apcupsd, lower-cased) to their deprecation
# repair issue translation keys.
DEPRECATED_SENSORS: Final = {
"apc": "apc_deprecated",
"end apc": "date_deprecated",
"date": "date_deprecated",
"apcmodel": "available_via_device_info",
"model": "available_via_device_info",
"firmware": "available_via_device_info",
"version": "available_via_device_info",
"upsname": "available_via_device_info",
"serialno": "available_via_device_info",
}
AVAILABLE_VIA_DEVICE_ATTR: Final = {
"apcmodel": "model",
"model": "model",
"firmware": "hw_version",
"version": "sw_version",
"upsname": "name",
"serialno": "serial_number",
}

View File

@@ -4,6 +4,8 @@ from __future__ import annotations
import logging
from homeassistant.components.automation import automations_with_entity
from homeassistant.components.script import scripts_with_entity
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
@@ -22,9 +24,11 @@ from homeassistant.const import (
UnitOfTime,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
import homeassistant.helpers.issue_registry as ir
from .const import LAST_S_TEST
from .const import AVAILABLE_VIA_DEVICE_ATTR, DEPRECATED_SENSORS, DOMAIN, LAST_S_TEST
from .coordinator import APCUPSdConfigEntry, APCUPSdCoordinator
from .entity import APCUPSdEntity
@@ -528,3 +532,62 @@ class APCUPSdSensor(APCUPSdEntity, SensorEntity):
self._attr_native_value, inferred_unit = infer_unit(self.coordinator.data[key])
if not self.native_unit_of_measurement:
self._attr_native_unit_of_measurement = inferred_unit
async def async_added_to_hass(self) -> None:
"""Handle when entity is added to Home Assistant.
If this is a deprecated sensor entity, create a repair issue to guide
the user to disable it.
"""
await super().async_added_to_hass()
if not self.enabled:
return
reason = DEPRECATED_SENSORS.get(self.entity_description.key)
if not reason:
return
automations = automations_with_entity(self.hass, self.entity_id)
scripts = scripts_with_entity(self.hass, self.entity_id)
if not automations and not scripts:
return
entity_registry = er.async_get(self.hass)
items = [
f"- [{entry.name or entry.original_name or entity_id}]"
f"(/config/{integration}/edit/{entry.unique_id or entity_id.split('.', 1)[-1]})"
for integration, entities in (
("automation", automations),
("script", scripts),
)
for entity_id in entities
if (entry := entity_registry.async_get(entity_id))
]
placeholders = {
"entity_name": str(self.name or self.entity_id),
"entity_id": self.entity_id,
"items": "\n".join(items),
}
if via_attr := AVAILABLE_VIA_DEVICE_ATTR.get(self.entity_description.key):
placeholders["available_via_device_attr"] = via_attr
if device_entry := self.device_entry:
placeholders["device_id"] = device_entry.id
ir.async_create_issue(
self.hass,
DOMAIN,
f"{reason}_{self.entity_id}",
breaks_in_ha_version="2026.6.0",
is_fixable=False,
severity=ir.IssueSeverity.WARNING,
translation_key=reason,
translation_placeholders=placeholders,
)
async def async_will_remove_from_hass(self) -> None:
"""Handle when entity will be removed from Home Assistant."""
await super().async_will_remove_from_hass()
if issue_key := DEPRECATED_SENSORS.get(self.entity_description.key):
ir.async_delete_issue(self.hass, DOMAIN, f"{issue_key}_{self.entity_id}")

View File

@@ -241,5 +241,19 @@
"cannot_connect": {
"message": "Cannot connect to APC UPS Daemon."
}
},
"issues": {
"apc_deprecated": {
"description": "The {entity_name} sensor (`{entity_id}`) is deprecated because it exposes internal details of the APC UPS Daemon response.\n\nIt is still referenced in the following automations or scripts:\n{items}\n\nUpdate those automations or scripts to use supported APC UPS entities instead. Reload the APC UPS Daemon integration afterwards to resolve this issue.",
"title": "{entity_name} sensor is deprecated"
},
"available_via_device_info": {
"description": "The {entity_name} sensor (`{entity_id}`) is deprecated because the same value is available from the device registry via `device_attr(\"{device_id}\", \"{available_via_device_attr}\")`.\n\nIt is still referenced in the following automations or scripts:\n{items}\n\nUpdate those automations or scripts to use the `device_attr` helper instead of this sensor. Reload the APC UPS Daemon integration afterwards to resolve this issue.",
"title": "{entity_name} sensor is deprecated"
},
"date_deprecated": {
"description": "The {entity_name} sensor (`{entity_id}`) is deprecated because the timestamp is already available from other APC UPS sensors via their last updated time.\n\nIt is still referenced in the following automations or scripts:\n{items}\n\nUpdate those automations or scripts to reference any entity's `last_updated` attribute instead (for example, `states.binary_sensor.apcups_online_status.last_updated`). Reload the APC UPS Daemon integration afterwards to resolve this issue.",
"title": "{entity_name} sensor is deprecated"
}
}
}

View File

@@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["zeroconf"],
"documentation": "https://www.home-assistant.io/integrations/apple_tv",
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["pyatv", "srptools"],
"requirements": ["pyatv==0.16.1;python_version<'3.14'"],

View File

@@ -4,6 +4,7 @@
"codeowners": ["@elupus"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/arcam_fmj",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["arcam"],
"requirements": ["arcam-fmj==1.8.2"],

View File

@@ -4,6 +4,7 @@
"codeowners": ["@ikalnyi"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/arve",
"integration_type": "hub",
"iot_class": "cloud_polling",
"requirements": ["asyncarve==0.1.1"]
}

View File

@@ -4,6 +4,7 @@
"codeowners": ["@milanmeu"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aseko_pool_live",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["aioaseko"],
"requirements": ["aioaseko==1.0.0"]

View File

@@ -3,8 +3,9 @@
from abc import ABC, abstractmethod
from dataclasses import dataclass
import logging
import math
from pymicro_vad import MicroVad
from pysilero_vad import SileroVoiceActivityDetector
from pyspeex_noise import AudioProcessor
from .const import BYTES_PER_CHUNK
@@ -42,8 +43,8 @@ class AudioEnhancer(ABC):
"""Enhance chunk of PCM audio @ 16Khz with 16-bit mono samples."""
class MicroVadSpeexEnhancer(AudioEnhancer):
"""Audio enhancer that runs microVAD and speex."""
class SileroVadSpeexEnhancer(AudioEnhancer):
"""Audio enhancer that runs Silero VAD and speex."""
def __init__(
self, auto_gain: int, noise_suppression: int, is_vad_enabled: bool
@@ -69,21 +70,49 @@ class MicroVadSpeexEnhancer(AudioEnhancer):
self.noise_suppression,
)
self.vad: MicroVad | None = None
self.vad: SileroVoiceActivityDetector | None = None
# We get 10ms chunks but Silero works on 32ms chunks, so we have to
# buffer audio. The previous speech probability is used until enough
# audio has been buffered.
self._vad_buffer: bytearray | None = None
self._vad_buffer_chunks = 0
self._vad_buffer_chunk_idx = 0
self._last_speech_probability: float | None = None
if self.is_vad_enabled:
self.vad = MicroVad()
_LOGGER.debug("Initialized microVAD")
self.vad = SileroVoiceActivityDetector()
# VAD buffer is a multiple of 10ms, but Silero VAD needs 32ms.
self._vad_buffer_chunks = int(
math.ceil(self.vad.chunk_bytes() / BYTES_PER_CHUNK)
)
self._vad_leftover_bytes = self.vad.chunk_bytes() - BYTES_PER_CHUNK
self._vad_buffer = bytearray(self.vad.chunk_bytes())
_LOGGER.debug("Initialized Silero VAD")
def enhance_chunk(self, audio: bytes, timestamp_ms: int) -> EnhancedAudioChunk:
"""Enhance 10ms chunk of PCM audio @ 16Khz with 16-bit mono samples."""
speech_probability: float | None = None
assert len(audio) == BYTES_PER_CHUNK
if self.vad is not None:
# Run VAD
speech_probability = self.vad.Process10ms(audio)
assert self._vad_buffer is not None
start_idx = self._vad_buffer_chunk_idx * BYTES_PER_CHUNK
self._vad_buffer[start_idx : start_idx + BYTES_PER_CHUNK] = audio
self._vad_buffer_chunk_idx += 1
if self._vad_buffer_chunk_idx >= self._vad_buffer_chunks:
# We have enough data to run Silero VAD (32 ms)
self._last_speech_probability = self.vad.process_chunk(
self._vad_buffer[: self.vad.chunk_bytes()]
)
# Copy leftover audio that wasn't processed to start
self._vad_buffer[: self._vad_leftover_bytes] = self._vad_buffer[
-self._vad_leftover_bytes :
]
self._vad_buffer_chunk_idx = 0
if self.audio_processor is not None:
# Run noise suppression and auto gain
@@ -92,5 +121,5 @@ class MicroVadSpeexEnhancer(AudioEnhancer):
return EnhancedAudioChunk(
audio=audio,
timestamp_ms=timestamp_ms,
speech_probability=speech_probability,
speech_probability=self._last_speech_probability,
)

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