Compare commits

..

1161 Commits

Author SHA1 Message Date
Franck Nijhof
a9bc380c32 Bumped version to 2023.10.0b6 2023-10-02 23:03:02 +02:00
Franck Nijhof
be32db70a0 Update Lokalise CLI to v2.6.8 (#101297) 2023-10-02 23:02:53 +02:00
Bram Kragten
0e29ccf069 Update frontend to 20231002.0 (#101294) 2023-10-02 23:02:49 +02:00
Franck Nijhof
9834c1de9a Bumped version to 2023.10.0b5 2023-10-02 21:34:50 +02:00
Nathan Spencer
791293ca87 Bump pylitterbot to 2023.4.9 (#101285) 2023-10-02 21:34:30 +02:00
Joost Lekkerkerker
98d7945521 Revert "Use shorthand attributes in Telldus live" (#101281) 2023-10-02 21:34:26 +02:00
Michael Hansen
06d6122663 Bump intents to 2023.10.2 (#101277) 2023-10-02 21:34:23 +02:00
Luke Lashley
bad9b1c95f Bump python-myq to 3.1.11 (#101266) 2023-10-02 21:34:20 +02:00
Franck Nijhof
a0e5f016e1 Add documentation URL for the Home Assistant Green (#101263) 2023-10-02 21:34:17 +02:00
Joost Lekkerkerker
5370db4a3e Bump aiowaqi to 2.0.0 (#101259) 2023-10-02 21:34:14 +02:00
Erik Montnemery
b069f92d95 Add missing device class to sensor.DEVICE_CLASS_UNITS (#101256) 2023-10-02 21:34:11 +02:00
Joost Lekkerkerker
9b810dcf9f Downgrade pylitterbot to 2023.4.5 (#101255) 2023-10-02 21:34:08 +02:00
Jc2k
3cfae48577 Add extra validation in private_ble_device config flow (#101254) 2023-10-02 21:34:05 +02:00
Erik Montnemery
ad53ff037e Fix color temperature setting in broadlink light (#101251) 2023-10-02 21:34:02 +02:00
Erik Montnemery
63b5ba6b3a Remove dead code from broadlink light (#101063) 2023-10-02 21:33:58 +02:00
Jesse Hills
e76396b184 ESPHome: fix voice assistant default audio settings (#101241) 2023-10-02 21:23:12 +02:00
Joost Lekkerkerker
ebf8061117 Fix withings webhook name (#101221) 2023-10-02 21:23:09 +02:00
Kevin Stillhammer
ced616fafa Remove invalid doc about multi origin/dest in google_travel_time (#101215) 2023-10-02 21:23:06 +02:00
J. Nick Koston
18f3fb42c9 Bump aioesphomeapi to 17.0.1 (#101214) 2023-10-02 21:23:03 +02:00
J. Nick Koston
bfe16e2536 Bump zeroconf to 0.115.1 (#101213) 2023-10-02 21:23:00 +02:00
Aidan Timson
98ca71fc96 Split get users into chunks of 100 for Twitch sensors (#101211)
* Split get users into chunks of 100

* Move to own function
2023-10-02 21:22:57 +02:00
Luke Lashley
93033e037d Bump python-roborock to 0.34.6 (#101147) 2023-10-02 21:22:51 +02:00
Simon Lamon
cfa923252b Fix loop in progress config flow (#97229)
* Fix data entry flow with multiple steps

* Update a test

* Update description and add a show progress change test

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-10-02 21:20:40 +02:00
Franck Nijhof
8c84237e6b Bumped version to 2023.10.0b4 2023-10-01 18:32:38 +02:00
Joost Lekkerkerker
cf6f0cf266 Correct JSONDecodeError in co2signal (#101206) 2023-10-01 18:32:29 +02:00
Joost Lekkerkerker
b24f09b47e Add config entry name to Withings webhook name (#101205) 2023-10-01 18:32:26 +02:00
Daniel Hjelseth Høyer
e0d7c1440b Update Mill library to 0.11.6 (#101180) 2023-10-01 18:32:23 +02:00
Allen Porter
b20f9c40be Clear calendar alarms after scheduling and add debug loggging (#101176) 2023-10-01 18:32:18 +02:00
Oliver
b27097808d Update denonavr to 0.11.4 (#101169) 2023-10-01 18:32:15 +02:00
Allen Porter
d7fa98454b Fix rainbird entity unique ids (#101168)
* Fix unique ids for rainbird entities

* Update entity unique id use based on config entry entity id

* Update tests/components/rainbird/test_binary_sensor.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Rename all entity_registry variables

* Shorten long comment under line length limits

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-10-01 18:32:12 +02:00
Tereza Tomcova
531479bf5b Bump PySwitchbot to 0.40.1 (#101164) 2023-10-01 18:32:09 +02:00
Raman Gupta
3941d2c897 Bump zwave-js-server-python to 0.52.1 (#101162) 2023-10-01 18:32:06 +02:00
hlyi
c4d85ac41f Report unavailability for yolink sensor and binary_sensor (#100743) 2023-10-01 18:32:03 +02:00
c0ffeeca7
5106907571 Terminology: Rename Multi-PAN to Multiprotocol to be consistent (#99262) 2023-10-01 18:31:59 +02:00
Franck Nijhof
04829f0a1b Bumped version to 2023.10.0b3 2023-09-30 10:54:01 +02:00
Raman Gupta
01182e8a5c Fix zwave_js firmware update logic (#101143)
* Fix zwave_js firmware update logic

* add comment

* tweak implementation for ssame outcome
2023-09-30 10:53:50 +02:00
Joost Lekkerkerker
af041d2900 Bump aiowaqi to 1.1.1 (#101129) 2023-09-30 10:53:46 +02:00
Joost Lekkerkerker
822af4d40d Return None when value is not known in OpenHardwareMonitor (#101127)
* Return None when value is not known

* Add to coverage
2023-09-30 10:53:43 +02:00
Franck Nijhof
730acb34f2 Revert pin on AlexaPy (#101123) 2023-09-30 10:53:39 +02:00
Joost Lekkerkerker
b5eb158697 Correct youtube stream selector in media extractor (#101119) 2023-09-30 10:53:36 +02:00
Joost Lekkerkerker
d216fbddae Add logging to media extractor to know the selected stream (#101117) 2023-09-30 10:53:32 +02:00
Joost Lekkerkerker
d84d83a42a Migrate WAQI unique id (#101112)
* Migrate unique_id

* Add docstring
2023-09-30 10:53:29 +02:00
Franck Nijhof
c1ade85d65 Pin charset-normalizer in our package constraints (#101107) 2023-09-30 10:53:25 +02:00
Franck Nijhof
124eda6906 Correct binary ignore for charset-normalizer to charset_normalizer (#101106) 2023-09-30 10:53:22 +02:00
Stefan Agner
65c7b30720 Stop the Home Assistant Core container by default (#101105) 2023-09-30 10:53:18 +02:00
Franck Nijhof
1d2c570a01 Ignore binary distribution wheels for charset-normalizer (#101104) 2023-09-30 10:53:15 +02:00
Marc Mueller
2cc229ce42 Fix circular dependency on homeassistant (#101099) 2023-09-30 10:53:12 +02:00
Franck Nijhof
73356ae232 Use pep 503 compatible wheels index for builds (#101096) 2023-09-30 10:53:09 +02:00
Franck Nijhof
bfd7275972 Update Home Assistant base image to 2023.09.0 (#101092) 2023-09-30 10:53:05 +02:00
jjlawren
ef3bd0100c Bump plexapi to 4.15.3 (#101088)
* Bump plexapi to 4.15.3

* Update tests for updated account endpoint

* Update tests for updated resources endpoint

* Switch to non-web client fixture

* Set __qualname__ attribute for new library behavior
2023-09-30 10:53:01 +02:00
TheJulianJES
3f57c33f32 Fix ZHA exception when writing cie_addr during configuration (#101087)
Fix ZHA exception when writing `cie_addr`
2023-09-30 10:52:58 +02:00
Matthias Alphart
bae3379938 Update xknxproject to 3.3.0 (#101081) 2023-09-30 10:52:55 +02:00
Michael Hansen
85838c6af9 Use wake word description if available (#101079) 2023-09-30 10:52:52 +02:00
TJ Horner
9c0bc57fed Add native precipitation unit for weatherkit (#101073) 2023-09-30 10:52:48 +02:00
tronikos
97448eff8f Bump opower to 0.0.35 (#101072) 2023-09-30 10:52:42 +02:00
Paul Bottein
2f6fefefa7 Update frontend to 20230928.0 (#101067) 2023-09-30 10:52:36 +02:00
Franck Nijhof
d8f96d7709 Bumped version to 2023.10.0b2 2023-09-28 20:05:38 +02:00
Joost Lekkerkerker
fff3c6c6e9 Bump aiowaqi to 1.1.0 (#99751)
* Bump aiowaqi to 1.1.0

* Fix hassfest

* Fix tests
2023-09-28 20:03:43 +02:00
Michael Hansen
17362e1954 Remove fma instructions from webrtc-noise-gain (#101060) 2023-09-28 20:03:21 +02:00
TJ Horner
1bbd4662b7 Bump apple_weatherkit to 1.0.4 (#101057) 2023-09-28 20:03:18 +02:00
Joost Lekkerkerker
ad8033c0f2 Don't show withings repair if it's not in YAML (#101054) 2023-09-28 20:03:15 +02:00
Álvaro Fernández Rojas
081f194f6a Update aioairzone-cloud to v0.2.3 (#101052)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2023-09-28 20:03:12 +02:00
Joost Lekkerkerker
f13059eaf5 Pin pydantic to 1.10.12 (#101044) 2023-09-28 20:03:08 +02:00
Joost Lekkerkerker
0147108b89 Fix onvif creating a new entity for every new event (#101035)
Use topic value as topic
2023-09-28 20:03:05 +02:00
Jesse Hills
ffad30734b ESPHome: dont send error when wake word is aborted (#101032)
* ESPHome dont send error when wake word is aborted

* Add test
2023-09-28 20:03:02 +02:00
Erik Montnemery
5bd306392f Add LED control support to Home Assistant Green (#100922)
* Add LED control support to Home Assistant Green

* Add strings.json

* Sort alphabetically

* Reorder LED schema

* Improve test coverage

* Apply suggestions from code review

Co-authored-by: Stefan Agner <stefan@agner.ch>

* Sort + fix test

* Remove reboot menu

---------

Co-authored-by: Stefan Agner <stefan@agner.ch>
2023-09-28 20:02:59 +02:00
Tereza Tomcova
d6c42ee8e7 Bump PySwitchbot to 0.40.0 to support Curtain 3 (#100619) 2023-09-28 20:02:55 +02:00
Joost Lekkerkerker
35eaebd182 Add feature to add measuring station via number in waqi (#99992)
* Add feature to add measuring station via number

* Add feature to add measuring station via number

* Add feature to add measuring station via number
2023-09-28 20:02:52 +02:00
tyjtyj
81e8ca130f Fix google maps device_tracker same last seen timestamp (#99963)
* Update device_tracker.py 

This fix the google_maps does not show current location when HA started/restarted and also fix unnecessary update when last_seen timestamp is the same. 
Unnecessary update is causing proximity sensor switching from between stationary and certain direction.

* Remove elif

* Fix Black check

* fix black check

* Update device_tracker.py

Better patch

* Update device_tracker.py

* Update device_tracker.py

Fix Black

* Update device_tracker.py

change warning to debug
2023-09-28 20:02:48 +02:00
lennart24
9ab340047d Add shutter_tilt support for Fibaro FGR 223 (#96283)
* add support for shutter_tilt for Fibaro FGR 223
add tests for fgr 223

* Adjust comments and docstring

---------

Co-authored-by: Lennart <18117505+Ced4@users.noreply.github.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-28 19:50:52 +02:00
Paulus Schoutsen
b02f64196b Bumped version to 2023.10.0b1 2023-09-27 21:00:57 -04:00
Michael Hansen
af37de46bd Use webrtc-noise-gain without AVX2 (#101028) 2023-09-27 21:00:50 -04:00
Marc Mueller
be93793db9 Update pyweatherflowudp to 1.4.3 (#101022) 2023-09-27 21:00:49 -04:00
J. Nick Koston
c287564e68 Fix HomeKit handling of unavailable state (#101021) 2023-09-27 21:00:48 -04:00
Jan Bouwhuis
115c3d6e49 Fix handling reload with invalid mqtt config (#101015)
Fix handling reload whith invalid mqtt config
2023-09-27 21:00:47 -04:00
Marcel van der Veldt
415042f356 Adopt Hue integration to latest changes in Hue firmware (#101001) 2023-09-27 21:00:46 -04:00
steffenrapp
dde4b07c29 Add homeassistant reload_all translatable service name and description (#100437)
* Update services.yaml

* Update strings.json

* Update strings.json
2023-09-27 21:00:45 -04:00
Jan-Philipp Benecke
10e8173d4e Restore state of trend sensor (#100332)
* Restoring state of trend sensor

* Handle unknown state & parametrize tests
2023-09-27 21:00:44 -04:00
Franck Nijhof
e7fbd3b54b Bumped version to 2023.10.0b0 2023-09-27 18:14:30 +02:00
Diogo Morgado
4066f657d3 Add "UV Index" to IPMA (#100383)
* Bump pyipma to 3.0.7

* Add uv index sensor to IPMA
2023-09-27 17:45:21 +02:00
Simone Chemelli
5541181969 Address Comelit cover late review (#101008)
address late review
2023-09-27 17:38:14 +02:00
Jeef
577b664c3b Add WeatherFlow integration (#75530)
* merge upstream

* Update homeassistant/components/weatherflow/__init__.py

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

* feat: Removing unused keys

* feat: Addressing PR to remove DEFAULT_HOST from init

* feat: Addressing PR abort case

* feat: Ensure there is a default host always

* feat: Addressing PR comments and fixing entity names via local testing

* feat: Tested units

* feat: updated variable names to hopefully add some clarity to the function

* feat: added more var names for clarity

* feat: Fixed abort

* Update homeassistant/components/weatherflow/__init__.py

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

* feat: Removed an unnecessary line

* feat: Test updates

* feat: Removed unreachable code

* feat: Tons of improvements

* removed debug code

* feat: small tweaks

* feat: Fixed density into HA Compatibility

* feat: Handled the options incorrectly... now fixed

* feat: Handled the options incorrectly... now fixed

* Update homeassistant/components/weatherflow/manifest.json

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

* Cleaned up callback in __init__
Cleaning up config_flow as well

* feat: Cleaned up a stupid test

* feat: Simulating a timeout event

* feat: Triggering timeout in mocking

* feat: trying to pass tests

* refactor: Moved code around so easier to test

* Update homeassistant/components/weatherflow/__init__.py

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

* feat: Incremental changes moving along well

* feat: Last fix before re-review

* feat: Hopefully the tests shall pass

* feat: Remove domian from unique id

* feat: Fixed entity name

* feat: Removed unneeded lambda - to make thread safe

* Working version...

* working

* working

* feat: Remove tuff

* feat: Removed dual call

* Update homeassistant/components/weatherflow/sensor.py

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

* Update homeassistant/components/weatherflow/strings.json

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

* feat: updates based on pr

* feat: removed some self refrences

* feat: Mod RSSI

* feat: Removed the custom Air Density (will add in a later PR)

* feat: Significant cleanup of config flow

* feat: Reworked the configflwo with the help of Joostlek

* feat: Updated test coverage

* feat: Removing bakcing lib attribute

* Update homeassistant/components/weatherflow/sensor.py

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

* Update homeassistant/components/weatherflow/sensor.py

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

* Update homeassistant/components/weatherflow/sensor.py

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

* Update homeassistant/components/weatherflow/sensor.py

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

* Update homeassistant/components/weatherflow/sensor.py

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

* feat: Updated translations

* feat: Renamed CUSTOM to VOC

* feat: Extreme simplification of config flow

* feat: Pushing incremental changes

* feat: Fixing test coverage

* feat: Added lambda expressions for attributes and removed the custom AirDensity sensor

* Update homeassistant/components/weatherflow/sensor.py

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

* Update homeassistant/components/weatherflow/sensor.py

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

* feat: Removed default lambda expression from raw_data_conv_fn

* feat: Added back default variable for lambda

* feat: Updated tests accordingly

* feat: Updated tests

* made sure to patch correct import

* made sure to patch correct import

* feat: Fixed up tests ... added missing asserts

* feat: Dropped model

* Update homeassistant/components/weatherflow/sensor.py

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

* Refactor: Updated code

* refactor: Removed commented code

* feat: close out all tests

* feat: Fixing the patch

* feat: Removed a bunch of stuff

* feat: Cleaning up tests even more

* fixed patch and paramaterized a test

* feat: Addressing most recent comments

* updates help of joostlek

* feat: Updated coverage for const

* Update homeassistant/components/weatherflow/strings.json

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

* Update homeassistant/components/weatherflow/strings.json

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

* Update homeassistant/components/weatherflow/strings.json

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

* Update homeassistant/components/weatherflow/strings.json

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

* Update homeassistant/components/weatherflow/strings.json

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

* Update homeassistant/components/weatherflow/sensor.py

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

* Update homeassistant/components/weatherflow/sensor.py

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

* Update homeassistant/components/weatherflow/strings.json

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

* Update homeassistant/components/weatherflow/sensor.py

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

* feat: Addressing more PR issues... probably still a few remain

* using const logger

* Update homeassistant/components/weatherflow/strings.json

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

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-27 17:28:05 +02:00
J. Nick Koston
b21451b3d1 Bump dbus-fast to 2.11.0 (#101005) 2023-09-27 10:23:06 -05:00
Álvaro Fernández Rojas
3178eac9cc Implement Airzone Cloud Zone climate support (#100792)
* Implement Airzone Cloud Zone climate support

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>

* airzone_cloud: add entity naming

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>

* airzone_cloud: implement requested changes

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>

---------

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2023-09-27 17:20:21 +02:00
Marc Mueller
c59404b5bc Fix additional test cases for Python 3.12 (#101006) 2023-09-27 17:19:20 +02:00
nachonam
9fdc8494b6 Add Freebox Home binary sensors (#92196)
Co-authored-by: Quentame <polletquentin74@me.com>
2023-09-27 17:11:31 +02:00
Joost Lekkerkerker
8b5bfd8cee Add test helper for cloud status updates (#100993)
* Add helper for cloud status updates

* Move import
2023-09-27 17:08:51 +02:00
Joost Lekkerkerker
25a80cd46f Add config flow to Twitch (#93451)
* Update twitch API

* Update twitchAPI

* Add tests

* Apply suggestions from code review

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

* Update sensor.py

* Update sensor.py

* Update sensor.py

* Update sensor.py

* Update sensor.py

* Fix coverage

* Move Twitch constants to separate file

* Move Twitch constants to separate file

* Move Twitch constants to separate file

* Add application credentials

* Add config flow

* Try to add tests

* Add strings

* Add tests

* Add tests

* Improve tests

* Fix tests

* Extract Twitch client creation

* Fix reauth

* Remove import flow

* Remove import flow

* Remove reauth

* Update

* Fix Ruff

* Fix feedback

* Add strings

* Add reauth

* Do stuff in init

* Fix stuff

* Fix stuff

* Fix stuff

* Fix stuff

* Fix stuff

* Start with tests

* Test coverage

* Test coverage

* Remove strings

* Cleanup

* Fix feedback

* Fix feedback

---------

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2023-09-27 15:45:52 +02:00
amitfin
91fcbb41b0 Skip timestamp check of the SIA events (#100660) 2023-09-27 15:13:38 +02:00
Luke Lashley
92694c53e0 Increase MyQ update interval (#100977) 2023-09-27 15:02:19 +02:00
Joost Lekkerkerker
7cb555739f Exclude manifest files from youtube media extraction (#100771)
* Exclude manifest files from youtube media extraction

* Simplify

* Fix
2023-09-27 14:48:03 +02:00
Joost Lekkerkerker
03827bda1e Use async_at_started in Withings (#100994)
* Use async_at_started in Withings

* Make nice
2023-09-27 14:13:11 +02:00
Erik Montnemery
f232ddb85e Bump py-dormakaba-dkey to 1.0.5 (#100992) 2023-09-27 13:57:28 +02:00
Jan-Philipp Benecke
96151e7faa Use local time instead of UTC time as default backup filenames (#100959)
Use local time instead of UTC for the backup name
2023-09-27 13:32:30 +02:00
Robert Svensson
01b5854968 Rework UniFi websocket (#100614)
* Rework websocket management

* remove unnecessary fixture

* Remove controller from mock_unifi_websocket

* Mock api.login in reconnect method

* Remove unnecessary edits

* Minor clean up

* Bump aiounifi to v63

* Wait on task cancellation
2023-09-27 10:56:24 +02:00
Jan-Philipp Benecke
134c005168 Add typing to poolsense (#100984) 2023-09-27 10:14:51 +02:00
G Johansson
43954d660b Add trigger weather template (#100824)
* Add trigger weather template

* Add tests

* mod dataclass

* Remove legacy forecast

* Fix test failure

* sorting

* add hourly test

* Add tests

* Add and fix tests

* Improve tests

---------

Co-authored-by: Erik <erik@montnemery.com>
2023-09-27 10:11:57 +02:00
Joost Lekkerkerker
fd53e116bb Add config flow to color extractor (#100862) 2023-09-27 10:11:42 +02:00
Jan Bouwhuis
0f38cd5794 Allow to reset an mqtt lock to an unknown state (#100985) 2023-09-27 09:50:01 +02:00
Joost Lekkerkerker
d2bcf88bbf Set device name as entity name for Comelit lights (#100986)
Fix entity name for Comelit lights
2023-09-27 09:39:57 +02:00
Marty Sun
4788dd2905 Add "start_irrigation" service for Yardian (#100257)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-27 08:59:15 +02:00
Simone Chemelli
d70308ae9f Add cover support to Comelit (#100904)
* add cover support to Comelit

* coveragerc

* Update homeassistant/components/comelit/cover.py

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

* Update homeassistant/components/comelit/cover.py

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

* Update homeassistant/components/comelit/cover.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-27 08:56:38 +02:00
Simone Chemelli
db5943ad6d Improve Comelit login with PIN (#100860)
* improve login

* library bump
2023-09-27 08:52:46 +02:00
Franck Nijhof
0afb060c24 Merge branch 'master' into dev 2023-09-27 08:51:27 +02:00
Joost Lekkerkerker
e5567c09b9 Deprecate Withings YAML (#100967) 2023-09-27 08:33:43 +02:00
Raman Gupta
70e3da207a Automatically enable/disable zwave_js server logging in lib (#100837)
* Bump zwave-js-server-python to 0.52.0

* Add WS command to enabled zwave_js server logging in lib

* enable and disable server logging automatically

* fix conditionals

* fix tests

* Add logging

* small tweaks

* Add logger as a dependency

* fix test

* Prepare for movement of event constant

* Add constant so tests pass
2023-09-27 01:17:52 -04:00
Raman Gupta
067b94899f Move EVENT_LOGGING_CHANGED to constants (#100974)
* Move EVENT_LOGGING_CHANGED to constants

* fix test

* remove logger as dependency for bluetooth and fix test
2023-09-27 01:06:14 -04:00
Jan-Philipp Benecke
009349acf0 Move poolsense base entity to its own file (#100981) 2023-09-27 07:04:20 +02:00
puddly
4e4d4992bf Bump ZHA dependencies (#100979) 2023-09-26 23:39:07 -05:00
TheJulianJES
93e2d4b74c Bump zha-quirks to 0.0.104 (#100975) 2023-09-26 23:20:23 -04:00
Michael Hansen
af8367a8c6 Send Wyoming Detect message during wake word detection (#100968)
* Send Detect message with desired wake word

* Add tests

* Fix test
2023-09-26 19:24:02 -05:00
Bram Kragten
9b574fd2c9 Update frontend to 20230926.0 (#100969) 2023-09-26 19:24:42 -04:00
Raman Gupta
65f307fe9c Add endpoint to zwave_js_notification event (#100951) 2023-09-26 18:48:59 -04:00
Michael Hansen
8a9b2f4515 Bump to webrtc-noise-gain 1.2.1 for 32-bit builds (#100942)
* Bump to 1.2.0 for 32-bit builds

* Bugfix with 1.2.1
2023-09-26 17:14:48 -05:00
Simone Chemelli
b617451a25 Add button platform to Vodafone Station (#100941)
* button platform initial commit

* fix is_suitable

* cleanup

* coveragerc

* add translations

* remove redundant key
2023-09-27 00:09:42 +02:00
Steven Looman
ad17f1622c Bump async-upnp-client to 0.36.1 (#100961) 2023-09-26 16:32:37 -05:00
Jan-Philipp Benecke
eab428f0e2 Move poolsense coordinator to its own file (#100964) 2023-09-26 23:28:25 +02:00
Jesse Hills
4c21aa18db Add audio_settings for pipeline from ESPHome device (#100894)
* Add audio_settings for pipeline from ESPHome device

* ruff fixes

* Bump aioesphomeapi 17.0.0

* Mypy

* Fix tests

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2023-09-26 16:27:26 -05:00
Michael Hammer
f899e5159b KNX: Provide project data and parser version via websocket (#100676)
* feat(knxproject-explore): providing knxproject via websocket, also xknxproject version in info mesage

* feat(knxproject-explore): adding test case

* reverted back adding of xknxproject version

* fix(): Enriching get project test case to check against FIXTURE

* feat(knxproject-explore): providing knxproject via websocket, also xknxproject version in info mesage

* feat(knxproject-explore): adding test case

* reverted back adding of xknxproject version

* fix(): Enriching get project test case to check against FIXTURE
2023-09-26 23:17:37 +02:00
Raman Gupta
176f5dc2d6 Bump zwave-js-server-python to 0.52.0 (#100833)
* Bump zwave-js-server-python to 0.52.0

* remove old function

* fix tests
2023-09-26 17:05:54 -04:00
Jan Bouwhuis
59a26010ba Cleanup redundant mqtt entity constructors (#100939)
* Remove redundant mqtt entity constructors

* Remove unrelated change

* Follow up comment

* Revert changes to mqtt update platform

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-26 23:03:11 +02:00
Jan-Philipp Benecke
d387308f3c Move motion blinds coordinator to its own file (#100952) 2023-09-26 22:50:46 +02:00
Jan Bouwhuis
8ec11910af Allow discovery config update mqtt update entities (#100957) 2023-09-26 15:21:27 -05:00
Joost Lekkerkerker
0f95de997f Support cloudhooks in Withings (#100916)
* Support cloudhooks in Withings

* Support cloudhooks in Withings

* Support cloudhooks in Withings

* Remove strings
2023-09-26 21:52:18 +02:00
Luke Lashley
42b006a108 Update MyQ to use python-myq 3.1.9 (#100949) 2023-09-26 14:48:36 -05:00
Erik Montnemery
b281fa17fc Simplify wake_word/info + improve test coverage (#100902)
* Simplify wake_word/info + improve test coverage

* Fix test

* Revert unrelated changes
2023-09-26 14:07:27 -05:00
Edouard Lafargue
4028596977 Add Medcom Bluetooth integration (#100289)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-26 13:41:34 -05:00
Simone Chemelli
60dd5f1d50 Bump aiovodafone to 0.3.1 (#100944) 2023-09-26 20:27:34 +02:00
Erik Montnemery
a9bcfe5700 Abort wake word detection when assist pipeline is modified (#100918) 2023-09-26 20:24:55 +02:00
Jan Bouwhuis
9254eea9e2 Remove unused attribute for MQTT lawn_mower (#100946)
Remove unused attributes for MQTT lawn_mower
2023-09-26 20:18:52 +02:00
Simone Chemelli
e18ff03244 Improve Vodafone Station setup dialog messages (#100937) 2023-09-26 20:16:50 +02:00
Jan Bouwhuis
4d7e3d2b0f Remove redundant initial assigment for mqtt siren (#100945) 2023-09-26 20:07:54 +02:00
Olen
e921e4a662 Move fetching of sw_version for Twinkly (#100286) 2023-09-26 20:04:17 +02:00
Joost Lekkerkerker
c7e4604cfd Call async added to hass super in Airvisual (#100449) 2023-09-26 20:03:44 +02:00
Jan-Philipp Benecke
d94b09655b Use snapshot assertion for wiz diagnostics test (#99154) 2023-09-26 20:03:22 +02:00
Joost Lekkerkerker
bdfdeb2bc0 Call async added to hass super in Risco (#100444) 2023-09-26 20:02:00 +02:00
Joost Lekkerkerker
ae7ede1253 Call async added to hass super in Smart Meter Texas (#100445) 2023-09-26 20:01:33 +02:00
Joost Lekkerkerker
9be5005a70 Use automatic title during config flow setup in Aurora (#99199) 2023-09-26 20:00:23 +02:00
Joost Lekkerkerker
bc665a1368 Remove setting name in AnthemAV config flow (#99148) 2023-09-26 19:58:47 +02:00
Jan Bouwhuis
20a2e129fb Intialize mqtt lock in an unknown state in pessimistic mode (#100943)
Intialize mqtt lock as unknown in pessimistic mode
2023-09-26 19:53:45 +02:00
Erik Montnemery
734c4e8e32 Rename WakeWord.ww_id to WakeWord.id (#100903)
* Rename WakeWord.ww_id to WakeWord.wake_word_id

* Revert unrelated changes

* Rename to id

* Correct rebase
2023-09-26 19:12:16 +02:00
Joost Lekkerkerker
074eb966dd Add config flow to AfterShip (#100872)
* Add config flow to Aftership

* Add config flow to Aftership

* Fix schema

* Update homeassistant/components/aftership/strings.json

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

* Fix feedback

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-26 18:05:23 +02:00
Michael
18fad569e0 Add support to remove orphan devices in AVM FRITZ!SmartHome (#100739) 2023-09-26 18:01:01 +02:00
Bram Kragten
82fdd8313f Update frontend manifest for new icons (#100936) 2023-09-26 17:53:26 +02:00
Joost Lekkerkerker
59207be5f8 Add body_exists to MockRequest in aiohttp util (#100932)
* Add body_exists to MockRequest in aiohttp util

* Add body_exists to MockRequest in aiohttp util

* Add body_exists to MockRequest in aiohttp util
2023-09-26 17:52:29 +02:00
Rami Mosleh
785b46af22 Add re-auth flow to glances integration (#100929)
* Add reauth flow to glances integration.

* add reauth string

* add reauth strings
2023-09-26 17:46:12 +02:00
Erik Montnemery
c823e407fd Tweak test wake_word.test_init.test_detected_entity (#100910) 2023-09-26 10:42:08 -05:00
J. Nick Koston
6551e52225 Bump zeroconf to 0.115.0 (#100931) 2023-09-26 10:08:27 -05:00
J. Nick Koston
c9a55c7f84 Cache the latest short term stat id for each metadata_id on each run (#100535) 2023-09-26 09:57:59 -05:00
J. Nick Koston
4b39bf7e5b Small cleanup to isy994 extra_state_attributes (#100935) 2023-09-26 09:57:25 -05:00
Allen Porter
822251a642 Update fitbit client to use asyncio (#100933) 2023-09-26 07:50:42 -07:00
Erik Montnemery
bd40cbcb21 Tweak pipeline.multiply_volume (#100905) 2023-09-26 09:19:57 -05:00
Rami Mosleh
31e9ca0099 Handle authorization error in glances config flow (#100866)
* Handle authroization error in glances config flow

* Remove validate_input method and expections

* update tests
2023-09-26 14:51:04 +02:00
Joost Lekkerkerker
91bc65be9c Add entity translations to SRP Energy (#99011) 2023-09-26 14:47:19 +02:00
David Knowles
73cfe659ea Make Hydrawise compliant with new naming standards (#100921)
* Make Hydrawise compliant with new naming standards

* Update binary_sensor.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-26 14:34:43 +02:00
Álvaro Fernández Rojas
29da43b9a9 Bump aioairzone-cloud to 0.2.2 (#100915)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2023-09-26 14:04:50 +02:00
steffenrapp
2165f0a538 Add missing input_button service translation (#100387) 2023-09-26 13:58:58 +02:00
Joost Lekkerkerker
4ffac3e7ed Cleanup Withings const import (#100914) 2023-09-26 13:16:37 +02:00
Marc Mueller
bd7a86a0a6 Remove async-timeout as core dependency (#100912) 2023-09-26 05:57:10 -05:00
Erik Montnemery
4df14b2625 Remove duplicated call to PipelineRun.end from PipelineInput.execute (#100909)
Remove duplicated call to PipelineRun.end from PipelineInput.execute
2023-09-26 12:38:25 +02:00
Dennis
e5a151c4c3 Add state classes to Tomorrowio sensors (#100692) 2023-09-26 12:33:39 +02:00
J. Nick Koston
667f4b1ca8 Mark Bluetooth scanner as not scanning when watchdog timeout is reached (#100738) 2023-09-26 05:29:46 -05:00
Marc Mueller
f837e6722c Update cryptography to 41.0.4 (#100911) 2023-09-26 05:27:56 -05:00
Joost Lekkerkerker
f21d924dd5 Add entity translations to Wallbox (#99021)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-26 11:41:40 +02:00
Erik Montnemery
1e76d37cee Rename PipelineData.pipeline_runs to pipeline_debug (#100907) 2023-09-26 11:35:51 +02:00
Joost Lekkerkerker
b0a7e68984 Rename Withings coordinator file (#100899)
Rename common.py to coordinator.py
2023-09-26 10:59:45 +02:00
Maikel Punie
249e20f8e5 Bump pyduotecno to 2023.9.0 (#100900) 2023-09-26 10:57:13 +02:00
Joost Lekkerkerker
4f63c7934b Add coordinator to Withings (#100378)
* Add coordinator to Withings

* Add coordinator to Withings

* Fix tests

* Remove common files

* Fix tests

* Fix tests

* Rename to Entity

* Fix

* Rename webhook handler

* Fix

* Fix external url

* Update homeassistant/components/withings/entity.py

Co-authored-by: Luke Lashley <conway220@gmail.com>

* Update homeassistant/components/withings/entity.py

Co-authored-by: Luke Lashley <conway220@gmail.com>

* Update homeassistant/components/withings/entity.py

Co-authored-by: Luke Lashley <conway220@gmail.com>

* Update homeassistant/components/withings/entity.py

Co-authored-by: Luke Lashley <conway220@gmail.com>

* fix imports

* Simplify

* Simplify

* Fix feedback

* Test if this makes changes clearer

* Test if this makes changes clearer

* Fix tests

* Remove name

* Fix feedback

---------

Co-authored-by: Luke Lashley <conway220@gmail.com>
2023-09-26 09:17:11 +02:00
David Knowles
8ba6fd7935 Add device info to Hydrawise (#100828)
* Add device info to Hydrawise

* Apply suggestions from code review

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

* Remove _attr_has_entity_name

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-26 09:15:20 +02:00
G Johansson
7b1b189f3e Add date range to Workday (#96255) 2023-09-26 08:21:36 +02:00
Jan-Philipp Benecke
9c1944f830 Enable strict typing in london underground (#100563)
* Enable strict typing in london underground

* Change typing from Any

* Remove redundant cast

* Change from Mapping to dict
2023-09-26 08:13:59 +02:00
Paulus Schoutsen
c5c5d9ed0c Allow fetching wake word entity info (#100893) 2023-09-25 21:33:04 -05:00
Allen Porter
fa2d77407a Add Rain Bird irrigation calendar (#87604)
* Initial version of a calendar for the rainbird integration

* Improve calendar support

* Revert changes to test fixtures

* Address ruff error

* Fix background task scheduling

* Use pytest.mark.freezetime to move to test setup

* Address PR feedback

* Make refresh a member

* Merge rainbird and calendar changes

* Increase test coverage

* Readability improvements

* Simplify timezone handling
2023-09-25 20:27:38 -04:00
Allen Porter
18f29993c5 Simplify fitbit unit system and conversions (#100825)
* Simplify fitbit unit conversions

* Use enum values in unit system schema

* Use fitbit unit system enums
2023-09-25 20:08:59 -04:00
Michael Hansen
785618909a Use webrtc-noise-gain for audio enhancement in Assist pipelines (#100698)
* Use webrtc-noise-gain instead of webrtcvad package

* Switching to ProcessedAudioChunk

* Refactor VAD and fix tests

* Add vad no chunking test

* Add test that runs audio enhancements
2023-09-25 20:03:50 -04:00
Jan Bouwhuis
a4f7f3ba7e Make sure time is changed in mqtt event test (#100889) 2023-09-26 00:32:12 +02:00
Jc2k
9fe6cd61df Bump aiohomekit to 3.0.5 (#100886) 2023-09-25 23:08:38 +01:00
Jc2k
cae19431d1 Simplify homekit_controller tests with snapshots (#100885) 2023-09-25 16:26:27 -05:00
Jan Bouwhuis
c5b32d6307 Add doorbell event to google_assistant (#97123)
* First attempt async_report_state_all

* Move notificationSupportedByAgent to SYNC response

* Make notificationSupportedByAgent conditional

* Add generic sync_options method

* Report event

* Add event_type as ID

* User UUID, imlement query_notifications

* Refactor query_notifications

* Add test

* MyPy

* Unreachable code

* Tweak

* Correct notification message

* Timestamp was wrong unit, it should be in seconds
* Can only allow doorbell class, since it's the only type

* Fix test

* Remove unrelated changes - improve coverage

* Additional tests

---------

Co-authored-by: Joakim Plate <elupus@ecce.se>
2023-09-25 23:20:02 +02:00
J. Nick Koston
6387263007 Bump async-upnp-client to 0.36.0 (#100881) 2023-09-25 16:19:40 -05:00
J. Nick Koston
d5c22bec82 Bump zeroconf to 0.114.0 (#100880) 2023-09-25 16:19:24 -05:00
J. Nick Koston
dbdc513aa5 Bump dbus-fast to 2.10.0 (#100879) 2023-09-25 16:19:03 -05:00
Joost Lekkerkerker
15f40f2c5a Bump yt-dlp to 2023.9.24 (#100884) 2023-09-25 23:06:48 +02:00
Jan Bouwhuis
90bf20c6f8 Add type hints for intent_script integration (#99393)
* Add type hints for intent_script integration

* Correct 2nd typo

* omit total=False as all options are set
2023-09-25 23:01:53 +02:00
Jan Bouwhuis
60b8775f4a Avoid redundant calls to async_write_ha_state in mqtt siren (#100813)
* Avoid redundant calls to async_write_ha_state

* Add comment
2023-09-25 22:36:13 +02:00
Jan-Philipp Benecke
2eefd21dcc Parametrize more co2signal config flow tests (#100882)
* Clean up co2signal tests

* Some more clean up

* Use named parameter ids of parametrize
2023-09-25 22:21:40 +02:00
Jan Bouwhuis
a242a1c107 Add tests for mqtt image (#100793)
* Rework mqtt image writing state

* Revert mixin changes, add attr

* Revert code changes
2023-09-25 22:20:32 +02:00
Jan Bouwhuis
7258bc6457 Avoid redundant calls to async_write_ha_state in mqtt vacuum (#100799)
* Avoid redundant calls to async_write_ha_state

* Add comment

* Rephrase
2023-09-25 22:17:29 +02:00
J. Nick Koston
969d6b852e Bump led-ble to 1.0.1 (#100873) 2023-09-25 14:34:02 -05:00
Jan-Philipp Benecke
b9a3863645 Handle json decode exception in co2signal (#100857)
* Handle json decode exception in co2signal

* Update homeassistant/components/co2signal/coordinator.py

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

* Fix import

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-25 21:21:01 +02:00
Jan Bouwhuis
ea1108503d Rework and fix mqtt siren writing state and attributes (#100871)
Rework mqtt siren writing state and attributes
2023-09-25 21:08:14 +02:00
Erik Montnemery
d76c5ed351 Use wake word settings in assist pipeline runs (#100864) 2023-09-25 12:58:10 -04:00
Marc Mueller
11e8bf0b9c Update types packages (#100850) 2023-09-25 18:53:22 +02:00
Jan Bouwhuis
30c7e7fbdf Avoid redundant calls to async_ha_write_state mqtt update platform (#100819)
Avoid redundant calls to async_ha_write_state
2023-09-25 18:08:02 +02:00
Jan Bouwhuis
cd3d3b76a3 Avoid redundant calls to async_ha_write_state in mqtt text (#100816)
Avoid redundant calls to async_ha_write_state
2023-09-25 18:07:24 +02:00
Jan Bouwhuis
8d10cdce4e Avoid redundant calls to async_ha_write_state in mqtt switch (#100815)
Avoid redundant calls to async_ha_write_state
2023-09-25 18:06:19 +02:00
Jan Bouwhuis
33d45b3454 Avoid redundant calls to async_write_ha_state in mqtt select (#100809)
Avoid redundant calls to async_write_ha_state
2023-09-25 18:05:42 +02:00
Jan Bouwhuis
180f248370 Avoid redundant calls to async_write_ha_state in mqtt number (#100808)
Avoid redundant calls to async_write_ha_state
2023-09-25 18:05:14 +02:00
Jan Bouwhuis
98cc2e8098 Avoid redundant calls to async_write_ha_state in mqtt lock (#100802)
Avoid redundant calls to async_write_ha_state
2023-09-25 18:04:33 +02:00
Jan Bouwhuis
ce02cbefc9 Avoid redundant calls to async_write_ha_state in mqtt lawn_mower (#100795)
Avoid redundant calls to async_write_ha_state
2023-09-25 18:03:52 +02:00
Jc2k
014fb61743 Fix missing device class on Velux Windows (#100863) 2023-09-25 11:03:11 -05:00
Jan Bouwhuis
002be37257 Rework and added tests for mqtt event (#100769)
Use write_state_on_attr_change and add tests
2023-09-25 18:02:17 +02:00
Jan Bouwhuis
f83a597603 Avoid redundant calls to async_write_ha_state in mqtt humidifier (#100781)
Avoid redundant calls to async_write_ha_state
2023-09-25 18:00:08 +02:00
Jan Bouwhuis
3da4815522 Avoid redundant calls to async_write_ha_state for mqtt fan (#100777)
Avoid redundant calls to async_write_ha_state
2023-09-25 17:59:33 +02:00
elmurato
84451e858e Simplify Minecraft Server SRV handling (#100726) 2023-09-25 17:56:26 +02:00
Erik Montnemery
803d24ad1a Rename wake_word.async_default_engine to wake_word.async_default_entity (#100855)
* Rename wake_word.async_default_engine to wake_word.async_default_entity

* tweak

* Some more rename

* Update tests
2023-09-25 17:08:37 +02:00
Jc2k
8ed0f05270 Add duration and sensitivity configuration for Eve Motion (#100861) 2023-09-25 09:52:27 -05:00
J. Nick Koston
4c255677c3 Add support for receivers to HomeKit (#100717) 2023-09-25 09:36:01 -05:00
J. Nick Koston
c1b9400833 Provide a better model for HomeKit service entries (#100848) 2023-09-25 09:34:53 -05:00
Jc2k
fb174f8063 Add valve position sensor for Eve Thermo (#100856) 2023-09-25 09:27:18 -05:00
Marc Mueller
dd302b291d Update pylint to 2.17.6 (#100849) 2023-09-25 09:14:07 -05:00
Erik Montnemery
5a3efb9149 Store wakeword settings in assist pipelines (#100847)
* Store wakeword settings in assist pipelines

* wakeword -> wake_word

* Remove unneeded variable
2023-09-25 16:07:26 +02:00
Jc2k
7334bc7c9b Add a select entity for homekit temperature display units (#100853) 2023-09-25 08:53:01 -05:00
Paulus Schoutsen
23b239ba77 Allow passing a wake word ID to detect wake word (#100832)
* Allow passing a wake word ID to detect wake word

* Do not inject default wake words in wake_word integration
2023-09-25 15:33:54 +02:00
Maikel Punie
8a44adb447 Add binary sensors for duotecno (#100844)
* Add binary sensors for duotecno

* Add comments
2023-09-25 13:34:39 +02:00
Kevin Worrel
77007ef091 Explicitly define ScreenLogic entity descriptions (#100173) 2023-09-25 06:26:26 -05:00
Alex Yao
2ae07096d2 Address late review on Life360 button (#100740) 2023-09-25 06:09:16 -05:00
Maikel Punie
19854ded16 Add duotecno climate (#99333)
* Add duotecno climate

* Add climate to .coveragerc

* Update homeassistant/components/duotecno/climate.py

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

* Update homeassistant/components/duotecno/climate.py

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

* more comments

* more comments

* more comments

* more comments

* fix typo

* Add translation key

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-25 12:52:51 +02:00
dependabot[bot]
2a443648fc Bump actions/checkout from 4.0.0 to 4.1.0 (#100836)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-25 11:01:12 +02:00
G Johansson
8d50be379c Create repairs in Workday if country or province is wrong (#98753)
* Repairs workday

* fix if not province exist

* Tests repairs

* Add tests

* Finalize tests

* Fix feedback

* simplify

* Less translations
2023-09-25 08:59:15 +02:00
G Johansson
c414e52b55 Change duration for timer.start service to only change running duration (#99628)
* Get back duration for timer

* running duration

* Mods

* Finish

* Fix start call

* remove restore idle

* running duration not None

* fix tests
2023-09-25 08:57:02 +02:00
J. Nick Koston
6b19602322 Bump aioesphomeapi to 16.0.6 (#100826)
changelog: https://github.com/esphome/aioesphomeapi/compare/v16.0.5...v16.0.6
2023-09-25 07:22:42 +02:00
Aaron Bach
7a6f337b01 Add missing SimpliSafe binary sensors (#100820) 2023-09-24 15:17:45 -06:00
Daniel Trnka
09729e8c46 Add Mysensors battery sensor (#100749)
* Move child related stuff to MySensorsChildEntity

* Dispatch signal for newly discovered MySensors node

* Create battery entity for each MySensors node

* Removed ATTR_BATTERY_LEVEL attribute from each node sensor

Attribute is redundant with newly introduced battery sensor entity

* Apply suggestions from code review

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-24 22:50:13 +02:00
Nathan Spencer
6d624ecb46 Bump pylitterbot to 2023.4.8 (#100811) 2023-09-24 22:46:43 +02:00
Allen Porter
66ebb479ea Rewrite fitbit sensor API response value parsing (#100782)
* Cleanup fitbit sensor API parsing

* Remove API code that is not used yet

* Remove dead code for battery levels

Small API parsing cleanup

* Address PR feedback

* Update homeassistant/components/fitbit/sensor.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-24 22:37:48 +02:00
Álvaro Fernández Rojas
5549f697cf Update AEMET-OpenData to v0.4.5 (#100818)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2023-09-24 22:18:31 +02:00
J. Nick Koston
b9e8566608 Bump bluetooth-data-tools to 0.12.0 (#100794) 2023-09-24 20:29:29 +02:00
Jc2k
0c89f5953f Preserve private ble device broadcast interval when MAC address rotates (#100796) 2023-09-24 19:24:12 +01:00
Franck Nijhof
0cbd46592a 2023.9.3 (#100755) 2023-09-24 18:58:43 +02:00
Scott Colby
49715f300a Allow workday sensor to be configured without a country (#93048)
* Merge branch 'dev' into workday_without_country

* ruff

* remove province check

* Remove not needed test

* Mod config flow

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2023-09-24 16:13:45 +02:00
Simone Chemelli
49b8937bb3 Fix Comelit device info (#100587) 2023-09-24 14:54:10 +02:00
Simone Chemelli
b19a0fb2e9 Fix Comelit device info (#100587) 2023-09-24 14:51:56 +02:00
Franck Nijhof
0ae285c404 Update home-assistant/builder to 2023.09.0 (#100797) 2023-09-24 14:50:50 +02:00
G Johansson
f22ecf2a09 Add strong to fan mode for Sensibo (#100773) 2023-09-24 14:50:47 +02:00
David Knowles
0eac0bb3c5 Bump pyschlage to 2023.9.1 (#100760) 2023-09-24 14:50:43 +02:00
David Knowles
25cb835faf Bump pyschlage to 2023.9.0 (#99624) 2023-09-24 14:50:38 +02:00
Franck Nijhof
4fb482610b Update home-assistant/wheels to 2023.09.1 (#100758)
* Update home-assistant/wheels to 2023.09.0

* Update home-assistant/wheels to 2023.09.1
2023-09-24 14:48:24 +02:00
sdb9696
1779222062 Bump ring-doorbell to 0.7.3 (#100688)
Bump ring to 0.7.3
2023-09-24 14:48:20 +02:00
Allen Porter
caacdabd3d Fix rainbird unique id (#99704)
* Don't set a unique id for devices with no serial

* Add additional check for the same config entry host/port when there is no serial

* Update homeassistant/components/rainbird/config_flow.py

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

* Update tests/components/rainbird/test_config_flow.py

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

* Update tests/components/rainbird/test_config_flow.py

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

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-24 14:48:17 +02:00
Erik Montnemery
0dc21504f5 Remove support for excluding attributes in recorder platforms (#100679) 2023-09-24 14:45:06 +02:00
Franck Nijhof
1b1901cb6d Update home-assistant/builder to 2023.09.0 (#100797) 2023-09-24 14:36:02 +02:00
Jan Bouwhuis
edb28be964 Avoid redundant calls to async_write_ha_state in mqtt device_tracker (#100767)
Avoid redundant calls to async_ha_write_state
2023-09-24 12:52:13 +02:00
Jc2k
f0375eb97e Expose bluetooth availability tracking interval controls to integrations (#100774) 2023-09-24 10:45:25 +02:00
AtomBrake
eb020dd66c Update powerwall password description (#100389)
Update strings.json

Updated wording of how to find password on newer model gateways
2023-09-24 08:02:48 +02:00
Nathan Tilley
d453f3809c Clean up FAA Delays constants (#100788)
Move const to platform
2023-09-24 07:02:34 +02:00
Allen Porter
ae29ddee74 Add more test coverage for fitbit sensors (#100776) 2023-09-23 15:38:53 -07:00
Nathan Tilley
451c085587 Bump faadelays to 2023.8.0 (#100700)
* Update component to use new API version

* Revert new features, implement #95546, bump library

* Revert #95546 changes, remove NOTAM
2023-09-24 00:06:49 +02:00
David Knowles
f8a8fe760d Add config flow to Hydrawise (#95589)
* Add config flow to Hydrawise

* Raise an issue when a YAML config is detected

* Add a test for YAML import

* Add missing __init__.py

* Update CODEOWNERS

* Update requirements_test_all.txt

* Add config flow data to strings.json

* Hande scan_interval not being in YAML on import

* Fix requirements

* Update deprecation dates

* Update requirements_test_all.txt

* Changes from review

* Update homeassistant/components/hydrawise/__init__.py

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

* Add already_configured to strings.json

* Add back setup_platform functions

* Apply suggestions from code review

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

* Add back setup_platform

* Update requirements_test_all.txt

* Run black on hydrawise/*.py

* Add missing import of HOMEASSISTANT_DOMAIN

* Use more specific errors in config flow

* Add additional tests

* Update config flow to use pydrawise.legacy

* Re-work YAML deprecation issues

* Revert some changes to binary_sensor, as requested in review

* Changes requested during review

* Apply suggestions from code review

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

* Remove unused STE_USER_DATA_SCHEMA

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

* Update comment in setup_platform

* Re-work the config flow again

* Apply suggestions from code review

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

* Update tests

* Add back the _default_watering_timer attribute

* Bump deprecation dates

* Update requirements_test_all.txt

* Update CODEOWNERS

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-24 00:03:07 +02:00
G Johansson
28dc17c0b3 Refactor Sensibo tests to use snapshot (#100775) 2023-09-23 23:37:02 +02:00
Allen Porter
8d8c7187d3 Fix rainbird unique id (#99704)
* Don't set a unique id for devices with no serial

* Add additional check for the same config entry host/port when there is no serial

* Update homeassistant/components/rainbird/config_flow.py

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

* Update tests/components/rainbird/test_config_flow.py

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

* Update tests/components/rainbird/test_config_flow.py

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

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-23 23:14:57 +02:00
G Johansson
1f66fc013c Add strong to fan mode for Sensibo (#100773) 2023-09-23 23:08:07 +02:00
G Johansson
06ade74711 Bump pysensibo 1.0.35 (#100245)
* Bump pysensibo 1.0.34

* 1.0.35

* Mod tests

* revert refactoring

* Fix tests
2023-09-23 23:01:08 +02:00
Joost Lekkerkerker
4a86892d82 Fix fitbit test code owner (#100772) 2023-09-23 13:49:08 -07:00
sdb9696
1fce60bd6f Bump ring-doorbell to 0.7.3 (#100688)
Bump ring to 0.7.3
2023-09-23 21:21:34 +02:00
Joost Lekkerkerker
ba6a92756a Call async added to hass super in Flo (#100453) 2023-09-23 12:05:53 -07:00
Allen Porter
781bc5b3bc Add tests for fitbit integration (#100765)
* Add tests for fitbit integration

* Update coveragerc

* Update test requirements
2023-09-23 12:04:44 -07:00
Joost Lekkerkerker
71aef4e95a Add media extractor tests (#100462)
* Add tests for media extractor

* Complete test coverage

* Fix test dep
2023-09-23 12:04:29 -07:00
David Knowles
a826f26642 Bump pyschlage to 2023.9.1 (#100760) 2023-09-23 20:37:57 +02:00
Allen Porter
d833c1a598 Add myself as a fitbit codeowner (#100766) 2023-09-23 20:32:52 +02:00
rappenze
a2730fb29d Fibaro finish separation of scenes (#100734) 2023-09-23 19:13:03 +02:00
Jan Bouwhuis
14b39c3bcf Correct some typo's in MQTT issue string (#100759) 2023-09-23 19:05:52 +02:00
Franck Nijhof
6383cafeb9 Update home-assistant/wheels to 2023.09.1 (#100758)
* Update home-assistant/wheels to 2023.09.0

* Update home-assistant/wheels to 2023.09.1
2023-09-23 17:38:21 +02:00
Maciej Bieniek
5c5dff034c Add event platform for Shelly gen1 devices (#100655)
* Initial commit

* Use description.key

* Add translations

* Check event_types

* Rename input_id to channel

* Fix removeal confition

* Add tests

* Sort classes and consts

* Use ShellyBlockEntity class

* Update tests

* Update homeassistant/components/shelly/event.py

Co-authored-by: Shay Levy <levyshay1@gmail.com>

---------

Co-authored-by: Shay Levy <levyshay1@gmail.com>
2023-09-23 16:03:57 +02:00
Franck Nijhof
527c7b21fd Bumped version to 2023.9.3 2023-09-23 13:47:05 +02:00
G Johansson
ce8062041f Fix weather template forecast attributes (#100748) 2023-09-23 13:46:00 +02:00
Michael Hansen
862a26afad Bump intents to 2023.9.22 (#100737) 2023-09-23 13:45:57 +02:00
puddly
c07a112601 Bump ZHA dependencies (#100732) 2023-09-23 13:45:53 +02:00
Erik Montnemery
88f379d08f Fix handling of unit system change in sensor (#100715) 2023-09-23 13:45:50 +02:00
Simone Chemelli
bb8850e8cf Bump aiocomelit to 0.0.8 (#100714)
* Bump aiocomelit to 0.0.8

* fix import

* fix tests
2023-09-23 13:45:47 +02:00
Jan Bouwhuis
556e40add5 Fix mqtt light rgbww update without state topic (#100707)
* Fix mqtt light rgbww update without state topic

* Add @callback decprator and correct mired conv
2023-09-23 13:45:44 +02:00
Raman Gupta
161e9d10bd Bump zwave-js-server-python to 0.51.3 (#100665) 2023-09-23 13:45:40 +02:00
Luke Lashley
fae063086c Bump python-roborock to 0.34.1 (#100652)
bump to 34.1
2023-09-23 13:45:37 +02:00
Robin Li
4f4f6c92d3 Fix ecobee aux_heat_off always returns to HEAT (#100630) 2023-09-23 13:45:34 +02:00
Raman Gupta
08f46ad61f Adjust hassfest.manifest based on config.action (#100577) 2023-09-23 13:45:31 +02:00
Luke Lashley
9d25ca33bb Fix Roborock send command service calling not being enum (#100574) 2023-09-23 13:45:25 +02:00
Teemu R
c059b1960e Fix xiaomi_miio button platform regression (#100527) 2023-09-23 13:45:22 +02:00
Markus Friedli
0a343037a7 Fix broken reconnect capability of fritzbox_callmonitor (#100526) 2023-09-23 13:45:18 +02:00
Joost Lekkerkerker
93081bcbea Only get meteo france alert coordinator if it exists (#100493)
Only get meteo france coordinator if it exists
2023-09-23 13:45:15 +02:00
J.P. Krauss
fcd9ae5a01 Fix error is measurement is not sent by AirNow (#100477) 2023-09-23 13:45:12 +02:00
Kevin Stillhammer
13028e50ea bump pywaze to 0.5.0 (#100456) 2023-09-23 13:45:08 +02:00
Robert Resch
74dbcae92f Fix timer reload description (#100433)
Fix copy/paste error of #100388
2023-09-23 13:45:05 +02:00
Matrix
d6c365014a Bump yolink-api to 0.3.1 (#100426) 2023-09-23 13:45:02 +02:00
Diogo Gomes
ba30e6fb1c Fix current condition in IPMA (#100412)
always use hourly forecast to retrieve current weather condition. fix #100393
2023-09-23 13:44:58 +02:00
steffenrapp
3e34fc3b82 Add missing timer service translation (#100388) 2023-09-23 13:44:55 +02:00
starkillerOG
e1ab0fe295 Bump reolink-aio to 0.7.10 (#100376) 2023-09-23 13:44:52 +02:00
starkillerOG
66a1522d88 Try Reolink ONVIF long polling if ONVIF push not supported (#100375) 2023-09-23 13:44:48 +02:00
Ståle Storø Hauknes
50a41f516d Fix Airthings ble migration (#100362)
* Import Platform for tests

* Migration bugfix

* Store new unique id as a variable in tests

* Add comments to tests
2023-09-23 13:44:45 +02:00
Guido Schmitz
94ef5f751f Fix timeout issue in devolo_home_network (#100350) 2023-09-23 13:44:41 +02:00
Joakim Plate
4d1ca93973 Remove _next_refresh variable in update coordinator (#100323)
* Remove _next_refresh variable

* Adjust tomorrowio
2023-09-23 13:43:56 +02:00
Daniel Hjelseth Høyer
57cfd2ef03 Update Mill library to 0.11.5, handle rate limiting (#100315) 2023-09-23 13:42:58 +02:00
J. Nick Koston
66dbcc04eb Bump yalexs to 1.9.0 (#100305) 2023-09-23 13:40:34 +02:00
J. Nick Koston
fed7fc9597 Bump yalexs-ble to 2.3.0 (#100007) 2023-09-23 13:40:11 +02:00
Charles Garwood
ef0d8da4ce Bump pyenphase to 1.11.4 (#100288) 2023-09-23 13:37:26 +02:00
Erik Montnemery
29ba5a4292 Future proof assist_pipeline.Pipeline (#100277) 2023-09-23 13:37:23 +02:00
Aarni Koskela
9e0d23f9a8 Bump sensirion-ble to 0.1.1 (#100271)
Bump to sensirion-ble==0.1.1

Fixes akx/sensirion-ble#6

Refs https://github.com/home-assistant/core/issues/93678#issuecomment-1694522112
2023-09-23 13:37:19 +02:00
Charles Garwood
9ec6e63384 Bump pyenphase to 1.11.3 (#100255) 2023-09-23 13:37:16 +02:00
Charles Garwood
daf21d677a Bump pyenphase to 1.11.2 (#100249)
* Bump pyenphase to 1.11.1

* Apply suggestions from code review

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-23 13:37:13 +02:00
Luke Lashley
64d5993434 Fix incorrect off peak translation key for Roborock (#100246)
fix incorrect translation key
2023-09-23 13:37:09 +02:00
starkillerOG
c9bee8233e Bump pynetgear to 0.10.10 (#100242) 2023-09-23 13:37:06 +02:00
Luke Lashley
094666005e Bump python-roborock to 0.34.0 (#100236) 2023-09-23 13:37:03 +02:00
starkillerOG
d2b5ffc9fc Netgear catch no info error (#100212) 2023-09-23 13:37:00 +02:00
Diogo Gomes
f50d47121e Always update unit of measurement of the utility_meter on state change (#99102) 2023-09-23 13:36:51 +02:00
G Johansson
173b70c850 Fix weather template forecast attributes (#100748) 2023-09-23 13:30:11 +02:00
Erik Montnemery
7a1ee98bb6 Fix handling of unit system change in sensor (#100715) 2023-09-23 13:28:14 +02:00
Shay Levy
439ca60cb6 Fix Shelly Gen2 event get input name method (#100733) 2023-09-23 12:45:41 +03:00
puddly
44fd60bd53 Bump ZHA dependencies (#100732) 2023-09-23 09:53:56 +02:00
Kevin Worrel
a087ea8b3d Bump screenlogicpy to v0.9.1 (#100744) 2023-09-23 09:40:07 +02:00
Abílio Costa
2ef69d1504 Improve Idasen Desk "no devices found" message (#100742) 2023-09-23 09:37:03 +02:00
Michael Hansen
b0c9ff033e Bump intents to 2023.9.22 (#100737) 2023-09-23 02:29:00 +02:00
rappenze
ad3cd72323 Remove unneeded instance check (#100736) 2023-09-23 00:42:32 +02:00
Jan Bouwhuis
c6d62faff3 Avoid redundant calls to async_write_ha_state in mqtt cover (#100720)
Avoid redundant calls to async_write_ha_state
2023-09-22 22:47:07 +02:00
Simone Chemelli
55c6d41d41 Bump aiocomelit to 0.0.8 (#100714)
* Bump aiocomelit to 0.0.8

* fix import

* fix tests
2023-09-22 23:38:33 +03:00
Olen
debee28856 Only get state once for all August sensor-tests (#100721) 2023-09-22 21:31:17 +02:00
Simone Chemelli
964192d246 Bump aiovodafone to 0.3.0 (#100729) 2023-09-22 21:21:44 +02:00
Joost Lekkerkerker
76cc04e52b Remove obsolete methods in HVV departures (#100451)
* Call async added to hass super in HVV departures

* Remove obsolete methods
2023-09-22 16:55:07 +02:00
Olen
2a49b6ca7e Add more august actions (#100667) 2023-09-22 14:42:17 +02:00
starkillerOG
8474c25cf1 Reolink remove unneeded str() (#100718) 2023-09-22 14:20:34 +02:00
Jan Bouwhuis
4c65c92fb0 Use shorthand attrs for MQTT cover (#100710)
* User shorthand attrs for MQTT cover

* Cleanup constructor

* Cleanup constructor
2023-09-22 13:41:31 +02:00
Daniel Weeber
4133162053 Add device class to denonavr (#100711)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-22 13:39:32 +02:00
Jan Bouwhuis
5b422daf36 Avoid redundant calls to async_write_ha_state in MQTT light (#100690)
* Limit state writes for mqtt light

* Additional tests and review follow up
2023-09-22 13:32:30 +02:00
Jan Bouwhuis
87ae5add8a Fix mqtt light rgbww update without state topic (#100707)
* Fix mqtt light rgbww update without state topic

* Add @callback decprator and correct mired conv
2023-09-22 13:31:29 +02:00
Joost Lekkerkerker
d30a5f4d54 Move samsung tv device class outside of constructor (#100712) 2023-09-22 12:45:22 +02:00
Pedro Januário
794736b503 Add switch platform to ecoforest integration (#100708)
* add switch platform to ecoforest integration

* ignore switch.py from coverage

* rename mixin

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

* update translations

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

* remove translation key

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

* move attr name to description

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

* fix broken change

* use entity description action

* use lambda with awaitable

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-22 12:20:48 +02:00
Jan Bouwhuis
a66ad39c4e Assign color_mode for mqtt light as ColorMode (#100709) 2023-09-22 12:09:37 +02:00
Jan Bouwhuis
384adb1c87 Avoid redundant calls to async_write_ha_state in MQTT climate & water_heater (#100696)
Limit state writes for mqtt climate & water_heater
2023-09-22 11:22:57 +02:00
Jan Bouwhuis
1041610a70 Avoid redundant calls to async_write_ha_state in MQTT mqtt alarm_control_panel (#100691)
Limit state writes for mqtt alarm_control_panel
2023-09-22 11:22:09 +02:00
J. Nick Koston
1dadfcd52c Avoid polling in sun sensor entities (#100693) 2023-09-22 11:16:37 +02:00
Pedro Januário
86a692bb22 Add additional sensors to ecoforest integration (#100681)
* add ecoforest additional sensors

* add ecoforest additional sensors

* use StateType

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

* use StateType

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

* update cpu temp translation

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

* use common translation

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

* use common on translation

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

* use common standby translation

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

* update strings

* update strings

* import state type

* relabel preheating

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

* add cpu temp disable by default

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-22 11:08:09 +02:00
Pedro Januário
cd30286913 Add number platform to ecoforest (#100694)
* add power number entity to ecoforest integration

* fix number.py header

* minor fixes

* change power to power level

* update comment for native value prop

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

* exclude number.py from coverage

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-21 22:36:39 +02:00
Bouwe Westerdijk
5cf5f5b4cf Add missing step-differentiation for the Plugwise temperature_offset (#100654) 2023-09-21 19:31:53 +02:00
c0ffeeca7
f973d4cc26 ZHA multiprotocol detected message: add info (#100686) 2023-09-21 19:23:02 +02:00
Bouwe Westerdijk
a609df2914 Update plugwise to v0.33.0 (#100689) 2023-09-21 19:19:03 +02:00
jimmyd-be
e57156dd9c Add Renson button entity (#99494)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-21 17:55:30 +02:00
Erik Montnemery
ab060b86d1 Remove async_process_integration_platform_for_component (#100680) 2023-09-21 17:06:41 +02:00
c0ffeeca7
1c7b3cb2d5 ZHA multiprotocol detected - fix typo (#100683) 2023-09-21 17:02:39 +02:00
Luke Lashley
e2bfa9f9cd Add last clean sensors to Roborock (#100661)
* Add water shortage binary sensor

* add last clean sensors

* fix tests

* fix tests again

* remove accidentally added binary sensor
2023-09-21 16:00:15 +02:00
Luke Lashley
6e0ab35f85 Add water shortage binary sensor (#100662) 2023-09-21 15:43:17 +02:00
Jan-Philipp Benecke
a08b74c550 Move coolmaster coordinator to its own file (#100425) 2023-09-21 15:20:58 +02:00
Pedro Januário
c170babba6 Add ecoforest integration (#100647)
* Add ecoforest integration

* fix file title

* remove host default from schema, hints will be given in the documentation

* moved input validation to async_step_user

* ensure we can receive device data while doing entry setup

* remove unecessary check before unique id is set

* added shorter syntax for async create entry

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

* use variable to set unique id

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

* Use _attr_has_entity_name from base entity

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

* remove unecessary comments in coordinator

* use shorthand for device information

* remove empty objects from manifest

* remove unecessary flag

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

* use _async_abort_entries_match to ensure device is not duplicated

* remove unecessary host attr

* fixed coordinator host attr to be used by entities to identify device

* remove unecessary assert

* use default device class temperature trasnlation key

* reuse base entity description

* use device serial number as identifier

* remove unused code

* Improve logging message

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

* Remove unused errors

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

* Raise a generic update failed

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

* use coordinator directly

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

* No need to check for serial number

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

* rename variable

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

* use renamed variable

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

* improve assertion

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

* use serial number in entity unique id

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

* raise config entry not ready on setup when error in connection

* improve test readability

* Improve python syntax

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

* abort when device already configured with same serial number

* improve tests

* fix test name

* use coordinator data

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

* improve asserts

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

* fix ci

* improve error handling

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-21 15:18:55 +02:00
Erik Montnemery
df73850f56 Move definition of attributes excluded from history to entity classes (#100430)
* Move definition of attributes excluded from history to entity classes

* Revert change which should be in a follow-up PR

* Fix sun unrecorded attributes

* Fix input_select unrecorded attributes
2023-09-21 15:02:47 +02:00
Jan Bouwhuis
aed3ba3acd Avoid redundant calls to async_ha_write_state in MQTT (binary) sensor (#100438)
* Only call `async_ha_write_state` on changes.

* Make helper class

* Use UndefinedType

* Remove del

* Integrate monitor into MqttEntity

* Track extra state attributes and availability

* Add `__slots__`

* Add monitor to MqttAttributes and MqttAvailability

* Write out loop

* Add test

* Make common test and parameterize

* Add test for last_reset attribute

* MqttMonitorEntity base class

* Rename attr and update docstr `track` method.

* correction doct

* Implement as a decorator

* Move tracking functions into decorator

* Rename decorator

* Follow up comment
2023-09-21 13:33:26 +02:00
Fletcher
11c4c37cf9 Add Slack thread/reply support (#93384) 2023-09-21 11:06:55 +02:00
Robert Resch
e4742c04f2 Fix missspelled package names (#100670) 2023-09-21 10:57:23 +02:00
Mike
15caf2ac03 Add support for Levoit Vital200s purifier (#100613) 2023-09-21 10:53:18 +02:00
Jan-Philipp Benecke
715d8dcb98 Add test to london underground (#100562)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-21 10:44:32 +02:00
J. Nick Koston
59daceafd2 Avoid calling extract_stack in system_log since it does blocking I/O (#100455) 2023-09-21 09:48:41 +02:00
elmurato
f2fc62138a Clean-up Minecraft Server constants (#100666) 2023-09-21 08:40:07 +02:00
Raman Gupta
9f56aec267 Bump zwave-js-server-python to 0.51.3 (#100665) 2023-09-21 02:13:48 -04:00
anonion
5c1a3998ae Add Enmax virtual integration to Opower (#100503)
* add enmax virtual integration supported by opower

* update integrations.json
2023-09-21 06:59:05 +02:00
Luke Lashley
ed3cdca454 Bump python-roborock to 0.34.1 (#100652)
bump to 34.1
2023-09-20 22:02:00 +02:00
dependabot[bot]
0525454738 Bump tibdex/github-app-token from 2.0.0 to 2.1.0 (#100632)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-20 20:47:38 +02:00
Andrei Demian
6752af8f27 Bump ismartgate to 5.0.1 (#100636) 2023-09-20 19:44:11 +02:00
J. Nick Koston
a03ad87cfb Avoid ConfigEntry lookups in hass.config_entries.async_entries for domain index (#100598) 2023-09-20 18:43:15 +02:00
J. Nick Koston
1f0c9a48d2 Update doorbird zeroconf checks to use stdlib ipaddress methods (#100623) 2023-09-20 18:35:55 +02:00
Erik Montnemery
fbcc5318c5 Move attributes to be excluded from recording to entity classes (#100239)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-20 18:09:12 +02:00
J. Nick Koston
ec5675ff4b Fix hkid matching in homekit_controller when zeroconf value is not upper case (#100641) 2023-09-20 17:37:13 +02:00
Luke Lashley
77001b26de Add second test device for Roborock (#100565) 2023-09-20 17:17:32 +02:00
J. Nick Koston
6f8734167f Bump SQLAlchemy to 2.0.21 (#99745) 2023-09-20 16:19:53 +02:00
J. Nick Koston
8b5129a7d9 Bump dbus-fast to 2.9.0 (#100638) 2023-09-20 13:58:34 +02:00
Robin Li
7014ed3453 Fix ecobee aux_heat_off always returns to HEAT (#100630) 2023-09-20 13:53:05 +02:00
J. Nick Koston
d675825b5a Avoid double lookups with data_entry_flow indices (#100627) 2023-09-20 11:55:51 +02:00
J. Nick Koston
06c7f0959c Update dhcp to use stdlib ipaddress methods (#100625) 2023-09-20 11:54:24 +02:00
J. Nick Koston
33f748493e Update enphase_envoy zeroconf checks to use stdlib ipaddress methods (#100624) 2023-09-20 09:49:16 +02:00
Jan-Philipp Benecke
7af62c35f5 Move faa_delays coordinator to its own file (#100548) 2023-09-20 08:59:49 +02:00
Jan-Philipp Benecke
03af467918 Move renson coordinator to its own file (#100610) 2023-09-20 08:47:20 +02:00
Abílio Costa
bd9bab000e Add integration for IKEA Idasen Desk (#99173)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-20 02:44:35 +02:00
J. Nick Koston
6c095a963d Switch config flows use newer zeroconf methods to check IP Addresses (#100568) 2023-09-20 01:08:58 +02:00
J. Nick Koston
1d5905b591 Use is for UNDEFINED check in async_update_entry (#100599) 2023-09-20 01:08:32 +02:00
elmurato
f1a70189ac Clean-up Minecraft Server tests (#100615)
Remove patching of getmac, fix typo
2023-09-19 22:14:21 +02:00
Maciej Bieniek
c099ec19f2 Add missing translations for Shelly event type states (#100608)
Add missing translations for event type
2023-09-19 20:30:18 +02:00
J. Nick Koston
0eca433004 Update zeroconf discovery to use IPAddress objects to avoid conversions (#100567) 2023-09-19 18:58:46 +02:00
Joost Lekkerkerker
8dd3d6f989 Call async added to hass super in Livisi (#100446) 2023-09-19 17:40:55 +02:00
Raman Gupta
2ad0fd1ce1 Adjust hassfest.manifest based on config.action (#100577) 2023-09-19 17:30:38 +02:00
Teemu R
7c4f08e6b3 Fix xiaomi_miio button platform regression (#100527) 2023-09-19 17:15:43 +02:00
Ian
c3f74ae022 Add config-flow to NextBus (#92149) 2023-09-19 17:10:29 +02:00
Joost Lekkerkerker
d9227a7e3d Add Spotify code owner (#100597) 2023-09-19 16:43:00 +02:00
Luke Lashley
ea78f419a9 Fix Roborock send command service calling not being enum (#100574) 2023-09-19 16:35:23 +02:00
elmurato
a2a62839bc Add DataUpdateCoordinator to Minecraft Server (#100075) 2023-09-19 15:59:58 +02:00
Jan-Philipp Benecke
2b8690d8bc Remove platform const in co2signal coordinator (#100592) 2023-09-19 12:44:09 +02:00
Joost Lekkerkerker
11a90016d0 Change Hue zigbee connectivity sensor into an enum (#98632) 2023-09-19 12:08:13 +02:00
Joost Lekkerkerker
f01c71e514 Fix lyric feedback (#100586) 2023-09-19 11:40:05 +02:00
Jan-Philipp Benecke
cf6eddee74 Move uptimerobot coordinator to its own file (#100558)
* Move uptimerobot coordinator to its own file

* Fix import of coordinator in platforms
2023-09-19 09:45:56 +02:00
Simone Chemelli
2722e5ddaa Add Vodafone Station sensor platform (#99948)
* Vodafone: add sensor platform

* fix for model VOX30 v1

* fix, cleanup, 2 new sensors

* apply review comments

* apply last review comment
2023-09-18 21:31:04 +02:00
Marc Mueller
37288d7788 Add pylint plugin to check for calls to base implementation (#100432) 2023-09-18 13:39:36 -05:00
rappenze
ddd62a8f63 Fibaro streamline hass.data entry (#100547)
* Fibaro streamline hass.data entry

* Fix tests
2023-09-18 20:22:23 +02:00
J. Nick Koston
fa1a1715c9 Drop codeowner for LIFX (#100556) 2023-09-18 10:08:49 -05:00
J. Nick Koston
49d742ce31 Drop codeowner for Magic Home/flux_led (#100557) 2023-09-18 10:08:38 -05:00
Jan-Philipp Benecke
adf34bdf8b Set co2signal integration type to service (#100543) 2023-09-18 12:56:35 +02:00
Joost Lekkerkerker
ec6c374761 Clean up lyric sensor platform (#100495)
* Clean up lyric sensor platform

* Clean up lyric sensor platform

* Clean up lyric sensor platform

* Update homeassistant/components/lyric/sensor.py

Co-authored-by: Aidan Timson <aidan@timmo.dev>

* Update homeassistant/components/lyric/sensor.py

Co-authored-by: Aidan Timson <aidan@timmo.dev>

* Update homeassistant/components/lyric/sensor.py

Co-authored-by: Aidan Timson <aidan@timmo.dev>

* Update homeassistant/components/lyric/sensor.py

Co-authored-by: Aidan Timson <aidan@timmo.dev>

---------

Co-authored-by: Aidan Timson <aidan@timmo.dev>
2023-09-18 12:42:31 +02:00
jan iversen
6ac1305c64 Adjust codeowners in modbus (#100474) 2023-09-18 12:39:09 +02:00
Marc Mueller
306f39b053 Update pytest warnings filter (#100546) 2023-09-18 12:26:16 +02:00
Marc Mueller
08c4e82cf9 Update typing-extensions to 4.8.0 (#100545) 2023-09-18 11:58:47 +02:00
Jan-Philipp Benecke
dc2afb71ae Move co2signal coordinator to its own file (#100541)
* Move co2signal coordinator to its own file

* Fix import
2023-09-18 11:56:28 +02:00
steffenrapp
45c0dc6854 Add missing conversation service translation (#100308)
* Update services.yaml

* Update strings.json

* Update services.yaml

* Update strings.json

* Update strings.json

* fix translation keys

* Fix translation keys
2023-09-18 11:44:41 +02:00
Ville Skyttä
902f997ee0 Fix google invalid token expiry test init for UTC offsets > 0 (#100533)
```
$ python3 -q
>>> import datetime, time
>>> time.tzname
('EET', 'EEST')
>>> datetime.datetime.max.timestamp()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: year 10000 is out of range
```
2023-09-18 12:39:43 +03:00
Marc Mueller
f41e3a2beb Remove duplicate mobile_app client fixture (#100530) 2023-09-18 10:52:43 +02:00
Glenn Waters
276d245409 Bump elkm1-lib to 2.2.6 (#100537) 2023-09-17 20:39:23 -05:00
Maciej Bieniek
f6243a1f79 Add event platform for Shelly gen2 devices (#99659)
* Add event platform for gen2 devices

* Add tests

* Add removal condition

* Simplify RpcEventDescription; fix availability

* Improve names and docstrings

* Improve the event entity name

* Use async_on_remove()

* Improve tests coverage

* Improve tests coverage

* Prefix the entity name with the device name in the old way

* Black

* Use DeviceInfo object
2023-09-18 00:38:08 +02:00
Marc Mueller
6acb182c38 Fix full black run condition [ci] (#100532) 2023-09-17 17:05:29 -05:00
starkillerOG
868afc037e Try Reolink ONVIF long polling if ONVIF push not supported (#100375) 2023-09-17 22:28:52 +02:00
Markus Friedli
dd1dc52994 Fix broken reconnect capability of fritzbox_callmonitor (#100526) 2023-09-17 20:00:09 +02:00
Ville Skyttä
2794ab1782 Fix huawei_lte current month up/download sensor error on delete (#100506)
Deleting one of them prematurely deleted the last reset item
subscription that is shared between the two.
2023-09-17 18:11:44 +02:00
tronikos
7aa02b8621 Bump opower to 0.0.34 (#100501) 2023-09-17 09:50:17 -05:00
Marc Mueller
48f9a38c74 Update numpy to 1.26.0 (#100512) 2023-09-17 09:49:21 -05:00
Dennis
ddeb2854aa Added device class to speedtestdotnet sensor entities. (#100500)
Added device class to sensor entities.
2023-09-16 15:40:16 -07:00
jan iversen
9931f45532 Deprecate modbus parameter retry_on_empty (#100292) 2023-09-16 21:14:52 +02:00
Jieyu Yan
81af45347f Add fan modes in Lyric integration (#100420)
* Add fan modes in Lyric integration

* add fan_mode only when available

* move supported_features to init

* mapped fan_modes to built-in modes

* log KeyError for fan_modes
2023-09-16 20:58:00 +02:00
Joost Lekkerkerker
f715f5c76f Only get meteo france alert coordinator if it exists (#100493)
Only get meteo france coordinator if it exists
2023-09-16 18:48:41 +02:00
J.P. Krauss
01ecef7f05 Fix error is measurement is not sent by AirNow (#100477) 2023-09-16 18:16:15 +02:00
Kevin
c8265a86b2 Bump python-androidtv to 0.0.72 (#100441)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-16 10:12:00 -05:00
J. Nick Koston
8a98a0e830 Avoid writing unifiprotect state when nothing has changed (#100439) 2023-09-16 09:57:43 -05:00
Joost Lekkerkerker
7b71d27637 Pass function correctly to Withings API (#100391)
* Pass function correctly to Withings API

* Add more typing
2023-09-16 16:20:24 +02:00
Ravaka Razafimanantsoa
f99dedfb42 Add switchbot cloud integration (#99607)
* Switches via API

* Using external library

* UT and checlist

* Updating file .coveragerc

* Update homeassistant/components/switchbot_via_api/switch.py

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

* Update homeassistant/components/switchbot_via_api/switch.py

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

* Update homeassistant/components/switchbot_via_api/switch.py

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

* Review fixes

* Apply suggestions from code review

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

* This base class shouldn't know about Remote

* Fixing suggestion

* Sometimes, the state from the API is not updated immediately

* Review changes

* Some review changes

* Review changes

* Review change: Adding type on commands

* Parameterizing some tests

* Review changes

* Updating .coveragerc

* Fixing error handling in coordinator

* Review changes

* Review changes

* Adding switchbot brand

* Apply suggestions from code review

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

* Review changes

* Adding strict typing

* Removing log in constructor

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-16 16:00:41 +02:00
jan iversen
568974fcc4 Modbus 100% test coverage (again) (#100482) 2023-09-16 14:00:22 +02:00
jan iversen
48dc81eff0 Simplify code, due to better error catching in modbus. (#100483) 2023-09-16 13:49:37 +02:00
Joost Lekkerkerker
30d604c851 Use central logger in Withings (#100406) 2023-09-16 13:46:11 +02:00
Jan-Philipp Benecke
16cc87bf45 Move flipr base entity to its own file (#100481)
* Move flipr base entity to its own file

* Add forgotten __init__.py
2023-09-16 11:55:49 +02:00
Jan-Philipp Benecke
b5c6e82374 Move co2signal models to their own file (#100478) 2023-09-16 11:49:49 +02:00
Jan-Philipp Benecke
57337b5cee Move flipr coordinator to its own file (#100467) 2023-09-16 11:19:49 +02:00
Jan-Philipp Benecke
024db6dadf Move cert_expiry coordinator to its own file (#100472)
* Move cert_expiry coordinator to its own file

* Add missing patched config flow test
2023-09-16 11:19:05 +02:00
Jan-Philipp Benecke
c504ca906d Move co2signal exceptions to their own file (#100473)
* Move co2signal exceptions to their own file

* Add myself as codeowner
2023-09-16 11:18:19 +02:00
Jan Bouwhuis
9747e0091f Use shorthand attrs for device_class zwave_js sensor (#100414)
* Use shorthand attrs zwave_js sensor

* Simplify
2023-09-16 10:13:27 +02:00
jan iversen
d25f45a957 Harden modbus against lib errors (#100469) 2023-09-16 09:57:55 +02:00
Joost Lekkerkerker
a111988232 Make codespell ignore snapshots (#100463) 2023-09-15 20:39:14 +02:00
J. Nick Koston
a4e0444b95 Bump sense-energy to 0.12.2 (#100459) 2023-09-15 13:38:14 -05:00
Kevin Stillhammer
c9975852bb bump pywaze to 0.5.0 (#100456) 2023-09-15 19:03:04 +02:00
Matrix
06949b181f Bump yolink-api to 0.3.1 (#100426) 2023-09-15 17:20:30 +02:00
jan iversen
fd83f7d87f Add test for modbus CONF_DEVICE_ADDR (#100435) 2023-09-15 16:12:44 +02:00
Robert Resch
b329439fff Fix timer reload description (#100433)
Fix copy/paste error of #100388
2023-09-15 16:05:56 +02:00
jan iversen
9eb0b844bc Test VIRTUAL_COUNT parameter (#100434) 2023-09-15 15:02:24 +02:00
steffenrapp
b4c095e944 Add missing timer service translation (#100388) 2023-09-15 14:42:27 +02:00
Seth
5ac149a760 Remove state class from RainMachine TIMESTAMP sensors (#100400) 2023-09-15 14:33:17 +02:00
jan iversen
ec2364ef43 Add virtual_count == slave_count in modbus configuration (#100398)
* Add virtual_count as config parameter.

* Review (other PR) comments.

* Review.

* Review comment.
2023-09-15 14:00:02 +02:00
jan iversen
c173ebd11a Add device_address to modbus configuration (#100399) 2023-09-15 13:49:33 +02:00
Joost Lekkerkerker
1737b27dd4 Generate withings webhook ID in config flow (#100395) 2023-09-15 12:58:56 +02:00
Erik Montnemery
d1afcd773f Revert "Cache entity properties that are never expected to change in the base class" (#100422)
Revert "Cache entity properties that are never expected to change in the base class (#95315)"

This reverts commit 042776ebb8.
2023-09-15 11:25:24 +02:00
Jan-Philipp Benecke
7723a9b36b Move airtouch4 coordinator to its own file (#100424) 2023-09-15 10:04:41 +02:00
TJ Horner
a8013836e1 Bump apple_weatherkit to 1.0.3 (#100416) 2023-09-15 08:28:27 +02:00
Erik Montnemery
a70235046a Tweak datetime service schema (#100380) 2023-09-15 08:07:27 +02:00
Diogo Gomes
9470c71d49 Fix current condition in IPMA (#100412)
always use hourly forecast to retrieve current weather condition. fix #100393
2023-09-15 07:52:50 +02:00
Jan-Philipp Benecke
772ac9766b Move awair coordinators to their own file (#100411)
* Move awair coordinators to their file

* Add awair/coordinator.py to .coveragerc
2023-09-15 07:52:29 +02:00
J. Nick Koston
b68ceb3ce4 Use more shorthand attributes in hyperion (#100213)
* Use more shorthand attributes in hyperion

There are likely some more here, but I only did the safe ones

* Update homeassistant/components/hyperion/switch.py

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

* Apply suggestions from code review

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-15 02:28:59 +00:00
J. Nick Koston
6a9c9ca735 Improve performance of mqtt_room (#100408) 2023-09-14 17:55:56 -05:00
J. Nick Koston
042776ebb8 Cache entity properties that are never expected to change in the base class (#95315) 2023-09-14 17:48:48 -05:00
Joakim Plate
5f20725fd5 Remove _next_refresh variable in update coordinator (#100323)
* Remove _next_refresh variable

* Adjust tomorrowio
2023-09-14 22:32:50 +02:00
J. Nick Koston
df74ed0d40 Bump bleak-retry-connector to 3.2.1 (#100377) 2023-09-14 15:13:15 -05:00
Jan Bouwhuis
23faa0882f Avoid multiline ternary use (#100381) 2023-09-14 22:10:28 +02:00
Joost Lekkerkerker
c34c4f8f03 Reload on Withings options flow update (#100397)
* Reload on Withings options flow update

* Remove reload from reauth
2023-09-14 21:54:49 +02:00
Jan-Philipp Benecke
157647dc44 Move solarlog coordinator to own file (#100402) 2023-09-14 21:52:21 +02:00
Joost Lekkerkerker
a62f16b4cc Remove obsolete strings from Withings (#100396) 2023-09-14 21:41:34 +02:00
starkillerOG
3f2a660dab Bump reolink-aio to 0.7.10 (#100376) 2023-09-14 21:24:23 +02:00
Robert Svensson
f909199125 Remove hard coded Icon from Unifi device scanner (#100401) 2023-09-14 20:13:46 +02:00
J. Nick Koston
1d4b731603 Bump zeroconf to 0.112.0 (#100386) 2023-09-14 12:40:47 -05:00
Jan Bouwhuis
6701a449bd Use shorthand attrs for tasmota (#100390) 2023-09-14 18:17:23 +02:00
Jan Bouwhuis
8b7061b634 Short handed device class for overkiz cover (#100394) 2023-09-14 11:10:31 -05:00
Jan Bouwhuis
89eec9990b Use shorthand device_type attr for plaato sensors (#100385) 2023-09-14 09:55:47 -05:00
jan iversen
d4a2927ebe Solve racing problem in modbus test (#100287)
* Test racing problem.

* review comment.

* Revert to approved state.

This reverts commit 983d9d68e8.
2023-09-14 16:03:32 +02:00
starkillerOG
7ea2087c45 Add Netgear entity translations (#100367)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-14 13:58:53 +02:00
Joost Lekkerkerker
6fc1407613 Extract Withings API specifics in own class (#100363)
* Extract Withings API specifics in own class

* Extract Withings API specifics in own class

* Ignore api test coverage

* fix feedback
2023-09-14 13:31:54 +02:00
Ståle Storø Hauknes
b858658516 Fix Airthings ble migration (#100362)
* Import Platform for tests

* Migration bugfix

* Store new unique id as a variable in tests

* Add comments to tests
2023-09-14 12:51:06 +02:00
Guido Schmitz
8a8f1aff83 Remove useless timeout guards in devolo_home_network (#100364) 2023-09-14 12:35:21 +02:00
Jan Rieger
f305661dd7 Change service set_location to use number input selectors (#100360) 2023-09-14 12:13:19 +02:00
starkillerOG
98c9edc00c Netgear cleanup (#99505)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-14 12:06:40 +02:00
Guido Schmitz
b84076d3d6 Fix timeout issue in devolo_home_network (#100350) 2023-09-14 10:28:45 +02:00
Franck Nijhof
b0f32a3547 Update apprise to 1.5.0 (#100351) 2023-09-14 10:10:31 +02:00
Erik Montnemery
4f58df1929 Drop useless passing of update_method to DataUpdateCoordinator (#100355) 2023-09-14 10:09:55 +02:00
Franck Nijhof
85fafcad11 Update awesomeversion to 23.8.0 (#100349) 2023-09-14 10:07:09 +02:00
Joost Lekkerkerker
4a48a92cba Use f-string instead of concatenation in Velux (#100353) 2023-09-14 10:06:43 +02:00
Jan Rieger
840d881c25 Add icon to GPSD (#100347) 2023-09-14 09:27:16 +02:00
Joost Lekkerkerker
923d945267 Use shorthand attributes in Smappee (#99837) 2023-09-14 09:25:21 +02:00
Marty Sun
6692a37f0d Add missing __init__.py file in yardian test folder (#100345) 2023-09-14 09:04:12 +02:00
J. Nick Koston
182976f5d3 Use more shorthand attributes in threshold binary_sensor (#100343) 2023-09-14 09:03:39 +02:00
J. Nick Koston
58bb624b24 Bump zeroconf to 0.111.0 (#100340) 2023-09-14 07:54:17 +02:00
mkmer
c265d3f3cc Late review for honeywell (#100299)
* Late review for honeywell

* Actually test same id different domain

* Update homeassistant/components/honeywell/climate.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update climate.py

* Refactor dont_remove

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-14 06:22:28 +02:00
J. Nick Koston
547f32818c Make core States use cached_property (#100312)
Need to validate this is worth removing __slots__
2023-09-13 20:33:25 -04:00
J. Nick Koston
3cc9410a62 Bump grpcio to 1.58.0 (#100314)
* Bump grpcio to 1.58.0

attempt to fix nightly

https://github.com/home-assistant/core/actions/runs/6167125867/job/16737677629

```
```

* forgot the script as well
2023-09-13 20:26:55 -04:00
J. Nick Koston
3be4edd647 Use shorthand attributes in saj (#100317)
supports #95315
2023-09-13 20:26:22 -04:00
J. Nick Koston
fe8156f013 Bump protobuf to 4.24.3 (#100329)
changelog: https://github.com/protocolbuffers/protobuf/compare/v24.0...v24.3
2023-09-13 20:25:52 -04:00
J. Nick Koston
f0e607869a Use shorthand attributes for supla cover device class (#100337)
from #95315
2023-09-13 20:25:33 -04:00
Jan Bouwhuis
01410c9fbb Shorthanded attrs for met integration (#100334) 2023-09-13 17:11:47 -05:00
Jan Bouwhuis
a7c6abfed1 Use shorthand atts for met_eireann (#100335) 2023-09-13 17:11:27 -05:00
Franck Nijhof
a02fcbc5c4 Update sentry-sdk to 1.31.0 (#100293) 2023-09-13 23:37:48 +02:00
J. Nick Koston
fe5eba9b31 Use cached_property in device registry (#100309) 2023-09-13 15:36:07 -05:00
Jan-Philipp Benecke
72f5c0741b Add missing sms coordinator to .coveragerc (#100327) 2023-09-13 15:29:16 -05:00
J. Nick Koston
ef6d77586a Bump python-amcrest to 1.9.8 (#100324) 2023-09-13 15:01:28 -05:00
Jan-Philipp Benecke
7b204ca36b Use snapshot assertion for nexia diagnostics test (#100328) 2023-09-13 15:00:29 -05:00
J. Nick Koston
877eedf6d7 Use cached_property in entity_registry (#100302) 2023-09-13 14:38:40 -05:00
J. Nick Koston
d8d756dd7d Bump dbus-fast to 2.7.0 (#100321) 2023-09-13 14:33:42 -05:00
Daniel Hjelseth Høyer
9ceeadc715 Update Mill library to 0.11.5, handle rate limiting (#100315) 2023-09-13 21:09:29 +02:00
Quentame
8625bf7894 Add some tests to Freebox (#99755) 2023-09-13 20:22:47 +02:00
J. Nick Koston
9631c0ba2b Use short hand attributes in onvif camera (#100319)
see #95315
2023-09-13 20:19:01 +02:00
Robert Svensson
7b00265cfe Remove legacy UniFi PoE client clean up (#100318) 2023-09-13 20:14:03 +02:00
Paulus Schoutsen
23a891ebb1 Update Roborock entity categories (#100316) 2023-09-13 13:43:28 -04:00
Jan Bouwhuis
0d33cba823 Use shorthand attrs in template integration (#100301) 2023-09-13 12:30:43 -05:00
Franck Nijhof
d17957ac1a Update debugpy to 1.8.0 (#100311) 2023-09-13 11:59:35 -05:00
J. Nick Koston
6a2dd4fe74 Bump yalexs to 1.9.0 (#100305) 2023-09-13 11:25:10 -05:00
Erik Montnemery
c3d1cdd0e9 Improve UserDict in device and entity registries (#100307) 2023-09-13 11:09:34 -05:00
Jan Rieger
ee65aa91e8 Allow setting the elevation in set_location (#99978)
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2023-09-13 18:09:12 +02:00
Joost Lekkerkerker
f6b094dfee Add options flow to Withings (#100300) 2023-09-13 18:08:15 +02:00
Erik Montnemery
6057fe5926 Replace StateMachine._domain_index with a UserDict (#100270)
* Replace StateMachine._domain_index with a UserDict

* Access the UserDict's backing dict directly

* Optimize
2023-09-13 18:05:17 +02:00
J. Nick Koston
d0feb063ec Fix missing super async_added_to_hass in lookin (#100296) 2023-09-13 10:03:36 -05:00
Jan Bouwhuis
871800778f Use shorthand attrs for velux (#100294)
* Use shorthand attrs for velux

* Update homeassistant/components/velux/cover.py

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

* black

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-13 16:50:33 +02:00
Jan Bouwhuis
f2f45380a9 Use shorthand attrs in iaqualink (#100281)
* Use shorthand attrs in iaqualink

* Use super

* Update homeassistant/components/iaqualink/light.py

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

* Remove self

* More follow ups

* Remove cast and type check

* Update homeassistant/components/iaqualink/__init__.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-13 16:34:14 +02:00
Charles Garwood
c3a7aee48e Bump pyenphase to 1.11.4 (#100288) 2023-09-13 16:04:34 +02:00
Joost Lekkerkerker
8498cdfb3c Remove profile from Withings config flow (#100202)
* Remove profile from Withings config flow

* Add config flow migration

* Add config flow migration

* Remove datamanager profile

* Remove datamanager profile

* Add manufacturer

* Remove migration

* Remove migration

* Fix feedback
2023-09-13 15:49:36 +02:00
starkillerOG
80aa19263b Netgear catch no info error (#100212) 2023-09-13 15:32:03 +02:00
Jan Bouwhuis
d44db6ee68 Use shorthand attrs for xbox base_sensor (#100290) 2023-09-13 15:10:35 +02:00
Franck Nijhof
65c9e5ee13 Update mutagen to 1.47.0 (#100284) 2023-09-13 14:40:27 +02:00
Franck Nijhof
afa0152261 Update syrupy to 4.5.0 (#100283) 2023-09-13 14:40:01 +02:00
Joost Lekkerkerker
38e013a90e Remove NZBGet configurable scan interval (#98869) 2023-09-13 14:15:40 +02:00
Jan Bouwhuis
d638efdcfc Use shorthanded attrs for vera sensor (#100269)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2023-09-13 13:50:00 +02:00
Jan Bouwhuis
9f3b1a8d44 Use hass.loop.create_future() in zha (#100056)
* Use hass.loop.create_future() in zha

* Remove not needed method
2023-09-13 13:32:00 +02:00
Kevin Stillhammer
958b923783 Limit waze_travel_time to 1 call every 0.5s (#100191) 2023-09-13 13:29:20 +02:00
Jan-Philipp Benecke
1f1411b6a5 Move sms coordinators to their own file (#100276) 2023-09-13 13:22:37 +02:00
Jan Bouwhuis
705ee3032b Use shorthanded attrs for yamaha_musiccast select (#100273) 2023-09-13 13:13:27 +02:00
Olen
7fe78fe9e4 Add diagnostics to Twinkly (#100146) 2023-09-13 13:09:57 +02:00
Erik Montnemery
684b2d4537 Improve type hint in entity_registry (#100278) 2023-09-13 12:42:06 +02:00
Erik Montnemery
4f8e28a781 Future proof assist_pipeline.Pipeline (#100277) 2023-09-13 12:41:28 +02:00
Joost Lekkerkerker
29d8be510e Test speedtest.net config entry lifecycle (#100280) 2023-09-13 12:40:26 +02:00
Erik Montnemery
aedd06b9a9 Tweak entity/source WS command handler (#100272) 2023-09-13 11:14:01 +02:00
Aarni Koskela
e5de7eacad Bump sensirion-ble to 0.1.1 (#100271)
Bump to sensirion-ble==0.1.1

Fixes akx/sensirion-ble#6

Refs https://github.com/home-assistant/core/issues/93678#issuecomment-1694522112
2023-09-13 10:21:55 +02:00
dependabot[bot]
1c10091d62 Bump docker/login-action from 2.2.0 to 3.0.0 (#100264)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-13 09:34:45 +02:00
TJ Horner
dd95b51d10 Address weatherkit late review comments (#100265)
* Address review comments from original weatherkit PR

* Use .get() for optional fields
2023-09-13 09:22:58 +02:00
John Hollowell
e87603aa59 Correct Venstar firmware version to use device's FW version instead of API version (#98493) 2023-09-13 08:35:59 +02:00
Luke Lashley
09f58ec396 Bump python-roborock to 0.34.0 (#100236) 2023-09-13 08:33:48 +02:00
TJ Horner
756f542ac6 Update apple_weatherkit to 1.0.2 (#100254) 2023-09-13 08:18:07 +02:00
Charles Garwood
270df003fe Bump pyenphase to 1.11.3 (#100255) 2023-09-13 08:15:33 +02:00
Marc Mueller
f5aa2559d7 Fix pylint config warning (#100251) 2023-09-13 08:14:01 +02:00
Marc Mueller
2518fbc973 Update jsonpath to 0.82.2 (#100252) 2023-09-13 01:41:50 +02:00
Simone Chemelli
fe85b20502 SamsungTV: Add unique_id for when missing (legacy models) (#96829)
* Add unique_id for when missing (legacy models)

* add comment

* update tests, thx @epenet
2023-09-13 01:24:49 +02:00
Luke Lashley
5272387bd3 Fix incorrect off peak translation key for Roborock (#100246)
fix incorrect translation key
2023-09-13 01:16:31 +02:00
Charles Garwood
f344000ef9 Bump pyenphase to 1.11.2 (#100249)
* Bump pyenphase to 1.11.1

* Apply suggestions from code review

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-13 00:17:29 +02:00
J. Nick Koston
bbcae19d0e Disable always responding to all SSDP M-SEARCH requests with the root device (#100224) 2023-09-12 17:15:13 -05:00
starkillerOG
8aa689ebae Bump pynetgear to 0.10.10 (#100242) 2023-09-12 23:36:44 +02:00
J. Nick Koston
fc75172d79 Bump async-upnp-client to 0.35.1 (#100248) 2023-09-12 16:35:39 -05:00
Joost Lekkerkerker
904913c1a6 Use shorthand attributes in VLC telnet (#99916)
* Use shorthand attributes in VLC telnet

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* fix mypy

* Attempt 3

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-12 22:37:51 +02:00
J. Nick Koston
1b40a56e2b Update ecobee zeroconf/homekit discovery (#100091) 2023-09-12 22:24:38 +02:00
Ville Skyttä
fa0b999d08 Upgrade ruff to 0.0.289 (#100238) 2023-09-12 22:22:10 +02:00
Jan Rieger
f2fac40019 Add strict typing to GPSD (#100030)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2023-09-12 22:21:58 +02:00
Jan Bouwhuis
e3837cd1e0 Use shorthand attr for mqtt assumed_state (#100241) 2023-09-12 22:21:13 +02:00
Paulus Schoutsen
c6ed235010 2023.9.2 (#100223) 2023-09-12 15:41:50 -04:00
Jan Bouwhuis
eb0ab3de93 User shorthand attr for mqtt alarm_control_panel (#100234) 2023-09-12 21:28:29 +02:00
Joost Lekkerkerker
458a3f0df2 Remove restore functionality in Speedtest.net (#96950) 2023-09-12 21:12:01 +02:00
Tom Harris
f9ce315d1b Support for Insteon 4 button KeypadLink device (#100132) 2023-09-12 21:10:40 +02:00
Álvaro Fernández Rojas
d417a27c85 Add meteoclimatic sensor statistics (#100186) 2023-09-12 21:08:58 +02:00
Allen Porter
368a1a944a Remove the uniqueid from todoist (#100206) 2023-09-12 21:08:13 +02:00
Erik Montnemery
bbcbb2e322 Improve Entity._suggest_report_issue (#100204) 2023-09-12 21:07:32 +02:00
Joost Lekkerkerker
76c569c62d Clean up variables in Soundtouch (#99859) 2023-09-12 21:00:05 +02:00
J. Nick Koston
5e2bf2b015 Set dynalite cover device class in constructor (#100232) 2023-09-12 20:57:57 +02:00
Joost Lekkerkerker
8fe5a5a398 Introduce base class for Trafikverket camera (#100114)
* Introduce base class for Trafikverket camera

* fix feedback

* Fix feedback
2023-09-12 20:48:47 +02:00
Erik Montnemery
09ad1a9a36 Remove unnecessary block use of pylint disable in components p-z (#100192) 2023-09-12 20:47:48 +02:00
Jan Bouwhuis
5fcb69e004 Use shorthanded attributes for MQTT cover (#100230) 2023-09-12 13:46:43 -05:00
Erik Montnemery
51576b7214 Improve typing of entity.entity_sources (#99407)
* Improve typing of entity.entity_sources

* Calculate entity info source when generating WS response

* Adjust typing

* Update tests
2023-09-12 20:41:26 +02:00
J. Nick Koston
cc252f705f Use short handle attributes for device class in netatmo cover (#100228) 2023-09-12 13:34:50 -05:00
mkmer
693a271e40 Clean up device registry for climate devices that no longer exist in Honeywell (#100072) 2023-09-12 20:29:47 +02:00
Joost Lekkerkerker
9672cdf3a9 Add entity translations to WLED (#99056) 2023-09-12 20:19:45 +02:00
J. Nick Koston
70c6bceaee Use short hand entity_registry_enabled_default in nws (#100227)
* Use short hand entity_registry_enabled_default in nws

see https://github.com/home-assistant/core/pull/95315

* Update homeassistant/components/nws/sensor.py
2023-09-12 20:12:14 +02:00
dependabot[bot]
93f3bc6c2b Bump sigstore/cosign-installer from 3.1.1 to 3.1.2 (#99563)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-12 20:11:12 +02:00
James Chaloupka
a9891e40fd Update Deprecated Selector Syntax (#99308) 2023-09-12 20:10:32 +02:00
Joost Lekkerkerker
69ac8a0a2b Use shorthand attributes in NWS (#99620) 2023-09-12 13:05:57 -05:00
J. Nick Koston
9c775a8a24 Set roku media player device class in constructor (#100225) 2023-09-12 12:58:20 -05:00
J. Nick Koston
42c35da818 Use more shorthand properties in homematicip_cloud (#100210) 2023-09-12 19:45:53 +02:00
J. Nick Koston
6a7d5a0fd4 Use more shorthand attributes in huawei_lte binary_sensor (#100211) 2023-09-12 19:45:44 +02:00
Jan Rieger
74a57e8676 Use more common translations (#100135) 2023-09-12 19:44:31 +02:00
uvjustin
5021c69886 Update Stream logging on EVENT_LOGGING_CHANGED (#99256) 2023-09-12 19:38:11 +02:00
J. Nick Koston
8af7475f73 Set TriggerBaseEntity device_class in init (#100216) 2023-09-12 19:36:56 +02:00
hahn-th
f5c0c7bf27 Bump homematicip_cloud to 1.0.15 (#99387) 2023-09-12 19:33:42 +02:00
Erik Montnemery
44af34083b Remove unnecessary pylint disable in tado (#100196) 2023-09-12 19:27:53 +02:00
Joost Lekkerkerker
a09372590f Use shorthand attributes in Smartthings (#100215) 2023-09-12 12:26:33 -05:00
Paulus Schoutsen
583ea2fed4 Bumped version to 2023.9.2 2023-09-12 13:01:31 -04:00
Joakim Sørensen
7b9ae6755a Bump hass-nabucasa from 0.70.0 to 0.71.0 (#100193)
Bump hass-nabucasa from 0.70.0 to 0.71.1
2023-09-12 13:01:31 -04:00
Jan Bouwhuis
e84a4661b0 Add intial property to imap_content event data (#100171)
* Add initial property to imap event data

* Simplify loop

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

* MyPy

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-12 18:54:32 +02:00
René Klomp
86bccf769e Add Entity Descriptions to SMA integration (#58707)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-12 11:30:55 -05:00
Jan Bouwhuis
63647d96dd Fix entity name attribute on mqtt entity is not removed on update (#100187)
Fix entity name attribute is not remove on update
2023-09-12 12:04:56 -04:00
Vincent Knoop Pathuis
f13ce5daff Bump Ultraheat to version 0.5.7 (#100172) 2023-09-12 12:04:55 -04:00
Erik Montnemery
1b494fb4ba Bump hatasmota to 0.7.3 (#100169) 2023-09-12 12:04:54 -04:00
Erik Montnemery
3c27283fc1 Adjust tasmota sensor device class and icon mapping (#100168) 2023-09-12 12:04:53 -04:00
Raman Gupta
1cd80c5b78 Bump zwave-js-server-python to 0.51.2 (#100159) 2023-09-12 12:04:52 -04:00
puddly
68b0f05758 Bump ZHA dependencies (#100156) 2023-09-12 12:04:51 -04:00
Michael
d1bc6df14f Fix AVM Fritz!Tools update entity (#100151)
* move update entity to coordinator

* fix tests
2023-09-12 12:04:50 -04:00
Robert Svensson
5068846fc9 Fix devices not always reporting IP - bump aiounifi to v62 (#100149) 2023-09-12 12:04:49 -04:00
Bram Kragten
04549925c2 Update frontend to 20230911.0 (#100139) 2023-09-12 12:04:48 -04:00
Erik Montnemery
8e2fa67cfd Bump hatasmota to 0.7.2 (#100129) 2023-09-12 12:04:47 -04:00
Erik Montnemery
7a4a792b7b Fix TriggerEntity.async_added_to_hass (#100119) 2023-09-12 12:04:45 -04:00
Greig Sheridan
df718ca509 Remove duplicated word in enphase description text (#100098) 2023-09-12 12:04:44 -04:00
Mike Degatano
2cb84274ec Fix addon slug validation (#100070)
* Fix addon slug validation

* Don't redefine compile
2023-09-12 12:04:43 -04:00
Simone Chemelli
55a4346460 Remove Comelit alarm data retrieval (#100067)
fix: remove alarm data retrieval
2023-09-12 12:04:42 -04:00
Simone Chemelli
a651e9df1d Bump aiovodafone to 0.2.0 (#100062)
bump aiovodafone to 0.2.0
2023-09-12 12:04:41 -04:00
Aidan Timson
a19bc71300 Bump systembridgeconnector to 3.8.2 (#100051)
Update systembridgeconnector to 3.8.2
2023-09-12 12:04:40 -04:00
Kevin Stillhammer
82a5615d7d Bump pywaze to 0.4.0 (#99995)
bump pywaze from 0.3.0 to 0.4.0
2023-09-12 12:04:39 -04:00
jan iversen
42f62485cf Bump pymodbus to v3.5.2 (#99988) 2023-09-12 12:04:38 -04:00
J. Nick Koston
3d09e859fc Avoid probing ipp printers for unique_id when it is available via mdns (#99982)
* Avoid probing ipp printers for unique_id when it is available via mdns

We would always probe the device in the ipp flow and than
abort if it was already configured. We avoid the probe for
most printers.

* dry

* coverage

* fix test

* add test for updating host
2023-09-12 12:04:37 -04:00
J. Nick Koston
f200ba7a86 Bump bluetooth-auto-recovery to 1.2.3 (#99979)
fixes #99977
2023-09-12 12:04:36 -04:00
Bouwe Westerdijk
7cdb4ec852 Bump plugwise to v0.32.2 (#99973)
* Bump plugwise to v0.32.2

* Adapt number.py to the backend updates

* Update related test-cases

* Update plugwise test-fixtures

* Update test_diagnostics.py
2023-09-12 12:04:35 -04:00
Raman Gupta
e6c2833032 Handle disconnects in zwave_js repair flow (#99964)
* Handle disconnects in zwave_js repair flow

* Combine logic to reduce LoC

* only check once
2023-09-12 12:04:33 -04:00
Luke Lashley
0f9d00e4aa Bump python-roborock to 33.2 (#99962)
bump to 33.2
2023-09-12 12:04:32 -04:00
J. Nick Koston
02831ad94f Bump bleak to 0.21.1 (#99960) 2023-09-12 12:04:31 -04:00
Marc Mueller
e597a6b640 Update RestrictedPython to 6.2 (#99955) 2023-09-12 12:04:30 -04:00
Ståle Storø Hauknes
f0b6367444 Airthings BLE unique id migration (#99832)
* Fix sensor unique id

* Add sensor identifiers

* Migrate entities to new unique id

* Fix linting issues

* Fix crash when migrating entity fails

* Change how entities are migrated

* Remve debug logging

* Remove unneeded async

* Remove migration code from init file

* Add migration code to sensor.py

* Adjust for loops to improve speed

* Bugfixes, improve documentation

* Remove old comment

* Remove unused function parameter

* Address PR feedback

* Add tests

* Improve tests and test data

* Refactor test

* Update logger level

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

* Adjust PR comments

* Address more PR comments

* Address PR comments and adjust tests

* Fix PR comment

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-12 12:04:29 -04:00
puddly
8e6ec01bfb Cache device trigger info during ZHA startup (#99764)
* Do not connect to the radio hardware within `_connect_zigpy_app`

* Make `connect_zigpy_app` public

* Create radio manager instances from config entries

* Cache device triggers on startup

* reorg zha init

* don't reuse gateway

* don't nuke yaml configuration

* review comments

* Fix existing unit tests

* Ensure `app.shutdown` is called, not just `app.disconnect`

* Revert creating group entities and device registry entries early

* Add unit tests

---------

Co-authored-by: David F. Mulcahey <david.mulcahey@icloud.com>
2023-09-12 12:04:28 -04:00
Tiit Rätsep
4c125fda9d Fix Soma cover tilt (#99717) 2023-09-12 12:04:27 -04:00
jan iversen
7235de1a0c Make modbus retry fast on read errors (#99576)
* Fast retry on read errors.

* Review comments.
2023-09-12 12:04:26 -04:00
jan iversen
d399ebb8e1 Read modbus data before scan_interval (#99243)
Read before scan_interval.
2023-09-12 12:04:25 -04:00
Michael Arthur
367d893fc8 Bugfix: Electric Kiwi reduce interval so oauth doesn't expire (#99489)
decrease interval time as EK have broken/changed their oauth again
2023-09-12 12:02:03 -04:00
jan iversen
d5ff05bdf5 Remove modbus pragma no cover and solve nan (#99221)
* Remove pragma no cover.

* Ruff !

* Review comments.

* update test.

* Review.

* review.

* Add slave test.
2023-09-12 12:02:02 -04:00
Joost Lekkerkerker
71c4f675e0 Use shorthand attributes in SPC (#100217) 2023-09-12 11:01:05 -05:00
Joost Lekkerkerker
4e202eb376 Use shorthand attributes in Yamaha Musiccast (#100220) 2023-09-12 10:35:01 -05:00
Joost Lekkerkerker
6545fba549 Use shorthand attributes in Universal (#100219) 2023-09-12 10:34:41 -05:00
Erik Montnemery
6485320bc4 Improve type annotations in websocket_api tests (#100198) 2023-09-12 17:31:25 +02:00
Joost Lekkerkerker
75951dd67b Use shorthand attributes in Point (#100214) 2023-09-12 10:15:36 -05:00
Joost Lekkerkerker
54c034185f Use shorthand attributes in Isy994 (#100209) 2023-09-12 10:13:13 -05:00
Erik Montnemery
6e6680dc4d Enable asyncio debug mode in tests (#100197) 2023-09-12 10:12:22 -05:00
J. Nick Koston
83ef5450e9 Use shorthand attributes in garadget cover (#100207) 2023-09-12 10:05:31 -05:00
J. Nick Koston
e2f7b3c6f8 Use shorthand attributes in buienradar camera (#100205) 2023-09-12 10:05:15 -05:00
J. Nick Koston
085a584d98 Use shorthand attributes in geniushub sensor (#100208) 2023-09-12 10:04:35 -05:00
Joost Lekkerkerker
4e17901fef Use shorthand attribute in Bloomsky (#100203) 2023-09-12 16:37:35 +02:00
Erik Montnemery
d495208995 Remove unnecessary block use of pylint disable in onvif (#100194) 2023-09-12 09:19:26 -05:00
jan iversen
c178388956 Remove modbus pragma no cover and solve nan (#99221)
* Remove pragma no cover.

* Ruff !

* Review comments.

* update test.

* Review.

* review.

* Add slave test.
2023-09-12 16:05:59 +02:00
jan iversen
9acca1bf58 Make modbus retry fast on read errors (#99576)
* Fast retry on read errors.

* Review comments.
2023-09-12 10:01:15 -04:00
Ståle Storø Hauknes
198532d51d Airthings BLE unique id migration (#99832)
* Fix sensor unique id

* Add sensor identifiers

* Migrate entities to new unique id

* Fix linting issues

* Fix crash when migrating entity fails

* Change how entities are migrated

* Remve debug logging

* Remove unneeded async

* Remove migration code from init file

* Add migration code to sensor.py

* Adjust for loops to improve speed

* Bugfixes, improve documentation

* Remove old comment

* Remove unused function parameter

* Address PR feedback

* Add tests

* Improve tests and test data

* Refactor test

* Update logger level

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

* Adjust PR comments

* Address more PR comments

* Address PR comments and adjust tests

* Fix PR comment

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-12 09:59:54 -04:00
Mike Degatano
2b62285eee Fix addon slug validation (#100070)
* Fix addon slug validation

* Don't redefine compile
2023-09-12 09:59:12 -04:00
Joakim Sørensen
1e2b0b65af Bump hass-nabucasa from 0.70.0 to 0.71.0 (#100193)
Bump hass-nabucasa from 0.70.0 to 0.71.1
2023-09-12 09:58:25 -04:00
Erik Montnemery
fabb098ec3 Simplify WS command entity/source (#99439) 2023-09-12 15:39:11 +02:00
Joost Lekkerkerker
e143bdf2f5 Use shorthand attributes in Vera (#99893) 2023-09-12 15:23:12 +02:00
Jan Bouwhuis
6b265120b3 Fix entity name attribute on mqtt entity is not removed on update (#100187)
Fix entity name attribute is not remove on update
2023-09-12 15:22:37 +02:00
Joost Lekkerkerker
76c3a638c4 Use shorthand attributes in Smarttub (#99839) 2023-09-12 15:17:57 +02:00
Joost Lekkerkerker
b5275016d4 Use shorthand attributes in Twinkly (#99891) 2023-09-12 15:08:18 +02:00
Joost Lekkerkerker
1ccf9cc400 Use shorthand attributes in Squeezebox (#99863) 2023-09-12 15:02:29 +02:00
Joost Lekkerkerker
1cf2f2f8b8 Use shorthand attributes in Songpal (#99849) 2023-09-12 15:00:11 +02:00
Joost Lekkerkerker
1ca505c228 Use shorthand attributes in Wiffi (#99919) 2023-09-12 14:58:03 +02:00
jan iversen
26ada30720 Remove default from deprecated close_comm_on_error (#100188) 2023-09-12 14:12:45 +02:00
Erik Montnemery
6b628f2d29 Remove unnecessary block use of pylint disable in components a-o (#100190) 2023-09-12 14:02:50 +02:00
jan iversen
71207e112e Bring modbus naming in sync with standard (#99285) 2023-09-12 10:59:50 +02:00
Vincent Knoop Pathuis
fead9d3a92 Bump Ultraheat to version 0.5.7 (#100172) 2023-09-12 10:45:35 +02:00
dependabot[bot]
0cd73e397b Bump tibdex/github-app-token from 1.8.2 to 2.0.0 (#100099)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-12 10:43:13 +02:00
Erik Montnemery
5bcb4f07a0 Bump hatasmota to 0.7.3 (#100169) 2023-09-12 09:58:05 +02:00
Joost Lekkerkerker
27c430bbac Use shorthand attributes in Smart meter texas (#99838)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-12 09:36:07 +02:00
Alex Yao
5ba573a1b4 Add Life360 Location Update Button (#99559)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: alexyao2015 <alexyao2015@users.noreply.github.com>
2023-09-12 09:34:11 +02:00
Álvaro Fernández Rojas
da13afbd3c Add missing AEMET wind gust speed (#100157) 2023-09-12 09:08:06 +02:00
Erik Montnemery
80b03b4acb Adjust tasmota sensor device class and icon mapping (#100168) 2023-09-12 08:59:39 +02:00
J. Nick Koston
e8ed4c1ace Bump dbus-fast to 2.6.0 (#100163)
changelog: https://github.com/Bluetooth-Devices/dbus-fast/compare/v2.4.0...v2.6.0
2023-09-12 08:56:02 +02:00
Allen Porter
183b77973f Add configuration flow to Todoist integration (#100094)
* Add config flow to todoist

* Fix service calls for todoist

* Fix configuration entry test setup

* Bump test coverage to 100%

* Apply pr feedback
2023-09-11 22:56:08 -07:00
Raman Gupta
8e43f79f19 Bump zwave-js-server-python to 0.51.2 (#100159) 2023-09-11 23:03:47 -04:00
Jan-Philipp Benecke
5d46e22591 Move airly coordinator to its own file (#99545) 2023-09-11 21:52:02 -05:00
J. Nick Koston
140af44e31 Bump dbus-fast to 2.4.0 (#100158) 2023-09-11 21:40:32 -05:00
J. Nick Koston
a20d1a357f Avoid probing ipp printers for unique_id when it is available via mdns (#99982)
* Avoid probing ipp printers for unique_id when it is available via mdns

We would always probe the device in the ipp flow and than
abort if it was already configured. We avoid the probe for
most printers.

* dry

* coverage

* fix test

* add test for updating host
2023-09-11 22:34:23 -04:00
Michael
3d28c6d636 Fix AVM Fritz!Tools update entity (#100151)
* move update entity to coordinator

* fix tests
2023-09-11 22:30:50 -04:00
puddly
15b9963a24 Bump ZHA dependencies (#100156) 2023-09-11 22:23:55 -04:00
Raman Gupta
e231da42e1 Handle disconnects in zwave_js repair flow (#99964)
* Handle disconnects in zwave_js repair flow

* Combine logic to reduce LoC

* only check once
2023-09-12 04:21:44 +02:00
Bram Kragten
e0e05f9546 Update frontend to 20230911.0 (#100139) 2023-09-11 23:06:21 +02:00
Jan-Philipp Benecke
4779cdf2ae Let the discovergy config flow test end with create entry (#100153) 2023-09-11 23:06:06 +02:00
Álvaro Fernández Rojas
851dc4cdf4 Use library for condition/wind direction conversions (#100117)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2023-09-11 22:26:58 +02:00
Joost Lekkerkerker
c347c78b6d Split Withings common file out to their own file (#100150)
* Split common out in logical pieces

* Split common out in logical pieces

* Split common out in logical pieces
2023-09-11 22:25:08 +02:00
Jan-Philipp Benecke
5a56adb3f5 Refactor discovergy config flow test to use parametrize (#100115)
* Refactor discovergy config flow test to use parametrize

* Formatting

* Implement code review sugesstions
2023-09-11 21:53:07 +02:00
Robert Svensson
13cd873e38 Fix devices not always reporting IP - bump aiounifi to v62 (#100149) 2023-09-11 21:50:29 +02:00
J. Nick Koston
0571a75c99 Bump zeroconf to 0.108.0 (#100148) 2023-09-11 14:42:13 -05:00
puddly
cbb28b6943 Migrate internal ZHA data to a dataclasses (#100127)
* Cache device triggers on startup

* reorg zha init

* don't reuse gateway

* don't nuke yaml configuration

* review comments

* Add unit tests

* Do not cache device and entity registries

* [WIP] Wrap ZHA data in a dataclass

* [WIP] Get unit tests passing

* Use a helper function for getting the gateway object to fix annotations

* Remove `bridge_id`

* Fix typing issues with entity references in group websocket info

* Use `Platform` instead of `str` for entity platform matching

* Use `get_zha_gateway` in a few more places

* Fix flaky unit test

* Use `slots` for ZHA data

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

---------

Co-authored-by: David F. Mulcahey <david.mulcahey@icloud.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-11 21:39:33 +02:00
Joost Lekkerkerker
5c206de906 Decouple Withings webhook tests from YAML (#100143) 2023-09-11 14:06:20 -05:00
Niels Perfors
ad5e9e9f5b Remove code owner Verisure (#100145) 2023-09-11 13:43:59 -05:00
J. Nick Koston
d5fc92eb90 Bump zeroconf to 0.107.0 (#100134)
changelog: https://github.com/python-zeroconf/python-zeroconf/compare/0.105.0...0.107.0
2023-09-11 20:34:35 +02:00
J. Nick Koston
fdb9ac20c3 Migrate mobile_app to use json helper (#100136) 2023-09-11 12:08:48 -05:00
TJ Horner
17db20fdd7 Add Apple WeatherKit integration (#99895) 2023-09-11 12:06:55 -05:00
J. Nick Koston
0fe88d60ac Guard expensive debug logging with isEnabledFor in alexa (#100137) 2023-09-11 11:39:10 -05:00
Erik Montnemery
18e08bc79f Bump hatasmota to 0.7.2 (#100129) 2023-09-11 11:35:48 -05:00
starkillerOG
56678851af Fix inverse naming of function in Reolink (#100113) 2023-09-11 18:03:22 +02:00
Erik Montnemery
6ccb74997c Fix ScrapeSensor.async_added_to_hass (#100125) 2023-09-11 16:58:56 +02:00
Álvaro Fernández Rojas
9c65e59cc8 Remove AEMET daily precipitation sensor test (#100118) 2023-09-11 09:46:59 -05:00
Robert Svensson
d8445a79fc UniFi streamline loading platforms (#100071)
* Streamline loading platforms

* Move platform registration logic to UnifiController class
2023-09-11 15:55:27 +02:00
J. Nick Koston
791482406c Cleanup isinstance checks in zeroconf (#100090) 2023-09-11 08:13:25 -05:00
J. Nick Koston
f4a7bb47fe Bump zeroconf to 0.105.0 (#100084) 2023-09-11 08:09:29 -05:00
J. Nick Koston
64fde640ca Bump pyunifiprotect to 4.20.0 (#100092) 2023-09-11 08:08:19 -05:00
puddly
a6f325d05a Cache device trigger info during ZHA startup (#99764)
* Do not connect to the radio hardware within `_connect_zigpy_app`

* Make `connect_zigpy_app` public

* Create radio manager instances from config entries

* Cache device triggers on startup

* reorg zha init

* don't reuse gateway

* don't nuke yaml configuration

* review comments

* Fix existing unit tests

* Ensure `app.shutdown` is called, not just `app.disconnect`

* Revert creating group entities and device registry entries early

* Add unit tests

---------

Co-authored-by: David F. Mulcahey <david.mulcahey@icloud.com>
2023-09-11 14:36:01 +02:00
Erik Montnemery
42046a3ce2 Fix TriggerEntity.async_added_to_hass (#100119) 2023-09-11 14:33:43 +02:00
Joost Lekkerkerker
a6e9bf830c Decouple Withings binary sensor test from YAML (#100120) 2023-09-11 13:58:47 +02:00
Joost Lekkerkerker
5781e5e03e Use json to store Withings test data fixtures (#99998)
* Decouple Withings sensor tests from yaml

* Improve Withings config flow tests

* Improve Withings config flow tests

* Fix feedback

* Use fixtures to store Withings testdata structures

* Use fixtures to store Withings testdata structures

* Use JSON

* Fix

* Use load_json_object_fixture
2023-09-11 12:36:37 +02:00
Marc Mueller
58072189fc Update black to 23.9.1 (#100108) 2023-09-11 12:14:50 +02:00
Tiit Rätsep
10bb8f5396 Fix Soma cover tilt (#99717) 2023-09-11 11:15:46 +02:00
Jan-Philipp Benecke
a4cb06d09f Also handle DiscovergyClientError as UpdateFailed (#100038)
* Also handle DiscovergyClientError as UpdateFailed

* Change AccessTokenExpired to InvalidLogin

* Also add DiscovergyClientError to config flow and tests
2023-09-11 11:00:50 +02:00
Jan Bouwhuis
20d0ebe3fa Add TYPE_CHECKING condition on type assertions for mqtt (#100107)
Add TYPE_CHECKING condition on type assertions
2023-09-11 10:58:33 +02:00
Rami Mosleh
eb0099dee8 Move smtp constants to const.py (#99542) 2023-09-11 09:36:55 +02:00
Joost Lekkerkerker
43fe8d16c3 Use shorthand attributes in ZAMG (#99925)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-11 09:32:43 +02:00
Greig Sheridan
f121e891fd Remove duplicated word in enphase description text (#100098) 2023-09-11 09:16:21 +02:00
Simone Chemelli
0fb678abfc Remove Comelit alarm data retrieval (#100067)
fix: remove alarm data retrieval
2023-09-11 08:49:10 +02:00
Michael Arthur
8beace265b Add unit tests for sensors Electric Kiwi (#97723)
* add unit tests for sensors

* newline long strings

* unit test check and move time

* rename entry to entity

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

* add types to test

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

* fix newlined f strings

* remove if statement

* add some more explaination

* Update datetime

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

* Simpler time update

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

* add missing datetime import

* Update docustring - grammar

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* address comments and issues raised

* address docstrings too long

* Fix docstring

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-11 01:30:25 +02:00
jimmyd-be
6c45f43c5d Renson number entity (#99358)
* Starting number sensor

* Filter change config

* Add translation to number entity

* add number entity to .coveragerc

* Moved has_entity_name to description + changed name of entity

* Add self.coordinator.async_request_refresh() after changing value

* Add device calss and unit of measurement to number entity
2023-09-11 01:24:57 +02:00
G Johansson
73a695d857 Fix incorrect docstring in TV Camera sensor test (#100083) 2023-09-11 01:22:33 +02:00
G Johansson
954293f77e Add binary sensors to Trafikverket Camera (#100082) 2023-09-11 01:12:19 +02:00
G Johansson
0fae65abde Fix missed name to translation key in Sensibo (#100080) 2023-09-11 01:10:59 +02:00
G Johansson
4ebb6bb823 Add sensors to Trafikverket Camera (#100078)
* Add sensors to Trafikverket Camera

* Remove active

* Fix test len
2023-09-11 00:56:12 +02:00
Matrix
45fc158823 Add yolink siren battery entity (#99310) 2023-09-11 00:31:58 +02:00
J. Nick Koston
80e05716c0 Bump dbus-fast to 2.2.0 (#100076) 2023-09-10 16:38:39 -05:00
dependabot[bot]
4474face88 Bump tibdex/github-app-token from 1.8.0 to 1.8.2 (#99434)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-10 22:23:18 +02:00
J. Nick Koston
2bda34b98a Bump flux_led to 1.0.4 (#100050) 2023-09-10 21:45:37 +02:00
J. Nick Koston
02a4289c6e Bump zeroconf to 0.104.0 (#100068) 2023-09-10 21:32:40 +02:00
J. Nick Koston
3b8d99dcd8 Add __slots__ to translation cache (#100069) 2023-09-10 20:46:55 +02:00
Álvaro Fernández Rojas
3238386f48 Add water heater support to Airzone (#98401)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-10 12:31:11 -05:00
Simone Chemelli
a5a82b94ac Bump aiovodafone to 0.2.0 (#100062)
bump aiovodafone to 0.2.0
2023-09-10 19:09:21 +02:00
J. Nick Koston
4f0cd5589c Bump aiohomekit to 3.0.3 (#100047) 2023-09-10 12:01:12 -05:00
Tony
3b25262d6c Address ruckus_unleashed late review (#99411) 2023-09-10 18:49:17 +02:00
Jan-Philipp Benecke
7acc606dd8 Remove unnecessary argument from discovergy coordinator (#100058) 2023-09-10 11:25:55 -05:00
Jan Bouwhuis
63852c565f Use hass.loop.create_future() in envisalink (#100057) 2023-09-10 11:25:25 -05:00
J. Nick Koston
50382a609c Create recorder futures with loop.create_future() (#100049) 2023-09-10 11:24:57 -05:00
Aidan Timson
51899ce5ad Add System Bridge notifications (#82318)
* System bridge notifications

Add notify platform

Add file to coverage

Restore and fix lint after rebase

Cleanup

Use entity to register notify service

Fix pylint

Update package to 3.6.0 and add audio actions

Update package to fix conflict

Remove addition

* Run pre-commit run --all-files

* Update homeassistant/components/system_bridge/notify.py

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

* Format

* Fix

* Remove duplicate import

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-10 17:32:52 +02:00
Jan Bouwhuis
6899245020 Use hass.loop.create_future() for bluetooth (#100054) 2023-09-10 17:16:16 +02:00
Jan Bouwhuis
1a5f093397 Uer hass.loop.create_future() for MQTT client (#100053) 2023-09-10 17:15:46 +02:00
Joost Lekkerkerker
05635c913f Add device to OpenUV (#100027) 2023-09-10 17:10:45 +02:00
Aidan Timson
140bc03fb1 Bump systembridgeconnector to 3.8.2 (#100051)
Update systembridgeconnector to 3.8.2
2023-09-10 17:02:42 +02:00
Joost Lekkerkerker
b165c28a7c Improve Withings config flow tests (#99697)
* Decouple Withings sensor tests from yaml

* Improve Withings config flow tests

* Improve Withings config flow tests

* Fix feedback

* Rename CONF_PROFILE to PROFILE
2023-09-10 16:18:45 +02:00
Yuxiang Zhu
739eb28b90 Make homekit RTP/RTCP source ports more deterministic (#99989) 2023-09-10 09:07:35 -05:00
mkmer
59e87c0864 Raise HomeAssistantError/ValueError for service calls in Honeywell (#100041) 2023-09-10 15:58:59 +02:00
mkmer
d56ad14673 Add diagnostic platform to Honeywell (#100046)
Add diagnostic platform
2023-09-10 15:49:56 +02:00
Marc Mueller
ccca12cf31 Update bthome-ble to 3.1.1 (#100042) 2023-09-10 08:42:47 -05:00
Diogo Gomes
553cdfbf99 Always update unit of measurement of the utility_meter on state change (#99102) 2023-09-10 08:29:38 -05:00
J. Nick Koston
5e81499855 Avoid json_decoder_fallback in /api/states (#100018) 2023-09-10 08:25:23 -05:00
J. Nick Koston
ad4619c038 Speed up serializing event messages (#100017) 2023-09-10 08:25:13 -05:00
fender4645
e4af50f955 Add debug message to doods (#100002)
* Debug message if no detections found or
no output file configured

* fix formatting

* black

---------

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2023-09-10 12:58:18 +02:00
Bouwe Westerdijk
446ca2e9ad Enable strict typing in Plugwise (#100033)
Add plugwise to .strict-typing
2023-09-10 12:16:59 +02:00
Bouwe Westerdijk
c01a9987b5 Add Plugwise temperature_offset number (#100029)
Add temperature_offset number
2023-09-10 11:34:09 +02:00
elmurato
1f3b3b1be3 Add sensor entity descriptions in Minecraft Server (#99971)
* Add sensor entity descriptions

* Fix review findings

* Fix type of value function to avoid inline lambda if conditions and add attribute function to avoid extra sensor entity class

* Correct name of binary sensor base entity

* Simplify adding of entities in platforms

* Do not use keyword arguments while adding entities
2023-09-10 10:20:26 +02:00
J. Nick Koston
4153181cd3 Bump aiodiscover to 1.5.1 (#100020)
changelog: https://github.com/bdraco/aiodiscover/compare/v1.4.16...v1.5.1
2023-09-10 10:17:59 +02:00
J. Nick Koston
3b588a839c Bump zeroconf to 0.103.0 (#100012) 2023-09-09 19:49:26 -05:00
Luke Lashley
602e36aa12 Add new sensors to Roborock (#99983)
* Add 3 new sensor types

* add state options for dock error

* add unit of measurement
2023-09-10 00:40:28 +02:00
Kevin Worrel
092580a3ed Bump screenlogicpy to v0.9.0 (#92475)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-09 17:39:54 -05:00
Joost Lekkerkerker
8de3945bd4 Fix renamed code owner for Versasense (#99976)
Fix renamed code owner
2023-09-10 00:38:57 +02:00
Joost Lekkerkerker
6c613fd255 Move static attributes outside of ws66i constructor (#99922)
Move static attributes outside of ws66i cosntructor
2023-09-10 00:38:43 +02:00
Joost Lekkerkerker
4bc079b219 Use snapshot assertion in Plugwise diagnostic test (#100008)
* Use snapshot assertion in Plugwise diagnostic test

* Use snapshot assertion in Plugwise diagnostic test
2023-09-10 00:38:17 +02:00
J. Nick Koston
e3f228ea52 Switch config_entries to use loop.create_future() (#100011) 2023-09-09 17:34:49 -05:00
J. Nick Koston
b370244ed4 Switch ESPHome Bluetooth to use loop.create_future() (#100010) 2023-09-09 17:34:31 -05:00
J. Nick Koston
b66437ff7b Bump yalexs-ble to 2.3.0 (#100007) 2023-09-09 17:34:11 -05:00
Bouwe Westerdijk
081d0bdce5 Bump plugwise to v0.32.2 (#99973)
* Bump plugwise to v0.32.2

* Adapt number.py to the backend updates

* Update related test-cases

* Update plugwise test-fixtures

* Update test_diagnostics.py
2023-09-09 23:50:26 +02:00
Joost Lekkerkerker
af8fd6c2d9 Restore airtouch4 codeowner (#99984) 2023-09-09 23:22:03 +02:00
Joost Lekkerkerker
eeaca8ae3c Use shorthand attributes in Vicare (#99915) 2023-09-09 23:18:41 +02:00
elmurato
23f4ccd4f1 Fix late review findings in Minecraft Server (#99865) 2023-09-09 22:32:13 +02:00
J. Nick Koston
aff49cb67a Bump bluetooth-auto-recovery to 1.2.3 (#99979)
fixes #99977
2023-09-09 19:23:15 +02:00
Kevin Stillhammer
862506af61 Bump pywaze to 0.4.0 (#99995)
bump pywaze from 0.3.0 to 0.4.0
2023-09-09 19:16:27 +02:00
Joost Lekkerkerker
a62ffeaa99 Decouple Withings sensor tests from yaml (#99691)
* Decouple Withings sensor tests from yaml

* Fix feedback

* Add pytest fixture

* Update tests/components/withings/test_sensor.py

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

* Update snapshots

* Update snapshots

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2023-09-09 19:11:28 +02:00
Joost Lekkerkerker
868fdd81da Add entity translations to withings (#99194)
* Add entity translations to Withings

* Add entity translations to Withings
2023-09-09 18:48:09 +02:00
jan iversen
743ce46311 Deprecate CLOSE_COMM_ON_ERROR (#99946) 2023-09-09 18:34:01 +02:00
Luke Lashley
71726130c3 Add binary sensors to Roborock (#99990)
* init binary sensors commit

* add binary sensors

* fix test

* Apply suggestions from code review

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-09 18:12:14 +02:00
Joost Lekkerkerker
9be16d9d42 Add config flow to WAQI (#98220)
* Migrate WAQI to aiowaqi library

* Migrate WAQI to aiowaqi library

* Migrate WAQI to aiowaqi library

* Add config flow to WAQI

* Finish config flow

* Add tests

* Add tests

* Fix ruff

* Add issues on failing to import

* Add issues on failing to import

* Add issues on failing to import

* Add importing issue

* Finish coverage

* Remove url from translation string

* Fix feedback

* Fix feedback
2023-09-09 17:49:54 +02:00
jan iversen
fdddbd7363 Bump pymodbus to v3.5.2 (#99988) 2023-09-09 17:45:19 +02:00
J. Nick Koston
bb2cdbe7bc Change SSDP discovery scan interval to 10 minutes (#99975)
* Change SSDP discovery scan interval to 10 minutes

The first version used a scan interval of 1 minute which we
increased to 2 minutes because it generated too much traffic.

We kept it at 2 minutes because Sonos historicly needed to
get SSDP discovery to stay alive. This is no longer the case
as Sonos has multiple ways to keep from going unavailable:

- mDNS support was added
- We now listen for SSDP alive and good bye all the time
- Each incoming packet from the device keeps it alive now
- We probe when we think the device might be offline

This means it should no longer be necessary to have such a
frequent scan which is a drag on all devices on the network
since its multicast

* adjust tests
2023-09-09 10:54:40 -04:00
G Johansson
e425662494 Bump pytrafikverket to 0.3.6 (#99869)
* Bump pytrafikverket to 0.3.6

* Fix config flow names

* str
2023-09-09 16:18:47 +02:00
Thomas Roager
74a7bccd65 Add zdb5100 light to zwave_js (#97586)
* added zdb5100 light

* added light to zdb5100

* Update tests/components/zwave_js/conftest.py

agree

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update tests/components/zwave_js/conftest.py

agree

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Rename logic_group_zdb5100_light_state.json to logic_group_zdb5100_state.json

name change

* Update tests/components/zwave_js/test_light.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update test_light.py

updated test and state

* Update test_light.py

incorrect endpoint

* changed the state

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-09 16:01:32 +02:00
Marc Mueller
c77eb70886 Add black caching [ci] (#99967)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-09 08:36:47 -05:00
Marc Mueller
483e9c92bd Update black to 23.9.0 (#99965) 2023-09-09 07:53:25 -05:00
Luke Lashley
dced72f2dd Bump python-roborock to 33.2 (#99962)
bump to 33.2
2023-09-09 14:15:28 +02:00
Robert Svensson
cf47a6c515 Add UniFi device uptime and temperature sensors (#99307)
* Add UniFi device uptime and temperature sensors

* Add native_unit_of_measurement to temperature
Remove seconds and milliseconds from device uptime
2023-09-09 11:12:44 +02:00
J. Nick Koston
f903cd6fc0 Bump dbus-fast to 2.0.1 (#99894) 2023-09-08 21:16:21 -05:00
J. Nick Koston
694638cbc0 Bump bleak to 0.21.1 (#99960) 2023-09-08 19:39:30 -05:00
Marc Mueller
e163e00acd Update RestrictedPython to 6.2 (#99955) 2023-09-08 18:51:26 -05:00
Joost Lekkerkerker
75f923a86e Use device class translations for Devolo Update entity (#99235) 2023-09-09 01:16:51 +02:00
elmurato
d59aa958b6 Add tests for Minecraft Server entry migration from v1 to v2 (#99954) 2023-09-08 23:03:27 +02:00
Bram Kragten
9e6ac1d7ec 2023.9.1 (#99950) 2023-09-08 22:46:00 +02:00
Daniel Hjelseth Høyer
2dcf6a6f5b Bump millheater to 0.11.2 (#99683)
Update Mill lib

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2023-09-08 21:17:02 +02:00
Bram Kragten
6e952134e7 Bumped version to 2023.9.1 2023-09-08 21:03:27 +02:00
Erik Montnemery
ff393f6b86 Bump hatasmota to 0.7.1 (#99818) 2023-09-08 21:02:43 +02:00
Erik Montnemery
f753f5af6e Make WS command render_template not give up if initial render raises (#99808) 2023-09-08 21:02:42 +02:00
Erik Montnemery
1654ef7759 Make WS command render_template not give up if initial render raises (#99808) 2023-09-08 21:02:06 +02:00
Erik Montnemery
b317e04cf1 Bump hatasmota to 0.7.1 (#99818) 2023-09-08 21:01:34 +02:00
J. Nick Koston
f0ee20c15c Bump orjson to 3.9.7 (#99938) 2023-09-08 13:59:35 -05:00
J. Nick Koston
19c2bbcd93 Bump zeroconf to 0.98.0 (#99748) 2023-09-08 20:57:03 +02:00
J. Nick Koston
7ded08464f Bump zeroconf to 0.97.0 (#99554)
changelog: https://github.com/python-zeroconf/python-zeroconf/compare/0.96.0...0.97.0
2023-09-08 20:56:23 +02:00
J. Nick Koston
c1447d5ce4 Bump zeroconf to 0.96.0 (#99549) 2023-09-08 20:56:02 +02:00
J. Nick Koston
55533350d2 Bump zeroconf to 0.93.1 (#99516)
* Bump zeroconf to 0.92.0

changelog: https://github.com/python-zeroconf/python-zeroconf/compare/0.91.1...0.92.0

* drop unused argument

* Update tests/components/thread/test_diagnostics.py

* lint

* again

* bump again since actions failed to release the wheels
2023-09-08 20:55:01 +02:00
Jan Bouwhuis
06109d22fd Fix key error MQTT binary_sensor when no name is set (#99943)
Log entitty ID when instead of name
2023-09-08 20:53:06 +02:00
Joost Lekkerkerker
f1bae7d37b Bump pyenphase to v1.11.0 (#99941) 2023-09-08 20:53:05 +02:00
jan iversen
0e4bf58736 Bump pymodbus v.3.5.1 (#99940) 2023-09-08 20:53:04 +02:00
jan iversen
50c34ab419 Bump pymodbus v3.5.0 (#99343)
Bump pymodbus v3.5.0.
2023-09-08 20:52:31 +02:00
Bram Kragten
fed061f69c Update frontend to 20230908.0 (#99939) 2023-09-08 20:51:08 +02:00
J. Nick Koston
330e527560 Upgrade bluetooth deps to fix timeout behavior on py3.11 (#99879) 2023-09-08 20:51:06 +02:00
Jan Bouwhuis
110a17ad6d Fix NOAA tides warnings (#99856) 2023-09-08 20:51:05 +02:00
puddly
dccccda502 Bump ZHA dependencies (#99855) 2023-09-08 20:51:04 +02:00
J. Nick Koston
02b6bbdcc6 Bump dbus-fast to 1.95.2 (#99852) 2023-09-08 20:51:03 +02:00
J. Nick Koston
cadf56c989 Bump dbus-fast to 1.95.0 (#99749) 2023-09-08 20:50:18 +02:00
Simone Chemelli
d50f9f4e51 Bump aiovodafone to 0.1.0 (#99851)
* bump aiovodafone to 0.1.0

* fix tests
2023-09-08 20:46:12 +02:00
J. Nick Koston
7dc7060825 Fix missing name and identifiers for ELKM1 connected devices (#99828) 2023-09-08 20:46:11 +02:00
Joost Lekkerkerker
0b4fedccff Use correct config entry id in Livisi (#99812) 2023-09-08 20:46:10 +02:00
Erik Montnemery
850c095988 Improve error handling in /api/states POST (#99810) 2023-09-08 20:46:09 +02:00
Erik Montnemery
31fb9d12ea Always set severity level flag on render_template error events (#99804) 2023-09-08 20:46:08 +02:00
lymanepp
590ac173ed Fix missing dew point and humidity in tomorrowio forecasts (#99793)
* Fix missing dew point and humidity in tomorrowio forecasts

* Add assertion for correct parameters to realtime_and_all_forecasts method
2023-09-08 20:46:07 +02:00
swamplynx
45e723135c Bump pylutron-caseta to v0.18.2 (#99789)
* Bump pylutron-caseta to v0.18.2

Minor bump to pylutron-caseta requirement to support wall mounted occupancy sensor device type in latest RA3 firmware.

* Update requirements_all.txt for pylutron-caseta 0.18.2

* Update requirements_test_all.txt for pylutron-caseta 0.18.2
2023-09-08 20:46:06 +02:00
J. Nick Koston
c217ea7b38 Bump pyenphase to 1.9.3 (#99787)
* Bump pyenphase to 1.9.2

changelog: https://github.com/pyenphase/pyenphase/compare/v1.9.1...v1.9.2

Handle the case where the user has manually specified a password for
local auth with firmware < 7.x but its incorrect.

The integration previously accepted any wrong password and would
reduce functionality down to what works without a password. We now
preserve that behavior to avoid breaking existing installs.

* bump
2023-09-08 20:46:05 +02:00
Aaron Bach
c740b79e1e Bump aiorecollect to 2023.09.0 (#99780) 2023-09-08 20:46:04 +02:00
Pawel
7c7fed0322 Add support for more busy codes for Epson (#99771)
add support for more busy codes
2023-09-08 20:46:02 +02:00
J. Nick Koston
a25f6bbd09 Bump sense_energy to 0.12.1 (#99763) 2023-09-08 20:46:01 +02:00
Quentame
fb56e48e07 Fix Freebox Home battery sensor (#99756) 2023-09-08 20:44:43 +02:00
Quentame
718f1a6673 Fix Freebox disk free space sensor (#99757)
* Fix Freebox disk free space sensor

* Add initial value assert to check results
2023-09-08 20:44:19 +02:00
Joost Lekkerkerker
c741214ab5 Revert "Bump pyoverkiz to 1.10.1 (#97916)" (#99742) 2023-09-08 19:59:32 +02:00
Jan Bouwhuis
64408cab10 Handle alexa invalid climate temp adjustment (#99740)
* Handle temp adjust when target state not set

* Update homeassistant/components/alexa/errors.py

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

* black

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-08 19:59:30 +02:00
Marc Mueller
8b69f9fda8 Fix tradfri asyncio.wait (#99730) 2023-09-08 19:59:29 +02:00
David Knowles
39669bc788 Fix the Hydrawise status sensor (#99271) 2023-09-08 19:59:28 +02:00
J. Nick Koston
d1ac4c9c46 Switch a few ssdp calls to use get_lower (#99931)
get_lower avoids lower casing already lower-cased strings
2023-09-08 13:59:25 -04:00
jan iversen
be4ea32049 Bump pymodbus v.3.5.1 (#99940) 2023-09-08 19:20:06 +02:00
Jan Bouwhuis
677431ed71 Fix key error MQTT binary_sensor when no name is set (#99943)
Log entitty ID when instead of name
2023-09-08 19:10:17 +02:00
J. Nick Koston
bd1d8675a9 Avoid many hass.is_stopping calls in the discovery helper (#99929)
async_has_matching_flow is more likely to be True than hass.is_stopping

This does not make much difference but it was adding noise to a profile
that I am digging into to look for another issue
2023-09-08 13:09:29 -04:00
Joost Lekkerkerker
9a45e2cf91 Bump pyenphase to v1.11.0 (#99941) 2023-09-08 19:08:32 +02:00
J. Nick Koston
d624bbbc0c Migrate elkm1 to use a dataclass for integration data (#99830)
* Migrate elkm1 to use a dataclass for integration data

* fix unsaved

* slotted

* missing coveragerc

* Revert "missing coveragerc"

This reverts commit 3397b40309.
2023-09-08 13:07:09 -04:00
J. Nick Koston
3d403c9b60 Refactor entity service calls to reduce complexity (#99783)
* Refactor entity service calls to reduce complexity

gets rid of the noqa C901

* Refactor entity service calls to reduce complexity

gets rid of the noqa C901

* short
2023-09-08 13:04:53 -04:00
Bram Kragten
16f7bc7bf8 Update frontend to 20230908.0 (#99939) 2023-09-08 18:59:08 +02:00
Joost Lekkerkerker
38247ae868 Use shorthand attributes in Volumio (#99918) 2023-09-08 17:31:57 +02:00
Joost Lekkerkerker
c6f8766b1e Use shorthand attributes in Zerproc (#99926) 2023-09-08 17:27:18 +02:00
Joost Lekkerkerker
5f6f2c2cab Use shorthand attributes in Wolflink (#99921) 2023-09-08 14:38:09 +02:00
Joost Lekkerkerker
5ddaf52b27 Use shorthand attributes in Wilight (#99920) 2023-09-08 14:29:59 +02:00
Michael Hansen
e69c88a0d2 Use aliases when listing pipeline languages (#99672) 2023-09-08 08:22:08 -04:00
J. Nick Koston
98ff3e233d Fix missing name and identifiers for ELKM1 connected devices (#99828) 2023-09-08 13:32:21 +02:00
J. Nick Koston
8742c550be Upgrade bluetooth deps to fix timeout behavior on py3.11 (#99879) 2023-09-08 13:25:25 +02:00
dependabot[bot]
67de96adfa Bump actions/cache from 3.3.1 to 3.3.2 (#99903) 2023-09-08 13:18:26 +02:00
Ali Yousuf
47a75cc064 Add more options to Islamic Prayer Times (#95156) 2023-09-08 13:07:33 +02:00
Joost Lekkerkerker
0cf32e74d6 Use shorthand attributes in Tp-link (#99888) 2023-09-08 12:36:46 +02:00
Joost Lekkerkerker
b2c3d95911 Use shorthand attributes in UPB (#99892) 2023-09-08 11:33:59 +02:00
Sam Crang
b2b57c5f87 Allow exporting of update domain to Prometheus (#99400) 2023-09-07 20:43:47 -07:00
lymanepp
b76ba002e2 Fix missing dew point and humidity in tomorrowio forecasts (#99793)
* Fix missing dew point and humidity in tomorrowio forecasts

* Add assertion for correct parameters to realtime_and_all_forecasts method
2023-09-07 22:12:18 -04:00
Joost Lekkerkerker
432894a401 Use shorthand attributes in SRP Energy (#99881) 2023-09-08 01:20:22 +02:00
Joost Lekkerkerker
92628ea068 Use shorthand attributes in Starline (#99882) 2023-09-08 01:16:35 +02:00
Joost Lekkerkerker
4e826f1704 Use shorthand attributes in Syncthing (#99883) 2023-09-08 01:16:08 +02:00
Joost Lekkerkerker
9e8a8012df Use shorthand attributes in Syncthru (#99884) 2023-09-08 01:15:58 +02:00
Joost Lekkerkerker
a3d6c6192e Use shorthand attributes in Tado (#99886) 2023-09-08 01:15:49 +02:00
Joost Lekkerkerker
56f05bee91 Use shorthand attributes in Tradfri (#99890) 2023-09-08 01:15:34 +02:00
Joost Lekkerkerker
c2b119bfaf Use shorthand attributes in Tp-link Omada (#99889) 2023-09-08 01:07:15 +02:00
Joost Lekkerkerker
5a66aac330 Use shorthand attributes in Telldus live (#99887) 2023-09-08 01:02:03 +02:00
Simone Chemelli
a82cd48282 Bump aiovodafone to 0.1.0 (#99851)
* bump aiovodafone to 0.1.0

* fix tests
2023-09-08 00:32:15 +02:00
J. Nick Koston
9d5595fd7d Bump zeroconf to 0.102.0 (#99875) 2023-09-07 16:08:53 -05:00
Jan Bouwhuis
cd8426152f Fix NOAA tides warnings (#99856) 2023-09-07 21:49:03 +02:00
mkmer
4ce9c1f304 Add Diagnostic platform to Aladdin Connect (#99682)
* Add diagnostics platform

* Add diagnostic platform

* Add raw data to diagnostics

* Remove config data
bump aioaladdinconnect, use new doors property for diag

* remove unnecessary component config
refactor diag output
2023-09-07 21:27:41 +02:00
jan iversen
77180a73b7 Modbus scale parameter cuts decimals (#99758) 2023-09-07 20:56:00 +02:00
jimmyd-be
1c27a0339d Renson fan (#94495)
* Add fan feature

* Changed order of platform

* Use super()._handle_coordinator_update()

* format file

* Set _attr_has_entity_name

* Cleanup Fan code

* Refresh after setting ventilation speed + translation

* remove unused translation key
2023-09-07 20:37:14 +02:00
G Johansson
0dc8e8dabe Add device class and UoM in Sensibo Number entities (#99861)
* device class and uom number platform

* icons
2023-09-07 20:34:23 +02:00
J. Nick Koston
54bd7c9af0 Bump dbus-fast to 1.95.2 (#99852) 2023-09-07 13:27:29 -05:00
J. Nick Koston
c68d96cf09 Bump zeroconf to 0.99.0 (#99853) 2023-09-07 13:25:29 -05:00
Joost Lekkerkerker
4017473d51 Use str instead of string placeholders in solaredge (#99843) 2023-09-07 20:00:43 +02:00
Joost Lekkerkerker
66d16108be Use shorthand attributes in Rainforest eagle (#99825) 2023-09-07 19:52:12 +02:00
Joost Lekkerkerker
02e077daab Use shorthand attributes in Ring (#99829) 2023-09-07 19:51:35 +02:00
Joost Lekkerkerker
a00cbe2677 Move shorthand attributes out of Snooz constructor (#99842) 2023-09-07 19:49:18 +02:00
Joost Lekkerkerker
dcd00546ba Use shorthand attributes in Sonarr (#99844) 2023-09-07 19:47:56 +02:00
puddly
e8c4ddf05c Bump ZHA dependencies (#99855) 2023-09-07 19:22:24 +02:00
Joost Lekkerkerker
94aec3e590 Use shorthand attributes in Opentherm gateway (#99630) 2023-09-07 18:30:58 +02:00
Joost Lekkerkerker
c567a2c3d4 Move unit of temperature to descriptions in Sensibo (#99835) 2023-09-07 17:36:07 +02:00
Quentame
c3e14d0514 Fix Freebox Home battery sensor (#99756) 2023-09-07 17:28:50 +02:00
Joost Lekkerkerker
69f6a115b6 Move shorthand attributes out of constructor in Sensibo (#99834)
Use shorthand attributes in Sensibo
2023-09-07 17:28:13 +02:00
Joost Lekkerkerker
73651dbffd Use shorthand attributes in Snapcast (#99840) 2023-09-07 16:37:30 +02:00
Joost Lekkerkerker
d9b48b03f7 Use shorthand attributes in Rachio (#99823) 2023-09-07 09:20:57 -05:00
Joost Lekkerkerker
2a3ebbc26c Use shorthand attributes in SharkIQ (#99836) 2023-09-07 16:08:44 +02:00
Joost Lekkerkerker
114b5bd1f0 Use shorthand attributes in Roomba (#99831) 2023-09-07 15:56:40 +02:00
Joost Lekkerkerker
1fe17b5bed Use shorthand attributes in Sense (#99833) 2023-09-07 15:56:21 +02:00
Joost Lekkerkerker
526b587170 Remove unused variable from rainbird (#99824) 2023-09-07 15:32:03 +02:00
Jan Rieger
0d6f202eb3 Change AVM FRITZ!Box Call monitor sensor into an enum (#99762)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2023-09-07 15:26:57 +02:00
Marc Mueller
c9a1836d45 Update coverage to 7.3.1 (#99805) 2023-09-07 14:54:56 +02:00
Joost Lekkerkerker
40a3d97230 Use shorthand attributes in Plex (#99769)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-07 13:55:16 +02:00
Joost Lekkerkerker
8a4cd913b8 Use shorthand attributes in Hisense (#99355) 2023-09-07 13:53:44 +02:00
Erik Montnemery
368acaf6fd Improve error handling in /api/states POST (#99810) 2023-09-07 13:33:38 +02:00
Erik Montnemery
eee5705458 Fix typo in TrackTemplateResultInfo (#99809) 2023-09-07 13:00:26 +02:00
Joost Lekkerkerker
306c7cd9a9 Use correct config entry id in Livisi (#99812) 2023-09-07 12:45:47 +02:00
Pawel
dfee5d06a6 Add support for more busy codes for Epson (#99771)
add support for more busy codes
2023-09-07 12:45:31 +02:00
elmurato
7c3605c82e Use config entry ID as unique ID and remove dependency to getmac in Minecraft Server (#97837)
* Use config entry ID as unique ID

* Add entry migration to v2 and and remove helper module

* Remove unneeded strings

* Add asserts for config, device and entity entries and improve comments

* Add debug log for config entry migration

* Reset config entry unique ID and use config entry ID instead

* Remove unnecessary unique ID debug log

* Revert usage of constants for tranlation keys and use dash as delimiter for entity unique id suffix

* Revert "Revert usage of constants for tranlation keys and use dash as delimiter for entity unique id suffix"

This reverts commit 07de334606054097e914404da04950e952bef6d2.

* Remove unused logger in entity module
2023-09-07 12:22:46 +02:00
swamplynx
e8dfa7e2c8 Bump pylutron-caseta to v0.18.2 (#99789)
* Bump pylutron-caseta to v0.18.2

Minor bump to pylutron-caseta requirement to support wall mounted occupancy sensor device type in latest RA3 firmware.

* Update requirements_all.txt for pylutron-caseta 0.18.2

* Update requirements_test_all.txt for pylutron-caseta 0.18.2
2023-09-07 12:17:38 +02:00
J. Nick Koston
f1ae523ff2 Bump pyenphase to 1.9.3 (#99787)
* Bump pyenphase to 1.9.2

changelog: https://github.com/pyenphase/pyenphase/compare/v1.9.1...v1.9.2

Handle the case where the user has manually specified a password for
local auth with firmware < 7.x but its incorrect.

The integration previously accepted any wrong password and would
reduce functionality down to what works without a password. We now
preserve that behavior to avoid breaking existing installs.

* bump
2023-09-07 12:17:04 +02:00
Rami Mosleh
0cc2c27115 Add strict typing to islamic prayer times (#99585)
* Add strict typing to islamic prayer times

* fix mypy errors
2023-09-07 12:16:31 +02:00
Erik Montnemery
e5210c5823 Always set severity level flag on render_template error events (#99804) 2023-09-07 12:00:19 +02:00
Arda ŞEREMET
9351e79dcb Bump ProgettiHWSW to 0.1.3 (#92668)
* Update manifest.json

* Update requirements_test_all.txt

* Update requirements_all.txt

* Updated dependencies file.

* Update manifest.json with correct naming convention.

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Updated requirements.

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-07 10:53:59 +02:00
Ståle Storø Hauknes
d2f9270bc9 Add my self as codeowner for airthings_ble (#99799)
Update airthings_ble codeowner
2023-09-07 10:36:49 +02:00
Quentame
1a22ab77e1 Fix Freebox disk free space sensor (#99757)
* Fix Freebox disk free space sensor

* Add initial value assert to check results
2023-09-07 10:28:08 +02:00
Maciej Bieniek
e1f4a3fa9f Add energy meter sensors for Shelly Pro EM (#99747)
* Add support for Pro EM

* Improve get_rpc_channel_name()

* Revert an unintended change

* Add tests
2023-09-07 06:59:04 +02:00
J. Nick Koston
0c7e0f5cd9 Bump sense_energy to 0.12.1 (#99763) 2023-09-06 20:01:22 -05:00
Aaron Bach
2565f153cd Bump aiorecollect to 2023.09.0 (#99780) 2023-09-06 17:26:14 -06:00
Joost Lekkerkerker
3afdecd51f Use shorthand attributes in Plum (#99770)
Use shorthand attributes in Plum shorthand
2023-09-06 23:37:31 +02:00
Joost Lekkerkerker
61b02e9c66 Use shorthand attributes in Progetti (#99772)
Use shorthand attributes in Progetti shorthand
2023-09-06 23:34:39 +02:00
Joost Lekkerkerker
b0e46f425f Remove deprecated entities from OpenTherm Gateway (#99712) 2023-09-06 21:50:48 +02:00
J. Nick Koston
533350b94a Bump dbus-fast to 1.95.0 (#99749) 2023-09-06 13:21:21 -05:00
J. Nick Koston
fdf902e053 Bump zeroconf to 0.98.0 (#99748) 2023-09-06 12:37:42 -05:00
Jan Bouwhuis
7c7456df99 Handle alexa invalid climate temp adjustment (#99740)
* Handle temp adjust when target state not set

* Update homeassistant/components/alexa/errors.py

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

* black

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-06 18:54:16 +02:00
Jan-Philipp Benecke
7a6c8767b3 Improve typing of trend component (#99719)
* Some typing in trend component

* Add missing type hint

* Enable strict typing on trend
2023-09-06 18:51:38 +02:00
Tomáš Holý
9bc07f50f9 Add additional fields for 3-phase UPS to nut (#98625)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-06 11:39:33 -05:00
mkmer
54d92b649b Raise error on open/close failure in Aladdin Connect (#99746)
Raise error on open/close failure
2023-09-06 18:33:58 +02:00
James Smith
f24c4ceab6 Enable strict typing for Climate component (#99301)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-06 17:55:41 +02:00
Marc Mueller
8bfdc5d3d9 Update pytest-aiohttp to 1.0.5 (#99744) 2023-09-06 17:37:11 +02:00
Joost Lekkerkerker
eab76fc621 Revert "Bump pyoverkiz to 1.10.1 (#97916)" (#99742) 2023-09-06 17:16:40 +02:00
Bram Kragten
f70469d6ef 2023.9.0 (#99741) 2023-09-06 17:16:35 +02:00
Marc Mueller
ab3bc1b74b Improve blink config_flow typing (#99579) 2023-09-06 17:00:16 +02:00
Marc Mueller
2628a86864 Update pre-commit to 3.4.0 (#99737) 2023-09-06 16:58:57 +02:00
Marc Mueller
d8035ddf47 Fix tradfri asyncio.wait (#99730) 2023-09-06 16:57:13 +02:00
Marc Mueller
5d54660802 Fix asyncio.wait typing (#99726) 2023-09-06 16:53:41 +02:00
David Knowles
0b95e4ac17 Fix the Hydrawise status sensor (#99271) 2023-09-06 16:51:27 +02:00
Bram Kragten
d369a70092 Bumped version to 2023.9.0 2023-09-06 16:09:56 +02:00
Bram Kragten
02fc735c08 Update frontend to 20230906.1 (#99733) 2023-09-06 16:09:06 +02:00
Erik Montnemery
b5d9014bbd Correct state attributes in group helper preview (#99723) 2023-09-06 16:09:05 +02:00
Erik Montnemery
d99e5e0c4f Correct state attributes in template helper preview (#99722) 2023-09-06 16:09:03 +02:00
Erik Montnemery
6f6306b39b Don't allow changing device class in template binary sensor options (#99720) 2023-09-06 16:09:02 +02:00
Erik Montnemery
067f946129 Send template render errors to template helper preview (#99716) 2023-09-06 16:09:01 +02:00
starkillerOG
107ca83d42 Reolink onvif not supported fix (#99714)
* only subscibe to ONVIF if supported

* Catch NotSupportedError when ONVIF is not supported

* fix styling
2023-09-06 16:09:00 +02:00
Erik Montnemery
c9a6ea94a7 Send template render errors to template helper preview (#99716) 2023-09-06 16:07:05 +02:00
Erik Montnemery
e1ea53e72f Correct state attributes in template helper preview (#99722) 2023-09-06 16:06:33 +02:00
Erik Montnemery
c376447ccd Don't allow changing device class in template binary sensor options (#99720) 2023-09-06 15:59:30 +02:00
Erik Montnemery
97710dc5b7 Correct state attributes in group helper preview (#99723) 2023-09-06 15:59:03 +02:00
David Knowles
bb765449eb Add binary_sensor to Schlage (#99637)
* Add binary_sensor to Schlage

* Apply suggestions from code review

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2023-09-06 15:03:54 +02:00
Bram Kragten
9700888df1 Update frontend to 20230906.1 (#99733) 2023-09-06 15:00:26 +02:00
starkillerOG
0037385336 Reolink onvif not supported fix (#99714)
* only subscibe to ONVIF if supported

* Catch NotSupportedError when ONVIF is not supported

* fix styling
2023-09-06 14:46:24 +02:00
Jan Bouwhuis
397952ceea Postpone Imap_email_content removal (#99721) 2023-09-06 12:45:46 +02:00
Jan Bouwhuis
b815ea1332 Revert "Remove imap_email_content integration" (#99713) 2023-09-06 11:54:18 +02:00
Marc Mueller
274507b5c9 Fix pylint plugin test DeprecationWarning (#99711) 2023-09-06 11:35:57 +02:00
J. Nick Koston
034fabe188 Use loop time to set context (#99701)
* Use loop time to set context

loop time is faster than utcnow, and since its only used internally it can
be switched without a breaking change

* fix mocking
2023-09-06 11:04:49 +02:00
Bram Kragten
98896834cd Bump version to 2023.9.0b6 2023-09-06 11:00:01 +02:00
Bram Kragten
800ff489b0 Update frontend to 20230906.0 (#99715) 2023-09-06 10:56:53 +02:00
Erik Montnemery
7b7fd35af2 Fix unit conversion for gas cost sensor (#99708) 2023-09-06 10:56:53 +02:00
J. Nick Koston
f9ee18352d Bump aioesphomeapi to 16.0.5 (#99698)
changelog: https://github.com/esphome/aioesphomeapi/compare/v16.0.4...v16.0.5

fixes `RuntimeError: set changed size during iteration`

https://github.com/esphome/aioesphomeapi/pull/538

some added debug logging which may help with https://github.com/home-assistant/core/issues/98221
2023-09-06 10:56:52 +02:00
Robert Svensson
e486ad735d Bump aiounifi to v61 (#99686)
* Bump aiounifi to v61

* Alter a test to cover the upstream change
2023-09-06 10:56:51 +02:00
Daniel Gangl
cea1109e25 Bump zamg to 0.3.0 (#99685) 2023-09-06 10:56:50 +02:00
c0ffeeca7
71afa0ff43 Yellow LED controls: rename LEDs (#99710)
- reorder, to reflect placement on board, left to right (yellow, green, red)
2023-09-06 10:46:52 +02:00
starkillerOG
96e932dad6 Bump reolink_aio to 0.7.9 (#99680) 2023-09-06 10:43:30 +02:00
puddly
aa32b658b2 Fix ZHA startup creating entities with non-unique IDs (#99679)
* Make the ZHAGateway initialization restartable so entities are unique

* Add a unit test
2023-09-06 10:43:29 +02:00
Erik Montnemery
0cbcacbbf5 Include template listener info in template preview (#99669) 2023-09-06 10:43:28 +02:00
Erik Montnemery
9d87e8d02b Allow specifying a custom log function for template render (#99572)
* Allow specifying a custom log function for template render

* Bypass template cache when reporting errors + fix tests

* Send errors as events

* Fix logic for creating new TemplateEnvironment

* Add strict mode back

* Only send error events if report_errors is True

* Force test of websocket_api only

* Debug test

* Run pytest with higher verbosity

* Timeout after 1 minute, enable syslog output

* Adjust timeout

* Add debug logs

* Fix unsafe call to WebSocketHandler._send_message

* Remove debug code

* Improve test coverage

* Revert accidental change

* Include severity in error events

* Remove redundant information from error events
2023-09-06 10:43:27 +02:00
Bram Kragten
00ada69e0b Update frontend to 20230906.0 (#99715) 2023-09-06 10:40:05 +02:00
Erik Montnemery
687e69f7c3 Fix unit conversion for gas cost sensor (#99708) 2023-09-06 10:35:04 +02:00
Erik Montnemery
48f7924e9e Allow specifying a custom log function for template render (#99572)
* Allow specifying a custom log function for template render

* Bypass template cache when reporting errors + fix tests

* Send errors as events

* Fix logic for creating new TemplateEnvironment

* Add strict mode back

* Only send error events if report_errors is True

* Force test of websocket_api only

* Debug test

* Run pytest with higher verbosity

* Timeout after 1 minute, enable syslog output

* Adjust timeout

* Add debug logs

* Fix unsafe call to WebSocketHandler._send_message

* Remove debug code

* Improve test coverage

* Revert accidental change

* Include severity in error events

* Remove redundant information from error events
2023-09-06 10:03:35 +02:00
Jan-Philipp Benecke
f41b045244 Use shorthand attributes in Trend (#99695) 2023-09-06 09:55:25 +02:00
Erik Montnemery
cdca4591a4 Include template listener info in template preview (#99669) 2023-09-06 09:49:42 +02:00
Jan-Philipp Benecke
b28fda2433 Move template coordinator to its own file (#99419)
* Move template update coordinator to its own file

* Add coordinator.py to .coveragerc

* Remove coordinator.py to .coveragerc

* Apply suggestions from code review

* Update homeassistant/components/template/coordinator.py

* Copy over fixes from upstream

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2023-09-06 08:54:25 +02:00
tronikos
d4ef570b0a Add a comment why state_class=total (#99703) 2023-09-06 08:43:46 +02:00
Rami Mosleh
d523734db1 Display channel number in Bravia TV if title is not available (#99567)
Display channel number if title is not available
2023-09-06 08:35:34 +02:00
Maciej Bieniek
d9a1ebafdd Show OTA update progress for Shelly gen2 devices (#99534)
* Show OTA update progress

* Use an event listener instead of a dispatcher

* Add tests

* Fix name

* Improve tests coverage

* Fix subscribe/unsubscribe logic

* Use async_on_remove()
2023-09-06 08:17:45 +02:00
Joost Lekkerkerker
4f05e61072 Add codeowner for Withings (#99681) 2023-09-05 21:14:56 -05:00
J. Nick Koston
da45f6cbb0 Bump aioesphomeapi to 16.0.5 (#99698)
changelog: https://github.com/esphome/aioesphomeapi/compare/v16.0.4...v16.0.5

fixes `RuntimeError: set changed size during iteration`

https://github.com/esphome/aioesphomeapi/pull/538

some added debug logging which may help with https://github.com/home-assistant/core/issues/98221
2023-09-05 20:42:50 -05:00
J. Nick Koston
e22b03d6b3 Switch homekit config flow sorted to use itemgetter (#99658)
Avoids unnecessary lambda
2023-09-05 21:18:46 -04:00
J. Nick Koston
a2dae60170 Refactor dispatcher to reduce run time and memory overhead (#99676)
* Fix memory leak in dispatcher removal

When we removed the last job/callable from the dict for the
signal we did not remove the dict for the signal which meant
it leaked

* comment

* cleanup a bit more
2023-09-05 21:18:27 -04:00
J. Nick Koston
b69cc29a78 Switch lambda to attrgetter in zha (#99660) 2023-09-05 22:45:45 +02:00
J. Nick Koston
a1359c1ce3 Replace lambda in script/gen_requirements_all.py with str.lower (#99665) 2023-09-05 22:44:59 +02:00
Jan Bouwhuis
c64d173fcb Remove imap_email_content integration (#99484) 2023-09-05 21:50:51 +02:00
starkillerOG
3f3d8b1e1e Bump reolink_aio to 0.7.9 (#99680) 2023-09-05 21:21:27 +02:00
Daniel Gangl
2cf25ee9ec Bump zamg to 0.3.0 (#99685) 2023-09-05 21:18:06 +02:00
Daniel Hjelseth Høyer
a9c41f76e3 Bump millheater to 0.11.2 (#99683)
Update Mill lib

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2023-09-05 21:14:39 +02:00
Robert Svensson
b0e40d95ad Bump aiounifi to v61 (#99686)
* Bump aiounifi to v61

* Alter a test to cover the upstream change
2023-09-05 21:13:28 +02:00
puddly
7ab1913ba4 Fix ZHA startup creating entities with non-unique IDs (#99679)
* Make the ZHAGateway initialization restartable so entities are unique

* Add a unit test
2023-09-05 20:30:28 +02:00
Bram Kragten
6b8027019b Bump version to 2023.9.0b5 2023-09-05 20:25:02 +02:00
Bram Kragten
fed84ebc40 Update frontend to 20230905.0 (#99677) 2023-09-05 20:24:51 +02:00
Raman Gupta
bd0fd9db77 Bump zwave-js-server-python to 0.51.1 (#99652)
* Bump zwave-js-server-python to 0.51.1

* Update test

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-05 20:24:50 +02:00
J. Nick Koston
5d1fe0eb00 Fix mobile app dispatcher performance (#99647)
Fix mobile app thundering heard

The mobile_app would setup a dispatcher to listener for updates on
every entity and reject the ones that were not for the unique id
that it was intrested in.

Instead we now register for a signal per unique id since we were
previously generating O(entities*sensors*devices) callbacks which
was causing the event loop to stall when there were a large
number of mobile app users.
2023-09-05 20:24:49 +02:00
itpeters
9e03f8a8d6 Fix long press event for matter generic switch (#99645) 2023-09-05 20:24:48 +02:00
Álvaro Fernández Rojas
c040672cab Update aioairzone to v0.6.8 (#99644)
* Update aioairzone to v0.6.8

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>

* Trigger CI

---------

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2023-09-05 20:24:47 +02:00
G Johansson
f0cf539e15 Fix missing unique id in SQL (#99641) 2023-09-05 20:24:46 +02:00
G Johansson
2a7c12013f Fix not stripping no device class in template helper binary sensor (#99640)
Strip none template helper binary sensor
2023-09-05 20:24:45 +02:00
Erik Montnemery
4c0e4fe745 Small cleanup of TemplateEnvironment (#99571)
* Small cleanup of TemplateEnvironment

* Fix typo
2023-09-05 20:24:44 +02:00
Bram Kragten
7fbb1c0fb6 Update frontend to 20230905.0 (#99677) 2023-09-05 20:12:40 +02:00
Joost Lekkerkerker
5ccf866e22 Use shorthand attributes for Plaato (#99634)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-05 19:01:51 +02:00
J. Nick Koston
e9062bb1b3 Replace lambda with attrgetter in homekit_controller (#99666) 2023-09-05 10:36:43 -05:00
J. Nick Koston
abb0537928 Replace lambda with itemgetter in script/gen_requirements_all.py (#99661) 2023-09-05 10:36:01 -05:00
J. Nick Koston
a04c61e77b Replace lambda with attrgetter in device_tracker device_trigger (#99663) 2023-09-05 16:41:35 +02:00
J. Nick Koston
035fea3ee0 Replace lambda with attrgetter in hassfest (#99662) 2023-09-05 16:40:25 +02:00
Joost Lekkerkerker
2c45d43e7b Use shorthand attributes in Neato (#99605)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-05 16:33:46 +02:00
Raman Gupta
5afba6327c Bump zwave-js-server-python to 0.51.1 (#99652)
* Bump zwave-js-server-python to 0.51.1

* Update test

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-05 09:58:32 -04:00
Joost Lekkerkerker
c6bdc380b6 Use shorthand attributes in Ondilo ico (#99627) 2023-09-05 15:40:43 +02:00
Joost Lekkerkerker
3c82045289 Use shorthand attributes in Omnilogic (#99626) 2023-09-05 15:40:11 +02:00
Joost Lekkerkerker
58af0ab0cd Use shorthand attributes in NZBGet (#99622) 2023-09-05 15:37:00 +02:00
Joost Lekkerkerker
0ae12ad08f Use shorthand attributes in Logi circle (#99592) 2023-09-05 15:27:38 +02:00
Joost Lekkerkerker
1f648feaef Use shorthand attributes in Kostal Plenticore (#99581) 2023-09-05 15:26:23 +02:00
Joost Lekkerkerker
447a9f4aad Use shorthand attributes in Konnected (#99580) 2023-09-05 15:25:00 +02:00
Joost Lekkerkerker
c49f086790 Use shorthand attributes in Kodi (#99578) 2023-09-05 15:22:52 +02:00
Joost Lekkerkerker
d5ad01ffbe Use shorthand attributes in Openhome (#99629) 2023-09-05 14:57:26 +02:00
itpeters
582eeea082 Fix long press event for matter generic switch (#99645) 2023-09-05 13:10:14 +02:00
Álvaro Fernández Rojas
c77a0a8caa Update aioairzone to v0.6.8 (#99644)
* Update aioairzone to v0.6.8

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>

* Trigger CI

---------

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2023-09-05 12:42:19 +02:00
Joost Lekkerkerker
f13e7706ed Use shorthand attributes in Nuheat (#99618) 2023-09-05 11:54:53 +02:00
dependabot[bot]
2c3a4b3497 Bump actions/checkout from 3.6.0 to 4.0.0 (#99651) 2023-09-05 08:57:09 +02:00
Joost Lekkerkerker
49bd7e6251 Use shorthand attributes for Picnic (#99633) 2023-09-04 20:59:44 -04:00
J. Nick Koston
fed1cab847 Fix mobile app dispatcher performance (#99647)
Fix mobile app thundering heard

The mobile_app would setup a dispatcher to listener for updates on
every entity and reject the ones that were not for the unique id
that it was intrested in.

Instead we now register for a signal per unique id since we were
previously generating O(entities*sensors*devices) callbacks which
was causing the event loop to stall when there were a large
number of mobile app users.
2023-09-04 20:56:34 -04:00
J. Nick Koston
ff2e0c570b Improve performance of google assistant supported checks (#99454)
* Improve performance of google assistant supported checks

* tweak

* tweak

* split function

* tweak
2023-09-04 20:53:59 -04:00
J. Nick Koston
63273a307a Fix Bluetooth passive update processor dispatching updates to unchanged entities (#99527)
* Fix passive update processor dispatching updates to unchanged entities

* adjust tests

* coverage

* fix

* Update homeassistant/components/bluetooth/update_coordinator.py
2023-09-04 20:42:05 -04:00
Martin Hjelmare
0b383067ef Move non legacy stt models out from legacy module (#99582) 2023-09-04 16:51:57 -04:00
J. Nick Koston
d2a52230ff Speed up responding to states being polled via API (#99621)
* Speed up responding to states being polled via API

Switch to using `as_dict_json` to avoid serializing states over and over when the
states api is polled since the mobile app is already building the cache as it also
polls the states via the websocket_api

* Speed up responding to states being polled via API

Switch to using `as_dict_json` to avoid serializing states over and over when the
states api is polled since the mobile app is already building the cache as it also
polls the states via the websocket_api

* fix json

* cover
2023-09-04 16:51:19 -04:00
G Johansson
47c20495bd Fix not stripping no device class in template helper binary sensor (#99640)
Strip none template helper binary sensor
2023-09-04 22:46:19 +02:00
Joost Lekkerkerker
216a174cba Move variables out of constructor in nightscout (#99612)
* Move variables out of constructor in nightscout

* Update homeassistant/components/nightscout/sensor.py

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

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2023-09-04 22:35:58 +02:00
G Johansson
b8f35fb577 Fix missing unique id in SQL (#99641) 2023-09-04 22:31:53 +02:00
Erik Montnemery
de73cafc8b Small cleanup of TemplateEnvironment (#99571)
* Small cleanup of TemplateEnvironment

* Fix typo
2023-09-04 22:19:40 +02:00
Joost Lekkerkerker
bc1575a477 Move variables out of constructor in Nobo hub (#99617) 2023-09-04 22:18:36 +02:00
J. Nick Koston
cab9c97598 Bump aioesphomeapi to 16.0.4 (#99541) 2023-09-04 21:06:13 +02:00
Joakim Plate
ba5822bed4 Bump gardena_bluetooth to 1.4.0 (#99530) 2023-09-04 21:06:11 +02:00
Bram Kragten
4fcb0a840a Bump version to 2023.9.0b4 2023-09-04 20:50:17 +02:00
Bram Kragten
6b988a99d5 Update frontend to 20230904.0 (#99636) 2023-09-04 20:49:43 +02:00
Erik Montnemery
0520cadfa6 Revert "Deprecate timer start optional duration parameter" (#99613)
Revert "Deprecate timer start optional duration parameter (#93471)"

This reverts commit 2ce5b08fc3.
2023-09-04 20:49:42 +02:00
Joost Lekkerkerker
89e280e136 Remove unneeded name property from Logi Circle (#99604) 2023-09-04 20:49:41 +02:00
Joost Lekkerkerker
30c6565205 Bump pyenphase to 1.9.1 (#99574) 2023-09-04 20:49:40 +02:00
Erik Montnemery
37f8f91171 Small cleanup of WS command render_template (#99562) 2023-09-04 20:49:40 +02:00
puddly
a7efeb2c87 Bump ZHA dependencies (#99561) 2023-09-04 20:49:39 +02:00
Robert Svensson
5c42ea57b3 Bump aiounifi to v60 (#99548) 2023-09-04 20:49:38 +02:00
G Johansson
c791ddc937 Fix loading filesize coordinator from wrong place (#99547)
* Fix loading filesize coordinator from wrong place

* aboslute in executor

* combine into executor
2023-09-04 20:49:37 +02:00
Jc2k
8ccd2b6457 Update bluetooth-data-tools to 1.11.0 (#99485) 2023-09-04 20:48:55 +02:00
J. Nick Koston
a60e23caf2 Bump bleak-retry-connector to 3.1.2 (#99540) 2023-09-04 20:45:32 +02:00
jan iversen
c677dae9c1 Modbus switch, allow restore "unknown" (#99533) 2023-09-04 20:45:32 +02:00
J. Nick Koston
453c5f90f8 Bump bleak to 0.21.0 (#99520)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-04 20:45:31 +02:00
J. Nick Koston
70b460f52b Bump aiohomekit to 3.0.2 (#99514) 2023-09-04 20:45:29 +02:00
J. Nick Koston
2bc08d1fcc Fix module check in _async_get_flow_handler (#99509)
We should have been checking for the module in hass.data[DATA_COMPONENTS]
and not hass.config.components as the check was ineffective if there were
no existing integrations instances for the domain which is the case for
discovery or when the integration is ignored
2023-09-04 20:45:29 +02:00
Erik Montnemery
423e8fbde3 Validate state in template helper preview (#99455)
* Validate state in template helper preview

* Deduplicate state validation
2023-09-04 20:45:28 +02:00
Erik Montnemery
e5fd6961a8 Set state of entity with invalid state to unknown (#99452)
* Set state of entity with invalid state to unknown

* Add test

* Apply suggestions from code review

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

* Update test_entity.py

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-04 20:45:27 +02:00
Mike O'Driscoll
bdc39e1d52 Fix recollect_waste month time boundary issue (#99429) 2023-09-04 20:45:26 +02:00
Tiit Rätsep
852589f025 Fix battery reading in SOMA API (#99403)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-04 20:45:25 +02:00
Erik Montnemery
2a5f8ee4a7 Don't set assumed_state in fan groups (#99399) 2023-09-04 20:45:24 +02:00
Erik Montnemery
1c2c13c938 Don't set assumed_state in cover groups (#99391) 2023-09-04 20:45:23 +02:00
Russell Cloran
e0594bffa1 Enumerate available states in Prometheus startup (#97993) 2023-09-04 20:45:22 +02:00
Michael
4524b38b80 Mark AVM Fritz!Smarthome as Gold integration (#97086)
set quality scale to gold
2023-09-04 20:45:22 +02:00
Allen Porter
269bcac982 Extend template entities with a script section (#96175)
* Extend template entities with a script section

This allows making a trigger entity that triggers a few times a day,
and allows collecting data from a service resopnse which can be
fed into a template entity.

The current alternatives are to publish and subscribe to events or to
store data in input entities.

* Make variables set in actions accessible to templates

* Format code

---------

Co-authored-by: Erik <erik@montnemery.com>
2023-09-04 20:45:21 +02:00
Bram Kragten
c1cfded355 Update frontend to 20230904.0 (#99636) 2023-09-04 14:44:20 -04:00
Michael
a77f1cbd9e Mark AVM Fritz!Smarthome as Gold integration (#97086)
set quality scale to gold
2023-09-04 14:23:46 -04:00
J. Nick Koston
e5ebba0753 Fix module check in _async_get_flow_handler (#99509)
We should have been checking for the module in hass.data[DATA_COMPONENTS]
and not hass.config.components as the check was ineffective if there were
no existing integrations instances for the domain which is the case for
discovery or when the integration is ignored
2023-09-04 14:19:10 -04:00
Erik Montnemery
7e36da4cc0 Small cleanup of WS command render_template (#99562) 2023-09-04 14:17:30 -04:00
Erik Montnemery
26fd36dc4c Revert "Deprecate timer start optional duration parameter" (#99613)
Revert "Deprecate timer start optional duration parameter (#93471)"

This reverts commit 2ce5b08fc3.
2023-09-04 20:10:16 +02:00
David Knowles
e57ed26896 Bump pyschlage to 2023.9.0 (#99624) 2023-09-04 19:51:33 +02:00
Joost Lekkerkerker
4812b21ffd Remove slugify from tomorrowio unique id (#99006) 2023-09-04 19:28:44 +02:00
Joost Lekkerkerker
cb5d4ee6fa Use shorthand attributes in Octoprint (#99623) 2023-09-04 19:00:19 +02:00
Joost Lekkerkerker
2391087836 Use shorthand attributes in Nest (#99606) 2023-09-04 09:50:33 -07:00
Joost Lekkerkerker
22e90a5755 Remove default state from Nibe (#99611)
Remove start state
2023-09-04 17:53:33 +02:00
Rami Mosleh
f2e0ff4f0f Bump simplepush api to 2.2.3 (#99599) 2023-09-04 16:24:20 +02:00
Duco Sebel
aa943b7103 Bumb python-homewizard-energy to 2.1.0 (#99598) 2023-09-04 16:21:55 +02:00
Joost Lekkerkerker
29664d04d0 Use shorthand attributes in Mutesync (#99600) 2023-09-04 15:31:33 +02:00
Joost Lekkerkerker
799d0e591c Remove unneeded name property from Logi Circle (#99604) 2023-09-04 15:29:30 +02:00
puddly
c225ee89d6 Bump ZHA dependencies (#99561) 2023-09-04 09:26:14 -04:00
Joost Lekkerkerker
8dc05894a8 Use shorthand attributes in Nanoleaf (#99601) 2023-09-04 15:18:48 +02:00
Joost Lekkerkerker
f1bb7c25db Use shorthand attributes in Motion eye (#99596) 2023-09-04 15:18:22 +02:00
Joost Lekkerkerker
cab0bde37b Use shorthand attributes in Lyric (#99593) 2023-09-04 15:05:33 +02:00
Rami Mosleh
3b6811dab6 Use CONF_SALT correctly in config_flow validation (#99597) 2023-09-04 14:59:18 +02:00
Erik Montnemery
7643820e59 Add loader.async_get_loaded_integration (#99440)
* Add loader.async_get_loaded_integration

* Decorate async_get_loaded_integration with @callback
2023-09-04 14:12:33 +02:00
Erik Montnemery
7c595ee2da Validate state in template helper preview (#99455)
* Validate state in template helper preview

* Deduplicate state validation
2023-09-04 14:10:43 +02:00
Erik Montnemery
709ce7e0af Set state of entity with invalid state to unknown (#99452)
* Set state of entity with invalid state to unknown

* Add test

* Apply suggestions from code review

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

* Update test_entity.py

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-04 14:09:51 +02:00
Erik Montnemery
6223af1899 Don't set assumed_state in fan groups (#99399) 2023-09-04 14:08:50 +02:00
Erik Montnemery
f3d8a0eaaf Don't set assumed_state in cover groups (#99391) 2023-09-04 14:08:38 +02:00
Joost Lekkerkerker
d5301fba90 Use shorthand attributes in Keenetic (#99577) 2023-09-04 13:50:05 +02:00
Joost Lekkerkerker
6194f7faea Bump pyenphase to 1.9.1 (#99574) 2023-09-04 07:39:24 -04:00
Joost Lekkerkerker
cf2d3674b9 Use shorthand attributes in Kulersky (#99583) 2023-09-04 13:29:56 +02:00
Joost Lekkerkerker
8ea3b877f6 Use shorthand attributes in Juicenet (#99575) 2023-09-04 13:21:30 +02:00
Joost Lekkerkerker
890eed1121 Use shorthand attributes in LCN (#99587) 2023-09-04 13:18:55 +02:00
Joost Lekkerkerker
051e9e7498 Use shorthand attributes in Laundrify (#99586) 2023-09-04 13:15:02 +02:00
Jan-Philipp Benecke
fa0b61e96a Move london underground coordinator to its own file (#99550) 2023-09-04 11:07:08 +02:00
Tiit Rätsep
b9536732bc Fix battery reading in SOMA API (#99403)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-04 10:03:58 +02:00
J. Nick Koston
de1de926a9 Bump zeroconf to 0.97.0 (#99554)
changelog: https://github.com/python-zeroconf/python-zeroconf/compare/0.96.0...0.97.0
2023-09-04 10:52:21 +03:00
Russell Cloran
9144ef7ed8 Enumerate available states in Prometheus startup (#97993) 2023-09-04 09:30:56 +02:00
Joost Lekkerkerker
69117cb8e3 Use shorthand attributes for DLNA dmr (#99236) 2023-09-04 09:23:33 +02:00
Joost Lekkerkerker
13ebb68b84 Use shorthand attributes in Home connect (#99385)
Co-authored-by: Robert Resch <robert@resch.dev>
2023-09-04 09:15:25 +02:00
Joost Lekkerkerker
f4f98010f9 Remove unused attributes from Econet (#99242) 2023-09-04 09:15:01 +02:00
Joost Lekkerkerker
f545389549 Move static shorthand devolo attributes outside of constructor (#99234)
Co-authored-by: Guido Schmitz <Shutgun@users.noreply.github.com>
2023-09-04 09:08:32 +02:00
Rami Mosleh
8d3828ae54 Add strict typing to glances (#99537) 2023-09-04 09:07:15 +02:00
Joost Lekkerkerker
1dc724274e Use shorthand attributes for Heos (#99344) 2023-09-04 09:05:59 +02:00
G Johansson
9d6cab8fe6 Fix loading filesize coordinator from wrong place (#99547)
* Fix loading filesize coordinator from wrong place

* aboslute in executor

* combine into executor
2023-09-04 07:33:46 +02:00
Marc Mueller
735b5cf1a0 Fix sql test warning (#99556) 2023-09-03 19:58:13 -05:00
Marc Mueller
115518cab9 Fix tolo test warning (#99555) 2023-09-03 19:58:01 -05:00
J. Nick Koston
377d9f6687 Bump zeroconf to 0.96.0 (#99549) 2023-09-03 17:06:21 -05:00
Allen Porter
8afab4845a Remove nest legacy service descriptions and translations (#99510) 2023-09-03 13:52:03 -07:00
Robert Svensson
f52ba7042d Bump aiounifi to v60 (#99548) 2023-09-03 21:31:25 +02:00
jan iversen
f85a3861f2 Make validator for modbus table controlled (#99092) 2023-09-03 21:04:58 +02:00
J. Nick Koston
7931d74938 Make bond BPUP callback a HassJob (#99470) 2023-09-03 12:39:49 -05:00
Rami Mosleh
ca44242095 Allow glances entries with same IP but different ports (#99536) 2023-09-03 19:22:59 +02:00
jan iversen
d19f617c25 Modbus switch, allow restore "unknown" (#99533) 2023-09-03 17:48:25 +02:00
Allen Porter
c938b9e7a3 Rename nest test_sensor_sdm.py to test_sensor.py (#99512) 2023-09-03 10:36:20 -05:00
jan iversen
c94d4f501b Read modbus data before scan_interval (#99243)
Read before scan_interval.
2023-09-03 17:13:49 +02:00
Mike O'Driscoll
c297eecb68 Fix recollect_waste month time boundary issue (#99429) 2023-09-03 10:08:17 -05:00
J. Nick Koston
186e796e25 Speed up fetching states by domain (#99467) 2023-09-03 09:30:39 -05:00
J. Nick Koston
b752419f25 Bump aioesphomeapi to 16.0.4 (#99541) 2023-09-03 09:13:34 -05:00
J. Nick Koston
d063650fec Bump bleak-retry-connector to 3.1.2 (#99540) 2023-09-03 09:13:21 -05:00
Rami Mosleh
8e22041ee9 Change calculation methods to a fixed list (#99535) 2023-09-03 16:12:37 +02:00
J. Nick Koston
8843a445c9 Reduce Bluetooth coordinator/processor overhead (#99526) 2023-09-03 08:59:15 -05:00
Yuxin Wang
9bba501057 Handle gracefully when unloading apcupsd config entries (#99513) 2023-09-03 15:54:00 +02:00
Michael Arthur
31d1752c74 Bugfix: Electric Kiwi reduce interval so oauth doesn't expire (#99489)
decrease interval time as EK have broken/changed their oauth again
2023-09-03 15:53:23 +02:00
J. Nick Koston
00893bbf14 Bump bleak to 0.21.0 (#99520)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-09-03 08:22:03 -05:00
J. Nick Koston
5f487b5d85 Refactor async_call_at and async_call_later event helpers to avoid creating closures (#99469) 2023-09-03 08:19:06 -05:00
Jc2k
1cd0cb4537 Add suggest_display_precision to private_ble_device (#99529) 2023-09-03 07:39:20 -05:00
Marc Mueller
6414248bee Update pytest warning filter (#99521) 2023-09-03 13:04:01 +02:00
J. Nick Koston
1183bd159e Bump zeroconf to 0.93.1 (#99516)
* Bump zeroconf to 0.92.0

changelog: https://github.com/python-zeroconf/python-zeroconf/compare/0.91.1...0.92.0

* drop unused argument

* Update tests/components/thread/test_diagnostics.py

* lint

* again

* bump again since actions failed to release the wheels
2023-09-03 11:16:26 +02:00
Joakim Plate
61dc217d92 Bump gardena_bluetooth to 1.4.0 (#99530) 2023-09-03 10:25:00 +02:00
Allen Porter
7b1c0c2df2 Extend template entities with a script section (#96175)
* Extend template entities with a script section

This allows making a trigger entity that triggers a few times a day,
and allows collecting data from a service resopnse which can be
fed into a template entity.

The current alternatives are to publish and subscribe to events or to
store data in input entities.

* Make variables set in actions accessible to templates

* Format code

---------

Co-authored-by: Erik <erik@montnemery.com>
2023-09-02 16:19:45 -07:00
Marc Mueller
6312f34538 Fix zha test RuntimeWarning (#99519) 2023-09-03 01:07:17 +02:00
Jc2k
4b11a632a1 Add sensors to private_ble_device (#99515) 2023-09-02 17:45:46 -05:00
J. Nick Koston
b8f8cd1797 Reduce overhead to retry config entry setup (#99471) 2023-09-02 16:46:53 -05:00
Richard Kroegel
bec36d3914 Add long-term statistics to BMW sensors (#99506)
* Add long-term statistics to BMW ConnectedDrive sensors

* Add sensor test snapshot

---------

Co-authored-by: rikroe <rikroe@users.noreply.github.com>
2023-09-02 14:44:28 -07:00
J. Nick Koston
f4f78cf000 Bump aiohomekit to 3.0.2 (#99514) 2023-09-02 15:25:42 -05:00
starkillerOG
cf8da2fc89 Motion blinds add translations (#99078) 2023-09-02 22:13:17 +02:00
starkillerOG
3c30ad1850 Motion blinds duplication reduction using entity baseclass (#99444) 2023-09-02 21:51:58 +02:00
Bram Kragten
7b50316b3e Bump version to 2023.9.0b3 2023-09-02 21:09:52 +02:00
J. Nick Koston
46343bc261 Bump zeroconf to 0.91.1 (#99490) 2023-09-02 21:09:19 +02:00
Andrew Onyshchuk
e726b49adb Update aiotractive to 0.5.6 (#99477) 2023-09-02 21:09:19 +02:00
G Johansson
cb1267477b Fix default language in Workday (#99463)
Workday fix default language
2023-09-02 21:09:17 +02:00
jimmyd-be
caaba5d422 Fix translation bug Renson sensors (#99461)
* Fix translation bug

* Revert "Fix translation bug"

This reverts commit 84b5e90dac.

* Fixed translation of Renson sensor
2023-09-02 21:09:17 +02:00
Erik Montnemery
9fec0be173 Log unexpected exceptions causing recorder shutdown (#99445) 2023-09-02 21:09:16 +02:00
Raman Gupta
8dcc96c083 Fix device name in zwave_js repair flow (#99414) 2023-09-02 21:09:15 +02:00
starkillerOG
270be19e1a Check new IP of Reolink camera from DHCP (#99381)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-02 21:09:14 +02:00
Daniel Hjelseth Høyer
f0878addca Update Tibber library to 0.28.2 (#99115) 2023-09-02 21:09:13 +02:00
Russell Cloran
f573c1e27c Handle timestamp sensors in Prometheus integration (#98001) 2023-09-02 21:09:12 +02:00
J. Nick Koston
0b065b118b Bump zeroconf to 0.91.1 (#99490) 2023-09-02 21:04:13 +02:00
starkillerOG
834f3810d3 Check new IP of Reolink camera from DHCP (#99381)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-02 21:00:33 +02:00
J. Nick Koston
1ab2e900f9 Improve lingering timer checks (#99472) 2023-09-02 12:43:27 -05:00
Allen Porter
1048f47a91 Code cleanup for nest device info (#99511) 2023-09-02 19:38:41 +02:00
Jan Bouwhuis
c3841f8734 Rework on mqtt certificate tests (#99503)
* Shared fixture on TEMP_DIR_NAME mock in MQTT tests

* Improve mqtt certificate file tests

* Update tests/components/mqtt/test_util.py

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

* Update tests/components/mqtt/conftest.py

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

* Avoid blocking code

* typo in sub function

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-02 19:26:11 +02:00
J. Nick Koston
6974d211e5 Switch isy994 to use async_call_later (#99487)
async_track_point_in_utc_time is not needed here since we only need to call
at timedelta(hours=25)
2023-09-02 10:14:33 -07:00
J. Nick Koston
acd9cfa929 Speed up calls to the all states api (#99462) 2023-09-02 12:08:07 -05:00
J. Nick Koston
6e743a5bb2 Switch mqtt to use async_call_later where possible (#99486) 2023-09-02 11:55:11 -05:00
Erik Montnemery
defd9e4001 Don't compile missing statistics when running tests (#99446) 2023-09-02 10:09:46 -05:00
Erik Montnemery
7168e71860 Log unexpected exceptions causing recorder shutdown (#99445) 2023-09-02 09:51:06 -05:00
Joost Lekkerkerker
9e9aa163f7 Use shorthand attributes in hlk_sw16 (#99383) 2023-09-02 09:42:32 -05:00
Jc2k
26b1222fae Support tracking private bluetooth devices (#99465)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-09-02 09:21:05 -05:00
Daniel Hjelseth Høyer
d88ee0dbe0 Update Tibber library to 0.28.2 (#99115) 2023-09-02 15:08:49 +02:00
Paarth Shah
4d3b978398 Change matrix component to use matrix-nio instead of matrix_client (#72797) 2023-09-02 15:02:55 +02:00
Joost Lekkerkerker
f48e8623da Use shorthand attributes in Hunterdouglas powerview (#99386) 2023-09-02 04:55:19 -05:00
Jan Bouwhuis
3d1efaa4ad Freeze time for MQTT sensor expire tests (#99496) 2023-09-02 04:10:57 -05:00
jimmyd-be
1e46ecbb48 Fix translation bug Renson sensors (#99461)
* Fix translation bug

* Revert "Fix translation bug"

This reverts commit 84b5e90dac.

* Fixed translation of Renson sensor
2023-09-02 10:55:12 +02:00
Russell Cloran
5fd14eade5 Handle timestamp sensors in Prometheus integration (#98001) 2023-09-02 10:20:36 +02:00
G Johansson
b681dc06e0 Fix default language in Workday (#99463)
Workday fix default language
2023-09-02 09:47:59 +02:00
Jc2k
e465a4f820 Update bluetooth-data-tools to 1.11.0 (#99485) 2023-09-01 17:33:19 -05:00
J. Nick Koston
7c87b38a23 Reduce overhead to process and publish MQTT messages (#99457) 2023-09-01 15:41:34 -05:00
J. Nick Koston
5a8fc43212 Refactor MQTT discovery to avoid creating closure if hash already in discovery_pending_discovered (#99458) 2023-09-01 15:40:53 -05:00
Andrew Onyshchuk
04bf126425 Update aiotractive to 0.5.6 (#99477) 2023-09-01 23:28:53 +03:00
J. Nick Koston
09f45660cf Avoid linear search of MQTT SUPPORTED_COMPONENTS (#99459)
By making this a set we avoid the linear search in async_discovery_message_received
2023-09-01 20:10:47 +02:00
Jan-Philipp Benecke
cf59ea3c47 Use snapshot assertion for netatmo diagnostics test (#99159) 2023-09-01 19:27:54 +02:00
Richard Mikalsen
1e6cddaa1d Turn off Mill heaters using local API (#99348)
* Update mill_local

* Add ability to turn heater on and off

* Use OperationMode from upstream library

* Fix: compare against value
2023-09-01 19:05:35 +02:00
Raman Gupta
169a318ec4 Fix device name in zwave_js repair flow (#99414) 2023-09-01 18:06:37 +02:00
Bram Kragten
1f0b3c4e33 Bump version to 2023.9.0b2 2023-09-01 18:01:07 +02:00
Bram Kragten
528e8c0fe7 Update frontend to 20230901.0 (#99464) 2023-09-01 17:58:15 +02:00
Erik Montnemery
eb8d375e35 Fix template helper strings (#99456) 2023-09-01 17:58:15 +02:00
Keilin Bickar
987a959b19 Update asynsleepiq library to 1.3.7 (#99431) 2023-09-01 17:58:14 +02:00
Paul Bottein
469a72a5f9 Use common key for away mode state translations (#99425) 2023-09-01 17:58:13 +02:00
Álvaro Fernández Rojas
a95691f306 Update AEMET-OpenData to v0.4.4 (#99418)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2023-09-01 17:58:12 +02:00
J. Nick Koston
ebf42ad342 Significantly reduce overhead to filter event triggers (#99376)
* fast

* cleanups

* cleanups

* cleanups

* comment

* comment

* add more cover

* comment

* pull more examples from forums to validate cover
2023-09-01 17:58:11 +02:00
Michael
057daa5fdb Address late review for Nextcloud (#99226) 2023-09-01 17:58:10 +02:00
puddly
2ec9abfd24 Create a ZHA repair when directly accessing a radio with multi-PAN firmware (#98275)
* Add the SiLabs flasher as a dependency

* Create a repair if the wrong firmware is detected on an EZSP device

* Update homeassistant/components/zha/strings.json

Co-authored-by: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com>

* Provide the ZHA config entry as a reusable fixture

* Create a separate repair when using non-Nabu Casa hardware

* Add unit tests

* Drop extraneous `config_entry.add_to_hass` added in 021def44

* Fully unit test all edge cases

* Move `socket://`-ignoring logic into repair function

* Open a repair from ZHA flows when the wrong firmware is running

* Fix existing unit tests

* Link to the flashing section in the documentation

* Reduce repair severity to `ERROR`

* Make issue persistent

* Add unit tests for new radio probing states

* Add unit tests for new config flow steps

* Handle probing failure raising an exception

* Implement review suggestions

* Address review comments

---------

Co-authored-by: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com>
2023-09-01 17:58:09 +02:00
puddly
0bae0824b4 Initialize ZHA device database before connecting to the radio (#98082)
* Create ZHA entities before attempting to connect to the coordinator

* Delete the ZHA gateway object when unloading the config entry

* Only load ZHA groups if the coordinator device info is known offline

* Do not create a coordinator ZHA device until it is ready

* [WIP] begin fixing unit tests

* [WIP] Fix existing unit tests (one failure left)

* Fix remaining unit test
2023-09-01 17:58:08 +02:00
Bram Kragten
1d80af870d Update frontend to 20230901.0 (#99464) 2023-09-01 17:28:52 +02:00
Erik Montnemery
390c046537 Fix template helper strings (#99456) 2023-09-01 17:14:42 +02:00
Paul Bottein
ac0565e3bc Use common key for away mode state translations (#99425) 2023-09-01 15:58:01 +02:00
puddly
38270ee823 Create a ZHA repair when directly accessing a radio with multi-PAN firmware (#98275)
* Add the SiLabs flasher as a dependency

* Create a repair if the wrong firmware is detected on an EZSP device

* Update homeassistant/components/zha/strings.json

Co-authored-by: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com>

* Provide the ZHA config entry as a reusable fixture

* Create a separate repair when using non-Nabu Casa hardware

* Add unit tests

* Drop extraneous `config_entry.add_to_hass` added in 021def44

* Fully unit test all edge cases

* Move `socket://`-ignoring logic into repair function

* Open a repair from ZHA flows when the wrong firmware is running

* Fix existing unit tests

* Link to the flashing section in the documentation

* Reduce repair severity to `ERROR`

* Make issue persistent

* Add unit tests for new radio probing states

* Add unit tests for new config flow steps

* Handle probing failure raising an exception

* Implement review suggestions

* Address review comments

---------

Co-authored-by: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com>
2023-09-01 09:05:45 -04:00
rappenze
680775c3e0 Discover more power and energy sensors in fibaro integration (#98253) 2023-09-01 10:48:08 +02:00
Joost Lekkerkerker
65246b99ec Use shorthand attributes in iZone (#99397) 2023-09-01 10:34:09 +02:00
Joost Lekkerkerker
6c93865cee Use shorthand attributes in Insteon (#99392) 2023-09-01 10:13:34 +02:00
Jan-Philipp Benecke
bbc390837e Move airnow coordinator to its own file (#99423) 2023-09-01 08:29:07 +02:00
Keilin Bickar
dc4ed5fea9 Update asynsleepiq library to 1.3.7 (#99431) 2023-09-01 08:24:13 +02:00
Allen Porter
1539853c0a Update google-nest-sdm to 3.0.2 (#99175)
* Update google-nest-sdm to 3.0.2

* Fix device typing

* Update homeassistant/components/nest/device_info.py

Co-authored-by: jan iversen <jancasacondor@gmail.com>

---------

Co-authored-by: jan iversen <jancasacondor@gmail.com>
2023-08-31 20:33:36 -07:00
Joost Lekkerkerker
2dab9eaf86 Use shorthand attributes in Isy994 (#99395) 2023-08-31 19:58:40 -05:00
Keith Burzinski
5e03954e69 Add @kbx81 as esphome codeowner (#99427)
* Add @kbx81 as esphome codeowner

* Add @kbx81 as esphome codeowner, take 2
2023-08-31 23:50:25 +02:00
Álvaro Fernández Rojas
97d38f4ca5 Update AEMET-OpenData to v0.4.4 (#99418)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2023-08-31 21:59:01 +02:00
Michael
d5adf33225 Address late review for Nextcloud (#99226) 2023-08-31 20:35:11 +02:00
J. Nick Koston
0da94c20b0 Significantly reduce overhead to filter event triggers (#99376)
* fast

* cleanups

* cleanups

* cleanups

* comment

* comment

* add more cover

* comment

* pull more examples from forums to validate cover
2023-08-31 13:47:01 -04:00
Jan-Philipp Benecke
2e7018a152 Move tankerkoenig coordinator and base entity to its own file (#99416)
* Move tankerkoenig coordinator and entity to its own file

* Add coordinator.py and entity.py to .coveragerc
2023-08-31 19:39:17 +02:00
puddly
22c5071270 Initialize ZHA device database before connecting to the radio (#98082)
* Create ZHA entities before attempting to connect to the coordinator

* Delete the ZHA gateway object when unloading the config entry

* Only load ZHA groups if the coordinator device info is known offline

* Do not create a coordinator ZHA device until it is ready

* [WIP] begin fixing unit tests

* [WIP] Fix existing unit tests (one failure left)

* Fix remaining unit test
2023-08-31 12:09:46 -04:00
Erik Montnemery
80caeafcb5 Add documentation URL for homeassistant_yellow (#99336)
* Add documentation URL for homeassistant_yellow

* Fix test

* Tweak
2023-08-31 10:50:53 -04:00
Joakim Sørensen
7042a02d72 Add remote alias to connection info response (#99410) 2023-08-31 10:43:32 -04:00
Bram Kragten
875809a827 Update frontend to 20230831.0 (#99405) 2023-08-31 15:32:37 +02:00
Erik Montnemery
f36a300651 Improve template sensor config flow validation (#99373) 2023-08-31 15:16:32 +02:00
Paul Bottein
047f936d4c Add entity component translation for water heater away mode attribute (#99394) 2023-08-31 14:29:24 +02:00
Joost Lekkerkerker
7ead5c44ea Use shorthand attributes in iCloud (#99390)
* Use shorthand attributes in iCloud

* Use shorthand attributes in iCloud
2023-08-31 12:37:21 +02:00
Austin Brunkhorst
2c545ef3d2 Update pysnooz to 0.8.6 (#99368) 2023-08-31 11:15:45 +02:00
Erik Montnemery
35560e01b9 Add documentation URL for homeassistant_sky_connect (#99377) 2023-08-31 10:39:24 +02:00
G Johansson
0fd9327c46 Revert "Sonos add yaml config issue" (#99379)
Revert "Sonos add yaml config issue (#97365)"

This reverts commit 2299430dbe.
2023-08-31 10:24:03 +02:00
Joost Lekkerkerker
c25b3e55e4 Add entity translations to Mill (#96541) 2023-08-31 10:13:39 +02:00
Brett Adams
e08661dad3 Patch service validation in Aussie Broadband (#99077)
* Bump pyAussieBB

* rolling back to previous version

* patching the pydantic 2.x issue in aussie_broadband integration

* adding test for validate_service_type

* adding test for validate_service_type

* fixing tests, again

* adding additional test

* doing fixes for live tests

* Implement Feedback

* Add test to detect pydantic2

* Update test_init.py

* Update docstring

---------

Co-authored-by: James Hodgkinson <james@terminaloutcomes.com>
2023-08-31 09:45:44 +02:00
J. Nick Koston
a41af4e6d3 Revert orjson to 3.9.2 (#99374)
* Revert "Update orjson to 3.9.4 (#98108)"

This reverts commit 3dd377cb2a.

* Revert "Update orjson to 3.9.3 (#97930)"

This reverts commit d993aa59ea.
2023-08-31 09:33:57 +02:00
Jan-Philipp Benecke
70843862aa Address late review for bsblan (#99360)
* Address late review comment

* Break also comment
2023-08-31 07:31:05 +02:00
tronikos
343e8f0ecc Opower MFA fixes (#99317)
opower mfa fixes
2023-08-31 06:36:07 +02:00
Joost Lekkerkerker
99a65fb45b Collapse supported features list in Deconz (#99233)
* Use shorthand attributes for Deconz

* revert changes
2023-08-30 23:57:23 +02:00
Marc Mueller
cc9f0aaf80 Escape core version [ci] (#99364) 2023-08-30 23:56:25 +02:00
Jan-Philipp Benecke
5819091af7 Move octoprint coordinator to its own file (#99359)
Move octoprint coordinator to own file
2023-08-30 22:31:51 +02:00
Erik Montnemery
03b1c7ad1d Minor improvement in tests of hardware integrations (#99361) 2023-08-30 21:11:52 +02:00
b-uwe
cdd22bf0fa Revert "Remove the virtual integration for ultraloq" (#99302)
Revert "Remove the virtual integration for ultraloq (#96355)"

This reverts commit 56bc708b28.
2023-08-30 14:58:57 -04:00
puddly
5fd88f5874 Bump ZHA dependencies (#99341)
* Bump ZHA dependencies

* Include bellows as well
2023-08-30 14:56:19 -04:00
jan iversen
8a4e48532c Bump pymodbus v3.5.0 (#99343)
Bump pymodbus v3.5.0.
2023-08-30 20:26:13 +02:00
Erik Montnemery
8c04e4c7a3 Add explicit test of template config entry setup (#99345) 2023-08-30 19:56:34 +02:00
Joost Lekkerkerker
59b1d4ba69 Bump version to 2023.10.0dev0 (#99349) 2023-08-30 19:32:10 +02:00
1815 changed files with 108407 additions and 30731 deletions

View File

@@ -29,11 +29,13 @@ omit =
homeassistant/components/adguard/switch.py
homeassistant/components/ads/*
homeassistant/components/aemet/weather_update_coordinator.py
homeassistant/components/aftership/*
homeassistant/components/aftership/__init__.py
homeassistant/components/aftership/sensor.py
homeassistant/components/agent_dvr/alarm_control_panel.py
homeassistant/components/agent_dvr/camera.py
homeassistant/components/agent_dvr/helpers.py
homeassistant/components/airnow/__init__.py
homeassistant/components/airnow/coordinator.py
homeassistant/components/airnow/sensor.py
homeassistant/components/airq/__init__.py
homeassistant/components/airq/coordinator.py
@@ -44,6 +46,7 @@ omit =
homeassistant/components/airthings_ble/sensor.py
homeassistant/components/airtouch4/__init__.py
homeassistant/components/airtouch4/climate.py
homeassistant/components/airtouch4/coordinator.py
homeassistant/components/airvisual/__init__.py
homeassistant/components/airvisual/sensor.py
homeassistant/components/airvisual_pro/__init__.py
@@ -100,6 +103,7 @@ omit =
homeassistant/components/azure_devops/__init__.py
homeassistant/components/azure_devops/sensor.py
homeassistant/components/azure_service_bus/*
homeassistant/components/awair/coordinator.py
homeassistant/components/baf/__init__.py
homeassistant/components/baf/climate.py
homeassistant/components/baf/entity.py
@@ -171,6 +175,7 @@ omit =
homeassistant/components/comed_hourly_pricing/sensor.py
homeassistant/components/comelit/__init__.py
homeassistant/components/comelit/const.py
homeassistant/components/comelit/cover.py
homeassistant/components/comelit/coordinator.py
homeassistant/components/comelit/light.py
homeassistant/components/comfoconnect/fan.py
@@ -179,6 +184,7 @@ omit =
homeassistant/components/control4/__init__.py
homeassistant/components/control4/director_utils.py
homeassistant/components/control4/light.py
homeassistant/components/coolmaster/coordinator.py
homeassistant/components/cppm_tracker/device_tracker.py
homeassistant/components/crownstone/__init__.py
homeassistant/components/crownstone/devices.py
@@ -242,6 +248,8 @@ omit =
homeassistant/components/duotecno/switch.py
homeassistant/components/duotecno/cover.py
homeassistant/components/duotecno/light.py
homeassistant/components/duotecno/climate.py
homeassistant/components/duotecno/binary_sensor.py
homeassistant/components/dwd_weather_warnings/const.py
homeassistant/components/dwd_weather_warnings/coordinator.py
homeassistant/components/dwd_weather_warnings/sensor.py
@@ -255,6 +263,12 @@ omit =
homeassistant/components/ecobee/notify.py
homeassistant/components/ecobee/sensor.py
homeassistant/components/ecobee/weather.py
homeassistant/components/ecoforest/__init__.py
homeassistant/components/ecoforest/coordinator.py
homeassistant/components/ecoforest/entity.py
homeassistant/components/ecoforest/number.py
homeassistant/components/ecoforest/sensor.py
homeassistant/components/ecoforest/switch.py
homeassistant/components/econet/__init__.py
homeassistant/components/econet/binary_sensor.py
homeassistant/components/econet/climate.py
@@ -276,7 +290,6 @@ omit =
homeassistant/components/electric_kiwi/__init__.py
homeassistant/components/electric_kiwi/api.py
homeassistant/components/electric_kiwi/oauth2.py
homeassistant/components/electric_kiwi/sensor.py
homeassistant/components/electric_kiwi/coordinator.py
homeassistant/components/electric_kiwi/select.py
homeassistant/components/eliqonline/sensor.py
@@ -355,6 +368,7 @@ omit =
homeassistant/components/ezviz/update.py
homeassistant/components/faa_delays/__init__.py
homeassistant/components/faa_delays/binary_sensor.py
homeassistant/components/faa_delays/coordinator.py
homeassistant/components/familyhub/camera.py
homeassistant/components/fastdotcom/*
homeassistant/components/ffmpeg/camera.py
@@ -379,7 +393,6 @@ omit =
homeassistant/components/firmata/pin.py
homeassistant/components/firmata/sensor.py
homeassistant/components/firmata/switch.py
homeassistant/components/fitbit/*
homeassistant/components/fivem/__init__.py
homeassistant/components/fivem/binary_sensor.py
homeassistant/components/fivem/coordinator.py
@@ -416,7 +429,6 @@ omit =
homeassistant/components/freebox/device_tracker.py
homeassistant/components/freebox/home_base.py
homeassistant/components/freebox/router.py
homeassistant/components/freebox/sensor.py
homeassistant/components/freebox/switch.py
homeassistant/components/fritz/common.py
homeassistant/components/fritz/device_tracker.py
@@ -529,7 +541,12 @@ omit =
homeassistant/components/hvv_departures/__init__.py
homeassistant/components/hvv_departures/binary_sensor.py
homeassistant/components/hvv_departures/sensor.py
homeassistant/components/hydrawise/*
homeassistant/components/hydrawise/__init__.py
homeassistant/components/hydrawise/binary_sensor.py
homeassistant/components/hydrawise/const.py
homeassistant/components/hydrawise/coordinator.py
homeassistant/components/hydrawise/sensor.py
homeassistant/components/hydrawise/switch.py
homeassistant/components/ialarm/alarm_control_panel.py
homeassistant/components/iammeter/sensor.py
homeassistant/components/iaqualink/binary_sensor.py
@@ -655,6 +672,7 @@ omit =
homeassistant/components/lg_soundbar/__init__.py
homeassistant/components/lg_soundbar/media_player.py
homeassistant/components/life360/__init__.py
homeassistant/components/life360/button.py
homeassistant/components/life360/coordinator.py
homeassistant/components/life360/device_tracker.py
homeassistant/components/lightwave/*
@@ -704,11 +722,13 @@ omit =
homeassistant/components/mailgun/notify.py
homeassistant/components/map/*
homeassistant/components/mastodon/notify.py
homeassistant/components/matrix/*
homeassistant/components/matrix/__init__.py
homeassistant/components/matrix/notify.py
homeassistant/components/matter/__init__.py
homeassistant/components/meater/__init__.py
homeassistant/components/meater/sensor.py
homeassistant/components/media_extractor/*
homeassistant/components/medcom_ble/__init__.py
homeassistant/components/medcom_ble/sensor.py
homeassistant/components/mediaroom/media_player.py
homeassistant/components/melcloud/__init__.py
homeassistant/components/melcloud/climate.py
@@ -732,6 +752,7 @@ omit =
homeassistant/components/mill/sensor.py
homeassistant/components/minecraft_server/__init__.py
homeassistant/components/minecraft_server/binary_sensor.py
homeassistant/components/minecraft_server/coordinator.py
homeassistant/components/minecraft_server/entity.py
homeassistant/components/minecraft_server/sensor.py
homeassistant/components/minio/minio_helper.py
@@ -747,7 +768,9 @@ omit =
homeassistant/components/moehlenhoff_alpha2/climate.py
homeassistant/components/moehlenhoff_alpha2/sensor.py
homeassistant/components/motion_blinds/__init__.py
homeassistant/components/motion_blinds/coordinator.py
homeassistant/components/motion_blinds/cover.py
homeassistant/components/motion_blinds/entity.py
homeassistant/components/motion_blinds/sensor.py
homeassistant/components/mpd/media_player.py
homeassistant/components/mqtt_room/sensor.py
@@ -791,6 +814,7 @@ omit =
homeassistant/components/netgear/__init__.py
homeassistant/components/netgear/button.py
homeassistant/components/netgear/device_tracker.py
homeassistant/components/netgear/entity.py
homeassistant/components/netgear/router.py
homeassistant/components/netgear/sensor.py
homeassistant/components/netgear/switch.py
@@ -843,6 +867,7 @@ omit =
homeassistant/components/obihai/connectivity.py
homeassistant/components/obihai/sensor.py
homeassistant/components/octoprint/__init__.py
homeassistant/components/octoprint/coordinator.py
homeassistant/components/oem/climate.py
homeassistant/components/ohmconnect/sensor.py
homeassistant/components/ombi/*
@@ -873,6 +898,7 @@ omit =
homeassistant/components/opengarage/cover.py
homeassistant/components/opengarage/entity.py
homeassistant/components/opengarage/sensor.py
homeassistant/components/openhardwaremonitor/sensor.py
homeassistant/components/openhome/__init__.py
homeassistant/components/openhome/const.py
homeassistant/components/openhome/media_player.py
@@ -954,6 +980,8 @@ omit =
homeassistant/components/point/sensor.py
homeassistant/components/poolsense/__init__.py
homeassistant/components/poolsense/binary_sensor.py
homeassistant/components/poolsense/coordinator.py
homeassistant/components/poolsense/entity.py
homeassistant/components/poolsense/sensor.py
homeassistant/components/powerwall/__init__.py
homeassistant/components/progettihwsw/__init__.py
@@ -1004,9 +1032,13 @@ omit =
homeassistant/components/rainmachine/util.py
homeassistant/components/renson/__init__.py
homeassistant/components/renson/const.py
homeassistant/components/renson/coordinator.py
homeassistant/components/renson/entity.py
homeassistant/components/renson/sensor.py
homeassistant/components/renson/button.py
homeassistant/components/renson/fan.py
homeassistant/components/renson/binary_sensor.py
homeassistant/components/renson/number.py
homeassistant/components/raspyrfm/*
homeassistant/components/recollect_waste/sensor.py
homeassistant/components/recorder/repack.py
@@ -1067,9 +1099,10 @@ omit =
homeassistant/components/saj/sensor.py
homeassistant/components/satel_integra/*
homeassistant/components/schluter/*
homeassistant/components/screenlogic/__init__.py
homeassistant/components/screenlogic/binary_sensor.py
homeassistant/components/screenlogic/climate.py
homeassistant/components/screenlogic/coordinator.py
homeassistant/components/screenlogic/const.py
homeassistant/components/screenlogic/entity.py
homeassistant/components/screenlogic/light.py
homeassistant/components/screenlogic/number.py
@@ -1133,6 +1166,7 @@ omit =
homeassistant/components/smarty/*
homeassistant/components/sms/__init__.py
homeassistant/components/sms/const.py
homeassistant/components/sms/coordinator.py
homeassistant/components/sms/gateway.py
homeassistant/components/sms/notify.py
homeassistant/components/sms/sensor.py
@@ -1149,6 +1183,7 @@ omit =
homeassistant/components/solaredge_local/sensor.py
homeassistant/components/solarlog/__init__.py
homeassistant/components/solarlog/sensor.py
homeassistant/components/solarlog/coordinator.py
homeassistant/components/solax/__init__.py
homeassistant/components/solax/sensor.py
homeassistant/components/soma/__init__.py
@@ -1241,6 +1276,9 @@ omit =
homeassistant/components/switchbot/sensor.py
homeassistant/components/switchbot/switch.py
homeassistant/components/switchbot/lock.py
homeassistant/components/switchbot_cloud/coordinator.py
homeassistant/components/switchbot_cloud/entity.py
homeassistant/components/switchbot_cloud/switch.py
homeassistant/components/switchmate/switch.py
homeassistant/components/syncthing/__init__.py
homeassistant/components/syncthing/sensor.py
@@ -1263,6 +1301,7 @@ omit =
homeassistant/components/system_bridge/__init__.py
homeassistant/components/system_bridge/binary_sensor.py
homeassistant/components/system_bridge/coordinator.py
homeassistant/components/system_bridge/notify.py
homeassistant/components/system_bridge/sensor.py
homeassistant/components/systemmonitor/sensor.py
homeassistant/components/tado/__init__.py
@@ -1274,6 +1313,8 @@ omit =
homeassistant/components/tank_utility/sensor.py
homeassistant/components/tankerkoenig/__init__.py
homeassistant/components/tankerkoenig/binary_sensor.py
homeassistant/components/tankerkoenig/coordinator.py
homeassistant/components/tankerkoenig/entity.py
homeassistant/components/tankerkoenig/sensor.py
homeassistant/components/tapsaff/binary_sensor.py
homeassistant/components/tautulli/__init__.py
@@ -1442,9 +1483,11 @@ omit =
homeassistant/components/vlc_telnet/__init__.py
homeassistant/components/vlc_telnet/media_player.py
homeassistant/components/vodafone_station/__init__.py
homeassistant/components/vodafone_station/button.py
homeassistant/components/vodafone_station/const.py
homeassistant/components/vodafone_station/coordinator.py
homeassistant/components/vodafone_station/device_tracker.py
homeassistant/components/vodafone_station/sensor.py
homeassistant/components/volkszaehler/sensor.py
homeassistant/components/volumio/__init__.py
homeassistant/components/volumio/browse_media.py
@@ -1465,11 +1508,15 @@ omit =
homeassistant/components/watson_tts/tts.py
homeassistant/components/watttime/__init__.py
homeassistant/components/watttime/sensor.py
homeassistant/components/weatherflow/__init__.py
homeassistant/components/weatherflow/const.py
homeassistant/components/weatherflow/sensor.py
homeassistant/components/wiffi/__init__.py
homeassistant/components/wiffi/binary_sensor.py
homeassistant/components/wiffi/sensor.py
homeassistant/components/wiffi/wiffi_strings.py
homeassistant/components/wirelesstag/*
homeassistant/components/withings/api.py
homeassistant/components/wolflink/__init__.py
homeassistant/components/wolflink/sensor.py
homeassistant/components/worldtidesinfo/sensor.py

View File

@@ -24,7 +24,7 @@ jobs:
publish: ${{ steps.version.outputs.publish }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
with:
fetch-depth: 0
@@ -56,7 +56,7 @@ jobs:
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v4.7.0
@@ -98,7 +98,7 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
@@ -190,14 +190,14 @@ jobs:
echo "${{ github.sha }};${{ github.ref }};${{ github.event_name }};${{ github.actor }}" > rootfs/OFFICIAL_IMAGE
- name: Login to GitHub Container Registry
uses: docker/login-action@v2.2.0
uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build base image
uses: home-assistant/builder@2023.08.0
uses: home-assistant/builder@2023.09.0
with:
args: |
$BUILD_ARGS \
@@ -205,8 +205,6 @@ jobs:
--cosign \
--target /data \
--generic ${{ needs.init.outputs.version }}
env:
CAS_API_KEY: ${{ secrets.CAS_TOKEN }}
- name: Archive translations
shell: bash
@@ -254,7 +252,7 @@ jobs:
- green
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set build additional args
run: |
@@ -268,22 +266,20 @@ jobs:
fi
- name: Login to GitHub Container Registry
uses: docker/login-action@v2.2.0
uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build base image
uses: home-assistant/builder@2023.08.0
uses: home-assistant/builder@2023.09.0
with:
args: |
$BUILD_ARGS \
--target /data/machine \
--cosign \
--machine "${{ needs.init.outputs.version }}=${{ matrix.machine }}"
env:
CAS_API_KEY: ${{ secrets.CAS_TOKEN }}
publish_ha:
name: Publish version files
@@ -293,7 +289,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Initialize git
uses: home-assistant/actions/helpers/git-init@master
@@ -331,21 +327,21 @@ jobs:
id-token: write
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Install Cosign
uses: sigstore/cosign-installer@v3.1.1
uses: sigstore/cosign-installer@v3.1.2
with:
cosign-release: "v2.0.2"
- name: Login to DockerHub
uses: docker/login-action@v2.2.0
uses: docker/login-action@v3.0.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2.2.0
uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}

View File

@@ -35,8 +35,9 @@ on:
env:
CACHE_VERSION: 5
PIP_CACHE_VERSION: 4
MYPY_CACHE_VERSION: 4
HA_SHORT_VERSION: 2023.9
MYPY_CACHE_VERSION: 5
BLACK_CACHE_VERSION: 1
HA_SHORT_VERSION: "2023.10"
DEFAULT_PYTHON: "3.11"
ALL_PYTHON_VERSIONS: "['3.11']"
# 10.3 is the oldest supported version
@@ -55,6 +56,7 @@ env:
POSTGRESQL_VERSIONS: "['postgres:12.14','postgres:15.2']"
PRE_COMMIT_CACHE: ~/.cache/pre-commit
PIP_CACHE: /tmp/pip-cache
BLACK_CACHE: /tmp/black-cache
SQLALCHEMY_WARN_20: 1
PYTHONASYNCIODEBUG: 1
HASS_CI: 1
@@ -87,7 +89,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Generate partial Python venv restore key
id: generate_python_cache_key
run: >-
@@ -220,7 +222,7 @@ jobs:
- info
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v4.7.0
@@ -229,7 +231,7 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v3.3.1
uses: actions/cache@v3.3.2
with:
path: venv
key: >-
@@ -244,7 +246,7 @@ jobs:
pip install "$(cat requirements_test.txt | grep pre-commit)"
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v3.3.1
uses: actions/cache@v3.3.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
lookup-only: true
@@ -265,16 +267,23 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v4.7.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Generate partial black restore key
id: generate-black-key
run: |
black_version=$(cat requirements_test_pre_commit.txt | grep black | cut -d '=' -f 3)
echo "version=$black_version" >> $GITHUB_OUTPUT
echo "key=black-${{ env.BLACK_CACHE_VERSION }}-$black_version-${{
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -283,21 +292,36 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Restore black cache
uses: actions/cache@v3.3.2
with:
path: ${{ env.BLACK_CACHE }}
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-black-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ steps.python.outputs.python-version }}-black-${{
env.BLACK_CACHE_VERSION }}-${{ steps.generate-black-key.outputs.version }}-${{
env.HA_SHORT_VERSION }}-
- name: Run black (fully)
if: needs.info.outputs.test_full_suite == 'true'
env:
BLACK_CACHE_DIR: ${{ env.BLACK_CACHE }}
run: |
. venv/bin/activate
pre-commit run --hook-stage manual black --all-files --show-diff-on-failure
- name: Run black (partially)
if: needs.info.outputs.test_full_suite == 'false'
shell: bash
env:
BLACK_CACHE_DIR: ${{ env.BLACK_CACHE }}
run: |
. venv/bin/activate
shopt -s globstar
@@ -311,7 +335,7 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v4.7.0
id: python
@@ -320,7 +344,7 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -329,7 +353,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -360,7 +384,7 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v4.7.0
id: python
@@ -369,7 +393,7 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -378,7 +402,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -454,7 +478,7 @@ jobs:
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v4.7.0
@@ -468,7 +492,7 @@ jobs:
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v3.3.1
uses: actions/cache@v3.3.2
with:
path: venv
lookup-only: true
@@ -477,7 +501,7 @@ jobs:
needs.info.outputs.python_cache_key }}
- name: Restore pip wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v3.3.1
uses: actions/cache@v3.3.2
with:
path: ${{ env.PIP_CACHE }}
key: >-
@@ -522,7 +546,7 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v4.7.0
@@ -531,7 +555,7 @@ jobs:
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -554,7 +578,7 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v4.7.0
@@ -563,7 +587,7 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -587,7 +611,7 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v4.7.0
@@ -596,7 +620,7 @@ jobs:
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -631,7 +655,7 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v4.7.0
@@ -647,7 +671,7 @@ jobs:
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -655,7 +679,7 @@ jobs:
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Restore mypy cache
uses: actions/cache@v3.3.1
uses: actions/cache@v3.3.2
with:
path: .mypy_cache
key: >-
@@ -713,7 +737,7 @@ jobs:
bluez \
ffmpeg
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v4.7.0
@@ -722,7 +746,7 @@ jobs:
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -865,7 +889,7 @@ jobs:
ffmpeg \
libmariadb-dev-compat
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v4.7.0
@@ -874,7 +898,7 @@ jobs:
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -989,7 +1013,7 @@ jobs:
ffmpeg \
postgresql-server-dev-14
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v4.7.0
@@ -998,7 +1022,7 @@ jobs:
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: venv
fail-on-cache-miss: true
@@ -1084,7 +1108,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Download all coverage artifacts
uses: actions/download-artifact@v3
- name: Upload coverage to Codecov (full coverage)

View File

@@ -42,7 +42,7 @@ jobs:
id: token
# Pinned to a specific version of the action for security reasons
# v1.7.0
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a
with:
app_id: ${{ secrets.ISSUE_TRIAGE_APP_ID }}
private_key: ${{ secrets.ISSUE_TRIAGE_APP_PEM }}

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v4.7.0

View File

@@ -26,7 +26,7 @@ jobs:
architectures: ${{ steps.info.outputs.architectures }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Get information
id: info
@@ -56,7 +56,7 @@ jobs:
echo "CI_BUILD=1"
echo "ENABLE_HEADLESS=1"
# Use C-Extension for sqlalchemy
# Use C-Extension for SQLAlchemy
echo "REQUIRE_SQLALCHEMY_CEXT=1"
) > .env_file
@@ -84,7 +84,7 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Download env_file
uses: actions/download-artifact@v3
@@ -97,7 +97,7 @@ jobs:
name: requirements_diff
- name: Build wheels
uses: home-assistant/wheels@2023.04.0
uses: home-assistant/wheels@2023.09.1
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
@@ -122,7 +122,7 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3.6.0
uses: actions/checkout@v4.1.0
- name: Download env_file
uses: actions/download-artifact@v3
@@ -178,7 +178,7 @@ jobs:
sed -i "/numpy/d" homeassistant/package_constraints.txt
- name: Build wheels (part 1)
uses: home-assistant/wheels@2023.04.0
uses: home-assistant/wheels@2023.09.1
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
@@ -186,13 +186,13 @@ jobs:
wheels-key: ${{ secrets.WHEELS_KEY }}
env-file: true
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev"
skip-binary: aiohttp;grpcio;sqlalchemy;protobuf
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_all.txtaa"
- name: Build wheels (part 2)
uses: home-assistant/wheels@2023.04.0
uses: home-assistant/wheels@2023.09.1
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
@@ -200,13 +200,13 @@ jobs:
wheels-key: ${{ secrets.WHEELS_KEY }}
env-file: true
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev"
skip-binary: aiohttp;grpcio;sqlalchemy;protobuf
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_all.txtab"
- name: Build wheels (part 3)
uses: home-assistant/wheels@2023.04.0
uses: home-assistant/wheels@2023.09.1
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
@@ -214,7 +214,7 @@ jobs:
wheels-key: ${{ secrets.WHEELS_KEY }}
env-file: true
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev"
skip-binary: aiohttp;grpcio;sqlalchemy;protobuf
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_all.txtac"

View File

@@ -1,12 +1,12 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.285
rev: v0.0.289
hooks:
- id: ruff
args:
- --fix
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 23.7.0
rev: 23.9.1
hooks:
- id: black
args:
@@ -21,7 +21,7 @@ repos:
- --skip="./.*,*.csv,*.json,*.ambr"
- --quiet-level=2
exclude_types: [csv, json]
exclude: ^tests/fixtures/|homeassistant/generated/
exclude: ^tests/fixtures/|homeassistant/generated/|tests/components/.*/snapshots/
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:

View File

@@ -88,6 +88,7 @@ homeassistant.components.camera.*
homeassistant.components.canary.*
homeassistant.components.clickatell.*
homeassistant.components.clicksend.*
homeassistant.components.climate.*
homeassistant.components.cloud.*
homeassistant.components.configurator.*
homeassistant.components.cover.*
@@ -136,9 +137,11 @@ homeassistant.components.fully_kiosk.*
homeassistant.components.geo_location.*
homeassistant.components.geocaching.*
homeassistant.components.gios.*
homeassistant.components.glances.*
homeassistant.components.goalzero.*
homeassistant.components.google.*
homeassistant.components.google_sheets.*
homeassistant.components.gpsd.*
homeassistant.components.greeneye_monitor.*
homeassistant.components.group.*
homeassistant.components.guardian.*
@@ -177,6 +180,7 @@ homeassistant.components.huawei_lte.*
homeassistant.components.hydrawise.*
homeassistant.components.hyperion.*
homeassistant.components.ibeacon.*
homeassistant.components.idasen_desk.*
homeassistant.components.image.*
homeassistant.components.image_processing.*
homeassistant.components.image_upload.*
@@ -186,6 +190,7 @@ homeassistant.components.input_select.*
homeassistant.components.integration.*
homeassistant.components.ipp.*
homeassistant.components.iqvia.*
homeassistant.components.islamic_prayer_times.*
homeassistant.components.isy994.*
homeassistant.components.jellyfin.*
homeassistant.components.jewish_calendar.*
@@ -209,10 +214,12 @@ homeassistant.components.local_ip.*
homeassistant.components.lock.*
homeassistant.components.logbook.*
homeassistant.components.logger.*
homeassistant.components.london_underground.*
homeassistant.components.lookin.*
homeassistant.components.luftdaten.*
homeassistant.components.mailbox.*
homeassistant.components.mastodon.*
homeassistant.components.matrix.*
homeassistant.components.matter.*
homeassistant.components.media_extractor.*
homeassistant.components.media_player.*
@@ -253,7 +260,10 @@ homeassistant.components.peco.*
homeassistant.components.persistent_notification.*
homeassistant.components.pi_hole.*
homeassistant.components.ping.*
homeassistant.components.plugwise.*
homeassistant.components.poolsense.*
homeassistant.components.powerwall.*
homeassistant.components.private_ble_device.*
homeassistant.components.proximity.*
homeassistant.components.prusalink.*
homeassistant.components.pure_energie.*
@@ -311,6 +321,7 @@ homeassistant.components.sun.*
homeassistant.components.surepetcare.*
homeassistant.components.switch.*
homeassistant.components.switchbee.*
homeassistant.components.switchbot_cloud.*
homeassistant.components.switcher_kis.*
homeassistant.components.synology_dsm.*
homeassistant.components.systemmonitor.*
@@ -332,6 +343,7 @@ homeassistant.components.trafikverket_camera.*
homeassistant.components.trafikverket_ferry.*
homeassistant.components.trafikverket_train.*
homeassistant.components.trafikverket_weatherstation.*
homeassistant.components.trend.*
homeassistant.components.tts.*
homeassistant.components.twentemilieu.*
homeassistant.components.unifi.*

View File

@@ -47,8 +47,10 @@ build.json @home-assistant/supervisor
/tests/components/airq/ @Sibgatulin @dl2080
/homeassistant/components/airthings/ @danielhiversen
/tests/components/airthings/ @danielhiversen
/homeassistant/components/airthings_ble/ @vincegio
/tests/components/airthings_ble/ @vincegio
/homeassistant/components/airthings_ble/ @vincegio @LaStrada
/tests/components/airthings_ble/ @vincegio @LaStrada
/homeassistant/components/airtouch4/ @samsinnamon
/tests/components/airtouch4/ @samsinnamon
/homeassistant/components/airvisual/ @bachya
/tests/components/airvisual/ @bachya
/homeassistant/components/airvisual_pro/ @bachya
@@ -203,6 +205,8 @@ build.json @home-assistant/supervisor
/tests/components/cloud/ @home-assistant/cloud
/homeassistant/components/cloudflare/ @ludeeus @ctalkington
/tests/components/cloudflare/ @ludeeus @ctalkington
/homeassistant/components/co2signal/ @jpbede
/tests/components/co2signal/ @jpbede
/homeassistant/components/coinbase/ @tombrien
/tests/components/coinbase/ @tombrien
/homeassistant/components/color_extractor/ @GenericStudent
@@ -305,6 +309,8 @@ build.json @home-assistant/supervisor
/tests/components/easyenergy/ @klaasnicolaas
/homeassistant/components/ecobee/ @marthoc @marcolivierarsenault
/tests/components/ecobee/ @marthoc @marcolivierarsenault
/homeassistant/components/ecoforest/ @pjanuario
/tests/components/ecoforest/ @pjanuario
/homeassistant/components/econet/ @vangorra @w1ll1am23
/tests/components/econet/ @vangorra @w1ll1am23
/homeassistant/components/ecovacs/ @OverloadUT @mib1185
@@ -354,8 +360,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/eq3btsmart/ @rytilahti
/homeassistant/components/escea/ @lazdavila
/tests/components/escea/ @lazdavila
/homeassistant/components/esphome/ @OttoWinter @jesserockz @bdraco
/tests/components/esphome/ @OttoWinter @jesserockz @bdraco
/homeassistant/components/esphome/ @OttoWinter @jesserockz @kbx81 @bdraco
/tests/components/esphome/ @OttoWinter @jesserockz @kbx81 @bdraco
/homeassistant/components/eufylife_ble/ @bdr99
/tests/components/eufylife_ble/ @bdr99
/homeassistant/components/event/ @home-assistant/core
@@ -384,6 +390,8 @@ build.json @home-assistant/supervisor
/tests/components/fireservicerota/ @cyberjunky
/homeassistant/components/firmata/ @DaAwesomeP
/tests/components/firmata/ @DaAwesomeP
/homeassistant/components/fitbit/ @allenporter
/tests/components/fitbit/ @allenporter
/homeassistant/components/fivem/ @Sander0542
/tests/components/fivem/ @Sander0542
/homeassistant/components/fjaraskupan/ @elupus
@@ -396,8 +404,8 @@ build.json @home-assistant/supervisor
/tests/components/flo/ @dmulcahey
/homeassistant/components/flume/ @ChrisMandich @bdraco @jeeftor
/tests/components/flume/ @ChrisMandich @bdraco @jeeftor
/homeassistant/components/flux_led/ @icemanch @bdraco
/tests/components/flux_led/ @icemanch @bdraco
/homeassistant/components/flux_led/ @icemanch
/tests/components/flux_led/ @icemanch
/homeassistant/components/forecast_solar/ @klaasnicolaas @frenck
/tests/components/forecast_solar/ @klaasnicolaas @frenck
/homeassistant/components/forked_daapd/ @uvjustin
@@ -554,6 +562,7 @@ build.json @home-assistant/supervisor
/homeassistant/components/hvv_departures/ @vigonotion
/tests/components/hvv_departures/ @vigonotion
/homeassistant/components/hydrawise/ @dknowles2 @ptcryan
/tests/components/hydrawise/ @dknowles2 @ptcryan
/homeassistant/components/hyperion/ @dermotduffy
/tests/components/hyperion/ @dermotduffy
/homeassistant/components/ialarm/ @RyuzakiKK
@@ -565,6 +574,8 @@ build.json @home-assistant/supervisor
/tests/components/ibeacon/ @bdraco
/homeassistant/components/icloud/ @Quentame @nzapponi
/tests/components/icloud/ @Quentame @nzapponi
/homeassistant/components/idasen_desk/ @abmantis
/tests/components/idasen_desk/ @abmantis
/homeassistant/components/ign_sismologia/ @exxamalte
/tests/components/ign_sismologia/ @exxamalte
/homeassistant/components/image/ @home-assistant/core
@@ -684,8 +695,6 @@ build.json @home-assistant/supervisor
/tests/components/lidarr/ @tkdrob
/homeassistant/components/life360/ @pnbruckner
/tests/components/life360/ @pnbruckner
/homeassistant/components/lifx/ @bdraco
/tests/components/lifx/ @bdraco
/homeassistant/components/light/ @home-assistant/core
/tests/components/light/ @home-assistant/core
/homeassistant/components/linux_battery/ @fabaff
@@ -707,6 +716,8 @@ build.json @home-assistant/supervisor
/tests/components/logger/ @home-assistant/core
/homeassistant/components/logi_circle/ @evanjd
/tests/components/logi_circle/ @evanjd
/homeassistant/components/london_underground/ @jpbede
/tests/components/london_underground/ @jpbede
/homeassistant/components/lookin/ @ANMalko @bdraco
/tests/components/lookin/ @ANMalko @bdraco
/homeassistant/components/loqed/ @mikewoudenberg
@@ -723,13 +734,18 @@ build.json @home-assistant/supervisor
/homeassistant/components/lyric/ @timmo001
/tests/components/lyric/ @timmo001
/homeassistant/components/mastodon/ @fabaff
/homeassistant/components/matrix/ @PaarthShah
/tests/components/matrix/ @PaarthShah
/homeassistant/components/matter/ @home-assistant/matter
/tests/components/matter/ @home-assistant/matter
/homeassistant/components/mazda/ @bdr99
/tests/components/mazda/ @bdr99
/homeassistant/components/meater/ @Sotolotl @emontnemery
/tests/components/meater/ @Sotolotl @emontnemery
/homeassistant/components/medcom_ble/ @elafargue
/tests/components/medcom_ble/ @elafargue
/homeassistant/components/media_extractor/ @joostlek
/tests/components/media_extractor/ @joostlek
/homeassistant/components/media_player/ @home-assistant/core
/tests/components/media_player/ @home-assistant/core
/homeassistant/components/media_source/ @hunterjm
@@ -766,8 +782,8 @@ build.json @home-assistant/supervisor
/tests/components/moat/ @bdraco
/homeassistant/components/mobile_app/ @home-assistant/core
/tests/components/mobile_app/ @home-assistant/core
/homeassistant/components/modbus/ @adamchengtkc @janiversen @vzahradnik
/tests/components/modbus/ @adamchengtkc @janiversen @vzahradnik
/homeassistant/components/modbus/ @janiversen
/tests/components/modbus/ @janiversen
/homeassistant/components/modem_callerid/ @tkdrob
/tests/components/modem_callerid/ @tkdrob
/homeassistant/components/modern_forms/ @wonderslug
@@ -793,8 +809,8 @@ build.json @home-assistant/supervisor
/tests/components/mutesync/ @currentoor
/homeassistant/components/my/ @home-assistant/core
/tests/components/my/ @home-assistant/core
/homeassistant/components/myq/ @ehendrix23
/tests/components/myq/ @ehendrix23
/homeassistant/components/myq/ @ehendrix23 @Lash-L
/tests/components/myq/ @ehendrix23 @Lash-L
/homeassistant/components/mysensors/ @MartinHjelmare @functionpointer
/tests/components/mysensors/ @MartinHjelmare @functionpointer
/homeassistant/components/mystrom/ @fabaff
@@ -949,6 +965,8 @@ build.json @home-assistant/supervisor
/tests/components/poolsense/ @haemishkyd
/homeassistant/components/powerwall/ @bdraco @jrester @daniel-simpson
/tests/components/powerwall/ @bdraco @jrester @daniel-simpson
/homeassistant/components/private_ble_device/ @Jc2k
/tests/components/private_ble_device/ @Jc2k
/homeassistant/components/profiler/ @bdraco
/tests/components/profiler/ @bdraco
/homeassistant/components/progettihwsw/ @ardaseremet
@@ -1057,8 +1075,8 @@ build.json @home-assistant/supervisor
/tests/components/rss_feed_template/ @home-assistant/core
/homeassistant/components/rtsp_to_webrtc/ @allenporter
/tests/components/rtsp_to_webrtc/ @allenporter
/homeassistant/components/ruckus_unleashed/ @gabe565 @lanrat
/tests/components/ruckus_unleashed/ @gabe565 @lanrat
/homeassistant/components/ruckus_unleashed/ @lanrat @ms264556 @gabe565
/tests/components/ruckus_unleashed/ @lanrat @ms264556 @gabe565
/homeassistant/components/ruuvi_gateway/ @akx
/tests/components/ruuvi_gateway/ @akx
/homeassistant/components/ruuvitag_ble/ @akx
@@ -1135,8 +1153,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/sky_hub/ @rogerselwyn
/homeassistant/components/skybell/ @tkdrob
/tests/components/skybell/ @tkdrob
/homeassistant/components/slack/ @tkdrob
/tests/components/slack/ @tkdrob
/homeassistant/components/slack/ @tkdrob @fletcherau
/tests/components/slack/ @tkdrob @fletcherau
/homeassistant/components/sleepiq/ @mfugate1 @kbickar
/tests/components/sleepiq/ @mfugate1 @kbickar
/homeassistant/components/slide/ @ualex73
@@ -1184,8 +1202,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/spider/ @peternijssen
/tests/components/spider/ @peternijssen
/homeassistant/components/splunk/ @Bre77
/homeassistant/components/spotify/ @frenck
/tests/components/spotify/ @frenck
/homeassistant/components/spotify/ @frenck @joostlek
/tests/components/spotify/ @frenck @joostlek
/homeassistant/components/sql/ @gjohansson-ST @dougiteixeira
/tests/components/sql/ @gjohansson-ST @dougiteixeira
/homeassistant/components/squeezebox/ @rajlaud
@@ -1229,6 +1247,8 @@ build.json @home-assistant/supervisor
/tests/components/switchbee/ @jafar-atili
/homeassistant/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
/tests/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
/homeassistant/components/switchbot_cloud/ @SeraphicRav
/tests/components/switchbot_cloud/ @SeraphicRav
/homeassistant/components/switcher_kis/ @thecode
/tests/components/switcher_kis/ @thecode
/homeassistant/components/switchmate/ @danielhiversen @qiz-li
@@ -1309,14 +1329,16 @@ build.json @home-assistant/supervisor
/tests/components/trafikverket_weatherstation/ @endor-force @gjohansson-ST
/homeassistant/components/transmission/ @engrbm87 @JPHutchins
/tests/components/transmission/ @engrbm87 @JPHutchins
/homeassistant/components/trend/ @jpbede
/tests/components/trend/ @jpbede
/homeassistant/components/tts/ @home-assistant/core @pvizeli
/tests/components/tts/ @home-assistant/core @pvizeli
/homeassistant/components/tuya/ @Tuya @zlinoliver @frenck
/tests/components/tuya/ @Tuya @zlinoliver @frenck
/homeassistant/components/twentemilieu/ @frenck
/tests/components/twentemilieu/ @frenck
/homeassistant/components/twinkly/ @dr1rrb @Robbie1221
/tests/components/twinkly/ @dr1rrb @Robbie1221
/homeassistant/components/twinkly/ @dr1rrb @Robbie1221 @Olen
/tests/components/twinkly/ @dr1rrb @Robbie1221 @Olen
/homeassistant/components/twitch/ @joostlek
/tests/components/twitch/ @joostlek
/homeassistant/components/ukraine_alarm/ @PaulAnnekov
@@ -1352,11 +1374,11 @@ build.json @home-assistant/supervisor
/homeassistant/components/velbus/ @Cereal2nd @brefra
/tests/components/velbus/ @Cereal2nd @brefra
/homeassistant/components/velux/ @Julius2342
/homeassistant/components/venstar/ @garbled1
/tests/components/venstar/ @garbled1
/homeassistant/components/verisure/ @frenck @niro1987
/tests/components/verisure/ @frenck @niro1987
/homeassistant/components/versasense/ @flamm3blemuff1n
/homeassistant/components/venstar/ @garbled1 @jhollowe
/tests/components/venstar/ @garbled1 @jhollowe
/homeassistant/components/verisure/ @frenck
/tests/components/verisure/ @frenck
/homeassistant/components/versasense/ @imstevenxyz
/homeassistant/components/version/ @ludeeus
/tests/components/version/ @ludeeus
/homeassistant/components/vesync/ @markperdue @webdjoe @thegardenmonkey
@@ -1384,7 +1406,8 @@ build.json @home-assistant/supervisor
/tests/components/wake_word/ @home-assistant/core @synesthesiam
/homeassistant/components/wallbox/ @hesselonline
/tests/components/wallbox/ @hesselonline
/homeassistant/components/waqi/ @andrey-git
/homeassistant/components/waqi/ @joostlek
/tests/components/waqi/ @joostlek
/homeassistant/components/water_heater/ @home-assistant/core
/tests/components/water_heater/ @home-assistant/core
/homeassistant/components/watson_tts/ @rutkai
@@ -1394,6 +1417,10 @@ build.json @home-assistant/supervisor
/tests/components/waze_travel_time/ @eifinger
/homeassistant/components/weather/ @home-assistant/core
/tests/components/weather/ @home-assistant/core
/homeassistant/components/weatherflow/ @natekspencer @jeeftor
/tests/components/weatherflow/ @natekspencer @jeeftor
/homeassistant/components/weatherkit/ @tjhorner
/tests/components/weatherkit/ @tjhorner
/homeassistant/components/webhook/ @home-assistant/core
/tests/components/webhook/ @home-assistant/core
/homeassistant/components/webostv/ @thecode
@@ -1411,8 +1438,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/wilight/ @leofig-rj
/tests/components/wilight/ @leofig-rj
/homeassistant/components/wirelesstag/ @sergeymaysak
/homeassistant/components/withings/ @vangorra
/tests/components/withings/ @vangorra
/homeassistant/components/withings/ @vangorra @joostlek
/tests/components/withings/ @vangorra @joostlek
/homeassistant/components/wiz/ @sbidy
/tests/components/wiz/ @sbidy
/homeassistant/components/wled/ @frenck
@@ -1446,6 +1473,7 @@ build.json @home-assistant/supervisor
/homeassistant/components/yandex_transport/ @rishatik92 @devbis
/tests/components/yandex_transport/ @rishatik92 @devbis
/homeassistant/components/yardian/ @h3l1o5
/tests/components/yardian/ @h3l1o5
/homeassistant/components/yeelight/ @zewelor @shenxn @starkillerOG @alexyao2015
/tests/components/yeelight/ @zewelor @shenxn @starkillerOG @alexyao2015
/homeassistant/components/yeelightsunflower/ @lindsaymarkward

View File

@@ -15,9 +15,8 @@ COPY homeassistant/package_constraints.txt homeassistant/homeassistant/
RUN \
pip3 install \
--no-cache-dir \
--no-index \
--only-binary=:all: \
--find-links "${WHEELS_LINKS}" \
--index-url "https://wheels.home-assistant.io/musllinux-index/" \
-r homeassistant/requirements.txt
COPY requirements_all.txt home_assistant_frontend-* home_assistant_intents-* homeassistant/
@@ -39,9 +38,8 @@ RUN \
MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \
pip3 install \
--no-cache-dir \
--no-index \
--only-binary=:all: \
--find-links "${WHEELS_LINKS}" \
--index-url "https://wheels.home-assistant.io/musllinux-index/" \
-r homeassistant/requirements_all.txt
## Setup Home Assistant Core
@@ -49,9 +47,8 @@ COPY . homeassistant/
RUN \
pip3 install \
--no-cache-dir \
--no-index \
--only-binary=:all: \
--find-links "${WHEELS_LINKS}" \
--index-url "https://wheels.home-assistant.io/musllinux-index/" \
-e ./homeassistant \
&& python3 -m compileall \
homeassistant/homeassistant

View File

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

View File

@@ -7,6 +7,7 @@
"homekit",
"ibeacon",
"icloud",
"itunes"
"itunes",
"weatherkit"
]
}

View File

@@ -1,5 +1,5 @@
{
"domain": "ikea",
"name": "IKEA",
"integrations": ["symfonisk", "tradfri"]
"integrations": ["symfonisk", "tradfri", "idasen_desk"]
}

View File

@@ -0,0 +1,5 @@
{
"domain": "switchbot",
"name": "SwitchBot",
"integrations": ["switchbot", "switchbot_cloud"]
}

View File

@@ -1,5 +1,5 @@
{
"domain": "u_tec",
"name": "U-tec",
"iot_standards": ["zwave"]
"integrations": ["ultraloq"]
}

View File

@@ -30,7 +30,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
longitude = entry.data[CONF_LONGITUDE]
station_updates = entry.options.get(CONF_STATION_UPDATES, True)
options = ConnectionOptions(api_key, station_updates)
options = ConnectionOptions(api_key, station_updates, True)
aemet = AEMET(aiohttp_client.async_get_clientsession(hass), options)
try:
await aemet.select_coordinates(latitude, longitude)

View File

@@ -40,7 +40,7 @@ class AemetConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
await self.async_set_unique_id(f"{latitude}-{longitude}")
self._abort_if_unique_id_configured()
options = ConnectionOptions(user_input[CONF_API_KEY], False)
options = ConnectionOptions(user_input[CONF_API_KEY], False, True)
aemet = AEMET(aiohttp_client.async_get_clientsession(self.hass), options)
try:
await aemet.select_coordinates(latitude, longitude)

View File

@@ -1,6 +1,19 @@
"""Constant values for the AEMET OpenData component."""
from __future__ import annotations
from aemet_opendata.const import (
AOD_COND_CLEAR_NIGHT,
AOD_COND_CLOUDY,
AOD_COND_FOG,
AOD_COND_LIGHTNING,
AOD_COND_LIGHTNING_RAINY,
AOD_COND_PARTLY_CLODUY,
AOD_COND_POURING,
AOD_COND_RAINY,
AOD_COND_SNOWY,
AOD_COND_SUNNY,
)
from homeassistant.components.weather import (
ATTR_CONDITION_CLEAR_NIGHT,
ATTR_CONDITION_CLOUDY,
@@ -55,94 +68,16 @@ ATTR_API_WIND_MAX_SPEED = "wind-max-speed"
ATTR_API_WIND_SPEED = "wind-speed"
CONDITIONS_MAP = {
ATTR_CONDITION_CLEAR_NIGHT: {
"11n", # Despejado (de noche)
},
ATTR_CONDITION_CLOUDY: {
"14", # Nuboso
"14n", # Nuboso (de noche)
"15", # Muy nuboso
"15n", # Muy nuboso (de noche)
"16", # Cubierto
"16n", # Cubierto (de noche)
"17", # Nubes altas
"17n", # Nubes altas (de noche)
},
ATTR_CONDITION_FOG: {
"81", # Niebla
"81n", # Niebla (de noche)
"82", # Bruma - Neblina
"82n", # Bruma - Neblina (de noche)
},
ATTR_CONDITION_LIGHTNING: {
"51", # Intervalos nubosos con tormenta
"51n", # Intervalos nubosos con tormenta (de noche)
"52", # Nuboso con tormenta
"52n", # Nuboso con tormenta (de noche)
"53", # Muy nuboso con tormenta
"53n", # Muy nuboso con tormenta (de noche)
"54", # Cubierto con tormenta
"54n", # Cubierto con tormenta (de noche)
},
ATTR_CONDITION_LIGHTNING_RAINY: {
"61", # Intervalos nubosos con tormenta y lluvia escasa
"61n", # Intervalos nubosos con tormenta y lluvia escasa (de noche)
"62", # Nuboso con tormenta y lluvia escasa
"62n", # Nuboso con tormenta y lluvia escasa (de noche)
"63", # Muy nuboso con tormenta y lluvia escasa
"63n", # Muy nuboso con tormenta y lluvia escasa (de noche)
"64", # Cubierto con tormenta y lluvia escasa
"64n", # Cubierto con tormenta y lluvia escasa (de noche)
},
ATTR_CONDITION_PARTLYCLOUDY: {
"12", # Poco nuboso
"12n", # Poco nuboso (de noche)
"13", # Intervalos nubosos
"13n", # Intervalos nubosos (de noche)
},
ATTR_CONDITION_POURING: {
"27", # Chubascos
"27n", # Chubascos (de noche)
},
ATTR_CONDITION_RAINY: {
"23", # Intervalos nubosos con lluvia
"23n", # Intervalos nubosos con lluvia (de noche)
"24", # Nuboso con lluvia
"24n", # Nuboso con lluvia (de noche)
"25", # Muy nuboso con lluvia
"25n", # Muy nuboso con lluvia (de noche)
"26", # Cubierto con lluvia
"26n", # Cubierto con lluvia (de noche)
"43", # Intervalos nubosos con lluvia escasa
"43n", # Intervalos nubosos con lluvia escasa (de noche)
"44", # Nuboso con lluvia escasa
"44n", # Nuboso con lluvia escasa (de noche)
"45", # Muy nuboso con lluvia escasa
"45n", # Muy nuboso con lluvia escasa (de noche)
"46", # Cubierto con lluvia escasa
"46n", # Cubierto con lluvia escasa (de noche)
},
ATTR_CONDITION_SNOWY: {
"33", # Intervalos nubosos con nieve
"33n", # Intervalos nubosos con nieve (de noche)
"34", # Nuboso con nieve
"34n", # Nuboso con nieve (de noche)
"35", # Muy nuboso con nieve
"35n", # Muy nuboso con nieve (de noche)
"36", # Cubierto con nieve
"36n", # Cubierto con nieve (de noche)
"71", # Intervalos nubosos con nieve escasa
"71n", # Intervalos nubosos con nieve escasa (de noche)
"72", # Nuboso con nieve escasa
"72n", # Nuboso con nieve escasa (de noche)
"73", # Muy nuboso con nieve escasa
"73n", # Muy nuboso con nieve escasa (de noche)
"74", # Cubierto con nieve escasa
"74n", # Cubierto con nieve escasa (de noche)
},
ATTR_CONDITION_SUNNY: {
"11", # Despejado
},
AOD_COND_CLEAR_NIGHT: ATTR_CONDITION_CLEAR_NIGHT,
AOD_COND_CLOUDY: ATTR_CONDITION_CLOUDY,
AOD_COND_FOG: ATTR_CONDITION_FOG,
AOD_COND_LIGHTNING: ATTR_CONDITION_LIGHTNING,
AOD_COND_LIGHTNING_RAINY: ATTR_CONDITION_LIGHTNING_RAINY,
AOD_COND_PARTLY_CLODUY: ATTR_CONDITION_PARTLYCLOUDY,
AOD_COND_POURING: ATTR_CONDITION_POURING,
AOD_COND_RAINY: ATTR_CONDITION_RAINY,
AOD_COND_SNOWY: ATTR_CONDITION_SNOWY,
AOD_COND_SUNNY: ATTR_CONDITION_SUNNY,
}
FORECAST_MONITORED_CONDITIONS = [
@@ -187,16 +122,3 @@ FORECAST_MODE_ATTR_API = {
FORECAST_MODE_DAILY: ATTR_API_FORECAST_DAILY,
FORECAST_MODE_HOURLY: ATTR_API_FORECAST_HOURLY,
}
WIND_BEARING_MAP = {
"C": None,
"N": 0.0,
"NE": 45.0,
"E": 90.0,
"SE": 135.0,
"S": 180.0,
"SO": 225.0,
"O": 270.0,
"NO": 315.0,
}

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.4.3"]
"requirements": ["AEMET-OpenData==0.4.5"]
}

View File

@@ -30,6 +30,7 @@ from .const import (
ATTR_API_FORECAST_TEMP_LOW,
ATTR_API_FORECAST_TIME,
ATTR_API_FORECAST_WIND_BEARING,
ATTR_API_FORECAST_WIND_MAX_SPEED,
ATTR_API_FORECAST_WIND_SPEED,
ATTR_API_HUMIDITY,
ATTR_API_PRESSURE,
@@ -99,6 +100,12 @@ FORECAST_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
name="Wind bearing",
native_unit_of_measurement=DEGREE,
),
SensorEntityDescription(
key=ATTR_API_FORECAST_WIND_MAX_SPEED,
name="Wind max speed",
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
device_class=SensorDeviceClass.WIND_SPEED,
),
SensorEntityDescription(
key=ATTR_API_FORECAST_WIND_SPEED,
name="Wind speed",
@@ -206,13 +213,14 @@ WEATHER_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
name="Wind max speed",
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
device_class=SensorDeviceClass.WIND_SPEED,
state_class=SensorStateClass.MEASUREMENT,
),
SensorEntityDescription(
key=ATTR_API_WIND_SPEED,
name="Wind speed",
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.WIND_SPEED,
state_class=SensorStateClass.MEASUREMENT,
),
)

View File

@@ -42,6 +42,7 @@ from .const import (
ATTR_API_PRESSURE,
ATTR_API_TEMPERATURE,
ATTR_API_WIND_BEARING,
ATTR_API_WIND_MAX_SPEED,
ATTR_API_WIND_SPEED,
ATTRIBUTION,
DOMAIN,
@@ -193,6 +194,11 @@ class AemetWeather(SingleCoordinatorWeatherEntity[WeatherUpdateCoordinator]):
"""Return the wind bearing."""
return self.coordinator.data[ATTR_API_WIND_BEARING]
@property
def native_wind_gust_speed(self):
"""Return the wind gust speed in native units."""
return self.coordinator.data[ATTR_API_WIND_MAX_SPEED]
@property
def native_wind_speed(self):
"""Return the wind speed."""

View File

@@ -34,6 +34,7 @@ from aemet_opendata.const import (
ATTR_DATA,
)
from aemet_opendata.exceptions import AemetError
from aemet_opendata.forecast import ForecastValue
from aemet_opendata.helpers import (
get_forecast_day_value,
get_forecast_hour_value,
@@ -78,7 +79,6 @@ from .const import (
ATTR_API_WIND_SPEED,
CONDITIONS_MAP,
DOMAIN,
WIND_BEARING_MAP,
)
_LOGGER = logging.getLogger(__name__)
@@ -90,11 +90,8 @@ WEATHER_UPDATE_INTERVAL = timedelta(minutes=10)
def format_condition(condition: str) -> str:
"""Return condition from dict CONDITIONS_MAP."""
for key, value in CONDITIONS_MAP.items():
if condition in value:
return key
_LOGGER.error('Condition "%s" not found in CONDITIONS_MAP', condition)
return condition
val = ForecastValue.parse_condition(condition)
return CONDITIONS_MAP.get(val, val)
def format_float(value) -> float | None:
@@ -489,10 +486,7 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
val = get_forecast_hour_value(
day_data[AEMET_ATTR_WIND_GUST], hour, key=AEMET_ATTR_DIRECTION
)[0]
if val in WIND_BEARING_MAP:
return WIND_BEARING_MAP[val]
_LOGGER.error("%s not found in Wind Bearing map", val)
return None
return ForecastValue.parse_wind_direction(val)
@staticmethod
def _get_wind_bearing_day(day_data):
@@ -500,10 +494,7 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
val = get_forecast_day_value(
day_data[AEMET_ATTR_WIND], key=AEMET_ATTR_DIRECTION
)
if val in WIND_BEARING_MAP:
return WIND_BEARING_MAP[val]
_LOGGER.error("%s not found in Wind Bearing map", val)
return None
return ForecastValue.parse_wind_direction(val)
@staticmethod
def _get_wind_max_speed(day_data, hour):

View File

@@ -1 +1,42 @@
"""The aftership component."""
"""The AfterShip integration."""
from __future__ import annotations
from pyaftership import AfterShip, AfterShipException
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_API_KEY, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN
PLATFORMS: list[Platform] = [Platform.SENSOR]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up AfterShip from a config entry."""
hass.data.setdefault(DOMAIN, {})
session = async_get_clientsession(hass)
aftership = AfterShip(api_key=entry.data[CONF_API_KEY], session=session)
try:
await aftership.trackings.list()
except AfterShipException as err:
raise ConfigEntryNotReady from err
hass.data[DOMAIN][entry.entry_id] = aftership
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok

View File

@@ -0,0 +1,90 @@
"""Config flow for AfterShip integration."""
from __future__ import annotations
import logging
from typing import Any
from pyaftership import AfterShip, AfterShipException
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow
from homeassistant.const import CONF_API_KEY, CONF_NAME
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN
from homeassistant.data_entry_flow import AbortFlow, FlowResult
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
class AfterShipConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for AfterShip."""
VERSION = 1
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}
if user_input is not None:
self._async_abort_entries_match({CONF_API_KEY: user_input[CONF_API_KEY]})
try:
aftership = AfterShip(
api_key=user_input[CONF_API_KEY],
session=async_get_clientsession(self.hass),
)
await aftership.trackings.list()
except AfterShipException:
_LOGGER.exception("Aftership raised exception")
errors["base"] = "cannot_connect"
else:
return self.async_create_entry(title="AfterShip", data=user_input)
return self.async_show_form(
step_id="user",
data_schema=vol.Schema({vol.Required(CONF_API_KEY): str}),
errors=errors,
)
async def async_step_import(self, config: dict[str, Any]) -> FlowResult:
"""Import configuration from yaml."""
try:
self._async_abort_entries_match({CONF_API_KEY: config[CONF_API_KEY]})
except AbortFlow as err:
async_create_issue(
self.hass,
DOMAIN,
"deprecated_yaml_import_issue_already_configured",
breaks_in_ha_version="2024.4.0",
is_fixable=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml_import_issue_already_configured",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "AfterShip",
},
)
raise err
async_create_issue(
self.hass,
HOMEASSISTANT_DOMAIN,
f"deprecated_yaml_{DOMAIN}",
breaks_in_ha_version="2024.4.0",
is_fixable=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "AfterShip",
},
)
return self.async_create_entry(
title=config.get(CONF_NAME, "AfterShip"),
data={CONF_API_KEY: config[CONF_API_KEY]},
)

View File

@@ -2,6 +2,7 @@
"domain": "aftership",
"name": "AfterShip",
"codeowners": [],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aftership",
"iot_class": "cloud_polling",
"requirements": ["pyaftership==21.11.0"]

View File

@@ -11,6 +11,7 @@ from homeassistant.components.sensor import (
PLATFORM_SCHEMA as BASE_PLATFORM_SCHEMA,
SensorEntity,
)
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_API_KEY, CONF_NAME
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers.aiohttp_client import async_get_clientsession
@@ -20,6 +21,7 @@ from homeassistant.helpers.dispatcher import (
async_dispatcher_send,
)
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import Throttle
@@ -58,19 +60,43 @@ async def async_setup_platform(
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Set up the AfterShip sensor platform."""
apikey = config[CONF_API_KEY]
name = config[CONF_NAME]
session = async_get_clientsession(hass)
aftership = AfterShip(api_key=apikey, session=session)
aftership = AfterShip(
api_key=config[CONF_API_KEY], session=async_get_clientsession(hass)
)
try:
await aftership.trackings.list()
except AfterShipException as err:
_LOGGER.error("No tracking data found. Check API key is correct: %s", err)
return
except AfterShipException:
async_create_issue(
hass,
DOMAIN,
"deprecated_yaml_import_issue_cannot_connect",
breaks_in_ha_version="2024.4.0",
is_fixable=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml_import_issue_cannot_connect",
translation_placeholders={
"integration_title": "AfterShip",
"url": "/config/integrations/dashboard/add?domain=aftership",
},
)
async_add_entities([AfterShipSensor(aftership, name)], True)
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=config
)
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up AfterShip sensor entities based on a config entry."""
aftership: AfterShip = hass.data[DOMAIN][config_entry.entry_id]
async_add_entities([AfterShipSensor(aftership, config_entry.title)], True)
async def handle_add_tracking(call: ServiceCall) -> None:
"""Call when a user adds a new Aftership tracking from Home Assistant."""

View File

@@ -1,4 +1,19 @@
{
"config": {
"step": {
"user": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]"
}
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
},
"services": {
"add_tracking": {
"name": "Add tracking",
@@ -32,5 +47,15 @@
}
}
}
},
"issues": {
"deprecated_yaml_import_issue_already_configured": {
"title": "The {integration_title} YAML configuration import failed",
"description": "Configuring {integration_title} using YAML is being removed but the YAML configuration was already imported.\n\nRemove the YAML configuration and restart Home Assistant."
},
"deprecated_yaml_import_issue_cannot_connect": {
"title": "The {integration_title} YAML configuration import failed",
"description": "Configuring {integration_title} using YAML is being removed but there was an connection error importing your YAML configuration.\n\nEnsure connection to {integration_title} works and restart Home Assistant to try again or remove the {integration_title} YAML configuration from your configuration.yaml file and continue to [set up the integration]({url}) manually."
}
}
}

View File

@@ -1,15 +1,8 @@
"""The Airly integration."""
from __future__ import annotations
from asyncio import timeout
from datetime import timedelta
import logging
from math import ceil
from aiohttp import ClientSession
from aiohttp.client_exceptions import ClientConnectorError
from airly import Airly
from airly.exceptions import AirlyError
from homeassistant.components.air_quality import DOMAIN as AIR_QUALITY_PLATFORM
from homeassistant.config_entries import ConfigEntry
@@ -17,53 +10,15 @@ from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, Pla
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util import dt as dt_util
from .const import (
ATTR_API_ADVICE,
ATTR_API_CAQI,
ATTR_API_CAQI_DESCRIPTION,
ATTR_API_CAQI_LEVEL,
CONF_USE_NEAREST,
DOMAIN,
MAX_UPDATE_INTERVAL,
MIN_UPDATE_INTERVAL,
NO_AIRLY_SENSORS,
)
from .const import CONF_USE_NEAREST, DOMAIN, MIN_UPDATE_INTERVAL
from .coordinator import AirlyDataUpdateCoordinator
PLATFORMS = [Platform.SENSOR]
_LOGGER = logging.getLogger(__name__)
def set_update_interval(instances_count: int, requests_remaining: int) -> timedelta:
"""Return data update interval.
The number of requests is reset at midnight UTC so we calculate the update
interval based on number of minutes until midnight, the number of Airly instances
and the number of remaining requests.
"""
now = dt_util.utcnow()
midnight = dt_util.find_next_time_expression_time(
now, seconds=[0], minutes=[0], hours=[0]
)
minutes_to_midnight = (midnight - now).total_seconds() / 60
interval = timedelta(
minutes=min(
max(
ceil(minutes_to_midnight / requests_remaining * instances_count),
MIN_UPDATE_INTERVAL,
),
MAX_UPDATE_INTERVAL,
)
)
_LOGGER.debug("Data will be update every %s", interval)
return interval
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Airly as config entry."""
api_key = entry.data[CONF_API_KEY]
@@ -131,75 +86,3 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
class AirlyDataUpdateCoordinator(DataUpdateCoordinator):
"""Define an object to hold Airly data."""
def __init__(
self,
hass: HomeAssistant,
session: ClientSession,
api_key: str,
latitude: float,
longitude: float,
update_interval: timedelta,
use_nearest: bool,
) -> None:
"""Initialize."""
self.latitude = latitude
self.longitude = longitude
# Currently, Airly only supports Polish and English
language = "pl" if hass.config.language == "pl" else "en"
self.airly = Airly(api_key, session, language=language)
self.use_nearest = use_nearest
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
async def _async_update_data(self) -> dict[str, str | float | int]:
"""Update data via library."""
data: dict[str, str | float | int] = {}
if self.use_nearest:
measurements = self.airly.create_measurements_session_nearest(
self.latitude, self.longitude, max_distance_km=5
)
else:
measurements = self.airly.create_measurements_session_point(
self.latitude, self.longitude
)
async with timeout(20):
try:
await measurements.update()
except (AirlyError, ClientConnectorError) as error:
raise UpdateFailed(error) from error
_LOGGER.debug(
"Requests remaining: %s/%s",
self.airly.requests_remaining,
self.airly.requests_per_day,
)
# Airly API sometimes returns None for requests remaining so we update
# update_interval only if we have valid value.
if self.airly.requests_remaining:
self.update_interval = set_update_interval(
len(self.hass.config_entries.async_entries(DOMAIN)),
self.airly.requests_remaining,
)
values = measurements.current["values"]
index = measurements.current["indexes"][0]
standards = measurements.current["standards"]
if index["description"] == NO_AIRLY_SENSORS:
raise UpdateFailed("Can't retrieve data: no Airly sensors in this area")
for value in values:
data[value["name"]] = value["value"]
for standard in standards:
data[f"{standard['pollutant']}_LIMIT"] = standard["limit"]
data[f"{standard['pollutant']}_PERCENT"] = standard["percent"]
data[ATTR_API_CAQI] = index["value"]
data[ATTR_API_CAQI_LEVEL] = index["level"].lower().replace("_", " ")
data[ATTR_API_CAQI_DESCRIPTION] = index["description"]
data[ATTR_API_ADVICE] = index["advice"]
return data

View File

@@ -0,0 +1,126 @@
"""DataUpdateCoordinator for the Airly integration."""
from asyncio import timeout
from datetime import timedelta
import logging
from math import ceil
from aiohttp import ClientSession
from aiohttp.client_exceptions import ClientConnectorError
from airly import Airly
from airly.exceptions import AirlyError
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_ADVICE,
ATTR_API_CAQI,
ATTR_API_CAQI_DESCRIPTION,
ATTR_API_CAQI_LEVEL,
DOMAIN,
MAX_UPDATE_INTERVAL,
MIN_UPDATE_INTERVAL,
NO_AIRLY_SENSORS,
)
_LOGGER = logging.getLogger(__name__)
def set_update_interval(instances_count: int, requests_remaining: int) -> timedelta:
"""Return data update interval.
The number of requests is reset at midnight UTC so we calculate the update
interval based on number of minutes until midnight, the number of Airly instances
and the number of remaining requests.
"""
now = dt_util.utcnow()
midnight = dt_util.find_next_time_expression_time(
now, seconds=[0], minutes=[0], hours=[0]
)
minutes_to_midnight = (midnight - now).total_seconds() / 60
interval = timedelta(
minutes=min(
max(
ceil(minutes_to_midnight / requests_remaining * instances_count),
MIN_UPDATE_INTERVAL,
),
MAX_UPDATE_INTERVAL,
)
)
_LOGGER.debug("Data will be update every %s", interval)
return interval
class AirlyDataUpdateCoordinator(DataUpdateCoordinator):
"""Define an object to hold Airly data."""
def __init__(
self,
hass: HomeAssistant,
session: ClientSession,
api_key: str,
latitude: float,
longitude: float,
update_interval: timedelta,
use_nearest: bool,
) -> None:
"""Initialize."""
self.latitude = latitude
self.longitude = longitude
# Currently, Airly only supports Polish and English
language = "pl" if hass.config.language == "pl" else "en"
self.airly = Airly(api_key, session, language=language)
self.use_nearest = use_nearest
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
async def _async_update_data(self) -> dict[str, str | float | int]:
"""Update data via library."""
data: dict[str, str | float | int] = {}
if self.use_nearest:
measurements = self.airly.create_measurements_session_nearest(
self.latitude, self.longitude, max_distance_km=5
)
else:
measurements = self.airly.create_measurements_session_point(
self.latitude, self.longitude
)
async with timeout(20):
try:
await measurements.update()
except (AirlyError, ClientConnectorError) as error:
raise UpdateFailed(error) from error
_LOGGER.debug(
"Requests remaining: %s/%s",
self.airly.requests_remaining,
self.airly.requests_per_day,
)
# Airly API sometimes returns None for requests remaining so we update
# update_interval only if we have valid value.
if self.airly.requests_remaining:
self.update_interval = set_update_interval(
len(self.hass.config_entries.async_entries(DOMAIN)),
self.airly.requests_remaining,
)
values = measurements.current["values"]
index = measurements.current["indexes"][0]
standards = measurements.current["standards"]
if index["description"] == NO_AIRLY_SENSORS:
raise UpdateFailed("Can't retrieve data: no Airly sensors in this area")
for value in values:
data[value["name"]] = value["value"]
for standard in standards:
data[f"{standard['pollutant']}_LIMIT"] = standard["limit"]
data[f"{standard['pollutant']}_PERCENT"] = standard["percent"]
data[ATTR_API_CAQI] = index["value"]
data[ATTR_API_CAQI_LEVEL] = index["level"].lower().replace("_", " ")
data[ATTR_API_CAQI_DESCRIPTION] = index["description"]
data[ATTR_API_ADVICE] = index["advice"]
return data

View File

@@ -2,11 +2,6 @@
import datetime
import logging
from aiohttp.client_exceptions import ClientConnectorError
from pyairnow import WebServiceAPI
from pyairnow.conv import aqi_to_concentration
from pyairnow.errors import AirNowError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_API_KEY,
@@ -17,26 +12,9 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import (
ATTR_API_AQI,
ATTR_API_AQI_DESCRIPTION,
ATTR_API_AQI_LEVEL,
ATTR_API_AQI_PARAM,
ATTR_API_CAT_DESCRIPTION,
ATTR_API_CAT_LEVEL,
ATTR_API_CATEGORY,
ATTR_API_PM25,
ATTR_API_POLLUTANT,
ATTR_API_REPORT_DATE,
ATTR_API_REPORT_HOUR,
ATTR_API_STATE,
ATTR_API_STATION,
ATTR_API_STATION_LATITUDE,
ATTR_API_STATION_LONGITUDE,
DOMAIN,
)
from .const import DOMAIN
from .coordinator import AirNowDataUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
PLATFORMS = [Platform.SENSOR]
@@ -107,72 +85,3 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Handle options update."""
await hass.config_entries.async_reload(entry.entry_id)
class AirNowDataUpdateCoordinator(DataUpdateCoordinator):
"""Define an object to hold Airly data."""
def __init__(
self, hass, session, api_key, latitude, longitude, distance, update_interval
):
"""Initialize."""
self.latitude = latitude
self.longitude = longitude
self.distance = distance
self.airnow = WebServiceAPI(api_key, session=session)
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
async def _async_update_data(self):
"""Update data via library."""
data = {}
try:
obs = await self.airnow.observations.latLong(
self.latitude,
self.longitude,
distance=self.distance,
)
except (AirNowError, ClientConnectorError) as error:
raise UpdateFailed(error) from error
if not obs:
raise UpdateFailed("No data was returned from AirNow")
max_aqi = 0
max_aqi_level = 0
max_aqi_desc = ""
max_aqi_poll = ""
for obv in obs:
# Convert AQIs to Concentration
pollutant = obv[ATTR_API_AQI_PARAM]
concentration = aqi_to_concentration(obv[ATTR_API_AQI], pollutant)
data[obv[ATTR_API_AQI_PARAM]] = concentration
# Overall AQI is the max of all pollutant AQIs
if obv[ATTR_API_AQI] > max_aqi:
max_aqi = obv[ATTR_API_AQI]
max_aqi_level = obv[ATTR_API_CATEGORY][ATTR_API_CAT_LEVEL]
max_aqi_desc = obv[ATTR_API_CATEGORY][ATTR_API_CAT_DESCRIPTION]
max_aqi_poll = pollutant
# Copy other data from PM2.5 Value
if obv[ATTR_API_AQI_PARAM] == ATTR_API_PM25:
# Copy Report Details
data[ATTR_API_REPORT_DATE] = obv[ATTR_API_REPORT_DATE]
data[ATTR_API_REPORT_HOUR] = obv[ATTR_API_REPORT_HOUR]
# Copy Station Details
data[ATTR_API_STATE] = obv[ATTR_API_STATE]
data[ATTR_API_STATION] = obv[ATTR_API_STATION]
data[ATTR_API_STATION_LATITUDE] = obv[ATTR_API_STATION_LATITUDE]
data[ATTR_API_STATION_LONGITUDE] = obv[ATTR_API_STATION_LONGITUDE]
# Store Overall AQI
data[ATTR_API_AQI] = max_aqi
data[ATTR_API_AQI_LEVEL] = max_aqi_level
data[ATTR_API_AQI_DESCRIPTION] = max_aqi_desc
data[ATTR_API_POLLUTANT] = max_aqi_poll
return data

View File

@@ -0,0 +1,99 @@
"""DataUpdateCoordinator for the AirNow integration."""
import logging
from aiohttp.client_exceptions import ClientConnectorError
from pyairnow import WebServiceAPI
from pyairnow.conv import aqi_to_concentration
from pyairnow.errors import AirNowError
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import (
ATTR_API_AQI,
ATTR_API_AQI_DESCRIPTION,
ATTR_API_AQI_LEVEL,
ATTR_API_AQI_PARAM,
ATTR_API_CAT_DESCRIPTION,
ATTR_API_CAT_LEVEL,
ATTR_API_CATEGORY,
ATTR_API_PM25,
ATTR_API_POLLUTANT,
ATTR_API_REPORT_DATE,
ATTR_API_REPORT_HOUR,
ATTR_API_STATE,
ATTR_API_STATION,
ATTR_API_STATION_LATITUDE,
ATTR_API_STATION_LONGITUDE,
DOMAIN,
)
_LOGGER = logging.getLogger(__name__)
class AirNowDataUpdateCoordinator(DataUpdateCoordinator):
"""The AirNow update coordinator."""
def __init__(
self, hass, session, api_key, latitude, longitude, distance, update_interval
):
"""Initialize."""
self.latitude = latitude
self.longitude = longitude
self.distance = distance
self.airnow = WebServiceAPI(api_key, session=session)
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
async def _async_update_data(self):
"""Update data via library."""
data = {}
try:
obs = await self.airnow.observations.latLong(
self.latitude,
self.longitude,
distance=self.distance,
)
except (AirNowError, ClientConnectorError) as error:
raise UpdateFailed(error) from error
if not obs:
raise UpdateFailed("No data was returned from AirNow")
max_aqi = 0
max_aqi_level = 0
max_aqi_desc = ""
max_aqi_poll = ""
for obv in obs:
# Convert AQIs to Concentration
pollutant = obv[ATTR_API_AQI_PARAM]
concentration = aqi_to_concentration(obv[ATTR_API_AQI], pollutant)
data[obv[ATTR_API_AQI_PARAM]] = concentration
# Overall AQI is the max of all pollutant AQIs
if obv[ATTR_API_AQI] > max_aqi:
max_aqi = obv[ATTR_API_AQI]
max_aqi_level = obv[ATTR_API_CATEGORY][ATTR_API_CAT_LEVEL]
max_aqi_desc = obv[ATTR_API_CATEGORY][ATTR_API_CAT_DESCRIPTION]
max_aqi_poll = pollutant
# Copy other data from PM2.5 Value
if obv[ATTR_API_AQI_PARAM] == ATTR_API_PM25:
# Copy Report Details
data[ATTR_API_REPORT_DATE] = obv[ATTR_API_REPORT_DATE]
data[ATTR_API_REPORT_HOUR] = obv[ATTR_API_REPORT_HOUR]
# Copy Station Details
data[ATTR_API_STATE] = obv[ATTR_API_STATE]
data[ATTR_API_STATION] = obv[ATTR_API_STATION]
data[ATTR_API_STATION_LATITUDE] = obv[ATTR_API_STATION_LATITUDE]
data[ATTR_API_STATION_LONGITUDE] = obv[ATTR_API_STATION_LONGITUDE]
# Store Overall AQI
data[ATTR_API_AQI] = max_aqi
data[ATTR_API_AQI_LEVEL] = max_aqi_level
data[ATTR_API_AQI_DESCRIPTION] = max_aqi_desc
data[ATTR_API_POLLUTANT] = max_aqi_poll
return data

View File

@@ -58,6 +58,16 @@ class AirNowEntityDescription(SensorEntityDescription, AirNowEntityDescriptionMi
"""Describes Airnow sensor entity."""
def station_extra_attrs(data: dict[str, Any]) -> dict[str, Any]:
"""Process extra attributes for station location (if available)."""
if ATTR_API_STATION in data:
return {
"lat": data.get(ATTR_API_STATION_LATITUDE),
"long": data.get(ATTR_API_STATION_LONGITUDE),
}
return {}
SENSOR_TYPES: tuple[AirNowEntityDescription, ...] = (
AirNowEntityDescription(
key=ATTR_API_AQI,
@@ -93,10 +103,7 @@ SENSOR_TYPES: tuple[AirNowEntityDescription, ...] = (
translation_key="station",
icon="mdi:blur",
value_fn=lambda data: data.get(ATTR_API_STATION),
extra_state_attributes_fn=lambda data: {
"lat": data[ATTR_API_STATION_LATITUDE],
"long": data[ATTR_API_STATION_LONGITUDE],
},
extra_state_attributes_fn=station_extra_attrs,
),
)

View File

@@ -19,7 +19,7 @@
"service_uuid": "b42e3882-ade7-11e4-89d3-123b93f75cba"
}
],
"codeowners": ["@vincegio"],
"codeowners": ["@vincegio", "@LaStrada"],
"config_flow": true,
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",

View File

@@ -5,25 +5,35 @@ import logging
from airthings_ble import AirthingsDevice
from homeassistant import config_entries
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONCENTRATION_PARTS_PER_BILLION,
CONCENTRATION_PARTS_PER_MILLION,
LIGHT_LUX,
PERCENTAGE,
EntityCategory,
Platform,
UnitOfPressure,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH, DeviceInfo
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import (
CONNECTION_BLUETOOTH,
DeviceInfo,
async_get as device_async_get,
)
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.entity_registry import (
RegistryEntry,
async_entries_for_device,
async_get as entity_async_get,
)
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
@@ -107,9 +117,44 @@ SENSORS_MAPPING_TEMPLATE: dict[str, SensorEntityDescription] = {
}
@callback
def async_migrate(hass: HomeAssistant, address: str, sensor_name: str) -> None:
"""Migrate entities to new unique ids (with BLE Address)."""
ent_reg = entity_async_get(hass)
unique_id_trailer = f"_{sensor_name}"
new_unique_id = f"{address}{unique_id_trailer}"
if ent_reg.async_get_entity_id(DOMAIN, Platform.SENSOR, new_unique_id):
# New unique id already exists
return
dev_reg = device_async_get(hass)
if not (
device := dev_reg.async_get_device(
connections={(CONNECTION_BLUETOOTH, address)}
)
):
return
entities = async_entries_for_device(
ent_reg,
device_id=device.id,
include_disabled_entities=True,
)
matching_reg_entry: RegistryEntry | None = None
for entry in entities:
if entry.unique_id.endswith(unique_id_trailer) and (
not matching_reg_entry or "(" not in entry.unique_id
):
matching_reg_entry = entry
if not matching_reg_entry or matching_reg_entry.unique_id == new_unique_id:
# Already has the newest unique id format
return
entity_id = matching_reg_entry.entity_id
ent_reg.async_update_entity(entity_id=entity_id, new_unique_id=new_unique_id)
_LOGGER.debug("Migrated entity '%s' to unique id '%s'", entity_id, new_unique_id)
async def async_setup_entry(
hass: HomeAssistant,
entry: config_entries.ConfigEntry,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Airthings BLE sensors."""
@@ -137,6 +182,7 @@ async def async_setup_entry(
sensor_value,
)
continue
async_migrate(hass, coordinator.data.address, sensor_type)
entities.append(
AirthingsSensor(coordinator, coordinator.data, sensors_mapping[sensor_type])
)
@@ -165,7 +211,7 @@ class AirthingsSensor(
if identifier := airthings_device.identifier:
name += f" ({identifier})"
self._attr_unique_id = f"{name}_{entity_description.key}"
self._attr_unique_id = f"{airthings_device.address}_{entity_description.key}"
self._attr_device_info = DeviceInfo(
connections={
(

View File

@@ -1,19 +1,13 @@
"""The AirTouch4 integration."""
import logging
from airtouch4pyapi import AirTouch
from airtouch4pyapi.airtouch import AirTouchStatus
from homeassistant.components.climate import SCAN_INTERVAL
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
from .coordinator import AirtouchDataUpdateCoordinator
PLATFORMS = [Platform.CLIMATE]
@@ -44,38 +38,3 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
class AirtouchDataUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching Airtouch data."""
def __init__(self, hass, airtouch):
"""Initialize global Airtouch data updater."""
self.airtouch = airtouch
super().__init__(
hass,
_LOGGER,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)
async def _async_update_data(self):
"""Fetch data from Airtouch."""
await self.airtouch.UpdateInfo()
if self.airtouch.Status != AirTouchStatus.OK:
raise UpdateFailed("Airtouch connection issue")
return {
"acs": [
{"ac_number": ac.AcNumber, "is_on": ac.IsOn}
for ac in self.airtouch.GetAcs()
],
"groups": [
{
"group_number": group.GroupNumber,
"group_name": group.GroupName,
"is_on": group.IsOn,
}
for group in self.airtouch.GetGroups()
],
}

View File

@@ -0,0 +1,46 @@
"""DataUpdateCoordinator for the airtouch integration."""
import logging
from airtouch4pyapi.airtouch import AirTouchStatus
from homeassistant.components.climate import SCAN_INTERVAL
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
class AirtouchDataUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching Airtouch data."""
def __init__(self, hass, airtouch):
"""Initialize global Airtouch data updater."""
self.airtouch = airtouch
super().__init__(
hass,
_LOGGER,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)
async def _async_update_data(self):
"""Fetch data from Airtouch."""
await self.airtouch.UpdateInfo()
if self.airtouch.Status != AirTouchStatus.OK:
raise UpdateFailed("Airtouch connection issue")
return {
"acs": [
{"ac_number": ac.AcNumber, "is_on": ac.IsOn}
for ac in self.airtouch.GetAcs()
],
"groups": [
{
"group_number": group.GroupNumber,
"group_name": group.GroupName,
"is_on": group.IsOn,
}
for group in self.airtouch.GetGroups()
],
}

View File

@@ -1,7 +1,7 @@
{
"domain": "airtouch4",
"name": "AirTouch 4",
"codeowners": [],
"codeowners": ["@samsinnamon"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airtouch4",
"iot_class": "local_polling",

View File

@@ -421,8 +421,10 @@ class AirVisualEntity(CoordinatorEntity):
self._entry = entry
self.entity_description = description
# pylint: disable-next=hass-missing-super-call
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
await super().async_added_to_hass()
@callback
def update() -> None:

View File

@@ -24,6 +24,7 @@ PLATFORMS: list[Platform] = [
Platform.CLIMATE,
Platform.SELECT,
Platform.SENSOR,
Platform.WATER_HEATER,
]
_LOGGER = logging.getLogger(__name__)

View File

@@ -106,6 +106,22 @@ class AirzoneHotWaterEntity(AirzoneEntity):
"""Return DHW value by key."""
return self.coordinator.data[AZD_HOT_WATER].get(key)
async def _async_update_dhw_params(self, params: dict[str, Any]) -> None:
"""Send DHW parameters to API."""
_params = {
API_SYSTEM_ID: 0,
**params,
}
_LOGGER.debug("update_dhw_params=%s", _params)
try:
await self.coordinator.airzone.set_dhw_parameters(_params)
except AirzoneError as error:
raise HomeAssistantError(
f"Failed to set dhw {self.name}: {error}"
) from error
self.coordinator.async_set_updated_data(self.coordinator.airzone.data())
class AirzoneWebServerEntity(AirzoneEntity):
"""Define an Airzone WebServer entity."""

View File

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

View File

@@ -0,0 +1,131 @@
"""Support for the Airzone water heater."""
from __future__ import annotations
from typing import Any, Final
from aioairzone.common import HotWaterOperation
from aioairzone.const import (
API_ACS_ON,
API_ACS_POWER_MODE,
API_ACS_SET_POINT,
AZD_HOT_WATER,
AZD_NAME,
AZD_OPERATION,
AZD_OPERATIONS,
AZD_TEMP,
AZD_TEMP_MAX,
AZD_TEMP_MIN,
AZD_TEMP_SET,
AZD_TEMP_UNIT,
)
from homeassistant.components.water_heater import (
STATE_ECO,
STATE_PERFORMANCE,
WaterHeaterEntity,
WaterHeaterEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, TEMP_UNIT_LIB_TO_HASS
from .coordinator import AirzoneUpdateCoordinator
from .entity import AirzoneHotWaterEntity
OPERATION_LIB_TO_HASS: Final[dict[HotWaterOperation, str]] = {
HotWaterOperation.Off: STATE_OFF,
HotWaterOperation.On: STATE_ECO,
HotWaterOperation.Powerful: STATE_PERFORMANCE,
}
OPERATION_MODE_TO_DHW_PARAMS: Final[dict[str, dict[str, Any]]] = {
STATE_OFF: {
API_ACS_ON: 0,
},
STATE_ECO: {
API_ACS_ON: 1,
API_ACS_POWER_MODE: 0,
},
STATE_PERFORMANCE: {
API_ACS_ON: 1,
API_ACS_POWER_MODE: 1,
},
}
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Add Airzone sensors from a config_entry."""
coordinator = hass.data[DOMAIN][entry.entry_id]
if AZD_HOT_WATER in coordinator.data:
async_add_entities([AirzoneWaterHeater(coordinator, entry)])
class AirzoneWaterHeater(AirzoneHotWaterEntity, WaterHeaterEntity):
"""Define an Airzone Water Heater."""
_attr_supported_features = (
WaterHeaterEntityFeature.TARGET_TEMPERATURE
| WaterHeaterEntityFeature.ON_OFF
| WaterHeaterEntityFeature.OPERATION_MODE
)
def __init__(
self,
coordinator: AirzoneUpdateCoordinator,
entry: ConfigEntry,
) -> None:
"""Initialize Airzone water heater entity."""
super().__init__(coordinator, entry)
self._attr_name = self.get_airzone_value(AZD_NAME)
self._attr_unique_id = f"{self._attr_unique_id}_dhw"
self._attr_operation_list = [
OPERATION_LIB_TO_HASS[operation]
for operation in self.get_airzone_value(AZD_OPERATIONS)
]
self._attr_temperature_unit = TEMP_UNIT_LIB_TO_HASS[
self.get_airzone_value(AZD_TEMP_UNIT)
]
self._async_update_attrs()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the water heater off."""
await self._async_update_dhw_params({API_ACS_ON: 0})
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the water heater off."""
await self._async_update_dhw_params({API_ACS_ON: 1})
async def async_set_operation_mode(self, operation_mode: str) -> None:
"""Set new target operation mode."""
params = OPERATION_MODE_TO_DHW_PARAMS.get(operation_mode, {})
await self._async_update_dhw_params(params)
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
params: dict[str, Any] = {}
if ATTR_TEMPERATURE in kwargs:
params[API_ACS_SET_POINT] = kwargs[ATTR_TEMPERATURE]
await self._async_update_dhw_params(params)
@callback
def _handle_coordinator_update(self) -> None:
"""Update attributes when the coordinator updates."""
self._async_update_attrs()
super()._handle_coordinator_update()
@callback
def _async_update_attrs(self) -> None:
"""Update water heater attributes."""
self._attr_current_temperature = self.get_airzone_value(AZD_TEMP)
self._attr_current_operation = OPERATION_LIB_TO_HASS[
self.get_airzone_value(AZD_OPERATION)
]
self._attr_max_temp = self.get_airzone_value(AZD_TEMP_MAX)
self._attr_min_temp = self.get_airzone_value(AZD_TEMP_MIN)
self._attr_target_temperature = self.get_airzone_value(AZD_TEMP_SET)

View File

@@ -14,6 +14,7 @@ from .coordinator import AirzoneUpdateCoordinator
PLATFORMS: list[Platform] = [
Platform.BINARY_SENSOR,
Platform.CLIMATE,
Platform.SENSOR,
]

View File

@@ -0,0 +1,208 @@
"""Support for the Airzone Cloud climate."""
from __future__ import annotations
from typing import Any, Final
from aioairzone_cloud.common import OperationAction, OperationMode, TemperatureUnit
from aioairzone_cloud.const import (
API_MODE,
API_OPTS,
API_POWER,
API_SETPOINT,
API_UNITS,
API_VALUE,
AZD_ACTION,
AZD_HUMIDITY,
AZD_MASTER,
AZD_MODE,
AZD_MODES,
AZD_POWER,
AZD_TEMP,
AZD_TEMP_SET,
AZD_TEMP_SET_MAX,
AZD_TEMP_SET_MIN,
AZD_TEMP_STEP,
AZD_ZONES,
)
from homeassistant.components.climate import (
ClimateEntity,
ClimateEntityFeature,
HVACAction,
HVACMode,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import AirzoneUpdateCoordinator
from .entity import AirzoneEntity, AirzoneZoneEntity
HVAC_ACTION_LIB_TO_HASS: Final[dict[OperationAction, HVACAction]] = {
OperationAction.COOLING: HVACAction.COOLING,
OperationAction.DRYING: HVACAction.DRYING,
OperationAction.FAN: HVACAction.FAN,
OperationAction.HEATING: HVACAction.HEATING,
OperationAction.IDLE: HVACAction.IDLE,
OperationAction.OFF: HVACAction.OFF,
}
HVAC_MODE_LIB_TO_HASS: Final[dict[OperationMode, HVACMode]] = {
OperationMode.STOP: HVACMode.OFF,
OperationMode.COOLING: HVACMode.COOL,
OperationMode.COOLING_AIR: HVACMode.COOL,
OperationMode.COOLING_RADIANT: HVACMode.COOL,
OperationMode.COOLING_COMBINED: HVACMode.COOL,
OperationMode.HEATING: HVACMode.HEAT,
OperationMode.HEAT_AIR: HVACMode.HEAT,
OperationMode.HEAT_RADIANT: HVACMode.HEAT,
OperationMode.HEAT_COMBINED: HVACMode.HEAT,
OperationMode.EMERGENCY_HEAT: HVACMode.HEAT,
OperationMode.VENTILATION: HVACMode.FAN_ONLY,
OperationMode.DRY: HVACMode.DRY,
OperationMode.AUTO: HVACMode.HEAT_COOL,
}
HVAC_MODE_HASS_TO_LIB: Final[dict[HVACMode, OperationMode]] = {
HVACMode.OFF: OperationMode.STOP,
HVACMode.COOL: OperationMode.COOLING,
HVACMode.HEAT: OperationMode.HEATING,
HVACMode.FAN_ONLY: OperationMode.VENTILATION,
HVACMode.DRY: OperationMode.DRY,
HVACMode.HEAT_COOL: OperationMode.AUTO,
}
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Add Airzone climate from a config_entry."""
coordinator: AirzoneUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
entities: list[AirzoneClimate] = []
# Zones
for zone_id, zone_data in coordinator.data.get(AZD_ZONES, {}).items():
entities.append(
AirzoneZoneClimate(
coordinator,
zone_id,
zone_data,
)
)
async_add_entities(entities)
class AirzoneClimate(AirzoneEntity, ClimateEntity):
"""Define an Airzone Cloud climate."""
_attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
_attr_temperature_unit = UnitOfTemperature.CELSIUS
async def async_turn_on(self) -> None:
"""Turn the entity on."""
params = {
API_POWER: {
API_VALUE: True,
},
}
await self._async_update_params(params)
async def async_turn_off(self) -> None:
"""Turn the entity off."""
params = {
API_POWER: {
API_VALUE: False,
},
}
await self._async_update_params(params)
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
params: dict[str, Any] = {}
if ATTR_TEMPERATURE in kwargs:
params[API_SETPOINT] = {
API_VALUE: kwargs[ATTR_TEMPERATURE],
API_OPTS: {
API_UNITS: TemperatureUnit.CELSIUS.value,
},
}
await self._async_update_params(params)
@callback
def _handle_coordinator_update(self) -> None:
"""Update attributes when the coordinator updates."""
self._async_update_attrs()
super()._handle_coordinator_update()
@callback
def _async_update_attrs(self) -> None:
"""Update climate attributes."""
self._attr_current_temperature = self.get_airzone_value(AZD_TEMP)
self._attr_current_humidity = self.get_airzone_value(AZD_HUMIDITY)
self._attr_hvac_action = HVAC_ACTION_LIB_TO_HASS[
self.get_airzone_value(AZD_ACTION)
]
if self.get_airzone_value(AZD_POWER):
self._attr_hvac_mode = HVAC_MODE_LIB_TO_HASS[
self.get_airzone_value(AZD_MODE)
]
else:
self._attr_hvac_mode = HVACMode.OFF
self._attr_max_temp = self.get_airzone_value(AZD_TEMP_SET_MAX)
self._attr_min_temp = self.get_airzone_value(AZD_TEMP_SET_MIN)
self._attr_target_temperature = self.get_airzone_value(AZD_TEMP_SET)
class AirzoneZoneClimate(AirzoneZoneEntity, AirzoneClimate):
"""Define an Airzone Cloud Zone climate."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: AirzoneUpdateCoordinator,
system_zone_id: str,
zone_data: dict,
) -> None:
"""Initialize Airzone Cloud Zone climate."""
super().__init__(coordinator, system_zone_id, zone_data)
self._attr_unique_id = system_zone_id
self._attr_target_temperature_step = self.get_airzone_value(AZD_TEMP_STEP)
self._attr_hvac_modes = [
HVAC_MODE_LIB_TO_HASS[mode] for mode in self.get_airzone_value(AZD_MODES)
]
if HVACMode.OFF not in self._attr_hvac_modes:
self._attr_hvac_modes += [HVACMode.OFF]
self._async_update_attrs()
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set hvac mode."""
slave_raise = False
params: dict[str, Any] = {}
if hvac_mode == HVACMode.OFF:
params[API_POWER] = {
API_VALUE: False,
}
else:
mode = HVAC_MODE_HASS_TO_LIB[hvac_mode]
if mode != self.get_airzone_value(AZD_MODE):
if self.get_airzone_value(AZD_MASTER):
params[API_MODE] = {
API_VALUE: mode.value,
}
else:
slave_raise = True
params[API_POWER] = {
API_VALUE: True,
}
await self._async_update_params(params)
if slave_raise:
raise HomeAssistantError(f"Mode can't be changed on slave zone {self.name}")

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from abc import ABC, abstractmethod
import logging
from typing import Any
from aioairzone_cloud.const import (
@@ -15,7 +16,9 @@ from aioairzone_cloud.const import (
AZD_WEBSERVERS,
AZD_ZONES,
)
from aioairzone_cloud.exceptions import AirzoneCloudError
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@@ -23,6 +26,8 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, MANUFACTURER
from .coordinator import AirzoneUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator], ABC):
"""Define an Airzone Cloud entity."""
@@ -36,6 +41,10 @@ class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator], ABC):
def get_airzone_value(self, key: str) -> Any:
"""Return Airzone Cloud entity value by key."""
async def _async_update_params(self, params: dict[str, Any]) -> None:
"""Send Airzone parameters to Cloud API."""
raise NotImplementedError
class AirzoneAidooEntity(AirzoneEntity):
"""Define an Airzone Cloud Aidoo entity."""
@@ -153,3 +162,15 @@ class AirzoneZoneEntity(AirzoneEntity):
if zone := self.coordinator.data[AZD_ZONES].get(self.zone_id):
value = zone.get(key)
return value
async def _async_update_params(self, params: dict[str, Any]) -> None:
"""Send Zone parameters to Cloud API."""
_LOGGER.debug("zone=%s: update_params=%s", self.name, params)
try:
await self.coordinator.airzone.api_set_zone_id_params(self.zone_id, params)
except AirzoneCloudError as error:
raise HomeAssistantError(
f"Failed to set {self.name} params: {error}"
) from error
self.coordinator.async_set_updated_data(self.coordinator.airzone.data())

View File

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

View File

@@ -10,7 +10,7 @@ from homeassistant.components.cover import CoverDeviceClass, CoverEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_CLOSED, STATE_CLOSING, STATE_OPENING
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import PlatformNotReady
from homeassistant.exceptions import HomeAssistantError, PlatformNotReady
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@@ -75,11 +75,13 @@ class AladdinDevice(CoverEntity):
async def async_close_cover(self, **kwargs: Any) -> None:
"""Issue close command to cover."""
await self._acc.close_door(self._device_id, self._number)
if not await self._acc.close_door(self._device_id, self._number):
raise HomeAssistantError("Aladdin Connect API failed to close the cover")
async def async_open_cover(self, **kwargs: Any) -> None:
"""Issue open command to cover."""
await self._acc.open_door(self._device_id, self._number)
if not await self._acc.open_door(self._device_id, self._number):
raise HomeAssistantError("Aladdin Connect API failed to open the cover")
async def async_update(self) -> None:
"""Update status of cover."""

View File

@@ -0,0 +1,29 @@
"""Diagnostics support for Aladdin Connect."""
from __future__ import annotations
from typing import Any
from AIOAladdinConnect import AladdinConnectClient
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from .const import DOMAIN
TO_REDACT = {"serial", "device_id"}
async def async_get_config_entry_diagnostics(
hass: HomeAssistant,
config_entry: ConfigEntry,
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
acc: AladdinConnectClient = hass.data[DOMAIN][config_entry.entry_id]
diagnostics_data = {
"doors": async_redact_data(acc.doors, TO_REDACT),
}
return diagnostics_data

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/aladdin_connect",
"iot_class": "cloud_polling",
"loggers": ["aladdin_connect"],
"requirements": ["AIOAladdinConnect==0.1.57"]
"requirements": ["AIOAladdinConnect==0.1.58"]
}

View File

@@ -707,7 +707,8 @@ class MediaPlayerCapabilities(AlexaEntity):
# AlexaEqualizerController is disabled for denonavr
# since it blocks alexa from discovering any devices.
domain = entity_sources(self.hass).get(self.entity_id, {}).get("domain")
entity_info = entity_sources(self.hass).get(self.entity_id)
domain = entity_info["domain"] if entity_info else None
if (
supported & media_player.MediaPlayerEntityFeature.SELECT_SOUND_MODE
and domain != "denonavr"

View File

@@ -90,6 +90,13 @@ class AlexaUnsupportedThermostatModeError(AlexaError):
error_type = "UNSUPPORTED_THERMOSTAT_MODE"
class AlexaUnsupportedThermostatTargetStateError(AlexaError):
"""Class to represent unsupported climate target state error."""
namespace = "Alexa.ThermostatController"
error_type = "INVALID_TARGET_STATE"
class AlexaTempRangeError(AlexaError):
"""Class to represent TempRange errors."""

View File

@@ -73,6 +73,7 @@ from .errors import (
AlexaSecurityPanelAuthorizationRequired,
AlexaTempRangeError,
AlexaUnsupportedThermostatModeError,
AlexaUnsupportedThermostatTargetStateError,
AlexaVideoActionNotPermittedForContentError,
)
from .state_report import AlexaDirective, AlexaResponse, async_enable_proactive_mode
@@ -911,7 +912,13 @@ async def async_api_adjust_target_temp(
}
)
else:
target_temp = float(entity.attributes[ATTR_TEMPERATURE]) + temp_delta
current_target_temp: str | None = entity.attributes.get(ATTR_TEMPERATURE)
if current_target_temp is None:
raise AlexaUnsupportedThermostatTargetStateError(
"The current target temperature is not set, "
"cannot adjust target temperature"
)
target_temp = float(current_target_temp) + temp_delta
if target_temp < min_temp or target_temp > max_temp:
raise AlexaTempRangeError(hass, target_temp, min_temp, max_temp)

View File

@@ -378,8 +378,9 @@ async def async_send_changereport_message(
response_text = await response.text()
_LOGGER.debug("Sent: %s", json.dumps(message_serialized))
_LOGGER.debug("Received (%s): %s", response.status, response_text)
if _LOGGER.isEnabledFor(logging.DEBUG):
_LOGGER.debug("Sent: %s", json.dumps(message_serialized))
_LOGGER.debug("Received (%s): %s", response.status, response_text)
if response.status == HTTPStatus.ACCEPTED:
return
@@ -531,8 +532,9 @@ async def async_send_doorbell_event_message(
response_text = await response.text()
_LOGGER.debug("Sent: %s", json.dumps(message_serialized))
_LOGGER.debug("Received (%s): %s", response.status, response_text)
if _LOGGER.isEnabledFor(logging.DEBUG):
_LOGGER.debug("Sent: %s", json.dumps(message_serialized))
_LOGGER.debug("Received (%s): %s", response.status, response_text)
if response.status == HTTPStatus.ACCEPTED:
return

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/amcrest",
"iot_class": "local_polling",
"loggers": ["amcrest"],
"requirements": ["amcrest==1.9.7"]
"requirements": ["amcrest==1.9.8"]
}

View File

@@ -8,8 +8,8 @@
"iot_class": "local_polling",
"loggers": ["adb_shell", "androidtv", "pure_python_adb"],
"requirements": [
"adb-shell[async]==0.4.3",
"androidtv[async]==0.0.70",
"adb-shell[async]==0.4.4",
"androidtv[async]==0.0.72",
"pure-python-adb[async]==0.3.0.dev0"
]
}

View File

@@ -9,8 +9,8 @@ from anthemav.connection import Connection
from anthemav.device_error import DeviceError
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME, CONF_PORT
from homeassistant.config_entries import ConfigFlow
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PORT
from homeassistant.data_entry_flow import FlowResult
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.device_registry import format_mac
@@ -43,7 +43,7 @@ async def connect_device(user_input: dict[str, Any]) -> Connection:
return avr
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
class AnthemAVConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Anthem A/V Receivers."""
VERSION = 1
@@ -57,9 +57,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
step_id="user", data_schema=STEP_USER_DATA_SCHEMA
)
if CONF_NAME not in user_input:
user_input[CONF_NAME] = DEFAULT_NAME
errors = {}
avr: Connection | None = None
@@ -84,7 +81,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
user_input[CONF_MODEL] = avr.protocol.model
await self.async_set_unique_id(user_input[CONF_MAC])
self._abort_if_unique_id_configured()
return self.async_create_entry(title=user_input[CONF_NAME], data=user_input)
return self.async_create_entry(title=DEFAULT_NAME, data=user_input)
finally:
if avr is not None:
avr.close()

View File

@@ -13,7 +13,7 @@ from homeassistant.components.media_player import (
MediaPlayerState,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_MAC, CONF_NAME
from homeassistant.const import CONF_MAC
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.dispatcher import async_dispatcher_connect
@@ -30,7 +30,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up entry."""
name = config_entry.data[CONF_NAME]
name = config_entry.title
mac_address = config_entry.data[CONF_MAC]
model = config_entry.data[CONF_MODEL]

View File

@@ -48,7 +48,8 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
hass.data[DOMAIN].pop(entry.entry_id)
if unload_ok and DOMAIN in hass.data:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok

View File

@@ -9,10 +9,12 @@ from aiohttp import web
from aiohttp.web_exceptions import HTTPBadRequest
import voluptuous as vol
from homeassistant.auth.models import User
from homeassistant.auth.permissions.const import POLICY_READ
from homeassistant.bootstrap import DATA_LOGGING
from homeassistant.components.http import HomeAssistantView, require_admin
from homeassistant.const import (
CONTENT_TYPE_JSON,
EVENT_HOMEASSISTANT_STOP,
MATCH_ALL,
URL_API,
@@ -28,7 +30,13 @@ from homeassistant.const import (
)
import homeassistant.core as ha
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceNotFound, TemplateError, Unauthorized
from homeassistant.exceptions import (
InvalidEntityFormatError,
InvalidStateError,
ServiceNotFound,
TemplateError,
Unauthorized,
)
from homeassistant.helpers import config_validation as cv, template
from homeassistant.helpers.json import json_dumps
from homeassistant.helpers.service import async_get_all_descriptions
@@ -189,16 +197,24 @@ class APIStatesView(HomeAssistantView):
name = "api:states"
@ha.callback
def get(self, request):
def get(self, request: web.Request) -> web.Response:
"""Get current states."""
user = request["hass_user"]
entity_perm = user.permissions.check_entity
states = [
state
for state in request.app["hass"].states.async_all()
if entity_perm(state.entity_id, "read")
]
return self.json(states)
user: User = request["hass_user"]
hass: HomeAssistant = request.app["hass"]
if user.is_admin:
states = (state.as_dict_json for state in hass.states.async_all())
else:
entity_perm = user.permissions.check_entity
states = (
state.as_dict_json
for state in hass.states.async_all()
if entity_perm(state.entity_id, "read")
)
response = web.Response(
body=f'[{",".join(states)}]', content_type=CONTENT_TYPE_JSON
)
response.enable_compression()
return response
class APIEntityStateView(HomeAssistantView):
@@ -208,21 +224,25 @@ class APIEntityStateView(HomeAssistantView):
name = "api:entity-state"
@ha.callback
def get(self, request, entity_id):
def get(self, request: web.Request, entity_id: str) -> web.Response:
"""Retrieve state of entity."""
user = request["hass_user"]
user: User = request["hass_user"]
hass: HomeAssistant = request.app["hass"]
if not user.permissions.check_entity(entity_id, POLICY_READ):
raise Unauthorized(entity_id=entity_id)
if state := request.app["hass"].states.get(entity_id):
return self.json(state)
if state := hass.states.get(entity_id):
return web.Response(
body=state.as_dict_json,
content_type=CONTENT_TYPE_JSON,
)
return self.json_message("Entity not found.", HTTPStatus.NOT_FOUND)
async def post(self, request, entity_id):
"""Update state of entity."""
if not request["hass_user"].is_admin:
raise Unauthorized(entity_id=entity_id)
hass = request.app["hass"]
hass: HomeAssistant = request.app["hass"]
try:
data = await request.json()
except ValueError:
@@ -237,13 +257,20 @@ class APIEntityStateView(HomeAssistantView):
is_new_state = hass.states.get(entity_id) is None
# Write state
hass.states.async_set(
entity_id, new_state, attributes, force_update, self.context(request)
)
try:
hass.states.async_set(
entity_id, new_state, attributes, force_update, self.context(request)
)
except InvalidEntityFormatError:
return self.json_message(
"Invalid entity ID specified.", HTTPStatus.BAD_REQUEST
)
except InvalidStateError:
return self.json_message("Invalid state specified.", HTTPStatus.BAD_REQUEST)
# Read the state back for our response
status_code = HTTPStatus.CREATED if is_new_state else HTTPStatus.OK
resp = self.json(hass.states.get(entity_id), status_code)
resp = self.json(hass.states.get(entity_id).as_dict(), status_code)
resp.headers.add("Location", f"/api/states/{entity_id}")

View File

@@ -26,7 +26,6 @@ from homeassistant.helpers.schema_config_entry_flow import (
SchemaFlowFormStep,
SchemaOptionsFlowHandler,
)
from homeassistant.util.network import is_ipv6_address
from .const import CONF_CREDENTIALS, CONF_IDENTIFIERS, CONF_START_OFF, DOMAIN
@@ -184,9 +183,9 @@ class AppleTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
self, discovery_info: zeroconf.ZeroconfServiceInfo
) -> FlowResult:
"""Handle device found via zeroconf."""
host = discovery_info.host
if is_ipv6_address(host):
if discovery_info.ip_address.version == 6:
return self.async_abort(reason="ipv6_not_supported")
host = discovery_info.host
self._async_abort_entries_match({CONF_ADDRESS: host})
service_type = discovery_info.type[:-1] # Remove leading .
name = discovery_info.name.replace(f".{service_type}.", "")

View File

@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/apprise",
"iot_class": "cloud_push",
"loggers": ["apprise"],
"requirements": ["apprise==1.4.5"]
"requirements": ["apprise==1.5.0"]
}

View File

@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/aquostv",
"iot_class": "local_polling",
"loggers": ["sharp_aquos_rc"],
"requirements": ["sharp-aquos-rc==0.3.2"]
"requirements": ["sharp_aquos_rc==0.3.2"]
}

View File

@@ -12,6 +12,7 @@ from homeassistant.helpers.typing import ConfigType
from .const import DATA_CONFIG, DOMAIN
from .error import PipelineNotFound
from .pipeline import (
AudioSettings,
Pipeline,
PipelineEvent,
PipelineEventCallback,
@@ -33,6 +34,7 @@ __all__ = (
"async_get_pipelines",
"async_setup",
"async_pipeline_from_audio_stream",
"AudioSettings",
"Pipeline",
"PipelineEvent",
"PipelineEventType",
@@ -71,6 +73,7 @@ async def async_pipeline_from_audio_stream(
conversation_id: str | None = None,
tts_audio_output: str | None = None,
wake_word_settings: WakeWordSettings | None = None,
audio_settings: AudioSettings | None = None,
device_id: str | None = None,
start_stage: PipelineStage = PipelineStage.STT,
end_stage: PipelineStage = PipelineStage.TTS,
@@ -93,6 +96,7 @@ async def async_pipeline_from_audio_stream(
event_callback=event_callback,
tts_audio_output=tts_audio_output,
wake_word_settings=wake_word_settings,
audio_settings=audio_settings or AudioSettings(),
),
)
await pipeline_input.validate()

View File

@@ -22,6 +22,14 @@ class WakeWordDetectionError(PipelineError):
"""Error in wake-word-detection portion of pipeline."""
class WakeWordDetectionAborted(WakeWordDetectionError):
"""Wake-word-detection was aborted."""
def __init__(self) -> None:
"""Set error message."""
super().__init__("wake_word_detection_aborted", "")
class WakeWordTimeoutError(WakeWordDetectionError):
"""Timeout when wake word was not detected."""

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/assist_pipeline",
"iot_class": "local_push",
"quality_scale": "internal",
"requirements": ["webrtcvad==2.0.10"]
"requirements": ["webrtc-noise-gain==1.2.3"]
}

View File

@@ -1,7 +1,9 @@
"""Classes for voice assistant pipelines."""
from __future__ import annotations
import array
import asyncio
from collections import deque
from collections.abc import AsyncGenerator, AsyncIterable, Callable, Iterable
from dataclasses import asdict, dataclass, field
from enum import StrEnum
@@ -10,10 +12,11 @@ from pathlib import Path
from queue import Queue
from threading import Thread
import time
from typing import Any, cast
from typing import Any, Final, cast
import wave
import voluptuous as vol
from webrtc_noise_gain import AudioProcessor
from homeassistant.components import (
conversation,
@@ -29,6 +32,7 @@ from homeassistant.components.tts.media_source import (
from homeassistant.core import Context, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.collection import (
CHANGE_UPDATED,
CollectionError,
ItemNotFound,
SerializedStorageCollection,
@@ -51,16 +55,17 @@ from .error import (
PipelineNotFound,
SpeechToTextError,
TextToSpeechError,
WakeWordDetectionAborted,
WakeWordDetectionError,
WakeWordTimeoutError,
)
from .ring_buffer import RingBuffer
from .vad import VoiceActivityTimeout, VoiceCommandSegmenter
from .vad import AudioBuffer, VoiceActivityTimeout, VoiceCommandSegmenter, chunk_samples
_LOGGER = logging.getLogger(__name__)
STORAGE_KEY = f"{DOMAIN}.pipelines"
STORAGE_VERSION = 1
STORAGE_VERSION_MINOR = 2
ENGINE_LANGUAGE_PAIRS = (
("stt_engine", "stt_language"),
@@ -86,12 +91,17 @@ PIPELINE_FIELDS = {
vol.Required("tts_engine"): vol.Any(str, None),
vol.Required("tts_language"): vol.Any(str, None),
vol.Required("tts_voice"): vol.Any(str, None),
vol.Required("wake_word_entity"): vol.Any(str, None),
vol.Required("wake_word_id"): vol.Any(str, None),
}
STORED_PIPELINE_RUNS = 10
SAVE_DELAY = 10
AUDIO_PROCESSOR_SAMPLES: Final = 160 # 10 ms @ 16 Khz
AUDIO_PROCESSOR_BYTES: Final = AUDIO_PROCESSOR_SAMPLES * 2 # 16-bit samples
async def _async_resolve_default_pipeline_settings(
hass: HomeAssistant,
@@ -111,6 +121,8 @@ async def _async_resolve_default_pipeline_settings(
tts_engine = None
tts_language = None
tts_voice = None
wake_word_entity = None
wake_word_id = None
# Find a matching language supported by the Home Assistant conversation agent
conversation_languages = language_util.matches(
@@ -188,6 +200,8 @@ async def _async_resolve_default_pipeline_settings(
"tts_engine": tts_engine_id,
"tts_language": tts_language,
"tts_voice": tts_voice,
"wake_word_entity": wake_word_entity,
"wake_word_id": wake_word_id,
}
@@ -295,9 +309,33 @@ class Pipeline:
tts_engine: str | None
tts_language: str | None
tts_voice: str | None
wake_word_entity: str | None
wake_word_id: str | None
id: str = field(default_factory=ulid_util.ulid)
@classmethod
def from_json(cls, data: dict[str, Any]) -> Pipeline:
"""Create an instance from a JSON serialization.
This function was added in HA Core 2023.10, previous versions will raise
if there are unexpected items in the serialized data.
"""
return cls(
conversation_engine=data["conversation_engine"],
conversation_language=data["conversation_language"],
id=data["id"],
language=data["language"],
name=data["name"],
stt_engine=data["stt_engine"],
stt_language=data["stt_language"],
tts_engine=data["tts_engine"],
tts_language=data["tts_language"],
tts_voice=data["tts_voice"],
wake_word_entity=data["wake_word_entity"],
wake_word_id=data["wake_word_id"],
)
def to_json(self) -> dict[str, Any]:
"""Return a JSON serializable representation for storage."""
return {
@@ -311,6 +349,8 @@ class Pipeline:
"tts_engine": self.tts_engine,
"tts_language": self.tts_language,
"tts_voice": self.tts_voice,
"wake_word_entity": self.wake_word_entity,
"wake_word_id": self.wake_word_id,
}
@@ -360,6 +400,60 @@ class WakeWordSettings:
"""Seconds of audio to buffer before detection and forward to STT."""
@dataclass(frozen=True)
class AudioSettings:
"""Settings for pipeline audio processing."""
noise_suppression_level: int = 0
"""Level of noise suppression (0 = disabled, 4 = max)"""
auto_gain_dbfs: int = 0
"""Amount of automatic gain in dbFS (0 = disabled, 31 = max)"""
volume_multiplier: float = 1.0
"""Multiplier used directly on PCM samples (1.0 = no change, 2.0 = twice as loud)"""
is_vad_enabled: bool = True
"""True if VAD is used to determine the end of the voice command."""
is_chunking_enabled: bool = True
"""True if audio is automatically split into 10 ms chunks (required for VAD, etc.)"""
def __post_init__(self) -> None:
"""Verify settings post-initialization."""
if (self.noise_suppression_level < 0) or (self.noise_suppression_level > 4):
raise ValueError("noise_suppression_level must be in [0, 4]")
if (self.auto_gain_dbfs < 0) or (self.auto_gain_dbfs > 31):
raise ValueError("auto_gain_dbfs must be in [0, 31]")
if self.needs_processor and (not self.is_chunking_enabled):
raise ValueError("Chunking must be enabled for audio processing")
@property
def needs_processor(self) -> bool:
"""True if an audio processor is needed."""
return (
self.is_vad_enabled
or (self.noise_suppression_level > 0)
or (self.auto_gain_dbfs > 0)
)
@dataclass(frozen=True, slots=True)
class ProcessedAudioChunk:
"""Processed audio chunk and metadata."""
audio: bytes
"""Raw PCM audio @ 16Khz with 16-bit mono samples"""
timestamp_ms: int
"""Timestamp relative to start of audio stream (milliseconds)"""
is_speech: bool | None
"""True if audio chunk likely contains speech, False if not, None if unknown"""
@dataclass
class PipelineRun:
"""Running context for a pipeline."""
@@ -375,13 +469,16 @@ class PipelineRun:
intent_agent: str | None = None
tts_audio_output: str | None = None
wake_word_settings: WakeWordSettings | None = None
audio_settings: AudioSettings = field(default_factory=AudioSettings)
id: str = field(default_factory=ulid_util.ulid)
stt_provider: stt.SpeechToTextEntity | stt.Provider = field(init=False)
tts_engine: str = field(init=False)
stt_provider: stt.SpeechToTextEntity | stt.Provider = field(init=False, repr=False)
tts_engine: str = field(init=False, repr=False)
tts_options: dict | None = field(init=False, default=None)
wake_word_engine: str = field(init=False)
wake_word_provider: wake_word.WakeWordDetectionEntity = field(init=False)
wake_word_entity_id: str = field(init=False, repr=False)
wake_word_entity: wake_word.WakeWordDetectionEntity = field(init=False, repr=False)
abort_wake_word_detection: bool = field(init=False, default=False)
debug_recording_thread: Thread | None = None
"""Thread that records audio to debug_recording_dir"""
@@ -389,6 +486,12 @@ class PipelineRun:
debug_recording_queue: Queue[str | bytes | None] | None = None
"""Queue to communicate with debug recording thread"""
audio_processor: AudioProcessor | None = None
"""VAD/noise suppression/auto gain"""
audio_processor_buffer: AudioBuffer = field(init=False, repr=False)
"""Buffer used when splitting audio into chunks for audio processing"""
def __post_init__(self) -> None:
"""Set language for pipeline."""
self.language = self.pipeline.language or self.hass.config.language
@@ -400,21 +503,30 @@ class PipelineRun:
raise InvalidPipelineStagesError(self.start_stage, self.end_stage)
pipeline_data: PipelineData = self.hass.data[DOMAIN]
if self.pipeline.id not in pipeline_data.pipeline_runs:
pipeline_data.pipeline_runs[self.pipeline.id] = LimitedSizeDict(
if self.pipeline.id not in pipeline_data.pipeline_debug:
pipeline_data.pipeline_debug[self.pipeline.id] = LimitedSizeDict(
size_limit=STORED_PIPELINE_RUNS
)
pipeline_data.pipeline_runs[self.pipeline.id][self.id] = PipelineRunDebug()
pipeline_data.pipeline_debug[self.pipeline.id][self.id] = PipelineRunDebug()
pipeline_data.pipeline_runs.add_run(self)
# Initialize with audio settings
self.audio_processor_buffer = AudioBuffer(AUDIO_PROCESSOR_BYTES)
if self.audio_settings.needs_processor:
self.audio_processor = AudioProcessor(
self.audio_settings.auto_gain_dbfs,
self.audio_settings.noise_suppression_level,
)
@callback
def process_event(self, event: PipelineEvent) -> None:
"""Log an event and call listener."""
self.event_callback(event)
pipeline_data: PipelineData = self.hass.data[DOMAIN]
if self.id not in pipeline_data.pipeline_runs[self.pipeline.id]:
if self.id not in pipeline_data.pipeline_debug[self.pipeline.id]:
# This run has been evicted from the logged pipeline runs already
return
pipeline_data.pipeline_runs[self.pipeline.id][self.id].events.append(event)
pipeline_data.pipeline_debug[self.pipeline.id][self.id].events.append(event)
def start(self, device_id: str | None) -> None:
"""Emit run start event."""
@@ -441,31 +553,36 @@ class PipelineRun:
)
)
pipeline_data: PipelineData = self.hass.data[DOMAIN]
pipeline_data.pipeline_runs.remove_run(self)
async def prepare_wake_word_detection(self) -> None:
"""Prepare wake-word-detection."""
engine = wake_word.async_default_engine(self.hass)
if engine is None:
entity_id = self.pipeline.wake_word_entity or wake_word.async_default_entity(
self.hass
)
if entity_id is None:
raise WakeWordDetectionError(
code="wake-engine-missing",
message="No wake word engine",
)
wake_word_provider = wake_word.async_get_wake_word_detection_entity(
self.hass, engine
wake_word_entity = wake_word.async_get_wake_word_detection_entity(
self.hass, entity_id
)
if wake_word_provider is None:
if wake_word_entity is None:
raise WakeWordDetectionError(
code="wake-provider-missing",
message=f"No wake-word-detection provider for: {engine}",
message=f"No wake-word-detection provider for: {entity_id}",
)
self.wake_word_engine = engine
self.wake_word_provider = wake_word_provider
self.wake_word_entity_id = entity_id
self.wake_word_entity = wake_word_entity
async def wake_word_detection(
self,
stream: AsyncIterable[bytes],
audio_chunks_for_stt: list[bytes],
stream: AsyncIterable[ProcessedAudioChunk],
audio_chunks_for_stt: list[ProcessedAudioChunk],
) -> wake_word.DetectionResult | None:
"""Run wake-word-detection portion of pipeline. Returns detection result."""
metadata_dict = asdict(
@@ -486,14 +603,14 @@ class PipelineRun:
PipelineEvent(
PipelineEventType.WAKE_WORD_START,
{
"engine": self.wake_word_engine,
"entity_id": self.wake_word_entity_id,
"metadata": metadata_dict,
},
)
)
if self.debug_recording_queue is not None:
self.debug_recording_queue.put_nowait(f"00_wake-{self.wake_word_engine}")
self.debug_recording_queue.put_nowait(f"00_wake-{self.wake_word_entity_id}")
wake_word_settings = self.wake_word_settings or WakeWordSettings()
@@ -506,27 +623,31 @@ class PipelineRun:
# Audio chunk buffer. This audio will be forwarded to speech-to-text
# after wake-word-detection.
num_audio_bytes_to_buffer = int(
wake_word_settings.audio_seconds_to_buffer * 16000 * 2 # 16-bit @ 16Khz
num_audio_chunks_to_buffer = int(
(wake_word_settings.audio_seconds_to_buffer * 16000)
/ AUDIO_PROCESSOR_SAMPLES
)
stt_audio_buffer: RingBuffer | None = None
if num_audio_bytes_to_buffer > 0:
stt_audio_buffer = RingBuffer(num_audio_bytes_to_buffer)
stt_audio_buffer: deque[ProcessedAudioChunk] | None = None
if num_audio_chunks_to_buffer > 0:
stt_audio_buffer = deque(maxlen=num_audio_chunks_to_buffer)
try:
# Detect wake word(s)
result = await self.wake_word_provider.async_process_audio_stream(
result = await self.wake_word_entity.async_process_audio_stream(
self._wake_word_audio_stream(
audio_stream=stream,
stt_audio_buffer=stt_audio_buffer,
wake_word_vad=wake_word_vad,
)
),
self.pipeline.wake_word_id,
)
if stt_audio_buffer is not None:
# All audio kept from right before the wake word was detected as
# a single chunk.
audio_chunks_for_stt.append(stt_audio_buffer.getvalue())
audio_chunks_for_stt.extend(stt_audio_buffer)
except WakeWordDetectionAborted:
raise
except WakeWordTimeoutError:
_LOGGER.debug("Timeout during wake word detection")
raise
@@ -550,7 +671,11 @@ class PipelineRun:
# speech-to-text so the user does not have to pause before
# speaking the voice command.
for chunk_ts in result.queued_audio:
audio_chunks_for_stt.append(chunk_ts[0])
audio_chunks_for_stt.append(
ProcessedAudioChunk(
audio=chunk_ts[0], timestamp_ms=chunk_ts[1], is_speech=False
)
)
wake_word_output = asdict(result)
@@ -568,8 +693,8 @@ class PipelineRun:
async def _wake_word_audio_stream(
self,
audio_stream: AsyncIterable[bytes],
stt_audio_buffer: RingBuffer | None,
audio_stream: AsyncIterable[ProcessedAudioChunk],
stt_audio_buffer: deque[ProcessedAudioChunk] | None,
wake_word_vad: VoiceActivityTimeout | None,
sample_rate: int = 16000,
sample_width: int = 2,
@@ -579,25 +704,27 @@ class PipelineRun:
Adds audio to a ring buffer that will be forwarded to speech-to-text after
detection. Times out if VAD detects enough silence.
"""
ms_per_sample = sample_rate // 1000
timestamp_ms = 0
chunk_seconds = AUDIO_PROCESSOR_SAMPLES / sample_rate
async for chunk in audio_stream:
if self.debug_recording_queue is not None:
self.debug_recording_queue.put_nowait(chunk)
if self.abort_wake_word_detection:
raise WakeWordDetectionAborted
yield chunk, timestamp_ms
timestamp_ms += (len(chunk) // sample_width) // ms_per_sample
if self.debug_recording_queue is not None:
self.debug_recording_queue.put_nowait(chunk.audio)
yield chunk.audio, chunk.timestamp_ms
# Wake-word-detection occurs *after* the wake word was actually
# spoken. Keeping audio right before detection allows the voice
# command to be spoken immediately after the wake word.
if stt_audio_buffer is not None:
stt_audio_buffer.put(chunk)
stt_audio_buffer.append(chunk)
if (wake_word_vad is not None) and (not wake_word_vad.process(chunk)):
raise WakeWordTimeoutError(
code="wake-word-timeout", message="Wake word was not detected"
)
if wake_word_vad is not None:
if not wake_word_vad.process(chunk_seconds, chunk.is_speech):
raise WakeWordTimeoutError(
code="wake-word-timeout", message="Wake word was not detected"
)
async def prepare_speech_to_text(self, metadata: stt.SpeechMetadata) -> None:
"""Prepare speech-to-text."""
@@ -630,7 +757,7 @@ class PipelineRun:
async def speech_to_text(
self,
metadata: stt.SpeechMetadata,
stream: AsyncIterable[bytes],
stream: AsyncIterable[ProcessedAudioChunk],
) -> str:
"""Run speech-to-text portion of pipeline. Returns the spoken text."""
if isinstance(self.stt_provider, stt.Provider):
@@ -654,11 +781,13 @@ class PipelineRun:
try:
# Transcribe audio stream
stt_vad: VoiceCommandSegmenter | None = None
if self.audio_settings.is_vad_enabled:
stt_vad = VoiceCommandSegmenter()
result = await self.stt_provider.async_process_audio_stream(
metadata,
self._speech_to_text_stream(
audio_stream=stream, stt_vad=VoiceCommandSegmenter()
),
self._speech_to_text_stream(audio_stream=stream, stt_vad=stt_vad),
)
except Exception as src_error:
_LOGGER.exception("Unexpected error during speech-to-text")
@@ -695,26 +824,25 @@ class PipelineRun:
async def _speech_to_text_stream(
self,
audio_stream: AsyncIterable[bytes],
audio_stream: AsyncIterable[ProcessedAudioChunk],
stt_vad: VoiceCommandSegmenter | None,
sample_rate: int = 16000,
sample_width: int = 2,
) -> AsyncGenerator[bytes, None]:
"""Yield audio chunks until VAD detects silence or speech-to-text completes."""
ms_per_sample = sample_rate // 1000
chunk_seconds = AUDIO_PROCESSOR_SAMPLES / sample_rate
sent_vad_start = False
timestamp_ms = 0
async for chunk in audio_stream:
if self.debug_recording_queue is not None:
self.debug_recording_queue.put_nowait(chunk)
self.debug_recording_queue.put_nowait(chunk.audio)
if stt_vad is not None:
if not stt_vad.process(chunk):
if not stt_vad.process(chunk_seconds, chunk.is_speech):
# Silence detected at the end of voice command
self.process_event(
PipelineEvent(
PipelineEventType.STT_VAD_END,
{"timestamp": timestamp_ms},
{"timestamp": chunk.timestamp_ms},
)
)
break
@@ -724,13 +852,12 @@ class PipelineRun:
self.process_event(
PipelineEvent(
PipelineEventType.STT_VAD_START,
{"timestamp": timestamp_ms},
{"timestamp": chunk.timestamp_ms},
)
)
sent_vad_start = True
yield chunk
timestamp_ms += (len(chunk) // sample_width) // ms_per_sample
yield chunk.audio
async def prepare_recognize_intent(self) -> None:
"""Prepare recognizing an intent."""
@@ -941,6 +1068,87 @@ class PipelineRun:
self.debug_recording_queue = None
self.debug_recording_thread = None
async def process_volume_only(
self,
audio_stream: AsyncIterable[bytes],
sample_rate: int = 16000,
sample_width: int = 2,
) -> AsyncGenerator[ProcessedAudioChunk, None]:
"""Apply volume transformation only (no VAD/audio enhancements) with optional chunking."""
ms_per_sample = sample_rate // 1000
ms_per_chunk = (AUDIO_PROCESSOR_SAMPLES // sample_width) // ms_per_sample
timestamp_ms = 0
async for chunk in audio_stream:
if self.audio_settings.volume_multiplier != 1.0:
chunk = _multiply_volume(chunk, self.audio_settings.volume_multiplier)
if self.audio_settings.is_chunking_enabled:
# 10 ms chunking
for chunk_10ms in chunk_samples(
chunk, AUDIO_PROCESSOR_BYTES, self.audio_processor_buffer
):
yield ProcessedAudioChunk(
audio=chunk_10ms,
timestamp_ms=timestamp_ms,
is_speech=None, # no VAD
)
timestamp_ms += ms_per_chunk
else:
# No chunking
yield ProcessedAudioChunk(
audio=chunk,
timestamp_ms=timestamp_ms,
is_speech=None, # no VAD
)
timestamp_ms += (len(chunk) // sample_width) // ms_per_sample
async def process_enhance_audio(
self,
audio_stream: AsyncIterable[bytes],
sample_rate: int = 16000,
sample_width: int = 2,
) -> AsyncGenerator[ProcessedAudioChunk, None]:
"""Split audio into 10 ms chunks and apply VAD/noise suppression/auto gain/volume transformation."""
assert self.audio_processor is not None
ms_per_sample = sample_rate // 1000
ms_per_chunk = (AUDIO_PROCESSOR_SAMPLES // sample_width) // ms_per_sample
timestamp_ms = 0
async for dirty_samples in audio_stream:
if self.audio_settings.volume_multiplier != 1.0:
# Static gain
dirty_samples = _multiply_volume(
dirty_samples, self.audio_settings.volume_multiplier
)
# Split into 10ms chunks for audio enhancements/VAD
for dirty_10ms_chunk in chunk_samples(
dirty_samples, AUDIO_PROCESSOR_BYTES, self.audio_processor_buffer
):
ap_result = self.audio_processor.Process10ms(dirty_10ms_chunk)
yield ProcessedAudioChunk(
audio=ap_result.audio,
timestamp_ms=timestamp_ms,
is_speech=ap_result.is_speech,
)
timestamp_ms += ms_per_chunk
def _multiply_volume(chunk: bytes, volume_multiplier: float) -> bytes:
"""Multiplies 16-bit PCM samples by a constant."""
def _clamp(val: float) -> float:
"""Clamp to signed 16-bit."""
return max(-32768, min(32767, val))
return array.array(
"h",
(int(_clamp(value * volume_multiplier)) for value in array.array("h", chunk)),
).tobytes()
def _pipeline_debug_recording_thread_proc(
run_recording_dir: Path,
@@ -1006,18 +1214,26 @@ class PipelineInput:
"""Run pipeline."""
self.run.start(device_id=self.device_id)
current_stage: PipelineStage | None = self.run.start_stage
stt_audio_buffer: list[bytes] = []
stt_audio_buffer: list[ProcessedAudioChunk] = []
stt_processed_stream: AsyncIterable[ProcessedAudioChunk] | None = None
if self.stt_stream is not None:
if self.run.audio_settings.needs_processor:
# VAD/noise suppression/auto gain/volume
stt_processed_stream = self.run.process_enhance_audio(self.stt_stream)
else:
# Volume multiplier only
stt_processed_stream = self.run.process_volume_only(self.stt_stream)
try:
if current_stage == PipelineStage.WAKE_WORD:
# wake-word-detection
assert self.stt_stream is not None
assert stt_processed_stream is not None
detect_result = await self.run.wake_word_detection(
self.stt_stream, stt_audio_buffer
stt_processed_stream, stt_audio_buffer
)
if detect_result is None:
# No wake word. Abort the rest of the pipeline.
await self.run.end()
return
current_stage = PipelineStage.STT
@@ -1026,28 +1242,30 @@ class PipelineInput:
intent_input = self.intent_input
if current_stage == PipelineStage.STT:
assert self.stt_metadata is not None
assert self.stt_stream is not None
assert stt_processed_stream is not None
stt_stream = self.stt_stream
stt_input_stream = stt_processed_stream
if stt_audio_buffer:
# Send audio in the buffer first to speech-to-text, then move on to stt_stream.
# This is basically an async itertools.chain.
async def buffer_then_audio_stream() -> AsyncGenerator[bytes, None]:
async def buffer_then_audio_stream() -> AsyncGenerator[
ProcessedAudioChunk, None
]:
# Buffered audio
for chunk in stt_audio_buffer:
yield chunk
# Streamed audio
assert self.stt_stream is not None
async for chunk in self.stt_stream:
assert stt_processed_stream is not None
async for chunk in stt_processed_stream:
yield chunk
stt_stream = buffer_then_audio_stream()
stt_input_stream = buffer_then_audio_stream()
intent_input = await self.run.speech_to_text(
self.stt_metadata,
stt_stream,
stt_input_stream,
)
current_stage = PipelineStage.INTENT
@@ -1205,7 +1423,7 @@ class PipelineStorageCollection(
def _deserialize_item(self, data: dict) -> Pipeline:
"""Create an item from its serialized representation."""
return Pipeline(**data)
return Pipeline.from_json(data)
def _serialize_item(self, item_id: str, item: Pipeline) -> dict:
"""Return the serialized representation of an item for storing."""
@@ -1342,13 +1560,48 @@ class PipelineStorageCollectionWebsocket(
connection.send_result(msg["id"])
@dataclass
class PipelineRuns:
"""Class managing pipelineruns."""
def __init__(self, pipeline_store: PipelineStorageCollection) -> None:
"""Initialize."""
self._pipeline_runs: dict[str, list[PipelineRun]] = {}
self._pipeline_store = pipeline_store
pipeline_store.async_add_listener(self._change_listener)
def add_run(self, pipeline_run: PipelineRun) -> None:
"""Add pipeline run."""
pipeline_id = pipeline_run.pipeline.id
if pipeline_id not in self._pipeline_runs:
self._pipeline_runs[pipeline_id] = []
self._pipeline_runs[pipeline_id].append(pipeline_run)
def remove_run(self, pipeline_run: PipelineRun) -> None:
"""Remove pipeline run."""
pipeline_id = pipeline_run.pipeline.id
self._pipeline_runs[pipeline_id].remove(pipeline_run)
async def _change_listener(
self, change_type: str, item_id: str, change: dict
) -> None:
"""Handle pipeline store changes."""
if change_type != CHANGE_UPDATED:
return
if pipeline_runs := self._pipeline_runs.get(item_id):
# Create a temporary list in case the list is modified while we iterate
for pipeline_run in list(pipeline_runs):
pipeline_run.abort_wake_word_detection = True
class PipelineData:
"""Store and debug data stored in hass.data."""
pipeline_runs: dict[str, LimitedSizeDict[str, PipelineRunDebug]]
pipeline_store: PipelineStorageCollection
pipeline_devices: set[str] = field(default_factory=set, init=False)
def __init__(self, pipeline_store: PipelineStorageCollection) -> None:
"""Initialize."""
self.pipeline_store = pipeline_store
self.pipeline_debug: dict[str, LimitedSizeDict[str, PipelineRunDebug]] = {}
self.pipeline_devices: set[str] = set()
self.pipeline_runs = PipelineRuns(pipeline_store)
@dataclass
@@ -1362,11 +1615,35 @@ class PipelineRunDebug:
)
class PipelineStore(Store[SerializedPipelineStorageCollection]):
"""Store entity registry data."""
async def _async_migrate_func(
self,
old_major_version: int,
old_minor_version: int,
old_data: SerializedPipelineStorageCollection,
) -> SerializedPipelineStorageCollection:
"""Migrate to the new version."""
if old_major_version == 1 and old_minor_version < 2:
# Version 1.2 adds wake word configuration
for pipeline in old_data["items"]:
# Populate keys which were introduced before version 1.2
pipeline.setdefault("wake_word_entity", None)
pipeline.setdefault("wake_word_id", None)
if old_major_version > 1:
raise NotImplementedError
return old_data
@singleton(DOMAIN)
async def async_setup_pipeline_store(hass: HomeAssistant) -> PipelineData:
"""Set up the pipeline storage collection."""
pipeline_store = PipelineStorageCollection(
Store(hass, STORAGE_VERSION, STORAGE_KEY)
PipelineStore(
hass, STORAGE_VERSION, STORAGE_KEY, minor_version=STORAGE_VERSION_MINOR
)
)
await pipeline_store.async_load()
PipelineStorageCollectionWebsocket(
@@ -1376,4 +1653,4 @@ async def async_setup_pipeline_store(hass: HomeAssistant) -> PipelineData:
PIPELINE_FIELDS,
PIPELINE_FIELDS,
).async_setup(hass)
return PipelineData({}, pipeline_store)
return PipelineData(pipeline_store)

View File

@@ -1,12 +1,13 @@
"""Voice activity detection."""
from __future__ import annotations
from abc import ABC, abstractmethod
from collections.abc import Iterable
from dataclasses import dataclass, field
from dataclasses import dataclass
from enum import StrEnum
from typing import Final
from typing import Final, cast
import webrtcvad
from webrtc_noise_gain import AudioProcessor
_SAMPLE_RATE: Final = 16000 # Hz
_SAMPLE_WIDTH: Final = 2 # bytes
@@ -32,6 +33,38 @@ class VadSensitivity(StrEnum):
return 1.0
class VoiceActivityDetector(ABC):
"""Base class for voice activity detectors (VAD)."""
@abstractmethod
def is_speech(self, chunk: bytes) -> bool:
"""Return True if audio chunk contains speech."""
@property
@abstractmethod
def samples_per_chunk(self) -> int | None:
"""Return number of samples per chunk or None if chunking is not required."""
class WebRtcVad(VoiceActivityDetector):
"""Voice activity detector based on webrtc."""
def __init__(self) -> None:
"""Initialize webrtcvad."""
# Just VAD: no noise suppression or auto gain
self._audio_processor = AudioProcessor(0, 0)
def is_speech(self, chunk: bytes) -> bool:
"""Return True if audio chunk contains speech."""
result = self._audio_processor.Process10ms(chunk)
return cast(bool, result.is_speech)
@property
def samples_per_chunk(self) -> int | None:
"""Return 10 ms."""
return int(0.01 * _SAMPLE_RATE) # 10 ms
class AudioBuffer:
"""Fixed-sized audio buffer with variable internal length."""
@@ -73,13 +106,7 @@ class AudioBuffer:
@dataclass
class VoiceCommandSegmenter:
"""Segments an audio stream into voice commands using webrtcvad."""
vad_mode: int = 3
"""Aggressiveness in filtering out non-speech. 3 is the most aggressive."""
vad_samples_per_chunk: int = 480 # 30 ms
"""Must be 10, 20, or 30 ms at 16Khz."""
"""Segments an audio stream into voice commands."""
speech_seconds: float = 0.3
"""Seconds of speech before voice command has started."""
@@ -108,85 +135,85 @@ class VoiceCommandSegmenter:
_reset_seconds_left: float = 0.0
"""Seconds left before resetting start/stop time counters."""
_vad: webrtcvad.Vad = None
_leftover_chunk_buffer: AudioBuffer = field(init=False)
_bytes_per_chunk: int = field(init=False)
_seconds_per_chunk: float = field(init=False)
def __post_init__(self) -> None:
"""Initialize VAD."""
self._vad = webrtcvad.Vad(self.vad_mode)
self._bytes_per_chunk = self.vad_samples_per_chunk * _SAMPLE_WIDTH
self._seconds_per_chunk = self.vad_samples_per_chunk / _SAMPLE_RATE
self._leftover_chunk_buffer = AudioBuffer(
self.vad_samples_per_chunk * _SAMPLE_WIDTH
)
"""Reset after initialization."""
self.reset()
def reset(self) -> None:
"""Reset all counters and state."""
self._leftover_chunk_buffer.clear()
self._speech_seconds_left = self.speech_seconds
self._silence_seconds_left = self.silence_seconds
self._timeout_seconds_left = self.timeout_seconds
self._reset_seconds_left = self.reset_seconds
self.in_command = False
def process(self, samples: bytes) -> bool:
"""Process 16-bit 16Khz mono audio samples.
def process(self, chunk_seconds: float, is_speech: bool | None) -> bool:
"""Process samples using external VAD.
Returns False when command is done.
"""
for chunk in chunk_samples(
samples, self._bytes_per_chunk, self._leftover_chunk_buffer
):
if not self._process_chunk(chunk):
self.reset()
return False
return True
@property
def audio_buffer(self) -> bytes:
"""Get partial chunk in the audio buffer."""
return self._leftover_chunk_buffer.bytes()
def _process_chunk(self, chunk: bytes) -> bool:
"""Process a single chunk of 16-bit 16Khz mono audio.
Returns False when command is done.
"""
is_speech = self._vad.is_speech(chunk, _SAMPLE_RATE)
self._timeout_seconds_left -= self._seconds_per_chunk
self._timeout_seconds_left -= chunk_seconds
if self._timeout_seconds_left <= 0:
self.reset()
return False
if not self.in_command:
if is_speech:
self._reset_seconds_left = self.reset_seconds
self._speech_seconds_left -= self._seconds_per_chunk
self._speech_seconds_left -= chunk_seconds
if self._speech_seconds_left <= 0:
# Inside voice command
self.in_command = True
else:
# Reset if enough silence
self._reset_seconds_left -= self._seconds_per_chunk
self._reset_seconds_left -= chunk_seconds
if self._reset_seconds_left <= 0:
self._speech_seconds_left = self.speech_seconds
elif not is_speech:
self._reset_seconds_left = self.reset_seconds
self._silence_seconds_left -= self._seconds_per_chunk
self._silence_seconds_left -= chunk_seconds
if self._silence_seconds_left <= 0:
self.reset()
return False
else:
# Reset if enough speech
self._reset_seconds_left -= self._seconds_per_chunk
self._reset_seconds_left -= chunk_seconds
if self._reset_seconds_left <= 0:
self._silence_seconds_left = self.silence_seconds
return True
def process_with_vad(
self,
chunk: bytes,
vad: VoiceActivityDetector,
leftover_chunk_buffer: AudioBuffer | None,
) -> bool:
"""Process an audio chunk using an external VAD.
A buffer is required if the VAD requires fixed-sized audio chunks (usually the case).
Returns False when voice command is finished.
"""
if vad.samples_per_chunk is None:
# No chunking
chunk_seconds = (len(chunk) // _SAMPLE_WIDTH) / _SAMPLE_RATE
is_speech = vad.is_speech(chunk)
return self.process(chunk_seconds, is_speech)
if leftover_chunk_buffer is None:
raise ValueError("leftover_chunk_buffer is required when vad uses chunking")
# With chunking
seconds_per_chunk = vad.samples_per_chunk / _SAMPLE_RATE
bytes_per_chunk = vad.samples_per_chunk * _SAMPLE_WIDTH
for vad_chunk in chunk_samples(chunk, bytes_per_chunk, leftover_chunk_buffer):
is_speech = vad.is_speech(vad_chunk)
if not self.process(seconds_per_chunk, is_speech):
return False
return True
@dataclass
class VoiceActivityTimeout:
@@ -198,73 +225,43 @@ class VoiceActivityTimeout:
reset_seconds: float = 0.5
"""Seconds of speech before resetting timeout."""
vad_mode: int = 3
"""Aggressiveness in filtering out non-speech. 3 is the most aggressive."""
vad_samples_per_chunk: int = 480 # 30 ms
"""Must be 10, 20, or 30 ms at 16Khz."""
_silence_seconds_left: float = 0.0
"""Seconds left before considering voice command as stopped."""
_reset_seconds_left: float = 0.0
"""Seconds left before resetting start/stop time counters."""
_vad: webrtcvad.Vad = None
_leftover_chunk_buffer: AudioBuffer = field(init=False)
_bytes_per_chunk: int = field(init=False)
_seconds_per_chunk: float = field(init=False)
def __post_init__(self) -> None:
"""Initialize VAD."""
self._vad = webrtcvad.Vad(self.vad_mode)
self._bytes_per_chunk = self.vad_samples_per_chunk * _SAMPLE_WIDTH
self._seconds_per_chunk = self.vad_samples_per_chunk / _SAMPLE_RATE
self._leftover_chunk_buffer = AudioBuffer(
self.vad_samples_per_chunk * _SAMPLE_WIDTH
)
"""Reset after initialization."""
self.reset()
def reset(self) -> None:
"""Reset all counters and state."""
self._leftover_chunk_buffer.clear()
self._silence_seconds_left = self.silence_seconds
self._reset_seconds_left = self.reset_seconds
def process(self, samples: bytes) -> bool:
"""Process 16-bit 16Khz mono audio samples.
def process(self, chunk_seconds: float, is_speech: bool | None) -> bool:
"""Process samples using external VAD.
Returns False when timeout is reached.
"""
for chunk in chunk_samples(
samples, self._bytes_per_chunk, self._leftover_chunk_buffer
):
if not self._process_chunk(chunk):
return False
return True
def _process_chunk(self, chunk: bytes) -> bool:
"""Process a single chunk of 16-bit 16Khz mono audio.
Returns False when timeout is reached.
"""
if self._vad.is_speech(chunk, _SAMPLE_RATE):
if is_speech:
# Speech
self._reset_seconds_left -= self._seconds_per_chunk
self._reset_seconds_left -= chunk_seconds
if self._reset_seconds_left <= 0:
# Reset timeout
self._silence_seconds_left = self.silence_seconds
else:
# Silence
self._silence_seconds_left -= self._seconds_per_chunk
self._silence_seconds_left -= chunk_seconds
if self._silence_seconds_left <= 0:
# Timeout reached
self.reset()
return False
# Slowly build reset counter back up
self._reset_seconds_left = min(
self.reset_seconds, self._reset_seconds_left + self._seconds_per_chunk
self.reset_seconds, self._reset_seconds_left + chunk_seconds
)
return True

View File

@@ -18,6 +18,7 @@ from homeassistant.util import language as language_util
from .const import DOMAIN
from .error import PipelineNotFound
from .pipeline import (
AudioSettings,
PipelineData,
PipelineError,
PipelineEvent,
@@ -71,6 +72,13 @@ def async_register_websocket_api(hass: HomeAssistant) -> None:
vol.Optional("audio_seconds_to_buffer"): vol.Any(
float, int
),
# Audio enhancement
vol.Optional("noise_suppression_level"): int,
vol.Optional("auto_gain_dbfs"): int,
vol.Optional("volume_multiplier"): float,
# Advanced use cases/testing
vol.Optional("no_vad"): bool,
vol.Optional("no_chunking"): bool,
}
},
extra=vol.ALLOW_EXTRA,
@@ -115,6 +123,7 @@ async def websocket_run(
handler_id: int | None = None
unregister_handler: Callable[[], None] | None = None
wake_word_settings: WakeWordSettings | None = None
audio_settings: AudioSettings | None = None
# Arguments to PipelineInput
input_args: dict[str, Any] = {
@@ -124,13 +133,14 @@ async def websocket_run(
if start_stage in (PipelineStage.WAKE_WORD, PipelineStage.STT):
# Audio pipeline that will receive audio as binary websocket messages
msg_input = msg["input"]
audio_queue: asyncio.Queue[bytes] = asyncio.Queue()
incoming_sample_rate = msg["input"]["sample_rate"]
incoming_sample_rate = msg_input["sample_rate"]
if start_stage == PipelineStage.WAKE_WORD:
wake_word_settings = WakeWordSettings(
timeout=msg["input"].get("timeout", DEFAULT_WAKE_WORD_TIMEOUT),
audio_seconds_to_buffer=msg["input"].get("audio_seconds_to_buffer", 0),
audio_seconds_to_buffer=msg_input.get("audio_seconds_to_buffer", 0),
)
async def stt_stream() -> AsyncGenerator[bytes, None]:
@@ -166,6 +176,15 @@ async def websocket_run(
channel=stt.AudioChannels.CHANNEL_MONO,
)
input_args["stt_stream"] = stt_stream()
# Audio settings
audio_settings = AudioSettings(
noise_suppression_level=msg_input.get("noise_suppression_level", 0),
auto_gain_dbfs=msg_input.get("auto_gain_dbfs", 0),
volume_multiplier=msg_input.get("volume_multiplier", 1.0),
is_vad_enabled=not msg_input.get("no_vad", False),
is_chunking_enabled=not msg_input.get("no_chunking", False),
)
elif start_stage == PipelineStage.INTENT:
# Input to conversation agent
input_args["intent_input"] = msg["input"]["text"]
@@ -185,6 +204,7 @@ async def websocket_run(
"timeout": timeout,
},
wake_word_settings=wake_word_settings,
audio_settings=audio_settings or AudioSettings(),
)
pipeline_input = PipelineInput(**input_args)
@@ -238,18 +258,18 @@ def websocket_list_runs(
pipeline_data: PipelineData = hass.data[DOMAIN]
pipeline_id = msg["pipeline_id"]
if pipeline_id not in pipeline_data.pipeline_runs:
if pipeline_id not in pipeline_data.pipeline_debug:
connection.send_result(msg["id"], {"pipeline_runs": []})
return
pipeline_runs = pipeline_data.pipeline_runs[pipeline_id]
pipeline_debug = pipeline_data.pipeline_debug[pipeline_id]
connection.send_result(
msg["id"],
{
"pipeline_runs": [
{"pipeline_run_id": id, "timestamp": pipeline_run.timestamp}
for id, pipeline_run in pipeline_runs.items()
for id, pipeline_run in pipeline_debug.items()
]
},
)
@@ -274,7 +294,7 @@ def websocket_get_run(
pipeline_id = msg["pipeline_id"]
pipeline_run_id = msg["pipeline_run_id"]
if pipeline_id not in pipeline_data.pipeline_runs:
if pipeline_id not in pipeline_data.pipeline_debug:
connection.send_error(
msg["id"],
websocket_api.const.ERR_NOT_FOUND,
@@ -282,9 +302,9 @@ def websocket_get_run(
)
return
pipeline_runs = pipeline_data.pipeline_runs[pipeline_id]
pipeline_debug = pipeline_data.pipeline_debug[pipeline_id]
if pipeline_run_id not in pipeline_runs:
if pipeline_run_id not in pipeline_debug:
connection.send_error(
msg["id"],
websocket_api.const.ERR_NOT_FOUND,
@@ -294,7 +314,7 @@ def websocket_get_run(
connection.send_result(
msg["id"],
{"events": pipeline_runs[pipeline_run_id].events},
{"events": pipeline_debug[pipeline_run_id].events},
)
@@ -332,7 +352,7 @@ async def websocket_list_languages(
dialect = language_util.Dialect.parse(language_tag)
languages.add(dialect.language)
if pipeline_languages is not None:
pipeline_languages &= languages
pipeline_languages = language_util.intersect(pipeline_languages, languages)
else:
pipeline_languages = languages
@@ -342,11 +362,15 @@ async def websocket_list_languages(
dialect = language_util.Dialect.parse(language_tag)
languages.add(dialect.language)
if pipeline_languages is not None:
pipeline_languages &= languages
pipeline_languages = language_util.intersect(pipeline_languages, languages)
else:
pipeline_languages = languages
connection.send_result(
msg["id"],
{"languages": pipeline_languages},
{
"languages": sorted(pipeline_languages)
if pipeline_languages
else pipeline_languages
},
)

View File

@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/asterisk_mbox",
"iot_class": "local_push",
"loggers": ["asterisk_mbox"],
"requirements": ["asterisk-mbox==0.5.0"]
"requirements": ["asterisk_mbox==0.5.0"]
}

View File

@@ -26,12 +26,16 @@ DOMAIN = "august"
OPERATION_METHOD_AUTORELOCK = "autorelock"
OPERATION_METHOD_REMOTE = "remote"
OPERATION_METHOD_KEYPAD = "keypad"
OPERATION_METHOD_MANUAL = "manual"
OPERATION_METHOD_TAG = "tag"
OPERATION_METHOD_MOBILE_DEVICE = "mobile"
ATTR_OPERATION_AUTORELOCK = "autorelock"
ATTR_OPERATION_METHOD = "method"
ATTR_OPERATION_REMOTE = "remote"
ATTR_OPERATION_KEYPAD = "keypad"
ATTR_OPERATION_MANUAL = "manual"
ATTR_OPERATION_TAG = "tag"
# Limit battery, online, and hardware updates to hourly
# in order to reduce the number of api requests and

View File

@@ -28,5 +28,5 @@
"documentation": "https://www.home-assistant.io/integrations/august",
"iot_class": "cloud_push",
"loggers": ["pubnub", "yalexs"],
"requirements": ["yalexs==1.8.0", "yalexs-ble==2.2.3"]
"requirements": ["yalexs==1.10.0", "yalexs-ble==2.3.0"]
}

View File

@@ -33,13 +33,17 @@ from . import AugustData
from .const import (
ATTR_OPERATION_AUTORELOCK,
ATTR_OPERATION_KEYPAD,
ATTR_OPERATION_MANUAL,
ATTR_OPERATION_METHOD,
ATTR_OPERATION_REMOTE,
ATTR_OPERATION_TAG,
DOMAIN,
OPERATION_METHOD_AUTORELOCK,
OPERATION_METHOD_KEYPAD,
OPERATION_METHOD_MANUAL,
OPERATION_METHOD_MOBILE_DEVICE,
OPERATION_METHOD_REMOTE,
OPERATION_METHOD_TAG,
)
from .entity import AugustEntityMixin
@@ -183,6 +187,8 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
self._device = device
self._operated_remote = None
self._operated_keypad = None
self._operated_manual = None
self._operated_tag = None
self._operated_autorelock = None
self._operated_time = None
self._attr_unique_id = f"{self._device_id}_lock_operator"
@@ -200,6 +206,8 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
self._attr_native_value = lock_activity.operated_by
self._operated_remote = lock_activity.operated_remote
self._operated_keypad = lock_activity.operated_keypad
self._operated_manual = lock_activity.operated_manual
self._operated_tag = lock_activity.operated_tag
self._operated_autorelock = lock_activity.operated_autorelock
self._attr_entity_picture = lock_activity.operator_thumbnail_url
@@ -212,6 +220,10 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
attributes[ATTR_OPERATION_REMOTE] = self._operated_remote
if self._operated_keypad is not None:
attributes[ATTR_OPERATION_KEYPAD] = self._operated_keypad
if self._operated_manual is not None:
attributes[ATTR_OPERATION_MANUAL] = self._operated_manual
if self._operated_tag is not None:
attributes[ATTR_OPERATION_TAG] = self._operated_tag
if self._operated_autorelock is not None:
attributes[ATTR_OPERATION_AUTORELOCK] = self._operated_autorelock
@@ -219,6 +231,10 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_REMOTE
elif self._operated_keypad:
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_KEYPAD
elif self._operated_manual:
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_MANUAL
elif self._operated_tag:
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_TAG
elif self._operated_autorelock:
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_AUTORELOCK
else:
@@ -241,6 +257,10 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
self._operated_remote = last_state.attributes[ATTR_OPERATION_REMOTE]
if ATTR_OPERATION_KEYPAD in last_state.attributes:
self._operated_keypad = last_state.attributes[ATTR_OPERATION_KEYPAD]
if ATTR_OPERATION_MANUAL in last_state.attributes:
self._operated_manual = last_state.attributes[ATTR_OPERATION_MANUAL]
if ATTR_OPERATION_TAG in last_state.attributes:
self._operated_tag = last_state.attributes[ATTR_OPERATION_TAG]
if ATTR_OPERATION_AUTORELOCK in last_state.attributes:
self._operated_autorelock = last_state.attributes[ATTR_OPERATION_AUTORELOCK]

View File

@@ -5,7 +5,7 @@ import logging
from auroranoaa import AuroraForecast
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, Platform
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client
@@ -29,11 +29,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
longitude = conf[CONF_LONGITUDE]
latitude = conf[CONF_LATITUDE]
threshold = options.get(CONF_THRESHOLD, DEFAULT_THRESHOLD)
name = conf[CONF_NAME]
coordinator = AuroraDataUpdateCoordinator(
hass=hass,
name=name,
api=api,
latitude=latitude,
longitude=longitude,

View File

@@ -1,4 +1,4 @@
"""Config flow for SpaceX Launches and Starman."""
"""Config flow for Aurora."""
from __future__ import annotations
import logging
@@ -8,7 +8,7 @@ from auroranoaa import AuroraForecast
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
from homeassistant.core import callback
from homeassistant.helpers import aiohttp_client, config_validation as cv
from homeassistant.helpers.schema_config_entry_flow import (
@@ -16,7 +16,7 @@ from homeassistant.helpers.schema_config_entry_flow import (
SchemaOptionsFlowHandler,
)
from .const import CONF_THRESHOLD, DEFAULT_NAME, DEFAULT_THRESHOLD, DOMAIN
from .const import CONF_THRESHOLD, DEFAULT_THRESHOLD, DOMAIN
_LOGGER = logging.getLogger(__name__)
@@ -50,7 +50,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
errors = {}
if user_input is not None:
name = user_input[CONF_NAME]
longitude = user_input[CONF_LONGITUDE]
latitude = user_input[CONF_LATITUDE]
@@ -70,7 +69,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=f"Aurora - {name}", data=user_input
title="Aurora visibility", data=user_input
)
return self.async_show_form(
@@ -78,13 +77,11 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
data_schema=self.add_suggested_values_to_schema(
vol.Schema(
{
vol.Required(CONF_NAME): str,
vol.Required(CONF_LONGITUDE): cv.longitude,
vol.Required(CONF_LATITUDE): cv.latitude,
}
),
{
CONF_NAME: DEFAULT_NAME,
CONF_LONGITUDE: self.hass.config.longitude,
CONF_LATITUDE: self.hass.config.latitude,
},

View File

@@ -6,4 +6,3 @@ AURORA_API = "aurora_api"
CONF_THRESHOLD = "forecast_threshold"
DEFAULT_THRESHOLD = 75
ATTRIBUTION = "Data provided by the National Oceanic and Atmospheric Administration"
DEFAULT_NAME = "Aurora Visibility"

View File

@@ -18,7 +18,6 @@ class AuroraDataUpdateCoordinator(DataUpdateCoordinator):
def __init__(
self,
hass: HomeAssistant,
name: str,
api: AuroraForecast,
latitude: float,
longitude: float,
@@ -29,12 +28,11 @@ class AuroraDataUpdateCoordinator(DataUpdateCoordinator):
super().__init__(
hass=hass,
logger=_LOGGER,
name=name,
name="Aurora",
update_interval=timedelta(minutes=5),
)
self.api = api
self.name = name
self.latitude = int(latitude)
self.longitude = int(longitude)
self.threshold = int(threshold)

View File

@@ -29,14 +29,9 @@ class AuroraEntity(CoordinatorEntity[AuroraDataUpdateCoordinator]):
self._attr_translation_key = translation_key
self._attr_unique_id = f"{coordinator.latitude}_{coordinator.longitude}"
self._attr_icon = icon
@property
def device_info(self) -> DeviceInfo:
"""Define the device based on name."""
return DeviceInfo(
self._attr_device_info = DeviceInfo(
entry_type=DeviceEntryType.SERVICE,
identifiers={(DOMAIN, str(self.unique_id))},
identifiers={(DOMAIN, self._attr_unique_id)},
manufacturer="NOAA",
model="Aurora Visibility Sensor",
name=self.coordinator.name,
)

View File

@@ -57,9 +57,6 @@ from homeassistant.helpers import condition
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.integration_platform import (
async_process_integration_platform_for_component,
)
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.script import (
@@ -249,10 +246,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
LOGGER, DOMAIN, hass
)
# Process integration platforms right away since
# we will create entities before firing EVENT_COMPONENT_LOADED
await async_process_integration_platform_for_component(hass, DOMAIN)
# Register automation as valid domain for Blueprint
async_get_blueprints(hass)
@@ -314,6 +307,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
class BaseAutomationEntity(ToggleEntity, ABC):
"""Base class for automation entities."""
_entity_component_unrecorded_attributes = frozenset(
(ATTR_LAST_TRIGGERED, ATTR_MODE, ATTR_CUR, ATTR_MAX, CONF_ID)
)
raw_config: ConfigType | None
@property

View File

@@ -9,8 +9,9 @@ blueprint:
name: Motion Sensor
selector:
entity:
domain: binary_sensor
device_class: motion
filter:
device_class: motion
domain: binary_sensor
light_target:
name: Light
selector:

View File

@@ -9,18 +9,21 @@ blueprint:
name: Person
selector:
entity:
domain: person
filter:
domain: person
zone_entity:
name: Zone
selector:
entity:
domain: zone
filter:
domain: zone
notify_device:
name: Device to notify
description: Device needs to run the official Home Assistant app to receive notifications.
selector:
device:
integration: mobile_app
filter:
integration: mobile_app
trigger:
platform: state

View File

@@ -1,12 +0,0 @@
"""Integration platform for recorder."""
from __future__ import annotations
from homeassistant.core import HomeAssistant, callback
from . import ATTR_CUR, ATTR_LAST_TRIGGERED, ATTR_MAX, ATTR_MODE, CONF_ID
@callback
def exclude_attributes(hass: HomeAssistant) -> set[str]:
"""Exclude extra attributes from being recorded in the database."""
return {ATTR_LAST_TRIGGERED, ATTR_MODE, ATTR_CUR, ATTR_MAX, CONF_ID}

View File

@@ -1,29 +1,16 @@
"""The awair component."""
from __future__ import annotations
from asyncio import gather, timeout
from dataclasses import dataclass
from datetime import timedelta
from aiohttp import ClientSession
from python_awair import Awair, AwairLocal
from python_awair.air_data import AirData
from python_awair.devices import AwairBaseDevice, AwairLocalDevice
from python_awair.exceptions import AuthError, AwairError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST, Platform
from homeassistant.const import CONF_HOST, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import (
API_TIMEOUT,
DOMAIN,
LOGGER,
UPDATE_INTERVAL_CLOUD,
UPDATE_INTERVAL_LOCAL,
from .const import DOMAIN
from .coordinator import (
AwairCloudDataUpdateCoordinator,
AwairDataUpdateCoordinator,
AwairLocalDataUpdateCoordinator,
)
PLATFORMS = [Platform.SENSOR]
@@ -70,93 +57,3 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
hass.data[DOMAIN].pop(config_entry.entry_id)
return unload_ok
@dataclass
class AwairResult:
"""Wrapper class to hold an awair device and set of air data."""
device: AwairBaseDevice
air_data: AirData
class AwairDataUpdateCoordinator(DataUpdateCoordinator[dict[str, AwairResult]]):
"""Define a wrapper class to update Awair data."""
def __init__(
self,
hass: HomeAssistant,
config_entry: ConfigEntry,
update_interval: timedelta | None,
) -> None:
"""Set up the AwairDataUpdateCoordinator class."""
self._config_entry = config_entry
self.title = config_entry.title
super().__init__(hass, LOGGER, name=DOMAIN, update_interval=update_interval)
async def _fetch_air_data(self, device: AwairBaseDevice) -> AwairResult:
"""Fetch latest air quality data."""
LOGGER.debug("Fetching data for %s", device.uuid)
air_data = await device.air_data_latest()
LOGGER.debug(air_data)
return AwairResult(device=device, air_data=air_data)
class AwairCloudDataUpdateCoordinator(AwairDataUpdateCoordinator):
"""Define a wrapper class to update Awair data from Cloud API."""
def __init__(
self, hass: HomeAssistant, config_entry: ConfigEntry, session: ClientSession
) -> None:
"""Set up the AwairCloudDataUpdateCoordinator class."""
access_token = config_entry.data[CONF_ACCESS_TOKEN]
self._awair = Awair(access_token=access_token, session=session)
super().__init__(hass, config_entry, UPDATE_INTERVAL_CLOUD)
async def _async_update_data(self) -> dict[str, AwairResult]:
"""Update data via Awair client library."""
async with timeout(API_TIMEOUT):
try:
LOGGER.debug("Fetching users and devices")
user = await self._awair.user()
devices = await user.devices()
results = await gather(
*(self._fetch_air_data(device) for device in devices)
)
return {result.device.uuid: result for result in results}
except AuthError as err:
raise ConfigEntryAuthFailed from err
except Exception as err:
raise UpdateFailed(err) from err
class AwairLocalDataUpdateCoordinator(AwairDataUpdateCoordinator):
"""Define a wrapper class to update Awair data from the local API."""
_device: AwairLocalDevice | None = None
def __init__(
self, hass: HomeAssistant, config_entry: ConfigEntry, session: ClientSession
) -> None:
"""Set up the AwairLocalDataUpdateCoordinator class."""
self._awair = AwairLocal(
session=session, device_addrs=[config_entry.data[CONF_HOST]]
)
super().__init__(hass, config_entry, UPDATE_INTERVAL_LOCAL)
async def _async_update_data(self) -> dict[str, AwairResult]:
"""Update data via Awair client library."""
async with timeout(API_TIMEOUT):
try:
if self._device is None:
LOGGER.debug("Fetching devices")
devices = await self._awair.devices()
self._device = devices[0]
result = await self._fetch_air_data(self._device)
return {result.device.uuid: result}
except AwairError as err:
LOGGER.error("Unexpected API error: %s", err)
raise UpdateFailed(err) from err

View File

@@ -0,0 +1,116 @@
"""DataUpdateCoordinators for awair integration."""
from __future__ import annotations
from asyncio import gather, timeout
from dataclasses import dataclass
from datetime import timedelta
from aiohttp import ClientSession
from python_awair import Awair, AwairLocal
from python_awair.air_data import AirData
from python_awair.devices import AwairBaseDevice, AwairLocalDevice
from python_awair.exceptions import AuthError, AwairError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import (
API_TIMEOUT,
DOMAIN,
LOGGER,
UPDATE_INTERVAL_CLOUD,
UPDATE_INTERVAL_LOCAL,
)
@dataclass
class AwairResult:
"""Wrapper class to hold an awair device and set of air data."""
device: AwairBaseDevice
air_data: AirData
class AwairDataUpdateCoordinator(DataUpdateCoordinator[dict[str, AwairResult]]):
"""Define a wrapper class to update Awair data."""
def __init__(
self,
hass: HomeAssistant,
config_entry: ConfigEntry,
update_interval: timedelta | None,
) -> None:
"""Set up the AwairDataUpdateCoordinator class."""
self._config_entry = config_entry
self.title = config_entry.title
super().__init__(hass, LOGGER, name=DOMAIN, update_interval=update_interval)
async def _fetch_air_data(self, device: AwairBaseDevice) -> AwairResult:
"""Fetch latest air quality data."""
LOGGER.debug("Fetching data for %s", device.uuid)
air_data = await device.air_data_latest()
LOGGER.debug(air_data)
return AwairResult(device=device, air_data=air_data)
class AwairCloudDataUpdateCoordinator(AwairDataUpdateCoordinator):
"""Define a wrapper class to update Awair data from Cloud API."""
def __init__(
self, hass: HomeAssistant, config_entry: ConfigEntry, session: ClientSession
) -> None:
"""Set up the AwairCloudDataUpdateCoordinator class."""
access_token = config_entry.data[CONF_ACCESS_TOKEN]
self._awair = Awair(access_token=access_token, session=session)
super().__init__(hass, config_entry, UPDATE_INTERVAL_CLOUD)
async def _async_update_data(self) -> dict[str, AwairResult]:
"""Update data via Awair client library."""
async with timeout(API_TIMEOUT):
try:
LOGGER.debug("Fetching users and devices")
user = await self._awair.user()
devices = await user.devices()
results = await gather(
*(self._fetch_air_data(device) for device in devices)
)
return {result.device.uuid: result for result in results}
except AuthError as err:
raise ConfigEntryAuthFailed from err
except Exception as err:
raise UpdateFailed(err) from err
class AwairLocalDataUpdateCoordinator(AwairDataUpdateCoordinator):
"""Define a wrapper class to update Awair data from the local API."""
_device: AwairLocalDevice | None = None
def __init__(
self, hass: HomeAssistant, config_entry: ConfigEntry, session: ClientSession
) -> None:
"""Set up the AwairLocalDataUpdateCoordinator class."""
self._awair = AwairLocal(
session=session, device_addrs=[config_entry.data[CONF_HOST]]
)
super().__init__(hass, config_entry, UPDATE_INTERVAL_LOCAL)
async def _async_update_data(self) -> dict[str, AwairResult]:
"""Update data via Awair client library."""
async with timeout(API_TIMEOUT):
try:
if self._device is None:
LOGGER.debug("Fetching devices")
devices = await self._awair.devices()
self._device = devices[0]
result = await self._fetch_air_data(self._device)
return {result.device.uuid: result}
except AwairError as err:
LOGGER.error("Unexpected API error: %s", err)
raise UpdateFailed(err) from err

View File

@@ -31,7 +31,6 @@ from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AwairDataUpdateCoordinator, AwairResult
from .const import (
API_CO2,
API_DUST,
@@ -46,6 +45,7 @@ from .const import (
ATTRIBUTION,
DOMAIN,
)
from .coordinator import AwairDataUpdateCoordinator, AwairResult
DUST_ALIASES = [API_PM25, API_PM10]

View File

@@ -14,7 +14,6 @@ from homeassistant import config_entries
from homeassistant.components import zeroconf
from homeassistant.const import CONF_IP_ADDRESS
from homeassistant.data_entry_flow import FlowResult
from homeassistant.util.network import is_ipv6_address
from .const import DOMAIN, RUN_TIMEOUT
from .models import BAFDiscovery
@@ -49,10 +48,10 @@ class BAFFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
self, discovery_info: zeroconf.ZeroconfServiceInfo
) -> FlowResult:
"""Handle zeroconf discovery."""
if discovery_info.ip_address.version == 6:
return self.async_abort(reason="ipv6_not_supported")
properties = discovery_info.properties
ip_address = discovery_info.host
if is_ipv6_address(ip_address):
return self.async_abort(reason="ipv6_not_supported")
uuid = properties["uuid"]
model = properties["model"]
name = properties["name"]

View File

@@ -59,7 +59,7 @@ def validate_input(auth: Auth) -> None:
raise Require2FA
def _send_blink_2fa_pin(auth: Auth, pin: str) -> bool:
def _send_blink_2fa_pin(auth: Auth, pin: str | None) -> bool:
"""Send 2FA pin to blink servers."""
blink = Blink()
blink.auth = auth
@@ -122,8 +122,9 @@ class BlinkConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle 2FA step."""
errors = {}
if user_input is not None:
pin = user_input.get(CONF_PIN)
pin: str | None = user_input.get(CONF_PIN)
try:
assert self.auth
valid_token = await self.hass.async_add_executor_job(
_send_blink_2fa_pin, self.auth, pin
)

View File

@@ -100,6 +100,7 @@ class BloomSkySensor(SensorEntity):
self._sensor_name = sensor_name
self._attr_name = f"{device['DeviceName']} {sensor_name}"
self._attr_unique_id = f"{self._device_id}-{sensor_name}"
self._attr_device_class = SENSOR_DEVICE_CLASS.get(sensor_name)
self._attr_native_unit_of_measurement = SENSOR_UNITS_IMPERIAL.get(
sensor_name, None
)
@@ -108,11 +109,6 @@ class BloomSkySensor(SensorEntity):
sensor_name, None
)
@property
def device_class(self) -> SensorDeviceClass | None:
"""Return the class of this device, from component DEVICE_CLASSES."""
return SENSOR_DEVICE_CLASS.get(self._sensor_name)
def update(self) -> None:
"""Request an update from the BloomSky API."""
self._bloomsky.refresh_devices()

View File

@@ -45,6 +45,8 @@ from .api import (
async_ble_device_from_address,
async_discovered_service_info,
async_get_advertisement_callback,
async_get_fallback_availability_interval,
async_get_learned_advertising_interval,
async_get_scanner,
async_last_service_info,
async_process_advertisements,
@@ -54,6 +56,7 @@ from .api import (
async_scanner_by_source,
async_scanner_count,
async_scanner_devices_by_address,
async_set_fallback_availability_interval,
async_track_unavailable,
)
from .base_scanner import BaseHaRemoteScanner, BaseHaScanner, BluetoothScannerDevice
@@ -86,12 +89,15 @@ __all__ = [
"async_address_present",
"async_ble_device_from_address",
"async_discovered_service_info",
"async_get_fallback_availability_interval",
"async_get_learned_advertising_interval",
"async_get_scanner",
"async_last_service_info",
"async_process_advertisements",
"async_rediscover_address",
"async_register_callback",
"async_register_scanner",
"async_set_fallback_availability_interval",
"async_track_unavailable",
"async_scanner_by_source",
"async_scanner_count",

View File

@@ -110,7 +110,7 @@ class ActiveBluetoothDataUpdateCoordinator(
return False
poll_age: float | None = None
if self._last_poll:
poll_age = monotonic_time_coarse() - self._last_poll
poll_age = service_info.time - self._last_poll
return self._needs_poll_method(service_info, poll_age)
async def _async_poll_data(

View File

@@ -103,7 +103,7 @@ class ActiveBluetoothProcessorCoordinator(
return False
poll_age: float | None = None
if self._last_poll:
poll_age = monotonic_time_coarse() - self._last_poll
poll_age = service_info.time - self._last_poll
return self._needs_poll_method(service_info, poll_age)
async def _async_poll_data(

View File

@@ -138,7 +138,7 @@ async def async_process_advertisements(
timeout: int,
) -> BluetoothServiceInfoBleak:
"""Process advertisements until callback returns true or timeout expires."""
done: Future[BluetoothServiceInfoBleak] = Future()
done: Future[BluetoothServiceInfoBleak] = hass.loop.create_future()
@hass_callback
def _async_discovered_device(
@@ -197,3 +197,27 @@ def async_get_advertisement_callback(
) -> Callable[[BluetoothServiceInfoBleak], None]:
"""Get the advertisement callback."""
return _get_manager(hass).scanner_adv_received
@hass_callback
def async_get_learned_advertising_interval(
hass: HomeAssistant, address: str
) -> float | None:
"""Get the learned advertising interval for a MAC address."""
return _get_manager(hass).async_get_learned_advertising_interval(address)
@hass_callback
def async_get_fallback_availability_interval(
hass: HomeAssistant, address: str
) -> float | None:
"""Get the fallback availability timeout for a MAC address."""
return _get_manager(hass).async_get_fallback_availability_interval(address)
@hass_callback
def async_set_fallback_availability_interval(
hass: HomeAssistant, address: str, interval: float
) -> None:
"""Override the fallback availability timeout for a MAC address."""
_get_manager(hass).async_set_fallback_availability_interval(address, interval)

View File

@@ -131,6 +131,9 @@ class BaseHaScanner(ABC):
self.name,
SCANNER_WATCHDOG_TIMEOUT,
)
self.scanning = False
return
self.scanning = not self._connecting
@contextmanager
def connecting(self) -> Generator[None, None, None]:
@@ -302,6 +305,7 @@ class BaseHaRemoteScanner(BaseHaScanner):
advertisement_monotonic_time: float,
) -> None:
"""Call the registered callback."""
self.scanning = not self._connecting
self._last_detection = advertisement_monotonic_time
try:
prev_discovery = self._discovered_device_advertisement_datas[address]

View File

@@ -18,7 +18,7 @@ from bluetooth_adapters import (
)
from homeassistant import config_entries
from homeassistant.components.logger import EVENT_LOGGING_CHANGED
from homeassistant.const import EVENT_LOGGING_CHANGED
from homeassistant.core import (
CALLBACK_TYPE,
Event,
@@ -108,6 +108,7 @@ class BluetoothManager:
"_cancel_unavailable_tracking",
"_cancel_logging_listener",
"_advertisement_tracker",
"_fallback_intervals",
"_unavailable_callbacks",
"_connectable_unavailable_callbacks",
"_callback_index",
@@ -139,6 +140,7 @@ class BluetoothManager:
self._cancel_logging_listener: CALLBACK_TYPE | None = None
self._advertisement_tracker = AdvertisementTracker()
self._fallback_intervals: dict[str, float] = {}
self._unavailable_callbacks: dict[
str, list[Callable[[BluetoothServiceInfoBleak], None]]
@@ -342,7 +344,9 @@ class BluetoothManager:
# since it may have gone to sleep and since we do not need an active
# connection to it we can only determine its availability
# by the lack of advertisements
if advertising_interval := intervals.get(address):
if advertising_interval := (
intervals.get(address) or self._fallback_intervals.get(address)
):
advertising_interval += TRACKER_BUFFERING_WOBBLE_SECONDS
else:
advertising_interval = (
@@ -355,6 +359,7 @@ class BluetoothManager:
# The second loop (connectable=False) is responsible for removing
# the device from all the interval tracking since it is no longer
# available for both connectable and non-connectable
self._fallback_intervals.pop(address, None)
tracker.async_remove_address(address)
self._integration_matcher.async_clear_address(address)
self._async_dismiss_discoveries(address)
@@ -386,7 +391,10 @@ class BluetoothManager:
"""Prefer previous advertisement from a different source if it is better."""
if new.time - old.time > (
stale_seconds := self._advertisement_tracker.intervals.get(
new.address, FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS
new.address,
self._fallback_intervals.get(
new.address, FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS
),
)
):
# If the old advertisement is stale, any new advertisement is preferred
@@ -779,3 +787,20 @@ class BluetoothManager:
def async_allocate_connection_slot(self, device: BLEDevice) -> bool:
"""Allocate a connection slot."""
return self.slot_manager.allocate_slot(device)
@hass_callback
def async_get_learned_advertising_interval(self, address: str) -> float | None:
"""Get the learned advertising interval for a MAC address."""
return self._advertisement_tracker.intervals.get(address)
@hass_callback
def async_get_fallback_availability_interval(self, address: str) -> float | None:
"""Get the fallback availability timeout for a MAC address."""
return self._fallback_intervals.get(address)
@hass_callback
def async_set_fallback_availability_interval(
self, address: str, interval: float
) -> None:
"""Override the fallback availability timeout for a MAC address."""
self._fallback_intervals[address] = interval

View File

@@ -3,7 +3,7 @@
"name": "Bluetooth",
"codeowners": ["@bdraco"],
"config_flow": true,
"dependencies": ["logger", "usb"],
"dependencies": ["usb"],
"documentation": "https://www.home-assistant.io/integrations/bluetooth",
"iot_class": "local_push",
"loggers": [
@@ -14,11 +14,11 @@
],
"quality_scale": "internal",
"requirements": [
"bleak==0.20.2",
"bleak-retry-connector==3.1.1",
"bluetooth-adapters==0.16.0",
"bluetooth-auto-recovery==1.2.1",
"bluetooth-data-tools==1.9.1",
"dbus-fast==1.94.1"
"bleak==0.21.1",
"bleak-retry-connector==3.2.1",
"bluetooth-adapters==0.16.1",
"bluetooth-auto-recovery==1.2.3",
"bluetooth-data-tools==1.12.0",
"dbus-fast==2.11.0"
]
}

View File

@@ -85,6 +85,7 @@ class PassiveBluetoothDataUpdateCoordinator(
change: BluetoothChange,
) -> None:
"""Handle a Bluetooth event."""
self._available = True
self.async_update_listeners()

View File

@@ -341,7 +341,8 @@ class PassiveBluetoothProcessorCoordinator(
change: BluetoothChange,
) -> None:
"""Handle a Bluetooth event."""
super()._async_handle_bluetooth_event(service_info, change)
was_available = self._available
self._available = True
if self.hass.is_stopping:
return
@@ -359,7 +360,7 @@ class PassiveBluetoothProcessorCoordinator(
self.logger.info("Coordinator %s recovered", self.name)
for processor in self._processors:
processor.async_handle_update(update)
processor.async_handle_update(update, was_available)
_PassiveBluetoothDataProcessorT = TypeVar(
@@ -516,20 +517,39 @@ class PassiveBluetoothDataProcessor(Generic[_T]):
@callback
def async_update_listeners(
self, data: PassiveBluetoothDataUpdate[_T] | None
self,
data: PassiveBluetoothDataUpdate[_T] | None,
was_available: bool | None = None,
) -> None:
"""Update all registered listeners."""
if was_available is None:
was_available = self.coordinator.available
# Dispatch to listeners without a filter key
for update_callback in self._listeners:
update_callback(data)
if not was_available or data is None:
# When data is None, or was_available is False,
# dispatch to all listeners as it means the device
# is flipping between available and unavailable
for listeners in self._entity_key_listeners.values():
for update_callback in listeners:
update_callback(data)
return
# Dispatch to listeners with a filter key
for listeners in self._entity_key_listeners.values():
for update_callback in listeners:
update_callback(data)
# if the key is in the data
entity_key_listeners = self._entity_key_listeners
for entity_key in data.entity_data:
if maybe_listener := entity_key_listeners.get(entity_key):
for update_callback in maybe_listener:
update_callback(data)
@callback
def async_handle_update(self, update: _T) -> None:
def async_handle_update(
self, update: _T, was_available: bool | None = None
) -> None:
"""Handle a Bluetooth event."""
try:
new_data = self.update_method(update)
@@ -554,7 +574,7 @@ class PassiveBluetoothDataProcessor(Generic[_T]):
)
self.data.update(new_data)
self.async_update_listeners(new_data)
self.async_update_listeners(new_data, was_available)
class PassiveBluetoothProcessorEntity(Entity, Generic[_PassiveBluetoothDataProcessorT]):

View File

@@ -329,6 +329,9 @@ class HaScanner(BaseHaScanner):
self.name,
SCANNER_WATCHDOG_TIMEOUT,
)
# Immediately mark the scanner as not scanning
# since the restart task will have to wait for the lock
self.scanning = False
self.hass.async_create_task(self._async_restart_scanner())
async def _async_restart_scanner(self) -> None:

View File

@@ -39,6 +39,8 @@ class BasePassiveBluetoothCoordinator(ABC):
self.mode = mode
self._last_unavailable_time = 0.0
self._last_name = address
# Subclasses are responsible for setting _available to True
# when the abstractmethod _async_handle_bluetooth_event is called.
self._available = async_address_present(hass, address, connectable)
@callback
@@ -88,23 +90,13 @@ class BasePassiveBluetoothCoordinator(ABC):
"""Return if the device is available."""
return self._available
@callback
def _async_handle_bluetooth_event_internal(
self,
service_info: BluetoothServiceInfoBleak,
change: BluetoothChange,
) -> None:
"""Handle a bluetooth event."""
self._available = True
self._async_handle_bluetooth_event(service_info, change)
@callback
def _async_start(self) -> None:
"""Start the callbacks."""
self._on_stop.append(
async_register_callback(
self.hass,
self._async_handle_bluetooth_event_internal,
self._async_handle_bluetooth_event,
BluetoothCallbackMatcher(
address=self.address, connectable=self.connectable
),

View File

@@ -120,15 +120,17 @@ class HaBleakScannerWrapper(BaseBleakScanner):
def register_detection_callback(
self, callback: AdvertisementDataCallback | None
) -> None:
) -> Callable[[], None]:
"""Register a detection callback.
The callback is called when a device is discovered or has a property changed.
This method takes the callback and registers it with the long running sscanner.
This method takes the callback and registers it with the long running scanner.
"""
self._advertisement_data_callback = callback
self._setup_detection_callback()
assert self._detection_cancel is not None
return self._detection_cancel
def _setup_detection_callback(self) -> None:
"""Set up the detection callback."""

View File

@@ -2,7 +2,6 @@
from __future__ import annotations
import asyncio
from collections.abc import Awaitable
from datetime import datetime, timedelta
import logging
from typing import Final
@@ -152,7 +151,7 @@ async def async_setup_scanner(
async def perform_bluetooth_update() -> None:
"""Discover Bluetooth devices and update status."""
_LOGGER.debug("Performing Bluetooth devices discovery and update")
tasks: list[Awaitable[None]] = []
tasks: list[asyncio.Task[None]] = []
try:
if track_new:

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