Compare commits

...

987 Commits

Author SHA1 Message Date
Franck Nijhof
3da8d0a741 Bump version to 2024.7.0b2 2024-06-26 23:55:20 +02:00
Paul Bottein
0701b0daa9 Update frontend to 20240626.2 (#120614) 2024-06-26 23:55:11 +02:00
Luca Angemi
bea6fe30b8 Fix telegram bot thread_id key error (#120613) 2024-06-26 23:55:08 +02:00
Franck Nijhof
7d5d81b229 Bump version to 2024.7.0b1 2024-06-26 22:51:27 +02:00
Franck Nijhof
242b3fa609 Update adguardhome to 0.7.0 (#120605) 2024-06-26 22:48:39 +02:00
Marc Mueller
74204e2ee6 Fix mqtt test fixture usage (#120602) 2024-06-26 22:47:52 +02:00
Jan Bouwhuis
da01635a07 Prevent changes to mutable bmw_connected_drive fixture data (#120600) 2024-06-26 22:47:32 +02:00
Shay Levy
b5c34808e6 Add last_error reporting to Shelly diagnostics (#120595) 2024-06-26 22:47:09 +02:00
Erik Montnemery
80e70993c8 Remove deprecated run_immediately flag from integration sensor (#120593) 2024-06-26 22:46:50 +02:00
Max
2e01e169ef Correct deprecation warning async_register_static_paths (#120592) 2024-06-26 22:46:30 +02:00
Markus Jacobsen
b35442ed2d Improve Bang & Olufsen error messages (#120587)
* Convert logger messages to raised errors where applicable

* Modify exception types

* Improve deezer / tidal error message

* Update homeassistant/components/bang_olufsen/strings.json

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>

* Update homeassistant/components/bang_olufsen/media_player.py

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>

---------

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>
2024-06-26 22:46:27 +02:00
Michael Hansen
1b45069620 Bump intents to 2024.6.26 (#120584)
Bump intents
2024-06-26 22:46:23 +02:00
Shay Levy
d3d0e05817 Change Shelly connect task log message level to error (#120582) 2024-06-26 22:46:20 +02:00
TheJulianJES
3d164c6721 Bump ZHA dependencies (#120581) 2024-06-26 22:46:17 +02:00
Florian
6dd1e09354 Don't allow switch toggle when device in locked in AVM FRITZ!SmartHome (#120132)
* fix: set state of the FritzBox-Switch to disabled if the option for manuel switching in the userinterface is disabled

* feat: raise an error instead of disabling switch

* feat: rename method signature

* fix: tests

* fix: wrong import

* feat: Update homeassistant/components/fritzbox/strings.json

Update error message

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>

* Update tests/components/fritzbox/test_switch.py

feat: update test

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>

* make ruff happy

* fix expected error message check

---------

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>
2024-06-26 22:46:13 +02:00
Shay Levy
ba456f2564 Align Shelly sleeping devices timeout with non-sleeping (#118969) 2024-06-26 22:46:06 +02:00
Franck Nijhof
3492171ff8 Bump version to 2024.7.0b0 2024-06-26 16:17:57 +02:00
Gerben Jongerius
f5c640ee5b Add additional tests to youless integration (#118869) 2024-06-26 16:11:21 +02:00
epenet
713abf4c6b Refactor PLATFORM_SCHEMA imports in tests (#120566) 2024-06-26 16:09:20 +02:00
Bouwe Westerdijk
32c07180f6 Delete removed device(s) at runtime in Plugwise (#120296) 2024-06-26 16:08:32 +02:00
Mr. Bubbles
55101fcc45 Add platinum scale to pyLoad integration (#120542)
Add platinum scale
2024-06-26 16:06:55 +02:00
G Johansson
3d5d4f8ddb Add config flow to statistics (#120496) 2024-06-26 16:06:35 +02:00
treetip
30a3e9af2b Add profile duration sensor for Vallox integration (#120240) 2024-06-26 15:54:13 +02:00
Erik Montnemery
862cd76f89 Add explanatory comment in tests/patch_time.py (#120572) 2024-06-26 15:49:34 +02:00
epenet
f65d91f6d2 Refactor PLATFORM_SCHEMA imports in platforms (#120564) 2024-06-26 15:44:59 +02:00
epenet
f4fa5b581e Import PLATFORM_SCHEMA from platform not from helpers (#120565) 2024-06-26 15:43:48 +02:00
Mr. Bubbles
294e1d4fc4 Fix class name and deprecation version (#120570) 2024-06-26 15:42:03 +02:00
Joost Lekkerkerker
66a803e56c Disable Aladdin Connect (#120558)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-26 15:41:20 +02:00
Luke Lashley
d0f82d6f02 Add support for Dyad vacuums to Roborock (#115331) 2024-06-26 15:40:19 +02:00
Bouwe Westerdijk
4defc4a58f Implement a reboot-button for Plugwise (#120554)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-26 15:28:50 +02:00
Mr. Bubbles
af9b4b98ca Add value_fn to switch entity description in pyLoad (#120569) 2024-06-26 15:09:42 +02:00
Mr. Bubbles
43d686e0f1 Redact the hostname in pyLoad diagnostics (#120567) 2024-06-26 14:59:14 +02:00
Mr. Bubbles
7eb9875a9e Add Base class for entities in PyLoad integration (#120563)
* Add Base class for entities

* Remove constructors
2024-06-26 14:45:04 +02:00
Teemu R
fc2968bc1b Adjust tplink codeowners (#120561) 2024-06-26 14:35:22 +02:00
Luke Lashley
b9be491016 Add options flow to Roborock (#104345)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-26 14:32:26 +02:00
Brett Adams
ec16fc235b Add new coordinators to Tessie (#118452)
* WIP

* wip

* Add energy classes

* Add basis for Testing

* Bump Library

* fix case

* bump library

* bump library again

* bump library for teslemetry

* reorder

* Fix super

* Update strings.json

* Tests

* Small tweaks

* Bump

* Bump teslemetry

* Remove version

* Add WC states

* Bump to match dev

* Review feedback

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Review feedback

* Review feedback 1

* Review feedback 2

* TessieWallConnectorStates Enum

* fixes

* Fix translations and value

* Update homeassistant/components/tessie/strings.json

* Update homeassistant/components/tessie/strings.json

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-26 14:23:06 +02:00
epenet
fd67fe417e Use ruff to force alias when importing PLATFORM_SCHEMA (#120539) 2024-06-26 14:22:52 +02:00
Joost Lekkerkerker
e39d26bdc0 Add switch platform to Airgradient (#120559) 2024-06-26 14:21:30 +02:00
Michael Hansen
d515a7f063 Add created_seconds to timer info and pass to ESPHome devices (#120364) 2024-06-26 14:20:11 +02:00
Mr. Bubbles
f5ff19d602 Add measurement unit and state_class to sensors in pyLoad (#120551) 2024-06-26 14:14:48 +02:00
Luke Lashley
69e0227682 Add Roborock to strict typing (#120379) 2024-06-26 14:13:49 +02:00
Joost Lekkerkerker
0d2aeb846f Increase max temperature to 40 for Tado (#120560) 2024-06-26 14:05:24 +02:00
Mr. Bubbles
1d0aa6bff0 Update docstrings in pyLoad tests (#120556) 2024-06-26 13:40:20 +02:00
Bouwe Westerdijk
b07453dca4 Implement remaining select-adaptions for Plugwise (#120544) 2024-06-26 13:37:08 +02:00
Mr. Bubbles
972b85a75b Fix class and variable naming errors in pyLoad integration (#120547) 2024-06-26 13:36:25 +02:00
Mr. Bubbles
13a9efb6a6 Convert dataclass to dict in pyLoad diagnostics (#120552) 2024-06-26 13:36:01 +02:00
Erik Montnemery
a36c40a434 Use state_reported events in Riemann sum sensor (#113869) 2024-06-26 13:35:01 +02:00
Bram Kragten
f0590f08b1 Update frontend to 20240626.0 (#120546) 2024-06-26 13:26:53 +02:00
Robert Resch
e8a3e3c8db Fix airgradient select entities (#120549) 2024-06-26 13:19:34 +02:00
Mr. Bubbles
34e266762e Remove unnecessary icon states in pyLoad integration (#120548)
Remove unnecessary icon states
2024-06-26 13:09:50 +02:00
Joost Lekkerkerker
7ef1db0549 Fix release in MPD issue (#120545) 2024-06-26 12:52:31 +02:00
epenet
be7a2c2cc2 Revert "Force alias when importing scene PLATFORM_SCHEMA" (#120540)
Revert "Force alias when importing scene PLATFORM_SCHEMA (#120534)"

This reverts commit 348ceca19f.
2024-06-26 12:40:41 +02:00
Richard Kroegel
d5bcfe9822 Improve BMW tests (#119171)
Co-authored-by: Richard <rikroe@users.noreply.github.com>
2024-06-26 12:27:55 +02:00
Erik Montnemery
9bbeb5d608 Add primary_config_entry attribute to device registry entries (#119959)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-26 12:26:24 +02:00
Erik Montnemery
f55ddfecf4 Correct type annotations in integration sensor tests (#120541) 2024-06-26 12:25:02 +02:00
epenet
36d8ffa79a Force alias when importing media player PLATFORM_SCHEMA (#120537) 2024-06-26 12:19:04 +02:00
Joost Lekkerkerker
fac8349c37 Add learning offset select to Airgradient (#120532) 2024-06-26 12:18:33 +02:00
Bouwe Westerdijk
d00fe1ce7f Import DOMAIN constants for Plugwise and implement (#120530) 2024-06-26 12:17:17 +02:00
epenet
c49fce5541 Force alias when importing sensor PLATFORM_SCHEMA (#120536) 2024-06-26 12:14:13 +02:00
epenet
348ceca19f Force alias when importing scene PLATFORM_SCHEMA (#120534) 2024-06-26 12:11:22 +02:00
epenet
32bab97f00 Force alias when importing light PLATFORM_SCHEMA (#120529) 2024-06-26 11:53:15 +02:00
epenet
912136be25 Force alias when importing lock PLATFORM_SCHEMA (#120531) 2024-06-26 11:52:57 +02:00
Brett Adams
d4dc7d76d9 Refactor Tessie for future PR (#120406)
* Bump tessie-api

* Refactor

* revert bump

* Fix cover

* Apply suggestions from code review

Co-authored-by: G Johansson <goran.johansson@shiftit.se>

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-06-26 11:46:30 +02:00
epenet
a8bf671663 Force alias when importing remote PLATFORM_SCHEMA (#120533) 2024-06-26 11:45:57 +02:00
Mr. Bubbles
42d235ce4d Add diagnostics platform to pyLoad integration (#120535) 2024-06-26 11:44:58 +02:00
Stefan Agner
44aad2b821 Improve Matter Server version incompatibility handling (#120416)
* Improve Matter Server version incompatibility handling

Improve the handling of Matter Server version. Noteably fix the issues
raised (add strings for the issue) and split the version check into
two cases: One if the server is too old and one if the server is too
new.

* Bump Python Matter Server library to 6.2.0b1

* Address review feedback
2024-06-26 11:43:51 +02:00
epenet
7b7b97a7a4 Force alias when importing event and fan PLATFORM_SCHEMA (#120524) 2024-06-26 11:35:39 +02:00
hahn-th
ae73500beb Add HmIP-ESI (#116863) 2024-06-26 11:33:44 +02:00
Marc Mueller
d527113d59 Improve schema typing (3) (#120521) 2024-06-26 11:30:07 +02:00
epenet
afbd24adfe Force alias when importing image processing PLATFORM_SCHEMA (#120527) 2024-06-26 11:29:52 +02:00
epenet
2c17d84fab Force alias when importing cover PLATFORM_SCHEMA (#120522) 2024-06-26 11:25:14 +02:00
epenet
17946c4b45 Force alias when importing geo location PLATFORM_SCHEMA (#120525) 2024-06-26 11:24:45 +02:00
epenet
59ae297ccd Force alias when importing humidifier PLATFORM_SCHEMA (#120526) 2024-06-26 11:24:21 +02:00
Erik Montnemery
d589eaf440 Simplify EVENT_STATE_REPORTED (#120508) 2024-06-26 11:23:26 +02:00
epenet
2c48843739 Force alias when importing device tracker PLATFORM_SCHEMA (#120523) 2024-06-26 11:13:27 +02:00
Bouwe Westerdijk
41026b9227 Implement @plugwise_command for Plugwise Select platform (#120509) 2024-06-26 11:04:00 +02:00
epenet
0c0f666a28 Force alias when importing camera PLATFORM_SCHEMA (#120514) 2024-06-26 11:03:13 +02:00
Mr. Bubbles
45dedf73c8 Add exception translations for pyLoad integration (#120520) 2024-06-26 11:00:31 +02:00
epenet
e06d7050f2 Force alias when importing climate PLATFORM_SCHEMA (#120518) 2024-06-26 10:55:09 +02:00
epenet
399130bc95 Force alias when importing binary sensor PLATFORM_SCHEMA (#120510) 2024-06-26 10:54:19 +02:00
Mr. Bubbles
8e598ec3ff Rename sensor to finished downloads in pyLoad integration (#120483) 2024-06-26 10:50:32 +02:00
epenet
c96dc00a3a Force alias when importing alarm control panel PLATFORM_SCHEMA (#120505) 2024-06-26 10:41:46 +02:00
epenet
6c81885cae Force alias when importing calendar PLATFORM_SCHEMA (#120512) 2024-06-26 10:40:17 +02:00
epenet
9b8922a678 Force alias when importing switch PLATFORM_SCHEMA (#120504) 2024-06-26 10:36:54 +02:00
Artur Pragacz
a4ba346dfc Switch onkyo to pyeiscp, making it local_push (#120026)
* Switch onkyo to pyeiscp, making it local_push

Major rewrite of the integration to use pyeiscp.
This facilitates use of the async push updates.
Streamline the code dealing with zones.
Handle sound mode.
Add myself to codeowners.

* Add types

* Add more types

* Address feedback

* Remove sound mode support for now

* Fix zone detection

* Keep legacy unique_id
2024-06-26 10:28:06 +02:00
Bouwe Westerdijk
0a48cc29b6 Implement @plugwise_command for Plugwise Number platform (#120503) 2024-06-26 10:24:29 +02:00
epenet
7b298f177c Force alias when importing tts PLATFORM_SCHEMA (#120500) 2024-06-26 10:23:37 +02:00
Mr. Bubbles
d76a82e340 Add switch platform to pyload integration (#120352) 2024-06-26 10:21:54 +02:00
epenet
caa57c56f6 Force alias when importing air_quality PLATFORM_SCHEMA (#120502) 2024-06-26 10:03:29 +02:00
epenet
4bfecea2f4 Force alias when importing notify PLATFORM_SCHEMA (#120494) 2024-06-26 10:02:24 +02:00
Joost Lekkerkerker
59959141af Remove Knocki triggers on runtime (#120452)
* Bump Knocki to 0.2.0

* Remove triggers on runtime in Knocki

* Fix
2024-06-26 09:52:05 +02:00
Mr. Bubbles
82b8b73b8a Add reconfiguration flow to pyLoad integration (#120485) 2024-06-26 09:46:50 +02:00
Erik Montnemery
4a86693254 Verify default timezone is restored when test ends (#116216) 2024-06-26 09:41:16 +02:00
G Johansson
c085057847 Add timezone testing in holiday (#120497) 2024-06-26 09:40:29 +02:00
starkillerOG
1b88448914 Do not wait for Reolink firmware check (#120377) 2024-06-26 09:34:45 +02:00
Jan Bouwhuis
c5b7d2d868 Cleanup mqtt platform tests part 3 (#120493) 2024-06-26 09:29:40 +02:00
Joost Lekkerkerker
5a0841155e Add unique_id to MPD (#120495) 2024-06-26 09:28:11 +02:00
Thomas Kistler
bff9d12cc0 Add active watering time sensor to Hydrawise (#120177) 2024-06-26 09:24:48 +02:00
J. Nick Koston
30e0bcb324 Bump dbus-fast to 2.22.1 (#120491) 2024-06-26 09:20:43 +02:00
Jan Bouwhuis
e567f8f3d5 Fix issue where an MQTT device is removed linked to two config entries (#120430)
* Fix issue where an MQTT device is removed linked to two config entries

* Update homeassistant/components/mqtt/discovery.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/mqtt/debug_info.py

Co-authored-by: J. Nick Koston <nick@koston.org>

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-26 09:14:33 +02:00
Michael Hansen
d3ceaef098 Allow timer management from any device (#120440) 2024-06-26 09:06:56 +02:00
Abílio Costa
8ce53d28e7 Handle availability in Idasen Desk height sensor (#120277) 2024-06-26 09:02:49 +02:00
Robert Resch
9f4bf6f11a Create repair when HA auth provider is running in legacy mode (#119975) 2024-06-26 09:00:33 +02:00
Erik Montnemery
005c71a4a5 Deduplicate alarm_control_panel services.yaml (#118796) 2024-06-26 08:55:28 +02:00
Jan Bouwhuis
fab901f9b6 Cleanup mqtt platform tests part 2 (#120490) 2024-06-26 08:53:28 +02:00
J. Nick Koston
cef1d35e31 Make fetching integrations with requirements safer (#120481) 2024-06-26 08:51:57 +02:00
Grubalex
b7e7905b54 Add Philips WiZ Lightbulbs to Matter TRANSITION_BLOCKLIST (#120461) 2024-06-26 08:51:55 +02:00
Mr. Bubbles
f23020919f Remove unused translation strings in pyLoad integration (#120476) 2024-06-26 08:51:12 +02:00
Mr. Bubbles
cc6aac5e75 Add missing textselectors in USER_DATA_SCHEMA in pyLoad integration (#120479) 2024-06-26 08:50:45 +02:00
G Johansson
0f7229f55f Fix holiday using utc instead of local time (#120432) 2024-06-26 08:45:53 +02:00
Mr. Bubbles
ba40340f82 Align deviceinfo entries in pyLoad integration (#120478) 2024-06-26 08:45:22 +02:00
J. Nick Koston
07b70cba10 Fix dropped unifiprotect motion events (#120489) 2024-06-26 08:32:43 +02:00
Marc Mueller
6fb32db151 Improve config vol.Invalid typing (#120482) 2024-06-26 03:03:54 +02:00
Marc Mueller
49df0c4366 Improve schema typing (2) (#120475) 2024-06-26 02:25:30 +02:00
EnjoyingM
2380696fcd Bump wolf-comm to 0.0.9 (#120473) 2024-06-26 02:22:09 +02:00
Marc Mueller
3937cc2963 Improve SERVICE_TO_METHOD typing (#120474) 2024-06-26 02:20:48 +02:00
Marc Mueller
0bc597f8c7 Improve vol.Invalid handling (#120480) 2024-06-26 02:13:09 +02:00
J. Nick Koston
ec2f98d075 Bump uiprotect to 3.7.0 (#120471) 2024-06-26 02:12:04 +02:00
Thomas Kistler
9718a9571e Add @thomaskistler as an owner of hydrawise (#120477) 2024-06-26 02:11:52 +02:00
Tom Harris
3cc3eb21b4 Bump pyinsteon to 1.6.3 to fix Insteon device status (#120464) 2024-06-26 00:04:09 +02:00
Luke Lashley
60519702b4 Bump python-roborock to 2.5.0 (#120466) 2024-06-26 00:03:01 +02:00
Jan Bouwhuis
038f2ce79f Cleanup mqtt platform tests part 1 (#120470) 2024-06-26 00:01:57 +02:00
Stefan Agner
5983344746 Handle http connection errors to Prusa printers (#120456) 2024-06-25 22:34:56 +02:00
Joost Lekkerkerker
1f0e47b251 Migrate Airgradient select entities to be config source dependent (#120462)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-25 22:27:52 +02:00
Teemu R
4290a1fcb5 Upgrade tplink with new platforms, features and device support (#120060)
Co-authored-by: Teemu Rytilahti <tpr@iki.fi>
Co-authored-by: sdb9696 <steven.beth@gmail.com>
Co-authored-by: Steven B <51370195+sdb9696@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Teemu R. <tpr@iki.fi>
2024-06-25 22:01:21 +02:00
Joost Lekkerkerker
9bc4361855 Bump Knocki to 0.2.0 (#120447) 2024-06-25 20:17:51 +02:00
Marc Mueller
f4b124f5f1 Fix invalid schemas (#120450) 2024-06-25 20:17:38 +02:00
Erik Montnemery
7d2ae5b3a5 Add WS command blueprint/substitute (#119890) 2024-06-25 20:15:11 +02:00
Marc Mueller
9dc26652ee Fix gtfs typing (#120451) 2024-06-25 20:08:04 +02:00
Erik Montnemery
75c7ae7c69 Support in service descriptions for input sections (#116100) 2024-06-25 20:00:48 +02:00
J. Nick Koston
c4b277b6ab Small cleanups to ESPHome manager reconnect shutdown (#120401) 2024-06-25 19:40:04 +02:00
Erik Montnemery
d4e93dd01d Validate new device identifiers and connections (#120413) 2024-06-25 19:17:54 +02:00
Marc Mueller
3559755aed Add import aliases for PLATFORM_SCHEMA (#120445) 2024-06-25 19:16:19 +02:00
Jan Bouwhuis
cbcf29720d Cleanup common mqtt tests (#120446) 2024-06-25 19:15:11 +02:00
Marc Mueller
185e79fa1b Improve intent schema typing (#120442) 2024-06-25 19:02:04 +02:00
Marc Mueller
b393024acd Improve collection schema typing (#120441) 2024-06-25 18:57:15 +02:00
Marc Mueller
197062139e Fix schema typing (1) (#120443) 2024-06-25 18:54:06 +02:00
Marc Mueller
f017134199 Fix missing vol.Optional keyword (#120444) 2024-06-25 18:53:06 +02:00
J. Nick Koston
e0b9855160 Bump uiprotect to 3.4.0 (#120433) 2024-06-25 18:22:56 +02:00
epenet
09e8f7e9bb Improve type hints in deconz tests (#120388) 2024-06-25 17:44:03 +02:00
Denis Shulyaka
2386ed3830 Add script llm tool (#118936)
* Add script llm tool

* Add tests

* More tests

* more test

* more test

* Add area and floor resolving

* coverage

* coverage

* fix ColorTempSelector

* fix mypy

* fix mypy

* add script reload test

* Cache script tool parameters

* Make custom_serializer a part of api

---------

Co-authored-by: Michael Hansen <mike@rhasspy.org>
2024-06-25 10:43:26 -05:00
Mr. Bubbles
77fea8a73e Add reauth flow to pyLoad integration (#120376)
Add reauth flow
2024-06-25 17:15:12 +02:00
Kevin Stillhammer
253514a124 Bump pywaze to 1.0.2 (#120412) 2024-06-25 17:08:36 +02:00
epenet
6a370bde34 Adjust imports in samsungtv tests (#120409) 2024-06-25 17:08:10 +02:00
epenet
6e5bc0da94 Improve type hints in cloud tests (#120420) 2024-06-25 17:07:50 +02:00
J. Nick Koston
4feca36ca6 Refactor esphome platform setup to reduce boilerplate (#120415) 2024-06-25 17:03:04 +02:00
J. Nick Koston
49e6316c42 Bump yalexs-ble to 2.4.3 (#120428) 2024-06-25 17:00:26 +02:00
J. Nick Koston
edaa5c60a7 Small cleanups to ESPHome (#120414) 2024-06-25 17:00:03 +02:00
Aaron Godfrey
f934fea754 Apply all todoist custom project filters for calendar events (#117454)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-25 15:34:54 +02:00
Marc Mueller
bcd1243686 Use VolDictType to improve schema typing (#120417) 2024-06-25 15:15:59 +02:00
Jan Bouwhuis
aa05f73210 Add fixture to synchronize with debouncer in MQTT tests (#120373)
* Add fixture to synchronze with debouncer in MQTT tests

* Migrate more tests to use the debouncer

* Migrate more tests

* Migrate util tests

* Improve mqtt on_callback test using new fixture

* Improve test_subscribe_error

* Migrate other tests

* Import EnsureJobAfterCooldown from `util.py` but patch `client.py`
2024-06-25 14:26:20 +02:00
Marc Mueller
b816fce976 Improve websocket_api schema typing (#120411) 2024-06-25 14:08:30 +02:00
J. Nick Koston
b5afc5a7f0 Fix incorrect mocking in ESPHome tests (#120410) 2024-06-25 13:31:50 +02:00
J. Nick Koston
c15718519b Improve test coverage for ESPHome manager (#120400) 2024-06-25 13:14:11 +02:00
epenet
76e890865e Adjust imports in cloud tests (#120386) 2024-06-25 13:13:14 +02:00
epenet
cbb3d48bd9 Improve type hints in dsmr tests (#120393) 2024-06-25 13:11:27 +02:00
J. Nick Koston
fccb7ea1f9 Migrate ESPHome to use entry.runtime_data (#120402) 2024-06-25 13:10:09 +02:00
Marc Mueller
7453b7df63 Improve mqtt schema typing (#120407) 2024-06-25 13:03:18 +02:00
Marc Mueller
62fd692d27 Improve async_register_admin_service schema typing (#120405) 2024-06-25 12:48:00 +02:00
Brett Adams
de8bccb650 Add services to Teslemetry (#119119)
* Add custom services

* Fixes

* wip

* Test coverage

* Update homeassistant/components/teslemetry/__init__.py

Co-authored-by: G Johansson <goran.johansson@shiftit.se>

* Add error translations

* Translate command error

* Fix test

* Expand on comment as requested

* Remove impossible cases

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-06-25 12:44:06 +02:00
Marc Mueller
3a5acd6a57 Use VolDictType for service schemas (#120403) 2024-06-25 12:33:41 +02:00
Marc Mueller
b4eee166aa Add voluptuous type aliases (#120399) 2024-06-25 11:58:27 +02:00
Marc Mueller
53f5dec1b4 Install libturbojpeg [ci] (#120397) 2024-06-25 11:26:45 +02:00
treetip
d3e76b1f39 Update vallox_websocket_api to 5.3.0 (#120395) 2024-06-25 11:24:57 +02:00
Erik Montnemery
0545ed8082 Section support for data entry flows (#118369)
* Add expandable support for data entry form flows

* Update config_validation.py

* optional options

* Adjust

* Correct translations of data within sections

* Update homeassistant/components/kitchen_sink/config_flow.py

Co-authored-by: Robert Resch <robert@resch.dev>

* Add missing import

* Update tests/components/kitchen_sink/test_config_flow.py

Co-authored-by: Robert Resch <robert@resch.dev>

* Format code

* Match frontend when serializing

* Move section class to data_entry_flow

* Correct serializing

* Fix import in kitchen_sink

* Move and update test

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-25 11:02:00 +02:00
epenet
3d1ff72a88 Improve type hints in device_automation tests (#120389) 2024-06-25 10:58:10 +02:00
starkillerOG
ddd8083302 Fix translation error in Reolink reauth flow (#120385) 2024-06-25 10:37:42 +02:00
Jan Bouwhuis
1d16cbec96 Move mqtt debouncer to mqtt utils (#120392) 2024-06-25 10:33:58 +02:00
epenet
46ed76df31 Improve type hints in diagnostics tests (#120391) 2024-06-25 10:07:05 +02:00
epenet
f8d5c9144a Improve type hints in device_tracker tests (#120390) 2024-06-25 10:06:38 +02:00
epenet
7f20c1a489 Improve type hints in demo tests (#120387) 2024-06-25 09:55:59 +02:00
Erik Montnemery
6fb400f76b Add test of get_all_descriptions resolving features (#120384) 2024-06-25 09:47:43 +02:00
David Bonnes
744161928e Bump evohome-async to 0.4.20 (#120353) 2024-06-25 08:25:04 +02:00
Jan Schneider
ced6c0dd8c Update moehlenhoff-alpha2 to 1.3.1 (#120351)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-25 08:11:26 +02:00
Mr. Bubbles
fd0fee1900 Add button platform to pyLoad integration (#120359) 2024-06-25 08:09:54 +02:00
Luke Lashley
adc074f60a Remove humbertogontijo as Codeowner for Roborock (#120336) 2024-06-25 08:03:20 +02:00
G Johansson
59998bc48a Use runtime_data in github (#120362) 2024-06-25 08:02:57 +02:00
Markus Jacobsen
aa8427abe5 Bump Bang & Olufsen mozart-open-api to 3.4.1.8.6 fixing blocking IO call (#120369)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-25 08:02:02 +02:00
Mr. Bubbles
59080a3a6f Strip whitespace characters from token in One-Time-Passwort (OTP) integration (#120380) 2024-06-25 08:00:19 +02:00
Marc Mueller
f1ddf80dff Fix dlna_dms test RuntimeWarning (#120341) 2024-06-25 03:34:23 +02:00
Michael Hansen
1e16afb43b Fix pylint error in Google generative AI tests (#120371)
* Fix pylint error

* Add second fix
2024-06-24 16:03:34 -05:00
Michael Hansen
6d917f0242 Don't run timer callbacks for delayed commands (#120367)
* Don't send timer events for delayed commands

* Don't run timer callbacks for delayed commands
2024-06-24 16:21:51 -04:00
Markus Jacobsen
d0961ca473 Make Bang & Olufsen products ignore .m3u media source files (#120317) 2024-06-24 21:06:57 +02:00
Joost Lekkerkerker
72d1b3e360 Deprecate Nanoleaf gesture device trigger (#120078) 2024-06-24 21:05:23 +02:00
starkillerOG
bbb8bb31f9 Only raise Reolink re-auth flow when login fails 3 consecutive times (#120291) 2024-06-24 21:03:41 +02:00
epenet
ea09d0cbed Use HassKey in cloud integration (#120322) 2024-06-24 21:02:08 +02:00
epenet
b223cb7bb9 Ensure config_entry is added to hass in tests (#120327) 2024-06-24 21:00:12 +02:00
David Knowles
3b79ab6e18 Reduce the amount of data fetched in individual Hydrawise API calls (#120328) 2024-06-24 20:58:54 +02:00
Michael Hansen
46dcf1dc44 Prioritize custom intents over builtin (#120358) 2024-06-24 20:57:56 +02:00
Robert Resch
6689dbbcc6 Deprecate DTE Energy Bridge (#120350)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-06-24 20:56:35 +02:00
G Johansson
00621ad512 Use runtime data in version (#120363) 2024-06-24 20:53:49 +02:00
Koen van Zuijlen
fb3059e6e6 Bump justnimbus to 0.7.4 (#120355) 2024-06-24 20:47:42 +02:00
Nathan Spencer
6b78e913f2 Bump pybalboa to 1.0.2 (#120360) 2024-06-24 20:45:30 +02:00
Charles Garwood
e2b0c55883 Bump python-fullykiosk to 0.0.14 (#120361) 2024-06-24 20:42:31 +02:00
Jan Bouwhuis
a7200a70b2 Set up mqtt tests from client fixture of mqtt entry setup fixture, not both (#120274)
* Fix entry setup and cleanup issues in mqtt tests

* Reduce changes by using mqtt_client_mock alias

* Reduce sleep time where possibe
2024-06-24 19:42:32 +02:00
Mr. Bubbles
1e5f4c2d75 Add additional sensors to pyLoad integration (#120309) 2024-06-24 18:56:33 +02:00
epenet
31157828e1 Improve type hints in cloudflare tests (#120344) 2024-06-24 18:55:36 +02:00
Marc Mueller
a4e22bcba6 Update tenacity constraint (#120348) 2024-06-24 18:52:49 +02:00
Robert Resch
641507a45a Add change username endpoint (#109057) 2024-06-24 18:51:19 +02:00
J. Nick Koston
1e3ee8419f Bump async-interrupt to 1.1.2 (#120321) 2024-06-24 18:41:42 +02:00
J. Nick Koston
dd379a9a0a Bump aiozoneinfo to 0.2.1 (#120319) 2024-06-24 18:39:38 +02:00
epenet
8bad421a04 Improve type hints in config tests (#120346) 2024-06-24 18:36:57 +02:00
epenet
4089b808c3 Improve type hints in comfoconnect tests (#120345) 2024-06-24 18:33:51 +02:00
Erik Montnemery
d073fd9b37 Improve integration sensor tests (#120326) 2024-06-24 18:33:08 +02:00
J. Nick Koston
0247f91855 Bump bleak to 0.22.2 (#120325) 2024-06-24 18:32:32 +02:00
J. Nick Koston
8e26655915 Bump led-ble to 1.0.2 (#120347) 2024-06-24 17:51:30 +02:00
J. Nick Koston
eab1dc5255 Bump home-assistant-bluetooth to 1.12.2 (#120338) 2024-06-24 17:38:17 +02:00
J. Nick Koston
063a3f3bca Bump discovery30303 to 0.3.2 (#120340) 2024-06-24 17:36:48 +02:00
J. Nick Koston
b7bf61a8c9 Bump habluetooth to 3.1.3 (#120337) 2024-06-24 17:35:33 +02:00
J. Nick Koston
bd6164ad4b Bump bluetooth-data-tools to 1.19.3 (#120323) 2024-06-24 17:10:57 +02:00
Lennard Beers
e2f9ba5455 Bump eq3btsmart to 1.1.9 (#120339) 2024-06-24 17:00:37 +02:00
Marc Mueller
d1de42a299 Replace deprecated attribute in abode (#120343) 2024-06-24 16:44:59 +02:00
epenet
015bc0e172 Use HassKey in homeassistant integration (#120332) 2024-06-24 16:37:07 +02:00
Jan Bouwhuis
85720f9e02 Fix setup and tear down issues for mqtt discovery and config flow tests (#120333)
* Fix setup and tear down issues for mqtt discovery and config flow tests

* Use async callback
2024-06-24 16:20:44 +02:00
J. Nick Koston
2776b28bb7 Bump govee-ble to 0.31.3 (#120335) 2024-06-24 16:20:07 +02:00
Erik Montnemery
0d1b050520 Remove create_create from StorageCollectionWebsocket.async_setup (#119489) 2024-06-24 15:41:08 +02:00
J. Nick Koston
1a27cea6f2 Bump bluetooth-adapters to 0.19.2 (#120324) 2024-06-24 15:25:08 +02:00
Jan Bouwhuis
389b9d1ad6 Make sure ACK's are processed before mqtt tests are teared down (#120329) 2024-06-24 15:16:09 +02:00
J. Nick Koston
57cdd33537 Bump aiosteamist to 1.0.0 (#120318) 2024-06-24 14:56:48 +02:00
J. Nick Koston
e6cb68d199 Bump aiohttp-fast-zlib to 0.1.1 (#120315) 2024-06-24 14:33:16 +02:00
J. Nick Koston
604561aac0 Bump uiprotect to 3.3.1 (#120314) 2024-06-24 14:33:04 +02:00
J. Nick Koston
37c60d800e Bump aionut to 4.3.3 (#120313) 2024-06-24 14:32:52 +02:00
J. Nick Koston
8acb73df2e Bump aiooui to 0.1.6 (#120312) 2024-06-24 14:32:28 +02:00
Erik Montnemery
a5e6728227 Improve integration sensor tests (#120316) 2024-06-24 14:17:52 +02:00
J. Nick Koston
fbdc06647b Bump aiodhcpwatcher to 1.0.2 (#120311) 2024-06-24 14:05:13 +02:00
epenet
b4d0de9c0f Improve type hints in conversation tests (#120306) 2024-06-24 13:41:55 +02:00
epenet
aef2f7d707 Improve type hints in canary tests (#120305) 2024-06-24 13:34:44 +02:00
epenet
e3806d12f4 Improve type hints in simplisafe tests (#120303) 2024-06-24 13:34:23 +02:00
Mr. Bubbles
237f20de6c Add DataUpdateCoordinator to pyLoad integration (#120237)
* Add DataUpdateCoordinator

* Update tests

* changes

* changes

* test coverage

* some changes

* Update homeassistant/components/pyload/sensor.py

* use dataclass

* fix ConfigEntry

* fix configtype

* fix some issues

* remove logger

* remove unnecessary else

* revert fixture changes

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-24 12:58:37 +02:00
Joost Lekkerkerker
674dfa6e9c Add button platform to AirGradient (#119917) 2024-06-24 11:55:48 +02:00
Joost Lekkerkerker
f3a1ca6d54 Add coordinator to Knocki (#120251) 2024-06-24 11:41:33 +02:00
Jason R. Coombs
c04a6cc639 Bump jaraco.abode to 5.1.2 (#117363)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-24 11:37:12 +02:00
Cyrill Raccaud
59dd63ea86 Remove deprecated attributes from Swiss public transport integration (#120256) 2024-06-24 11:18:10 +02:00
Erik Montnemery
e32a27a8ff Remove hass_recorder test fixture (#120295) 2024-06-24 11:14:08 +02:00
Marc Mueller
be6dfc7a70 Typing improvements (#120297) 2024-06-24 11:07:22 +02:00
Arie Catsman
158c8b8400 Add optional test fixture collection to enphase_envoy diagnostic report (#116242)
* diagnostics_fixtures

* fix codespell errors

* fix merge order and typo

* remove pointless-string-statement
2024-06-24 10:37:32 +02:00
tronikos
deee10813c Ensure flume sees the most recent notifications (#120290) 2024-06-24 10:08:51 +02:00
tronikos
0dff7e8a55 Bump PyFlume to 0.8.7 (#120288) 2024-06-24 10:02:30 +02:00
Marc Mueller
b798d76706 Update mypy-dev to 1.11.0a9 (#120289) 2024-06-24 09:57:15 +02:00
Bouwe Westerdijk
213cb6f0fd Improve Plugwise runtime-updating (#120230) 2024-06-24 09:57:04 +02:00
Joost Lekkerkerker
ab9cbf64da Add sensors to Airgradient (#120286) 2024-06-24 09:54:22 +02:00
Paulus Schoutsen
5c2db162c4 Remove "no API" prompt (#120280) 2024-06-24 08:57:59 +02:00
Joost Lekkerkerker
4785810dc3 Migrate AEMET to has entity name (#120284) 2024-06-24 08:54:46 +02:00
Allen Porter
fa9bced6b0 Load local calendar ics in background thread to avoid timezone I/O in event loop (#120276) 2024-06-24 08:43:42 +02:00
Raman Gupta
6a5c1fc613 Replace custom validator from zwave_js with from_dict funcs (#120279) 2024-06-24 08:43:13 +02:00
Luca Angemi
fdade67211 Add device info for Aemet (#120243)
* Update sensor.py

* Update weather.py

* Update sensor.py

* ruff

* add device info to entity

* remove info from sensor

* remove info from weather

* ruff

* amend entity

* Update sensor.py

* Update weather.py

* ruff again

* add DOMAIN

* type unique_id

* Update entity.py

* Update entity.py

* assert

* update tests

* change snapshot
2024-06-24 08:20:34 +02:00
Thomas55555
fe3027f7de Adjust base entities in Husqvarna Automower (#120258)
* adjust base entities

* Adjust docstrings
2024-06-24 08:16:26 +02:00
Mr. Bubbles
d095d4e60d Change suggested data rate unit to Mbit/s in pyLoad (#120275)
Change data rate unit to Mbit/s
2024-06-24 07:53:15 +02:00
Danilo Bargen
66b91a84f9 mystrom: Add MAC and Config URL to devices (#120271)
* Add MAC address to mystrom switch devices

* Add configuration URL to mystrom switch devices
2024-06-23 21:39:58 -04:00
Paulus Schoutsen
19f97a3e53 LLM to handle decimal attributes (#120257) 2024-06-23 17:09:57 -04:00
Tsvi Mostovicz
143e8d09af Fix blocking call in Jewish Calendar while initializing location (#120265) 2024-06-23 16:04:16 -05:00
J. Nick Koston
436c36e3dd Bump aioesphomeapi to 24.6.1 (#120261) 2024-06-23 22:20:46 +02:00
Steven Looman
55a2645e78 Bump async_upnp_client to 0.39.0 (#120250) 2024-06-23 14:21:56 -05:00
Abílio Costa
480ffeda2c Remove connection state handling from Idasen Desk (#120242) 2024-06-23 12:56:10 -05:00
Tsvi Mostovicz
29da88d8f6 Create a Jewish Calendar entity (#120253)
* Set has_entity_name to true

* Move common code to jewish calendar service entity

* Remove already existing assignment

* Move data to common entity

* Remove description name

* Use config entry title instead of name for the device

* Address comments
2024-06-23 19:55:27 +02:00
Matthew FitzGerald-Chamberlain
034b5e88e0 Add Aprilaire air cleaning and fresh air functionality (#120174)
* Add custom services for Aprilaire

* Add icons.json

* Use select/number entities instead of services

* Remove unneeded consts

* Remove number platform

* Code review updates

* Update homeassistant/components/aprilaire/strings.json

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Code review updates

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-23 19:47:09 +02:00
Cyrill Raccaud
7efd1079bd Add Swiss public transport via stations (#115891)
* add via stations

* bump minor version due to backwards incompatibility

* better coverage of many via station options in unit tests

* fix migration unit test for new minor version 1.3

* switch version bump to major and improve migration test

* fixes

* improve error messages

* use placeholders for strings
2024-06-23 19:26:55 +02:00
J. Nick Koston
5fbb965624 Bump uiprotect to 3.1.8 (#120244) 2024-06-23 11:35:58 -05:00
J. Nick Koston
fa4b7f3078 Bump yalexs to 6.4.1 (#120248) 2024-06-23 11:16:11 -05:00
Joost Lekkerkerker
080d90b63a Add airgradient param fixture (#120241) 2024-06-23 17:48:54 +02:00
Joost Lekkerkerker
9769dec44b Add number platform to AirGradient (#120247)
* Add number entity

* Add airgradient number entities

* Fix
2024-06-23 17:45:43 +02:00
Jan Bouwhuis
f1fd52bc30 Fix issue in mqtt fixture calling disconnect handler (#120246) 2024-06-23 10:37:08 -05:00
Tsvi Mostovicz
2cc34fd7e7 Improve Jewish calendar entities (#120236)
* By default don't enable all sensors

* Fix tests

* Add entity category

* Set has_entity_name to true

* Revert "Set has_entity_name to true"

This reverts commit 5ebfcde78ab0ff54bdca037b3bf3e6ec187cafea.
2024-06-23 17:26:45 +02:00
Mr. Bubbles
473b3b61eb Add string and icon translations to pyLoad integration (#120234)
add string and icon translations to pyLoad
2024-06-23 14:25:36 +02:00
Virenbar
001abdaccf Fix generic thermostat string (#120235) 2024-06-23 13:49:43 +02:00
Mr. Bubbles
826587abb2 Add DeviceInfo to pyLoad integration (#120232)
* Add device info to pyLoad integration

* Update homeassistant/components/pyload/sensor.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/pyload/sensor.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* remove name, add entry_type

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-23 13:16:00 +02:00
Joakim Plate
84d1d11138 Add config flow to generic hygrostat (#119017)
* Add config flow to hygrostat

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-23 12:56:41 +02:00
G Johansson
4474e8c7ef Remove YAML import for tado (#120231) 2024-06-23 12:51:12 +02:00
Mr. Bubbles
28fb361c64 Add config flow to pyLoad integration (#120135)
* Add config flow to pyLoad integration

* address issues

* remove suggested values

* Fix exception

* abort import flow on error

* readd repair issues on error

* fix ruff

* changes

* changes

* exception hints
2024-06-23 12:34:32 +02:00
Bouwe Westerdijk
f257fcb0d1 Bump plugwise to v0.38.3 (#120152) 2024-06-23 10:58:08 +02:00
Mr. Bubbles
f0d5640f5d Bump pyloadapi to v1.2.0 (#120218) 2024-06-22 21:22:13 -05:00
Paulus Schoutsen
bc45dcbad3 Add template config_entry_attr function (#119899)
* Template config_entry_attr function

* Complete test coverage

* Improve readability
2024-06-22 21:51:09 -04:00
tronikos
22467cc575 Avoid Opower time gaps (#117763)
* Avoid time gaps

* fix mypy

* async_get_time_zone
2024-06-22 21:33:44 -04:00
J. Nick Koston
ea0c93e3db Update uiprotect to 3.1.1 (#120173) 2024-06-22 18:11:48 -05:00
Shay Levy
57e615aa36 Don't log Shelly push update failures if there are no errors (#120189) 2024-06-23 00:36:58 +03:00
Scott K Logan
1ca187611d Bump aioraven to 0.6.0 (#120184) 2024-06-22 16:35:21 -05:00
G Johansson
b59e7ede9a Raise on incorrect suggested unit for sensor (#120180) 2024-06-22 22:05:45 +02:00
Matthias Alphart
08fae5d419 Add reconfigure flow to Fronius (#116132) 2024-06-22 21:12:32 +02:00
Franck Nijhof
135379adc3 Merge branch 'master' into dev 2024-06-22 21:10:17 +02:00
G Johansson
5ddda14e59 Remove deprecated (moved) helpers from helpers.__init__ (#120172) 2024-06-22 20:55:03 +02:00
G Johansson
f14e8b728c Remove YAML import from ping (#120176) 2024-06-22 20:39:32 +02:00
G Johansson
f06bd1b66f Remove YAML import from homeworks (#120171) 2024-06-22 20:05:34 +02:00
G Johansson
9b341f5b67 Don't record attributes in sql (#120170) 2024-06-22 19:42:55 +02:00
tronikos
725c309c0d Add image entity (screenshot) in Fully Kiosk Browser (#119622) 2024-06-22 19:37:18 +02:00
G Johansson
753ab08b5e Add capability to exclude all attributes from recording (#119725) 2024-06-22 19:30:28 +02:00
Pete Sage
3cf52a4767 Sonos add tests for media_player.play_media share link (#120169) 2024-06-22 19:13:37 +02:00
Bouke Haarsma
28eef00cce Huisbaasje rebranded to EnergyFlip (#120151)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-06-22 19:09:40 +02:00
Franck Nijhof
8e93116ed3 Update Home Assistant base image to 2024.06.1 (#120168) 2024-06-22 18:52:44 +02:00
Yazan Majadba
b2ade94d15 Add new Islamic prayer times calculation methods (#113763)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-22 18:52:18 +02:00
Thomas55555
1bd95d3596 Add service for Husqvarna Automower (#117269) 2024-06-22 18:40:13 +02:00
puddly
bd65afa207 Prioritize the correct CP2102N serial port on macOS (#116461) 2024-06-22 18:37:55 +02:00
Joakim Plate
4d982a9227 Add config flow to generic thermostat (#119930)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-22 18:26:39 +02:00
Etienne Soufflet
6a34e1b7ca Add tado climate swings and fan level (#117378) 2024-06-22 18:25:17 +02:00
G Johansson
cac55d0f47 Remove YAML import for lutron (#120159)
* Remove YAML import for lutron

* Restore constants
2024-06-22 18:23:35 +02:00
Christian Neumeier
6045c2bb08 Add diagnostics support to Zeversolar integration (#118245) 2024-06-22 17:34:48 +02:00
Indu Prakash
65a740f35e Fix airnow timezone look up (#120136) 2024-06-22 17:31:39 +02:00
r-xyz
cdc157de74 Add styled formatting option to Signal Messenger integration - Bump pysignalclirestapi to 0.3.24 (#117148) 2024-06-22 17:29:42 +02:00
Indu Prakash
abb88bcb8a Updated pynws to 1.8.2 (#120164) 2024-06-22 17:24:31 +02:00
Lucas Mindêllo de Andrade
3d7a47fb6b Tuya curtain robot stuck in open state (#118444) 2024-06-22 17:22:46 +02:00
Joakim Plate
b5a7fb1c33 Add valve entity to gardena (#120160)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-22 17:02:53 +02:00
Brent Petit
ed0e0eee71 Create auxHeatOnly switch in Ecobee integration (#116323)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-22 16:44:43 +02:00
Mr. Bubbles
856aa38539 Add feature to generate OTP token in One-Time Password (OTP) integration (#120055) 2024-06-22 16:43:04 +02:00
dougiteixeira
10edf85311 Update test_device_cleaning in Template (#120163) 2024-06-22 15:59:46 +02:00
dougiteixeira
02f0050819 Update test_device_cleaning in Derivative (#120162) 2024-06-22 15:54:35 +02:00
dougiteixeira
e9515b7584 Update test_device_cleaning in Utiltity Meter. (#120161) 2024-06-22 15:46:55 +02:00
dougiteixeira
61931d15cd Use the new device helpers in Threshold (#120158) 2024-06-22 15:38:58 +02:00
dougiteixeira
0b5c533669 Link the Trend helper entity to the source entity device (#119755) 2024-06-22 15:31:47 +02:00
dougiteixeira
30f3f1082f Use the new device helpers in Integral (#120157) 2024-06-22 15:30:38 +02:00
Mr. Bubbles
f2a4566eef Add re-auth flow to Bring integration (#115327) 2024-06-22 15:14:53 +02:00
tronikos
cea7231aab Add notify entities in Fully Kiosk Browser (#119371) 2024-06-22 15:04:52 +02:00
dougiteixeira
89b7bf2108 Add the ability to change the source entity of the Derivative helper (#119754) 2024-06-22 15:03:43 +02:00
SLaks
2dfa0a3c90 Add Jewish Calendar attributes for non-date sensors (#116252) 2024-06-22 14:30:19 +02:00
Joakim Plate
2ce510357d Mark ambilight as not available when off (#120155) 2024-06-22 13:42:20 +02:00
vmonkey
56d5e41b28 Add switches to Tuya dehumidifier: anion, filter_reset, and child_lock (#105200)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-06-22 13:41:45 +02:00
Dawid Pietryga
5cdd650023 Add satel integra binary switches unique_id (#118660) 2024-06-22 13:35:26 +02:00
Lenn
93e87997be Add sensors to Motionblinds BLE integration (#114226)
* Add sensors

* Add sensor.py to .coveragerc

* Move icons to icons.json

* Remove signal strength translation key

* Change native_value attribute name in entity description to initial_value

* Use str instead of enum for MotionConnectionType for options

* Add calibration options to entity description

* Fix icons

* Change translations of connection and calibration

* Move entity descriptions to __init__

* Use generic sensor class

* Use generic sensor class

* Update homeassistant/components/motionblinds_ble/strings.json

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/motionblinds_ble/sensor.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/motionblinds_ble/strings.json

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/motionblinds_ble/strings.json

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-22 13:25:03 +02:00
Matthew FitzGerald-Chamberlain
ea8d0ba2ce Add sensors for Aprilaire integration (#113194)
* Add sensors for Aprilaire integration

* Exclude from coverage

* Exclude from coverage

* Add comment

* Update homeassistant/components/aprilaire/sensor.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Code review updates

* Code review updates

* Code review updates

* Code review updates

* Remove temperature conversion

* Add suggested display precision

* Code review updates

* Merge fix

* Code review fixes

* Fix type errors

* Revert change

* Fix type errors

* Type errors

* Use common keys

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-22 13:20:33 +02:00
Jan-Philipp Benecke
1c2aa9a49b Add preview to Threshold config & option flow (#117181)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-06-22 13:19:57 +02:00
Jack Boswell
2b2c4e8262 Expose altitude for Starlink device tracker (#115508) 2024-06-22 12:56:28 +02:00
On Freund
6d0ae77288 Reload Risco on connection reset (#120150) 2024-06-22 12:55:42 +02:00
GraceGRD
6a19808718 Add transparent command to opentherm_gw (#116494) 2024-06-22 12:53:13 +02:00
dougiteixeira
6e32a96ff3 Add the ability to bind the template helper entity to a device (#117753) 2024-06-22 12:45:06 +02:00
David Symonds
f258034f9c Support todoist task description in new_task service (#116203) 2024-06-22 12:42:46 +02:00
cRemE-fReSh
f8c1710753 Add Tuya pool heating pumps (#118415)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-22 12:42:32 +02:00
Alexandre CUER
cb045a794d Add coordinator to emoncms (#120008) 2024-06-22 12:41:54 +02:00
Michael
1a962b415e Add support to consider device holiday and summer mode in AVM Fritz!Smarthome (#119862) 2024-06-22 12:40:03 +02:00
tronikos
ad1f0db5a4 Pass prompt as system_instruction for Gemini 1.5 models (#120147) 2024-06-22 12:35:48 +02:00
Jan Bouwhuis
57eb8dab6a Fix file yaml import fails on scan_interval (#120154) 2024-06-22 12:28:41 +02:00
mletenay
f676760ab1 Add GoodWe async_update support to number/select entities (#116739) 2024-06-22 12:27:32 +02:00
Franck Nijhof
0feead385a Add unique ID support to Flux (#120142) 2024-06-22 12:23:17 +02:00
tronikos
9002d85f9b Support playback of videos in Fully Kiosk Browser (#119496) 2024-06-22 12:05:39 +02:00
Michael Oborne
1bbfe7854f Add Tuya reverse_energy_total and total_power sensors (#114801)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-06-22 11:58:54 +02:00
Marcos A L M Macedo
03d8f4162e Add sensor total production energy for Tuya (#113565) 2024-06-22 11:58:36 +02:00
Bouke Haarsma
ed2ad5ceaa Increase precision of Huisbaasje gas readings (#120138) 2024-06-22 11:46:11 +02:00
Jan Gaedicke
5e71eb4e0d Add support for VESKA-micro-inverter (VK-800) to tuya integration (#115996) 2024-06-22 11:28:59 +02:00
Erwin Douna
6e15c06aa9 Melcloud add reconfigure flow (#115999) 2024-06-22 11:25:42 +02:00
Raman Gupta
d9e26077c6 Add discovery rule for a Z-Wave Basic CC sensor (#105134) 2024-06-22 11:22:32 +02:00
Matthias Alphart
77edc149ec Add distinct import / export entities to Fronius (#116535) 2024-06-22 11:12:21 +02:00
peteS-UK
3d9f053256 Update naming to reflect name change from Logitech Media Server to Lyrion Music Server (#119480)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-06-22 10:58:23 +02:00
Ryan Mattson
f1759982ad Lyric: Only pull priority rooms when its an LCC device (#116876) 2024-06-22 10:48:02 +02:00
Kevin Stillhammer
e0d8c4d726 Ensure kraken tracked pairs can be deselected (#117461) 2024-06-22 10:47:21 +02:00
Shai Ungar
03aba7e7ab Address late seventeentrack review (#116792) 2024-06-22 10:46:31 +02:00
Marc Mueller
a76fa9f3bf Update pytest warnings filter (#120143) 2024-06-22 10:45:18 +02:00
IceBotYT
7efd547962 Fix peco integration (#117165) 2024-06-22 10:37:37 +02:00
wittypluck
0a30032b96 Enable statistics for UniFi remaining power sensors (#120073)
Unifi: Add StateClass Measurement to all power sensors
2024-06-22 10:31:20 +02:00
Charles Garwood
f3d2ba7d8d Add additional checks for Enpower supported feature (#117107) 2024-06-22 09:27:17 +02:00
Lenn
32a94fc114 Motionblinds Bluetooth options (#120110) 2024-06-22 09:13:14 +02:00
Pete Sage
88039597e5 Sonos add tests for media_player.play_media library track (#120119) 2024-06-22 09:09:38 +02:00
Pete Sage
cbfb587f2d Sonos add tests for media_player.play_media favorite_item_id (#120120) 2024-06-22 09:08:12 +02:00
Marc Mueller
bd72637fec Extend component root imports in tests (1) (#120122) 2024-06-22 09:06:31 +02:00
Marc Mueller
2e3aeae520 Extend component root imports in tests (2) (#120123) 2024-06-22 09:06:05 +02:00
Brett Adams
cb78caf455 Platinum quality on Teslemetry (#115191) 2024-06-22 08:56:50 +02:00
J. Nick Koston
47587ee3fb Fix race against is_smart_detected in unifiprotect (#120133) 2024-06-21 17:11:28 -05:00
Marc Mueller
1aa9094d3d Adjust hddtemp test Telnet patch location (#120121) 2024-06-21 23:19:47 +02:00
J. Nick Koston
4d11dd6739 Add additional license plate test coverage to unifiprotect (#120125) 2024-06-21 15:16:33 -05:00
J. Nick Koston
c3ab72a1f9 Fix comparing end of event in unifiprotect (#120124) 2024-06-21 14:48:09 -05:00
Franck Nijhof
b315b566e5 2024.6.4 (#120114) 2024-06-21 20:31:04 +02:00
starkillerOG
8b4a5042bb Use UID instead of MAC or channel for unique_ID in Reolink (#119744) 2024-06-21 20:27:30 +02:00
Michael
d6be733287 Add config flow to Feedreader (#118047) 2024-06-21 20:23:47 +02:00
tronikos
ba7388546e Implement Android TV Remote browse media with apps and activity list (#117126) 2024-06-21 20:17:04 +02:00
Marc Hörsken
c13efa3664 Bump blinkpy to 0.23.0 (#119418) 2024-06-21 20:08:08 +02:00
Thomas Kistler
febcb33545 Update pydrawise to 2024.6.4 (#119868) 2024-06-21 20:00:47 +02:00
Franck Nijhof
e62268d5ea Revert "Make UniFi services handle unloaded config entry (#120028)"
This reverts commit 39f67afa64.
2024-06-21 19:59:25 +02:00
J. Nick Koston
f7e194b32c Adjust blocking I/O messages to provide developer help (#120113) 2024-06-21 12:55:22 -05:00
Ludovic BOUÉ
2ad5b1c3a6 Add Matter discovery schemas for BooleanState sensors (#117870)
Co-authored-by: Stefan Agner <stefan@agner.ch>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
2024-06-21 18:57:18 +02:00
Erwin Douna
cb563f25fa Add DSMR MQTT subscribe error handling (#118316)
Add eror handling
2024-06-21 18:52:39 +02:00
Franck Nijhof
c1dc6fd511 Bump version to 2024.6.4 2024-06-21 18:42:30 +02:00
Michael Hansen
92c12fdf0a Bump intents to 2024.6.21 (#120106) 2024-06-21 18:42:19 +02:00
Álvaro Fernández Rojas
53a21dcb6b Update AEMET-OpenData to v0.5.2 (#120065) 2024-06-21 18:42:17 +02:00
Jan Bouwhuis
59b2f4e56f Bump aioimaplib to 1.1.0 (#120045) 2024-06-21 18:42:13 +02:00
Glenn Waters
75a469f4d6 Bump env-canada to 0.6.3 (#120035)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-21 18:42:10 +02:00
Robert Svensson
39f67afa64 Make UniFi services handle unloaded config entry (#120028) 2024-06-21 18:41:33 +02:00
BestPig
5b322f1af5 Fix songpal crash for soundbars without sound modes (#119999)
Getting soundField on soundbar that doesn't support it crash raise an exception, so it make the whole components unavailable. As there is no simple way to know if soundField is supported, I just get all sound settings, and then pick soundField one if present. If not present, then return None to make it continue, it will just have to effect to display no sound mode and not able to select one (Exactly what we want).
2024-06-21 18:41:30 +02:00
Thomas Kistler
5edf480a15 Fix Hydrawise volume unit bug (#119988) 2024-06-21 18:41:27 +02:00
Erik Montnemery
96adf98625 Always create a new HomeAssistant object when falling back to recovery mode (#119969) 2024-06-21 18:41:24 +02:00
Bouwe Westerdijk
500ef94ad4 Bump plugwise to v0.37.4.1 (#119963)
* Bump plugwise to v0.37.4

* bump plugwise to v0.37.4.1
2024-06-21 18:41:21 +02:00
Artur Pragacz
a55e82366a Fix Onkyo zone volume (#119949) 2024-06-21 18:41:18 +02:00
G Johansson
c3607bd6d5 Bump python-holidays to 0.51 (#119918) 2024-06-21 18:41:15 +02:00
G Johansson
16314c5c7c Bump babel to 2.15.0 (#119006) 2024-06-21 18:41:10 +02:00
Jeef
91064697b5 Bump weatherflow4py to 0.2.21 (#119889) 2024-06-21 18:39:45 +02:00
Tsvi Mostovicz
5b1b137fd2 Bump hdate to 0.10.9 (#119887) 2024-06-21 18:39:42 +02:00
Brent Petit
e1225d3f56 Fix up ecobee windspeed unit (#119870) 2024-06-21 18:39:39 +02:00
J. Nick Koston
99d1de901e Bump aiozoneinfo to 0.2.0 (#119845) 2024-06-21 18:39:35 +02:00
AlCalzone
a1884ed821 Add discovery for Z-Wave Meter Reset (#119968) 2024-06-21 18:39:22 +02:00
Marc Mueller
08578147f5 Pin tenacity to 8.3.0 (#119815) 2024-06-21 18:36:10 +02:00
0bmay
0b4bbbffc8 Bump py-canary to v0.5.4 (#119793)
fix gathering data from Canary sensors
2024-06-21 18:36:06 +02:00
dubstomp
98aeb0b034 Add Kasa Dimmer to Matter TRANSITION_BLOCKLIST (#119751) 2024-06-21 18:36:03 +02:00
jjlawren
7a9537dcc9 Fix model import in Spotify (#119747)
* Always import HomeAssistantSpotifyData in spotify.media_browser

Relocate HomeAssistantSpotifyData to avoid circular import

* Fix moved import

* Rename module to 'models'

* Adjust docstring
2024-06-21 18:36:00 +02:00
Tsvi Mostovicz
8e63bd3ac0 Fix Jewish Calendar unique id migration (#119683)
* Implement correct passing fix

* Keep the test as is, as it simulates the current behavior

* Last minor change
2024-06-21 18:35:57 +02:00
Lode Smets
ddec6d04e1 Fix for Synology DSM shared images (#117695)
* Fix for shared images

* - FIX: Synology shared photos

* - changes after review

* Added test

* added test

* fix test
2024-06-21 18:35:48 +02:00
J. Nick Koston
5e375dbf38 Update uiprotect to 1.20.0 (#120108) 2024-06-21 18:26:14 +02:00
Michael Hansen
8aed04cd3c Bump intents to 2024.6.21 (#120106) 2024-06-21 18:19:52 +02:00
TheJulianJES
1bebf79e5c Fix Solarlog snapshot missing self-consumption sensor (#120111) 2024-06-21 17:53:05 +02:00
Robert Contreras
842763bd27 Add Home Connect binary_sensor unit tests (#115323) 2024-06-21 17:37:22 +02:00
Joost Lekkerkerker
2770811dda Add Knocki integration (#119140)
Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com>
2024-06-21 17:22:03 +02:00
Thomas55555
710e245819 Also test if command can be send successfully in Husqvarna Automower (#120107) 2024-06-21 17:02:20 +02:00
Matthias Alphart
c342c1e4d6 Device automation extra fields translation for ZHA (#119520)
Co-authored-by: Matthias Alphart <farmio@alphart.net>
Co-authored-by: puddly <32534428+puddly@users.noreply.github.com>
2024-06-21 17:00:55 +02:00
epenet
f03759295f Refactor Tibber realtime entity creation (#118031) 2024-06-21 16:52:09 +02:00
Marcel van der Veldt
4110f4f393 Fix Matter entity names (#120038) 2024-06-21 16:42:22 +02:00
Thomas Kistler
180c244a78 Change Ambient Network timestamp updates (#116941) 2024-06-21 16:36:53 +02:00
Álvaro Fernández Rojas
f353b3fa54 Add Airzone Cloud air/floor demand binary sensors (#120103) 2024-06-21 16:22:05 +02:00
dontinelli
97a025ccc1 Add sensor for self-consumption in solarlog (#119885) 2024-06-21 16:16:09 +02:00
tronikos
b931c3ffcf Include required name in reauth_confirm of Opower (#119627) 2024-06-21 16:14:55 +02:00
Robert Resch
db826c9727 Bum uv to 0.2.13 (#120101) 2024-06-21 16:10:57 +02:00
Ethem Cem Özkan
7f5a71d281 Tado water heater code quality changes (#119811)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-06-21 16:01:57 +02:00
Álvaro Fernández Rojas
289a54d632 Update aioairzone-cloud to v0.5.3 (#120100) 2024-06-21 15:59:57 +02:00
Mr. Bubbles
7fa74fcb07 Refactor sensor platform of Pyload integration (#119716) 2024-06-21 15:57:36 +02:00
Erik Montnemery
a10f9a5f6d Allow opting out of warnings when removing unknown frontend panel (#119824) 2024-06-21 15:56:22 +02:00
jvmahon
12f812d6da Add number platform to Matter integration (#119770)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
2024-06-21 15:53:50 +02:00
epenet
648ef94888 Improve type hints in core helper tests (#120096) 2024-06-21 15:43:27 +02:00
Thomas55555
4aecd23f1d Fix Husqvarna Automower schedule switch turning back on (#117692) 2024-06-21 15:27:39 +02:00
Josef Zweck
e149aa6b2e Add backflush sensor to lamarzocco (#119888)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-21 15:27:22 +02:00
tronikos
6caf614efd Add camera entity in Fully Kiosk Browser (#119483) 2024-06-21 15:08:32 +02:00
Erwin Douna
7f20173f6d MelCloud add diagnostics platform (#115962) 2024-06-21 15:07:43 +02:00
Marcel van der Veldt
bad5eaf329 Add entity ids to grouped hue light (#113053) 2024-06-21 15:04:42 +02:00
karwosts
7ba1e4446c Fix for in climate hvac_mode_changed trigger (#116455) 2024-06-21 14:53:28 +02:00
Lenn
af59072203 Bump motionblindsble to 0.1.0 (#120093) 2024-06-21 14:50:37 +02:00
dougiteixeira
a8ba22f6bb Add device linking and stale device link clean up helpers (#119761) 2024-06-21 14:46:39 +02:00
epenet
e2a34d209f Improve type hints in Config entry oauth2 tests (#120090) 2024-06-21 14:44:28 +02:00
Marc Mueller
5c2f78a4b9 Fix solarlog client close (#120092) 2024-06-21 14:35:45 +02:00
Mr. Bubbles
905c1c5700 Fix removed exception InternalServerError in ista EcoTrend integration (#120089) 2024-06-21 13:51:46 +02:00
Brent Petit
901317ec39 Remove rstrip from ecobee binary_sensor __init__ (#118062) 2024-06-21 13:40:26 +02:00
starkillerOG
225e90c99e Add playback of autotrack lens to Reolink (#119829)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-21 13:38:51 +02:00
dontinelli
a0f81cb401 Add solarlog reconfigure flow (#119913) 2024-06-21 13:35:22 +02:00
Tobias Schmitt
988148d385 Add ZHA cod.m coordinator discovery (#115471) 2024-06-21 13:33:53 +02:00
Aidan Timson
7d86921d09 Reduce line length for unique id (#120086) 2024-06-21 13:30:21 +02:00
neturmel
c9ddabaead Support tuya diivoo dual zone irrigationkit (ggq) (#115090)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-21 13:28:20 +02:00
Erwin Douna
b186b3536f Add Home Connect child lock (#118544) 2024-06-21 13:26:37 +02:00
Mr. Bubbles
f5f2e04126 Add reauth flow to ista EcoTrend integration (#118955) 2024-06-21 13:25:24 +02:00
Michael Hansen
18767154df Generate and keep conversation id for Wyoming satellite (#118835) 2024-06-21 13:24:53 +02:00
TheJulianJES
955685e116 Pin codecov-cli to v0.6.0 (#120084) 2024-06-21 13:22:32 +02:00
Jan Čermák
4707108146 Samsung AC Wind Mode (#119750) 2024-06-21 13:19:42 +02:00
Marc Mueller
f0452e9ba0 Update mypy dev 1.11.0a8 (#120032) 2024-06-21 13:15:18 +02:00
Aidan Timson
01d4629a2b Move coordinator store to entry runtime data for Azure DevOps (#119408)
Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com>
2024-06-21 13:14:32 +02:00
c0ffeeca7
7bfa1e4729 System information: apply sentence-style capitalization (#119893) 2024-06-21 12:59:57 +02:00
Robert Svensson
ed7a888c07 Add one UniFi sensor test to validate entity attributes (#119914) 2024-06-21 12:59:31 +02:00
Rami Mosleh
e1a6ac59e1 Move transmission services registration to async_setup (#119593)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-06-21 12:58:33 +02:00
G Johansson
127af149ca Remove legacy template hass config option (#119925) 2024-06-21 12:53:55 +02:00
Joakim Plate
6420837d58 Calculate device class as soon as it is known in integral (#119940) 2024-06-21 12:47:57 +02:00
dontinelli
af9f4f310b Add additional tests for solarlog (#119928) 2024-06-21 12:44:25 +02:00
epenet
904cf26d31 Add MockToggleEntity type hints in tests (#120075) 2024-06-21 12:32:03 +02:00
Joost Lekkerkerker
fa1e4a225d Bump aiomealie to 0.4.0 (#120076) 2024-06-21 12:27:33 +02:00
J. Nick Koston
324f07378a Bump uiprotect to 1.19.3 (#120079) 2024-06-21 05:25:28 -05:00
G Johansson
1c1d5a8d9b Add unrecorded attributes in dnsip (#119726)
* Add unrecorded attributes in dnsip

* Fix names
2024-06-21 12:25:03 +02:00
Igor Santos
a52a2383c5 Tuya's light POS actually means "opposite state" (#119948) 2024-06-21 12:22:33 +02:00
Evgeny
0aacc67c38 OpenWeatherMap remove obsolete forecast sensors (#119922) 2024-06-21 12:21:57 +02:00
Robert Svensson
6ddc872655 Improve UniFi device tracker client tests (#119982) 2024-06-21 12:20:13 +02:00
Max Gross
2157d0c05e Fix unit of measurement for Comed Hourly Pricing (#115594)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-21 12:16:13 +02:00
Mr. Bubbles
79bc6fc1a8 Bump pyecotrend-ista to 3.3.1 (#120037) 2024-06-21 12:14:44 +02:00
epenet
5bbc4c80c5 Adjust CI job for Check pylint on tests (#120080)
* Adjust Check pylint on tests CI job

* Apply suggestion

Co-authored-by: Robert Resch <robert@resch.dev>

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-21 12:12:15 +02:00
J. Nick Koston
15e52de7e9 Avoid constructing unifiprotect enabled callable when unused (#120074) 2024-06-21 11:58:45 +02:00
starkillerOG
c8ce935ec7 Check Reolink IPC channels for firmware repair issue (#119241)
* Add IPC channels to firmware repair issue

* fix tests

* fix typo
2024-06-21 11:57:48 +02:00
Brett Adams
ecd61c6b6d Add entities with no data in Tessie (#119550) 2024-06-21 11:57:19 +02:00
epenet
55134e23ea Add type hints in automation tests (#120077) 2024-06-21 11:56:52 +02:00
G Johansson
5cdafba667 Make attribute names in dnsip lowercase (for translation) (#119727) 2024-06-21 11:43:53 +02:00
Brett Adams
fde7ddfa71 Fix charge behavior in Tessie (#119546) 2024-06-21 11:30:57 +02:00
Robert Hillis
64cef6e082 Store runtime data inside the config entry in Litter Robot (#119547) 2024-06-21 11:28:44 +02:00
G Johansson
9c5879656c Remove legacy list event calendar service (#118663) 2024-06-21 11:18:51 +02:00
Joost Lekkerkerker
d21908a0e4 Add event entity to Nanoleaf (#120013)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-06-21 11:16:00 +02:00
epenet
7af79ba013 Add MockModule type hints in tests (#120007) 2024-06-21 11:11:48 +02:00
dontinelli
0dd5391cd7 Add Siemes and Millisiemens as additional units of conductivity and enable conversion between conductivity units (#118728) 2024-06-21 11:10:15 +02:00
Mr. Bubbles
818750dfd1 Add icons to One-Time Password (OTP) (#120066) 2024-06-21 11:07:45 +02:00
Erik Montnemery
d2a5683fa0 Raise repair issues when automations can't be set up (#120010) 2024-06-21 11:07:30 +02:00
Joost Lekkerkerker
5138c3de0a Add Mealie integration (#119678) 2024-06-21 11:04:55 +02:00
epenet
dc6c1f4e87 Add MockPlatform type hints in tests (#120012)
* Add MockPlatform type hints in tests

* Remove useless code

* Improve

* Revert "Improve"

This reverts commit 9ad04f925514af46a7cd64f94a518fc093da825c.
2024-06-21 11:04:15 +02:00
Joost Lekkerkerker
53022df8a4 Add sensor tests for APSystems (#117512) 2024-06-21 11:01:42 +02:00
epenet
54d8ce5ca9 Revert "Temporary pin CI to Python 3.12.3" (#119454) 2024-06-21 11:00:07 +02:00
Robert Svensson
94800cb11e UniFi temp fix to handle runtime data (#120031)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-06-21 10:55:21 +02:00
Thomas Kistler
aba5bb08dd Add Ambient Weather brand (#115898) 2024-06-21 10:51:46 +02:00
Joost Lekkerkerker
a6724db01b Fix calculation in Refoss (#120069) 2024-06-21 10:42:25 +02:00
Glenn Waters
3b6189a432 Bump env-canada to 0.6.3 (#120035)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-21 10:37:51 +02:00
Robert Svensson
6fb5a12ef1 Make UniFi services handle unloaded config entry (#120028) 2024-06-21 10:36:52 +02:00
Álvaro Fernández Rojas
f30b20b4df Update AEMET-OpenData to v0.5.2 (#120065) 2024-06-21 10:34:39 +02:00
J. Nick Koston
7375764301 Bump anyio to 4.4.0 (#120061) 2024-06-21 10:31:37 +02:00
Mr. Bubbles
4515eedea9 Add unique_id to One-Time Password (OTP) (#120050) 2024-06-21 10:28:52 +02:00
Álvaro Fernández Rojas
53d3475b1d Update aioairzone to v0.7.7 (#120067) 2024-06-21 10:28:11 +02:00
Marc Mueller
e5846fdffd Update pydantic to 1.10.17 (#119430) 2024-06-21 10:16:36 +02:00
Raman Gupta
3a8b0c3573 Bump zwave-js-server-python to 0.57.0 (#120047) 2024-06-21 09:29:10 +02:00
Mr. Bubbles
f770fa0de0 Fix translation key in config flow of One-Time Password (OTP) integration (#120053) 2024-06-21 09:22:55 +02:00
Thomas Kistler
4aa7a9faee Fix Hydrawise volume unit bug (#119988) 2024-06-21 09:07:14 +02:00
dependabot[bot]
b3722d60cb Bump actions/checkout from 4.1.6 to 4.1.7 (#120063)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-21 08:55:06 +02:00
Jan Bouwhuis
2add53e334 Bump aioimaplib to 1.1.0 (#120045) 2024-06-21 08:47:50 +02:00
Markus Jacobsen
1962759953 Add Bang olufsen init testing (#119834) 2024-06-21 07:35:38 +01:00
RJPoelstra
353e4865e1 Make preset list indicate whether the current mount position matches a preset in Vogel's Motionmount (#118731) 2024-06-21 06:22:12 +01:00
J. Nick Koston
4de8cca911 Disable generic unifiprotect object sensors by default (#120059) 2024-06-20 22:12:31 -05:00
J. Nick Koston
68462b014c Fix unifiprotect smart detection when end is set (#120027) 2024-06-20 22:03:07 -05:00
Leo Shen
ecadaf314d Add support for Switchbot Lock Pro (#119326)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-20 19:26:43 -05:00
J. Nick Koston
fb25902de9 Cleanup unifiprotect subscriptions logic (#120049) 2024-06-20 18:35:35 -05:00
J. Nick Koston
ee85c0e44c Bump uiprotect to 1.19.2 (#120048) 2024-06-20 18:34:57 -05:00
Robert Svensson
87e405396b Bump aiounifi to v79 (#120033) 2024-06-20 20:12:40 +02:00
epenet
325a49e8ff Enable pylint on tests (#119279)
* Enable pylint on tests

* Remove jobs==1
2024-06-20 16:02:49 +02:00
BestPig
7c5fcec062 Fix songpal crash for soundbars without sound modes (#119999)
Getting soundField on soundbar that doesn't support it crash raise an exception, so it make the whole components unavailable. As there is no simple way to know if soundField is supported, I just get all sound settings, and then pick soundField one if present. If not present, then return None to make it continue, it will just have to effect to display no sound mode and not able to select one (Exactly what we want).
2024-06-20 13:06:30 +02:00
mikosoft83
99cae16b75 Change meteoalarm scan interval (#119194) 2024-06-20 12:59:30 +02:00
epenet
1235338f1b Fix hass-component-root-import warnings in otp tests (#120019) 2024-06-20 12:39:26 +02:00
Joost Lekkerkerker
e89b9b0093 Small clean up for Refoss sensor platform (#120015) 2024-06-20 11:49:03 +02:00
Joost Lekkerkerker
4d7a857555 Use runtimedata in nanoleaf (#120009)
* Use runtimedata in nanoleaf

* Update homeassistant/components/nanoleaf/light.py

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-06-20 11:08:01 +02:00
ashionky
3224224bf8 Add Sensor for Refoss Integration (#116965)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-20 10:29:37 +02:00
Mr. Bubbles
1eb8b5a27c Add config flow to One-Time Password (OTP) integration (#118493) 2024-06-20 10:03:29 +02:00
Jan Bouwhuis
60ba80a28d Only (re)subscribe MQTT topics using the debouncer (#119995)
* Only (re)subscribe using the debouncer

* Update test

* Fix test

* Reset mock
2024-06-19 23:57:18 +02:00
Leo Shen
0053c92d2b Update PySwitchbot to 0.48.0 (#119998) 2024-06-19 16:56:20 -05:00
Pete Sage
ebbb63cd08 Fix Sonos album images with special characters not displaying in media browser UI (#118249)
* initial commit

* initial commit

* simplify tests

* rename symbol

* original_uri -> original_url

* change symbol name

---------

Co-authored-by: Dave T <17680170+davet2001@users.noreply.github.com>
2024-06-19 22:38:49 +01:00
G Johansson
e6967298ec Remove circuit integration (#119921) 2024-06-19 23:14:43 +02:00
Erik Montnemery
f32cb8545c Use MockHAClientWebSocket.send_json_auto_id in blueprint tests (#119956) 2024-06-19 23:07:56 +02:00
Artur Pragacz
42b62ec427 Fix Onkyo zone volume (#119949) 2024-06-19 22:48:34 +02:00
Robert Resch
bae008b0e2 Remove legacy_api_password auth provider (#119976) 2024-06-19 22:46:30 +02:00
Erik Montnemery
7d14b9c5c8 Always create a new HomeAssistant object when falling back to recovery mode (#119969) 2024-06-19 22:45:59 +02:00
Alexandre CUER
6dc680d251 Use aiohttp.ClientSession in EmoncmsClient (#119989) 2024-06-19 22:41:32 +02:00
Robert Svensson
49349de74e Unifi break out switch availability test to separate test (#119990) 2024-06-19 22:40:13 +02:00
Joost Lekkerkerker
52bf3a028f Move Nanoleaf event canceling (#119909)
* Move Nanoleaf event canceling

* Fix

* Fix
2024-06-19 22:16:16 +02:00
J. Nick Koston
d9c7887bbf Update yalexs to 6.4.0 (#119987) 2024-06-19 14:11:36 -05:00
Pete Sage
528422d238 Address Hydrawise review (#119965)
adjust formatting
2024-06-19 20:37:26 +02:00
Franck Nijhof
6c80f865f5 Remove deprecated WLED binary sensor platform (#119984) 2024-06-19 20:29:40 +02:00
Erik Montnemery
5ee418724b Tweak type annotations of energy websocket handlers (#119957) 2024-06-19 20:01:02 +02:00
epenet
f0dc39a903 Improve typing in core tests (#119958)
Add missing return values in core tests
2024-06-19 19:58:07 +02:00
G Johansson
8e3b58dc28 Clean weather tests (#119916) 2024-06-19 19:55:20 +02:00
Jan Bouwhuis
8ad63a0020 Fix flaky todoist test (#119954)
Fix flakey todoist test
2024-06-19 20:43:05 +03:00
Robert Svensson
970836da0c Clean up config option tests in UniFi device tracker tests (#119978) 2024-06-19 19:42:23 +02:00
Joost Lekkerkerker
6fa54229fe Bump airgradient to 0.6.0 (#119962)
* Bump airgradient to 0.6.0

* Bump airgradient to 0.6.0

* Bump airgradient to 0.6.0

* Bump airgradient to 0.6.0
2024-06-19 20:38:57 +03:00
Bouwe Westerdijk
e1f244e1c2 Bump plugwise to v0.37.4.1 (#119963)
* Bump plugwise to v0.37.4

* bump plugwise to v0.37.4.1
2024-06-19 19:23:14 +02:00
Tsvi Mostovicz
9371277b85 Bump hdate to 0.10.9 (#119887) 2024-06-19 09:21:43 -05:00
J. Nick Koston
87e52bb660 Small cleanups to august (#119950) 2024-06-19 09:21:04 -05:00
epenet
52bc006a72 Update default pylint.importStrategy in dev container (#119900) 2024-06-19 11:27:01 +02:00
Jan Bouwhuis
854b6c99fe Address review on comment group registry maintenance (#119952)
Address late review on comment group registry maintenance
2024-06-19 10:51:56 +02:00
J. Nick Koston
a642454e6f Bump sqlalchemy to 2.0.31 (#119951) 2024-06-19 08:09:04 +02:00
J. Nick Koston
5ae13c2ae2 Make use_device_name a cached_property in the base entity class (#119758)
There is a small risk that _attr_name or entity_description
would not be set before state was first written, but that
would likely be a bug.
2024-06-18 21:52:36 -04:00
J. Nick Koston
6a3778c48e Deprecate register_static_path in favor of async_register_static_paths (#119895)
* Deprecate register_static_path in favor of async_register_static_path

`hass.http.register_static_path` is deprecated because it does blocking I/O in the event loop, instead call `await hass.http.async_register_static_path([StaticPathConfig(url_path, path, cache_headers)])`

The arguments to `async_register_static_path` are the same as `register_static_path` except they are wrapped in the `StaticPathConfig` dataclass and an iterable of them is accepted to allow registering multiple paths at once to avoid multiple executor jobs.

* add date

* spacing
2024-06-18 21:51:24 -04:00
J. Nick Koston
b11801df50 Reduce code needed to set august unique ids (#119942)
* Reduce code needed to set august unique ids

Set the unique ids in the base class since they always
use the same format

* Reduce code needed to set august unique ids

Set the unique ids in the base class since they always
use the same format
2024-06-18 21:43:06 -04:00
J. Nick Koston
f88b24f8a4 Combine statements that return the same result in august binary_sensor (#119944) 2024-06-18 21:40:21 -04:00
J. Nick Koston
c686eda305 Reduce duplicate code in baf for entities with descriptions (#119945)
* Reduce duplicate code in baf for entities with descriptions

* Reduce duplicate code in baf for entities with descriptions

* no cover

* no cover
2024-06-18 21:39:32 -04:00
Joakim Plate
ef51fc0d97 Remove code slated for deletion in integral (#119935)
* Remove code slated for deletion in integral
2024-06-19 02:25:11 +02:00
J. Nick Koston
60e64d14af Bump yalexs to 6.3.0 to move camera logic to the lib (#119941) 2024-06-18 18:52:41 -05:00
J. Nick Koston
8f3dcd6557 Cleanup august dataclasses (#119938) 2024-06-18 18:21:19 -05:00
J. Nick Koston
025d861e67 Update yalexs to 6.1.0 (#119910) 2024-06-18 17:36:07 -05:00
J. Nick Koston
39e5e517b0 Small cleanups to august (#119931) 2024-06-18 17:35:55 -05:00
J. Nick Koston
98140e0171 Reduce duplicate code in august to create entities (#119934) 2024-06-18 17:35:38 -05:00
Maciej Bieniek
54f8b5afdf Add pulse counter frequency sensors to Shelly (#119898)
* Add pulse counter frequency sensors

* Cleaning

---------

Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
2024-06-18 23:08:30 +02:00
J. Nick Koston
3d45ced02e Cleanup code to add august sensors (#119929) 2024-06-18 16:03:46 -05:00
J. Nick Koston
b8cafe7e5e Small cleanups to august (#119912) 2024-06-18 15:43:16 -05:00
Joost Lekkerkerker
8a38424c24 Add more airgradient configuration entities (#119191) 2024-06-18 22:34:11 +02:00
Jeef
f0026d171e Bump weatherflow4py to 0.2.21 (#119889) 2024-06-18 15:31:59 -05:00
Franck Nijhof
b419ca2241 Register Z-Wave services on integration setup (#119924) 2024-06-18 22:27:52 +02:00
G Johansson
fe8805de6d Remove deprecated blink refresh service (#119919)
* Remove deprecated blink refresh service

* Remove string

* Fix tests
2024-06-18 22:26:44 +02:00
Shay Levy
f61347719f Allow removal of a Switcher device (#119927)
Allow removal of Switcher device
2024-06-18 23:26:29 +03:00
G Johansson
08864959ee Remove YAML import for Suez Water (#119923)
Remove YAML import for suez water
2024-06-18 22:26:10 +02:00
HarvsG
adcd0cc2a4 DNS IP custom ports for IPv4 (#113993)
* squash DNS IP enable port

* linting

* fix config entries in tests.

* fix more config entries

* fix parameter order

* Add defaults for legacy config entries

* test legacy config are not broken

* test driven migration

* define versions for future proofing

* remove defaults as should be covered by migrations in the future

* adds config migration

* spacing

* Review: remove unnecessary statements

Co-authored-by: G Johansson <goran.johansson@shiftit.se>

* Apply suggestions from code review

Co-authored-by: G Johansson <goran.johansson@shiftit.se>

* make default ports the same

* test migration from future error

* linting

* Small tweaks

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-06-18 22:24:36 +02:00
G Johansson
9723b97f4b Bump python-holidays to 0.51 (#119918) 2024-06-18 22:05:11 +02:00
Thomas55555
0a781b8fa2 Add button platform to Husqvarna Automower (#119856)
* Add button platform to Husqvarna Automower

* test coverage

* adapt to library changes

* Address review
2024-06-18 21:24:09 +02:00
Joost Lekkerkerker
484a24512c Bump airgradient to 0.5.0 (#119911) 2024-06-18 20:51:54 +02:00
MallocArray
be4db90c91 Update airgradient names to NOx index and VOC index (#119152)
* Update names to NOx index and VOC index

* Fix snapshots

* Fix snapshots

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2024-06-18 20:31:33 +02:00
epenet
ec9f2f698c Add type hints to MockGroup and MockUser in tests (#119897) 2024-06-18 13:11:10 -05:00
Jan Bouwhuis
66faeb28d7 Fix late group platform registration (#119789)
* Fix late group platform registration

* use a callback instead

* Run thread safe

* Not working domain filter

* Also update if a group has nested group's

* Only update if the siingle state type key could change

* Avoid redundant regisister hooks

* Use set, add comment

* Revert changes

* Keep callback cleanup const

* Cleanup after dependencies

* Preimport and cleanup excluded domains

* Revert test changes as we assume early set up now

* Migrate alarm_control_panel

* Migrate climate

* Migrate cover

* Migrate device_tracker

* Migrate lock

* Migrate media_player

* Migrate person

* Migrate plant

* Migrate vacuum

* Migrate water_heater

* Remove water_heater group_pre_import

* Use Platform enum if possible

* Also use platform enum for excluded domains

* Set registry to self._registry

* move deregistering call back hook to async_added_to_hass

* Add comment

* Do no pass mutable reference to EXCLUDED_DOMAINS

* Remove unneeded type hint
2024-06-18 20:01:16 +02:00
Joost Lekkerkerker
edb391a0bd Extract coordinator to separate module in Nanoleaf (#119896)
* Extract coordinator to separate module in Nanoleaf

* Extract coordinator to separate module in Nanoleaf

* Extract coordinator to separate module in Nanoleaf
2024-06-18 19:50:07 +02:00
J. Nick Koston
419dcbf9a1 Fix typo in KEY_ALLOW_CONFIGRED_CORS (#119905) 2024-06-18 12:44:27 -05:00
J. Nick Koston
d2faaa1531 Remove useless function get_ufp_event from unifiprotect (#119906) 2024-06-18 12:29:26 -05:00
J. Nick Koston
407df2aedf Small cleanup to unifiprotect entity descriptions (#119904) 2024-06-18 12:08:22 -05:00
Joost Lekkerkerker
e0de436a58 Add myself as codeowner for Nanoleaf (#119892) 2024-06-18 12:03:30 -05:00
Erik Montnemery
7940303149 Add WS command frontend/subscribe_extra_js (#119833)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-18 16:18:42 +02:00
Erik Montnemery
0ca3f25c57 Add WS command for subscribing to storage collection changes (#119481) 2024-06-18 16:15:42 +02:00
Paulus Schoutsen
3c08a02ecf Update cover intent response (#119756)
* Update cover response

* Fix intent test
2024-06-18 15:54:08 +02:00
Josef Zweck
25b3fe6b64 Bump lmcloud to 1.1.13 (#119880)
* bump lmcloud to 1.1.12

* update diagnostics

* bump to 1.1.13
2024-06-18 14:49:04 +02:00
Markus Jacobsen
3046329f4f Add Tidal play_media support to Bang & Olufsen (#119838)
Add tidal play_media support
2024-06-18 13:00:27 +01:00
epenet
041746a50b Improve type hints in data_entry_flow tests (#119877) 2024-06-18 13:25:28 +02:00
Robert Hillis
6b27e9a745 Store runtime data inside the config entry in Deluge (#119549) 2024-06-18 13:23:11 +02:00
epenet
a1a8d38181 Move fixtures to decorators in netgear_lte tests (#119882) 2024-06-18 12:40:06 +02:00
epenet
f5fd389512 Fix hass-component-root-import warning in esphome tests (#119883) 2024-06-18 12:39:36 +02:00
Robert Hillis
dc388c76f9 Store runtime data inside the config entry in Steam (#119881) 2024-06-18 12:28:43 +02:00
Joost Lekkerkerker
9128dc198a Centralize lidarr device creation (#119822) 2024-06-18 12:10:11 +02:00
epenet
0ff0022877 Ignore use-implicit-booleaness-not-comparison pylint warnings in tests (#119876) 2024-06-18 12:00:24 +02:00
Franck Nijhof
fa1e23e905 Merge branch 'master' into dev 2024-06-18 11:49:25 +02:00
Thomas Kistler
2906fca40c Update pydrawise to 2024.6.4 (#119868) 2024-06-18 10:26:31 +02:00
Jan Bouwhuis
6eb9d1e01d Gracefully disconnect MQTT entry if entry is reloaded (#119753) 2024-06-18 09:29:22 +02:00
Robert Hillis
67223b2a2d Store runtime data inside the config entry in Lidarr (#119548) 2024-06-18 09:13:24 +02:00
Robert Hillis
d5d906e148 Add update coordinator to Netgear LTE (#115474) 2024-06-18 09:12:02 +02:00
dontinelli
2555827030 Replace Solarlog unmaintained library (#117484)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-18 09:06:22 +02:00
J. Nick Koston
faa55de538 Fix blocking I/O in the event loop when registering static paths (#119629) 2024-06-18 08:18:31 +02:00
Paulus Schoutsen
eb89ce47ea Inline primary integration (#119860) 2024-06-18 08:08:08 +02:00
Brent Petit
4be3b53143 Fix up ecobee windspeed unit (#119870) 2024-06-18 07:58:00 +02:00
Thomas55555
dc553a81a1 Bump aioautomower to 2024.6.1 (#119871) 2024-06-18 07:50:05 +02:00
Jesse Hills
f8711dbfbf Add esphome native device update entities (#119339)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-18 16:31:50 +12:00
Robert Hillis
faf2a447a4 Store runtime data inside the config entry in Sense (#119740) 2024-06-17 20:43:45 -05:00
Robert Hillis
ac51851664 Handle general update failure in Sense (#119739) 2024-06-17 19:53:46 -05:00
J. Nick Koston
a876a55d2f Bump uiprotect to 0.19.0 (#119863) 2024-06-17 17:08:43 -05:00
Christoph
7410db08fb Bump xiaomi_ble to 0.30.0 (#119859)
* bump xiaome_ble to 0.30.0

bump xiaomi_ble to 0.30.0

* bump xiaome_ble to 0.30.0

bump xiaomi_ble to 0.30.0

* bump xiaome_ble to 0.30.0

bump xiaomi_ble to 0.30.0
2024-06-17 23:57:47 +02:00
Maciej Bieniek
f5dfefb3a6 Use the humidity value in Shelly Wall Display climate entity (#119830)
* Use the humidity value with the climate entity if available

* Update tests

* Use walrus

---------

Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
2024-06-17 23:17:05 +03:00
G Johansson
b6b6248713 Remove legacy get forecast service from Weather (#118664)
* Remove legacy get forecast service from Weather

* Fix tests

* Fix test

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-17 21:13:28 +02:00
J. Nick Koston
75e8fc0f9c Fix homekit_controller haa fixture (#119855) 2024-06-17 13:34:05 -05:00
Robert Hillis
adacdd3a9f Run Radarr movie coordinator first refresh in background (#119827) 2024-06-17 19:18:59 +02:00
Joost Lekkerkerker
e5eef7c6dd Fix Dremel 3D printer tests (#119853) 2024-06-17 19:17:52 +02:00
J. Nick Koston
2560d7aeda Bump uiprotect to 1.18.1 (#119848)
changelog: https://github.com/uilibs/uiprotect/compare/v1.17.0...v1.18.1
2024-06-17 19:17:36 +02:00
Maciej Bieniek
87c1d5a6a7 Remove the switch entity for Shelly Gas Valve (#119817)
Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
2024-06-17 19:17:06 +02:00
J. Nick Koston
57308599cd Bump aiozoneinfo to 0.2.0 (#119845) 2024-06-17 19:05:44 +02:00
jvmahon
71a9ba25dc Use "Button" label to name Matter event (#119768) 2024-06-17 15:30:59 +02:00
Erik Montnemery
8af5748716 Add frontend.remove_extra_js_url (#119831) 2024-06-17 15:15:00 +02:00
Erik Montnemery
c0a3b507c0 Add tests of frontend.add_extra_js_url (#119826) 2024-06-17 14:39:07 +02:00
Alexandre CUER
442554c223 Migrate Emoncms to external library (#119772)
* Migrate Emoncms to external library

https://github.com/Open-Building-Management/pyemoncms

* Remove the throttle decorator

* Remove MIN_TIME_BETWEEN_UPDATES as not used
2024-06-17 13:59:47 +02:00
Robert Hillis
dcca749d50 Store runtime data inside the config entry in Radarr (#119749)
* Store runtime data inside the config entry in Radarr

* move entry typing outside constructor
2024-06-17 13:47:49 +02:00
Joost Lekkerkerker
9f46b582d3 Avoid touching internals in Radarr tests (#119821)
* Avoid touching internals in Radarr tests

* Fix

* Fix
2024-06-17 13:33:36 +02:00
Joost Lekkerkerker
cfbc854c84 Remove deprecated import swiss public transport import flow (#119813) 2024-06-17 13:24:10 +02:00
starkillerOG
d34be0e8fa Bump reolink-aio to 0.9.3 (#119820) 2024-06-17 12:58:58 +02:00
Tsvi Mostovicz
369f9772f2 Fix Jewish Calendar unique id migration (#119683)
* Implement correct passing fix

* Keep the test as is, as it simulates the current behavior

* Last minor change
2024-06-17 12:37:30 +02:00
Erik Montnemery
e0378f79a4 Remove create_list from StorageCollectionWebsocket.async_setup (#119508) 2024-06-17 12:16:36 +02:00
dubstomp
0ae4903686 Add Kasa Dimmer to Matter TRANSITION_BLOCKLIST (#119751) 2024-06-17 11:31:18 +02:00
Marc Mueller
1d873115f3 Pin tenacity to 8.3.0 (#119815) 2024-06-17 11:17:35 +02:00
epenet
4e3cc43343 Fix consider-using-tuple warning in tplink_omada tests (#119814)
Fix consider-using-tuple in tplink_omada tests
2024-06-17 11:13:34 +02:00
azerty9971
75fa0b91d8 Add support for Tuya energy data for WKCZ devices (#119635)
Add support for energy sensors for  WKCZ devices
2024-06-17 10:59:36 +02:00
Marlon
496338fa4e Add number input for apsystems (#118825)
* Add number input for apsystems

* Exclude number from apsystems from coverage

* Remove unnecessary int-float conversion in apsystems number

* Remove unnecessary int-float conversion in apsystems number and redundant and single use variables

* Add translation for apsystems number
2024-06-17 10:31:21 +02:00
G Johansson
8556f3e7c8 Remove deprecated speedtest service from Fast.com (#119780)
* Remove deprecated speedtest service from Fast.com

* Remove not needed tests
2024-06-17 10:04:46 +02:00
G Johansson
d1d21811fa Remove YAML import from streamlabswater (#119783) 2024-06-17 10:04:18 +02:00
0bmay
09b49ee505 Bump py-canary to v0.5.4 (#119793)
fix gathering data from Canary sensors
2024-06-17 10:02:42 +02:00
G Johansson
75b0acf6b6 Remove YAML import from System monitor (#119782) 2024-06-17 09:52:25 +02:00
J. Nick Koston
b1c5845d35 Bump uiprotect to 1.17.0 (#119802)
* Bump uiprotect to 1.16.0

changelog: https://github.com/uilibs/uiprotect/compare/v1.12.1...v1.16.0

* one more bump
2024-06-17 09:51:28 +02:00
MarkGodwin
f09063d706 Add device trackers to tplink_omada (#115601)
* Add device trackers to tplink_omada

* tplink_omada - Remove trackers and options flow

* Addressed code review feedback

* Run linter

* Use entity registry fixture
2024-06-17 07:36:35 +02:00
G Johansson
bd37ce6e9a Remove beat (internet time) from time_date (#119785) 2024-06-16 23:36:06 -04:00
J. Nick Koston
fc3fbc6862 Bump uiprotect to 1.12.1 (#119799) 2024-06-16 18:06:45 -05:00
J. Nick Koston
4879c8b72e Increase unifiprotect polling interval to 60s (#119800) 2024-06-16 17:31:28 -05:00
Jan Bouwhuis
05e690ba0d Remove not used group class method (#119798) 2024-06-17 00:27:07 +02:00
J. Nick Koston
8c613bc869 Cleanup unifiprotect ProtectData object (#119787) 2024-06-16 17:08:09 -05:00
J. Nick Koston
85ca6f15be Add some suggested units to unifiprotect sensors (#119790) 2024-06-16 15:04:28 -05:00
J. Nick Koston
affbc30d0d Move unifiprotect services register to async_setup (#119786) 2024-06-16 14:50:03 -05:00
J. Nick Koston
151b3b3b0a Reduce duplicate code in unifiprotect entities (#119779) 2024-06-16 14:14:59 -05:00
J. Nick Koston
2713a3fdb1 Bump uiprotect to 1.12.0 (#119763) 2024-06-16 14:14:41 -05:00
J. Nick Koston
03027893ff Fix precision for unifiprotect sensors (#119781) 2024-06-16 13:54:58 -05:00
Paulus Schoutsen
54e6459a41 Speed up getting conversation agent languages (#119554)
Speed up getting conversation languages
2024-06-16 13:35:43 -04:00
Paulus Schoutsen
836abe68c7 Track primary integration (#119741)
* Track primary integration

* Update snapshots

* More snapshots updated

* Uno mas

* Update snapshot
2024-06-16 13:26:06 -04:00
J. Nick Koston
59ca5b04fa Migrate unifiprotect to use has_entity_name (#119759) 2024-06-16 09:00:14 -05:00
Shay Levy
b20160a465 Cleanup Shelly entry unload (#119748)
* Cleanup Shelly entry unload

* store platforms on runtime_data
2024-06-16 08:25:23 -05:00
starkillerOG
3a672642ea Reolink extend diagnostic data (#119745)
* Add diagnostic info

* fix

* change order

* update tests
2024-06-16 14:02:10 +02:00
J. Nick Koston
c519e12042 Cleanup unifiprotect entity model (#119746)
* Small cleanups to unifiprotect

* Small cleanups to unifiprotect

* Small cleanups to unifiprotect

* Small cleanups to unifiprotect

* tweak

* comments

* comments

* stale docstrings

* missed one

* remove dead code

* remove dead code

* remove dead code

* remove dead code

* cleanup
2024-06-15 22:02:03 -04:00
Lode Smets
c0a680a80a Fix for Synology DSM shared images (#117695)
* Fix for shared images

* - FIX: Synology shared photos

* - changes after review

* Added test

* added test

* fix test
2024-06-16 00:48:08 +02:00
jjlawren
59ade9cf93 Fix model import in Spotify (#119747)
* Always import HomeAssistantSpotifyData in spotify.media_browser

Relocate HomeAssistantSpotifyData to avoid circular import

* Fix moved import

* Rename module to 'models'

* Adjust docstring
2024-06-16 00:47:47 +02:00
Franck Nijhof
394dafd980 2024.6.3 (#119742) 2024-06-15 21:05:26 +02:00
Franck Nijhof
eba429dc54 Temporary pin CI to Python 3.12.3 (#119261) 2024-06-15 20:36:35 +02:00
Franck Nijhof
89ce8478de Bump version to 2024.6.3 2024-06-15 18:23:39 +02:00
Franck Nijhof
a4a8315376 Ensure workday issues are not persistent (#119732) 2024-06-15 18:23:29 +02:00
Franck Nijhof
3a705fd668 Ensure UniFi Protect EA warning is not persistent (#119730) 2024-06-15 18:23:25 +02:00
TheJulianJES
dc0fc318b8 Bump ZHA dependencies (#119713)
* Bump bellows to 0.39.1

* Bump zigpy to 0.64.1
2024-06-15 18:23:22 +02:00
J. Nick Koston
5ceb8537eb Bump uiprotect to 1.7.2 (#119705)
changelog: https://github.com/uilibs/uiprotect/compare/v1.7.1...v1.7.2
2024-06-15 18:23:19 +02:00
J. Nick Koston
d7d7782a69 Bump uiprotect to 1.7.1 (#119694)
changelog: https://github.com/uilibs/uiprotect/compare/v1.6.0...v1.7.0
2024-06-15 18:23:16 +02:00
G Johansson
2d4176d581 Fix alarm default code in concord232 (#119691) 2024-06-15 18:23:12 +02:00
J. Nick Koston
204e9a79c5 Bump uiprotect to 1.6.0 (#119661) 2024-06-15 18:23:09 +02:00
J. Nick Koston
ace7da2328 Bump uiprotect to 1.4.1 (#119653) 2024-06-15 18:21:52 +02:00
mletenay
dfe25ff804 Bump goodwe to 0.3.6 (#119646) 2024-06-15 18:21:49 +02:00
J. Nick Koston
2b44cf898e Soften unifiprotect EA channel message (#119641) 2024-06-15 18:21:45 +02:00
Paul Bottein
c77ed921de Update frontend to 20240610.1 (#119634) 2024-06-15 18:21:03 +02:00
Jan Bouwhuis
78e13d138f Fix group enabled platforms are preloaded if they have alternative states (#119621) 2024-06-15 18:20:05 +02:00
J. Nick Koston
4e394597bd Bump uiprotect to 1.2.1 (#119620)
* Bump uiprotect to 1.2.0

changelog: https://github.com/uilibs/uiprotect/compare/v1.1.0...v1.2.0

* bump
2024-06-15 18:20:02 +02:00
starkillerOG
78c2dc708c Fix error for Reolink snapshot streams (#119572) 2024-06-15 18:19:58 +02:00
Ethem Cem Özkan
4c1d2e7ac8 Revert "Revert Use integration fallback configuration for tado water fallback" (#119526)
* Revert "Revert Use integration fallback configuration for tado water heater fallback (#119466)"

This reverts commit ade936e6d5.

* add decide method for duration

* add repair issue to let users know

* test module for repairs

* Update strings.json

Co-authored-by: Franck Nijhof <frenck@frenck.nl>

* repair issue should not be persistent

* use issue_registery fixture instead of mocking

* fix comment

* parameterize repair issue created test case

---------

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-15 18:19:55 +02:00
Jan-Philipp Benecke
7b809a8e55 Partially revert "Add more debug logging to Ping integration" (#119487) 2024-06-15 18:19:52 +02:00
Erwin Douna
4eea448f9d Revert Use integration fallback configuration for tado water heater fallback (#119466) 2024-06-15 18:19:48 +02:00
Joakim Plate
f58882c878 Add loggers to gardena bluetooth (#119460) 2024-06-15 18:19:45 +02:00
J. Nick Koston
4e6e9f35b5 Bump uiprotect to 1.1.0 (#119449) 2024-06-15 18:19:42 +02:00
Sebastian Goscik
d5e9976b2c Bump uiprotect to v1.0.1 (#119436) 2024-06-15 18:19:39 +02:00
MJJ
8d547d4599 Bump buieradar to 1.0.6 (#119433) 2024-06-15 18:19:32 +02:00
J. Nick Koston
94d79440a0 Fix incorrect key name in unifiprotect options strings (#119417) 2024-06-15 18:19:29 +02:00
J. Nick Koston
d602b7d19b Bump uiprotect to 1.0.0 (#119415) 2024-06-15 18:19:26 +02:00
J. Nick Koston
fb5de55c3e Bump uiprotect to 0.13.0 (#119344) 2024-06-15 18:19:23 +02:00
J. Nick Koston
5cf0ee936d Bump uiprotect to 0.10.1 (#119327)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2024-06-15 18:19:19 +02:00
tronikos
7443878333 Make remaining time of timers available to LLMs (#118696)
* Include speech_slots in IntentResponse.as_dict

* Populate speech_slots only if available

* fix typo

* Add test

* test all fields

* Fix another test

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2024-06-15 18:19:16 +02:00
Ethem Cem Özkan
9065042960 Revert "Revert Use integration fallback configuration for tado water fallback" (#119526)
* Revert "Revert Use integration fallback configuration for tado water heater fallback (#119466)"

This reverts commit ade936e6d5.

* add decide method for duration

* add repair issue to let users know

* test module for repairs

* Update strings.json

Co-authored-by: Franck Nijhof <frenck@frenck.nl>

* repair issue should not be persistent

* use issue_registery fixture instead of mocking

* fix comment

* parameterize repair issue created test case

---------

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-06-15 18:16:10 +02:00
Robert Hillis
410ef8ce14 Store runtime data inside the config entry in Efergy (#119551)
* Store runtime data inside the config entry in Efergy

* store later
2024-06-15 18:14:34 +02:00
Jan Bouwhuis
b405e2f03e Improve logging use of deprecated schema option for mqtt vacuum (#119724) 2024-06-15 16:50:12 +02:00
Franck Nijhof
af0f540dd4 Ensure UniFi Protect EA warning is not persistent (#119730) 2024-06-15 08:05:18 -04:00
Franck Nijhof
08ef556736 Ensure workday issues are not persistent (#119732) 2024-06-15 08:04:42 -04:00
Erik Montnemery
7e61ec96e7 Make the radius of the home zone configurable (#119385) 2024-06-15 13:22:01 +02:00
Diogo Gomes
8cf1890772 Moves diagnostic information from attributes to diagnostic in Utility Meter (#118637)
* move diag information from attributes to diagnostic

* remove constant attributes

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-06-15 12:50:19 +02:00
Brett Adams
dac661831e Add unique IDs to config entries for Teslemetry (#115616)
* Add basic UID

* Add Unique IDs

* Add debug message

* Readd debug message

* Minor bump config version

* Ruff

* Rework migration

* Fix migration return

* Review feedback

* Add test for v2
2024-06-15 12:10:02 +02:00
Josef Zweck
a515562a11 Bring back auto on off switches to lamarzocco (#119421)
* add auto on off switches
2024-06-15 11:33:29 +02:00
Matthias Alphart
c8e9a3a8f4 Device automation extra fields translation for KNX (#119518) 2024-06-15 11:31:10 +02:00
Sid
8c5c7203ea Bump ruff to 0.4.9 (#119721) 2024-06-15 11:28:10 +02:00
Paul Bottein
7a3a57c78e Add open state support to matter lock (#119682) 2024-06-15 11:24:33 +02:00
Aidan Timson
f1f82ffbf8 Update aioazuredevops to 2.1.1 (#119720)
* Update aioazuredevops to 2.1.1

* Update tests
2024-06-15 05:30:38 +02:00
TheJulianJES
c75db797d0 Bump ZHA dependencies (#119713)
* Bump bellows to 0.39.1

* Bump zigpy to 0.64.1
2024-06-14 22:33:38 +02:00
Jay
8397d6a29f Envisalink add arming as a state to alarm control panel (#119702)
Envisalink Add Arming as a State
2024-06-14 21:51:20 +02:00
starkillerOG
2639336ab0 Prefer mp4 playback in Reolink (#119630)
* If possible use PLAYBACK of mp4 files

* bring test_coverage back to 100%

* Do not reasign the vod_type multiple times

Co-authored-by: Dave T <17680170+davet2001@users.noreply.github.com>

* fix indent

* add white space

* fix tests

* Update homeassistant/components/reolink/media_source.py

Co-authored-by: Dave T <17680170+davet2001@users.noreply.github.com>

---------

Co-authored-by: Dave T <17680170+davet2001@users.noreply.github.com>
2024-06-14 21:38:53 +02:00
Thomas55555
c2e31e9846 Add work area sensor for Husqvarna Automower (#119704)
* Add work area sensor to Husqvarna Automower

* fix exist_fn
2024-06-14 21:34:47 +02:00
J. Nick Koston
c0ff2d866f Reduce code needed to check unifiprotect attrs (#119706)
* Reduce code needed to check unifiprotect attrs

* Apply suggestions from code review

* Update homeassistant/components/unifiprotect/manifest.json

* Apply suggestions from code review

* revert

* adjust

* tweak

* make mypy happy
2024-06-14 21:29:18 +02:00
J. Nick Koston
f8bf357811 Remove set default doorbell text service from unifiprotect (#119695)
UI has removed this functionality in UI Protect 4.x

discovered via https://github.com/uilibs/uiprotect/issues/57
2024-06-14 21:25:14 +02:00
tronikos
6b8bddf6e3 Make remaining time of timers available to LLMs (#118696)
* Include speech_slots in IntentResponse.as_dict

* Populate speech_slots only if available

* fix typo

* Add test

* test all fields

* Fix another test

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2024-06-14 20:47:41 +02:00
Mr. Bubbles
c077c2a972 Fix pyload async_update SensorEntity raising exceptions (#119655)
* Fix Sensorentity raising exceptions

* Increase test coverage
2024-06-14 20:47:06 +02:00
G Johansson
05cbda0e50 Fix alarm default code in concord232 (#119691) 2024-06-14 20:45:27 +02:00
J. Nick Koston
6bdfed6910 Bump uiprotect to 1.7.2 (#119705)
changelog: https://github.com/uilibs/uiprotect/compare/v1.7.1...v1.7.2
2024-06-14 20:43:40 +02:00
J. Nick Koston
d2bcd5d1fb Refactor unifiprotect switch to match other platforms (#119698)
- Use _attr_is_on for nvr entities
- implement _async_get_state_attrs for nvr entities
- define MODEL_DESCRIPTIONS_WITH_CLASS
2024-06-14 13:22:12 -05:00
J. Nick Koston
6e322c310b Split binary sensor classes in unifiprotect (#119696)
* Split binary sensor classes in unifiprotect

There were two types of binary sensors, ones that can change device_class at
run-time (re-mountable ones), and ones that cannot. Instead of having
branching in the class, split the class

* tweak order to match name
2024-06-14 13:16:49 -05:00
J. Nick Koston
10a2fd7cb6 Bump uiprotect to 1.7.1 (#119694)
changelog: https://github.com/uilibs/uiprotect/compare/v1.6.0...v1.7.0
2024-06-14 10:56:26 -05:00
starkillerOG
da64f61083 Add firmware update entities for Reolink IPC channel cameras (#119637) 2024-06-14 08:12:55 -04:00
epenet
01be5d5f6b Move fixtures to decorators in core tests (#119675) 2024-06-14 13:32:42 +02:00
dependabot[bot]
b80f7185b2 Bump codecov/codecov-action from 4.4.1 to 4.5.0 (#119668)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-14 09:28:17 +02:00
dependabot[bot]
fb801946bb Bump github/codeql-action from 3.25.9 to 3.25.10 (#119669)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-14 09:27:54 +02:00
epenet
453564fd03 Force full CI on all root test files (#119673) 2024-06-14 09:27:18 +02:00
epenet
3e9d25f81d Add missing argument type hints to component tests (#119671) 2024-06-14 09:26:46 +02:00
epenet
83b97d3218 Add missing argument type hints to recorder tests (#119672) 2024-06-14 09:25:26 +02:00
Erik Montnemery
003f216820 Rename collection.CollectionChangeSet to collection.CollectionChange (#119532) 2024-06-14 08:54:37 +02:00
J. Nick Koston
9082dc2a79 Reduce recorder overhead when entity filter is empty (#119631) 2024-06-14 08:43:51 +02:00
epenet
9f41133bbc Add missing argument type to core tests (#119667) 2024-06-14 08:42:01 +02:00
Rami Mosleh
f3ce562847 Store Glances coordinator in runtime_data (#119607) 2024-06-14 08:39:04 +02:00
mletenay
1d62056d9b Bump goodwe to 0.3.6 (#119646) 2024-06-14 08:29:32 +02:00
epenet
4b29c35453 Tweak logging statements in tests (#119664) 2024-06-14 08:28:47 +02:00
J. Nick Koston
e6b7301367 Fix blocking I/O in CachingStaticResource (#119663) 2024-06-14 08:27:50 +02:00
epenet
38a6e666a7 Add missing return type to some test functions (#119665) 2024-06-14 08:26:45 +02:00
epenet
26e21bb356 Adjust incorrect unnecessary-lambda pylint disable statement in demo tests (#119666) 2024-06-14 08:25:35 +02:00
Erik Montnemery
471e2a17a2 Improve error messages when config entry is in wrong state (#119591)
* Improve error messages when config entry is in wrong state

* Apply suggestions from code review

Co-authored-by: Joakim Sørensen <ludeeus@ludeeus.dev>

* Adjust tests

---------

Co-authored-by: Joakim Sørensen <ludeeus@ludeeus.dev>
2024-06-14 08:00:36 +02:00
Jan Bouwhuis
9e146a51c2 Fix group enabled platforms are preloaded if they have alternative states (#119621) 2024-06-14 07:46:24 +02:00
Matrix
3336bdb402 Fix Yolink device incorrect state (#119658)
fix device incorrect state
2024-06-14 07:31:02 +02:00
Joakim Plate
097844aca6 Allow arm levels be in order for google assistant (#119645) 2024-06-14 07:18:57 +02:00
J. Nick Koston
95b9e15306 Bump uiprotect to 1.6.0 (#119661) 2024-06-13 23:34:55 -05:00
J. Nick Koston
b11d832fb1 Bump uiprotect to 1.4.1 (#119653) 2024-06-13 21:01:25 -05:00
Shay Levy
efa7240ac5 Use single list for Shelly non-sleeping platforms (#119540) 2024-06-13 20:27:40 -05:00
tronikos
87ddb02828 Bump python-fullykiosk to 0.0.13 (#119544)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-13 20:41:37 -04:00
Jan Bouwhuis
a992654a8b Fix blocking IO calls in mqtt client setup (#119647) 2024-06-13 17:47:38 -05:00
dougiteixeira
cd80b9b318 Remove obsolete device links in Utility Meter helper (#119328)
* Make sure we update the links between the devices and config entries when the changes source device
2024-06-13 23:44:13 +02:00
J. Nick Koston
09aa9cf842 Soften unifiprotect EA channel message (#119641) 2024-06-13 16:31:39 -05:00
J. Nick Koston
0c3a5ae5da Dispatch unifiprotect websocket messages based on model (#119633) 2024-06-13 16:17:31 -05:00
J. Nick Koston
de27f24a4c Use the existing api client for unifiprotect repairs if available (#119640)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2024-06-13 16:17:11 -05:00
Mr. Bubbles
7bbd28d385 Migrate library to PyLoadAPI 1.1.0 in pyLoad integration (#116053)
* Migrate pyLoad integration to externa API library

* Add const to .coveragerc

* raise update failed when cookie expired

* fix exceptions

* Add tests

* bump to PyLoadAPI 1.1.0

* remove unreachable code

* fix tests

* Improve logging and exception handling

- Modify manifest.json to update logger configuration.
- Improve error messages for authentication failures in sensor.py.
- Simplify and rename pytest fixtures in conftest.py.
- Update test cases in test_sensor.py to check for log entries and remove unnecessary code.

* remove exception translations
2024-06-13 22:52:19 +02:00
Shay Levy
40b98b70b0 Wait for background tasks in Shelly tests (#119636) 2024-06-13 22:36:03 +03:00
Paul Bottein
72c6257131 Update frontend to 20240610.1 (#119634) 2024-06-13 15:34:58 -04:00
starkillerOG
b8851f2f3c Cleanup Reolink firmware update entity (#119239) 2024-06-13 21:27:30 +02:00
Thomas55555
b4a77f8341 Bump aioautomower to 2024.6.0 (#119625) 2024-06-13 19:58:04 +02:00
J. Nick Koston
fc6dd7ce7d Bump uiprotect to 1.2.1 (#119620)
* Bump uiprotect to 1.2.0

changelog: https://github.com/uilibs/uiprotect/compare/v1.1.0...v1.2.0

* bump
2024-06-13 19:28:42 +02:00
J. Nick Koston
6d31991021 Reduce duplicate code in unifiprotect (#119624) 2024-06-13 11:44:29 -05:00
epenet
8e1103050c Fix dangerous-default-value warnings in core tests (#119568) 2024-06-13 17:10:37 +02:00
epenet
a80a372c1c Fix dangerous-default-value warnings in nzbget tests (#119580) 2024-06-13 17:10:00 +02:00
epenet
ed52ff3076 Fix dangerous-default-value warnings in ezviz tests (#119589) 2024-06-13 17:09:26 +02:00
epenet
75e0aee8fc Fix dangerous-default-value warnings in homematicip_cloud tests (#119583) 2024-06-13 17:08:40 +02:00
epenet
835d422a90 Fix dangerous-default-value warnings in control4 tests (#119592) 2024-06-13 17:06:12 +02:00
epenet
6901c24ab7 Fix dangerous-default-value warnings in aussie broadband tests (#119596) 2024-06-13 17:03:16 +02:00
epenet
382eb1e3b2 Fix dangerous-default-value warnings in rituals_perfume_genie tests (#119590) 2024-06-13 17:02:26 +02:00
epenet
1440ad26c8 Fix dangerous-default-value warnings in plex tests (#119603) 2024-06-13 17:01:52 +02:00
epenet
97e19cb61c Fix dangerous-default-value warnings in cloudflare tests (#119598) 2024-06-13 17:00:18 +02:00
epenet
49b28cca62 Fix consider-using-with warnings in core tests (#119606) 2024-06-13 16:59:40 +02:00
epenet
384fa53cc0 Fix dangerous-default-value warnings in panasonic_viera tests (#119602) 2024-06-13 16:59:05 +02:00
epenet
ca8d3e0c83 Ignore unnecessary-lambda warnings in tests (#119564) 2024-06-13 16:58:41 +02:00
Rami Mosleh
bb2883a5a8 Store imap coordinator in runtime_data (#119611) 2024-06-13 16:58:05 +02:00
epenet
50fe29ccc1 Fix attribute-defined-outside-init in harmony tests (#119614) 2024-06-13 16:57:20 +02:00
epenet
3b8337985c Fix dangerous-default-value warnings in environment_canada tests (#119586) 2024-06-13 16:56:22 +02:00
epenet
349ac54616 Fix dangerous-default-value warnings in auth tests (#119597) 2024-06-13 16:55:48 +02:00
epenet
2a061f58eb Fix dangerous-default-value warnings in tessie tests (#119605) 2024-06-13 16:55:06 +02:00
Rami Mosleh
f2ce510484 Store islamic prayer times coordinator in runtime_data (#119612) 2024-06-13 16:54:40 +02:00
epenet
23edbf7bbf Fix dangerous-default-value warnings in subaru tests (#119604) 2024-06-13 16:53:00 +02:00
epenet
27ee204e2f Fix dangerous-default-value warnings in mqtt tests (#119584) 2024-06-13 16:51:45 +02:00
epenet
e34c42c0a9 Fix dangerous-default-value warnings in greeneye_monitor tests (#119581) 2024-06-13 16:47:53 +02:00
Erik Montnemery
9f322b20d1 Use send_json_auto_id in some collection tests (#119570)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-06-13 16:04:32 +02:00
epenet
8871090463 Fix dangerous-default-value warnings in fronius tests (#119600) 2024-06-13 13:53:17 +02:00
epenet
27c08bcb5e Fix dangerous-default-value warnings in lastfm tests (#119601) 2024-06-13 11:57:45 +02:00
epenet
315e5f1d95 Fix import-outside-toplevel pylint warnings in zha tests (#119451) 2024-06-13 11:55:56 +02:00
epenet
40d9d22e76 Fix dangerous-default-value warnings in deconz tests (#119599) 2024-06-13 11:55:37 +02:00
Rami Mosleh
030fe6df4a Store Mikrotik coordinator in runtime_data (#119594) 2024-06-13 11:53:32 +02:00
Robert Resch
f5b86154b4 Bump deebot-client to 8.0.0 (#119515)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-06-13 11:49:20 +02:00
epenet
d211af75ef Fix dangerous-default-value warnings in cloud tests (#119585) 2024-06-13 10:30:44 +02:00
Matrix
55f8a36572 Improve code readability (#119558) 2024-06-13 09:31:29 +02:00
starkillerOG
440771bdea Fix error for Reolink snapshot streams (#119572) 2024-06-13 09:30:53 +02:00
William Grant
c02ac5e538 Classify more ecowitt power supply sensors as diagnostics (#119555) 2024-06-13 09:29:57 +02:00
epenet
b2be3e0a9b Fix dangerous-default-value warnings in automation tests (#119576) 2024-06-13 09:29:04 +02:00
epenet
cadb6317bf Fix dangerous-default-value warnings in canary tests (#119578) 2024-06-13 09:28:11 +02:00
epenet
b5d16bb3ca Fix dangerous-default-value warnings in version tests (#119577) 2024-06-13 09:27:51 +02:00
epenet
92d150ff57 Fix dangerous-default-value warnings in integration tests (#119574) 2024-06-13 09:21:59 +02:00
epenet
a06f098312 Fix dangerous-default-value warnings in switchbot tests (#119575) 2024-06-13 09:20:53 +02:00
dependabot[bot]
08403df20e Bump actions/checkout from 4.1.6 to 4.1.7 (#119566)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-13 09:19:26 +02:00
Robert Hillis
cad6163162 Store runtime data inside the config entry in Tautulli (#119552) 2024-06-13 08:57:28 +02:00
epenet
610f21c4a6 Fix unnecessary-lambda warnings in tests (#119563) 2024-06-13 08:56:14 +02:00
dependabot[bot]
4af3879fc2 Bump github/codeql-action from 3.25.8 to 3.25.9 (#119567)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-13 08:56:04 +02:00
dependabot[bot]
0a727aba4a Bump dawidd6/action-download-artifact from 5 to 6 (#119565)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-13 08:55:50 +02:00
J. Nick Koston
d52ce03aa4 Ensure asyncio blocking checks are undone after tests run (#119542)
* Ensure asyncio blocking checks are undone after tests run

* no reason to ever enable twice

* we are patching objects, make it more generic

* make sure bootstrap unblocks as well

* move disable to tests only

* re-protect

* Update tests/test_block_async_io.py

Co-authored-by: Erik Montnemery <erik@montnemery.com>

* Revert "Update tests/test_block_async_io.py"

This reverts commit 2d46028e21b4095479302629a201c3cfc811b2c2.

* tweak name

* fixture only

* Update tests/conftest.py

* Update tests/conftest.py

* Apply suggestions from code review

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-06-13 08:52:01 +02:00
epenet
669569ca49 Fix dangerous-default-value in zha tests (#119560) 2024-06-13 08:35:05 +02:00
epenet
dda6ccccd2 Fix dangerous-default-value in nest tests (#119561)
* Fix dangerous-default-value in nest tests

* Adjust

* Adjust
2024-06-12 23:32:55 -07:00
J. Nick Koston
dbd3147c9b Remove async_late_forward_entry_setups and instead implicitly hold the lock (#119088)
* Refactor config entry forwards to implictly obtain the lock instead of explictly

This is a bit of a tradeoff to not need async_late_forward_entry_setups

The downside is we can no longer detect non-awaited plastform setups
as we will always implicitly obtain the lock instead of explictly.

Note, this PR is incomplete and is only for discussion purposes
at this point

* preen

* cover

* cover

* restore check for non-awaited platform setup

* cleanup

* fix missing word

* make non-awaited test safer
2024-06-12 21:06:11 -04:00
Josef Zweck
4e121fcbe8 Remove steam temp sensor for Linea Mini (#119423) 2024-06-12 23:35:51 +02:00
Jan-Philipp Benecke
fd83b9a7c6 Add missing attribute translations to water heater entity component (#119531) 2024-06-12 23:34:01 +02:00
Jan Bouwhuis
532f6d1d97 Return override target temp for incomfort climate (#119528) 2024-06-12 23:13:12 +02:00
Erik Montnemery
51891ff8e2 Fix typo in google_assistant (#119522) 2024-06-12 22:45:41 +02:00
Matthias Alphart
929dd9f5da Device automation extra fields translation for LCN (#119519) 2024-06-12 22:45:10 +02:00
Matthias Alphart
39f3a294dc Device automation extra fields translation for Z-Wave-JS (#119529) 2024-06-12 22:44:50 +02:00
epenet
e3e80c83b7 Fix contextmanager-generator-missing-cleanup warning in tests (#119478) 2024-06-12 22:38:11 +02:00
epenet
f7326d3baf Ignore too-many-nested-blocks warning in zha tests (#119479) 2024-06-12 22:33:40 +02:00
Jan Bouwhuis
541c941006 Add state icons to incomfort water_heater entities (#119527) 2024-06-12 22:25:49 +02:00
J. Nick Koston
a586e7fb72 Remove useless delegation in unifiprotect (#119514) 2024-06-12 22:23:18 +02:00
Erik Montnemery
2661581d4e Fix typos in collection helper (#119524) 2024-06-12 20:37:38 +02:00
Franck Nijhof
090d296135 2024.6.2 (#119376) 2024-06-11 14:41:12 +02:00
Franck Nijhof
415bfb40a7 Bump version to 2024.6.2 2024-06-11 11:21:51 +02:00
Maciej Bieniek
7ced4e981e Bump imgw-pib backend library to version 1.0.5 (#119360)
Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
2024-06-11 11:17:29 +02:00
swcloudgenie
b656ef4d4f Fix AladdinConnect OAuth domain (#119336)
fix aladdin connect oauth domain
2024-06-11 11:17:26 +02:00
Erik Montnemery
6ea18a7b24 Fix statistic_during_period after core restart (#119323) 2024-06-11 11:17:22 +02:00
Bram Kragten
a0ac9fe6c9 Update frontend to 20240610.0 (#119320) 2024-06-11 11:16:04 +02:00
Jan-Philipp Benecke
135735126a Add more debug logging to Ping integration (#119318) 2024-06-11 11:10:36 +02:00
J. Nick Koston
3bc6cf666a Bump uiprotect to 0.4.1 (#119308) 2024-06-11 11:10:33 +02:00
Franck Nijhof
1929e103c0 Fix persistence on OpenWeatherMap raised repair issue (#119289) 2024-06-11 11:10:30 +02:00
J. Nick Koston
74b49556f9 Improve workday test coverage (#119259) 2024-06-11 11:10:27 +02:00
J. Nick Koston
8d40f4d39f Bump uiprotect to 0.4.0 (#119256) 2024-06-11 11:10:24 +02:00
Allen Porter
eed126c6d4 Bump google-nest-sdm to 4.0.5 (#119255) 2024-06-11 11:10:21 +02:00
J. Nick Koston
38cd84fa5f Fix climate on/off in nexia (#119254) 2024-06-11 11:10:18 +02:00
Abílio Costa
a28f5baeeb Fix wrong arg name in Idasen Desk config flow (#119247) 2024-06-11 11:10:14 +02:00
J. Nick Koston
f9352dfe8f Switch unifiprotect lib to use uiprotect (#119243) 2024-06-11 11:09:20 +02:00
J. Nick Koston
5beff34069 Remove myself as codeowner for unifiprotect (#118824) 2024-06-11 10:59:51 +02:00
Joakim Plate
119d4c2316 Always provide a currentArmLevel in Google assistant (#119238) 2024-06-11 10:29:34 +02:00
epenet
1e7ab07d9e Revert SamsungTV migration (#119234) 2024-06-11 10:29:31 +02:00
Ethem Cem Özkan
7896e7675c Bump python-roborock to 2.3.0 (#119228) 2024-06-11 10:29:28 +02:00
wittypluck
8b415a0376 Fix Glances v4 network and container issues (glances-api 0.8.0) (#119226) 2024-06-11 10:29:25 +02:00
Angel Nunez Mencias
6a656c5d49 Fixes crashes when receiving malformed decoded payloads (#119216)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2024-06-11 10:29:21 +02:00
G Johansson
8d094bf12e Fix envisalink alarm (#119212) 2024-06-11 10:29:18 +02:00
Sid
c71b6bdac9 Add fallback to entry_id when no mac address is retrieved in enigma2 (#119185) 2024-06-11 10:29:15 +02:00
tronikos
57cc1f841b Bump opower to 0.4.7 (#119183) 2024-06-11 10:29:12 +02:00
Quentin
d8f3778d77 Fix elgato light color detection (#119177) 2024-06-11 10:29:08 +02:00
Shay Levy
9a8e3ad5cc Handle Shelly BLE errors during connect and disconnect (#119174) 2024-06-11 10:29:05 +02:00
Michael
019d33c06c Use more conservative timeout values in Synology DSM (#119169)
use ClientTimeout object
2024-06-11 10:29:02 +02:00
Michael
40ebf3b2a9 Bump py-synologydsm-api to 2.4.4 (#119156)
bump py-synologydsm-api to 2.4.4
2024-06-11 10:28:58 +02:00
Tom Brien
7912c9e95c Fix workday timezone (#119148) 2024-06-11 10:28:55 +02:00
Paulus Schoutsen
4bb1ea1da1 Ensure intent tools have safe names (#119144) 2024-06-11 10:28:51 +02:00
Joost Lekkerkerker
a696ea18d3 Bump aiowaqi to 3.1.0 (#119124) 2024-06-11 10:28:48 +02:00
Shay Levy
df96b94985 Bump aioshelly to 10.0.1 (#119123) 2024-06-11 10:28:45 +02:00
tronikos
0f8ed4e73d Catch GoogleAPICallError in Google Generative AI (#119118) 2024-06-11 10:28:41 +02:00
tronikos
34477d3559 Properly handle escaped unicode characters passed to tools in Google Generative AI (#119117) 2024-06-11 10:28:38 +02:00
Austin Drummond
96ac566032 Fix control 4 on os 2 (#119104) 2024-06-11 10:28:35 +02:00
J. Nick Koston
87f48b15d1 Ensure multiple executions of a restart automation in the same event loop iteration are allowed (#119100)
* Add test for restarting automation

related issue #119097

* fix

* add a delay since restart is an infinite loop

* tests
2024-06-11 10:28:31 +02:00
kaareseras
a1f2140ed7 Fix Azure data explorer (#119089)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-11 10:28:28 +02:00
tronikos
db7a9321be Bump google-generativeai to 0.6.0 (#119062) 2024-06-11 10:28:24 +02:00
G Johansson
ebb0a453f4 Calculate attributes when entity information available in Group sensor (#119021) 2024-06-11 10:28:21 +02:00
Joakim Plate
7da10794a8 Update gardena library to 1.4.2 (#119010) 2024-06-11 10:28:18 +02:00
Ruben Bokobza
461f0865af Bump pyElectra to 1.2.1 (#118958) 2024-06-11 10:28:15 +02:00
karwosts
fc83bb1737 Fix statistic_during_period wrongly prioritizing ST statistics over LT (#115291)
* Fix statistic_during_period wrongly prioritizing ST statistics over LT

* comment

* start of a test

* more testcases

* fix sts insertion range

* update from review

* remove unneeded comments

* update logic

* min/mean/max testing
2024-06-11 10:28:09 +02:00
Franck Nijhof
b28cdcfc49 2024.6.1 (#119096) 2024-06-07 21:20:44 +02:00
Franck Nijhof
3f70e2b6f0 Bump version to 2024.6.1 2024-06-07 20:26:53 +02:00
Joost Lekkerkerker
ed22e98861 Fix Azure Data Explorer strings (#119067) 2024-06-07 20:24:03 +02:00
Marc Mueller
093f07c04e Add type ignore comments (#119052) 2024-06-07 20:24:00 +02:00
Joost Lekkerkerker
b5693ca604 Fix AirGradient name (#119046) 2024-06-07 20:23:57 +02:00
J. Nick Koston
20b77aa15f Fix remember_the_milk calling configurator async api from the wrong thread (#119029) 2024-06-07 20:23:53 +02:00
J. Nick Koston
1cbd3ab930 Fix refactoring error in snmp switch (#119028) 2024-06-07 20:23:50 +02:00
Matthias Alphart
31b44b7846 Fix KNX climate.set_hvac_mode not turning on (#119012) 2024-06-07 20:23:47 +02:00
Matthias Alphart
de3a0841d8 Increase test coverage for KNX Climate (#117903)
* Increase test coverage fro KNX Climate

* fix test type annotation
2024-06-07 20:23:40 +02:00
Mike Degatano
581fb2f9f4 Always have addon url in detached_addon_missing (#119011) 2024-06-07 20:21:25 +02:00
Shay Levy
5bb4e4f5d9 Hold connection lock in Shelly RPC reconnect (#119009) 2024-06-07 20:21:22 +02:00
J. Nick Koston
cfa619b67e Remove isal from after_dependencies in http (#119000) 2024-06-07 20:21:18 +02:00
Michael Hansen
56db7fc7dc Fix exposure checks on some intents (#118988)
* Check exposure in climate intent

* Check exposure in todo list

* Check exposure for weather

* Check exposure in humidity intents

* Add extra checks to weather tests

* Add more checks to todo intent test

* Move climate intents to async_match_targets

* Update test_intent.py

* Update test_intent.py

* Remove patch
2024-06-07 20:20:41 +02:00
Joost Lekkerkerker
1f6be7b4d1 Fix unit of measurement for airgradient sensor (#118981) 2024-06-07 20:18:45 +02:00
Maciej Bieniek
52d1432d81 Bump imgw-pib library to version 1.0.4 (#118978)
Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
2024-06-07 20:18:41 +02:00
David Knowles
14da1e9b23 Bump pydrawise to 2024.6.3 (#118977) 2024-06-07 20:18:38 +02:00
G Johansson
d6e1d05e87 Bump python-holidays to 0.50 (#118965) 2024-06-07 20:18:35 +02:00
G Johansson
62f73cfcca Fix Alarm control panel not require code in several integrations (#118961) 2024-06-07 20:18:32 +02:00
Maciej Bieniek
6e9a53d02e Bump imgw-pib backend library to version 1.0.2 (#118953)
Bump imgw-pib to version 1.0.2

Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
2024-06-07 20:18:28 +02:00
J. Nick Koston
394c13af1d Revert "Bump orjson to 3.10.3 (#116945)" (#118920)
This reverts commit dc50095d06.
2024-06-07 20:17:01 +02:00
Jan-Philipp Benecke
86b13e8ae3 Fix flaky Google Assistant test (#118914)
* Fix flaky Google Assistant test

* Trigger full ci
2024-06-07 20:16:58 +02:00
Rami Mosleh
5a7332a135 Check if imap message text has a value instead of checking if its not None (#118901)
* Check if message_text has a value instead of checking if its not None

* Strip message_text to ensure that its actually empty or not

* Add test with multipart payload having empty plain text
2024-06-07 20:16:55 +02:00
Michael Hansen
0f9a91d369 Prioritize literal text with name slots in sentence matching (#118900)
Prioritize literal text with name slots
2024-06-07 20:16:52 +02:00
Marc Mueller
00dd86fb4b Update requests to 2.32.3 (#118868)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-07 20:16:47 +02:00
Franck Nijhof
460909a7f6 2024.6.0 (#118400) 2024-06-05 20:06:01 +02:00
Franck Nijhof
21fd012447 Bump version to 2024.6.0 2024-06-05 19:00:08 +02:00
Robert Resch
c27f0c560e Replace slave by meter in v2c (#118893) 2024-06-05 18:59:52 +02:00
Michael Hansen
0f4a1b421e Bump intents to 2024.6.5 (#118890) 2024-06-05 18:59:49 +02:00
Erik Montnemery
5e35ce2996 Improve WS command validate_config (#118864)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-05 18:59:44 +02:00
Franck Nijhof
e5804307e7 Bump version to 2024.6.0b9 2024-06-05 15:51:19 +02:00
Bram Kragten
3b74b63b23 Update frontend to 20240605.0 (#118875) 2024-06-05 15:51:08 +02:00
Marc Mueller
06df32d9d4 Fix TypeAliasType not callable in senz (#118872) 2024-06-05 15:51:05 +02:00
Jan Bouwhuis
63947e4980 Improve repair issue when notify service is still being used (#118855)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-06-05 15:51:02 +02:00
Ethem Cem Özkan
ac6a377478 Bump python-roborock to 2.2.3 (#118853)
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-06-05 15:50:59 +02:00
Paulus Schoutsen
18af423a78 Fix the radio browser doing I/O in the event loop (#118842) 2024-06-05 15:50:56 +02:00
Franck Nijhof
f1445bc8f5 Fix capitalization of protocols in Reolink option flow (#118839) 2024-06-05 15:50:53 +02:00
starkillerOG
3784c99305 Conserve Reolink battery by not waking the camera on each update (#118773)
* update to new cmd_list type

* Wake battery cams each 1 hour

* fix styling

* fix epoch

* fix timezone

* force full update when using generic update service

* improve comment

* Use time.time() instead of datetime

* fix import order
2024-06-05 15:50:50 +02:00
Pete Sage
0084d6c5bd Fix Hydrawise sensor availability (#118669)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-06-05 15:50:47 +02:00
Franck Nijhof
f1e6375406 Bump version to 2024.6.0b8 2024-06-04 21:32:36 +02:00
Jan-Philipp Benecke
9157905f80 Initialize the Sentry SDK within an import executor job to not block event loop (#118830) 2024-06-04 21:31:49 +02:00
J. Nick Koston
b02c9aa2ef Ensure name of task is logged for unhandled loop exceptions (#118822) 2024-06-04 21:31:45 +02:00
Bram Kragten
6e30fd7633 Update frontend to 20240604.0 (#118811) 2024-06-04 21:31:42 +02:00
Stefan Agner
74b29c2e54 Bump Python Matter Server library to 6.1.0 (#118806) 2024-06-04 21:31:38 +02:00
Maciej Bieniek
b1b26af92b Check if Shelly entry.runtime_data is available (#118805)
* Check if runtime_data is available

* Add tests

* Use `is` operator

---------

Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
2024-06-04 21:31:33 +02:00
arturyak
b107ffd30d Add missing FAN_ONLY mode to ccm15 (#118804) 2024-06-04 21:31:28 +02:00
Joost Lekkerkerker
776675404a Set unique id in aladdin connect config flow (#118798) 2024-06-04 21:30:08 +02:00
Paulus Schoutsen
38ee32fed2 Include script description in LLM exposed entities (#118749)
* Include script description in LLM exposed entities

* Fix race in test

* Fix type

* Expose script

* Remove fields
2024-06-04 21:21:26 +02:00
Tsvi Mostovicz
111d11aaca Fix updating options in Jewish Calendar (#118643) 2024-06-04 21:21:23 +02:00
Jack Boswell
ff8752ea4f Fix calculation of Starlink sleep end setting (#115507)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-04 21:21:13 +02:00
Franck Nijhof
2151f7ebf3 Bump version to 2024.6.0b7 2024-06-04 12:20:22 +02:00
Richard Kroegel
50efce4e53 Allow per-sensor unit conversion on BMW sensors (#110272)
* Update BMW sensors to use device_class

* Test adjustments

* Trigger CI

* Remove unneeded cast

* Set suggested_display_precision to 0

* Rebase for climate_status

* Change charging_status to ENUM device class

* Add test for Enum translations

* Pin Enum sensor values

* Use snapshot_platform helper

* Remove translation tests

* Formatting

* Remove comment

* Use const.STATE_UNKOWN

* Fix typo

* Update strings

* Loop through Enum sensors

* Revert enum sensor changes

---------

Co-authored-by: Richard <rikroe@users.noreply.github.com>
2024-06-04 12:20:08 +02:00
Richard Kroegel
c8538f3c08 Use snapshot_platform helper for BMW tests (#118735)
* Use snapshot_platform helper

* Remove comments

---------

Co-authored-by: Richard <rikroe@users.noreply.github.com>
2024-06-04 12:19:01 +02:00
Richard Kroegel
4bfff12570 Set lock state to unkown on BMW API error (#118559)
* Revert to previous lock state on BMW API error

* Set lock state to unkown on error and force refresh from API

---------

Co-authored-by: Richard <rikroe@users.noreply.github.com>
2024-06-04 12:02:47 +02:00
Richard Kroegel
f2b1635969 Refactor fixture calling for BMW tests (#118708)
* Refactor BMW tests to use pytest.mark.usefixtures

* Fix freeze_time

---------

Co-authored-by: Richard <rikroe@users.noreply.github.com>
2024-06-04 12:01:40 +02:00
Joost Lekkerkerker
b3b8ae31fd Move Aladdin stale device removal to init module (#118784) 2024-06-04 11:58:35 +02:00
Joost Lekkerkerker
ba96fc272b Re-enable sensor platform for Aladdin Connect (#118782) 2024-06-04 11:58:32 +02:00
Joost Lekkerkerker
c702174fa0 Add coordinator to Aladdin Connect (#118781) 2024-06-04 11:58:29 +02:00
Joost Lekkerkerker
5d6fe7387e Use model from Aladdin Connect lib (#118778)
* Use model from Aladdin Connect lib

* Fix
2024-06-04 11:58:25 +02:00
Joost Lekkerkerker
c76b7a48d3 Initial cleanup for Aladdin connect (#118777) 2024-06-04 11:58:22 +02:00
Joost Lekkerkerker
954e8ff9b3 Bump airgradient to 0.4.3 (#118776) 2024-06-04 11:58:18 +02:00
Joakim Sørensen
8c332ddbdb Update hass-nabucasa to version 0.81.1 (#118768) 2024-06-04 11:58:15 +02:00
Jan Bouwhuis
01c4ca2749 Recover mqtt abbrevations optimizations (#118762)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-04 11:58:12 +02:00
Michael Hansen
4b4b5362d9 Clean up exposed domains (#118753)
* Remove lock and script

* Add media player

* Fix tests
2024-06-04 11:58:08 +02:00
Jan Bouwhuis
70d7cedf08 Do not log mqtt origin info if the log level does not allow it (#118752) 2024-06-04 11:58:05 +02:00
Michael Hansen
7bbfb1a22b Bump intents to 2024.6.3 (#118748) 2024-06-04 11:58:02 +02:00
Paulus Schoutsen
d68d871054 Update OpenAI prompt on each interaction (#118747) 2024-06-04 11:57:58 +02:00
Jan Bouwhuis
69bdefb02d Revert "Allow MQTT device based auto discovery" (#118746)
Revert "Allow MQTT device based auto discovery (#109030)"

This reverts commit 585892f067.
2024-06-04 11:57:55 +02:00
Paulus Schoutsen
ebaec6380f Google Gen AI: Copy messages to avoid changing the trace data (#118745) 2024-06-04 11:57:51 +02:00
starkillerOG
9cf6e9b21a Bump reolink-aio to 0.9.1 (#118655)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-04 11:55:34 +02:00
David Bonnes
eb1a9eda60 Harden evohome against failures to retrieve zone schedules (#118517) 2024-06-04 11:55:21 +02:00
Franck Nijhof
26344ffd74 Bump version to 2024.6.0b6 2024-06-03 21:27:31 +02:00
Paulus Schoutsen
2940104008 Remove dispatcher from Tag entity (#118671)
* Remove dispatcher from Tag entity

* type

* Don't use  helper

* Del is faster than pop

* Use id in update

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-06-03 21:27:08 +02:00
Joost Lekkerkerker
8072a268a1 Require firmware version 3.1.1 for airgradient (#118744) 2024-06-03 21:26:19 +02:00
Bram Kragten
b5f557ad73 Update frontend to 20240603.0 (#118736) 2024-06-03 21:26:16 +02:00
Michael Hansen
f977b54312 Resolve areas/floors to ids in intent_script (#118734) 2024-06-03 21:26:13 +02:00
Jan-Philipp Benecke
11b2f201f3 Rename Discovergy to inexogy (#118724) 2024-06-03 21:26:10 +02:00
Erik Montnemery
8cc3c147fe Tweak light service schema (#118720) 2024-06-03 21:26:07 +02:00
epenet
fd9ea2f224 Bump renault-api to 0.2.3 (#118718) 2024-06-03 21:26:04 +02:00
Diogo Gomes
f064f44a09 Address reviews comments in #117147 (#118714) 2024-06-03 21:26:01 +02:00
Erik Montnemery
f3d1157bc4 Remove tag_id from tag store (#118713) 2024-06-03 21:25:58 +02:00
mkmer
85982d2b87 Remove unintended translation key from blink (#118712) 2024-06-03 21:25:55 +02:00
Erik Montnemery
cc83443ad1 Don't store tag_id in tag storage (#118707) 2024-06-03 21:25:52 +02:00
tronikos
8a516207e9 Use ISO format when passing date to LLMs (#118705) 2024-06-03 21:25:49 +02:00
Mick Vleeshouwer
f805df8390 Bump pyoverkiz to 1.13.11 (#118703) 2024-06-03 21:25:46 +02:00
Joost Lekkerkerker
ea85ed6992 Disable both option in Airgradient select (#118702) 2024-06-03 21:25:43 +02:00
Joost Lekkerkerker
54425b756e Configure device in airgradient config flow (#118699) 2024-06-03 21:25:40 +02:00
Paul Bottein
7b43b587a7 Bump python-roborock to 2.2.2 (#118697) 2024-06-03 21:25:37 +02:00
Matrix
7e71975358 Fixing device model compatibility issues. (#118686) 2024-06-03 21:25:34 +02:00
J. Nick Koston
e0232510d7 Revert "Add websocket API to get list of recorded entities (#92640)" (#118644)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2024-06-03 21:21:45 +02:00
Paulus Schoutsen
84f9bb1d63 Automatically fill in slots based on LLM context (#118619)
* Automatically fill in slots from LLM context

* Add tests

* Apply suggestions from code review

Co-authored-by: Allen Porter <allen@thebends.org>

---------

Co-authored-by: Allen Porter <allen@thebends.org>
2024-06-03 21:21:41 +02:00
David Knowles
b436fe94ae Bump pydrawise to 2024.6.2 (#118608) 2024-06-03 21:21:38 +02:00
epenet
aff5da5762 Address late review comment in samsungtv (#118539)
Address late comment in samsungtv
2024-06-03 21:21:29 +02:00
Paulus Schoutsen
b5783e6f5c Bump version to 2024.6.0b5 2024-06-03 01:10:10 +00:00
G Johansson
1708b60ecf Fix entity state dispatching for Tag entities (#118662) 2024-06-03 01:10:06 +00:00
puddly
3c012c497b Bump ZHA dependencies (#118658)
* Bump bellows to 0.39.0

* Do not create a backup if there is no active ZHA gateway object

* Bump universal-silabs-flasher as well
2024-06-03 01:10:05 +00:00
Joost Lekkerkerker
4d2dc9a40e Fix incorrect placeholder in SharkIQ (#118640)
Update strings.json
2024-06-03 01:10:05 +00:00
Jan Bouwhuis
3653a51288 Fix handling undecoded mqtt sensor payloads (#118633) 2024-06-03 01:10:04 +00:00
J. Nick Koston
9366a4e69b Include a traceback for non-strict event loop blocking detection (#118620) 2024-06-03 01:10:03 +00:00
Luca Angemi
1d1af7ec11 Fix telegram bot send_document (#118616) 2024-06-03 01:10:02 +00:00
tronikos
236b19c5b3 Use gemini-1.5-flash-latest in google_generative_ai_conversation.generate_content (#118594) 2024-06-03 01:10:02 +00:00
tronikos
1afbfd687f Strip Google AI text responses (#118593)
* Strip Google AI test responses

* strip each part
2024-06-03 01:10:01 +00:00
Paulus Schoutsen
20159d0277 Add base prompt for LLMs (#118592) 2024-06-03 01:10:00 +00:00
tronikos
4df3d43e45 Stop instructing LLM to not pass the domain as a list (#118590) 2024-06-03 01:10:00 +00:00
Michael
1a588760b9 Avoid future exception during setup of Synology DSM (#118583)
* avoid future exception during integration setup

* clear future flag during setup

* always clear the flag (with comment)
2024-06-03 01:09:58 +00:00
Jan-Philipp Benecke
6ba9e7d5fd Run ruff format for device registry (#118582) 2024-06-03 01:09:58 +00:00
epenet
4b06c5d2fb Update device connections in samsungtv (#118556) 2024-06-03 01:09:57 +00:00
Adam Pasztor
bfc1c62a49 Bump pyads to 3.4.0 (#116934)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-06-03 01:09:57 +00:00
Thomas Ytterdal
c52fabcf77 Ignore myuplink sensors without a description that provide non-numeric values (#115525)
Ignore sensors without a description that provide non-numeric values

Co-authored-by: Jan-Philipp Benecke <jan-philipp@bnck.me>
2024-06-03 01:09:56 +00:00
Paulus Schoutsen
b39d7b39e1 Bump version to 2024.6.0b4 2024-05-31 19:34:58 +00:00
Paulus Schoutsen
c01c155037 Fix openAI tool calls (#118577) 2024-05-31 19:34:38 +00:00
epenet
b459559c8b Add ability to replace connections in DeviceRegistry (#118555)
* Add ability to replace connections in DeviceRegistry

* Add more tests

* Improve coverage

* Apply suggestion

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>

---------

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2024-05-31 19:34:38 +00:00
Maciej Bieniek
d823e56659 In Brother integration use SnmpEngine from SNMP integration (#118554)
Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-05-31 19:34:37 +00:00
Michael Chisholm
e401a0da7f Fix KeyError in dlna_dmr SSDP config flow when checking existing config entries (#118549)
Fix KeyError checking existing dlna_dmr config entries
2024-05-31 19:34:36 +00:00
Tsvi Mostovicz
3f6df28ef3 Fix YAML deprecation breaking version in jewish calendar and media extractor (#118546)
* Fix YAML deprecation breaking version

* Update

* fix media extractor deprecation as well

* Add issue_domain
2024-05-31 19:34:35 +00:00
Joost Lekkerkerker
9b63779063 Fix typo in OWM strings (#118538)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-05-31 19:34:35 +00:00
Josef Zweck
4998fe5e6d Migrate openai_conversation to entry.runtime_data (#118535)
* switch to entry.runtime_data

* check for missing config entry

* Update homeassistant/components/openai_conversation/__init__.py

---------

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2024-05-31 19:34:34 +00:00
Brett Adams
a59c890779 Fix off_grid_vehicle_charging_reserve_percent in Teselemetry (#118532) 2024-05-31 19:34:34 +00:00
Luca Angemi
a2cdb349f4 Fix telegram doing blocking I/O in the event loop (#118531) 2024-05-31 19:34:33 +00:00
J. Nick Koston
267228cae0 Fix openweathermap config entry migration (#118526)
* Fix openweathermap config entry migration

The options keys were accidentally migrated to data so
they could no longer be changed in the options flow

* more fixes

* adjust

* reduce

* fix

* adjust
2024-05-31 19:34:32 +00:00
J. Nick Koston
ba769f4d9f Fix snmp doing blocking I/O in the event loop (#118521) 2024-05-31 19:34:31 +00:00
Denis Shulyaka
c09bc726d1 Add OpenAI Conversation system prompt user_name and llm_context variables (#118512)
* OpenAI Conversation: Add variables to the system prompt

* User name and llm_context

* test for user name

* test for user id

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2024-05-31 19:34:31 +00:00
Josef Zweck
c441f689bf Add typing for OpenAI client and fallout (#118514)
* typing for client and consequences

* Update homeassistant/components/openai_conversation/conversation.py

---------

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2024-05-31 19:34:07 +00:00
Denis Shulyaka
395e1ae31e Add Google Generative AI Conversation system prompt user_name and llm_context variables (#118510)
* Google Generative AI Conversation: Add variables to the system prompt

* User name and llm_context

* test for template variables

* test for template variables

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2024-05-31 19:32:47 +00:00
Bas Brussee
2e45d678b8 Revert "Fix Tibber sensors state class" (#118409)
Revert "Fix Tibber sensors state class (#117085)"

This reverts commit 658c1f3d97.
2024-05-31 19:32:46 +00:00
Paulus Schoutsen
17cb25a5b6 Rename llm.ToolContext to llm.LLMContext (#118566) 2024-05-31 19:32:07 +00:00
Paulus Schoutsen
e5e26de06f Bump version to 2024.6.0b3 2024-05-31 02:20:10 +00:00
tronikos
7dab255c15 Fix unnecessary single quotes escaping in Google AI (#118522) 2024-05-31 02:19:58 +00:00
tronikos
cea7347ed9 Improve LLM prompt (#118520) 2024-05-31 02:19:56 +00:00
tronikos
f4a876c590 Fix LLMs asking which area when there is only one device (#118518)
* Ignore deprecated open and close cover intents for LLMs

* Fix LLMs asking which area when there is only one device

* remove unrelated changed

* remove unrelated changes
2024-05-31 02:19:55 +00:00
tronikos
117a02972d Ignore deprecated open and close cover intents for LLMs (#118515) 2024-05-31 02:19:54 +00:00
G Johansson
3fb40deacb Fix key issue in config entry options in Openweathermap (#118506) 2024-05-31 02:19:54 +00:00
G Johansson
38c88c576b Fix tado non-string unique id for device trackers (#118505)
* Fix tado none string unique id for device trackers

* Add comment

* Fix comment
2024-05-31 02:19:53 +00:00
Paulus Schoutsen
e95b63bc89 Intent script: allow setting description and platforms (#118500)
* Add description to intent_script

* Allow setting platforms
2024-05-31 02:19:51 +00:00
Jan Bouwhuis
ea44b534e6 Fix group platform dependencies (#118499) 2024-05-31 02:19:50 +00:00
G Johansson
7646d853f4 Remove not needed hass object from Tag (#118498) 2024-05-31 02:19:49 +00:00
G Johansson
248c7c33b2 Fix blocking call in holiday (#118496) 2024-05-31 02:19:48 +00:00
Paulus Schoutsen
eb887a707c Ignore the toggle intent (#118491) 2024-05-31 02:19:46 +00:00
David Bonnes
e3ddbb2768 Fix evohome so it doesn't retrieve schedules unnecessarily (#118478) 2024-05-31 02:19:45 +00:00
Jan-Philipp Benecke
008aec5670 Log aiohttp error in rest_command (#118453) 2024-05-31 02:19:45 +00:00
Tsvi Mostovicz
d93d7159db Fix Jewish calendar unique id's (#117985)
* Initial commit

* Fix updating of unique id

* Add testing to check the unique id is being updated correctly

* Reload the config entry and confirm the unique id has not been changed

* Move updating unique_id to __init__.py as suggested

* Change the config_entry variable's name back from config to config_entry

* Move the loop into the update_unique_ids method

* Move test from test_config_flow to test_init

* Try an early optimization to check if we need to update the unique ids

* Mention the correct version

* Implement suggestions

* Ensure all entities are migrated correctly

* Just to be sure keep the previous assertion as well
2024-05-31 02:19:44 +00:00
Diogo Gomes
e6e017dab7 Add support for V2C Trydan 2.1.7 (#117147)
* Support for firmware 2.1.7

* add device ID as unique_id

* add device ID as unique_id

* add test device id as unique_id

* backward compatibility

* move outside try

* Sensor return type

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* not needed

* make slave error enum state

* fix enum

* Update homeassistant/components/v2c/sensor.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/v2c/strings.json

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/v2c/strings.json

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* simplify tests

* fix misspellings from upstream library

* add sensor tests

* just enough coverage for enum sensor

* Refactor V2C tests (#117264)

* Refactor V2C tests

* fix rebase issues

* ruff

* review

* fix https://github.com/home-assistant/core/issues/117296

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-05-31 02:19:43 +00:00
dontinelli
486c72db73 Adjustment of unit of measurement for light (#116695) 2024-05-31 02:19:42 +00:00
Franck Nijhof
4beb184faf Bump version to 2024.6.0b2 2024-05-30 17:02:58 +02:00
Bram Kragten
4951b60b1d Update frontend to 20240530.0 (#118489) 2024-05-30 17:02:37 +02:00
Marcel van der Veldt
9095941b62 Mark Matter climate dry/fan mode support on Panasonic AC (#118485) 2024-05-30 17:02:32 +02:00
Marcel van der Veldt
e906812fbd Extend Matter sensor discovery schemas for Air Purifier / Air Quality devices (#118483)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-05-30 17:02:26 +02:00
Robert Resch
522152e7d2 Set enity_category to config for airgradient select entities (#118477) 2024-05-30 17:02:21 +02:00
lunmay
50acc26812 Typo fix in media_extractor (#118473) 2024-05-30 17:02:16 +02:00
Maciej Bieniek
356374cdc3 Raise ConfigEntryNotReady when there is no _id in the Tractive data (#118467)
Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
2024-05-30 17:02:11 +02:00
Robert Resch
98d905562e Bump deebot-client to 7.3.0 (#118462) 2024-05-30 17:02:05 +02:00
tronikos
48342837c0 Instruct LLM to not pass a list to the domain (#118451) 2024-05-30 17:02:00 +02:00
tronikos
3e0d9516a9 Improve LLM prompt (#118443)
* Improve LLM prompt

* test

* improvements

* improvements
2024-05-30 17:01:55 +02:00
Alexey Guseynov
c6c36718b9 Add Total Volatile Organic Compounds (tVOC) matter discovery schema (#116963) 2024-05-30 17:01:49 +02:00
Franck Nijhof
8ee1d8865c Bump version to 2024.6.0b1 2024-05-30 01:19:49 +02:00
J. Nick Koston
5d5210b47d Fix google_mail doing blocking i/o in the event loop (take 2) (#118441) 2024-05-30 01:18:34 +02:00
tronikos
27cc97bbeb Bump opower to 0.4.6 (#118434) 2024-05-30 01:18:31 +02:00
J. Nick Koston
9728103de4 Fix blocking I/O in the event loop in meteo_france (#118429) 2024-05-30 01:18:28 +02:00
Evgeny
ebf9013569 Fix OpenWeatherMap migration (#118428) 2024-05-30 01:18:24 +02:00
J. Nick Koston
b75f3d9681 Fix workday doing blocking I/O in the event loop (#118422) 2024-05-30 01:18:21 +02:00
J. Nick Koston
0d4990799f Fix google_mail doing blocking I/O in the event loop (#118421)
fixes #118411
2024-05-30 01:18:17 +02:00
J. Nick Koston
1e77a59561 Fix google_tasks doing blocking I/O in the event loop (#118418)
fixes #118407
2024-05-30 01:17:37 +02:00
J. Nick Koston
7ee2f09fe1 Ensure paho.mqtt.client is imported in the executor (#118412)
fixes #118405
2024-05-30 00:12:34 +02:00
Michael Hansen
23d9b4b17f Handle case where timer device id exists but is not registered (delayed command) (#118410)
Handle case where device id exists but is not registered
2024-05-30 00:12:30 +02:00
Marcel van der Veldt
a580d834da Fix light discovery for Matter dimmable plugin unit (#118404) 2024-05-30 00:12:27 +02:00
Marcel van der Veldt
4fb6e59fdc Add translation strings for Matter Fan presets (#118401) 2024-05-30 00:12:24 +02:00
swcloudgenie
ad3823764a New official genie garage integration (#117020)
* new official genie garage integration

* move api constants into api module

* move scan interval constant to cover.py
2024-05-30 00:12:19 +02:00
Franck Nijhof
024de4f8a6 Bump version to 2024.6.0b0 2024-05-29 20:17:13 +02:00
2151 changed files with 70836 additions and 20118 deletions

View File

@@ -120,24 +120,20 @@ tests: &tests
- pylint/**
- requirements_test_pre_commit.txt
- requirements_test.txt
- tests/*.py
- tests/auth/**
- tests/backports/**
- tests/common.py
- tests/components/history/**
- tests/components/logbook/**
- tests/components/recorder/**
- tests/components/sensor/**
- tests/conftest.py
- tests/hassfest/**
- tests/helpers/**
- tests/ignore_uncaught_exceptions.py
- tests/mock/**
- tests/pylint/**
- tests/scripts/**
- tests/syrupy.py
- tests/test_util/**
- tests/testing_config/**
- tests/typing.py
- tests/util/**
other: &other

View File

@@ -87,9 +87,12 @@ omit =
homeassistant/components/aprilaire/climate.py
homeassistant/components/aprilaire/coordinator.py
homeassistant/components/aprilaire/entity.py
homeassistant/components/aprilaire/select.py
homeassistant/components/aprilaire/sensor.py
homeassistant/components/apsystems/__init__.py
homeassistant/components/apsystems/coordinator.py
homeassistant/components/apsystems/entity.py
homeassistant/components/apsystems/number.py
homeassistant/components/apsystems/sensor.py
homeassistant/components/aqualogic/*
homeassistant/components/aquostv/media_player.py
@@ -120,6 +123,7 @@ omit =
homeassistant/components/awair/coordinator.py
homeassistant/components/azure_service_bus/*
homeassistant/components/baf/__init__.py
homeassistant/components/baf/binary_sensor.py
homeassistant/components/baf/climate.py
homeassistant/components/baf/entity.py
homeassistant/components/baf/fan.py
@@ -128,7 +132,6 @@ omit =
homeassistant/components/baf/sensor.py
homeassistant/components/baf/switch.py
homeassistant/components/baidu/tts.py
homeassistant/components/bang_olufsen/__init__.py
homeassistant/components/bang_olufsen/entity.py
homeassistant/components/bang_olufsen/media_player.py
homeassistant/components/bang_olufsen/util.py
@@ -180,7 +183,6 @@ omit =
homeassistant/components/canary/camera.py
homeassistant/components/cert_expiry/helper.py
homeassistant/components/channels/*
homeassistant/components/circuit/*
homeassistant/components/cisco_ios/device_tracker.py
homeassistant/components/cisco_mobility_express/device_tracker.py
homeassistant/components/cisco_webex_teams/notify.py
@@ -536,7 +538,6 @@ omit =
homeassistant/components/hko/weather.py
homeassistant/components/hlk_sw16/__init__.py
homeassistant/components/hlk_sw16/switch.py
homeassistant/components/home_connect/binary_sensor.py
homeassistant/components/home_connect/entity.py
homeassistant/components/home_connect/light.py
homeassistant/components/home_connect/switch.py
@@ -816,6 +817,7 @@ omit =
homeassistant/components/motionblinds_ble/cover.py
homeassistant/components/motionblinds_ble/entity.py
homeassistant/components/motionblinds_ble/select.py
homeassistant/components/motionblinds_ble/sensor.py
homeassistant/components/motionmount/__init__.py
homeassistant/components/motionmount/binary_sensor.py
homeassistant/components/motionmount/entity.py
@@ -853,7 +855,9 @@ omit =
homeassistant/components/nad/media_player.py
homeassistant/components/nanoleaf/__init__.py
homeassistant/components/nanoleaf/button.py
homeassistant/components/nanoleaf/coordinator.py
homeassistant/components/nanoleaf/entity.py
homeassistant/components/nanoleaf/event.py
homeassistant/components/nanoleaf/light.py
homeassistant/components/neato/__init__.py
homeassistant/components/neato/api.py
@@ -1061,7 +1065,6 @@ omit =
homeassistant/components/pushbullet/sensor.py
homeassistant/components/pushover/notify.py
homeassistant/components/pushsafer/notify.py
homeassistant/components/pyload/sensor.py
homeassistant/components/qbittorrent/__init__.py
homeassistant/components/qbittorrent/coordinator.py
homeassistant/components/qbittorrent/sensor.py
@@ -1109,6 +1112,7 @@ omit =
homeassistant/components/refoss/bridge.py
homeassistant/components/refoss/coordinator.py
homeassistant/components/refoss/entity.py
homeassistant/components/refoss/sensor.py
homeassistant/components/refoss/switch.py
homeassistant/components/refoss/util.py
homeassistant/components/rejseplanen/sensor.py
@@ -1257,9 +1261,6 @@ omit =
homeassistant/components/solaredge/__init__.py
homeassistant/components/solaredge/coordinator.py
homeassistant/components/solaredge_local/sensor.py
homeassistant/components/solarlog/__init__.py
homeassistant/components/solarlog/coordinator.py
homeassistant/components/solarlog/sensor.py
homeassistant/components/solax/__init__.py
homeassistant/components/solax/sensor.py
homeassistant/components/soma/__init__.py
@@ -1650,6 +1651,7 @@ omit =
homeassistant/components/xiaomi_miio/remote.py
homeassistant/components/xiaomi_miio/sensor.py
homeassistant/components/xiaomi_miio/switch.py
homeassistant/components/xiaomi_miio/typing.py
homeassistant/components/xiaomi_tv/media_player.py
homeassistant/components/xmpp/notify.py
homeassistant/components/xs1/*
@@ -1688,8 +1690,6 @@ omit =
homeassistant/components/yolink/siren.py
homeassistant/components/yolink/switch.py
homeassistant/components/yolink/valve.py
homeassistant/components/youless/__init__.py
homeassistant/components/youless/sensor.py
homeassistant/components/zabbix/*
homeassistant/components/zamg/coordinator.py
homeassistant/components/zengge/light.py

View File

@@ -32,6 +32,7 @@
"python.pythonPath": "/home/vscode/.local/ha-venv/bin/python",
"python.terminal.activateEnvInCurrentTerminal": true,
"python.testing.pytestArgs": ["--no-cov"],
"pylint.importStrategy": "fromEnvironment",
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,

View File

@@ -10,7 +10,7 @@ on:
env:
BUILD_TYPE: core
DEFAULT_PYTHON: "3.12.3"
DEFAULT_PYTHON: "3.12"
PIP_TIMEOUT: 60
UV_HTTP_TIMEOUT: 60
UV_SYSTEM_PYTHON: "true"
@@ -27,7 +27,7 @@ jobs:
publish: ${{ steps.version.outputs.publish }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
with:
fetch-depth: 0
@@ -90,11 +90,11 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@v5
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/frontend
@@ -105,7 +105,7 @@ jobs:
- name: Download nightly wheels of intents
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@v5
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/intents-package
@@ -242,7 +242,7 @@ jobs:
- green
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set build additional args
run: |
@@ -279,7 +279,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Initialize git
uses: home-assistant/actions/helpers/git-init@master
@@ -320,7 +320,7 @@ jobs:
registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"]
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Install Cosign
uses: sigstore/cosign-installer@v3.5.0
@@ -450,7 +450,7 @@ jobs:
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.0

View File

@@ -37,8 +37,8 @@ env:
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 8
HA_SHORT_VERSION: "2024.7"
DEFAULT_PYTHON: "3.12.3"
ALL_PYTHON_VERSIONS: "['3.12.3']"
DEFAULT_PYTHON: "3.12"
ALL_PYTHON_VERSIONS: "['3.12']"
# 10.3 is the oldest supported version
# - 10.3.32 is the version currently shipped with Synology (as of 17 Feb 2022)
# 10.6 is the current long-term-support
@@ -89,7 +89,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Generate partial Python venv restore key
id: generate_python_cache_key
run: |
@@ -226,7 +226,7 @@ jobs:
- info
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.0
@@ -272,7 +272,7 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.0
id: python
@@ -312,7 +312,7 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.0
id: python
@@ -351,7 +351,7 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.0
id: python
@@ -445,7 +445,7 @@ jobs:
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.0
@@ -488,6 +488,7 @@ jobs:
sudo apt-get -y install \
bluez \
ffmpeg \
libturbojpeg \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
@@ -522,7 +523,7 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.0
@@ -554,7 +555,7 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.0
@@ -587,7 +588,7 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.0
@@ -620,6 +621,51 @@ jobs:
python --version
pylint --ignore-missing-annotations=y homeassistant/components/${{ needs.info.outputs.integrations_glob }}
pylint-tests:
name: Check pylint on tests
runs-on: ubuntu-22.04
timeout-minutes: 20
if: |
(github.event.inputs.mypy-only != 'true' || github.event.inputs.pylint-only == 'true')
&& (needs.info.outputs.tests_glob || needs.info.outputs.test_full_suite == 'true')
needs:
- info
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.0.2
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Register pylint problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/pylint.json"
- name: Run pylint (fully)
if: needs.info.outputs.test_full_suite == 'true'
run: |
. venv/bin/activate
python --version
pylint --ignore-missing-annotations=y tests
- name: Run pylint (partially)
if: needs.info.outputs.test_full_suite == 'false'
shell: bash
run: |
. venv/bin/activate
python --version
pylint --ignore-missing-annotations=y tests/components/${{ needs.info.outputs.tests_glob }}
mypy:
name: Check mypy
runs-on: ubuntu-22.04
@@ -631,7 +677,7 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.0
@@ -702,9 +748,10 @@ jobs:
sudo apt-get -y install \
bluez \
ffmpeg \
libturbojpeg \
libgammu-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.0
@@ -764,9 +811,10 @@ jobs:
sudo apt-get -y install \
bluez \
ffmpeg \
libturbojpeg \
libgammu-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.0
@@ -881,9 +929,10 @@ jobs:
sudo apt-get -y install \
bluez \
ffmpeg \
libturbojpeg \
libmariadb-dev-compat
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.0
@@ -1005,9 +1054,10 @@ jobs:
sudo apt-get -y install \
bluez \
ffmpeg \
libturbojpeg \
postgresql-server-dev-14
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.0
@@ -1102,18 +1152,19 @@ jobs:
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Download all coverage artifacts
uses: actions/download-artifact@v4.1.7
with:
pattern: coverage-*
- name: Upload coverage to Codecov
if: needs.info.outputs.test_full_suite == 'true'
uses: codecov/codecov-action@v4.4.1
uses: codecov/codecov-action@v4.5.0
with:
fail_ci_if_error: true
flags: full-suite
token: ${{ secrets.CODECOV_TOKEN }}
version: v0.6.0
pytest-partial:
runs-on: ubuntu-22.04
@@ -1148,9 +1199,10 @@ jobs:
sudo apt-get -y install \
bluez \
ffmpeg \
libturbojpeg \
libgammu-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.0
@@ -1237,14 +1289,15 @@ jobs:
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Download all coverage artifacts
uses: actions/download-artifact@v4.1.7
with:
pattern: coverage-*
- name: Upload coverage to Codecov
if: needs.info.outputs.test_full_suite == 'false'
uses: codecov/codecov-action@v4.4.1
uses: codecov/codecov-action@v4.5.0
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
version: v0.6.0

View File

@@ -21,14 +21,14 @@ jobs:
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.25.8
uses: github/codeql-action/init@v3.25.10
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.25.8
uses: github/codeql-action/analyze@v3.25.10
with:
category: "/language:python"

View File

@@ -10,7 +10,7 @@ on:
- "**strings.json"
env:
DEFAULT_PYTHON: "3.12.3"
DEFAULT_PYTHON: "3.12"
jobs:
upload:
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.0

View File

@@ -17,7 +17,7 @@ on:
- "script/gen_requirements_all.py"
env:
DEFAULT_PYTHON: "3.12.3"
DEFAULT_PYTHON: "3.12"
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name}}
@@ -32,7 +32,7 @@ jobs:
architectures: ${{ steps.info.outputs.architectures }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
@@ -118,7 +118,7 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Download env_file
uses: actions/download-artifact@v4.1.7
@@ -156,7 +156,7 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.1.6
uses: actions/checkout@v4.1.7
- name: Download env_file
uses: actions/download-artifact@v4.1.7

View File

@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.8
rev: v0.4.9
hooks:
- id: ruff
args:
@@ -69,7 +69,7 @@ repos:
entry: script/run-in-env.sh pylint -j 0 --ignore-missing-annotations=y
language: script
types_or: [python, pyi]
files: ^homeassistant/.+\.(py|pyi)$
files: ^(homeassistant|tests)/.+\.(py|pyi)$
- id: gen_requirements_all
name: gen_requirements_all
entry: script/run-in-env.sh python3 -m script.gen_requirements_all

View File

@@ -261,6 +261,7 @@ homeassistant.components.jellyfin.*
homeassistant.components.jewish_calendar.*
homeassistant.components.jvc_projector.*
homeassistant.components.kaleidescape.*
homeassistant.components.knocki.*
homeassistant.components.knx.*
homeassistant.components.kraken.*
homeassistant.components.lacrosse.*
@@ -369,6 +370,7 @@ homeassistant.components.rhasspy.*
homeassistant.components.ridwell.*
homeassistant.components.ring.*
homeassistant.components.rituals_perfume_genie.*
homeassistant.components.roborock.*
homeassistant.components.roku.*
homeassistant.components.romy.*
homeassistant.components.rpi_power.*

View File

@@ -4,5 +4,7 @@
// https://github.com/microsoft/vscode-python/issues/14067
"python.testing.pytestArgs": ["--no-cov"],
// https://code.visualstudio.com/docs/python/testing#_pytest-configuration-settings
"python.testing.pytestEnabled": false
"python.testing.pytestEnabled": false,
// https://code.visualstudio.com/docs/python/linting#_general-settings
"pylint.importStrategy": "fromEnvironment"
}

View File

@@ -239,7 +239,6 @@ build.json @home-assistant/supervisor
/tests/components/ccm15/ @ocalvo
/homeassistant/components/cert_expiry/ @jjlawren
/tests/components/cert_expiry/ @jjlawren
/homeassistant/components/circuit/ @braam
/homeassistant/components/cisco_ios/ @fbradyirl
/homeassistant/components/cisco_mobility_express/ @fbradyirl
/homeassistant/components/cisco_webex_teams/ @fbradyirl
@@ -632,8 +631,8 @@ build.json @home-assistant/supervisor
/tests/components/huum/ @frwickst
/homeassistant/components/hvv_departures/ @vigonotion
/tests/components/hvv_departures/ @vigonotion
/homeassistant/components/hydrawise/ @dknowles2 @ptcryan
/tests/components/hydrawise/ @dknowles2 @ptcryan
/homeassistant/components/hydrawise/ @dknowles2 @thomaskistler @ptcryan
/tests/components/hydrawise/ @dknowles2 @thomaskistler @ptcryan
/homeassistant/components/hyperion/ @dermotduffy
/tests/components/hyperion/ @dermotduffy
/homeassistant/components/ialarm/ @RyuzakiKK
@@ -738,6 +737,8 @@ build.json @home-assistant/supervisor
/tests/components/kitchen_sink/ @home-assistant/core
/homeassistant/components/kmtronic/ @dgomes
/tests/components/kmtronic/ @dgomes
/homeassistant/components/knocki/ @joostlek @jgatto1
/tests/components/knocki/ @joostlek @jgatto1
/homeassistant/components/knx/ @Julius2342 @farmio @marvin-w
/tests/components/knx/ @Julius2342 @farmio @marvin-w
/homeassistant/components/kodi/ @OnFreund
@@ -827,6 +828,8 @@ build.json @home-assistant/supervisor
/tests/components/matrix/ @PaarthShah
/homeassistant/components/matter/ @home-assistant/matter
/tests/components/matter/ @home-assistant/matter
/homeassistant/components/mealie/ @joostlek
/tests/components/mealie/ @joostlek
/homeassistant/components/meater/ @Sotolotl @emontnemery
/tests/components/meater/ @Sotolotl @emontnemery
/homeassistant/components/medcom_ble/ @elafargue
@@ -838,6 +841,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/media_source/ @hunterjm
/tests/components/media_source/ @hunterjm
/homeassistant/components/mediaroom/ @dgomes
/homeassistant/components/melcloud/ @erwindouna
/tests/components/melcloud/ @erwindouna
/homeassistant/components/melissa/ @kennedyshead
/tests/components/melissa/ @kennedyshead
/homeassistant/components/melnor/ @vanstinator
@@ -910,8 +915,8 @@ build.json @home-assistant/supervisor
/tests/components/myuplink/ @pajzo @astrandb
/homeassistant/components/nam/ @bieniu
/tests/components/nam/ @bieniu
/homeassistant/components/nanoleaf/ @milanmeu
/tests/components/nanoleaf/ @milanmeu
/homeassistant/components/nanoleaf/ @milanmeu @joostlek
/tests/components/nanoleaf/ @milanmeu @joostlek
/homeassistant/components/neato/ @Santobert
/tests/components/neato/ @Santobert
/homeassistant/components/nederlandse_spoorwegen/ @YarmoM
@@ -992,6 +997,7 @@ build.json @home-assistant/supervisor
/tests/components/ondilo_ico/ @JeromeHXP
/homeassistant/components/onewire/ @garbled1 @epenet
/tests/components/onewire/ @garbled1 @epenet
/homeassistant/components/onkyo/ @arturpragacz
/homeassistant/components/onvif/ @hunterjm
/tests/components/onvif/ @hunterjm
/homeassistant/components/open_meteo/ @frenck
@@ -1100,6 +1106,8 @@ build.json @home-assistant/supervisor
/tests/components/pvoutput/ @frenck
/homeassistant/components/pvpc_hourly_pricing/ @azogue
/tests/components/pvpc_hourly_pricing/ @azogue
/homeassistant/components/pyload/ @tr4nt0r
/tests/components/pyload/ @tr4nt0r
/homeassistant/components/qbittorrent/ @geoffreylagaisse @finder39
/tests/components/qbittorrent/ @geoffreylagaisse @finder39
/homeassistant/components/qingping/ @bdraco
@@ -1178,8 +1186,8 @@ build.json @home-assistant/supervisor
/tests/components/rituals_perfume_genie/ @milanmeu @frenck
/homeassistant/components/rmvtransport/ @cgtobi
/tests/components/rmvtransport/ @cgtobi
/homeassistant/components/roborock/ @humbertogontijo @Lash-L
/tests/components/roborock/ @humbertogontijo @Lash-L
/homeassistant/components/roborock/ @Lash-L
/tests/components/roborock/ @Lash-L
/homeassistant/components/roku/ @ctalkington
/tests/components/roku/ @ctalkington
/homeassistant/components/romy/ @xeniter
@@ -1303,8 +1311,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/solaredge/ @frenck @bdraco
/tests/components/solaredge/ @frenck @bdraco
/homeassistant/components/solaredge_local/ @drobtravels @scheric
/homeassistant/components/solarlog/ @Ernst79
/tests/components/solarlog/ @Ernst79
/homeassistant/components/solarlog/ @Ernst79 @dontinelli
/tests/components/solarlog/ @Ernst79 @dontinelli
/homeassistant/components/solax/ @squishykid
/tests/components/solax/ @squishykid
/homeassistant/components/soma/ @ratsept @sebfortier2288
@@ -1452,8 +1460,8 @@ build.json @home-assistant/supervisor
/tests/components/tomorrowio/ @raman325 @lymanepp
/homeassistant/components/totalconnect/ @austinmroczek
/tests/components/totalconnect/ @austinmroczek
/homeassistant/components/tplink/ @rytilahti @thegardenmonkey @bdraco @sdb9696
/tests/components/tplink/ @rytilahti @thegardenmonkey @bdraco @sdb9696
/homeassistant/components/tplink/ @rytilahti @bdraco @sdb9696
/tests/components/tplink/ @rytilahti @bdraco @sdb9696
/homeassistant/components/tplink_omada/ @MarkGodwin
/tests/components/tplink_omada/ @MarkGodwin
/homeassistant/components/traccar/ @ludeeus

View File

@@ -12,7 +12,7 @@ ENV \
ARG QEMU_CPU
# Install uv
RUN pip3 install uv==0.1.43
RUN pip3 install uv==0.2.13
WORKDIR /usr/src

View File

@@ -1,10 +1,10 @@
image: ghcr.io/home-assistant/{arch}-homeassistant
build_from:
aarch64: ghcr.io/home-assistant/aarch64-homeassistant-base:2024.06.0
armhf: ghcr.io/home-assistant/armhf-homeassistant-base:2024.06.0
armv7: ghcr.io/home-assistant/armv7-homeassistant-base:2024.06.0
amd64: ghcr.io/home-assistant/amd64-homeassistant-base:2024.06.0
i386: ghcr.io/home-assistant/i386-homeassistant-base:2024.06.0
aarch64: ghcr.io/home-assistant/aarch64-homeassistant-base:2024.06.1
armhf: ghcr.io/home-assistant/armhf-homeassistant-base:2024.06.1
armv7: ghcr.io/home-assistant/armv7-homeassistant-base:2024.06.1
amd64: ghcr.io/home-assistant/amd64-homeassistant-base:2024.06.1
i386: ghcr.io/home-assistant/i386-homeassistant-base:2024.06.1
codenotary:
signer: notary@home-assistant.io
base_image: notary@home-assistant.io

View File

@@ -28,6 +28,7 @@ from .const import ACCESS_TOKEN_EXPIRATION, GROUP_ID_ADMIN, REFRESH_TOKEN_EXPIRA
from .mfa_modules import MultiFactorAuthModule, auth_mfa_module_from_config
from .models import AuthFlowResult
from .providers import AuthProvider, LoginFlow, auth_provider_from_config
from .providers.homeassistant import HassAuthProvider
EVENT_USER_ADDED = "user_added"
EVENT_USER_UPDATED = "user_updated"
@@ -73,6 +74,13 @@ async def auth_manager_from_config(
key = (provider.type, provider.id)
provider_hash[key] = provider
if isinstance(provider, HassAuthProvider):
# Can be removed in 2026.7 with the legacy mode of homeassistant auth provider
# We need to initialize the provider to create the repair if needed as otherwise
# the provider will be initialized on first use, which could be rare as users
# don't frequently change auth settings
await provider.async_initialize()
if module_configs:
modules = await asyncio.gather(
*(auth_mfa_module_from_config(hass, config) for config in module_configs)
@@ -374,6 +382,13 @@ class AuthManager:
self.hass.bus.async_fire(EVENT_USER_UPDATED, {"user_id": user.id})
@callback
def async_update_user_credentials_data(
self, credentials: models.Credentials, data: dict[str, Any]
) -> None:
"""Update credentials data."""
self._store.async_update_user_credentials_data(credentials, data=data)
async def async_activate_user(self, user: models.User) -> None:
"""Activate a user."""
await self._store.async_activate_user(user)

View File

@@ -296,6 +296,14 @@ class AuthStore:
refresh_token.expire_at = None
self._async_schedule_save()
@callback
def async_update_user_credentials_data(
self, credentials: models.Credentials, data: dict[str, Any]
) -> None:
"""Update credentials data."""
credentials.data = data
self._async_schedule_save()
async def async_load(self) -> None: # noqa: C901
"""Load the users."""
if self._loaded:

View File

@@ -14,6 +14,7 @@ import voluptuous as vol
from homeassistant.const import CONF_ID
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import issue_registry as ir
from homeassistant.helpers.storage import Store
from ..models import AuthFlowResult, Credentials, UserMeta
@@ -55,6 +56,27 @@ class InvalidUser(HomeAssistantError):
"""
class InvalidUsername(InvalidUser):
"""Raised when invalid username is specified.
Will not be raised when validating authentication.
"""
def __init__(
self,
*args: object,
translation_key: str | None = None,
translation_placeholders: dict[str, str] | None = None,
) -> None:
"""Initialize exception."""
super().__init__(
*args,
translation_domain="auth",
translation_key=translation_key,
translation_placeholders=translation_placeholders,
)
class Data:
"""Hold the user data."""
@@ -67,13 +89,15 @@ class Data:
self._data: dict[str, list[dict[str, str]]] | None = None
# Legacy mode will allow usernames to start/end with whitespace
# and will compare usernames case-insensitive.
# Remove in 2020 or when we launch 1.0.
# Deprecated in June 2019 and will be removed in 2026.7
self.is_legacy = False
@callback
def normalize_username(self, username: str) -> str:
def normalize_username(
self, username: str, *, force_normalize: bool = False
) -> str:
"""Normalize a username based on the mode."""
if self.is_legacy:
if self.is_legacy and not force_normalize:
return username
return username.strip().casefold()
@@ -83,44 +107,49 @@ class Data:
if (data := await self._store.async_load()) is None:
data = cast(dict[str, list[dict[str, str]]], {"users": []})
seen: set[str] = set()
self._async_check_for_not_normalized_usernames(data)
self._data = data
@callback
def _async_check_for_not_normalized_usernames(
self, data: dict[str, list[dict[str, str]]]
) -> None:
not_normalized_usernames: set[str] = set()
for user in data["users"]:
username = user["username"]
# check if we have duplicates
if (folded := username.casefold()) in seen:
self.is_legacy = True
if self.normalize_username(username, force_normalize=True) != username:
logging.getLogger(__name__).warning(
(
"Home Assistant auth provider is running in legacy mode "
"because we detected usernames that are case-insensitive"
"equivalent. Please change the username: '%s'."
"because we detected usernames that are normalized (lowercase and without spaces)."
" Please change the username: '%s'."
),
username,
)
not_normalized_usernames.add(username)
break
seen.add(folded)
# check if we have unstripped usernames
if username != username.strip():
self.is_legacy = True
logging.getLogger(__name__).warning(
(
"Home Assistant auth provider is running in legacy mode "
"because we detected usernames that start or end in a "
"space. Please change the username: '%s'."
),
username,
)
break
self._data = data
if not_normalized_usernames:
self.is_legacy = True
ir.async_create_issue(
self.hass,
"auth",
"homeassistant_provider_not_normalized_usernames",
breaks_in_ha_version="2026.7.0",
is_fixable=False,
severity=ir.IssueSeverity.WARNING,
translation_key="homeassistant_provider_not_normalized_usernames",
translation_placeholders={
"usernames": f'- "{'"\n- "'.join(sorted(not_normalized_usernames))}"'
},
learn_more_url="homeassistant://config/users",
)
else:
self.is_legacy = False
ir.async_delete_issue(
self.hass, "auth", "homeassistant_provider_not_normalized_usernames"
)
@property
def users(self) -> list[dict[str, str]]:
@@ -162,13 +191,11 @@ class Data:
return hashed
def add_auth(self, username: str, password: str) -> None:
"""Add a new authenticated user/pass."""
username = self.normalize_username(username)
"""Add a new authenticated user/pass.
if any(
self.normalize_username(user["username"]) == username for user in self.users
):
raise InvalidUser
Raises InvalidUsername if the new username is invalid.
"""
self._validate_new_username(username)
self.users.append(
{
@@ -207,6 +234,49 @@ class Data:
else:
raise InvalidUser
@callback
def _validate_new_username(self, new_username: str) -> None:
"""Validate that username is normalized and unique.
Raises InvalidUsername if the new username is invalid.
"""
normalized_username = self.normalize_username(
new_username, force_normalize=True
)
if normalized_username != new_username:
raise InvalidUsername(
translation_key="username_not_normalized",
translation_placeholders={"new_username": new_username},
)
if any(
self.normalize_username(user["username"]) == normalized_username
for user in self.users
):
raise InvalidUsername(
translation_key="username_already_exists",
translation_placeholders={"username": new_username},
)
@callback
def change_username(self, username: str, new_username: str) -> None:
"""Update the username.
Raises InvalidUser if user cannot be found.
Raises InvalidUsername if the new username is invalid.
"""
username = self.normalize_username(username)
self._validate_new_username(new_username)
for user in self.users:
if self.normalize_username(user["username"]) == username:
user["username"] = new_username
assert self._data is not None
self._async_check_for_not_normalized_usernames(self._data)
break
else:
raise InvalidUser
async def async_save(self) -> None:
"""Save data."""
if self._data is not None:
@@ -278,6 +348,20 @@ class HassAuthProvider(AuthProvider):
)
await self.data.async_save()
async def async_change_username(
self, credential: Credentials, new_username: str
) -> None:
"""Validate new username and change it including updating credentials object."""
if self.data is None:
await self.async_initialize()
assert self.data is not None
self.data.change_username(credential.data["username"], new_username)
self.hass.auth.async_update_user_credentials_data(
credential, {**credential.data, "username": new_username}
)
await self.data.async_save()
async def async_get_or_create_credentials(
self, flow_result: Mapping[str, str]
) -> Credentials:

View File

@@ -1,123 +0,0 @@
"""Support Legacy API password auth provider.
It will be removed when auth system production ready
"""
from __future__ import annotations
from collections.abc import Mapping
import hmac
from typing import Any, cast
import voluptuous as vol
from homeassistant.core import async_get_hass, callback
from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from ..models import AuthFlowResult, Credentials, UserMeta
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
AUTH_PROVIDER_TYPE = "legacy_api_password"
CONF_API_PASSWORD = "api_password"
_CONFIG_SCHEMA = AUTH_PROVIDER_SCHEMA.extend(
{vol.Required(CONF_API_PASSWORD): cv.string}, extra=vol.PREVENT_EXTRA
)
def _create_repair_and_validate(config: dict[str, Any]) -> dict[str, Any]:
async_create_issue(
async_get_hass(),
"auth",
"deprecated_legacy_api_password",
breaks_in_ha_version="2024.6.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_legacy_api_password",
)
return _CONFIG_SCHEMA(config) # type: ignore[no-any-return]
CONFIG_SCHEMA = _create_repair_and_validate
LEGACY_USER_NAME = "Legacy API password user"
class InvalidAuthError(HomeAssistantError):
"""Raised when submitting invalid authentication."""
@AUTH_PROVIDERS.register(AUTH_PROVIDER_TYPE)
class LegacyApiPasswordAuthProvider(AuthProvider):
"""An auth provider support legacy api_password."""
DEFAULT_TITLE = "Legacy API Password"
@property
def api_password(self) -> str:
"""Return api_password."""
return str(self.config[CONF_API_PASSWORD])
async def async_login_flow(self, context: dict[str, Any] | None) -> LoginFlow:
"""Return a flow to login."""
return LegacyLoginFlow(self)
@callback
def async_validate_login(self, password: str) -> None:
"""Validate password."""
api_password = str(self.config[CONF_API_PASSWORD])
if not hmac.compare_digest(
api_password.encode("utf-8"), password.encode("utf-8")
):
raise InvalidAuthError
async def async_get_or_create_credentials(
self, flow_result: Mapping[str, str]
) -> Credentials:
"""Return credentials for this login."""
credentials = await self.async_credentials()
if credentials:
return credentials[0]
return self.async_create_credentials({})
async def async_user_meta_for_credentials(
self, credentials: Credentials
) -> UserMeta:
"""Return info for the user.
Will be used to populate info when creating a new user.
"""
return UserMeta(name=LEGACY_USER_NAME, is_active=True)
class LegacyLoginFlow(LoginFlow):
"""Handler for the login flow."""
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> AuthFlowResult:
"""Handle the step of the form."""
errors = {}
if user_input is not None:
try:
cast(
LegacyApiPasswordAuthProvider, self._auth_provider
).async_validate_login(user_input["password"])
except InvalidAuthError:
errors["base"] = "invalid_auth"
if not errors:
return await self.async_finish({})
return self.async_show_form(
step_id="init",
data_schema=vol.Schema({vol.Required("password"): str}),
errors=errors,
)

View File

@@ -1,7 +1,9 @@
"""Block blocking calls being done in asyncio."""
import builtins
from collections.abc import Callable
from contextlib import suppress
from dataclasses import dataclass
import glob
from http.client import HTTPConnection
import importlib
@@ -46,53 +48,131 @@ def _check_sleep_call_allowed(mapped_args: dict[str, Any]) -> bool:
return False
@dataclass(slots=True, frozen=True)
class BlockingCall:
"""Class to hold information about a blocking call."""
original_func: Callable
object: object
function: str
check_allowed: Callable[[dict[str, Any]], bool] | None
strict: bool
strict_core: bool
skip_for_tests: bool
_BLOCKING_CALLS: tuple[BlockingCall, ...] = (
BlockingCall(
original_func=HTTPConnection.putrequest,
object=HTTPConnection,
function="putrequest",
check_allowed=None,
strict=True,
strict_core=True,
skip_for_tests=False,
),
BlockingCall(
original_func=time.sleep,
object=time,
function="sleep",
check_allowed=_check_sleep_call_allowed,
strict=True,
strict_core=True,
skip_for_tests=False,
),
BlockingCall(
original_func=glob.glob,
object=glob,
function="glob",
check_allowed=None,
strict=False,
strict_core=False,
skip_for_tests=False,
),
BlockingCall(
original_func=glob.iglob,
object=glob,
function="iglob",
check_allowed=None,
strict=False,
strict_core=False,
skip_for_tests=False,
),
BlockingCall(
original_func=os.walk,
object=os,
function="walk",
check_allowed=None,
strict=False,
strict_core=False,
skip_for_tests=False,
),
BlockingCall(
original_func=os.listdir,
object=os,
function="listdir",
check_allowed=None,
strict=False,
strict_core=False,
skip_for_tests=True,
),
BlockingCall(
original_func=os.scandir,
object=os,
function="scandir",
check_allowed=None,
strict=False,
strict_core=False,
skip_for_tests=True,
),
BlockingCall(
original_func=builtins.open,
object=builtins,
function="open",
check_allowed=_check_file_allowed,
strict=False,
strict_core=False,
skip_for_tests=True,
),
BlockingCall(
original_func=importlib.import_module,
object=importlib,
function="import_module",
check_allowed=_check_import_call_allowed,
strict=False,
strict_core=False,
skip_for_tests=True,
),
)
@dataclass(slots=True)
class BlockedCalls:
"""Class to track which calls are blocked."""
calls: set[BlockingCall]
_BLOCKED_CALLS = BlockedCalls(set())
def enable() -> None:
"""Enable the detection of blocking calls in the event loop."""
calls = _BLOCKED_CALLS.calls
if calls:
raise RuntimeError("Blocking call detection is already enabled")
loop_thread_id = threading.get_ident()
# Prevent urllib3 and requests doing I/O in event loop
HTTPConnection.putrequest = protect_loop( # type: ignore[method-assign]
HTTPConnection.putrequest, loop_thread_id=loop_thread_id
)
for blocking_call in _BLOCKING_CALLS:
if _IN_TESTS and blocking_call.skip_for_tests:
continue
# Prevent sleeping in event loop.
time.sleep = protect_loop(
time.sleep,
check_allowed=_check_sleep_call_allowed,
loop_thread_id=loop_thread_id,
)
glob.glob = protect_loop(
glob.glob, strict_core=False, strict=False, loop_thread_id=loop_thread_id
)
glob.iglob = protect_loop(
glob.iglob, strict_core=False, strict=False, loop_thread_id=loop_thread_id
)
os.walk = protect_loop(
os.walk, strict_core=False, strict=False, loop_thread_id=loop_thread_id
)
if not _IN_TESTS:
# Prevent files being opened inside the event loop
os.listdir = protect_loop( # type: ignore[assignment]
os.listdir, strict_core=False, strict=False, loop_thread_id=loop_thread_id
)
os.scandir = protect_loop( # type: ignore[assignment]
os.scandir, strict_core=False, strict=False, loop_thread_id=loop_thread_id
)
builtins.open = protect_loop( # type: ignore[assignment]
builtins.open,
strict_core=False,
strict=False,
check_allowed=_check_file_allowed,
loop_thread_id=loop_thread_id,
)
# unittest uses `importlib.import_module` to do mocking
# so we cannot protect it if we are running tests
importlib.import_module = protect_loop(
importlib.import_module,
strict_core=False,
strict=False,
check_allowed=_check_import_call_allowed,
protected_function = protect_loop(
blocking_call.original_func,
strict=blocking_call.strict,
strict_core=blocking_call.strict_core,
check_allowed=blocking_call.check_allowed,
loop_thread_id=loop_thread_id,
)
setattr(blocking_call.object, blocking_call.function, protected_function)
calls.add(blocking_call)

View File

@@ -256,22 +256,39 @@ async def async_setup_hass(
runtime_config: RuntimeConfig,
) -> core.HomeAssistant | None:
"""Set up Home Assistant."""
hass = core.HomeAssistant(runtime_config.config_dir)
async_enable_logging(
hass,
runtime_config.verbose,
runtime_config.log_rotate_days,
runtime_config.log_file,
runtime_config.log_no_color,
)
def create_hass() -> core.HomeAssistant:
"""Create the hass object and do basic setup."""
hass = core.HomeAssistant(runtime_config.config_dir)
loader.async_setup(hass)
if runtime_config.debug or hass.loop.get_debug():
hass.config.debug = True
async_enable_logging(
hass,
runtime_config.verbose,
runtime_config.log_rotate_days,
runtime_config.log_file,
runtime_config.log_no_color,
)
if runtime_config.debug or hass.loop.get_debug():
hass.config.debug = True
hass.config.safe_mode = runtime_config.safe_mode
hass.config.skip_pip = runtime_config.skip_pip
hass.config.skip_pip_packages = runtime_config.skip_pip_packages
return hass
async def stop_hass(hass: core.HomeAssistant) -> None:
"""Stop hass."""
# Ask integrations to shut down. It's messy but we can't
# do a clean stop without knowing what is broken
with contextlib.suppress(TimeoutError):
async with hass.timeout.async_timeout(10):
await hass.async_stop()
hass = create_hass()
hass.config.safe_mode = runtime_config.safe_mode
hass.config.skip_pip = runtime_config.skip_pip
hass.config.skip_pip_packages = runtime_config.skip_pip_packages
if runtime_config.skip_pip or runtime_config.skip_pip_packages:
_LOGGER.warning(
"Skipping pip installation of required modules. This may cause issues"
@@ -283,7 +300,6 @@ async def async_setup_hass(
_LOGGER.info("Config directory: %s", runtime_config.config_dir)
loader.async_setup(hass)
block_async_io.enable()
config_dict = None
@@ -309,27 +325,28 @@ async def async_setup_hass(
if config_dict is None:
recovery_mode = True
await stop_hass(hass)
hass = create_hass()
elif not basic_setup_success:
_LOGGER.warning("Unable to set up core integrations. Activating recovery mode")
recovery_mode = True
await stop_hass(hass)
hass = create_hass()
elif any(domain not in hass.config.components for domain in CRITICAL_INTEGRATIONS):
_LOGGER.warning(
"Detected that %s did not load. Activating recovery mode",
",".join(CRITICAL_INTEGRATIONS),
)
# Ask integrations to shut down. It's messy but we can't
# do a clean stop without knowing what is broken
with contextlib.suppress(TimeoutError):
async with hass.timeout.async_timeout(10):
await hass.async_stop()
recovery_mode = True
old_config = hass.config
old_logging = hass.data.get(DATA_LOGGING)
hass = core.HomeAssistant(old_config.config_dir)
recovery_mode = True
await stop_hass(hass)
hass = create_hass()
if old_logging:
hass.data[DATA_LOGGING] = old_logging
hass.config.debug = old_config.debug

View File

@@ -0,0 +1,5 @@
{
"domain": "ambient_weather",
"name": "Ambient Weather",
"integrations": ["ambient_network", "ambient_station"]
}

View File

@@ -5,13 +5,6 @@ from __future__ import annotations
from typing import cast
from jaraco.abode.devices.sensor import BinarySensor
from jaraco.abode.helpers.constants import (
TYPE_CONNECTIVITY,
TYPE_MOISTURE,
TYPE_MOTION,
TYPE_OCCUPANCY,
TYPE_OPENING,
)
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
@@ -34,11 +27,11 @@ async def async_setup_entry(
data: AbodeSystem = hass.data[DOMAIN]
device_types = [
TYPE_CONNECTIVITY,
TYPE_MOISTURE,
TYPE_MOTION,
TYPE_OCCUPANCY,
TYPE_OPENING,
"connectivity",
"moisture",
"motion",
"occupancy",
"door",
]
async_add_entities(

View File

@@ -8,7 +8,6 @@ from typing import Any, cast
from jaraco.abode.devices.base import Device
from jaraco.abode.devices.camera import Camera as AbodeCam
from jaraco.abode.helpers import timeline
from jaraco.abode.helpers.constants import TYPE_CAMERA
import requests
from requests.models import Response
@@ -34,7 +33,7 @@ async def async_setup_entry(
async_add_entities(
AbodeCamera(data, device, timeline.CAPTURE_IMAGE)
for device in data.abode.get_devices(generic_type=TYPE_CAMERA)
for device in data.abode.get_devices(generic_type="camera")
)

View File

@@ -3,7 +3,6 @@
from typing import Any
from jaraco.abode.devices.cover import Cover
from jaraco.abode.helpers.constants import TYPE_COVER
from homeassistant.components.cover import CoverEntity
from homeassistant.config_entries import ConfigEntry
@@ -23,7 +22,7 @@ async def async_setup_entry(
async_add_entities(
AbodeCover(data, device)
for device in data.abode.get_devices(generic_type=TYPE_COVER)
for device in data.abode.get_devices(generic_type="cover")
)

View File

@@ -105,7 +105,7 @@ class AbodeAutomation(AbodeEntity):
super().__init__(data)
self._automation = automation
self._attr_name = automation.name
self._attr_unique_id = automation.automation_id
self._attr_unique_id = automation.id
self._attr_extra_state_attributes = {
"type": "CUE automation",
}

View File

@@ -6,7 +6,6 @@ from math import ceil
from typing import Any
from jaraco.abode.devices.light import Light
from jaraco.abode.helpers.constants import TYPE_LIGHT
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
@@ -36,7 +35,7 @@ async def async_setup_entry(
async_add_entities(
AbodeLight(data, device)
for device in data.abode.get_devices(generic_type=TYPE_LIGHT)
for device in data.abode.get_devices(generic_type="light")
)

View File

@@ -3,7 +3,6 @@
from typing import Any
from jaraco.abode.devices.lock import Lock
from jaraco.abode.helpers.constants import TYPE_LOCK
from homeassistant.components.lock import LockEntity
from homeassistant.config_entries import ConfigEntry
@@ -23,7 +22,7 @@ async def async_setup_entry(
async_add_entities(
AbodeLock(data, device)
for device in data.abode.get_devices(generic_type=TYPE_LOCK)
for device in data.abode.get_devices(generic_type="lock")
)

View File

@@ -9,5 +9,5 @@
},
"iot_class": "cloud_push",
"loggers": ["jaraco.abode", "lomond"],
"requirements": ["jaraco.abode==3.3.0", "jaraco.functools==3.9.0"]
"requirements": ["jaraco.abode==5.1.2"]
}

View File

@@ -7,15 +7,6 @@ from dataclasses import dataclass
from typing import cast
from jaraco.abode.devices.sensor import Sensor
from jaraco.abode.helpers.constants import (
HUMI_STATUS_KEY,
LUX_STATUS_KEY,
STATUSES_KEY,
TEMP_STATUS_KEY,
TYPE_SENSOR,
UNIT_CELSIUS,
UNIT_FAHRENHEIT,
)
from homeassistant.components.sensor import (
SensorDeviceClass,
@@ -32,8 +23,8 @@ from .const import DOMAIN
from .entity import AbodeDevice
ABODE_TEMPERATURE_UNIT_HA_UNIT = {
UNIT_FAHRENHEIT: UnitOfTemperature.FAHRENHEIT,
UNIT_CELSIUS: UnitOfTemperature.CELSIUS,
"°F": UnitOfTemperature.FAHRENHEIT,
"°C": UnitOfTemperature.CELSIUS,
}
@@ -47,7 +38,7 @@ class AbodeSensorDescription(SensorEntityDescription):
SENSOR_TYPES: tuple[AbodeSensorDescription, ...] = (
AbodeSensorDescription(
key=TEMP_STATUS_KEY,
key="temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement_fn=lambda device: ABODE_TEMPERATURE_UNIT_HA_UNIT[
device.temp_unit
@@ -55,13 +46,13 @@ SENSOR_TYPES: tuple[AbodeSensorDescription, ...] = (
value_fn=lambda device: cast(float, device.temp),
),
AbodeSensorDescription(
key=HUMI_STATUS_KEY,
key="humidity",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement_fn=lambda _: PERCENTAGE,
value_fn=lambda device: cast(float, device.humidity),
),
AbodeSensorDescription(
key=LUX_STATUS_KEY,
key="lux",
device_class=SensorDeviceClass.ILLUMINANCE,
native_unit_of_measurement_fn=lambda _: LIGHT_LUX,
value_fn=lambda device: cast(float, device.lux),
@@ -78,8 +69,8 @@ async def async_setup_entry(
async_add_entities(
AbodeSensor(data, device, description)
for description in SENSOR_TYPES
for device in data.abode.get_devices(generic_type=TYPE_SENSOR)
if description.key in device.get_value(STATUSES_KEY)
for device in data.abode.get_devices(generic_type="sensor")
if description.key in device.get_value("statuses")
)

View File

@@ -5,7 +5,6 @@ from __future__ import annotations
from typing import Any, cast
from jaraco.abode.devices.switch import Switch
from jaraco.abode.helpers.constants import TYPE_SWITCH, TYPE_VALVE
from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry
@@ -17,7 +16,7 @@ from . import AbodeSystem
from .const import DOMAIN
from .entity import AbodeAutomation, AbodeDevice
DEVICE_TYPES = [TYPE_SWITCH, TYPE_VALVE]
DEVICE_TYPES = ["switch", "valve"]
async def async_setup_entry(
@@ -89,4 +88,4 @@ class AbodeAutomationSwitch(AbodeAutomation, SwitchEntity):
@property
def is_on(self) -> bool:
"""Return True if the automation is enabled."""
return bool(self._automation.is_enabled)
return bool(self._automation.enabled)

View File

@@ -9,7 +9,10 @@ from typing import Any
import serial
import voluptuous as vol
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.components.switch import (
PLATFORM_SCHEMA as SWITCH_PLATFORM_SCHEMA,
SwitchEntity,
)
from homeassistant.const import (
CONF_FILENAME,
CONF_NAME,
@@ -38,7 +41,7 @@ from .const import (
_LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = SWITCH_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_FILENAME): cv.isdevice,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,

View File

@@ -10,7 +10,7 @@ import voluptuous as vol
from homeassistant.components.device_tracker import (
DOMAIN,
PLATFORM_SCHEMA as BASE_PLATFORM_SCHEMA,
PLATFORM_SCHEMA as DEVICE_TRACKER_PLATFORM_SCHEMA,
DeviceScanner,
)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
@@ -23,7 +23,7 @@ from .model import Device
_LOGGER: Final = logging.getLogger(__name__)
PLATFORM_SCHEMA: Final = BASE_PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA: Final = DEVICE_TRACKER_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PASSWORD): cv.string,

View File

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

View File

@@ -7,7 +7,7 @@ import voluptuous as vol
from homeassistant.components.binary_sensor import (
DEVICE_CLASSES_SCHEMA,
PLATFORM_SCHEMA,
PLATFORM_SCHEMA as BINARY_SENSOR_PLATFORM_SCHEMA,
BinarySensorDeviceClass,
BinarySensorEntity,
)
@@ -20,7 +20,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import CONF_ADS_VAR, DATA_ADS, STATE_KEY_STATE, AdsEntity
DEFAULT_NAME = "ADS binary sensor"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,

View File

@@ -10,7 +10,7 @@ import voluptuous as vol
from homeassistant.components.cover import (
ATTR_POSITION,
DEVICE_CLASSES_SCHEMA,
PLATFORM_SCHEMA,
PLATFORM_SCHEMA as COVER_PLATFORM_SCHEMA,
CoverEntity,
CoverEntityFeature,
)
@@ -36,7 +36,7 @@ CONF_ADS_VAR_OPEN = "adsvar_open"
CONF_ADS_VAR_CLOSE = "adsvar_close"
CONF_ADS_VAR_STOP = "adsvar_stop"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = COVER_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_ADS_VAR_POSITION): cv.string,

View File

@@ -9,7 +9,7 @@ import voluptuous as vol
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
PLATFORM_SCHEMA,
PLATFORM_SCHEMA as LIGHT_PLATFORM_SCHEMA,
ColorMode,
LightEntity,
)
@@ -29,7 +29,7 @@ from . import (
)
DEFAULT_NAME = "ADS Light"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = LIGHT_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_ADS_VAR_BRIGHTNESS): cv.string,

View File

@@ -4,7 +4,10 @@ from __future__ import annotations
import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.components.sensor import (
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
SensorEntity,
)
from homeassistant.const import CONF_NAME, CONF_UNIT_OF_MEASUREMENT
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
@@ -22,7 +25,7 @@ from . import (
)
DEFAULT_NAME = "ADS sensor"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_ADS_FACTOR): cv.positive_int,

View File

@@ -7,7 +7,10 @@ from typing import Any
import pyads
import voluptuous as vol
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.components.switch import (
PLATFORM_SCHEMA as SWITCH_PLATFORM_SCHEMA,
SwitchEntity,
)
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
@@ -18,7 +21,7 @@ from . import CONF_ADS_VAR, DATA_ADS, STATE_KEY_STATE, AdsEntity
DEFAULT_NAME = "ADS Switch"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = SWITCH_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,

View File

@@ -7,14 +7,35 @@ from typing import Any
from aemet_opendata.helpers import dict_nested_value
from homeassistant.components.weather import Forecast
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import ATTRIBUTION, DOMAIN
from .coordinator import WeatherUpdateCoordinator
class AemetEntity(CoordinatorEntity[WeatherUpdateCoordinator]):
"""Define an AEMET entity."""
_attr_attribution = ATTRIBUTION
_attr_has_entity_name = True
def __init__(
self,
coordinator: WeatherUpdateCoordinator,
name: str,
unique_id: str,
) -> None:
"""Initialize the entity."""
super().__init__(coordinator)
self._attr_device_info = DeviceInfo(
name=name,
entry_type=DeviceEntryType.SERVICE,
identifiers={(DOMAIN, unique_id)},
manufacturer="AEMET",
model="Forecast",
)
def get_aemet_forecast(self, forecast_mode: str) -> list[Forecast]:
"""Return AEMET entity forecast by mode."""
return self.coordinator.data["forecast"][forecast_mode]

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/aemet",
"iot_class": "cloud_polling",
"loggers": ["aemet_opendata"],
"requirements": ["AEMET-OpenData==0.5.1"]
"requirements": ["AEMET-OpenData==0.5.2"]
}

View File

@@ -43,7 +43,6 @@ from homeassistant.components.sensor import (
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
DEGREE,
PERCENTAGE,
@@ -86,7 +85,6 @@ from .const import (
ATTR_API_WIND_BEARING,
ATTR_API_WIND_MAX_SPEED,
ATTR_API_WIND_SPEED,
ATTRIBUTION,
CONDITIONS_MAP,
)
from .coordinator import WeatherUpdateCoordinator
@@ -366,12 +364,15 @@ async def async_setup_entry(
name = domain_data.name
coordinator = domain_data.coordinator
unique_id = config_entry.unique_id
assert unique_id is not None
async_add_entities(
AemetSensor(
name,
coordinator,
description,
config_entry,
unique_id,
)
for description in FORECAST_SENSORS + WEATHER_SENSORS
if dict_nested_value(coordinator.data["lib"], description.keys) is not None
@@ -381,7 +382,6 @@ async def async_setup_entry(
class AemetSensor(AemetEntity, SensorEntity):
"""Implementation of an AEMET OpenData sensor."""
_attr_attribution = ATTRIBUTION
entity_description: AemetSensorEntityDescription
def __init__(
@@ -389,13 +389,12 @@ class AemetSensor(AemetEntity, SensorEntity):
name: str,
coordinator: WeatherUpdateCoordinator,
description: AemetSensorEntityDescription,
config_entry: ConfigEntry,
unique_id: str,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
super().__init__(coordinator, name, unique_id)
self.entity_description = description
self._attr_name = f"{name} {description.name}"
self._attr_unique_id = f"{config_entry.unique_id}-{description.key}"
self._attr_unique_id = f"{unique_id}-{description.key}"
@property
def native_value(self):

View File

@@ -28,7 +28,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AemetConfigEntry
from .const import ATTRIBUTION, CONDITIONS_MAP
from .const import CONDITIONS_MAP
from .coordinator import WeatherUpdateCoordinator
from .entity import AemetEntity
@@ -43,10 +43,10 @@ async def async_setup_entry(
name = domain_data.name
weather_coordinator = domain_data.coordinator
async_add_entities(
[AemetWeather(name, config_entry.unique_id, weather_coordinator)],
False,
)
unique_id = config_entry.unique_id
assert unique_id is not None
async_add_entities([AemetWeather(name, unique_id, weather_coordinator)])
class AemetWeather(
@@ -55,7 +55,6 @@ class AemetWeather(
):
"""Implementation of an AEMET OpenData weather."""
_attr_attribution = ATTRIBUTION
_attr_native_precipitation_unit = UnitOfPrecipitationDepth.MILLIMETERS
_attr_native_pressure_unit = UnitOfPressure.HPA
_attr_native_temperature_unit = UnitOfTemperature.CELSIUS
@@ -63,16 +62,16 @@ class AemetWeather(
_attr_supported_features = (
WeatherEntityFeature.FORECAST_DAILY | WeatherEntityFeature.FORECAST_HOURLY
)
_attr_name = None
def __init__(
self,
name,
unique_id,
name: str,
unique_id: str,
coordinator: WeatherUpdateCoordinator,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
self._attr_name = name
super().__init__(coordinator, name, unique_id)
self._attr_unique_id = unique_id
@property

View File

@@ -9,19 +9,20 @@ from typing import Final, final
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
from homeassistant.core import HomeAssistant
from homeassistant.helpers.config_validation import ( # noqa: F401
PLATFORM_SCHEMA,
PLATFORM_SCHEMA_BASE,
)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import ConfigType, StateType
from . import group as group_pre_import # noqa: F401
from .const import DOMAIN
_LOGGER: Final = logging.getLogger(__name__)
ENTITY_ID_FORMAT: Final = DOMAIN + ".{}"
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA
PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE
SCAN_INTERVAL: Final = timedelta(seconds=30)
ATTR_AQI: Final = "air_quality_index"
ATTR_CO2: Final = "carbon_dioxide"
ATTR_CO: Final = "carbon_monoxide"
@@ -34,10 +35,6 @@ ATTR_PM_10: Final = "particulate_matter_10"
ATTR_PM_2_5: Final = "particulate_matter_2_5"
ATTR_SO2: Final = "sulphur_dioxide"
ENTITY_ID_FORMAT: Final = DOMAIN + ".{}"
SCAN_INTERVAL: Final = timedelta(seconds=30)
PROP_TO_ATTR: Final[dict[str, str]] = {
"air_quality_index": ATTR_AQI,
"carbon_dioxide": ATTR_CO2,

View File

@@ -1,20 +0,0 @@
"""Describe group states."""
from __future__ import annotations
from typing import TYPE_CHECKING
from homeassistant.core import HomeAssistant, callback
if TYPE_CHECKING:
from homeassistant.components.group import GroupIntegrationRegistry
from .const import DOMAIN
@callback
def async_describe_on_off_states(
hass: HomeAssistant, registry: GroupIntegrationRegistry
) -> None:
"""Describe group on off states."""
registry.exclude_domain(DOMAIN)

View File

@@ -15,7 +15,13 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN
from .coordinator import AirGradientConfigCoordinator, AirGradientMeasurementCoordinator
PLATFORMS: list[Platform] = [Platform.SELECT, Platform.SENSOR]
PLATFORMS: list[Platform] = [
Platform.BUTTON,
Platform.NUMBER,
Platform.SELECT,
Platform.SENSOR,
Platform.SWITCH,
]
@dataclass

View File

@@ -0,0 +1,104 @@
"""Support for AirGradient buttons."""
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from airgradient import AirGradientClient, ConfigurationControl
from homeassistant.components.button import (
DOMAIN as BUTTON_DOMAIN,
ButtonEntity,
ButtonEntityDescription,
)
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import DOMAIN, AirGradientConfigEntry
from .coordinator import AirGradientConfigCoordinator
from .entity import AirGradientEntity
@dataclass(frozen=True, kw_only=True)
class AirGradientButtonEntityDescription(ButtonEntityDescription):
"""Describes AirGradient button entity."""
press_fn: Callable[[AirGradientClient], Awaitable[None]]
CO2_CALIBRATION = AirGradientButtonEntityDescription(
key="co2_calibration",
translation_key="co2_calibration",
entity_category=EntityCategory.CONFIG,
press_fn=lambda client: client.request_co2_calibration(),
)
LED_BAR_TEST = AirGradientButtonEntityDescription(
key="led_bar_test",
translation_key="led_bar_test",
entity_category=EntityCategory.CONFIG,
press_fn=lambda client: client.request_led_bar_test(),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AirGradientConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up AirGradient button entities based on a config entry."""
model = entry.runtime_data.measurement.data.model
coordinator = entry.runtime_data.config
added_entities = False
@callback
def _check_entities() -> None:
nonlocal added_entities
if (
coordinator.data.configuration_control is ConfigurationControl.LOCAL
and not added_entities
):
entities = [AirGradientButton(coordinator, CO2_CALIBRATION)]
if "L" in model:
entities.append(AirGradientButton(coordinator, LED_BAR_TEST))
async_add_entities(entities)
added_entities = True
elif (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
and added_entities
):
entity_registry = er.async_get(hass)
for entity_description in (CO2_CALIBRATION, LED_BAR_TEST):
unique_id = f"{coordinator.serial_number}-{entity_description.key}"
if entity_id := entity_registry.async_get_entity_id(
BUTTON_DOMAIN, DOMAIN, unique_id
):
entity_registry.async_remove(entity_id)
added_entities = False
coordinator.async_add_listener(_check_entities)
_check_entities()
class AirGradientButton(AirGradientEntity, ButtonEntity):
"""Defines an AirGradient button."""
entity_description: AirGradientButtonEntityDescription
coordinator: AirGradientConfigCoordinator
def __init__(
self,
coordinator: AirGradientConfigCoordinator,
description: AirGradientButtonEntityDescription,
) -> None:
"""Initialize airgradient button."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
async def async_press(self) -> None:
"""Press the button."""
await self.entity_description.press_fn(self.coordinator.client)

View File

@@ -2,6 +2,14 @@
import logging
from airgradient import PmStandard
DOMAIN = "airgradient"
LOGGER = logging.getLogger(__package__)
PM_STANDARD = {
PmStandard.UGM3: "ugm3",
PmStandard.USAQI: "us_aqi",
}
PM_STANDARD_REVERSE = {v: k for k, v in PM_STANDARD.items()}

View File

@@ -1,5 +1,13 @@
{
"entity": {
"button": {
"co2_calibration": {
"default": "mdi:molecule-co2"
},
"led_bar_test": {
"default": "mdi:lightbulb-on-outline"
}
},
"sensor": {
"total_volatile_organic_component_index": {
"default": "mdi:molecule"

View File

@@ -6,6 +6,6 @@
"documentation": "https://www.home-assistant.io/integrations/airgradient",
"integration_type": "device",
"iot_class": "local_polling",
"requirements": ["airgradient==0.4.3"],
"requirements": ["airgradient==0.6.0"],
"zeroconf": ["_airgradient._tcp.local."]
}

View File

@@ -0,0 +1,127 @@
"""Support for AirGradient number entities."""
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from airgradient import AirGradientClient, Config
from airgradient.models import ConfigurationControl
from homeassistant.components.number import (
DOMAIN as NUMBER_DOMAIN,
NumberEntity,
NumberEntityDescription,
)
from homeassistant.const import PERCENTAGE, EntityCategory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirGradientConfigEntry
from .const import DOMAIN
from .coordinator import AirGradientConfigCoordinator
from .entity import AirGradientEntity
@dataclass(frozen=True, kw_only=True)
class AirGradientNumberEntityDescription(NumberEntityDescription):
"""Describes AirGradient number entity."""
value_fn: Callable[[Config], int]
set_value_fn: Callable[[AirGradientClient, int], Awaitable[None]]
DISPLAY_BRIGHTNESS = AirGradientNumberEntityDescription(
key="display_brightness",
translation_key="display_brightness",
entity_category=EntityCategory.CONFIG,
native_min_value=0,
native_max_value=100,
native_step=1,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda config: config.display_brightness,
set_value_fn=lambda client, value: client.set_display_brightness(value),
)
LED_BAR_BRIGHTNESS = AirGradientNumberEntityDescription(
key="led_bar_brightness",
translation_key="led_bar_brightness",
entity_category=EntityCategory.CONFIG,
native_min_value=0,
native_max_value=100,
native_step=1,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda config: config.led_bar_brightness,
set_value_fn=lambda client, value: client.set_led_bar_brightness(value),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AirGradientConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up AirGradient number entities based on a config entry."""
model = entry.runtime_data.measurement.data.model
coordinator = entry.runtime_data.config
added_entities = False
@callback
def _async_check_entities() -> None:
nonlocal added_entities
if (
coordinator.data.configuration_control is ConfigurationControl.LOCAL
and not added_entities
):
entities = []
if "I" in model:
entities.append(AirGradientNumber(coordinator, DISPLAY_BRIGHTNESS))
if "L" in model:
entities.append(AirGradientNumber(coordinator, LED_BAR_BRIGHTNESS))
async_add_entities(entities)
added_entities = True
elif (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
and added_entities
):
entity_registry = er.async_get(hass)
for entity_description in (DISPLAY_BRIGHTNESS, LED_BAR_BRIGHTNESS):
unique_id = f"{coordinator.serial_number}-{entity_description.key}"
if entity_id := entity_registry.async_get_entity_id(
NUMBER_DOMAIN, DOMAIN, unique_id
):
entity_registry.async_remove(entity_id)
added_entities = False
coordinator.async_add_listener(_async_check_entities)
_async_check_entities()
class AirGradientNumber(AirGradientEntity, NumberEntity):
"""Defines an AirGradient number entity."""
entity_description: AirGradientNumberEntityDescription
coordinator: AirGradientConfigCoordinator
def __init__(
self,
coordinator: AirGradientConfigCoordinator,
description: AirGradientNumberEntityDescription,
) -> None:
"""Initialize AirGradient number."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
@property
def native_value(self) -> int | None:
"""Return the state of the number."""
return self.entity_description.value_fn(self.coordinator.data)
async def async_set_native_value(self, value: float) -> None:
"""Set the selected value."""
await self.entity_description.set_value_fn(self.coordinator.client, int(value))
await self.coordinator.async_request_refresh()

View File

@@ -4,16 +4,20 @@ from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from airgradient import AirGradientClient, Config
from airgradient.models import ConfigurationControl, TemperatureUnit
from airgradient.models import ConfigurationControl, LedBarMode, TemperatureUnit
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.components.select import (
DOMAIN as SELECT_DOMAIN,
SelectEntity,
SelectEntityDescription,
)
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirGradientConfigEntry
from .const import DOMAIN
from .const import DOMAIN, PM_STANDARD, PM_STANDARD_REVERSE
from .coordinator import AirGradientConfigCoordinator
from .entity import AirGradientEntity
@@ -24,7 +28,6 @@ class AirGradientSelectEntityDescription(SelectEntityDescription):
value_fn: Callable[[Config], str | None]
set_value_fn: Callable[[AirGradientClient, str], Awaitable[None]]
requires_display: bool = False
CONFIG_CONTROL_ENTITY = AirGradientSelectEntityDescription(
@@ -32,15 +35,17 @@ CONFIG_CONTROL_ENTITY = AirGradientSelectEntityDescription(
translation_key="configuration_control",
options=[ConfigurationControl.CLOUD.value, ConfigurationControl.LOCAL.value],
entity_category=EntityCategory.CONFIG,
value_fn=lambda config: config.configuration_control
if config.configuration_control is not ConfigurationControl.NOT_INITIALIZED
else None,
value_fn=lambda config: (
config.configuration_control
if config.configuration_control is not ConfigurationControl.NOT_INITIALIZED
else None
),
set_value_fn=lambda client, value: client.set_configuration_control(
ConfigurationControl(value)
),
)
PROTECTED_SELECT_TYPES: tuple[AirGradientSelectEntityDescription, ...] = (
DISPLAY_SELECT_TYPES: tuple[AirGradientSelectEntityDescription, ...] = (
AirGradientSelectEntityDescription(
key="display_temperature_unit",
translation_key="display_temperature_unit",
@@ -50,7 +55,83 @@ PROTECTED_SELECT_TYPES: tuple[AirGradientSelectEntityDescription, ...] = (
set_value_fn=lambda client, value: client.set_temperature_unit(
TemperatureUnit(value)
),
requires_display=True,
),
AirGradientSelectEntityDescription(
key="display_pm_standard",
translation_key="display_pm_standard",
options=list(PM_STANDARD_REVERSE),
entity_category=EntityCategory.CONFIG,
value_fn=lambda config: PM_STANDARD.get(config.pm_standard),
set_value_fn=lambda client, value: client.set_pm_standard(
PM_STANDARD_REVERSE[value]
),
),
)
LED_BAR_ENTITIES: tuple[AirGradientSelectEntityDescription, ...] = (
AirGradientSelectEntityDescription(
key="led_bar_mode",
translation_key="led_bar_mode",
options=[x.value for x in LedBarMode],
entity_category=EntityCategory.CONFIG,
value_fn=lambda config: config.led_bar_mode,
set_value_fn=lambda client, value: client.set_led_bar_mode(LedBarMode(value)),
),
)
LEARNING_TIME_OFFSET_OPTIONS = [
"12",
"60",
"120",
"360",
"720",
]
ABC_DAYS = [
"8",
"30",
"90",
"180",
"0",
]
def _get_value(value: int, values: list[str]) -> str | None:
str_value = str(value)
return str_value if str_value in values else None
CONTROL_ENTITIES: tuple[AirGradientSelectEntityDescription, ...] = (
AirGradientSelectEntityDescription(
key="nox_index_learning_time_offset",
translation_key="nox_index_learning_time_offset",
options=LEARNING_TIME_OFFSET_OPTIONS,
entity_category=EntityCategory.CONFIG,
value_fn=lambda config: _get_value(
config.nox_learning_offset, LEARNING_TIME_OFFSET_OPTIONS
),
set_value_fn=lambda client, value: client.set_nox_learning_offset(int(value)),
),
AirGradientSelectEntityDescription(
key="voc_index_learning_time_offset",
translation_key="voc_index_learning_time_offset",
options=LEARNING_TIME_OFFSET_OPTIONS,
entity_category=EntityCategory.CONFIG,
value_fn=lambda config: _get_value(
config.tvoc_learning_offset, LEARNING_TIME_OFFSET_OPTIONS
),
set_value_fn=lambda client, value: client.set_tvoc_learning_offset(int(value)),
),
AirGradientSelectEntityDescription(
key="co2_automatic_baseline_calibration",
translation_key="co2_automatic_baseline_calibration",
options=ABC_DAYS,
entity_category=EntityCategory.CONFIG,
value_fn=lambda config: _get_value(
config.co2_automatic_baseline_calibration_days, ABC_DAYS
),
set_value_fn=lambda client,
value: client.set_co2_automatic_baseline_calibration(int(value)),
),
)
@@ -62,21 +143,57 @@ async def async_setup_entry(
) -> None:
"""Set up AirGradient select entities based on a config entry."""
config_coordinator = entry.runtime_data.config
coordinator = entry.runtime_data.config
measurement_coordinator = entry.runtime_data.measurement
entities = [AirGradientSelect(config_coordinator, CONFIG_CONTROL_ENTITY)]
async_add_entities([AirGradientSelect(coordinator, CONFIG_CONTROL_ENTITY)])
model = measurement_coordinator.data.model
added_entities = False
@callback
def _async_check_entities() -> None:
nonlocal added_entities
entities.extend(
AirGradientProtectedSelect(config_coordinator, description)
for description in PROTECTED_SELECT_TYPES
if (
description.requires_display
and measurement_coordinator.data.model.startswith("I")
)
)
coordinator.data.configuration_control is ConfigurationControl.LOCAL
and not added_entities
):
entities: list[AirGradientSelect] = [
AirGradientSelect(coordinator, description)
for description in CONTROL_ENTITIES
]
if "I" in model:
entities.extend(
AirGradientSelect(coordinator, description)
for description in DISPLAY_SELECT_TYPES
)
if "L" in model:
entities.extend(
AirGradientSelect(coordinator, description)
for description in LED_BAR_ENTITIES
)
async_add_entities(entities)
async_add_entities(entities)
added_entities = True
elif (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
and added_entities
):
entity_registry = er.async_get(hass)
for entity_description in (
DISPLAY_SELECT_TYPES + LED_BAR_ENTITIES + CONTROL_ENTITIES
):
unique_id = f"{coordinator.serial_number}-{entity_description.key}"
if entity_id := entity_registry.async_get_entity_id(
SELECT_DOMAIN, DOMAIN, unique_id
):
entity_registry.async_remove(entity_id)
added_entities = False
coordinator.async_add_listener(_async_check_entities)
_async_check_entities()
class AirGradientSelect(AirGradientEntity, SelectEntity):
@@ -104,19 +221,3 @@ class AirGradientSelect(AirGradientEntity, SelectEntity):
"""Change the selected option."""
await self.entity_description.set_value_fn(self.coordinator.client, option)
await self.coordinator.async_request_refresh()
class AirGradientProtectedSelect(AirGradientSelect):
"""Defines a protected AirGradient select entity."""
async def async_select_option(self, option: str) -> None:
"""Change the selected option."""
if (
self.coordinator.data.configuration_control
is not ConfigurationControl.LOCAL
):
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="no_local_configuration",
)
await super().async_select_option(option)

View File

@@ -3,7 +3,13 @@
from collections.abc import Callable
from dataclasses import dataclass
from airgradient.models import Measures
from airgradient import Config
from airgradient.models import (
ConfigurationControl,
LedBarMode,
Measures,
TemperatureUnit,
)
from homeassistant.components.sensor import (
SensorDeviceClass,
@@ -18,60 +24,69 @@ from homeassistant.const import (
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
EntityCategory,
UnitOfTemperature,
UnitOfTime,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from . import AirGradientConfigEntry
from .coordinator import AirGradientMeasurementCoordinator
from .const import PM_STANDARD, PM_STANDARD_REVERSE
from .coordinator import AirGradientConfigCoordinator, AirGradientMeasurementCoordinator
from .entity import AirGradientEntity
@dataclass(frozen=True, kw_only=True)
class AirGradientSensorEntityDescription(SensorEntityDescription):
"""Describes AirGradient sensor entity."""
class AirGradientMeasurementSensorEntityDescription(SensorEntityDescription):
"""Describes AirGradient measurement sensor entity."""
value_fn: Callable[[Measures], StateType]
SENSOR_TYPES: tuple[AirGradientSensorEntityDescription, ...] = (
AirGradientSensorEntityDescription(
@dataclass(frozen=True, kw_only=True)
class AirGradientConfigSensorEntityDescription(SensorEntityDescription):
"""Describes AirGradient config sensor entity."""
value_fn: Callable[[Config], StateType]
MEASUREMENT_SENSOR_TYPES: tuple[AirGradientMeasurementSensorEntityDescription, ...] = (
AirGradientMeasurementSensorEntityDescription(
key="pm01",
device_class=SensorDeviceClass.PM1,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.pm01,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="pm02",
device_class=SensorDeviceClass.PM25,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.pm02,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="pm10",
device_class=SensorDeviceClass.PM10,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.pm10,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.ambient_temperature,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="humidity",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.relative_humidity,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="signal_strength",
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
@@ -80,33 +95,33 @@ SENSOR_TYPES: tuple[AirGradientSensorEntityDescription, ...] = (
entity_registry_enabled_default=False,
value_fn=lambda status: status.signal_strength,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="tvoc",
translation_key="total_volatile_organic_component_index",
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.total_volatile_organic_component_index,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="nitrogen_index",
translation_key="nitrogen_index",
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.nitrogen_index,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="co2",
device_class=SensorDeviceClass.CO2,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.rco2,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="pm003",
translation_key="pm003_count",
native_unit_of_measurement="particles/dL",
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.pm003_count,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="nox_raw",
translation_key="raw_nitrogen",
native_unit_of_measurement="ticks",
@@ -114,7 +129,7 @@ SENSOR_TYPES: tuple[AirGradientSensorEntityDescription, ...] = (
entity_registry_enabled_default=False,
value_fn=lambda status: status.raw_nitrogen,
),
AirGradientSensorEntityDescription(
AirGradientMeasurementSensorEntityDescription(
key="tvoc_raw",
translation_key="raw_total_volatile_organic_component",
native_unit_of_measurement="ticks",
@@ -124,6 +139,77 @@ SENSOR_TYPES: tuple[AirGradientSensorEntityDescription, ...] = (
),
)
CONFIG_SENSOR_TYPES: tuple[AirGradientConfigSensorEntityDescription, ...] = (
AirGradientConfigSensorEntityDescription(
key="co2_automatic_baseline_calibration_days",
translation_key="co2_automatic_baseline_calibration_days",
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.DAYS,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda config: config.co2_automatic_baseline_calibration_days,
),
AirGradientConfigSensorEntityDescription(
key="nox_learning_offset",
translation_key="nox_learning_offset",
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.DAYS,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda config: config.nox_learning_offset,
),
AirGradientConfigSensorEntityDescription(
key="tvoc_learning_offset",
translation_key="tvoc_learning_offset",
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.DAYS,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda config: config.tvoc_learning_offset,
),
)
CONFIG_LED_BAR_SENSOR_TYPES: tuple[AirGradientConfigSensorEntityDescription, ...] = (
AirGradientConfigSensorEntityDescription(
key="led_bar_mode",
translation_key="led_bar_mode",
device_class=SensorDeviceClass.ENUM,
options=[x.value for x in LedBarMode],
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda config: config.led_bar_mode,
),
AirGradientConfigSensorEntityDescription(
key="led_bar_brightness",
translation_key="led_bar_brightness",
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda config: config.led_bar_brightness,
),
)
CONFIG_DISPLAY_SENSOR_TYPES: tuple[AirGradientConfigSensorEntityDescription, ...] = (
AirGradientConfigSensorEntityDescription(
key="display_temperature_unit",
translation_key="display_temperature_unit",
device_class=SensorDeviceClass.ENUM,
options=[x.value for x in TemperatureUnit],
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda config: config.temperature_unit,
),
AirGradientConfigSensorEntityDescription(
key="display_pm_standard",
translation_key="display_pm_standard",
device_class=SensorDeviceClass.ENUM,
options=list(PM_STANDARD_REVERSE),
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda config: PM_STANDARD.get(config.pm_standard),
),
AirGradientConfigSensorEntityDescription(
key="display_brightness",
translation_key="display_brightness",
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda config: config.display_brightness,
),
)
async def async_setup_entry(
hass: HomeAssistant,
@@ -134,7 +220,9 @@ async def async_setup_entry(
coordinator = entry.runtime_data.measurement
listener: Callable[[], None] | None = None
not_setup: set[AirGradientSensorEntityDescription] = set(SENSOR_TYPES)
not_setup: set[AirGradientMeasurementSensorEntityDescription] = set(
MEASUREMENT_SENSOR_TYPES
)
@callback
def add_entities() -> None:
@@ -147,7 +235,7 @@ async def async_setup_entry(
if description.value_fn(coordinator.data) is None:
not_setup.add(description)
else:
sensors.append(AirGradientSensor(coordinator, description))
sensors.append(AirGradientMeasurementSensor(coordinator, description))
if sensors:
async_add_entities(sensors)
@@ -159,17 +247,33 @@ async def async_setup_entry(
add_entities()
entities = [
AirGradientConfigSensor(entry.runtime_data.config, description)
for description in CONFIG_SENSOR_TYPES
]
if "L" in coordinator.data.model:
entities.extend(
AirGradientConfigSensor(entry.runtime_data.config, description)
for description in CONFIG_LED_BAR_SENSOR_TYPES
)
if "I" in coordinator.data.model:
entities.extend(
AirGradientConfigSensor(entry.runtime_data.config, description)
for description in CONFIG_DISPLAY_SENSOR_TYPES
)
async_add_entities(entities)
class AirGradientSensor(AirGradientEntity, SensorEntity):
class AirGradientMeasurementSensor(AirGradientEntity, SensorEntity):
"""Defines an AirGradient sensor."""
entity_description: AirGradientSensorEntityDescription
entity_description: AirGradientMeasurementSensorEntityDescription
coordinator: AirGradientMeasurementCoordinator
def __init__(
self,
coordinator: AirGradientMeasurementCoordinator,
description: AirGradientSensorEntityDescription,
description: AirGradientMeasurementSensorEntityDescription,
) -> None:
"""Initialize airgradient sensor."""
super().__init__(coordinator)
@@ -180,3 +284,28 @@ class AirGradientSensor(AirGradientEntity, SensorEntity):
def native_value(self) -> StateType:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self.coordinator.data)
class AirGradientConfigSensor(AirGradientEntity, SensorEntity):
"""Defines an AirGradient sensor."""
entity_description: AirGradientConfigSensorEntityDescription
coordinator: AirGradientConfigCoordinator
def __init__(
self,
coordinator: AirGradientConfigCoordinator,
description: AirGradientConfigSensorEntityDescription,
) -> None:
"""Initialize airgradient sensor."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
self._attr_entity_registry_enabled_default = (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
)
@property
def native_value(self) -> StateType:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self.coordinator.data)

View File

@@ -24,6 +24,22 @@
}
},
"entity": {
"button": {
"co2_calibration": {
"name": "Calibrate CO2 sensor"
},
"led_bar_test": {
"name": "Test LED bar"
}
},
"number": {
"led_bar_brightness": {
"name": "LED bar brightness"
},
"display_brightness": {
"name": "Display brightness"
}
},
"select": {
"configuration_control": {
"name": "Configuration source",
@@ -38,29 +54,111 @@
"c": "Celsius",
"f": "Fahrenheit"
}
},
"display_pm_standard": {
"name": "Display PM standard",
"state": {
"ugm3": "µg/m³",
"us_aqi": "US AQI"
}
},
"led_bar_mode": {
"name": "LED bar mode",
"state": {
"off": "Off",
"co2": "Carbon dioxide",
"pm": "Particulate matter"
}
},
"nox_index_learning_time_offset": {
"name": "NOx index learning offset",
"state": {
"12": "12 hours",
"60": "60 hours",
"120": "120 hours",
"360": "360 hours",
"720": "720 hours"
}
},
"voc_index_learning_time_offset": {
"name": "VOC index learning offset",
"state": {
"12": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::state::12%]",
"60": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::state::60%]",
"120": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::state::120%]",
"360": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::state::360%]",
"720": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::state::720%]"
}
},
"co2_automatic_baseline_calibration": {
"name": "CO2 automatic baseline calibration",
"state": {
"8": "8 days",
"30": "30 days",
"90": "90 days",
"180": "180 days",
"0": "[%key:common::state::off%]"
}
}
},
"sensor": {
"total_volatile_organic_component_index": {
"name": "Total VOC index"
"name": "VOC index"
},
"nitrogen_index": {
"name": "Nitrogen index"
"name": "NOx index"
},
"pm003_count": {
"name": "PM0.3"
},
"raw_total_volatile_organic_component": {
"name": "Raw total VOC"
"name": "Raw VOC"
},
"raw_nitrogen": {
"name": "Raw nitrogen"
"name": "Raw NOx"
},
"display_pm_standard": {
"name": "[%key:component::airgradient::entity::select::display_pm_standard::name%]",
"state": {
"ugm3": "[%key:component::airgradient::entity::select::display_pm_standard::state::ugm3%]",
"us_aqi": "[%key:component::airgradient::entity::select::display_pm_standard::state::us_aqi%]"
}
},
"co2_automatic_baseline_calibration_days": {
"name": "Carbon dioxide automatic baseline calibration"
},
"nox_learning_offset": {
"name": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::name%]"
},
"tvoc_learning_offset": {
"name": "[%key:component::airgradient::entity::select::voc_index_learning_time_offset::name%]"
},
"led_bar_mode": {
"name": "[%key:component::airgradient::entity::select::led_bar_mode::name%]",
"state": {
"off": "[%key:component::airgradient::entity::select::led_bar_mode::state::off%]",
"co2": "[%key:component::airgradient::entity::select::led_bar_mode::state::co2%]",
"pm": "[%key:component::airgradient::entity::select::led_bar_mode::state::pm%]"
}
},
"led_bar_brightness": {
"name": "[%key:component::airgradient::entity::number::led_bar_brightness::name%]"
},
"display_temperature_unit": {
"name": "[%key:component::airgradient::entity::select::display_temperature_unit::name%]",
"state": {
"c": "[%key:component::airgradient::entity::select::display_temperature_unit::state::c%]",
"f": "[%key:component::airgradient::entity::select::display_temperature_unit::state::f%]"
}
},
"display_brightness": {
"name": "[%key:component::airgradient::entity::number::display_brightness::name%]"
}
},
"switch": {
"post_data_to_airgradient": {
"name": "Post data to Airgradient"
}
}
},
"exceptions": {
"no_local_configuration": {
"message": "Device should be configured with local configuration to be able to change settings."
}
}
}

View File

@@ -0,0 +1,110 @@
"""Support for AirGradient switch entities."""
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import Any
from airgradient import AirGradientClient, Config
from airgradient.models import ConfigurationControl
from homeassistant.components.switch import (
DOMAIN as SWITCH_DOMAIN,
SwitchEntity,
SwitchEntityDescription,
)
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirGradientConfigEntry
from .const import DOMAIN
from .coordinator import AirGradientConfigCoordinator
from .entity import AirGradientEntity
@dataclass(frozen=True, kw_only=True)
class AirGradientSwitchEntityDescription(SwitchEntityDescription):
"""Describes AirGradient switch entity."""
value_fn: Callable[[Config], bool]
set_value_fn: Callable[[AirGradientClient, bool], Awaitable[None]]
POST_DATA_TO_AIRGRADIENT = AirGradientSwitchEntityDescription(
key="post_data_to_airgradient",
translation_key="post_data_to_airgradient",
entity_category=EntityCategory.CONFIG,
value_fn=lambda config: config.post_data_to_airgradient,
set_value_fn=lambda client, value: client.enable_sharing_data(enable=value),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AirGradientConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up AirGradient switch entities based on a config entry."""
coordinator = entry.runtime_data.config
added_entities = False
@callback
def _async_check_entities() -> None:
nonlocal added_entities
if (
coordinator.data.configuration_control is ConfigurationControl.LOCAL
and not added_entities
):
async_add_entities(
[AirGradientSwitch(coordinator, POST_DATA_TO_AIRGRADIENT)]
)
added_entities = True
elif (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
and added_entities
):
entity_registry = er.async_get(hass)
unique_id = f"{coordinator.serial_number}-{POST_DATA_TO_AIRGRADIENT.key}"
if entity_id := entity_registry.async_get_entity_id(
SWITCH_DOMAIN, DOMAIN, unique_id
):
entity_registry.async_remove(entity_id)
added_entities = False
coordinator.async_add_listener(_async_check_entities)
_async_check_entities()
class AirGradientSwitch(AirGradientEntity, SwitchEntity):
"""Defines an AirGradient switch entity."""
entity_description: AirGradientSwitchEntityDescription
coordinator: AirGradientConfigCoordinator
def __init__(
self,
coordinator: AirGradientConfigCoordinator,
description: AirGradientSwitchEntityDescription,
) -> None:
"""Initialize AirGradient switch."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
@property
def is_on(self) -> bool:
"""Return the state of the switch."""
return self.entity_description.value_fn(self.coordinator.data)
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
await self.entity_description.set_value_fn(self.coordinator.client, True)
await self.coordinator.async_request_refresh()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off."""
await self.entity_description.set_value_fn(self.coordinator.client, False)
await self.coordinator.async_request_refresh()

View File

@@ -14,6 +14,7 @@ ATTR_API_POLLUTANT = "Pollutant"
ATTR_API_REPORT_DATE = "DateObserved"
ATTR_API_REPORT_HOUR = "HourObserved"
ATTR_API_REPORT_TZ = "LocalTimeZone"
ATTR_API_REPORT_TZINFO = "LocalTimeZoneInfo"
ATTR_API_STATE = "StateCode"
ATTR_API_STATION = "ReportingArea"
ATTR_API_STATION_LATITUDE = "Latitude"

View File

@@ -12,6 +12,7 @@ from pyairnow.errors import AirNowError
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util import dt as dt_util
from .const import (
ATTR_API_AQI,
@@ -26,6 +27,7 @@ from .const import (
ATTR_API_REPORT_DATE,
ATTR_API_REPORT_HOUR,
ATTR_API_REPORT_TZ,
ATTR_API_REPORT_TZINFO,
ATTR_API_STATE,
ATTR_API_STATION,
ATTR_API_STATION_LATITUDE,
@@ -96,7 +98,9 @@ class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
# Copy Report Details
data[ATTR_API_REPORT_DATE] = obv[ATTR_API_REPORT_DATE]
data[ATTR_API_REPORT_HOUR] = obv[ATTR_API_REPORT_HOUR]
data[ATTR_API_REPORT_TZ] = obv[ATTR_API_REPORT_TZ]
data[ATTR_API_REPORT_TZINFO] = await dt_util.async_get_time_zone(
obv[ATTR_API_REPORT_TZ]
)
# Copy Station Details
data[ATTR_API_STATE] = obv[ATTR_API_STATE]

View File

@@ -23,7 +23,6 @@ from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util.dt import get_time_zone
from . import AirNowConfigEntry, AirNowDataUpdateCoordinator
from .const import (
@@ -35,7 +34,7 @@ from .const import (
ATTR_API_PM25,
ATTR_API_REPORT_DATE,
ATTR_API_REPORT_HOUR,
ATTR_API_REPORT_TZ,
ATTR_API_REPORT_TZINFO,
ATTR_API_STATION,
ATTR_API_STATION_LATITUDE,
ATTR_API_STATION_LONGITUDE,
@@ -84,7 +83,7 @@ SENSOR_TYPES: tuple[AirNowEntityDescription, ...] = (
f"{data[ATTR_API_REPORT_DATE]} {data[ATTR_API_REPORT_HOUR]}",
"%Y-%m-%d %H",
)
.replace(tzinfo=get_time_zone(data[ATTR_API_REPORT_TZ]))
.replace(tzinfo=data[ATTR_API_REPORT_TZINFO])
.isoformat(),
},
),

View File

@@ -11,5 +11,5 @@
"documentation": "https://www.home-assistant.io/integrations/airzone",
"iot_class": "local_polling",
"loggers": ["aioairzone"],
"requirements": ["aioairzone==0.7.6"]
"requirements": ["aioairzone==0.7.7"]
}

View File

@@ -8,8 +8,10 @@ from typing import Any, Final
from aioairzone_cloud.const import (
AZD_ACTIVE,
AZD_AIDOOS,
AZD_AIR_DEMAND,
AZD_AQ_ACTIVE,
AZD_ERRORS,
AZD_FLOOR_DEMAND,
AZD_PROBLEMS,
AZD_SYSTEMS,
AZD_WARNINGS,
@@ -77,10 +79,20 @@ ZONE_BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]
device_class=BinarySensorDeviceClass.RUNNING,
key=AZD_ACTIVE,
),
AirzoneBinarySensorEntityDescription(
device_class=BinarySensorDeviceClass.RUNNING,
key=AZD_AIR_DEMAND,
translation_key="air_demand",
),
AirzoneBinarySensorEntityDescription(
key=AZD_AQ_ACTIVE,
translation_key="air_quality_active",
),
AirzoneBinarySensorEntityDescription(
device_class=BinarySensorDeviceClass.RUNNING,
key=AZD_FLOOR_DEMAND,
translation_key="floor_demand",
),
AirzoneBinarySensorEntityDescription(
attributes={
"warnings": AZD_WARNINGS,

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/airzone_cloud",
"iot_class": "cloud_push",
"loggers": ["aioairzone_cloud"],
"requirements": ["aioairzone-cloud==0.5.2"]
"requirements": ["aioairzone-cloud==0.5.3"]
}

View File

@@ -18,8 +18,14 @@
},
"entity": {
"binary_sensor": {
"air_demand": {
"name": "Air demand"
},
"air_quality_active": {
"name": "Air Quality active"
},
"floor_demand": {
"name": "Floor demand"
}
},
"select": {

View File

@@ -1,9 +1,9 @@
"""The Aladdin Connect Genie integration."""
# mypy: ignore-errors
from __future__ import annotations
from genie_partner_sdk.client import AladdinConnectClient
# from genie_partner_sdk.client import AladdinConnectClient
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant

View File

@@ -1,10 +1,11 @@
"""API for Aladdin Connect Genie bound to Home Assistant OAuth."""
# mypy: ignore-errors
from typing import cast
from aiohttp import ClientSession
from genie_partner_sdk.auth import Auth
# from genie_partner_sdk.auth import Auth
from homeassistant.helpers.config_entry_oauth2_flow import OAuth2Session
API_URL = "https://twdvzuefzh.execute-api.us-east-2.amazonaws.com/v1"

View File

@@ -1,11 +1,11 @@
"""Define an object to coordinate fetching Aladdin Connect data."""
# mypy: ignore-errors
from datetime import timedelta
import logging
from genie_partner_sdk.client import AladdinConnectClient
from genie_partner_sdk.model import GarageDoor
# from genie_partner_sdk.client import AladdinConnectClient
# from genie_partner_sdk.model import GarageDoor
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

View File

@@ -1,9 +1,9 @@
"""Cover Entity for Genie Garage Door."""
# mypy: ignore-errors
from typing import Any
from genie_partner_sdk.model import GarageDoor
# from genie_partner_sdk.model import GarageDoor
from homeassistant.components.cover import (
CoverDeviceClass,
CoverEntity,

View File

@@ -1,6 +1,6 @@
"""Defines a base Aladdin Connect entity."""
from genie_partner_sdk.model import GarageDoor
# mypy: ignore-errors
# from genie_partner_sdk.model import GarageDoor
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity

View File

@@ -4,6 +4,7 @@
"codeowners": ["@swcloudgenie"],
"config_flow": true,
"dependencies": ["application_credentials"],
"disabled": "This integration is disabled because it uses non-open source code to operate.",
"documentation": "https://www.home-assistant.io/integrations/aladdin_connect",
"iot_class": "cloud_polling",
"requirements": ["genie-partner-sdk==1.0.2"]

View File

@@ -0,0 +1,5 @@
extend = "../../../pyproject.toml"
lint.extend-ignore = [
"F821"
]

View File

@@ -1,13 +1,13 @@
"""Support for Aladdin Connect Garage Door sensors."""
# mypy: ignore-errors
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from genie_partner_sdk.client import AladdinConnectClient
from genie_partner_sdk.model import GarageDoor
# from genie_partner_sdk.client import AladdinConnectClient
# from genie_partner_sdk.model import GarageDoor
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,

View File

@@ -34,7 +34,6 @@ from homeassistant.helpers.entity import Entity, EntityDescription
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import ConfigType
from . import group as group_pre_import # noqa: F401
from .const import ( # noqa: F401
_DEPRECATED_FORMAT_NUMBER,
_DEPRECATED_FORMAT_TEXT,
@@ -53,8 +52,10 @@ from .const import ( # noqa: F401
_LOGGER: Final = logging.getLogger(__name__)
SCAN_INTERVAL: Final = timedelta(seconds=30)
ENTITY_ID_FORMAT: Final = DOMAIN + ".{}"
PLATFORM_SCHEMA: Final = cv.PLATFORM_SCHEMA
PLATFORM_SCHEMA_BASE: Final = cv.PLATFORM_SCHEMA_BASE
SCAN_INTERVAL: Final = timedelta(seconds=30)
CONF_DEFAULT_CODE = "default_code"
@@ -62,8 +63,6 @@ ALARM_SERVICE_SCHEMA: Final = make_entity_service_schema(
{vol.Optional(ATTR_CODE): cv.string}
)
PLATFORM_SCHEMA: Final = cv.PLATFORM_SCHEMA
PLATFORM_SCHEMA_BASE: Final = cv.PLATFORM_SCHEMA_BASE
# mypy: disallow-any-generics

View File

@@ -1,43 +0,0 @@
"""Describe group states."""
from __future__ import annotations
from typing import TYPE_CHECKING
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_CUSTOM_BYPASS,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_ARMED_VACATION,
STATE_ALARM_TRIGGERED,
STATE_OFF,
STATE_ON,
)
from homeassistant.core import HomeAssistant, callback
from .const import DOMAIN
if TYPE_CHECKING:
from homeassistant.components.group import GroupIntegrationRegistry
@callback
def async_describe_on_off_states(
hass: HomeAssistant, registry: GroupIntegrationRegistry
) -> None:
"""Describe group on off states."""
registry.on_off_states(
DOMAIN,
{
STATE_ON,
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_CUSTOM_BYPASS,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_ARMED_VACATION,
STATE_ALARM_TRIGGERED,
},
STATE_ON,
STATE_OFF,
)

View File

@@ -1,14 +1,15 @@
# Describes the format for available alarm control panel services
.common_service_fields: &common_service_fields
code:
example: "1234"
selector:
text:
alarm_disarm:
target:
entity:
domain: alarm_control_panel
fields:
code:
example: "1234"
selector:
text:
fields: *common_service_fields
alarm_arm_custom_bypass:
target:
@@ -16,11 +17,7 @@ alarm_arm_custom_bypass:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS
fields:
code:
example: "1234"
selector:
text:
fields: *common_service_fields
alarm_arm_home:
target:
@@ -28,11 +25,7 @@ alarm_arm_home:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_HOME
fields:
code:
example: "1234"
selector:
text:
fields: *common_service_fields
alarm_arm_away:
target:
@@ -40,23 +33,14 @@ alarm_arm_away:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_AWAY
fields:
code:
example: "1234"
selector:
text:
fields: *common_service_fields
alarm_arm_night:
target:
entity:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_NIGHT
fields:
code:
example: "1234"
selector:
text:
fields: *common_service_fields
alarm_arm_vacation:
target:
@@ -64,11 +48,7 @@ alarm_arm_vacation:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_VACATION
fields:
code:
example: "1234"
selector:
text:
fields: *common_service_fields
alarm_trigger:
target:
@@ -76,8 +56,4 @@ alarm_trigger:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.TRIGGER
fields:
code:
example: "1234"
selector:
text:
fields: *common_service_fields

View File

@@ -10,7 +10,10 @@ from alpha_vantage.timeseries import TimeSeries
import voluptuous as vol
from homeassistant.components import persistent_notification
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.components.sensor import (
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
SensorEntity,
)
from homeassistant.const import CONF_API_KEY, CONF_CURRENCY, CONF_NAME
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
@@ -59,7 +62,7 @@ CURRENCY_SCHEMA = vol.Schema(
}
)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_API_KEY): cv.string,
vol.Optional(CONF_FOREIGN_EXCHANGE): vol.All(cv.ensure_list, [CURRENCY_SCHEMA]),

View File

@@ -10,7 +10,7 @@ import botocore
import voluptuous as vol
from homeassistant.components.tts import (
PLATFORM_SCHEMA as BASE_PLATFORM_SCHEMA,
PLATFORM_SCHEMA as TTS_PLATFORM_SCHEMA,
Provider,
TtsAudioType,
)
@@ -49,7 +49,7 @@ from .const import (
_LOGGER: Final = logging.getLogger(__name__)
PLATFORM_SCHEMA: Final = BASE_PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA: Final = TTS_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_REGION, default=DEFAULT_REGION): vol.In(SUPPORTED_REGIONS),
vol.Inclusive(CONF_ACCESS_KEY_ID, ATTR_CREDENTIALS): cv.string,

View File

@@ -12,6 +12,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_MAC
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util import dt as dt_util
from .const import API_LAST_DATA, DOMAIN, LOGGER
from .helper import get_station_name
@@ -24,6 +25,7 @@ class AmbientNetworkDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]])
config_entry: ConfigEntry
station_name: str
last_measured: datetime | None = None
def __init__(self, hass: HomeAssistant, api: OpenAPI) -> None:
"""Initialize the coordinator."""
@@ -47,19 +49,13 @@ class AmbientNetworkDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]])
f"Station '{self.config_entry.title}' did not report any data"
)
# Eliminate data if the station hasn't been updated for a while.
if (created_at := last_data.get("created_at")) is None:
raise UpdateFailed(
f"Station '{self.config_entry.title}' did not report a time stamp"
)
# Eliminate data that has been generated more than an hour ago. The station is
# probably offline.
if int(created_at / 1000) < int(
(datetime.now() - timedelta(hours=1)).timestamp()
):
raise UpdateFailed(
f"Station '{self.config_entry.title}' reported stale data"
# Some stations do not report a "created_at" or "dateutc".
# See https://github.com/home-assistant/core/issues/116917
if (ts := last_data.get("created_at")) is not None or (
ts := last_data.get("dateutc")
) is not None:
self.last_measured = datetime.fromtimestamp(
ts / 1000, tz=dt_util.DEFAULT_TIME_ZONE
)
return cast(dict[str, Any], last_data)

View File

@@ -299,12 +299,10 @@ class AmbientNetworkSensor(AmbientNetworkEntity, SensorEntity):
mac_address: str,
) -> None:
"""Initialize a sensor object."""
super().__init__(coordinator, description, mac_address)
def _update_attrs(self) -> None:
"""Update sensor attributes."""
value = self.coordinator.data.get(self.entity_description.key)
# Treatments for special units.
@@ -315,3 +313,8 @@ class AmbientNetworkSensor(AmbientNetworkEntity, SensorEntity):
self._attr_available = value is not None
self._attr_native_value = value
if self.coordinator.last_measured is not None:
self._attr_extra_state_attributes = {
"last_measured": self.coordinator.last_measured
}

View File

@@ -182,7 +182,7 @@ class AmbientStation:
# already been done):
if not self._entry_setup_complete:
self._hass.async_create_task(
self._hass.config_entries.async_late_forward_entry_setups(
self._hass.config_entries.async_forward_entry_setups(
self._entry, PLATFORMS
),
eager_start=True,

View File

@@ -9,7 +9,7 @@ from asmog import AmpioSmog
import voluptuous as vol
from homeassistant.components.air_quality import (
PLATFORM_SCHEMA as BASE_PLATFORM_SCHEMA,
PLATFORM_SCHEMA as AIR_QUALITY_PLATFORM_SCHEMA,
AirQualityEntity,
)
from homeassistant.const import CONF_NAME
@@ -24,7 +24,7 @@ from .const import CONF_STATION_ID, SCAN_INTERVAL
_LOGGER: Final = logging.getLogger(__name__)
PLATFORM_SCHEMA: Final = BASE_PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA: Final = AIR_QUALITY_PLATFORM_SCHEMA.extend(
{vol.Required(CONF_STATION_ID): cv.string, vol.Optional(CONF_NAME): cv.string}
)

View File

@@ -24,12 +24,22 @@ from homeassistant.config_entries import (
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME
from homeassistant.core import callback
from homeassistant.helpers.device_registry import format_mac
from homeassistant.helpers.selector import (
SelectOptionDict,
SelectSelector,
SelectSelectorConfig,
SelectSelectorMode,
)
from .const import CONF_ENABLE_IME, DOMAIN
from .const import CONF_APP_ICON, CONF_APP_NAME, CONF_APPS, CONF_ENABLE_IME, DOMAIN
from .helpers import create_api, get_enable_ime
_LOGGER = logging.getLogger(__name__)
APPS_NEW_ID = "NewApp"
CONF_APP_DELETE = "app_delete"
CONF_APP_ID = "app_id"
STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required("host"): str,
@@ -213,17 +223,46 @@ class AndroidTVRemoteConfigFlow(ConfigFlow, domain=DOMAIN):
class AndroidTVRemoteOptionsFlowHandler(OptionsFlowWithConfigEntry):
"""Android TV Remote options flow."""
def __init__(self, config_entry: ConfigEntry) -> None:
"""Initialize options flow."""
super().__init__(config_entry)
self._apps: dict[str, Any] = self.options.setdefault(CONF_APPS, {})
self._conf_app_id: str | None = None
@callback
def _save_config(self, data: dict[str, Any]) -> ConfigFlowResult:
"""Save the updated options."""
new_data = {k: v for k, v in data.items() if k not in [CONF_APPS]}
if self._apps:
new_data[CONF_APPS] = self._apps
return self.async_create_entry(title="", data=new_data)
async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Manage the options."""
if user_input is not None:
return self.async_create_entry(title="", data=user_input)
if sel_app := user_input.get(CONF_APPS):
return await self.async_step_apps(None, sel_app)
return self._save_config(user_input)
apps_list = {
k: f"{v[CONF_APP_NAME]} ({k})" if CONF_APP_NAME in v else k
for k, v in self._apps.items()
}
apps = [SelectOptionDict(value=APPS_NEW_ID, label="Add new")] + [
SelectOptionDict(value=k, label=v) for k, v in apps_list.items()
]
return self.async_show_form(
step_id="init",
data_schema=vol.Schema(
{
vol.Optional(CONF_APPS): SelectSelector(
SelectSelectorConfig(
options=apps, mode=SelectSelectorMode.DROPDOWN
)
),
vol.Required(
CONF_ENABLE_IME,
default=get_enable_ime(self.config_entry),
@@ -231,3 +270,61 @@ class AndroidTVRemoteOptionsFlowHandler(OptionsFlowWithConfigEntry):
}
),
)
async def async_step_apps(
self, user_input: dict[str, Any] | None = None, app_id: str | None = None
) -> ConfigFlowResult:
"""Handle options flow for apps list."""
if app_id is not None:
self._conf_app_id = app_id if app_id != APPS_NEW_ID else None
return self._async_apps_form(app_id)
if user_input is not None:
app_id = user_input.get(CONF_APP_ID, self._conf_app_id)
if app_id:
if user_input.get(CONF_APP_DELETE, False):
self._apps.pop(app_id)
else:
self._apps[app_id] = {
CONF_APP_NAME: user_input.get(CONF_APP_NAME, ""),
CONF_APP_ICON: user_input.get(CONF_APP_ICON, ""),
}
return await self.async_step_init()
@callback
def _async_apps_form(self, app_id: str) -> ConfigFlowResult:
"""Return configuration form for apps."""
app_schema = {
vol.Optional(
CONF_APP_NAME,
description={
"suggested_value": self._apps[app_id].get(CONF_APP_NAME, "")
if app_id in self._apps
else ""
},
): str,
vol.Optional(
CONF_APP_ICON,
description={
"suggested_value": self._apps[app_id].get(CONF_APP_ICON, "")
if app_id in self._apps
else ""
},
): str,
}
if app_id == APPS_NEW_ID:
data_schema = vol.Schema({**app_schema, vol.Optional(CONF_APP_ID): str})
else:
data_schema = vol.Schema(
{**app_schema, vol.Optional(CONF_APP_DELETE, default=False): bool}
)
return self.async_show_form(
step_id="apps",
data_schema=data_schema,
description_placeholders={
"app_id": f"`{app_id}`" if app_id != APPS_NEW_ID else "",
},
)

View File

@@ -6,5 +6,8 @@ from typing import Final
DOMAIN: Final = "androidtv_remote"
CONF_APPS = "apps"
CONF_ENABLE_IME: Final = "enable_ime"
CONF_ENABLE_IME_DEFAULT_VALUE: Final = True
CONF_APP_NAME = "app_name"
CONF_APP_ICON = "app_icon"

View File

@@ -2,6 +2,8 @@
from __future__ import annotations
from typing import Any
from androidtvremote2 import AndroidTVRemote, ConnectionClosed
from homeassistant.config_entries import ConfigEntry
@@ -11,7 +13,7 @@ from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
from homeassistant.helpers.entity import Entity
from .const import DOMAIN
from .const import CONF_APPS, DOMAIN
class AndroidTVRemoteBaseEntity(Entity):
@@ -26,6 +28,7 @@ class AndroidTVRemoteBaseEntity(Entity):
self._api = api
self._host = config_entry.data[CONF_HOST]
self._name = config_entry.data[CONF_NAME]
self._apps: dict[str, Any] = config_entry.options.get(CONF_APPS, {})
self._attr_unique_id = config_entry.unique_id
self._attr_is_on = api.is_on
device_info = api.device_info

View File

@@ -8,17 +8,20 @@ from typing import Any
from androidtvremote2 import AndroidTVRemote, ConnectionClosed
from homeassistant.components.media_player import (
MediaClass,
MediaPlayerDeviceClass,
MediaPlayerEntity,
MediaPlayerEntityFeature,
MediaPlayerState,
MediaType,
)
from homeassistant.components.media_player.browse_media import BrowseMedia
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AndroidTVRemoteConfigEntry
from .const import CONF_APP_ICON, CONF_APP_NAME
from .entity import AndroidTVRemoteBaseEntity
PARALLEL_UPDATES = 0
@@ -50,6 +53,7 @@ class AndroidTVRemoteMediaPlayerEntity(AndroidTVRemoteBaseEntity, MediaPlayerEnt
| MediaPlayerEntityFeature.PLAY
| MediaPlayerEntityFeature.STOP
| MediaPlayerEntityFeature.PLAY_MEDIA
| MediaPlayerEntityFeature.BROWSE_MEDIA
)
def __init__(
@@ -65,7 +69,11 @@ class AndroidTVRemoteMediaPlayerEntity(AndroidTVRemoteBaseEntity, MediaPlayerEnt
def _update_current_app(self, current_app: str) -> None:
"""Update current app info."""
self._attr_app_id = current_app
self._attr_app_name = current_app
self._attr_app_name = (
self._apps[current_app].get(CONF_APP_NAME, current_app)
if current_app in self._apps
else current_app
)
def _update_volume_info(self, volume_info: dict[str, str | bool]) -> None:
"""Update volume info."""
@@ -176,12 +184,41 @@ class AndroidTVRemoteMediaPlayerEntity(AndroidTVRemoteBaseEntity, MediaPlayerEnt
await self._channel_set_task
return
if media_type == MediaType.URL:
if media_type in [MediaType.URL, MediaType.APP]:
self._send_launch_app_command(media_id)
return
raise ValueError(f"Invalid media type: {media_type}")
async def async_browse_media(
self,
media_content_type: MediaType | str | None = None,
media_content_id: str | None = None,
) -> BrowseMedia:
"""Browse apps."""
children = [
BrowseMedia(
media_class=MediaClass.APP,
media_content_type=MediaType.APP,
media_content_id=app_id,
title=app.get(CONF_APP_NAME, ""),
thumbnail=app.get(CONF_APP_ICON, ""),
can_play=False,
can_expand=False,
)
for app_id, app in self._apps.items()
]
return BrowseMedia(
title="Applications",
media_class=MediaClass.DIRECTORY,
media_content_id="apps",
media_content_type=MediaType.APPS,
children_media_class=MediaClass.APP,
can_play=False,
can_expand=True,
children=children,
)
async def _send_key_commands(
self, key_codes: list[str], delay_secs: float = 0.1
) -> None:

View File

@@ -21,6 +21,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AndroidTVRemoteConfigEntry
from .const import CONF_APP_NAME
from .entity import AndroidTVRemoteBaseEntity
PARALLEL_UPDATES = 0
@@ -41,17 +42,28 @@ class AndroidTVRemoteEntity(AndroidTVRemoteBaseEntity, RemoteEntity):
_attr_supported_features = RemoteEntityFeature.ACTIVITY
def _update_current_app(self, current_app: str) -> None:
"""Update current app info."""
self._attr_current_activity = (
self._apps[current_app].get(CONF_APP_NAME, current_app)
if current_app in self._apps
else current_app
)
@callback
def _current_app_updated(self, current_app: str) -> None:
"""Update the state when the current app changes."""
self._attr_current_activity = current_app
self._update_current_app(current_app)
self.async_write_ha_state()
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
await super().async_added_to_hass()
self._attr_current_activity = self._api.current_app
self._attr_activity_list = [
app.get(CONF_APP_NAME, "") for app in self._apps.values()
]
self._update_current_app(self._api.current_app)
self._api.add_current_app_updated_callback(self._current_app_updated)
async def async_will_remove_from_hass(self) -> None:
@@ -66,6 +78,14 @@ class AndroidTVRemoteEntity(AndroidTVRemoteBaseEntity, RemoteEntity):
self._send_key_command("POWER")
activity = kwargs.get(ATTR_ACTIVITY, "")
if activity:
activity = next(
(
app_id
for app_id, app in self._apps.items()
if app.get(CONF_APP_NAME, "") == activity
),
activity,
)
self._send_launch_app_command(activity)
async def async_turn_off(self, **kwargs: Any) -> None:

View File

@@ -39,8 +39,19 @@
"step": {
"init": {
"data": {
"apps": "Configure applications list",
"enable_ime": "Enable IME. Needed for getting the current app. Disable for devices that show 'Use keyboard on mobile device screen' instead of the on screen keyboard."
}
},
"apps": {
"title": "Configure Android Apps",
"description": "Configure application id {app_id}",
"data": {
"app_name": "Application Name",
"app_id": "Application ID",
"app_icon": "Application Icon",
"app_delete": "Check to delete this application"
}
}
}
}

View File

@@ -9,7 +9,10 @@ from typing import Any
from anel_pwrctrl import Device, DeviceMaster, Switch
import voluptuous as vol
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.components.switch import (
PLATFORM_SCHEMA as SWITCH_PLATFORM_SCHEMA,
SwitchEntity,
)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
@@ -24,7 +27,7 @@ CONF_PORT_SEND = "port_send"
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=5)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = SWITCH_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_PORT_RECV): cv.port,
vol.Required(CONF_PORT_SEND): cv.port,

View File

@@ -29,7 +29,7 @@ from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import collection, config_entry_oauth2_flow
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import ConfigType
from homeassistant.helpers.typing import ConfigType, VolDictType
from homeassistant.loader import (
IntegrationNotFound,
async_get_application_credentials,
@@ -49,14 +49,14 @@ DATA_STORAGE = "storage"
CONF_AUTH_DOMAIN = "auth_domain"
DEFAULT_IMPORT_NAME = "Import from configuration.yaml"
CREATE_FIELDS = {
CREATE_FIELDS: VolDictType = {
vol.Required(CONF_DOMAIN): cv.string,
vol.Required(CONF_CLIENT_ID): vol.All(cv.string, vol.Strip),
vol.Required(CONF_CLIENT_SECRET): vol.All(cv.string, vol.Strip),
vol.Optional(CONF_AUTH_DOMAIN): cv.string,
vol.Optional(CONF_NAME): cv.string,
}
UPDATE_FIELDS: dict = {} # Not supported
UPDATE_FIELDS: VolDictType = {} # Not supported
CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN)

View File

@@ -12,7 +12,7 @@ from homeassistant.components.notify import (
ATTR_TARGET,
ATTR_TITLE,
ATTR_TITLE_DEFAULT,
PLATFORM_SCHEMA,
PLATFORM_SCHEMA as NOTIFY_PLATFORM_SCHEMA,
BaseNotificationService,
)
from homeassistant.const import CONF_URL
@@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__)
CONF_FILE = "config"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = NOTIFY_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_URL): vol.All(cv.ensure_list, [str]),
vol.Optional(CONF_FILE): cv.string,

View File

@@ -15,7 +15,11 @@ from homeassistant.helpers.device_registry import format_mac
from .const import DOMAIN
from .coordinator import AprilaireCoordinator
PLATFORMS: list[Platform] = [Platform.CLIMATE]
PLATFORMS: list[Platform] = [
Platform.CLIMATE,
Platform.SELECT,
Platform.SENSOR,
]
_LOGGER = logging.getLogger(__name__)

View File

@@ -0,0 +1,153 @@
"""The Aprilaire select component."""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import cast
from pyaprilaire.const import Attribute
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import AprilaireCoordinator
from .entity import BaseAprilaireEntity
AIR_CLEANING_EVENT_MAP = {0: "off", 3: "event_clean", 4: "allergies"}
AIR_CLEANING_MODE_MAP = {0: "off", 1: "constant_clean", 2: "automatic"}
FRESH_AIR_EVENT_MAP = {0: "off", 2: "3hour", 3: "24hour"}
FRESH_AIR_MODE_MAP = {0: "off", 1: "automatic"}
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Aprilaire select devices."""
coordinator: AprilaireCoordinator = hass.data[DOMAIN][config_entry.unique_id]
assert config_entry.unique_id is not None
descriptions: list[AprilaireSelectDescription] = []
if coordinator.data.get(Attribute.AIR_CLEANING_AVAILABLE) == 1:
descriptions.extend(
[
AprilaireSelectDescription(
key="air_cleaning_event",
translation_key="air_cleaning_event",
options_map=AIR_CLEANING_EVENT_MAP,
event_value_key=Attribute.AIR_CLEANING_EVENT,
mode_value_key=Attribute.AIR_CLEANING_MODE,
is_event=True,
select_option_fn=coordinator.client.set_air_cleaning,
),
AprilaireSelectDescription(
key="air_cleaning_mode",
translation_key="air_cleaning_mode",
options_map=AIR_CLEANING_MODE_MAP,
event_value_key=Attribute.AIR_CLEANING_EVENT,
mode_value_key=Attribute.AIR_CLEANING_MODE,
is_event=False,
select_option_fn=coordinator.client.set_air_cleaning,
),
]
)
if coordinator.data.get(Attribute.VENTILATION_AVAILABLE) == 1:
descriptions.extend(
[
AprilaireSelectDescription(
key="fresh_air_event",
translation_key="fresh_air_event",
options_map=FRESH_AIR_EVENT_MAP,
event_value_key=Attribute.FRESH_AIR_EVENT,
mode_value_key=Attribute.FRESH_AIR_MODE,
is_event=True,
select_option_fn=coordinator.client.set_fresh_air,
),
AprilaireSelectDescription(
key="fresh_air_mode",
translation_key="fresh_air_mode",
options_map=FRESH_AIR_MODE_MAP,
event_value_key=Attribute.FRESH_AIR_EVENT,
mode_value_key=Attribute.FRESH_AIR_MODE,
is_event=False,
select_option_fn=coordinator.client.set_fresh_air,
),
]
)
async_add_entities(
AprilaireSelectEntity(coordinator, description, config_entry.unique_id)
for description in descriptions
)
@dataclass(frozen=True, kw_only=True)
class AprilaireSelectDescription(SelectEntityDescription):
"""Class describing Aprilaire select entities."""
options_map: dict[int, str]
event_value_key: str
mode_value_key: str
is_event: bool
select_option_fn: Callable[[int, int], Awaitable]
class AprilaireSelectEntity(BaseAprilaireEntity, SelectEntity):
"""Base select entity for Aprilaire."""
entity_description: AprilaireSelectDescription
def __init__(
self,
coordinator: AprilaireCoordinator,
description: AprilaireSelectDescription,
unique_id: str,
) -> None:
"""Initialize a select for an Aprilaire device."""
self.entity_description = description
self.values_map = {v: k for k, v in description.options_map.items()}
super().__init__(coordinator, unique_id)
self._attr_options = list(description.options_map.values())
@property
def current_option(self) -> str:
"""Get the current option."""
if self.entity_description.is_event:
value_key = self.entity_description.event_value_key
else:
value_key = self.entity_description.mode_value_key
current_value = int(self.coordinator.data.get(value_key, 0))
return self.entity_description.options_map.get(current_value, "off")
async def async_select_option(self, option: str) -> None:
"""Set the current option."""
if self.entity_description.is_event:
event_value = self.values_map[option]
mode_value = cast(
int, self.coordinator.data.get(self.entity_description.mode_value_key)
)
else:
mode_value = self.values_map[option]
event_value = cast(
int, self.coordinator.data.get(self.entity_description.event_value_key)
)
await self.entity_description.select_option_fn(mode_value, event_value)

View File

@@ -0,0 +1,308 @@
"""The Aprilaire sensor component."""
from __future__ import annotations
from dataclasses import dataclass
from typing import cast
from pyaprilaire.const import Attribute
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from .const import DOMAIN
from .coordinator import AprilaireCoordinator
from .entity import BaseAprilaireEntity
DEHUMIDIFICATION_STATUS_MAP: dict[StateType, str] = {
0: "idle",
1: "idle",
2: "on",
3: "on",
4: "off",
}
HUMIDIFICATION_STATUS_MAP: dict[StateType, str] = {
0: "idle",
1: "idle",
2: "on",
3: "off",
}
VENTILATION_STATUS_MAP: dict[StateType, str] = {
0: "idle",
1: "idle",
2: "on",
3: "idle",
4: "idle",
5: "idle",
6: "off",
}
AIR_CLEANING_STATUS_MAP: dict[StateType, str] = {
0: "idle",
1: "idle",
2: "on",
3: "off",
}
FAN_STATUS_MAP: dict[StateType, str] = {0: "off", 1: "on"}
def get_entities(
entity_class: type[BaseAprilaireSensor],
coordinator: AprilaireCoordinator,
unique_id: str,
descriptions: tuple[AprilaireSensorDescription, ...],
) -> list[BaseAprilaireSensor]:
"""Get the entities for a list of sensor descriptions."""
entities = (
entity_class(coordinator, description, unique_id)
for description in descriptions
)
return [entity for entity in entities if entity.exists]
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Aprilaire sensor devices."""
coordinator: AprilaireCoordinator = hass.data[DOMAIN][config_entry.unique_id]
assert config_entry.unique_id is not None
entities = (
get_entities(
AprilaireHumiditySensor,
coordinator,
config_entry.unique_id,
HUMIDITY_SENSORS,
)
+ get_entities(
AprilaireTemperatureSensor,
coordinator,
config_entry.unique_id,
TEMPERATURE_SENSORS,
)
+ get_entities(
AprilaireStatusSensor, coordinator, config_entry.unique_id, STATUS_SENSORS
)
)
async_add_entities(entities)
@dataclass(frozen=True, kw_only=True)
class AprilaireSensorDescription(SensorEntityDescription):
"""Class describing Aprilaire sensor entities."""
status_key: str | None
value_key: str
@dataclass(frozen=True, kw_only=True)
class AprilaireStatusSensorDescription(AprilaireSensorDescription):
"""Class describing Aprilaire status sensor entities."""
status_map: dict[StateType, str]
HUMIDITY_SENSORS: tuple[AprilaireSensorDescription, ...] = (
AprilaireSensorDescription(
key="indoor_humidity_controlling_sensor",
translation_key="indoor_humidity_controlling_sensor",
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
status_key=Attribute.INDOOR_HUMIDITY_CONTROLLING_SENSOR_STATUS,
value_key=Attribute.INDOOR_HUMIDITY_CONTROLLING_SENSOR_VALUE,
),
AprilaireSensorDescription(
key="outdoor_humidity_controlling_sensor",
translation_key="outdoor_humidity_controlling_sensor",
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
status_key=Attribute.OUTDOOR_HUMIDITY_CONTROLLING_SENSOR_STATUS,
value_key=Attribute.OUTDOOR_HUMIDITY_CONTROLLING_SENSOR_VALUE,
),
)
TEMPERATURE_SENSORS: tuple[AprilaireSensorDescription, ...] = (
AprilaireSensorDescription(
key="indoor_temperature_controlling_sensor",
translation_key="indoor_temperature_controlling_sensor",
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
status_key=Attribute.INDOOR_TEMPERATURE_CONTROLLING_SENSOR_STATUS,
value_key=Attribute.INDOOR_TEMPERATURE_CONTROLLING_SENSOR_VALUE,
),
AprilaireSensorDescription(
key="outdoor_temperature_controlling_sensor",
translation_key="outdoor_temperature_controlling_sensor",
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
status_key=Attribute.OUTDOOR_TEMPERATURE_CONTROLLING_SENSOR_STATUS,
value_key=Attribute.OUTDOOR_TEMPERATURE_CONTROLLING_SENSOR_VALUE,
),
)
STATUS_SENSORS: tuple[AprilaireSensorDescription, ...] = (
AprilaireStatusSensorDescription(
key="dehumidification_status",
translation_key="dehumidification_status",
device_class=SensorDeviceClass.ENUM,
status_key=Attribute.DEHUMIDIFICATION_AVAILABLE,
value_key=Attribute.DEHUMIDIFICATION_STATUS,
status_map=DEHUMIDIFICATION_STATUS_MAP,
options=list(set(DEHUMIDIFICATION_STATUS_MAP.values())),
),
AprilaireStatusSensorDescription(
key="humidification_status",
translation_key="humidification_status",
device_class=SensorDeviceClass.ENUM,
status_key=Attribute.HUMIDIFICATION_AVAILABLE,
value_key=Attribute.HUMIDIFICATION_STATUS,
status_map=HUMIDIFICATION_STATUS_MAP,
options=list(set(HUMIDIFICATION_STATUS_MAP.values())),
),
AprilaireStatusSensorDescription(
key="ventilation_status",
translation_key="ventilation_status",
device_class=SensorDeviceClass.ENUM,
status_key=Attribute.VENTILATION_AVAILABLE,
value_key=Attribute.VENTILATION_STATUS,
status_map=VENTILATION_STATUS_MAP,
options=list(set(VENTILATION_STATUS_MAP.values())),
),
AprilaireStatusSensorDescription(
key="air_cleaning_status",
translation_key="air_cleaning_status",
device_class=SensorDeviceClass.ENUM,
status_key=Attribute.AIR_CLEANING_AVAILABLE,
value_key=Attribute.AIR_CLEANING_STATUS,
status_map=AIR_CLEANING_STATUS_MAP,
options=list(set(AIR_CLEANING_STATUS_MAP.values())),
),
AprilaireStatusSensorDescription(
key="fan_status",
translation_key="fan_status",
device_class=SensorDeviceClass.ENUM,
status_key=None,
value_key=Attribute.FAN_STATUS,
status_map=FAN_STATUS_MAP,
options=list(set(FAN_STATUS_MAP.values())),
),
)
class BaseAprilaireSensor(BaseAprilaireEntity, SensorEntity):
"""Base sensor entity for Aprilaire."""
entity_description: AprilaireSensorDescription
status_sensor_available_value: int | None = None
status_sensor_exists_values: list[int]
def __init__(
self,
coordinator: AprilaireCoordinator,
description: AprilaireSensorDescription,
unique_id: str,
) -> None:
"""Initialize a sensor for an Aprilaire device."""
self.entity_description = description
super().__init__(coordinator, unique_id)
@property
def exists(self) -> bool:
"""Return True if the sensor exists."""
if self.entity_description.status_key is None:
return True
return (
self.coordinator.data.get(self.entity_description.status_key)
in self.status_sensor_exists_values
)
@property
def available(self) -> bool:
"""Return True if the sensor is available."""
if (
self.entity_description.status_key is None
or self.status_sensor_available_value is None
):
return True
if not super().available:
return False
return (
self.coordinator.data.get(self.entity_description.status_key)
== self.status_sensor_available_value
)
@property
def native_value(self) -> StateType:
"""Return the value reported by the sensor."""
# Valid cast as pyaprilaire only provides str | int | float
return cast(
StateType, self.coordinator.data.get(self.entity_description.value_key)
)
class AprilaireHumiditySensor(BaseAprilaireSensor):
"""Humidity sensor entity for Aprilaire."""
status_sensor_available_value = 0
status_sensor_exists_values = [0, 1, 2]
class AprilaireTemperatureSensor(BaseAprilaireSensor):
"""Temperature sensor entity for Aprilaire."""
status_sensor_available_value = 0
status_sensor_exists_values = [0, 1, 2]
@property
def suggested_display_precision(self) -> int | None:
"""Return the suggested number of decimal digits for display."""
if self.unit_of_measurement == UnitOfTemperature.CELSIUS:
return 1
return 0
class AprilaireStatusSensor(BaseAprilaireSensor):
"""Status sensor entity for Aprilaire."""
status_sensor_exists_values = [1, 2]
entity_description: AprilaireStatusSensorDescription
@property
def native_value(self) -> StateType:
"""Return the value reported by the sensor mapped to the status option."""
raw_value = super().native_value
return self.entity_description.status_map.get(raw_value)

View File

@@ -23,6 +23,92 @@
"thermostat": {
"name": "Thermostat"
}
},
"select": {
"air_cleaning_event": {
"name": "Air cleaning event",
"state": {
"off": "[%key:common::state::off%]",
"event_clean": "Event clean (3 hour)",
"allergies": "Allergies (24 hour)"
}
},
"air_cleaning_mode": {
"name": "Air cleaning mode",
"state": {
"off": "[%key:common::state::off%]",
"constant_clean": "Constant clean",
"automatic": "Automatic"
}
},
"fresh_air_event": {
"name": "Fresh air event",
"state": {
"off": "[%key:common::state::off%]",
"3hour": "3 hour event",
"24hour": "24 hour event"
}
},
"fresh_air_mode": {
"name": "Fresh air mode",
"state": {
"off": "[%key:common::state::off%]",
"automatic": "[%key:component::aprilaire::entity::select::air_cleaning_mode::state::automatic%]"
}
}
},
"sensor": {
"indoor_humidity_controlling_sensor": {
"name": "Indoor humidity controlling sensor"
},
"outdoor_humidity_controlling_sensor": {
"name": "Outdoor humidity controlling sensor"
},
"indoor_temperature_controlling_sensor": {
"name": "Indoor temperature controlling sensor"
},
"outdoor_temperature_controlling_sensor": {
"name": "Outdoor temperature controlling sensor"
},
"dehumidification_status": {
"name": "Dehumidification status",
"state": {
"idle": "[%key:common::state::idle%]",
"on": "[%key:common::state::on%]",
"off": "[%key:common::state::off%]"
}
},
"humidification_status": {
"name": "Humidification status",
"state": {
"idle": "[%key:common::state::idle%]",
"on": "[%key:common::state::on%]",
"off": "[%key:common::state::off%]"
}
},
"ventilation_status": {
"name": "Ventilation status",
"state": {
"idle": "[%key:common::state::idle%]",
"on": "[%key:common::state::on%]",
"off": "[%key:common::state::off%]"
}
},
"air_cleaning_status": {
"name": "Air cleaning status",
"state": {
"idle": "[%key:common::state::idle%]",
"on": "[%key:common::state::on%]",
"off": "[%key:common::state::off%]"
}
},
"fan_status": {
"name": "Fan status",
"state": {
"on": "[%key:common::state::on%]",
"off": "[%key:common::state::off%]"
}
}
}
}
}

View File

@@ -12,7 +12,7 @@ import geopy.distance
import voluptuous as vol
from homeassistant.components.device_tracker import (
PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA,
PLATFORM_SCHEMA as DEVICE_TRACKER_PLATFORM_SCHEMA,
SeeCallback,
)
from homeassistant.const import (
@@ -53,7 +53,7 @@ FILTER_PORT = 14580
MSG_FORMATS = ["compressed", "uncompressed", "mic-e", "object"]
PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = DEVICE_TRACKER_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_CALLSIGNS): cv.ensure_list,
vol.Required(CONF_USERNAME): cv.string,

View File

@@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant
from .coordinator import ApSystemsDataCoordinator
PLATFORMS: list[Platform] = [Platform.SENSOR]
PLATFORMS: list[Platform] = [Platform.NUMBER, Platform.SENSOR]
@dataclass

View File

@@ -0,0 +1,52 @@
"""The output limit which can be set in the APsystems local API integration."""
from __future__ import annotations
from homeassistant.components.number import NumberDeviceClass, NumberEntity, NumberMode
from homeassistant.const import UnitOfPower
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import DiscoveryInfoType
from . import ApSystemsConfigEntry, ApSystemsData
from .entity import ApSystemsEntity
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ApSystemsConfigEntry,
add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Set up the sensor platform."""
add_entities([ApSystemsMaxOutputNumber(config_entry.runtime_data)])
class ApSystemsMaxOutputNumber(ApSystemsEntity, NumberEntity):
"""Base sensor to be used with description."""
_attr_native_max_value = 800
_attr_native_min_value = 30
_attr_native_step = 1
_attr_device_class = NumberDeviceClass.POWER
_attr_mode = NumberMode.BOX
_attr_native_unit_of_measurement = UnitOfPower.WATT
_attr_translation_key = "max_output"
def __init__(
self,
data: ApSystemsData,
) -> None:
"""Initialize the sensor."""
super().__init__(data)
self._api = data.coordinator.api
self._attr_unique_id = f"{data.device_id}_output_limit"
async def async_update(self) -> None:
"""Set the state with the value fetched from the inverter."""
self._attr_native_value = await self._api.get_max_power()
async def async_set_native_value(self, value: float) -> None:
"""Set the desired output power."""
self._attr_native_value = await self._api.set_max_power(int(value))

View File

@@ -132,6 +132,7 @@ class ApSystemsSensorWithDescription(
"""Base sensor to be used with description."""
entity_description: ApsystemsLocalApiSensorDescription
_attr_has_entity_name = True
def __init__(
self,

View File

@@ -25,6 +25,9 @@
"today_production": { "name": "Production of today" },
"today_production_p1": { "name": "Production of today from P1" },
"today_production_p2": { "name": "Production of today from P2" }
},
"number": {
"max_output": { "name": "Max output" }
}
}
}

View File

@@ -13,7 +13,7 @@ from .coordinator import AquacellCoordinator
PLATFORMS = [Platform.SENSOR]
AquacellConfigEntry = ConfigEntry[AquacellCoordinator]
type AquacellConfigEntry = ConfigEntry[AquacellCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: AquacellConfigEntry) -> bool:

View File

@@ -7,7 +7,7 @@ from dataclasses import dataclass
import voluptuous as vol
from homeassistant.components.sensor import (
PLATFORM_SCHEMA,
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
@@ -104,7 +104,7 @@ SENSOR_TYPES: tuple[AquaLogicSensorEntityDescription, ...] = (
SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES]
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_MONITORED_CONDITIONS, default=SENSOR_KEYS): vol.All(
cv.ensure_list, [vol.In(SENSOR_KEYS)]

View File

@@ -7,7 +7,10 @@ from typing import Any
from aqualogic.core import States
import voluptuous as vol
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.components.switch import (
PLATFORM_SCHEMA as SWITCH_PLATFORM_SCHEMA,
SwitchEntity,
)
from homeassistant.const import CONF_MONITORED_CONDITIONS
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
@@ -30,7 +33,7 @@ SWITCH_TYPES = {
"aux_7": "Aux 7",
}
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = SWITCH_PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_MONITORED_CONDITIONS, default=list(SWITCH_TYPES)): vol.All(
cv.ensure_list, [vol.In(SWITCH_TYPES)]

View File

@@ -10,7 +10,7 @@ import sharp_aquos_rc
import voluptuous as vol
from homeassistant.components.media_player import (
PLATFORM_SCHEMA,
PLATFORM_SCHEMA as MEDIA_PLAYER_PLATFORM_SCHEMA,
MediaPlayerEntity,
MediaPlayerEntityFeature,
MediaPlayerState,
@@ -37,7 +37,7 @@ DEFAULT_PASSWORD = "password"
DEFAULT_TIMEOUT = 0.5
DEFAULT_RETRIES = 2
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
PLATFORM_SCHEMA = MEDIA_PLAYER_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,

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