Compare commits

..

158 Commits

Author SHA1 Message Date
Claude 16ec9f43c9 Fix flaky test in hydrawise by falling back to main coordinator data
When new zones/controllers are discovered by the main coordinator,
entities may be created for the water_use coordinator before it has
refreshed. This caused KeyError when accessing zones/controllers
that exist in the main coordinator but not yet in the water_use
coordinator's data.

The fix adds a _get_data() method that checks if the entity's
controller/zone exists in the current coordinator's data, and falls
back to the main coordinator's data if not. This also handles the
case when controllers/zones are removed - the entity gracefully
skips updating instead of raising KeyError.
2025-12-15 02:39:30 +00:00
Xidorn Quan e58fc6976d Bump aioasuswrt to 1.5.4 (#159038) 2025-12-15 01:04:42 +01:00
Kevin Fronczak 9def627a57 Bump blinkpy to 0.25.2 (#159049) 2025-12-15 00:57:21 +01:00
Paul Tarjan 9b56759c1e Add 'task:' label to exception handler log messages (#158674) 2025-12-14 23:55:13 +01:00
Joost Lekkerkerker c3f743cafd Add integration_type hub to fujitsu_fglair (#159026) 2025-12-14 23:51:59 +01:00
Joost Lekkerkerker 160c495ddc Add integration_type hub to freedompro (#159024) 2025-12-14 23:50:05 +01:00
Ludovic BOUÉ 9a1cd8545d Add Ikea scroll wheel Matter fixture (#159037) 2025-12-14 23:49:55 +01:00
Joost Lekkerkerker fa81e6cd04 Add integration_type device to frontier_silicon (#159025) 2025-12-14 23:49:38 +01:00
Joost Lekkerkerker 746f4ef1e2 Add integration_type service to glances (#159033) 2025-12-14 23:49:31 +01:00
Joost Lekkerkerker 0149de6ba6 Add integration_type service to anglian_water (#158839) 2025-12-14 21:16:52 +01:00
Joost Lekkerkerker 1df2f18e0a Add integration_type service to environment_canada (#159007) 2025-12-14 21:12:54 +01:00
Joost Lekkerkerker 5800824893 Add integration_type service to firefly_iii (#159013) 2025-12-14 21:12:23 +01:00
Joost Lekkerkerker aac07b6b4b Add integration_type device to fully_kiosk (#159027) 2025-12-14 21:10:29 +01:00
Joost Lekkerkerker 2448ce1970 Add integration_type service to garages_amsterdam (#159028) 2025-12-14 21:08:34 +01:00
Joost Lekkerkerker 7b40e3b8a7 Add integration_type service to geocaching (#159030) 2025-12-14 21:07:31 +01:00
Joost Lekkerkerker 29d06cfcc9 Add integration_type service to github (#159032) 2025-12-14 19:29:44 +01:00
Joost Lekkerkerker 365d168ddd Add integration_type device to gardena_bluetooth (#159029) 2025-12-14 19:20:54 +01:00
Joost Lekkerkerker 234191336e Add integration_type service to fitbit (#159015) 2025-12-14 10:19:34 -08:00
Joost Lekkerkerker ba57b72658 Add integration_type service to elvia (#159002) 2025-12-14 19:09:12 +01:00
Allen Porter bb08b315b8 Add exception handling for rate limited or unauthorized MQTT requests (#158997) 2025-12-14 18:45:12 +01:00
Petro31 50621df244 Update unnecessary error logging of unknown and unavailable source states from mold indicator (#158979) 2025-12-14 16:52:38 +01:00
Jan Bouwhuis 2db7b5c99f Assume cover or valve is always "running" in google assistant when the state is assumed or the position is reported to allow it to be be stopped (#158919) 2025-12-14 10:24:40 -05:00
Michael 78af3acf35 Bump pyfritzhome to 0.6.18 (#158877) 2025-12-14 08:12:25 +01:00
Joost Lekkerkerker b72f04d44e Add integration_type hub to electrasmart (#158942) 2025-12-14 07:17:50 +01:00
Joost Lekkerkerker 35f287e330 Add integration_type hub to ekeybionyx (#158941) 2025-12-14 07:16:40 +01:00
Joost Lekkerkerker 0a55f83b46 Add integration_type hub to econet (#158940) 2025-12-14 07:14:44 +01:00
Joost Lekkerkerker 5030d0ba90 Add integration_type device to ecoforest (#158939) 2025-12-14 07:13:44 +01:00
Joost Lekkerkerker f582f06ee4 Add integration_type service to eafm (#158937) 2025-12-14 06:59:46 +01:00
Joost Lekkerkerker 662bada5d8 Add integration_type hub to duotecno (#158936) 2025-12-14 06:59:13 +01:00
Joost Lekkerkerker 3ca338dd25 Add integration_type device to dunehd (#158935) 2025-12-14 06:58:03 +01:00
Joost Lekkerkerker 9337a0e71b Add integration_type device to droplet (#158933) 2025-12-14 06:56:08 +01:00
Joost Lekkerkerker ccbb00197d Add integration_type hub to drop_connect (#158932) 2025-12-14 06:55:22 +01:00
Joost Lekkerkerker 0f59c17e61 Add integration_type service to dexcom (#158928) 2025-12-14 06:42:34 +01:00
Joost Lekkerkerker 6253ade3e2 Add integration_type service to datadog (#158927) 2025-12-14 06:40:48 +01:00
Joost Lekkerkerker e5890378a1 Add integration_type device to daikin (#158926) 2025-12-14 06:40:29 +01:00
Joost Lekkerkerker b8ab0bcadf Add integration_type service to dnsip (#158930) 2025-12-13 16:25:51 -06:00
Joost Lekkerkerker 19cb827577 Add integration_type device to doorbird (#158931) 2025-12-13 16:23:37 -06:00
Joost Lekkerkerker 03676d7e5a Add integration_type hub to ecobee (#158938) 2025-12-13 16:23:15 -06:00
Magnus 13f3b49b96 Bump aioasuswrt 1.5.3 (#158882) 2025-12-13 22:43:21 +01:00
Allen Porter 90c8c56a06 Suppress roborock failures under some unavailability threshold (#158673)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 22:30:21 +01:00
Josef Zweck afb9e18a7d Add brew by weight controls to lamarzocco (#158169) 2025-12-13 22:28:11 +01:00
Andrew Jackson 2c2934065f Bump aiomealie to 1.1.1 and statically define mealplan entry types (#158907) 2025-12-13 22:26:31 +01:00
mettolen 0bead67df9 Add device uptime to Airobot integration (#158516) 2025-12-13 22:20:52 +01:00
James Cole 2895849203 Update strings for Firefly III integration (#158911) 2025-12-13 22:20:30 +01:00
David Recordon b2400708ac Add myself as a maintainer for Control4 (#158948) 2025-12-13 22:15:35 +01:00
Anthony Garera 0bed9c20b3 Bump python-overseerr to 0.8.0 (#158924) 2025-12-13 19:31:21 +01:00
Brett Adams d3fb7a7b87 Bump tesla-fleet-api to 1.2.7 (#158904) 2025-12-13 15:02:19 +01:00
Bouwe Westerdijk 60dcca4143 Show Plugwise configuration-link on gateway only (#158094) 2025-12-13 11:38:23 +01:00
Paul Tarjan 01f498f239 Clarify previous state in total_increasing warning message (#158805) 2025-12-13 11:15:37 +01:00
Andre Lengwenus 15055b8e8e Fix race condition in LCN climate and cover entites (#158894) 2025-12-13 11:12:20 +01:00
Bouwe Westerdijk 6826619e12 Revert adding entity_category to Plugwise thermostat schedule select (#158901) 2025-12-13 11:08:17 +01:00
Joost Lekkerkerker b50a8e04a8 Add integration_type hub to airtouch5 (#158834)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:47:27 +01:00
Joost Lekkerkerker c6c67c5357 Add integration_type hub to blue_current (#158863) 2025-12-13 10:46:12 +01:00
Joost Lekkerkerker c82803d1e2 Add integration_type hub to agent_dvr (#158829)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:45:09 +01:00
Joost Lekkerkerker 732b30f181 Add integration_type hub to airzone (#158835)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:44:05 +01:00
Joost Lekkerkerker 0e2e57a657 Add integration_type device to android_ip_webcam (#158838)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:42:39 +01:00
Joost Lekkerkerker f00b0080a9 Add integration_type device to advantage_air (#158826)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:39:58 +01:00
Joost Lekkerkerker ad970c1234 Add integration_type hub to cert_expiry (#158897) 2025-12-13 10:39:14 +01:00
Joost Lekkerkerker 02ec56bffa Add integration_type device to ccm15 (#158896)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-13 10:37:36 +01:00
Joost Lekkerkerker 8388c290bf Add integration_type hub to canary (#158895) 2025-12-13 09:41:01 +01:00
Joost Lekkerkerker 576ee99faf Add integration_type hub to control4 (#158900) 2025-12-13 09:36:36 +01:00
Joost Lekkerkerker 8a3534c345 Add integration_type service to coinbase (#158899) 2025-12-13 09:31:54 +01:00
Joost Lekkerkerker e1e91c5568 Add integration_type service to cloudflare (#158898) 2025-12-13 09:31:25 +01:00
epenet 1e09bddb1d Cleanup deprecated alias in core (#158799) 2025-12-13 09:29:15 +01:00
Joost Lekkerkerker 90e4340595 Add integration_type hub to brunt (#158870)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-12-13 09:04:05 +01:00
Joost Lekkerkerker 120b17349c Add integration_type service to aussie_broadband (#158853) 2025-12-13 08:56:35 +01:00
Joost Lekkerkerker 8a26961304 Add integration_type service to aurora (#158852) 2025-12-13 08:56:01 +01:00
Joost Lekkerkerker 407b675080 Add integration_type device to atag (#158850) 2025-12-13 08:55:35 +01:00
Joost Lekkerkerker 274844271b Add integration_type hub to aseko_pool_live (#158849) 2025-12-13 08:54:46 +01:00
Joost Lekkerkerker f11e4e7bda Add integration_type hub to aosmith (#158843) 2025-12-13 08:52:45 +01:00
Joost Lekkerkerker 96f8c39c6f Add integration_type device to anthemav (#158841) 2025-12-13 08:51:25 +01:00
Joost Lekkerkerker 77b79fef8d Add integration_type hub to anova (#158840) 2025-12-13 08:50:24 +01:00
mkmer a0d2f285f3 blink: Remove mkmer as codeowner (#158884) 2025-12-13 08:45:13 +01:00
Joost Lekkerkerker 3aef05d1ec Add integration_type hub to airzone_cloud (#158836) 2025-12-13 08:43:57 +01:00
Joost Lekkerkerker 510e391ee4 Add integration_type device to airtouch4 (#158833) 2025-12-13 08:41:17 +01:00
Joost Lekkerkerker 54adfdd694 Add integration_type device to bluesound (#158865) 2025-12-13 08:38:48 +01:00
Joost Lekkerkerker d45f920b4a Add integration_type service to amberelectric (#158837) 2025-12-13 08:37:16 +01:00
Joost Lekkerkerker 3080ef9a4a Add integration_type device to airthings_ble (#158832) 2025-12-13 08:36:06 +01:00
Joost Lekkerkerker 51cebb52f3 Add integration_type hub to airthings (#158831) 2025-12-13 08:34:28 +01:00
Joost Lekkerkerker 7b0d4c47b7 Add integration_type service to airnow (#158830) 2025-12-13 08:33:53 +01:00
Joost Lekkerkerker a660ab3f97 Add integration_type service to aftership (#158828) 2025-12-13 08:32:31 +01:00
Joost Lekkerkerker dd8fc16788 Add integration_type service to aemet (#158827) 2025-12-13 08:32:01 +01:00
Joost Lekkerkerker 2b0fab0468 Add integration_type service to brottsplatskartan (#158869) 2025-12-13 08:30:59 +01:00
Joost Lekkerkerker 3bb88ed433 Add integration_type hub to bosch_shc (#158868) 2025-12-13 08:30:04 +01:00
Joost Lekkerkerker 984385cd98 Add integration_type service to buienradar (#158871) 2025-12-13 08:27:55 +01:00
Joost Lekkerkerker 09de108676 Add integration_type service to caldav (#158872) 2025-12-13 08:26:40 +01:00
Joost Lekkerkerker ebc7581718 Add integration_type hub to bmw_connected_drive (#158866) 2025-12-13 08:26:16 +01:00
Joost Lekkerkerker e55162812d Add integration_type hub to blink (#158862) 2025-12-13 08:22:22 +01:00
Joost Lekkerkerker aa6ccaa024 Add integration_type device to blebox (#158860) 2025-12-13 08:21:25 +01:00
Joost Lekkerkerker e1b009a6de Add integration_type device to balboa (#158859) 2025-12-13 08:20:12 +01:00
Joost Lekkerkerker 91ddc525b0 Add integration_type service to azure_event_hub (#158857) 2025-12-13 08:18:56 +01:00
Joost Lekkerkerker d7d7954ac2 Add integration_type service to azure_devops (#158856) 2025-12-13 08:18:35 +01:00
Joost Lekkerkerker e87c260df7 Add integration_type service to azure_data_explorer (#158855) 2025-12-13 08:18:13 +01:00
Joost Lekkerkerker 5185c6cd68 Add integration_type hub to arve (#158848) 2025-12-13 08:17:37 +01:00
Joost Lekkerkerker 7599c918e2 Add integration_type hub to august (#158851) 2025-12-12 23:00:06 +01:00
Joost Lekkerkerker fa7e22ec91 Add integration_type device to arcam_fmj (#158846) 2025-12-12 22:59:47 +01:00
Joost Lekkerkerker 606519e51b Add integration_type device to baf (#158858) 2025-12-12 22:59:28 +01:00
Joost Lekkerkerker 8e39e010f7 Add integration_type device to bluemaestro (#158864) 2025-12-12 22:59:13 +01:00
Joost Lekkerkerker dc01cf49a0 Add integration_type hub to bond (#158867) 2025-12-12 22:58:57 +01:00
Joost Lekkerkerker 1f3ad382f1 Set Denon AVR integration type to device (#158815) 2025-12-12 20:33:56 +01:00
Joost Lekkerkerker 2595c7dcb2 Set Actron Air integration type to hub (#158816) 2025-12-12 20:33:25 +01:00
Kamil Breguła d445b320de Accept URLs in WLED Host input (#157793)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-12-12 18:55:03 +01:00
epenet 7b6df1a8a0 Cleanup deprecated typing helpers (#158806) 2025-12-12 17:04:41 +01:00
Manu 2a151dcd19 Add tests for discovery to Xbox integration (#158808) 2025-12-12 17:02:32 +01:00
epenet adbab150af Move blue_current services to separate module (#158389) 2025-12-12 16:50:34 +01:00
Allen Porter d20edf7928 Improve Roborock exception logging behavior for Zeo/Dyad devices (#158465)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-12 16:43:45 +01:00
Ludovic BOUÉ 7d6d37fe76 Fix Matter Door Lock Operating Mode select entity (#158468) 2025-12-12 16:30:48 +01:00
Ludovic BOUÉ 228e0453a7 Add Matter Thermostat remote sensing status (#157650) 2025-12-12 16:26:27 +01:00
Raphael Hehl 1da31c0530 Move icons to icons.json for unifiprotect (#158800)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2025-12-12 16:23:11 +01:00
Joost Lekkerkerker 41ad15e577 Bump pySmartThings to 3.5.1 (#158795) 2025-12-12 15:45:08 +01:00
Markus Jacobsen 421af881fe Add video source reporting to Bang & Olufsen (#158675) 2025-12-12 15:40:12 +01:00
Klaas Schoute 715a484f7e Add AutarcoSensorBase class for Autarco sensors (#158691)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-12 15:39:18 +01:00
Samuel Xiao 0a789f51b8 Switchbot Cloud: Fixed binary sensors didn't update automatically (#158434)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-12 15:39:08 +01:00
epenet fa25d45123 Remove incorrect bring test (#158797) 2025-12-12 15:32:27 +01:00
johanzander 6d255b2521 Add state_class to Growatt power and energy sensors (#158705)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-12 15:27:47 +01:00
peteS-UK 5ffb39f064 Trap for missing UUID in config_flow for Squeezebox (#158721)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-12-12 15:15:04 +01:00
Zoltán Farkasdi d642109436 Netatmo NOCamera on/off fix (#158741) 2025-12-12 14:57:57 +01:00
Heindrich Paul 10f6d8d14f Add diagnostics support for Nederlandse Spoorwegen integration (#158722)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-12 14:36:35 +01:00
Thomas55555 a94678cb06 Bump google air quality api to 2.0.2 (#158742) 2025-12-12 14:35:07 +01:00
Manu 0d8d466003 Increase Xbox update interval to 15 seconds and refactor title data handling (#158780) 2025-12-12 14:04:25 +01:00
Marc Mueller 8ddf3e1734 Update pytest warnings filter (#158790) 2025-12-12 13:54:00 +01:00
cdutr d88047a750 Migrate Blink component to use hardware_id instead of device_id (#158765) 2025-12-12 13:49:19 +01:00
Jordan Harvey 61c7ac81d6 Bump pynintendoparental to 2.1.1 (#158779) 2025-12-12 13:45:48 +01:00
Josef Zweck bbe07bddb0 Bump pylamarzocco to 2.2.4 (#158774) 2025-12-12 13:45:14 +01:00
Denis Shulyaka a3afc2beb1 Bump openai to 2.11.0 (#158785) 2025-12-12 13:40:43 +01:00
epenet 374cd93d3d Replace Tuya remap methods with helper class (#158718) 2025-12-12 13:37:29 +01:00
Maciej Bieniek 6e99411084 Add get_kvs_value and set_kvs_value actions for Shelly RPC devices (#157349) 2025-12-12 13:15:25 +01:00
dependabot[bot] 41d5415c86 Bump actions/cache from 4.3.0 to 5.0.0 (#158771) 2025-12-12 10:39:58 +01:00
Allen Porter 052d56f358 Bump ical to 12.1.1 (#158770) 2025-12-12 08:34:22 +01:00
Abílio Costa 0a676b5812 Remove alarm panel test from text tests (#158743) 2025-12-12 02:18:40 +01:00
Michael 1f4cf67daa Add turned off and turned on triggers to switch platform (#158688)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-11 22:02:22 +00:00
Maikel Punie bb4ec229ce Add Velbus VLP file loading (#154883) 2025-12-11 22:53:01 +01:00
ndrwrbgs ff62b460d5 Update advanced_options display text for MQTT (#158728) 2025-12-11 22:16:35 +01:00
Willem-Jan van Rootselaar 9b48e92940 Bump python-bsblan to 3.1.4 (#158725)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-12-11 18:04:57 +00:00
Magnus c03b9d1f87 Bump aioasuswrt to 1.5.2 (#158727) 2025-12-11 17:31:46 +00:00
Koknico 3f30df203c Add support for AtlanticDomesticHotWaterProductionV2_CETHI_V4_IOComponent to Overkiz (#157872) 2025-12-11 13:10:37 +01:00
epenet 7fe0d96c88 Remove unnecessary wrapper base method in Tuya (#158708) 2025-12-11 10:13:24 +01:00
Joost Lekkerkerker cdc2192bba Clean up Homelink tests (#158685)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-11 09:10:02 +01:00
Matt Zimmerman 74b1c1f6fd Bump python-smarttub to 0.0.46 (#158702) 2025-12-11 09:07:46 +01:00
J. Nick Koston 69c7a7b0ab Pin pycares to 4.11.0 (#158695) 2025-12-10 22:00:59 -05:00
Norbert Rittel ef302215cc Add two common config flow strings in energyid (#158680) 2025-12-10 21:23:18 +01:00
Norbert Rittel 6378f5f02a Use common reauth_successful string in rituals_perfume_genie (#158684) 2025-12-10 21:14:25 +01:00
Bouwe Westerdijk 79245195cd Bump Plugwise to v1.11.0 (#158067) 2025-12-10 21:03:27 +01:00
epenet d0e33a6e04 Use process_raw_value in Tuya JsonTypeInformation (#158517) 2025-12-10 20:13:16 +01:00
Joost Lekkerkerker f55fc788db Cleanup homelink config flow (#158479) 2025-12-10 18:39:44 +01:00
epenet 6152e0fa27 Split action and state wrapper in Tuya alarm control panel (#158532) 2025-12-10 18:37:04 +01:00
Matthias Alphart f1a89741c0 Add counter for KNX DataSecure undecodable telegrams (#157844) 2025-12-10 17:59:00 +01:00
Paul Tarjan 7629c9f280 Fix flaky test_stream_source timeout in generic camera tests (#158506) 2025-12-10 17:49:27 +01:00
Abílio Costa 6b8650c6d9 Remove uneeded check in whirlpool oven temperature sensors (#157997) 2025-12-10 17:45:34 +01:00
Paul Tarjan 48f186368a Fix flaky playstation_network test_image_platform test (#158296) 2025-12-10 17:07:58 +01:00
Allen Porter d65baac8d4 Bump python-roborock to 3.12.2 (#158572) 2025-12-10 17:05:57 +01:00
Paul Tarjan d57801407b Fix flaky test_calls_not_allowed by using thread-safe event signaling (#158504) 2025-12-10 16:38:34 +01:00
Markus Jacobsen 4495a76557 Change Bang & Olufsen "stopped" state translation (#158534) 2025-12-10 16:37:48 +01:00
Paul Tarjan 99dfb93ac0 Fix flaky test_rename_entity_collision test (#158297) 2025-12-10 16:36:52 +01:00
Abílio Costa 7c7c0aad25 Rename trigger helper state checkers (#158537)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-10 14:56:56 +00:00
Andrew Jackson 5992898340 Add measurement state class to ohme sensors (#158541) 2025-12-10 15:35:24 +01:00
Sander Blomvågnes 4f2ff9a4f4 Add codeowner and integration_type to Entur manifest (#158543) 2025-12-10 15:26:24 +01:00
bestycame a8a135c2ca Bump hanna-cloud to version 0.0.7 (#158536)
Co-authored-by: Olivier d'Otreppe <odotreppe@abbove.com>
2025-12-10 14:50:05 +01:00
275 changed files with 8627 additions and 1548 deletions
+3 -3
View File
@@ -263,7 +263,7 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: &actions-cache actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: &actions-cache actions/cache@a7833574556fa59680c1b7cb190c1735db73ebf0 # v5.0.0
with:
path: venv
key: &key-pre-commit-venv >-
@@ -304,7 +304,7 @@ jobs:
- &cache-restore-pre-commit-venv
name: Restore base Python virtual environment
id: cache-venv
uses: &actions-cache-restore actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: &actions-cache-restore actions/cache/restore@a7833574556fa59680c1b7cb190c1735db73ebf0 # v5.0.0
with:
path: venv
fail-on-cache-miss: true
@@ -511,7 +511,7 @@ jobs:
fi
- name: Save apt cache
if: steps.cache-apt-check.outputs.cache-hit != 'true'
uses: &actions-cache-save actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: &actions-cache-save actions/cache/save@a7833574556fa59680c1b7cb190c1735db73ebf0 # v5.0.0
with:
path: *path-apt-cache
key: *key-apt-cache
Generated
+5 -5
View File
@@ -220,8 +220,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/bizkaibus/ @UgaitzEtxebarria
/homeassistant/components/blebox/ @bbx-a @swistakm
/tests/components/blebox/ @bbx-a @swistakm
/homeassistant/components/blink/ @fronzbot @mkmer
/tests/components/blink/ @fronzbot @mkmer
/homeassistant/components/blink/ @fronzbot
/tests/components/blink/ @fronzbot
/homeassistant/components/blue_current/ @gleeuwen @NickKoepr @jtodorova23
/tests/components/blue_current/ @gleeuwen @NickKoepr @jtodorova23
/homeassistant/components/bluemaestro/ @bdraco
@@ -308,8 +308,8 @@ build.json @home-assistant/supervisor
/tests/components/config/ @home-assistant/core
/homeassistant/components/configurator/ @home-assistant/core
/tests/components/configurator/ @home-assistant/core
/homeassistant/components/control4/ @lawtancool
/tests/components/control4/ @lawtancool
/homeassistant/components/control4/ @lawtancool @davidrecordon
/tests/components/control4/ @lawtancool @davidrecordon
/homeassistant/components/conversation/ @home-assistant/core @synesthesiam @arturpragacz
/tests/components/conversation/ @home-assistant/core @synesthesiam @arturpragacz
/homeassistant/components/cookidoo/ @miaucl
@@ -464,7 +464,7 @@ build.json @home-assistant/supervisor
/tests/components/enigma2/ @autinerd
/homeassistant/components/enphase_envoy/ @bdraco @cgarwood @catsmanac
/tests/components/enphase_envoy/ @bdraco @cgarwood @catsmanac
/homeassistant/components/entur_public_transport/ @hfurubotten
/homeassistant/components/entur_public_transport/ @hfurubotten @SanderBlom
/homeassistant/components/environment_canada/ @gwww @michaeldavie
/tests/components/environment_canada/ @gwww @michaeldavie
/homeassistant/components/ephember/ @ttroy50 @roberty99
@@ -10,6 +10,7 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/actron_air",
"integration_type": "hub",
"iot_class": "cloud_polling",
"quality_scale": "bronze",
"requirements": ["actron-neo-api==0.1.87"]
@@ -4,6 +4,7 @@
"codeowners": ["@Bre77"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/advantage_air",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["advantage_air"],
"requirements": ["advantage-air==0.4.4"]
@@ -4,6 +4,7 @@
"codeowners": ["@Noltari"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aemet",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["aemet_opendata"],
"requirements": ["AEMET-OpenData==0.6.4"]
@@ -4,6 +4,7 @@
"codeowners": [],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aftership",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["pyaftership==21.11.0"]
}
@@ -4,6 +4,7 @@
"codeowners": ["@ispysoftware"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/agent_dvr",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["agent"],
"requirements": ["agent-py==0.0.24"]
@@ -4,6 +4,7 @@
"codeowners": ["@asymworks"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airnow",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["pyairnow"],
"requirements": ["pyairnow==1.3.1"]
+18 -2
View File
@@ -4,6 +4,7 @@ from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime, timedelta
from pyairobotrest.models import ThermostatStatus
@@ -23,6 +24,8 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.util.dt import utcnow
from homeassistant.util.variance import ignore_variance
from . import AirobotConfigEntry
from .entity import AirobotEntity
@@ -34,10 +37,15 @@ PARALLEL_UPDATES = 0
class AirobotSensorEntityDescription(SensorEntityDescription):
"""Describes Airobot sensor entity."""
value_fn: Callable[[ThermostatStatus], StateType]
value_fn: Callable[[ThermostatStatus], StateType | datetime]
supported_fn: Callable[[ThermostatStatus], bool] = lambda _: True
uptime_to_stable_datetime = ignore_variance(
lambda value: utcnow().replace(microsecond=0) - timedelta(seconds=value),
timedelta(minutes=2),
)
SENSOR_TYPES: tuple[AirobotSensorEntityDescription, ...] = (
AirobotSensorEntityDescription(
key="air_temperature",
@@ -96,6 +104,14 @@ SENSOR_TYPES: tuple[AirobotSensorEntityDescription, ...] = (
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda status: status.errors,
),
AirobotSensorEntityDescription(
key="device_uptime",
translation_key="device_uptime",
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda status: uptime_to_stable_datetime(status.device_uptime),
entity_registry_enabled_default=False,
),
)
@@ -129,6 +145,6 @@ class AirobotSensor(AirobotEntity, SensorEntity):
self._attr_unique_id = f"{coordinator.data.status.device_id}_{description.key}"
@property
def native_value(self) -> StateType:
def native_value(self) -> StateType | datetime:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self.coordinator.data.status)
@@ -17,6 +17,7 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/airthings",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["airthings"],
"requirements": ["airthings-cloud==0.2.0"]
@@ -27,6 +27,7 @@
"config_flow": true,
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",
"integration_type": "device",
"iot_class": "local_polling",
"requirements": ["airthings-ble==1.2.0"]
}
@@ -4,6 +4,7 @@
"codeowners": ["@samsinnamon"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airtouch4",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["airtouch4pyapi"],
"requirements": ["airtouch4pyapi==1.0.5"]
@@ -4,6 +4,7 @@
"codeowners": ["@danzel"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airtouch5",
"integration_type": "hub",
"iot_class": "local_push",
"loggers": ["airtouch5py"],
"requirements": ["airtouch5py==0.3.0"]
@@ -9,6 +9,7 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/airzone",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["aioairzone"],
"requirements": ["aioairzone==1.0.4"]
@@ -4,6 +4,7 @@
"codeowners": ["@Noltari"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airzone_cloud",
"integration_type": "hub",
"iot_class": "cloud_push",
"loggers": ["aioairzone_cloud"],
"requirements": ["aioairzone-cloud==0.7.2"]
@@ -4,6 +4,7 @@
"codeowners": ["@madpilot"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/amberelectric",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["amberelectric"],
"requirements": ["amberelectric==2.0.12"]
@@ -4,6 +4,7 @@
"codeowners": ["@engrbm87"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/android_ip_webcam",
"integration_type": "device",
"iot_class": "local_polling",
"requirements": ["pydroid-ipcam==3.0.0"]
}
@@ -4,6 +4,7 @@
"codeowners": ["@pantherale0"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/anglian_water",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["pyanglianwater"],
"quality_scale": "bronze",
@@ -4,6 +4,7 @@
"codeowners": ["@Lash-L"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/anova",
"integration_type": "hub",
"iot_class": "cloud_push",
"loggers": ["anova_wifi"],
"requirements": ["anova-wifi==0.17.0"]
@@ -4,6 +4,7 @@
"codeowners": ["@hyralex"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/anthemav",
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["anthemav"],
"requirements": ["anthemav==1.4.1"]
@@ -4,6 +4,7 @@
"codeowners": ["@bdr99"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aosmith",
"integration_type": "hub",
"iot_class": "cloud_polling",
"requirements": ["py-aosmith==1.0.15"]
}
@@ -4,6 +4,7 @@
"codeowners": ["@elupus"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/arcam_fmj",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["arcam"],
"requirements": ["arcam-fmj==1.8.2"],
@@ -4,6 +4,7 @@
"codeowners": ["@ikalnyi"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/arve",
"integration_type": "hub",
"iot_class": "cloud_polling",
"requirements": ["asyncarve==0.1.1"]
}
@@ -4,6 +4,7 @@
"codeowners": ["@milanmeu"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aseko_pool_live",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["aioaseko"],
"requirements": ["aioaseko==1.0.0"]
@@ -7,5 +7,5 @@
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["aioasuswrt", "asusrouter", "asyncssh"],
"requirements": ["aioasuswrt==1.5.1", "asusrouter==1.21.3"]
"requirements": ["aioasuswrt==1.5.4", "asusrouter==1.21.3"]
}
@@ -4,6 +4,7 @@
"codeowners": ["@MatsNL"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/atag",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["pyatag"],
"requirements": ["pyatag==0.3.5.3"]
@@ -27,6 +27,7 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/august",
"integration_type": "hub",
"iot_class": "cloud_push",
"loggers": ["pubnub", "yalexs"],
"requirements": ["yalexs==9.2.0", "yalexs-ble==3.2.2"]
@@ -4,6 +4,7 @@
"codeowners": ["@djtimca"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aurora",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["auroranoaa"],
"requirements": ["auroranoaa==0.0.5"]
@@ -4,6 +4,7 @@
"codeowners": ["@nickw444", "@Bre77"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aussie_broadband",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["aussiebb"],
"requirements": ["pyaussiebb==0.1.5"]
@@ -6,10 +6,7 @@ rules:
This integration does not provide additional actions.
appropriate-polling: done
brands: done
common-modules:
status: todo
comment: |
The entity.py file is not used in this integration.
common-modules: done
config-flow-test-coverage: done
config-flow: done
dependency-transparency: done
+24 -24
View File
@@ -204,13 +204,25 @@ async def async_setup_entry(
async_add_entities(entities)
class AutarcoBatterySensorEntity(
CoordinatorEntity[AutarcoDataUpdateCoordinator], SensorEntity
):
class AutarcoSensorBase(CoordinatorEntity[AutarcoDataUpdateCoordinator], SensorEntity):
"""Base class for Autarco sensors."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: AutarcoDataUpdateCoordinator,
description: SensorEntityDescription,
) -> None:
"""Initialize Autarco sensor base."""
super().__init__(coordinator)
self.entity_description = description
class AutarcoBatterySensorEntity(AutarcoSensorBase):
"""Defines an Autarco battery sensor."""
entity_description: AutarcoBatterySensorEntityDescription
_attr_has_entity_name = True
def __init__(
self,
@@ -218,10 +230,8 @@ class AutarcoBatterySensorEntity(
coordinator: AutarcoDataUpdateCoordinator,
description: AutarcoBatterySensorEntityDescription,
) -> None:
"""Initialize Autarco sensor."""
super().__init__(coordinator)
self.entity_description = description
"""Initialize Autarco battery sensor."""
super().__init__(coordinator, description)
self._attr_unique_id = (
f"{coordinator.account_site.site_id}_battery_{description.key}"
)
@@ -239,13 +249,10 @@ class AutarcoBatterySensorEntity(
return self.entity_description.value_fn(self.coordinator.data.battery)
class AutarcoSolarSensorEntity(
CoordinatorEntity[AutarcoDataUpdateCoordinator], SensorEntity
):
class AutarcoSolarSensorEntity(AutarcoSensorBase):
"""Defines an Autarco solar sensor."""
entity_description: AutarcoSolarSensorEntityDescription
_attr_has_entity_name = True
def __init__(
self,
@@ -253,10 +260,8 @@ class AutarcoSolarSensorEntity(
coordinator: AutarcoDataUpdateCoordinator,
description: AutarcoSolarSensorEntityDescription,
) -> None:
"""Initialize Autarco sensor."""
super().__init__(coordinator)
self.entity_description = description
"""Initialize Autarco solar sensor."""
super().__init__(coordinator, description)
self._attr_unique_id = (
f"{coordinator.account_site.site_id}_solar_{description.key}"
)
@@ -273,13 +278,10 @@ class AutarcoSolarSensorEntity(
return self.entity_description.value_fn(self.coordinator.data.solar)
class AutarcoInverterSensorEntity(
CoordinatorEntity[AutarcoDataUpdateCoordinator], SensorEntity
):
class AutarcoInverterSensorEntity(AutarcoSensorBase):
"""Defines an Autarco inverter sensor."""
entity_description: AutarcoInverterSensorEntityDescription
_attr_has_entity_name = True
def __init__(
self,
@@ -288,10 +290,8 @@ class AutarcoInverterSensorEntity(
description: AutarcoInverterSensorEntityDescription,
serial_number: str,
) -> None:
"""Initialize Autarco sensor."""
super().__init__(coordinator)
self.entity_description = description
"""Initialize Autarco inverter sensor."""
super().__init__(coordinator, description)
self._serial_number = serial_number
self._attr_unique_id = f"{serial_number}_{description.key}"
self._attr_device_info = DeviceInfo(
@@ -131,6 +131,7 @@ _EXPERIMENTAL_TRIGGER_PLATFORMS = {
"lawn_mower",
"light",
"media_player",
"switch",
"text",
"vacuum",
}
@@ -4,6 +4,7 @@
"codeowners": ["@kaareseras"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/azure_data_explorer",
"integration_type": "service",
"iot_class": "cloud_push",
"loggers": ["azure"],
"requirements": ["azure-kusto-ingest==4.5.1", "azure-kusto-data[aio]==4.5.1"]
@@ -4,6 +4,7 @@
"codeowners": ["@timmo001"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/azure_devops",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["aioazuredevops"],
"requirements": ["aioazuredevops==2.2.2"]
@@ -4,6 +4,7 @@
"codeowners": ["@eavanvalkenburg"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/azure_event_hub",
"integration_type": "service",
"iot_class": "cloud_push",
"loggers": ["azure"],
"requirements": ["azure-eventhub==5.11.1"],
@@ -4,6 +4,7 @@
"codeowners": ["@bdraco", "@jfroy"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/baf",
"integration_type": "device",
"iot_class": "local_push",
"requirements": ["aiobafi6==0.9.0"],
"zeroconf": [
@@ -12,6 +12,7 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/balboa",
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["pybalboa"],
"requirements": ["pybalboa==1.1.3"]
@@ -22,6 +22,7 @@ class BeoSource:
NET_RADIO: Final[Source] = Source(name="B&O Radio", id="netRadio")
SPDIF: Final[Source] = Source(name="Optical", id="spdif")
TIDAL: Final[Source] = Source(name="Tidal", id="tidal")
TV: Final[Source] = Source(name="TV", id="tv")
UNKNOWN: Final[Source] = Source(name="Unknown Source", id="unknown")
URI_STREAMER: Final[Source] = Source(name="Audio Streamer", id="uriStreamer")
@@ -32,7 +33,7 @@ BEO_STATES: dict[str, MediaPlayerState] = {
"buffering": MediaPlayerState.PLAYING,
"idle": MediaPlayerState.IDLE,
"paused": MediaPlayerState.PAUSED,
"stopped": MediaPlayerState.PAUSED,
"stopped": MediaPlayerState.IDLE,
"ended": MediaPlayerState.PAUSED,
"error": MediaPlayerState.IDLE,
# A device's initial state is "unknown" and should be treated as "idle"
@@ -55,12 +56,13 @@ BEO_REPEAT_TO_HA: dict[str, RepeatMode] = {
class BeoMediaType(StrEnum):
"""Bang & Olufsen specific media types."""
FAVOURITE = "favourite"
DEEZER = "deezer"
FAVOURITE = "favourite"
OVERLAY_TTS = "overlay_tts"
RADIO = "radio"
TIDAL = "tidal"
TTS = "provider"
OVERLAY_TTS = "overlay_tts"
TV = "tv"
class BeoModel(StrEnum):
@@ -218,6 +218,7 @@ class BeoMediaPlayer(BeoEntity, MediaPlayerEntity):
self._sources: dict[str, str] = {}
self._state: str = MediaPlayerState.IDLE
self._video_sources: dict[str, str] = {}
self._video_source_id_map: dict[str, str] = {}
self._sound_modes: dict[str, int] = {}
# Beolink compatible sources
@@ -355,6 +356,9 @@ class BeoMediaPlayer(BeoEntity, MediaPlayerEntity):
and menu_item.label != "TV"
):
self._video_sources[key] = menu_item.label
self._video_source_id_map[
menu_item.content.content_uri.removeprefix("tv://")
] = menu_item.label
# Combine the source dicts
self._sources = self._audio_sources | self._video_sources
@@ -627,10 +631,11 @@ class BeoMediaPlayer(BeoEntity, MediaPlayerEntity):
def media_content_type(self) -> MediaType | str | None:
"""Return the current media type."""
content_type = {
BeoSource.URI_STREAMER.id: MediaType.URL,
BeoSource.DEEZER.id: BeoMediaType.DEEZER,
BeoSource.TIDAL.id: BeoMediaType.TIDAL,
BeoSource.NET_RADIO.id: BeoMediaType.RADIO,
BeoSource.TIDAL.id: BeoMediaType.TIDAL,
BeoSource.TV.id: BeoMediaType.TV,
BeoSource.URI_STREAMER.id: MediaType.URL,
}
# Hard to determine content type.
if self._source_change.id in content_type:
@@ -690,7 +695,11 @@ class BeoMediaPlayer(BeoEntity, MediaPlayerEntity):
@property
def source(self) -> str | None:
"""Return the current audio source."""
"""Return the current audio/video source."""
# Associate TV content ID with a video source
if self.media_content_id in self._video_source_id_map:
return self._video_source_id_map[self.media_content_id]
return self._source_change.name
@property
@@ -4,6 +4,7 @@
"codeowners": ["@bbx-a", "@swistakm"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/blebox",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["blebox_uniapi"],
"requirements": ["blebox-uniapi==2.5.0"],
@@ -64,6 +64,12 @@ async def async_migrate_entry(hass: HomeAssistant, entry: BlinkConfigEntry) -> b
if entry.version == 2:
await _reauth_flow_wrapper(hass, entry, data)
return False
if entry.version == 3:
# Migrate device_id to hardware_id for blinkpy 0.25.x OAuth2 compatibility
if "device_id" in data:
data["hardware_id"] = data.pop("device_id")
hass.config_entries.async_update_entry(entry, data=data, version=4)
return True
return True
@@ -21,7 +21,7 @@ from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DEVICE_ID, DOMAIN
from .const import DOMAIN, HARDWARE_ID
_LOGGER = logging.getLogger(__name__)
@@ -43,7 +43,7 @@ async def _send_blink_2fa_pin(blink: Blink, pin: str | None) -> bool:
class BlinkConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a Blink config flow."""
VERSION = 3
VERSION = 4
def __init__(self) -> None:
"""Initialize the blink flow."""
@@ -53,7 +53,7 @@ class BlinkConfigFlow(ConfigFlow, domain=DOMAIN):
async def _handle_user_input(self, user_input: dict[str, Any]):
"""Handle user input."""
self.auth = Auth(
{**user_input, "device_id": DEVICE_ID},
{**user_input, "hardware_id": HARDWARE_ID},
no_prompt=True,
session=async_get_clientsession(self.hass),
)
+1 -1
View File
@@ -3,7 +3,7 @@
from homeassistant.const import Platform
DOMAIN = "blink"
DEVICE_ID = "Home Assistant"
HARDWARE_ID = "Home Assistant"
CONF_MIGRATE = "migrate"
CONF_CAMERA = "camera"
+3 -2
View File
@@ -1,7 +1,7 @@
{
"domain": "blink",
"name": "Blink",
"codeowners": ["@fronzbot", "@mkmer"],
"codeowners": ["@fronzbot"],
"config_flow": true,
"dhcp": [
{
@@ -18,7 +18,8 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/blink",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["blinkpy"],
"requirements": ["blinkpy==0.25.1"]
"requirements": ["blinkpy==0.25.2"]
}
@@ -13,32 +13,25 @@ from bluecurrent_api.exceptions import (
RequestLimitReached,
WebsocketError,
)
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.const import CONF_API_TOKEN, CONF_DEVICE_ID, Platform
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.exceptions import (
ConfigEntryAuthFailed,
ConfigEntryNotReady,
ServiceValidationError,
)
from homeassistant.helpers import config_validation as cv, device_registry as dr
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_API_TOKEN, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.typing import ConfigType
from .const import (
BCU_APP,
CHARGEPOINT_SETTINGS,
CHARGEPOINT_STATUS,
CHARGING_CARD_ID,
DOMAIN,
EVSE_ID,
LOGGER,
PLUG_AND_CHARGE,
SERVICE_START_CHARGE_SESSION,
VALUE,
)
from .services import async_setup_services
type BlueCurrentConfigEntry = ConfigEntry[Connector]
@@ -54,13 +47,12 @@ VALUE_TYPES = [CHARGEPOINT_STATUS, CHARGEPOINT_SETTINGS]
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
SERVICE_START_CHARGE_SESSION_SCHEMA = vol.Schema(
{
vol.Required(CONF_DEVICE_ID): cv.string,
# When no charging card is provided, use no charging card (BCU_APP = no charging card).
vol.Optional(CHARGING_CARD_ID, default=BCU_APP): cv.string,
}
)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up Blue Current."""
async_setup_services(hass)
return True
async def async_setup_entry(
@@ -88,66 +80,6 @@ async def async_setup_entry(
return True
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up Blue Current."""
async def start_charge_session(service_call: ServiceCall) -> None:
"""Start a charge session with the provided device and charge card ID."""
# When no charge card is provided, use the default charge card set in the config flow.
charging_card_id = service_call.data[CHARGING_CARD_ID]
device_id = service_call.data[CONF_DEVICE_ID]
# Get the device based on the given device ID.
device = dr.async_get(hass).devices.get(device_id)
if device is None:
raise ServiceValidationError(
translation_domain=DOMAIN, translation_key="invalid_device_id"
)
blue_current_config_entry: ConfigEntry | None = None
for config_entry_id in device.config_entries:
config_entry = hass.config_entries.async_get_entry(config_entry_id)
if not config_entry or config_entry.domain != DOMAIN:
# Not the blue_current config entry.
continue
if config_entry.state is not ConfigEntryState.LOADED:
raise ServiceValidationError(
translation_domain=DOMAIN, translation_key="config_entry_not_loaded"
)
blue_current_config_entry = config_entry
break
if not blue_current_config_entry:
# The device is not connected to a valid blue_current config entry.
raise ServiceValidationError(
translation_domain=DOMAIN, translation_key="no_config_entry"
)
connector = blue_current_config_entry.runtime_data
# Get the evse_id from the identifier of the device.
evse_id = next(
identifier[1]
for identifier in device.identifiers
if identifier[0] == DOMAIN
)
await connector.client.start_session(evse_id, charging_card_id)
hass.services.async_register(
DOMAIN,
SERVICE_START_CHARGE_SESSION,
start_charge_session,
SERVICE_START_CHARGE_SESSION_SCHEMA,
)
return True
async def async_unload_entry(
hass: HomeAssistant, config_entry: BlueCurrentConfigEntry
) -> bool:
@@ -4,6 +4,7 @@
"codeowners": ["@gleeuwen", "@NickKoepr", "@jtodorova23"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/blue_current",
"integration_type": "hub",
"iot_class": "cloud_push",
"loggers": ["bluecurrent_api"],
"requirements": ["bluecurrent-api==1.3.2"]
@@ -0,0 +1,79 @@
"""The Blue Current integration."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.const import CONF_DEVICE_ID
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import config_validation as cv, device_registry as dr
from .const import BCU_APP, CHARGING_CARD_ID, DOMAIN, SERVICE_START_CHARGE_SESSION
SERVICE_START_CHARGE_SESSION_SCHEMA = vol.Schema(
{
vol.Required(CONF_DEVICE_ID): cv.string,
# When no charging card is provided, use no charging card (BCU_APP = no charging card).
vol.Optional(CHARGING_CARD_ID, default=BCU_APP): cv.string,
}
)
async def start_charge_session(service_call: ServiceCall) -> None:
"""Start a charge session with the provided device and charge card ID."""
# When no charge card is provided, use the default charge card set in the config flow.
charging_card_id = service_call.data[CHARGING_CARD_ID]
device_id = service_call.data[CONF_DEVICE_ID]
# Get the device based on the given device ID.
device = dr.async_get(service_call.hass).devices.get(device_id)
if device is None:
raise ServiceValidationError(
translation_domain=DOMAIN, translation_key="invalid_device_id"
)
blue_current_config_entry: ConfigEntry | None = None
for config_entry_id in device.config_entries:
config_entry = service_call.hass.config_entries.async_get_entry(config_entry_id)
if not config_entry or config_entry.domain != DOMAIN:
# Not the blue_current config entry.
continue
if config_entry.state is not ConfigEntryState.LOADED:
raise ServiceValidationError(
translation_domain=DOMAIN, translation_key="config_entry_not_loaded"
)
blue_current_config_entry = config_entry
break
if not blue_current_config_entry:
# The device is not connected to a valid blue_current config entry.
raise ServiceValidationError(
translation_domain=DOMAIN, translation_key="no_config_entry"
)
connector = blue_current_config_entry.runtime_data
# Get the evse_id from the identifier of the device.
evse_id = next(
identifier[1] for identifier in device.identifiers if identifier[0] == DOMAIN
)
await connector.client.start_session(evse_id, charging_card_id)
@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Register the services."""
hass.services.async_register(
DOMAIN,
SERVICE_START_CHARGE_SESSION,
start_charge_session,
SERVICE_START_CHARGE_SESSION_SCHEMA,
)
@@ -11,6 +11,7 @@
"config_flow": true,
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/bluemaestro",
"integration_type": "device",
"iot_class": "local_push",
"requirements": ["bluemaestro-ble==0.4.1"]
}
@@ -5,6 +5,7 @@
"codeowners": ["@thrawnarn", "@LouisChrist"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/bluesound",
"integration_type": "device",
"iot_class": "local_polling",
"requirements": ["pyblu==2.0.5"],
"zeroconf": [
@@ -4,6 +4,7 @@
"codeowners": ["@gerard33", "@rikroe"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["bimmer_connected"],
"requirements": ["bimmer-connected[china]==0.17.3"]
@@ -14,6 +14,7 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/bond",
"integration_type": "hub",
"iot_class": "local_push",
"loggers": ["bond_async"],
"requirements": ["bond-async==0.2.1"],
@@ -5,6 +5,7 @@
"codeowners": ["@tschamm"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/bosch_shc",
"integration_type": "hub",
"iot_class": "local_push",
"loggers": ["boschshcpy"],
"requirements": ["boschshcpy==0.2.107"],
@@ -4,6 +4,7 @@
"codeowners": ["@gjohansson-ST"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/brottsplatskartan",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["brottsplatskartan"],
"requirements": ["brottsplatskartan==1.0.5"]
@@ -4,6 +4,7 @@
"codeowners": ["@eavanvalkenburg"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/brunt",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["brunt"],
"requirements": ["brunt==1.2.0"]
@@ -7,7 +7,7 @@
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["bsblan"],
"requirements": ["python-bsblan==3.1.3"],
"requirements": ["python-bsblan==3.1.4"],
"zeroconf": [
{
"name": "bsb-lan*",
@@ -4,6 +4,7 @@
"codeowners": ["@mjj4791", "@ties", "@Robbie1221"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/buienradar",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["buienradar", "vincenty"],
"requirements": ["buienradar==1.0.6"]
@@ -4,6 +4,7 @@
"codeowners": [],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/caldav",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["caldav", "vobject"],
"requirements": ["caldav==2.1.0", "icalendar==6.3.1", "vobject==0.9.9"]
@@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["ffmpeg"],
"documentation": "https://www.home-assistant.io/integrations/canary",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["canary"],
"requirements": ["py-canary==0.5.4"],
@@ -4,6 +4,7 @@
"codeowners": ["@ocalvo"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/ccm15",
"integration_type": "hub",
"iot_class": "local_polling",
"requirements": ["py_ccm15==0.1.2"]
}
@@ -4,5 +4,6 @@
"codeowners": ["@jjlawren"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/cert_expiry",
"integration_type": "service",
"iot_class": "cloud_polling"
}
@@ -4,6 +4,7 @@
"codeowners": ["@ludeeus", "@ctalkington"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/cloudflare",
"integration_type": "service",
"iot_class": "cloud_push",
"loggers": ["pycfdns"],
"requirements": ["pycfdns==3.0.0"],
@@ -4,6 +4,7 @@
"codeowners": ["@tombrien"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/coinbase",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["coinbase"],
"requirements": ["coinbase-advanced-py==1.2.2"]
@@ -1,9 +1,10 @@
{
"domain": "control4",
"name": "Control4",
"codeowners": ["@lawtancool"],
"codeowners": ["@lawtancool", "@davidrecordon"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/control4",
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["pyControl4"],
"requirements": ["pyControl4==1.5.0"],
@@ -4,6 +4,7 @@
"codeowners": ["@fredrike"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/daikin",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["pydaikin"],
"requirements": ["pydaikin==2.17.1"],
@@ -4,6 +4,7 @@
"codeowners": [],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/datadog",
"integration_type": "service",
"iot_class": "local_push",
"loggers": ["datadog"],
"quality_scale": "legacy",
@@ -4,6 +4,7 @@
"codeowners": ["@ol-iver", "@starkillerOG"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/denonavr",
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["denonavr"],
"requirements": ["denonavr==1.2.0"],
@@ -4,6 +4,7 @@
"codeowners": ["@gagebenne"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/dexcom",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["pydexcom"],
"requirements": ["pydexcom==0.2.3"]
@@ -4,6 +4,7 @@
"codeowners": ["@gjohansson-ST"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/dnsip",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["aiodns==3.6.0"]
}
@@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["http", "repairs"],
"documentation": "https://www.home-assistant.io/integrations/doorbird",
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["doorbirdpy"],
"requirements": ["DoorBirdPy==3.0.11"],
@@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["mqtt"],
"documentation": "https://www.home-assistant.io/integrations/drop_connect",
"integration_type": "hub",
"iot_class": "local_push",
"mqtt": ["drop_connect/discovery/#"],
"requirements": ["dropmqttapi==1.0.3"]
@@ -4,6 +4,7 @@
"codeowners": ["@sarahseidman"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/droplet",
"integration_type": "device",
"iot_class": "local_push",
"quality_scale": "bronze",
"requirements": ["pydroplet==2.3.4"],
@@ -4,6 +4,7 @@
"codeowners": [],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/dunehd",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["pdunehd"],
"requirements": ["pdunehd==1.3.2"]
@@ -4,6 +4,7 @@
"codeowners": ["@cereal2nd"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/duotecno",
"integration_type": "hub",
"iot_class": "local_push",
"loggers": ["pyduotecno", "pyduotecno-node", "pyduotecno-unit"],
"requirements": ["pyDuotecno==2024.10.1"],
@@ -4,6 +4,7 @@
"codeowners": ["@Jc2k"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/eafm",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["aioeafm"],
"requirements": ["aioeafm==0.1.2"]
@@ -7,6 +7,7 @@
"homekit": {
"models": ["EB", "ecobee*"]
},
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["pyecobee"],
"requirements": ["python-ecobee-api==0.3.2"],
@@ -4,6 +4,7 @@
"codeowners": ["@pjanuario"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/ecoforest",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["pyecoforest"],
"requirements": ["pyecoforest==0.4.0"]
@@ -4,6 +4,7 @@
"codeowners": ["@w1ll1am23"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/econet",
"integration_type": "hub",
"iot_class": "cloud_push",
"loggers": ["paho_mqtt", "pyeconet"],
"requirements": ["pyeconet==0.1.28"]
@@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["application_credentials", "http"],
"documentation": "https://www.home-assistant.io/integrations/ekeybionyx",
"integration_type": "hub",
"iot_class": "local_push",
"quality_scale": "bronze",
"requirements": ["ekey-bionyxpy==1.0.0"]
@@ -4,6 +4,7 @@
"codeowners": ["@jafar-atili"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/electrasmart",
"integration_type": "hub",
"iot_class": "cloud_polling",
"requirements": ["pyElectra==1.2.4"]
}
@@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["recorder"],
"documentation": "https://www.home-assistant.io/integrations/elvia",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["elvia==0.1.0"]
}
@@ -1,8 +1,8 @@
{
"config": {
"abort": {
"already_configured": "This device is already configured.",
"reauth_successful": "Reauthentication successful."
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"create_entry": {
"add_sensor_mapping_hint": "You can now add mappings from any sensor in Home Assistant to {integration_name} using the '+ add sensor mapping' button."
@@ -1,8 +1,9 @@
{
"domain": "entur_public_transport",
"name": "Entur",
"codeowners": ["@hfurubotten"],
"codeowners": ["@hfurubotten", "@SanderBlom"],
"documentation": "https://www.home-assistant.io/integrations/entur_public_transport",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["enturclient"],
"quality_scale": "legacy",
@@ -4,6 +4,7 @@
"codeowners": ["@gwww", "@michaeldavie"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/environment_canada",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["env_canada"],
"requirements": ["env-canada==0.12.1"]
@@ -4,6 +4,7 @@
"codeowners": ["@erwindouna"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/firefly_iii",
"integration_type": "service",
"iot_class": "local_polling",
"quality_scale": "bronze",
"requirements": ["pyfirefly==0.1.8"]
@@ -42,11 +42,11 @@
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
},
"data_description": {
"api_key": "The API key for authenticating with Firefly",
"api_key": "The API key for authenticating with Firefly III",
"url": "[%key:common::config_flow::data::url%]",
"verify_ssl": "Verify the SSL certificate of the Firefly instance"
"verify_ssl": "Verify the SSL certificate of the Firefly III instance"
},
"description": "You can create an API key in the Firefly UI. Go to **Options > Profile** and select the **OAuth** tab. Create a new personal access token and copy it (it will only display once)."
"description": "You can create an API key in the Firefly III UI. Go to **Options > Profile** and select the **OAuth** tab. Create a new personal access token and copy it (it will only display once)."
}
}
},
@@ -84,13 +84,13 @@
},
"exceptions": {
"cannot_connect": {
"message": "An error occurred while trying to connect to the Firefly instance: {error}"
"message": "An error occurred while trying to connect to the Firefly III instance: {error}"
},
"invalid_auth": {
"message": "An error occurred while trying to authenticate: {error}"
},
"timeout_connect": {
"message": "A timeout occurred while trying to connect to the Firefly instance: {error}"
"message": "A timeout occurred while trying to connect to the Firefly III instance: {error}"
}
}
}
@@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["application_credentials", "http"],
"documentation": "https://www.home-assistant.io/integrations/fitbit",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["fitbit", "fitbit_web_api"],
"requirements": ["fitbit==0.3.1", "fitbit-web-api==2.13.5"]
@@ -4,6 +4,7 @@
"codeowners": ["@stefano055415"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/freedompro",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["pyfreedompro"],
"requirements": ["pyfreedompro==1.1.0"]
@@ -7,7 +7,7 @@
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["pyfritzhome"],
"requirements": ["pyfritzhome==0.6.17"],
"requirements": ["pyfritzhome==0.6.18"],
"ssdp": [
{
"st": "urn:schemas-upnp-org:device:fritzbox:1"
@@ -4,7 +4,12 @@
"codeowners": ["@wlcrs"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/frontier_silicon",
"integration_type": "device",
"iot_class": "local_polling",
"requirements": ["afsapi==0.2.7"],
"ssdp": [{ "st": "urn:schemas-frontier-silicon-com:undok:fsapi:1" }]
"ssdp": [
{
"st": "urn:schemas-frontier-silicon-com:undok:fsapi:1"
}
]
}
@@ -4,6 +4,7 @@
"codeowners": ["@crevetor"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/fujitsu_fglair",
"integration_type": "hub",
"iot_class": "cloud_polling",
"requirements": ["ayla-iot-unofficial==1.4.7"]
}
@@ -10,6 +10,7 @@
}
],
"documentation": "https://www.home-assistant.io/integrations/fully_kiosk",
"integration_type": "device",
"iot_class": "local_polling",
"mqtt": ["fully/deviceInfo/+"],
"quality_scale": "bronze",
@@ -4,6 +4,7 @@
"codeowners": ["@klaasnicolaas"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/garages_amsterdam",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["odp-amsterdam==6.1.2"]
}
@@ -12,6 +12,7 @@
"config_flow": true,
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/gardena_bluetooth",
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["bleak", "bleak_esphome", "gardena_bluetooth"],
"requirements": ["gardena-bluetooth==1.6.0"]
@@ -10,7 +10,7 @@ from homeassistant.helpers import aiohttp_client, config_entry_oauth2_flow
from . import oauth2
from .const import DOMAIN
from .coordinator import HomeLinkConfigEntry, HomeLinkCoordinator, HomeLinkData
from .coordinator import HomeLinkConfigEntry, HomeLinkCoordinator
PLATFORMS: list[Platform] = [Platform.EVENT]
@@ -44,9 +44,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: HomeLinkConfigEntry) ->
)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = HomeLinkData(
provider=provider, coordinator=coordinator, last_update_id=None
)
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
@@ -54,5 +52,5 @@ async def async_setup_entry(hass: HomeAssistant, entry: HomeLinkConfigEntry) ->
async def async_unload_entry(hass: HomeAssistant, entry: HomeLinkConfigEntry) -> bool:
"""Unload a config entry."""
await entry.runtime_data.coordinator.async_on_unload(None)
await entry.runtime_data.async_on_unload(None)
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
@@ -7,7 +7,7 @@ import botocore.exceptions
from homelink.auth.srp_auth import SRPAuth
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.config_entries import ConfigFlowResult
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
from homeassistant.helpers.config_entry_oauth2_flow import AbstractOAuth2FlowHandler
@@ -34,7 +34,7 @@ class SRPFlowHandler(AbstractOAuth2FlowHandler, domain=DOMAIN):
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> config_entries.ConfigFlowResult:
) -> ConfigFlowResult:
"""Ask for username and password."""
errors: dict[str, str] = {}
if user_input is not None:
@@ -3,7 +3,6 @@
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from functools import partial
import logging
from typing import TypedDict
@@ -17,19 +16,10 @@ from homeassistant.util.ssl import get_default_context
_LOGGER = logging.getLogger(__name__)
type HomeLinkConfigEntry = ConfigEntry[HomeLinkData]
type HomeLinkConfigEntry = ConfigEntry[HomeLinkCoordinator]
type EventCallback = Callable[[HomeLinkEventData], None]
@dataclass
class HomeLinkData:
"""Class for HomeLink integration runtime data."""
provider: MQTTProvider
coordinator: HomeLinkCoordinator
last_update_id: str | None
class HomeLinkEventData(TypedDict):
"""Data for a single event."""
@@ -68,7 +58,7 @@ class HomeLinkCoordinator:
self._listeners[target_event_id] = update_callback
return partial(self.__async_remove_listener_internal, target_event_id)
def __async_remove_listener_internal(self, listener_id: str):
def __async_remove_listener_internal(self, listener_id: str) -> None:
del self._listeners[listener_id]
@callback
@@ -92,7 +82,7 @@ class HomeLinkCoordinator:
await self.discover_devices()
self.provider.listen(self.on_message)
async def discover_devices(self):
async def discover_devices(self) -> None:
"""Discover devices and build the Entities."""
self.device_data = await self.provider.discover()
@@ -3,25 +3,24 @@
from __future__ import annotations
from homeassistant.components.event import EventDeviceClass, EventEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DOMAIN, EVENT_PRESSED
from .coordinator import HomeLinkCoordinator, HomeLinkEventData
from .coordinator import HomeLinkConfigEntry, HomeLinkCoordinator, HomeLinkEventData
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: HomeLinkConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Add the entities for the binary sensor."""
coordinator = config_entry.runtime_data.coordinator
"""Add the entities for the event platform."""
coordinator = config_entry.runtime_data
async_add_entities(
HomeLinkEventEntity(button.id, button.name, device.id, device.name, coordinator)
HomeLinkEventEntity(coordinator, button.id, button.name, device.id, device.name)
for device in coordinator.device_data
for button in device.buttons
)
@@ -40,11 +39,11 @@ class HomeLinkEventEntity(EventEntity):
def __init__(
self,
coordinator: HomeLinkCoordinator,
button_id: str,
param_name: str,
device_id: str,
device_name: str,
coordinator: HomeLinkCoordinator,
) -> None:
"""Initialize the event entity."""
@@ -74,5 +73,4 @@ class HomeLinkEventEntity(EventEntity):
if update_data["requestId"] != self.last_request_id:
self._trigger_event(EVENT_PRESSED)
self.last_request_id = update_data["requestId"]
self.async_write_ha_state()
self.async_write_ha_state()
@@ -5,6 +5,7 @@
"config_flow": true,
"dependencies": ["application_credentials"],
"documentation": "https://www.home-assistant.io/integrations/geocaching",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["geocachingapi==0.3.0"]
}
@@ -4,6 +4,7 @@
"codeowners": ["@timmo001", "@ludeeus"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/github",
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["aiogithubapi"],
"requirements": ["aiogithubapi==24.6.0"]
@@ -4,6 +4,7 @@
"codeowners": ["@engrbm87"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/glances",
"integration_type": "service",
"iot_class": "local_polling",
"loggers": ["glances_api"],
"requirements": ["glances-api==0.8.0"]

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