Compare commits

..

208 Commits

Author SHA1 Message Date
bkobus-bbx 0e0901993d Fix blebox light temperature scaling (#170573) 2026-05-19 08:47:23 +00:00
Franck Nijhof 54aba11091 Bump version to 2026.5.3 2026-05-19 08:39:50 +00:00
Mick Vleeshouwer dc9116a7a7 Fix tilt and position support for VenetianBlind covers in Overkiz (#170974) 2026-05-19 08:39:38 +00:00
Mick Vleeshouwer 1e90882918 Fix is_closed state and position for DynamicPergola covers in Overkiz (#170983) 2026-05-19 08:37:54 +00:00
puddly e8295e14b1 Fix ZHA config entries using a URI without a port (#171164) 2026-05-19 08:35:43 +00:00
Mick Vleeshouwer 7ebaaf129a Fix controls for UpDownGarageDoor4T and additional 4T covers in Overkiz (#171144) 2026-05-19 08:35:00 +00:00
Michael ee734dede6 Bump aioimmich to 0.14.1 (#171138) 2026-05-19 08:33:58 +00:00
Franck Nijhof ebc582c813 Return media_content_id as string in forked_daapd (#171059) 2026-05-19 08:33:56 +00:00
James Nimmo 311e5a9bd2 Bump pyIntesishome to 1.8.8 (#171041) 2026-05-19 08:33:54 +00:00
Franck Nijhof cd6c3c878b Fix WeatherFlow websocket crash when data payload is None (#171037) 2026-05-19 08:33:52 +00:00
Franck Nijhof 51589ec2ff Add stop command to Overkiz pergola horizontal awning covers (#171034) 2026-05-19 08:33:50 +00:00
Franck Nijhof 8e1a04dc82 Fix Verisure alarm crash when cloud rejects arm/disarm command (#171024) 2026-05-19 08:33:48 +00:00
Mick Vleeshouwer 6b15f9a2ec Add additional overrides to cover entity in Overkiz (#171019) 2026-05-19 08:33:46 +00:00
Franck Nijhof 8d66752556 Fix shorthand template conditions in choose blocks crashing all automations (#171018) 2026-05-19 08:33:44 +00:00
Franck Nijhof 266767e37d Handle Daikin connection errors gracefully in coordinator (#171017) 2026-05-19 08:33:42 +00:00
Franck Nijhof d39775ac34 Fix manual alarm panel crash on restore with invalid state (#171016) 2026-05-19 08:33:40 +00:00
Franck Nijhof a314f7bf64 Fix Control4 climate crash when humidity is 'Undefined' (#171015) 2026-05-19 08:33:38 +00:00
Franck Nijhof 37478d33eb Fix SleepIQ timer units: seconds should be minutes for core climate and foot warmer (#171013) 2026-05-19 08:33:36 +00:00
Franck Nijhof 5a76f3bd19 Fix Growatt mix device IndexError when chart data is empty (#171012) 2026-05-19 08:33:34 +00:00
Franck Nijhof 17e105083e Fix threshold preview crash when hysteresis is not provided (#171009) 2026-05-19 08:33:32 +00:00
Franck Nijhof db8589b2bc Fix time trigger crash when using entity_id dict format without offset (#171006)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2026-05-19 08:33:30 +00:00
Franck Nijhof 771b016f33 Fix Netatmo valve KeyError when hvac_action state is unavailable in Overkiz (#171004) 2026-05-19 08:33:28 +00:00
Franck Nijhof 0bc0745e8c Use asyncio.get_running_loop() in emulated_hue UPnP responder (#171000)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 08:31:43 +00:00
Franck Nijhof ea084797d3 Load template extensions by class to prevent import deadlock (#170995)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 08:31:41 +00:00
Franck Nijhof 2456753caf Prevent Google Assistant entity sync from blocking startup (#170991)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 08:31:39 +00:00
Mick Vleeshouwer 070de13c14 Fix controls for OpenCloseGate4T (rts:GateOpenerRTS4TComponent) in Overkiz (#170987) 2026-05-19 08:30:30 +00:00
Mick Vleeshouwer 5e45f37ee6 Fix is_closed state for DiscretePositionableGarageDoor in Overkiz (#170981) 2026-05-19 08:25:10 +00:00
Franck Nijhof 4a96880f51 Reduce GoodWe connect retries to avoid blocking startup (#170964)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 08:20:26 +00:00
Franck Nijhof 228ac01124 Use correct state_class for utility meters with device classes that don't support total_increasing (#170962)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 08:20:24 +00:00
Franck Nijhof d366027e6b Fix utility meter next_reset shifting forward on entity rename (#170957)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 08:20:22 +00:00
puddly 2f35ad2a8a Disable USB discovery for teleinfo (#170933) 2026-05-19 08:20:20 +00:00
Mick Vleeshouwer 95cc9aed64 Fix is_closed state for SlidingDiscreteGateWithPedestrianPosition covers in Overkiz (#170913) 2026-05-19 08:19:03 +00:00
Franck Nijhof 37d6449a49 Populate uid and recurrence_id in CalDAV calendar events (#170910) 2026-05-19 08:14:10 +00:00
J. Nick Koston 249b5435d9 Bump aiodns to 4.0.3 (#170865)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2026-05-19 08:07:21 +00:00
bkobus-bbx 3293ebcea5 Fix ValueError when turning on blebox light with brightness set to 0 (#170769)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-05-19 08:07:18 +00:00
Daniil Karpenko 47d8adc77c Add tilt controls for UpDownSheerScreen in Overkiz (#170563)
Co-authored-by: Mick Vleeshouwer <mick@imick.nl>
2026-05-19 08:01:00 +00:00
Keith Roehrenbeck 356e6a691b Fix Apple TV keyboard focus binary_sensor missing on cold start (#170360) 2026-05-19 08:00:58 +00:00
Florent Thoumie b26c2f3854 Improve iaqualink 429 handling (#170231) 2026-05-19 08:00:56 +00:00
Luka Matijević 0830988687 Bump qbittorrent-api to 2026.5.1 (#170181) 2026-05-19 08:00:54 +00:00
Franck Nijhof 1e47149764 Fix hassfest warning 2026-05-15 20:26:51 +00:00
Franck Nijhof 116b63ca3a Bump version to 2026.5.2 2026-05-15 20:13:00 +00:00
Ronald van der Meer 3096bcf8a9 Bump python-duco-connectivity to 0.4.0 (#170661) 2026-05-15 20:12:26 +00:00
Ronald van der Meer a4027029d0 Migrate Duco to python-duco-connectivity and remove temperature sensors (#170237) 2026-05-15 20:11:35 +00:00
Bram Kragten fffc9d0695 Update frontend to 20260429.4 (#170567) 2026-05-15 20:06:23 +00:00
G Johansson 3ca5cf5add Add missing optional category strings in workday (#170505)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-15 20:06:21 +00:00
Jan Bouwhuis 087cb77042 Fix MQTT settings in device subentry device settings are not recalled when reconfiguring the device (#170484) 2026-05-15 20:06:19 +00:00
Michael Keck 8bd1c07ec9 Increase WebDAV client timeout from 10 to 30 seconds (#170476) 2026-05-15 20:06:17 +00:00
J. Nick Koston 9ecb59590b Bump aioharmony to 1.0.3 (#170459) 2026-05-15 20:02:46 +00:00
Rob Bierbooms e14eb9fbc5 Fix influxdb reconfigure for v1 configuration (#170448) 2026-05-15 20:01:59 +00:00
TheJulianJES 149c796227 Fix fractional setpoints in Matter climate not rounded (#170442) 2026-05-15 20:01:11 +00:00
J. Nick Koston 3383e5b1e9 Bump aioesphomeapi to 44.24.1 (#170428) 2026-05-15 20:00:24 +00:00
Åke Strandberg 05862c6dc8 Bump pymiele version to 0.6.2 (#170419) 2026-05-15 19:59:37 +00:00
Petar Petrov b35ac41470 Apply unit_of_measurement to energy combined power sensor (#170404) 2026-05-15 19:58:50 +00:00
James Nimmo 20cec56512 Bump pyintesishome to 1.8.7 (#170382) 2026-05-15 19:58:03 +00:00
puddly 74580262b6 Bump serialx to 1.7.3 (#170368) 2026-05-15 19:57:16 +00:00
Pascal Brunot f75cdae602 Bump serialx to 1.7.2 (#170272) 2026-05-15 19:56:59 +00:00
Jan Bouwhuis 8c95f4f7ae Fix duplicate doorbell events when entity becomes unavailable (#170354)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-15 19:54:02 +00:00
Robert Svensson c3ec51c471 Bump axis to v71 (#170347) 2026-05-15 19:54:00 +00:00
Raman Gupta 0f80a4bc18 Cancel previous Debouncer timer handle in _schedule_timer (#170339)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-15 19:53:58 +00:00
Maciej Bieniek 0761d618f1 Fix Shelly media player availability (#170319) 2026-05-15 19:53:57 +00:00
Stefan Agner 03e3c46faf Fix hassio.backup_partial AttributeError when folders are specified (#170312)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 19:53:55 +00:00
Craig Dean d1962b0df2 Bump renault-api to 0.5.8 (#170309) 2026-05-15 19:53:53 +00:00
Florent Thoumie 7a38a2303a iaqualink: set system specific polling interval (#170279) 2026-05-15 19:53:51 +00:00
Maciej Bieniek 6f5c2a8614 Bump imgw-pib to 2.1.2 (#170274) 2026-05-15 19:53:49 +00:00
Sören Beye ff36498698 fix: Do not forget segments from state when a new config arrives (#170265)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-15 19:53:47 +00:00
Willem-Jan van Rootselaar 23e19ea2e4 Handle empty BSB-LAN heating circuits (#170249) 2026-05-15 19:53:46 +00:00
Ronald van der Meer c33f174041 Bump python-duco-client to 0.5.0 (#170065) 2026-05-15 19:52:32 +00:00
Ronald van der Meer bbe64d74e3 Bump python-duco-client to 0.4.2 (#170027) 2026-05-15 19:52:30 +00:00
Ronald van der Meer ed3a71f2ee Add API version to Duco diagnostics for support triage (#169802) 2026-05-15 19:51:21 +00:00
Ronald van der Meer 46c49daba4 Add system health platform for Duco integration (#169517) 2026-05-15 19:48:52 +00:00
Ronald van der Meer a2f2ded188 Add target flow level and mode end time sensors to Duco integration (#169298) 2026-05-15 19:47:15 +00:00
Simone Chemelli 7be061796d Fix entities refresh for UptimeRobot (#170217) 2026-05-15 19:32:16 +00:00
Jan Bouwhuis 27c7d8de0c Fix MQTT device discovery not using shared QoS and encoding options (#170195)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-15 19:32:14 +00:00
Simone Chemelli 07542523b5 Reinit API on stale session for Vodafone Station (#170190) 2026-05-15 19:32:12 +00:00
puddly 18597bb653 Set serial port description from description, not product (#170160)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2026-05-15 19:32:10 +00:00
Christian Lackas c4be57a294 homematicip_cloud: fix HmIP-FLC lock state polarity (#170159) 2026-05-15 19:32:08 +00:00
Christian Lackas 7ceaebb086 Fix homematicip_cloud config entry setup crash after migration to 2026.5.0 (#170156) 2026-05-15 19:32:06 +00:00
Mick Vleeshouwer 7c5ef09734 Fix local API incorrectly marking devices as unavailable in Overkiz (#170118)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2026-05-15 19:32:05 +00:00
Thijs W. b4d8ba66fe Update afsapi to 1.0.1 (#170073) 2026-05-15 19:32:02 +00:00
puddly 308221ce67 Migrate ZBT-1 and ZBT-2 to use serial number for unique_id (#169879)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-05-15 19:30:56 +00:00
Simone Chemelli 1344213335 Fix non unique_id for Comelit (#169756)
Co-authored-by: Copilot <copilot@github.com>
2026-05-15 19:26:54 +00:00
r2xj 7e405e9014 Only use SmartThings switch for light if it should (#166424)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-15 19:26:52 +00:00
LG-ThinQ-Integration b0c45132ed Fix ValueError for non-numeric value in LG ThinQ (#166300)
Co-authored-by: YunseonPark-LGE <yunseon.park@lge.com>
2026-05-15 19:26:49 +00:00
Franck Nijhof dd0cdc4fc4 Bump version to 2026.5.1 2026-05-08 18:54:08 +00:00
Mick Vleeshouwer 18ea40c46d Fix tilt support for UpDownVenetianBlind (rts:VenetianBlindRTSComponent) in Overkiz (#170047) 2026-05-08 18:53:57 +00:00
Mick Vleeshouwer a23131efc8 Fix is_closed state for DynamicGate covers in Overkiz (#170130) 2026-05-08 18:53:10 +00:00
bkobus-bbx 4940a0abae Bump blebox_uniapi to v2.5.3 (#170115) 2026-05-08 18:53:08 +00:00
Willem-Jan van Rootselaar 5f98d5ae52 Bump python-bsblan to 5.2.1 (#170100) 2026-05-08 18:53:06 +00:00
TheJulianJES ba18cded30 Bump ZHA to 1.3.1 (#170095) 2026-05-08 18:53:04 +00:00
TheJulianJES fb7504e9df Fix Z-Wave discovery crash with unknown node firmware version (#170090) 2026-05-08 18:53:02 +00:00
Mick Vleeshouwer 106f815a1e Fix sensors getting wrong unit from MeasuredValueType attribute in Overkiz (#170088) 2026-05-08 18:53:00 +00:00
Mick Vleeshouwer 167757762b Set is_closed state to None when a cover state returns "unknown" in Overkiz (#170081) 2026-05-08 18:52:58 +00:00
Robert Resch 3a902e1a16 Bump deebot-client to 18.3.0 (#170066) 2026-05-08 18:52:56 +00:00
Mick Vleeshouwer 85c11672d8 Bump pyOverkiz to 1.20.3 (#170060) 2026-05-08 18:52:54 +00:00
Mick Vleeshouwer 89649df20d Fix cover controls for UpDownBioclimaticPergola in Overkiz (#170058) 2026-05-08 18:52:52 +00:00
Mick Vleeshouwer 7b749b95ce Fix tilt controls for TiltOnlyVenetianBlind in Overkiz (#170055)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-08 18:52:50 +00:00
Mick Vleeshouwer cc140be85c Fix is_closed state for DynamicGarageDoor in Overkiz (#170052) 2026-05-08 18:52:47 +00:00
Robert Svensson e1ad765414 Fix websocket certificate verification Bump axis to v70 (#170038) 2026-05-08 18:48:55 +00:00
Michael 44b1fea745 Proper handling of malformed data during FRITZ!Box Tools setup (#170030) 2026-05-08 18:48:54 +00:00
Ronald van der Meer 5dd04363b2 Bump python-duco-client to 0.4.1 (#169991) 2026-05-08 18:48:51 +00:00
Ronald van der Meer 03aa979309 Bump python-duco-client to 0.4.0 (#169776) 2026-05-08 18:48:49 +00:00
Daniel Hjelseth Høyer 6fabbb354b Bump pyTibber to 0.37.5 (#169981)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-05-08 18:45:50 +00:00
Erik Montnemery f644448d0f Add support for options to todo triggers (#169947) 2026-05-08 18:45:48 +00:00
G Johansson 4e61581cd8 Bump holidays to 0.96 (#169939) 2026-05-08 18:45:47 +00:00
puddly 6f87d02b72 Bump serialx to 1.7.1 (#169928) 2026-05-08 18:45:45 +00:00
Joakim Plate 348f6149b4 Update gardena ble to 2.8.1 (#169914) 2026-05-08 18:45:43 +00:00
Stefan Agner a4227ef1bc Fix hassio auth IndexError on Supervisor Unix socket requests (#169911) 2026-05-08 18:45:41 +00:00
Jeef aac49a567f Fix IntelliFire setup recovery (#169739) 2026-05-08 18:45:39 +00:00
Rob Treacy 76b878b136 Fix WiZ Light config flow timeout by properly closing UDP connections (#168456) 2026-05-08 18:45:37 +00:00
th3spis 2d05931683 Added wfsens as a occupancy source in wiz (#166799)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-05-08 18:45:35 +00:00
Franck Nijhof b193d951d7 Bump version to 2026.5.0 2026-05-06 15:01:09 +00:00
Franck Nijhof 4cd0d9dcec Bump version to 2026.5.0b4 2026-05-06 13:27:18 +00:00
Daniel Hjelseth Høyer 32f65b2e11 Bump pyTibber to 0.37.4 (#169907) 2026-05-06 13:27:09 +00:00
Erik Montnemery 8c79d1e44b Remove _get_tracked_value method from EntityConditionBase (#169906) 2026-05-06 13:27:07 +00:00
Erik Montnemery 8d53f7a520 Exclude incompatible humidifier entities from humidifier automations (#169905) 2026-05-06 13:27:05 +00:00
Erik Montnemery cc83ee88fb Exclude incompatible water_heater entities from water_heater automations (#169904) 2026-05-06 13:27:03 +00:00
Erik Montnemery 0c5b02eff3 Exclude incompatible climate entities from climate automations (#169903) 2026-05-06 13:27:02 +00:00
Erik Montnemery 9da9f8fd50 Unload scripts and conditions created by template entities (#169366) 2026-05-06 13:27:00 +00:00
Franck Nijhof d70ffcd3e9 Bump version to 2026.5.0b3 2026-05-06 11:16:10 +00:00
Erik Montnemery 3e26d0dfe3 Exclude incompatible entities from temperature automations (#169901) 2026-05-06 11:15:56 +00:00
Erik Montnemery eab9747b32 Exclude incompatible entities from humidity automations (#169898) 2026-05-06 11:15:54 +00:00
Erik Montnemery 9e955d8294 Add media_player volume condition (#169897) 2026-05-06 11:15:52 +00:00
Bram Kragten f08cd01ff8 Update frontend to 20260429.3 (#169893) 2026-05-06 11:10:49 +00:00
Erik Montnemery eabaf3b0fe Add media_player muted conditions (#169892) 2026-05-06 11:10:47 +00:00
Tom Matheussen 65ca790d15 Bump satel_integra to 1.3.1 (#169889) 2026-05-06 11:10:45 +00:00
Joost Lekkerkerker d177944f7a Fix Zinvolt select options (#169886) 2026-05-06 11:10:43 +00:00
Erik Montnemery 7f186f4430 Add media_player volume triggers (#169885) 2026-05-06 11:10:41 +00:00
Erik Montnemery 4f4f4642a7 Add method _should_include to EntityConditionBase (#169884)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-06 11:10:39 +00:00
Erik Montnemery 12e443cd31 Improve entity trigger tests (#169881) 2026-05-06 11:10:37 +00:00
Erik Montnemery 22a7daabe7 Add method _should_include to EntityTriggerBase (#169837) 2026-05-06 11:10:35 +00:00
Erik Montnemery c139e99abd Improve condition test helper docstrings (#169871) 2026-05-06 11:09:06 +00:00
Erik Montnemery 2bfdb96a3f Improve trigger test helper docstrings (#169869) 2026-05-06 11:09:04 +00:00
puddly 4b24ca924b Bump serialx to 1.7.0 (#169867) 2026-05-06 11:09:02 +00:00
Michael Hansen 1d3d714e4f Bump intents to 2026.5.5 (#169855) 2026-05-06 11:09:00 +00:00
Erik Montnemery ffae6eda8a Validate yaml matches implementation in automation options_supported tests (#169798) 2026-05-06 11:05:41 +00:00
Erik Montnemery 4dd996b728 Add trigger media_player.unmuted (#169797) 2026-05-06 11:05:40 +00:00
Erik Montnemery afad1e8dac Improve mobile_app device tracker tests (#169724) 2026-05-06 11:05:38 +00:00
Manu 8e41933251 Record notification from legacy notify action in Mobile App (#169749) 2026-05-06 11:00:21 +00:00
Erik Montnemery c581eaad53 Add trigger timer.time_remaining (#169763) 2026-05-06 10:58:59 +00:00
Ludovic BOUÉ 3050e79d06 Expose SET_SPEED for all fans via PercentSetting in Matter (#169696)
Co-authored-by: Ludovic BOUÉ <132135057+lboue@users.noreply.github.com>
2026-05-06 08:55:15 +00:00
Andres Ruiz 0e8ecd1065 Catch additional errors as potentially retryable errors during energy data updates (#169646) 2026-05-06 08:55:13 +00:00
Paulus Schoutsen 94732139f4 Bump version to 2026.5.0b2 2026-05-05 10:29:37 -04:00
Denis Shulyaka c5e08b2409 Return the requested format for OpenAI TTS (#169839)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-05 10:29:30 -04:00
Joost Lekkerkerker c12e1b5f4a Add Zunzunbee Zigbee brand (#169838) 2026-05-05 10:29:29 -04:00
Joost Lekkerkerker 6cfedb55e6 Add Sensereo matter brand (#169836) 2026-05-05 10:29:27 -04:00
Åke Strandberg af4cb9530b Add missing code for miele washing machine (#169795) 2026-05-05 10:29:26 -04:00
Matthias Alphart 58e97e7d5f Update xknxproject to 3.9.0 (#169775) 2026-05-05 10:29:25 -04:00
Daniel Hjelseth Høyer 2945b51617 Bump pyTibber to 0.37.3 (#169762) 2026-05-05 10:29:24 -04:00
Keilin Bickar 9d0e2df627 bump sense-energy to 0.14.1 (#169761) 2026-05-05 10:29:23 -04:00
Steve Syrell 643ae080db Bump Insteon-panel to 0.6.2 (#169757) 2026-05-05 10:29:22 -04:00
G Johansson a7eaa51179 Fix config flow validation in Nord Pool (#169751) 2026-05-05 10:29:21 -04:00
Petro31 e15852ff38 Fix uptime template sensor (#169743) 2026-05-05 10:29:20 -04:00
Diogo Gomes f6dec34136 Bump pytrydan to 1.0.0 (#169742) 2026-05-05 10:29:19 -04:00
Raj Laud 53905fbc49 Bump victron-ble-ha-parser to 0.7.0 (#169736)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-05 10:29:17 -04:00
Thomas D 8218ff0fe8 Add missing initialization charging power status option to Volvo (#169727) 2026-05-05 10:29:16 -04:00
kernelpanic85 663f7e3e6b Add Celsius and Fahrenheit to Smartthings UNITS mapping (#169686) 2026-05-05 10:29:15 -04:00
Nathan Spencer 4dfa2b8b88 Limit power status binary sensor to non-LR5 devices (#169659) 2026-05-05 10:29:14 -04:00
Nathan Spencer f828b165b1 Bump pylitterbot to 2025.4.0 (#169652) 2026-05-05 10:29:13 -04:00
shbatm c56c506648 Add precipitation device class to WeatherFlow Cloud accumulation sensors (#169638)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:29:12 -04:00
Artur Pragacz 8e5bf2a35f Fix async_unload teardown race in scripts (#169562) 2026-05-05 10:29:10 -04:00
Erik Montnemery 4d575e69a4 Improve template reload (#169480) 2026-05-05 10:29:09 -04:00
Christian Lackas 4f78bbccc0 Use all_devices in ViCare diagnostics for completeness (#169429) 2026-05-05 10:29:08 -04:00
Erik Montnemery 2d66ebe54a Add trigger media_player.muted (#156736) 2026-05-05 10:29:07 -04:00
Paulus Schoutsen a3e1209778 Bump version to 2026.5.0b1 2026-05-04 12:44:42 -04:00
Paul Bottein 7c44a0b88d Update frontend to 20260429.2 (#169748) 2026-05-04 12:44:23 -04:00
Manu 126058e0fa Bump bring-api to 1.1.2 (#169729) 2026-05-04 12:44:22 -04:00
Thomas D 28742822cb Ignore location FORBIDDEN response for the Volvo integration (#169713) 2026-05-04 12:44:21 -04:00
karwosts 179d370c2a Use uptime device_class for Uptime sensor (#169692) 2026-05-04 12:44:20 -04:00
Allen Porter 2d8f3691cf Update Nest doorbell event to use standard DoorbellEventType.RING (#169691) 2026-05-04 12:44:19 -04:00
Tom ce4fc9e880 Improve ProxmoxVE config flow preparing bug fixing (#169682)
Co-authored-by: Erwin Douna <e.douna@gmail.com>
2026-05-04 12:44:18 -04:00
Ronald van der Meer 9e357e7e5a Bump python-duco-client to 0.3.10 (#169677) 2026-05-04 12:44:17 -04:00
OMEGA_RAZER ed35b23e62 Updated prowlpy to 1.1.5 (#169671) 2026-05-04 12:44:17 -04:00
Tom Matheussen 191d2d1f12 Bump satel_integra to 1.3.0 (#169668) 2026-05-04 12:44:16 -04:00
SeifEddineMezned b165d8251f Fix grammar in mqtt/strings.json: "Minimal one" → "At least one" (#169666) 2026-05-04 12:44:15 -04:00
Midori Kochiya 5e8886aeb7 Fix M1S-T500 update error (#169651) 2026-05-04 12:44:14 -04:00
Michael bdb66635f8 Pass None config entry to schluter coordinator (#169621) 2026-05-04 12:44:13 -04:00
Michael 5ba6e348da Fix detection of CPU temperature sensor support on olde FRITZ!Box models (#169620) 2026-05-04 12:44:12 -04:00
Petro31 ed52b0ce80 Change vacuum template config names for clean area (#169599)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2026-05-04 12:44:11 -04:00
Jan-Philipp Benecke 33ee3d6967 Decrease WebDAV client timeout (#169591) 2026-05-04 12:44:10 -04:00
tronikos f36676c32c Bump opower to 0.18.2 (#169588) 2026-05-04 12:44:09 -04:00
Ronald van der Meer 77beddb1e7 Fix Duco unknown node type not re-evaluated after becoming known (#169579) 2026-05-04 12:42:31 -04:00
SeifEddineMezned 1677e410b3 Fix possessive apostrophe errors in mqtt/strings.json (#169576)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2026-05-04 12:38:37 -04:00
SeifEddineMezned 1be09347cd Fix grammar and clarity in samsungtv/strings.json (#169574) 2026-05-04 12:38:36 -04:00
Simone Chemelli c30ac2c0f3 Bump pyuptimerobot to 25.0.0 (#169572) 2026-05-04 12:37:45 -04:00
Shay Levy 145c7435a5 Bump aioshelly to 13.25.0 (#169569) 2026-05-04 12:36:21 -04:00
Paul Bottein 60f3b3bcc0 Update frontend to 20260429.1 (#169565) 2026-05-04 12:36:20 -04:00
Dan Raper 03e6d3bd30 Bump ohme to 1.9.0 (#169556) 2026-05-04 12:36:19 -04:00
Abílio Costa ee4d150e13 Use the correct schema for triggers/conditions "for" option (#169539) 2026-05-04 12:35:29 -04:00
bkobus-bbx 148603a10e Bump blebox_uniapi to 2.5.2 (#169534) 2026-05-04 12:33:13 -04:00
Erik Montnemery 1dbd933d3c Enable duration support in all entity conditions (#169532)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: frenck <195327+frenck@users.noreply.github.com>
2026-05-04 12:32:30 -04:00
Matthias Alphart f7ee7423fe Update knx-frontend to 2026.4.30.60856 (#169529) 2026-05-04 12:26:31 -04:00
Tomer 6322f1e37a Victron GX: Bug fix: parent device is mapped to the wrong device (#169525)
Co-authored-by: Copilot <copilot@github.com>
2026-05-04 12:26:30 -04:00
Manu 0d8c7fbb9d Fix: Migrate also device entries to subentry in GitHub integration (#169523) 2026-05-04 12:26:29 -04:00
Boris Bolshem 70e30b02a4 Fix KeyError in telegram_bot media group download debug log (#169519) 2026-05-04 12:26:28 -04:00
Simone Chemelli ebd21ea9b2 Fix uptime sensor for Synology DSM (#169512) 2026-05-04 12:26:27 -04:00
Erik Montnemery 9aa092cd34 Correct wake_on_lan entity behavior when entity_id changes (#169486)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-04 12:26:26 -04:00
TheJulianJES b274fe85b7 Re-interview ZHA device on websocket reconfigure (#169483) 2026-05-04 12:26:25 -04:00
Erik Montnemery 777c36998c Remove scripts from DATA_SCRIPTS on unload (#169415) 2026-05-04 12:26:24 -04:00
Kurt Chrisford a3977428f9 Implement current setpoint method in actron air integration (#169358) 2026-05-04 12:26:23 -04:00
Simone Chemelli 2d626c263c Storage problem management for Comelit Serial Bridge (#169297) 2026-05-04 12:26:22 -04:00
Jeef d1461f2e68 Bump weatherflow4py to 1.5.4 (#168994) 2026-05-04 12:26:21 -04:00
bkobus-bbx 3b778d2cc7 fix: incorrect position inversion for blebox gateBox cover (#168893) 2026-05-04 12:26:20 -04:00
Yuval Weiss 67b7d17a2f Add Broadlink infrared emitter support (#168889) 2026-05-04 12:26:18 -04:00
Tomer 1afeadc342 Victron GX: bug fix for missing translation key (#168461)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-04 12:26:17 -04:00
jftkcs f6aa4e2092 Fix reasoning summary handling for OpenAI o-models (#168093)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Denis Shulyaka <Shulyaka@gmail.com>
2026-05-04 12:26:16 -04:00
Khole 3b00c5bb96 Check device registration before completing Hive reauth flow (#168035)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Erwin Douna <e.douna@gmail.com>
2026-05-04 12:26:15 -04:00
Franck Nijhof ef7eed579b Bump version to 2026.5.0b0 2026-04-29 16:40:46 +00:00
Franck Nijhof 568a0085fe Bump version to 2026.5.0 2026-04-29 15:50:10 +00:00
10091 changed files with 46685 additions and 131593 deletions
@@ -18,13 +18,6 @@ description: Reviews GitHub pull requests and provides feedback comments. This i
4. Ensure any existing review comments have been addressed.
5. Generate constructive review comments in the CONSOLE. DO NOT POST TO GITHUB YOURSELF.
## Verification:
- After the review, run parallel subagents for each finding to double check it.
- Spawn up to a maximum of 10 parallel subagents at a time.
- Gather the results from the subagents and summarize them in the final review comments.
## IMPORTANT:
- Just review. DO NOT make any changes
- Be constructive and specific in your comments
@@ -15,15 +15,11 @@ description: Everything you need to know to build, test and review Home Assistan
- For entity actions and entity services, avoid requesting redundant defensive checks for fields already enforced by Home Assistant validation schemas and entity filters; only request extra guards when values bypass validation or are transformed unsafely.
- When validation guarantees a key is present, prefer direct dictionary indexing (`data["key"]`) over `.get("key")` so invalid assumptions fail fast.
- Integrations should be thin wrappers. Protocol parsing, device state machines, or other domain logic belong in a separate PyPI library, not in the integration itself. If unsure, ask before inlining.
- Integrations should not implement fixes or workarounds for limitations in libraries. Instead, the library should be updated to fix the issue.
The following platforms have extra guidelines:
- **Diagnostics**: [`platform-diagnostics.md`](platform-diagnostics.md) for diagnostic data collection
- **Repairs**: [`platform-repairs.md`](platform-repairs.md) for user-actionable repair issues
## Entity platforms
- Ensure `async_added_to_hass()` and `async_will_remove_from_hass()` have symmetrical behavior. For example, if a subscription is created in `async_added_to_hass()`, it should be unsubscribed in `async_will_remove_from_hass()`. Also, if something is torn down in `async_will_remove_from_hass()`, it should be set up in `async_added_to_hass()`.
## Integration Quality Scale
+1 -1
View File
@@ -14,6 +14,7 @@ Dockerfile.dev linguist-language=Dockerfile
# Generated files
CODEOWNERS linguist-generated=true
Dockerfile linguist-generated=true
homeassistant/generated/*.py linguist-generated=true
machine/* linguist-generated=true
mypy.ini linguist-generated=true
@@ -22,4 +23,3 @@ requirements_all.txt linguist-generated=true
requirements_test_all.txt linguist-generated=true
requirements_test_pre_commit.txt linguist-generated=true
script/hassfest/docker/Dockerfile linguist-generated=true
.github/workflows/*.lock.yml linguist-generated=true
+8 -23
View File
@@ -6,7 +6,6 @@
- Start review comments with a short, one-sentence summary of the suggested fix.
- Do not comment on code style, formatting or linting issues.
- A Pull Request with a dependency version bump should only contain changes required for the version bump. If the PR includes other changes, request that they are removed from the PR.
# GitHub Copilot & Claude Code Instructions
@@ -16,36 +15,22 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
- **Do NOT amend, squash, or rebase commits that have already been pushed to the PR branch after the PR is opened** - Reviewers need to follow the commit history, as well as see what changed since their last review
## Pull Requests
- When opening a pull request, use the repository's PR template (`.github/PULL_REQUEST_TEMPLATE.md`). NEVER REMOVE ANYTHING from the template.
- Do not remove checkboxes that are not checked — leave all unchecked checkboxes in place so reviewers can see which options were not selected.
## Development Commands
- When entering a new environment or worktree, run `script/setup` to set up the virtual environment with all development dependencies (pylint, pre-commit hooks, etc.). This is required before committing.
- .vscode/tasks.json contains useful commands used for development.
.vscode/tasks.json contains useful commands used for development.
## Python Syntax Notes
- Home Assistant officially supports Python 3.14 as its minimum version. Do not flag syntax or features that require Python 3.14 as issues, and do not suggest workarounds for older Python versions.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue.
- Python 3.14 evaluates annotations lazily (PEP 649). Forward references in annotations do not need to be quoted — annotations can reference names defined later in the module without quoting them or using `from __future__ import annotations`. Do not flag unquoted forward references in annotations as issues.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue since Home Assistant officially supports Python 3.14.
## Testing
- Use `uv run pytest` to run tests
- After modifying `strings.json` for an integration, regenerate the English translation file before running tests: `.venv/bin/python3 -m script.translations develop --integration <integration_name>`. Tests load translations from the generated `translations/en.json`, not directly from `strings.json`.
- When writing or modifying tests, ensure all test function parameters have type annotations.
- Prefer concrete types (for example, `HomeAssistant`, `MockConfigEntry`, etc.) over `Any`.
- Prefer `@pytest.mark.usefixtures` over arguments, if the argument is not going to be used.
- Avoid using conditions/branching in tests. Instead, either split tests or adjust the test parametrization to cover all cases without branching.
- If multiple tests share most of their code, use `pytest.mark.parametrize` to merge them into a single parameterized test instead of duplicating the body. Use `pytest.param` with an `id` parameter to name the test cases clearly.
- We use Syrupy for snapshot testing. Leverage `.ambr` snapshots instead of repetitive and exhaustive generation of test data within Python code itself.
When writing or modifying tests, ensure all test function parameters have type annotations.
Prefer concrete types (for example, `HomeAssistant`, `MockConfigEntry`, etc.) over `Any`.
## Good practices
- Integrations with Platinum or Gold level in the Integration Quality Scale reflect a high standard of code quality and maintainability. When looking for examples of something, these are good places to start. The level is indicated in the manifest.json of the integration.
- When reviewing entity actions, do not suggest extra defensive checks for input fields that are already validated by Home Assistant's service/action schemas and entity selection filters. Suggest additional guards only when data bypasses those validators or is transformed into a less-safe form.
- When validation guarantees a dict key exists, prefer direct key access (`data["key"]`) instead of `.get("key")` so contract violations are surfaced instead of silently masked.
- Do not add comments that just restate the code on the following line(s) (e.g. `# Check if initialized` above `if self.initialized:`). Comments should only explain why — non-obvious constraints, surprising behavior, or workarounds — never what.
Integrations with Platinum or Gold level in the Integration Quality Scale reflect a high standard of code quality and maintainability. When looking for examples of something, these are good places to start. The level is indicated in the manifest.json of the integration.
When reviewing entity actions, do not suggest extra defensive checks for input fields that are already validated by Home Assistant's service/action schemas and entity selection filters. Suggest additional guards only when data bypasses those validators or is transformed into a less-safe form.
When validation guarantees a dict key exists, prefer direct key access (`data["key"]`) instead of `.get("key")` so contract violations are surfaced instead of silently masked.
-3
View File
@@ -11,6 +11,3 @@ updates:
- github_actions
cooldown:
default-days: 7
ignore:
# Managed by gh aw compile. Version-locked to the gh-aw compiler; do not bump.
- dependency-name: "github/gh-aw-actions/**"
@@ -18,15 +18,11 @@ excludeAgent: "cloud-agent"
- For entity actions and entity services, avoid requesting redundant defensive checks for fields already enforced by Home Assistant validation schemas and entity filters; only request extra guards when values bypass validation or are transformed unsafely.
- When validation guarantees a key is present, prefer direct dictionary indexing (`data["key"]`) over `.get("key")` so invalid assumptions fail fast.
- Integrations should be thin wrappers. Protocol parsing, device state machines, or other domain logic belong in a separate PyPI library, not in the integration itself. If unsure, ask before inlining.
- Integrations should not implement fixes or workarounds for limitations in libraries. Instead, the library should be updated to fix the issue.
The following platforms have extra guidelines:
- **Diagnostics**: [`platform-diagnostics.md`](platform-diagnostics.md) for diagnostic data collection
- **Repairs**: [`platform-repairs.md`](platform-repairs.md) for user-actionable repair issues
## Entity platforms
- Ensure `async_added_to_hass()` and `async_will_remove_from_hass()` have symmetrical behavior. For example, if a subscription is created in `async_added_to_hass()`, it should be unsubscribed in `async_will_remove_from_hass()`. Also, if something is torn down in `async_will_remove_from_hass()`, it should be set up in `async_added_to_hass()`.
## Integration Quality Scale
+1 -29
View File
@@ -6,7 +6,6 @@
"pep621",
"pip_requirements",
"pre-commit",
"dockerfile",
"custom.regex",
"homeassistant-manifest"
],
@@ -22,10 +21,6 @@
]
},
"dockerfile": {
"managerFilePatterns": ["/^Dockerfile$/"]
},
"homeassistant-manifest": {
"managerFilePatterns": [
"/^homeassistant/components/[^/]+/manifest\\.json$/"
@@ -40,14 +35,6 @@
"matchStrings": ["required-version = \">=(?<currentValue>[\\d.]+)\""],
"depNameTemplate": "ruff",
"datasourceTemplate": "pypi"
},
{
"customType": "regex",
"description": "Update go2rtc RECOMMENDED_VERSION in const.py alongside the Dockerfile pin",
"managerFilePatterns": ["/^homeassistant/components/go2rtc/const\\.py$/"],
"matchStrings": ["RECOMMENDED_VERSION = \"(?<currentValue>[\\d.]+)\""],
"depNameTemplate": "ghcr.io/alexxit/go2rtc",
"datasourceTemplate": "docker"
}
],
@@ -128,7 +115,6 @@
"standard-aifc",
"standard-telnetlib",
"ulid-transform",
"unidiff",
"url-normalize",
"xmltodict"
],
@@ -142,8 +128,7 @@
"home-assistant-bluetooth",
"home-assistant-frontend",
"home-assistant-intents",
"infrared-protocols",
"rf-protocols"
"infrared-protocols"
],
"enabled": true,
"minimumReleaseAge": null,
@@ -198,13 +183,6 @@
"enabled": true,
"labels": ["dependency"]
},
{
"description": "Docker allowlist (ghcr.io exposes no release timestamps so the global cooldown needs to be bypassed)",
"matchPackageNames": ["ghcr.io/alexxit/go2rtc"],
"enabled": true,
"minimumReleaseAge": null,
"labels": ["dependency"]
},
{
"description": "Group ruff pre-commit hook with its PyPI twin into one PR",
"matchPackageNames": ["astral-sh/ruff-pre-commit", "ruff"],
@@ -234,12 +212,6 @@
"matchPackageNames": ["pylint", "astroid"],
"groupName": "pylint",
"groupSlug": "pylint"
},
{
"description": "Group go2rtc Dockerfile pin with const.py RECOMMENDED_VERSION into one PR",
"matchPackageNames": ["ghcr.io/alexxit/go2rtc"],
"groupName": "go2rtc",
"groupSlug": "go2rtc"
}
]
}
+5 -5
View File
@@ -14,7 +14,7 @@ env:
UV_HTTP_TIMEOUT: 60
UV_SYSTEM_PYTHON: "true"
# Base image version from https://github.com/home-assistant/docker
BASE_IMAGE_VERSION: "2026.05.0"
BASE_IMAGE_VERSION: "2026.01.0"
ARCHITECTURES: '["amd64", "aarch64"]'
permissions: {}
@@ -108,7 +108,7 @@ jobs:
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21
uses: dawidd6/action-download-artifact@8305c0f1062bb0d184d09ef4493ecb9288447732 # v20
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/frontend
@@ -119,7 +119,7 @@ jobs:
- name: Download nightly wheels of intents
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21
uses: dawidd6/action-download-artifact@8305c0f1062bb0d184d09ef4493ecb9288447732 # v20
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: OHF-Voice/intents-package
@@ -323,7 +323,7 @@ jobs:
exclude-list: '["odroid-xu","qemuarm","qemux86","raspberrypi","raspberrypi2","raspberrypi3","raspberrypi4","tinker"]'
publish_container:
name: Publish to ${{ matrix.registry }}
name: Publish meta container for ${{ matrix.registry }}
environment: ${{ needs.init.outputs.channel }}
if: github.repository_owner == 'home-assistant'
needs: ["init", "build_base"]
@@ -338,7 +338,7 @@ jobs:
registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"]
steps:
- name: Install Cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
with:
cosign-release: "v2.5.3"
@@ -1,74 +0,0 @@
name: Check requirements (deterministic)
# Stage 1 of the Check requirements pipeline.
#
# Runs the deterministic Python checks and uploads the structured
# results as an artifact. Stage 2 (the agentic workflow defined in
# `check-requirements.md`) consumes the artifact on completion.
# yamllint disable-line rule:truthy
on:
# Auto-trigger on PRs that touch tracked requirement files is disabled
# for now while we iterate — testing the workflow_run handoff to the
# agentic stage is hard with an auto-trigger. Re-enable once the chain
# has been validated end-to-end.
# pull_request:
# types: [opened, synchronize, reopened]
# paths:
# - "**/requirements*.txt"
# - "homeassistant/package_constraints.txt"
workflow_dispatch:
inputs:
pull_request_number:
description: "Pull request number to (re-)check"
required: true
type: number
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ inputs.pull_request_number || github.event.pull_request.number }}
cancel-in-progress: true
jobs:
deterministic:
name: Run deterministic requirement checks
runs-on: ubuntu-24.04
permissions:
contents: read
pull-requests: read # To fetch the PR diff via gh CLI
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
check-latest: true
- name: Install script dependencies
run: pip install -r script/check_requirements/requirements.txt
- name: Collect PR diff
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ inputs.pull_request_number || github.event.pull_request.number }}
run: |
mkdir -p deterministic
gh pr diff "${PR_NUMBER}" > deterministic/pr.diff
- name: Run deterministic checks
env:
PR_NUMBER: ${{ inputs.pull_request_number || github.event.pull_request.number }}
run: |
python -m script.check_requirements \
--pr-number "${PR_NUMBER}" \
--diff deterministic/pr.diff \
--output deterministic/results.json
- name: Upload deterministic-results artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: check-requirements-deterministic
path: deterministic/results.json
if-no-files-found: error
retention-days: 7
File diff suppressed because it is too large Load Diff
-253
View File
@@ -1,253 +0,0 @@
---
on:
workflow_run:
workflows: ["Check requirements (deterministic)"]
types: [completed]
permissions:
contents: read
actions: read
issues: read
pull-requests: read
network:
allowed:
- python
tools:
web-fetch: {}
github:
toolsets: [default, actions]
min-integrity: unapproved
safe-outputs:
add-comment:
max: 1
target: "${{ env.PR_NUMBER }}"
concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_sha }}
cancel-in-progress: true
steps:
- name: Download deterministic-results artifact
if: github.event.workflow_run.conclusion == 'success'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: check-requirements-deterministic
path: /tmp/gh-aw/deterministic
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Extract PR number from artifact
if: github.event.workflow_run.conclusion == 'success'
run: |
PR=$(python3 -c 'import json,sys;print(json.load(open("/tmp/gh-aw/deterministic/results.json"))["pr_number"])')
echo "PR_NUMBER=${PR}" >> "${GITHUB_ENV}"
post-steps:
- name: Verify agent produced an add_comment safe-output
if: always() && github.event.workflow_run.conclusion == 'success'
run: |
OUTPUT=/tmp/gh-aw/agent_output.json
if [ ! -f "${OUTPUT}" ]; then
echo "::error::Agent output file ${OUTPUT} is missing; the agent did not run to completion."
exit 1
fi
if ! grep -q '"add_comment"' "${OUTPUT}"; then
echo "::error::Agent did not emit an add_comment safe-output; no review comment was posted to the PR."
echo "Agent output:"
cat "${OUTPUT}"
exit 1
fi
description: >
Resolves the deterministic-stage artifact's NEEDS_AGENT checks for changed
Python package requirements on PRs targeting the core repo, then posts the
final review comment. Triggered by completion of the deterministic workflow.
Reads the uploaded artifact from disk, replaces placeholders for any check
whose status is `needs_agent`, and posts the merged comment using the PR
number recorded inside the artifact itself. Each check kind has a dedicated
instruction section below; if the artifact contains a check kind that does
not have a section here, the agent fails hard rather than guess.
---
# Check requirements (AW)
You are a code review assistant for the Home Assistant project. The
deterministic stage has already evaluated every check it can on its own
and produced an artifact containing the PR number, per-package check
results, and a pre-rendered comment with placeholders. **Your only job is
to read that artifact, resolve any `needs_agent` checks, and post the
final comment.**
## Step 1 — Read the deterministic-stage artifact
The deterministic stage uploaded its results to the runner at
`/tmp/gh-aw/deterministic/results.json`.
The JSON has this shape:
- `pr_number` — the PR being checked. The `add_comment` safe-output is
already targeted at this PR (the workflow extracted `pr_number` from
the artifact and wired it into the safe-output config), so **you do
not need to set `item_number` yourself** — just emit `add_comment`
with the rendered body.
- `needs_agent``true` iff any package's check needs resolution.
- `packages[]` — one entry per changed package. Each entry has:
- `name`, `old_version` (`null` for a newly added package; otherwise the
previous pin), `new_version`, `repo_url`, `publisher_kind`.
- `checks` — a dict keyed by **check kind** (string). Each value has a
`status` (`pass`, `warn`, `fail`, or `needs_agent`) and `details`.
- `rendered_comment` — the final PR comment body, already rendered. For
every check whose status is `needs_agent` it contains two placeholders
you must replace:
- `{{CHECK_CELL:<pkg-name>:<check-kind>}}` — one cell of the summary
table. Replace with exactly one of `✅`, `⚠️`, `❌`.
- `{{CHECK_DETAIL:<pkg-name>:<check-kind>}}` — the body of one bullet
in the package's `<details>` block. Replace with
`<icon> <one-line explanation>` (the bullet's leading
`- **<label>**:` is already rendered — replace only the placeholder).
You **must not** modify any other content in `rendered_comment`. Do not
re-evaluate checks that already have a deterministic status. Do not add
or remove packages.
## Step 2 — Resolve each `needs_agent` check
For each `package` in `packages`:
For each `(check_kind, result)` in `package.checks` where
`result.status == "needs_agent"`:
1. Look up `## Check kind: <check_kind>` in the **Check instructions**
section below.
2. **If no matching section exists**: emit a single `add_comment` whose
body is:
```
<!-- requirements-check -->
## Check requirements
❌ Internal error: the deterministic artifact contains a check kind
(`<check_kind>` on package `<pkg-name>`) that this workflow has no
instructions for. Update `.github/workflows/check-requirements.md`
to add a matching `## Check kind: <check_kind>` section, or remove
the kind from the deterministic stage.
```
Then stop. **Do not improvise** a verdict for an unknown check kind.
3. Otherwise, follow the instructions in that section. They tell you
which icon (✅/⚠️/❌) and one-line explanation to produce.
## Step 3 — Post the comment
1. Replace every `{{CHECK_CELL:…}}` and `{{CHECK_DETAIL:…}}` placeholder
in `rendered_comment` with the resolved value.
2. Emit the resulting markdown using `add_comment` — set `body` to the
merged `rendered_comment` verbatim (the leading
`<!-- requirements-check -->` marker must be preserved). The PR
target is already set by the workflow; do not pass `item_number`.
If the artifact's top-level `needs_agent` is `false` (no checks need
you), emit `rendered_comment` unchanged.
## Check instructions
### Check kind: `repo_public`
Verify that the package's source repository is publicly reachable.
1. Read `package.repo_url`.
2. Use the `web-fetch` tool to GET that URL.
3. Decide the verdict:
- HTTP 200, returns a public repository page → ✅
`<repo_url> is publicly accessible.`
- HTTP 4xx/5xx, or the response redirects to a login / sign-in page →
❌ `Source repository at <repo_url> is not publicly accessible.
Home Assistant requires all dependencies to have publicly available
source code.`
- Any other inconclusive result → ⚠️ with a one-line description.
If `repo_public` resolves to ❌ for a package, **also** mark that
package's `release_pipeline` cell/detail as `` (em dash) and explain
`Skipped because the source repository is not publicly accessible.` —
because the release pipeline cannot be inspected without a public repo.
### Check kind: `pr_link`
Verify the PR description contains the right link for the change.
1. Fetch the PR body via the GitHub MCP tool, using the `pr_number`
field from the artifact.
2. Extract all URLs from the body.
3. For a **new package** (`package.old_version` is `null`):
- The PR body must contain a URL that points at `package.repo_url`
(any sub-path of the same `owner/repo` on the same host is
acceptable). A PyPI link is **not** sufficient.
- ✅ if such a URL is present.
- ❌ otherwise:
`PR description must link to the source repository at <repo_url>.
A PyPI page link is not sufficient.`
4. For a **version bump** (`package.old_version` is not `null`):
- The PR body must contain a URL on the same host as
`package.repo_url` that references **both** `package.old_version`
and `package.new_version` (e.g. a GitHub compare URL
`compare/vX...vY`, a release / changelog URL containing both
versions, etc.).
- ✅ if such a URL is present and the versions match the actual bump.
- ❌ otherwise:
`PR description should link to a changelog or compare URL on
<repo_url> that mentions both <old_version> and <new_version>.`
### Check kind: `release_pipeline`
Inspect the upstream project's release / publish CI pipeline.
For each package needing inspection, determine the source repository
host from `package.repo_url`, then apply the corresponding checklist.
#### GitHub repositories (`github.com`)
1. List workflows: `GET /repos/{owner}/{repo}/actions/workflows`.
2. Identify any workflow whose name or filename suggests publishing to
PyPI (`release`, `publish`, `pypi`, or `deploy`).
3. Fetch the workflow file and check:
- **Trigger sanity**: triggered by `push` to tags,
`release: published`, or `workflow_run` on a release job —
**not** solely `workflow_dispatch` with no environment-protection
guard.
- **OIDC / Trusted Publisher**: look for `id-token: write` and one of
`pypa/gh-action-pypi-publish`, `actions/attest-build-provenance`,
or `TWINE_PASSWORD` from a static `secrets.PYPI_TOKEN`.
- **No manual upload bypass**: no ungated `twine upload` or
`pip upload`.
4. Verdict:
- ✅ if OIDC + sane triggers + no bypass.
- ⚠️ if static token but version bump, or details unclear.
- ❌ if static token on a new package, or only-manual triggers with
no environment protection.
#### GitLab repositories (`gitlab.com` or self-hosted GitLab)
1. Resolve the project ID via
`GET https://gitlab.com/api/v4/projects/{url-encoded-namespace-and-name}`.
2. Fetch `.gitlab-ci.yml` via
`GET https://gitlab.com/api/v4/projects/{id}/repository/files/.gitlab-ci.yml/raw?ref=HEAD`.
3. Apply the same conceptual checks: tag-only / protected-branch
triggers, GitLab OIDC `id_tokens` or CI/CD protected `PYPI_TOKEN`, no
ungated `twine upload`. Same verdict rules as GitHub.
#### Other code hosting providers (Bitbucket, Codeberg, Gitea, Sourcehut, …)
1. Use `web-fetch` to retrieve any visible CI configuration
(`.circleci/config.yml`, `Jenkinsfile`, `azure-pipelines.yml`,
`bitbucket-pipelines.yml`, `.builds/*.yml`).
2. Apply the conceptual checks: automated triggers, CI-injected
credentials, no manual `twine upload`.
3. If no CI config can be retrieved: ⚠️ `Release pipeline could not be
inspected; hosting provider is not GitHub or GitLab.`
## Notes
- Be constructive and helpful. Reference the inspected workflow / CI
file by URL where useful so the contributor can fix the issue.
- The dedup of the requirements-check comment is handled by gh-aw's
`add_comment` safe-output via the `<!-- requirements-check -->`
marker on the first line of `rendered_comment`.
- If the deterministic workflow concluded with a non-success status,
this workflow's `if:` guard on `Download deterministic-results
artifact` skipped the download. If you find no file at
`/tmp/gh-aw/deterministic/results.json`, emit nothing — the post-step
verification is also gated and will not complain.
+35 -34
View File
@@ -38,8 +38,9 @@ on:
env:
CACHE_VERSION: 3
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 1
HA_SHORT_VERSION: "2026.6"
HA_SHORT_VERSION: "2026.5"
ADDITIONAL_PYTHON_VERSIONS: "[]"
# 10.3 is the oldest supported version
# - 10.3.32 is the version currently shipped with Synology (as of 17 Feb 2022)
@@ -281,7 +282,7 @@ jobs:
echo "::add-matcher::.github/workflows/matchers/check-executables-have-shebangs.json"
echo "::add-matcher::.github/workflows/matchers/codespell.json"
- name: Run prek
uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2.0.3
uses: j178/prek-action@cbc2f23eb5539cf20d82d1aabd0d0ecbcc56f4e3 # v2.0.2
env:
PREK_SKIP: no-commit-to-branch,mypy,pylint,gen_requirements_all,hassfest,hassfest-metadata,hassfest-mypy-config,zizmor
RUFF_OUTPUT_FORMAT: github
@@ -302,7 +303,7 @@ jobs:
with:
persist-credentials: false
- name: Run zizmor
uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2.0.3
uses: j178/prek-action@cbc2f23eb5539cf20d82d1aabd0d0ecbcc56f4e3 # v2.0.2
with:
extra-args: --all-files zizmor
@@ -357,6 +358,12 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Generate partial uv restore key
id: generate-uv-key
run: |
uv_version=$(cat requirements.txt | grep uv | cut -d '=' -f 3)
echo "version=${uv_version}" >> $GITHUB_OUTPUT
echo "key=uv-${UV_CACHE_VERSION}-${uv_version}-${HA_SHORT_VERSION}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
@@ -365,25 +372,19 @@ jobs:
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Generate partial uv restore key
if: steps.cache-venv.outputs.cache-hit != 'true'
id: generate-uv-key
env:
RUNNER_OS: ${{ runner.os }}
RUNNER_ARCH: ${{ runner.arch }}
PYTHON_VERSION: ${{ steps.python.outputs.python-version }}
HASH_FILES: ${{ hashFiles('requirements.txt', 'requirements_all.txt', 'requirements_test.txt', 'homeassistant/package_constraints.txt') }}
run: |
partial_key="${RUNNER_OS}-${RUNNER_ARCH}-${PYTHON_VERSION}-uv-"
echo "partial_key=${partial_key}" >> $GITHUB_OUTPUT
echo "full_key=${partial_key}${HASH_FILES}" >> $GITHUB_OUTPUT
- name: Restore uv wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
id: cache-uv
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ${{ env.UV_CACHE_DIR }}
key: ${{ steps.generate-uv-key.outputs.full_key }}
restore-keys: ${{ steps.generate-uv-key.outputs.partial_key }}
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-uv-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-uv-${{
env.UV_CACHE_VERSION }}-${{ steps.generate-uv-key.outputs.version }}-${{
env.HA_SHORT_VERSION }}-
- name: Check if apt cache exists
id: cache-apt-check
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
@@ -453,7 +454,8 @@ jobs:
pip install "$(grep '^uv' < requirements.txt)"
uv pip install -U "pip>=25.2"
uv pip install -r requirements.txt
uv pip install -r requirements_all.txt -r requirements_test.txt
python -m script.gen_requirements_all ci
uv pip install -r requirements_all_pytest.txt -r requirements_test.txt
uv pip install -e . --config-settings editable_mode=compat
- name: Dump pip freeze
run: |
@@ -469,21 +471,24 @@ jobs:
overwrite: true
- name: Remove pip_freeze
run: rm pip_freeze.txt
- name: Remove generated requirements_all
if: steps.cache-venv.outputs.cache-hit != 'true'
run: rm requirements_all_pytest.txt requirements_all_wheels_*.txt
- name: Check dirty
run: |
./script/check_dirty
- name: Prune uv cache
if: steps.cache-venv.outputs.cache-hit != 'true'
id: prune-uv-cache
run: |
. venv/bin/activate
uv cache prune --ci
- name: Save uv wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
if: |
(success() && steps.cache-venv.outputs.cache-hit != 'true')
|| (always()
&& steps.create-venv.outcome == 'success'
&& steps.cache-uv.outputs.cache-matched-key == '')
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ${{ env.UV_CACHE_DIR }}
key: ${{ steps.generate-uv-key.outputs.full_key }}
key: >-
${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-uv-key.outputs.key }}
- name: Save base Python virtual environment
if: always() && steps.create-venv.outcome == 'success'
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
@@ -632,7 +637,7 @@ jobs:
with:
persist-credentials: false
- name: Dependency review
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
with:
license-check: false # We use our own license audit checks
@@ -853,7 +858,7 @@ jobs:
run: |
. venv/bin/activate
python --version
mypy --num-workers=4 homeassistant pylint
mypy homeassistant pylint
- name: Run mypy (partially)
if: needs.info.outputs.test_full_suite == 'false'
shell: bash
@@ -862,7 +867,7 @@ jobs:
run: |
. venv/bin/activate
python --version
mypy --num-workers=4 $(printf "homeassistant/components/%s " ${INTEGRATIONS_GLOB})
mypy $(printf "homeassistant/components/%s " ${INTEGRATIONS_GLOB})
prepare-pytest-full:
name: Split tests for full run
@@ -1088,7 +1093,6 @@ jobs:
options: >-
--health-cmd="if command -v mariadb-admin >/dev/null; then mariadb-admin ping -uroot -ppassword; else mysqladmin ping -uroot -ppassword; fi"
--health-interval=5s --health-timeout=2s --health-retries=3
--tmpfs /var/lib/mysql:size=2g,mode=0750
needs:
- info
- base
@@ -1246,10 +1250,7 @@ jobs:
- 5432:5432
env:
POSTGRES_PASSWORD: password
options: >-
--health-cmd="pg_isready -hlocalhost -Upostgres"
--health-interval=5s --health-timeout=2s --health-retries=3
--tmpfs /var/lib/postgresql/data:size=2g,mode=0700
options: --health-cmd="pg_isready -hlocalhost -Upostgres" --health-interval=5s --health-timeout=2s --health-retries=3
needs:
- info
- base
+2 -2
View File
@@ -28,11 +28,11 @@ jobs:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
with:
category: "/language:python"
@@ -236,7 +236,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@17ff458cb182449bbb2e43701fcd98f6af8f6570 # v2.1.0
uses: actions/ai-inference@e09e65981758de8b2fdab13c2bfb7c7d5493b0b6 # v2.0.7
with:
model: openai/gpt-4o
system-prompt: |
@@ -62,7 +62,7 @@ jobs:
- name: Detect language using AI
id: ai_language_detection
if: steps.detect_language.outputs.should_continue == 'true'
uses: actions/ai-inference@17ff458cb182449bbb2e43701fcd98f6af8f6570 # v2.1.0
uses: actions/ai-inference@e09e65981758de8b2fdab13c2bfb7c7d5493b0b6 # v2.0.7
with:
model: openai/gpt-4o-mini
system-prompt: |
+1 -3
View File
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.13
rev: v0.15.12
hooks:
- id: ruff-check
args:
@@ -23,7 +23,6 @@ repos:
- id: zizmor
args:
- --pedantic
exclude: ^\.github/workflows/.*\.lock\.yml$
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
@@ -47,7 +46,6 @@ repos:
additional_dependencies:
- prettier@3.6.2
- prettier-plugin-sort-json@4.2.0
exclude: ^\.github/workflows/.*\.lock\.yml$
- repo: https://github.com/cdce8p/python-typing-update
rev: v0.6.0
hooks:
+1 -1
View File
@@ -1 +1 @@
3.14.5
3.14.2
-9
View File
@@ -139,7 +139,6 @@ homeassistant.components.cambridge_audio.*
homeassistant.components.camera.*
homeassistant.components.canary.*
homeassistant.components.casper_glow.*
homeassistant.components.centriconnect.*
homeassistant.components.cert_expiry.*
homeassistant.components.clickatell.*
homeassistant.components.clicksend.*
@@ -156,7 +155,6 @@ homeassistant.components.counter.*
homeassistant.components.cover.*
homeassistant.components.cpuspeed.*
homeassistant.components.crownstone.*
homeassistant.components.data_grand_lyon.*
homeassistant.components.date.*
homeassistant.components.datetime.*
homeassistant.components.deako.*
@@ -250,7 +248,6 @@ homeassistant.components.gpsd.*
homeassistant.components.greeneye_monitor.*
homeassistant.components.group.*
homeassistant.components.guardian.*
homeassistant.components.guntamatic.*
homeassistant.components.habitica.*
homeassistant.components.hardkernel.*
homeassistant.components.hardware.*
@@ -298,7 +295,6 @@ homeassistant.components.imap.*
homeassistant.components.imgw_pib.*
homeassistant.components.immich.*
homeassistant.components.incomfort.*
homeassistant.components.indevolt.*
homeassistant.components.inels.*
homeassistant.components.infrared.*
homeassistant.components.input_button.*
@@ -358,7 +354,6 @@ homeassistant.components.lunatone.*
homeassistant.components.lutron.*
homeassistant.components.madvr.*
homeassistant.components.manual.*
homeassistant.components.marantz_infrared.*
homeassistant.components.mastodon.*
homeassistant.components.matrix.*
homeassistant.components.matter.*
@@ -425,11 +420,9 @@ homeassistant.components.opower.*
homeassistant.components.oralb.*
homeassistant.components.otbr.*
homeassistant.components.otp.*
homeassistant.components.ouman_eh_800.*
homeassistant.components.overkiz.*
homeassistant.components.overseerr.*
homeassistant.components.p1_monitor.*
homeassistant.components.paj_gps.*
homeassistant.components.panel_custom.*
homeassistant.components.paperless_ngx.*
homeassistant.components.peblar.*
@@ -449,7 +442,6 @@ homeassistant.components.private_ble_device.*
homeassistant.components.prometheus.*
homeassistant.components.proximity.*
homeassistant.components.prusalink.*
homeassistant.components.ptdevices.*
homeassistant.components.pure_energie.*
homeassistant.components.purpleair.*
homeassistant.components.pushbullet.*
@@ -492,7 +484,6 @@ homeassistant.components.rss_feed_template.*
homeassistant.components.russound_rio.*
homeassistant.components.ruuvi_gateway.*
homeassistant.components.ruuvitag_ble.*
homeassistant.components.samsung_infrared.*
homeassistant.components.samsungtv.*
homeassistant.components.saunum.*
homeassistant.components.scene.*
-1
View File
@@ -1,6 +1,5 @@
ignore: |
tests/fixtures/core/config/yaml_errors/
.github/workflows/*.lock.yml
rules:
braces:
level: error
+8 -22
View File
@@ -6,36 +6,22 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
- **Do NOT amend, squash, or rebase commits that have already been pushed to the PR branch after the PR is opened** - Reviewers need to follow the commit history, as well as see what changed since their last review
## Pull Requests
- When opening a pull request, use the repository's PR template (`.github/PULL_REQUEST_TEMPLATE.md`). NEVER REMOVE ANYTHING from the template.
- Do not remove checkboxes that are not checked — leave all unchecked checkboxes in place so reviewers can see which options were not selected.
## Development Commands
- When entering a new environment or worktree, run `script/setup` to set up the virtual environment with all development dependencies (pylint, pre-commit hooks, etc.). This is required before committing.
- .vscode/tasks.json contains useful commands used for development.
.vscode/tasks.json contains useful commands used for development.
## Python Syntax Notes
- Home Assistant officially supports Python 3.14 as its minimum version. Do not flag syntax or features that require Python 3.14 as issues, and do not suggest workarounds for older Python versions.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue.
- Python 3.14 evaluates annotations lazily (PEP 649). Forward references in annotations do not need to be quoted — annotations can reference names defined later in the module without quoting them or using `from __future__ import annotations`. Do not flag unquoted forward references in annotations as issues.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue since Home Assistant officially supports Python 3.14.
## Testing
- Use `uv run pytest` to run tests
- After modifying `strings.json` for an integration, regenerate the English translation file before running tests: `.venv/bin/python3 -m script.translations develop --integration <integration_name>`. Tests load translations from the generated `translations/en.json`, not directly from `strings.json`.
- When writing or modifying tests, ensure all test function parameters have type annotations.
- Prefer concrete types (for example, `HomeAssistant`, `MockConfigEntry`, etc.) over `Any`.
- Prefer `@pytest.mark.usefixtures` over arguments, if the argument is not going to be used.
- Avoid using conditions/branching in tests. Instead, either split tests or adjust the test parametrization to cover all cases without branching.
- If multiple tests share most of their code, use `pytest.mark.parametrize` to merge them into a single parameterized test instead of duplicating the body. Use `pytest.param` with an `id` parameter to name the test cases clearly.
- We use Syrupy for snapshot testing. Leverage `.ambr` snapshots instead of repetitive and exhaustive generation of test data within Python code itself.
When writing or modifying tests, ensure all test function parameters have type annotations.
Prefer concrete types (for example, `HomeAssistant`, `MockConfigEntry`, etc.) over `Any`.
## Good practices
- Integrations with Platinum or Gold level in the Integration Quality Scale reflect a high standard of code quality and maintainability. When looking for examples of something, these are good places to start. The level is indicated in the manifest.json of the integration.
- When reviewing entity actions, do not suggest extra defensive checks for input fields that are already validated by Home Assistant's service/action schemas and entity selection filters. Suggest additional guards only when data bypasses those validators or is transformed into a less-safe form.
- When validation guarantees a dict key exists, prefer direct key access (`data["key"]`) instead of `.get("key")` so contract violations are surfaced instead of silently masked.
- Do not add comments that just restate the code on the following line(s) (e.g. `# Check if initialized` above `if self.initialized:`). Comments should only explain why — non-obvious constraints, surprising behavior, or workarounds — never what.
Integrations with Platinum or Gold level in the Integration Quality Scale reflect a high standard of code quality and maintainability. When looking for examples of something, these are good places to start. The level is indicated in the manifest.json of the integration.
When reviewing entity actions, do not suggest extra defensive checks for input fields that are already validated by Home Assistant's service/action schemas and entity selection filters. Suggest additional guards only when data bypasses those validators or is transformed into a less-safe form.
When validation guarantees a dict key exists, prefer direct key access (`data["key"]`) instead of `.get("key")` so contract violations are surfaced instead of silently masked.
Generated
+6 -31
View File
@@ -68,8 +68,6 @@ CLAUDE.md @home-assistant/core
/tests/components/agent_dvr/ @ispysoftware
/homeassistant/components/ai_task/ @home-assistant/core
/tests/components/ai_task/ @home-assistant/core
/homeassistant/components/aidot/ @s1eedz @HongBryan
/tests/components/aidot/ @s1eedz @HongBryan
/homeassistant/components/air_quality/ @home-assistant/core
/tests/components/air_quality/ @home-assistant/core
/homeassistant/components/airgradient/ @airgradienthq @joostlek
@@ -198,7 +196,6 @@ CLAUDE.md @home-assistant/core
/homeassistant/components/autoskope/ @mcisk
/tests/components/autoskope/ @mcisk
/homeassistant/components/avea/ @pattyland
/tests/components/avea/ @pattyland
/homeassistant/components/awair/ @ahayworth @ricohageman
/tests/components/awair/ @ahayworth @ricohageman
/homeassistant/components/aws_s3/ @tomasbedrich
@@ -291,16 +288,12 @@ CLAUDE.md @home-assistant/core
/tests/components/cast/ @emontnemery
/homeassistant/components/ccm15/ @ocalvo
/tests/components/ccm15/ @ocalvo
/homeassistant/components/centriconnect/ @gresrun
/tests/components/centriconnect/ @gresrun
/homeassistant/components/cert_expiry/ @jjlawren
/tests/components/cert_expiry/ @jjlawren
/homeassistant/components/chacon_dio/ @cnico
/tests/components/chacon_dio/ @cnico
/homeassistant/components/chess_com/ @joostlek
/tests/components/chess_com/ @joostlek
/homeassistant/components/cielo_home/ @ihsan-cielo @mudasar-cielo
/tests/components/cielo_home/ @ihsan-cielo @mudasar-cielo
/homeassistant/components/cisco_ios/ @fbradyirl
/homeassistant/components/cisco_mobility_express/ @fbradyirl
/homeassistant/components/cisco_webex_teams/ @fbradyirl
@@ -352,8 +345,6 @@ CLAUDE.md @home-assistant/core
/tests/components/cync/ @Kinachi249
/homeassistant/components/daikin/ @fredrike
/tests/components/daikin/ @fredrike
/homeassistant/components/data_grand_lyon/ @Crocmagnon
/tests/components/data_grand_lyon/ @Crocmagnon
/homeassistant/components/date/ @home-assistant/core
/tests/components/date/ @home-assistant/core
/homeassistant/components/datetime/ @home-assistant/core
@@ -697,8 +688,6 @@ CLAUDE.md @home-assistant/core
/tests/components/growatt_server/ @johanzander
/homeassistant/components/guardian/ @bachya
/tests/components/guardian/ @bachya
/homeassistant/components/guntamatic/ @JensTimmerman
/tests/components/guntamatic/ @JensTimmerman
/homeassistant/components/habitica/ @tr4nt0r
/tests/components/habitica/ @tr4nt0r
/homeassistant/components/hanna/ @bestycame
@@ -983,8 +972,8 @@ CLAUDE.md @home-assistant/core
/tests/components/lektrico/ @lektrico
/homeassistant/components/letpot/ @jpelgrom
/tests/components/letpot/ @jpelgrom
/homeassistant/components/lg_infrared/ @abmantis
/tests/components/lg_infrared/ @abmantis
/homeassistant/components/lg_infrared/ @home-assistant/core
/tests/components/lg_infrared/ @home-assistant/core
/homeassistant/components/lg_netcast/ @Drafteed @splinter98
/tests/components/lg_netcast/ @Drafteed @splinter98
/homeassistant/components/lg_thinq/ @LG-ThinQ-Integration
@@ -1047,8 +1036,6 @@ CLAUDE.md @home-assistant/core
/tests/components/lyric/ @timmo001
/homeassistant/components/madvr/ @iloveicedgreentea
/tests/components/madvr/ @iloveicedgreentea
/homeassistant/components/marantz_infrared/ @balloob
/tests/components/marantz_infrared/ @balloob
/homeassistant/components/mastodon/ @fabaff @andrew-codechimp
/tests/components/mastodon/ @fabaff @andrew-codechimp
/homeassistant/components/matrix/ @PaarthShah
@@ -1105,8 +1092,6 @@ CLAUDE.md @home-assistant/core
/tests/components/minecraft_server/ @elmurato @zachdeibert
/homeassistant/components/minio/ @tkislan
/tests/components/minio/ @tkislan
/homeassistant/components/mitsubishi_comfort/ @nikolairahimi
/tests/components/mitsubishi_comfort/ @nikolairahimi
/homeassistant/components/moat/ @bdraco
/tests/components/moat/ @bdraco
/homeassistant/components/mobile_app/ @home-assistant/core
@@ -1311,8 +1296,6 @@ CLAUDE.md @home-assistant/core
/tests/components/osoenergy/ @osohotwateriot
/homeassistant/components/otbr/ @home-assistant/core
/tests/components/otbr/ @home-assistant/core
/homeassistant/components/ouman_eh_800/ @Markus98
/tests/components/ouman_eh_800/ @Markus98
/homeassistant/components/ourgroceries/ @OnFreund
/tests/components/ourgroceries/ @OnFreund
/homeassistant/components/overkiz/ @imicknl
@@ -1323,8 +1306,6 @@ CLAUDE.md @home-assistant/core
/tests/components/ovo_energy/ @timmo001
/homeassistant/components/p1_monitor/ @klaasnicolaas
/tests/components/p1_monitor/ @klaasnicolaas
/homeassistant/components/paj_gps/ @skipperro
/tests/components/paj_gps/ @skipperro
/homeassistant/components/palazzetti/ @dotvav
/tests/components/palazzetti/ @dotvav
/homeassistant/components/panel_custom/ @home-assistant/frontend
@@ -1397,8 +1378,6 @@ CLAUDE.md @home-assistant/core
/tests/components/proxmoxve/ @Corbeno @erwindouna @CoMPaTech
/homeassistant/components/ps4/ @ktnrg45
/tests/components/ps4/ @ktnrg45
/homeassistant/components/ptdevices/ @ParemTech-Inc @frogman85978
/tests/components/ptdevices/ @ParemTech-Inc @frogman85978
/homeassistant/components/pterodactyl/ @elmurato
/tests/components/pterodactyl/ @elmurato
/homeassistant/components/pure_energie/ @klaasnicolaas
@@ -1512,8 +1491,8 @@ CLAUDE.md @home-assistant/core
/tests/components/roku/ @ctalkington
/homeassistant/components/romy/ @xeniter
/tests/components/romy/ @xeniter
/homeassistant/components/roomba/ @pschmitt @cyr-ius @shenxn
/tests/components/roomba/ @pschmitt @cyr-ius @shenxn
/homeassistant/components/roomba/ @pschmitt @cyr-ius @shenxn @Orhideous
/tests/components/roomba/ @pschmitt @cyr-ius @shenxn @Orhideous
/homeassistant/components/roon/ @pavoni
/tests/components/roon/ @pavoni
/homeassistant/components/route_b_smart_meter/ @SeraphicRav
@@ -1536,8 +1515,6 @@ CLAUDE.md @home-assistant/core
/homeassistant/components/sabnzbd/ @shaiu @jpbede
/tests/components/sabnzbd/ @shaiu @jpbede
/homeassistant/components/saj/ @fredericvl
/homeassistant/components/samsung_infrared/ @lmaertin
/tests/components/samsung_infrared/ @lmaertin
/homeassistant/components/samsungtv/ @chemelli74 @epenet
/tests/components/samsungtv/ @chemelli74 @epenet
/homeassistant/components/sanix/ @tomaszsluszniak
@@ -2036,8 +2013,6 @@ CLAUDE.md @home-assistant/core
/tests/components/xiaomi_miio/ @rytilahti @syssi @starkillerOG
/homeassistant/components/xiaomi_tv/ @simse
/homeassistant/components/xmpp/ @fabaff @flowolf
/homeassistant/components/xthings_cloud/ @XthingsJacobs
/tests/components/xthings_cloud/ @XthingsJacobs
/homeassistant/components/yale/ @bdraco
/tests/components/yale/ @bdraco
/homeassistant/components/yale_smart_alarm/ @gjohansson-ST
@@ -2068,8 +2043,8 @@ CLAUDE.md @home-assistant/core
/tests/components/zeroconf/ @bdraco
/homeassistant/components/zerproc/ @emlove
/tests/components/zerproc/ @emlove
/homeassistant/components/zeversolar/ @kvanzuijlen @mhuiskes
/tests/components/zeversolar/ @kvanzuijlen @mhuiskes
/homeassistant/components/zeversolar/ @kvanzuijlen
/tests/components/zeversolar/ @kvanzuijlen
/homeassistant/components/zha/ @dmulcahey @adminiuga @puddly @TheJulianJES
/tests/components/zha/ @dmulcahey @adminiuga @puddly @TheJulianJES
/homeassistant/components/zimi/ @markhannon
Generated
+2 -2
View File
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile@sha256:2780b5c3bab67f1f76c781860de469442999ed1a0d7992a5efdf2cffc0e3d769
# Partly generated by hassfest.
# Automatically generated by hassfest.
#
# To update, run python3 -m script.hassfest -p docker
ARG BUILD_FROM
@@ -26,7 +26,7 @@ WORKDIR /usr/src
COPY rootfs /
# Add go2rtc binary
COPY --from=ghcr.io/alexxit/go2rtc:1.9.14@sha256:675c318b23c06fd862a61d262240c9a63436b4050d177ffc68a32710d9e05bae /usr/local/bin/go2rtc /bin/go2rtc
COPY --from=ghcr.io/alexxit/go2rtc@sha256:675c318b23c06fd862a61d262240c9a63436b4050d177ffc68a32710d9e05bae /usr/local/bin/go2rtc /bin/go2rtc
## Setup Home Assistant Core dependencies
COPY --parents requirements.txt homeassistant/package_constraints.txt homeassistant/
+2
View File
@@ -1,5 +1,7 @@
"""Start Home Assistant."""
from __future__ import annotations
import argparse
from contextlib import suppress
import faulthandler
+6 -6
View File
@@ -1,5 +1,7 @@
"""Provide an authentication layer for Home Assistant."""
from __future__ import annotations
import asyncio
from collections import OrderedDict
from collections.abc import Mapping
@@ -73,12 +75,10 @@ async def auth_manager_from_config(
provider_hash[key] = provider
if isinstance(provider, HassAuthProvider):
# Can be removed in 2026.7 with the legacy mode of
# homeassistant auth provider.
# We need to initialize the provider to create the repair
# if needed as otherwise the provider will be initialized
# on first use, which could be rare as users don't
# frequently change auth settings
# Can be removed in 2026.7 with the legacy mode of homeassistant auth provider
# We need to initialize the provider to create the repair if needed as otherwise
# the provider will be initialized on first use, which could be rare as users
# don't frequently change auth settings
await provider.async_initialize()
if module_configs:
+2
View File
@@ -1,5 +1,7 @@
"""Storage for auth models."""
from __future__ import annotations
from datetime import timedelta
import hmac
import itertools
+2
View File
@@ -5,6 +5,8 @@ we can cache the result of the decode of valid tokens
to speed up the process.
"""
from __future__ import annotations
from collections.abc import Container, Iterable, Sequence
from datetime import timedelta
from functools import lru_cache
@@ -1,5 +1,7 @@
"""Pluggable auth modules for Home Assistant."""
from __future__ import annotations
import logging
import types
from typing import Any
@@ -1,5 +1,7 @@
"""Example auth module."""
from __future__ import annotations
from typing import Any
import voluptuous as vol
+2
View File
@@ -3,6 +3,8 @@
Sending HOTP through notify service
"""
from __future__ import annotations
import asyncio
import logging
from typing import Any, cast
+2
View File
@@ -1,5 +1,7 @@
"""Time-based One Time Password auth module."""
from __future__ import annotations
import asyncio
from io import BytesIO
from typing import Any, cast
+2
View File
@@ -1,5 +1,7 @@
"""Auth models."""
from __future__ import annotations
from datetime import datetime, timedelta
from ipaddress import IPv4Address, IPv6Address
import secrets
@@ -1,5 +1,7 @@
"""Permissions for Home Assistant."""
from __future__ import annotations
from collections.abc import Callable, Iterable
from typing import TYPE_CHECKING
@@ -1,5 +1,7 @@
"""Entity permissions."""
from __future__ import annotations
from collections import OrderedDict
from collections.abc import Callable
+2
View File
@@ -1,5 +1,7 @@
"""Permission for events."""
from __future__ import annotations
from typing import Any, Final
from homeassistant.const import (
+2
View File
@@ -1,5 +1,7 @@
"""Merging of policies."""
from __future__ import annotations
from typing import cast
from .types import CategoryType, PolicyType
+2
View File
@@ -1,5 +1,7 @@
"""Models for permissions."""
from __future__ import annotations
from typing import TYPE_CHECKING
import attr
+2
View File
@@ -1,5 +1,7 @@
"""Helpers to deal with permissions."""
from __future__ import annotations
from collections.abc import Callable
from functools import wraps
from typing import cast
+2
View File
@@ -1,5 +1,7 @@
"""Auth providers for Home Assistant."""
from __future__ import annotations
from collections.abc import Mapping
import logging
import types
@@ -1,5 +1,7 @@
"""Auth provider that validates credentials via an external command."""
from __future__ import annotations
import asyncio
from collections.abc import Mapping
import logging
@@ -1,5 +1,7 @@
"""Home Assistant auth provider."""
from __future__ import annotations
import asyncio
import base64
from collections.abc import Mapping
@@ -120,10 +122,9 @@ class Data:
if self.normalize_username(username, force_normalize=True) != username:
logging.getLogger(__name__).warning(
(
"Home Assistant auth provider is running in"
" legacy mode because we detected usernames"
" that are normalized (lowercase and without"
" spaces). Please change the username: '%s'."
"Home Assistant auth provider is running in legacy mode "
"because we detected usernames that are normalized (lowercase and without spaces)."
" Please change the username: '%s'."
),
username,
)
@@ -140,9 +141,7 @@ class Data:
severity=ir.IssueSeverity.WARNING,
translation_key="homeassistant_provider_not_normalized_usernames",
translation_placeholders={
"usernames": (
f'- "{'"\n- "'.join(sorted(not_normalized_usernames))}"'
)
"usernames": f'- "{'"\n- "'.join(sorted(not_normalized_usernames))}"'
},
learn_more_url="homeassistant://config/users",
)
@@ -1,5 +1,7 @@
"""Example auth provider."""
from __future__ import annotations
from collections.abc import Mapping
import hmac
@@ -4,6 +4,8 @@ It shows list of users if access from trusted network.
Abort login flow if not access from trusted network.
"""
from __future__ import annotations
from collections.abc import Mapping
from ipaddress import (
IPv4Address,
+4 -6
View File
@@ -1,5 +1,7 @@
"""Home Assistant module to handle restoring backups."""
from __future__ import annotations
from collections.abc import Iterable
from dataclasses import dataclass
import json
@@ -60,10 +62,7 @@ def restore_backup_file_content(config_dir: Path) -> RestoreBackupFileContent |
def _clear_configuration_directory(config_dir: Path, keep: Iterable[str]) -> None:
"""Delete all files and directories in the config dir.
Entries in the keep list are preserved.
"""
"""Delete all files and directories in the config directory except entries in the keep list."""
keep_paths = [config_dir.joinpath(path) for path in keep]
entries_to_remove = sorted(
entry for entry in config_dir.iterdir() if entry not in keep_paths
@@ -104,8 +103,7 @@ def _extract_backup(
)
) > HA_VERSION:
raise ValueError(
f"You need at least Home Assistant version"
f" {backup_meta_version} to restore this backup"
f"You need at least Home Assistant version {backup_meta_version} to restore this backup"
)
with securetar.SecureTarFile(
+7 -10
View File
@@ -1,5 +1,7 @@
"""Provide methods to bootstrap a Home Assistant instance."""
from __future__ import annotations
import asyncio
from collections import defaultdict
import contextlib
@@ -17,8 +19,7 @@ from time import monotonic
from typing import TYPE_CHECKING, Any
# Import cryptography early since import openssl is not thread-safe
# _frozen_importlib._DeadlockError: deadlock detected by
# _ModuleLock('cryptography.hazmat.backends.openssl.backend')
# _frozen_importlib._DeadlockError: deadlock detected by _ModuleLock('cryptography.hazmat.backends.openssl.backend')
import cryptography.hazmat.backends.openssl.backend # noqa: F401
import voluptuous as vol
import yarl
@@ -166,14 +167,10 @@ FRONTEND_INTEGRATIONS = {
# visible in frontend
"frontend",
}
# Stage 0 is divided into substages. Each substage has a name,
# a set of integrations and a timeout.
# The substage containing recorder should have no timeout, as it
# could cancel a database migration.
# Recorder freezes "recorder" timeout during a migration, but it
# does not freeze other timeouts.
# If we add timeouts to the frontend substages, we should make sure
# they don't apply in recovery mode.
# Stage 0 is divided into substages. Each substage has a name, a set of integrations and a timeout.
# The substage containing recorder should have no timeout, as it could cancel a database migration.
# Recorder freezes "recorder" timeout during a migration, but it does not freeze other timeouts.
# If we add timeouts to the frontend substages, we should make sure they don't apply in recovery mode.
STAGE_0_INTEGRATIONS = (
# Load logging and http deps as soon as possible
("logging, http deps", LOGGING_AND_HTTP_DEPS_INTEGRATIONS, None),
-5
View File
@@ -1,5 +0,0 @@
{
"domain": "marantz",
"name": "Marantz",
"integrations": ["marantz", "marantz_infrared"]
}
-5
View File
@@ -1,5 +0,0 @@
{
"domain": "mitsubishi",
"name": "Mitsubishi",
"integrations": ["melcloud", "mitsubishi_comfort"]
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
"domain": "samsung",
"name": "Samsung",
"integrations": ["familyhub", "samsung_infrared", "samsungtv", "syncthru"]
"integrations": ["familyhub", "samsungtv", "syncthru"]
}
@@ -1,5 +1,7 @@
"""Support for the Abode Security System."""
from __future__ import annotations
from dataclasses import dataclass, field
from functools import partial
from pathlib import Path
@@ -1,5 +1,7 @@
"""Support for Abode Security System alarm control panels."""
from __future__ import annotations
from jaraco.abode.devices.alarm import Alarm
from homeassistant.components.alarm_control_panel import (
@@ -1,5 +1,7 @@
"""Support for Abode Security System binary sensors."""
from __future__ import annotations
from typing import cast
from jaraco.abode.devices.binary_sensor import BinarySensor
+2
View File
@@ -1,5 +1,7 @@
"""Support for Abode Security System cameras."""
from __future__ import annotations
from datetime import timedelta
from typing import Any, cast
@@ -1,5 +1,7 @@
"""Config flow for the Abode Security System component."""
from __future__ import annotations
from collections.abc import Mapping
from http import HTTPStatus
from typing import Any, cast
+2
View File
@@ -1,5 +1,7 @@
"""Constants for the Abode Security System component."""
from __future__ import annotations
import logging
LOGGER = logging.getLogger(__package__)
+2
View File
@@ -1,5 +1,7 @@
"""Support for Abode Security System lights."""
from __future__ import annotations
from math import ceil
from typing import Any
+2
View File
@@ -1,5 +1,7 @@
"""Support for Abode Security System sensors."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import cast
+2 -1
View File
@@ -1,5 +1,7 @@
"""Support for the Abode Security System."""
from __future__ import annotations
from typing import TYPE_CHECKING
from jaraco.abode.exceptions import Exception as AbodeException
@@ -44,7 +46,6 @@ def _change_setting(call: ServiceCall) -> None:
try:
_get_abode_system(call.hass).abode.set_setting(setting, value)
# pylint: disable-next=home-assistant-action-swallowed-exception
except AbodeException as ex:
LOGGER.warning(ex)
+2
View File
@@ -1,5 +1,7 @@
"""Support for Abode Security System switches."""
from __future__ import annotations
from typing import Any, cast
from jaraco.abode.devices.switch import Switch
@@ -1,5 +1,7 @@
"""Coordinator for Acaia integration."""
from __future__ import annotations
from datetime import timedelta
import logging
@@ -1,5 +1,7 @@
"""Diagnostics support for Acaia."""
from __future__ import annotations
from dataclasses import asdict
from typing import Any
@@ -1,5 +1,7 @@
"""The AccuWeather component."""
from __future__ import annotations
import asyncio
import logging
@@ -1,5 +1,7 @@
"""Adds config flow for AccuWeather."""
from __future__ import annotations
from asyncio import timeout
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any
@@ -1,5 +1,7 @@
"""Constants for AccuWeather integration."""
from __future__ import annotations
from datetime import timedelta
from typing import Final
@@ -1,5 +1,7 @@
"""The AccuWeather coordinator."""
from __future__ import annotations
from asyncio import timeout
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
@@ -1,5 +1,7 @@
"""Diagnostics support for AccuWeather."""
from __future__ import annotations
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
@@ -1,5 +1,7 @@
"""Support for the AccuWeather service."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any, cast
@@ -1,5 +1,7 @@
"""Provide info to system health."""
from __future__ import annotations
from typing import Any
from accuweather.const import ENDPOINT
@@ -1,5 +1,7 @@
"""Support for the AccuWeather service."""
from __future__ import annotations
from typing import cast
from homeassistant.components.weather import (
@@ -1,5 +1,7 @@
"""Use serial protocol of Acer projector to obtain state of the projector."""
from __future__ import annotations
from typing import Final
from homeassistant.const import STATE_OFF, STATE_ON
@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/acer_projector",
"iot_class": "local_polling",
"quality_scale": "legacy",
"requirements": ["serialx==1.8.0"]
"requirements": ["serialx==1.7.3"]
}
@@ -1,5 +1,7 @@
"""Use serial protocol of Acer projector to obtain state of the projector."""
from __future__ import annotations
import logging
import re
from typing import Any
@@ -1,5 +1,7 @@
"""Config flow for Rollease Acmeda Automate Pulse Hub."""
from __future__ import annotations
from asyncio import timeout
from contextlib import suppress
from typing import Any
+2
View File
@@ -1,5 +1,7 @@
"""Support for Acmeda Roller Blinds."""
from __future__ import annotations
from typing import Any
from homeassistant.components.cover import (
@@ -1,5 +1,7 @@
"""Base class for Acmeda Roller Blinds."""
from __future__ import annotations
import aiopulse
from homeassistant.core import callback
@@ -1,5 +1,7 @@
"""Helper functions for Acmeda Pulse."""
from __future__ import annotations
from typing import TYPE_CHECKING
from aiopulse import Roller
+2
View File
@@ -1,5 +1,7 @@
"""Code to handle a Pulse Hub."""
from __future__ import annotations
import asyncio
from collections.abc import Callable
@@ -1,5 +1,7 @@
"""Support for Acmeda Roller Blind Batteries."""
from __future__ import annotations
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.const import PERCENTAGE
from homeassistant.core import HomeAssistant, callback
@@ -1,5 +1,7 @@
"""Support for Actiontec MI424WR (Verizon FIOS) routers."""
from __future__ import annotations
import re
from typing import Final
@@ -1,5 +1,7 @@
"""Support for Actiontec MI424WR (Verizon FIOS) routers."""
from __future__ import annotations
import logging
from typing import Final
@@ -6,12 +6,7 @@ from typing import Any
from actron_neo_api import ActronAirAPI, ActronAirAuthError
from homeassistant.config_entries import (
SOURCE_REAUTH,
SOURCE_RECONFIGURE,
ConfigFlow,
ConfigFlowResult,
)
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_API_TOKEN
from homeassistant.exceptions import HomeAssistantError
@@ -110,14 +105,6 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
data_updates={CONF_API_TOKEN: self._api.refresh_token_value},
)
# Check if this is a reconfigure flow
if self.source == SOURCE_RECONFIGURE:
self._abort_if_unique_id_mismatch(reason="wrong_account")
return self.async_update_reload_and_abort(
self._get_reconfigure_entry(),
data_updates={CONF_API_TOKEN: self._api.refresh_token_value},
)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=user_data.email,
@@ -151,20 +138,6 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
return self.async_show_form(step_id="reauth_confirm")
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle reconfiguration request."""
return await self.async_step_reconfigure_confirm()
async def async_step_reconfigure_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm reconfiguration dialog."""
if user_input is not None:
return await self.async_step_user()
return self.async_show_form(step_id="reconfigure_confirm")
async def async_step_connection_error(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@@ -1,5 +1,7 @@
"""Coordinator for Actron Air integration."""
from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
@@ -1,5 +1,7 @@
"""Diagnostics support for Actron Air."""
from __future__ import annotations
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
@@ -60,7 +60,7 @@ rules:
entity-translations: done
exception-translations: done
icon-translations: done
reconfiguration-flow: done
reconfiguration-flow: todo
repair-issues:
status: exempt
comment: This integration does not have any known issues that require repair.
@@ -4,8 +4,7 @@
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]",
"oauth2_error": "Failed to start authentication flow",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
"wrong_account": "You must authenticate with the same Actron Air account that was originally configured."
"wrong_account": "You must reauthenticate with the same Actron Air account that was originally configured."
},
"error": {
"oauth2_error": "Failed to start authentication flow. Please try again later."
@@ -23,10 +22,6 @@
"description": "Your Actron Air authentication has expired. Select continue to reauthenticate with your Actron Air account. You will be prompted to log in again to restore the connection.",
"title": "Authentication expired"
},
"reconfigure_confirm": {
"description": "Reconfigure your Actron Air account. You will be prompted to log in again. Note: you must use the same account that was originally configured.",
"title": "Reconfigure Actron Air"
},
"timeout": {
"data": {},
"description": "The authentication process timed out. Please try again.",
@@ -1,5 +1,7 @@
"""The Adax integration."""
from __future__ import annotations
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
+2
View File
@@ -1,5 +1,7 @@
"""Support for Adax wifi-enabled home heaters."""
from __future__ import annotations
from typing import Any, cast
from adax import Adax
@@ -1,5 +1,7 @@
"""Config flow for Adax integration."""
from __future__ import annotations
import logging
from typing import Any
+2
View File
@@ -1,5 +1,7 @@
"""Support for Adax energy sensors."""
from __future__ import annotations
from dataclasses import dataclass
from typing import cast
@@ -1,5 +1,7 @@
"""Support for AdGuard Home."""
from __future__ import annotations
from dataclasses import dataclass
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
@@ -1,5 +1,7 @@
"""Config flow to configure the AdGuard Home integration."""
from __future__ import annotations
from typing import Any
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
@@ -1,5 +1,7 @@
"""AdGuard Home base entity."""
from __future__ import annotations
from adguardhome import AdGuardHomeError
from homeassistant.config_entries import SOURCE_HASSIO
@@ -1,5 +1,7 @@
"""Support for AdGuard Home sensors."""
from __future__ import annotations
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from datetime import timedelta
@@ -79,12 +79,6 @@
"exceptions": {
"config_entry_not_loaded": {
"message": "Config entry not loaded."
},
"error_while_turn_off": {
"message": "An error occurred while turning off AdGuard Home switch."
},
"error_while_turn_on": {
"message": "An error occurred while turning on AdGuard Home switch."
}
},
"services": {
+7 -12
View File
@@ -1,5 +1,7 @@
"""Support for AdGuard Home switches."""
from __future__ import annotations
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from datetime import timedelta
@@ -9,11 +11,10 @@ from adguardhome import AdGuardHome, AdGuardHomeError
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
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 .const import DOMAIN, LOGGER
from .entity import AdGuardHomeEntity
SCAN_INTERVAL = timedelta(seconds=10)
@@ -117,23 +118,17 @@ class AdGuardHomeSwitch(AdGuardHomeEntity, SwitchEntity):
"""Turn off the switch."""
try:
await self.entity_description.turn_off_fn(self.adguard)()
except AdGuardHomeError as err:
except AdGuardHomeError:
LOGGER.error("An error occurred while turning off AdGuard Home switch")
self._attr_available = False
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="error_while_turn_off",
) from err
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the switch."""
try:
await self.entity_description.turn_on_fn(self.adguard)()
except AdGuardHomeError as err:
except AdGuardHomeError:
LOGGER.error("An error occurred while turning on AdGuard Home switch")
self._attr_available = False
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="error_while_turn_on",
) from err
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
@@ -1,5 +1,7 @@
"""AdGuard Home Update platform."""
from __future__ import annotations
from datetime import timedelta
from typing import Any
@@ -1,5 +1,7 @@
"""Support for ADS binary sensors."""
from __future__ import annotations
import pyads
import voluptuous as vol
+2
View File
@@ -1,5 +1,7 @@
"""Support for Automation Device Specification (ADS)."""
from __future__ import annotations
from enum import StrEnum
from typing import TYPE_CHECKING
+2
View File
@@ -1,5 +1,7 @@
"""Support for ADS covers."""
from __future__ import annotations
from typing import Any
import pyads
+3 -2
View File
@@ -1,5 +1,7 @@
"""Support for ADS light sources."""
from __future__ import annotations
from typing import Any
import pyads
@@ -106,8 +108,7 @@ class AdsLight(AdsEntity, LightEntity):
self._attr_supported_color_modes = filter_supported_color_modes(color_modes)
self._attr_color_mode = next(iter(self._attr_supported_color_modes))
# Set color temperature range
# (static config values take precedence over defaults)
# Set color temperature range (static config values take precedence over defaults)
if ads_var_color_temp_kelvin is not None:
self._attr_min_color_temp_kelvin = (
min_color_temp_kelvin
+2 -1
View File
@@ -1,5 +1,7 @@
"""Support for ADS select entities."""
from __future__ import annotations
import pyads
import voluptuous as vol
@@ -19,7 +21,6 @@ from .hub import AdsHub
DEFAULT_NAME = "ADS select"
# pylint: disable-next=home-assistant-duplicate-const
CONF_OPTIONS = "options"
PLATFORM_SCHEMA = SELECT_PLATFORM_SCHEMA.extend(
+2
View File
@@ -1,5 +1,7 @@
"""Support for ADS sensors."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.components.sensor import (

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