Compare commits

..

553 Commits

Author SHA1 Message Date
Paul Bottein 6860e0f3b9 Remove comment 2026-06-25 13:02:39 +02:00
Paul Bottein d3be0cc852 Simplify live attribute handling and use event enum 2026-06-25 12:49:01 +02:00
Paul Bottein c830c05cbd Expose selected state attributes in the logbook 2026-06-25 12:15:44 +02:00
Ronald van der Meer 2be55a06cc Migrate Duco sensor units to UnitOfRatio (#174791) 2026-06-25 10:09:55 +02:00
bkobus-bbx d786fb16a0 Migrate blebox to UnitOfDensity / UnitOfRatio enums (#174790) 2026-06-25 10:08:56 +02:00
J. Nick Koston f78dd797b1 Bump habluetooth to 6.25.1 (#174700) 2026-06-25 09:40:43 +02:00
davidrule1969 0d957a971d Bump pySwitchbot to 2.3.0 (#174678) 2026-06-25 08:51:22 +02:00
Raphael Hehl cff3a711f3 Bump uiprotect to 15.0.0 (#174709) 2026-06-25 08:42:32 +02:00
Brandon Rothweiler 177c4a4fb5 Bump dropbox to silver quality (#174706) 2026-06-25 07:39:05 +02:00
Samuel Xiao 7d8204f5e7 Bump switchbot-api to 2.12.0 (#174705) 2026-06-25 07:37:59 +02:00
Franck Nijhof 9aed167f71 Bump version to 2026.8.0.dev0 (#174693) 2026-06-25 00:44:19 +02:00
Franck Nijhof a8630f5570 Add delegated charging mode to Renault integration (#174687) 2026-06-24 23:35:13 +02:00
J. Nick Koston 2a75b0e2fb Bump habluetooth to 6.24.0 (#174688) 2026-06-24 23:34:38 +02:00
Brandon Rothweiler 9c4ad761c4 Add missing scope and authorize param to Dropbox OAuth (#174587) 2026-06-24 22:26:30 +02:00
Erwin Douna 8e3e1044a1 Tami4 group executor job (#174668) 2026-06-24 22:01:24 +02:00
Colin bec6c94e32 openevse: Convert config to textselector (#174675) 2026-06-24 21:50:41 +02:00
Colin c9729df69a openevse: Add missing callback test (#174560) 2026-06-24 21:33:30 +02:00
Christian Lackas 70ff0fd682 Bump homematicip to 2.13.2 (#174673) 2026-06-24 20:43:23 +02:00
Erwin Douna 258ae6d506 Vera core group executor job (#174669) 2026-06-24 20:37:08 +02:00
Ville Skyttä 4f93afd6ae Remove myself from huawei_lte codeowners (#174671) 2026-06-24 19:57:24 +02:00
Erwin Douna 7968fc4809 Huawei group executor job (#174666) 2026-06-24 19:43:54 +02:00
TheJulianJES 975f2a831e Bump zha-quirks to 2.1.0 (#174662) 2026-06-24 18:42:41 +02:00
Leonardo Merza cc2944d626 Fix ecobee active sensor reporting for custom presets and shared device names (#174417) 2026-06-24 17:21:45 +01:00
Mick Vleeshouwer 548ec5cacf Enable action queue to batch concurrent commands in Overkiz (#174275) 2026-06-24 17:19:15 +02:00
karwosts dc6eef2844 Fix date-only input_datetime timestamp attribute to use the correct TZ (#174357) 2026-06-24 17:15:09 +02:00
Stefan Agner 0808e30e37 Add repair when IPv6 is disabled for Matter (#174653)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-24 17:11:54 +02:00
Manu f0ed257f47 Refactor Steam integration config flow and tests (#174504)
Co-authored-by: Erwin Douna <e.douna@gmail.com>
2026-06-24 17:06:29 +02:00
Petro31 b4b710b474 Add restore state framework for template entities (#172847) 2026-06-24 16:54:56 +02:00
Bram Kragten 0004a82fe4 Update frontend to 20260624.0 (#174657) 2026-06-24 15:46:44 +01:00
epenet 0c4bc95bdd Migrate base entity attributes to StrEnum (#174633) 2026-06-24 15:38:49 +01:00
Manu 5fdab795e8 Remove Avi-on integration (#174649) 2026-06-24 16:35:22 +02:00
Manu 2193665909 Remove BeeWi SmartClim (#174651) 2026-06-24 16:32:05 +02:00
Martin Hjelmare c9d91d5812 Add enabled entity limit per config entry (#174194) 2026-06-24 16:07:54 +02:00
Erik Montnemery de9d9c66c1 Add additional sun conditions (#174537) 2026-06-24 16:00:08 +02:00
Paul Bottein dfcc4d1ae4 Fix friendly name for restored unavailable entities (#174614) 2026-06-24 14:47:39 +01:00
TimL d71812f09b Bump pysmlight to 0.4.0 (#174640) 2026-06-24 15:19:35 +02:00
Ariel Ebersberger a323ebe634 Reword "advanced operation" channel warning in Home Assistant Hardware (#174645) 2026-06-24 14:57:18 +02:00
Ariel Ebersberger 024bba55cf Reword "Configure advanced voice settings" in ElevenLabs (#174642) 2026-06-24 14:33:41 +02:00
Ariel Ebersberger a5546566e7 Rename "(advanced)" service names in Z-Wave (#174644) 2026-06-24 14:32:38 +02:00
Ariel Ebersberger 3d9994ee4f Rename "Local Risco Panel (advanced)" option in Risco (#174643) 2026-06-24 14:31:55 +02:00
Erik Montnemery c542f38387 Add checks for did_not_trigger calls to trigger tests (#174636)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 13:05:08 +01:00
wollew 49d6166b7e Bump pyvlx to 0.2.36 (#174638) 2026-06-24 13:21:45 +02:00
J. Nick Koston 7249190c64 Bump habluetooth to 6.23.1 (#174639) 2026-06-24 13:21:12 +02:00
epenet cebdde6ab4 Migrate device tracker entity attributes to StrEnum (#174621) 2026-06-24 12:53:43 +02:00
epenet 031f4cd965 Migrate remaining platform entity attributes to StrEnum (#174625) 2026-06-24 12:52:50 +02:00
Ariel Ebersberger a734f7110c Rename "Advanced options" to "Additional options" in DNS IP (#174628) 2026-06-24 12:38:16 +02:00
Ariel Ebersberger 395e949591 Rename "Advanced settings" to "Additional settings" in History Stats (#174629) 2026-06-24 12:38:00 +02:00
Ariel Ebersberger 484e60a1c4 Rename "Advanced options" to "Additional options" in SQL (#174631) 2026-06-24 12:19:38 +02:00
Ariel Ebersberger b7a234fbd9 Rename "Advanced settings" to "Additional settings" in Telegram bot (#174632) 2026-06-24 12:19:08 +02:00
Ariel Ebersberger a1982fbd54 Rename "Advanced settings" to "Additional settings" in Autoskope (#174630) 2026-06-24 12:18:53 +02:00
epenet c384cd9894 Migrate calendar entity attributes to StrEnum (#174615) 2026-06-24 12:10:37 +02:00
Tom 1aefd2a5ac Bump airOS dependency to support open wireless (#174559) 2026-06-24 12:00:38 +02:00
epenet e3605be5cd Migrate siren entity attributes to StrEnum (#174616) 2026-06-24 11:54:13 +02:00
epenet e87a41a01d Migrate text entity attributes to StrEnum (#174619) 2026-06-24 11:51:28 +02:00
epenet 190ff034aa Migrate vacuum entity attributes to StrEnum (#174617) 2026-06-24 11:46:29 +02:00
epenet b301925687 Migrate cover entity attributes to StrEnum (#174601) 2026-06-24 11:18:37 +02:00
epenet 7a0f5b066e Migrate humidifier entity attributes to StrEnum (#174609) 2026-06-24 11:17:45 +02:00
epenet 308fad166d Migrate media player entity attributes to StrEnum (#174605) 2026-06-24 11:16:33 +02:00
epenet 1305c2978c Migrate fan entity attributes to StrEnum (#174610) 2026-06-24 11:12:45 +02:00
epenet 955ad6db1b Migrate valve entity attributes to StrEnum (#174611) 2026-06-24 11:12:02 +02:00
Andreas Schneider 87dc013803 Use age-based filter for Matter BLE advertisement history replay (#173488) 2026-06-24 04:11:29 -05:00
Stefan Agner 1bb41cb2dd Use translated message when Matter Server add-on is not ready (#174529)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 11:02:08 +02:00
epenet 277af6c60b Migrate update entity attributes to StrEnum (#174608) 2026-06-24 10:57:58 +02:00
Raphael Hehl 69e18aa580 Source UniFi Protect light auto-shutoff duration from the public API (#174518) 2026-06-24 03:54:38 -05:00
Raphael Hehl 75852fc191 Add ufp_public_enabled_fn for public-API availability gating to UniFi Protect (#174544) 2026-06-24 03:53:49 -05:00
Mark Ruys a661b678a2 Add Sensoterra CODEOWNERs (#174431)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-24 10:53:36 +02:00
Raphael Hehl bd0951110d Drive the UniFi Protect doorbell ring event from the public events websocket (#174546) 2026-06-24 03:53:01 -05:00
epenet 899f904cf3 Migrate weather entity attributes to StrEnum (#174604) 2026-06-24 10:38:25 +02:00
epenet d2e7426aa5 Migrate image entity attributes to StrEnum (#174606) 2026-06-24 10:37:38 +02:00
epenet c0e02457bc Migrate lock entity attributes to StrEnum (#174607) 2026-06-24 10:37:11 +02:00
epenet e7562b50cf Migrate water heater entity attributes to StrEnum (#174603) 2026-06-24 10:32:38 +02:00
Thomas c36e4a03e0 Bump boschshcpy to 0.3.5 (#174550) 2026-06-24 10:16:45 +02:00
Nathan Spencer 71430af6ff Bump pylitterbot to 2025.5.0 (#174554) 2026-06-24 10:15:43 +02:00
Åke Strandberg 815cce5a0c Tweak aqvify entity names (#174597) 2026-06-24 10:08:15 +02:00
Robert Svensson 32929755eb Tighten the Axis unique ID in config flow (#172283) 2026-06-24 10:07:10 +02:00
Manu 88d4d1c879 Remove SCSGate integration (#174571) 2026-06-24 10:02:23 +02:00
Manu 51bd71d096 Remove Acer projector integration (#174579) 2026-06-24 09:58:09 +02:00
Thomas 1fcf9eb5b7 Add @mosandlt as codeowner for bosch_shc (#174563) 2026-06-24 09:57:19 +02:00
epenet 1917a007f8 Migrate event entity attributes to StrEnum (#174592) 2026-06-24 09:56:20 +02:00
Paul Bottein b095baa65a Bump Yoto quality scale to platinum (#174598) 2026-06-24 09:52:20 +02:00
Przemysław Szypowicz 2bd81c7351 Remove broken Ampio Smog integration (#173080) 2026-06-24 09:50:46 +02:00
Paul Bottein a576aef9a4 Add dynamic and stale device handling to Yoto (#173298)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-24 09:32:10 +02:00
Michael Hansen c2e780dfd2 Improve Wyoming satellite reconnect and tolerance of other satellites (#174460)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 09:22:03 +02:00
epenet 687064d5cc Migrate Ratio units to StrEnum (#172568) 2026-06-24 09:21:28 +02:00
epenet 0b801d74cd Migrate camera entity attributes to StrEnum (#174591) 2026-06-24 09:15:44 +02:00
epenet dbdcb1a91e Migrate alarm control panel entity attributes to StrEnum (#174590) 2026-06-24 09:06:16 +02:00
epenet f9bf7ab122 Migrate sensor entity attributes to StrEnum (#174595) 2026-06-24 09:05:32 +02:00
epenet d484f75c7b Migrate number entity attributes to StrEnum (#174593) 2026-06-24 09:04:22 +02:00
dependabot[bot] 5ba4d588b6 Bump actions/checkout from 6.0.3 to 7.0.0 (#174596)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 08:59:49 +02:00
epenet 42da67e7a9 Migrate light entity attributes to StrEnum (#174589) 2026-06-24 08:58:00 +02:00
Joost Lekkerkerker 7d08a7b898 Add new integration quality scale rules (#174555) 2026-06-24 08:53:46 +02:00
puddly 05016e46c8 Bump ZHA to 2.0.0 (#174586) 2026-06-24 08:52:44 +02:00
J. Nick Koston 58603326e3 Bump habluetooth to 6.19.1 (#174582) 2026-06-23 22:58:58 -05:00
Steve Rice 10fe3dc13f Add cloudhook support to switchbot_cloud webhook (#174566)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 21:50:08 -04:00
J. Nick Koston adf2f2854c Active scan govee_ble only when needed and widen the window to 30s (#174557) 2026-06-23 21:03:38 -04:00
A. Gideonse 7fd101005d Bump indevolt-api to 1.8.6 (#174573) 2026-06-24 03:03:09 +02:00
J. Nick Koston 40aa8dd617 Widen the INKBIRD IBS-TH2 active scan window to 30s (#174565) 2026-06-23 21:02:55 -04:00
Matthias Alphart fb283dfb93 Update knx-frontend to 2026.6.23.203726 (#174567) 2026-06-23 20:55:45 -04:00
J. Nick Koston 2084d52504 Bump habluetooth to 6.13.0 (#174568) 2026-06-23 20:55:34 -04:00
Fabian Munkes cb914495e7 Add username parameter to play media action in Music Assistant (#174486) 2026-06-24 01:04:44 +02:00
J. Nick Koston 97f2eecc57 Bump bluetooth-adapters to 2.4.0 (#174575) 2026-06-23 17:58:06 -05:00
J. Nick Koston 2d1b3f799d Bump dbus-fast to 5.0.22 (#174569) 2026-06-23 23:32:27 +02:00
J. Nick Koston f57418ed60 Bump govee-ble to 1.4.0 (#174553) 2026-06-23 20:27:33 +02:00
Abílio Costa 8d1bf68045 Enable mypy explicit-override check (#171853)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-06-23 18:20:08 +01:00
Raphael Hehl c5bfad9bfe Remove UniFi LED (unifiled) integration (#168232)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-06-23 17:45:31 +02:00
Abílio Costa 679b0ac2aa Add agent instruction to prevent divider comments (#174531) 2026-06-23 16:41:43 +01:00
epenet 22a583c83f Migrate climate entity attributes to StrEnum (#174528) 2026-06-23 16:48:38 +02:00
epenet d966f71832 Migrate select entity attributes to StrEnum (#174536) 2026-06-23 16:44:47 +02:00
Manu 08569420f6 Remove Eliqonline integration (#174538) 2026-06-23 17:10:21 +03:00
Ronald van der Meer c1bcbca520 Add filter remaining days sensor to Duco (#174316) 2026-06-23 15:16:42 +02:00
Simone Chemelli c73c647162 Improve docstring for async_get_entity_id() method (#174532) 2026-06-23 14:50:34 +02:00
Markus Tuominen b2f1c38b6f Bump ouman-eh-800-api to 1.0.0 (#174458) 2026-06-23 14:45:19 +02:00
Erik Montnemery e8824bedf5 Add additional sun triggers (#174485) 2026-06-23 14:23:29 +02:00
Ajinkya Gokhale 27b107f4a5 Update energieleser to silver quality scale (#174535) 2026-06-23 14:23:06 +02:00
Petro31 7536e8647f Fix entities listed in template blueprints (#171861)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-23 13:35:20 +02:00
Simone Chemelli 75c6058396 Add "Drop in" select to Alexa Devices (#174336) 2026-06-23 10:47:44 +02:00
Matthias Alphart 77533e5af5 Rename "Advanced options" in KNX strings (#174523) 2026-06-23 10:27:11 +02:00
LG-ThinQ-Integration 31a1e7c5e1 Bump thinqconnect 1.0.13 (#174510)
Co-authored-by: YunseonPark-LGE <yunseon.park@lge.com>
2026-06-23 09:55:33 +02:00
renovate[bot] 20f4e7306b Update pytest-unordered to 0.8.0 (#174515) 2026-06-23 09:15:35 +02:00
Mick Vleeshouwer 5c1ac08c92 Catch connection errors when executing Overkiz commands (#174453) 2026-06-23 08:51:36 +02:00
Franck Nijhof 5631c68069 Reword trigger descriptions for presence and detection entities (#174467) 2026-06-23 08:51:14 +02:00
Franck Nijhof 8648611278 Clarify the media player play media action name (#174480) 2026-06-23 08:49:04 +02:00
Franck Nijhof 971d15be1e Improve trigger wording for lawn mower and vacuum entities (#174477)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-06-23 08:48:45 +02:00
Åke Strandberg b6f2429ff3 Bump pyaqvify to 0.0.12 (#174516) 2026-06-23 08:35:13 +02:00
Jacob Hurwitz c676e2a806 Bump python-dropbox-api to 0.1.4 (#174512) 2026-06-23 07:22:21 +02:00
Robert Resch a27ea536db Enable aw check requirements on each deps PR (#174481) 2026-06-23 02:14:03 +02:00
Erwin Douna 22e25d9ce2 MELCloud Home exand sensor state behavior (#174495) 2026-06-23 00:44:14 +02:00
Nikhil Deepak 1cb5e31901 Pass keep_alive parameter to Ollama AI Task calls (#165410)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-23 00:16:56 +02:00
Thijs W. 4f414d0035 Fix duplicate-configuration edge-case in Frontier Silicon config flow (#172916) 2026-06-23 00:11:51 +02:00
Franck Nijhof 30b648ea6a Bump holidays to 0.99 (#174501) 2026-06-23 00:10:33 +02:00
fdebrus 18a259718f Vistapool: add reauthentication flow (#172825)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-23 00:09:33 +02:00
fdebrus 45de0f4b4a Add select platform to Vistapool (#172547)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-23 00:08:14 +02:00
Erwin Douna 940bf5bf09 Portainer fix type narrowing (#173040) 2026-06-23 00:07:34 +02:00
starkillerOG 07e78b6dbf Bump reolink-aio to 0.21.2 (#174497) 2026-06-23 00:06:47 +02:00
Franck Nijhof abcb677b57 Bump SQLAlchemy to 2.0.51 (#174499) 2026-06-22 23:59:00 +02:00
Ermanno Baschiera 7e638f9d0c Bump Helty Flow to silver quality scale (#173132)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:57:21 +02:00
Thomas D 8aca6115f4 Trigger location update on certain events for the Volvo integration (#172651)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 23:53:42 +02:00
Oscar Calvo dd688986f1 Add CCM15 swing control (#173793)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 23:51:53 +02:00
Branden Cash c519b7ba07 Populate hourly statistics in srp_energy (#167371)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Signed-off-by: Branden Cash <203336+ammmze@users.noreply.github.com>
2026-06-22 23:51:33 +02:00
Pete Sage 158595464a Cancel timers for Sonos on shutdown/reload (#172830) 2026-06-22 23:47:27 +02:00
Franck Nijhof f81aff0a69 Remove runtime_data dependency from SIA options flow (#174489) 2026-06-22 23:43:46 +02:00
Arie Catsman 9f90e6ec22 Bump pyenphase to v3.0.0 (#174496) 2026-06-23 00:41:23 +03:00
Simone Chemelli 31b311e17a Improve availability of notify enttities for Alexa Devices (#174220)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 23:37:27 +02:00
Manu 7e07f2ab87 Add notify entities to Notifications for Android TV / Fire TV (#169087) 2026-06-22 23:36:45 +02:00
Przemko92 312f4c8c35 Add new values for Compit climate (#174238)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 23:29:01 +02:00
Brett Adams ddeeba5f87 Bump Splunk to silver quality scale (#174236)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 23:20:16 +02:00
Przemko92 82a043bc47 Add new values for Compit sensor (#174240) 2026-06-22 23:17:32 +02:00
Alain 629b9a5f9b SwitchBot cloud fix webhook handling (#169141)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 23:16:22 +02:00
tacopiek 9400c2e40e Add energy_today sensor to LG ThinQ (#172983)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 23:16:07 +02:00
epenet 8a57bb0640 Refactor thermopro tests to avoid thermopro_sensor.async_setup_entry (#173880) 2026-06-22 23:14:39 +02:00
Chris ab8f1bf88e Add OpenEVSE button platform (#172964) 2026-06-22 23:14:27 +02:00
Erwin Douna b61ad539d9 MELCloud Home add frost and overheat protection (#174224) 2026-06-22 23:13:57 +02:00
Franck Nijhof 283dcee830 Fix Rachio calendar error when no events are scheduled (#173624) 2026-06-22 23:13:02 +02:00
Franck Nijhof e61a3ac684 Bump pyAtome to 0.1.2 (#173902) 2026-06-22 23:11:31 +02:00
Franck Nijhof 5595ba12fb Bump kiwiki-client to 0.1.2 (#173903)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-06-22 23:09:51 +02:00
Mick Vleeshouwer 1bfd4d1500 Handle ApplicationNotAllowedError in Overkiz cloud config flow (#174498) 2026-06-22 23:03:51 +02:00
Manu 249c3bb5dd Refactor sensor platform of Steam integration (#174415) 2026-06-22 22:59:42 +02:00
Ariel Ebersberger 982fe7a370 Use value comparison for value-based enums (#174494) 2026-06-22 22:44:26 +02:00
EnjoyingM 035e7e0a38 Wolflink Shared and multidevice hub support (#172795)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 22:40:14 +02:00
J. Nick Koston f6b0036ccc Bump zeroconf to 0.150.0 (#174484) 2026-06-22 22:29:17 +02:00
Denis Shulyaka b2a26afb14 Promote Anthropic IQS to Gold (#170268) 2026-06-22 22:20:39 +02:00
Mick Vleeshouwer 231470f4dc Configure RTS command duration on the Overkiz client (#174448) 2026-06-22 22:04:11 +02:00
Erwin Douna 8aeb5d63ab MELCloud Home add icon for holiday mode (#174459) 2026-06-22 22:02:10 +02:00
some-random-climber d613591463 Use service helper in Picnic (#174271) 2026-06-22 21:59:34 +02:00
Abílio Costa dc6269f52d Add override decorator to remaining homeassistant dir files (#174488) 2026-06-22 21:56:03 +02:00
some-random-climber 31690ac2d3 Use service helper in Volvo (#174267) 2026-06-22 21:54:54 +02:00
Tim Laing ffe008c6b2 Fix iCloud auth bug (#173816) 2026-06-22 21:52:47 +02:00
Raphael Hehl dc48c3e30f Fix UniFi Protect package detection via public events websocket (#173733) 2026-06-22 14:45:20 -05:00
Jonathan Swoboda 448fd04137 Convert epoch to datetime for ESPHome uptime sensor device class (#174223) 2026-06-22 21:30:31 +02:00
AlCalzone 41e7837bcf Set openSenseMap to bronze on the quality scale (#173864)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 21:29:59 +02:00
Mattie 951062fa82 Add SG Ready select entity to Qube heat pump (#170114)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 21:29:25 +02:00
Allen Porter f2ac5a4153 Support Roborock dynamic devices and simplify startup error handling (#173704) 2026-06-22 21:27:29 +02:00
Franck Nijhof 12832fe3cd Remove invalid state_class from System Monitor battery_empty sensor (#174487) 2026-06-22 21:09:46 +02:00
some-random-climber d35e58fdc7 Move service registration to async_setup in cloudflare (#174131) 2026-06-22 20:56:48 +02:00
smartcircuits 3570cd0ee3 Add reauthentication flow to WattWächter Plus (#174281)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 20:56:22 +02:00
Brett Adams 5a99cb4cca Fix Teslemetry rear seat heater entity availability (#174248)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-22 20:54:55 +02:00
Abílio Costa d49a9c4780 Add override decorator to components S to T (#174483) 2026-06-22 20:52:27 +02:00
Abílio Costa c330a983e4 Add override decorator to components U to Z (#174482) 2026-06-22 20:51:13 +02:00
Legendberg e47f58362a Add per-day sleep schedule entities for Litter-Robot 5 (#173569)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2026-06-22 20:48:51 +02:00
Franck Nijhof 18f5998162 Improve trigger wording for button, event, and helper entities (#174472)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2026-06-22 20:46:09 +02:00
Paul Bottein e41d9d5447 Standardize constants across entity platforms (#174446) 2026-06-22 20:44:15 +02:00
Michael Hansen 9509bcb8e3 Forward intent response text to ESPHome voice satellite (#174452) 2026-06-22 20:43:04 +02:00
Erwin Douna eb50acfc26 MELCloud Home add icon state behavior (#174461) 2026-06-22 20:42:27 +02:00
Franck Nijhof 3a880644bc Fix Rainforest RAVEn sensor returning string None as state (#174295) 2026-06-22 20:38:27 +02:00
Franck Nijhof 0a39eb3f5d Improve trigger and condition wording for scene, select, and to-do list entities (#174473) 2026-06-22 19:37:46 +01:00
Erik Montnemery 91f4168439 Simplify sun entity (#174464)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2026-06-22 20:29:59 +02:00
Franck Nijhof e1c8f3da78 Improve trigger and condition wording for media player entities (#174474) 2026-06-22 19:27:32 +01:00
Franck Nijhof c868f760d5 Reword trigger descriptions for Assist, alarm, calendar, and update entities (#174475) 2026-06-22 19:23:26 +01:00
Abílio Costa 8965e2241e Add override decorator to components P to R (#174478) 2026-06-22 20:21:39 +02:00
Franck Nijhof b17e86d45c Improve zone trigger and condition wording (#174476) 2026-06-22 19:21:01 +01:00
Abílio Costa 91e70bcc1a Add override decorator to components N to O (#174479) 2026-06-22 20:20:21 +02:00
Franck Nijhof 11f86f30ac Reword trigger descriptions for air quality entities (#174471) 2026-06-22 19:19:39 +01:00
Franck Nijhof 75c490139d Reword trigger descriptions for climate entities (#174469) 2026-06-22 19:14:05 +01:00
Franck Nijhof 4ccd854225 Improve trigger and condition wording for numeric sensor entities (#174470) 2026-06-22 19:13:26 +01:00
galo2099 b7fbbf5a1f Handle stale Tesla Fleet energy sites (#170278)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-22 20:13:15 +02:00
Franck Nijhof 5e05f6f845 Reword trigger descriptions for lights, switches, and output entities (#174468) 2026-06-22 19:12:32 +01:00
Franck Nijhof 294d1cb726 Reword trigger descriptions for opening and closing entities (#174466) 2026-06-22 19:11:49 +01:00
Crocmagnon 7074c291a0 Bump data_grand_lyon_ha to v0.9.0 (#174286) 2026-06-22 20:02:47 +02:00
Franck Nijhof 8bf668186d Cast OpenTherm Gateway device info fields to string (#174290) 2026-06-22 20:02:13 +02:00
Yardian Support 1d02788001 Fix a standby binary sensor bug in yardian (#174341)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 20:01:45 +02:00
Axelwin 3cc975aae3 Add V2G charge states to Renault charge_state sensor (#173463)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-06-22 20:00:47 +02:00
some-random-climber 28294dfdfc Use service helper in Sonarr (#174273) 2026-06-22 19:37:28 +02:00
Abílio Costa b2aa1c1b8d Add override decorator to components J to M (#174465) 2026-06-22 19:35:53 +02:00
Abílio Costa fa13cedf83 Add override decorator to components H to I (#174462) 2026-06-22 19:21:49 +02:00
Abílio Costa 0b7e2fa28b Add override decorator to components F to G (#172136) 2026-06-22 19:21:29 +02:00
Franck Nijhof 7edcbff62c Rename entity trigger and condition keys for consistency (#174463) 2026-06-22 19:19:44 +02:00
Abílio Costa aeb020c60f Add override decorator to components C to E (#172085) 2026-06-22 19:17:40 +02:00
Moura 9c2914d03a nx584: update bypassed zone attribute from events (#174353)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 19:16:37 +02:00
Léon 980d3c28fd Add To-do list platform to Alexa Devices (#171136)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
2026-06-22 18:22:41 +02:00
Michael a7fb69cf3e Add fan speed mode control to Synology DSM (#173051)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-06-22 18:06:45 +02:00
TheJulianJES b24791fa71 Remove unused hass.data[DOMAIN] from Thread integration (#168863) 2026-06-22 17:59:25 +02:00
Erik Montnemery b6b8391cbf Remove purpose-specific triggers and conditions from labs (#174450) 2026-06-22 16:58:51 +01:00
Erik Montnemery dad7da0e3b Remove sun helper cache (#174457) 2026-06-22 17:58:47 +02:00
Lukas 87cdf3a0e3 Virtual intgration BWT (SEKO pooldose) (#174311) 2026-06-22 17:47:46 +02:00
Willem-Jan van Rootselaar 634980b53f Bump python-bsblan to 6.1.3 (#172843) 2026-06-22 17:44:39 +02:00
Paul Bottein e244b7f2b6 Add config switches to Yoto (#173973)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-06-22 17:43:05 +02:00
Marc Hörsken 761f1f8a0e Use pytest fixture parametrization instead of duplicate fixtures (#174304)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-22 17:41:27 +02:00
MarkGodwin a51c653797 Allow multiple sites for same TP-Link Omada controller (#168535) 2026-06-22 17:41:18 +02:00
David Bayer af6ae63eeb Fix blink 2fa auth flow (#174356) 2026-06-22 17:29:18 +02:00
Tom 11b49607bd Add airOS (insecure ssl) support for legacy v6 devices (#172954) 2026-06-22 17:21:03 +02:00
Erwin Douna 956e26196a MELCloud Home add Holiday mode sensors (#174454) 2026-06-22 17:08:31 +02:00
Abílio Costa 3946162140 Add override decorator to components A to B (#172081) 2026-06-22 15:14:48 +01:00
Clément Notin c3f7a1d5b0 [Daikin] Specify time period for consumption sensors (#174395) 2026-06-22 15:34:35 +02:00
Åke Strandberg c9a6502c16 Add a coordinator for slow polling and add new sensors to aqvify (#174075) 2026-06-22 15:30:20 +02:00
Hai-Nam Nguyen 708d5b46e8 Add Nexen virtual integration (#173594) 2026-06-22 14:41:32 +02:00
Eduard Reñé Claramunt 49bd80541c Add @edurenye as SAJ codeowner (#174438) 2026-06-22 13:45:03 +02:00
tronikos a8c42222a3 Bump opower to 0.18.6 (#174430) 2026-06-22 13:30:00 +02:00
Eduard Reñé Claramunt 7e805f2f2a Allow SAJ Solar Inverter to be configured through the UI (#160052)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-06-22 12:40:28 +02:00
Erwin Douna 7e684dbcca Bump aiomelcloudhome to 0.1.9 (#174413) 2026-06-22 12:34:20 +02:00
Markus Tuominen cdd063083d Add entity-unique-id-redundant-domain pylint check (#173434)
Co-authored-by: Ariel Ebersberger <ariel@ebersberger.io>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-22 12:33:38 +02:00
Jordan Harvey 1e4e77465a Bump pyanglianwater to 3.2.2 (#174433) 2026-06-22 12:24:55 +02:00
Erik Montnemery 16671e29d8 Trigger add did not trigger callback (#174116) 2026-06-22 10:54:16 +02:00
Mick Vleeshouwer b8dc091a21 Normalize Overkiz RTS tilt command arguments (#174297) 2026-06-22 09:38:50 +02:00
Manu 66afd77a96 Improve config flow strings in Steam integration (#174418) 2026-06-22 09:28:45 +02:00
tronikos 134519e97f Add fan timer timeout timestamp sensor to Nest integration (#174330)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-22 09:22:04 +02:00
Fabian Munkes c1957f2f35 Bump music-assistant-client to 1.3.6 (#174345)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-06-22 08:43:14 +02:00
Peter Grauvogel 89e2b2b9fc Adjust Green Planet Energy service wording (#174406) 2026-06-22 08:05:09 +02:00
Mick Vleeshouwer 9a1f40280b Retry Overkiz setup on transient server unavailable errors (#174411) 2026-06-22 08:04:58 +02:00
Manu 1518aaa82d Bump steamodd to 5.0 (#174421) 2026-06-22 08:04:24 +02:00
Manu 6dd60a3723 Remove tikteck integration (#174423) 2026-06-22 08:03:31 +02:00
Matthias Alphart c6b4d5c7c3 Update xknx to 3.16.0 (#174312) 2026-06-22 06:10:59 +02:00
Paulus Schoutsen d782cd8289 Fix singleton leaving a dangling Event when wrapped coroutine raises (#174400)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 23:26:44 -04:00
Paulus Schoutsen 2f633193e9 Fix flaky KNX sensor validation test (#174396)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 23:24:50 -04:00
Raphael Hehl 5ada338f13 Source UniFi Protect UP-Sense battery from the public API (#174229)
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-06-21 15:52:44 -05:00
Raphael Hehl 5e6085f961 Source UniFi Protect camera streams from the public API (#174369) 2026-06-21 15:44:26 -05:00
Paulus Schoutsen 8198aa263b Lazy load repairs platforms (#174374)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 15:08:30 -05:00
Paulus Schoutsen 2abe5d23f4 Lazily load cast integration platforms (#174373)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 15:07:48 -05:00
Paulus Schoutsen e8428ea639 Formalize deprecation of system_health.async_register_info (#174352)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-21 14:53:25 -05:00
Paulus Schoutsen 81f7e53dfa Fix flaky test_thread_fails_raise (#174398)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 14:48:57 -05:00
RDFurman 151fd1409f Remove rdfurman from honeywell codeowners (#174401) 2026-06-21 14:15:15 -04:00
Mick Vleeshouwer 690fb22c11 Add tests for the Overkiz binary sensor platform (#174402) 2026-06-21 14:14:41 -04:00
Mick Vleeshouwer 395c02ddb4 Update pyoverkiz to 2.0.2 (#174403) 2026-06-21 14:13:18 -04:00
Chase 78f903d0f6 Migrate jsonpath to jsonpath-python dependencies (#174364)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-21 12:54:31 -04:00
renovate[bot] ea7ccae927 Update infrared-protocols to 6.3.0 (#174326) 2026-06-21 18:01:48 +02:00
Alistair Francis 2008551cc9 husqvarna_automower_ble: Update to use automower-ble 0.2.9 (#174384)
Signed-off-by: Alistair Francis <alistair@alistair23.me>
2026-06-21 11:20:27 -04:00
Bert 2b7cd9295a Bump pymodbus to 3.13.1 (#174332) 2026-06-21 11:17:54 -04:00
Franck Nijhof a4131e128c Merge branch 'master' into dev 2026-06-21 14:20:23 +00:00
Mick Vleeshouwer 05ec46906c Add fan platform to Overkiz (#174362) 2026-06-21 13:36:08 +02:00
Franck Nijhof 06aa380e09 Fix Tesla Fleet/Teslemetry cable lock showing unlocked when data unavailable (#174287) 2026-06-21 12:20:04 +02:00
Raphael Hehl 758c6c62b2 Bump uiprotect to 14.0.0 (#174381) 2026-06-21 12:10:53 +02:00
Fabian Munkes 27d229b161 Fix an incompatible type arg in config flow of Music Assistant (#174380) 2026-06-21 10:33:01 +02:00
Alistair Francis 010b789026 husqvarna_automower_ble: Improve error logging and handle TimeOuts (#174343) 2026-06-21 07:56:50 +02:00
Mick Vleeshouwer ee1d378574 Fix UndefinedType._singleton leaking into Overkiz sub-device entity names (#174360) 2026-06-21 07:49:47 +02:00
Mick Vleeshouwer 324f08d00f Add separate battery sensors for Overkiz smoke sensors (#174365) 2026-06-21 07:48:08 +02:00
Yardian Support 957c24fcd7 Bump pyyardian to 1.4.1 (#174347) 2026-06-20 19:36:14 -04:00
MarkGodwin 97dbd59750 Bump tplink-omada-client to 1.5.8 to fix #170082 (#174350) 2026-06-20 19:35:30 -04:00
Przemysław Szypowicz 16c7ec30b0 Bump pyatv to 0.18.0 (#174354)
Co-authored-by: Przemysław Szypowicz <2733699+pszypowicz@users.noreply.github.com>
2026-06-20 19:29:05 -04:00
Joost Lekkerkerker bd4cdeb510 Add new Withings MAC range (#174366) 2026-06-20 19:27:29 -04:00
Maciej Bieniek ac1f82d130 Bump brother to 6.1.1 (#174368) 2026-06-20 19:27:05 -04:00
Joost Lekkerkerker a9393d777e Add vacuum room support to Google Assistant (#164617)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2026-06-20 21:26:25 +02:00
Raphael Hehl d28827a4f2 Bump uiprotect to 13.5.1 (#174355) 2026-06-20 13:11:25 -05:00
Paulus Schoutsen ae8f689388 Lazily load system_health and hardware integration platforms (#174325)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 10:45:07 -04:00
Allen Porter 05553090b9 Strict port matching for network URL helpers (#173657)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-20 10:29:31 -04:00
Michael 926d8c9129 Fix immich integration setup (#174344) 2026-06-20 16:12:15 +02:00
Raphael Hehl 9bd6cfa924 Bump uiprotect to 13.4.0 (#174315) 2026-06-20 11:42:13 +02:00
Mick Vleeshouwer 689abbd943 Link to documentation for Overkiz local API setup (#174264) 2026-06-20 07:20:31 +02:00
Franck Nijhof 7e62ff35fd 2026.6.4 (#174308) 2026-06-19 22:57:25 +02:00
Ronald van der Meer 0497d455fc Bump python-duco-connectivity to 0.7.1 (#174306) 2026-06-19 22:03:37 +02:00
Lukas 92238e5e47 bump to pooldose api 0.9.6 (#174310) 2026-06-19 21:54:24 +02:00
TheJulianJES 0a5c1ef8eb Bump dsmr-parser to 1.9.0 (#174307) 2026-06-19 18:59:16 +00:00
TheJulianJES 3362d66ffb Bump dsmr-parser to 1.9.0 (#174307) 2026-06-19 20:58:06 +02:00
Michael a88093afd2 Bump aioimmich to 0.15.0 (#174305) 2026-06-19 18:55:13 +00:00
J. Nick Koston 9fd90283b3 Bump pyroute2 to 0.9.6 (#172521) 2026-06-19 18:55:11 +00:00
Michael 09317ed51b Bump aioimmich to 0.15.0 (#174305) 2026-06-19 20:54:26 +02:00
Franck Nijhof 3159242b68 Bump version to 2026.6.4 2026-06-19 18:26:51 +00:00
Simone Chemelli f5985b03e4 Remove event entities from virtual groups for Alexa Devices (#174303) 2026-06-19 18:25:53 +00:00
Franck Nijhof 040a3bcb10 Cast Xiaomi Gateway sub-device firmware version to string (#174294) 2026-06-19 18:25:52 +00:00
Bram Kragten 5aaf6704a9 Update frontend to 20260527.7 (#174285) 2026-06-19 18:25:50 +00:00
Franck Nijhof 2fcd00b301 Fix econet fan mode select returning int instead of str (#174274) 2026-06-19 18:25:48 +00:00
Franck Nijhof 0b439e6e4c Re-raise non-401 HTTP errors in Tank Utility setup (#174272) 2026-06-19 18:25:46 +00:00
Franck Nijhof d13a5b7eec Handle Weheat API errors during config flow entry creation (#174234) 2026-06-19 18:25:45 +00:00
Franck Nijhof de49716ec1 Skip fill sensor for Rituals diffusers without fill data (#174232) 2026-06-19 18:25:43 +00:00
Franck Nijhof 67c6921847 Include Sonos favorites in source list and gate SELECT_SOURCE dynamically (#174231) 2026-06-19 18:25:41 +00:00
Franck Nijhof 002b638013 Fix Elk-M1 reconfigure failing when entry has no unique_id (#174230) 2026-06-19 18:25:39 +00:00
Josef Zweck 4b60ed30c7 Update max prebrew numbers in lamarzocco (#174204) 2026-06-19 18:25:37 +00:00
Simone Chemelli 6f1deec507 Bump aiocomelit to 2.0.7 (#174183) 2026-06-19 18:25:35 +00:00
Franck Nijhof 227ba8032f Bump aiocomelit to 2.0.5 (#173800) 2026-06-19 18:25:34 +00:00
Bernát Gábor 7da3ecf033 Cast SwitchBot Cloud device sw_version to string (#174167) 2026-06-19 18:14:20 +00:00
Simone Chemelli 8b293a18d3 Bump aioamazondevices to 14.1.3 (#174158) 2026-06-19 18:14:18 +00:00
Simone Chemelli 3dc077f280 Fix stale routine entities removal for Alexa Devices (#174138) 2026-06-19 18:14:16 +00:00
Simone Chemelli d368a95323 Bump aioamazondevices to 14.1.2 (#174114)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-06-19 18:14:14 +00:00
Franck Nijhof 495f41a742 Filter out closed sites in Amber Electric config flow (#174084) 2026-06-19 18:12:01 +00:00
Franck Nijhof 9f7529706d Cast system version to string for simplisafe device model (#174081) 2026-06-19 18:11:59 +00:00
Franck Nijhof 8f6b1dff9c Bump opower to 0.18.5 (#174080) 2026-06-19 18:11:58 +00:00
Franck Nijhof f260a1bb7b Retry webdav setup on connection errors (#174077) 2026-06-19 18:11:56 +00:00
Franck Nijhof 157e137ea9 Cast numeric firmware to string for squeezebox hw_version (#174076) 2026-06-19 18:11:54 +00:00
Jan Bouwhuis b2e1a296d4 Fix MQTT discovery option unjustly added to entry data (#174073) 2026-06-19 18:11:52 +00:00
Franck Nijhof e78a2c9f01 Add missing subentry flow translations in scrape (#174006) 2026-06-19 18:11:50 +00:00
Franck Nijhof 9011225a42 Add missing flow form field translations in tractive (#174005) 2026-06-19 18:11:48 +00:00
Franck Nijhof 81ef9b99c2 Add missing flow form field translation in iskra (#174004) 2026-06-19 18:11:46 +00:00
Franck Nijhof fa0207698a Add missing flow form field translations in ecobee (#174002) 2026-06-19 18:11:44 +00:00
Franck Nijhof 275883a95a Add missing flow form field translation in airvisual (#174000) 2026-06-19 18:11:42 +00:00
Franck Nijhof ebd252a225 Fix flow form field translations in modem_callerid (#173999) 2026-06-19 18:11:40 +00:00
Franck Nijhof 2de6c0281d Fix flow form field translation key in sia (#173998) 2026-06-19 18:11:38 +00:00
Franck Nijhof f95671f0f4 Fix flow form field translations in local_calendar (#173997) 2026-06-19 18:11:36 +00:00
Franck Nijhof 5fcae9ecf7 Add missing flow form field translation in honeywell (#173996) 2026-06-19 18:11:35 +00:00
Franck Nijhof 0b86cfa496 Add missing flow form field translation in otp (#173994) 2026-06-19 18:11:33 +00:00
Franck Nijhof d45bdf37d5 Fix flow form field translations in hlk_sw16 (#173993) 2026-06-19 18:11:31 +00:00
Franck Nijhof a9205df4a3 Fix flow form field translation keys in here_travel_time (#173992) 2026-06-19 18:11:29 +00:00
John Pettitt c333744fd2 Add API_GEN_4 support to Subaru integration (#173956) 2026-06-19 18:11:27 +00:00
Assaf Inbal 2f64601990 Bump pyituran to 0.1.6 (#173833) 2026-06-19 18:11:25 +00:00
Franck Nijhof cbd35be271 Bump pyrainbird to 6.3.1 (#173786) 2026-06-19 18:07:34 +00:00
Franck Nijhof 92ac14f42a Bump aioamazondevices to 14.0.4 (#173761) 2026-06-19 18:07:32 +00:00
Franck Nijhof 45e568c73e Add missing flow form field translation in snooz (#173760) 2026-06-19 18:07:30 +00:00
Franck Nijhof a121b8d146 Add missing flow form field translation in motionblinds_ble (#173758) 2026-06-19 18:07:28 +00:00
Franck Nijhof a2bd7d5857 Add missing flow form field translation in blink (#173756) 2026-06-19 18:07:26 +00:00
Franck Nijhof a6e639377b Fix options flow form field translation key in plaato (#173755) 2026-06-19 18:07:24 +00:00
Franck Nijhof 2147a851c3 Fix flow form field translation key in meteoclimatic (#173754) 2026-06-19 18:07:22 +00:00
Franck Nijhof 9034afd29e Add missing flow form field translation in gogogate2 (#173753) 2026-06-19 18:07:20 +00:00
Franck Nijhof 5c5d259f63 Add missing flow form field translation in melnor (#173752) 2026-06-19 18:07:18 +00:00
Franck Nijhof cc16a9086f Fix flow form field translation key in lookin (#173751) 2026-06-19 18:07:16 +00:00
Franck Nijhof 5d1f8f770c Add missing flow form field translation in lacrosse_view (#173750) 2026-06-19 18:07:14 +00:00
Franck Nijhof cea6b9b0b7 Add missing flow form field translations in islamic_prayer_times (#173749) 2026-06-19 18:07:12 +00:00
G Johansson 77f7c26399 Bump lxml to 6.1.1 (#173748) 2026-06-19 18:07:10 +00:00
Franck Nijhof 8e0a5b258c Add missing flow form field translation in hue (#173747) 2026-06-19 18:07:08 +00:00
Franck Nijhof f8b942818c Add missing flow form field translation in flux_led (#173746) 2026-06-19 18:07:06 +00:00
Franck Nijhof 9660d12c77 Add missing flow form field translation in tuya (#173745) 2026-06-19 18:07:04 +00:00
Franck Nijhof 7f1533a6e1 Skip Miele fan set_percentage when already at the target step (#173725) 2026-06-19 18:07:02 +00:00
J. Nick Koston 336d9e9126 Bump aiodiscover to 3.3.2 (#173705) 2026-06-19 18:07:00 +00:00
J. Nick Koston 1dde2d918e Bump aiodiscover to 3.3.1 (#172882) 2026-06-19 18:06:58 +00:00
Åke Strandberg 34a6b0ca61 Add missing Miele dishwasher codes (#173662) 2026-06-19 17:50:28 +00:00
Raman Gupta e92286ecd6 Stop validating # of slots in zwave_js.set_credential action (#173644) 2026-06-19 17:50:26 +00:00
Franck Nijhof 82bb9748db Avoid leaking Immich API key in error logs (#173541) 2026-06-19 17:50:24 +00:00
Rob Bierbooms 68e5e58a1c Solve issue with double slash in url when writing data to InfluxDB (#173395) 2026-06-19 17:50:22 +00:00
johanzander f3e8403e9a Fix Growatt total_output_power 1000x too low with V1 API (#172474)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-19 17:50:20 +00:00
Franck Nijhof 3f5a7d79c5 Handle BatteryNotification in Z-Wave JS notification events (#174282) 2026-06-19 19:43:21 +02:00
Franck Nijhof e87d896caf Cast Xiaomi Gateway sub-device firmware version to string (#174294) 2026-06-19 19:42:52 +02:00
Simone Chemelli 4a335bf4ef Remove event entities from virtual groups for Alexa Devices (#174303) 2026-06-19 19:42:15 +02:00
Bruno Pantaleão Gonçalves 7e9dc12dc5 Add live activity token retention, notify usage and clean up cycle to mobile_app (#172928) 2026-06-19 18:19:05 +02:00
Abílio Costa 3c7774d9b8 Simplify target helper callback comments (#174293) 2026-06-19 17:03:22 +02:00
epenet 4d7fc228df Add tests for aftership services (#174280) 2026-06-19 16:53:31 +02:00
Paul Bottein 71058c7a0a Mark Yoto documentation quality scale rules as done (#174292) 2026-06-19 16:50:59 +02:00
Bram Kragten 6bb3725d96 Update frontend to 20260527.7 (#174285) 2026-06-19 15:50:28 +02:00
Ronald van der Meer 97d1095bb2 Bump python-duco-connectivity to 0.7.0 (#174283) 2026-06-19 15:40:36 +02:00
Franck Nijhof b6c7104b18 Fix Elk-M1 reconfigure failing when entry has no unique_id (#174230) 2026-06-19 15:15:53 +02:00
Franck Nijhof ef36d99048 Include Sonos favorites in source list and gate SELECT_SOURCE dynamically (#174231) 2026-06-19 15:14:39 +02:00
Franck Nijhof 938b16b7cc Handle Weheat API errors during config flow entry creation (#174234) 2026-06-19 15:13:05 +02:00
Franck Nijhof dd32682215 Re-raise non-401 HTTP errors in Tank Utility setup (#174272) 2026-06-19 15:12:18 +02:00
Franck Nijhof fb2254a89f Fix econet fan mode select returning int instead of str (#174274) 2026-06-19 14:51:39 +02:00
smartcircuits f47a540a48 Add WattWächter Plus integration (#165238)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-19 13:36:51 +02:00
Erwin Douna b06bfe1740 MELCloud Home add frost and overheat protection sensors (#174200) 2026-06-19 13:10:11 +02:00
epenet 3b25b4cfa6 Add service helper to get a single loaded config entry (#174190) 2026-06-19 13:01:07 +02:00
epenet 1a363e05aa Use service helper in energyzero (#174261) 2026-06-19 12:42:29 +02:00
Jonathan Horowitz 876ffe3b6c Add Chef iQ integration (#174171)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 12:41:57 +02:00
Maciej Bieniek 35a2dcb222 Bump nextdns to 5.0.1 (#174268) 2026-06-19 12:34:11 +02:00
Ajinkya Gokhale afed9c71c4 Add new energieleser integration (#172464)
Co-authored-by: Amit Krishna <218109745+amitkio@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-19 12:29:56 +02:00
Yardian Support 21899662d1 Refine Yardian zone switches (#173177)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-19 11:57:42 +02:00
Christian Lackas 249e1d3548 Bump homematicip to 2.13.1 (#174266) 2026-06-19 11:42:32 +02:00
Stefan Agner feeaad7894 Use http ApiConfig instead of parsing raw http config in hassio (#174265)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 11:40:55 +02:00
Franck Nijhof b930ee62e5 Wrap cloud OAuth2 token refresh errors into proper exception types (#174233) 2026-06-19 09:18:23 +02:00
renovate[bot] 699299a8e8 Update ruff to v0.15.17 (#174246) 2026-06-19 09:17:35 +02:00
Brett Adams a33a92982a Add Teslemetry command quota sensor (#173954)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-06-19 08:49:57 +02:00
Erwin Douna 4547abc00a MELCloud Home add constant in diagnostics (#174219) 2026-06-19 08:41:48 +02:00
Franck Nijhof 855c2339af Skip fill sensor for Rituals diffusers without fill data (#174232) 2026-06-19 08:39:35 +02:00
renovate[bot] 5e15c3aeb3 Update infrared-protocols to 6.1.0 (#174247)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-19 06:56:30 +02:00
Paul Bottein c001fd12fb Bump yoto-api to 4.3.1 (#174241) 2026-06-19 06:54:42 +02:00
Sarah Seidman ff87c544d3 Add leak alerts to Droplet integration (#173634) 2026-06-18 22:00:54 +02:00
Paul Bottein 4134e83c6c Add ambient color selects to Yoto (#173909)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-18 21:54:13 +02:00
Justin Mutter 3533d7eb77 Add tests for the AquaLogic integration (#173548) 2026-06-18 21:41:53 +02:00
Paul Bottein 32f15aaa87 Add display brightness and max volume numbers to Yoto (#173968) 2026-06-18 21:38:30 +02:00
John Hillery 39e7b664a0 Rewrite Nexia integration platform tests with a mock Nexia library (#172584) 2026-06-18 21:33:24 +02:00
Martin Claesson 0d80806302 Add Kiosker blackout details sensors (#173306) 2026-06-18 21:31:06 +02:00
Martin Claesson 4eb2089173 Add Kiosker blackout details binary sensor (#173303) 2026-06-18 21:30:36 +02:00
Franck Nijhof 8f0f0e3324 Bump epicstore-api to 0.1.9 (#173939) 2026-06-18 20:59:17 +02:00
Onero-testdev ba33e53409 Add SwitchBot Standing Fan switch platform (#173579)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 20:53:06 +02:00
Mick Vleeshouwer c8933ada07 Use device.states and device.attributes helpers in Overkiz (#173281) 2026-06-18 20:35:19 +02:00
some-random-climber 29a5f7a9db Use hass.config_entries.async_setup in ps4 migration tests (#174120) 2026-06-18 20:31:43 +02:00
Mick Vleeshouwer 92accdd4d3 Add Rexel (OAuth2/PKCE) support to Overkiz (#173604) 2026-06-18 20:30:02 +02:00
J. Diego Rodríguez Royo b41636ddd4 Bump aiohomeconnect to 0.38.0 (#174228) 2026-06-18 20:28:12 +02:00
Tom 3dadf078de Update ProxmoxVE quality scale (#174123) 2026-06-18 20:18:54 +02:00
BrettLynch123 0b7a134fa6 Add max charge and discharge power sensors to Powerwall (#172971) 2026-06-18 20:15:58 +02:00
Erwin Douna 1889597fe4 aiomelclouhome bump 0.1.8 (#174225) 2026-06-18 20:12:46 +02:00
Oscar Calvo 2f87887396 Fix ccm15 setup abort (blocking httpx client) and non-contiguous AC slots (#173652) 2026-06-18 20:11:03 +02:00
Ariel Ebersberger 7423281768 Use default cosign-release for pinned cosign-installer version (#174216) 2026-06-18 19:56:51 +02:00
Raphael Hehl 03b533e3be Track public devices websocket health for UniFi Protect public-API entities (#174191) 2026-06-18 19:43:41 +02:00
Brett Adams 0f1017d580 Add repair issues for Teslemetry vehicle metadata problems (#174102)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 19:19:00 +02:00
Harvey d466fa593d Use reachability diagnostics for __init__.py in HueBLE (#174140) 2026-06-18 18:38:34 +02:00
Erwin Douna aed7e460e3 Bump aiomelcloudhome to 0.1.7 (#174210) 2026-06-18 17:36:49 +02:00
Raphael Hehl c9f233005e Bump uiprotect to 13.3.0 (#174217) 2026-06-18 17:32:33 +02:00
Manu 8f367a3f28 Raise repair issue for under-voltage events in Raspberry Pi power supply checker (#174127) 2026-06-18 17:28:20 +02:00
Simone Chemelli 66716e94c6 Add announcements and communications switches to Alexa Devices (#174132) 2026-06-18 17:25:30 +02:00
Brett Adams 15aaddf4ac Add command error-path tests to Teslemetry (#174163)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 17:23:27 +02:00
Arcadiy Ivanov 9decee350f Add entity-based location tracking to NWS integration (#172310)
Co-authored-by: Ariel Ebersberger <31776703+justanotherariel@users.noreply.github.com>
2026-06-18 17:21:06 +02:00
Erwin Douna 51b5c5dcc8 MELCloud Home add stale devices feature (#173589)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-18 17:06:53 +02:00
Erwin Douna ffd08265bd MELCloud Home add reauth flow (#173502) 2026-06-18 16:59:41 +02:00
epenet f8ce98ed39 Avoid core constant to access remote data in here_travel_time (#174212) 2026-06-18 15:58:33 +02:00
epenet b6d0525a7c Remove single-use constant in weatherflow_cloud (#174211) 2026-06-18 15:44:22 +02:00
jegoforth 7d1c67d930 Add Tuya fixture for register booster fan (#173959) 2026-06-18 15:43:14 +02:00
acuszka a35cb62a9c Add Tuya fixture for GIEX watering timer (#174145)
Co-authored-by: acuszka <acuszka@users.noreply.github.com>
2026-06-18 15:42:39 +02:00
Raphael Hehl bffc677454 Remove UniFi Protect Doorlock support (#174196) 2026-06-18 15:23:14 +02:00
Joost Lekkerkerker 73e47ff537 Add Switchbot art frame icons (#174206) 2026-06-18 14:52:12 +02:00
Josef Zweck d81cb63950 Update max prebrew numbers in lamarzocco (#174204) 2026-06-18 14:40:25 +02:00
Brett Adams ca559c01c0 Raise ServiceValidationError for unmatched Teslemetry service devices (#174109)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 14:36:07 +02:00
Raphael Hehl 750adbc7ac Bump uiprotect to 13.2.0 (#174202) 2026-06-18 14:35:56 +02:00
Simone Chemelli 4719a015c6 Bump aioshelly to 13.26.2 (#174199) 2026-06-18 15:28:26 +03:00
Maciej Bieniek c5f1bdc446 Rename Advanced settings to Additional settings in Brother (#174198) 2026-06-18 14:21:03 +02:00
Erwin Douna ae3041d71f Bump aiomelcloudhome 0.1.6 (#174189) 2026-06-18 13:31:14 +02:00
Samuel Xiao 4485ec0bcc Switchbot Cloud: Add Service AI for Art Frame(UploadImage) (#172888) 2026-06-18 13:28:32 +02:00
Oscar Calvo a5c89863d3 Bump py_ccm15 to 0.6.0 (#174099) 2026-06-18 13:00:13 +02:00
Abílio Costa 3d8cb1c615 Add button platform to Edifier Infrared (#174136) 2026-06-18 11:51:01 +01:00
Simone Chemelli 857250a9f0 Bump aiocomelit to 2.0.7 (#174183) 2026-06-18 11:54:47 +02:00
Maciej Bieniek 5bd09e858a Bump imgw_pib to 2.4.0 (#174180) 2026-06-18 10:42:32 +02:00
Bernát Gábor 409ac3fd82 Cast SwitchBot Cloud device sw_version to string (#174167) 2026-06-18 09:38:45 +02:00
Erik Montnemery 605f69f056 Improve tests of helpers.trigger.extract_devices/entities (#172407) 2026-06-18 09:36:54 +02:00
Erik Montnemery 2f9d39827d Open repair issue when deprecated trigger behavior is used (#173259)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-06-18 09:36:02 +02:00
Paulus Schoutsen c268610f7d Add radio frequency entity name translation (#174173)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 09:34:02 +02:00
Robert Resch c6de1e9c5d Fix summary for aw check requirements (#174160) 2026-06-18 09:31:59 +02:00
Ronald van der Meer cd872c4b1c Fix Duco error placeholders and test typing (#174177) 2026-06-18 09:27:05 +02:00
Franck Nijhof c7dd266d07 Suppress SMTPException from quit() during SMTP notify retry (#174104) 2026-06-18 09:25:23 +02:00
Ronald van der Meer 0adc26cec8 Add ventilation state select to Duco box nodes (#173807)
Co-authored-by: Erwin Douna <e.douna@gmail.com>
2026-06-18 09:10:40 +02:00
Simone Chemelli 645caea76e Fix stale routine entities removal for Alexa Devices (#174138) 2026-06-18 08:20:56 +02:00
Paulus Schoutsen 944301a9e0 Raise ConfigEntryNotReady on Ollama connection errors (#174175)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-18 08:19:45 +02:00
jasonjhofmann 7a1e91e47a Add network MAC connection to AsusWRT router (#173679) 2026-06-18 07:09:12 +02:00
Paulus Schoutsen 64c6ef4a74 Document uv upgrade workaround in AGENTS.md (#174176) 2026-06-18 07:03:35 +02:00
Paulus Schoutsen 4d7a2358fa Add API to query radio frequency information (#173134)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-17 22:38:56 -04:00
Simone Chemelli 9430e84506 Bump aioamazondevices to 14.1.3 (#174158) 2026-06-17 23:46:50 +02:00
Jan Čermák ebe80afbb8 Remove radio firmware version from device info in homeassistant_yellow (#174124) 2026-06-17 23:36:09 +02:00
Jan Čermák 8bd19b6a30 Add Raspberry Pi Firmware update entity (#172929) 2026-06-17 23:36:01 +02:00
Ville Skyttä 34434e8508 Docstring and comment grammar etc fixes (#174144) 2026-06-17 23:06:10 +02:00
Manu b26fcc523e Fix tests in Onboarding integration (#174147) 2026-06-17 22:11:55 +02:00
Franck Nijhof f045b68493 Cast numeric firmware to string for squeezebox hw_version (#174076) 2026-06-17 21:31:43 +02:00
Manu 48ba38f5f5 Refactor Raspberry Pi Power Checker integration (#174135) 2026-06-17 18:33:26 +02:00
Nikolai Rahimi 44f5ad84b9 Bump mitsubishi-comfort to 0.3.2 (#174100)
Co-authored-by: Nikolai Rahimi <nikolairahimi@users.noreply.github.com>
2026-06-17 16:22:08 +02:00
some-random-climber 7330c25685 Remove battery_level attribute from icloud device tracker (#174117) 2026-06-17 16:09:15 +02:00
Leo Periou e59086d299 Change myneomitis codeowner (#174130) 2026-06-17 15:54:54 +02:00
Manu 27f44f83fb Add reauthentication flow to SMTP (#174092)
Co-authored-by: Erwin Douna <e.douna@gmail.com>
2026-06-17 13:59:43 +02:00
Simone Chemelli 05c94fa578 Bump aioamazondevices to 14.1.2 (#174114)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-06-17 13:48:42 +02:00
Tom 64b608b439 Set parallel updates for ProxmoxVE buttons (#174125) 2026-06-17 13:33:13 +02:00
Dellle c5b90cf8d1 Bump elevenlabs to 2.51.0 (#174112)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-17 13:11:30 +02:00
Marc Hörsken 31259725ec Add support for slat-based WMS covers like venetian blinds (#145005)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-06-17 13:10:53 +02:00
Jan Bouwhuis 8ad7c12405 Fix MQTT discovery option unjustly added to entry data (#174073) 2026-06-17 12:16:29 +02:00
Martin Hjelmare 66f0f170b7 Add pylint naive_now checker (#174053)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2026-06-17 11:44:42 +02:00
some-random-climber da91865130 Remove battery_level attribute from starline device tracker (#174118) 2026-06-17 11:10:36 +02:00
Mark 3437bcfb42 Add Rabbit Air air quality sensor (#172993) 2026-06-17 10:49:53 +02:00
Åke Strandberg 1fd5d0a5fd Aqvify reaches Platinum tier (#174111) 2026-06-17 10:49:41 +02:00
Dellle 404c58435a Bump sentence-stream to 1.3.0 (#174113) 2026-06-17 10:48:42 +02:00
Erik Montnemery 7aba1daa16 Adjust language in condition history manager comments (#174106) 2026-06-17 09:23:32 +02:00
Jan Bouwhuis 12397cc4c1 Rename advanced settings/options in MQTT subentry translation strings (#174071) 2026-06-17 09:22:25 +02:00
Josef Zweck 73cdf7e067 Revert "Add pyserial-asyncio and pyserial-asyncio-fast to deprecated packages" (#174110) 2026-06-17 09:18:44 +02:00
Franck Nijhof 4e2cfecd96 Filter out closed sites in Amber Electric config flow (#174084) 2026-06-17 09:18:19 +02:00
Åke Strandberg 4625f7de27 Aqvify has reached gold tier (#174018) 2026-06-17 09:11:42 +02:00
Brett Adams 53a1db405c Improve test coverage of Teslemetry offline polling (#174108)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 08:47:08 +02:00
Paul Bottein ff7262d36f Fix Yoto quality scale comments (#174088) 2026-06-17 08:43:08 +02:00
tronikos 54feb95b76 Gemini: Update TTS model to gemini-3.1 and adjust configuration options (#174094) 2026-06-17 08:42:00 +02:00
epenet d9e2b49c0c Fix incorrect use of entity component constants in template (#172532) 2026-06-17 07:55:57 +02:00
renovate[bot] 4f9051464d Update cryptography to 48.0.1 (#174096) 2026-06-17 07:34:00 +02:00
Paulus Schoutsen 87894fd623 Activate venv before running python commands (#174093) 2026-06-17 07:32:22 +02:00
Franck Nijhof 34a70a9210 Clean up deprecated solar_rising entity from sun integration (#174079) 2026-06-17 06:44:16 +02:00
Paulus Schoutsen c9fb6a13fb Remove stale requirements_test_all.txt reference (#174095) 2026-06-17 05:08:20 +02:00
Franck Nijhof 28076bcad6 2026.6.3 (#173633) 2026-06-12 21:49:56 +02:00
Franck Nijhof ff25428e56 Fix undefined DOMAIN in image upload tests 2026-06-12 19:12:56 +00:00
Franck Nijhof 608acd422f Bump version to 2026.6.3 2026-06-12 18:33:03 +00:00
Franck Nijhof c860e83ec9 Disambiguate duplicate channel names in LG Netcast source list (#173560) 2026-06-12 18:32:03 +00:00
Franck Nijhof c9f3f4a265 Sort aliases in LLM prompts for stable prefix caching (#173558) 2026-06-12 18:32:01 +00:00
Franck Nijhof e346a801d1 Return enum values from config_entry_attr template function (#173554) 2026-06-12 18:31:59 +00:00
Franck Nijhof a5c193931f Fix Rituals Perfume Genie sw_version dict passed to device registry (#173552) 2026-06-12 18:31:57 +00:00
Franck Nijhof d273350db1 Suppress InsecureKeyLengthWarning in HTML5 push notifications (#173551) 2026-06-12 18:31:55 +00:00
Franck Nijhof 45f27b8b6e Fix Yale Smart Living panic button unique_id for multiple hubs (#173547) 2026-06-12 18:31:53 +00:00
Franck Nijhof d3208a420f Convert OpenGarage sw_version to string for device registry (#173546) 2026-06-12 18:31:51 +00:00
Franck Nijhof d0d35e380f Convert RainMachine hw_version to string for device registry (#173545) 2026-06-12 18:31:49 +00:00
Franck Nijhof 2735e58d7f Convert JPEG-incompatible image modes to RGB in image upload thumbnail generation (#173538) 2026-06-12 18:31:47 +00:00
Franck Nijhof ad3eab80c3 Fix iCloud RuntimeError on unload by running cancel in executor (#173537) 2026-06-12 18:31:45 +00:00
Franck Nijhof 18e5d284b4 Fix Hue grouped light icon by adding translation_key (#173536) 2026-06-12 18:31:43 +00:00
Franck Nijhof e5052eaf44 Fix Hue light level sensor crash on None value (#173532) 2026-06-12 18:31:41 +00:00
Ernst Klamer 62c2e8d2fd Bump bthome-ble to 3.23.4 (#173526) 2026-06-12 18:31:39 +00:00
Bram Kragten 1f505067dd Update frontend to 20260527.6 (#173522) 2026-06-12 18:31:37 +00:00
Stefan Agner 72875b3b5e Refresh preferred Thread border agent address on OTBR reconnect (#173508)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: puddly <32534428+puddly@users.noreply.github.com>
2026-06-12 18:31:35 +00:00
renovate[bot] 3be755e496 Update hassil to 3.7.0 (#173484)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-12 18:31:33 +00:00
Michael Hansen 5285798052 Bump hassil to 3.6.0 (#173031) 2026-06-12 18:31:31 +00:00
Diogo Gomes da49e37946 Bump pytrydan to 1.0.2 (#173479) 2026-06-12 18:28:13 +00:00
Simone Chemelli 2f9de98f2d Bump aioamazondevices to 14.0.3 (#173478) 2026-06-12 18:28:09 +00:00
starkillerOG 383a6426fc Bump reolink_aio to 0.21.0 (#173477) 2026-06-12 18:28:06 +00:00
Robert Resch 5ed60cd057 Revert "Unify query token auth in http views" (#173466) 2026-06-12 18:28:04 +00:00
Tom Cassady a1250b7bfb Fix UniFi Protect ufp_set debug log printing UndefinedType for translation-key entities (#173460) 2026-06-12 18:28:02 +00:00
Simone Chemelli 240e5219ad Redact more fields in diagnostics for Alexa devices (#173446) 2026-06-12 18:28:00 +00:00
Simone Chemelli 418f352ce7 Change update interval for UptimeRobot (#173435) 2026-06-12 18:27:58 +00:00
Jan Bouwhuis 599967b1d8 Do not enable MQTT entities though discovery that were disabled by user (#173404) 2026-06-12 18:27:56 +00:00
Nikolai Rahimi ad82729357 Add debug logging for Mitsubishi Comfort polling failures (#173364) 2026-06-12 18:27:54 +00:00
Franck Nijhof 30d8bf4231 2026.6.2 (#173397) 2026-06-09 22:13:22 +02:00
Triggs 5436d8af9b Bump codecov/codecov-action from v6.0.1 to v7.0.0 (#173232)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2026-06-09 19:26:01 +00:00
epenet 88adf39ef3 Use explicit DOMAIN import in mqtt tests (#173093) 2026-06-09 19:20:12 +00:00
Franck Nijhof 14b14bddf1 Bump version to 2026.6.2 2026-06-09 18:41:21 +00:00
Michael Hansen 3c4a30be6b Only allow specific protocols with ffmpeg in Wyoming satellite announce (#173381)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-09 18:34:34 +00:00
Joost Lekkerkerker 2988eb4b19 Set Zinvolt max output to 2kW if unlocked (#173367) 2026-06-09 18:34:32 +00:00
Nikolai Rahimi 00eef14558 Bump mitsubishi-comfort to 0.3.1 (#173362) 2026-06-09 18:34:30 +00:00
Joost Lekkerkerker d02516dd09 Handle unavailable Zinvolt devices better (#173359) 2026-06-09 18:34:28 +00:00
Jan Bouwhuis aabb6b3d04 Fix reload fails when MQTT entry is not set up (#173335)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2026-06-09 18:34:26 +00:00
tronikos 50c2c7c4bc Bump opower to 0.18.4 (#173323) 2026-06-09 18:34:24 +00:00
Joakim Plate e81dd426bb Ensure we provide strings to vol.In for philips js (#173313) 2026-06-09 18:34:22 +00:00
Michael Hansen c4c569c181 Mitigate TTS ResultStream leak in pipeline (#173290) 2026-06-09 18:34:20 +00:00
Simone Chemelli 6182426132 Bump renault-api to 0.5.12 (#173289) 2026-06-09 18:34:18 +00:00
Martin Hjelmare a073cc4f7d Fix homeassistant hardware unique id migration (#173258) 2026-06-09 18:34:16 +00:00
Mark Purcell 07ddc08d84 Bump pydaikin to 2.18.1 (#173249) 2026-06-09 18:34:14 +00:00
Bram Kragten 17673dcf55 Update frontend to 20260527.5 (#173236) 2026-06-09 18:34:12 +00:00
starkillerOG a864bc1c80 Adjust ONVIF event fallbacks for battery cameras (#173214)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-09 18:34:10 +00:00
Shay Levy a15d80daa2 Fix Shelly virtual component unit retrieval (#173183) 2026-06-09 18:34:08 +00:00
Joost Lekkerkerker e123b29258 Have Plugwise handle unavailable temperature measurements (#173173) 2026-06-09 18:34:06 +00:00
J. Nick Koston 5669a7b602 Wait for Shelly bluetooth proxy connection at startup (#173165) 2026-06-09 18:34:05 +00:00
J. Nick Koston fe358a4a1f Wait for ESPHome bluetooth proxy connection at startup (#173164) 2026-06-09 18:34:03 +00:00
mvn23 3a93d6370b Ensure opentherm_gw boiler and thermostat manufacturers are strings (#173162) 2026-06-09 18:34:01 +00:00
Bouwe Westerdijk 89576f01e6 Bump plugwise to v1.11.4 (#173147) 2026-06-09 18:33:59 +00:00
tronikos f51895b0c9 Bump opower to 0.18.3 (#173141) 2026-06-09 18:30:18 +00:00
Joakim Plate d0dcbfadaa Switch to active scanner for gardena (#173062) 2026-06-09 18:30:16 +00:00
Simone Chemelli 5e0d3627c2 Improve and complete exception handling for Alexa Devices (#173053) 2026-06-09 18:30:14 +00:00
Diogo Gomes 80c90732a3 Bump pytrydan to v1.0.1 (#173047) 2026-06-09 18:30:12 +00:00
Yardian Support 16eca3909a Bump pyyardian to 1.4.0 (#173020)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-06-09 18:30:10 +00:00
peteS-UK 1b471da31f Update PARALLEL_UPDATES to 0 for Squeezebox platforms (#172906) 2026-06-09 18:30:08 +00:00
Franck Nijhof 7391209f48 2026.6.1 (#173122) 2026-06-05 22:25:21 +02:00
Franck Nijhof 0683344079 Bump version to 2026.6.1 2026-06-05 18:02:28 +00:00
Joakim Plate 0b77cf9e4b Fix process advertisement for active scans (#173116) 2026-06-05 18:02:10 +00:00
Noah Husby e0a87d966d Bump aiostreammagic to 2.13.2 (#173114) 2026-06-05 18:02:08 +00:00
Paul Bottein af53d2d082 Bump yoto-api to 3.1.6 (#173104) 2026-06-05 18:02:06 +00:00
Joost Lekkerkerker da7fa80e75 Bump pySmartThings to 4.0.1 (#173092) 2026-06-05 18:02:04 +00:00
Robert Resch 6cf1e7fb48 Bump wheels to 2026.06.0 (#173089) 2026-06-05 18:02:02 +00:00
Jan Bouwhuis 18fa0ac47d Create certificate files before trying to migrate the MQTT config entry (#173087)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-05 18:01:59 +00:00
Robert Resch 4afced1a49 Unify query token auth in http views (#173082) 2026-06-05 18:01:57 +00:00
Ronald van der Meer 74a4471160 Fix Duco mode end time sensor name (#173045) 2026-06-05 18:01:55 +00:00
Franck Nijhof 857a3de066 Convert LinkPlay configuration_url to string for device registry (#173034) 2026-06-05 18:01:53 +00:00
Erwin Douna 06bf2ff6de Portainer extend timeout for disk space coordinator (#173032) 2026-06-05 18:01:51 +00:00
G Johansson 6a5dae9cc3 Bump holidays to 0.98 (#173029) 2026-06-05 18:01:49 +00:00
Erik Montnemery 475ebbc028 Fix person in_zones propagation from scanner in home zone (#173007) 2026-06-05 18:01:47 +00:00
Maciej Bieniek 6e7643e997 Bump imgw_pib to 2.2.2 (#172999) 2026-06-05 18:01:45 +00:00
Erik Montnemery 1f954cda0d Improve person tests (#172997) 2026-06-05 18:01:43 +00:00
Jan Bouwhuis 2961fca1b1 Fix value template in MQTT Fan and Siren subentry setup (#172980) 2026-06-05 18:01:41 +00:00
Abílio Costa 106b189206 Bump idasen-ha to 2.7.0 (#172962) 2026-06-05 18:01:39 +00:00
Nikolai Rahimi 0387034f4e Fix Mitsubishi Comfort devices skipped due to unresolved local address (#172959) 2026-06-05 18:01:37 +00:00
starkillerOG f81b6abca9 Add more Reolink diagnostic info (#172945) 2026-06-05 18:01:35 +00:00
Thomas55555 43f6e7977e Bump aioautomower to 2.7.6 (#172937) 2026-06-05 18:01:33 +00:00
Samuel Xiao 706fea4ec5 Switchbot Cloud: Fixed an issue where condition filtering for enabled Webhooks was abnormal (#172903) 2026-06-05 18:01:32 +00:00
Kurt Chrisford 74d23503e7 Bump actron-neo-api to 0.5.12 (#172902) 2026-06-05 18:01:30 +00:00
rjones-gentex 4ca5da2365 Upgrade HomeLink package, set integration type (#172371) 2026-06-05 17:50:58 +00:00
Eric Stern 53c77ae2ef Fix SleepIQ 401 storm by isolating client session cookies (#172276) 2026-06-05 17:50:56 +00:00
bk86a 14968f9d67 Fix Lyric sensor crash when next_period_time is None (#167831)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-05 17:50:54 +00:00
7627 changed files with 146454 additions and 108004 deletions
+2 -1
View File
@@ -24,7 +24,7 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
## 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.
- 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. If uv reports that no download was found for the required Python version, the environment is running an outdated version of uv; upgrade it with `curl -LsSf https://astral.sh/uv/install.sh | sh` and run `script/setup` again.
- .vscode/tasks.json contains useful commands used for development.
- After finishing a code session, run `uv run prek run --all-files` to check for linting and formatting issues.
@@ -53,3 +53,4 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
- 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.
- Keep comments concise. Prefer one short line stating the non-obvious constraint, or no comment at all.
- 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. Never add comments that justify a change by referencing what the code looked like before.
- Do not add section or divider comments (e.g. `# --- XYZ Triggers ---`) inside or outside of functions, since those can easily become stale and be misleading.
+6 -8
View File
@@ -38,7 +38,7 @@ jobs:
base_image_version: ${{ env.BASE_IMAGE_VERSION }}
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
@@ -102,7 +102,7 @@ jobs:
os: ubuntu-24.04-arm
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
@@ -245,7 +245,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
@@ -292,7 +292,7 @@ jobs:
contents: read
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
@@ -339,8 +339,6 @@ jobs:
steps:
- name: Install Cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
with:
cosign-release: "v2.5.3"
- name: Login to DockerHub
if: matrix.registry == 'docker.io/homeassistant'
@@ -471,7 +469,7 @@ jobs:
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
@@ -518,7 +516,7 @@ jobs:
HASSFEST_IMAGE_TAG: ghcr.io/home-assistant/hassfest:${{ needs.init.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
@@ -8,15 +8,11 @@ name: Check requirements (deterministic)
# 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"
pull_request:
types: [opened, synchronize, reopened]
paths:
- "requirements*.txt"
- "homeassistant/package_constraints.txt"
workflow_dispatch:
inputs:
pull_request_number:
@@ -40,7 +36,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python
+4 -4
View File
@@ -31,7 +31,7 @@
# - GITHUB_TOKEN
#
# Custom actions used:
# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
@@ -155,7 +155,7 @@ jobs:
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Checkout .github and .agents folders
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
sparse-checkout: |
@@ -404,7 +404,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Create gh-aw temp directory
@@ -1236,7 +1236,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
+10
View File
@@ -164,6 +164,9 @@ Read the JSON directly for the full schema. Key fields:
- `{{CHECK_DETAIL:<pkg>:<kind>}}``<icon> <one-line explanation>`
(the bullet's `- **<label>**:` prefix is already rendered; replace
only the placeholder).
- `{{SUMMARY}}` → the single top-of-comment summary line, present only
when at least one check needed resolving. Fill it **after** resolving
every check, based on the final cell verdicts (see Step 3).
Do not modify other content in `rendered_comment`, do not re-evaluate
deterministic checks, do not add or remove packages. If `needs_agent`
@@ -192,6 +195,13 @@ Replace every placeholder with the resolved value and emit
`<!-- requirements-check -->` marker. The PR target is already wired;
do not pass `item_number`.
If a `{{SUMMARY}}` placeholder is present, replace it last, once every
`{{CHECK_CELL:…}}` is resolved:
- `All requirements checks passed. ✅` — when every check cell across all
packages is `✅` or `☑️` (treat `—`/skipped as not a problem).
- `⚠️ Some checks require attention — see the details below.` — when any
cell is `⚠️` or `❌`.
## Check instructions
### Check kind: `repo_public`
+21 -21
View File
@@ -39,7 +39,7 @@ on:
env:
CACHE_VERSION: 3
MYPY_CACHE_VERSION: 1
HA_SHORT_VERSION: "2026.7"
HA_SHORT_VERSION: "2026.8"
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)
@@ -98,7 +98,7 @@ jobs:
skip_coverage: ${{ steps.info.outputs.skip_coverage }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Generate partial Python venv restore key
@@ -264,7 +264,7 @@ jobs:
&& github.event.inputs.audit-licenses-only != 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Register problem matchers
@@ -291,7 +291,7 @@ jobs:
&& github.event.inputs.audit-licenses-only != 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Run zizmor
@@ -318,7 +318,7 @@ jobs:
- script/hassfest/docker/Dockerfile
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Register hadolint problem matcher
@@ -341,7 +341,7 @@ jobs:
python-version: ${{ fromJson(needs.info.outputs.python_versions) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
@@ -469,7 +469,7 @@ jobs:
&& github.event.inputs.audit-licenses-only != 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install additional OS dependencies
@@ -512,7 +512,7 @@ jobs:
&& github.event.inputs.audit-licenses-only != 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python
@@ -548,7 +548,7 @@ jobs:
&& github.event.inputs.audit-licenses-only != 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python
@@ -576,7 +576,7 @@ jobs:
&& github.event_name == 'pull_request'
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Dependency review
@@ -603,7 +603,7 @@ jobs:
python-version: ${{ fromJson(needs.info.outputs.python_versions) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
@@ -654,7 +654,7 @@ jobs:
|| github.event.inputs.pylint-only == 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python
@@ -707,7 +707,7 @@ jobs:
&& (needs.info.outputs.tests_glob || needs.info.outputs.test_full_suite == 'true')
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python
@@ -758,7 +758,7 @@ jobs:
|| github.event.inputs.mypy-only == 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python
@@ -825,7 +825,7 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install additional OS dependencies
@@ -889,7 +889,7 @@ jobs:
group: ${{ fromJson(needs.info.outputs.test_groups) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install additional OS dependencies
@@ -1030,7 +1030,7 @@ jobs:
mariadb-group: ${{ fromJson(needs.info.outputs.mariadb_groups) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install additional OS dependencies
@@ -1179,7 +1179,7 @@ jobs:
postgresql-group: ${{ fromJson(needs.info.outputs.postgresql_groups) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install additional OS dependencies
@@ -1317,7 +1317,7 @@ jobs:
if: needs.info.outputs.skip_coverage != 'true'
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Download all coverage artifacts
@@ -1355,7 +1355,7 @@ jobs:
group: ${{ fromJson(needs.info.outputs.test_groups) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install additional OS dependencies
@@ -1476,7 +1476,7 @@ jobs:
- pytest-partial
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Download all coverage artifacts
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
steps:
- name: Check out code from GitHub
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
+3 -3
View File
@@ -29,7 +29,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
@@ -116,7 +116,7 @@ jobs:
os: ubuntu-24.04-arm
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
@@ -167,7 +167,7 @@ jobs:
os: ubuntu-24.04-arm
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
+1 -1
View File
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.16
rev: v0.15.17
hooks:
- id: ruff-check
args:
+2 -3
View File
@@ -43,7 +43,6 @@ homeassistant.components
homeassistant.components.abode.*
homeassistant.components.acaia.*
homeassistant.components.accuweather.*
homeassistant.components.acer_projector.*
homeassistant.components.acmeda.*
homeassistant.components.actiontec.*
homeassistant.components.actron_air.*
@@ -77,7 +76,6 @@ homeassistant.components.amberelectric.*
homeassistant.components.ambient_network.*
homeassistant.components.ambient_station.*
homeassistant.components.amcrest.*
homeassistant.components.ampio.*
homeassistant.components.analytics.*
homeassistant.components.analytics_insights.*
homeassistant.components.android_ip_webcam.*
@@ -142,6 +140,7 @@ homeassistant.components.canary.*
homeassistant.components.casper_glow.*
homeassistant.components.centriconnect.*
homeassistant.components.cert_expiry.*
homeassistant.components.chef_iq.*
homeassistant.components.clickatell.*
homeassistant.components.clicksend.*
homeassistant.components.climate.*
@@ -496,7 +495,6 @@ homeassistant.components.rss_feed_template.*
homeassistant.components.russound_rio.*
homeassistant.components.ruuvi_gateway.*
homeassistant.components.ruuvitag_ble.*
homeassistant.components.samsung_exlink.*
homeassistant.components.samsung_infrared.*
homeassistant.components.samsungtv.*
homeassistant.components.saunum.*
@@ -627,6 +625,7 @@ homeassistant.components.waqi.*
homeassistant.components.water_heater.*
homeassistant.components.watts.*
homeassistant.components.watttime.*
homeassistant.components.wattwaechter.*
homeassistant.components.weather.*
homeassistant.components.web_rtc.*
homeassistant.components.webhook.*
+2 -1
View File
@@ -13,7 +13,7 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
## 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.
- 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. If uv reports that no download was found for the required Python version, the environment is running an outdated version of uv; upgrade it with `curl -LsSf https://astral.sh/uv/install.sh | sh` and run `script/setup` again.
- .vscode/tasks.json contains useful commands used for development.
- After finishing a code session, run `uv run prek run --all-files` to check for linting and formatting issues.
@@ -42,3 +42,4 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
- 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.
- Keep comments concise. Prefer one short line stating the non-obvious constraint, or no comment at all.
- 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. Never add comments that justify a change by referencing what the code looked like before.
- Do not add section or divider comments (e.g. `# --- XYZ Triggers ---`) inside or outside of functions, since those can easily become stale and be misleading.
Generated
+20 -17
View File
@@ -230,7 +230,6 @@ CLAUDE.md @home-assistant/core
/tests/components/battery/ @home-assistant/core
/homeassistant/components/bayesian/ @HarvsG
/tests/components/bayesian/ @HarvsG
/homeassistant/components/beewi_smartclim/ @alemuro
/homeassistant/components/binary_sensor/ @home-assistant/core
/tests/components/binary_sensor/ @home-assistant/core
/homeassistant/components/bizkaibus/ @UgaitzEtxebarria
@@ -254,8 +253,8 @@ CLAUDE.md @home-assistant/core
/tests/components/bond/ @bdraco @prystupa @joshs85 @marciogranzotto
/homeassistant/components/bosch_alarm/ @mag1024 @sanjay900
/tests/components/bosch_alarm/ @mag1024 @sanjay900
/homeassistant/components/bosch_shc/ @tschamm
/tests/components/bosch_shc/ @tschamm
/homeassistant/components/bosch_shc/ @tschamm @mosandlt
/tests/components/bosch_shc/ @tschamm @mosandlt
/homeassistant/components/brands/ @home-assistant/core
/tests/components/brands/ @home-assistant/core
/homeassistant/components/braviatv/ @bieniu @Drafteed
@@ -299,6 +298,8 @@ CLAUDE.md @home-assistant/core
/tests/components/cert_expiry/ @jjlawren
/homeassistant/components/chacon_dio/ @cnico
/tests/components/chacon_dio/ @cnico
/homeassistant/components/chef_iq/ @Invader444
/tests/components/chef_iq/ @Invader444
/homeassistant/components/chess_com/ @joostlek
/tests/components/chess_com/ @joostlek
/homeassistant/components/cielo_home/ @ihsan-cielo @mudasar-cielo
@@ -494,6 +495,8 @@ CLAUDE.md @home-assistant/core
/tests/components/emulated_kasa/ @kbickar
/homeassistant/components/energenie_power_sockets/ @gnumpi
/tests/components/energenie_power_sockets/ @gnumpi
/homeassistant/components/energieleser/ @AjinkyaGokhale @amitkio
/tests/components/energieleser/ @AjinkyaGokhale @amitkio
/homeassistant/components/energy/ @home-assistant/core
/tests/components/energy/ @home-assistant/core
/homeassistant/components/energyid/ @JrtPec @Molier
@@ -777,8 +780,8 @@ CLAUDE.md @home-assistant/core
/tests/components/homevolt/ @danielhiversen @liudger
/homeassistant/components/homewizard/ @DCSBL
/tests/components/homewizard/ @DCSBL
/homeassistant/components/honeywell/ @rdfurman @mkmer
/tests/components/honeywell/ @rdfurman @mkmer
/homeassistant/components/honeywell/ @mkmer
/tests/components/honeywell/ @mkmer
/homeassistant/components/honeywell_string_lights/ @balloob
/tests/components/honeywell_string_lights/ @balloob
/homeassistant/components/hr_energy_qube/ @MattieGit
@@ -787,8 +790,8 @@ CLAUDE.md @home-assistant/core
/tests/components/html5/ @alexyao2015 @tr4nt0r
/homeassistant/components/http/ @home-assistant/core
/tests/components/http/ @home-assistant/core
/homeassistant/components/huawei_lte/ @scop @fphammerle
/tests/components/huawei_lte/ @scop @fphammerle
/homeassistant/components/huawei_lte/ @fphammerle
/tests/components/huawei_lte/ @fphammerle
/homeassistant/components/hue/ @marcelveldt
/tests/components/hue/ @marcelveldt
/homeassistant/components/hue_ble/ @flip-dots
@@ -1167,8 +1170,8 @@ CLAUDE.md @home-assistant/core
/tests/components/mutesync/ @currentoor
/homeassistant/components/my/ @home-assistant/core
/tests/components/my/ @home-assistant/core
/homeassistant/components/myneomitis/ @l-pr
/tests/components/myneomitis/ @l-pr
/homeassistant/components/myneomitis/ @Epyes
/tests/components/myneomitis/ @Epyes
/homeassistant/components/mysensors/ @MartinHjelmare @functionpointer
/tests/components/mysensors/ @MartinHjelmare @functionpointer
/homeassistant/components/mystrom/ @fabaff
@@ -1554,9 +1557,8 @@ CLAUDE.md @home-assistant/core
/tests/components/rympro/ @OnFreund @elad-bar @maorcc
/homeassistant/components/sabnzbd/ @shaiu @jpbede
/tests/components/sabnzbd/ @shaiu @jpbede
/homeassistant/components/saj/ @fredericvl
/homeassistant/components/samsung_exlink/ @balloob
/tests/components/samsung_exlink/ @balloob
/homeassistant/components/saj/ @fredericvl @edurenye
/tests/components/saj/ @fredericvl @edurenye
/homeassistant/components/samsung_infrared/ @lmaertin
/tests/components/samsung_infrared/ @lmaertin
/homeassistant/components/samsungtv/ @chemelli74
@@ -1600,8 +1602,8 @@ CLAUDE.md @home-assistant/core
/tests/components/sensorpush/ @bdraco
/homeassistant/components/sensorpush_cloud/ @sstallion
/tests/components/sensorpush_cloud/ @sstallion
/homeassistant/components/sensoterra/ @markruys
/tests/components/sensoterra/ @markruys
/homeassistant/components/sensoterra/ @SanderBakkumCuriousInc @curious-florian @markruys
/tests/components/sensoterra/ @SanderBakkumCuriousInc @curious-florian @markruys
/homeassistant/components/sentry/ @dcramer @frenck
/tests/components/sentry/ @dcramer @frenck
/homeassistant/components/senz/ @milanmeu
@@ -1709,8 +1711,8 @@ CLAUDE.md @home-assistant/core
/tests/components/sql/ @gjohansson-ST @dougiteixeira
/homeassistant/components/squeezebox/ @rajlaud @pssc @peteS-UK
/tests/components/squeezebox/ @rajlaud @pssc @peteS-UK
/homeassistant/components/srp_energy/ @briglx
/tests/components/srp_energy/ @briglx
/homeassistant/components/srp_energy/ @briglx @ammmze
/tests/components/srp_energy/ @briglx @ammmze
/homeassistant/components/starline/ @anonym-tsk
/tests/components/starline/ @anonym-tsk
/homeassistant/components/statistics/ @ThomDietrich @gjohansson-ST
@@ -1897,7 +1899,6 @@ CLAUDE.md @home-assistant/core
/tests/components/unifi_direct/ @tofuSCHNITZEL
/homeassistant/components/unifi_discovery/ @RaHehl
/tests/components/unifi_discovery/ @RaHehl
/homeassistant/components/unifiled/ @florisvdk
/homeassistant/components/unifiprotect/ @RaHehl
/tests/components/unifiprotect/ @RaHehl
/homeassistant/components/upb/ @gwww
@@ -1991,6 +1992,8 @@ CLAUDE.md @home-assistant/core
/tests/components/watts/ @theobld-ww @devender-verma-ww @ssi-spyro
/homeassistant/components/watttime/ @bachya
/tests/components/watttime/ @bachya
/homeassistant/components/wattwaechter/ @smartcircuits
/tests/components/wattwaechter/ @smartcircuits
/homeassistant/components/waze_travel_time/ @eifinger
/tests/components/waze_travel_time/ @eifinger
/homeassistant/components/weather/ @home-assistant/core
+3 -1
View File
@@ -6,7 +6,7 @@ from collections.abc import Mapping
from datetime import datetime, timedelta
from functools import partial
import time
from typing import Any, cast
from typing import Any, cast, override
import jwt
@@ -109,6 +109,7 @@ class AuthManagerFlowManager(
super().__init__(hass)
self.auth_manager = auth_manager
@override
async def async_create_flow(
self,
handler_key: tuple[str, str],
@@ -122,6 +123,7 @@ class AuthManagerFlowManager(
raise KeyError(f"Unknown auth provider {handler_key}")
return await auth_provider.async_login_flow(context)
@override
async def async_finish_flow(
self,
flow: FlowHandler[AuthFlowContext, AuthFlowResult, tuple[str, str]],
+1
View File
@@ -39,6 +39,7 @@ class _PyJWSWithLoadCache(PyJWS):
# We only ever have a global instance of this class
# so we do not have to worry about the LRU growing
# each time we create a new instance.
@override
def _load(self, jwt: str | bytes) -> tuple[bytes, bytes, dict, bytes]:
"""Load a JWS."""
return super()._load(jwt)
@@ -1,6 +1,6 @@
"""Example auth module."""
from typing import Any
from typing import Any, override
import voluptuous as vol
@@ -35,6 +35,7 @@ class InsecureExampleModule(MultiFactorAuthModule):
self._data = config["data"]
@property
@override
def input_schema(self) -> vol.Schema:
"""Validate login flow input data."""
return vol.Schema({vol.Required("pin"): str})
@@ -44,6 +45,7 @@ class InsecureExampleModule(MultiFactorAuthModule):
"""Validate async_setup_user input data."""
return vol.Schema({vol.Required("pin"): str})
@override
async def async_setup_flow(self, user_id: str) -> SetupFlow:
"""Return a data entry flow handler for setup module.
@@ -51,6 +53,7 @@ class InsecureExampleModule(MultiFactorAuthModule):
"""
return SetupFlow(self, self.setup_schema, user_id)
@override
async def async_setup_user(self, user_id: str, setup_data: Any) -> Any:
"""Set up user to use mfa module."""
# data shall has been validate in caller
@@ -64,6 +67,7 @@ class InsecureExampleModule(MultiFactorAuthModule):
self._data.append({"user_id": user_id, "pin": pin})
@override
async def async_depose_user(self, user_id: str) -> None:
"""Remove user from mfa module."""
found = None
@@ -74,10 +78,12 @@ class InsecureExampleModule(MultiFactorAuthModule):
if found:
self._data.remove(found)
@override
async def async_is_user_setup(self, user_id: str) -> bool:
"""Return whether user is setup."""
return any(data["user_id"] == user_id for data in self._data)
@override
async def async_validate(self, user_id: str, user_input: dict[str, Any]) -> bool:
"""Return True if validation passed."""
return any(
+8 -1
View File
@@ -5,7 +5,7 @@ Sending HOTP through notify service
import asyncio
import logging
from typing import Any, cast
from typing import Any, cast, override
import attr
import voluptuous as vol
@@ -107,6 +107,7 @@ class NotifyAuthModule(MultiFactorAuthModule):
self._init_lock = asyncio.Lock()
@property
@override
def input_schema(self) -> vol.Schema:
"""Validate login flow input data."""
return vol.Schema({vol.Required(INPUT_FIELD_CODE): str})
@@ -159,6 +160,7 @@ class NotifyAuthModule(MultiFactorAuthModule):
return sorted(unordered_services)
@override
async def async_setup_flow(self, user_id: str) -> NotifySetupFlow:
"""Return a data entry flow handler for setup module.
@@ -168,6 +170,7 @@ class NotifyAuthModule(MultiFactorAuthModule):
self, self.input_schema, user_id, self.aync_get_available_notify_services()
)
@override
async def async_setup_user(self, user_id: str, setup_data: Any) -> Any:
"""Set up auth module for user."""
if self._user_settings is None:
@@ -181,6 +184,7 @@ class NotifyAuthModule(MultiFactorAuthModule):
await self._async_save()
@override
async def async_depose_user(self, user_id: str) -> None:
"""Depose auth module for user."""
if self._user_settings is None:
@@ -190,6 +194,7 @@ class NotifyAuthModule(MultiFactorAuthModule):
if self._user_settings.pop(user_id, None):
await self._async_save()
@override
async def async_is_user_setup(self, user_id: str) -> bool:
"""Return whether user is setup."""
if self._user_settings is None:
@@ -198,6 +203,7 @@ class NotifyAuthModule(MultiFactorAuthModule):
return user_id in self._user_settings
@override
async def async_validate(self, user_id: str, user_input: dict[str, Any]) -> bool:
"""Return True if validation passed."""
if self._user_settings is None:
@@ -283,6 +289,7 @@ class NotifySetupFlow(SetupFlow[NotifyAuthModule]):
self._notify_service: str | None = None
self._target: str | None = None
@override
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> FlowResult:
+8 -1
View File
@@ -2,7 +2,7 @@
import asyncio
from io import BytesIO
from typing import Any, cast
from typing import Any, cast, override
import voluptuous as vol
@@ -87,6 +87,7 @@ class TotpAuthModule(MultiFactorAuthModule):
self._init_lock = asyncio.Lock()
@property
@override
def input_schema(self) -> vol.Schema:
"""Validate login flow input data."""
return vol.Schema({vol.Required(INPUT_FIELD_CODE): str})
@@ -115,6 +116,7 @@ class TotpAuthModule(MultiFactorAuthModule):
self._users[user_id] = ota_secret # type: ignore[index]
return ota_secret
@override
async def async_setup_flow(self, user_id: str) -> TotpSetupFlow:
"""Return a data entry flow handler for setup module.
@@ -124,6 +126,7 @@ class TotpAuthModule(MultiFactorAuthModule):
assert user is not None
return TotpSetupFlow(self, self.input_schema, user)
@override
async def async_setup_user(self, user_id: str, setup_data: Any) -> str:
"""Set up auth module for user."""
if self._users is None:
@@ -136,6 +139,7 @@ class TotpAuthModule(MultiFactorAuthModule):
await self._async_save()
return result
@override
async def async_depose_user(self, user_id: str) -> None:
"""Depose auth module for user."""
if self._users is None:
@@ -144,6 +148,7 @@ class TotpAuthModule(MultiFactorAuthModule):
if self._users.pop(user_id, None): # type: ignore[union-attr]
await self._async_save()
@override
async def async_is_user_setup(self, user_id: str) -> bool:
"""Return whether user is setup."""
if self._users is None:
@@ -151,6 +156,7 @@ class TotpAuthModule(MultiFactorAuthModule):
return user_id in self._users # type: ignore[operator]
@override
async def async_validate(self, user_id: str, user_input: dict[str, Any]) -> bool:
"""Return True if validation passed."""
if self._users is None:
@@ -189,6 +195,7 @@ class TotpSetupFlow(SetupFlow[TotpAuthModule]):
super().__init__(auth_module, setup_schema, user.id)
self._user = user
@override
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> FlowResult:
+6 -1
View File
@@ -1,7 +1,7 @@
"""Permissions for Home Assistant."""
from collections.abc import Callable, Iterable
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, override
import voluptuous as vol
@@ -68,14 +68,17 @@ class PolicyPermissions(AbstractPermissions):
self._policy = policy
self._perm_lookup = perm_lookup
@override
def access_all_entities(self, key: str) -> bool:
"""Check if we have a certain access to all entities."""
return test_all(self._policy.get(CAT_ENTITIES), key)
@override
def _entity_func(self) -> Callable[[str, str], bool]:
"""Return a function that can test entity access."""
return compile_entities(self._policy.get(CAT_ENTITIES), self._perm_lookup)
@override
def __eq__(self, other: object) -> bool:
"""Equals check."""
return isinstance(other, PolicyPermissions) and other._policy == self._policy
@@ -84,10 +87,12 @@ class PolicyPermissions(AbstractPermissions):
class _OwnerPermissions(AbstractPermissions):
"""Owner permissions."""
@override
def access_all_entities(self, key: str) -> bool:
"""Check if we have a certain access to all entities."""
return True
@override
def _entity_func(self) -> Callable[[str, str], bool]:
"""Return a function that can test entity access."""
return lambda entity_id, key: True
+5 -1
View File
@@ -4,7 +4,7 @@ import asyncio
from collections.abc import Mapping
import logging
import os
from typing import Any
from typing import Any, override
import voluptuous as vol
@@ -57,6 +57,7 @@ class CommandLineAuthProvider(AuthProvider):
super().__init__(*args, **kwargs)
self._user_meta: dict[str, dict[str, Any]] = {}
@override
async def async_login_flow(
self, context: AuthFlowContext | None
) -> CommandLineLoginFlow:
@@ -105,6 +106,7 @@ class CommandLineAuthProvider(AuthProvider):
meta[key] = value
self._user_meta[username] = meta
@override
async def async_get_or_create_credentials(
self, flow_result: Mapping[str, str]
) -> Credentials:
@@ -117,6 +119,7 @@ class CommandLineAuthProvider(AuthProvider):
# Create new credentials.
return self.async_create_credentials({"username": username})
@override
async def async_user_meta_for_credentials(
self, credentials: Credentials
) -> UserMeta:
@@ -136,6 +139,7 @@ class CommandLineAuthProvider(AuthProvider):
class CommandLineLoginFlow(LoginFlow[CommandLineAuthProvider]):
"""Handler for the login flow."""
@override
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> AuthFlowResult:
@@ -4,7 +4,7 @@ import asyncio
import base64
from collections.abc import Mapping
import logging
from typing import Any, cast
from typing import Any, cast, override
import bcrypt
import voluptuous as vol
@@ -302,6 +302,7 @@ class HassAuthProvider(AuthProvider):
self.data: Data | None = None
self._init_lock = asyncio.Lock()
@override
async def async_initialize(self) -> None:
"""Initialize the auth provider."""
async with self._init_lock:
@@ -312,6 +313,7 @@ class HassAuthProvider(AuthProvider):
await data.async_load()
self.data = data
@override
async def async_login_flow(self, context: AuthFlowContext | None) -> HassLoginFlow:
"""Return a flow to login."""
return HassLoginFlow(self)
@@ -369,6 +371,7 @@ class HassAuthProvider(AuthProvider):
)
await self.data.async_save()
@override
async def async_get_or_create_credentials(
self, flow_result: Mapping[str, str]
) -> Credentials:
@@ -387,6 +390,7 @@ class HassAuthProvider(AuthProvider):
# Create new credentials.
return self.async_create_credentials({"username": username})
@override
async def async_user_meta_for_credentials(
self, credentials: Credentials
) -> UserMeta:
@@ -410,6 +414,7 @@ class HassAuthProvider(AuthProvider):
class HassLoginFlow(LoginFlow[HassAuthProvider]):
"""Handler for the login flow."""
@override
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> AuthFlowResult:
@@ -2,6 +2,7 @@
from collections.abc import Mapping
import hmac
from typing import override
import voluptuous as vol
@@ -33,6 +34,7 @@ class InvalidAuthError(HomeAssistantError):
class ExampleAuthProvider(AuthProvider):
"""Example auth provider based on hardcoded usernames and passwords."""
@override
async def async_login_flow(
self, context: AuthFlowContext | None
) -> ExampleLoginFlow:
@@ -61,6 +63,7 @@ class ExampleAuthProvider(AuthProvider):
):
raise InvalidAuthError
@override
async def async_get_or_create_credentials(
self, flow_result: Mapping[str, str]
) -> Credentials:
@@ -74,6 +77,7 @@ class ExampleAuthProvider(AuthProvider):
# Create new credentials.
return self.async_create_credentials({"username": username})
@override
async def async_user_meta_for_credentials(
self, credentials: Credentials
) -> UserMeta:
@@ -95,6 +99,7 @@ class ExampleAuthProvider(AuthProvider):
class ExampleLoginFlow(LoginFlow[ExampleAuthProvider]):
"""Handler for the login flow."""
@override
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> AuthFlowResult:
@@ -13,7 +13,7 @@ from ipaddress import (
ip_address,
ip_network,
)
from typing import Any, cast
from typing import Any, cast, override
import voluptuous as vol
@@ -98,10 +98,12 @@ class TrustedNetworksAuthProvider(AuthProvider):
]
@property
@override
def support_mfa(self) -> bool:
"""Trusted Networks auth provider does not support MFA."""
return False
@override
async def async_login_flow(
self, context: AuthFlowContext | None
) -> TrustedNetworksLoginFlow:
@@ -144,6 +146,7 @@ class TrustedNetworksAuthProvider(AuthProvider):
self.config[CONF_ALLOW_BYPASS_LOGIN],
)
@override
async def async_get_or_create_credentials(
self, flow_result: Mapping[str, str]
) -> Credentials:
@@ -172,6 +175,7 @@ class TrustedNetworksAuthProvider(AuthProvider):
# We only allow login as exist user
raise InvalidUserError
@override
async def async_user_meta_for_credentials(
self, credentials: Credentials
) -> UserMeta:
@@ -203,6 +207,7 @@ class TrustedNetworksAuthProvider(AuthProvider):
raise InvalidAuthError("Can't allow access from Home Assistant Cloud")
@callback
@override
def async_validate_refresh_token(
self, refresh_token: RefreshToken, remote_ip: str | None = None
) -> None:
@@ -230,6 +235,7 @@ class TrustedNetworksLoginFlow(LoginFlow[TrustedNetworksAuthProvider]):
self._ip_address = ip_addr
self._allow_bypass_login = allow_bypass_login
@override
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> AuthFlowResult:
+2 -1
View File
@@ -14,7 +14,7 @@ import platform
import sys
import threading
from time import monotonic
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, override
# Import cryptography early since import openssl is not thread-safe
# _frozen_importlib._DeadlockError: deadlock detected by
@@ -697,6 +697,7 @@ def _create_log_file(
class _RotatingFileHandlerWithoutShouldRollOver(RotatingFileHandler):
"""RotatingFileHandler that does not check if it should roll over on every log."""
@override
def shouldRollover(self, record: logging.LogRecord) -> bool:
"""Never roll over.
+1 -7
View File
@@ -1,11 +1,5 @@
{
"domain": "samsung",
"name": "Samsung",
"integrations": [
"familyhub",
"samsung_exlink",
"samsung_infrared",
"samsungtv",
"syncthru"
]
"integrations": ["familyhub", "samsung_infrared", "samsungtv", "syncthru"]
}
-1
View File
@@ -7,7 +7,6 @@
"unifi_access",
"unifi_direct",
"unifi_discovery",
"unifiled",
"unifiprotect"
]
}
@@ -1,5 +1,7 @@
"""Support for Abode Security System alarm control panels."""
from typing import override
from jaraco.abode.devices.alarm import Alarm
from homeassistant.components.alarm_control_panel import (
@@ -38,6 +40,7 @@ class AbodeAlarm(AbodeDevice, AlarmControlPanelEntity):
_device: Alarm
@property
@override
def alarm_state(self) -> AlarmControlPanelState | None:
"""Return the state of the device."""
if self._device.is_standby:
@@ -48,19 +51,23 @@ class AbodeAlarm(AbodeDevice, AlarmControlPanelEntity):
return AlarmControlPanelState.ARMED_HOME
return None
@override
def alarm_disarm(self, code: str | None = None) -> None:
"""Send disarm command."""
self._device.set_standby()
@override
def alarm_arm_home(self, code: str | None = None) -> None:
"""Send arm home command."""
self._device.set_home()
@override
def alarm_arm_away(self, code: str | None = None) -> None:
"""Send arm away command."""
self._device.set_away()
@property
@override
def extra_state_attributes(self) -> dict[str, str]:
"""Return the state attributes."""
return {
@@ -1,6 +1,6 @@
"""Support for Abode Security System binary sensors."""
from typing import cast
from typing import cast, override
from jaraco.abode.devices.binary_sensor import BinarySensor
@@ -45,11 +45,13 @@ class AbodeBinarySensor(AbodeDevice, BinarySensorEntity):
_device: BinarySensor
@property
@override
def is_on(self) -> bool:
"""Return True if the binary sensor is on."""
return cast(bool, self._device.is_on)
@property
@override
def device_class(self) -> BinarySensorDeviceClass | None:
"""Return the class of the binary sensor."""
if self._device.get_value("is_window") == "1":
+6 -1
View File
@@ -1,7 +1,7 @@
"""Support for Abode Security System cameras."""
from datetime import timedelta
from typing import Any, cast
from typing import Any, cast, override
from jaraco.abode.devices.base import Device
from jaraco.abode.devices.camera import Camera as AbodeCam
@@ -49,6 +49,7 @@ class AbodeCamera(AbodeDevice, Camera):
self._event = event
self._response: Response | None = None
@override
async def async_added_to_hass(self) -> None:
"""Subscribe Abode events."""
await super().async_added_to_hass()
@@ -87,6 +88,7 @@ class AbodeCamera(AbodeDevice, Camera):
else:
self._response = None
@override
def camera_image(
self, width: int | None = None, height: int | None = None
) -> bytes | None:
@@ -98,10 +100,12 @@ class AbodeCamera(AbodeDevice, Camera):
return None
@override
def turn_on(self) -> None:
"""Turn on camera."""
self._device.privacy_mode(False)
@override
def turn_off(self) -> None:
"""Turn off camera."""
self._device.privacy_mode(True)
@@ -113,6 +117,7 @@ class AbodeCamera(AbodeDevice, Camera):
self.schedule_update_ha_state()
@property
@override
def is_on(self) -> bool:
"""Return true if on."""
return cast(bool, self._device.is_on)
@@ -2,7 +2,7 @@
from collections.abc import Mapping
from http import HTTPStatus
from typing import Any, cast
from typing import Any, cast, override
from jaraco.abode.client import Client as Abode
from jaraco.abode.exceptions import (
@@ -106,6 +106,7 @@ class AbodeFlowHandler(ConfigFlow, domain=DOMAIN):
title=cast(str, self._username), data=config_data
)
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
+4 -1
View File
@@ -1,6 +1,6 @@
"""Support for Abode Security System covers."""
from typing import Any
from typing import Any, override
from jaraco.abode.devices.cover import Cover
@@ -33,14 +33,17 @@ class AbodeCover(AbodeDevice, CoverEntity):
_attr_name = None
@property
@override
def is_closed(self) -> bool:
"""Return true if cover is closed, else False."""
return not self._device.is_open
@override
def close_cover(self, **kwargs: Any) -> None:
"""Issue close command to cover."""
self._device.close_cover()
@override
def open_cover(self, **kwargs: Any) -> None:
"""Issue open command to cover."""
self._device.open_cover()
+8
View File
@@ -1,5 +1,7 @@
"""Support for Abode Security System entities."""
from typing import override
from jaraco.abode.automation import Automation as AbodeAuto
from jaraco.abode.devices.base import Device as AbodeDev
@@ -21,6 +23,7 @@ class AbodeEntity(Entity):
self._data = data
self._attr_should_poll = data.polling
@override
async def async_added_to_hass(self) -> None:
"""Subscribe to Abode connection status updates."""
await self.hass.async_add_executor_job(
@@ -31,6 +34,7 @@ class AbodeEntity(Entity):
self._data.entity_ids.add(self.entity_id)
@override
async def async_will_remove_from_hass(self) -> None:
"""Unsubscribe from Abode connection status updates."""
await self.hass.async_add_executor_job(
@@ -52,6 +56,7 @@ class AbodeDevice(AbodeEntity):
self._device = device
self._attr_unique_id = device.uuid
@override
async def async_added_to_hass(self) -> None:
"""Subscribe to device events."""
await super().async_added_to_hass()
@@ -61,6 +66,7 @@ class AbodeDevice(AbodeEntity):
self._update_callback,
)
@override
async def async_will_remove_from_hass(self) -> None:
"""Unsubscribe from device events."""
await super().async_will_remove_from_hass()
@@ -73,6 +79,7 @@ class AbodeDevice(AbodeEntity):
self._device.refresh()
@property
@override
def extra_state_attributes(self) -> dict[str, str]:
"""Return the state attributes."""
return {
@@ -83,6 +90,7 @@ class AbodeDevice(AbodeEntity):
}
@property
@override
def device_info(self) -> DeviceInfo:
"""Return device registry information for this entity."""
return DeviceInfo(
+9 -1
View File
@@ -1,7 +1,7 @@
"""Support for Abode Security System lights."""
from math import ceil
from typing import Any
from typing import Any, override
from jaraco.abode.devices.light import Light
@@ -43,6 +43,7 @@ class AbodeLight(AbodeDevice, LightEntity):
_attr_max_color_temp_kelvin = DEFAULT_MAX_KELVIN
_attr_min_color_temp_kelvin = DEFAULT_MIN_KELVIN
@override
def turn_on(self, **kwargs: Any) -> None:
"""Turn on the light."""
if ATTR_COLOR_TEMP_KELVIN in kwargs and self._device.is_color_capable:
@@ -61,16 +62,19 @@ class AbodeLight(AbodeDevice, LightEntity):
self._device.switch_on()
@override
def turn_off(self, **kwargs: Any) -> None:
"""Turn off the light."""
self._device.switch_off()
@property
@override
def is_on(self) -> bool:
"""Return true if device is on."""
return bool(self._device.is_on)
@property
@override
def brightness(self) -> int | None:
"""Return the brightness of the light."""
if self._device.is_dimmable and self._device.has_brightness:
@@ -81,6 +85,7 @@ class AbodeLight(AbodeDevice, LightEntity):
return None
@property
@override
def color_temp_kelvin(self) -> int | None:
"""Return the color temp of the light."""
if self._device.has_color:
@@ -88,6 +93,7 @@ class AbodeLight(AbodeDevice, LightEntity):
return None
@property
@override
def hs_color(self) -> tuple[float, float] | None:
"""Return the color of the light."""
_hs = None
@@ -96,6 +102,7 @@ class AbodeLight(AbodeDevice, LightEntity):
return _hs
@property
@override
def color_mode(self) -> ColorMode:
"""Return the color mode of the light."""
if self._device.is_dimmable and self._device.is_color_capable:
@@ -107,6 +114,7 @@ class AbodeLight(AbodeDevice, LightEntity):
return ColorMode.ONOFF
@property
@override
def supported_color_modes(self) -> set[ColorMode]:
"""Flag supported color modes."""
if self._device.is_dimmable and self._device.is_color_capable:
+4 -1
View File
@@ -1,6 +1,6 @@
"""Support for the Abode Security System locks."""
from typing import Any
from typing import Any, override
from jaraco.abode.devices.lock import Lock
@@ -32,15 +32,18 @@ class AbodeLock(AbodeDevice, LockEntity):
_device: Lock
_attr_name = None
@override
def lock(self, **kwargs: Any) -> None:
"""Lock the device."""
self._device.lock()
@override
def unlock(self, **kwargs: Any) -> None:
"""Unlock the device."""
self._device.unlock()
@property
@override
def is_locked(self) -> bool:
"""Return true if device is on."""
return bool(self._device.is_locked)
+3 -1
View File
@@ -2,7 +2,7 @@
from collections.abc import Callable
from dataclasses import dataclass
from typing import cast
from typing import cast, override
from jaraco.abode.devices.sensor import Sensor
@@ -94,11 +94,13 @@ class AbodeSensor(AbodeDevice, SensorEntity):
self._attr_unique_id = f"{device.uuid}-{description.key}"
@property
@override
def native_value(self) -> float:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self._device)
@property
@override
def native_unit_of_measurement(self) -> str:
"""Return the native unit of measurement."""
return self.entity_description.native_unit_of_measurement_fn(self._device)
+3 -6
View File
@@ -7,8 +7,7 @@ import voluptuous as vol
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import config_validation as cv, service
from homeassistant.helpers.dispatcher import dispatcher_send
from .const import DOMAIN, LOGGER
@@ -31,10 +30,8 @@ AUTOMATION_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
def _get_abode_system(hass: HomeAssistant) -> AbodeSystem:
"""Return the Abode system for the loaded config entry."""
entries: list[AbodeConfigEntry] = hass.config_entries.async_loaded_entries(DOMAIN)
if not entries:
raise ServiceValidationError("Abode integration is not loaded")
return entries[0].runtime_data
entry: AbodeConfigEntry = service.async_get_config_entry(hass, DOMAIN, None)
return entry.runtime_data
def _change_setting(call: ServiceCall) -> None:
+8 -1
View File
@@ -1,6 +1,6 @@
"""Support for Abode Security System switches."""
from typing import Any, cast
from typing import Any, cast, override
from jaraco.abode.devices.switch import Switch
@@ -43,15 +43,18 @@ class AbodeSwitch(AbodeDevice, SwitchEntity):
_device: Switch
_attr_name = None
@override
def turn_on(self, **kwargs: Any) -> None:
"""Turn on the device."""
self._device.switch_on()
@override
def turn_off(self, **kwargs: Any) -> None:
"""Turn off the device."""
self._device.switch_off()
@property
@override
def is_on(self) -> bool:
"""Return true if device is on."""
return cast(bool, self._device.is_on)
@@ -62,6 +65,7 @@ class AbodeAutomationSwitch(AbodeAutomation, SwitchEntity):
_attr_translation_key = "automation"
@override
async def async_added_to_hass(self) -> None:
"""Set up trigger automation service."""
await super().async_added_to_hass()
@@ -69,11 +73,13 @@ class AbodeAutomationSwitch(AbodeAutomation, SwitchEntity):
signal = f"abode_trigger_automation_{self.entity_id}"
self.async_on_remove(async_dispatcher_connect(self.hass, signal, self.trigger))
@override
def turn_on(self, **kwargs: Any) -> None:
"""Enable the automation."""
if self._automation.enable(True):
self.schedule_update_ha_state()
@override
def turn_off(self, **kwargs: Any) -> None:
"""Disable the automation."""
if self._automation.enable(False):
@@ -84,6 +90,7 @@ class AbodeAutomationSwitch(AbodeAutomation, SwitchEntity):
self._automation.trigger()
@property
@override
def is_on(self) -> bool:
"""Return True if the automation is enabled."""
return bool(self._automation.enabled)
@@ -2,6 +2,7 @@
from collections.abc import Callable
from dataclasses import dataclass
from typing import override
from aioacaia.acaiascale import AcaiaScale
@@ -56,6 +57,7 @@ class AcaiaBinarySensor(AcaiaEntity, BinarySensorEntity):
entity_description: AcaiaBinarySensorEntityDescription
@property
@override
def is_on(self) -> bool:
"""Return true if the binary sensor is on."""
return self.entity_description.is_on_fn(self._scale)
+2 -1
View File
@@ -2,7 +2,7 @@
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from typing import Any
from typing import Any, override
from aioacaia.acaiascale import AcaiaScale
@@ -58,6 +58,7 @@ class AcaiaButton(AcaiaEntity, ButtonEntity):
entity_description: AcaiaButtonEntityDescription
@override
async def async_press(self) -> None:
"""Handle the button press."""
await self.entity_description.press_fn(self._scale)
@@ -1,7 +1,7 @@
"""Config flow for Acaia integration."""
import logging
from typing import Any
from typing import Any, override
from aioacaia.exceptions import AcaiaDeviceNotFound, AcaiaError, AcaiaUnknownDevice
from aioacaia.helpers import is_new_scale
@@ -34,6 +34,7 @@ class AcaiaConfigFlow(ConfigFlow, domain=DOMAIN):
self._discovered: dict[str, Any] = {}
self._discovered_devices: dict[str, str] = {}
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@@ -94,6 +95,7 @@ class AcaiaConfigFlow(ConfigFlow, domain=DOMAIN):
errors=errors,
)
@override
async def async_step_bluetooth(
self, discovery_info: BluetoothServiceInfoBleak
) -> ConfigFlowResult:
@@ -2,6 +2,7 @@
from datetime import timedelta
import logging
from typing import override
from aioacaia.acaiascale import AcaiaScale
from aioacaia.exceptions import AcaiaDeviceNotFound, AcaiaError
@@ -59,6 +60,7 @@ class AcaiaCoordinator(DataUpdateCoordinator[None]):
"""Return the scale object."""
return self._scale
@override
async def _async_update_data(self) -> None:
"""Fetch data."""
+2
View File
@@ -1,6 +1,7 @@
"""Base class for Acaia entities."""
from dataclasses import dataclass
from typing import override
from homeassistant.helpers.device_registry import (
CONNECTION_BLUETOOTH,
@@ -41,6 +42,7 @@ class AcaiaEntity(CoordinatorEntity[AcaiaCoordinator]):
)
@property
@override
def available(self) -> bool:
"""Returns whether entity is available."""
return super().available and self._scale.connected
@@ -14,9 +14,15 @@ rules:
status: exempt
comment: |
No custom actions are defined.
docs-conditions:
status: exempt
comment: This integration does not have any conditions.
docs-high-level-description: done
docs-installation-instructions: done
docs-removal-instructions: done
docs-triggers:
status: exempt
comment: This integration does not have any triggers.
entity-event-setup:
status: exempt
comment: |
+6
View File
@@ -2,6 +2,7 @@
from collections.abc import Callable
from dataclasses import dataclass
from typing import override
from aioacaia.acaiascale import AcaiaDeviceState, AcaiaScale
from aioacaia.const import UnitMass as AcaiaUnitOfMass
@@ -98,6 +99,7 @@ class AcaiaSensor(AcaiaEntity, SensorEntity):
entity_description: AcaiaDynamicUnitSensorEntityDescription
@property
@override
def native_unit_of_measurement(self) -> str | None:
"""Return the unit of measurement of this entity."""
if (
@@ -108,6 +110,7 @@ class AcaiaSensor(AcaiaEntity, SensorEntity):
return self.entity_description.native_unit_of_measurement
@property
@override
def native_value(self) -> int | float | None:
"""Return the state of the entity."""
return self.entity_description.value_fn(self._scale)
@@ -119,6 +122,7 @@ class AcaiaRestoreSensor(AcaiaEntity, RestoreSensor):
entity_description: AcaiaSensorEntityDescription
_restored_data: SensorExtraStoredData | None = None
@override
async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await super().async_added_to_hass()
@@ -134,6 +138,7 @@ class AcaiaRestoreSensor(AcaiaEntity, RestoreSensor):
self._attr_native_value = self.entity_description.value_fn(self._scale)
@callback
@override
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
if self._scale.device_state is not None:
@@ -141,6 +146,7 @@ class AcaiaRestoreSensor(AcaiaEntity, RestoreSensor):
self._async_write_ha_state()
@property
@override
def available(self) -> bool:
"""Return True if entity is available."""
return super().available or self.native_value is not None
@@ -2,7 +2,7 @@
from asyncio import timeout
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, override
from accuweather import AccuWeather, ApiError, InvalidApiKeyError, RequestsExceededError
from aiohttp import ClientError
@@ -24,6 +24,7 @@ class AccuWeatherFlowHandler(ConfigFlow, domain=DOMAIN):
_latitude: float | None = None
_longitude: float | None = None
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@@ -5,7 +5,7 @@ from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from datetime import timedelta
import logging
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, override
from accuweather import AccuWeather, ApiError, InvalidApiKeyError, RequestsExceededError
from aiohttp.client_exceptions import ClientConnectorError
@@ -77,6 +77,7 @@ class AccuWeatherObservationDataUpdateCoordinator(
update_interval=UPDATE_INTERVAL_OBSERVATION,
)
@override
async def _async_update_data(self) -> dict[str, Any]:
"""Update data via library."""
try:
@@ -135,6 +136,7 @@ class AccuWeatherForecastDataUpdateCoordinator(
update_interval=update_interval,
)
@override
async def _async_update_data(self) -> list[dict[str, Any]]:
"""Update forecast data via library."""
try:
@@ -2,7 +2,7 @@
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any, cast
from typing import Any, cast, override
from homeassistant.components.sensor import (
SensorDeviceClass,
@@ -436,16 +436,19 @@ class AccuWeatherSensor(
self._attr_device_info = coordinator.device_info
@property
@override
def native_value(self) -> str | int | float | None:
"""Return the state."""
return self.entity_description.value_fn(self._sensor_data)
@property
@override
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes."""
return self.entity_description.attr_fn(self.coordinator.data)
@callback
@override
def _handle_coordinator_update(self) -> None:
"""Handle data update."""
self._sensor_data = self._get_sensor_data(
@@ -495,16 +498,19 @@ class AccuWeatherForecastSensor(
self.forecast_day = forecast_day
@property
@override
def native_value(self) -> str | int | float | None:
"""Return the state."""
return self.entity_description.value_fn(self._sensor_data)
@property
@override
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes."""
return self.entity_description.attr_fn(self._sensor_data)
@callback
@override
def _handle_coordinator_update(self) -> None:
"""Handle data update."""
self._sensor_data = self._get_sensor_data(
@@ -1,6 +1,6 @@
"""Support for the AccuWeather service."""
from typing import cast
from typing import cast, override
from homeassistant.components.weather import (
ATTR_FORECAST_CLOUD_COVERAGE,
@@ -96,16 +96,19 @@ class AccuWeatherEntity(
self.hourly_coordinator = accuweather_data.coordinator_hourly_forecast
@property
@override
def condition(self) -> str | None:
"""Return the current condition."""
return CONDITION_MAP.get(self.observation_coordinator.data["WeatherIcon"])
@property
@override
def cloud_coverage(self) -> float:
"""Return the Cloud coverage in %."""
return cast(float, self.observation_coordinator.data["CloudCover"])
@property
@override
def native_apparent_temperature(self) -> float:
"""Return the apparent temperature."""
return cast(
@@ -116,6 +119,7 @@ class AccuWeatherEntity(
)
@property
@override
def native_temperature(self) -> float:
"""Return the temperature."""
return cast(
@@ -124,6 +128,7 @@ class AccuWeatherEntity(
)
@property
@override
def native_pressure(self) -> float:
"""Return the pressure."""
return cast(
@@ -131,6 +136,7 @@ class AccuWeatherEntity(
)
@property
@override
def native_dew_point(self) -> float:
"""Return the dew point."""
return cast(
@@ -138,11 +144,13 @@ class AccuWeatherEntity(
)
@property
@override
def humidity(self) -> int:
"""Return the humidity."""
return cast(int, self.observation_coordinator.data["RelativeHumidity"])
@property
@override
def native_wind_gust_speed(self) -> float:
"""Return the wind gust speed."""
return cast(
@@ -153,6 +161,7 @@ class AccuWeatherEntity(
)
@property
@override
def native_wind_speed(self) -> float:
"""Return the wind speed."""
return cast(
@@ -163,6 +172,7 @@ class AccuWeatherEntity(
)
@property
@override
def wind_bearing(self) -> int:
"""Return the wind bearing."""
return cast(
@@ -170,6 +180,7 @@ class AccuWeatherEntity(
)
@property
@override
def native_visibility(self) -> float:
"""Return the visibility."""
return cast(
@@ -178,11 +189,13 @@ class AccuWeatherEntity(
)
@property
@override
def uv_index(self) -> float:
"""Return the UV index."""
return cast(float, self.observation_coordinator.data["UVIndex"])
@callback
@override
def _async_forecast_daily(self) -> list[Forecast] | None:
"""Return the daily forecast in native units."""
return [
@@ -213,6 +226,7 @@ class AccuWeatherEntity(
]
@callback
@override
def _async_forecast_hourly(self) -> list[Forecast] | None:
"""Return the hourly forecast in native units."""
return [
@@ -1 +0,0 @@
"""The acer_projector component."""
@@ -1,34 +0,0 @@
"""Use serial protocol of Acer projector to obtain state of the projector."""
from typing import Final
from homeassistant.const import STATE_OFF, STATE_ON
CONF_READ_TIMEOUT: Final = "timeout"
CONF_WRITE_TIMEOUT: Final = "write_timeout"
DEFAULT_NAME: Final = "Acer Projector"
DEFAULT_READ_TIMEOUT: Final = 1
DEFAULT_WRITE_TIMEOUT: Final = 1
ECO_MODE: Final = "ECO Mode"
ICON: Final = "mdi:projector"
INPUT_SOURCE: Final = "Input Source"
LAMP: Final = "Lamp"
LAMP_HOURS: Final = "Lamp Hours"
MODEL: Final = "Model"
# Commands known to the projector
CMD_DICT: Final[dict[str, str]] = {
LAMP: "* 0 Lamp ?\r",
LAMP_HOURS: "* 0 Lamp\r",
INPUT_SOURCE: "* 0 Src ?\r",
ECO_MODE: "* 0 IR 052\r",
MODEL: "* 0 IR 035\r",
STATE_ON: "* 0 IR 001\r",
STATE_OFF: "* 0 IR 002\r",
}
@@ -1,9 +0,0 @@
{
"domain": "acer_projector",
"name": "Acer Projector",
"codeowners": [],
"documentation": "https://www.home-assistant.io/integrations/acer_projector",
"iot_class": "local_polling",
"quality_scale": "legacy",
"requirements": ["serialx==1.8.2"]
}
@@ -1,153 +0,0 @@
"""Use serial protocol of Acer projector to obtain state of the projector."""
import logging
import re
from typing import Any
from serialx import Serial, SerialException
import voluptuous as vol
from homeassistant.components.switch import (
PLATFORM_SCHEMA as SWITCH_PLATFORM_SCHEMA,
SwitchEntity,
)
from homeassistant.const import (
CONF_FILENAME,
CONF_NAME,
STATE_OFF,
STATE_ON,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .const import (
CMD_DICT,
CONF_READ_TIMEOUT,
CONF_WRITE_TIMEOUT,
DEFAULT_NAME,
DEFAULT_READ_TIMEOUT,
DEFAULT_WRITE_TIMEOUT,
ECO_MODE,
ICON,
INPUT_SOURCE,
LAMP,
LAMP_HOURS,
)
_LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA = SWITCH_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_FILENAME): cv.isdevice,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_READ_TIMEOUT, default=DEFAULT_READ_TIMEOUT): cv.positive_int,
vol.Optional(
CONF_WRITE_TIMEOUT, default=DEFAULT_WRITE_TIMEOUT
): cv.positive_int,
}
)
def setup_platform(
hass: HomeAssistant,
config: ConfigType,
add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Connect with serial port and return Acer Projector."""
serial_port = config[CONF_FILENAME]
name = config[CONF_NAME]
read_timeout = config[CONF_READ_TIMEOUT]
write_timeout = config[CONF_WRITE_TIMEOUT]
add_entities([AcerSwitch(serial_port, name, read_timeout, write_timeout)], True)
class AcerSwitch(SwitchEntity):
"""Represents an Acer Projector as a switch."""
_attr_icon = ICON
def __init__(
self,
serial_port: str,
name: str,
read_timeout: int,
write_timeout: int,
) -> None:
"""Init of the Acer projector."""
self._serial_port = serial_port
self._read_timeout = read_timeout
self._write_timeout = write_timeout
self._attr_name = name
self._attributes = {
LAMP_HOURS: STATE_UNKNOWN,
INPUT_SOURCE: STATE_UNKNOWN,
ECO_MODE: STATE_UNKNOWN,
}
def _write_read(self, msg: str) -> str:
"""Write to the projector and read the return."""
# Sometimes the projector won't answer for no reason or the projector
# was disconnected during runtime.
# This way the projector can be reconnected and will still work
try:
with Serial.from_url(
self._serial_port,
read_timeout=self._read_timeout,
write_timeout=self._write_timeout,
) as serial:
serial.write(msg.encode("utf-8"))
# Size is an experience value there is no real limit.
# AFAIK there is no limit and no end character so we will usually
# need to wait for timeout
return serial.read_until(size=20).decode("utf-8")
except (OSError, SerialException, TimeoutError) as exc:
raise HomeAssistantError(
f"Problem communicating with {self._serial_port}"
) from exc
def _write_read_format(self, msg: str) -> str:
"""Write msg, obtain answer and format output."""
# answers are formatted as ***\answer\r***
awns = self._write_read(msg)
if match := re.search(r"\r(.+)\r", awns):
return match.group(1)
return STATE_UNKNOWN
def update(self) -> None:
"""Get the latest state from the projector."""
awns = self._write_read_format(CMD_DICT[LAMP])
if awns == "Lamp 1":
self._attr_is_on = True
self._attr_available = True
elif awns == "Lamp 0":
self._attr_is_on = False
self._attr_available = True
else:
self._attr_available = False
for key in self._attributes:
if msg := CMD_DICT.get(key):
awns = self._write_read_format(msg)
self._attributes[key] = awns
self._attr_extra_state_attributes = self._attributes
def turn_on(self, **kwargs: Any) -> None:
"""Turn the projector on."""
msg = CMD_DICT[STATE_ON]
self._write_read(msg)
self._attr_is_on = True
def turn_off(self, **kwargs: Any) -> None:
"""Turn the projector off."""
msg = CMD_DICT[STATE_OFF]
self._write_read(msg)
self._attr_is_on = False
@@ -2,7 +2,7 @@
from asyncio import timeout
from contextlib import suppress
from typing import Any
from typing import Any, override
import aiopulse
import voluptuous as vol
@@ -22,6 +22,7 @@ class AcmedaFlowHandler(ConfigFlow, domain=DOMAIN):
"""Initialize the config flow."""
self.discovered_hubs: dict[str, aiopulse.Hub] | None = None
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
+13 -1
View File
@@ -1,6 +1,6 @@
"""Support for Acmeda Roller Blinds."""
from typing import Any
from typing import Any, override
from homeassistant.components.cover import (
ATTR_POSITION,
@@ -48,6 +48,7 @@ class AcmedaCover(AcmedaEntity, CoverEntity):
_attr_name = None
@property
@override
def current_cover_position(self) -> int | None:
"""Return the current position of the roller blind.
@@ -59,6 +60,7 @@ class AcmedaCover(AcmedaEntity, CoverEntity):
return position
@property
@override
def current_cover_tilt_position(self) -> int | None:
"""Return the current tilt of the roller blind.
@@ -70,6 +72,7 @@ class AcmedaCover(AcmedaEntity, CoverEntity):
return position
@property
@override
def supported_features(self) -> CoverEntityFeature:
"""Flag supported features."""
supported_features = CoverEntityFeature(0)
@@ -91,38 +94,47 @@ class AcmedaCover(AcmedaEntity, CoverEntity):
return supported_features
@property
@override
def is_closed(self) -> bool:
"""Return if the cover is closed."""
return self.roller.closed_percent == 100 # type: ignore[no-any-return]
@override
async def async_close_cover(self, **kwargs: Any) -> None:
"""Close the roller."""
await self.roller.move_down()
@override
async def async_open_cover(self, **kwargs: Any) -> None:
"""Open the roller."""
await self.roller.move_up()
@override
async def async_stop_cover(self, **kwargs: Any) -> None:
"""Stop the roller."""
await self.roller.move_stop()
@override
async def async_set_cover_position(self, **kwargs: Any) -> None:
"""Move the roller shutter to a specific position."""
await self.roller.move_to(100 - kwargs[ATTR_POSITION])
@override
async def async_close_cover_tilt(self, **kwargs: Any) -> None:
"""Close the roller."""
await self.roller.move_down()
@override
async def async_open_cover_tilt(self, **kwargs: Any) -> None:
"""Open the roller."""
await self.roller.move_up()
@override
async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
"""Stop the roller."""
await self.roller.move_stop()
@override
async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
"""Tilt the roller shutter to a specific position."""
await self.roller.move_to(100 - kwargs[ATTR_POSITION])
@@ -1,5 +1,7 @@
"""Base class for Acmeda Roller Blinds."""
from typing import override
import aiopulse
from homeassistant.core import callback
@@ -40,6 +42,7 @@ class AcmedaEntity(entity.Entity):
await self.async_remove(force_remove=True)
@override
async def async_added_to_hass(self) -> None:
"""Entity has been added to hass."""
self.roller.callback_subscribe(self.notify_update)
@@ -52,6 +55,7 @@ class AcmedaEntity(entity.Entity):
)
)
@override
async def async_will_remove_from_hass(self) -> None:
"""Entity being removed from hass."""
self.roller.callback_unsubscribe(self.notify_update)
@@ -63,6 +67,7 @@ class AcmedaEntity(entity.Entity):
self.async_write_ha_state()
@property
@override
def unique_id(self) -> str:
"""Return the unique ID of this roller."""
return str(self.roller.id)
@@ -73,6 +78,7 @@ class AcmedaEntity(entity.Entity):
return self.roller.id # type: ignore[no-any-return]
@property
@override
def device_info(self) -> dr.DeviceInfo:
"""Return the device info."""
return dr.DeviceInfo(
@@ -1,5 +1,7 @@
"""Support for Acmeda Roller Blind Batteries."""
from typing import override
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.const import PERCENTAGE
from homeassistant.core import HomeAssistant, callback
@@ -44,6 +46,7 @@ class AcmedaBattery(AcmedaEntity, SensorEntity):
_attr_native_unit_of_measurement = PERCENTAGE
@property
@override
def native_value(self) -> float | int | None:
"""Return the state of the device."""
return self.roller.battery # type: ignore[no-any-return]
@@ -1,7 +1,7 @@
"""Support for Actiontec MI424WR (Verizon FIOS) routers."""
import logging
from typing import Final
from typing import Final, override
import telnetlib # pylint: disable=deprecated-module
import voluptuous as vol
@@ -50,11 +50,13 @@ class ActiontecDeviceScanner(DeviceScanner):
data = self.get_actiontec_data()
self.success_init = data is not None
@override
def scan_devices(self) -> list[str]:
"""Scan for new devices and return a list with found device IDs."""
self._update_info()
return [client.mac_address for client in self.last_results]
@override
def get_device_name(self, device: str) -> str | None:
"""Return the name of the given device or None if we don't know."""
for client in self.last_results:
+21 -1
View File
@@ -1,6 +1,6 @@
"""Climate platform for Actron Air integration."""
from typing import Any
from typing import Any, override
from actron_neo_api import ActronAirStatus, ActronAirZone
@@ -94,6 +94,7 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
self._attr_unique_id = self._serial_number
@property
@override
def hvac_modes(self) -> list[HVACMode]:
"""Return the list of supported HVAC modes."""
modes = [
@@ -105,11 +106,13 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
return modes
@property
@override
def min_temp(self) -> float:
"""Return the minimum temperature that can be set."""
return self._status.min_temp
@property
@override
def max_temp(self) -> float:
"""Return the maximum temperature that can be set."""
return self._status.max_temp
@@ -120,6 +123,7 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
return self.coordinator.data
@property
@override
def hvac_mode(self) -> HVACMode | None:
"""Return the current HVAC mode."""
if not self._status.user_aircon_settings.is_on:
@@ -129,39 +133,46 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
return HVAC_MODE_MAPPING_ACTRONAIR_TO_HA.get(mode)
@property
@override
def fan_mode(self) -> str | None:
"""Return the current fan mode."""
fan_mode = self._status.user_aircon_settings.base_fan_mode
return FAN_MODE_MAPPING_ACTRONAIR_TO_HA.get(fan_mode)
@property
@override
def current_humidity(self) -> float:
"""Return the current humidity."""
return self._status.master_info.live_humidity_pc
@property
@override
def current_temperature(self) -> float:
"""Return the current temperature."""
return self._status.master_info.live_temp_c
@property
@override
def target_temperature(self) -> float:
"""Return the target temperature."""
return self._status.user_aircon_settings.current_setpoint
@actron_air_command
@override
async def async_set_fan_mode(self, fan_mode: str) -> None:
"""Set a new fan mode."""
api_fan_mode = FAN_MODE_MAPPING_HA_TO_ACTRONAIR[fan_mode]
await self._status.user_aircon_settings.set_fan_mode(api_fan_mode)
@actron_air_command
@override
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the HVAC mode."""
ac_mode = HVAC_MODE_MAPPING_HA_TO_ACTRONAIR[hvac_mode]
await self._status.ac_system.set_system_mode(ac_mode)
@actron_air_command
@override
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set the temperature."""
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
@@ -191,6 +202,7 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
self._attr_unique_id: str = self._zone_identifier
@property
@override
def hvac_modes(self) -> list[HVACMode]:
"""Return the list of supported HVAC modes."""
status = self.coordinator.data
@@ -203,11 +215,13 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
return modes
@property
@override
def min_temp(self) -> float:
"""Return the minimum temperature that can be set."""
return self._zone.min_temp
@property
@override
def max_temp(self) -> float:
"""Return the maximum temperature that can be set."""
return self._zone.max_temp
@@ -219,6 +233,7 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
return status.zones[self._zone_id]
@property
@override
def hvac_mode(self) -> HVACMode | None:
"""Return the current HVAC mode."""
if self._zone.is_active:
@@ -227,27 +242,32 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
return HVACMode.OFF
@property
@override
def current_humidity(self) -> float | None:
"""Return the current humidity."""
return self._zone.humidity
@property
@override
def current_temperature(self) -> float | None:
"""Return the current temperature."""
return self._zone.live_temp_c
@property
@override
def target_temperature(self) -> float | None:
"""Return the target temperature."""
return self._zone.current_setpoint
@actron_air_command
@override
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the HVAC mode."""
is_enabled = hvac_mode != HVACMode.OFF
await self._zone.enable(is_enabled)
@actron_air_command
@override
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set the temperature."""
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
@@ -2,7 +2,7 @@
import asyncio
from collections.abc import Mapping
from typing import Any
from typing import Any, override
from actron_neo_api import ActronAirAPI, ActronAirAuthError
@@ -30,6 +30,7 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
self._expires_minutes: str = "30"
self.login_task: asyncio.Task[None] | None = None
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@@ -2,6 +2,7 @@
from dataclasses import dataclass
from datetime import timedelta
from typing import override
from actron_neo_api import (
ActronAirAPI,
@@ -60,6 +61,7 @@ class ActronAirSystemCoordinator(DataUpdateCoordinator[ActronAirStatus]):
self.status = self.api.state_manager.get_status(self.serial_number)
self.last_seen = dt_util.utcnow()
@override
async def _async_update_data(self) -> ActronAirStatus:
"""Fetch updates and merge incremental changes into the full state."""
try:
@@ -2,7 +2,7 @@
from collections.abc import Callable, Coroutine
from functools import wraps
from typing import Any, Concatenate
from typing import Any, Concatenate, override
from actron_neo_api import ActronAirAPIError, ActronAirZone
@@ -50,6 +50,7 @@ class ActronAirEntity(CoordinatorEntity[ActronAirSystemCoordinator]):
self._serial_number = coordinator.serial_number
@property
@override
def available(self) -> bool:
"""Return True if entity is available."""
return not self.coordinator.is_device_stale()
@@ -12,9 +12,15 @@ rules:
docs-actions:
status: exempt
comment: This integration does not have custom service actions.
docs-conditions:
status: exempt
comment: This integration does not have any conditions.
docs-high-level-description: done
docs-installation-instructions: done
docs-removal-instructions: done
docs-triggers:
status: exempt
comment: This integration does not have any triggers.
entity-event-setup:
status: exempt
comment: This integration does not subscribe to external events.
@@ -2,7 +2,7 @@
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import Any
from typing import Any, override
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.const import EntityCategory
@@ -101,16 +101,19 @@ class ActronAirSwitch(ActronAirAcEntity, SwitchEntity):
self._attr_unique_id = f"{coordinator.serial_number}_{description.key}"
@property
@override
def is_on(self) -> bool:
"""Return true if the switch is on."""
return self.entity_description.is_on_fn(self.coordinator)
@actron_air_command
@override
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
await self.entity_description.set_fn(self.coordinator, True)
@actron_air_command
@override
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off."""
await self.entity_description.set_fn(self.coordinator, False)
+9 -1
View File
@@ -1,6 +1,6 @@
"""Support for Adax wifi-enabled home heaters."""
from typing import Any, cast
from typing import Any, cast, override
from adax import Adax
from adax_local import Adax as AdaxLocal
@@ -82,6 +82,7 @@ class AdaxDevice(CoordinatorEntity[AdaxCloudCoordinator], ClimateEntity):
self._apply_data(self.room)
@property
@override
def available(self) -> bool:
"""Whether the entity is available or not."""
return super().available and self._device_id in self.coordinator.data
@@ -91,6 +92,7 @@ class AdaxDevice(CoordinatorEntity[AdaxCloudCoordinator], ClimateEntity):
"""Gets the data for this particular device."""
return self.coordinator.data[self._device_id]
@override
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set hvac mode."""
if hvac_mode == HVACMode.HEAT:
@@ -108,6 +110,7 @@ class AdaxDevice(CoordinatorEntity[AdaxCloudCoordinator], ClimateEntity):
# Request data refresh from source to verify that update was successful
await self.coordinator.async_request_refresh()
@override
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
@@ -117,6 +120,7 @@ class AdaxDevice(CoordinatorEntity[AdaxCloudCoordinator], ClimateEntity):
)
@callback
@override
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
if room := self.room:
@@ -161,6 +165,7 @@ class LocalAdaxDevice(CoordinatorEntity[AdaxLocalCoordinator], ClimateEntity):
manufacturer="Adax",
)
@override
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set hvac mode."""
if hvac_mode == HVACMode.HEAT:
@@ -179,6 +184,7 @@ class LocalAdaxDevice(CoordinatorEntity[AdaxLocalCoordinator], ClimateEntity):
self._attr_hvac_mode = hvac_mode
self.async_write_ha_state()
@override
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
@@ -211,11 +217,13 @@ class LocalAdaxDevice(CoordinatorEntity[AdaxLocalCoordinator], ClimateEntity):
self._attr_target_temperature = target_temp
@callback
@override
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._update_hvac_attributes()
super()._handle_coordinator_update()
@override
async def async_added_to_hass(self) -> None:
"""When entity is added to hass."""
await super().async_added_to_hass()
+2 -1
View File
@@ -1,7 +1,7 @@
"""Config flow for Adax integration."""
import logging
from typing import Any
from typing import Any, override
import adax
import adax_local
@@ -39,6 +39,7 @@ class AdaxConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 2
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
+3 -1
View File
@@ -1,7 +1,7 @@
"""DataUpdateCoordinator for the Adax component."""
import logging
from typing import Any, cast
from typing import Any, cast, override
from adax import Adax
from adax_local import Adax as AdaxLocal
@@ -39,6 +39,7 @@ class AdaxCloudCoordinator(DataUpdateCoordinator[dict[str, dict[str, Any]]]):
websession=async_get_clientsession(hass),
)
@override
async def _async_update_data(self) -> dict[str, dict[str, Any]]:
"""Fetch data from the Adax."""
try:
@@ -87,6 +88,7 @@ class AdaxLocalCoordinator(DataUpdateCoordinator[dict[str, Any] | None]):
websession=async_get_clientsession(hass, verify_ssl=False),
)
@override
async def _async_update_data(self) -> dict[str, Any]:
"""Fetch data from the Adax."""
if result := await self.adax_data_handler.get_status():
+3 -1
View File
@@ -1,7 +1,7 @@
"""Support for Adax energy sensors."""
from dataclasses import dataclass
from typing import cast
from typing import cast, override
from homeassistant.components.sensor import (
SensorDeviceClass,
@@ -95,6 +95,7 @@ class AdaxSensor(CoordinatorEntity[AdaxCloudCoordinator], SensorEntity):
)
@property
@override
def available(self) -> bool:
"""Return True if entity is available."""
return (
@@ -104,6 +105,7 @@ class AdaxSensor(CoordinatorEntity[AdaxCloudCoordinator], SensorEntity):
)
@property
@override
def native_value(self) -> int | float | None:
"""Return the native value of the sensor."""
return self.coordinator.data[self._device_id].get(
@@ -1,6 +1,6 @@
"""Config flow to configure the AdGuard Home integration."""
from typing import Any
from typing import Any, override
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
import voluptuous as vol
@@ -57,6 +57,7 @@ class AdGuardHomeFlowHandler(ConfigFlow, domain=DOMAIN):
errors=errors or {},
)
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@@ -102,6 +103,7 @@ class AdGuardHomeFlowHandler(ConfigFlow, domain=DOMAIN):
},
)
@override
async def async_step_hassio(
self, discovery_info: HassioServiceInfo
) -> ConfigFlowResult:
@@ -1,5 +1,7 @@
"""AdGuard Home base entity."""
from typing import override
from adguardhome import AdGuardHomeError
from homeassistant.config_entries import SOURCE_HASSIO
@@ -47,6 +49,7 @@ class AdGuardHomeEntity(Entity):
raise NotImplementedError
@property
@override
def device_info(self) -> DeviceInfo:
"""Return device information about this AdGuard Home instance."""
if self._entry.source == SOURCE_HASSIO:
+3 -2
View File
@@ -3,7 +3,7 @@
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from datetime import timedelta
from typing import Any
from typing import Any, override
from adguardhome import AdGuardHome
@@ -108,7 +108,7 @@ class AdGuardHomeSensor(AdGuardHomeEntity, SensorEntity):
"""Initialize AdGuard Home sensor."""
super().__init__(data, entry)
self.entity_description = description
self._attr_unique_id = "_".join(
self._attr_unique_id = "_".join( # pylint: disable=home-assistant-entity-unique-id-redundant-domain
[
DOMAIN,
self.adguard.host,
@@ -118,6 +118,7 @@ class AdGuardHomeSensor(AdGuardHomeEntity, SensorEntity):
]
)
@override
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
value = await self.entity_description.value_fn(self.adguard)
+5 -2
View File
@@ -3,7 +3,7 @@
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from datetime import timedelta
from typing import Any
from typing import Any, override
from adguardhome import AdGuardHome, AdGuardHomeError
@@ -103,7 +103,7 @@ class AdGuardHomeSwitch(AdGuardHomeEntity, SwitchEntity):
"""Initialize AdGuard Home switch."""
super().__init__(data, entry)
self.entity_description = description
self._attr_unique_id = "_".join(
self._attr_unique_id = "_".join( # pylint: disable=home-assistant-entity-unique-id-redundant-domain
[
DOMAIN,
self.adguard.host,
@@ -113,6 +113,7 @@ class AdGuardHomeSwitch(AdGuardHomeEntity, SwitchEntity):
]
)
@override
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the switch."""
try:
@@ -124,6 +125,7 @@ class AdGuardHomeSwitch(AdGuardHomeEntity, SwitchEntity):
translation_key="error_while_turn_off",
) from err
@override
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the switch."""
try:
@@ -135,6 +137,7 @@ class AdGuardHomeSwitch(AdGuardHomeEntity, SwitchEntity):
translation_key="error_while_turn_on",
) from err
@override
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._attr_is_on = await self.entity_description.is_on_fn(self.adguard)()
+4 -2
View File
@@ -1,7 +1,7 @@
"""AdGuard Home Update platform."""
from datetime import timedelta
from typing import Any
from typing import Any, override
from adguardhome import AdGuardHomeError
@@ -46,10 +46,11 @@ class AdGuardHomeUpdate(AdGuardHomeEntity, UpdateEntity):
"""Initialize AdGuard Home update."""
super().__init__(data, entry)
self._attr_unique_id = "_".join(
self._attr_unique_id = "_".join( # pylint: disable=home-assistant-entity-unique-id-redundant-domain
[DOMAIN, self.adguard.host, str(self.adguard.port), "update"]
)
@override
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
value = await self.adguard.update.update_available()
@@ -58,6 +59,7 @@ class AdGuardHomeUpdate(AdGuardHomeEntity, UpdateEntity):
self._attr_release_summary = value.announcement
self._attr_release_url = value.announcement_url
@override
async def async_install(
self, version: str | None, backup: bool, **kwargs: Any
) -> None:
@@ -1,5 +1,7 @@
"""Support for ADS binary sensors."""
from typing import override
import pyads
import voluptuous as vol
@@ -60,11 +62,13 @@ class AdsBinarySensor(AdsEntity, BinarySensorEntity):
super().__init__(ads_hub, name, ads_var)
self._attr_device_class = device_class or BinarySensorDeviceClass.MOVING
@override
async def async_added_to_hass(self) -> None:
"""Register device notification."""
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_BOOL)
@property
@override
def is_on(self) -> bool:
"""Return True if the entity is on."""
return self._state_dict[STATE_KEY_STATE]
+9 -1
View File
@@ -1,6 +1,6 @@
"""Support for ADS covers."""
from typing import Any
from typing import Any, override
import pyads
import voluptuous as vol
@@ -122,6 +122,7 @@ class AdsCover(AdsEntity, CoverEntity):
if ads_var_pos_set is not None:
self._attr_supported_features |= CoverEntityFeature.SET_POSITION
@override
async def async_added_to_hass(self) -> None:
"""Register device notification."""
if self._ads_var is not None:
@@ -133,6 +134,7 @@ class AdsCover(AdsEntity, CoverEntity):
)
@property
@override
def is_closed(self) -> bool | None:
"""Return if the cover is closed."""
if self._ads_var is not None:
@@ -142,15 +144,18 @@ class AdsCover(AdsEntity, CoverEntity):
return None
@property
@override
def current_cover_position(self) -> int:
"""Return current position of cover."""
return self._state_dict[STATE_KEY_POSITION]
@override
def stop_cover(self, **kwargs: Any) -> None:
"""Fire the stop action."""
if self._ads_var_stop:
self._ads_hub.write_by_name(self._ads_var_stop, True, pyads.PLCTYPE_BOOL)
@override
def set_cover_position(self, **kwargs: Any) -> None:
"""Set cover position."""
position = kwargs[ATTR_POSITION]
@@ -159,6 +164,7 @@ class AdsCover(AdsEntity, CoverEntity):
self._ads_var_pos_set, position, pyads.PLCTYPE_BYTE
)
@override
def open_cover(self, **kwargs: Any) -> None:
"""Move the cover up."""
if self._ads_var_open is not None:
@@ -166,6 +172,7 @@ class AdsCover(AdsEntity, CoverEntity):
elif self._ads_var_pos_set is not None:
self.set_cover_position(position=100)
@override
def close_cover(self, **kwargs: Any) -> None:
"""Move the cover down."""
if self._ads_var_close is not None:
@@ -174,6 +181,7 @@ class AdsCover(AdsEntity, CoverEntity):
self.set_cover_position(position=0)
@property
@override
def available(self) -> bool:
"""Return False if state has not been updated yet."""
if self._ads_var is not None or self._ads_var_position is not None:
+2 -1
View File
@@ -3,7 +3,7 @@
import asyncio
from asyncio import timeout
import logging
from typing import Any
from typing import Any, override
from homeassistant.helpers.entity import Entity
@@ -65,6 +65,7 @@ class AdsEntity(Entity):
_LOGGER.debug("Variable %s: Timeout during first update", ads_var)
@property
@override
def available(self) -> bool:
"""Return False if state has not been updated yet."""
return self._state_dict[STATE_KEY_STATE] is not None
+7 -1
View File
@@ -1,6 +1,6 @@
"""Support for ADS light sources."""
from typing import Any
from typing import Any, override
import pyads
import voluptuous as vol
@@ -120,6 +120,7 @@ class AdsLight(AdsEntity, LightEntity):
else DEFAULT_MAX_KELVIN
)
@override
async def async_added_to_hass(self) -> None:
"""Register device notification."""
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_BOOL)
@@ -139,20 +140,24 @@ class AdsLight(AdsEntity, LightEntity):
)
@property
@override
def brightness(self) -> int | None:
"""Return the brightness of the light (0..255)."""
return self._state_dict[STATE_KEY_BRIGHTNESS]
@property
@override
def color_temp_kelvin(self) -> int | None:
"""Return the color temperature in Kelvin."""
return self._state_dict[STATE_KEY_COLOR_TEMP_KELVIN]
@property
@override
def is_on(self) -> bool:
"""Return True if the entity is on."""
return self._state_dict[STATE_KEY_STATE]
@override
def turn_on(self, **kwargs: Any) -> None:
"""Turn the light on or set a specific dimmer value."""
brightness = kwargs.get(ATTR_BRIGHTNESS)
@@ -170,6 +175,7 @@ class AdsLight(AdsEntity, LightEntity):
self._ads_var_color_temp_kelvin, color_temp, pyads.PLCTYPE_UINT
)
@override
def turn_off(self, **kwargs: Any) -> None:
"""Turn the light off."""
self._ads_hub.write_by_name(self._ads_var, False, pyads.PLCTYPE_BOOL)
+4
View File
@@ -1,5 +1,7 @@
"""Support for ADS select entities."""
from typing import override
import pyads
import voluptuous as vol
@@ -61,6 +63,7 @@ class AdsSelect(AdsEntity, SelectEntity):
self._attr_options = options
self._attr_current_option = None
@override
async def async_added_to_hass(self) -> None:
"""Register device notification."""
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_INT)
@@ -68,6 +71,7 @@ class AdsSelect(AdsEntity, SelectEntity):
self._ads_var, pyads.PLCTYPE_INT, self._handle_ads_value
)
@override
def select_option(self, option: str) -> None:
"""Change the selected option."""
if option in self._attr_options:
+4
View File
@@ -1,5 +1,7 @@
"""Support for ADS sensors."""
from typing import override
import voluptuous as vol
from homeassistant.components.sensor import (
@@ -108,6 +110,7 @@ class AdsSensor(AdsEntity, SensorEntity):
self._attr_state_class = state_class
self._attr_native_unit_of_measurement = unit_of_measurement
@override
async def async_added_to_hass(self) -> None:
"""Register device notification."""
await self.async_initialize_device(
@@ -118,6 +121,7 @@ class AdsSensor(AdsEntity, SensorEntity):
)
@property
@override
def native_value(self) -> StateType:
"""Return the state of the device."""
return self._state_dict[STATE_KEY_STATE]
+5 -1
View File
@@ -1,6 +1,6 @@
"""Support for ADS switch platform."""
from typing import Any
from typing import Any, override
import pyads
import voluptuous as vol
@@ -46,19 +46,23 @@ def setup_platform(
class AdsSwitch(AdsEntity, SwitchEntity):
"""Representation of an ADS switch device."""
@override
async def async_added_to_hass(self) -> None:
"""Register device notification."""
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_BOOL)
@property
@override
def is_on(self) -> bool:
"""Return True if the entity is on."""
return self._state_dict[STATE_KEY_STATE]
@override
def turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
self._ads_hub.write_by_name(self._ads_var, True, pyads.PLCTYPE_BOOL)
@override
def turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off."""
self._ads_hub.write_by_name(self._ads_var, False, pyads.PLCTYPE_BOOL)
+5
View File
@@ -1,5 +1,7 @@
"""Support for ADS valves."""
from typing import override
import pyads
import voluptuous as vol
@@ -67,15 +69,18 @@ class AdsValve(AdsEntity, ValveEntity):
self._attr_reports_position = False
self._attr_is_closed = True
@override
async def async_added_to_hass(self) -> None:
"""Register device notification."""
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_BOOL)
@override
def open_valve(self, **kwargs) -> None:
"""Open the valve."""
self._ads_hub.write_by_name(self._ads_var, True, pyads.PLCTYPE_BOOL)
self._attr_is_closed = False
@override
def close_valve(self, **kwargs) -> None:
"""Close the valve."""
self._ads_hub.write_by_name(self._ads_var, False, pyads.PLCTYPE_BOOL)
@@ -1,5 +1,7 @@
"""Binary Sensor platform for Advantage Air integration."""
from typing import override
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
@@ -55,6 +57,7 @@ class AdvantageAirFilter(AdvantageAirAcEntity, BinarySensorEntity):
self._attr_unique_id += "-filter"
@property
@override
def is_on(self) -> bool:
"""Return if filter needs cleaning."""
return self._ac["filterCleanStatus"]
@@ -74,6 +77,7 @@ class AdvantageAirZoneMotion(AdvantageAirZoneEntity, BinarySensorEntity):
self._attr_unique_id += "-motion"
@property
@override
def is_on(self) -> bool:
"""Return if motion is detect."""
return self._zone["motion"] == 20
@@ -94,6 +98,7 @@ class AdvantageAirZoneMyZone(AdvantageAirZoneEntity, BinarySensorEntity):
self._attr_unique_id += "-myzone"
@property
@override
def is_on(self) -> bool:
"""Return if this zone is the myZone."""
return self._zone["number"] == self._ac["myZone"]
@@ -2,7 +2,7 @@
from decimal import Decimal
import logging
from typing import Any
from typing import Any, override
from homeassistant.components.climate import (
ATTR_TARGET_TEMP_HIGH,
@@ -156,12 +156,14 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
)
@callback
@override
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._async_configure_preset()
super()._handle_coordinator_update()
@property
@override
def current_temperature(self) -> float | None:
"""Return the selected zones current temperature."""
if self._myzone:
@@ -169,6 +171,7 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
return None
@property
@override
def target_temperature(self) -> float | None:
"""Return the current target temperature."""
# If the system is in MyZone mode, and a zone is set,
@@ -178,6 +181,7 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
return self._ac["setTemp"]
@property
@override
def hvac_mode(self) -> HVACMode | None:
"""Return the current HVAC modes."""
if self._ac["state"] == ADVANTAGE_AIR_STATE_ON:
@@ -185,6 +189,7 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
return HVACMode.OFF
@property
@override
def hvac_action(self) -> HVACAction | None:
"""Return the current running HVAC action."""
if self._ac["state"] == ADVANTAGE_AIR_STATE_OFF:
@@ -196,24 +201,29 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
return HVAC_ACTIONS.get(self._ac["mode"])
@property
@override
def fan_mode(self) -> str | None:
"""Return the current fan modes."""
return FAN_AUTO if self._ac["fan"] == ADVANTAGE_AIR_MYFAN else self._ac["fan"]
@property
@override
def target_temperature_high(self) -> float | None:
"""Return the temperature cool mode is enabled."""
return self._ac.get(ADVANTAGE_AIR_COOL_TARGET)
@property
@override
def target_temperature_low(self) -> float | None:
"""Return the temperature heat mode is enabled."""
return self._ac.get(ADVANTAGE_AIR_HEAT_TARGET)
@override
async def async_turn_on(self) -> None:
"""Set the HVAC State to on."""
await self.async_update_ac({"state": ADVANTAGE_AIR_STATE_ON})
@override
async def async_turn_off(self) -> None:
"""Set the HVAC State to off."""
await self.async_update_ac(
@@ -222,6 +232,7 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
}
)
@override
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the HVAC Mode and State."""
if hvac_mode == HVACMode.OFF:
@@ -236,6 +247,7 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
}
)
@override
async def async_set_fan_mode(self, fan_mode: str) -> None:
"""Set the Fan Mode."""
if fan_mode == FAN_AUTO and self._ac.get(ADVANTAGE_AIR_AUTOFAN_ENABLED):
@@ -244,6 +256,7 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
mode = fan_mode
await self.async_update_ac({"fan": mode})
@override
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set the Temperature."""
if ATTR_TEMPERATURE in kwargs:
@@ -256,6 +269,7 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
}
)
@override
async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set the preset mode."""
change = {}
@@ -289,6 +303,7 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity):
self._attr_name = self._zone["name"]
@property
@override
def hvac_mode(self) -> HVACMode:
"""Return the current state as HVAC mode."""
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
@@ -296,6 +311,7 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity):
return HVACMode.OFF
@property
@override
def hvac_action(self) -> HVACAction | None:
"""Return the HVAC action.
@@ -316,23 +332,28 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity):
return HVACAction.OFF
@property
@override
def current_temperature(self) -> float | None:
"""Return the current temperature."""
return self._zone["measuredTemp"]
@property
@override
def target_temperature(self) -> float:
"""Return the target temperature."""
return self._zone["setTemp"]
@override
async def async_turn_on(self) -> None:
"""Set the HVAC State to on."""
await self.async_update_zone({"state": ADVANTAGE_AIR_STATE_OPEN})
@override
async def async_turn_off(self) -> None:
"""Set the HVAC State to off."""
await self.async_update_zone({"state": ADVANTAGE_AIR_STATE_CLOSE})
@override
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the HVAC Mode and State."""
if hvac_mode == HVACMode.OFF:
@@ -340,6 +361,7 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity):
else:
await self.async_turn_on()
@override
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set the Temperature."""
temp = kwargs.get(ATTR_TEMPERATURE)
@@ -1,6 +1,6 @@
"""Config Flow for Advantage Air integration."""
from typing import Any
from typing import Any, override
from advantage_air import ApiError, advantage_air
import voluptuous as vol
@@ -28,6 +28,7 @@ class AdvantageAirConfigFlow(ConfigFlow, domain=DOMAIN):
DOMAIN = DOMAIN
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@@ -2,7 +2,7 @@
from datetime import timedelta
import logging
from typing import Any
from typing import Any, override
from advantage_air import ApiError, advantage_air
@@ -45,6 +45,7 @@ class AdvantageAirCoordinator(DataUpdateCoordinator[dict[str, Any]]):
)
self.api = api
@override
async def _async_update_data(self) -> dict[str, Any]:
"""Fetch data from the API."""
try:
@@ -1,6 +1,6 @@
"""Cover platform for Advantage Air integration."""
from typing import Any
from typing import Any, override
from homeassistant.components.cover import (
ATTR_POSITION,
@@ -66,27 +66,32 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, CoverEntity):
self._attr_name = self._zone["name"]
@property
@override
def is_closed(self) -> bool:
"""Return if vent is fully closed."""
return self._zone["state"] == ADVANTAGE_AIR_STATE_CLOSE
@property
@override
def current_cover_position(self) -> int:
"""Return vents current position as a percentage."""
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
return self._zone["value"]
return 0
@override
async def async_open_cover(self, **kwargs: Any) -> None:
"""Fully open zone vent."""
await self.async_update_zone(
{"state": ADVANTAGE_AIR_STATE_OPEN, "value": 100},
)
@override
async def async_close_cover(self, **kwargs: Any) -> None:
"""Fully close zone vent."""
await self.async_update_zone({"state": ADVANTAGE_AIR_STATE_CLOSE})
@override
async def async_set_cover_position(self, **kwargs: Any) -> None:
"""Change vent position."""
position = round(kwargs[ATTR_POSITION] / 5) * 5
@@ -117,14 +122,17 @@ class AdvantageAirThingCover(AdvantageAirThingEntity, CoverEntity):
self._attr_device_class = device_class
@property
@override
def is_closed(self) -> bool:
"""Return if cover is fully closed."""
return self._data["value"] == 0
@override
async def async_open_cover(self, **kwargs: Any) -> None:
"""Fully open zone vent."""
return await self.async_turn_on()
@override
async def async_close_cover(self, **kwargs: Any) -> None:
"""Fully close zone vent."""
return await self.async_turn_off()
@@ -1,6 +1,6 @@
"""Light platform for Advantage Air integration."""
from typing import Any
from typing import Any, override
from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity
from homeassistant.core import HomeAssistant
@@ -70,14 +70,17 @@ class AdvantageAirLight(AdvantageAirEntity, LightEntity):
return self.coordinator.data["myLights"]["lights"][self._id]
@property
@override
def is_on(self) -> bool:
"""Return if the light is on."""
return self._data["state"] == ADVANTAGE_AIR_STATE_ON
@override
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the light on."""
await self.async_update_state(True)
@override
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the light off."""
await self.async_update_state(False)
@@ -99,10 +102,12 @@ class AdvantageAirLightDimmable(AdvantageAirLight):
)
@property
@override
def brightness(self) -> int:
"""Return the brightness of this light between 0..255."""
return round(self._data["value"] * 255 / 100)
@override
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the light on and optionally set the brightness."""
if ATTR_BRIGHTNESS in kwargs:
@@ -124,10 +129,12 @@ class AdvantageAirThingLightDimmable(AdvantageAirThingEntity, LightEntity):
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
@property
@override
def brightness(self) -> int:
"""Return the brightness of this light between 0..255."""
return round(self._data["value"] * 255 / 100)
@override
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the light on by setting the brightness."""
await self.async_update_value(round(kwargs.get(ATTR_BRIGHTNESS, 255) / 2.55))
@@ -18,9 +18,15 @@ rules:
comment: Data descriptions missing
dependency-transparency: done
docs-actions: done
docs-conditions:
status: exempt
comment: This integration does not have any conditions.
docs-high-level-description: done
docs-installation-instructions: todo
docs-removal-instructions: todo
docs-triggers:
status: exempt
comment: This integration does not have any triggers.
entity-event-setup:
status: exempt
comment: Entities do not explicitly subscribe to events.
@@ -1,5 +1,7 @@
"""Select platform for Advantage Air integration."""
from typing import override
from homeassistant.components.select import SelectEntity
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@@ -48,10 +50,12 @@ class AdvantageAirMyZone(AdvantageAirAcEntity, SelectEntity):
self._attr_options.append(zone["name"])
@property
@override
def current_option(self) -> str:
"""Return the current MyZone."""
return self._number_to_name[self._ac["myZone"]]
@override
async def async_select_option(self, option: str) -> None:
"""Set the MyZone."""
await self.async_update_ac({"myZone": self._name_to_number[option]})
@@ -1,7 +1,7 @@
"""Sensor platform for Advantage Air integration."""
from decimal import Decimal
from typing import Any
from typing import Any, override
from homeassistant.components.sensor import (
SensorDeviceClass,
@@ -67,11 +67,13 @@ class AdvantageAirTimeTo(AdvantageAirAcEntity, SensorEntity):
self._attr_unique_id += f"-timeto{action}"
@property
@override
def native_value(self) -> Decimal:
"""Return the current value."""
return self._ac[self._time_key]
@property
@override
def icon(self) -> str:
"""Return a representative icon of the timer."""
if self._ac[self._time_key] > 0:
@@ -100,6 +102,7 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, SensorEntity):
self._attr_unique_id += "-vent"
@property
@override
def native_value(self) -> Decimal:
"""Return the current value of the air vent."""
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
@@ -107,6 +110,7 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, SensorEntity):
return Decimal(0)
@property
@override
def icon(self) -> str:
"""Return a representative icon."""
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
@@ -130,11 +134,13 @@ class AdvantageAirZoneSignal(AdvantageAirZoneEntity, SensorEntity):
self._attr_unique_id += "-signal"
@property
@override
def native_value(self) -> Decimal:
"""Return the current value of the wireless signal."""
return self._zone["rssi"]
@property
@override
def icon(self) -> str:
"""Return a representative icon."""
if self._zone["rssi"] >= 80:
@@ -166,6 +172,7 @@ class AdvantageAirZoneTemp(AdvantageAirZoneEntity, SensorEntity):
self._attr_unique_id += "-temp"
@property
@override
def native_value(self) -> Decimal:
"""Return the current value of the measured temperature."""
return self._zone["measuredTemp"]
@@ -1,6 +1,6 @@
"""Switch platform for Advantage Air integration."""
from typing import Any
from typing import Any, override
from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
from homeassistant.core import HomeAssistant
@@ -57,14 +57,17 @@ class AdvantageAirFreshAir(AdvantageAirAcEntity, SwitchEntity):
self._attr_unique_id += "-freshair"
@property
@override
def is_on(self) -> bool:
"""Return the fresh air status."""
return self._ac["freshAirStatus"] == ADVANTAGE_AIR_STATE_ON
@override
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn fresh air on."""
await self.async_update_ac({"freshAirStatus": ADVANTAGE_AIR_STATE_ON})
@override
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn fresh air off."""
await self.async_update_ac({"freshAirStatus": ADVANTAGE_AIR_STATE_OFF})
@@ -83,14 +86,17 @@ class AdvantageAirMyFan(AdvantageAirAcEntity, SwitchEntity):
self._attr_unique_id += "-myfan"
@property
@override
def is_on(self) -> bool:
"""Return the MyFan status."""
return self._ac[ADVANTAGE_AIR_AUTOFAN_ENABLED]
@override
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn MyFan on."""
await self.async_update_ac({ADVANTAGE_AIR_AUTOFAN_ENABLED: True})
@override
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn MyFan off."""
await self.async_update_ac({ADVANTAGE_AIR_AUTOFAN_ENABLED: False})
@@ -109,14 +115,17 @@ class AdvantageAirNightMode(AdvantageAirAcEntity, SwitchEntity):
self._attr_unique_id += "-nightmode"
@property
@override
def is_on(self) -> bool:
"""Return the Night Mode status."""
return self._ac[ADVANTAGE_AIR_NIGHT_MODE_ENABLED]
@override
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn Night Mode on."""
await self.async_update_ac({ADVANTAGE_AIR_NIGHT_MODE_ENABLED: True})
@override
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn Night Mode off."""
await self.async_update_ac({ADVANTAGE_AIR_NIGHT_MODE_ENABLED: False})
@@ -1,5 +1,7 @@
"""Advantage Air Update platform."""
from typing import override
from homeassistant.components.update import UpdateEntity
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
@@ -40,11 +42,13 @@ class AdvantageAirApp(AdvantageAirEntity, UpdateEntity):
)
@property
@override
def installed_version(self) -> str:
"""Return the current app version."""
return self.coordinator.data["system"]["myAppRev"]
@property
@override
def latest_version(self) -> str:
"""Return if there is an update."""
if self.coordinator.data["system"]["needsUpdate"]:
@@ -1,6 +1,6 @@
"""Config flow for AEMET OpenData."""
from typing import Any
from typing import Any, override
from aemet_opendata.exceptions import AuthError
from aemet_opendata.interface import AEMET, ConnectionOptions
@@ -31,6 +31,7 @@ OPTIONS_FLOW = {
class AemetConfigFlow(ConfigFlow, domain=DOMAIN):
"""Config flow for AEMET OpenData."""
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@@ -82,6 +83,7 @@ class AemetConfigFlow(ConfigFlow, domain=DOMAIN):
@staticmethod
@callback
@override
def async_get_options_flow(
config_entry: ConfigEntry,
) -> SchemaOptionsFlowHandler:
@@ -4,7 +4,7 @@ from asyncio import timeout
from dataclasses import dataclass
from datetime import timedelta
import logging
from typing import Any, Final, cast
from typing import Any, Final, cast, override
from aemet_opendata.const import (
AOD_CONDITION,
@@ -60,6 +60,7 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
update_interval=WEATHER_UPDATE_INTERVAL,
)
@override
async def _async_update_data(self) -> dict[str, Any]:
"""Update coordinator data."""
async with timeout(API_TIMEOUT):
+2 -1
View File
@@ -1,6 +1,6 @@
"""Support for the AEMET OpenData images."""
from typing import Final
from typing import Final, override
from aemet_opendata.const import AOD_DATETIME, AOD_IMG_BYTES, AOD_IMG_TYPE, AOD_RADAR
from aemet_opendata.helpers import dict_nested_value
@@ -68,6 +68,7 @@ class AemetImage(AemetEntity, ImageEntity):
self._async_update_attrs()
@callback
@override
def _handle_coordinator_update(self) -> None:
"""Update attributes when the coordinator updates."""
self._async_update_attrs()
+2 -1
View File
@@ -3,7 +3,7 @@
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime
from typing import Final
from typing import Final, override
from aemet_opendata.const import (
AOD_CONDITION,
@@ -399,6 +399,7 @@ class AemetSensor(AemetEntity, SensorEntity):
self._attr_unique_id = f"{unique_id}-{description.key}"
@property
@override
def native_value(self):
"""Return the state of the device."""
value = self.get_aemet_value(self.entity_description.keys)
+11
View File
@@ -1,5 +1,7 @@
"""Support for the AEMET OpenData service."""
from typing import override
from aemet_opendata.const import (
AOD_CONDITION,
AOD_FORECAST_DAILY,
@@ -74,47 +76,56 @@ class AemetWeather(
self._attr_unique_id = unique_id
@property
@override
def condition(self) -> str | None:
"""Return the current condition."""
cond = self.get_aemet_value([AOD_WEATHER, AOD_CONDITION])
return CONDITIONS_MAP.get(cond)
@callback
@override
def _async_forecast_daily(self) -> list[Forecast]:
"""Return the daily forecast in native units."""
return self.get_aemet_forecast(AOD_FORECAST_DAILY)
@callback
@override
def _async_forecast_hourly(self) -> list[Forecast]:
"""Return the hourly forecast in native units."""
return self.get_aemet_forecast(AOD_FORECAST_HOURLY)
@property
@override
def humidity(self) -> float | None:
"""Return the humidity."""
return self.get_aemet_value([AOD_WEATHER, AOD_HUMIDITY])
@property
@override
def native_pressure(self) -> float | None:
"""Return the pressure."""
return self.get_aemet_value([AOD_WEATHER, AOD_PRESSURE])
@property
@override
def native_temperature(self) -> float | None:
"""Return the temperature."""
return self.get_aemet_value([AOD_WEATHER, AOD_TEMP])
@property
@override
def wind_bearing(self) -> float | None:
"""Return the wind bearing."""
return self.get_aemet_value([AOD_WEATHER, AOD_WIND_DIRECTION])
@property
@override
def native_wind_gust_speed(self) -> float | None:
"""Return the wind gust speed in native units."""
return self.get_aemet_value([AOD_WEATHER, AOD_WIND_SPEED_MAX])
@property
@override
def native_wind_speed(self) -> float | None:
"""Return the wind speed."""
return self.get_aemet_value([AOD_WEATHER, AOD_WIND_SPEED])
@@ -1,7 +1,7 @@
"""Config flow for AfterShip integration."""
import logging
from typing import Any
from typing import Any, override
from pyaftership import AfterShip, AfterShipException
import voluptuous as vol
@@ -20,6 +20,7 @@ class AfterShipConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 1
@override
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
+4 -1
View File
@@ -1,7 +1,7 @@
"""Support for non-delivered packages recorded in AfterShip."""
import logging
from typing import Any, Final
from typing import Any, Final, override
from pyaftership import AfterShip, AfterShipException
@@ -96,15 +96,18 @@ class AfterShipSensor(SensorEntity):
self._attr_name = name
@property
@override
def native_value(self) -> int | None:
"""Return the state of the sensor."""
return self._state
@property
@override
def extra_state_attributes(self) -> dict[str, str]:
"""Return attributes for the sensor."""
return self._attributes
@override
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
self.async_on_remove(
@@ -1,5 +1,7 @@
"""Support for Agent DVR Alarm Control Panels."""
from typing import override
from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
AlarmControlPanelEntityFeature,
@@ -70,23 +72,27 @@ class AgentBaseStation(AlarmControlPanelEntity):
else:
self._attr_alarm_state = AlarmControlPanelState.DISARMED
@override
async def async_alarm_disarm(self, code: str | None = None) -> None:
"""Send disarm command."""
await self._client.disarm()
self._attr_alarm_state = AlarmControlPanelState.DISARMED
@override
async def async_alarm_arm_away(self, code: str | None = None) -> None:
"""Send arm away command. Uses custom mode."""
await self._client.arm()
await self._client.set_active_profile(CONF_AWAY_MODE_NAME)
self._attr_alarm_state = AlarmControlPanelState.ARMED_AWAY
@override
async def async_alarm_arm_home(self, code: str | None = None) -> None:
"""Send arm home command. Uses custom mode."""
await self._client.arm()
await self._client.set_active_profile(CONF_HOME_MODE_NAME)
self._attr_alarm_state = AlarmControlPanelState.ARMED_HOME
@override
async def async_alarm_arm_night(self, code: str | None = None) -> None:
"""Send arm night command. Uses custom mode."""
await self._client.arm()
@@ -2,6 +2,7 @@
from datetime import timedelta
import logging
from typing import override
from agent import AgentError
@@ -95,6 +96,7 @@ class AgentCamera(MjpegCamera):
}
@property
@override
def is_recording(self) -> bool:
"""Return whether the monitor is recording."""
return self.device.recording
@@ -115,11 +117,13 @@ class AgentCamera(MjpegCamera):
return self.device.connected
@property
@override
def is_on(self) -> bool:
"""Return true if on."""
return self.device.online
@property
@override
def motion_detection_enabled(self) -> bool:
"""Return the camera motion detection status."""
return self.device.detector_active
@@ -132,10 +136,12 @@ class AgentCamera(MjpegCamera):
"""Disable alerts."""
await self.device.alerts_off()
@override
async def async_enable_motion_detection(self) -> None:
"""Enable motion detection."""
await self.device.detector_on()
@override
async def async_disable_motion_detection(self) -> None:
"""Disable motion detection."""
await self.device.detector_off()
@@ -148,6 +154,7 @@ class AgentCamera(MjpegCamera):
"""Stop recording."""
await self.device.record_stop()
@override
async def async_turn_on(self) -> None:
"""Enable the camera."""
await self.device.enable()
@@ -156,6 +163,7 @@ class AgentCamera(MjpegCamera):
"""Take a snapshot."""
await self.device.snapshot()
@override
async def async_turn_off(self) -> None:
"""Disable the camera."""
await self.device.disable()

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