Compare commits

..

489 Commits

Author SHA1 Message Date
Michael Hansen
083766776d Add Assist satellite ESPHome + VoIP 2024-09-06 01:44:33 +00:00
Michael Hansen
60b0f0dc53 Add assist satellite entity component (#125351)
* Add assist_satellite

* Update homeassistant/components/assist_satellite/manifest.json

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>

* Update homeassistant/components/assist_satellite/manifest.json

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>

* Add platform constant

* Update Dockerfile

* Apply suggestions from code review

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

* Address comments

* Update docstring async_internal_announce

* Update CODEOWNERS

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-09-05 21:16:30 -04:00
Paulus Schoutsen
c3921f2112 Add model ID to unifiprotect (#125376) 2024-09-05 19:44:28 -04:00
Paulus Schoutsen
aa619c5594 Add model ID to awair (#125373)
* Add model ID to awair

* less diff
2024-09-05 19:42:50 -04:00
Paulus Schoutsen
0677a256ec Add model ID to Wemo (#125368) 2024-09-05 23:03:50 +02:00
Paulus Schoutsen
97ffbf5aad Add model ID to samsungtv (#125369) 2024-09-05 23:03:37 +02:00
Paulus Schoutsen
006b2da14e Add model ID to roborock (#125366) 2024-09-05 16:52:45 -04:00
Paulus Schoutsen
56b4ddc6b4 Add model ID to Sonos (#125364) 2024-09-05 16:52:17 -04:00
G Johansson
2c0c0b9e21 Extend deprecation of aux_heat in ClimateEntity (#125360) 2024-09-05 22:34:35 +02:00
Mark Ruys
9e312f2063 Add Sensoterra integration (#119642)
* Initial version

* Baseline release

* Refactor based on first PR feedback

* Refactoring based on second PR feedback

* Initial version

* Baseline release

* Refactor based on first PR feedback

* Refactoring based on second PR feedback

* Refactoring based on PR feedback

* Refactoring based on PR feedback

* Remove extra attribute soil type

Soil type isn't really a sensor, but more like a configuration entity.
Move soil type to a different PR to keep this PR simpler.

* Refactor SensoterraSensor to a named tuple

* Implement feedback on PR

* Remove .coveragerc

* Add async_set_unique_id to config flow

* Small fix based on feedback

* Add test form unique_id

* Fix

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2024-09-05 21:37:44 +02:00
G Johansson
bbeecb40ae Remove deprecated aux_heat from zha (#125247)
Remove aux_heat from zha
2024-09-05 21:35:24 +02:00
YogevBokobza
48c9361c01 Bump aioswitcher to 4.0.3 (#125355) 2024-09-05 22:34:11 +03:00
Robert Contreras
d686b877b1 Home Connect add FridgeFreezer switch entities (#122881)
* Home Connect add FridgeFreezer switch entities

* Fix unrelated test

* Implemented requested changes from review

* Move exist_fn check code to setup

* Assign entity_description during init

* Resolve issue with functional testing
2024-09-05 20:52:12 +02:00
Bouwe Westerdijk
d2d01b337d Bump plugwise to v1.0.0 (#125354) 2024-09-05 20:16:11 +02:00
peteS-UK
b0bfe71b9b Fix typo in squeezebox (#125352)
Spelling Correction on SERVER_MODEL
2024-09-05 18:44:19 +02:00
Phill (pssc)
38f3fa0210 Add Squeezebox server service binary sensors (#122473)
* squeezebox add binary sensor + coordinator

* squeezebox add connected via for media_player

* squeezebox add Player type for player

* Add more type info

* Fix linter errors

* squeezebox use our own status entity

* squeezebox rework device handling based on freedback

* Fix device creation

* squeezebox rework coordinator error handling

* Fix lint type error

* Correct spelling

* Correct spelling

* remove large comments

* insert small comment

* add translation support

* Simply sensor

* clean update function, minimise comments to the useful bits

* Fix after testing

* Update homeassistant/components/squeezebox/entity.py

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

* move data prep out of Device assign for clarity

* stop being a generic api

* Humans need to read the sensors...

* ruff format

* Humans need to read the sensors...

* Revert "ruff format"

This reverts commit 8fcb8143e7c4427e75d31f9dd57f6c2027f8df6a.

* ruff format

* Humans need to read the sensors...

* errors after testing

* infered

* drop context

* cutdown coordinator for the binary sensors

* add tests for binary sensors

* Fix import

* add some basic media_player tests

* Fix spelling and file headers

* Fix spelling

* remove uuid and use service device cat

* use diag device

* assert execpted value

* ruff format

* Update homeassistant/components/squeezebox/__init__.py

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

* Simplify T/F

* Fix file header

* remove redudant check

* remove player tests from this commit

* Fix formatting

* remove unused

* Fix function Type

* Fix Any to bool

* Fix browser tests

* Patch our squeebox componemt not the server in the lib

* ruff

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-05 16:49:07 +02:00
Erik Montnemery
86ae70780c Refactor recorder retryable_database_job decorator (#125306) 2024-09-05 13:09:27 +02:00
mvn23
65e16b4814 Split opentherm_gw entity base class (#125330)
Add OpenThermStatusEntity to allow entities that don't need status updates
2024-09-05 13:03:16 +02:00
Adam Pasztor
70966c2b63 Add new data types to ADS integration (#125201)
* feat: Introduce new data types to ADS integration.

* refactor: ADS data unpacking based on PLC data type

* refactor: handle BOOL and STRING as special cases.
2024-09-05 12:07:19 +02:00
Malte Franken
ba7f36328d Add diagnostics to GeoNet NZ Quakes integration (#125320)
* add diagnostics platform

* add tests

* add snapshot data

* remove from no diagnostics list
2024-09-05 11:35:36 +02:00
TimL
511ecf98d5 Add reauth flow for Smlight (#124418)
* Add reauth flow for smlight integration

* add strings for reauth

* trigger reauth flow on authentication errors

* Add tests for reauth flow

* test for update failed on auth error

* restore name title placeholder

* raise config entry error to trigger reauth

* Add test for reauth triggered at startup

---------

Co-authored-by: Tim Lunn <tim@feathertop.org>
2024-09-05 11:02:05 +02:00
Malte Franken
b5831344a0 Add diagnostics to GDACS integration (#125296)
* simple diagnostics

* add service status information

* remove from no diagnostics list

* wip

* cater for the case where status info is undefined

* make test work

* code reformatted

* add snapshot data

* simplify code
2024-09-05 10:53:12 +02:00
Erik Montnemery
984eba809c Simplify generic decorators in recorder (#125301)
* Simplify generic decorators in recorder

* Remove additional case
2024-09-05 10:16:44 +02:00
epenet
f778033bd8 Improve config flow type hints in ukraine_alarm (#125302) 2024-09-05 09:55:57 +02:00
Erik Montnemery
a8f2204f4f Teach recorder data migrator base class to update MigrationChanges (#125214)
* Teach recorder data migrator base class to update MigrationChanges

* Bump migration version

* Improve test coverage

* Update migration.py

* Revert migrator version bump

* Remove unneeded change
2024-09-05 08:56:18 +02:00
Simon Lamon
4c56cbe8c8 Add follower to the PlayingMode enum (#125294)
Update media_player.py
2024-09-05 08:50:49 +02:00
J. Nick Koston
71d35a03e1 Switch hassio to use with_path where possible (#125268)
* Switch hassio to use with_path where possible

Any place we are joining to the root url, we can use with_path
as its much faster

* revert
2024-09-05 08:12:43 +02:00
Marc Mueller
c8fd48523f Use TypeVar defaults for Generator (#125228) 2024-09-04 18:10:21 -10:00
J. Nick Koston
fbd3bf7a98 Bump yarl to 1.9.9 (#125264) 2024-09-04 11:32:33 -10:00
J. Nick Koston
a0356f587e Fix yarl binary wheel builds for armv7l and armhf (#125270) 2024-09-04 11:32:08 -10:00
Jordi
199a4b725b Increase AquaCell timeout and handle timeout exception properly (#125263)
* Increase timeout and add handling of timeout exception

* Raise update failed instead of config entry error
2024-09-04 23:22:31 +02:00
Raj Laud
505df84783 Squeezebox remove deprecated sync and unsync services (#125271)
* Squeezebox remove deprecated sync and unsync

* Squeezebox remove sync group attribute
2024-09-04 23:17:39 +02:00
Shay Levy
baa9473383 Address BTHome review comment (#125259)
* Address BTHome review comment

* Review comment

Co-authored-by: Ernst Klamer <e.klamer@gmail.com>

* generator expression

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

---------

Co-authored-by: Ernst Klamer <e.klamer@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-09-04 23:24:52 +03:00
ilan
ba5d23290a Add madvr diagnostics (#125109)
* feat: add basic diagnostics

* fix: add mock data

* fix: regen snapshots
2024-09-04 21:57:37 +02:00
Shai Ungar
adda02b6b1 Add service to 17track to archive package (#123493)
* Add service archive package

* Update homeassistant/components/seventeentrack/icons.json

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

* CR fix in tests

* CR fix in services.py

* string references

* extract constant keys

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-04 21:56:11 +02:00
G Johansson
1f59bd9f92 Don't show input panel if default code provided in envisalink (#125256) 2024-09-04 21:49:28 +02:00
G Johansson
b61678d39c Fix blocking call in yale_smart_alarm (#125255) 2024-09-04 21:14:54 +02:00
Christopher Fenner
b23297bb7e Add hysteresis entity for heat pumps via ViCare (#124294)
* add hysteresis entity

* update PyViCare-neo dependency

* add hysteresis switch on / of entities

* Revert "add hysteresis entity"

This reverts commit dcb5680d0ca1958640e68de36f6befbf6416ab41.
2024-09-04 20:32:40 +02:00
TimL
f56c38d69b Add uptime sensors for Smlight (#124408)
* Add uptime sensor as derived sensor class

* Add strings for uptime sensors

* Update sensor tests to include uptime sensors

* test zigbee uptime when disconnected
2024-09-04 20:31:56 +02:00
tronikos
c2b24dd355 Add debug logging in get_cost_reads in opower (#124473)
Add debug statements in get_cost_reads in opower
2024-09-04 20:30:24 +02:00
Tal Taub
c4c8e74a8a Add Custom Drink Entities Tami4 Edge (#124506)
* Add drinks as button entities instead of using actions

* Remove button extensions

* Add an extension to create new buttons

* Use translation key for buttons names

* Change translation key wording

* Call async_add_entities once

* Add icons

* Update homeassistant/components/tami4/button.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-04 20:29:06 +02:00
G Johansson
c4029300c2 Remove deprecated aux_heat from honeywell (#125248) 2024-09-04 20:28:45 +02:00
J. Nick Koston
52320844fc Revert "Disable IPv6 in the opower integration to fix AEP utilities" (#125208)
Revert "Disable IPv6 in the opower integration to fix AEP utilities (#107203)"

This reverts commit 2a9a046fab.
2024-09-04 08:05:13 -10:00
Pete Sage
b4e20409de Add Sonos tests and update error handling for unknown media (#124578)
* initial commit

* simplify tests
2024-09-04 20:03:26 +02:00
Michael Hansen
4ecc6555bf Add support for sample bytes in preferred TTS format (#125235) 2024-09-04 13:42:41 -04:00
mvn23
892c32c8b7 Add button platform to opentherm_gw (#125185)
* Add button platform to opentherm_gw

* Add tests for button.py

* Update tests/components/opentherm_gw/test_button.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-04 19:20:05 +02:00
Artur Pragacz
bad305dcbf Add Onkyo to strict typing (#124617) 2024-09-04 19:11:34 +02:00
TimL
7266a16295 Add Button platform for Smlight integration (#124970)
* Add button platform for smlight integration

* Add strings required for button platform

* Add commands api to smlight mock client

* Add tests for smlight button platform

* Move entity category to class

* Disable by default Zigbee flash mode
2024-09-04 19:10:59 +02:00
epenet
416a2de179 Improve config flow type hints in screenlogic (#125199) 2024-09-04 19:09:41 +02:00
Christopher Fenner
349ea35dc3 Fix device identifier in ViCare integration (#124483)
* use correct serial

* add migration handler

* adjust init call

* add missing types

* adjust init call

* adjust init call

* adjust init call

* adjust init call

* Update types.py

* fix loop

* fix loop

* fix parameter order

* align parameter naming

* remove comment

* correct init

* update

* Update types.py

* correct merge

* revert type change

* add test case

* add helper

* add test case

* update snapshot

* add snapshot

* add device.serial data point

* fix device unique id

* update snapshot

* add comments

* update nmigration

* fix missing parameter

* move static parameters

* fix circuit access

* update device.serial

* update snapshots

* remove test case

* Update binary_sensor.py

* convert climate entity

* Update entity.py

* update snapshot

* use snake case

* add migration test

* enhance test case

* add test case

* Apply suggestions from code review

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-04 18:41:20 +02:00
epenet
0fb1fbf0d1 Improve config flow type hints (q-s) (#125198)
* Improve config flow type hints (q-s)

* Revert screenlogic

* Revert starline
2024-09-04 18:38:34 +02:00
epenet
643fd34478 Improve config flow type hints in starline (#125202) 2024-09-04 18:38:19 +02:00
Duco Sebel
186c9aa33b Remove ExternalDevice migration in HomeWizard (#125197) 2024-09-04 18:32:57 +02:00
Martins Sipenko
af51241c0d Reenable Smarty integration (#124148)
* Reenable Smarty integration

* Updated codeowners to myself

* Revert "Updated codeowners to myself"

This reverts commit 639fef32b90d22117938f864e6ea3c55b0fc5074.

* Upgraded pysmarty2 to version 0.10.1 which is not pinned to specific pymodbus version

* Update requirements_all.txt
2024-09-04 18:01:49 +02:00
Shay Levy
eaee8d5b78 Fix BTHome validate triggers for device with multiple buttons (#125183)
* Fix BTHome validate triggers for device with multiple buttons

* Remove None default
2024-09-04 17:34:11 +02:00
Michael Hansen
638434c103 Bump intents to 2024.9.4 (#125232) 2024-09-04 17:36:25 +03:00
Marc Mueller
3a44098ddf Fix Path.__enter__ DeprecationWarning in tests (#125227) 2024-09-04 07:12:57 -07:00
LG-ThinQ-Integration
1e1c3506fe Bump thinqconnect to 0.9.6 (#125155)
* Refactor LG ThinQ integration

* Rename ha_bridge_list to bridge_list

* Update for reviews

* Correct spells
Do not use mqtt related api

* Guarantee update status

* Update for reviews

* Update reviews

---------

Co-authored-by: jangwon.lee <jangwon.lee@lge.com>
2024-09-04 15:52:41 +02:00
Iskra kranj
b557e9e826 Add Iskra integration (#121488)
* Add iskra integration

* iskra non resettable counters naming fix

* added iskra config_flow test

* fixed iskra integration according to code review

* changed iskra config flow test

* iskra integration, fixed codeowners

* Removed counters code & minor fixes

* added comment

* Update homeassistant/components/iskra/__init__.py

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

* Updated Iskra integration according to review

* Update homeassistant/components/iskra/strings.json

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

* Updated iskra integration according to review

* minor iskra integration change

* iskra integration changes according to review

* iskra integration changes according to review

* Changed iskra integration according to review

* added iskra config_flow range validation

* Fixed tests for iskra integration

* Update homeassistant/components/iskra/coordinator.py

* Update homeassistant/components/iskra/config_flow.py

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

* Fixed iskra integration according to review

* Changed voluptuous schema for iskra integration and added data_descriptions

* Iskra integration tests lint error fix

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-04 15:33:23 +02:00
Denis Shulyaka
da0d1b71ce Update Anthropic default model to Haiku (#125225) 2024-09-04 06:30:28 -07:00
Robert Resch
4d96ed4c68 Update modified_at datetime on storage collection changes (#125218) 2024-09-04 15:05:51 +02:00
Marc Mueller
1bc63a61be Fix enum lookup (#125220) 2024-09-04 15:05:28 +02:00
Michal Jál
5c35ccb9ca Allow Switchbot users to force nightlatch (#124326)
* Add option to force nightlatch operation mode

* Fix format

* Make the new option available only for lock pro entry

* use senor_type instead of switchbot model + tests

* Update homeassistant/components/switchbot/lock.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-04 15:03:59 +02:00
J. Nick Koston
a1ecefee21 Bump aioesphomeapi to 25.3.2 (#125188)
changelog: https://github.com/esphome/aioesphomeapi/compare/v25.3.1...v25.3.2
2024-09-04 08:35:52 -04:00
Hessel
b5d7eba4f6 Add new number component for setting the wallbox ICP current (#125209)
* Add new number component for setting the wallbox ICP current

* feat: Add number component for wallbox ICP current control
2024-09-04 14:00:38 +02:00
starkillerOG
4b111008df Add 100% coverage of Reolink button platform (#124380)
* Add 100% button coverage

* review comments

* fix

* Use SERVICE_PRESS constant

* Use DOMAIN instead of const.DOMAIN

* styling

* User entity_registry_enabled_by_default fixture

* fixes

* Split out ptz_move test

* use SERVICE_PTZ_MOVE constant
2024-09-04 12:16:57 +02:00
Lenn
fb5afff9d5 Add Motionblinds Bluetooth diagnostics (#121899)
* Add diagnostics platform

* Add diagnostics test

* Remove comments

* Exclude created_at and modified_at from snapshot

* Fix entry_id in mock_config_entry

* Add repr to excluded props from snapshot

* Improve diagnostics

* Use function name instead of number for callback diagnostics

* Remove info from diagnostics

* Reformat
2024-09-04 12:11:11 +02:00
Robert Resch
38a1c97a51 Bump deebot-client to 8.4.0 (#125207) 2024-09-04 11:46:41 +02:00
J. Nick Koston
b26e4d672f Bump yarl to 1.9.8 (#125193)
changelog: https://github.com/aio-libs/yarl/compare/v1.9.7...v1.9.8
2024-09-04 11:44:49 +02:00
Bram Kragten
daa5268cf2 Update frontend to 20240904.0 (#125206) 2024-09-04 11:35:14 +02:00
Matthias Alphart
9da3f98c23 Update knx-frontend to 2024.9.4.64538 (#125196) 2024-09-04 11:00:02 +02:00
Erik Montnemery
8fd691be69 Teach recorder data migrator base class to remove index (#125168)
* Teach recorder data migrator base class to remove index

* Fix tests
2024-09-04 09:52:41 +02:00
Erik Montnemery
7fc0e36b2f Move recorder EntityIDPostMigrationTask to migration (#125136)
* Move recorder EntityIDPostMigrationTask to migration

* Update test
2024-09-04 08:38:46 +02:00
Erik Montnemery
482bed522f Fix missing patch in nextdns tests (#125195) 2024-09-04 08:34:51 +02:00
Raman Gupta
7788685340 Get zwave_js statistics data from model (#120281)
* Get zwave_js statistics data from model

* Add migration logic

* Update comment

* revert change to forward entry
2024-09-04 08:16:56 +02:00
Dian
af1af6f391 Bump xiaomi-ble to 0.31.1 to add support for human presence sensor XMOSB01XS (#124751) 2024-09-03 20:11:32 -10:00
Shay Levy
d5c2e6ec35 Add myself as codeowner for BTHome (#125184) 2024-09-04 00:20:25 +03:00
Erik Montnemery
d8382c6de2 Improve recorder tests to check indices are removed (#125164) 2024-09-03 22:56:27 +02:00
starkillerOG
c4cfff4b3f Add 100% coverage of Reolink update platform (#124521)
* Add 100% update test coverage

* Add assertion
2024-09-03 22:50:00 +02:00
G Johansson
cfe0c95c97 Bump python-holidays to 0.56 (#125182) 2024-09-03 22:43:03 +02:00
Maciej Bieniek
50c1bf8bb0 Add re-auth flow to NextDNS integration (#125101) 2024-09-03 22:38:07 +02:00
Erik Montnemery
cc3d059783 Refactor recorder EventIDPostMigration data migrator (#125126) 2024-09-03 22:37:50 +02:00
Joakim Sørensen
4aa86a574f Add include-hidden-files to upload env_file artifact (#125179) 2024-09-03 22:23:26 +02:00
J. Nick Koston
3a8039cbc0 Bump yalexs to 8.6.3 (#125176)
Fixes the battery state not refreshing due to a refactoring
error in the library.

changelog: https://github.com/bdraco/yalexs/compare/v8.6.2...v8.6.3
2024-09-03 22:18:19 +02:00
Joakim Plate
e4f9f6447f Update gardena_bluetooth dependency to 1.4.3 (#125175) 2024-09-03 21:45:43 +02:00
mvn23
14482ff6da Update opentherm_gw tests to prepare for new platforms (#125172)
Move MockConfigEntry to a fixture
2024-09-03 21:18:38 +02:00
Hans Kröner
be8f14167f Expose UV Index in Met.no (#124992)
UV Index now also appears in forecasts.
2024-09-03 21:00:44 +02:00
J. Nick Koston
27032c1780 Bump yalexs to 8.6.2 (#125162)
changelog: https://github.com/bdraco/yalexs/compare/v8.6.0...v8.6.2
2024-09-03 19:53:10 +02:00
Paul Bottein
61a722218a Update frontend to 20240903.1 (#125160) 2024-09-03 19:52:38 +02:00
Raj Laud
3137c27e56 Fix type errors in squeezebox (#125166) 2024-09-03 19:50:44 +02:00
Nerdix
7b35c3036e Enhance error handling when changing a timer's duration (#121786)
* Update remaining before checking duration

* fix comment

* calculation based on transient field

* lint

* remove useless brackets
2024-09-03 19:47:00 +02:00
mvn23
8e03f3a045 Update opentherm_gw tests to avoid patching internals (#125152)
* Update tests to avoid patching internals

* * Use fixtures for tests
* Update variable names in tests for clarity

* Use hass.config_entries.async_setup instead of setup.async_setup_component
2024-09-03 19:19:43 +02:00
Raj Laud
8f26cff65a Enable strict typing for the Squeezebox integration (#125161)
* Strict typing for squeezebox

* Improve unit tests

* Refactor tests to use websockets and services.async_call

* Apply suggestions from code review

* Fix merge conflict
2024-09-03 19:19:30 +02:00
Alex Wijnholds
00533bae4b Add support for total YouTube views (#123144)
* Add support for retrieving the total views of a channel.

* Add missing tests

* Re-order imports

* Another run on code format

* Add missing translation

* Update YouTube test snapshots
2024-09-03 17:44:20 +02:00
Alexandre CUER
8255728f53 Migrate emoncms to config flow (#121336)
* Migrate emoncms to config flow

* tests coverage 98%

* use runtime_data

* Remove pyemoncms bump.

* Remove not needed yaml parameters add async_update_data to coordinator

* Reduce snapshot size

* Remove CONF_UNIT_OF_MEASUREMENT

* correct path in emoncms_client mock

* Remove init connexion check
as done by config_entry_first_refresh
since async_update_data catches exceptionand raise UpdateFailed

* Remove CONF_EXCLUDE_FEEDID from config flow

* Update homeassistant/components/emoncms/__init__.py

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

* Update homeassistant/components/emoncms/sensor.py

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

* Update homeassistant/components/emoncms/strings.json

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

* Use options in options flow and common strings

* Extend the ConfigEntry type

* Define the type explicitely

* Add data description in strings.json

* Update tests/components/emoncms/test_config_flow.py

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

* Update tests/components/emoncms/test_config_flow.py

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

* Add test import same yaml conf + corrections

* Add test user flow

* Use data_description...

* Use snapshot_platform in test_sensor

* Transfer all fixtures in conftest

* Add async_step_choose_feeds to ask flows to user

* Test abortion reason in test_flow_import_failure

* Add issue when value_template is i yaml conf

* make text more expressive in strings.json

* Add issue when no feed imported during migration.

* Update tests/components/emoncms/test_config_flow.py

* Update tests/components/emoncms/test_config_flow.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-03 17:21:13 +02:00
ollo69
470335e27a Add sensors for AsusWRT using http(s) library (#124337)
* Additional sensors for AsusWRT using http(s) library

* Remove temperature sensors refactor from PR

* Fix test function name

* Change translation a suggested

* Requested changes
2024-09-03 17:11:17 +02:00
Andrew Jackson
56887747a6 Bump aiomealie to 0.9.2 (#125153)
Bump mealie version
2024-09-03 17:09:26 +02:00
Erik Montnemery
1dcae0c0a6 Improve some comments in recorder tests (#125118) 2024-09-03 17:04:08 +02:00
Erik Montnemery
8759a6a14d Make optional arguments to frame.report kwarg only (#125062)
* Make optional arguments to frame.report kwarg only

* Update homeassistant/helpers/frame.py

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

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-09-03 17:03:36 +02:00
Hans Kröner
5d072d1030 Bump PyMetno to 0.13.0 (#125151) 2024-09-03 16:51:13 +02:00
Raj Laud
78517f75e8 Add favorites support to Media Browser for Squeezebox integration (#124732)
* Add Favorites support to Media Browser

* CI fixes

* More CI Fixes

* Another CI

* Change icons for other library items to use standard LMS icons

* Change max favorites to BROWSE_LIMIT

* Simplify library_payload to consolidate favorite and non-favorite items

* Simplify library_payload to consolidate favorite and non-favorite items

* Add support for favorite hierarchy

* small fix for icon naming with local albums

* Add ability to expand an album from a favorite list

* Reformat to fix linting error

* and ruff format

* Use library calls from pysqueezebox

* Folder and playback support

* Bump to pysqueezebox 0.8.0

* Bump pysqueezebox version to 0.8.1

* Add unit tests

* Improve unit tests

* Refactor tests to use websockets and services.async_call

* Apply suggestions from code review

---------

Co-authored-by: peteS-UK <64092177+peteS-UK@users.noreply.github.com>
2024-09-03 16:50:55 +02:00
MJJ
42ed7fbb0d Increase timeout for fetching buienradar weather data (#124597)
Increase timeout for fetching weather data
2024-09-03 16:50:30 +02:00
Michael
96be3e2505 Use SnapshotAssertion in more AVM Fritz!Box Tools tests (#125037)
use SnapshotAssertion in more tests
2024-09-03 16:39:06 +02:00
UltimateGG
2fa3b9070c Fix updating insteon modem configuration while disconnected (#121918)
#121917 Fix updating insteon modem configuration while disconnected
2024-09-03 16:31:48 +02:00
mvn23
d827c53a85 Remove opentherm_gw options migration (#125046) 2024-09-03 15:59:12 +02:00
G Johansson
436ac72b82 End deprecation setting attributes directly on config entry (#123729)
* End deprecation setting attr directly on config entry

* Update ollama test

* Fix android_tv
2024-09-03 15:56:00 +02:00
Martin Hjelmare
7c15075231 Clean up Z-wave error log when raising in service handlers (#125138) 2024-09-03 15:49:11 +02:00
S
8e3ad2d1f3 Extended epson projector integration to include serial connections (#121630)
* Extended epson projector integration to include serial connections

* Fix review changes

* Improve epson types and translations

* Fix comment

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2024-09-03 15:46:57 +02:00
dependabot[bot]
733bbf9cd1 Bump actions/upload-artifact from 4.3.6 to 4.4.0 (#125056)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.6 to 4.4.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4.3.6...v4.4.0)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-03 15:46:05 +02:00
Jakob Schlyter
822660732b Support setting Amazon Polly engine in service call (#120226) 2024-09-03 15:45:37 +02:00
Erik Montnemery
d6bd4312ab Add explaining comments in cv.template tests (#125081) 2024-09-03 15:34:31 +02:00
J. Nick Koston
491bde181c Speed up hassio send_command url check (#125122)
* Speed up hassio send_command url check

The send_command call checked the resulting path to make
sure that the input path was not modified when converting
to a URL. Since the host is is pre-set, we only need to check
the processed raw_path matches command instead of converting
back to a string, and than comparing it against another
constructed string.

* Speed up hassio send_command url check

The send_command call checked the resulting path to make
sure that the input path was not modified when converting
to a URL. Since the host is is pre-set, we only need to check
the processed raw_path matches command instead of converting
back to a string, and than comparing it against another
constructed string.

* adjust
2024-09-03 15:29:02 +02:00
Artur Pragacz
fdce524811 Add Onkyo Receiver class to improve typing (#124190) 2024-09-03 15:27:33 +02:00
Erik Montnemery
cf10549df4 Restore unnecessary assignment of Template.hass in event helper (#125143) 2024-09-03 15:25:35 +02:00
Marcel van der Veldt
fd01e22ca4 Fix energy sensor for ThirdReality Matter powerplug (#125140) 2024-09-03 15:24:49 +02:00
tronikos
334359bb0a Add Google Cloud Speech-to-Text (STT) (#120854)
* Google Cloud

* .

* fix

* mypy

* add tests

* Update .coveragerc

* Update const.py

* upload file, reconfigure and import flow

* fixes

* default to latest_short

* mypy

* update

* Allow clearing options in the UI

* update

* update

* update
2024-09-03 15:23:07 +02:00
Steven B.
eda1656e75 Abort ring config_flow if account is already configured (#125120)
* Abort ring config_flow if account is already configured

* Update tests/components/ring/test_config_flow.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-03 15:22:38 +02:00
Robert Resch
6cea6be4a7 Improve hassfest docker image (#125133)
* Improve hassfest docker image

* Use fixed uv version

* Use cli params instead env

* run hassfest

* Exclude pycache
2024-09-03 14:59:01 +02:00
Brett Adams
6ecc5c19a2 Add climate platform to Tesla Fleet (#123169)
* Add climate

* docstring

* Add tests

* Fix limited scope situation

* Add another test

* Add icons

* Type vehicle data

* Replace inline temperatures

* Fix handle_vehicle_command type

* Fix preset turning HVAC off

* Fix cop_mode check

* Use constants

* Reference docs in command signing error

* Move to a read-only check

* Remove raise_for

* Fixes

* Tests

* Remove raise_for_signing

* Remove unused strings

* Fix async_set_temperature

* Correct tests

* Remove HVAC modes at startup in read-only mode

* Fix order of init actions to set hvac_modes correctly

* Fix no temp test

* Add handle command type

* Docstrings

* fix matches and fix a bug

* Split tests

* Fix issues from rebase
2024-09-03 14:38:47 +02:00
Erik Montnemery
c321bd70e1 Log deprecation warning when cv.template is called from wrong thread (#125141)
Log deprecation warning when cv.template is called from wrong thread
2024-09-03 14:37:21 +02:00
Erik Montnemery
851600630c Log deprecation warning when template.Template is created without hass (#125142)
* Log deprecation warning when template.Template is created without hass

* Improve docstring
2024-09-03 14:28:33 +02:00
Michal Jál
e3896d1f60 Bump PySwitchbot to 0.48.2 (#125113) 2024-09-03 14:22:39 +02:00
Aaron Bach
c71cf272c8 Fix unhandled exception with missing IQVIA data (#125114) 2024-09-03 14:21:52 +02:00
Robert Resch
d12c6f89d2 Bump hadolint to 2.12.0 and use matrix for all Dockerfiles (#125131)
* Bump hadolint to 2.12.0 and use matrix for all Dockerfiles

* Fix

* Disable fail fast
2024-09-03 14:13:43 +02:00
Steven B.
5965d8d503 Pass hass clientsession to ring config flow (#125119)
Pass hass clientsession to ring config flow
2024-09-03 14:00:30 +02:00
ilan
94f458ff98 Bump py-madvr2 to 1.6.32 (#125049)
feat: update lib
2024-09-03 13:56:59 +02:00
Allen Porter
c07a9e9d59 Add dependency on google-photos-library-api: Change the Google Photos client library to a new external package (#125040)
* Change the Google Photos client library to a new external package

* Remove mime type guessing

* Update tests to mock out the client library and iterators

* Update homeassistant/components/google_photos/media_source.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-03 13:54:43 +02:00
Philip Vanloo
b9db9eeab2 Add Linkplay mTLS/HTTPS and improve logging (#124307)
* Work

* Implement 0.0.8 changes, fixup tests

* Cleanup

* Implement new playmodes, close clientsession upon ha close

* Implement new playmodes, close clientsession upon ha close

* Add test for zeroconf bridge failure

* Bump 0.0.9
Address old comments in 113940

* Exact _async_register_default_clientsession_shutdown
2024-09-03 13:34:47 +02:00
Christopher Fenner
f34b449f61 Correct device serial for ViCare integration (#125125)
* expose correct serial

* adapt inits

* adjust _build_entities

* adapt inits

* add serial data point

* update snapshot

* apply suggestions

* apply suggestions
2024-09-03 12:50:05 +02:00
Artur Pragacz
fc24843274 Fix Onkyo action select_hdmi_output (#125115)
* Fix Onkyo service select_hdmi_output

* Move Hasskey directly under Onkyo domain
2024-09-03 12:43:31 +02:00
Steven B.
22b6239304 Convert ring integration to use entry.runtime_data (#125127) 2024-09-03 12:04:35 +02:00
LG-ThinQ-Integration
aa8fe99113 Add binary_sensor platform to LG Thinq (#125054)
* Add binary_sensor entity

* Update the document link due to the domain name change

* Update casing

---------

Co-authored-by: jangwon.lee <jangwon.lee@lge.com>
2024-09-03 09:30:46 +02:00
Erik Montnemery
7c223db1d5 Remove recorder PostSchemaMigrationTask (#125076)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-09-03 07:51:27 +02:00
Jan Bouwhuis
0c18b2e7ff Remove is_on function from homeassistant.components (#125104)
* Remove `is_on` method from `homeassistant.components`

* Cleanup test
2024-09-03 06:57:25 +02:00
dontinelli
d68ee8dcea Replace _host_in_configuration_exists with async_abort_entries_match in solarlog (#125099)
* Add diagnostics to solarlog

* Fix wrong comment

* Move to async_abort_entries_match

* Remove obsolete method solarlog_entries

* Update tests/components/solarlog/test_config_flow.py

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

* Update tests/components/solarlog/test_config_flow.py

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

* Update tests/components/solarlog/test_config_flow.py

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

* Update tests/components/solarlog/test_config_flow.py

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

* Amend import of config_entries.SOURCE_USER

* Update tests/components/solarlog/test_config_flow.py

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

* Ruff

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-03 00:38:09 +02:00
cnico
671aaa7e95 Bump flipr api to 1.6.1 (#125106) 2024-09-02 23:51:10 +02:00
Álvaro Fernández Rojas
faefe624f6 Add Airzone Cloud Aidoo HVAC indoor/outdoor sensors (#125013)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2024-09-02 22:17:24 +02:00
J. Nick Koston
f93259a2f1 Bump yalexs to 8.6.0 (#125102) 2024-09-02 21:43:34 +02:00
Erik Montnemery
606524f9e7 Test string timestamps are wiped after migration to schema version 32 (#125091)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-09-02 21:33:35 +02:00
J. Nick Koston
cd89db9bb6 Add coverage for late unifiprotect person detection events (#125103) 2024-09-02 09:26:02 -10:00
Richard Kroegel
f760c13e8f Fix blocking calls for OpenAI conversation (#125010) 2024-09-02 09:23:38 -10:00
Martin Hjelmare
687cd32142 Handle telegram polling errors (#124327) 2024-09-02 09:23:24 -10:00
Artur Pragacz
fb27297df9 Fix area registry indexing when there is a name collision (#125050) 2024-09-02 09:23:07 -10:00
Avi Miller
3e350bdc90 Bump aiolifx to 1.0.9 and remove unused HomeKit model prefixes (#125055)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-09-02 09:22:39 -10:00
Erik Montnemery
0b14f0a379 Add test of statistics timestamp migration (#125100) 2024-09-02 09:13:26 -10:00
Maciej Bieniek
3206979488 Add separate entities for temperature, humidity and pressure in AccuWeather integration (#125041)
* Add temperature, humidity and pressure sensors

* Make uv index sensor disabled by default

* Fix type
2024-09-02 20:46:32 +02:00
Jan Bouwhuis
4c27bfbf7f Cleanup removed options for mqtt climate (#125083) 2024-09-02 20:35:36 +02:00
dontinelli
7c4fd9473c Add diagnostics to solarlog (#125072)
* Add diagnostics to solarlog

* Fix wrong comment
2024-09-02 20:08:44 +02:00
Paul Bottein
633c904852 Update frontend to 20240902.0 (#125093) 2024-09-02 20:04:33 +02:00
dontinelli
5300eddf33 Remove roundig in Solarlog and add suggested_display_precision (#125094)
* Remove roundig and add suggested_display_precision

* Add suggested_unit_of_measurement

* Put lamda in parentheses
2024-09-02 19:50:09 +02:00
Erik Montnemery
9f558d13e6 Correct start version in recorder schema migration tests (#125090)
* Correct start version in recorder schema migration tests

* Remove default from states.last_updated_ts
2024-09-02 19:32:01 +02:00
Steven B.
9ae59e5ea0 Bump ring-doorbell to 0.9.3 (#125087) 2024-09-02 18:18:45 +02:00
Steven B.
1b1c1c2a55 Call async_write_ha_state after ring update (#125096)
Use async_write_ha_state after ring update
2024-09-02 18:03:58 +02:00
Erik Montnemery
df4bd721b5 Deprecate template.attach (#124843) 2024-09-02 15:33:10 +02:00
Erik Montnemery
baa876d4d9 Remove lying comment from service.async_register_entity_service (#125079) 2024-09-02 15:18:02 +02:00
LG-ThinQ-Integration
b99dceab74 Do not LG thinq retry entry setup, when a single coordinator failed (#125052)
Do not retry entry setup, when a single coordinator failed.

Co-authored-by: jangwon.lee <jangwon.lee@lge.com>
2024-09-02 14:58:06 +02:00
Erik Montnemery
114e254aa6 Don't raise when registering entity service with invalid schema (#125057)
* Don't raise when registering entity service with invalid schema

* Update homeassistant/helpers/service.py

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

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2024-09-02 14:20:50 +02:00
Erik Montnemery
fbfd8c48aa Remove unused event from recorder (#125067) 2024-09-02 13:33:51 +02:00
tronikos
d40e3145fe Setup Google Cloud from the UI (#121502)
* Google Cloud can now be setup from the UI

* mypy

* Add BaseGoogleCloudProvider

* Allow clearing options in the UI

* Address feedback

* Don't translate Google Cloud title

* mypy

* Revert strict typing changes

* Address comments
2024-09-02 04:30:18 -07:00
tronikos
f4a16c8dc9 Add strict typing in Google Cloud (#125068) 2024-09-02 04:07:12 -07:00
Nidre
2ce6bd2378 Update Matter light transition blocklist to include YNDX LightStrip (#124657) 2024-09-02 12:28:49 +02:00
J. Nick Koston
9334099bed Bump habluetooth to 3.4.0 (#125058)
changelog: https://github.com/Bluetooth-Devices/habluetooth/compare/v3.3.2...v3.4.0
2024-09-02 11:28:42 +02:00
dontinelli
077edb08f6 Bump fyta_cli to 0.6.6 (#125065) 2024-09-02 11:27:31 +02:00
epenet
72d5146a3e Improve renault tests (#125064) 2024-09-02 10:46:35 +02:00
tronikos
fa14321aa1 Bump androidtvremote2 to 0.1.2 to fix blocking event loop when loading ssl certificate chain (#125061)
Bump androidtvremote2 to 0.1.2
2024-09-02 01:41:29 -07:00
Erik Montnemery
8f679fcbf3 Fix motionblinds_ble tests (#125060) 2024-09-02 09:51:05 +02:00
G Johansson
78cf7dc873 New template merge_response (#114204)
* New template merge_response

* Extending

* Extend comment

* Update

* Fixes

* Fix comments

* Mods

* snapshots

* Fixes from discussion
2024-09-02 08:13:10 +02:00
Allen Porter
9fff3a13a5 Clarify comment in google photos upload service (#125042) 2024-09-01 21:49:38 -07:00
Shay Levy
99f43400bf Bump aioshelly to 11.4.2 (#125036) 2024-09-01 11:08:19 -10:00
J. Nick Koston
77b464f2bd Bump yarl to 1.9.7 (#125035) 2024-09-01 10:47:24 -10:00
Michael
07e251d488 Add diagnostics platform to modern forms (#125032) 2024-09-01 22:04:29 +02:00
dontinelli
659d135fca Add ConductivityConverter in websocket_api.py (#125029) 2024-09-01 21:02:32 +02:00
Álvaro Fernández Rojas
24414369d7 Update aioairzone-cloud to v0.6.5 (#125030)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2024-09-01 21:28:13 +03:00
Etienne Soufflet
92c1fb77e9 Fix Tado fan speed for AC (#122415)
* change capabilities

* fix tests 2

* improve usability with capabilities

* fix swings management

* Update homeassistant/components/tado/climate.py

Co-authored-by: Erwin Douna <e.douna@gmail.com>

* fix after Erwin's review

* fix after joostlek's review

* use constant

* use in instead of get

---------

Co-authored-by: Erwin Douna <e.douna@gmail.com>
2024-09-01 18:33:45 +02:00
Martin Hjelmare
ae1f53775f Bump python-telegram-bot to 21.5 (#125025) 2024-09-01 17:51:31 +02:00
Dmitry Krasnoukhov
bd6b5568eb Extend hjjcy device category in Tuya integration (#124854)
* Extend hjjcy device category in Tuya integration

* Better AQI level names
2024-09-01 17:50:53 +02:00
Malte Franken
5f2964d3e8 Bump aio-georss-gdacs to 0.10 (#125021)
bump aio-georss-gdacs to 0.10
2024-09-01 17:38:48 +02:00
Joost Lekkerkerker
c6865d0862 Bump aiomealie to 0.9.1 (#125017) 2024-09-01 17:37:06 +02:00
Richard Kroegel
ef8fc3913e Fix ollama blocking on load_default_certs (#125012)
* Fix ollama blocking on load_default_certs

* Use get_default_context instead of client_context
2024-09-01 17:35:55 +02:00
mvn23
56667ec2bc Migrate opentherm_gw climate entity unique_id (#125024)
* Migrate climate entity unique_id to match the format used by other opentherm_gw entities
* Add test to verify migration
2024-09-01 17:22:03 +02:00
Richard Kroegel
fa21613951 Fix telegram_bot blocking on load_default_certs (#125014)
* Fix telegram_bot blocking on load_default_certs

* Use sync variant of create_issue
2024-09-01 17:13:04 +02:00
Richard Kroegel
f735d12a66 Fix BMW client blocking on load_default_certs (#125015)
* Fix BMW client blocking load_default_certs

* Use get_default_context
2024-09-01 16:26:14 +02:00
mvn23
2f7a396778 Split opentherm_gw entities between different devices (#124869)
* * Add migration from single device to multiple devices, removing all old entities
* Create new devices for Boiler and Thermostat
* Add classes for new entities based on the new devices

* Split binary_sensor entities into devices

* Split sensor entities into different devices

* Move climate entity to thermostat device

* Fix climate entity away mode

* Fix translation placeholders

* Allow sensor values with capital letters

* * Add EntityCategory
* Update and add device_classes

* Fix translation keys

* Fix climate entity category

* Update tests

* Handle `available` property in `entity.py`

* Improve GPIO state binary_sensor translations

* Fix: Updates are already subscribed to in the base entity

* Remove entity_id generation from sensor and binary_sensor entities

* * Use _attr_name on climate class instead of through entity_description
* Add type hints

* Rewrite to derive entities for all OpenTherm devices from a single base class

* Improve type annotations

* Use OpenThermDataSource to access status dict

* Move entity_category from entity_description to _attr_entity_category

* Move entity descriptions with the same translation_key closer together

* Update tests

* Add device migration test

* * Add missing sensors and binary_sensors back
* Improve migration, do not delete old entities from registry

* Add comments for migration period

* Use single lists for entity descriptions

* Avoid changing sensor values, remove translations

* * Import only required class from pyotgw
* Update tests
2024-09-01 13:28:08 +02:00
Jeef
12336f5c15 Bump Intellifire to 4.1.9 (#121091)
* rebase

* Minor patch to fix duplicate DeviceInfo beign created - if data hasnt updated yet

* rebase

* Minor patch to fix duplicate DeviceInfo beign created - if data hasnt updated yet

* fixing formatting

* Update homeassistant/components/intellifire/__init__.py

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

* Update homeassistant/components/intellifire/__init__.py

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

* Removing cloud connectivity sensor - leaving local one in

* Renaming class to something more useful

* addressing pr

* Update homeassistant/components/intellifire/__init__.py

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

* add ruff exception

* Fix test annotations

* remove access to private variable

* Bumping to 4.1.9 instead of 4.1.5

* A renaming

* rename

* Updated testing

* Update __init__.py

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

* updateing styrings

* Update tests/components/intellifire/conftest.py

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

* Testing refactor - WIP

* everything is passing - cleanup still needed

* cleaning up comments

* update pr

* unrename

* Update homeassistant/components/intellifire/coordinator.py

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

* fixing sentence

* fixed fixture and removed error codes

* reverted a bad change

* fixing strings.json

* revert renaming

* fix

* typing inother pr

* adding extra tests - one has a really dumb name

* using a real value

* added a migration in

* Update homeassistant/components/intellifire/config_flow.py

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

* Update tests/components/intellifire/test_init.py

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

* cleanup continues

* addressing pr

* switch back to debug

* Update tests/components/intellifire/conftest.py

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

* some changes

* restore property mock cuase didnt work otherwise

* cleanup has begun

* removed extra text

* addressing pr stuff

* fixed reauth

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-09-01 12:48:38 +02:00
dontinelli
1661304f10 Bump solarlog_cli to 0.2.2 (#124948)
* Add inverter-devices

* Minor code adjustments

* Update manifest.json

Seperate dependency upgrade to seperate PR

* Update requirements_all.txt

Seperate dependency upgrade to seperate PR

* Update requirements_test_all.txt

Seperate dependency upgrade to seperate PR

* Update homeassistant/components/solarlog/sensor.py

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

* Split up base class, document SolarLogSensorEntityDescription

* Split up sensor types

* Update snapshot

* Bump solarlog_cli to 0.2.1

* Add strict typing

* Bump fyta_cli to 0.6.3 (#124574)

* Ensure write access to hassrelease data folder (#124573)

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

* Update a roborock blocking call to be fully async (#124266)

Remove a blocking call in roborock

* Add inverter-devices

* Split up sensor types

* Update snapshot

* Bump solarlog_cli to 0.2.1

* Backport/rebase

* Tidy up

* Simplyfication coordinator.py

* Minor adjustments

* Ruff

* Bump solarlog_cli to 0.2.2

* Update homeassistant/components/solarlog/sensor.py

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

* Update homeassistant/components/solarlog/config_flow.py

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

* Update homeassistant/components/solarlog/sensor.py

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

* Update persentage-values in fixture

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Allen Porter <allen@thebends.org>
2024-09-01 12:47:52 +02:00
Álvaro Fernández Rojas
68162e1a27 Update aioairzone-cloud to v0.6.4 (#125007)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2024-09-01 12:45:59 +02:00
Bill Flood
95a25c72dc Use constant for default medium type in Mopeka (#125002)
- Updated the Mopeka BLE device setup to use const
  DEFAULT_MEDIUM_TYPE
- Fix Spelling error in a coment
2024-09-01 07:12:24 +02:00
Allen Porter
30772da0e1 Add Google Photos media source support for albums and favorites (#124985) 2024-08-31 14:39:18 -07:00
Allen Porter
ef84a8869e Add Google Photos service for uploading content (#124956)
* Add Google Photos upload support

* Fix format

* Merge in scope/reauth changes

* Address PR feedback

* Fix blocking i/o in async
2024-08-31 21:16:14 +02:00
Allen Porter
d3879a36d1 Add loggers for Google Photos integration (#124986) 2024-08-31 21:11:22 +02:00
Allen Porter
93afc9458a Update nest to only include the image attachment payload for cameras that support fetching media (#124590)
Only include the image attachment payload for cameras that support fetching media
2024-08-31 11:38:45 -07:00
Marc Mueller
5cd8e4ab7e Update mypy-dev to 1.12.0a3 (#124939)
* Update mypy-dev to 1.12.0a3

* Fix
2024-08-31 19:34:41 +02:00
Álvaro Fernández Rojas
994c2ebca1 Update aioairzone-cloud to v0.6.3 (#124978)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2024-08-31 17:30:58 +02:00
Allen Porter
81f5068354 Clean up Google Photos media source (#124977)
* Clean up Google Photos media source

* Fix typo

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-08-31 08:22:50 -07:00
Brett Adams
3e60d7aa11 Small code quality fix in Teslemetry (#124603)
* Fix cop_mode logic bug

* Update climate.py

* Fix attributes
2024-08-31 07:41:00 -07:00
Joost Lekkerkerker
30aa3a26ad Merge coordinators in Airgradient (#124714) 2024-08-31 07:40:12 -07:00
epenet
9da5dd0090 Improve config flow type hints in cast (#124861) 2024-08-31 07:38:06 -07:00
Brett Adams
65f007ace7 Remove HVAC Modes when no scopes in Teslemetry (#124612)
* Remove modes when not scoped

* Fix inits

* Re-add raise

* Remove unused raise_for_scope

* Set hvac_modes when not scoped

* tests
2024-08-31 07:28:35 -07:00
Joost Lekkerkerker
2a8feda691 Define household support in Mealie (#124950) 2024-08-31 12:00:12 +02:00
Andre Lengwenus
36b7e8569e Send entity name or original name to LCN frontend (#124518)
* Send name or original name to frontend

* Use walrus operator

* Fix docstring

* Fix mutated config_entry.data
2024-08-31 11:42:22 +02:00
Alan Murray
221f961574 Bump aiopulse to 0.4.6 (#124964)
Non-breaking changes to fix isses:
 * eliminating hub exceptions raised due use of unicode strings.
 * eliminating hub exceptions raised due to Timers being configured on hub.
2024-08-31 11:33:58 +02:00
J. Nick Koston
7210cc1da6 Bump yarl to 1.9.6 (#124955)
* Bump yarl to 1.9.5

changelog: https://github.com/aio-libs/yarl/compare/v1.9.4...v1.9.5

* remove default port since mocker does exact matching and yarl now normalizes this

* 1.9.6
2024-08-31 11:03:08 +02:00
vhkristof
5fa23b1785 Bump renault-api to v0.2.7 (#124858)
* Bump renault-api to v0.2.7

* Updated requirements_all and requirements_test_all
2024-08-31 10:56:23 +02:00
Allen Porter
2cab9f7fe9 Address additional Google Photos integration feedback (#124957)
* Address review feedback

* Fix typing for  arguments
2024-08-31 10:10:45 +02:00
J. Nick Koston
3bfcb1ebdd Restore sisyphus integration (#124749)
* Revert "Disable sisyphus integration (#124742)"

This reverts commit 1b304e60d9.

* Restore sisyphus integration

reverts #124742 and updates the lib instead

changelog: https://github.com/jkeljo/sisyphus-control/compare/v3.1.3...v3.1.4

release is pending: https://github.com/jkeljo/sisyphus-control/pull/8#issuecomment-2313893689
2024-08-31 10:07:36 +02:00
Allen Porter
c1eb5f8b74 Fix Google Photos get media calls (#124958) 2024-08-31 10:01:51 +02:00
Allen Porter
582b7eab66 Add missing translation for Google Photos reauth (#124959) 2024-08-31 10:01:27 +02:00
Alex Yao
26281662b5 Enable config flow for html5 (#112806)
* html5: Enable config flow

* Add tests

* attempt check create_issue

* replace len with call_count

* fix config flow tests

* test user config

* more tests

* remove whitespace

* Update homeassistant/components/html5/issues.py

Co-authored-by: Steven B. <51370195+sdb9696@users.noreply.github.com>

* Update homeassistant/components/html5/issues.py

Co-authored-by: Steven B. <51370195+sdb9696@users.noreply.github.com>

* fix config

* Adjust issues log

* lint

* lint

* rename create issue

* fix typing

* update codeowners

* fix test

* fix tests

* Update issues.py

* Update tests/components/html5/test_config_flow.py

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

* Update tests/components/html5/test_config_flow.py

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

* Update tests/components/html5/test_config_flow.py

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

* update from review

* remove ternary

* fix

* fix missing service

* fix tests

* updates

* adress review comments

* fix indent

* fix

* fix format

* cleanup from review

* Restore config schema and use HA issue

* Restore config schema and use HA issue

---------

Co-authored-by: alexyao2015 <alexyao2015@users.noreply.github.com>
Co-authored-by: Steven B. <51370195+sdb9696@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-08-30 23:22:14 +02:00
Joost Lekkerkerker
ac39bf991f Rename lg_thinq domain name (#124926) 2024-08-30 22:34:34 +02:00
J. Nick Koston
0a9e20615e Limit maximum template render output to 256KiB (#124946)
* Limit maximum template render output to 256KiB

fixes #124931

256KiB is likely to still block the event loop for an unreasonable amont of
time but its likely someone is using the template engine for large
blocks of data so we want a limit which still allows that but has
a reasonable safety to prevent the system from crashing down

* Update homeassistant/helpers/template.py
2024-08-30 22:33:57 +02:00
J. Nick Koston
8cafa1bcdf Bump google-generativeai to 0.7.2 (#124940)
changelog: https://github.com/google-gemini/generative-ai-python/compare/v0.6.0...v0.7.2
2024-08-30 22:33:26 +02:00
J. Nick Koston
66ddf44399 Bump google-cloud-pubsub to 2.23.0 (#124937)
changelog: https://github.com/googleapis/python-pubsub/compare/v2.13.11...v2.23.0
2024-08-30 22:32:23 +02:00
J. Nick Koston
933ae143b3 Bump google-cloud-texttospeech to 2.17.2 (#124938)
changelog: https://github.com/googleapis/google-cloud-python/compare/google-cloud-texttospeech-v2.16.3...google-cloud-texttospeech-v2.17.2
2024-08-30 22:32:09 +02:00
Joost Lekkerkerker
8c2e63807c Make set_value required in number template (#124917)
* Make set_value required in number template

* Make set_value required in number template

* Fix tests
2024-08-30 22:02:10 +02:00
J. Nick Koston
460363c4ba Bump aioshelly to 11.4.1 to accomodate shelly GetStatus calls that take a few seconds to respond (#124893)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2024-08-30 09:05:16 -10:00
Steven B.
29a17edaa5 Exclude tplink firmware entities (#124935)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-08-30 08:56:30 -10:00
Steven B.
ed161d3d49 Bump python-kasa to 0.7.2 (#124930) 2024-08-30 08:43:28 -10:00
Louis Christ
7868ffac35 Enable strict typing checking for bluesound integration (#123821)
* Enable strict typing

* Fix types

* Update to pyblu 0.5.2 for typing support

* Update pyblu to 1.0.0

* Update pyblu to 1.0.1

* Update error handling

* Fix tests

* Remove return None from methods only returning None
2024-08-30 20:21:27 +02:00
tronikos
910fb0930e Attempt to fix IndexError in Opower (#124478)
* Change the order of async_add_external_statistics in Opower

* Use consumption_statistic_id instead of cost_statistic_id
2024-08-30 08:34:27 -07:00
Allen Porter
cb742a677c Add Google Photos reauth support (#124933)
* Add Google Photos reauth support

* Update tests/components/google_photos/test_config_flow.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-30 17:31:24 +02:00
IceBotYT
28c24e5fef Bump nice-go to 0.3.8 (#124872)
* Bump nice-go to 0.3.6

* Bump to 0.3.7

* Bump to 0.3.8
2024-08-30 17:08:58 +02:00
Mr. Bubbles
50577883dc Add option to login with username/email and password in Habitica integration (#117622)
* add login/password authentication

* add advanced config flow

* remove unused exception classes, fix errors

* update username in init

* update tests

* update strings

* combine steps with menu

* remove username from entry

* update tests

* Revert "update tests"

This reverts commit 6ac8ad6a26547b623e217db817ec4d0cf8c91f1d.

* Revert "remove username from entry"

This reverts commit d9323fb72df3f9d41be0a53bb0cbe16be718d005.

* small changes

* remove pylint broad-excep

* run habitipy init in executor

* Add text selectors

* changes
2024-08-30 17:08:06 +02:00
dontinelli
20f9b9e412 Add inverter-devices to solarlog (#123205)
* Add inverter-devices

* Minor code adjustments

* Update manifest.json

Seperate dependency upgrade to seperate PR

* Update requirements_all.txt

Seperate dependency upgrade to seperate PR

* Update requirements_test_all.txt

Seperate dependency upgrade to seperate PR

* Update homeassistant/components/solarlog/sensor.py

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

* Split up base class, document SolarLogSensorEntityDescription

* Split up sensor types

* Update snapshot

* Add all devices in config_flow

* Remove options flow

* Move devices in config_entry from options to data

* Correct mock_config_entry

* Minor adjustments

* Remove enabled_devices from config

* Remove obsolete test

* Update snapshot

* Delete obsolete code snips

* Update homeassistant/components/solarlog/sensor.py

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

* Remove obsolete test in setting up sensors

* Update homeassistant/components/solarlog/sensor.py

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

* Update homeassistant/components/solarlog/entity.py

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

* Update homeassistant/components/solarlog/config_flow.py

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

* Fix typing error

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-30 17:03:24 +02:00
Aidan Timson
1d05a917f9 Add work items per type and state counter sensors to Azure DevOps (#119737)
* Add work item data

* Add work item sensors

* Add icon

* Add test fixtures

* Add none return tests

* Apply suggestions from code review

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

* Apply suggestion

* Use icon translations

* Apply suggestions from code review

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

* Update test

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-30 16:45:46 +02:00
Joost Lekkerkerker
240bd6c3bf Bump aiomealie to 0.9.0 (#124924)
* Bump aiomealie to 0.9.0

* Bump aiomealie to 0.9.0
2024-08-30 16:41:48 +02:00
Allen Porter
c01bb44757 Add Google Photos integration (#124835)
* Add Google Photos integration

* Mark credentials typing

* Add code review suggestions to simpilfy google_photos

* Update tests/components/google_photos/conftest.py

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

* Apply suggestions from code review

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

* Fix comment typo

* Update test fixtures from review feedback

* Remove unnecessary test for services

* Remove keyword argument

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-30 07:27:19 -07:00
TimL
5e93394ae7 Ensure smilight fixtures select correct platform for tests (#124305)
* Fix return type hint for setup_integration

* Ensure platform fixture selects tested platform
2024-08-30 16:25:30 +02:00
starkillerOG
a8b55a16fd Add 100% coverage of Reolink host.py (#124577)
* Add 100% host test coverage

* Add missing test
2024-08-30 16:24:27 +02:00
LG-ThinQ-Integration
d7fb245213 Add LG ThinQ Integration (#123860)
* Add manifest.json

* add switch entity

* Add tests

* fix function's name

* adjust the changes after running scipt

* Update homeassistant/components/lgthinq/__init__.py

Accept the suggested change about format.

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

* Update homeassistant/components/lgthinq/__init__.py

Accept suggested change for log removal

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

* Delete homeassistant/components/lgthinq/services.yaml

* Update homeassistant/components/lgthinq/switch.py

Accpet suggested change for log removal

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

* Update homeassistant/components/lgthinq/strings.json

Accept suggested change for service removal

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

* Update homeassistant/components/lgthinq/manifest.json

Accept suggested change for spaces removal

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

* Delete homeassistant/components/lgthinq/icons.json

* Update __init__.py

Remove unnecessary check code

* Modification to pass ruff-format

* Modification for mypy issues

* Remove service registry and related code

* Update strings.json

Modification to pass the prettier issues

* Update manifest.json

Modification to pass the prettier issues

* Update homeassistant/components/lgthinq/__init__.py

Remove the unnecessary log.

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

* Update homeassistant/components/lgthinq/__init__.py

Remove unnecessary log.

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

* Update homeassistant/components/lgthinq/__init__.py

Remove unnecessary code.

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

* Update homeassistant/components/lgthinq/__init__.py

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

* Modifications for the review and related autocheck

* Update homeassistant/components/lgthinq/config_flow.py

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

* Update homeassistant/components/lgthinq/config_flow.py

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

* Modifications for reviews and autocheck

* Modifications for the reviews and autocheck

* Update homeassistant/components/lgthinq/const.py

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

* Update homeassistant/components/lgthinq/const.py

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

* Update homeassistant/components/lgthinq/const.py

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

* Update homeassistant/components/lgthinq/device.py

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

* Update homeassistant/components/lgthinq/device.py

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

* Remove type definition after Final

* Update const.py

Do not use Final for DOMAIN

* Refactoring for reviews
- remove thinq.py
- remove type definition
- remove entry name in config flow
- put config flow steps into a single step

* Update tests
- remove region

* Refactoring for reviews
- move property.py into PyPI library
- replace error_code handling with try/catch
- remove http response handling
- remove generic
- remove unnecessary class or map instance
- refactor adding entities logic

* Refactoring
- remove unused code
- change import path

* Update tests

* Refactoring for reviews
1. Use coordinator extended class instead of LGDevice
2. Rename entity_helper.py to entity.py
3. Move entity description to each entity file
4. Remove dynamic device creation code

* Refactoring for reviews

* Update requirements

* Fix for reviews

* Modify tests for reviews

* Update for reviews

* Remove property info and description class

* Update tests/components/lgthinq/test_config_flow.py

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

* Update tests/components/lgthinq/test_config_flow.py

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

* Update homeassistant/components/lgthinq/entity.py

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

* Update homeassistant/components/lgthinq/switch.py

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

* Update tests/components/lgthinq/test_config_flow.py

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

* Update for reviews

* Update homeassistant/components/lgthinq/switch.py

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

* Update homeassistant/components/lgthinq/switch.py

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

* Update for reviews

* Fix ruff issues

* Fix ruff check

* Fix for reviews

* Fix ruff check

* Fix for reviews

* Fix prettier failure and hassfest failure

---------

Co-authored-by: Jangwon Lee <jangwon.lee@lge.com>
Co-authored-by: yunseon.park <yunseon.park@lge.com>
Co-authored-by: nahyun.lee <nahyun.lee@lge.com>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-30 15:12:49 +02:00
puddly
6467c8d611 Bump ZHA to 0.0.32 (#124804)
* Always prefer XY color mode in ZHA

Remove a few more HS remnants

* Use new ZHA OTA format

* Bump ZHA to 0.0.32

* Fix existing OTA unit tests

* Fix schema conversion test to account for new command parameters

* Update snapshot with new `zcl_type` kwarg

* Migrate existing entities to icon translations

* Remove "no longer compatible" test

* Test that the library release summary is correctly exposed to ZHA

* Revert "Always prefer XY color mode in ZHA"

This reverts commit 8fb7789ea8ddb6ed2a287aed5010374c0452f6c9.

* Test `release_notes`, not `release_summary`
2024-08-30 14:48:09 +02:00
Robert Svensson
c47b37af4f Use snapshot in Axis camera tests (#122677) 2024-08-30 14:40:28 +02:00
starkillerOG
a5bacf5652 Add 100% coverage of Reolink switch platform (#124482)
* Add 100% switch test coverage

* use DOMAIN instead of const.DOMAIN

* Split tests and use parametrize

* Revert "Split tests and use parametrize"

This reverts commit 50d2184ce67b1ac95bd1517cb4963707f9c7954a.

* fixes
2024-08-30 14:39:12 +02:00
starkillerOG
6589216ed3 Add 100% coverage of Reolink camera platform (#124381)
* Add 100% camera test coverage

* review comments

* use DOMAIN instead of const.DOMAIN

* use entity_registry_enabled_by_default fixture

* fixes
2024-08-30 14:34:49 +02:00
starkillerOG
b6dc410464 Add 100% coverage of Reolink light platform (#124382)
* Add 100% light test coverage

* review comments

* fix

* use STATE_ON

* split tests
2024-08-30 14:34:17 +02:00
starkillerOG
928ff7c78c Add 100% coverage of Reolink sensor platform (#124472)
* Add 100% sensor test coverage

* use DOMAIN instead of const.DOMAIN

* snake_case

* better split tests

* styling

* Use entity_registry_enabled_by_default fixture
2024-08-30 14:32:57 +02:00
tdfountain
c9335598db Alphabetize keys list for nut sensor icons (#124188)
Alphabetize keys list for sensor icons
2024-08-30 14:32:32 +02:00
Jeef
32babd3958 Clean up Weatherflow Cloud (#124643)
cleanup
2024-08-30 13:32:07 +02:00
shapournemati-iotty
7f405686d1 Add shapournemati to iotty codeowners (#123649)
* add shapournemati to codeowners for improved support

* update codeowners with hassfest script

* update codeowners with hassfest script
2024-08-30 13:30:56 +02:00
Lektri.co
5bd736029f Add lektrico integration (#102371)
* Add Lektrico Integration

* Make the changes proposed by Lash-L: new coordinator.py, new entity.py; use: translation_key, last_update_sucess, PlatformNotReady; remove: global variables

* Replace FlowResult with ConfigFlowResult and add tests.

* Remove unused lines.

* Remove Options from condif_flow

* Fix ruff and mypy.

* Fix CODEOWNERS.

* Run python3 -m script.hassfest.

* Correct rebase mistake.

* Make modifications suggested by emontnemery.

* Add pytest fixtures.

* Remove meaningless patches.

* Update .coveragerc

* Replace CONF_FRIENDLY_NAME with CONF_NAME.

* Remove underscores.

* Update tests.

* Update test file with is and no config_entries. .

* Set serial_number in DeviceInfo and add return type of the async_update_data to DataUpdateCoordinator.

* Use suggested_unit_of_measurement for KILO_WATT and replace Any in value_fn (sensor file).

* Add device class duration to charging_time sensor.

* Change raising  PlatformNotReady to raising IntegrationError.

* Test the unique id of the entry.

* Rename PF Lx with Power factor Lx and remove PF from strings.json.

* Remove comment.

* Make state and limit reason sensors to be enum sensors.

* Use result variable to check unique_id in test.

* Remove CONF_NAME from entry and __init__ from LektricoFlowHandler.

* Remove session parameter from LektricoDeviceDataUpdateCoordinator.

* Use config_entry: ConfigEntry in coordinator.

* Replace Connected,NeedAuth with Waiting for Authentication.

* Use lektricowifi 0.0.29.

* Use lektricowifi 0.0.39

* Use lektricowifi 0.0.40

* Use lektricowifi 0.0.41

* Replace hass.data with entry.runtime_data

* Delete .coveragerc

* Restructure the user step

* Fix tests

* Add returned value of _async_update_data to class DataUpdateCoordinator

* Use hw_version at DeviceInfo

* Remove a variable

* Use StateType

* Replace friendly_name with device_name

* Use sentence case in translation strings

* Uncomment and fix test_discovered_zeroconf

* Add type LektricoConfigEntry

* Remove commented code

* Remove the type of coordinator in sensor async_setup_entry

* Make zeroconf test end in ABORT, not FORM

* Remove all async_block_till_done from tests

* End test_user_setup_device_offline with CREATE_ENTRY

* Patch the full Device

* Add snapshot tests

* Overwrite the type LektricoSensorEntityDescription outside of the constructor

* Test separate already_configured for zeroconf

---------

Co-authored-by: mihaela.tarjoianu <mihaela.tarjoianu@scada.ro>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-08-30 13:20:15 +02:00
Robert Resch
397198c6d0 Optimize hassfest image (#124855)
* Optimize hassfest docker image

* Adjust CI

* Use dynamic uv version

* Remove workaround
2024-08-30 13:09:10 +02:00
Michael Arthur
54188b4128 Add returning activity to Husqvarna lawn mower (#124511)
* add returning activity to husqvarna lawn mower

* Update test, fix bug with comparison operator
2024-08-30 12:59:13 +02:00
Jeef
f3da9de744 Bump weatherflow4py to 0.2.23 (#124072)
patch weatherflow for new data
2024-08-30 12:45:08 +02:00
Raj Laud
aeb95c4509 Bump pysqueezebox to v0.8.1 (#124856) 2024-08-30 12:43:29 +02:00
Louis Christ
f394dfb8d0 Handle CancelledError in bluesound integration (#124873)
Catch CancledError in async_will_remove_from_hass
2024-08-30 11:38:07 +02:00
J. Nick Koston
6781a76de2 Speed up ssdp domain matching (#124842)
* Speed up ssdp domain matching

Switch all() expression to dict.items() <= dict.items()

* rewrite as setcomp
2024-08-30 11:36:31 +02:00
epenet
69a9aa4594 Improve type hints in icloud config flow (#124900) 2024-08-30 11:25:58 +02:00
epenet
afa02dcce9 Improve type hints in growatt_server config flow (#124901) 2024-08-30 11:25:29 +02:00
epenet
febb382030 Improve type hints in hvv_departures config flow (#124902) 2024-08-30 11:25:08 +02:00
epenet
1906155c18 Improve type hints in mobile_app config flow (#124906) 2024-08-30 11:24:34 +02:00
epenet
ffabd5d7db Improve type hints in konnected config flow (#124904) 2024-08-30 11:24:06 +02:00
Christopher Fenner
9e2360791d Add hot water target temp number entity in ViCare integration (#123633)
* add DHW target temp number entity

* Update number.py

* Update strings.json

* Update strings.json

* update test snapshot

* fix snapshot
2024-08-30 11:22:48 +02:00
epenet
19cbc1b258 Improve type hints in plex config flow (#124914) 2024-08-30 11:22:07 +02:00
epenet
df2ea1e875 Improve type hints in nina config flow (#124910)
* Improve type hints in nina config flow

* Apply suggestions from code review

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-30 11:21:05 +02:00
epenet
74fa30e59d Improve config flow type hints (g-m) (#124907) 2024-08-30 11:05:18 +02:00
epenet
6833af6286 Improve config flow type hints (n-p) (#124909) 2024-08-30 11:04:58 +02:00
Josef Zweck
4940968cd5 Bump lmcloud 1.2.2 (#124911)
bump lmcloud 1.2.2
2024-08-30 11:02:29 +02:00
dependabot[bot]
a9975071c3 Bump actions/setup-python from 5.1.1 to 5.2.0 (#124899)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.1.1 to 5.2.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.1.1...v5.2.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-30 10:53:06 +02:00
Christopher Fenner
cc4340b80c Remove update call from init in ViCare integration (#124905)
fix
2024-08-30 10:50:18 +02:00
Willem-Jan van Rootselaar
252f05e0f7 Update diagnostics for BSBLan (#124508)
* update diagnostics to include static

and make room for multiple coordinator data objects

* fix mac address is not stored in config_entry but on device
2024-08-30 10:41:07 +02:00
dependabot[bot]
f5e0382123 Bump github/codeql-action from 3.26.5 to 3.26.6 (#124898)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.5 to 3.26.6.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3.26.5...v3.26.6)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-30 10:29:25 +02:00
Josef Zweck
600c6a0dcb Bump lmcloud to 1.2.1 (#124908) 2024-08-30 10:05:28 +02:00
J. Nick Koston
df60e59a95 Address yale review comments part 2 (#124887)
* Remove some unneeded block till done

* Additional state check cleanups and snapshots

* Use more snapshots in yale tests
2024-08-30 09:37:19 +02:00
J. Nick Koston
cf90e77e57 Add a repair issue for Yale Home users using the August integration (#124895)
The Yale Home brand will stop working with the August integration very
soon. Users must migrate to the Yale integration to avoid an interruption in service.
2024-08-30 09:35:19 +02:00
J. Nick Koston
3e0bd44d2a Bump aioesphomeapi to 25.3.1 (#124890)
changelog: https://github.com/esphome/aioesphomeapi/compare/v25.2.1...v25.3.1
2024-08-29 16:19:12 -10:00
Erik Montnemery
7bb93d4f3e Deduplicate warning messages in recorder DB migration (#124845) 2024-08-29 19:05:27 -07:00
Tony
4dfc11a140 Bump aioruckus to v0.41 removing blocking call to load_default_certs from ruckus_unleashed integration (#123974)
* fix ruckusd_unleashed blocking call to load_default_certs

* remove extra loggers, bump aioruckus ver for debian packagers
2024-08-29 19:03:51 -07:00
TheJulianJES
7eeebf198b Fix ZHA group removal entity registry cleanup (#124889)
* Fix ZHA cleanup entity registry parameter

* Fix missing `gateway` when accessing coordinator device

* Get `ZHADeviceProxy` for coordinator device
2024-08-29 20:13:47 -04:00
J. Nick Koston
175ffe29f6 Bump yalexs to 8.5.5 (#124891)
changelog: https://github.com/bdraco/yalexs/compare/v8.5.4...v8.5.5
2024-08-30 01:07:21 +02:00
Michael Hansen
ff9937f942 Bump intents to 2024.8.29 (#124874) 2024-08-29 13:29:11 -05:00
Robert Resch
ef452427e3 Bump PyTurboJPEG to 1.7.5 (#124865) 2024-08-29 19:34:19 +02:00
J. Nick Koston
a04970bd54 Address august review comments (#124819)
* Address august review comments

Followup to https://github.com/home-assistant/core/pull/124677

* cleanup loop

* drop mixin name

* event entity add cleanup

* remove duplicate prop

* pep0695 type

* remove some not needed block till done

* cleanup august tests

* switch to freezegun

* snapshots for dev reg

* SOURCE_USER nit

* snapshots

* pytest.raises

* not loaded check
2024-08-29 19:32:13 +02:00
Joost Lekkerkerker
149aebb0bc Add missing translation key in Knocki (#124862) 2024-08-29 17:25:04 +02:00
Bram Kragten
c36fc70ab4 Update frontend to 20240829.0 (#124864) 2024-08-29 17:24:25 +02:00
epenet
681fe3485d Improve config flow type hints (a-f) (#124859) 2024-08-29 17:24:04 +02:00
Fredrik Erlandsson
34680becaa Bump pydaikin to 2.13.6 (#124852) 2024-08-29 13:20:57 +02:00
Erik Montnemery
354f4491c8 Avoid unnecessary copying of variables when setting up automations (#124844) 2024-08-29 13:03:47 +02:00
Andrew Jackson
c4fd1cfc8f Fix Mastodon migrate config entry log warning (#124848)
Fix migrate config entry
2024-08-29 12:23:04 +02:00
Erik Montnemery
a4e9e4b23b Tweak exception message in yaml loader (#124841) 2024-08-29 11:31:19 +02:00
Pete Sage
eac7794741 Fix sonos get_queue service call to restrict to sonos media_player entities (#124815)
add sonos to filter
2024-08-29 11:29:54 +02:00
Jan Bouwhuis
1cb9690001 Cleanup unused hass_storage mocks in mqtt tests (#124846) 2024-08-29 10:52:57 +02:00
AutonomousOwl
1101e7ef64 Update utility_account_id in Opower to be lowercase in statistic id (#124837)
Update utility_account_id to be lowercase in statistic id
2024-08-28 23:34:13 -07:00
Tobias Sauerwein
3b6128d590 Bump pyatmo to 8.1.0 (#124340) 2024-08-29 07:59:07 +02:00
Jeremy Cook
7f4fca63ed SmartThings edge driver for heatit thermostats does not require cooling setpoint (#123188)
* remove cooling setpoint requirement for thermostats. Air conditioning remains unchanged

* remove cooling setpoint requirement for thermostats. Air conditioning remains unchanged

* versions should not be set on core integrations.

* Added tests for minimal smartthings thermostat with no cooling.

* Added tests for minimal smartthings thermostat with no cooling.

* Formatted tests with ruff format
2024-08-29 07:49:05 +02:00
J. Nick Koston
4b59ef4733 Set GoogleEntity entity_id in constructor (#124830) 2024-08-28 15:47:11 -10:00
David Bonnes
3d39f6ce88 Fix evohome test by setting datetime to match snapshot (#124824)
* initial commit

* freeze time instead

* use fixture instead of API
2024-08-29 00:34:20 +02:00
J. Nick Koston
5f810d908f Add missing dependencies to yale (#124821)
* Add missing dependencies to yale

* try another way

* Revert "try another way"

This reverts commit fbb731a33491bf51290fd98acde7b532ea39fb88.

* patch out cloud setup
2024-08-29 00:28:41 +02:00
AlCalzone
c7cfd56b72 Support Z-Wave JS dimming lights using color intensity (#122639)
* Z-Wave JS: support non-dimmable color lights

* remove black_is_off light, support on/off/color

* fix: tests for on/off light

* fix: typo

* remove commented out old test code

* add test for off and on

* support colored lights without separate brightness control

* add test for color-only light

* refactor: extract color only light

* fix: preserve color when changing brightness

* extend tests

* refactor again

* refactor scale check

* refactor: remove impossible check

* review feedback

* review feedback

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-08-29 00:01:53 +02:00
David Bonnes
ada6b7875c Add evohome test for setup (#123129)
* allow for different systems

* installation is a load_json_*fixture param

* allow installation to be parameterized

* test setup of various systems

* add more fixtures

* test setup of integration

* tweak test

* tweak const

* add expected state/services

* extend setup test

* tidy up

* tidy up tweaks

* code tweaks

* refactor expected results dicts

* woops

* refatcor serialize

* refactor test

* tweak

* tweak code

* rename symbol

* ensure actual I/O remains blocked

* tweak

* typo

* use constants

* Update conftest.py

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

* change filename

* add config fixture

* config is a fixture

* config is a fixture now 2

* lint

* lint

* refactor

* lint

* lint

* restore email addr

* use const

* use snapshots instead of helper class

* doctweak

* correct snapshot

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-08-28 22:40:57 +02:00
Fredrik Erlandsson
2b20b2a80b Bump tellduslive to 0.10.12 (#124816)
* Bump tellduslive version

* update licenses.py too
2024-08-28 22:10:49 +03:00
J. Nick Koston
5825e8fee8 Redirect virtual integration yale_home to point to yale (#124817) 2024-08-28 09:01:17 -10:00
J. Nick Koston
70488ffd15 Address yale review comments (#124810)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-28 09:00:52 -10:00
epenet
2900fa733d Use reauth_confirm in co2signal (#124781) 2024-08-28 20:43:11 +02:00
epenet
7d61dd13d9 Use reauth_confirm in discovergy (#124782) 2024-08-28 20:42:50 +02:00
Fredrik Erlandsson
af8131e68f Bump pydaikin to 2.13.5 (#124802)
bump pydaikin version
2024-08-28 19:19:04 +02:00
Blake Bryant
c049129147 Add Deako integration (#121132)
* Deako integration using pydeako

* fix: address feedback

- make unit tests more e2e
- use runtime_data to store connection

* fix: address feedback part 2

- added better type safety for Deako config entries
- refactored the config flow tests to use a conftest mock instead of directly patching
- removed pytest.mark.asyncio test decorators

* fix: address feedback pt 3

- simplify config entry type
- add test for single_instance_allowed
- remove light.py get_state(), only used once, no need to be separate function

* fix: ruff format

* Update homeassistant/components/deako/__init__.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-28 19:16:05 +02:00
Robert Resch
2dce876a86 Bump version to 2024.10.0dev0 (#124808) 2024-08-28 18:51:50 +02:00
Matthias Alphart
1650cee16c Check KNX integration is loaded on websocket calls (#123178) 2024-08-28 18:10:38 +02:00
Kristian Haugene
25cdd737a9 Add current intraday price ranking to Tibber price sensor (#124595) 2024-08-28 18:05:27 +02:00
Sid
9153d16a6d Enable Ruff TCH rules (#124396)
* Enable Ruff TCH rules

* Ignore TCH001-003

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-08-28 18:01:41 +02:00
J. Nick Koston
03ead27f6c Split august and yale integrations (#124677)
* Split august and yale integrations [part 1] (#122253)

* merge with dev

* Remove unused constant

* Remove yale IPv6 workaround (#123409)

* Convert yale to use oauth (#123806)

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

* Update yale for switch from pubnub to websockets (#124675)

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-28 17:46:03 +02:00
epenet
edad766fd3 Use start_reauth helper method in integration tests (u-z) (#124796) 2024-08-28 16:51:16 +02:00
epenet
9bcc31a9fe Use start_reauth helper method in integration tests (s) (#124793) 2024-08-28 16:49:05 +02:00
epenet
7652c35ee6 Use start_reauth helper method in integration tests (t) (#124794) 2024-08-28 16:47:10 +02:00
G Johansson
dd52f4c84a Remove deprecated mailbox platform (#123740)
* Remove deprecated mailbox platform

* Remove from const

* Remove from type hints

* Remove from pyproject
2024-08-28 16:41:23 +02:00
Robert Resch
45bb2cdd82 Build hassfest docker image and pushlish it on beta/stable releases (#124706) 2024-08-28 16:38:12 +02:00
Paul Bottein
a4bfb0e92c Update frontend to 20240828.0 (#124791) 2024-08-28 16:35:44 +02:00
epenet
26006f8036 Use start_reauth helper method in broadlink and bthome (#124783)
* Use start_reauth helper method in broadlink reauth tests

* Also include bthome
2024-08-28 16:34:09 +02:00
epenet
ef4caa951c Use start_reauth helper method in integration tests (p-r) (#124792) 2024-08-28 16:20:47 +02:00
Pete Sage
5824d06fd7 Add get_queue action for Sonos (#124707)
* initial commit

* use constants

* use constants

* update typing

* add queue fixture

* remove blank line

* update docstring

* update icons

* use list comprehension
2024-08-28 16:19:48 +02:00
epenet
57a73d1b1b Use start_reauth helper method in integration tests (m-o) (#124790) 2024-08-28 16:19:31 +02:00
Aidan Timson
731aaaafe2 Update aioazuredevops to 2.2.1 (#124788)
* Update aioazuredevops to 2.2.1

* Update test
2024-08-28 16:01:32 +02:00
epenet
bdd3aa8e39 Use start_reauth helper method in config flow tests (a-d) (#124780)
* Use start_reauth helper method in integration tests (a-d)

* Revert broadlink

* Revert bthome
2024-08-28 15:48:36 +02:00
epenet
99335a07e5 Use start_reauth helper method in integration tests (e-g) (#124785)
* Use start_reauth helper method in integration tests (e-g)

* Include fireservicerota
2024-08-28 15:47:57 +02:00
epenet
9d633f2087 Use start_reauth helper method in integration tests (h-l) (#124787) 2024-08-28 15:47:35 +02:00
Erik Montnemery
174f22aa2f Prevent nesting sections in data entry flows (#124645) 2024-08-28 15:42:15 +02:00
Brett Adams
e39b3796f3 Fix OAuth reauth in Tesla Fleet (#124744)
* Fix auth failure

* Test

* Fix test

* Only reauth on 401

* Cover 401 and others

* Update homeassistant/components/tesla_fleet/strings.json

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>

---------

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2024-08-28 14:58:16 +02:00
Michael
11370979e5 Fix translation for AVM Fritz!Box Tools (#124784)
add missing ssl option to strings
2024-08-28 14:54:30 +02:00
Erik Montnemery
0afae45bc5 Trigger full CI run on Blueprint integration changes (#124778) 2024-08-28 14:27:01 +02:00
Matrix
f8ac952cd7 Add YoLink lock V2 support (#124202)
* Add Lock V2 Support

* Change as suggestions
2024-08-28 14:18:55 +02:00
Erik Montnemery
c4e5d67551 Enforce new service icon schema for core integrations (#124772)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2024-08-28 14:14:45 +02:00
Erik Montnemery
cff4e46694 Deduplicate TTS mocks (#124773) 2024-08-28 13:48:49 +02:00
Erik Montnemery
38ef216894 Update icons.json to new service schema part 4 (#124771) 2024-08-28 13:48:13 +02:00
Erik Montnemery
1a2d013c97 Update icons.json to new service schema part 3 (#124770) 2024-08-28 13:48:01 +02:00
Erik Montnemery
cffa8b4feb Update icons.json to new service schema part 2 (#124769) 2024-08-28 13:47:41 +02:00
Erik Montnemery
fce2e21c9f Update icons.json to new service schema part 1 (#124768) 2024-08-28 13:47:02 +02:00
epenet
a0ffa69b49 Standardize reauth step variable name in aseko_pool_live (#124765) 2024-08-28 13:29:18 +02:00
epenet
a0089685dd Simplify aussie_broadband reauth flow (#124774)
* Simplify aussie_broadband config flow

* Apply suggestions from code review

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

* Update config_flow.py

* Update config_flow.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-28 13:19:58 +02:00
Matthias Alphart
633ff0ea42 Handle KNX expose conversion exceptions and unavailable states (#124776) 2024-08-28 13:14:34 +02:00
epenet
163795e73a Use reauth_confirm in weatherflow_cloud (#124761) 2024-08-28 13:09:45 +02:00
epenet
45eebf3285 Use reauth_confirm in sharkiq (#124762) 2024-08-28 13:09:21 +02:00
epenet
14eec2e57a Add start_reauth helper method to MockConfigEntry (#124767)
* Add start_reauth helper method to MockConfigEntry

* Two more
2024-08-28 13:08:26 +02:00
epenet
274d98f4d7 Standardize reauth step variable name in permobil (#124764) 2024-08-28 13:02:21 +02:00
epenet
51a5a78eb5 Standardize reauth step variable name in config flows (#124760) 2024-08-28 13:01:00 +02:00
epenet
d4ae592a85 Improve config flow type hints in sms (#124352)
* Improve config flow type hints in sms

* Drop async_step_import
2024-08-28 13:00:30 +02:00
epenet
8ff8ed7f76 Cleanup unused import in upb config flow (#124694)
* Cleanup unused import in upb config flow

* More cleanup
2024-08-28 13:00:10 +02:00
epenet
18b49a6f62 Cleanup unused import in solarlog config flow (#124713) 2024-08-28 12:59:53 +02:00
epenet
35d318818a Improve config flow type hints in sense (#124350) 2024-08-28 12:59:12 +02:00
epenet
0a94242337 Improve config flow type hints in vesync (#124351) 2024-08-28 12:56:22 +02:00
starkillerOG
d1681fac72 Improve mediabrowser names for DUO lens Reolink cameras (#124766)
* Improve playback of DUO lens cameras like TrackMix

* fix styling

* Adjust tests accordingly
2024-08-28 12:54:30 +02:00
Matthias Alphart
8504a16e83 Use KNX group address format from project (#124084) 2024-08-28 12:34:28 +02:00
Matthias Alphart
41e66edd14 Set default name for KNX outgoing telegram source (#124439) 2024-08-28 12:31:30 +02:00
starkillerOG
10b3119b4a Use Position instead of Angle for TiltOnlyDevice in motion blinds (#123521)
Use Position instead of Angle for TiltOnlyBlinds
2024-08-28 11:27:34 +02:00
Erik Montnemery
c772c4a2d5 Allow specifying icons for service sections (#124656)
* Allow specifying icons for service sections

* Improve kitchen_sink example
2024-08-28 11:15:26 +02:00
starkillerOG
e9830f0835 Bump reolink_aio to 0.9.8 (#124763) 2024-08-28 11:13:37 +02:00
epenet
bcc66c9a86 Standardize import step variable name (part 5) (#124698)
* Standardize import step variable name (part 5)

* Revert point

* Adjust soma tests
2024-08-28 09:51:49 +02:00
epenet
1f3c99dff3 Standardize import step variable name in cert_expiry (#124696) 2024-08-28 09:51:25 +02:00
epenet
b085ac9296 Standardize import step variable name in geonetnz_volcano (#124699) 2024-08-28 09:48:17 +02:00
Erik Montnemery
1add00a68d Deduplicate STT mocks (#124754) 2024-08-28 09:25:56 +02:00
J. Nick Koston
f9bf7f7e05 Small cleanups to shelly (#124758) 2024-08-27 21:00:31 -10:00
J. Nick Koston
a63c5e6725 Cache shelly coordinator properties that never change (#124756) 2024-08-27 21:00:20 -10:00
Sergey Dudanov
4108b7ada6 Remove unused normalized units from unit converters (#122797)
remove unused normalized units in unit converters
2024-08-28 08:45:40 +02:00
J. Nick Koston
42388450e1 Restore control4 integration (#124750)
* Revert "Disable control4 integration (#124746)"

This reverts commit 16dd6b1712.

* Restore control4 integration

reverts #124746 and updates the lib instead

changelog: https://github.com/lawtancool/pyControl4/compare/v1.1.0...v1.1.3

Note that there is no release yet, see https://github.com/lawtancool/pyControl4/pull/32

* Apply suggestions from code review
2024-08-28 07:54:28 +02:00
Jan Bouwhuis
e720a14dc4 Cleanup removed schema option from mqtt vacuum platform (#124722) 2024-08-28 07:49:05 +02:00
J. Nick Koston
9d3895d69a Bump yalexs to 8.5.4 (#124672) 2024-08-27 15:36:00 -10:00
J. Nick Koston
16dd6b1712 Disable control4 integration (#124746) 2024-08-27 15:12:52 -10:00
functionpointer
e447d83024 Use ssl util in Tibber (#123369)
Tibber: Use homeassistant.util.ssl
2024-08-28 03:04:08 +02:00
Michael Hansen
8fee1975b4 Bump pyspeex-noise to 1.0.2 (#124721)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2024-08-27 14:26:46 -10:00
puddly
3533ac163c Remove unnecessary assertion for the Yellow firmware type (#124747) 2024-08-28 01:57:08 +02:00
J. Nick Koston
1b304e60d9 Disable sisyphus integration (#124742) 2024-08-27 12:53:48 -10:00
J. Nick Koston
5bd17c9198 Bump aioshelly to 11.3.0 (#124741) 2024-08-27 12:34:30 -10:00
J. Nick Koston
136f0e423e Bump aioambient to 2024.08.0 (#124729) 2024-08-27 12:33:17 -10:00
Jesse Hills
e84d9e21f7 Handle single state requests from ESPHome (#124660)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-08-27 12:15:41 -10:00
J. Nick Koston
fa084143ef Bump dbus-fast to 2.24.0 (#124737)
changelog: https://github.com/Bluetooth-Devices/dbus-fast/compare/v2.23.0...v2.24.0
2024-08-27 23:58:11 +02:00
J. Nick Koston
ca17c70109 Remove socketio constraints (#124730)
We have been stuck on an old version of socketio for a few years
now due to https://github.com/jkeljo/sisyphus-control/issues/6 and
no solution has been reached.

The constraint is blocking any integration from using socketio 4.x servers as the old version
only supports socketio 3.x servers which have reached EOL (https://socket.io/docs/v3/)
2024-08-27 23:42:42 +02:00
puddly
5818e2c2d4 Yellow firmware selection options flow (#122868)
* Implement Yellow config flow for firmware selection

* Use the probed firmware type when setting up Yellow

* Add translation strings

* Ensure (most) existing `init` tests pass

* Remove multi-PAN setup config flow unit tests

* Get existing config flow unit tests passing

* Add unit tests for uninstalling multi-PAN and such

* Consolidate entity creation for Yellow and clean up steps

* Be explicit with multiple inheritance overrides

* Address review comments
2024-08-27 23:14:41 +02:00
Shay Levy
467749eb57 Fix Shelly sleepy RPC setup if device is already awake (#124734) 2024-08-27 10:48:13 -10:00
Jan Bouwhuis
dd0c353afb Fix nice_go integration tests (#124736) 2024-08-27 10:28:54 -10:00
IceBotYT
9e762fa222 Bump Nice G.O. to 0.3.5 (#124667)
* Bump Nice G.O. to 0.3.1

* Bump to 0.3.5
2024-08-27 19:53:00 +02:00
Michael
ea04269c49 Improve test coverage for nextcloud (#123148)
* add first data driven tests

* remove unused mock

* test unique_id migration

* test errors during setup

* test error during data update

* test update entity

* system_versionis always available

* make use of snapshot_platform helper

* use parametrize test for coordinator update errors

* apply suggestions

* don't touch internals on coordinator tests

* rework to use async_get_or_create instead of mock_registry
2024-08-27 19:48:39 +02:00
Erik Montnemery
e2d84f9a58 Add support for multiple otbr config entries (#124289)
* Add support for multiple otbr config entries

* Fix test

* Drop useless fixture

* Address review comments

* Change unique id from xa to id

* Improve error text

* Store data in ConfigEntry.runtime_data

* Remove useless function
2024-08-27 19:07:35 +02:00
Erik Montnemery
52b6f00363 Adjust name of Google Translate TTS provider (#124688) 2024-08-27 19:07:04 +02:00
Erik Montnemery
55c42fde88 Improve validation of entity service schemas (#124102)
* Improve validation of entity service schemas

* Update tests/helpers/test_entity_platform.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-27 19:05:49 +02:00
epenet
0dc1eb8757 Cleanup unused import in zwave_js config flow (#124716) 2024-08-27 18:41:27 +02:00
Paulus Schoutsen
1936aeccb9 Add a test for async_converse (#124697) 2024-08-27 11:01:00 -05:00
epenet
c1c158c0aa Adjust docstring in airvisual_pro config flow (#124712) 2024-08-27 16:48:04 +02:00
epenet
bcfc7ea481 Cleanup unused import in google config flow (#124711) 2024-08-27 07:36:07 -07:00
Antoine Reversat
de8bbaadd1 Fix review comments in fglair (#124710)
* Replace if len() == 0 with if not

* Replace list + filter with list comprehensions

* Move consts that are only used in one module to said module
2024-08-27 16:26:18 +02:00
epenet
318259689f Standardize import step variable name (part 4) (#124692)
* Standardize import step variable name (part 4)

* One more

* Revert geonetnz_volcano

* Revert SMS due to coverage

* Revert somfy_mylink due to coverage
2024-08-27 16:18:11 +02:00
epenet
f802611359 Cleanup unused import in somfy_mylink config flow (#124709) 2024-08-27 16:04:00 +02:00
Erik Montnemery
53479b5924 Adjust name of legacy Home Assistant Cloud TTS provider (#124685) 2024-08-27 15:13:58 +02:00
Erik Montnemery
9cae786f40 Add ConfigEntries.async_get_loaded (#124705) 2024-08-27 14:20:57 +02:00
functionpointer
48292beec8 Update pyTibber to 0.30.1 (#124407)
Update to pyTibber==0.30.1
2024-08-27 13:19:15 +02:00
Matrix
a45ba51f89 Update YoLink FlexFob Automation (#123631)
* Change FlexFob Trigger

* Update device trigger tests
2024-08-27 13:17:14 +02:00
Jon Seager
9119884e53 Add touchlinesl integration (#124557)
* touchlinesl: init integration

* integration(touchlinesl): address review feedback

* integration(touchlinesl): address review feedback

* integration(touchlinesl): add a coordinator to manage data updates

* integration(touchlinesl): address review feedback

* integration(touchline_sl): address feedback (and rename)

* integration(touchline_sl): address feedback

* integration(touchline_sl): address feedback

* integration(touchline_sl): update strings

* integration(touchline_sl): address feedback

* integration(touchline_sl): address feedback
2024-08-27 13:15:31 +02:00
Matrix
37e2839fa3 Add power entity for yolink plug (#124678)
* Add Plug power entity

* change state class to total

* Add translations and moving icon to icon.json

* sort translation key

* Fix suggestions
2024-08-27 12:03:50 +02:00
epenet
6b0428774d Standardize import step variable name (part 2) (#124679) 2024-08-27 11:22:35 +02:00
J. Nick Koston
0d2f22838a Reduce complexity of _sorted_statistics_to_dict (#123936)
* comp stats queries

* tweak

* reduce
2024-08-27 11:22:10 +02:00
J. Nick Koston
4bc19876ca Small speed up to creating stats database rows (#124587)
* Small speed up to creating stats database rows

Calling .timestamp() directly is faster on new cpython

* more cleanup
2024-08-27 11:18:12 +02:00
J. Nick Koston
902d76da36 Small cleanup to normalize states (#124614)
- Remove duplicate state_unit lookup
- Use undefined instead of object
2024-08-27 11:17:34 +02:00
J. Nick Koston
d8161c431f Add support for using an entityfilter to subscribe_entities (#124641)
* Add support for using an entityfilter to subscribe_entities

* filter init

* fix

* coverage
2024-08-27 11:17:05 +02:00
J. Nick Koston
68d6f1c1aa Bump zeroconf to 0.133.0 (#124673)
changelog: https://github.com/python-zeroconf/python-zeroconf/compare/0.132.2...0.133.0
2024-08-27 11:15:00 +02:00
Erik Montnemery
ef1d53c207 Include engine name in TTS WS responses (#124683) 2024-08-27 11:14:41 +02:00
Erik Montnemery
823b62d8ab Include engine name in STT WS responses (#124684) 2024-08-27 11:14:17 +02:00
epenet
dece7e0f9c Cleanup unused import in proximity config flow (#124681)
* Cleanup unused import in proximity config flow

* Cleanup tests
2024-08-27 11:08:33 +02:00
epenet
68cdf8877c Standardize import step variable name (part 3) (#124680) 2024-08-27 10:50:13 +02:00
epenet
831a1d7ad1 Standardize import step variable name (part 1) (#124674) 2024-08-27 10:34:47 +02:00
Erik Montnemery
715f4bd2c3 Set deprecated flag on TTS engines replaced by entities in WS list (#124676) 2024-08-27 10:09:49 +02:00
Yuxin Wang
74a12bb802 Replace LASTSTEST with LAST_S_TEST (#124668) 2024-08-27 06:50:15 +02:00
Ståle Storø Hauknes
51fd8e1288 Bump airthings-ble to 0.9.1 (#124658) 2024-08-26 13:59:28 -10:00
Richard Kroegel
2fe19c04b9 Bump bimmer_connected to 0.16.2 (#124651) 2024-08-26 13:57:25 -10:00
Jesse Hills
37019d33fd Bump aioesphomeapi to 25.2.1 (#124659) 2024-08-26 12:29:54 -10:00
Alexey ALERT Rubashёff
0fe939cd7c Update overkiz Atlantic Water Heater operation mode switching (#124619)
* conventional operation state usage

* MartinHjelmare indentation request

* Manual Mode binary sensor

* Removed usage of unconventional operation states

* Removed usage of unconventional operation state

* STATE_OFF operation mode support
2024-08-26 21:31:07 +02:00
Maciej Bieniek
b960ebeb8b Add WS outbound config to Shelly diagnostics (#124654)
Add WS Outbound config to diagnostics
2024-08-26 22:17:38 +03:00
starkillerOG
7334fb0125 Add Reolink chime play action (#123245)
* Add chime play service

* fix supported_feature

* finalize

* add tests

* Adjust to device service

* fix issue

* Add tests

* actions -> services

* fix styling

* Use conftest fixture for test_chime

* Update tests/components/reolink/test_services.py

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

* use ATTR_RINGTONE and rename chime_play to play_chime

* Add translatable exceptions

* fix styling

* Remove option to use entity_id

* fixes

* Fix translations

* fix

* fix translation key

* remove translation key

* use callback for async_setup_services

* fix styling

* Add test_play_chime_service_unloaded

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-08-26 21:12:32 +02:00
Maciej Bieniek
d8fe3c5377 Add missing units for xpercent, xfreq and xcounts Shelly sensors (#124288) 2024-08-26 08:59:18 -10:00
J. Nick Koston
76182c246d Auto configure outbound websocket for sleepy shelly RPC devices (#124545) 2024-08-26 08:37:36 -10:00
Erik Montnemery
b9aaba0432 Prevent duplicating constraints during schema migration (#124616) 2024-08-26 08:35:54 -10:00
Paulus Schoutsen
156948c496 Fix defaults for cloud STT/TTS (#121229)
* Fix defaults for cloud STT/TTS

* Prefer entity over legacy provider

* Remove unrealistic tests

* Add tests which show cloud stt/tts entity is preferred

---------

Co-authored-by: Erik <erik@montnemery.com>
2024-08-26 19:39:09 +02:00
ilan
547dbf77aa Use runtime data instead of hass.data in jvc projector (#124608)
* feat: use runtime data instead of hass.data

* fix: extend ConfigEntry
2024-08-26 19:26:53 +02:00
Erik Montnemery
a68cd712c6 Move data entry section translations (#124648) 2024-08-26 18:45:28 +02:00
Maciej Bieniek
9e7aeed848 Bump nextdns to version 3.2.0 (#124646) 2024-08-26 18:25:10 +02:00
Álvaro Fernández Rojas
95fa123a0b Add Airzone main zone mode select (#124566)
* airzone: select: add zone master mode

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

* airzone: select: use MAIN instead of MASTER

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

* airzone: select: call async_add_entities once

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

* airzone: select: add options lambda function

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

* airzone: select: implement requested changes

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

* airzone: select: options_fn: return list

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

---------

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2024-08-26 17:57:31 +02:00
WebSpider
657ff58500 Fix device class for motion_light blueprint (#124495)
* Fix device class for motion_light blueprint.
Fixes #124353

* Update to accept both motion and occupancy
2024-08-26 17:39:27 +02:00
Jan Bouwhuis
ff029e5efc Cleanup not used data field for mqtt hassio config flow confirm step (#124486) 2024-08-26 17:33:47 +02:00
Erik Montnemery
f4528b288f Fix overriding name in MockTTSEntity (#124639)
* Fix overriding name in MockTTSEntity

* Fix
2024-08-26 15:28:55 +02:00
Paulus Schoutsen
1aa0dbdaf5 Revert "Revert "Use speex for noise suppression and auto gain"" (#124637)
Revert "Revert "Use speex for noise suppression and auto gain" (#124620)"

This reverts commit 302ffe5e56.
2024-08-26 15:10:43 +02:00
J. Nick Koston
743df84569 Reduce multiple calls to calculate sensor unit in tplink (#124606)
accessing unit on the feature is not cached and it had
to be looked up every time
2024-08-26 13:49:26 +02:00
J. Nick Koston
16231da5ef Bump cached-ipaddress to 0.5.0 (#124602)
changelog: https://github.com/bdraco/cached-ipaddress/compare/v0.3.0...v0.5.0
2024-08-26 13:48:52 +02:00
Erik Montnemery
7b71f024fb Prefer stt entity over legacy stt provider (#124625)
* Prefer stt entity over legacy stt provider

* Update assist_pipeline tests
2024-08-26 13:43:14 +02:00
darkfader
0a05cdc381 Add conductivity sensor to bthome (#124312)
* Add conductivity sensor to bthome

* Update icons.json

* Update sensor.py
2024-08-26 13:40:40 +02:00
dependabot[bot]
106559371c Bump github/codeql-action from 3.26.4 to 3.26.5 (#124615)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.4 to 3.26.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3.26.4...v3.26.5)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 13:33:55 +02:00
Erik Montnemery
cafd953f87 Add test showing we prefer tts entity over legacy tts provider (#124624) 2024-08-26 11:10:58 +02:00
Andre Lengwenus
7ddd755acc Handle LCN entity instances only in corresponding platform (#124589)
* Handle switch entity instance only in switch platform

* Add other platforms
2024-08-26 10:17:51 +02:00
Paulus Schoutsen
302ffe5e56 Revert "Use speex for noise suppression and auto gain" (#124620)
Revert "Use speex for noise suppression and auto gain (#124591)"

This reverts commit 592f60643a.
2024-08-26 10:12:05 +02:00
Jan Bouwhuis
65216df3a5 Auto recover mqtt config entry secret if Mosquitto add-on was re-installed (#124514)
Auto recover mqtt config entry secret if Mosquitto add-on is re-installed
2024-08-26 09:40:25 +02:00
J. Nick Koston
76ebb0df08 Improve performance of generate diffs of state change events (#124601)
dict comps are inlined in cpython 3.12+
2024-08-26 08:49:31 +02:00
Christopher Fenner
0591b5e47b Improve code quality for ViCare integration (#124613)
* move type to module

* set translation key outside of init

* align import alias

* align constructor parameter order/naming

* move static attr init outside init function

* add missing types

* fix test

* revert move of _attributes
2024-08-26 08:30:28 +02:00
Yuxin Wang
bb6f9ec844 Set native value to be None instead of STATE_UNKNOWN for APCUPSD integration (#124609) 2024-08-25 19:09:37 -10:00
Michael Hansen
592f60643a Use speex for noise suppression and auto gain (#124591) 2024-08-25 23:50:32 -05:00
Brett Adams
3035588dfa Dont turn HVAC off with preset in Teslemetry (#124604)
Dont turn HVAC off with preset
2024-08-25 20:58:59 -07:00
J. Nick Koston
6e727a49bf Remove unused constant in dhcp (#124605) 2024-08-25 20:58:20 -07:00
Jeef
0dfe12840d Add SimpleFin binary sensor for errors (#122554)
* Binary Sensor Support

* updated requirements

* ng ambr

* update strings.json

* update snapshot
2024-08-25 20:57:57 -07:00
Jesse Hills
d915fee833 Bump aioesphomeapi to 25.2.0 (#124607) 2024-08-25 17:47:48 -10:00
J. Nick Koston
9ea41b4d26 Bump yalexs to 8.4.2 (#124593)
changelog: https://github.com/bdraco/yalexs/compare/v8.4.1...v8.4.2

If the pubnub connection failed, the integration would fallback
to polling. This would could get users banned so we no longer do that.
2024-08-25 23:45:06 +03:00
Pete Sage
8bc9fd23bb Add Sonos tests for announce and update error handling (#124539)
* initial commit

* update error message

* use match for error message
2024-08-25 21:25:20 +02:00
Allen Porter
18212052a4 Update nest events to include attachment image and video urls (#124554) 2024-08-25 21:24:06 +02:00
Allen Porter
3304e27fa3 Add ollama context window size configuration (#124555)
* Add ollama context window size configuration

* Set higher max context size
2024-08-25 21:22:57 +02:00
J. Nick Koston
be206156b0 Fix shelly sleepy entities never being created (#124547) 2024-08-25 09:21:23 -10:00
J. Nick Koston
0628f96713 Ensure all chars are polling when requesting manual update in homekit_controller (#124582)
related issue #123963
2024-08-25 21:21:15 +02:00
J. Nick Koston
41b129e990 Split esphome state property decorators (#124332) 2024-08-25 18:48:17 +02:00
epenet
ebc49d938a Improve config flow type hints (part 2) (#124344) 2024-08-25 18:36:44 +02:00
epenet
58b7711bdd Improve config flow type hints (part 3) (#124346) 2024-08-25 18:36:03 +02:00
epenet
909dfcc436 Improve config flow type hints (part 5) (#124349) 2024-08-25 18:34:39 +02:00
J. Nick Koston
70fc8fa2eb Improve performance of fetching stats metadata (#124428) 2024-08-25 18:33:21 +02:00
J. Nick Koston
242aae514e Small cleanups to list_statistic_ids (#124451) 2024-08-25 18:32:32 +02:00
dontinelli
d94b1e6e8a Add icons for conductivity (#124576) 2024-08-25 18:14:38 +02:00
Allen Porter
d18e81f932 Update a roborock blocking call to be fully async (#124266)
Remove a blocking call in roborock
2024-08-25 08:56:17 -07:00
Paulus Schoutsen
d3293336b1 Ensure write access to hassrelease data folder (#124573)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-08-25 17:24:06 +02:00
dontinelli
1eeb3bdcdf Bump fyta_cli to 0.6.3 (#124574) 2024-08-25 17:23:21 +02:00
Avi Miller
36bfd7b9ce Bump aiolifx to 1.0.8 to support LIFX B10 and T10 Candles (#124263)
Signed-off-by: Avi Miller <me@dje.li>
2024-08-25 07:15:51 -07:00
J. Nick Koston
f84a04e113 Bump ulid-transform to 1.0.2 (#124544)
changelog: https://github.com/bdraco/ulid-transform/compare/v0.13.1...v1.0.2

python 3.13 support added
python 3.10 support dropped
2024-08-25 07:13:40 -07:00
Mr. Bubbles
c9e7c76ee5 Fix missing id in Habitica completed todos API response (#124565)
* Fix missing id in completed todos API response

* Copy id only if none

* Update homeassistant/components/habitica/coordinator.py

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

---------

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2024-08-25 15:15:47 +02:00
Jan Bouwhuis
5550b1a74e Only support remote activity on Alexa if feature is set and at least one feature is in the activity_list (#124567)
Only support remote activity on Alexa if feaure is set and at least one feature is in the activity_list
2024-08-25 15:09:08 +02:00
Marcel van der Veldt
51b520db0c Prevent KeyError when Matter device sends invalid value for StartUpOnOff (#124280) 2024-08-25 15:06:16 +02:00
Christopher Maio
f06c21c8cc Update Matter light transition blocklist to include GE Cync Undercabinet Lights (#124138) 2024-08-25 15:05:13 +02:00
IceBotYT
fcf0bef2cd Remove platform from unique ID in Nice G.O. (#124548)
* Remove domain from unique ID in Nice G.O.

* Snapshots
2024-08-25 14:13:50 +02:00
J. Nick Koston
7c8e00e5e0 Bump yalexs to 8.4.1 (#124553)
changelog: https://github.com/bdraco/yalexs/compare/v8.4.0...v8.4.1
2024-08-25 13:16:20 +02:00
Jonas Bergler
ce72157bf7 Bump pyEmby to 1.10 (#124549) 2024-08-25 11:43:21 +02:00
Andrew Jackson
31f5539311 Change logger level on config migration for Mastodon (#124558) 2024-08-25 09:53:30 +02:00
J. Nick Koston
b63fb9f17f Bump bluetooth-data-tools to 1.20.0 (#124542)
changelog: https://github.com/Bluetooth-Devices/bluetooth-data-tools/compare/v1.19.4...v1.20.0
2024-08-24 18:18:54 -10:00
IceBotYT
9b3718edfb Remove sync API use in Nice G.O. (#124546) 2024-08-25 03:27:08 +02:00
Michael Hansen
156e39ebb2 Add minimum command seconds to VAD (#124447) 2024-08-24 22:21:03 +02:00
Allen Porter
c506188c13 Fix nest event entities to only register a single event per session (#124535) 2024-08-24 22:17:59 +02:00
Allen Porter
b64c21cce6 Bump to python-nest-sdm to 5.0.0 (#124536) 2024-08-24 22:16:55 +02:00
David F. Mulcahey
e85755fbda Fix ZHA device lookup when ZHA devices are shared with additional integrations (#124429)
* Fix ZHA device lookup when ZHA devices are shared with additional integrations

* clean up except error types

* remove impossible to create exceptions
2024-08-24 15:52:27 -04:00
Allen Porter
3e3d27f48d Add nest event platform (#123042)
* Add nest event platform

* Translate entities

* Put motion events into a single entity type

* Remove none types

* Set event entity descriptions as kw only

* Update translations for event entities

* Add single event entity per trait type

* Update translation keys
2024-08-24 08:44:44 -07:00
red-island
32f75597a9 Fix tilt calculation for HomeKit cover devices (#123532) 2024-08-24 16:12:32 +01:00
cnico
d7d35f74f2 Bump flipr-api to 1.6.0 (#124522)
bump flipr-api to 1.6.0
2024-08-24 17:09:52 +02:00
Markus Jacobsen
5dc03752ca Add type hinting to Bang & Olufsen test (#124423) 2024-08-24 12:59:08 +02:00
Michael Arthur
b26446bd88 Add returning activity to ecovacs lawn mower (#124519) 2024-08-24 12:53:49 +02:00
Robert Svensson
9e13184256 Add deCONZ Air Purifier Fan Mode select entity support (#124513)
* Add deCONZ Air Purifier Fan Mode select entity support

* Remove unused constants
2024-08-24 09:51:09 +02:00
J. Nick Koston
b7170c78a5 Bump yalexs to 8.4.0 (#124520) 2024-08-23 20:44:12 -10:00
Steven B.
e26d363b5e Convert ring integration to the async ring-doorbell api (#124365)
* Bump ring-doorbell to 0.9.0

* Convert ring integration to async ring-doorbell api

* Use mock auth fixture class to get token_updater

* Fix typo in fixture name
2024-08-24 08:23:31 +02:00
Joost Lekkerkerker
7ae8f4c9d0 Don't abort airgradient user flow if flow in progress (#124300) 2024-08-24 07:20:00 +02:00
Lenn
664e0258bf Bump motionblindsble to 0.1.1 (#124322) 2024-08-24 07:19:11 +02:00
Joost Lekkerkerker
8023cbcc38 Don't raise WLED user flow unique_id check (#124481) 2024-08-24 07:04:50 +02:00
jjlawren
22c322fc37 Bump plexapi to 4.15.16 (#124512) 2024-08-24 07:01:25 +02:00
J. Nick Koston
2bb4a8747c Bump fnv-hash-fast to 1.0.2 (#124489) 2024-08-24 06:58:52 +02:00
Andre Lengwenus
098a006f32 Bump lcn-frontend to 0.1.6 (#124490) 2024-08-24 06:56:48 +02:00
David F. Mulcahey
d47a296d7a Resolve versions of ZHA dependencies earlier to prevent blocking call in event loop (#124496) 2024-08-24 06:52:58 +02:00
Matthias Alphart
c2ce71a38c Update xknx to 3.1.1 (#124257) 2024-08-24 06:48:02 +02:00
Artur Pragacz
a7c6abc54e Always assign unique_id in Onkyo (#120543) 2024-08-23 21:04:44 -07:00
Christophe Gagnier
79ba315008 Add charging enabled switch to TechnoVE (#121484)
* Add session_active switch to TechnoVE

* Replace multi-line lambda with function def

* Make lambda one line
2024-08-23 22:45:26 +02:00
Jan Bouwhuis
26e87509be Cleanup hassio fixtures in home assistant hardware integration tests (#124500) 2024-08-23 19:40:35 +02:00
J. Nick Koston
af2fec89d8 Bump yalexs to 8.3.3 (#124492)
* Bump yalexs to 8.2.0

changelog: https://github.com/bdraco/yalexs/compare/v8.1.4...v8.2.0

* bump to 8.3.1

* bump

* one more bump to ensure we do not hit the ratelimit/shutdown cleanly

* empty commit to restart ci since close/open did not work in flight
2024-08-23 19:23:05 +02:00
Steven B.
61cee043e6 Do not report tplink discovery failures as legacy connection failures (#124432)
* Do not report discovery failures as legacy connection failures

* Fix catching BaseException
2024-08-23 10:17:48 -05:00
Jan Bouwhuis
fd57931cc9 Cleanup redundant fixtures on matter integration for addon tests (#124445) 2024-08-23 16:27:14 +02:00
Jan Bouwhuis
44b6bca89a Refactor and cleanup zwave_js fixtures to share them (#124485)
Refactor and cleanup zwave_js fixtures to use
2024-08-23 15:42:57 +02:00
starkillerOG
0bd9386df2 Reolink add 100% coverage of siren platform (#124474) 2024-08-23 15:15:04 +02:00
1690 changed files with 61526 additions and 16705 deletions

View File

@@ -14,6 +14,7 @@ core: &core
base_platforms: &base_platforms
- homeassistant/components/air_quality/**
- homeassistant/components/alarm_control_panel/**
- homeassistant/components/assist_satellite/**
- homeassistant/components/binary_sensor/**
- homeassistant/components/button/**
- homeassistant/components/calendar/**
@@ -61,6 +62,7 @@ components: &components
- homeassistant/components/auth/**
- homeassistant/components/automation/**
- homeassistant/components/backup/**
- homeassistant/components/blueprint/**
- homeassistant/components/bluetooth/**
- homeassistant/components/cloud/**
- homeassistant/components/config/**

View File

@@ -32,7 +32,7 @@ jobs:
fetch-depth: 0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -69,7 +69,7 @@ jobs:
run: find ./homeassistant/components/*/translations -name "*.json" | tar zcvf translations.tar.gz -T -
- name: Upload translations
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: translations
path: translations.tar.gz
@@ -116,7 +116,7 @@ jobs:
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
if: needs.init.outputs.channel == 'dev'
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -453,7 +453,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -482,3 +482,56 @@ jobs:
export TWINE_PASSWORD="${{ secrets.TWINE_TOKEN }}"
twine upload dist/* --skip-existing
hassfest-image:
name: Build and test hassfest image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
needs: ["init"]
if: github.repository_owner == 'home-assistant'
env:
HASSFEST_IMAGE_NAME: ghcr.io/home-assistant/hassfest
HASSFEST_IMAGE_TAG: ghcr.io/home-assistant/hassfest:${{ needs.init.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Login to GitHub Container Registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker image
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0
with:
context: . # So action will not pull the repository again
file: ./script/hassfest/docker/Dockerfile
load: true
tags: ${{ env.HASSFEST_IMAGE_TAG }}
- name: Run hassfest against core
run: docker run --rm -v ${{ github.workspace }}/homeassistant:/github/workspace/homeassistant ${{ env.HASSFEST_IMAGE_TAG }} --core-integrations-path=/github/workspace/homeassistant/components
- name: Push Docker image
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
id: push
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0
with:
context: . # So action will not pull the repository again
file: ./script/hassfest/docker/Dockerfile
push: true
tags: ${{ env.HASSFEST_IMAGE_TAG }},${{ env.HASSFEST_IMAGE_NAME }}:latest
- name: Generate artifact attestation
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2
with:
subject-name: ${{ env.HASSFEST_IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true

View File

@@ -40,7 +40,7 @@ env:
CACHE_VERSION: 10
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 8
HA_SHORT_VERSION: "2024.9"
HA_SHORT_VERSION: "2024.10"
DEFAULT_PYTHON: "3.12"
ALL_PYTHON_VERSIONS: "['3.12']"
# 10.3 is the oldest supported version
@@ -234,7 +234,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -279,7 +279,7 @@ jobs:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -319,7 +319,7 @@ jobs:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -359,7 +359,7 @@ jobs:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -429,17 +429,28 @@ jobs:
. venv/bin/activate
pre-commit run --show-diff-on-failure --hook-stage manual codespell --all-files
lint-hadolint:
name: Check ${{ matrix.file }}
runs-on: ubuntu-24.04
needs:
- info
- pre-commit
strategy:
fail-fast: false
matrix:
file:
- Dockerfile
- Dockerfile.dev
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.7
- name: Register hadolint problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/hadolint.json"
- name: Check Dockerfile
uses: docker://hadolint/hadolint:v1.18.2
- name: Check ${{ matrix.file }}
uses: docker://hadolint/hadolint:v2.12.0
with:
args: hadolint Dockerfile
- name: Check Dockerfile.dev
uses: docker://hadolint/hadolint:v1.18.2
with:
args: hadolint Dockerfile.dev
args: hadolint ${{ matrix.file }}
base:
name: Prepare dependencies
@@ -454,7 +465,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
@@ -538,7 +549,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -571,7 +582,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -605,7 +616,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -623,7 +634,7 @@ jobs:
. venv/bin/activate
pip-licenses --format=json --output-file=licenses.json
- name: Upload licenses
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: licenses
path: licenses.json
@@ -648,7 +659,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -695,7 +706,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -740,7 +751,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -815,7 +826,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -833,7 +844,7 @@ jobs:
. venv/bin/activate
python -m script.split_tests ${{ needs.info.outputs.test_group_count }} tests
- name: Upload pytest_buckets
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: pytest_buckets
path: pytest_buckets.txt
@@ -879,7 +890,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
@@ -934,14 +945,14 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${{ matrix.group }}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-full.conclusion == 'failure'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{ matrix.group }}
path: pytest-*.txt
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
path: coverage.xml
@@ -999,7 +1010,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
@@ -1060,7 +1071,7 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${mariadb}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.mariadb }}
@@ -1068,7 +1079,7 @@ jobs:
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: coverage-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.mariadb }}
@@ -1125,7 +1136,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
@@ -1187,7 +1198,7 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${postgresql}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.postgresql }}
@@ -1195,7 +1206,7 @@ jobs:
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: coverage-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.postgresql }}
@@ -1271,7 +1282,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
@@ -1329,14 +1340,14 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${{ matrix.group }}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{ matrix.group }}
path: pytest-*.txt
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
path: coverage.xml

View File

@@ -24,11 +24,11 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.26.4
uses: github/codeql-action/init@v3.26.6
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.26.4
uses: github/codeql-action/analyze@v3.26.6
with:
category: "/language:python"

View File

@@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@v4.1.7
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}

View File

@@ -36,7 +36,7 @@ jobs:
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.1.1
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -82,14 +82,15 @@ jobs:
) > .env_file
- name: Upload env_file
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: env_file
path: ./.env_file
include-hidden-files: true
overwrite: true
- name: Upload requirements_diff
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: requirements_diff
path: ./requirements_diff.txt
@@ -101,7 +102,7 @@ jobs:
python -m script.gen_requirements_all ci
- name: Upload requirements_all_wheels
uses: actions/upload-artifact@v4.3.6
uses: actions/upload-artifact@v4.4.0
with:
name: requirements_all_wheels
path: ./requirements_all_wheels_*.txt
@@ -139,7 +140,7 @@ jobs:
wheels-key: ${{ secrets.WHEELS_KEY }}
env-file: true
apk: "libffi-dev;openssl-dev;yaml-dev;nasm"
skip-binary: aiohttp
skip-binary: aiohttp;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements.txt"
@@ -211,7 +212,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;charset-normalizer;grpcio;SQLAlchemy;protobuf;pydantic;pymicro-vad
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf;pydantic;pymicro-vad;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_old-cython.txt"
@@ -226,7 +227,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;nasm"
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf;pydantic;pymicro-vad
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf;pydantic;pymicro-vad;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_all.txtaa"
@@ -240,7 +241,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;nasm"
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf;pydantic;pymicro-vad
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf;pydantic;pymicro-vad;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_all.txtab"
@@ -254,7 +255,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;nasm"
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf;pydantic;pymicro-vad
skip-binary: aiohttp;charset-normalizer;grpcio;SQLAlchemy;protobuf;pydantic;pymicro-vad;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_all.txtac"

View File

@@ -95,6 +95,7 @@ homeassistant.components.aruba.*
homeassistant.components.arwn.*
homeassistant.components.aseko_pool_live.*
homeassistant.components.assist_pipeline.*
homeassistant.components.assist_satellite.*
homeassistant.components.asuswrt.*
homeassistant.components.autarco.*
homeassistant.components.auth.*
@@ -110,6 +111,7 @@ homeassistant.components.bitcoin.*
homeassistant.components.blockchain.*
homeassistant.components.blue_current.*
homeassistant.components.blueprint.*
homeassistant.components.bluesound.*
homeassistant.components.bluetooth.*
homeassistant.components.bluetooth_adapters.*
homeassistant.components.bluetooth_tracker.*
@@ -139,6 +141,7 @@ homeassistant.components.cpuspeed.*
homeassistant.components.crownstone.*
homeassistant.components.date.*
homeassistant.components.datetime.*
homeassistant.components.deako.*
homeassistant.components.deconz.*
homeassistant.components.default_config.*
homeassistant.components.demo.*
@@ -208,6 +211,8 @@ homeassistant.components.glances.*
homeassistant.components.goalzero.*
homeassistant.components.google.*
homeassistant.components.google_assistant_sdk.*
homeassistant.components.google_cloud.*
homeassistant.components.google_photos.*
homeassistant.components.google_sheets.*
homeassistant.components.gpsd.*
homeassistant.components.greeneye_monitor.*
@@ -278,6 +283,7 @@ homeassistant.components.lawn_mower.*
homeassistant.components.lcn.*
homeassistant.components.ld2410_ble.*
homeassistant.components.led_ble.*
homeassistant.components.lektrico.*
homeassistant.components.lidarr.*
homeassistant.components.lifx.*
homeassistant.components.light.*
@@ -294,7 +300,6 @@ homeassistant.components.london_underground.*
homeassistant.components.lookin.*
homeassistant.components.luftdaten.*
homeassistant.components.madvr.*
homeassistant.components.mailbox.*
homeassistant.components.manual.*
homeassistant.components.map.*
homeassistant.components.mastodon.*
@@ -337,6 +342,7 @@ homeassistant.components.nut.*
homeassistant.components.onboarding.*
homeassistant.components.oncue.*
homeassistant.components.onewire.*
homeassistant.components.onkyo.*
homeassistant.components.open_meteo.*
homeassistant.components.openexchangerates.*
homeassistant.components.opensky.*
@@ -396,6 +402,7 @@ homeassistant.components.select.*
homeassistant.components.sensibo.*
homeassistant.components.sensirion_ble.*
homeassistant.components.sensor.*
homeassistant.components.sensoterra.*
homeassistant.components.senz.*
homeassistant.components.sfr_box.*
homeassistant.components.shelly.*
@@ -408,9 +415,11 @@ homeassistant.components.slack.*
homeassistant.components.sleepiq.*
homeassistant.components.smhi.*
homeassistant.components.snooz.*
homeassistant.components.solarlog.*
homeassistant.components.sonarr.*
homeassistant.components.speedtestdotnet.*
homeassistant.components.sql.*
homeassistant.components.squeezebox.*
homeassistant.components.ssdp.*
homeassistant.components.starlink.*
homeassistant.components.statistics.*

View File

@@ -143,6 +143,8 @@ build.json @home-assistant/supervisor
/tests/components/aseko_pool_live/ @milanmeu
/homeassistant/components/assist_pipeline/ @balloob @synesthesiam
/tests/components/assist_pipeline/ @balloob @synesthesiam
/homeassistant/components/assist_satellite/ @home-assistant/core @synesthesiam
/tests/components/assist_satellite/ @home-assistant/core @synesthesiam
/homeassistant/components/asuswrt/ @kennedyshead @ollo69
/tests/components/asuswrt/ @kennedyshead @ollo69
/homeassistant/components/atag/ @MatsNL
@@ -228,8 +230,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/bsblan/ @liudger
/tests/components/bsblan/ @liudger
/homeassistant/components/bt_smarthub/ @typhoon2099
/homeassistant/components/bthome/ @Ernst79
/tests/components/bthome/ @Ernst79
/homeassistant/components/bthome/ @Ernst79 @thecode
/tests/components/bthome/ @Ernst79 @thecode
/homeassistant/components/buienradar/ @mjj4791 @ties @Robbie1221
/tests/components/buienradar/ @mjj4791 @ties @Robbie1221
/homeassistant/components/button/ @home-assistant/core
@@ -294,6 +296,8 @@ build.json @home-assistant/supervisor
/tests/components/date/ @home-assistant/core
/homeassistant/components/datetime/ @home-assistant/core
/tests/components/datetime/ @home-assistant/core
/homeassistant/components/deako/ @sebirdman @balake @deakolights
/tests/components/deako/ @sebirdman @balake @deakolights
/homeassistant/components/debugpy/ @frenck
/tests/components/debugpy/ @frenck
/homeassistant/components/deconz/ @Kane610
@@ -547,11 +551,14 @@ build.json @home-assistant/supervisor
/tests/components/google_assistant/ @home-assistant/cloud
/homeassistant/components/google_assistant_sdk/ @tronikos
/tests/components/google_assistant_sdk/ @tronikos
/homeassistant/components/google_cloud/ @lufton
/homeassistant/components/google_cloud/ @lufton @tronikos
/tests/components/google_cloud/ @lufton @tronikos
/homeassistant/components/google_generative_ai_conversation/ @tronikos
/tests/components/google_generative_ai_conversation/ @tronikos
/homeassistant/components/google_mail/ @tkdrob
/tests/components/google_mail/ @tkdrob
/homeassistant/components/google_photos/ @allenporter
/tests/components/google_photos/ @allenporter
/homeassistant/components/google_sheets/ @tkdrob
/tests/components/google_sheets/ @tkdrob
/homeassistant/components/google_tasks/ @allenporter
@@ -629,6 +636,8 @@ build.json @home-assistant/supervisor
/tests/components/homewizard/ @DCSBL
/homeassistant/components/honeywell/ @rdfurman @mkmer
/tests/components/honeywell/ @rdfurman @mkmer
/homeassistant/components/html5/ @alexyao2015
/tests/components/html5/ @alexyao2015
/homeassistant/components/http/ @home-assistant/core
/tests/components/http/ @home-assistant/core
/homeassistant/components/huawei_lte/ @scop @fphammerle
@@ -707,8 +716,8 @@ build.json @home-assistant/supervisor
/tests/components/ios/ @robbiet480
/homeassistant/components/iotawatt/ @gtdiehl @jyavenard
/tests/components/iotawatt/ @gtdiehl @jyavenard
/homeassistant/components/iotty/ @pburgio
/tests/components/iotty/ @pburgio
/homeassistant/components/iotty/ @pburgio @shapournemati-iotty
/tests/components/iotty/ @pburgio @shapournemati-iotty
/homeassistant/components/iperf3/ @rohankapoorcom
/homeassistant/components/ipma/ @dgomes
/tests/components/ipma/ @dgomes
@@ -721,6 +730,8 @@ build.json @home-assistant/supervisor
/tests/components/iron_os/ @tr4nt0r
/homeassistant/components/isal/ @bdraco
/tests/components/isal/ @bdraco
/homeassistant/components/iskra/ @iskramis
/tests/components/iskra/ @iskramis
/homeassistant/components/islamic_prayer_times/ @engrbm87 @cpfair
/tests/components/islamic_prayer_times/ @engrbm87 @cpfair
/homeassistant/components/israel_rail/ @shaiu
@@ -797,8 +808,12 @@ build.json @home-assistant/supervisor
/tests/components/leaone/ @bdraco
/homeassistant/components/led_ble/ @bdraco
/tests/components/led_ble/ @bdraco
/homeassistant/components/lektrico/ @lektrico
/tests/components/lektrico/ @lektrico
/homeassistant/components/lg_netcast/ @Drafteed @splinter98
/tests/components/lg_netcast/ @Drafteed @splinter98
/homeassistant/components/lg_thinq/ @LG-ThinQ-Integration
/tests/components/lg_thinq/ @LG-ThinQ-Integration
/homeassistant/components/lidarr/ @tkdrob
/tests/components/lidarr/ @tkdrob
/homeassistant/components/lifx/ @Djelibeybi
@@ -1275,6 +1290,8 @@ build.json @home-assistant/supervisor
/tests/components/sensorpro/ @bdraco
/homeassistant/components/sensorpush/ @bdraco
/tests/components/sensorpush/ @bdraco
/homeassistant/components/sensoterra/ @markruys
/tests/components/sensoterra/ @markruys
/homeassistant/components/sentry/ @dcramer @frenck
/tests/components/sentry/ @dcramer @frenck
/homeassistant/components/senz/ @milanmeu
@@ -1493,6 +1510,8 @@ build.json @home-assistant/supervisor
/tests/components/tomorrowio/ @raman325 @lymanepp
/homeassistant/components/totalconnect/ @austinmroczek
/tests/components/totalconnect/ @austinmroczek
/homeassistant/components/touchline_sl/ @jnsgruk
/tests/components/touchline_sl/ @jnsgruk
/homeassistant/components/tplink/ @rytilahti @bdraco @sdb9696
/tests/components/tplink/ @rytilahti @bdraco @sdb9696
/homeassistant/components/tplink_omada/ @MarkGodwin
@@ -1658,6 +1677,8 @@ build.json @home-assistant/supervisor
/tests/components/xiaomi_miio/ @rytilahti @syssi @starkillerOG
/homeassistant/components/xiaomi_tv/ @simse
/homeassistant/components/xmpp/ @fabaff @flowolf
/homeassistant/components/yale/ @bdraco
/tests/components/yale/ @bdraco
/homeassistant/components/yale_smart_alarm/ @gjohansson-ST
/tests/components/yale_smart_alarm/ @gjohansson-ST
/homeassistant/components/yalexs_ble/ @bdraco

View File

@@ -42,7 +42,8 @@ WORKDIR /usr/src
# Setup hass-release
RUN git clone --depth 1 https://github.com/home-assistant/hass-release \
&& uv pip install --system -e hass-release/
&& uv pip install --system -e hass-release/ \
&& chown -R vscode /usr/src/hass-release/data
USER vscode
ENV VIRTUAL_ENV="/home/vscode/.local/ha-venv"

View File

@@ -9,6 +9,7 @@
"google_generative_ai_conversation",
"google_mail",
"google_maps",
"google_photos",
"google_pubsub",
"google_sheets",
"google_tasks",

View File

@@ -1,5 +1,5 @@
{
"domain": "lg",
"name": "LG",
"integrations": ["lg_netcast", "lg_soundbar", "webostv"]
"integrations": ["lg_netcast", "lg_thinq", "lg_soundbar", "webostv"]
}

View File

@@ -0,0 +1,5 @@
{
"domain": "roth",
"name": "Roth",
"integrations": ["touchline", "touchline_sl"]
}

View File

@@ -1,5 +1,11 @@
{
"domain": "yale",
"name": "Yale",
"integrations": ["august", "yale_smart_alarm", "yalexs_ble", "yale_home"]
"integrations": [
"august",
"yale_smart_alarm",
"yalexs_ble",
"yale_home",
"yale"
]
}

View File

@@ -6,52 +6,3 @@ Component design guidelines:
format "<DOMAIN>.<OBJECT_ID>".
- Each component should publish services only under its own domain.
"""
from __future__ import annotations
import logging
from homeassistant.core import HomeAssistant, split_entity_id
from homeassistant.helpers.frame import report
from homeassistant.helpers.group import expand_entity_ids
_LOGGER = logging.getLogger(__name__)
def is_on(hass: HomeAssistant, entity_id: str | None = None) -> bool:
"""Load up the module to call the is_on method.
If there is no entity id given we will check all.
"""
report(
(
"uses homeassistant.components.is_on."
" This is deprecated and will stop working in Home Assistant 2024.9, it"
" should be updated to use the function of the platform directly."
),
error_if_core=True,
)
if entity_id:
entity_ids = expand_entity_ids(hass, [entity_id])
else:
entity_ids = hass.states.entity_ids()
for ent_id in entity_ids:
domain = split_entity_id(ent_id)[0]
try:
component = getattr(hass.components, domain)
except ImportError:
_LOGGER.error("Failed to call %s.is_on: component not found", domain)
continue
if not hasattr(component, "is_on"):
_LOGGER.warning("Integration %s has no is_on method", domain)
continue
if component.is_on(ent_id):
return True
return False

View File

@@ -7,8 +7,14 @@
}
},
"services": {
"capture_image": "mdi:camera",
"change_setting": "mdi:cog",
"trigger_automation": "mdi:play"
"capture_image": {
"service": "mdi:camera"
},
"change_setting": {
"service": "mdi:cog"
},
"trigger_automation": {
"service": "mdi:play"
}
}
}

View File

@@ -18,6 +18,7 @@ from homeassistant.const import (
UV_INDEX,
UnitOfIrradiance,
UnitOfLength,
UnitOfPressure,
UnitOfSpeed,
UnitOfTemperature,
UnitOfTime,
@@ -279,6 +280,15 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
value_fn=lambda data: cast(float, data[API_METRIC][ATTR_VALUE]),
translation_key="realfeel_temperature_shade",
),
AccuWeatherSensorDescription(
key="RelativeHumidity",
device_class=SensorDeviceClass.HUMIDITY,
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda data: cast(int, data),
translation_key="humidity",
),
AccuWeatherSensorDescription(
key="Precipitation",
device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
@@ -288,6 +298,16 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
attr_fn=lambda data: {"type": data["PrecipitationType"]},
translation_key="precipitation",
),
AccuWeatherSensorDescription(
key="Pressure",
device_class=SensorDeviceClass.PRESSURE,
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
native_unit_of_measurement=UnitOfPressure.HPA,
value_fn=lambda data: cast(float, data[API_METRIC][ATTR_VALUE]),
translation_key="pressure",
),
AccuWeatherSensorDescription(
key="PressureTendency",
device_class=SensorDeviceClass.ENUM,
@@ -295,9 +315,19 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
value_fn=lambda data: cast(str, data["LocalizedText"]).lower(),
translation_key="pressure_tendency",
),
AccuWeatherSensorDescription(
key="Temperature",
device_class=SensorDeviceClass.TEMPERATURE,
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
value_fn=lambda data: cast(float, data[API_METRIC][ATTR_VALUE]),
translation_key="temperature",
),
AccuWeatherSensorDescription(
key="UVIndex",
state_class=SensorStateClass.MEASUREMENT,
entity_registry_enabled_default=False,
native_unit_of_measurement=UV_INDEX,
value_fn=lambda data: cast(int, data),
attr_fn=lambda data: {ATTR_LEVEL: data["UVIndexText"]},
@@ -324,6 +354,7 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
AccuWeatherSensorDescription(
key="Wind",
device_class=SensorDeviceClass.WIND_SPEED,
entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
value_fn=lambda data: cast(float, data[ATTR_SPEED][API_METRIC][ATTR_VALUE]),

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/acmeda",
"iot_class": "local_push",
"loggers": ["aiopulse"],
"requirements": ["aiopulse==0.4.4"]
"requirements": ["aiopulse==0.4.6"]
}

View File

@@ -66,10 +66,20 @@
}
},
"services": {
"add_url": "mdi:link-plus",
"remove_url": "mdi:link-off",
"enable_url": "mdi:link-variant",
"disable_url": "mdi:link-variant-off",
"refresh": "mdi:refresh"
"add_url": {
"service": "mdi:link-plus"
},
"remove_url": {
"service": "mdi:link-off"
},
"enable_url": {
"service": "mdi:link-variant"
},
"disable_url": {
"service": "mdi:link-variant-off"
},
"refresh": {
"service": "mdi:refresh"
}
}
}

View File

@@ -29,18 +29,40 @@ DATA_ADS = "data_ads"
# Supported Types
ADSTYPE_BOOL = "bool"
ADSTYPE_BYTE = "byte"
ADSTYPE_DINT = "dint"
ADSTYPE_INT = "int"
ADSTYPE_UDINT = "udint"
ADSTYPE_UINT = "uint"
ADSTYPE_SINT = "sint"
ADSTYPE_USINT = "usint"
ADSTYPE_DINT = "dint"
ADSTYPE_UDINT = "udint"
ADSTYPE_WORD = "word"
ADSTYPE_DWORD = "dword"
ADSTYPE_LREAL = "lreal"
ADSTYPE_REAL = "real"
ADSTYPE_STRING = "string"
ADSTYPE_TIME = "time"
ADSTYPE_DATE = "date"
ADSTYPE_DATE_AND_TIME = "dt"
ADSTYPE_TOD = "tod"
ADS_TYPEMAP = {
ADSTYPE_BOOL: pyads.PLCTYPE_BOOL,
ADSTYPE_BYTE: pyads.PLCTYPE_BYTE,
ADSTYPE_DINT: pyads.PLCTYPE_DINT,
ADSTYPE_INT: pyads.PLCTYPE_INT,
ADSTYPE_UDINT: pyads.PLCTYPE_UDINT,
ADSTYPE_UINT: pyads.PLCTYPE_UINT,
ADSTYPE_SINT: pyads.PLCTYPE_SINT,
ADSTYPE_USINT: pyads.PLCTYPE_USINT,
ADSTYPE_DINT: pyads.PLCTYPE_DINT,
ADSTYPE_UDINT: pyads.PLCTYPE_UDINT,
ADSTYPE_WORD: pyads.PLCTYPE_WORD,
ADSTYPE_DWORD: pyads.PLCTYPE_DWORD,
ADSTYPE_REAL: pyads.PLCTYPE_REAL,
ADSTYPE_LREAL: pyads.PLCTYPE_LREAL,
ADSTYPE_STRING: pyads.PLCTYPE_STRING,
ADSTYPE_TIME: pyads.PLCTYPE_TIME,
ADSTYPE_DATE: pyads.PLCTYPE_DATE,
ADSTYPE_DATE_AND_TIME: pyads.PLCTYPE_DT,
ADSTYPE_TOD: pyads.PLCTYPE_TOD,
}
CONF_ADS_FACTOR = "factor"
@@ -75,12 +97,23 @@ SCHEMA_SERVICE_WRITE_DATA_BY_NAME = vol.Schema(
{
vol.Required(CONF_ADS_TYPE): vol.In(
[
ADSTYPE_BOOL,
ADSTYPE_BYTE,
ADSTYPE_INT,
ADSTYPE_UINT,
ADSTYPE_BYTE,
ADSTYPE_BOOL,
ADSTYPE_SINT,
ADSTYPE_USINT,
ADSTYPE_DINT,
ADSTYPE_UDINT,
ADSTYPE_WORD,
ADSTYPE_DWORD,
ADSTYPE_REAL,
ADSTYPE_LREAL,
ADSTYPE_STRING,
ADSTYPE_TIME,
ADSTYPE_DATE,
ADSTYPE_DATE_AND_TIME,
ADSTYPE_TOD,
]
),
vol.Required(CONF_ADS_VALUE): vol.Coerce(int),
@@ -222,37 +255,53 @@ class AdsHub:
def _device_notification_callback(self, notification, name):
"""Handle device notifications."""
contents = notification.contents
hnotify = int(contents.hNotification)
_LOGGER.debug("Received notification %d", hnotify)
# get dynamically sized data array
# Get dynamically sized data array
data_size = contents.cbSampleSize
data = (ctypes.c_ubyte * data_size).from_address(
data_address = (
ctypes.addressof(contents)
+ pyads.structs.SAdsNotificationHeader.data.offset
)
data = (ctypes.c_ubyte * data_size).from_address(data_address)
try:
with self._lock:
notification_item = self._notification_items[hnotify]
except KeyError:
# Acquire notification item
with self._lock:
notification_item = self._notification_items.get(hnotify)
if not notification_item:
_LOGGER.error("Unknown device notification handle: %d", hnotify)
return
# Parse data to desired datatype
if notification_item.plc_datatype == pyads.PLCTYPE_BOOL:
# Data parsing based on PLC data type
plc_datatype = notification_item.plc_datatype
unpack_formats = {
pyads.PLCTYPE_BYTE: "<b",
pyads.PLCTYPE_INT: "<h",
pyads.PLCTYPE_UINT: "<H",
pyads.PLCTYPE_SINT: "<b",
pyads.PLCTYPE_USINT: "<B",
pyads.PLCTYPE_DINT: "<i",
pyads.PLCTYPE_UDINT: "<I",
pyads.PLCTYPE_WORD: "<H",
pyads.PLCTYPE_DWORD: "<I",
pyads.PLCTYPE_LREAL: "<d",
pyads.PLCTYPE_REAL: "<f",
pyads.PLCTYPE_TOD: "<i", # Treat as DINT
pyads.PLCTYPE_DATE: "<i", # Treat as DINT
pyads.PLCTYPE_DT: "<i", # Treat as DINT
pyads.PLCTYPE_TIME: "<i", # Treat as DINT
}
if plc_datatype == pyads.PLCTYPE_BOOL:
value = bool(struct.unpack("<?", bytearray(data))[0])
elif notification_item.plc_datatype == pyads.PLCTYPE_INT:
value = struct.unpack("<h", bytearray(data))[0]
elif notification_item.plc_datatype == pyads.PLCTYPE_BYTE:
value = struct.unpack("<B", bytearray(data))[0]
elif notification_item.plc_datatype == pyads.PLCTYPE_UINT:
value = struct.unpack("<H", bytearray(data))[0]
elif notification_item.plc_datatype == pyads.PLCTYPE_DINT:
value = struct.unpack("<i", bytearray(data))[0]
elif notification_item.plc_datatype == pyads.PLCTYPE_UDINT:
value = struct.unpack("<I", bytearray(data))[0]
elif plc_datatype == pyads.PLCTYPE_STRING:
value = (
bytearray(data).split(b"\x00", 1)[0].decode("utf-8", errors="ignore")
)
elif plc_datatype in unpack_formats:
value = struct.unpack(unpack_formats[plc_datatype], bytearray(data))[0]
else:
value = bytearray(data)
_LOGGER.warning("No callback available for this datatype")

View File

@@ -1,5 +1,7 @@
{
"services": {
"write_data_by_name": "mdi:pencil"
"write_data_by_name": {
"service": "mdi:pencil"
}
}
}

View File

@@ -1,5 +1,7 @@
{
"services": {
"set_time_to": "mdi:timer-cog"
"set_time_to": {
"service": "mdi:timer-cog"
}
}
}

View File

@@ -7,7 +7,11 @@
}
},
"services": {
"add_tracking": "mdi:package-variant-plus",
"remove_tracking": "mdi:package-variant-minus"
"add_tracking": {
"service": "mdi:package-variant-plus"
},
"remove_tracking": {
"service": "mdi:package-variant-minus"
}
}
}

View File

@@ -1,9 +1,19 @@
{
"services": {
"start_recording": "mdi:record-rec",
"stop_recording": "mdi:stop",
"enable_alerts": "mdi:bell-alert",
"disable_alerts": "mdi:bell-off",
"snapshot": "mdi:camera"
"start_recording": {
"service": "mdi:record-rec"
},
"stop_recording": {
"service": "mdi:stop"
},
"enable_alerts": {
"service": "mdi:bell-alert"
},
"disable_alerts": {
"service": "mdi:bell-off"
},
"snapshot": {
"service": "mdi:camera"
}
}
}

View File

@@ -2,18 +2,14 @@
from __future__ import annotations
from dataclasses import dataclass
from airgradient import AirGradientClient, get_model_name
from airgradient import AirGradientClient
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN
from .coordinator import AirGradientConfigCoordinator, AirGradientMeasurementCoordinator
from .coordinator import AirGradientCoordinator
PLATFORMS: list[Platform] = [
Platform.BUTTON,
@@ -25,15 +21,7 @@ PLATFORMS: list[Platform] = [
]
@dataclass
class AirGradientData:
"""AirGradient data class."""
measurement: AirGradientMeasurementCoordinator
config: AirGradientConfigCoordinator
type AirGradientConfigEntry = ConfigEntry[AirGradientData]
type AirGradientConfigEntry = ConfigEntry[AirGradientCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: AirGradientConfigEntry) -> bool:
@@ -43,27 +31,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirGradientConfigEntry)
entry.data[CONF_HOST], session=async_get_clientsession(hass)
)
measurement_coordinator = AirGradientMeasurementCoordinator(hass, client)
config_coordinator = AirGradientConfigCoordinator(hass, client)
coordinator = AirGradientCoordinator(hass, client)
await measurement_coordinator.async_config_entry_first_refresh()
await config_coordinator.async_config_entry_first_refresh()
await coordinator.async_config_entry_first_refresh()
device_registry = dr.async_get(hass)
device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
identifiers={(DOMAIN, measurement_coordinator.serial_number)},
manufacturer="AirGradient",
model=get_model_name(measurement_coordinator.data.model),
model_id=measurement_coordinator.data.model,
serial_number=measurement_coordinator.data.serial_number,
sw_version=measurement_coordinator.data.firmware_version,
)
entry.runtime_data = AirGradientData(
measurement=measurement_coordinator,
config=config_coordinator,
)
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

View File

@@ -15,8 +15,9 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import DOMAIN, AirGradientConfigEntry
from .coordinator import AirGradientConfigCoordinator
from . import AirGradientConfigEntry
from .const import DOMAIN
from .coordinator import AirGradientCoordinator
from .entity import AirGradientEntity
@@ -47,8 +48,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up AirGradient button entities based on a config entry."""
model = entry.runtime_data.measurement.data.model
coordinator = entry.runtime_data.config
coordinator = entry.runtime_data
model = coordinator.data.measures.model
added_entities = False
@@ -57,7 +58,7 @@ async def async_setup_entry(
nonlocal added_entities
if (
coordinator.data.configuration_control is ConfigurationControl.LOCAL
coordinator.data.config.configuration_control is ConfigurationControl.LOCAL
and not added_entities
):
entities = [AirGradientButton(coordinator, CO2_CALIBRATION)]
@@ -67,7 +68,8 @@ async def async_setup_entry(
async_add_entities(entities)
added_entities = True
elif (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
coordinator.data.config.configuration_control
is not ConfigurationControl.LOCAL
and added_entities
):
entity_registry = er.async_get(hass)
@@ -87,11 +89,10 @@ class AirGradientButton(AirGradientEntity, ButtonEntity):
"""Defines an AirGradient button."""
entity_description: AirGradientButtonEntityDescription
coordinator: AirGradientConfigCoordinator
def __init__(
self,
coordinator: AirGradientConfigCoordinator,
coordinator: AirGradientCoordinator,
description: AirGradientButtonEntityDescription,
) -> None:
"""Initialize airgradient button."""

View File

@@ -92,7 +92,9 @@ class AirGradientConfigFlow(ConfigFlow, domain=DOMAIN):
except AirGradientError:
errors["base"] = "cannot_connect"
else:
await self.async_set_unique_id(current_measures.serial_number)
await self.async_set_unique_id(
current_measures.serial_number, raise_on_progress=False
)
self._abort_if_unique_id_configured()
await self.set_configuration_source()
return self.async_create_entry(

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
from typing import TYPE_CHECKING
@@ -16,7 +17,15 @@ if TYPE_CHECKING:
from . import AirGradientConfigEntry
class AirGradientCoordinator[_DataT](DataUpdateCoordinator[_DataT]):
@dataclass
class AirGradientData:
"""Class for AirGradient data."""
measures: Measures
config: Config
class AirGradientCoordinator(DataUpdateCoordinator[AirGradientData]):
"""Class to manage fetching AirGradient data."""
config_entry: AirGradientConfigEntry
@@ -33,25 +42,11 @@ class AirGradientCoordinator[_DataT](DataUpdateCoordinator[_DataT]):
assert self.config_entry.unique_id
self.serial_number = self.config_entry.unique_id
async def _async_update_data(self) -> _DataT:
async def _async_update_data(self) -> AirGradientData:
try:
return await self._update_data()
measures = await self.client.get_current_measures()
config = await self.client.get_config()
except AirGradientError as error:
raise UpdateFailed(error) from error
async def _update_data(self) -> _DataT:
raise NotImplementedError
class AirGradientMeasurementCoordinator(AirGradientCoordinator[Measures]):
"""Class to manage fetching AirGradient data."""
async def _update_data(self) -> Measures:
return await self.client.get_current_measures()
class AirGradientConfigCoordinator(AirGradientCoordinator[Config]):
"""Class to manage fetching AirGradient data."""
async def _update_data(self) -> Config:
return await self.client.get_config()
else:
return AirGradientData(measures, config)

View File

@@ -1,5 +1,7 @@
"""Base class for AirGradient entities."""
from airgradient import get_model_name
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@@ -15,6 +17,12 @@ class AirGradientEntity(CoordinatorEntity[AirGradientCoordinator]):
def __init__(self, coordinator: AirGradientCoordinator) -> None:
"""Initialize airgradient entity."""
super().__init__(coordinator)
measures = coordinator.data.measures
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, coordinator.serial_number)},
manufacturer="AirGradient",
model=get_model_name(measures.model),
model_id=measures.model,
serial_number=coordinator.serial_number,
sw_version=measures.firmware_version,
)

View File

@@ -18,7 +18,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirGradientConfigEntry
from .const import DOMAIN
from .coordinator import AirGradientConfigCoordinator
from .coordinator import AirGradientCoordinator
from .entity import AirGradientEntity
@@ -62,8 +62,8 @@ async def async_setup_entry(
) -> None:
"""Set up AirGradient number entities based on a config entry."""
model = entry.runtime_data.measurement.data.model
coordinator = entry.runtime_data.config
coordinator = entry.runtime_data
model = coordinator.data.measures.model
added_entities = False
@@ -72,7 +72,7 @@ async def async_setup_entry(
nonlocal added_entities
if (
coordinator.data.configuration_control is ConfigurationControl.LOCAL
coordinator.data.config.configuration_control is ConfigurationControl.LOCAL
and not added_entities
):
entities = []
@@ -84,7 +84,8 @@ async def async_setup_entry(
async_add_entities(entities)
added_entities = True
elif (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
coordinator.data.config.configuration_control
is not ConfigurationControl.LOCAL
and added_entities
):
entity_registry = er.async_get(hass)
@@ -104,11 +105,10 @@ class AirGradientNumber(AirGradientEntity, NumberEntity):
"""Defines an AirGradient number entity."""
entity_description: AirGradientNumberEntityDescription
coordinator: AirGradientConfigCoordinator
def __init__(
self,
coordinator: AirGradientConfigCoordinator,
coordinator: AirGradientCoordinator,
description: AirGradientNumberEntityDescription,
) -> None:
"""Initialize AirGradient number."""
@@ -119,7 +119,7 @@ class AirGradientNumber(AirGradientEntity, NumberEntity):
@property
def native_value(self) -> int | None:
"""Return the state of the number."""
return self.entity_description.value_fn(self.coordinator.data)
return self.entity_description.value_fn(self.coordinator.data.config)
async def async_set_native_value(self, value: float) -> None:
"""Set the selected value."""

View File

@@ -18,7 +18,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirGradientConfigEntry
from .const import DOMAIN, PM_STANDARD, PM_STANDARD_REVERSE
from .coordinator import AirGradientConfigCoordinator
from .coordinator import AirGradientCoordinator
from .entity import AirGradientEntity
@@ -144,13 +144,11 @@ async def async_setup_entry(
) -> None:
"""Set up AirGradient select entities based on a config entry."""
coordinator = entry.runtime_data.config
measurement_coordinator = entry.runtime_data.measurement
coordinator = entry.runtime_data
model = coordinator.data.measures.model
async_add_entities([AirGradientSelect(coordinator, CONFIG_CONTROL_ENTITY)])
model = measurement_coordinator.data.model
added_entities = False
@callback
@@ -158,7 +156,7 @@ async def async_setup_entry(
nonlocal added_entities
if (
coordinator.data.configuration_control is ConfigurationControl.LOCAL
coordinator.data.config.configuration_control is ConfigurationControl.LOCAL
and not added_entities
):
entities: list[AirGradientSelect] = [
@@ -179,7 +177,8 @@ async def async_setup_entry(
async_add_entities(entities)
added_entities = True
elif (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
coordinator.data.config.configuration_control
is not ConfigurationControl.LOCAL
and added_entities
):
entity_registry = er.async_get(hass)
@@ -201,11 +200,10 @@ class AirGradientSelect(AirGradientEntity, SelectEntity):
"""Defines an AirGradient select entity."""
entity_description: AirGradientSelectEntityDescription
coordinator: AirGradientConfigCoordinator
def __init__(
self,
coordinator: AirGradientConfigCoordinator,
coordinator: AirGradientCoordinator,
description: AirGradientSelectEntityDescription,
) -> None:
"""Initialize AirGradient select."""
@@ -216,7 +214,7 @@ class AirGradientSelect(AirGradientEntity, SelectEntity):
@property
def current_option(self) -> str | None:
"""Return the state of the select."""
return self.entity_description.value_fn(self.coordinator.data)
return self.entity_description.value_fn(self.coordinator.data.config)
async def async_select_option(self, option: str) -> None:
"""Change the selected option."""

View File

@@ -32,7 +32,7 @@ from homeassistant.helpers.typing import StateType
from . import AirGradientConfigEntry
from .const import PM_STANDARD, PM_STANDARD_REVERSE
from .coordinator import AirGradientConfigCoordinator, AirGradientMeasurementCoordinator
from .coordinator import AirGradientCoordinator
from .entity import AirGradientEntity
@@ -218,7 +218,7 @@ async def async_setup_entry(
) -> None:
"""Set up AirGradient sensor entities based on a config entry."""
coordinator = entry.runtime_data.measurement
coordinator = entry.runtime_data
listener: Callable[[], None] | None = None
not_setup: set[AirGradientMeasurementSensorEntityDescription] = set(
MEASUREMENT_SENSOR_TYPES
@@ -232,7 +232,7 @@ async def async_setup_entry(
not_setup = set()
sensors = []
for description in sensor_descriptions:
if description.value_fn(coordinator.data) is None:
if description.value_fn(coordinator.data.measures) is None:
not_setup.add(description)
else:
sensors.append(AirGradientMeasurementSensor(coordinator, description))
@@ -248,64 +248,65 @@ async def async_setup_entry(
add_entities()
entities = [
AirGradientConfigSensor(entry.runtime_data.config, description)
AirGradientConfigSensor(coordinator, description)
for description in CONFIG_SENSOR_TYPES
]
if "L" in coordinator.data.model:
if "L" in coordinator.data.measures.model:
entities.extend(
AirGradientConfigSensor(entry.runtime_data.config, description)
AirGradientConfigSensor(coordinator, description)
for description in CONFIG_LED_BAR_SENSOR_TYPES
)
if "I" in coordinator.data.model:
if "I" in coordinator.data.measures.model:
entities.extend(
AirGradientConfigSensor(entry.runtime_data.config, description)
AirGradientConfigSensor(coordinator, description)
for description in CONFIG_DISPLAY_SENSOR_TYPES
)
async_add_entities(entities)
class AirGradientMeasurementSensor(AirGradientEntity, SensorEntity):
class AirGradientSensor(AirGradientEntity, SensorEntity):
"""Defines an AirGradient sensor."""
entity_description: AirGradientMeasurementSensorEntityDescription
coordinator: AirGradientMeasurementCoordinator
def __init__(
self,
coordinator: AirGradientMeasurementCoordinator,
description: AirGradientMeasurementSensorEntityDescription,
coordinator: AirGradientCoordinator,
description: SensorEntityDescription,
) -> None:
"""Initialize airgradient sensor."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
class AirGradientMeasurementSensor(AirGradientSensor):
"""Defines an AirGradient sensor."""
entity_description: AirGradientMeasurementSensorEntityDescription
@property
def native_value(self) -> StateType:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self.coordinator.data)
return self.entity_description.value_fn(self.coordinator.data.measures)
class AirGradientConfigSensor(AirGradientEntity, SensorEntity):
class AirGradientConfigSensor(AirGradientSensor):
"""Defines an AirGradient sensor."""
entity_description: AirGradientConfigSensorEntityDescription
coordinator: AirGradientConfigCoordinator
def __init__(
self,
coordinator: AirGradientConfigCoordinator,
coordinator: AirGradientCoordinator,
description: AirGradientConfigSensorEntityDescription,
) -> None:
"""Initialize airgradient sensor."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
super().__init__(coordinator, description)
self._attr_entity_registry_enabled_default = (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
coordinator.data.config.configuration_control
is not ConfigurationControl.LOCAL
)
@property
def native_value(self) -> StateType:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self.coordinator.data)
return self.entity_description.value_fn(self.coordinator.data.config)

View File

@@ -19,7 +19,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirGradientConfigEntry
from .const import DOMAIN
from .coordinator import AirGradientConfigCoordinator
from .coordinator import AirGradientCoordinator
from .entity import AirGradientEntity
@@ -46,7 +46,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up AirGradient switch entities based on a config entry."""
coordinator = entry.runtime_data.config
coordinator = entry.runtime_data
added_entities = False
@@ -55,7 +55,7 @@ async def async_setup_entry(
nonlocal added_entities
if (
coordinator.data.configuration_control is ConfigurationControl.LOCAL
coordinator.data.config.configuration_control is ConfigurationControl.LOCAL
and not added_entities
):
async_add_entities(
@@ -63,7 +63,8 @@ async def async_setup_entry(
)
added_entities = True
elif (
coordinator.data.configuration_control is not ConfigurationControl.LOCAL
coordinator.data.config.configuration_control
is not ConfigurationControl.LOCAL
and added_entities
):
entity_registry = er.async_get(hass)
@@ -82,11 +83,10 @@ class AirGradientSwitch(AirGradientEntity, SwitchEntity):
"""Defines an AirGradient switch entity."""
entity_description: AirGradientSwitchEntityDescription
coordinator: AirGradientConfigCoordinator
def __init__(
self,
coordinator: AirGradientConfigCoordinator,
coordinator: AirGradientCoordinator,
description: AirGradientSwitchEntityDescription,
) -> None:
"""Initialize AirGradient switch."""
@@ -97,7 +97,7 @@ class AirGradientSwitch(AirGradientEntity, SwitchEntity):
@property
def is_on(self) -> bool:
"""Return the state of the switch."""
return self.entity_description.value_fn(self.coordinator.data)
return self.entity_description.value_fn(self.coordinator.data.config)
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""

View File

@@ -7,7 +7,7 @@ from homeassistant.components.update import UpdateDeviceClass, UpdateEntity
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirGradientConfigEntry, AirGradientMeasurementCoordinator
from . import AirGradientConfigEntry, AirGradientCoordinator
from .entity import AirGradientEntity
SCAN_INTERVAL = timedelta(hours=1)
@@ -20,18 +20,17 @@ async def async_setup_entry(
) -> None:
"""Set up Airgradient update platform."""
data = config_entry.runtime_data
coordinator = config_entry.runtime_data
async_add_entities([AirGradientUpdate(data.measurement)], True)
async_add_entities([AirGradientUpdate(coordinator)], True)
class AirGradientUpdate(AirGradientEntity, UpdateEntity):
"""Representation of Airgradient Update."""
_attr_device_class = UpdateDeviceClass.FIRMWARE
coordinator: AirGradientMeasurementCoordinator
def __init__(self, coordinator: AirGradientMeasurementCoordinator) -> None:
def __init__(self, coordinator: AirGradientCoordinator) -> None:
"""Initialize the entity."""
super().__init__(coordinator)
self._attr_unique_id = f"{coordinator.serial_number}-update"
@@ -44,7 +43,7 @@ class AirGradientUpdate(AirGradientEntity, UpdateEntity):
@property
def installed_version(self) -> str:
"""Return the installed version of the entity."""
return self.coordinator.data.firmware_version
return self.coordinator.data.measures.firmware_version
async def async_update(self) -> None:
"""Update the entity."""

View File

@@ -24,5 +24,5 @@
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",
"iot_class": "local_polling",
"requirements": ["airthings-ble==0.9.0"]
"requirements": ["airthings-ble==0.9.1"]
}

View File

@@ -80,11 +80,9 @@ class AirVisualProFlowHandler(ConfigFlow, domain=DOMAIN):
"""Initialize."""
self._reauth_entry: ConfigEntry | None = None
async def async_step_import(
self, import_config: dict[str, Any]
) -> ConfigFlowResult:
"""Import a config entry from configuration.yaml."""
return await self.async_step_user(import_config)
async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult:
"""Import a config entry from `airvisual` integration (see #83882)."""
return await self.async_step_user(import_data)
async def async_step_reauth(
self, entry_data: Mapping[str, Any]

View File

@@ -2,16 +2,21 @@
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any, Final
from aioairzone.common import GrilleAngle, SleepTimeout
from aioairzone.common import GrilleAngle, OperationMode, SleepTimeout
from aioairzone.const import (
API_COLD_ANGLE,
API_HEAT_ANGLE,
API_MODE,
API_SLEEP,
AZD_COLD_ANGLE,
AZD_HEAT_ANGLE,
AZD_MASTER,
AZD_MODE,
AZD_MODES,
AZD_SLEEP,
AZD_ZONES,
)
@@ -33,6 +38,9 @@ class AirzoneSelectDescription(SelectEntityDescription):
api_param: str
options_dict: dict[str, int]
options_fn: Callable[[dict[str, Any], dict[str, int]], list[str]] = (
lambda zone_data, value: list(value)
)
GRILLE_ANGLE_DICT: Final[dict[str, int]] = {
@@ -42,6 +50,15 @@ GRILLE_ANGLE_DICT: Final[dict[str, int]] = {
"40deg": GrilleAngle.DEG_40,
}
MODE_DICT: Final[dict[str, int]] = {
"cool": OperationMode.COOLING,
"dry": OperationMode.DRY,
"fan": OperationMode.FAN,
"heat": OperationMode.HEATING,
"heat_cool": OperationMode.AUTO,
"stop": OperationMode.STOP,
}
SLEEP_DICT: Final[dict[str, int]] = {
"off": SleepTimeout.SLEEP_OFF,
"30m": SleepTimeout.SLEEP_30,
@@ -50,6 +67,26 @@ SLEEP_DICT: Final[dict[str, int]] = {
}
def main_zone_options(
zone_data: dict[str, Any],
options: dict[str, int],
) -> list[str]:
"""Filter available modes."""
modes = zone_data.get(AZD_MODES, [])
return [k for k, v in options.items() if v in modes]
MAIN_ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
AirzoneSelectDescription(
api_param=API_MODE,
key=AZD_MODE,
options_dict=MODE_DICT,
options_fn=main_zone_options,
translation_key="modes",
),
)
ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
AirzoneSelectDescription(
api_param=API_COLD_ANGLE,
@@ -95,7 +132,20 @@ async def async_setup_entry(
received_zones = set(zones_data)
new_zones = received_zones - added_zones
if new_zones:
async_add_entities(
entities: list[AirzoneZoneSelect] = [
AirzoneZoneSelect(
coordinator,
description,
entry,
system_zone_id,
zones_data.get(system_zone_id),
)
for system_zone_id in new_zones
for description in MAIN_ZONE_SELECT_TYPES
if description.key in zones_data.get(system_zone_id)
and zones_data.get(system_zone_id).get(AZD_MASTER) is True
]
entities += [
AirzoneZoneSelect(
coordinator,
description,
@@ -106,7 +156,8 @@ async def async_setup_entry(
for system_zone_id in new_zones
for description in ZONE_SELECT_TYPES
if description.key in zones_data.get(system_zone_id)
)
]
async_add_entities(entities)
added_zones.update(new_zones)
entry.async_on_unload(coordinator.async_add_listener(_async_entity_listener))
@@ -153,6 +204,11 @@ class AirzoneZoneSelect(AirzoneZoneEntity, AirzoneBaseSelect):
f"{self._attr_unique_id}_{system_zone_id}_{description.key}"
)
self.entity_description = description
self._attr_options = self.entity_description.options_fn(
zone_data, description.options_dict
)
self.values_dict = {v: k for k, v in description.options_dict.items()}
self._async_update_attrs()

View File

@@ -52,6 +52,17 @@
"40deg": "[%key:component::airzone::entity::select::grille_angles::state::40deg%]"
}
},
"modes": {
"name": "Mode",
"state": {
"cool": "[%key:component::climate::entity_component::_::state::cool%]",
"dry": "[%key:component::climate::entity_component::_::state::dry%]",
"fan": "[%key:component::climate::entity_component::_::state::fan_only%]",
"heat": "[%key:component::climate::entity_component::_::state::heat%]",
"heat_cool": "[%key:component::climate::entity_component::_::state::heat_cool%]",
"stop": "Stop"
}
},
"sleep_times": {
"name": "Sleep",
"state": {

View File

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

View File

@@ -12,7 +12,16 @@ from aioairzone_cloud.const import (
AZD_AQ_PM_10,
AZD_CPU_USAGE,
AZD_HUMIDITY,
AZD_INDOOR_EXCHANGER_TEMP,
AZD_INDOOR_RETURN_TEMP,
AZD_INDOOR_WORK_TEMP,
AZD_MEMORY_FREE,
AZD_OUTDOOR_CONDENSER_PRESS,
AZD_OUTDOOR_DISCHARGE_TEMP,
AZD_OUTDOOR_ELECTRIC_CURRENT,
AZD_OUTDOOR_EVAPORATOR_PRESS,
AZD_OUTDOOR_EXCHANGER_TEMP,
AZD_OUTDOOR_TEMP,
AZD_TEMP,
AZD_THERMOSTAT_BATTERY,
AZD_THERMOSTAT_COVERAGE,
@@ -32,7 +41,9 @@ from homeassistant.const import (
PERCENTAGE,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
EntityCategory,
UnitOfElectricCurrent,
UnitOfInformation,
UnitOfPressure,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant, callback
@@ -48,6 +59,78 @@ from .entity import (
)
AIDOO_SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = (
SensorEntityDescription(
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
key=AZD_INDOOR_EXCHANGER_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
translation_key="indoor_exchanger_temp",
),
SensorEntityDescription(
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
key=AZD_INDOOR_RETURN_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
translation_key="indoor_return_temp",
),
SensorEntityDescription(
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
key=AZD_INDOOR_WORK_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
translation_key="indoor_work_temp",
),
SensorEntityDescription(
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
key=AZD_OUTDOOR_CONDENSER_PRESS,
native_unit_of_measurement=UnitOfPressure.KPA,
state_class=SensorStateClass.MEASUREMENT,
translation_key="outdoor_condenser_press",
),
SensorEntityDescription(
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
key=AZD_OUTDOOR_DISCHARGE_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
translation_key="outdoor_discharge_temp",
),
SensorEntityDescription(
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
key=AZD_OUTDOOR_ELECTRIC_CURRENT,
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
state_class=SensorStateClass.MEASUREMENT,
translation_key="outdoor_electric_current",
),
SensorEntityDescription(
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
key=AZD_OUTDOOR_EVAPORATOR_PRESS,
native_unit_of_measurement=UnitOfPressure.KPA,
state_class=SensorStateClass.MEASUREMENT,
translation_key="outdoor_evaporator_press",
),
SensorEntityDescription(
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
key=AZD_OUTDOOR_EXCHANGER_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
translation_key="outdoor_exchanger_temp",
),
SensorEntityDescription(
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
key=AZD_OUTDOOR_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
translation_key="outdoor_temp",
),
SensorEntityDescription(
device_class=SensorDeviceClass.TEMPERATURE,
key=AZD_TEMP,

View File

@@ -45,6 +45,33 @@
"free_memory": {
"name": "Free memory"
},
"indoor_exchanger_temp": {
"name": "Indoor exchanger temperature"
},
"indoor_return_temp": {
"name": "Indoor return temperature"
},
"indoor_work_temp": {
"name": "Indoor working temperature"
},
"outdoor_condenser_press": {
"name": "Outdoor condenser pressure"
},
"outdoor_discharge_temp": {
"name": "Outdoor discharge temperature"
},
"outdoor_electric_current": {
"name": "Outdoor electric current"
},
"outdoor_evaporator_press": {
"name": "Outdoor evaporator pressure"
},
"outdoor_exchanger_temp": {
"name": "Outdoor exchanger temperature"
},
"outdoor_temp": {
"name": "Outdoor temperature"
},
"thermostat_coverage": {
"name": "Signal percentage"
}

View File

@@ -15,12 +15,26 @@
}
},
"services": {
"alarm_arm_away": "mdi:shield-lock",
"alarm_arm_home": "mdi:shield-home",
"alarm_arm_night": "mdi:shield-moon",
"alarm_arm_custom_bypass": "mdi:security",
"alarm_disarm": "mdi:shield-off",
"alarm_trigger": "mdi:bell-ring",
"alarm_arm_vacation": "mdi:shield-airplane"
"alarm_arm_away": {
"service": "mdi:shield-lock"
},
"alarm_arm_home": {
"service": "mdi:shield-home"
},
"alarm_arm_night": {
"service": "mdi:shield-moon"
},
"alarm_arm_custom_bypass": {
"service": "mdi:security"
},
"alarm_disarm": {
"service": "mdi:shield-off"
},
"alarm_trigger": {
"service": "mdi:bell-ring"
},
"alarm_arm_vacation": {
"service": "mdi:shield-airplane"
}
}
}

View File

@@ -7,7 +7,11 @@
}
},
"services": {
"alarm_keypress": "mdi:dialpad",
"alarm_toggle_chime": "mdi:abc"
"alarm_keypress": {
"service": "mdi:dialpad"
},
"alarm_toggle_chime": {
"service": "mdi:abc"
}
}
}

View File

@@ -1,7 +1,13 @@
{
"services": {
"toggle": "mdi:bell-ring",
"turn_off": "mdi:bell-off",
"turn_on": "mdi:bell-alert"
"toggle": {
"service": "mdi:bell-ring"
},
"turn_off": {
"service": "mdi:bell-off"
},
"turn_on": {
"service": "mdi:bell-alert"
}
}
}

View File

@@ -661,9 +661,12 @@ class RemoteCapabilities(AlexaEntity):
def interfaces(self) -> Generator[AlexaCapability]:
"""Yield the supported interfaces."""
yield AlexaPowerController(self.entity)
yield AlexaModeController(
self.entity, instance=f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}"
)
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
activities = self.entity.attributes.get(remote.ATTR_ACTIVITY_LIST) or []
if activities and supported & remote.RemoteEntityFeature.ACTIVITY:
yield AlexaModeController(
self.entity, instance=f"{remote.DOMAIN}.{remote.ATTR_ACTIVITY}"
)
yield AlexaEndpointHealth(self.hass, self.entity)
yield Alexa(self.entity)

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from collections import defaultdict
import logging
from typing import Any, Final
@@ -114,6 +115,8 @@ def get_engine(
all_voices: dict[str, dict[str, str]] = {}
all_engines: dict[str, set[str]] = defaultdict(set)
all_voices_req = polly_client.describe_voices()
for voice in all_voices_req.get("Voices", []):
@@ -124,8 +127,12 @@ def get_engine(
language_code: str | None = voice.get("LanguageCode")
if language_code is not None and language_code not in supported_languages:
supported_languages.append(language_code)
for engine in voice.get("SupportedEngines"):
all_engines[engine].add(voice_id)
return AmazonPollyProvider(polly_client, config, supported_languages, all_voices)
return AmazonPollyProvider(
polly_client, config, supported_languages, all_voices, all_engines
)
class AmazonPollyProvider(Provider):
@@ -137,13 +144,16 @@ class AmazonPollyProvider(Provider):
config: ConfigType,
supported_languages: list[str],
all_voices: dict[str, dict[str, str]],
all_engines: dict[str, set[str]],
) -> None:
"""Initialize Amazon Polly provider for TTS."""
self.client = polly_client
self.config = config
self.supported_langs = supported_languages
self.all_voices = all_voices
self.all_engines = all_engines
self.default_voice: str = self.config[CONF_VOICE]
self.default_engine: str = self.config[CONF_ENGINE]
self.name = "Amazon Polly"
@property
@@ -159,12 +169,12 @@ class AmazonPollyProvider(Provider):
@property
def default_options(self) -> dict[str, str]:
"""Return dict include default options."""
return {CONF_VOICE: self.default_voice}
return {CONF_VOICE: self.default_voice, CONF_ENGINE: self.default_engine}
@property
def supported_options(self) -> list[str]:
"""Return a list of supported options."""
return [CONF_VOICE]
return [CONF_VOICE, CONF_ENGINE]
def get_tts_audio(
self,
@@ -179,9 +189,14 @@ class AmazonPollyProvider(Provider):
_LOGGER.error("%s does not support the %s language", voice_id, language)
return None, None
engine = options.get(CONF_ENGINE, self.default_engine)
if voice_id not in self.all_engines[engine]:
_LOGGER.error("%s does not support the %s engine", voice_id, engine)
return None, None
_LOGGER.debug("Requesting TTS file for text: %s", message)
resp = self.client.synthesize_speech(
Engine=self.config[CONF_ENGINE],
Engine=engine,
OutputFormat=self.config[CONF_OUTPUT_FORMAT],
SampleRate=self.config[CONF_SAMPLE_RATE],
Text=message,

View File

@@ -7,5 +7,5 @@
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["aioambient"],
"requirements": ["aioambient==2024.01.0"]
"requirements": ["aioambient==2024.08.0"]
}

View File

@@ -7,5 +7,5 @@
"integration_type": "hub",
"iot_class": "cloud_push",
"loggers": ["aioambient"],
"requirements": ["aioambient==2024.01.0"]
"requirements": ["aioambient==2024.08.0"]
}

View File

@@ -1,15 +1,37 @@
{
"services": {
"enable_recording": "mdi:record-rec",
"disable_recording": "mdi:stop",
"enable_audio": "mdi:volume-high",
"disable_audio": "mdi:volume-off",
"enable_motion_recording": "mdi:motion-sensor",
"disable_motion_recording": "mdi:motion-sensor-off",
"goto_preset": "mdi:pan",
"set_color_bw": "mdi:palette",
"start_tour": "mdi:panorama",
"stop_tour": "mdi:panorama-outline",
"ptz_control": "mdi:pan"
"enable_recording": {
"service": "mdi:record-rec"
},
"disable_recording": {
"service": "mdi:stop"
},
"enable_audio": {
"service": "mdi:volume-high"
},
"disable_audio": {
"service": "mdi:volume-off"
},
"enable_motion_recording": {
"service": "mdi:motion-sensor"
},
"disable_motion_recording": {
"service": "mdi:motion-sensor-off"
},
"goto_preset": {
"service": "mdi:pan"
},
"set_color_bw": {
"service": "mdi:palette"
},
"start_tour": {
"service": "mdi:panorama"
},
"stop_tour": {
"service": "mdi:panorama-outline"
},
"ptz_control": {
"service": "mdi:pan"
}
}
}

View File

@@ -1,8 +1,16 @@
{
"services": {
"adb_command": "mdi:console",
"download": "mdi:download",
"upload": "mdi:upload",
"learn_sendevent": "mdi:remote"
"adb_command": {
"service": "mdi:console"
},
"download": {
"service": "mdi:download"
},
"upload": {
"service": "mdi:upload"
},
"learn_sendevent": {
"service": "mdi:remote"
}
}
}

View File

@@ -8,6 +8,6 @@
"iot_class": "local_push",
"loggers": ["androidtvremote2"],
"quality_scale": "platinum",
"requirements": ["androidtvremote2==0.1.1"],
"requirements": ["androidtvremote2==0.1.2"],
"zeroconf": ["_androidtvremote2._tcp.local."]
}

View File

@@ -8,7 +8,7 @@ LOGGER = logging.getLogger(__package__)
CONF_RECOMMENDED = "recommended"
CONF_PROMPT = "prompt"
CONF_CHAT_MODEL = "chat_model"
RECOMMENDED_CHAT_MODEL = "claude-3-5-sonnet-20240620"
RECOMMENDED_CHAT_MODEL = "claude-3-haiku-20240307"
CONF_MAX_TOKENS = "max_tokens"
RECOMMENDED_MAX_TOKENS = 1024
CONF_TEMPERATURE = "temperature"

View File

@@ -6,4 +6,4 @@ DOMAIN: Final = "apcupsd"
CONNECTION_TIMEOUT: int = 10
# Field name of last self test retrieved from apcupsd.
LASTSTEST: Final = "laststest"
LAST_S_TEST: Final = "laststest"

View File

@@ -13,7 +13,6 @@ from homeassistant.components.sensor import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
PERCENTAGE,
STATE_UNKNOWN,
UnitOfApparentPower,
UnitOfElectricCurrent,
UnitOfElectricPotential,
@@ -26,7 +25,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, LASTSTEST
from .const import DOMAIN, LAST_S_TEST
from .coordinator import APCUPSdCoordinator
PARALLEL_UPDATES = 0
@@ -157,8 +156,8 @@ SENSORS: dict[str, SensorEntityDescription] = {
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
),
LASTSTEST: SensorEntityDescription(
key=LASTSTEST,
LAST_S_TEST: SensorEntityDescription(
key=LAST_S_TEST,
translation_key="last_self_test",
),
"lastxfer": SensorEntityDescription(
@@ -423,7 +422,7 @@ async def async_setup_entry(
# periodical (or manual) self test since last daemon restart. It might not be available
# when we set up the integration, and we do not know if it would ever be available. Here we
# add it anyway and mark it as unknown initially.
for resource in available_resources | {LASTSTEST}:
for resource in available_resources | {LAST_S_TEST}:
if resource not in SENSORS:
_LOGGER.warning("Invalid resource from APCUPSd: %s", resource.upper())
continue
@@ -484,7 +483,7 @@ class APCUPSdSensor(CoordinatorEntity[APCUPSdCoordinator], SensorEntity):
# performed) and may disappear again after certain event. So we mark the state as "unknown"
# when it becomes unknown after such events.
if key not in self.coordinator.data:
self._attr_native_value = STATE_UNKNOWN
self._attr_native_value = None
return
self._attr_native_value, inferred_unit = infer_unit(self.coordinator.data[key])

View File

@@ -56,7 +56,7 @@ class AquaCellConfigFlow(ConfigFlow, domain=DOMAIN):
refresh_token = await api.authenticate(
user_input[CONF_EMAIL], user_input[CONF_PASSWORD]
)
except ApiException:
except (ApiException, TimeoutError):
errors["base"] = "cannot_connect"
except AuthenticationFailed:
errors["base"] = "invalid_auth"

View File

@@ -56,7 +56,7 @@ class AquacellCoordinator(DataUpdateCoordinator[dict[str, Softener]]):
so entities can quickly look up their data.
"""
async with asyncio.timeout(10):
async with asyncio.timeout(30):
# Check if the refresh token is expired
expiry_time = (
self.refresh_token_creation_time
@@ -72,7 +72,7 @@ class AquacellCoordinator(DataUpdateCoordinator[dict[str, Softener]]):
softeners = await self.aquacell_api.get_all_softeners()
except AuthenticationFailed as err:
raise ConfigEntryError from err
except AquacellApiException as err:
except (AquacellApiException, TimeoutError) as err:
raise UpdateFailed(f"Error communicating with API: {err}") from err
return {softener.dsn: softener for softener in softeners}

View File

@@ -101,7 +101,7 @@ class AsekoConfigFlow(ConfigFlow, domain=DOMAIN):
)
async def async_step_reauth(
self, user_input: Mapping[str, Any]
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Perform reauth upon an API authentication error."""
@@ -109,10 +109,10 @@ class AsekoConfigFlow(ConfigFlow, domain=DOMAIN):
self.context["entry_id"]
)
return await self.async_step_reauth_confirm(user_input)
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(
self, user_input: Mapping | None = None
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Dialog that informs the user that reauth is required."""

View File

@@ -3,6 +3,7 @@
from __future__ import annotations
from collections.abc import AsyncIterable
from typing import Any
import voluptuous as vol
@@ -16,6 +17,7 @@ from .const import (
DATA_LAST_WAKE_UP,
DOMAIN,
EVENT_RECORDING,
OPTION_PREFERRED,
SAMPLE_CHANNELS,
SAMPLE_RATE,
SAMPLE_WIDTH,
@@ -57,6 +59,7 @@ __all__ = (
"PipelineNotFound",
"WakeWordSettings",
"EVENT_RECORDING",
"OPTION_PREFERRED",
"SAMPLES_PER_CHUNK",
"SAMPLE_RATE",
"SAMPLE_WIDTH",
@@ -99,7 +102,7 @@ async def async_pipeline_from_audio_stream(
wake_word_phrase: str | None = None,
pipeline_id: str | None = None,
conversation_id: str | None = None,
tts_audio_output: str | None = None,
tts_audio_output: str | dict[str, Any] | None = None,
wake_word_settings: WakeWordSettings | None = None,
audio_settings: AudioSettings | None = None,
device_id: str | None = None,

View File

@@ -5,6 +5,7 @@ from dataclasses import dataclass
import logging
from pymicro_vad import MicroVad
from pyspeex_noise import AudioProcessor
from .const import BYTES_PER_CHUNK
@@ -41,8 +42,8 @@ class AudioEnhancer(ABC):
"""Enhance chunk of PCM audio @ 16Khz with 16-bit mono samples."""
class MicroVadEnhancer(AudioEnhancer):
"""Audio enhancer that just runs microVAD."""
class MicroVadSpeexEnhancer(AudioEnhancer):
"""Audio enhancer that runs microVAD and speex."""
def __init__(
self, auto_gain: int, noise_suppression: int, is_vad_enabled: bool
@@ -50,6 +51,24 @@ class MicroVadEnhancer(AudioEnhancer):
"""Initialize audio enhancer."""
super().__init__(auto_gain, noise_suppression, is_vad_enabled)
self.audio_processor: AudioProcessor | None = None
# Scale from 0-4
self.noise_suppression = noise_suppression * -15
# Scale from 0-31
self.auto_gain = auto_gain * 300
if (self.auto_gain != 0) or (self.noise_suppression != 0):
self.audio_processor = AudioProcessor(
self.auto_gain, self.noise_suppression
)
_LOGGER.debug(
"Initialized speex with auto_gain=%s, noise_suppression=%s",
self.auto_gain,
self.noise_suppression,
)
self.vad: MicroVad | None = None
self.threshold = 0.5
@@ -61,12 +80,17 @@ class MicroVadEnhancer(AudioEnhancer):
"""Enhance 10ms chunk of PCM audio @ 16Khz with 16-bit mono samples."""
is_speech: bool | None = None
assert len(audio) == BYTES_PER_CHUNK
if self.vad is not None:
# Run VAD
assert len(audio) == BYTES_PER_CHUNK
speech_prob = self.vad.Process10ms(audio)
is_speech = speech_prob > self.threshold
if self.audio_processor is not None:
# Run noise suppression and auto gain
audio = self.audio_processor.Process10ms(audio).audio
return EnhancedAudioChunk(
audio=audio, timestamp_ms=timestamp_ms, is_speech=is_speech
)

View File

@@ -22,3 +22,5 @@ SAMPLE_CHANNELS = 1 # mono
MS_PER_CHUNK = 10
SAMPLES_PER_CHUNK = SAMPLE_RATE // (1000 // MS_PER_CHUNK) # 10 ms @ 16Khz
BYTES_PER_CHUNK = SAMPLES_PER_CHUNK * SAMPLE_WIDTH * SAMPLE_CHANNELS # 16-bit
OPTION_PREFERRED = "preferred"

View File

@@ -7,5 +7,5 @@
"integration_type": "system",
"iot_class": "local_push",
"quality_scale": "internal",
"requirements": ["pymicro-vad==1.0.1"]
"requirements": ["pymicro-vad==1.0.1", "pyspeex-noise==1.0.2"]
}

View File

@@ -49,7 +49,7 @@ from homeassistant.util import (
)
from homeassistant.util.limited_size_dict import LimitedSizeDict
from .audio_enhancer import AudioEnhancer, EnhancedAudioChunk, MicroVadEnhancer
from .audio_enhancer import AudioEnhancer, EnhancedAudioChunk, MicroVadSpeexEnhancer
from .const import (
BYTES_PER_CHUNK,
CONF_DEBUG_RECORDING_DIR,
@@ -504,7 +504,7 @@ class AudioSettings:
is_vad_enabled: bool = True
"""True if VAD is used to determine the end of the voice command."""
silence_seconds: float = 0.5
silence_seconds: float = 0.7
"""Seconds of silence after voice command has ended."""
def __post_init__(self) -> None:
@@ -538,7 +538,7 @@ class PipelineRun:
language: str = None # type: ignore[assignment]
runner_data: Any | None = None
intent_agent: str | None = None
tts_audio_output: str | None = None
tts_audio_output: str | dict[str, Any] | None = None
wake_word_settings: WakeWordSettings | None = None
audio_settings: AudioSettings = field(default_factory=AudioSettings)
@@ -589,7 +589,7 @@ class PipelineRun:
# Initialize with audio settings
if self.audio_settings.needs_processor and (self.audio_enhancer is None):
# Default audio enhancer
self.audio_enhancer = MicroVadEnhancer(
self.audio_enhancer = MicroVadSpeexEnhancer(
self.audio_settings.auto_gain_dbfs,
self.audio_settings.noise_suppression_level,
self.audio_settings.is_vad_enabled,
@@ -906,6 +906,8 @@ class PipelineRun:
metadata,
self._speech_to_text_stream(audio_stream=stream, stt_vad=stt_vad),
)
except (asyncio.CancelledError, TimeoutError):
raise # expected
except Exception as src_error:
_LOGGER.exception("Unexpected error during speech-to-text")
raise SpeechToTextError(
@@ -1052,12 +1054,15 @@ class PipelineRun:
if self.pipeline.tts_voice is not None:
tts_options[tts.ATTR_VOICE] = self.pipeline.tts_voice
if self.tts_audio_output is not None:
if isinstance(self.tts_audio_output, dict):
tts_options.update(self.tts_audio_output)
elif isinstance(self.tts_audio_output, str):
tts_options[tts.ATTR_PREFERRED_FORMAT] = self.tts_audio_output
if self.tts_audio_output == "wav":
# 16 Khz, 16-bit mono
tts_options[tts.ATTR_PREFERRED_SAMPLE_RATE] = SAMPLE_RATE
tts_options[tts.ATTR_PREFERRED_SAMPLE_CHANNELS] = SAMPLE_CHANNELS
tts_options[tts.ATTR_PREFERRED_SAMPLE_BYTES] = SAMPLE_WIDTH
try:
options_supported = await tts.async_support_options(

View File

@@ -9,12 +9,10 @@ from homeassistant.const import EntityCategory, Platform
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import collection, entity_registry as er, restore_state
from .const import DOMAIN
from .const import DOMAIN, OPTION_PREFERRED
from .pipeline import AssistDevice, PipelineData, PipelineStorageCollection
from .vad import VadSensitivity
OPTION_PREFERRED = "preferred"
@callback
def get_chosen_pipeline(

View File

@@ -78,6 +78,9 @@ class VoiceCommandSegmenter:
speech_seconds: float = 0.3
"""Seconds of speech before voice command has started."""
command_seconds: float = 1.0
"""Minimum number of seconds for a voice command."""
silence_seconds: float = 0.7
"""Seconds of silence after voice command has ended."""
@@ -96,6 +99,9 @@ class VoiceCommandSegmenter:
_speech_seconds_left: float = 0.0
"""Seconds left before considering voice command as started."""
_command_seconds_left: float = 0.0
"""Seconds left before voice command could stop."""
_silence_seconds_left: float = 0.0
"""Seconds left before considering voice command as stopped."""
@@ -112,6 +118,7 @@ class VoiceCommandSegmenter:
def reset(self) -> None:
"""Reset all counters and state."""
self._speech_seconds_left = self.speech_seconds
self._command_seconds_left = self.command_seconds - self.speech_seconds
self._silence_seconds_left = self.silence_seconds
self._timeout_seconds_left = self.timeout_seconds
self._reset_seconds_left = self.reset_seconds
@@ -142,6 +149,9 @@ class VoiceCommandSegmenter:
if self._speech_seconds_left <= 0:
# Inside voice command
self.in_command = True
self._command_seconds_left = (
self.command_seconds - self.speech_seconds
)
self._silence_seconds_left = self.silence_seconds
_LOGGER.debug("Voice command started")
else:
@@ -154,7 +164,8 @@ class VoiceCommandSegmenter:
# Silence in command
self._reset_seconds_left = self.reset_seconds
self._silence_seconds_left -= chunk_seconds
if self._silence_seconds_left <= 0:
self._command_seconds_left -= chunk_seconds
if (self._silence_seconds_left <= 0) and (self._command_seconds_left <= 0):
# Command finished successfully
self.reset()
_LOGGER.debug("Voice command finished")
@@ -163,6 +174,7 @@ class VoiceCommandSegmenter:
# Speech in command.
# Reset silence counter if enough speech.
self._reset_seconds_left -= chunk_seconds
self._command_seconds_left -= chunk_seconds
if self._reset_seconds_left <= 0:
self._silence_seconds_left = self.silence_seconds
self._reset_seconds_left = self.reset_seconds

View File

@@ -0,0 +1,65 @@
"""Base class for assist satellite entities."""
import logging
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import ConfigType
from .const import DOMAIN, AssistSatelliteEntityFeature
from .entity import AssistSatelliteEntity, AssistSatelliteEntityDescription
from .errors import SatelliteBusyError
from .websocket_api import async_register_websocket_api
__all__ = [
"DOMAIN",
"AssistSatelliteEntity",
"AssistSatelliteEntityDescription",
"AssistSatelliteEntityFeature",
"SatelliteBusyError",
]
_LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
component = hass.data[DOMAIN] = EntityComponent[AssistSatelliteEntity](
_LOGGER, DOMAIN, hass
)
await component.async_setup(config)
component.async_register_entity_service(
"announce",
vol.All(
cv.make_entity_service_schema(
{
vol.Optional("message"): str,
vol.Optional("media_id"): str,
}
),
cv.has_at_least_one_key("message", "media_id"),
),
"async_internal_announce",
[AssistSatelliteEntityFeature.ANNOUNCE],
)
async_register_websocket_api(hass)
return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up a config entry."""
component: EntityComponent[AssistSatelliteEntity] = hass.data[DOMAIN]
return await component.async_setup_entry(entry)
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
component: EntityComponent[AssistSatelliteEntity] = hass.data[DOMAIN]
return await component.async_unload_entry(entry)

View File

@@ -0,0 +1,12 @@
"""Constants for assist satellite."""
from enum import IntFlag
DOMAIN = "assist_satellite"
class AssistSatelliteEntityFeature(IntFlag):
"""Supported features of Assist satellite entity."""
ANNOUNCE = 1
"""Device supports remotely triggered announcements."""

View File

@@ -0,0 +1,332 @@
"""Assist satellite entity."""
from abc import abstractmethod
import asyncio
from collections.abc import AsyncIterable
from enum import StrEnum
import logging
import time
from typing import Any, Final, final
from homeassistant.components import media_source, stt, tts
from homeassistant.components.assist_pipeline import (
OPTION_PREFERRED,
AudioSettings,
PipelineEvent,
PipelineEventType,
PipelineStage,
async_get_pipeline,
async_get_pipelines,
async_pipeline_from_audio_stream,
vad,
)
from homeassistant.components.media_player import async_process_play_media_url
from homeassistant.components.tts.media_source import (
generate_media_source_id as tts_generate_media_source_id,
)
from homeassistant.core import Context, callback
from homeassistant.helpers import entity
from homeassistant.helpers.entity import EntityDescription
from homeassistant.util import ulid
from .const import AssistSatelliteEntityFeature
from .errors import AssistSatelliteError, SatelliteBusyError
_CONVERSATION_TIMEOUT_SEC: Final = 5 * 60 # 5 minutes
_LOGGER = logging.getLogger(__name__)
class AssistSatelliteState(StrEnum):
"""Valid states of an Assist satellite entity."""
LISTENING_WAKE_WORD = "listening_wake_word"
"""Device is streaming audio for wake word detection to Home Assistant."""
LISTENING_COMMAND = "listening_command"
"""Device is streaming audio with the voice command to Home Assistant."""
PROCESSING = "processing"
"""Home Assistant is processing the voice command."""
RESPONDING = "responding"
"""Device is speaking the response."""
class AssistSatelliteEntityDescription(EntityDescription, frozen_or_thawed=True):
"""A class that describes Assist satellite entities."""
class AssistSatelliteEntity(entity.Entity):
"""Entity encapsulating the state and functionality of an Assist satellite."""
entity_description: AssistSatelliteEntityDescription
_attr_should_poll = False
_attr_supported_features = AssistSatelliteEntityFeature(0)
_attr_pipeline_entity_id: str | None = None
_attr_vad_sensitivity_entity_id: str | None = None
_conversation_id: str | None = None
_conversation_id_time: float | None = None
_run_has_tts: bool = False
_is_announcing = False
_wake_word_intercept_future: asyncio.Future[str | None] | None = None
__assist_satellite_state = AssistSatelliteState.LISTENING_WAKE_WORD
@final
@property
def state(self) -> str | None:
"""Return state of the entity."""
return self.__assist_satellite_state
@property
def pipeline_entity_id(self) -> str | None:
"""Entity ID of the pipeline to use for the next conversation."""
return self._attr_pipeline_entity_id
@property
def vad_sensitivity_entity_id(self) -> str | None:
"""Entity ID of the VAD sensitivity to use for the next conversation."""
return self._attr_vad_sensitivity_entity_id
async def async_intercept_wake_word(self) -> str | None:
"""Intercept the next wake word from the satellite.
Returns the detected wake word phrase or None.
"""
if self._wake_word_intercept_future is not None:
raise SatelliteBusyError("Wake word interception already in progress")
# Will cause next wake word to be intercepted in
# async_accept_pipeline_from_satellite
self._wake_word_intercept_future = asyncio.Future()
_LOGGER.debug("Next wake word will be intercepted: %s", self.entity_id)
try:
return await self._wake_word_intercept_future
finally:
self._wake_word_intercept_future = None
async def async_internal_announce(
self,
message: str | None = None,
media_id: str | None = None,
) -> None:
"""Play and show an announcement on the satellite.
If media_id is not provided, message is synthesized to
audio with the selected pipeline.
If media_id is provided, it is played directly. It is possible
to omit the message and the satellite will not show any text.
Calls async_announce with message and media id.
"""
if message is None:
message = ""
if not media_id:
# Synthesize audio and get URL
pipeline_id = self._resolve_pipeline()
pipeline = async_get_pipeline(self.hass, pipeline_id)
tts_options: dict[str, Any] = {}
if pipeline.tts_voice is not None:
tts_options[tts.ATTR_VOICE] = pipeline.tts_voice
media_id = tts_generate_media_source_id(
self.hass,
message,
engine=pipeline.tts_engine,
language=pipeline.tts_language,
options=tts_options,
)
if media_source.is_media_source_id(media_id):
media = await media_source.async_resolve_media(
self.hass,
media_id,
None,
)
media_id = media.url
# Resolve to full URL
media_id = async_process_play_media_url(self.hass, media_id)
if self._is_announcing:
raise SatelliteBusyError
self._is_announcing = True
try:
# Block until announcement is finished
await self.async_announce(message, media_id)
finally:
self._is_announcing = False
async def async_announce(self, message: str, media_id: str) -> None:
"""Announce media on the satellite.
Should block until the announcement is done playing.
"""
raise NotImplementedError
async def async_accept_pipeline_from_satellite(
self,
audio_stream: AsyncIterable[bytes],
start_stage: PipelineStage = PipelineStage.STT,
end_stage: PipelineStage = PipelineStage.TTS,
wake_word_phrase: str | None = None,
) -> None:
"""Triggers an Assist pipeline in Home Assistant from a satellite."""
if self._wake_word_intercept_future and start_stage in (
PipelineStage.WAKE_WORD,
PipelineStage.STT,
):
if start_stage == PipelineStage.WAKE_WORD:
self._wake_word_intercept_future.set_exception(
AssistSatelliteError(
"Only on-device wake words currently supported"
)
)
return
# Intercepting wake word and immediately end pipeline
_LOGGER.debug(
"Intercepted wake word: %s (entity_id=%s)",
wake_word_phrase,
self.entity_id,
)
if wake_word_phrase is None:
self._wake_word_intercept_future.set_exception(
AssistSatelliteError("No wake word phrase provided")
)
else:
self._wake_word_intercept_future.set_result(wake_word_phrase)
self._internal_on_pipeline_event(PipelineEvent(PipelineEventType.RUN_END))
return
device_id = self.registry_entry.device_id if self.registry_entry else None
# Refresh context if necessary
if (
(self._context is None)
or (self._context_set is None)
or ((time.time() - self._context_set) > entity.CONTEXT_RECENT_TIME_SECONDS)
):
self.async_set_context(Context())
assert self._context is not None
# Reset conversation id if necessary
if (self._conversation_id_time is None) or (
(time.monotonic() - self._conversation_id_time) > _CONVERSATION_TIMEOUT_SEC
):
self._conversation_id = None
if self._conversation_id is None:
self._conversation_id = ulid.ulid()
# Update timeout
self._conversation_id_time = time.monotonic()
# Set entity state based on pipeline events
self._run_has_tts = False
await async_pipeline_from_audio_stream(
self.hass,
context=self._context,
event_callback=self._internal_on_pipeline_event,
stt_metadata=stt.SpeechMetadata(
language="", # set in async_pipeline_from_audio_stream
format=stt.AudioFormats.WAV,
codec=stt.AudioCodecs.PCM,
bit_rate=stt.AudioBitRates.BITRATE_16,
sample_rate=stt.AudioSampleRates.SAMPLERATE_16000,
channel=stt.AudioChannels.CHANNEL_MONO,
),
stt_stream=audio_stream,
pipeline_id=self._resolve_pipeline(),
conversation_id=self._conversation_id,
device_id=device_id,
tts_audio_output="wav",
wake_word_phrase=wake_word_phrase,
audio_settings=AudioSettings(
silence_seconds=self._resolve_vad_sensitivity()
),
start_stage=start_stage,
end_stage=end_stage,
)
@abstractmethod
def on_pipeline_event(self, event: PipelineEvent) -> None:
"""Handle pipeline events."""
@callback
def _internal_on_pipeline_event(self, event: PipelineEvent) -> None:
"""Set state based on pipeline stage."""
if event.type is PipelineEventType.WAKE_WORD_START:
self._set_state(AssistSatelliteState.LISTENING_WAKE_WORD)
elif event.type is PipelineEventType.STT_START:
self._set_state(AssistSatelliteState.LISTENING_COMMAND)
elif event.type is PipelineEventType.INTENT_START:
self._set_state(AssistSatelliteState.PROCESSING)
elif event.type is PipelineEventType.TTS_START:
# Wait until tts_response_finished is called to return to waiting state
self._run_has_tts = True
self._set_state(AssistSatelliteState.RESPONDING)
elif event.type is PipelineEventType.RUN_END:
if not self._run_has_tts:
self._set_state(AssistSatelliteState.LISTENING_WAKE_WORD)
self.on_pipeline_event(event)
@callback
def _set_state(self, state: AssistSatelliteState) -> None:
"""Set the entity's state."""
self.__assist_satellite_state = state
self.async_write_ha_state()
@callback
def tts_response_finished(self) -> None:
"""Tell entity that the text-to-speech response has finished playing."""
self._set_state(AssistSatelliteState.LISTENING_WAKE_WORD)
@callback
def _resolve_pipeline(self) -> str | None:
"""Resolve pipeline from select entity to id.
Return None to make async_get_pipeline look up the preferred pipeline.
"""
if not (pipeline_entity_id := self.pipeline_entity_id):
return None
if (pipeline_entity_state := self.hass.states.get(pipeline_entity_id)) is None:
raise RuntimeError("Pipeline entity not found")
if pipeline_entity_state.state != OPTION_PREFERRED:
# Resolve pipeline by name
for pipeline in async_get_pipelines(self.hass):
if pipeline.name == pipeline_entity_state.state:
return pipeline.id
return None
@callback
def _resolve_vad_sensitivity(self) -> float:
"""Resolve VAD sensitivity from select entity to enum."""
vad_sensitivity = vad.VadSensitivity.DEFAULT
if vad_sensitivity_entity_id := self.vad_sensitivity_entity_id:
if (
vad_sensitivity_state := self.hass.states.get(vad_sensitivity_entity_id)
) is None:
raise RuntimeError("VAD sensitivity entity not found")
vad_sensitivity = vad.VadSensitivity(vad_sensitivity_state.state)
return vad.VadSensitivity.to_seconds(vad_sensitivity)

View File

@@ -0,0 +1,11 @@
"""Errors for assist satellite."""
from homeassistant.exceptions import HomeAssistantError
class AssistSatelliteError(HomeAssistantError):
"""Base class for assist satellite errors."""
class SatelliteBusyError(AssistSatelliteError):
"""Satellite is busy and cannot handle the request."""

View File

@@ -0,0 +1,12 @@
{
"entity_component": {
"_": {
"default": "mdi:account-voice"
}
},
"services": {
"announce": {
"service": "mdi:bullhorn"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"domain": "assist_satellite",
"name": "Assist Satellite",
"codeowners": ["@home-assistant/core", "@synesthesiam"],
"dependencies": ["assist_pipeline", "stt", "tts"],
"documentation": "https://www.home-assistant.io/integrations/assist_satellite",
"integration_type": "entity",
"quality_scale": "internal"
}

View File

@@ -0,0 +1,16 @@
announce:
target:
entity:
domain: assist_satellite
supported_features:
- assist_satellite.AssistSatelliteEntityFeature.ANNOUNCE
fields:
message:
required: false
example: "Time to wake up!"
selector:
text:
media_id:
required: false
selector:
text:

View File

@@ -0,0 +1,30 @@
{
"title": "Assist satellite",
"entity_component": {
"_": {
"name": "Assist satellite",
"state": {
"listening_wake_word": "Wake word",
"listening_command": "Voice command",
"responding": "Responding",
"processing": "Processing"
}
}
},
"services": {
"announce": {
"name": "Announce",
"description": "Let the satellite announce a message.",
"fields": {
"message": {
"name": "Message",
"description": "The message to announce."
},
"media_id": {
"name": "Media ID",
"description": "The media ID to announce instead of using text-to-speech."
}
}
}
}
}

View File

@@ -0,0 +1,46 @@
"""Assist satellite Websocket API."""
from typing import Any
import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_component import EntityComponent
from .const import DOMAIN
from .entity import AssistSatelliteEntity
@callback
def async_register_websocket_api(hass: HomeAssistant) -> None:
"""Register the websocket API."""
websocket_api.async_register_command(hass, websocket_intercept_wake_word)
@callback
@websocket_api.websocket_command(
{
vol.Required("type"): "assist_satellite/intercept_wake_word",
vol.Required("entity_id"): cv.entity_domain(DOMAIN),
}
)
@websocket_api.require_admin
@websocket_api.async_response
async def websocket_intercept_wake_word(
hass: HomeAssistant,
connection: websocket_api.connection.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Intercept the next wake word from a satellite."""
component: EntityComponent[AssistSatelliteEntity] = hass.data[DOMAIN]
satellite = component.get_entity(msg["entity_id"])
if satellite is None:
connection.send_error(
msg["id"], websocket_api.ERR_NOT_FOUND, "Entity not found"
)
return
wake_word_phrase = await satellite.async_intercept_wake_word()
connection.send_result(msg["id"], {"wake_word_phrase": wake_word_phrase})

View File

@@ -5,6 +5,7 @@ from __future__ import annotations
from abc import ABC, abstractmethod
from collections import namedtuple
from collections.abc import Awaitable, Callable, Coroutine
from datetime import datetime
import functools
import logging
from typing import Any, cast
@@ -40,17 +41,23 @@ from .const import (
PROTOCOL_HTTPS,
PROTOCOL_TELNET,
SENSORS_BYTES,
SENSORS_CPU,
SENSORS_LOAD_AVG,
SENSORS_MEMORY,
SENSORS_RATES,
SENSORS_TEMPERATURES,
SENSORS_TEMPERATURES_LEGACY,
SENSORS_UPTIME,
)
SENSORS_TYPE_BYTES = "sensors_bytes"
SENSORS_TYPE_COUNT = "sensors_count"
SENSORS_TYPE_CPU = "sensors_cpu"
SENSORS_TYPE_LOAD_AVG = "sensors_load_avg"
SENSORS_TYPE_MEMORY = "sensors_memory"
SENSORS_TYPE_RATES = "sensors_rates"
SENSORS_TYPE_TEMPERATURES = "sensors_temperatures"
SENSORS_TYPE_UPTIME = "sensors_uptime"
WrtDevice = namedtuple("WrtDevice", ["ip", "name", "connected_to"]) # noqa: PYI024
@@ -346,6 +353,7 @@ class AsusWrtHttpBridge(AsusWrtBridge):
async def async_get_available_sensors(self) -> dict[str, dict[str, Any]]:
"""Return a dictionary of available sensors for this bridge."""
sensors_cpu = await self._get_available_cpu_sensors()
sensors_temperatures = await self._get_available_temperature_sensors()
sensors_loadavg = await self._get_loadavg_sensors_availability()
return {
@@ -353,20 +361,49 @@ class AsusWrtHttpBridge(AsusWrtBridge):
KEY_SENSORS: SENSORS_BYTES,
KEY_METHOD: self._get_bytes,
},
SENSORS_TYPE_CPU: {
KEY_SENSORS: sensors_cpu,
KEY_METHOD: self._get_cpu_usage,
},
SENSORS_TYPE_LOAD_AVG: {
KEY_SENSORS: sensors_loadavg,
KEY_METHOD: self._get_load_avg,
},
SENSORS_TYPE_MEMORY: {
KEY_SENSORS: SENSORS_MEMORY,
KEY_METHOD: self._get_memory_usage,
},
SENSORS_TYPE_RATES: {
KEY_SENSORS: SENSORS_RATES,
KEY_METHOD: self._get_rates,
},
SENSORS_TYPE_UPTIME: {
KEY_SENSORS: SENSORS_UPTIME,
KEY_METHOD: self._get_uptime,
},
SENSORS_TYPE_TEMPERATURES: {
KEY_SENSORS: sensors_temperatures,
KEY_METHOD: self._get_temperatures,
},
}
async def _get_available_cpu_sensors(self) -> list[str]:
"""Check which cpu information is available on the router."""
try:
available_cpu = await self._api.async_get_cpu_usage()
available_sensors = [t for t in SENSORS_CPU if t in available_cpu]
except AsusWrtError as exc:
_LOGGER.warning(
(
"Failed checking cpu sensor availability for ASUS router"
" %s. Exception: %s"
),
self.host,
exc,
)
return []
return available_sensors
async def _get_available_temperature_sensors(self) -> list[str]:
"""Check which temperature information is available on the router."""
try:
@@ -415,3 +452,25 @@ class AsusWrtHttpBridge(AsusWrtBridge):
async def _get_temperatures(self) -> Any:
"""Fetch temperatures information from the router."""
return await self._api.async_get_temperatures()
@handle_errors_and_zip(AsusWrtError, None)
async def _get_cpu_usage(self) -> Any:
"""Fetch cpu information from the router."""
return await self._api.async_get_cpu_usage()
@handle_errors_and_zip(AsusWrtError, None)
async def _get_memory_usage(self) -> Any:
"""Fetch memory information from the router."""
return await self._api.async_get_memory_usage()
async def _get_uptime(self) -> dict[str, Any]:
"""Fetch uptime from the router."""
try:
uptimes = await self._api.async_get_uptime()
except AsusWrtError as exc:
raise UpdateFailed(exc) from exc
last_boot = datetime.fromisoformat(uptimes["last_boot"])
uptime = uptimes["uptime"]
return dict(zip(SENSORS_UPTIME, [last_boot, uptime], strict=False))

View File

@@ -27,7 +27,20 @@ PROTOCOL_TELNET = "telnet"
# Sensors
SENSORS_BYTES = ["sensor_rx_bytes", "sensor_tx_bytes"]
SENSORS_CONNECTED_DEVICE = ["sensor_connected_device"]
SENSORS_CPU = [
"cpu_total_usage",
"cpu1_usage",
"cpu2_usage",
"cpu3_usage",
"cpu4_usage",
"cpu5_usage",
"cpu6_usage",
"cpu7_usage",
"cpu8_usage",
]
SENSORS_LOAD_AVG = ["sensor_load_avg1", "sensor_load_avg5", "sensor_load_avg15"]
SENSORS_MEMORY = ["mem_usage_perc", "mem_free", "mem_used"]
SENSORS_RATES = ["sensor_rx_rates", "sensor_tx_rates"]
SENSORS_TEMPERATURES_LEGACY = ["2.4GHz", "5.0GHz", "CPU"]
SENSORS_TEMPERATURES = [*SENSORS_TEMPERATURES_LEGACY, "5.0GHz_2", "6.0GHz"]
SENSORS_UPTIME = ["sensor_last_boot", "sensor_uptime"]

View File

@@ -24,6 +24,21 @@
},
"load_avg_15m": {
"default": "mdi:cpu-32-bit"
},
"cpu_usage": {
"default": "mdi:cpu-32-bit"
},
"cpu_core_usage": {
"default": "mdi:cpu-32-bit"
},
"memory_usage": {
"default": "mdi:memory"
},
"memory_free": {
"default": "mdi:memory"
},
"memory_used": {
"default": "mdi:memory"
}
}
}

View File

@@ -11,10 +11,12 @@ from homeassistant.components.sensor import (
SensorStateClass,
)
from homeassistant.const import (
PERCENTAGE,
EntityCategory,
UnitOfDataRate,
UnitOfInformation,
UnitOfTemperature,
UnitOfTime,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@@ -30,9 +32,12 @@ from .const import (
KEY_SENSORS,
SENSORS_BYTES,
SENSORS_CONNECTED_DEVICE,
SENSORS_CPU,
SENSORS_LOAD_AVG,
SENSORS_MEMORY,
SENSORS_RATES,
SENSORS_TEMPERATURES,
SENSORS_UPTIME,
)
from .router import AsusWrtRouter
@@ -46,6 +51,19 @@ class AsusWrtSensorEntityDescription(SensorEntityDescription):
UNIT_DEVICES = "Devices"
CPU_CORE_SENSORS: tuple[AsusWrtSensorEntityDescription, ...] = tuple(
AsusWrtSensorEntityDescription(
key=sens_key,
translation_key="cpu_core_usage",
translation_placeholders={"core_id": str(core_id)},
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
suggested_display_precision=1,
)
for core_id, sens_key in enumerate(SENSORS_CPU[1:], start=1)
)
CONNECTION_SENSORS: tuple[AsusWrtSensorEntityDescription, ...] = (
AsusWrtSensorEntityDescription(
key=SENSORS_CONNECTED_DEVICE[0],
@@ -167,6 +185,61 @@ CONNECTION_SENSORS: tuple[AsusWrtSensorEntityDescription, ...] = (
entity_registry_enabled_default=False,
suggested_display_precision=1,
),
AsusWrtSensorEntityDescription(
key=SENSORS_MEMORY[0],
translation_key="memory_usage",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
suggested_display_precision=1,
),
AsusWrtSensorEntityDescription(
key=SENSORS_MEMORY[1],
translation_key="memory_free",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.DATA_SIZE,
native_unit_of_measurement=UnitOfInformation.MEGABYTES,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
suggested_display_precision=2,
factor=1024,
),
AsusWrtSensorEntityDescription(
key=SENSORS_MEMORY[2],
translation_key="memory_used",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.DATA_SIZE,
native_unit_of_measurement=UnitOfInformation.MEGABYTES,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
suggested_display_precision=2,
factor=1024,
),
AsusWrtSensorEntityDescription(
key=SENSORS_UPTIME[0],
translation_key="last_boot",
device_class=SensorDeviceClass.TIMESTAMP,
),
AsusWrtSensorEntityDescription(
key=SENSORS_UPTIME[1],
translation_key="uptime",
state_class=SensorStateClass.TOTAL,
device_class=SensorDeviceClass.DURATION,
native_unit_of_measurement=UnitOfTime.SECONDS,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
),
AsusWrtSensorEntityDescription(
key=SENSORS_CPU[0],
translation_key="cpu_usage",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
suggested_display_precision=1,
),
*CPU_CORE_SENSORS,
)

View File

@@ -88,6 +88,27 @@
},
"6ghz_temperature": {
"name": "6GHz Temperature"
},
"cpu_usage": {
"name": "CPU usage"
},
"cpu_core_usage": {
"name": "CPU core {core_id} usage"
},
"memory_usage": {
"name": "Memory usage"
},
"memory_free": {
"name": "Memory free"
},
"memory_used": {
"name": "Memory used"
},
"last_boot": {
"name": "Last boot"
},
"uptime": {
"name": "Uptime"
}
}
},

View File

@@ -6,15 +6,16 @@ from pathlib import Path
from typing import cast
from aiohttp import ClientResponseError
from yalexs.const import Brand
from yalexs.exceptions import AugustApiAIOHTTPError
from yalexs.manager.exceptions import CannotConnect, InvalidAuth, RequireValidation
from yalexs.manager.gateway import Config as YaleXSConfig
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers import device_registry as dr, issue_registry as ir
from .const import DOMAIN, PLATFORMS
from .data import AugustData
@@ -24,7 +25,27 @@ from .util import async_create_august_clientsession
type AugustConfigEntry = ConfigEntry[AugustData]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
@callback
def _async_create_yale_brand_migration_issue(
hass: HomeAssistant, entry: AugustConfigEntry
) -> None:
"""Create an issue for a brand migration."""
ir.async_create_issue(
hass,
DOMAIN,
"yale_brand_migration",
breaks_in_ha_version="2024.9",
learn_more_url="https://www.home-assistant.io/integrations/yale",
translation_key="yale_brand_migration",
is_fixable=False,
severity=ir.IssueSeverity.CRITICAL,
translation_placeholders={
"migrate_url": "https://my.home-assistant.io/redirect/config_flow_start?domain=yale"
},
)
async def async_setup_entry(hass: HomeAssistant, entry: AugustConfigEntry) -> bool:
"""Set up August from a config entry."""
session = async_create_august_clientsession(hass)
august_gateway = AugustGateway(Path(hass.config.config_dir), session)
@@ -40,6 +61,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True
async def async_remove_entry(hass: HomeAssistant, entry: AugustConfigEntry) -> None:
"""Remove an August config entry."""
ir.async_delete_issue(hass, DOMAIN, "yale_brand_migration")
async def async_unload_entry(hass: HomeAssistant, entry: AugustConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
@@ -51,6 +77,8 @@ async def async_setup_august(
"""Set up the August component."""
config = cast(YaleXSConfig, entry.data)
await august_gateway.async_setup(config)
if august_gateway.api.brand == Brand.YALE_HOME:
_async_create_yale_brand_migration_issue(hass, entry)
await august_gateway.async_authenticate()
await august_gateway.async_refresh_access_token_if_needed()
data = entry.runtime_data = AugustData(hass, august_gateway)

View File

@@ -109,12 +109,11 @@ async def async_setup_entry(
for description in SENSOR_TYPES_DOORBELL
)
for doorbell in data.doorbells:
entities.extend(
AugustDoorbellBinarySensor(data, doorbell, description)
for description in SENSOR_TYPES_DOORBELL + SENSOR_TYPES_VIDEO_DOORBELL
)
entities.extend(
AugustDoorbellBinarySensor(data, doorbell, description)
for description in SENSOR_TYPES_DOORBELL + SENSOR_TYPES_VIDEO_DOORBELL
for doorbell in data.doorbells
)
async_add_entities(entities)

View File

@@ -5,7 +5,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AugustConfigEntry
from .entity import AugustEntityMixin
from .entity import AugustEntity
async def async_setup_entry(
@@ -18,7 +18,7 @@ async def async_setup_entry(
async_add_entities(AugustWakeLockButton(data, lock, "wake") for lock in data.locks)
class AugustWakeLockButton(AugustEntityMixin, ButtonEntity):
class AugustWakeLockButton(AugustEntity, ButtonEntity):
"""Representation of an August lock wake button."""
_attr_translation_key = "wake"

View File

@@ -16,7 +16,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AugustConfigEntry, AugustData
from .const import DEFAULT_NAME, DEFAULT_TIMEOUT
from .entity import AugustEntityMixin
from .entity import AugustEntity
_LOGGER = logging.getLogger(__name__)
@@ -38,7 +38,7 @@ async def async_setup_entry(
)
class AugustCamera(AugustEntityMixin, Camera):
class AugustCamera(AugustEntity, Camera):
"""An implementation of an August security camera."""
_attr_translation_key = "camera"

View File

@@ -9,7 +9,7 @@ from typing import Any
import aiohttp
import voluptuous as vol
from yalexs.authenticator_common import ValidationResult
from yalexs.const import BRANDS, DEFAULT_BRAND
from yalexs.const import BRANDS_WITHOUT_OAUTH, DEFAULT_BRAND, Brand
from yalexs.manager.exceptions import CannotConnect, InvalidAuth, RequireValidation
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
@@ -28,6 +28,12 @@ from .const import (
from .gateway import AugustGateway
from .util import async_create_august_clientsession
# The Yale Home Brand is not supported by the August integration
# anymore and should migrate to the Yale integration
AVAILABLE_BRANDS = BRANDS_WITHOUT_OAUTH.copy()
del AVAILABLE_BRANDS[Brand.YALE_HOME]
_LOGGER = logging.getLogger(__name__)
@@ -118,7 +124,7 @@ class AugustConfigFlow(ConfigFlow, domain=DOMAIN):
vol.Required(
CONF_BRAND,
default=self._user_auth_details.get(CONF_BRAND, DEFAULT_BRAND),
): vol.In(BRANDS),
): vol.In(AVAILABLE_BRANDS),
vol.Required(
CONF_LOGIN_METHOD,
default=self._user_auth_details.get(
@@ -208,7 +214,7 @@ class AugustConfigFlow(ConfigFlow, domain=DOMAIN):
vol.Required(
CONF_BRAND,
default=self._user_auth_details.get(CONF_BRAND, DEFAULT_BRAND),
): vol.In(BRANDS),
): vol.In(BRANDS_WITHOUT_OAUTH),
vol.Required(CONF_PASSWORD): str,
}
),

View File

@@ -20,7 +20,7 @@ from .const import MANUFACTURER
DEVICE_TYPES = ["keypad", "lock", "camera", "doorbell", "door", "bell"]
class AugustEntityMixin(Entity):
class AugustEntity(Entity):
"""Base implementation for August device."""
_attr_should_poll = False
@@ -87,7 +87,7 @@ class AugustEntityMixin(Entity):
self._update_from_data()
class AugustDescriptionEntity(AugustEntityMixin):
class AugustDescriptionEntity(AugustEntity):
"""An August entity with a description."""
def __init__(

View File

@@ -63,22 +63,17 @@ async def async_setup_entry(
) -> None:
"""Set up the august event platform."""
data = config_entry.runtime_data
entities: list[AugustEventEntity] = []
for lock in data.locks:
detail = data.get_device_detail(lock.device_id)
if detail.doorbell:
entities.extend(
AugustEventEntity(data, lock, description)
for description in TYPES_DOORBELL
)
for doorbell in data.doorbells:
entities.extend(
AugustEventEntity(data, doorbell, description)
for description in TYPES_DOORBELL + TYPES_VIDEO_DOORBELL
)
entities: list[AugustEventEntity] = [
AugustEventEntity(data, lock, description)
for description in TYPES_DOORBELL
for lock in data.locks
if (detail := data.get_device_detail(lock.device_id)) and detail.doorbell
]
entities.extend(
AugustEventEntity(data, doorbell, description)
for description in TYPES_DOORBELL + TYPES_VIDEO_DOORBELL
for doorbell in data.doorbells
)
async_add_entities(entities)
@@ -86,7 +81,6 @@ class AugustEventEntity(AugustDescriptionEntity, EventEntity):
"""An august event entity."""
entity_description: AugustEventEntityDescription
_attr_has_entity_name = True
_last_activity: Activity | None = None
@callback

View File

@@ -19,7 +19,7 @@ from homeassistant.helpers.restore_state import RestoreEntity
import homeassistant.util.dt as dt_util
from . import AugustConfigEntry, AugustData
from .entity import AugustEntityMixin
from .entity import AugustEntity
_LOGGER = logging.getLogger(__name__)
@@ -36,7 +36,7 @@ async def async_setup_entry(
async_add_entities(AugustLock(data, lock) for lock in data.locks)
class AugustLock(AugustEntityMixin, RestoreEntity, LockEntity):
class AugustLock(AugustEntity, RestoreEntity, LockEntity):
"""Representation of an August lock."""
_attr_name = None

View File

@@ -4,10 +4,6 @@
"codeowners": ["@bdraco"],
"config_flow": true,
"dhcp": [
{
"hostname": "yale-connect-plus",
"macaddress": "00177A*"
},
{
"hostname": "connect",
"macaddress": "D86162*"
@@ -28,5 +24,5 @@
"documentation": "https://www.home-assistant.io/integrations/august",
"iot_class": "cloud_push",
"loggers": ["pubnub", "yalexs"],
"requirements": ["yalexs==8.1.4", "yalexs-ble==2.4.3"]
"requirements": ["yalexs==8.6.3", "yalexs-ble==2.4.3"]
}

View File

@@ -4,7 +4,7 @@ from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any, Generic, TypeVar, cast
from typing import Any, cast
from yalexs.activity import ActivityType, LockOperationActivity
from yalexs.doorbell import Doorbell
@@ -42,7 +42,7 @@ from .const import (
OPERATION_METHOD_REMOTE,
OPERATION_METHOD_TAG,
)
from .entity import AugustDescriptionEntity, AugustEntityMixin
from .entity import AugustDescriptionEntity, AugustEntity
def _retrieve_device_battery_state(detail: LockDetail) -> int:
@@ -55,14 +55,13 @@ def _retrieve_linked_keypad_battery_state(detail: KeypadDetail) -> int | None:
return detail.battery_percentage
_T = TypeVar("_T", LockDetail, KeypadDetail)
@dataclass(frozen=True, kw_only=True)
class AugustSensorEntityDescription(SensorEntityDescription, Generic[_T]):
class AugustSensorEntityDescription[T: LockDetail | KeypadDetail](
SensorEntityDescription
):
"""Mixin for required keys."""
value_fn: Callable[[_T], int | None]
value_fn: Callable[[T], int | None]
SENSOR_TYPE_DEVICE_BATTERY = AugustSensorEntityDescription[LockDetail](
@@ -114,7 +113,7 @@ async def async_setup_entry(
async_add_entities(entities)
class AugustOperatorSensor(AugustEntityMixin, RestoreSensor):
class AugustOperatorSensor(AugustEntity, RestoreSensor):
"""Representation of an August lock operation sensor."""
_attr_translation_key = "operator"
@@ -198,10 +197,12 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreSensor):
self._operated_autorelock = last_attrs[ATTR_OPERATION_AUTORELOCK]
class AugustBatterySensor(AugustDescriptionEntity, SensorEntity, Generic[_T]):
class AugustBatterySensor[T: LockDetail | KeypadDetail](
AugustDescriptionEntity, SensorEntity
):
"""Representation of an August sensor."""
entity_description: AugustSensorEntityDescription[_T]
entity_description: AugustSensorEntityDescription[T]
_attr_device_class = SensorDeviceClass.BATTERY
_attr_native_unit_of_measurement = PERCENTAGE

View File

@@ -1,4 +1,10 @@
{
"issues": {
"yale_brand_migration": {
"title": "Yale Home has a new integration",
"description": "Add the [Yale integration]({migrate_url}), and remove the August integration as soon as possible to avoid an interruption in service. The Yale Home brand will stop working with the August integration soon and will be removed in a future release."
}
},
"config": {
"error": {
"unhandled": "Unhandled error: {error}",

View File

@@ -63,16 +63,11 @@ def _activity_time_based(latest: Activity) -> Activity | None:
"""Get the latest state of the sensor."""
start = latest.activity_start_time
end = latest.activity_end_time + TIME_TO_DECLARE_DETECTION
if start <= _native_datetime() <= end:
if start <= datetime.now() <= end:
return latest
return None
def _native_datetime() -> datetime:
"""Return time in the format august uses without timezone."""
return datetime.now()
def retrieve_online_state(
data: AugustData, detail: DoorbellDetail | LockDetail
) -> bool:

View File

@@ -75,11 +75,10 @@ class AuroraABBConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 1
def __init__(self):
def __init__(self) -> None:
"""Initialise the config flow."""
self.config = None
self._com_ports_list: list[str] | None = None
self._default_com_port = None
self._default_com_port: str | None = None
async def async_step_user(
self, user_input: dict[str, Any] | None = None

View File

@@ -22,11 +22,11 @@ class AussieBroadbandConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 1
def __init__(self):
def __init__(self) -> None:
"""Initialize the config flow."""
self.data: dict = {}
self.options: dict = {CONF_SERVICES: []}
self.services: list[dict[str]] = []
self.services: list[dict[str, Any]] = []
self.client: AussieBB | None = None
self._reauth_username: str | None = None
@@ -99,15 +99,11 @@ class AussieBroadbandConfigFlow(ConfigFlow, domain=DOMAIN):
}
if not (errors := await self.async_auth(data)):
entry = await self.async_set_unique_id(self._reauth_username.lower())
if entry:
self.hass.config_entries.async_update_entry(
entry,
data=data,
)
await self.hass.config_entries.async_reload(entry.entry_id)
return self.async_abort(reason="reauth_successful")
return self.async_create_entry(title=self._reauth_username, data=data)
entry = self.hass.config_entries.async_get_entry(
self.context["entry_id"]
)
assert entry
return self.async_update_reload_and_abort(entry, data=data)
return self.async_show_form(
step_id="reauth_confirm",

View File

@@ -991,15 +991,15 @@ async def _create_automation_entities(
# Add trigger variables to variables
variables = None
if CONF_TRIGGER_VARIABLES in config_block:
if CONF_TRIGGER_VARIABLES in config_block and CONF_VARIABLES in config_block:
variables = ScriptVariables(
dict(config_block[CONF_TRIGGER_VARIABLES].as_dict())
)
if CONF_VARIABLES in config_block:
if variables:
variables.variables.update(config_block[CONF_VARIABLES].as_dict())
else:
variables = config_block[CONF_VARIABLES]
variables.variables.update(config_block[CONF_VARIABLES].as_dict())
elif CONF_TRIGGER_VARIABLES in config_block:
variables = config_block[CONF_TRIGGER_VARIABLES]
elif CONF_VARIABLES in config_block:
variables = config_block[CONF_VARIABLES]
entity = AutomationEntity(
automation_id,

View File

@@ -10,8 +10,10 @@ blueprint:
selector:
entity:
filter:
device_class: motion
domain: binary_sensor
- device_class: occupancy
domain: binary_sensor
- device_class: motion
domain: binary_sensor
light_target:
name: Light
selector:

View File

@@ -9,10 +9,20 @@
}
},
"services": {
"turn_on": "mdi:robot",
"turn_off": "mdi:robot-off",
"toggle": "mdi:robot",
"trigger": "mdi:robot",
"reload": "mdi:reload"
"turn_on": {
"service": "mdi:robot"
},
"turn_off": {
"service": "mdi:robot-off"
},
"toggle": {
"service": "mdi:robot"
},
"trigger": {
"service": "mdi:robot"
},
"reload": {
"service": "mdi:reload"
}
}
}

View File

@@ -293,6 +293,7 @@ class AwairSensor(CoordinatorEntity[AwairDataUpdateCoordinator], SensorEntity):
identifiers={(DOMAIN, self._device.uuid)},
manufacturer="Awair",
model=self._device.model,
model_id=self._device.device_type,
name=(
self._device.name
or cast(ConfigEntry, self.coordinator.config_entry).title

View File

@@ -1,6 +1,5 @@
"""Config flow for AWS component."""
from collections.abc import Mapping
from typing import Any
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
@@ -13,11 +12,9 @@ class AWSFlowHandler(ConfigFlow, domain=DOMAIN):
VERSION = 1
async def async_step_import(
self, user_input: Mapping[str, Any]
) -> ConfigFlowResult:
async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult:
"""Import a config entry."""
if self._async_current_entries():
return self.async_abort(reason="single_instance_allowed")
return self.async_create_entry(title="configuration.yaml", data=user_input)
return self.async_create_entry(title="configuration.yaml", data=import_data)

View File

@@ -6,8 +6,14 @@ import logging
from typing import Final
from aioazuredevops.client import DevOpsClient
from aioazuredevops.models.builds import Build
from aioazuredevops.helper import (
WorkItemTypeAndState,
work_item_types_states_filter,
work_items_by_type_and_state,
)
from aioazuredevops.models.build import Build
from aioazuredevops.models.core import Project
from aioazuredevops.models.work_item_type import Category
import aiohttp
from homeassistant.config_entries import ConfigEntry
@@ -20,6 +26,7 @@ from .const import CONF_ORG, DOMAIN
from .data import AzureDevOpsData
BUILDS_QUERY: Final = "?queryOrder=queueTimeDescending&maxBuildsPerDefinition=1"
IGNORED_CATEGORIES: Final[list[Category]] = [Category.COMPLETED, Category.REMOVED]
def ado_exception_none_handler(func: Callable) -> Callable:
@@ -105,13 +112,60 @@ class AzureDevOpsDataUpdateCoordinator(DataUpdateCoordinator[AzureDevOpsData]):
BUILDS_QUERY,
)
@ado_exception_none_handler
async def _get_work_items(
self, project_name: str
) -> list[WorkItemTypeAndState] | None:
"""Get the work items."""
if (
work_item_types := await self.client.get_work_item_types(
self.organization,
project_name,
)
) is None:
# If no work item types are returned, return an empty list
return []
if (
work_item_ids := await self.client.get_work_item_ids(
self.organization,
project_name,
# Filter out completed and removed work items so we only get active work items
states=work_item_types_states_filter(
work_item_types,
ignored_categories=IGNORED_CATEGORIES,
),
)
) is None:
# If no work item ids are returned, return an empty list
return []
if (
work_items := await self.client.get_work_items(
self.organization,
project_name,
work_item_ids,
)
) is None:
# If no work items are returned, return an empty list
return []
return work_items_by_type_and_state(
work_item_types,
work_items,
ignored_categories=IGNORED_CATEGORIES,
)
async def _async_update_data(self) -> AzureDevOpsData:
"""Fetch data from Azure DevOps."""
# Get the builds from the project
builds = await self._get_builds(self.project.name)
work_items = await self._get_work_items(self.project.name)
return AzureDevOpsData(
organization=self.organization,
project=self.project,
builds=builds,
work_items=work_items,
)

View File

@@ -2,7 +2,8 @@
from dataclasses import dataclass
from aioazuredevops.models.builds import Build
from aioazuredevops.helper import WorkItemTypeAndState
from aioazuredevops.models.build import Build
from aioazuredevops.models.core import Project
@@ -13,3 +14,4 @@ class AzureDevOpsData:
organization: str
project: Project
builds: list[Build]
work_items: list[WorkItemTypeAndState]

View File

@@ -3,6 +3,9 @@
"sensor": {
"latest_build": {
"default": "mdi:pipe"
},
"work_item_count": {
"default": "mdi:ticket"
}
}
}

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/azure_devops",
"iot_class": "cloud_polling",
"loggers": ["aioazuredevops"],
"requirements": ["aioazuredevops==2.1.1"]
"requirements": ["aioazuredevops==2.2.1"]
}

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