Compare commits

...

171 Commits

Author SHA1 Message Date
Franck Nijhof
a301d51fb2 2024.10.3 (#128654) 2024-10-18 17:06:51 +02:00
Franck Nijhof
515771553f Bump version to 2024.10.3 2024-10-18 13:22:48 +02:00
mvn23
e204812d2b Bump pyotgw to 2.2.2 (#128594) 2024-10-18 13:22:22 +02:00
Petar Petrov
ca703cb858 Increase Z-Wave fallback thermostat range to 0-50 C (#128543)
* Z-Wave JS: Increase fallback thermostat range to 0-50 C

* update test
2024-10-18 13:21:49 +02:00
Louis Christ
b018d4a97d Bump pyblu to 1.0.4 (#128482) 2024-10-18 13:21:46 +02:00
dontinelli
146768ff8a Bump solarlog_cli to 0.3.2 (#128293) 2024-10-18 13:21:43 +02:00
Allen Porter
ea7473ed67 Bump gcal_sync to 6.1.6 (#128270) 2024-10-18 13:21:40 +02:00
Álvaro Fernández Rojas
0e8393766f Update aioairzone to v0.9.5 (#128265)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2024-10-18 13:21:36 +02:00
Álvaro Fernández Rojas
7d2536c503 Update aioairzone to v0.9.4 (#127792) 2024-10-18 13:21:31 +02:00
Simon Lamon
f9cbf1b30c Keep the provided name when creating a tag (#128240)
* Keep the name

* Add patch

* Update homeassistant/components/tag/__init__.py

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

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-10-18 13:20:21 +02:00
Adam Petrovic
d66d87d271 Fix daikin entities not refreshing quickly (#128230)
* Fix daikin entities not refreshing quickly

* Update homeassistant/components/daikin/switch.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-18 13:20:18 +02:00
Joost Lekkerkerker
5a8fa6cf38 Bump yt-dlp to 2024.10.07 (#128182) 2024-10-18 13:20:15 +02:00
Chris Talkington
76340035db Fix playing media via roku (#128133)
* re-support playing media via roku

* fixes

* test fixes

* Update test_media_player.py

* always send media type

* add description to options flow
2024-10-18 13:20:12 +02:00
puddly
0a26e68d0c Use the same ZHA database path during startup and when loading device triggers (#128130)
Use the same zigpy database path source as in the radio manager
2024-10-18 13:20:09 +02:00
Marc Hörsken
14127b910f Improve discovery of WMS WebControl pro by updating IP address (#128007) 2024-10-18 13:20:06 +02:00
Michael
ba4d081021 Fix printer uptime fluctuations in IPP (#127725)
* decrease uptime accuracy from seconds to minutes

* adjust tests

* calc uptime timestamp in coordinator

* bump pyipp to 0.17.0

* revert changes, just use the new printer.booted_at property

---------

Co-authored-by: Chris Talkington <chris@talkingtontech.com>
2024-10-18 13:19:43 +02:00
Marc Mueller
18d65d513e Update home-assistant-bluetooth to 1.13.0 (#127691) 2024-10-18 13:18:52 +02:00
Franck Nijhof
6952d2420f 2024.10.2 (#128176) 2024-10-11 18:25:02 +02:00
Franck Nijhof
9176994947 Bump version to 2024.10.2 2024-10-11 17:54:37 +02:00
Thomas55555
d389b55f40 Fix model in Husqvarna Automower (#128168) 2024-10-11 17:54:24 +02:00
Christopher Fenner
0ccff9fc54 Fix preset handling issue in ViCare (#128167)
* add test case

* fix test case

* fix issue

* change order
2024-10-11 17:54:21 +02:00
tronikos
a8836ca7b6 Remove some redundant code in Opower's coordinator from the fix in #128141 (#128150) 2024-10-11 17:54:17 +02:00
tronikos
f5d04a970f Bump opower to 0.8.3 (#128144) 2024-10-11 17:54:14 +02:00
tronikos
7aec98dafd Fix regression in Opower that was introduced in 2024.10.0 (#128141)
* Avoid KeyError when statistics have gaps

* fix break

* Remove unnecessary check
2024-10-11 17:54:10 +02:00
Marc Mueller
773564d4f5 Fix license script for ftfy (#128138) 2024-10-11 17:54:04 +02:00
Thomas55555
3e2edc1a2d Bump aioautomower to 2024.10.0 (#128137)
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2024-10-11 17:53:59 +02:00
Bram Kragten
9cfc9b9baf Update frontend to 20241002.3 (#128106) 2024-10-11 17:52:03 +02:00
David Knowles
92b67ead83 Increase Hydrawise polling interval to 60 seconds (#128090) 2024-10-11 17:50:35 +02:00
Steven B
ee9525cc00 Fix ring realtime events (#128083) 2024-10-11 17:49:38 +02:00
kingy444
571bfaf5d7 Fix casing on Powerview Gen3 zeroconf discovery (#128076) 2024-10-11 17:37:31 +02:00
Matthias Alphart
a3475607b2 Update xknxproject to 3.8.1 (#128057) 2024-10-11 17:37:28 +02:00
Michael
f0a653d010 Add missing translation string for re-auth flows (#128055) 2024-10-11 17:37:23 +02:00
Steven B.
eecdf66013 Fix missing reauth name translation placeholder in ring integration (#128048) 2024-10-11 17:37:19 +02:00
dontinelli
f99db05a4a Add missing translation string in solarlog (#128015) 2024-10-11 17:37:16 +02:00
Teemu R.
635731421f Increase tplink climate precision (#127996) 2024-10-11 17:37:13 +02:00
Maikel Punie
44743df7d6 Bump pyduotecno to 2024.10.0 (#127979) 2024-10-11 17:37:09 +02:00
epenet
33617694cc Fix firmware version parsing in venstar (#127974) 2024-10-11 17:37:06 +02:00
Raman Gupta
ed445d20b9 Fix zwave_js config validation for values (#127972) 2024-10-11 17:37:02 +02:00
Lenn
66c2fe091b Bump motionblindsble to 0.1.2 (#127954) 2024-10-11 17:36:59 +02:00
Antoine Reversat
8c80f47a35 Fix europe authentication in Fujitsu FGLair (#127947) 2024-10-11 17:36:53 +02:00
Marc Hörsken
e37025c1c7 Update pywmspro to 0.2.1 to fix handling of unknown products (#127942) 2024-10-11 17:36:50 +02:00
Marc Hörsken
0aabde081b Fix discovery of WMS WebControl pro by using IP address (#127939) 2024-10-11 17:36:46 +02:00
Steven B.
a1c9d53474 Bump python-kasa to 0.7.5 (#127934) 2024-10-11 17:36:43 +02:00
Maciej Bieniek
094996ad0c Bump imgw_pib library to version 1.0.6 (#127925)
Bump `imgw_pib`
2024-10-11 17:36:40 +02:00
Manu
ce359a7689 Add support of due date calculation for grey dailies in Habitica integration (#127923)
Fix grey dailies due date calculation
2024-10-11 17:36:36 +02:00
epenet
ee599160b3 Add missing translation string in yamaha_musiccast (#127912) 2024-10-11 17:36:32 +02:00
epenet
dd076f7a13 Add missing translation string in otbr (#127909) 2024-10-11 17:36:29 +02:00
dcmeglio
3021d38b6f Bump pyeconet to 0.1.23 (#127896) 2024-10-11 17:36:25 +02:00
G Johansson
bfcabeaf26 Bump holidays library to 0.58 (#127876) 2024-10-11 17:36:22 +02:00
G Johansson
c31e0336dc Don't error with missing information in systemmonitor diagnostics (#127868) 2024-10-11 17:36:14 +02:00
G Johansson
a1e42cac7a Fix merge_response template not mutate original object (#127865)
* Fix merge_response template not mutate original object

* Add comment
2024-10-11 17:36:11 +02:00
Michael
14a3e5b771 Add missing translation string in AVM Fritz!Smarthome (#127864) 2024-10-11 17:36:07 +02:00
azerty9971
5901c543da Fix wrong DPTypes returned by Tuya's cloud (#127860)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-10-11 17:36:04 +02:00
Jon Seager
456b80e6ae Bump pytouchlinesl to 0.1.8 (#127859) 2024-10-11 17:36:00 +02:00
dontinelli
e5644ae011 Reverse unintended change of unique_id for solarlog (#127845) 2024-10-11 17:35:57 +02:00
epenet
41c794c733 Add missing and fix incorrect translation string in duotecno (#127834) 2024-10-11 17:35:53 +02:00
epenet
a481448d46 Fix incorrect translation string in bryant_evolution (#127830) 2024-10-11 17:35:49 +02:00
epenet
2bd7ce618a Add missing translation string in blebox (#127827) 2024-10-11 17:35:45 +02:00
Erik Montnemery
da1ac4f1e9 Correct cleanup of sensor statistics repairs (#127826) 2024-10-11 17:35:42 +02:00
epenet
f0cb638106 Fix incorrect translation string in azure event hub (#127820) 2024-10-11 17:35:38 +02:00
epenet
dad2396d01 Add missing and fix incorrect translation string in aurora (#127818) 2024-10-11 17:35:34 +02:00
epenet
91e4d8b663 Fix incorrect translation string in analytics_insights (#127815) 2024-10-11 17:35:31 +02:00
epenet
e35496133e Add missing and fix incorrect translation string in alarmdecoder (#127814) 2024-10-11 17:35:28 +02:00
epenet
3be808ae1e Fix incorrect string in amberlectric (#127807) 2024-10-11 17:35:23 +02:00
TimL
c5772916a1 Bump pysmlight to v0.1.3 (#127804)
Bump pysmlight v0.1.3

Co-authored-by: Tim Lunn <tim@feathertop.org>
2024-10-11 17:35:18 +02:00
Álvaro Fernández Rojas
8cd63b80b1 Update aioairzone-cloud to v0.6.6 (#127789) 2024-10-11 17:35:14 +02:00
Johan Gustafsson
c087654386 Fix aurora alert sensor always Off (#127780) 2024-10-11 17:35:11 +02:00
Erik Montnemery
60b9e65c78 Bump pychromecast to 14.0.3 (#127778) 2024-10-11 17:35:08 +02:00
J. Nick Koston
79b304a5d2 Bump DoorBirdPy to 3.0.4 (#127760)
changelog: https://gitlab.com/klikini/doorbirdpy/-/compare/3.0.3...eea287316c6fd84b63cc67fd743cc1128ea14568?from_project_id=7409088&straight=false

fixes #126598
2024-10-11 17:35:00 +02:00
Franck Nijhof
bb9fd126e5 Update DoorBirdPy to 3.0.3 (#126949) 2024-10-11 17:34:40 +02:00
dontinelli
bff2d5c26c Bump solarlog_cli to 0.3.1 (#127753) 2024-10-11 17:31:18 +02:00
Ricardo Marques
46d9ac8380 Fix custom account config flow setup (#127750) 2024-10-11 17:31:15 +02:00
Simon Lamon
5da3ca4bb1 Bump python-linkplay to 0.0.15 (#127748) 2024-10-11 17:31:12 +02:00
Johan Gustafsson
2c99fdc092 Fix Aurora integration casts longitude and latitude to integer (#127740)
Fix Aurora integration casts longitude and latitude to integer (#100817)
2024-10-11 17:31:07 +02:00
Raj Laud
31a075fb13 Remove stale references in squeezebox services.yaml (#127739) 2024-10-11 17:31:04 +02:00
René Klomp
1d132d7a1e Migrate SMA unique id to str (#127732) 2024-10-11 17:31:01 +02:00
Michael
3b6f88cfa7 Increase connection timeout in CalDAV (#127727) 2024-10-11 17:30:57 +02:00
Joost Lekkerkerker
b927763d8d Add translation string for Withings wrong account (#127719) 2024-10-11 17:30:54 +02:00
Joost Lekkerkerker
d00e1cb6a5 Bump airgradient to 0.9.1 (#127718) 2024-10-11 17:30:50 +02:00
Joost Lekkerkerker
adf7474edb Bump NYT Games to 0.4.3 (#127717) 2024-10-11 17:30:46 +02:00
Joost Lekkerkerker
041d663cb8 Fix Withings log message (#127716) 2024-10-11 17:30:42 +02:00
Joost Lekkerkerker
37f611a8d3 Fix typo in HDMI CEC (#127714) 2024-10-11 17:30:39 +02:00
David Knowles
be99329efa Fix problems with automatic management of Schlage locks (#127689)
Use the correct identifiers for existing lock devices
2024-10-11 17:30:35 +02:00
Marc Mueller
327cb70bb8 Revert "Fix enum lookup (#125220)" (#127680)
This reverts commit 1bc63a61be.
2024-10-11 17:30:32 +02:00
dontinelli
be2b5a4c3a Bump fyta_cli to 0.6.7 (#127650) 2024-10-11 17:30:29 +02:00
Richard Cox
d1eda9dd73 Update Radarr config flow to standardize ports (#127620) 2024-10-11 17:30:25 +02:00
Brett Adams
b902cb5a13 Fix wake up in Tesla Fleet (#127615) 2024-10-11 17:30:21 +02:00
tronikos
1184ee4a59 Bump opower to 0.8.2 (#127598)
* Bump opower to 0.8.1 to fix enmax

* Update manifest.json

* Update requirements_all.txt

* Update requirements_test_all.txt
2024-10-11 17:30:18 +02:00
Noah Husby
2cf898afcc Bump aiostreammagic to 2.5.0 (#127595) 2024-10-11 17:30:13 +02:00
Louis Christ
df53e19eda Bump pyblu to 1.0.3 (#127571) 2024-10-11 17:28:18 +02:00
Brett Adams
7f79b26341 Fix Island status in Teslemetry (#127504) 2024-10-11 17:28:13 +02:00
Franck Nijhof
2182bc3af2 2024.10.1 (#127566) 2024-10-04 19:33:37 +02:00
Franck Nijhof
2cbf53ad7b Bump version to 2024.10.1 2024-10-04 14:57:14 +02:00
Joost Lekkerkerker
c52607b465 Revert "Bump pychromecast to 14.0.2 (#127333)" (#127555)
This reverts commit 2ab66f62fa.
2024-10-04 14:57:01 +02:00
Joost Lekkerkerker
087566072d Strip the NYT Games token (#127548) 2024-10-04 14:56:58 +02:00
Joost Lekkerkerker
6b814afd39 Create new clientsession for NYT Games (#127547) 2024-10-04 14:56:54 +02:00
Franck Nijhof
ea8aa6b07d Adjust polling rate of Rituals Perfume Genie (#127544) 2024-10-04 14:56:51 +02:00
Paarth Shah
1b0f731e30 Bump matrix-nio to 0.25.2 (#127535) 2024-10-04 14:56:48 +02:00
robinostlund
1ebde4a880 Fix int value in unique_id for Tellduslive (#127526)
Fix int in unique_id
2024-10-04 14:56:45 +02:00
Andrew Jackson
e53bd477b4 Bump aiomealie to 0.9.3 (#127454) 2024-10-04 14:56:41 +02:00
Brett Adams
3f9287c36b Add missing number platform to init of Tesla Fleet (#127406)
Add number platform to init
2024-10-04 14:56:38 +02:00
Erik Montnemery
b2b940fc32 Remove assumption in ConfigEntryItems about unique unique_id (#127399) 2024-10-04 14:56:35 +02:00
TimL
7d9e170512 Bump pysmlight 0.1.2 (#127376)
Co-authored-by: Tim Lunn <tim@feathertop.org>
2024-10-04 14:56:29 +02:00
Paul Bottein
6ab92abe80 Fix device id support for alarm control panel template (#127340) 2024-10-04 14:47:25 +02:00
Franck Nijhof
5db4a73d8e 2024.10.0 (#126782) 2024-10-02 19:41:46 +02:00
Franck Nijhof
acb0aeaa9a Bump version to 2024.10.0 2024-10-02 19:17:08 +02:00
Michael Hansen
dc7c909316 Bump intents to 2024.10.2 (#127338) 2024-10-02 19:14:50 +02:00
Erik Montnemery
a052e15319 Bump pychromecast to 14.0.2 (#127333) 2024-10-02 19:12:56 +02:00
Franck Nijhof
a50b299a82 Bump version to 2024.10.0b12 2024-10-02 17:18:01 +02:00
Bram Kragten
a6808a8fda Update frontend to 20241002.2 (#127331) 2024-10-02 17:16:58 +02:00
Franck Nijhof
7ac944c537 Bump version to 2024.10.0b11 2024-10-02 16:01:13 +02:00
Bram Kragten
7d3dd2dd6b Update frontend to 20241002.1 (#127292) 2024-10-02 16:00:43 +02:00
Christopher Fenner
48538ef5d5 Fix climate entity in ViCare integration (#127128)
do not reset _attributes
2024-10-02 16:00:38 +02:00
Franck Nijhof
5365439fd4 Bump version to 2024.10.0b10 2024-10-02 10:52:33 +02:00
Erik Montnemery
9c28a4e8a0 Make recorder WS command recorder/clear_statistics wait (#127120) 2024-10-02 10:51:30 +02:00
Bram Kragten
565203047c Update frontend to 20241002.0 (#127264) 2024-10-02 10:50:39 +02:00
Erik Montnemery
b9795a2ae7 Make recorder WS command recorder/update_statistics_metadata wait (#127179) 2024-10-02 10:50:35 +02:00
Franck Nijhof
4e4f8ee3a4 Bump version to 2024.10.0b9 2024-10-02 09:26:37 +02:00
Martin Hjelmare
b8fd921c81 Revert "Support Z-Wave JS dimming lights using color intensity (#122639)" (#127256)
This reverts commit c7cfd56b72.
2024-10-02 09:26:28 +02:00
Teemu R.
fcf91954ff Remove codefences from issue titles (#127254) 2024-10-02 09:26:25 +02:00
Michael Hansen
49708196ac Run unsubscribe callbacks when Assist satellite entity is removed from HA (#127234)
* Unsubscribe when removed from HA

* Use builtin async_on_remove
2024-10-02 09:26:22 +02:00
functionpointer
8c8a2eef21 Fix Tibber get_prices when called with aware datetime (#123289)
* Tibber: Add extra test to expose aware/naive datetime issue

* Tibber: Fix get_prices action not working with aware datetimes

* Tibber: Simplify comparison

* Tibber: Combine timezone tests into single parametrized one

* Tibber: Split test again to prevent if statement
2024-10-02 09:26:15 +02:00
Franck Nijhof
749a5b37c9 Bump version to 2024.10.0b8 2024-10-01 22:14:57 +02:00
epenet
60079a14e7 Update log error message for Samsung TV (#127231) 2024-10-01 22:14:50 +02:00
Erik Montnemery
df6edd09c0 Don't create statistics issues when sensor is unavailable or unknown (#127226) 2024-10-01 22:14:47 +02:00
epenet
88ff94dd69 Use reconfigure_confirm in bryant_evolution config flow (#127222) 2024-10-01 22:14:44 +02:00
epenet
067b81a60b Use reconfigure_confirm in enphase_envoy config flow (#127221) 2024-10-01 22:14:40 +02:00
epenet
03553b8bb9 Use reconfigure_confirm in homeworks config flow (#127218)
* Use reconfigure_confirm in homeworks config flow

* Fix tests
2024-10-01 22:14:37 +02:00
Franck Nijhof
bce7552d4d Update gotailwind to 0.2.4 (#127129) 2024-10-01 22:14:34 +02:00
Russell Cloran
53a2777831 Update prometheus-client to 0.21.0 (#126965) 2024-10-01 22:14:31 +02:00
Bill Flood
507492947a Fix Tailwind cover exception when door is already in the requested state (#124543) 2024-10-01 22:14:27 +02:00
Franck Nijhof
41b3eb9f79 Bump version to 2024.10.0b7 2024-10-01 14:54:05 +02:00
epenet
f2c746122e Use reconfigure_confirm in google_travel_time config flow (#127220) 2024-10-01 14:53:39 +02:00
epenet
e25a54aef4 Use reconfigure_confirm in lcn config flow (#127217) 2024-10-01 14:53:36 +02:00
epenet
5c42e45048 Fix reconfigure_confirm logic in madvr config flow (#127216) 2024-10-01 14:53:32 +02:00
epenet
c8b92bc858 Use reconfigure_confirm in solarlog config flow (#127215)
* Use reconfigure_confirm in solarlog config flow

* Fix test
2024-10-01 14:53:29 +02:00
epenet
9d059fcfaa Use reconfigure_confirm in vallox config flow (#127214) 2024-10-01 14:53:26 +02:00
Martin Hjelmare
ce5f193219 Fix Z-Wave rediscovery (#127213) 2024-10-01 14:53:22 +02:00
Erik Montnemery
92023ecbe6 Update assist_satellite connection test sound (#127183) 2024-10-01 14:53:19 +02:00
cdnninja
1e0164a96a Allows unload when unsupported devices vesync (#127153)
Allows unload when unsupported devices
2024-10-01 14:53:15 +02:00
G Johansson
6f5eac3143 Add config flow validation that calibration factor is not zero (#127136)
* Add config flow validation that calibration factor is not zero

* Add test
2024-10-01 14:50:10 +02:00
Nerdix
60dfccb747 Roborock fix "selected map" when first map in list is selected (#127126)
* avoid None when current_map = 0

* combine statements
2024-10-01 14:46:41 +02:00
Franck Nijhof
e9dc09755e Bump version to 2024.10.0b6 2024-09-30 20:51:44 +02:00
G Johansson
1ce2b18aaf Allow negative calibration factor in mold_indicator (#127133) 2024-09-30 20:51:34 +02:00
Franck Nijhof
abd351e326 Update RestrictedPython to 7.3 (#127130) 2024-09-30 20:51:31 +02:00
starkillerOG
d3e6069095 Mark Reolink camera entities as unavailable when camera is offline (#127127)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2024-09-30 20:51:28 +02:00
Bram Kragten
f0c3900842 Update frontend to 20240930.0 (#127125) 2024-09-30 20:51:25 +02:00
Martin Hjelmare
25247de6a6 Bump zwave-js-server-python to 0.58.1 (#127114)
* Bump zwave-js-server-python to 0.58.1

* Update tests
2024-09-30 20:51:21 +02:00
Franck Nijhof
f3a72dda7b Bump version to 2024.10.0b5 2024-09-30 14:14:01 +02:00
Joost Lekkerkerker
b6af6ddea2 Bump yt-dlp to 2024.09.27 (#127096) 2024-09-30 14:05:12 +02:00
Joost Lekkerkerker
a2cd17ef0a Make Laundrify unique id a string (#127092) 2024-09-30 14:05:08 +02:00
Simon Goodall
b8ed449944 Check "status" is present before access during device update (#127091) 2024-09-30 14:05:05 +02:00
Matthias Alphart
dc79299301 Update xknxproject to 3.8.0 (#127072) 2024-09-30 14:05:02 +02:00
Luca Dibattista
fa295b93a7 Fix Roomba help URL (#127065)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-09-30 14:04:58 +02:00
J. Nick Koston
725c361e9c Add missing OUI to august (#127064) 2024-09-30 14:04:55 +02:00
Jon Caruana
a8f25b1b93 Bump pylitejet to 0.6.3 (#127063) 2024-09-30 14:04:51 +02:00
Kevin Stillhammer
3ee85b3356 Clarify excl/incl filter functionality for waze_travel_time (#127056) 2024-09-30 14:04:48 +02:00
J. Nick Koston
22c85bf5f7 Fix removing nulls when encoding events for PostgreSQL (#127053) 2024-09-30 14:04:45 +02:00
Shai Ungar
0a18838fb0 Fix timestamp isoformat in seventeentrack (#127052)
fix timestamp isoformat
2024-09-30 14:04:41 +02:00
Shai Ungar
62629a0b34 Fix repair when integration does not exist (#127050) 2024-09-30 14:04:38 +02:00
Allen Porter
b42848fd7a Bump gcal_sync to 6.1.5 (#127049) 2024-09-30 14:04:34 +02:00
Franck Nijhof
9070806172 Update ical to 8.2.0 (#126954) 2024-09-30 14:04:31 +02:00
Allen Porter
4e11797d72 Update local_calendar/todo to avoid blocking in the event loop (#127048) 2024-09-30 14:01:12 +02:00
Michael
8f47b63762 Bump py-synologydsm-api to 2.5.3 (#127035) 2024-09-30 14:01:08 +02:00
Jan Bouwhuis
daa13235e6 Allow null / None value for non numeric mqtt sensor without warnings (#127032)
Allow `null` / `None` value for mqtt sensor without warnings
2024-09-30 14:01:04 +02:00
J. Nick Koston
084c2d976e Bump anyio to 4.6.0 (#127013) 2024-09-30 14:01:00 +02:00
Michael Hansen
75363b609b Don't log voice assistant config timeout error (#127010)
Don't log config timeout error
2024-09-30 14:00:56 +02:00
J. Nick Koston
8d09982f3b Bump aiohttp to 3.10.8 (#127009)
changelog: https://github.com/aio-libs/aiohttp/compare/v3.10.7...v3.10.8

Fixes a long standing cancellation leak on timeout
2024-09-30 14:00:51 +02:00
Paulus Schoutsen
aa5e8eaf19 Exclude Text-to-Speech cache from backups (#127001)
Text-to-speech cache doesn't need to be included in backups.
2024-09-30 14:00:43 +02:00
G Johansson
fc97eb8151 Workday raise issues only to next year (#126997)
* Workday - raise issues only for current and next year

* variable
2024-09-30 14:00:24 +02:00
G Johansson
a68d7c9b9d Add unique id to mold_indicator (#126990) 2024-09-30 13:59:18 +02:00
264 changed files with 3599 additions and 1567 deletions

View File

@@ -37,7 +37,7 @@ on:
type: boolean
env:
CACHE_VERSION: 10
CACHE_VERSION: 11
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 9
HA_SHORT_VERSION: "2024.10"

View File

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

View File

@@ -85,6 +85,7 @@ HVAC_MODE_LIB_TO_HASS: Final[dict[OperationMode, HVACMode]] = {
OperationMode.HEATING: HVACMode.HEAT,
OperationMode.FAN: HVACMode.FAN_ONLY,
OperationMode.DRY: HVACMode.DRY,
OperationMode.AUX_HEATING: HVACMode.HEAT,
OperationMode.AUTO: HVACMode.HEAT_COOL,
}
HVAC_MODE_HASS_TO_LIB: Final[dict[HVACMode, OperationMode]] = {
@@ -157,9 +158,10 @@ class AirzoneClimate(AirzoneZoneEntity, ClimateEntity):
self._attr_temperature_unit = TEMP_UNIT_LIB_TO_HASS[
self.get_airzone_value(AZD_TEMP_UNIT)
]
self._attr_hvac_modes = [
_attr_hvac_modes = [
HVAC_MODE_LIB_TO_HASS[mode] for mode in self.get_airzone_value(AZD_MODES)
]
self._attr_hvac_modes = list(dict.fromkeys(_attr_hvac_modes))
if (
self.get_airzone_value(AZD_SPEED) is not None
and self.get_airzone_value(AZD_SPEEDS) is not None

View File

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

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.6.5"]
"requirements": ["aioairzone-cloud==0.6.6"]
}

View File

@@ -22,7 +22,8 @@
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"create_entry": {
"default": "Successfully connected to AlarmDecoder."
@@ -37,7 +38,7 @@
"title": "Configure AlarmDecoder",
"description": "What would you like to edit?",
"data": {
"edit_select": "Edit"
"edit_selection": "Edit"
}
},
"arm_settings": {

View File

@@ -10,7 +10,7 @@
},
"site": {
"data": {
"site_nmi": "Site NMI",
"site_id": "Site NMI",
"site_name": "Site Name"
},
"description": "Select the NMI of the site you would like to add"

View File

@@ -17,7 +17,7 @@
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"error": {
"no_integration_selected": "You must select at least one integration to track"
"no_integrations_selected": "You must select at least one integration to track"
}
},
"options": {
@@ -37,7 +37,7 @@
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"error": {
"no_integration_selected": "[%key:component::analytics_insights::config::error::no_integration_selected%]"
"no_integrations_selected": "[%key:component::analytics_insights::config::error::no_integrations_selected%]"
}
},
"entity": {

Binary file not shown.

View File

@@ -16,6 +16,10 @@
"hostname": "connect",
"macaddress": "2C9FFB*"
},
{
"hostname": "connect",
"macaddress": "789C85*"
},
{
"hostname": "august*",
"macaddress": "E076D0*"

View File

@@ -4,6 +4,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from .const import CONF_THRESHOLD, DEFAULT_THRESHOLD
from .coordinator import AuroraDataUpdateCoordinator
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
@@ -21,9 +22,19 @@ async def async_setup_entry(hass: HomeAssistant, entry: AuroraConfigEntry) -> bo
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
entry.async_on_unload(entry.add_update_listener(update_listener))
return True
async def update_listener(hass: HomeAssistant, entry: AuroraConfigEntry) -> None:
"""Handle options update."""
entry.runtime_data.threshold = int(
entry.options.get(CONF_THRESHOLD, DEFAULT_THRESHOLD)
)
# refresh the state of the visibility alert binary sensor
await entry.runtime_data.async_request_refresh()
async def async_unload_entry(hass: HomeAssistant, entry: AuroraConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@@ -38,8 +38,8 @@ class AuroraDataUpdateCoordinator(DataUpdateCoordinator[int]):
)
self.api = AuroraForecast(async_get_clientsession(hass))
self.latitude = int(self.config_entry.data[CONF_LATITUDE])
self.longitude = int(self.config_entry.data[CONF_LONGITUDE])
self.latitude = round(self.config_entry.data[CONF_LATITUDE])
self.longitude = round(self.config_entry.data[CONF_LONGITUDE])
self.threshold = int(
self.config_entry.options.get(CONF_THRESHOLD, DEFAULT_THRESHOLD)
)

View File

@@ -14,14 +14,15 @@
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
"options": {
"step": {
"init": {
"data": {
"threshold": "Threshold (%)"
"forecast_threshold": "Threshold (%)"
}
}
}

View File

@@ -38,7 +38,7 @@
},
"options": {
"step": {
"options": {
"init": {
"title": "Options for the Azure Event Hub.",
"data": {
"send_interval": "Interval between sending batches to the hub."

View File

@@ -13,4 +13,5 @@ EXCLUDE_FROM_BACKUP = [
"*.log",
"backups/*.tar",
"OZW_Log.txt",
"tts/*",
]

View File

@@ -15,7 +15,9 @@
"description": "Set up your BleBox to integrate with Home Assistant.",
"data": {
"host": "[%key:common::config_flow::data::ip%]",
"port": "[%key:common::config_flow::data::port%]"
"password": "[%key:common::config_flow::data::password%]",
"port": "[%key:common::config_flow::data::port%]",
"username": "[%key:common::config_flow::data::username%]"
},
"title": "Set up your BleBox device"
}

View File

@@ -6,7 +6,7 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/bluesound",
"iot_class": "local_polling",
"requirements": ["pyblu==1.0.2"],
"requirements": ["pyblu==1.0.4"],
"zeroconf": [
{
"type": "_musc._tcp.local."

View File

@@ -493,6 +493,8 @@ class BluesoundPlayer(MediaPlayerEntity):
return None
position = self._status.seconds
if position is None:
return None
if mediastate == MediaPlayerState.PLAYING:
position += (dt_util.utcnow() - self._last_status_update).total_seconds()

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from collections.abc import Mapping
import logging
from typing import Any
@@ -61,6 +62,12 @@ class BryantConfigFlow(ConfigFlow, domain=DOMAIN):
)
async def async_step_reconfigure(
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle integration reconfiguration."""
return await self.async_step_reconfigure_confirm()
async def async_step_reconfigure_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle integration reconfiguration."""
@@ -83,5 +90,7 @@ class BryantConfigFlow(ConfigFlow, domain=DOMAIN):
)
errors["base"] = "cannot_connect"
return self.async_show_form(
step_id="reconfigure", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
step_id="reconfigure_confirm",
data_schema=STEP_USER_DATA_SCHEMA,
errors=errors,
)

View File

@@ -1,6 +1,11 @@
{
"config": {
"step": {
"reconfigure_confirm": {
"data": {
"filename": "[%key:component::bryant_evolution::config::step::user::data::filename%]"
}
},
"user": {
"data": {
"filename": "Serial port filename"

View File

@@ -34,7 +34,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
username=entry.data[CONF_USERNAME],
password=entry.data[CONF_PASSWORD],
ssl_verify_cert=entry.data[CONF_VERIFY_SSL],
timeout=10,
timeout=30,
)
try:
await hass.async_add_executor_job(client.principal)

View File

@@ -111,7 +111,7 @@
},
"issues": {
"deprecated_service_calendar_list_events": {
"title": "Detected use of deprecated action `calendar.list_events`",
"title": "Detected use of deprecated action calendar.list_events",
"fix_flow": {
"step": {
"confirm": {

View File

@@ -7,6 +7,6 @@
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["aiostreammagic"],
"requirements": ["aiostreammagic==2.3.1"],
"requirements": ["aiostreammagic==2.5.0"],
"zeroconf": ["_stream-magic._tcp.local.", "_smoip._tcp.local."]
}

View File

@@ -14,6 +14,6 @@
"documentation": "https://www.home-assistant.io/integrations/cast",
"iot_class": "local_polling",
"loggers": ["casttube", "pychromecast"],
"requirements": ["PyChromecast==14.0.1"],
"requirements": ["PyChromecast==14.0.3"],
"zeroconf": ["_googlecast._tcp.local."]
}

View File

@@ -25,7 +25,7 @@
},
"issues": {
"deprecated_gender": {
"title": "The `{deprecated_option}` text-to-speech option is deprecated",
"title": "The {deprecated_option} text-to-speech option is deprecated",
"fix_flow": {
"step": {
"confirm": {

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/conversation",
"integration_type": "system",
"quality_scale": "internal",
"requirements": ["hassil==1.7.4", "home-assistant-intents==2024.9.23"]
"requirements": ["hassil==1.7.4", "home-assistant-intents==2024.10.2"]
}

View File

@@ -159,6 +159,7 @@ class DaikinClimate(DaikinEntity, ClimateEntity):
if values:
await self.device.set(values)
await self.coordinator.async_refresh()
@property
def unique_id(self) -> str:
@@ -261,6 +262,7 @@ class DaikinClimate(DaikinEntity, ClimateEntity):
await self.device.set_advanced_mode(
HA_PRESET_TO_DAIKIN[PRESET_ECO], ATTR_STATE_OFF
)
await self.coordinator.async_refresh()
@property
def preset_modes(self) -> list[str]:
@@ -275,9 +277,11 @@ class DaikinClimate(DaikinEntity, ClimateEntity):
async def async_turn_on(self) -> None:
"""Turn device on."""
await self.device.set({})
await self.coordinator.async_refresh()
async def async_turn_off(self) -> None:
"""Turn device off."""
await self.device.set(
{HA_ATTR_TO_DAIKIN[ATTR_HVAC_MODE]: HA_STATE_TO_DAIKIN[HVACMode.OFF]}
)
await self.coordinator.async_refresh()

View File

@@ -63,10 +63,12 @@ class DaikinZoneSwitch(DaikinEntity, SwitchEntity):
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the zone on."""
await self.device.set_zone(self._zone_id, "zone_onoff", "1")
await self.coordinator.async_refresh()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the zone off."""
await self.device.set_zone(self._zone_id, "zone_onoff", "0")
await self.coordinator.async_refresh()
class DaikinStreamerSwitch(DaikinEntity, SwitchEntity):
@@ -88,10 +90,12 @@ class DaikinStreamerSwitch(DaikinEntity, SwitchEntity):
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the zone on."""
await self.device.set_streamer("on")
await self.coordinator.async_refresh()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the zone off."""
await self.device.set_streamer("off")
await self.coordinator.async_refresh()
class DaikinToggleSwitch(DaikinEntity, SwitchEntity):
@@ -112,7 +116,9 @@ class DaikinToggleSwitch(DaikinEntity, SwitchEntity):
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the zone on."""
await self.device.set({})
await self.coordinator.async_refresh()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the zone off."""
await self.device.set({DAIKIN_ATTR_MODE: "off"})
await self.coordinator.async_refresh()

View File

@@ -7,7 +7,7 @@
"documentation": "https://www.home-assistant.io/integrations/doorbird",
"iot_class": "local_push",
"loggers": ["doorbirdpy"],
"requirements": ["DoorBirdPy==3.0.2"],
"requirements": ["DoorBirdPy==3.0.4"],
"zeroconf": [
{
"type": "_axis-video._tcp.local.",

View File

@@ -7,5 +7,5 @@
"iot_class": "local_push",
"loggers": ["pyduotecno", "pyduotecno-node", "pyduotecno-unit"],
"quality_scale": "silver",
"requirements": ["pyDuotecno==2024.9.0"]
"requirements": ["pyDuotecno==2024.10.0"]
}

View File

@@ -5,18 +5,21 @@
"data": {
"host": "[%key:common::config_flow::data::host%]",
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]"
"password": "[%key:common::config_flow::data::password%]",
"port": "[%key:common::config_flow::data::port%]"
},
"data_description": {
"host": "The hostname or IP address of your Duotecno device."
}
}
},
"abort": {
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]",
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
"entity": {

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/econet",
"iot_class": "cloud_push",
"loggers": ["paho_mqtt", "pyeconet"],
"requirements": ["pyeconet==0.1.22"]
"requirements": ["pyeconet==0.1.23"]
}

View File

@@ -54,6 +54,8 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 1
_reconnect_entry: ConfigEntry
def __init__(self) -> None:
"""Initialize an envoy flow."""
self.ip_address: str | None = None
@@ -233,17 +235,22 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN):
)
async def async_step_reconfigure(
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Add reconfigure step to allow to manually reconfigure a config entry."""
entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
assert entry
self._reconnect_entry = entry
return await self.async_step_reconfigure_confirm()
async def async_step_reconfigure_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Add reconfigure step to allow to manually reconfigure a config entry."""
errors: dict[str, str] = {}
description_placeholders: dict[str, str] = {}
entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
assert entry
suggested_values: dict[str, Any] | MappingProxyType[str, Any] = (
user_input or entry.data
user_input or self._reconnect_entry.data
)
host: Any = suggested_values.get(CONF_HOST)
@@ -284,7 +291,7 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN):
error="reconfigure_successful",
)
if not self.unique_id:
await self.async_set_unique_id(entry.unique_id)
await self.async_set_unique_id(self._reconnect_entry.unique_id)
self.context["title_placeholders"] = {
CONF_SERIAL: self.unique_id,
@@ -292,7 +299,7 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN):
}
return self.async_show_form(
step_id="reconfigure",
step_id="reconfigure_confirm",
data_schema=self.add_suggested_values_to_schema(
self._async_generate_schema(), suggested_values
),

View File

@@ -13,7 +13,7 @@
"host": "The hostname or IP address of your Enphase Envoy gateway."
}
},
"reconfigure": {
"reconfigure_confirm": {
"description": "[%key:component::enphase_envoy::config::step::user::description%]",
"data": {
"host": "[%key:common::config_flow::data::host%]",

View File

@@ -133,7 +133,7 @@ class EsphomeAssistSatellite(
# Empty config. Updated when added to HA.
self._satellite_config = assist_satellite.AssistSatelliteConfiguration(
available_wake_words=[], active_wake_words=[], max_active_wake_words=0
available_wake_words=[], active_wake_words=[], max_active_wake_words=1
)
@property
@@ -179,7 +179,13 @@ class EsphomeAssistSatellite(
async def _update_satellite_config(self) -> None:
"""Get the latest satellite configuration from the device."""
config = await self.cli.get_voice_assistant_configuration(_CONFIG_TIMEOUT_SEC)
try:
config = await self.cli.get_voice_assistant_configuration(
_CONFIG_TIMEOUT_SEC
)
except TimeoutError:
# Placeholder config will be used
return
# Update available/active wake words
self._satellite_config.available_wake_words = [
@@ -206,7 +212,7 @@ class EsphomeAssistSatellite(
)
if feature_flags & VoiceAssistantFeature.API_AUDIO:
# TCP audio
self.entry_data.disconnect_callbacks.add(
self.async_on_remove(
self.cli.subscribe_voice_assistant(
handle_start=self.handle_pipeline_start,
handle_stop=self.handle_pipeline_stop,
@@ -216,7 +222,7 @@ class EsphomeAssistSatellite(
)
else:
# UDP audio
self.entry_data.disconnect_callbacks.add(
self.async_on_remove(
self.cli.subscribe_voice_assistant(
handle_start=self.handle_pipeline_start,
handle_stop=self.handle_pipeline_stop,
@@ -229,7 +235,7 @@ class EsphomeAssistSatellite(
assert (self.registry_entry is not None) and (
self.registry_entry.device_id is not None
)
self.entry_data.disconnect_callbacks.add(
self.async_on_remove(
async_register_timer_handler(
self.hass, self.registry_entry.device_id, self.handle_timer_event
)

View File

@@ -47,6 +47,7 @@
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
},
"error": {
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
}
},

View File

@@ -20,5 +20,5 @@
"documentation": "https://www.home-assistant.io/integrations/frontend",
"integration_type": "system",
"quality_scale": "internal",
"requirements": ["home-assistant-frontend==20240927.0"]
"requirements": ["home-assistant-frontend==20241002.3"]
}

View File

@@ -9,5 +9,5 @@ DOMAIN = "fujitsu_fglair"
CONF_REGION = "region"
CONF_EUROPE = "is_europe"
REGION_EU = "EU"
REGION_EU = "eu"
REGION_DEFAULT = "default"

View File

@@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/fujitsu_fglair",
"iot_class": "cloud_polling",
"requirements": ["ayla-iot-unofficial==1.4.1"]
"requirements": ["ayla-iot-unofficial==1.4.2"]
}

View File

@@ -7,5 +7,5 @@
"integration_type": "hub",
"iot_class": "cloud_polling",
"quality_scale": "platinum",
"requirements": ["fyta_cli==0.6.6"]
"requirements": ["fyta_cli==0.6.7"]
}

View File

@@ -7,5 +7,5 @@
"documentation": "https://www.home-assistant.io/integrations/calendar.google",
"iot_class": "cloud_polling",
"loggers": ["googleapiclient"],
"requirements": ["gcal-sync==6.1.4", "oauth2client==4.1.3", "ical==8.1.1"]
"requirements": ["gcal-sync==6.1.6", "oauth2client==4.1.3", "ical==8.2.0"]
}

View File

@@ -172,10 +172,12 @@ class BaseGoogleCloudProvider:
_LOGGER.error("Error: %s when validating options: %s", err, options)
return None, None
encoding = texttospeech.AudioEncoding(options[CONF_ENCODING])
gender: texttospeech.SsmlVoiceGender | None = texttospeech.SsmlVoiceGender(
encoding: texttospeech.AudioEncoding = texttospeech.AudioEncoding[
options[CONF_ENCODING]
] # type: ignore[misc]
gender: texttospeech.SsmlVoiceGender | None = texttospeech.SsmlVoiceGender[
options[CONF_GENDER]
)
] # type: ignore[misc]
voice = options[CONF_VOICE]
if voice:
gender = None

View File

@@ -21,7 +21,8 @@
"wrong_account": "Wrong account: Please authenticate with the right account.",
"oauth_timeout": "[%key:common::config_flow::abort::oauth2_timeout%]",
"oauth_unauthorized": "[%key:common::config_flow::abort::oauth2_unauthorized%]",
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]"
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"create_entry": {
"default": "[%key:common::config_flow::create_entry::authenticated%]"

View File

@@ -21,7 +21,8 @@
"wrong_account": "Wrong account: Please authenticate with the right account.",
"oauth_timeout": "[%key:common::config_flow::abort::oauth2_timeout%]",
"oauth_unauthorized": "[%key:common::config_flow::abort::oauth2_unauthorized%]",
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]"
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"create_entry": {
"default": "[%key:common::config_flow::create_entry::authenticated%]"

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any
import voluptuous as vol
@@ -207,6 +208,8 @@ class GoogleTravelTimeConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 1
_context_entry: ConfigEntry
@staticmethod
@callback
def async_get_options_flow(
@@ -235,28 +238,33 @@ class GoogleTravelTimeConfigFlow(ConfigFlow, domain=DOMAIN):
)
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle reconfiguration."""
entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
if TYPE_CHECKING:
assert entry
self._context_entry = entry
return await self.async_step_reconfigure_confirm()
async def async_step_reconfigure_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle reconfiguration."""
errors: dict[str, str] | None = None
user_input = user_input or {}
if user_input:
if user_input is not None:
errors = await validate_input(self.hass, user_input)
if not errors:
return self.async_update_reload_and_abort(
entry,
self._context_entry,
data=user_input,
reason="reconfigure_successful",
)
return self.async_show_form(
step_id="reconfigure",
step_id="reconfigure_confirm",
data_schema=self.add_suggested_values_to_schema(
RECONFIGURE_SCHEMA, entry.data.copy()
RECONFIGURE_SCHEMA, self._context_entry.data.copy()
),
errors=errors,
)

View File

@@ -11,7 +11,7 @@
"destination": "Destination"
}
},
"reconfigure": {
"reconfigure_confirm": {
"description": "[%key:component::google_travel_time::config::step::user::description%]",
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",

View File

@@ -152,7 +152,7 @@
},
"issues": {
"deprecated_task_entity": {
"title": "The Habitica `{task_name}` sensor is deprecated",
"title": "The Habitica {task_name} sensor is deprecated",
"description": "The Habitica entity `{entity}` is deprecated and will be removed in a future release.\nPlease update your automations and scripts to replace the sensor entity with the newly added todo entity.\nWhen you are done migrating you can disable `{entity}`."
}
},

View File

@@ -14,6 +14,9 @@ from homeassistant.util import dt as dt_util
def next_due_date(task: dict[str, Any], last_cron: str) -> datetime.date | None:
"""Calculate due date for dailies and yesterdailies."""
if task["everyX"] == 0 or not task.get("nextDue"): # grey dailies never become due
return None
today = to_date(last_cron)
startdate = to_date(task["startDate"])
if TYPE_CHECKING:

View File

@@ -24,11 +24,11 @@
},
"cmd": {
"name": "Command",
"description": "Command itself. Could be decimal number or string with hexadeximal notation: \"0x10\"."
"description": "Command itself. Could be decimal number or string with hexadecimal notation: \"0x10\"."
},
"dst": {
"name": "Destination",
"description": "Destination for command. Could be decimal number or string with hexadeximal notation: \"0x10\"."
"description": "Destination for command. Could be decimal number or string with hexadecimal notation: \"0x10\"."
},
"raw": {
"name": "Raw",
@@ -36,7 +36,7 @@
},
"src": {
"name": "Source",
"description": "Source of command. Could be decimal number or string with hexadeximal notation: \"0x10\"."
"description": "Source of command. Could be decimal number or string with hexadecimal notation: \"0x10\"."
}
}
},

View File

@@ -127,5 +127,5 @@ class HiveSensorEntity(HiveEntity, SensorEntity):
await self.hive.session.updateData(self.device)
self.device = await self.hive.sensor.getSensor(self.device)
self._attr_native_value = self.entity_description.fn(
self.device["status"]["state"]
self.device.get("status", {}).get("state")
)

View File

@@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/holiday",
"iot_class": "local_polling",
"requirements": ["holidays==0.57", "babel==2.15.0"]
"requirements": ["holidays==0.58", "babel==2.15.0"]
}

View File

@@ -19,7 +19,7 @@
"description": "The currency {currency} is no longer in use, please reconfigure the currency configuration."
},
"legacy_templates_false": {
"title": "`legacy_templates` config key is being removed",
"title": "legacy_templates config key is being removed",
"description": "Nothing will change with your templates.\n\nRemove the `legacy_templates` key from the `homeassistant` configuration in your configuration.yaml file and restart Home Assistant to fix this issue."
},
"legacy_templates_true": {
@@ -43,7 +43,7 @@
"description": "It's not possible to configure {platform} {domain} by adding `{platform_key}` to the {domain} configuration. Please check the documentation for more information on how to set up this integration.\n\nTo resolve this:\n1. Remove `{platform_key}` occurences from the `{domain}:` configuration in your YAML configuration file.\n2. Restart Home Assistant.\n\nExample that should be removed:\n{yaml_example}"
},
"storage_corruption": {
"title": "Storage corruption detected for `{storage_key}`",
"title": "Storage corruption detected for {storage_key}",
"fix_flow": {
"step": {
"confirm": {

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from collections.abc import Mapping
from functools import partial
import logging
from typing import Any
@@ -557,6 +558,8 @@ OPTIONS_FLOW = {
class HomeworksConfigFlowHandler(ConfigFlow, domain=DOMAIN):
"""Config flow for Lutron Homeworks."""
_context_entry: ConfigEntry
async def _validate_edit_controller(
self, user_input: dict[str, Any]
) -> dict[str, Any]:
@@ -580,18 +583,24 @@ class HomeworksConfigFlowHandler(ConfigFlow, domain=DOMAIN):
return user_input
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle a reconfigure flow."""
entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
assert entry
self._context_entry = entry
return await self.async_step_reconfigure_confirm()
async def async_step_reconfigure_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle a reconfigure flow."""
errors = {}
suggested_values = {
CONF_HOST: entry.options[CONF_HOST],
CONF_PORT: entry.options[CONF_PORT],
CONF_USERNAME: entry.data.get(CONF_USERNAME),
CONF_PASSWORD: entry.data.get(CONF_PASSWORD),
CONF_HOST: self._context_entry.options[CONF_HOST],
CONF_PORT: self._context_entry.options[CONF_PORT],
CONF_USERNAME: self._context_entry.data.get(CONF_USERNAME),
CONF_PASSWORD: self._context_entry.data.get(CONF_PASSWORD),
}
if user_input:
@@ -608,16 +617,16 @@ class HomeworksConfigFlowHandler(ConfigFlow, domain=DOMAIN):
else:
password = user_input.pop(CONF_PASSWORD, None)
username = user_input.pop(CONF_USERNAME, None)
new_data = entry.data | {
new_data = self._context_entry.data | {
CONF_PASSWORD: password,
CONF_USERNAME: username,
}
new_options = entry.options | {
new_options = self._context_entry.options | {
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
}
return self.async_update_reload_and_abort(
entry,
self._context_entry,
data=new_data,
options=new_options,
reason="reconfigure_successful",
@@ -625,7 +634,7 @@ class HomeworksConfigFlowHandler(ConfigFlow, domain=DOMAIN):
)
return self.async_show_form(
step_id="reconfigure",
step_id="reconfigure_confirm",
data_schema=self.add_suggested_values_to_schema(
DATA_SCHEMA_EDIT_CONTROLLER, suggested_values
),

View File

@@ -22,7 +22,7 @@
"name": "[%key:component::homeworks::config::step::user::data_description::name%]"
}
},
"reconfigure": {
"reconfigure_confirm": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
"port": "[%key:common::config_flow::data::port%]",
@@ -45,8 +45,8 @@
},
"data_description": {
"name": "A unique name identifying the Lutron Homeworks controller",
"password": "[%key:component::homeworks::config::step::reconfigure::data_description::password%]",
"username": "[%key:component::homeworks::config::step::reconfigure::data_description::username%]"
"password": "[%key:component::homeworks::config::step::reconfigure_confirm::data_description::password%]",
"username": "[%key:component::homeworks::config::step::reconfigure_confirm::data_description::username%]"
},
"description": "Add a Lutron Homeworks controller"
}

View File

@@ -23,7 +23,7 @@ _LOGGER = logging.getLogger(__name__)
HAP_SUFFIX = "._hap._tcp.local."
POWERVIEW_G2_SUFFIX = "._powerview._tcp.local."
POWERVIEW_G3_SUFFIX = "._powerview-g3._tcp.local."
POWERVIEW_G3_SUFFIX = "._PowerView-G3._tcp.local."
async def validate_input(hass: HomeAssistant, hub_address: str) -> dict[str, str]:

View File

@@ -19,5 +19,5 @@
"iot_class": "local_polling",
"loggers": ["aiopvapi"],
"requirements": ["aiopvapi==3.1.1"],
"zeroconf": ["_powerview._tcp.local.", "_powerview-g3._tcp.local."]
"zeroconf": ["_powerview._tcp.local.", "_PowerView-G3._tcp.local."]
}

View File

@@ -125,7 +125,9 @@ class AutomowerBaseEntity(CoordinatorEntity[AutomowerDataUpdateCoordinator]):
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, mower_id)},
manufacturer="Husqvarna",
model=self.mower_attributes.system.model,
model=self.mower_attributes.system.model.removeprefix(
"HUSQVARNA "
).removeprefix("Husqvarna "),
name=self.mower_attributes.system.name,
serial_number=self.mower_attributes.system.serial_number,
suggested_area="Garden",

View File

@@ -7,5 +7,5 @@
"documentation": "https://www.home-assistant.io/integrations/husqvarna_automower",
"iot_class": "cloud_push",
"loggers": ["aioautomower"],
"requirements": ["aioautomower==2024.9.3"]
"requirements": ["aioautomower==2024.10.0"]
}

View File

@@ -10,7 +10,7 @@ DEFAULT_WATERING_TIME = timedelta(minutes=15)
MANUFACTURER = "Hydrawise"
SCAN_INTERVAL = timedelta(seconds=30)
SCAN_INTERVAL = timedelta(seconds=60)
SIGNAL_UPDATE_HYDRAWISE = "hydrawise_update"

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/imgw_pib",
"iot_class": "cloud_polling",
"quality_scale": "platinum",
"requirements": ["imgw_pib==1.0.5"]
"requirements": ["imgw_pib==1.0.6"]
}

View File

@@ -8,6 +8,6 @@
"iot_class": "local_polling",
"loggers": ["deepmerge", "pyipp"],
"quality_scale": "platinum",
"requirements": ["pyipp==0.16.0"],
"requirements": ["pyipp==0.17.0"],
"zeroconf": ["_ipps._tcp.local.", "_ipp._tcp.local."]
}

View File

@@ -4,7 +4,7 @@ from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime, timedelta
from datetime import datetime
from typing import Any
from pyipp import Marker, Printer
@@ -19,7 +19,6 @@ from homeassistant.const import ATTR_LOCATION, PERCENTAGE, EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.util.dt import utcnow
from . import IPPConfigEntry
from .const import (
@@ -80,7 +79,7 @@ PRINTER_SENSORS: tuple[IPPSensorEntityDescription, ...] = (
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
value_fn=lambda printer: (utcnow() - timedelta(seconds=printer.info.uptime)),
value_fn=lambda printer: printer.booted_at,
),
)

View File

@@ -29,7 +29,8 @@
"invalid_host": "The host entry was not in full URL format, e.g., http://192.168.10.100:80"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
},
"options": {

View File

@@ -24,6 +24,7 @@
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"error": {

View File

@@ -12,7 +12,7 @@
"quality_scale": "platinum",
"requirements": [
"xknx==3.2.0",
"xknxproject==3.7.1",
"xknxproject==3.8.1",
"knx-frontend==2024.9.10.221729"
],
"single_config_entry": true

View File

@@ -2,6 +2,8 @@
from __future__ import annotations
import logging
from laundrify_aio import LaundrifyAPI
from laundrify_aio.exceptions import ApiConnectionException, UnauthorizedException
@@ -14,6 +16,8 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DEFAULT_POLL_INTERVAL, DOMAIN
from .coordinator import LaundrifyUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
@@ -51,3 +55,21 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Migrate entry."""
_LOGGER.debug("Migrating from version %s", entry.version)
if entry.version == 1:
# 1 -> 2: Unique ID from integer to string
if entry.minor_version == 1:
minor_version = 2
hass.config_entries.async_update_entry(
entry, unique_id=str(entry.unique_id), minor_version=minor_version
)
_LOGGER.debug("Migration successful")
return True

View File

@@ -29,6 +29,7 @@ class LaundrifyConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for laundrify."""
VERSION = 1
MINOR_VERSION = 2
async def async_step_user(
self, user_input: dict[str, Any] | None = None
@@ -64,7 +65,7 @@ class LaundrifyConfigFlow(ConfigFlow, domain=DOMAIN):
else:
entry_data = {CONF_ACCESS_TOKEN: access_token}
await self.async_set_unique_id(account_id)
await self.async_set_unique_id(str(account_id))
self._abort_if_unique_id_configured()
# Create a new entry if it doesn't exist

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from collections.abc import Mapping
import logging
from typing import Any
@@ -9,7 +10,7 @@ import pypck
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.config_entries import ConfigFlowResult
from homeassistant.config_entries import ConfigEntry, ConfigFlowResult
from homeassistant.const import (
CONF_BASE,
CONF_DEVICES,
@@ -113,6 +114,8 @@ class LcnFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1
MINOR_VERSION = 2
_context_entry: ConfigEntry
async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult:
"""Import existing configuration from LCN."""
# validate the imported connection parameters
@@ -193,31 +196,41 @@ class LcnFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_create_entry(title=data[CONF_HOST], data=data)
async def async_step_reconfigure(
self, entry_data: Mapping[str, Any]
) -> config_entries.ConfigFlowResult:
"""Reconfigure LCN configuration."""
entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
assert entry
self._context_entry = entry
return await self.async_step_reconfigure_confirm()
async def async_step_reconfigure_confirm(
self, user_input: dict[str, Any] | None = None
) -> config_entries.ConfigFlowResult:
"""Reconfigure LCN configuration."""
errors = None
entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
assert entry
if user_input is not None:
user_input[CONF_HOST] = entry.data[CONF_HOST]
user_input[CONF_HOST] = self._context_entry.data[CONF_HOST]
await self.hass.config_entries.async_unload(entry.entry_id)
await self.hass.config_entries.async_unload(self._context_entry.entry_id)
if (error := await validate_connection(user_input)) is not None:
errors = {CONF_BASE: error}
if errors is None:
data = entry.data.copy()
data = self._context_entry.data.copy()
data.update(user_input)
self.hass.config_entries.async_update_entry(entry, data=data)
await self.hass.config_entries.async_setup(entry.entry_id)
self.hass.config_entries.async_update_entry(
self._context_entry, data=data
)
await self.hass.config_entries.async_setup(self._context_entry.entry_id)
return self.async_abort(reason="reconfigure_successful")
await self.hass.config_entries.async_setup(entry.entry_id)
await self.hass.config_entries.async_setup(self._context_entry.entry_id)
return self.async_show_form(
step_id="reconfigure",
data_schema=self.add_suggested_values_to_schema(CONFIG_SCHEMA, entry.data),
step_id="reconfigure_confirm",
data_schema=self.add_suggested_values_to_schema(
CONFIG_SCHEMA, self._context_entry.data
),
errors=errors or {},
)

View File

@@ -34,7 +34,7 @@
"acknowledge": "Retry sendig commands if no response is received (increases bus traffic)."
}
},
"reconfigure": {
"reconfigure_confirm": {
"title": "Reconfigure LCN host",
"description": "Reconfigure connection to LCN host.",
"data": {

View File

@@ -6,6 +6,7 @@
"documentation": "https://www.home-assistant.io/integrations/linkplay",
"integration_type": "hub",
"iot_class": "local_polling",
"requirements": ["python-linkplay==0.0.12"],
"loggers": ["linkplay"],
"requirements": ["python-linkplay==0.0.15"],
"zeroconf": ["_linkplay._tcp.local."]
}

View File

@@ -8,5 +8,5 @@
"iot_class": "local_push",
"loggers": ["pylitejet"],
"quality_scale": "platinum",
"requirements": ["pylitejet==0.6.2"]
"requirements": ["pylitejet==0.6.3"]
}

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
import asyncio
from datetime import date, datetime, timedelta
import logging
from typing import Any
@@ -74,6 +75,7 @@ class LocalCalendarEntity(CalendarEntity):
"""Initialize LocalCalendarEntity."""
self._store = store
self._calendar = calendar
self._calendar_lock = asyncio.Lock()
self._event: CalendarEvent | None = None
self._attr_name = name
self._attr_unique_id = unique_id
@@ -110,8 +112,10 @@ class LocalCalendarEntity(CalendarEntity):
async def async_create_event(self, **kwargs: Any) -> None:
"""Add a new event to calendar."""
event = _parse_event(kwargs)
EventStore(self._calendar).add(event)
await self._async_store()
async with self._calendar_lock:
event_store = EventStore(self._calendar)
await self.hass.async_add_executor_job(event_store.add, event)
await self._async_store()
await self.async_update_ha_state(force_refresh=True)
async def async_delete_event(
@@ -124,15 +128,16 @@ class LocalCalendarEntity(CalendarEntity):
range_value: Range = Range.NONE
if recurrence_range == Range.THIS_AND_FUTURE:
range_value = Range.THIS_AND_FUTURE
try:
EventStore(self._calendar).delete(
uid,
recurrence_id=recurrence_id,
recurrence_range=range_value,
)
except EventStoreError as err:
raise HomeAssistantError(f"Error while deleting event: {err}") from err
await self._async_store()
async with self._calendar_lock:
try:
EventStore(self._calendar).delete(
uid,
recurrence_id=recurrence_id,
recurrence_range=range_value,
)
except EventStoreError as err:
raise HomeAssistantError(f"Error while deleting event: {err}") from err
await self._async_store()
await self.async_update_ha_state(force_refresh=True)
async def async_update_event(
@@ -147,16 +152,23 @@ class LocalCalendarEntity(CalendarEntity):
range_value: Range = Range.NONE
if recurrence_range == Range.THIS_AND_FUTURE:
range_value = Range.THIS_AND_FUTURE
try:
EventStore(self._calendar).edit(
uid,
new_event,
recurrence_id=recurrence_id,
recurrence_range=range_value,
)
except EventStoreError as err:
raise HomeAssistantError(f"Error while updating event: {err}") from err
await self._async_store()
async with self._calendar_lock:
event_store = EventStore(self._calendar)
def apply_edit() -> None:
event_store.edit(
uid,
new_event,
recurrence_id=recurrence_id,
recurrence_range=range_value,
)
try:
await self.hass.async_add_executor_job(apply_edit)
except EventStoreError as err:
raise HomeAssistantError(f"Error while updating event: {err}") from err
await self._async_store()
await self.async_update_ha_state(force_refresh=True)

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/local_calendar",
"iot_class": "local_polling",
"loggers": ["ical"],
"requirements": ["ical==8.1.1"]
"requirements": ["ical==8.2.0"]
}

View File

@@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/local_todo",
"iot_class": "local_polling",
"requirements": ["ical==8.1.1"]
"requirements": ["ical==8.2.0"]
}

View File

@@ -1,5 +1,6 @@
"""A Local To-do todo platform."""
import asyncio
import datetime
import logging
@@ -130,6 +131,7 @@ class LocalTodoListEntity(TodoListEntity):
"""Initialize LocalTodoListEntity."""
self._store = store
self._calendar = calendar
self._calendar_lock = asyncio.Lock()
self._attr_name = name.capitalize()
self._attr_unique_id = unique_id
@@ -159,23 +161,28 @@ class LocalTodoListEntity(TodoListEntity):
async def async_create_todo_item(self, item: TodoItem) -> None:
"""Add an item to the To-do list."""
todo = _convert_item(item)
self._new_todo_store().add(todo)
await self.async_save()
async with self._calendar_lock:
todo_store = self._new_todo_store()
await self.hass.async_add_executor_job(todo_store.add, todo)
await self.async_save()
await self.async_update_ha_state(force_refresh=True)
async def async_update_todo_item(self, item: TodoItem) -> None:
"""Update an item to the To-do list."""
todo = _convert_item(item)
self._new_todo_store().edit(todo.uid, todo)
await self.async_save()
async with self._calendar_lock:
todo_store = self._new_todo_store()
await self.hass.async_add_executor_job(todo_store.edit, todo.uid, todo)
await self.async_save()
await self.async_update_ha_state(force_refresh=True)
async def async_delete_todo_items(self, uids: list[str]) -> None:
"""Delete an item from the To-do list."""
store = self._new_todo_store()
for uid in uids:
store.delete(uid)
await self.async_save()
async with self._calendar_lock:
for uid in uids:
store.delete(uid)
await self.async_save()
await self.async_update_ha_state(force_refresh=True)
async def async_move_todo_item(
@@ -184,23 +191,24 @@ class LocalTodoListEntity(TodoListEntity):
"""Re-order an item to the To-do list."""
if uid == previous_uid:
return
todos = self._calendar.todos
item_idx: dict[str, int] = {itm.uid: idx for idx, itm in enumerate(todos)}
if uid not in item_idx:
raise HomeAssistantError(
"Item '{uid}' not found in todo list {self.entity_id}"
)
if previous_uid and previous_uid not in item_idx:
raise HomeAssistantError(
"Item '{previous_uid}' not found in todo list {self.entity_id}"
)
dst_idx = item_idx[previous_uid] + 1 if previous_uid else 0
src_idx = item_idx[uid]
src_item = todos.pop(src_idx)
if dst_idx > src_idx:
dst_idx -= 1
todos.insert(dst_idx, src_item)
await self.async_save()
async with self._calendar_lock:
todos = self._calendar.todos
item_idx: dict[str, int] = {itm.uid: idx for idx, itm in enumerate(todos)}
if uid not in item_idx:
raise HomeAssistantError(
"Item '{uid}' not found in todo list {self.entity_id}"
)
if previous_uid and previous_uid not in item_idx:
raise HomeAssistantError(
"Item '{previous_uid}' not found in todo list {self.entity_id}"
)
dst_idx = item_idx[previous_uid] + 1 if previous_uid else 0
src_idx = item_idx[uid]
src_item = todos.pop(src_idx)
if dst_idx > src_idx:
dst_idx -= 1
todos.insert(dst_idx, src_item)
await self.async_save()
await self.async_update_ha_state(force_refresh=True)
async def async_save(self) -> None:

View File

@@ -1,6 +1,7 @@
"""Config flow for the integration."""
import asyncio
from collections.abc import Mapping
import logging
from typing import Any
@@ -41,17 +42,17 @@ class MadVRConfigFlow(ConfigFlow, domain=DOMAIN):
return await self._handle_config_step(user_input)
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle reconfiguration of the device."""
self.entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
return await self.async_step_reconfigure_confirm(user_input)
return await self.async_step_reconfigure_confirm()
async def async_step_reconfigure_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle a reconfiguration flow initialized by the user."""
return await self._handle_config_step(user_input, step_id="reconfigure")
return await self._handle_config_step(user_input, step_id="reconfigure_confirm")
async def _handle_config_step(
self, user_input: dict[str, Any] | None = None, step_id: str = "user"

View File

@@ -13,7 +13,7 @@
"port": "The port your madVR Envy is listening on. In 99% of cases, leave this as the default."
}
},
"reconfigure": {
"reconfigure_confirm": {
"title": "Reconfigure madVR Envy",
"description": "Your device needs to be on in order to reconfigure the integation.",
"data": {

View File

@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/matrix",
"iot_class": "cloud_push",
"loggers": ["matrix_client"],
"requirements": ["matrix-nio==0.25.1", "Pillow==10.4.0"]
"requirements": ["matrix-nio==0.25.2", "Pillow==10.4.0"]
}

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/mealie",
"integration_type": "service",
"iot_class": "local_polling",
"requirements": ["aiomealie==0.9.2"]
"requirements": ["aiomealie==0.9.3"]
}

View File

@@ -19,7 +19,8 @@
}
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"error": {
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",

View File

@@ -8,6 +8,6 @@
"iot_class": "calculated",
"loggers": ["yt_dlp"],
"quality_scale": "internal",
"requirements": ["yt-dlp==2024.08.06"],
"requirements": ["yt-dlp==2024.10.07"],
"single_config_entry": true
}

View File

@@ -21,6 +21,7 @@
"no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]",
"user_rejected_authorize": "[%key:common::config_flow::abort::oauth2_user_rejected_authorize%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"unknown": "[%key:common::config_flow::error::unknown%]",
"wrong_account": "You can only reauthenticate this entry with the same microBees account."
},

View File

@@ -71,15 +71,15 @@
},
"issues": {
"removed_lazy_error_count": {
"title": "`{config_key}` configuration key is being removed",
"title": "{config_key} configuration key is being removed",
"description": "Please remove the `{config_key}` key from the {integration} entry in your configuration.yaml file and restart Home Assistant to fix this issue. All errors will be reported, as lazy_error_count is accepted but ignored"
},
"deprecated_retries": {
"title": "`{config_key}` configuration key is being removed",
"title": "{config_key} configuration key is being removed",
"description": "Please remove the `{config_key}` key from the {integration} entry in your configuration.yaml file and restart Home Assistant to fix this issue.\n\nThe maximum number of retries is now fixed to 3."
},
"missing_modbus_name": {
"title": "Modbus entry with host `{sub_2}` missing name",
"title": "Modbus entry with host {sub_2} missing name",
"description": "Please add `{sub_1}` key to the {integration} entry with host `{sub_2}` in your configuration.yaml file and restart Home Assistant to fix this issue\n\n. `{sub_1}: {sub_3}` have been added."
},
"duplicate_modbus_entry": {
@@ -99,7 +99,7 @@
"description": "Please add at least one entity to Modbus {sub_1} in your configuration.yaml file and restart Home Assistant to fix this issue."
},
"deprecated_restart": {
"title": "`modbus.restart` is being removed",
"title": "modbus.restart is being removed",
"description": "Please use reload yaml via the developer tools in the UI instead of via the `modbus.restart` action."
}
}

View File

@@ -12,6 +12,7 @@ from homeassistant.const import CONF_NAME, Platform
from homeassistant.helpers.schema_config_entry_flow import (
SchemaCommonFlowHandler,
SchemaConfigFlowHandler,
SchemaFlowError,
SchemaFlowFormStep,
)
from homeassistant.helpers.selector import (
@@ -33,18 +34,20 @@ from .const import (
)
async def validate_duplicate(
async def validate_input(
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
) -> dict[str, Any]:
"""Validate already existing entry."""
handler.parent_handler._async_abort_entries_match({**handler.options, **user_input}) # noqa: SLF001
if user_input[CONF_CALIBRATION_FACTOR] == 0.0:
raise SchemaFlowError("calibration_is_zero")
return user_input
DATA_SCHEMA_OPTIONS = vol.Schema(
{
vol.Required(CONF_CALIBRATION_FACTOR): NumberSelector(
NumberSelectorConfig(min=0, step="any", mode=NumberSelectorMode.BOX)
NumberSelectorConfig(step=0.1, mode=NumberSelectorMode.BOX)
)
}
)
@@ -74,13 +77,13 @@ DATA_SCHEMA_CONFIG = vol.Schema(
CONFIG_FLOW = {
"user": SchemaFlowFormStep(
schema=DATA_SCHEMA_CONFIG,
validate_user_input=validate_duplicate,
validate_user_input=validate_input,
),
}
OPTIONS_FLOW = {
"init": SchemaFlowFormStep(
DATA_SCHEMA_OPTIONS,
validate_user_input=validate_duplicate,
validate_user_input=validate_input,
)
}

View File

@@ -90,6 +90,7 @@ async def async_setup_platform(
outdoor_temp_sensor,
indoor_humidity_sensor,
calib_factor,
None,
)
],
False,
@@ -118,6 +119,7 @@ async def async_setup_entry(
outdoor_temp_sensor,
indoor_humidity_sensor,
calib_factor,
entry.entry_id,
)
],
False,
@@ -141,10 +143,12 @@ class MoldIndicator(SensorEntity):
outdoor_temp_sensor: str,
indoor_humidity_sensor: str,
calib_factor: float,
unique_id: str | None,
) -> None:
"""Initialize the sensor."""
self._state: str | None = None
self._attr_name = name
self._attr_unique_id = unique_id
self._indoor_temp_sensor = indoor_temp_sensor
self._indoor_humidity_sensor = indoor_humidity_sensor
self._outdoor_temp_sensor = outdoor_temp_sensor

View File

@@ -3,6 +3,9 @@
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"calibration_is_zero": "Calibration factor can't be zero."
},
"step": {
"user": {
"description": "Add Mold indicator helper",
@@ -27,6 +30,9 @@
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"calibration_is_zero": "Calibration factor can't be zero."
},
"step": {
"init": {
"description": "Adjust the calibration factor as required",

View File

@@ -14,5 +14,5 @@
"integration_type": "device",
"iot_class": "assumed_state",
"loggers": ["motionblindsble"],
"requirements": ["motionblindsble==0.1.1"]
"requirements": ["motionblindsble==0.1.2"]
}

View File

@@ -260,14 +260,18 @@ class MqttSensor(MqttEntity, RestoreSensor):
msg.topic,
)
return
if payload == PAYLOAD_NONE:
self._attr_native_value = None
return
if self._numeric_state_expected:
if payload == "":
_LOGGER.debug("Ignore empty state from '%s'", msg.topic)
elif payload == PAYLOAD_NONE:
self._attr_native_value = None
else:
self._attr_native_value = payload
return
if self.options and payload not in self.options:
_LOGGER.warning(
"Ignoring invalid option received on topic '%s', got '%s', allowed: %s",

View File

@@ -74,7 +74,7 @@
}
},
"migrate_notify_service": {
"title": "Legacy action `notify.{service_name}` stll being used",
"title": "Legacy action notify.{service_name} stll being used",
"fix_flow": {
"step": {
"confirm": {

View File

@@ -7,7 +7,7 @@ from nyt_games import NYTGamesClient
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_TOKEN, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.aiohttp_client import async_create_clientsession
from .coordinator import NYTGamesCoordinator
@@ -23,7 +23,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NYTGamesConfigEntry) ->
"""Set up NYTGames from a config entry."""
client = NYTGamesClient(
entry.data[CONF_TOKEN], session=async_get_clientsession(hass)
entry.data[CONF_TOKEN], session=async_create_clientsession(hass)
)
coordinator = NYTGamesCoordinator(hass, client)

View File

@@ -7,7 +7,7 @@ import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_TOKEN
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.aiohttp_client import async_create_clientsession
from .const import DOMAIN, LOGGER
@@ -21,8 +21,9 @@ class NYTGamesConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a flow initialized by the user."""
errors: dict[str, str] = {}
if user_input:
session = async_get_clientsession(self.hass)
client = NYTGamesClient(user_input[CONF_TOKEN], session=session)
session = async_create_clientsession(self.hass)
token = user_input[CONF_TOKEN].strip()
client = NYTGamesClient(token, session=session)
try:
user_id = await client.get_user_id()
except NYTGamesAuthenticationError:
@@ -35,7 +36,9 @@ class NYTGamesConfigFlow(ConfigFlow, domain=DOMAIN):
else:
await self.async_set_unique_id(str(user_id))
self._abort_if_unique_id_configured()
return self.async_create_entry(title="NYT Games", data=user_input)
return self.async_create_entry(
title="NYT Games", data={CONF_TOKEN: token}
)
return self.async_show_form(
step_id="user",
data_schema=vol.Schema({vol.Required(CONF_TOKEN): str}),

View File

@@ -23,7 +23,7 @@ class NYTGamesData:
wordle: Wordle
spelling_bee: SpellingBee | None
connections: Connections
connections: Connections | None
class NYTGamesCoordinator(DataUpdateCoordinator[NYTGamesData]):

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/nyt_games",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["nyt_games==0.4.2"]
"requirements": ["nyt_games==0.4.3"]
}

View File

@@ -161,10 +161,11 @@ async def async_setup_entry(
NYTGamesSpellingBeeSensor(coordinator, description)
for description in SPELLING_BEE_SENSORS
)
entities.extend(
NYTGamesConnectionsSensor(coordinator, description)
for description in CONNECTIONS_SENSORS
)
if coordinator.data.connections is not None:
entities.extend(
NYTGamesConnectionsSensor(coordinator, description)
for description in CONNECTIONS_SENSORS
)
async_add_entities(entities)
@@ -236,4 +237,5 @@ class NYTGamesConnectionsSensor(ConnectionsEntity, SensorEntity):
@property
def native_value(self) -> StateType | date:
"""Return the state of the sensor."""
assert self.coordinator.data.connections is not None
return self.entity_description.value_fn(self.coordinator.data.connections)

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/opentherm_gw",
"iot_class": "local_push",
"loggers": ["pyotgw"],
"requirements": ["pyotgw==2.2.1"]
"requirements": ["pyotgw==2.2.2"]
}

View File

@@ -130,20 +130,32 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]):
continue
start = cost_reads[0].start_time
_LOGGER.debug("Getting statistics at: %s", start)
stats = await get_instance(self.hass).async_add_executor_job(
statistics_during_period,
self.hass,
start,
start + timedelta(seconds=1),
{cost_statistic_id, consumption_statistic_id},
"hour",
None,
{"sum"},
)
# In the common case there should be a previous statistic at start time
# so we only need to fetch one statistic. If there isn't any, fetch all.
for end in (start + timedelta(seconds=1), None):
stats = await get_instance(self.hass).async_add_executor_job(
statistics_during_period,
self.hass,
start,
end,
{cost_statistic_id, consumption_statistic_id},
"hour",
None,
{"sum"},
)
if stats:
break
if end:
_LOGGER.debug(
"Not found. Trying to find the oldest statistic after %s",
start,
)
# We are in this code path only if get_last_statistics found a stat
# so statistics_during_period should also have found at least one.
assert stats
cost_sum = cast(float, stats[cost_statistic_id][0]["sum"])
consumption_sum = cast(float, stats[consumption_statistic_id][0]["sum"])
last_stats_time = stats[consumption_statistic_id][0]["start"]
assert last_stats_time == start.timestamp()
cost_statistics = []
consumption_statistics = []

View File

@@ -7,5 +7,5 @@
"documentation": "https://www.home-assistant.io/integrations/opower",
"iot_class": "cloud_polling",
"loggers": ["opower"],
"requirements": ["opower==0.8.0"]
"requirements": ["opower==0.8.3"]
}

View File

@@ -13,7 +13,9 @@
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"abort": {
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
"already_configured": "The Thread border router is already configured",
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
"issues": {

View File

@@ -32,7 +32,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
client_session=async_get_clientsession(hass),
)
if custom_account := entry.data.get(CONF_ACCOUNT) is not None:
if (custom_account := entry.data.get(CONF_ACCOUNT)) is not None:
client.custom_account_id = custom_account
try:
@@ -49,7 +49,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_update_data() -> OVODailyUsage:
"""Fetch data from OVO Energy."""
if custom_account := entry.data.get(CONF_ACCOUNT) is not None:
if (custom_account := entry.data.get(CONF_ACCOUNT)) is not None:
client.custom_account_id = custom_account
async with asyncio.timeout(10):

View File

@@ -46,7 +46,7 @@ class OVOEnergyFlowHandler(ConfigFlow, domain=DOMAIN):
client_session=async_get_clientsession(self.hass),
)
if custom_account := user_input.get(CONF_ACCOUNT) is not None:
if (custom_account := user_input.get(CONF_ACCOUNT)) is not None:
client.custom_account_id = custom_account
try:

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