Compare commits

...

163 Commits

Author SHA1 Message Date
Erik 2f608d8650 Use numerical_value when compiling statistics 2023-02-01 14:03:33 +01:00
Erik 65324431a4 Add numerical_value state attribute to sensor 2023-02-01 13:58:43 +01:00
Franck Nijhof 4dba9c09fc Only report invalid numeric value for sensors once (#87010) 2023-01-31 12:44:18 +01:00
On Freund 35b82db8b0 Rympro integration code fixes (#86734)
* Address review comments

* Add coordinator.py to coveragerc

* Apply suggestions from code review

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>

* Update homeassistant/components/rympro/coordinator.py

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>

* Move SCAN_INTERVAL to coordinator.py

---------

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2023-01-31 10:40:43 +01:00
Martin Mauch a28e7e1541 Fix typo in EnOcean (#86868) 2023-01-31 09:49:37 +01:00
Bouwe Westerdijk 7f01d57965 Bump plugwise to v0.27.5 (#87001)
fixes undefined
2023-01-31 09:32:39 +01:00
epenet 0d018d53f1 Don't run tests if ruff fails (#87003) 2023-01-31 09:31:49 +01:00
Michael Davie be25d17e02 Bump env_canada to 0.5.27 (#86996)
fixes undefined
2023-01-31 08:56:27 +01:00
epenet 7db166b515 Fix tests typing helper (#86956) 2023-01-31 08:48:35 +01:00
Jan Bouwhuis 33ede351f0 Cleanup code for parsing yaml MQTT config (#86944)
* Cleanup code for parsing yaml configs

* Add abstractmethod decorator to async_update

* Replace get() with default-list ensured by schema
2023-01-31 08:24:33 +01:00
Paulus Schoutsen 1c4ba61725 Bump ESPHome Dashboard API 1.2.3 (#86997) 2023-01-31 00:05:59 -05:00
Michael Hansen f4654128db Add synesthesiam as a codeowner on intent (#86998) 2023-01-30 23:46:42 -05:00
Michael Hansen be69c81db5 Prioritize entity names over area names in Assist matching (#86982)
* Refactor async_match_states

* Check entity name after state, before aliases

* Give entity name matches priority over area names

* Don't force result to have area

* Add area alias in tests

* Move name/area list creation back

* Clean up PR

* More clean up
2023-01-30 23:46:25 -05:00
Marcel van der Veldt f8c6e4c20a Add support for Hue Smart Scenes (Natural Lights) (#85517)
* Bump aiohue to 4.6.0

* fix device name for lights

* fix name for groups too

* ignore smart scenes

* bump to 4.6.1 instead

* Add support for Smart Scenes (Natural lights) in Hue

* update base entity class

* fix test fixture

* update tests

* fix scene test

* fix typo

* use underlying scene controller

* use enum value

* update tests

* add current scene name within smart scene

* extra attributes are only valid if the scene is active

* Update v2_resources.json

* typo

* fix after merge
2023-01-30 23:32:37 -05:00
Paulus Schoutsen d88849fb04 ESPHome handle remove password and no encryption (#86995)
* ESPHome handle remove password and no encryption

* Start reauth for invalid api password

---------

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2023-01-30 23:05:48 -05:00
PeteRager e706696271 Nest - Climate shorten line to be less than 88 chars (#86989)
Lines to be less than 88
2023-01-30 19:14:24 -08:00
shbatm 53638ba138 Bump pyisy to 3.1.11 (#86981)
* Bump pyisy to 3.1.10

* Bump pyisy to 3.1.11
2023-01-30 21:36:51 -05:00
puddly 47453420c1 Bump ZHA dependencies (#86979)
Bump ZHA dependency bellows from 0.34.6 to 0.34.7
2023-01-30 21:35:27 -05:00
Bram Kragten 0c383e28c4 Update frontend to 20230130.0 (#86978) 2023-01-30 21:34:26 -05:00
Paulus Schoutsen 98b4a412f7 ESPHome discovered dashboard checks reauth flows (#86993) 2023-01-30 21:32:52 -05:00
GitHub Action da35ac1942 [ci skip] Translation update 2023-01-31 00:25:29 +00:00
mkmer 365ce55d77 Honeywell auto mode invalid attribute (#86728)
fixes undefined
2023-01-31 00:04:00 +01:00
Michael Hansen 28affe91be Set synesthesiam as codeowner of conversation (#86958) 2023-01-30 23:02:25 +01:00
Paulus Schoutsen 2cdeb6f1cd Check dashboard when showing reauth form (#86980) 2023-01-30 22:46:42 +01:00
Steven Looman 7e206b5854 Fix error on empty location in ssdp messages (#86970) 2023-01-30 22:43:58 +01:00
Franck Nijhof 1edd00c51f Allow any state class when using the precipitation device class (#86977) 2023-01-30 22:43:23 +01:00
ollo69 772df02cce Catch AndroidTV exception on setup (#86819)
fixes undefined
2023-01-30 22:42:32 +01:00
puddly 8337d4613e ZHA config flow cleanup (#86742)
fixes undefined
2023-01-30 22:21:34 +01:00
Steven Looman 50373500c3 Ensure a proper scope_id is given for IPv6 addresses when initializing the SSDP component (#86975)
fixes undefined
2023-01-30 22:14:48 +01:00
Paul Bottein a8b23d7139 Uses PolledSmartEnergySummation for ZLinky (#86960) 2023-01-30 22:10:55 +01:00
Raman Gupta c715534821 Bump zwave-js-server-python to 0.45.0 (#86771) 2023-01-30 14:27:37 -05:00
Paulus Schoutsen e0f8b5bbd1 Fix some mobile app sensor registration/update issues (#86965)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2023-01-30 20:08:19 +01:00
Michael Hansen f7fdaadde0 Performance improvements for Assist (#86966)
* Move hassil recognize into executor

* Bump hassil to 0.2.6

* Disable template parsing in name/area lists

* Don't iterate over hass.config.components directly
2023-01-30 12:25:22 -06:00
Jan Bouwhuis e57dad79fc Fix MQTT discovery failing after bad config update (#86935)
* Fix MQTT discovery failing after bad config update

* Update last discovery payload after update success

* Improve test, correct update assignment

* send_discovery_done to finally-catch vol.Error

* Just use try..finally

* Remove extra line

* use elif to avoid log confusion
2023-01-30 19:15:11 +01:00
J. Nick Koston 00118a6f96 Speed up live history setup if there is no pending data to commit (#86942) 2023-01-30 19:00:34 +01:00
J. Nick Koston f874258e7e Silence spurious warnings about removing ix_states_entity_id with newer installs (#86961)
* Silence spurious warnings about removing ix_states_entity_id with newer installs

https://ptb.discord.com/channels/330944238910963714/427516175237382144/1069648035459641465

* Silence spurious warnings about removing ix_states_entity_id with newer installs

https://ptb.discord.com/channels/330944238910963714/427516175237382144/1069648035459641465
2023-01-30 12:38:33 -05:00
Erik Montnemery 53c5f02ca2 Remove some dead code from recorder (#86697) 2023-01-30 18:37:48 +01:00
Shay Levy 857df05308 Add Shelly Gen2 update entity for sleeping devices (#86837) 2023-01-30 19:05:13 +02:00
PeteRager d22e670334 Avoid Nest climate set_temperature eating error (#86920)
* Update climate_sdm.py

* Update test case to detect KeyError

* Throw a defined exception if the condition in encoutered

Include keys from device_traits in error message

* Less diagnostic information in error message
2023-01-30 08:01:41 -08:00
Marc Mueller 2c12171e25 Update actions/cache to v3.2.4 (#86943) 2023-01-30 16:42:01 +01:00
Mick Vleeshouwer 98a79dd5a2 Fix ThreeWayHandle sensor in Overkiz integration (#86953)
Fix typo in sensor.py

Fixes https://github.com/home-assistant/core/issues/85913
2023-01-30 17:15:53 +02:00
Tom Puttemans 73cd03255f Ignore empty payloads from DSMR Reader (#86841)
* Ignore empty payloads from DSMR Reader

* Simplify empty payload handling

If the native value hasn't changed, requesting to store it won't have a performance impact.

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

---------

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2023-01-30 08:56:57 -05:00
Erik Montnemery d4489faa68 Drop minus sign on negative zero (#86939)
* Drop minus sign on negative zero

* Add tests
2023-01-30 08:31:27 -05:00
Maciej Bieniek 5f57648578 Use more human-readable sensor names in Airly (#86893)
* Use more human-readable sensor names

* Use abbreviations for long names
2023-01-30 08:29:06 -05:00
Ben Dews 21d1c647c5 Add configuration options to OpenAI integration (#86768)
* Added multiple features to OpenAI integration

* Fixed failed test

* Removed features and improved tests

* initiated component before starting options flow
2023-01-30 08:24:11 -05:00
Robert Hillis 032a37b121 Address Google mail late review (#86847) 2023-01-30 14:18:56 +01:00
Franck Nijhof 3b5fd4bd06 Enable Ruff TRY004 (#86811) 2023-01-30 14:06:52 +01:00
mkmer 7368c86ecb Add Reauth config flow to honeywell (#86170) 2023-01-30 13:57:14 +01:00
epenet 7e7a27f8b9 Add type hints to http client fixtures (#86795) 2023-01-30 13:40:07 +01:00
Maciej Bieniek cc36848a6d Use native_precision instead of round in Accuweather (#86869) 2023-01-30 12:36:24 +01:00
Nick Touran d2e75e4f7a Add Autofocus, IR lamp, and Wiper switches in ONVIF (#84317)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-01-30 12:08:07 +01:00
Maciej Bieniek d485630ce9 Use device class ENUM for Accuweather pressure tendency sensor (#86887)
* Use device class ENUM for pressure tendency sensor

* Format
2023-01-30 12:03:23 +01:00
Franck Nijhof a4fa0925b7 Small improvement to Withings tests (#86937) 2023-01-30 11:03:42 +01:00
Franck Nijhof c56832bb2c Enable Ruff SIM300 (#86793) 2023-01-30 11:03:23 +01:00
Franck Nijhof 9ac8f9aa37 Revert "Adjust D-Link entity naming" (#86936) 2023-01-30 10:56:56 +01:00
Robert Hillis 709d1cb8af Adjust D-Link entity naming (#86906) 2023-01-30 10:29:12 +01:00
Franck Nijhof 1958dd5550 Update ruff to v0.0.237 (#86932) 2023-01-30 10:15:24 +01:00
Malte Franken 92a833b192 Bump aio_geojson_generic_client to 0.3 (#86918) 2023-01-30 10:11:41 +01:00
J. Nick Koston 4e9bd09d39 Fix old indices not being removed in schema migration leading to slow MySQL queries (#86917)
fixes #83787
2023-01-29 21:33:23 -05:00
GitHub Action b82ecfdd28 [ci skip] Translation update 2023-01-30 00:21:11 +00:00
J. Nick Koston 0f4b17755e Improve logging and handling when websocket gets behind (#86854)
fixes undefined
2023-01-29 10:49:27 -10:00
J. Nick Koston c612a92cfb Use python defaults for comparing State, LazyState, and Event objects (#86856)
* Speed up comparing State and Event objects

Use default python implementation for State and Event __hash__ and __eq__

The default implementation compared based on the id() of the object
which is effectively what we want here anyways. These overrides are
left over from the days when these used to be attrs objects

By avoiding implementing these ourselves all of the equality checks
can happen in native code

* tweak

* adjust tests

* write out some more

* fix test to not compare objects

* more test fixes

* more test fixes

* correct stats tests

* fix more tests

* fix more tests

* update sensor recorder tests
2023-01-29 13:31:43 -05:00
Joakim Sørensen 80ffac48a3 Revert "Mark repo as safe directory to git config (#83755)" (#86888)
This reverts commit dc000d2289.
2023-01-29 13:07:50 -05:00
Allen Porter 4f965f0eca Bump pyrainbird to 2.0.0 (#86851) 2023-01-29 15:11:56 +01:00
Joakim Sørensen 569bf3bb76 Bump pytautulli from 21.11.0 to 23.1.1 (#86891) 2023-01-29 15:07:05 +01:00
Joakim Sørensen f9e8247401 Bump isort from 5.11.4 to 5.12.0 (#86890) 2023-01-29 15:04:17 +01:00
Malte Franken 344a0c55a5 Add integration_type to geo_json_events (#86878)
define integration type
2023-01-29 15:02:13 +01:00
Thomas Schamm 11e125f2e8 Add Bosch SHC description and host form strings (#86897)
* Add description to setup SHC II. Add missing host info in reauth_confirm

* Remove template value in en.json
2023-01-29 15:00:36 +01:00
J. Nick Koston 691a234090 Cache the names and area lists in the default agent (#86874)
* Cache the names and area lists in the default agent

fixes #86803

* add coverage to make sure the entity cache busts

* add areas test

* cover the last line
2023-01-29 07:16:29 -05:00
Maciej Bieniek eebc338c3b Support native_precision in Airly integration (#86843)
* Use native_precision

* Refactor extra_state_attributes
2023-01-29 11:44:23 +01:00
J. Nick Koston 58de7b8df0 Fix v32 schema migration when MySQL global.time_zone is configured with non-UTC timezone (#86867)
* Fix v32 schema migration when MySQL timezone is not UTC

* tweak
2023-01-28 22:06:07 -05:00
Martin Hjelmare b1e939d1f1 Fix tradfri air quality device class (#86861) 2023-01-28 22:05:31 -05:00
J. Nick Koston ec3475910f Improve websocket throughput of state changes (#86855)
After the start event we tend to get an event storm of state
changes which can get the websocket behind. #86854 will
help with that a bit, but we can reduce the overhead
to build a state diff when the attributes have not
changed
2023-01-28 22:05:06 -05:00
Robert Hillis 799edd90aa Fix D-Link attributes (#86842)
* Fix D-Link attributes

* fix blocking call
2023-01-28 22:03:58 -05:00
GitHub Action 0f6f63da64 [ci skip] Translation update 2023-01-29 00:26:29 +00:00
Paul Bottein e93bfa6556 Update frontend to 20230128.0 (#86838) 2023-01-28 18:49:29 -05:00
Jan Bouwhuis 6a94a58325 Correct stale doc string for MQTT tag platform (#86862) 2023-01-29 00:23:22 +02:00
PeteRager a7ddd592fb Nest improve error message on climate actions (#86853)
* Nest - Climate - Error Messages

1. Error messages were incorrect for some methods, for example async_set_temperature was reporting failure to set hvac_mode. This is corrected.
2. Error messages were incomplete and were not including the entity_id,and the operation being performed that failed.
3. Add unit tests to test the exception handling

* Move tests into exiisting error test

* Improve readability of error message
2023-01-28 12:58:28 -08:00
Allen Porter 733798f483 Fix nest climate set temperature error message string (#86852) 2023-01-28 11:02:46 -08:00
J. Nick Koston af5fd74d6f Bump ismartgate to 5.0.0 (#86830)
python 3.11 support

changelog: https://github.com/bdraco/ismartgate/compare/v4.0.4...v5.0.0
2023-01-28 07:14:36 +01:00
Luca Angemi efd2817221 Add state class to nest legacy sensors (#86810)
* Add state class to nest legacy sensors

Add state class (measurement) to humidity and temperature for the nest legacy sensors.

* Update

Update
2023-01-27 21:20:51 -08:00
J. Nick Koston d97a061285 Chunk MariaDB and Postgresql data migration to avoid running out of buffer space (#86680)
* Chunk MariaDB data migration to avoid running out of buffer space

This will make the migration slower but since the innodb_buffer_pool_size
is using the defaul to 128M and not tuned to the db size there is a
risk of running out of buffer space for large databases

* Update homeassistant/components/recorder/migration.py

* hard code since bandit thinks its an injection

* Update homeassistant/components/recorder/migration.py

* guard against manually modified data/corrupt db

* adjust to 10k per chunk

* adjust to 50k per chunk

* memory still just fine at 250k

* but slower

* commit after each chunk to reduce lock pressure

* adjust

* set to 0 if null so we do not loop forever (this should only happen if the data is missing)

* set to 0 if null so we do not loop forever (this should only happen if the data is missing)

* tweak

* tweak

* limit cleanup

* lower limit to give some more buffer

* lower limit to give some more buffer

* where required for sqlite

* sqlite can wipe as many as needed with no limit

* limit on mysql only

* chunk postgres

* fix limit

* tweak

* fix reference

* fix

* tweak for ram

* postgres memory reduction

* defer cleanup

* fix

* same order
2023-01-27 22:39:45 -05:00
shbatm e2edbc4259 Check for missing ISY994 Z-Wave Properties (#86829)
* Check for missing Z-Wave Properties

* Fix black from mobile
2023-01-27 22:16:28 -05:00
J. Nick Koston d0c7f42559 Fix Bluetooth discoveries missing between restarts (#86808)
* Fix Bluetooth discoveries missing between restarts

* do not load other integrations

* coverage
2023-01-27 22:16:16 -05:00
Robert Hillis b69576d6de Add D-link tests (#86825)
* Fix D-Link config flow auth

* Add tests to D-Link

* pyupgrade
2023-01-27 22:15:27 -05:00
Robert Hillis adb0d85511 Fix D-Link config flow auth (#86824) 2023-01-27 21:38:25 -05:00
GitHub Action 072f228e4d [ci skip] Translation update 2023-01-28 00:23:36 +00:00
Shay Levy 803cd8d9a3 Handle state unknown if last state is missing in Shelly (#86813)
Shelly - handle state unknown if last state is missing
2023-01-27 23:34:56 +01:00
Ville Skyttä 50c2992f36 Drop py39 from black target-version (#86814) 2023-01-27 22:39:52 +02:00
dependabot[bot] 15492aead0 Bump tibdex/github-app-token from 1.7.0 to 1.8.0 (#86767)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-27 20:35:56 +01:00
Bouwe Westerdijk 661f7e1522 Bump plugwise to v0.27.4 (#86812)
fixes undefined
2023-01-27 20:00:44 +01:00
Franck Nijhof e9543a7254 Enable Ruff PT021 (#86801) 2023-01-27 17:14:04 +01:00
Franck Nijhof 8f74bff354 Enable Ruff PLC0414 (#86799) 2023-01-27 16:32:04 +01:00
Shay Levy f9f9741d2a Separate Shelly tests parameters in parametrize (#86778)
Shelly tests - separate parameters in parametrize
2023-01-27 14:28:35 +01:00
Franck Nijhof ef800335fb Enable Ruff PT022 (#86792)
* Enable Ruff PT022

* Adjust found cases
2023-01-27 13:57:06 +01:00
Franck Nijhof 8c993116e1 Enable Ruff SIM401 (#86790)
* Enable Ruff SIM401

* Adjust found cases
2023-01-27 13:08:44 +01:00
Franck Nijhof bfbf9b9751 Adjusts imports in tests to match our relative import rules (#86788) 2023-01-27 12:51:58 +01:00
Franck Nijhof 89c0b27b42 Migrates tests to use UnitOfPressure enum (#86785) 2023-01-27 12:13:27 +01:00
epenet 561fc2d771 Remove deprecated unit system properties (#86643)
* Remove deprecated unit system properties

* Fix tests
2023-01-27 12:09:26 +01:00
Franck Nijhof 3ff3834cae Re-enable Ruff UP024 (#86784) 2023-01-27 12:03:27 +01:00
Franck Nijhof a79885ceaf Enable Ruff SIM117 (#86783) 2023-01-27 11:52:49 +01:00
Franck Nijhof 57cf11f067 Enable Ruff PT015 (#86775) 2023-01-27 11:10:29 +01:00
Franck Nijhof 49148421cb Migrates tests to use UnitOfSpeed enum (#86777) 2023-01-27 10:58:55 +01:00
Franck Nijhof fca3382d37 Migrates tests to use MediaPlayerEntityFeature enum (#86779) 2023-01-27 10:56:40 +01:00
Franck Nijhof 42c4f2f7fa Add ability for pytest to run only on changed tests in codebase (#86776) 2023-01-27 10:35:18 +01:00
Shay Levy ae6bc96002 Shelly code quality (#86733) 2023-01-27 10:47:05 +02:00
Franck Nijhof e4a78420b8 Enable Ruff PT013 (#86757)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-01-27 09:09:46 +01:00
Malte Franken bd9a8ba6f1 Bump aio_georss_gdacs to 0.8 (#86761)
bump aio_georss_gdacs to 0.8
2023-01-27 08:44:30 +01:00
Jesse Hills 78207121c0 Remove esphome password from config flow data if not needed (#86763)
* Remove esphome password if not needed

* Add test

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2023-01-26 21:45:51 -05:00
Paulus Schoutsen 687184138c ESPHome update: Store reference to runtime data, not one of its values (#86762)
Store reference to runtime data, not one of its values
2023-01-26 21:45:42 -05:00
Franck Nijhof e738924780 Enable Ruff SIM105 (#86759)
* Enable Ruff SIM105

* Adjust existing cases
2023-01-26 21:06:22 -05:00
GitHub Action 71d7098530 [ci skip] Translation update 2023-01-27 00:25:12 +00:00
Aaron Bach 020d52c3e2 Fix state class issues in Ambient PWS (#86758)
fixes undefined
2023-01-27 00:14:46 +01:00
Marc Mueller b84cf3a3d9 Improve bosch_shc config_flow typing (#86739) 2023-01-26 23:39:12 +01:00
Shay Levy 2c8cb13034 Bump aioshelly to 5.3.1 (#86751) 2023-01-27 00:34:31 +02:00
Paulus Schoutsen 9cd48b4999 OpenAI: Fix device without model (#86754) 2023-01-26 23:25:02 +01:00
tronikos 04bc522fa5 Google Assistant SDK: Test unload when enable_conversation_agent (#86707)
Test unload when enable_conversation_agent
2023-01-26 16:17:23 -05:00
Marc Mueller caa1ba7e13 Improve nuki typing (#86736)
* Use NukiCoordinator

* Make NukiEntity generic

* Remove unnecessary ABC
2023-01-26 23:03:36 +02:00
mkmer 138a522d2e Bump AIOAladdinConnect to 0.1.54 (#86749) 2023-01-26 23:00:54 +02:00
Franck Nijhof 62dcbe5258 Enable Ruff PT001 (#86730) 2023-01-26 18:05:05 +01:00
Franck Nijhof 7ed9967245 Fix state classes for duration device class (#86727) 2023-01-26 17:26:52 +01:00
epenet b3380261d7 Add hints to get_service in azure service bus (#86694) 2023-01-26 17:20:52 +01:00
Franck Nijhof eb5d63237c Update ruff to v0.0.235 (#86719) 2023-01-26 17:17:13 +01:00
epenet 2bef69c6a7 Add hints to get_service in integrations (1/2) (#86692) 2023-01-26 16:56:57 +01:00
epenet 0d579f6ac3 Add hints to get_service in integrations (2/2) (#86693) 2023-01-26 16:55:57 +01:00
epenet 8a5a1b810a Add hints to get_service in netgear-lte (#86700) 2023-01-26 16:54:57 +01:00
epenet 95d0329d6c Add hints to get_service in tplink-lte (#86702) 2023-01-26 16:53:24 +01:00
Franck Nijhof d4955a3d87 Replace assert False by raising an error (#86686) 2023-01-26 16:51:43 +01:00
Michael Hansen adeaf746ec Use device area id in intent matching (#86678)
* Use device area id when matching

* Normalize whitespace in response

* Add extra test entity
2023-01-26 09:48:49 -06:00
Franck Nijhof 38203003d2 Remove gas device class from current sensor in dsmr_reader (#86725) 2023-01-26 16:44:52 +01:00
epenet 25c451832b Remove pragma: no cover when not raising (#86706) 2023-01-26 16:34:05 +01:00
StefanIacobLivisi 468457eff4 Bump aiolivisi to 0.0.15 (#86721) 2023-01-26 16:28:16 +01:00
epenet 7af86fe130 Improve notify type hints (#86685) 2023-01-26 16:23:03 +01:00
Marc Mueller 54fcf58449 Use mypy caching [ci] (#86715) 2023-01-26 15:59:37 +01:00
Martin Hjelmare c727f403ff Bump python-matter-server to 2.0.2 (#86712) 2023-01-26 15:43:12 +01:00
Robert Svensson 4181a9baf0 Improve Axis config flow tests (#86644)
* Improve Axis config flow tests

* Don't use prepare_config_entry
2023-01-26 14:29:06 +01:00
David F. Mulcahey 6e285c87c3 Update Inovelli Blue Series switch support in ZHA (#86711) 2023-01-26 08:27:44 -05:00
Patrick ZAJDA 2e70de9dd9 Migrate Nuki to new entity naming style (#80021)
Co-authored-by: Pascal Vizeli <pvizeli@syshack.ch>
2023-01-26 13:50:19 +01:00
mkmer 6ea234ed57 Add DeviceInfo to Honeywell (#86179)
* Add DeviceInfo
Add has_entity_name

* has_entity_name to class attribute

* Update homeassistant/components/honeywell/sensor.py

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

* Update homeassistant/components/honeywell/sensor.py

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

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2023-01-26 13:28:36 +01:00
MHFDoge 282d6af2a2 Add known webostv button to list (#86674)
Add known button to list.
2023-01-26 13:55:07 +02:00
Pascal Reeb 484e73beaa Add device registration to the Nuki component (#79806)
* Add device registration to the Nuki component

* Name is always given by the API

* implement pvizeli's suggestions

* switch device_registry to snake_case

* fix entity naming

* unify manufacturer names
2023-01-26 12:38:10 +01:00
Robert Svensson 9a6e620810 Fix missing interface key in deCONZ logbook (#86684)
fixes undefined
2023-01-26 11:44:01 +01:00
epenet 1139555448 Add hints to get_service in kodi (#86698) 2023-01-26 11:40:48 +01:00
epenet cbcff6435f Add hints to get_service in joaoapps join (#86699) 2023-01-26 11:15:00 +01:00
Erik Montnemery fea30c1ce9 Terminate strings at NUL when recording states and events (#86687) 2023-01-26 11:11:03 +01:00
epenet b9ffc67a44 Add hints to get_service in syslog (#86701) 2023-01-26 11:10:50 +01:00
epenet ca8cc284ed Add hints to get_service in rest (#86703) 2023-01-26 11:08:06 +01:00
Paulus Schoutsen ff91fb7d74 Make openai conversation prompt template more readable + test case (#86676) 2023-01-26 11:04:15 +01:00
Franck Nijhof 021ac84405 Add recorder platform to required test category (#86704) 2023-01-26 11:03:56 +01:00
Franck Nijhof 17d3159e77 Remove unneeded use of keys() in ZHA (#86668)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2023-01-26 11:02:46 +01:00
Andrey Kupreychik fa7ad20372 Update ndms2_client to 0.1.2 (#86624)
fix https://github.com/home-assistant/core/issues/86379
fixes undefined
2023-01-26 08:53:20 +01:00
Paulus Schoutsen 28a3b4a32c Add error handling for OpenAI (#86671)
* Add error handling for OpenAI

* Simplify area filtering

* better prompt
2023-01-25 22:17:19 -05:00
David F. Mulcahey c395698ea2 Bump ZHA quirks lib (#86669) 2023-01-25 22:15:09 -05:00
Paulus Schoutsen e06603bbbd Google Assistant: unset agent on unload (#86635) 2023-01-25 21:33:30 -05:00
J. Nick Koston 4cafd393c6 Correct units on mopeka battery voltage sensor (#86663) 2023-01-26 02:14:59 +01:00
Franck Nijhof e50a531cd9 Code styling tweaks to the tests - Part 2 (#86662)
Co-authored-by: jjlawren <jjlawren@users.noreply.github.com>
2023-01-26 01:23:53 +01:00
GitHub Action 7ab88fa713 [ci skip] Translation update 2023-01-26 00:23:39 +00:00
Franck Nijhof 4955dd3e1b Code styling tweaks to Nexia tests (#86660) 2023-01-25 23:36:17 +01:00
J. Nick Koston 1d1d69ca02 Update scaffold scripts to use async_forward_entry_setups (#86647) 2023-01-25 21:26:31 +01:00
Robert Svensson a56f6cb863 Assert Axis config entry state not hass.data (#86648) 2023-01-25 21:15:03 +01:00
Franck Nijhof 7d672b4a4d Bump version to 2023.3.0dev0 (#86632) 2023-01-25 20:50:44 +01:00
Paulus Schoutsen df0fc30695 Fix oauth2 error (#86634) 2023-01-25 20:50:16 +01:00
Joakim Plate 1b97a51b5e Print expected device class units in error log (#86125) 2023-01-25 20:45:50 +01:00
1011 changed files with 13338 additions and 4784 deletions
+1 -4
View File
@@ -205,10 +205,7 @@ omit =
homeassistant/components/discord/notify.py
homeassistant/components/dlib_face_detect/image_processing.py
homeassistant/components/dlib_face_identify/image_processing.py
homeassistant/components/dlink/__init__.py
homeassistant/components/dlink/data.py
homeassistant/components/dlink/entity.py
homeassistant/components/dlink/switch.py
homeassistant/components/dominos/*
homeassistant/components/doods/*
homeassistant/components/doorbird/__init__.py
@@ -1001,6 +998,7 @@ omit =
homeassistant/components/russound_rio/media_player.py
homeassistant/components/russound_rnet/media_player.py
homeassistant/components/rympro/__init__.py
homeassistant/components/rympro/coordinator.py
homeassistant/components/rympro/sensor.py
homeassistant/components/sabnzbd/__init__.py
homeassistant/components/sabnzbd/sensor.py
@@ -1148,7 +1146,6 @@ omit =
homeassistant/components/stream/core.py
homeassistant/components/stream/fmp4utils.py
homeassistant/components/stream/hls.py
homeassistant/components/stream/recorder.py
homeassistant/components/stream/worker.py
homeassistant/components/streamlabswater/*
homeassistant/components/suez_water/*
+64 -109
View File
@@ -30,7 +30,8 @@ on:
env:
CACHE_VERSION: 3
PIP_CACHE_VERSION: 3
HA_SHORT_VERSION: 2023.2
MYPY_CACHE_VERSION: 3
HA_SHORT_VERSION: 2023.3
DEFAULT_PYTHON: "3.10"
ALL_PYTHON_VERSIONS: "['3.10']"
PRE_COMMIT_CACHE: ~/.cache/pre-commit
@@ -187,7 +188,7 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v3.2.3
uses: actions/cache@v3.2.4
with:
path: venv
key: >-
@@ -202,7 +203,7 @@ jobs:
pip install "$(cat requirements_test.txt | grep pre-commit)"
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v3.2.3
uses: actions/cache@v3.2.4
with:
path: ${{ env.PRE_COMMIT_CACHE }}
key: >-
@@ -231,30 +232,22 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if pre-commit cache restore failed
if: steps.cache-precommit.outputs.cache-hit != 'true'
run: |
echo "Failed to restore pre-commit environment from cache"
exit 1
- name: Run black (fully)
if: needs.info.outputs.test_full_suite == 'true'
run: |
@@ -285,30 +278,22 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if pre-commit cache restore failed
if: steps.cache-precommit.outputs.cache-hit != 'true'
run: |
echo "Failed to restore pre-commit environment from cache"
exit 1
- name: Register flake8 problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/flake8.json"
@@ -324,6 +309,7 @@ jobs:
. venv/bin/activate
shopt -s globstar
pre-commit run --hook-stage manual flake8 --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/{*,**/*}
lint-ruff:
name: Check ruff
runs-on: ubuntu-latest
@@ -341,30 +327,22 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if pre-commit cache restore failed
if: steps.cache-precommit.outputs.cache-hit != 'true'
run: |
echo "Failed to restore pre-commit environment from cache"
exit 1
- name: Register ruff problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/ruff.json"
@@ -380,6 +358,7 @@ jobs:
. venv/bin/activate
shopt -s globstar
pre-commit run --hook-stage manual ruff --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/{*,**/*}
lint-isort:
name: Check isort
runs-on: ubuntu-20.04
@@ -397,30 +376,22 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if pre-commit cache restore failed
if: steps.cache-precommit.outputs.cache-hit != 'true'
run: |
echo "Failed to restore pre-commit environment from cache"
exit 1
- name: Run isort
run: |
. venv/bin/activate
@@ -443,30 +414,22 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.pre-commit_cache_key }}
- name: Fail job if pre-commit cache restore failed
if: steps.cache-precommit.outputs.cache-hit != 'true'
run: |
echo "Failed to restore pre-commit environment from cache"
exit 1
- name: Run pyupgrade (fully)
if: needs.info.outputs.test_full_suite == 'true'
@@ -575,7 +538,7 @@ jobs:
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v3.2.3
uses: actions/cache@v3.2.4
with:
path: venv
key: >-
@@ -583,7 +546,7 @@ jobs:
needs.info.outputs.python_cache_key }}
- name: Restore pip wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v3.2.3
uses: actions/cache@v3.2.4
with:
path: ${{ env.PIP_CACHE }}
key: >-
@@ -637,17 +600,13 @@ jobs:
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Run hassfest
run: |
. venv/bin/activate
@@ -673,17 +632,13 @@ jobs:
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Run gen_requirements_all.py
run: |
. venv/bin/activate
@@ -710,17 +665,13 @@ jobs:
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Register pylint problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/pylint.json"
@@ -756,19 +707,33 @@ jobs:
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Generate partial mypy restore key
id: generate-mypy-key
run: |
mypy_version=$(cat requirements_test.txt | grep mypy | cut -d '=' -f 3)
echo "version=$mypy_version" >> $GITHUB_OUTPUT
echo "key=mypy-${{ env.MYPY_CACHE_VERSION }}-$mypy_version-${{
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Restore mypy cache
uses: actions/cache@v3.2.4
with:
path: .mypy_cache
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-mypy-key.outputs.key }}
restore-keys: |
${{ runner.os }}-${{ steps.python.outputs.python-version }}-mypy-${{
env.MYPY_CACHE_VERSION }}-${{ steps.generate-mypy-key.outputs.version }}-${{
env.HA_SHORT_VERSION }}-
- name: Register mypy problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/mypy.json"
@@ -810,17 +775,13 @@ jobs:
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Run pip check
run: |
. venv/bin/activate
@@ -840,8 +801,9 @@ jobs:
- gen-requirements-all
- hassfest
- lint-black
- lint-other
- lint-isort
- lint-other
- lint-ruff
- mypy
strategy:
fail-fast: false
@@ -867,16 +829,12 @@ jobs:
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Register Python problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/python.json"
@@ -965,8 +923,9 @@ jobs:
- gen-requirements-all
- hassfest
- lint-black
- lint-other
- lint-isort
- lint-other
- lint-ruff
- mypy
strategy:
fail-fast: false
@@ -992,16 +951,12 @@ jobs:
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v3.2.3
uses: actions/cache/restore@v3.2.4
with:
path: venv
fail-on-cache-miss: true
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Register Python problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/python.json"
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
id: token
# Pinned to a specific version of the action for security reasons
# v1.7.0
uses: tibdex/github-app-token@021a2405c7f990db57f5eae5397423dcc554159c
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.ISSUE_TRIAGE_APP_ID }}
private_key: ${{ secrets.ISSUE_TRIAGE_APP_PEM }}
+2 -2
View File
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.231
rev: v0.0.237
hooks:
- id: ruff
args:
@@ -60,7 +60,7 @@ repos:
- --configfile=tests/bandit.yaml
files: ^(homeassistant|script|tests)/.+\.py$
- repo: https://github.com/PyCQA/isort
rev: 5.11.4
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/pre-commit/pre-commit-hooks
+14
View File
@@ -27,6 +27,20 @@
},
"problemMatcher": []
},
{
"label": "Pytest (changed tests only)",
"type": "shell",
"command": "pytest --timeout=10 --picked",
"group": {
"kind": "test",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Flake8",
"type": "shell",
+6 -6
View File
@@ -211,8 +211,8 @@ build.json @home-assistant/supervisor
/tests/components/configurator/ @home-assistant/core
/homeassistant/components/control4/ @lawtancool
/tests/components/control4/ @lawtancool
/homeassistant/components/conversation/ @home-assistant/core
/tests/components/conversation/ @home-assistant/core
/homeassistant/components/conversation/ @home-assistant/core @synesthesiam
/tests/components/conversation/ @home-assistant/core @synesthesiam
/homeassistant/components/coolmaster/ @OnFreund
/tests/components/coolmaster/ @OnFreund
/homeassistant/components/coronavirus/ @home-assistant/core
@@ -566,8 +566,8 @@ build.json @home-assistant/supervisor
/tests/components/integration/ @dgomes
/homeassistant/components/intellifire/ @jeeftor
/tests/components/intellifire/ @jeeftor
/homeassistant/components/intent/ @home-assistant/core
/tests/components/intent/ @home-assistant/core
/homeassistant/components/intent/ @home-assistant/core @synesthesiam
/tests/components/intent/ @home-assistant/core @synesthesiam
/homeassistant/components/intesishome/ @jnimmo
/homeassistant/components/ios/ @robbiet480
/tests/components/ios/ @robbiet480
@@ -1003,8 +1003,8 @@ build.json @home-assistant/supervisor
/tests/components/ruuvi_gateway/ @akx
/homeassistant/components/ruuvitag_ble/ @akx
/tests/components/ruuvitag_ble/ @akx
/homeassistant/components/rympro/ @OnFreund
/tests/components/rympro/ @OnFreund
/homeassistant/components/rympro/ @OnFreund @elad-bar @maorcc
/tests/components/rympro/ @OnFreund @elad-bar @maorcc
/homeassistant/components/sabnzbd/ @shaiu
/tests/components/sabnzbd/ @shaiu
/homeassistant/components/safe_mode/ @home-assistant/core
+2
View File
@@ -19,6 +19,7 @@ coverage:
- homeassistant/components/*/intent.py
- homeassistant/components/*/logbook.py
- homeassistant/components/*/media_source.py
- homeassistant/components/*/recorder.py
- homeassistant/components/*/scene.py
patch:
default:
@@ -36,6 +37,7 @@ coverage:
- homeassistant/components/*/intent.py
- homeassistant/components/*/logbook.py
- homeassistant/components/*/media_source.py
- homeassistant/components/*/recorder.py
- homeassistant/components/*/scene.py
comment: false
@@ -2,7 +2,7 @@
"config": {
"abort": {
"reauth_successful": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u0442\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u043a\u0430\u0446\u0438\u044f \u0431\u0435\u0448\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u0430",
"single_instance_allowed": "\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0430 \u0435 \u0441\u0430\u043c\u043e \u0435\u0434\u043d\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043d\u0430 Abode."
"single_instance_allowed": "\u0412\u0435\u0447\u0435 \u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d\u043e. \u0412\u044a\u0437\u043c\u043e\u0436\u043d\u0430 \u0435 \u0441\u0430\u043c\u043e \u0435\u0434\u043d\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f."
},
"error": {
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0445 \u043f\u0440\u0438 \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435"
@@ -248,7 +248,8 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
state_class=SensorStateClass.MEASUREMENT,
metric_unit=UnitOfLength.METERS,
us_customary_unit=UnitOfLength.FEET,
value_fn=lambda data, unit: round(cast(float, data[unit][ATTR_VALUE])),
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
native_precision=0,
),
AccuWeatherSensorDescription(
key="CloudCover",
@@ -300,8 +301,10 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
),
AccuWeatherSensorDescription(
key="PressureTendency",
device_class=SensorDeviceClass.ENUM,
icon="mdi:gauge",
name="Pressure tendency",
options=["falling", "rising", "steady"],
translation_key="pressure_tendency",
value_fn=lambda data, _: cast(str, data["LocalizedText"]).lower(),
),
@@ -1,4 +1,6 @@
"""Config flow to configure Agent devices."""
from contextlib import suppress
from agent import AgentConnectionError, AgentError
from agent.a import Agent
import voluptuous as vol
@@ -31,10 +33,8 @@ class AgentFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
server_origin = generate_url(host, port)
agent_client = Agent(server_origin, async_get_clientsession(self.hass))
try:
with suppress(AgentConnectionError, AgentError):
await agent_client.update()
except (AgentConnectionError, AgentError):
pass
await agent_client.close()
+58 -70
View File
@@ -3,7 +3,7 @@ from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any, cast
from typing import Any
from homeassistant.components.sensor import (
SensorDeviceClass,
@@ -19,11 +19,10 @@ from homeassistant.const import (
UnitOfPressure,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceEntryType
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AirlyDataUpdateCoordinator
@@ -62,7 +61,7 @@ PARALLEL_UPDATES = 1
class AirlySensorEntityDescription(SensorEntityDescription):
"""Class describing Airly sensor entities."""
value: Callable = round
attrs: Callable[[dict[str, Any]], dict[str, Any]] = lambda data: {}
SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
@@ -70,12 +69,19 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
key=ATTR_API_CAQI,
icon="mdi:air-filter",
name=ATTR_API_CAQI,
native_precision=0,
native_unit_of_measurement="CAQI",
attrs=lambda data: {
ATTR_LEVEL: data[ATTR_API_CAQI_LEVEL],
ATTR_ADVICE: data[ATTR_API_ADVICE],
ATTR_DESCRIPTION: data[ATTR_API_CAQI_DESCRIPTION],
},
),
AirlySensorEntityDescription(
key=ATTR_API_PM1,
device_class=SensorDeviceClass.PM1,
name=ATTR_API_PM1,
name="PM1.0",
native_precision=0,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
),
@@ -83,28 +89,39 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
key=ATTR_API_PM25,
device_class=SensorDeviceClass.PM25,
name="PM2.5",
native_precision=0,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
attrs=lambda data: {
ATTR_LIMIT: data[f"{ATTR_API_PM25}_{SUFFIX_LIMIT}"],
ATTR_PERCENT: round(data[f"{ATTR_API_PM25}_{SUFFIX_PERCENT}"]),
},
),
AirlySensorEntityDescription(
key=ATTR_API_PM10,
device_class=SensorDeviceClass.PM10,
name=ATTR_API_PM10,
native_precision=0,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
attrs=lambda data: {
ATTR_LIMIT: data[f"{ATTR_API_PM10}_{SUFFIX_LIMIT}"],
ATTR_PERCENT: round(data[f"{ATTR_API_PM10}_{SUFFIX_PERCENT}"]),
},
),
AirlySensorEntityDescription(
key=ATTR_API_HUMIDITY,
device_class=SensorDeviceClass.HUMIDITY,
name=ATTR_API_HUMIDITY.capitalize(),
native_precision=1,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value=lambda value: round(value, 1),
),
AirlySensorEntityDescription(
key=ATTR_API_PRESSURE,
device_class=SensorDeviceClass.PRESSURE,
name=ATTR_API_PRESSURE.capitalize(),
native_precision=0,
native_unit_of_measurement=UnitOfPressure.HPA,
state_class=SensorStateClass.MEASUREMENT,
),
@@ -112,36 +129,56 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
key=ATTR_API_TEMPERATURE,
device_class=SensorDeviceClass.TEMPERATURE,
name=ATTR_API_TEMPERATURE.capitalize(),
native_precision=1,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
value=lambda value: round(value, 1),
),
AirlySensorEntityDescription(
key=ATTR_API_CO,
name=ATTR_API_CO,
name="Carbon monoxide",
native_precision=0,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
attrs=lambda data: {
ATTR_LIMIT: data[f"{ATTR_API_CO}_{SUFFIX_LIMIT}"],
ATTR_PERCENT: round(data[f"{ATTR_API_CO}_{SUFFIX_PERCENT}"]),
},
),
AirlySensorEntityDescription(
key=ATTR_API_NO2,
device_class=SensorDeviceClass.NITROGEN_DIOXIDE,
name=ATTR_API_NO2,
name="Nitrogen dioxide",
native_precision=0,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
attrs=lambda data: {
ATTR_LIMIT: data[f"{ATTR_API_NO2}_{SUFFIX_LIMIT}"],
ATTR_PERCENT: round(data[f"{ATTR_API_NO2}_{SUFFIX_PERCENT}"]),
},
),
AirlySensorEntityDescription(
key=ATTR_API_SO2,
device_class=SensorDeviceClass.SULPHUR_DIOXIDE,
name=ATTR_API_SO2,
name="Sulphur dioxide",
native_precision=0,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
attrs=lambda data: {
ATTR_LIMIT: data[f"{ATTR_API_SO2}_{SUFFIX_LIMIT}"],
ATTR_PERCENT: round(data[f"{ATTR_API_SO2}_{SUFFIX_PERCENT}"]),
},
),
AirlySensorEntityDescription(
key=ATTR_API_O3,
device_class=SensorDeviceClass.OZONE,
name=ATTR_API_O3,
name="Ozone",
native_precision=0,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
attrs=lambda data: {
ATTR_LIMIT: data[f"{ATTR_API_O3}_{SUFFIX_LIMIT}"],
ATTR_PERCENT: round(data[f"{ATTR_API_O3}_{SUFFIX_PERCENT}"]),
},
),
)
@@ -190,64 +227,15 @@ class AirlySensor(CoordinatorEntity[AirlyDataUpdateCoordinator], SensorEntity):
self._attr_unique_id = (
f"{coordinator.latitude}-{coordinator.longitude}-{description.key}".lower()
)
self._attrs: dict[str, Any] = {}
self._attr_native_value = coordinator.data[description.key]
self._attr_extra_state_attributes = description.attrs(coordinator.data)
self.entity_description = description
@property
def native_value(self) -> StateType:
"""Return the state."""
state = self.coordinator.data[self.entity_description.key]
return cast(StateType, self.entity_description.value(state))
@property
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes."""
if self.entity_description.key == ATTR_API_CAQI:
self._attrs[ATTR_LEVEL] = self.coordinator.data[ATTR_API_CAQI_LEVEL]
self._attrs[ATTR_ADVICE] = self.coordinator.data[ATTR_API_ADVICE]
self._attrs[ATTR_DESCRIPTION] = self.coordinator.data[
ATTR_API_CAQI_DESCRIPTION
]
if self.entity_description.key == ATTR_API_PM25:
self._attrs[ATTR_LIMIT] = self.coordinator.data[
f"{ATTR_API_PM25}_{SUFFIX_LIMIT}"
]
self._attrs[ATTR_PERCENT] = round(
self.coordinator.data[f"{ATTR_API_PM25}_{SUFFIX_PERCENT}"]
)
if self.entity_description.key == ATTR_API_PM10:
self._attrs[ATTR_LIMIT] = self.coordinator.data[
f"{ATTR_API_PM10}_{SUFFIX_LIMIT}"
]
self._attrs[ATTR_PERCENT] = round(
self.coordinator.data[f"{ATTR_API_PM10}_{SUFFIX_PERCENT}"]
)
if self.entity_description.key == ATTR_API_CO:
self._attrs[ATTR_LIMIT] = self.coordinator.data[
f"{ATTR_API_CO}_{SUFFIX_LIMIT}"
]
self._attrs[ATTR_PERCENT] = round(
self.coordinator.data[f"{ATTR_API_CO}_{SUFFIX_PERCENT}"]
)
if self.entity_description.key == ATTR_API_NO2:
self._attrs[ATTR_LIMIT] = self.coordinator.data[
f"{ATTR_API_NO2}_{SUFFIX_LIMIT}"
]
self._attrs[ATTR_PERCENT] = round(
self.coordinator.data[f"{ATTR_API_NO2}_{SUFFIX_PERCENT}"]
)
if self.entity_description.key == ATTR_API_SO2:
self._attrs[ATTR_LIMIT] = self.coordinator.data[
f"{ATTR_API_SO2}_{SUFFIX_LIMIT}"
]
self._attrs[ATTR_PERCENT] = round(
self.coordinator.data[f"{ATTR_API_SO2}_{SUFFIX_PERCENT}"]
)
if self.entity_description.key == ATTR_API_O3:
self._attrs[ATTR_LIMIT] = self.coordinator.data[
f"{ATTR_API_O3}_{SUFFIX_LIMIT}"
]
self._attrs[ATTR_PERCENT] = round(
self.coordinator.data[f"{ATTR_API_O3}_{SUFFIX_PERCENT}"]
)
return self._attrs
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._attr_native_value = self.coordinator.data[self.entity_description.key]
self._attr_extra_state_attributes = self.entity_description.attrs(
self.coordinator.data
)
self.async_write_ha_state()
@@ -12,8 +12,8 @@
"data": {
"api_key": "API \u043a\u043b\u044e\u0447 \u0437\u0430 Airly",
"latitude": "\u0428\u0438\u0440\u0438\u043d\u0430",
"longitude": "\u0414\u044a\u043b\u0436\u0438\u043d\u0430",
"name": "\u0418\u043c\u0435 \u043d\u0430 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f\u0442\u0430"
"longitude": "\u0413\u0435\u043e\u0433\u0440\u0430\u0444\u0441\u043a\u0430 \u0434\u044a\u043b\u0436\u0438\u043d\u0430",
"name": "\u0418\u043c\u0435"
},
"description": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e\u0442\u043e \u043d\u0430 \u0432\u044a\u0437\u0434\u0443\u0445\u0430 Airly \u0417\u0430 \u0434\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0430\u0442\u0435 \u043a\u043b\u044e\u0447 \u0437\u0430 API, \u043e\u0442\u0438\u0434\u0435\u0442\u0435 \u043d\u0430 https://developer.airly.eu/register"
}
@@ -2,7 +2,7 @@
"domain": "aladdin_connect",
"name": "Aladdin Connect",
"documentation": "https://www.home-assistant.io/integrations/aladdin_connect",
"requirements": ["AIOAladdinConnect==0.1.53"],
"requirements": ["AIOAladdinConnect==0.1.54"],
"codeowners": ["@mkmer"],
"iot_class": "cloud_polling",
"loggers": ["aladdin_connect"],
@@ -3,6 +3,9 @@
"abort": {
"already_configured": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u0432\u0435\u0447\u0435 \u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d\u043e"
},
"create_entry": {
"default": "\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0430\u043d \u0441 AlarmDecoder."
},
"error": {
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435"
},
@@ -19,5 +22,30 @@
}
}
}
},
"options": {
"step": {
"arm_settings": {
"data": {
"code_arm_required": "\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0435 \u043a\u043e\u0434 \u0437\u0430 \u043f\u043e\u0435\u043c\u0430\u043d\u0435 \u043f\u043e\u0434 \u043e\u0445\u0440\u0430\u043d\u0430"
}
},
"init": {
"data": {
"edit_select": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u043d\u0435"
}
},
"zone_details": {
"data": {
"zone_name": "\u0418\u043c\u0435 \u043d\u0430 \u0437\u043e\u043d\u0430",
"zone_type": "\u0422\u0438\u043f \u0437\u043e\u043d\u0430"
}
},
"zone_select": {
"data": {
"zone_number": "\u041d\u043e\u043c\u0435\u0440 \u043d\u0430 \u0437\u043e\u043d\u0430"
}
}
}
}
}
@@ -128,7 +128,6 @@ SENSOR_DESCRIPTIONS = (
key=TYPE_AQI_PM25_24H,
name="AQI PM2.5 24h avg",
device_class=SensorDeviceClass.AQI,
state_class=SensorStateClass.TOTAL_INCREASING,
),
SensorEntityDescription(
key=TYPE_AQI_PM25_IN,
@@ -140,7 +139,6 @@ SENSOR_DESCRIPTIONS = (
key=TYPE_AQI_PM25_IN_24H,
name="AQI PM2.5 indoor 24h avg",
device_class=SensorDeviceClass.AQI,
state_class=SensorStateClass.TOTAL_INCREASING,
),
SensorEntityDescription(
key=TYPE_BAROMABSIN,
@@ -182,7 +180,7 @@ SENSOR_DESCRIPTIONS = (
name="Event rain",
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.MEASUREMENT,
state_class=SensorStateClass.TOTAL,
),
SensorEntityDescription(
key=TYPE_FEELSLIKE,
@@ -287,7 +285,6 @@ SENSOR_DESCRIPTIONS = (
name="Last rain",
icon="mdi:water",
device_class=SensorDeviceClass.TIMESTAMP,
state_class=SensorStateClass.MEASUREMENT,
),
SensorEntityDescription(
key=TYPE_LIGHTNING_PER_DAY,
@@ -315,7 +312,7 @@ SENSOR_DESCRIPTIONS = (
name="Monthly rain",
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.MEASUREMENT,
state_class=SensorStateClass.TOTAL,
),
SensorEntityDescription(
key=TYPE_PM25_24H,
@@ -586,7 +583,7 @@ SENSOR_DESCRIPTIONS = (
name="Lifetime rain",
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.MEASUREMENT,
state_class=SensorStateClass.TOTAL_INCREASING,
),
SensorEntityDescription(
key=TYPE_UV,
@@ -599,7 +596,7 @@ SENSOR_DESCRIPTIONS = (
name="Weekly rain",
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.MEASUREMENT,
state_class=SensorStateClass.TOTAL,
),
SensorEntityDescription(
key=TYPE_WINDDIR,
+31 -3
View File
@@ -6,6 +6,13 @@ import os
from typing import Any
from adb_shell.auth.keygen import keygen
from adb_shell.exceptions import (
AdbTimeoutError,
InvalidChecksumError,
InvalidCommandError,
InvalidResponseError,
TcpTimeoutException,
)
from androidtv.adb_manager.adb_manager_sync import ADBPythonSync, PythonRSASigner
from androidtv.setup_async import (
AndroidTVAsync,
@@ -43,6 +50,18 @@ from .const import (
SIGNAL_CONFIG_ENTITY,
)
ADB_PYTHON_EXCEPTIONS: tuple = (
AdbTimeoutError,
BrokenPipeError,
ConnectionResetError,
ValueError,
InvalidChecksumError,
InvalidCommandError,
InvalidResponseError,
TcpTimeoutException,
)
ADB_TCP_EXCEPTIONS: tuple = (ConnectionResetError, RuntimeError)
PLATFORMS = [Platform.MEDIA_PLAYER]
RELOAD_OPTIONS = [CONF_STATE_DETECTION_RULES]
@@ -132,9 +151,18 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Android TV platform."""
state_det_rules = entry.options.get(CONF_STATE_DETECTION_RULES)
aftv, error_message = await async_connect_androidtv(
hass, entry.data, state_detection_rules=state_det_rules
)
if CONF_ADB_SERVER_IP not in entry.data:
exceptions = ADB_PYTHON_EXCEPTIONS
else:
exceptions = ADB_TCP_EXCEPTIONS
try:
aftv, error_message = await async_connect_androidtv(
hass, entry.data, state_detection_rules=state_det_rules
)
except exceptions as exc:
raise ConfigEntryNotReady(exc) from exc
if not aftv:
raise ConfigEntryNotReady(error_message)
@@ -7,13 +7,6 @@ import functools
import logging
from typing import Any, Concatenate, ParamSpec, TypeVar
from adb_shell.exceptions import (
AdbTimeoutError,
InvalidChecksumError,
InvalidCommandError,
InvalidResponseError,
TcpTimeoutException,
)
from androidtv.constants import APPS, KEYS
from androidtv.exceptions import LockNotAcquiredException
import voluptuous as vol
@@ -42,7 +35,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import get_androidtv_mac
from . import ADB_PYTHON_EXCEPTIONS, ADB_TCP_EXCEPTIONS, get_androidtv_mac
from .const import (
ANDROID_DEV,
ANDROID_DEV_OPT,
@@ -252,19 +245,10 @@ class ADBDevice(MediaPlayerEntity):
# ADB exceptions to catch
if not aftv.adb_server_ip:
# Using "adb_shell" (Python ADB implementation)
self.exceptions = (
AdbTimeoutError,
BrokenPipeError,
ConnectionResetError,
ValueError,
InvalidChecksumError,
InvalidCommandError,
InvalidResponseError,
TcpTimeoutException,
)
self.exceptions = ADB_PYTHON_EXCEPTIONS
else:
# Using "pure-python-adb" (communicate with ADB server)
self.exceptions = (ConnectionResetError, RuntimeError)
self.exceptions = ADB_TCP_EXCEPTIONS
# Property attributes
self._attr_extra_state_attributes = {
@@ -4,7 +4,8 @@
"already_configured": "Apparaat is al geconfigureerd"
},
"error": {
"cannot_connect": "Kan geen verbinding maken"
"cannot_connect": "Kan geen verbinding maken",
"cannot_receive_deviceinfo": "Kon het MAC adres niet ophalen. Zorg ervoor dat het apparaat aanstaat"
},
"step": {
"user": {
+9 -1
View File
@@ -1,4 +1,6 @@
"""Apprise platform for notify component."""
from __future__ import annotations
import logging
import apprise
@@ -12,7 +14,9 @@ from homeassistant.components.notify import (
BaseNotificationService,
)
from homeassistant.const import CONF_URL
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
_LOGGER = logging.getLogger(__name__)
@@ -26,7 +30,11 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
)
def get_service(hass, config, discovery_info=None):
def get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> AppriseNotificationService | None:
"""Get the Apprise notification service."""
# Create our Apprise Instance (reference our asset)
a_obj = apprise.Apprise()
@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"reauth_successful": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u0442\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u043a\u0430\u0446\u0438\u044f \u0431\u0435\u0448\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u0430"
},
"error": {
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435",
"invalid_auth": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u0432\u0430\u043d\u0435"
@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "El servicio ya est\u00e1 configurado"
},
"error": {
"cannot_connect": "No se pudo conectar"
},
@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "A szolg\u00e1ltat\u00e1s m\u00e1r konfigur\u00e1lva van"
},
"error": {
"cannot_connect": "Sikertelen csatlakoz\u00e1s"
},
@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Layanan sudah dikonfigurasi"
},
"error": {
"cannot_connect": "Gagal terhubung"
},
@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Dienst is al ingesteld"
},
"error": {
"cannot_connect": "Kan geen verbinding maken"
},
@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Us\u0142uga jest ju\u017c skonfigurowana"
},
"error": {
"cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia"
},
@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "O servi\u00e7o j\u00e1 est\u00e1 configurado"
},
"error": {
"cannot_connect": "Falha ao conectar"
},
@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Slu\u017eba u\u017e je nakonfigurovan\u00e1"
},
"error": {
"cannot_connect": "Nepodarilo sa pripoji\u0165"
},
+1 -1
View File
@@ -438,7 +438,7 @@ def _create_auth_code_store() -> tuple[StoreResultType, RetrieveResultType]:
def store_result(client_id: str, result: Credentials) -> str:
"""Store flow result and return a code to retrieve it."""
if not isinstance(result, Credentials):
raise ValueError("result has to be a Credentials instance")
raise TypeError("result has to be a Credentials instance")
code = uuid.uuid4().hex
temp_results[(client_id, code)] = (
+9 -1
View File
@@ -1,4 +1,6 @@
"""AWS platform for notify component."""
from __future__ import annotations
import asyncio
import base64
import json
@@ -20,7 +22,9 @@ from homeassistant.const import (
CONF_PROFILE_NAME,
CONF_SERVICE,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.json import JSONEncoder
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .const import CONF_CONTEXT, CONF_CREDENTIAL_NAME, CONF_REGION, DATA_SESSIONS
@@ -33,7 +37,11 @@ async def get_available_regions(hass, service):
return await session.get_available_regions(service)
async def async_get_service(hass, config, discovery_info=None):
async def async_get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> AWSNotify | None:
"""Get the AWS notification service."""
if discovery_info is None:
_LOGGER.error("Please config aws notify platform in aws component")
@@ -10,7 +10,7 @@
"already_in_progress": "\u0412 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0442\u0435\u0447\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e.",
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435"
},
"flow_title": "Axis \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e: {name} ({host})",
"flow_title": "{name} ({host})",
"step": {
"user": {
"data": {
@@ -1,9 +1,11 @@
"""Support for azure service bus notification."""
from __future__ import annotations
import json
import logging
from azure.servicebus import ServiceBusMessage
from azure.servicebus.aio import ServiceBusClient
from azure.servicebus.aio import ServiceBusClient, ServiceBusSender
from azure.servicebus.exceptions import (
MessagingEntityNotFoundError,
ServiceBusConnectionError,
@@ -19,7 +21,9 @@ from homeassistant.components.notify import (
BaseNotificationService,
)
from homeassistant.const import CONTENT_TYPE_JSON
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
CONF_CONNECTION_STRING = "connection_string"
CONF_QUEUE_NAME = "queue"
@@ -47,11 +51,15 @@ PLATFORM_SCHEMA = vol.All(
_LOGGER = logging.getLogger(__name__)
def get_service(hass, config, discovery_info=None):
def get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> ServiceBusNotificationService | None:
"""Get the notification service."""
connection_string = config[CONF_CONNECTION_STRING]
queue_name = config.get(CONF_QUEUE_NAME)
topic_name = config.get(CONF_TOPIC_NAME)
connection_string: str = config[CONF_CONNECTION_STRING]
queue_name: str | None = config.get(CONF_QUEUE_NAME)
topic_name: str | None = config.get(CONF_TOPIC_NAME)
# Library can do synchronous IO when creating the clients.
# Passes in loop here, but can't run setup on the event loop.
@@ -59,10 +67,11 @@ def get_service(hass, config, discovery_info=None):
connection_string, loop=hass.loop
)
client: ServiceBusSender | None = None
try:
if queue_name:
client = servicebus.get_queue_sender(queue_name)
else:
elif topic_name:
client = servicebus.get_topic_sender(topic_name)
except (ServiceBusConnectionError, MessagingEntityNotFoundError) as err:
_LOGGER.error(
@@ -72,7 +81,7 @@ def get_service(hass, config, discovery_info=None):
)
return None
return ServiceBusNotificationService(client)
return ServiceBusNotificationService(client) if client else None
class ServiceBusNotificationService(BaseNotificationService):
@@ -201,7 +201,7 @@
"on": "Problem"
},
"running": {
"off": "Nicht ausgef\u00fchrt",
"off": "L\u00e4uft nicht",
"on": "L\u00e4uft"
},
"safety": {
@@ -164,10 +164,7 @@ class BlackbirdZone(MediaPlayerEntity):
return
self._attr_state = MediaPlayerState.ON if state.power else MediaPlayerState.OFF
idx = state.av
if idx in self._source_id_name:
self._attr_source = self._source_id_name[idx]
else:
self._attr_source = None
self._attr_source = self._source_id_name.get(idx)
@property
def media_title(self):
@@ -5,7 +5,7 @@
},
"error": {
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435",
"invalid_auth": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u0432\u0430\u043d\u0435",
"invalid_auth": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u043a\u0430\u0446\u0438\u044f",
"unknown": "\u041d\u0435\u043e\u0447\u0430\u043a\u0432\u0430\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430"
},
"step": {
@@ -71,16 +71,14 @@ class BlinkStickLight(LightEntity):
"""Turn the device on."""
if ATTR_HS_COLOR in kwargs:
self._attr_hs_color = kwargs[ATTR_HS_COLOR]
if ATTR_BRIGHTNESS in kwargs:
self._attr_brightness = kwargs[ATTR_BRIGHTNESS]
else:
self._attr_brightness = 255
assert self.brightness is not None
self._attr_is_on = self.brightness > 0
brightness: int = kwargs.get(ATTR_BRIGHTNESS, 255)
self._attr_brightness = brightness
self._attr_is_on = bool(brightness)
assert self.hs_color
rgb_color = color_util.color_hsv_to_RGB(
self.hs_color[0], self.hs_color[1], self.brightness / 255 * 100
self.hs_color[0], self.hs_color[1], brightness / 255 * 100
)
self._stick.set_color(red=rgb_color[0], green=rgb_color[1], blue=rgb_color[2])
+15 -1
View File
@@ -85,7 +85,7 @@ def _dispatch_bleak_callback(
"""Dispatch the callback."""
if not callback:
# Callback destroyed right before being called, ignore
return # pragma: no cover
return
if (uuids := filters.get(FILTER_UUIDS)) and not uuids.intersection(
advertisement_data.service_uuids
@@ -209,6 +209,20 @@ class BluetoothManager:
self._bluetooth_adapters, self.storage
)
self.async_setup_unavailable_tracking()
seen: set[str] = set()
for address, service_info in itertools.chain(
self._connectable_history.items(), self._all_history.items()
):
if address in seen:
continue
seen.add(address)
for domain in self._integration_matcher.match_domains(service_info):
discovery_flow.async_create_flow(
self.hass,
domain,
{"source": config_entries.SOURCE_BLUETOOTH},
service_info,
)
@hass_callback
def async_stop(self, event: Event) -> None:
@@ -285,7 +285,7 @@ class PassiveBluetoothDataProcessor(Generic[_T]):
if not isinstance(new_data, PassiveBluetoothDataUpdate):
self.last_update_success = False # type: ignore[unreachable]
raise ValueError(
raise TypeError(
f"The update_method for {self.coordinator.name} returned"
f" {new_data} instead of a PassiveBluetoothDataUpdate"
)
@@ -1,5 +1,16 @@
{
"config": {
"flow_title": "{name}"
"flow_title": "{name}",
"step": {
"bluetooth_confirm": {
"description": "Vai v\u0113laties iestat\u012bt {name}?"
},
"user": {
"data": {
"address": "Ier\u012bce"
},
"description": "Izv\u0113lieties ier\u012bci, kuru iestat\u012bt"
}
}
}
}
@@ -5,7 +5,7 @@
},
"error": {
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435",
"invalid_auth": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u0432\u0430\u043d\u0435",
"invalid_auth": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u043a\u0430\u0446\u0438\u044f",
"unknown": "\u041d\u0435\u043e\u0447\u0430\u043a\u0432\u0430\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430"
},
"flow_title": "{name} ({host})",
@@ -92,7 +92,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1
info: dict[str, str | None]
host: str | None = None
host: str
async def async_step_reauth(self, entry_data: Mapping[str, Any]) -> FlowResult:
"""Perform reauth upon an API authentication error."""
@@ -107,8 +107,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
step_id="reauth_confirm",
data_schema=HOST_SCHEMA,
)
self.host = host = user_input[CONF_HOST]
self.info = await self._get_info(host)
self.host = user_input[CONF_HOST]
self.info = await self._get_info(self.host)
return await self.async_step_credentials()
async def async_step_user(
@@ -117,18 +117,17 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle the initial step."""
errors: dict[str, str] = {}
if user_input is not None:
host = user_input[CONF_HOST]
self.host = user_input[CONF_HOST]
try:
self.info = info = await self._get_info(host)
self.info = await self._get_info(self.host)
except SHCConnectionError:
errors["base"] = "cannot_connect"
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
await self.async_set_unique_id(info["unique_id"])
self._abort_if_unique_id_configured({CONF_HOST: host})
self.host = host
await self.async_set_unique_id(self.info["unique_id"])
self._abort_if_unique_id_configured({CONF_HOST: self.host})
return await self.async_step_credentials()
return self.async_show_form(
@@ -14,11 +14,14 @@
}
},
"confirm_discovery": {
"description": "Please press the Bosch Smart Home Controller's front-side button until LED starts flashing.\nReady to continue to set up {model} @ {host} with Home Assistant?"
"description": "Smart Home Controller I: Please press the front-side button until LED starts flashing.\nSmart Home Controller II: Press the function button shortly. Cloud and network lights start blinking orange.\nDevice is now ready to be paired.\n\nReady to continue to set up {model} @ {host} with Home Assistant?"
},
"reauth_confirm": {
"title": "[%key:common::config_flow::title::reauth%]",
"description": "The bosch_shc integration needs to re-authenticate your account"
"description": "The bosch_shc integration needs to re-authenticate your account",
"data": {
"host": "[%key:common::config_flow::data::host%]"
}
}
},
"error": {
@@ -12,6 +12,9 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"reauth_confirm": {
"data": {
"host": "\u0425\u043e\u0441\u0442"
},
"title": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f\u0442\u0430"
},
"user": {
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "Prem el bot\u00f3 de la part frontal/lateral del controlador Bosh Smart Home fins que el LED parpellegi.\nPreparat per continuar la configuraci\u00f3 de {model} @ {host} amb Home Assistant?"
"description": "Smart Home Controller I: Prem el bot\u00f3 de la part frontal/lateral fins que el LED parpellegi.\nSmart Home Controller II: Prem el bot\u00f3 de funci\u00f3 breument. Els LEDs d'acc\u00e9s al n\u00favol i de connexi\u00f3 comen\u00e7aran a parpellejar.\nEl dispositiu est\u00e0 llest per a la vinculaci\u00f3.\n\nPreparat per continuar la configuraci\u00f3 de {model} @ {host} amb Home Assistant?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "Amfitri\u00f3"
},
"description": "La integraci\u00f3 bosch_shc ha de tornar a autenticar el teu compte",
"title": "Reautenticaci\u00f3 de la integraci\u00f3"
},
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "Bitte dr\u00fccke die frontseitige Taste des Bosch Smart Home Controllers, bis die LED zu blinken beginnt.\nBist du bereit, mit der Einrichtung von {model} @ {host} in Home Assistant fortzufahren?"
"description": "Smart Home Controller I: Bitte dr\u00fccke die Taste auf der Vorderseite, bis die LED zu blinken beginnt.\nSmart Home Controller II: Dr\u00fccke kurz die Funktionstaste. Cloud- und Netzwerk-Lampen beginnen orange zu blinken.\nDas Ger\u00e4t ist nun bereit f\u00fcr das Pairing.\n\nBist du bereit, mit der Einrichtung von {model} @ {host} mit Home Assistant fortzufahren?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "Host"
},
"description": "Die bosch_shc Integration muss dein Konto neu authentifizieren",
"title": "Integration erneut authentifizieren"
},
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "Please press the Bosch Smart Home Controller's front-side button until LED starts flashing.\nReady to continue to set up {model} @ {host} with Home Assistant?"
"description": "Smart Home Controller I: Please press the front-side button until LED starts flashing.\nSmart Home Controller II: Press the function button shortly. Cloud and network lights start blinking orange.\nDevice is now ready to be paired.\n\nReady to continue to set up {model} @ {host} with Home Assistant?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "Host"
},
"description": "The bosch_shc integration needs to re-authenticate your account",
"title": "Reauthenticate Integration"
},
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "Por favor, pulsa el bot\u00f3n frontal del Smart Home Controller de Bosch hasta que el LED empiece a parpadear.\n\u00bfPreparado para seguir configurando {model} @ {host} con Home Assistant?"
"description": "Smart Home Controller I: por favor, pulsa el bot\u00f3n frontal hasta que el LED comience a parpadear.\nSmart Home Controller II: pulsa el bot\u00f3n de funci\u00f3n brevemente. Las luces de la red y la nube comienzan a parpadear en naranja.\nEl dispositivo ya est\u00e1 listo para emparejarse. \n\n\u00bfPreparado para continuar configurando {model} @ {host} con Home Assistant?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "Host"
},
"description": "La integraci\u00f3n bosch_shc necesita volver a autentificar tu cuenta",
"title": "Volver a autenticar la integraci\u00f3n"
},
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "Vajuta palun Bosch Smart Home Controlleri esik\u00fclje nuppu kuni LED hakkab vilkuma.\n Kas oled valmis j\u00e4tkama {model} @ {host} seadistamist Home Assistanti abil?"
"description": "Smart Home Controller I: vajuta esik\u00fclje nuppu kuni LED hakkab vilkuma.\nSmart Home Controller II: vajuta l\u00fchidalt funktsiooninuppu. Pilve- ja v\u00f5rgutuled hakkavad oran\u017eilt vilkuma.\nSeade on n\u00fc\u00fcd sidumiseks valmis.\n\nKas oled valmis j\u00e4tkama {model} @ {host} seadistamist Home Assistantiga?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "Host"
},
"description": "Bosch_shc sidumine peab konto uuesti autentima.",
"title": "Taastuvastamine"
},
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "Tekan tombol sisi depan Bosch Smart Home Controller hingga LED mulai berkedip.\nSiap melanjutkan penyiapan {model} @ {host} dengan Home Assistant?"
"description": "Smart Home Controller I: Tekan tombol sisi depan hingga LED mulai berkedip.\nSmart Home Controller II: Tekan tombol fungsi sebentar. Lampu cloud dan jaringan mulai berkedip oranye.\nPerangkat sekarang siap untuk dipasangkan.\n\nSiap untuk melanjutkan penyiapan {model} @ {host} dengan Home Assistant?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "Host"
},
"description": "Integrasi bosch_shc perlu mengautentikasi ulang akun Anda",
"title": "Autentikasi Ulang Integrasi"
},
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "Trykk p\u00e5 Bosch Smart Home Controller-frontknappen til LED-lampen begynner \u00e5 blinke.\n Klar til \u00e5 fortsette \u00e5 konfigurere {model} @ {host} med Home Assistant?"
"description": "Smart Home Controller I: Trykk p\u00e5 knappen p\u00e5 forsiden til LED begynner \u00e5 blinke.\n Smart Home Controller II: Trykk kort p\u00e5 funksjonsknappen. Sky- og nettverkslys begynner \u00e5 blinke oransje.\n Enheten er n\u00e5 klar til \u00e5 bli paret. \n\n Er du klar til \u00e5 fortsette \u00e5 konfigurere {model} @ {host} med Home Assistant?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "Vert"
},
"description": "Bosch_shc-integrasjonen m\u00e5 godkjenne kontoen din p\u00e5 nytt",
"title": "Godkjenne integrering p\u00e5 nytt"
},
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "Pressione o bot\u00e3o frontal do Bosch Smart Home Controller at\u00e9 que o LED comece a piscar.\n Pronto para continuar a configurar {model} @ {host} com o Home Assistant?"
"description": "Smart Home Controller I: Por favor, pressione o bot\u00e3o frontal at\u00e9 que o LED comece a piscar.\n Smart Home Controller II: Pressione brevemente o bot\u00e3o de fun\u00e7\u00e3o. As luzes da nuvem e da rede come\u00e7am a piscar em laranja.\n O dispositivo agora est\u00e1 pronto para ser emparelhado. \n\n Pronto para continuar a configurar {model} @ {host} com o Home Assistant?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "Host"
},
"description": "A integra\u00e7\u00e3o bosch_shc precisa re-autenticar sua conta",
"title": "Reautenticar Integra\u00e7\u00e3o"
},
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "\u0423\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0439\u0442\u0435 \u043a\u043d\u043e\u043f\u043a\u0443 \u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u043d\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u043f\u043e\u043a\u0430 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043d\u044b\u0435 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043d\u0435 \u043d\u0430\u0447\u043d\u0443\u0442 \u043c\u0438\u0433\u0430\u0442\u044c.\n\u0413\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 Home Assistant \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 {model} @ {host}?"
"description": "Smart Home Controller I: \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043a\u043d\u043e\u043f\u043a\u0443 \u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435, \u043f\u043e\u043a\u0430 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 \u043d\u0435 \u043d\u0430\u0447\u043d\u0435\u0442 \u043c\u0438\u0433\u0430\u0442\u044c.\nSmart Home Controller II: \u041a\u0440\u0430\u0442\u043a\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443. \u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043e\u0431\u043b\u0430\u043a\u0430 \u0438 \u0441\u0435\u0442\u0438 \u043d\u0430\u0447\u043d\u0443\u0442 \u043c\u0438\u0433\u0430\u0442\u044c \u043e\u0440\u0430\u043d\u0436\u0435\u0432\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c.\n\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0433\u043e\u0442\u043e\u0432\u043e \u043a \u0441\u043e\u043f\u0440\u044f\u0436\u0435\u043d\u0438\u044e.\n\n\u0413\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 {model} @ {host}?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "\u0425\u043e\u0441\u0442"
},
"description": "\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Bosch SHC",
"title": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f"
},
@@ -14,7 +14,7 @@
"flow_title": "Bosch SHC: {name}",
"step": {
"confirm_discovery": {
"description": "Stla\u010dte tla\u010didlo na prednej strane ovl\u00e1da\u010da Bosch Smart Home Controller, k\u00fdm LED neza\u010dne blika\u0165.\n Ste pripraven\u00ed pokra\u010dova\u0165 v nastavovan\u00ed {model} @ {host} pomocou Home Assistant?"
"description": "Smart Home Controller I: Stla\u010dte pros\u00edm tla\u010didlo na prednej strane, k\u00fdm LED neza\u010dne blika\u0165.\n Smart Home Controller II: Kr\u00e1tko stla\u010dte funk\u010dn\u00e9 tla\u010didlo. Kontrolky cloudu a siete za\u010dn\u00fa blika\u0165 na oran\u017eovo.\n Zariadenie je teraz pripraven\u00e9 na sp\u00e1rovanie. \n\n Ste pripraven\u00ed pokra\u010dova\u0165 v nastavovan\u00ed {model} @ {host} pomocou Home Assistant?"
},
"credentials": {
"data": {
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "Hostite\u013e"
},
"description": "Integr\u00e1cia bosch_shc mus\u00ed znova overi\u0165 v\u00e1\u0161 \u00fa\u010det",
"title": "Znova overi\u0165 integr\u00e1ciu"
},
@@ -22,6 +22,9 @@
}
},
"reauth_confirm": {
"data": {
"host": "\u4e3b\u6a5f\u7aef"
},
"description": "bosch_shc \u6574\u5408\u9700\u8981\u91cd\u65b0\u8a8d\u8b49\u60a8\u7684\u5e33\u865f",
"title": "\u91cd\u65b0\u8a8d\u8b49\u6574\u5408"
},
+1 -1
View File
@@ -60,7 +60,7 @@ class BroadlinkDevice:
@property
def available(self):
"""Return True if the device is available."""
if self.update_manager is None: # pragma: no cover
if self.update_manager is None:
return False
return self.update_manager.available
@@ -2,13 +2,13 @@
"config": {
"abort": {
"already_configured": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u0432\u0435\u0447\u0435 \u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d\u043e",
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0445 \u043f\u0440\u0438 \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435",
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435",
"invalid_host": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e \u0438\u043c\u0435 \u043d\u0430 \u0445\u043e\u0441\u0442 \u0438\u043b\u0438 IP \u0430\u0434\u0440\u0435\u0441",
"not_supported": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u043d\u0435 \u0441\u0435 \u043f\u043e\u0434\u0434\u044a\u0440\u0436\u0430",
"unknown": "\u041d\u0435\u043e\u0447\u0430\u043a\u0432\u0430\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430"
},
"error": {
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0445 \u043f\u0440\u0438 \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435",
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435",
"unknown": "\u041d\u0435\u043e\u0447\u0430\u043a\u0432\u0430\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430"
},
"flow_title": "{name} ({model} at {host})",
@@ -5,7 +5,7 @@
"unknown": "\u041d\u0435\u043e\u0447\u0430\u043a\u0432\u0430\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430"
},
"error": {
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0445 \u043f\u0440\u0438 \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435"
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435"
},
"flow_title": "{name}",
"step": {
@@ -21,10 +21,11 @@ def get_cert(
"""Get the certificate for the host and port combination."""
ctx = ssl.create_default_context()
address = (host, port)
with socket.create_connection(address, timeout=TIMEOUT) as sock:
with ctx.wrap_socket(sock, server_hostname=address[0]) as ssock:
cert = ssock.getpeercert()
return cert
with socket.create_connection(address, timeout=TIMEOUT) as sock, ctx.wrap_socket(
sock, server_hostname=address[0]
) as ssock:
cert = ssock.getpeercert()
return cert
async def get_cert_expiry_timestamp(
+9 -1
View File
@@ -1,15 +1,23 @@
"""Unify Circuit platform for notify component."""
from __future__ import annotations
import logging
from circuit_webhook import Circuit
from homeassistant.components.notify import BaseNotificationService
from homeassistant.const import CONF_URL
from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
_LOGGER = logging.getLogger(__name__)
def get_service(hass, config, discovery_info=None):
def get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> CircuitNotificationService | None:
"""Get the Unify Circuit notification service."""
if discovery_info is None:
return None
@@ -1,4 +1,6 @@
"""Cisco Webex Teams notify component."""
from __future__ import annotations
import logging
import voluptuous as vol
@@ -10,7 +12,9 @@ from homeassistant.components.notify import (
BaseNotificationService,
)
from homeassistant.const import CONF_TOKEN
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
_LOGGER = logging.getLogger(__name__)
@@ -21,7 +25,11 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
)
def get_service(hass, config, discovery_info=None):
def get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> CiscoWebexTeamsNotificationService | None:
"""Get the CiscoWebexTeams notification service."""
client = WebexTeamsAPI(access_token=config[CONF_TOKEN])
@@ -1,4 +1,6 @@
"""clicksend_tts platform for notify component."""
from __future__ import annotations
from http import HTTPStatus
import json
import logging
@@ -14,7 +16,9 @@ from homeassistant.const import (
CONF_USERNAME,
CONTENT_TYPE_JSON,
)
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
_LOGGER = logging.getLogger(__name__)
@@ -49,7 +53,11 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
)
def get_service(hass, config, discovery_info=None):
def get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> ClicksendNotificationService | None:
"""Get the ClickSend notification service."""
if not _authenticate(config):
_LOGGER.error("You are not authorized to access ClickSend")
@@ -1,44 +1,128 @@
{
"device_automation": {
"action_type": {
"set_hvac_mode": "Changer le mode HVAC sur {entity_name}.",
"set_hvac_mode": "D\u00e9finir le mode CVC de {entity_name}",
"set_preset_mode": "Changer les pr\u00e9r\u00e9glages de {entity_name}"
},
"condition_type": {
"is_hvac_mode": "{entity_name} est d\u00e9fini sur un mode HVAC sp\u00e9cifique",
"is_hvac_mode": "{entity_name} est r\u00e9gl\u00e9 sur un mode CVC sp\u00e9cifique",
"is_preset_mode": "{entity_name} est d\u00e9fini sur un mode pr\u00e9d\u00e9fini sp\u00e9cifique"
},
"trigger_type": {
"current_humidity_changed": "Changement d'humidit\u00e9 mesur\u00e9e pour {entity_name}",
"current_temperature_changed": "Changement de temp\u00e9rature mesur\u00e9e pour {entity_name}",
"hvac_mode_changed": "Mode HVAC chang\u00e9 pour {entity_name}"
"hvac_mode_changed": "Modification du mode CVC de {entity_name}"
}
},
"state": {
"_": {
"auto": "Auto",
"cool": "Frais",
"dry": "Sec",
"fan_only": "Ventilateur seul",
"heat": "Chauffe",
"heat_cool": "Chaud/Froid",
"cool": "Rafra\u00eechissement",
"dry": "Ass\u00e9chage",
"fan_only": "Ventilation uniquement",
"heat": "Chauffage",
"heat_cool": "Chauffage / Rafra\u00eechissement",
"off": "D\u00e9sactiv\u00e9"
}
},
"state_attributes": {
"_": {
"hvac_action": {
"aux_heat": {
"name": "Chauffage auxiliaire"
},
"current_humidity": {
"name": "Humidit\u00e9 actuelle"
},
"current_temperature": {
"name": "Temp\u00e9rature actuelle"
},
"fan_mode": {
"name": "Mode de ventilation",
"state": {
"auto": "Auto",
"diffuse": "Diffuse",
"focus": "Focalis\u00e9e",
"high": "\u00c9lev\u00e9e",
"low": "Faible",
"medium": "Moyenne",
"middle": "Milieu",
"off": "D\u00e9sactiv\u00e9e",
"on": "Activ\u00e9e",
"top": "Haute"
}
},
"fan_modes": {
"name": "Modes de ventilation"
},
"humidity": {
"name": "Humidit\u00e9 cible"
},
"hvac_action": {
"name": "Action actuelle",
"state": {
"cooling": "Rafra\u00eechissement",
"drying": "Ass\u00e9chage",
"fan": "Ventilation",
"heating": "Chauffe",
"idle": "Inactif",
"off": "Arr\u00eat"
}
},
"hvac_modes": {
"name": "Modes CVC"
},
"max_humidity": {
"name": "Humidit\u00e9 cible maximale"
},
"max_temp": {
"name": "Temp\u00e9rature cible maximale"
},
"min_humidity": {
"name": "Humidit\u00e9 cible minimale"
},
"min_temp": {
"name": "Temp\u00e9rature cible minimale"
},
"preset_mode": {
"name": "Pr\u00e9r\u00e9glage",
"state": {
"activity": "Activit\u00e9",
"away": "Absent",
"comfort": "Confort"
"boost": "Boost",
"comfort": "Confort",
"eco": "\u00c9co",
"home": "\u00c0 la maison",
"none": "Aucun",
"sleep": "Nuit"
}
},
"preset_modes": {
"name": "Pr\u00e9r\u00e9glages"
},
"swing_mode": {
"name": "Mode d\u2019oscillation",
"state": {
"both": "Les deux",
"horizontal": "Horizontale",
"off": "D\u00e9sactiv\u00e9e",
"on": "Activ\u00e9e",
"vertical": "Verticale"
}
},
"swing_modes": {
"name": "Modes d\u2019oscillation"
},
"target_temp_high": {
"name": "Temp\u00e9rature cible sup\u00e9rieure"
},
"target_temp_low": {
"name": "Temp\u00e9rature cible inf\u00e9rieure"
},
"target_temp_step": {
"name": "Pas de temp\u00e9rature cible"
},
"temperature": {
"name": "Temp\u00e9rature cible"
}
}
},
@@ -40,8 +40,8 @@
"name": "\u98ce\u901f",
"state": {
"auto": "\u81ea\u52a8",
"high": "\u9ad8",
"low": "\u4f4e",
"high": "\u5f3a",
"low": "\u5f31",
"medium": "\u4e2d",
"middle": "\u4e2d\u95f4",
"off": "\u5173",
@@ -38,7 +38,7 @@ async def async_provide_implementation(hass: HomeAssistant, domain: str):
for service in services:
if (
service["service"] == domain
and CURRENT_PLAIN_VERSION >= service["min_version"]
and service["min_version"] <= CURRENT_PLAIN_VERSION
and (
service.get("accepts_new_authorizations", True)
or (
@@ -5,7 +5,7 @@
},
"error": {
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435",
"invalid_auth": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u0432\u0430\u043d\u0435",
"invalid_auth": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u043a\u0430\u0446\u0438\u044f",
"unknown": "\u041d\u0435\u043e\u0447\u0430\u043a\u0432\u0430\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430"
},
"step": {
@@ -11,7 +11,7 @@ import re
from typing import IO, Any
from hassil.intents import Intents, ResponseType, SlotList, TextSlotList
from hassil.recognize import recognize
from hassil.recognize import RecognizeResult, recognize_all
from hassil.util import merge_dict
from home_assistant_intents import get_intents
import yaml
@@ -71,6 +71,8 @@ class DefaultAgent(AbstractConversationAgent):
# intent -> [sentences]
self._config_intents: dict[str, Any] = {}
self._areas_list: TextSlotList | None = None
self._names_list: TextSlotList | None = None
async def async_initialize(self, config_intents):
"""Initialize the default agent."""
@@ -81,6 +83,22 @@ class DefaultAgent(AbstractConversationAgent):
if config_intents:
self._config_intents = config_intents
self.hass.bus.async_listen(
area_registry.EVENT_AREA_REGISTRY_UPDATED,
self._async_handle_area_registry_changed,
run_immediately=True,
)
self.hass.bus.async_listen(
entity_registry.EVENT_ENTITY_REGISTRY_UPDATED,
self._async_handle_entity_registry_changed,
run_immediately=True,
)
self.hass.bus.async_listen(
core.EVENT_STATE_CHANGED,
self._async_handle_state_changed,
run_immediately=True,
)
async def async_process(self, user_input: ConversationInput) -> ConversationResult:
"""Process a sentence."""
language = user_input.language or self.hass.config.language
@@ -109,7 +127,12 @@ class DefaultAgent(AbstractConversationAgent):
"name": self._make_names_list(),
}
result = recognize(user_input.text, lang_intents.intents, slot_lists=slot_lists)
result = await self.hass.async_add_executor_job(
self._recognize,
user_input,
lang_intents,
slot_lists,
)
if result is None:
_LOGGER.debug("No intent was matched for '%s'", user_input.text)
return _make_error_result(
@@ -160,21 +183,43 @@ class DefaultAgent(AbstractConversationAgent):
).get(response_key)
if response_str:
response_template = template.Template(response_str, self.hass)
intent_response.async_set_speech(
response_template.async_render(
{
"slots": {
entity_name: entity_value.text or entity_value.value
for entity_name, entity_value in result.entities.items()
}
speech = response_template.async_render(
{
"slots": {
entity_name: entity_value.text or entity_value.value
for entity_name, entity_value in result.entities.items()
}
)
}
)
# Normalize whitespace
speech = " ".join(speech.strip().split())
intent_response.async_set_speech(speech)
return ConversationResult(
response=intent_response, conversation_id=conversation_id
)
def _recognize(
self,
user_input: ConversationInput,
lang_intents: LanguageIntents,
slot_lists: dict[str, SlotList],
) -> RecognizeResult | None:
"""Search intents for a match to user input."""
# Prioritize matches with entity names above area names
maybe_result: RecognizeResult | None = None
for result in recognize_all(
user_input.text, lang_intents.intents, slot_lists=slot_lists
):
if "name" in result.entities:
return result
# Keep looking in case an entity has the same name
maybe_result = result
return maybe_result
async def async_reload(self, language: str | None = None):
"""Clear cached intents for a language."""
if language is None:
@@ -196,13 +241,15 @@ class DefaultAgent(AbstractConversationAgent):
async def async_get_or_load_intents(self, language: str) -> LanguageIntents | None:
"""Load all intents of a language with lock."""
hass_components = set(self.hass.config.components)
async with self._lang_lock[language]:
return await self.hass.async_add_executor_job(
self._get_or_load_intents,
language,
self._get_or_load_intents, language, hass_components
)
def _get_or_load_intents(self, language: str) -> LanguageIntents | None:
def _get_or_load_intents(
self, language: str, hass_components: set[str]
) -> LanguageIntents | None:
"""Load all intents for language (run inside executor)."""
lang_intents = self._lang_intents.get(language)
@@ -215,7 +262,7 @@ class DefaultAgent(AbstractConversationAgent):
# Check if any new components have been loaded
intents_changed = False
for component in self.hass.config.components:
for component in hass_components:
if component in loaded_components:
continue
@@ -310,8 +357,29 @@ class DefaultAgent(AbstractConversationAgent):
return lang_intents
@core.callback
def _async_handle_area_registry_changed(self, event: core.Event) -> None:
"""Clear area area cache when the area registry has changed."""
self._areas_list = None
@core.callback
def _async_handle_entity_registry_changed(self, event: core.Event) -> None:
"""Clear names list cache when an entity changes aliases."""
if event.data["action"] == "update" and "aliases" not in event.data["changes"]:
return
self._names_list = None
@core.callback
def _async_handle_state_changed(self, event: core.Event) -> None:
"""Clear names list cache when a state is added or removed from the state machine."""
if event.data.get("old_state") and event.data.get("new_state"):
return
self._names_list = None
def _make_areas_list(self) -> TextSlotList:
"""Create slot list mapping area names/aliases to area ids."""
if self._areas_list is not None:
return self._areas_list
registry = area_registry.async_get(self.hass)
areas = []
for entry in registry.async_list_areas():
@@ -320,31 +388,34 @@ class DefaultAgent(AbstractConversationAgent):
for alias in entry.aliases:
areas.append((alias, entry.id))
return TextSlotList.from_tuples(areas)
self._areas_list = TextSlotList.from_tuples(areas, allow_template=False)
return self._areas_list
def _make_names_list(self) -> TextSlotList:
"""Create slot list mapping entity names/aliases to entity ids."""
if self._names_list is not None:
return self._names_list
states = self.hass.states.async_all()
registry = entity_registry.async_get(self.hass)
entities = entity_registry.async_get(self.hass)
names = []
for state in states:
domain = state.entity_id.split(".", maxsplit=1)[0]
context = {"domain": domain}
context = {"domain": state.domain}
entry = registry.async_get(state.entity_id)
if entry is not None:
if entry.entity_category:
entity = entities.async_get(state.entity_id)
if entity is not None:
if entity.entity_category:
# Skip configuration/diagnostic entities
continue
if entry.aliases:
for alias in entry.aliases:
if entity.aliases:
for alias in entity.aliases:
names.append((alias, state.entity_id, context))
# Default name
names.append((state.name, state.entity_id, context))
return TextSlotList.from_tuples(names)
self._names_list = TextSlotList.from_tuples(names, allow_template=False)
return self._names_list
def _get_error_text(
self, response_type: ResponseType, lang_intents: LanguageIntents
@@ -2,9 +2,9 @@
"domain": "conversation",
"name": "Conversation",
"documentation": "https://www.home-assistant.io/integrations/conversation",
"requirements": ["hassil==0.2.5", "home-assistant-intents==2023.1.25"],
"requirements": ["hassil==0.2.6", "home-assistant-intents==2023.1.25"],
"dependencies": ["http"],
"codeowners": ["@home-assistant/core"],
"codeowners": ["@home-assistant/core", "@synesthesiam"],
"quality_scale": "internal",
"iot_class": "local_push",
"integration_type": "system"
@@ -2,7 +2,7 @@
"config": {
"error": {
"cannot_connect": "\u00c9chec de connexion",
"no_units": "Impossible de trouver des unit\u00e9s HVAC dans l'h\u00f4te CoolMasterNet."
"no_units": "Aucune unit\u00e9 CVC n\u2019a \u00e9t\u00e9 trouv\u00e9e dans l\u2019h\u00f4te CoolMasterNet."
},
"step": {
"user": {
@@ -2,7 +2,7 @@
"config": {
"abort": {
"already_configured": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u0432\u0435\u0447\u0435 \u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d\u043e",
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0445 \u043f\u0440\u0438 \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435"
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435"
},
"error": {
"api_password": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u0432\u0430\u043d\u0435, \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u0442\u0435 API \u043a\u043b\u044e\u0447 \u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u0430.",
@@ -88,7 +88,7 @@ class DeconzFlowHandler(ConfigFlow, domain=DOMAIN):
"""
if user_input is not None:
if CONF_MANUAL_INPUT == user_input[CONF_HOST]:
if user_input[CONF_HOST] == CONF_MANUAL_INPUT:
return await self.async_step_manual_input()
for bridge in self.bridges:
@@ -17,6 +17,10 @@ from .device_trigger import (
CONF_BUTTON_2,
CONF_BUTTON_3,
CONF_BUTTON_4,
CONF_BUTTON_5,
CONF_BUTTON_6,
CONF_BUTTON_7,
CONF_BUTTON_8,
CONF_CLOSE,
CONF_DIM_DOWN,
CONF_DIM_UP,
@@ -95,6 +99,10 @@ INTERFACES = {
CONF_BUTTON_2: "Button 2",
CONF_BUTTON_3: "Button 3",
CONF_BUTTON_4: "Button 4",
CONF_BUTTON_5: "Button 5",
CONF_BUTTON_6: "Button 6",
CONF_BUTTON_7: "Button 7",
CONF_BUTTON_8: "Button 8",
CONF_SIDE_1: "Side 1",
CONF_SIDE_2: "Side 2",
CONF_SIDE_3: "Side 3",
@@ -10,7 +10,7 @@
"linking_not_possible": "\u041d\u0435 \u043c\u043e\u0436\u0430 \u0434\u0430 \u0441\u0435 \u0441\u0432\u044a\u0440\u0436\u0435 \u0441 \u0448\u043b\u044e\u0437\u0430",
"no_key": "\u041d\u0435 \u043c\u043e\u0436\u0430 \u0434\u0430 \u0441\u0435 \u043f\u043e\u043b\u0443\u0447\u0438 API \u043a\u043b\u044e\u0447"
},
"flow_title": "deCONZ Zigbee \u0448\u043b\u044e\u0437 ({host})",
"flow_title": "{host}",
"step": {
"hassio_confirm": {
"description": "\u0418\u0441\u043a\u0430\u0442\u0435 \u043b\u0438 \u0434\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u0442\u0435 Home Assistant \u0434\u0430 \u0441\u0435 \u0441\u0432\u044a\u0440\u0437\u0432\u0430 \u0441 deCONZ \u0431\u0430\u0437\u043e\u0432\u0430 \u0441\u0442\u0430\u043d\u0446\u0438\u044f, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0435\u043d \u043e\u0442 \u0434\u043e\u0431\u0430\u0432\u043a\u0430\u0442\u0430 \u0437\u0430 Supervisor {addon}?",
@@ -65,8 +65,8 @@
"trigger_type": {
"remote_awakened": "A k\u00e9sz\u00fcl\u00e9k fel\u00e9bredt",
"remote_button_double_press": "\"{subtype}\" gombra k\u00e9tszer kattintottak",
"remote_button_long_press": "A \"{subtype}\" gomb folyamatosan lenyomva",
"remote_button_long_release": "A \"{subtype}\" gomb hossz\u00fa megnyom\u00e1s ut\u00e1n elengedve",
"remote_button_long_press": "\"{subtype}\" gomb folyamatosan lenyomva",
"remote_button_long_release": "\"{subtype}\" gomb hossz\u00fa megnyom\u00e1s ut\u00e1n elengedve",
"remote_button_quadruple_press": "\"{subtype}\" gombra n\u00e9gyszer kattintottak",
"remote_button_quintuple_press": "\"{subtype}\" gombra \u00f6tsz\u00f6r kattintottak",
"remote_button_rotated": "A gomb elforgatva: \"{subtype}\"",
@@ -99,6 +99,6 @@ class DelugeFlowHandler(ConfigFlow, domain=DOMAIN):
return "cannot_connect"
except Exception as ex: # pylint:disable=broad-except
if type(ex).__name__ == "BadLoginError":
return "invalid_auth" # pragma: no cover
return "invalid_auth"
return "unknown"
return None
@@ -1,5 +1,28 @@
{
"entity": {
"climate": {
"ubercool": {
"state_attributes": {
"fan_mode": {
"state": {
"auto_high": "Auto \u00e9lev\u00e9e",
"auto_low": "Auto faible",
"on_high": "Sur \u00e9lev\u00e9e",
"on_low": "Sur faible"
}
},
"swing_mode": {
"state": {
"1": "1",
"2": "2",
"3": "3",
"auto": "Auto",
"off": "D\u00e9sactiv\u00e9e"
}
}
}
}
},
"sensor": {
"thermostat_mode": {
"state": {
@@ -39,5 +39,14 @@
}
}
},
"selector": {
"time_unit": {
"options": {
"h": "\u038f\u03c1\u03b5\u03c2",
"min": "\u039b\u03b5\u03c0\u03c4\u03ac",
"s": "\u0394\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1"
}
}
},
"title": "\u0391\u03b9\u03c3\u03b8\u03b7\u03c4\u03ae\u03c1\u03b1\u03c2 \u03c0\u03b1\u03c1\u03b1\u03b3\u03ce\u03b3\u03c9\u03bd"
}
@@ -39,5 +39,15 @@
}
}
},
"selector": {
"time_unit": {
"options": {
"d": "D\u00edas",
"h": "Horas",
"min": "Minutos",
"s": "Segundos"
}
}
},
"title": "Sensor de derivaci\u00f3n"
}
@@ -39,5 +39,15 @@
}
}
},
"selector": {
"time_unit": {
"options": {
"d": "Nap",
"h": "\u00d3ra",
"min": "Perc",
"s": "M\u00e1sodperc"
}
}
},
"title": "Sz\u00e1rmaz\u00e9kos \u00e9rz\u00e9kel\u0151"
}
@@ -39,5 +39,15 @@
}
}
},
"selector": {
"time_unit": {
"options": {
"d": "Hari",
"h": "Jam",
"min": "Menit",
"s": "Detik"
}
}
},
"title": "Sensor Turunan"
}
@@ -39,5 +39,15 @@
}
}
},
"selector": {
"time_unit": {
"options": {
"d": "Dagen",
"h": "Uren",
"min": "Minuten",
"s": "Seconden"
}
}
},
"title": "Afgeleide"
}
@@ -39,5 +39,15 @@
}
}
},
"selector": {
"time_unit": {
"options": {
"d": "Dager",
"h": "Timer",
"min": "Minutter",
"s": "Sekunder"
}
}
},
"title": "Avledet sensor"
}
@@ -39,5 +39,15 @@
}
}
},
"selector": {
"time_unit": {
"options": {
"d": "Dias",
"h": "Horas",
"min": "Minutos",
"s": "Segundos"
}
}
},
"title": "Sensor derivativo"
}
@@ -39,5 +39,15 @@
}
}
},
"selector": {
"time_unit": {
"options": {
"d": "Dni",
"h": "Hodiny",
"min": "Min\u00faty",
"s": "Sekundy"
}
}
},
"title": "Deriva\u010dn\u00fd sn\u00edma\u010d"
}
+1 -1
View File
@@ -23,7 +23,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
entry.data[CONF_USERNAME],
entry.data[CONF_USE_LEGACY_PROTOCOL],
)
if not smartplug.authenticated and entry.data[CONF_USE_LEGACY_PROTOCOL]:
if not smartplug.authenticated and smartplug.use_legacy_protocol:
raise ConfigEntryNotReady("Cannot connect/authenticate")
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = SmartPlugData(smartplug)
@@ -131,6 +131,6 @@ class DLinkFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
except Exception as ex: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception: %s", ex)
return "unknown"
if smartplug.authenticated:
return None
return "cannot_connect"
if not smartplug.authenticated and smartplug.use_legacy_protocol:
return "cannot_connect"
return None
+3 -3
View File
@@ -19,9 +19,9 @@ class SmartPlugData:
"""Initialize the data object."""
self.smartplug = smartplug
self.state: str | None = None
self.temperature: str | None = None
self.current_consumption = None
self.total_consumption: str | None = None
self.temperature: str = ""
self.current_consumption: str = ""
self.total_consumption: str = ""
self.available = False
self._n_tried = 0
self._last_tried: datetime | None = None
+14 -9
View File
@@ -94,17 +94,22 @@ class SmartPlugSwitch(DLinkEntity, SwitchEntity):
@property
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes of the device."""
attrs: dict[str, Any] = {}
if self.data.temperature and self.data.temperature.isnumeric():
attrs[ATTR_TEMPERATURE] = self.hass.config.units.temperature(
try:
temperature = self.hass.config.units.temperature(
int(self.data.temperature), UnitOfTemperature.CELSIUS
)
else:
attrs[ATTR_TEMPERATURE] = None
if self.data.total_consumption and self.data.total_consumption.isnumeric():
attrs[ATTR_TOTAL_CONSUMPTION] = float(self.data.total_consumption)
else:
attrs[ATTR_TOTAL_CONSUMPTION] = None
except ValueError:
temperature = None
try:
total_consumption = float(self.data.total_consumption)
except ValueError:
total_consumption = None
attrs = {
ATTR_TOTAL_CONSUMPTION: total_consumption,
ATTR_TEMPERATURE: temperature,
}
return attrs
@@ -12,7 +12,7 @@
"data": {
"password": "Senha (padr\u00e3o: c\u00f3digo PIN no verso)",
"use_legacy_protocol": "Usar protocolo legado",
"username": "Nome de usu\u00e1rio"
"username": "Usu\u00e1rio"
}
},
"user": {
@@ -3,7 +3,7 @@
"name": "DLNA Digital Media Renderer",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/dlna_dmr",
"requirements": ["async-upnp-client==0.33.0", "getmac==0.8.2"],
"requirements": ["async-upnp-client==0.33.1", "getmac==0.8.2"],
"dependencies": ["ssdp"],
"after_dependencies": ["media_source"],
"ssdp": [
@@ -3,7 +3,7 @@
"name": "DLNA Digital Media Server",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/dlna_dms",
"requirements": ["async-upnp-client==0.33.0"],
"requirements": ["async-upnp-client==0.33.1"],
"dependencies": ["ssdp"],
"after_dependencies": ["media_source"],
"ssdp": [
@@ -14,6 +14,9 @@
}
},
"options": {
"abort": {
"already_configured": "El servicio ya est\u00e1 configurado"
},
"error": {
"invalid_resolver": "Direcci\u00f3n IP no v\u00e1lida para resolver"
},
@@ -14,6 +14,9 @@
}
},
"options": {
"abort": {
"already_configured": "A szolg\u00e1ltat\u00e1s m\u00e1r konfigur\u00e1lva van"
},
"error": {
"invalid_resolver": "\u00c9rv\u00e9nytelen IP-c\u00edm a felold\u00f3hoz"
},
@@ -14,6 +14,9 @@
}
},
"options": {
"abort": {
"already_configured": "Layanan sudah dikonfigurasi"
},
"error": {
"invalid_resolver": "Alamat IP tidak valid untuk resolver"
},
@@ -14,6 +14,9 @@
}
},
"options": {
"abort": {
"already_configured": "Dienst is al ingesteld"
},
"error": {
"invalid_resolver": "Ongeldig IP-adres voor resolver"
},
@@ -14,6 +14,9 @@
}
},
"options": {
"abort": {
"already_configured": "Us\u0142uga jest ju\u017c skonfigurowana"
},
"error": {
"invalid_resolver": "Nieprawid\u0142owy adres IP dla resolvera"
},
@@ -14,6 +14,9 @@
}
},
"options": {
"abort": {
"already_configured": "O servi\u00e7o j\u00e1 est\u00e1 configurado"
},
"error": {
"invalid_resolver": "Endere\u00e7o IP inv\u00e1lido para resolver"
},
@@ -14,6 +14,9 @@
}
},
"options": {
"abort": {
"already_configured": "Slu\u017eba u\u017e je nakonfigurovan\u00e1"
},
"error": {
"invalid_resolver": "Neplatn\u00e1 adresa IP pre resolver"
},
@@ -2,7 +2,7 @@
"config": {
"error": {
"cannot_connect": "\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435",
"invalid_auth": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u0432\u0430\u043d\u0435",
"invalid_auth": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u043a\u0430\u0446\u0438\u044f",
"unknown": "\u041d\u0435\u043e\u0447\u0430\u043a\u0432\u0430\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430"
},
"flow_title": "{name} ({host})",
+9 -1
View File
@@ -1,14 +1,22 @@
"""Support for SMS notifications from the Dovado router."""
from __future__ import annotations
import logging
from homeassistant.components.notify import ATTR_TARGET, BaseNotificationService
from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import DOMAIN as DOVADO_DOMAIN
_LOGGER = logging.getLogger(__name__)
def get_service(hass, config, discovery_info=None):
def get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> DovadoSMSNotificationService:
"""Get the Dovado Router SMS notification service."""
return DovadoSMSNotificationService(hass.data[DOVADO_DOMAIN].client)
@@ -209,7 +209,6 @@ SENSORS: tuple[DSMRReaderSensorEntityDescription, ...] = (
DSMRReaderSensorEntityDescription(
key="dsmr/consumption/gas/currently_delivered",
name="Current gas usage",
device_class=SensorDeviceClass.GAS,
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
state_class=SensorStateClass.MEASUREMENT,
),
@@ -69,7 +69,10 @@ class DSMRSensor(SensorEntity):
@callback
def message_received(message):
"""Handle new MQTT messages."""
if self.entity_description.state is not None:
if message.payload == "":
self._attr_native_value = None
elif self.entity_description.state is not None:
# Perform optional additional parsing
self._attr_native_value = self.entity_description.state(message.payload)
else:
self._attr_native_value = message.payload

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