Compare commits

..

756 Commits

Author SHA1 Message Date
Paulus Schoutsen
cdf7372fd8 Bumped version to 2021.3.0b3 2021-02-26 19:21:15 +00:00
Allen Porter
0969cc985b Bump google-nest-sdm to v0.2.12 to improve API call error messages (#47108) 2021-02-26 19:21:08 +00:00
Stefan Agner
5e2bafca56 Add new machine generic-x86-64 to build matrix (#47095)
The Intel NUC machine runs on most UEFI capable x86-64 machines today.
Lets start a new machine generic-x86-64 which will replace intel-nuc
over time.
2021-02-26 19:21:07 +00:00
Simone Chemelli
1d1be8ad1a Bump aioshelly to 0.6.1 (#47088) 2021-02-26 19:21:06 +00:00
Marcel van der Veldt
d55f0df09a Fix Z-Wave JS discovery schema for thermostat devices (#47087)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-26 19:21:06 +00:00
Erik Montnemery
96e118ccfe Bump pychromecast to 8.1.2 (#47085) 2021-02-26 19:21:05 +00:00
Paulus Schoutsen
255b6faa7f Upgrade aiohttp to 3.7.4 (#47077) 2021-02-26 19:21:04 +00:00
rikroe
4cd40d0f9f Bump bimmer_connected to 0.7.15 and fix bugs (#47066)
Co-authored-by: rikroe <rikroe@users.noreply.github.com>
2021-02-26 19:21:03 +00:00
J. Nick Koston
c12769213d Add suggested area to hue (#47056) 2021-02-26 19:21:02 +00:00
CurrentThread
6a850a1481 Add support for Shelly SHBTN-2 device triggers (#46644) 2021-02-26 19:21:02 +00:00
Joakim Plate
101897c260 Add support for v6 features to philips js integration (#46422) 2021-02-26 19:21:01 +00:00
Paulus Schoutsen
6cdd6c3f44 Bumped version to 2021.3.0b2 2021-02-26 06:01:42 +00:00
Paulus Schoutsen
2c30579a11 Bump Z-Wave JS Server Python to 0.20.0 (#47076) 2021-02-26 06:01:35 +00:00
Raman Gupta
ae0d301fd9 catch ValueError when unique ID update fails because its taken and remove the duplicate entity (#47072) 2021-02-26 06:01:34 +00:00
J. Nick Koston
a7a66e8ddb Ensure hue options show the defaults when the config options have not yet been saved (#47067) 2021-02-26 06:01:33 +00:00
Bram Kragten
5228bbd43c Revert CORS changes for my home assistant (#47064)
* Revert CORS changes for my home assistant

* Update test_init.py

* Update test_init.py
2021-02-26 06:01:33 +00:00
Bram Kragten
35bce434cc Updated frontend to 20210225.0 (#47059) 2021-02-26 06:01:32 +00:00
Paulus Schoutsen
33a6fb1baf Bumped version to 2021.3.0b1 2021-02-25 19:42:48 +00:00
Paulus Schoutsen
399c299cf2 Remove deprecated credstash + keyring (#47033) 2021-02-25 19:42:43 +00:00
Raman Gupta
c797e0c8de Fix zwave_js unique ID migration logic (#47031) 2021-02-25 19:42:42 +00:00
Simone Chemelli
cb2dd6d908 Fix missing Shelly external input (#47028)
* Add support for external input (Shelly 1/1pm add-on)

* Make external sensor naming consistent

* Fix case consistency
2021-02-25 19:42:41 +00:00
Ron Klinkien
a3cde9b19e Bump python-garminconnect to 0.1.19 to fix broken api (#47020) 2021-02-25 19:42:40 +00:00
Joakim Sørensen
a58931280a Use dispatch instead of eventbus for supervisor events (#46986)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-02-25 19:42:40 +00:00
J. Nick Koston
2fef4c4eef Ensure doorbird events are re-registered when changing options (#46860)
- Fixed the update listener not being unsubscribed

- DRY up some of the code

- Fix sync code being called in async

- Reduce executor jumps
2021-02-25 19:42:39 +00:00
Franck Nijhof
567ec26c48 Bumped version to 2021.3.0b0 2021-02-24 22:01:28 +01:00
Marcel van der Veldt
23cbd2dda3 Change Z-Wave JS discovery logic to adopt changes to DeviceClass (#46983)
Co-authored-by: raman325 <7243222+raman325@users.noreply.github.com>
2021-02-24 12:59:06 -08:00
Bram Kragten
afae253432 Update frontend to 20210224.0 (#47013) 2021-02-24 21:18:24 +01:00
Simone Chemelli
4c294adfe8 Add missing tilt icon to Shelly tilt sensor (#46993) 2021-02-24 21:18:14 +01:00
Nathan Tilley
8d2606134d Add FAA Delays Integration (#41347)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-24 14:11:20 -06:00
jjlawren
ba51ada494 Bump plexapi to 4.4.0 (#47007) 2021-02-24 21:00:58 +01:00
jjlawren
2f1dba74d1 Use Plex server URL as config entry title (#47010) 2021-02-24 20:57:02 +01:00
Tobias Sauerwein
39baeb62f2 Add Sonos media browser image proxy (#46902) 2021-02-24 20:51:12 +01:00
Erik Montnemery
daf7595ca6 Support value_template in MQTT triggers (#46891)
* Support value_template in MQTT triggers

* Rename value_template to payload_template

* Revert "Rename value_template to payload_template"

This reverts commit 902094eefc6612e6b5c3bdb7440520af050c7f20.
2021-02-24 20:16:36 +01:00
Raman Gupta
783e0f9a14 Setup config entry even if vizio device is unreachable (#46864) 2021-02-24 20:15:47 +01:00
Marcel van der Veldt
868a536d81 Add number platform to Z-Wave JS (#46956)
* add number platform to zwave_js integration
* add discovery scheme for thermostat valve control, using number platform

Co-authored-by: kpine <keith.pine@gmail.com>
2021-02-24 19:39:35 +01:00
Milan Meulemans
0eb8951aed Remove recursive key reference (#46999) 2021-02-24 13:29:53 -05:00
Tobias Sauerwein
722b1e8746 Add Netatmo device trigger (#45387)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-24 19:20:40 +01:00
Milan Meulemans
db0d815f9d Use location common key reference in totalconnect (#46995) 2021-02-24 12:44:12 -05:00
Raman Gupta
106ae18432 Climacell fixes: Use common keys for strings, fix temp_low measurement, add windy condition (#46991)
* use common keys for lat and long

* additional fixes

* Update homeassistant/components/climacell/strings.json

Co-authored-by: Milan Meulemans <milan.meulemans@live.be>

Co-authored-by: Milan Meulemans <milan.meulemans@live.be>
2021-02-24 11:15:01 -05:00
Joakim Sørensen
11a89bc3ac Add addon selector (#46789) 2021-02-24 17:02:48 +01:00
Fabian Affolter
0ef16dd563 Set awesomeversion to 21.2.3 (#46989) 2021-02-24 16:43:09 +01:00
Martin Hjelmare
db8f597f10 Fix zwave_js config flow server version timeout (#46990) 2021-02-24 16:22:58 +01:00
Raman Gupta
424526db7e Migrate zwave_js entities to use new unique ID format (#46979)
* migrate zwave_js entities to use new unique ID format

* remove extra param from helper

* add comment to remove migration logic in the future

* update comment

* use instance attribute instead of calling functino on every state update
2021-02-24 09:41:10 -05:00
adrian-vlad
44293a3738 Add enable and disable services for recorder (#45778) 2021-02-24 07:26:05 -06:00
Álvaro Fernández Rojas
470121e5b0 Restore Tado binary sensor attributes (#46069) 2021-02-24 07:17:01 -06:00
Maciej Bieniek
b645b151f9 Catch AuthRequired exception in confirm discovery step for Shelly config flow (#46135) 2021-02-24 07:13:32 -06:00
Franck Nijhof
8f19d041e4 Merge branch 'master' into dev 2021-02-24 13:52:44 +01:00
Franck Nijhof
45b50c53ad Mullvad integration improvements (#46987) 2021-02-24 13:43:44 +01:00
Bram Kragten
b0d56970a5 Fix TTS services name (#46988) 2021-02-24 13:43:24 +01:00
Martin Hjelmare
17f4c9dd06 Improve mysensors config flow (#46984) 2021-02-24 12:52:04 +01:00
MeIchthys
1a73cb4791 Mullvad VPN (#44189)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-02-24 12:04:38 +01:00
Martin Hjelmare
1c7c6163dd Save mysensors gateway type in config entry (#46981) 2021-02-24 11:31:31 +01:00
Raman Gupta
eccdae60bf Add ClimaCell weather integration (#36547)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-24 09:34:27 +01:00
Matthias Alphart
a632215541 Validate KNX addresses (#46933) 2021-02-24 08:37:41 +01:00
Franck Nijhof
42fd3be0e8 Add template support to service targets (#46977)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-02-23 22:46:00 -08:00
Steven Looman
3e26e2adad Handle device IP change in upnp (#46859) 2021-02-23 21:00:47 -06:00
Allen Porter
19f5b467b7 Make FAN_ON use the max duration rather than 15 min default (#46489) 2021-02-23 20:38:52 -06:00
Nathan Spencer
b8f7bc12ee Add switches and sensors to Litter-Robot (#46942) 2021-02-23 20:34:25 -06:00
Marcel van der Veldt
d4d68ebc64 Extend zwave_js discovery scheme for lights (#46907) 2021-02-23 16:31:24 -08:00
Matthias Alphart
d02b27a5d0 Update xknx to 0.17.1 (#46974) 2021-02-23 16:26:17 -08:00
J. Nick Koston
87cbbcb014 Automatically create HomeKit accessory mode entries (#46473)
When we set up HomeKit, we asked users if they wanted
to create an entry in bridge or accessory mode.

This approach required the user to understand how HomeKit works and
choose which type to create.

When the user includes the media player or camera domains,
we exclude them from the bridge and create the additional entries
for each entity in accessory mode.
2021-02-23 16:22:23 -08:00
HomeAssistant Azure
9159f54900 [ci skip] Translation update 2021-02-24 00:04:14 +00:00
Raman Gupta
b657fd02cd deep copy zwave_js state in test fixtures so tests are more isolated (#46976) 2021-02-23 18:58:25 -05:00
Raman Gupta
1a99562e91 Add zwave_js.refresh_value service (#46944)
* add poll_value service

* switch vol.All to vol.Schema

* more relevant log message

* switch service name to refresh_value, add parameter to refresh all watched values, fix tests

* rename parameter and create task for polling command so we don't wait for a response

* raise ValueError for unknown entity

* better error message

* fix test
2021-02-23 18:58:04 -05:00
Milan Meulemans
228096847b Fix typo in fireservicerota strings (#46973) 2021-02-23 23:42:24 +01:00
jjlawren
425d56d024 Fix Plex showing removed shared users (#46971) 2021-02-23 23:36:46 +01:00
tkdrob
c9847920af Use core constants for dht (#46029) 2021-02-23 23:32:39 +01:00
MHV33
23b2953773 Add more shopping list services (#45591)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-02-23 23:25:50 +01:00
Michael
d96249e39c Implement additional DataUpdateCoordinator to harmonize the data update handling of Synology DSM (#46113) 2021-02-23 16:23:50 -06:00
Matthias Alphart
b583ded8b5 Fix KNX services.yaml (#46897) 2021-02-23 22:59:16 +01:00
J. Nick Koston
d68a51ddce Avoid having to ask for the bond token when possible during config (#46845) 2021-02-23 13:42:56 -08:00
Simone Chemelli
00dd557cce Fix Shelly mireds and color_temp return type (#46112) 2021-02-23 22:42:33 +01:00
Martin Hjelmare
089effbe3f Improve zwave_js config flow (#46906) 2021-02-23 13:41:19 -08:00
jjlawren
272e975a52 Fix Plex handling of clips (#46667) 2021-02-23 22:38:24 +01:00
J. Nick Koston
eb8d723689 Bump pymyq to fix myq in core (#46962) 2021-02-23 21:50:06 +01:00
Jon Caruana
6a8b5ee51b LiteJet is now configured using config_flow (#44409)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-23 14:20:58 -06:00
J. Nick Koston
ffe42e150a Add missing target to increase_speed/decrease_speed service (#46939) 2021-02-23 12:03:30 -06:00
Raman Gupta
5a3bd30e01 Add zwave_js.set_config_parameter service (#46673)
* create zwave_js.set_config_value service

* update docstring

* PR comments

* make proposed changes

* handle providing a label for the new value

* fix docstring

* use new library function

* config param endpoint is always 0

* corresponding changes from upstream PR

* bug fixes and add tests

* create zwave_js.set_config_value service

* update docstring

* PR comments

* make proposed changes

* handle providing a label for the new value

* fix docstring

* use new library function

* config param endpoint is always 0

* corresponding changes from upstream PR

* bug fixes and add tests

* use lambda to avoid extra function

* add services description file

* bring back the missing selector

* move helper functions to helper file for reuse

* allow target selector for automation editor

* formatting

* fix service schema

* update docstrings

* raise error in service if call to set value is unsuccessful

* Update homeassistant/components/zwave_js/services.yaml

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

* Update homeassistant/components/zwave_js/services.yaml

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

* Update homeassistant/components/zwave_js/services.yaml

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

* Update homeassistant/components/zwave_js/services.yaml

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

* Update homeassistant/components/zwave_js/services.yaml

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

* Update homeassistant/components/zwave_js/services.yaml

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

* remove extra param to vol.Optional

* switch to set over list for nodes

* switch to set over list for nodes

Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-02-23 11:35:11 -05:00
Martin Hjelmare
c94968d811 Catch more zwave_js errors (#46957) 2021-02-23 16:36:53 +01:00
Philip Allgaier
7a7147edcf Add stop tilt support to KNX (#46947) 2021-02-23 16:34:02 +01:00
Charles Garwood
3c35b6558b Return states list from zwave_js get_config_parameters websocket if available (#46954) 2021-02-23 09:31:47 -05:00
Bram Kragten
f0f752936b Update homeassistant services.yaml (#46952)
Add names and missing target to turn off service
2021-02-23 14:49:04 +01:00
Bram Kragten
afa91e886b Add description to tts and notify services (#46764)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-02-23 14:29:57 +01:00
Franck Nijhof
ea4bbd771f Add service names to previously enriched services (#46929)
Co-authored-by: Tobias Sauerwein <cgtobi@users.noreply.github.com>
2021-02-23 14:10:13 +01:00
Maciej Bieniek
593e7aea5a Bump accuweather to 0.1.0 (#46951) 2021-02-23 14:00:21 +01:00
Martin Hjelmare
6fe72b04eb Add zwave_js constant for add-on slug (#46950) 2021-02-23 13:24:07 +01:00
tkdrob
4fdb617e22 Clean up constants (#46924)
* Clean up constants

* fix imports
2021-02-23 09:56:44 +01:00
J. Nick Koston
08889a9819 Fix smaty fan typing (#46941) 2021-02-23 07:14:39 +01:00
J. Nick Koston
f33618d33d Add suggested area support to isy994 (#46927) 2021-02-22 21:27:33 -06:00
J. Nick Koston
bd87047ff2 Update tasmota to use new fan entity model (#45877) 2021-02-22 21:27:21 -06:00
J. Nick Koston
fb2a100f5e Add suggested area to tado (#46932)
I realized tado shows what we internally call `zone_name` as
the room name in the app.
2021-02-22 21:27:09 -06:00
uvjustin
f005c68630 Restore stream recorder functionality and add discontinuity support (#46772)
* Add discontinuity support to stream recorder

* Use same container options for both StreamOutputs

* Fix pts adjuster

* Remove redundant/incorrect duplicate hls segment check

* Use same StreamBuffer across outputs

* Remove keepalive check for recorder

* Set output video timescale explicitly

* Disable avoid_negative_ts
2021-02-23 10:37:19 +08:00
Raman Gupta
1cecf229b9 Add zwave_js set_config_parameter WS API command (#46910)
* add WS API command

* handle error scenario better

* fixes and remove duplicate catch

* make elif statement more compact

* fix conflict

* switch to str(err)
2021-02-22 20:34:47 -05:00
HomeAssistant Azure
580d25c622 [ci skip] Translation update 2021-02-23 00:05:06 +00:00
Raman Gupta
20ccec9aab Add zwave_js/get_log_config and zwave_js/update_log_config WS API commands (#46601)
* Add zwave_js.update_log_config service

* fix comment

* reduce lines

* move update_log_config from service to ws API call

* fix docstring

* Add zwave_js/get_log_config WS API command

* resolve stale comments

* remove transports since it will be removed from upstream PR

* add support to update all log config parameters since they could be useful outside of the UI for advanced users

* fix comment

* switch to lambda instead of single line validator

* fix rebase

* re-add ATTR_DOMAIN
2021-02-22 18:35:19 -05:00
Raman Gupta
9d7c64ec1a Add missing required=true to code slot field in zwave_js.set_lock_usercode service (#46931) 2021-02-22 23:42:12 +01:00
Charles Garwood
04e07d8b2c Add get_config_parameters websocket command to zwave_js (#46463)
* Add get_configuration_values websocket command to zwave_js

* Tweak return value

* Review comments and cleanup returned values

* Update test

* Rename to get_config_parameters

* Add get_configuration_values websocket command to zwave_js

* Rename to get_config_parameters

* fix test

* fix tests #2

* Add readable to metadata

Co-authored-by: Raman Gupta <7243222+raman325@users.noreply.github.com>
2021-02-22 17:03:38 -05:00
Bram Kragten
be33336d96 Update frontend to 20210222.0 (#46928) 2021-02-22 22:48:47 +01:00
Philip Allgaier
8ac9faef3b Description tweaks for automation services (#46926) 2021-02-22 21:36:38 +01:00
tkdrob
f0c7aff248 Clean up Mitemp_bt constants (#46881)
* Use core constants for acer_projector

* Use core constants for mitemp_bt

* remove acer changes
2021-02-22 21:12:00 +01:00
kpine
fb32c2e3a8 Test zwave_js GE 12730 fan controller device-specific discovery (#46840)
* Add test for GE 12730 fan controller device-specific discovery

* Adjust

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-22 10:56:23 -08:00
Nathan Spencer
e70d896e1b Add litterrobot integration (#45886) 2021-02-22 08:53:57 -10:00
Raman Gupta
668574c48f Add name and target filter to vizio entity service (#46916)
* Add name and target filter to vizio entity service

* Update homeassistant/components/vizio/services.yaml

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

* add selectors

* Update homeassistant/components/vizio/services.yaml

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

* Update homeassistant/components/vizio/services.yaml

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

* Update homeassistant/components/vizio/services.yaml

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

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-02-22 13:31:18 -05:00
Michal Knizek
5907129b25 Increase tado API polling interval to 5 minutes (#46915)
Polling interval of 15 seconds causes high load on tado servers and does
not provide enough value to warrant it. tado plans to introduce a rate
limit to prevent such misuse of the API, therefore the polling interval
needs to be increased to make sure the integration works well in the
future.
2021-02-22 19:30:23 +01:00
Raman Gupta
6e10b39d67 add name and target filter to zwave_js lock services.yaml (#46914) 2021-02-22 12:54:06 -05:00
Tobias Sauerwein
692942b399 Add service names to Netatmo services (#46909) 2021-02-22 18:50:01 +01:00
Franck Nijhof
c8ffac20b9 Add name to services (#46905) 2021-02-22 16:26:46 +01:00
tkdrob
75e04f3a71 Clean up constants (#46885) 2021-02-22 15:28:08 +01:00
Matt Zimmerman
81d011efc5 Add binary sensor to SmartTub for online status (#46889) 2021-02-22 04:10:00 -10:00
Franck Nijhof
603191702f Cleanup of possibily confusing comment in esphome (#46903) 2021-02-22 14:43:29 +01:00
Simone Chemelli
82a9dc620c Add device_class to Shelly cover domain (#46894)
Fix author
2021-02-22 14:31:22 +01:00
Jaroslav Hanslík
36b56586de Bump samsungtvws from 1.4.0 to 1.6.0 (#46878) 2021-02-22 13:58:32 +01:00
starkillerOG
338c07a56b Add Xiaomi Miio vacuum config flow (#46669) 2021-02-22 13:01:02 +01:00
Franck Nijhof
23c2bd4e69 Upgrade mypy to 0.812 (#46898) 2021-02-22 12:44:40 +01:00
Austin Mroczek
e5aef45bd7 Add usercode support to totalconnect (#39199)
* Add test for invalid usercode

* Add usercodes to totalconnect.

* Update existing tests for usercodes

* Fix tests

* Add test for invalid usercode

* Add usercodes to totalconnect.

* Update existing tests for usercodes

* Fix tests

* Remove YAML support

* Fix conflict

* Bump to total_connect_client 0.56

* Change Exception to HomeAssistantError

* Fix config_flow.py

* Simplify async_setup since no yaml

* Remove import from config flow and tests

* Add reauth and test for it.  Various other fixes.

* Fix pylint in __init__

* Show config yaml as deprecated

* separate config_flow and init tests

* Assert ENTRY_STATE_SETUP_ERROR in init test

* Add test for reauth flow

* Fix reauth and tests

* Fix strings

* Restore username and usercode with new passord

* Correct the integration name

* Update tests/components/totalconnect/test_config_flow.py

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

* Update tests/components/totalconnect/test_init.py

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

* Update .coveragerc

* Add test for invalid auth during reauth

* Bump total-connect-client to 0.57

* Fix .coveragerc

* More tests for usercodes

* Fix usercode test

* Reload config entry on reauth

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-22 10:39:10 +01:00
Anders Melchiorsen
d61d39de08 Handle ConditionError with multiple entity_id for state/numeric_state (#46855) 2021-02-22 08:11:59 +01:00
Jan-Willem Mulder
75b37b4c2a Expose locked attribute in deCONZ climate platform (#46814) 2021-02-22 07:53:58 +01:00
Matt Zimmerman
b2b476596b Add UV sensor to SmartTub (#46888) 2021-02-21 20:25:01 -10:00
Diogo Gomes
5c29adea3d Add KMTronic Integration (#41682)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-21 20:12:50 -10:00
Matt Zimmerman
5cd022a683 Add light platform to SmartTub (#46886)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-21 20:09:21 -10:00
Matthias Alphart
1a27af43cc Add KNX service exposure_register (#45257) 2021-02-21 19:38:17 -10:00
Matt Zimmerman
5d8390fd9b Add support for SmartTub filtration cycles (#46868) 2021-02-21 19:36:50 -10:00
Anders Melchiorsen
b1a24c8bbb Log the name of automations with condition errors (#46854) 2021-02-21 19:34:45 -10:00
Jonathan Keslin
b6b1e725c7 Add support for VeSync dimmer switches (#44713)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-21 19:16:13 -10:00
Matt Zimmerman
a8be5be376 Add switch platform and pump entity to SmartTub (#46842) 2021-02-21 18:48:27 -10:00
Matt Zimmerman
d32dbc4cdd Add support for SmartTub heat modes (#46876) 2021-02-21 18:46:54 -10:00
Diogo Gomes
0e44d61225 Add weather platform to template domain (#45031)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-21 18:08:00 -10:00
Matt Zimmerman
12c4db076c Add more sensors to SmartTub integration (#46839) 2021-02-21 17:40:23 -10:00
tkdrob
8330940996 Clean up acer_projector constants (#46880) 2021-02-21 20:31:09 -05:00
tkdrob
29c0696537 Clean up denonavr constants (#46883) 2021-02-21 20:30:23 -05:00
HomeAssistant Azure
871427f5f1 [ci skip] Translation update 2021-02-22 00:06:36 +00:00
Charles Garwood
50a07f6d25 Log zwave_js connection errors (#46867) 2021-02-21 22:42:06 +01:00
J. Nick Koston
c1ee9f7e4a Fix unmocked I/O in rituals_perfume_genie config flow test (#46862) 2021-02-21 20:47:38 +01:00
Anders Melchiorsen
d33a1a5ff8 Refine printing of ConditionError (#46838)
* Refine printing of ConditionError

* Improve coverage

* name -> type
2021-02-21 14:54:36 +01:00
J. Nick Koston
e2fd255a96 Cleanup recorder tests (#46836) 2021-02-21 09:52:41 +01:00
J. Nick Koston
d9ab1482bc Add support for preset modes in homekit fans (#45962) 2021-02-20 19:24:14 -08:00
Erik Montnemery
5e26bda52d Add support for disabling config entries (#46779) 2021-02-20 19:21:39 -08:00
Erik Montnemery
2d70806035 Add support for "alias" in script steps device, device_condition, and conditions (#46647)
Co-authored-by: Donnie <donniekarnsinsb@hotmail.com>
2021-02-20 19:21:09 -08:00
Garrett
3ad207a499 Add new Subaru integration (#35760)
Co-authored-by: On Freund <onfreund@gmail.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-20 16:52:44 -10:00
Steven Looman
efa339ca54 Allow upnp ignore SSDP-discoveries (#46592) 2021-02-20 16:26:17 -10:00
HomeAssistant Azure
0cb1f61deb [ci skip] Translation update 2021-02-21 00:07:04 +00:00
Tom Harris
f045c0512b Fix Insteon config flow with add X10 and device override (#45854) 2021-02-20 13:00:18 -10:00
Matt Zimmerman
115fe26642 Add smarttub sensor platform and state sensor (#46775) 2021-02-20 12:25:02 -10:00
puddly
2b6619f815 Bump zigpy-znp from 0.3.0 to 0.4.0 (#46828) 2021-02-20 16:57:16 -05:00
Milan Meulemans
4af619d383 Add Rituals Perfume Genie integration (#46218)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-20 11:55:23 -10:00
Eric Severance
6e52b26c06 Speed-up wemo discovery (#46821)
* Speed-up wemo discovery

* Use gather_with_concurrency to limit concurrent executor usage

* Comment fixup: asyncio executors -> executor threads
2021-02-20 11:16:50 -10:00
Martin Hjelmare
43a5852561 Fix habitica entry unload clean up (#46798)
* Fix habitica entry unload clean up

* Fix service remove

* Add entry setup and unload test

* Fix config flow tests

* Assert service
2021-02-20 20:59:59 +01:00
Eric Severance
fe4cf611f7 Disable update polling for Wemo when devices can push updates (#46806) 2021-02-20 09:37:48 -10:00
Eric Severance
806369ddc1 Bump pywemo to 0.6.3 (#46825) 2021-02-20 20:21:01 +01:00
Martin
6bb848455f Add open/close tilt support to KNX cover (#46583) 2021-02-20 09:09:43 -10:00
Matthias Alphart
194c0d2b08 knx-read-service (#46670) 2021-02-20 09:09:23 -10:00
Matthias Alphart
2cf46330b1 Enable KNX routing optional local_ip (#46133) 2021-02-20 09:08:59 -10:00
marecabo
c6c0e2416c Validate icon and device_class of ESPHome sensor entities (#46709) 2021-02-20 13:05:35 -06:00
Anders Melchiorsen
9f4874bb81 Explicitly create_task for asyncio.wait (#46325) 2021-02-20 19:57:46 +01:00
Chris Talkington
cf69415272 Implement suggested area in roku (#46819)
* implement suggested area in roku

* Update const.py

* Update test_media_player.py

* Update test_media_player.py

* Update test_media_player.py

* Update test_media_player.py
2021-02-20 12:57:24 -06:00
kpine
2ae790283c Detect iBlinds v2.0 switch value as a cover not light (#46807)
* Remove unused "fibaro_fgs222" discovery hint

* Simplify multilevel switch current value discovery schema

* Force iBlinds v2.0 devices to be discovered as cover entities

* Rename discovery test file
2021-02-20 19:52:23 +01:00
Matthias Alphart
2940df09e9 Update xknx to 0.17.0 (#46809) 2021-02-20 08:45:04 -10:00
Michael
da1808226e change log level to info (#46823) 2021-02-20 08:42:37 -10:00
uvjustin
39da0dc409 Add rtsp transport options to generic camera (#46623)
* Add rtsp transport options to generic camera
2021-02-21 02:11:50 +08:00
J. Nick Koston
adf480025d Add support for bond up and down lights (#46233) 2021-02-20 08:03:40 -10:00
Chris Talkington
65e8835f28 Update rokuecp to 0.8.0 (#46799)
* update rokuecp to 0.8.0

* Update requirements_test_all.txt

* Update requirements_all.txt
2021-02-20 10:59:22 -06:00
Fabian Affolter
b5c7493b60 Upgrade TwitterAPI to 2.6.6 (#46812) 2021-02-20 17:26:21 +01:00
Allen Porter
4aa4f7e285 Rollback stream StreamOutput refactoring in PR#46610 (#46684)
* Rollback PR#46610

* Update stream tests post-merge
2021-02-20 06:49:39 -08:00
Raman Gupta
788134cbc4 Bump zwave-js-server-python to 0.18.0 (#46787)
* updates to support changes in zwave-js-server-python

* bump lib version

* use named arguments for optional args

* re-add lost commits
2021-02-20 09:50:00 +01:00
Anders Melchiorsen
26ce316c18 Do not trigger when numeric_state is true at startup (#46424) 2021-02-20 09:11:36 +01:00
J. Nick Koston
b775a0d796 Run homekit service calls in async since the server is now async (#45859)
* Simplify homekit runs and service calls

Now that the homekit server is async, call_service
and run are running in the Home Assistant event loop

* remove comment

* remove another comment
2021-02-19 21:34:52 -10:00
J. Nick Koston
41332493b5 Add suggested area support to Sonos (#46794) 2021-02-19 21:28:52 -10:00
J. Nick Koston
9b69549f73 Recover and restart the recorder if the sqlite database encounters corruption while running (#46612) 2021-02-19 21:26:24 -10:00
J. Nick Koston
5b0b01d727 Implement suggested areas in bond (#45942)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-19 21:06:43 -10:00
J. Nick Koston
6707496c5d Update alexa for new fan model (#45836) 2021-02-19 22:45:14 -08:00
J. Nick Koston
5b95f61fd3 Update smarty to use new fan entity model (#45879) 2021-02-19 22:38:45 -08:00
J. Nick Koston
773a202777 Implement percentage step sizes in HomeKit (#46722) 2021-02-19 22:37:12 -08:00
J. Nick Koston
749883dc62 Implement suggested area in lutron_caseta (#45941) 2021-02-19 20:24:49 -10:00
J. Nick Koston
500cb17298 Ensure HomeAssistant can still restart when a library file is missing (#46664) 2021-02-19 22:22:48 -08:00
J. Nick Koston
22dbac259b Ensure recorder shuts down cleanly on restart before startup is finished (#46604) 2021-02-19 22:18:21 -08:00
J. Nick Koston
4078a8782e Add suggested area to hunterdouglas_powerview (#46774) 2021-02-19 22:17:00 -08:00
J. Nick Koston
11277faa93 Add suggested area to nexia (#46776) 2021-02-19 20:01:22 -10:00
J. Nick Koston
2807cb1de7 Implement suggested area for netatmo (#46802) 2021-02-19 21:57:37 -08:00
J. Nick Koston
3e334a4950 Fix typing of fan speed count and steps (#46790) 2021-02-19 19:57:21 -10:00
J. Nick Koston
0e9148e239 Add suggested area support to nuheat (#46801) 2021-02-19 21:57:02 -08:00
Erik Montnemery
54cf954353 Add device_entities template function/filter (#46406) 2021-02-19 21:50:59 -08:00
J. Nick Koston
2f3c2f5f4d Add support for using a single endpoint for rest data (#46711) 2021-02-19 21:44:15 -08:00
J. Nick Koston
71586b7661 Cleanup inconsistencies in zha fan and make it a bit more dry (#46714)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-19 19:42:14 -10:00
J. Nick Koston
bb7e4d7daa Implement suggested_area in the device registry (#45940)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-19 19:34:33 -10:00
Eric Severance
e6125a1e4e Bump pywemo to 0.6.2 (#46797) 2021-02-20 03:49:39 +01:00
HomeAssistant Azure
fd60d4273b [ci skip] Translation update 2021-02-20 00:08:25 +00:00
Raman Gupta
47dcd2bf32 Format zwave_js dump as json (#46792) 2021-02-19 18:44:15 -05:00
Raman Gupta
4d23ffacd1 Add zwave_js thermostat fan mode and fan state support (#46793)
* add thermostat fan mode and fan state support

* return when fan mode is not supported

* use get just in case

* validate state key is in states so we dont have to use get

* pylint
2021-02-20 00:20:10 +01:00
Denise Yu
32bec5ea63 Update GitHub Issue Form template (#46791)
This PR fixes the bug report template!

Details: https://gh-community.github.io/issue-template-feedback/changes/#what-do-i-need-to-do
2021-02-19 21:23:34 +01:00
Andreas Oetken
250327fac4 Allow multiple recipients for XMPP (#45328)
* recipient is a string list instead of a single string now
* this does NOT break existing automations/etc using this component
2021-02-19 15:56:20 +01:00
Joakim Sørensen
3e82509263 Use string instead of slug for add-on slug validation (#46784) 2021-02-19 15:23:59 +01:00
Franck Nijhof
6ad7020f99 Add Home Assistant color (#46751) 2021-02-19 13:30:27 +01:00
Tobias Sauerwein
d2a187a57b Bump RMVtransport to 0.3.1 (#46780) 2021-02-19 13:28:00 +01:00
Anders Melchiorsen
bfea7d0baa Raise ConditionError for and/or/not errors (#46767) 2021-02-19 13:15:30 +01:00
Anders Melchiorsen
e7e3e09063 Raise ConditionError for zone errors (#46253)
* Raise ConditionError for zone errors

* Do not test missing state

* Handle multiple entities/zones
2021-02-19 13:14:47 +01:00
dependabot[bot]
40068c2f1b Bump actions/stale from v3.0.16 to v3.0.17 (#46777) 2021-02-19 08:57:28 +01:00
J. Nick Koston
0ed0c7c026 Fix backwards compatibility with vesync fans (#45950) 2021-02-19 08:54:40 +01:00
J. Nick Koston
f2b303d509 Implement percentage step sizes for fans (#46512)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-18 21:05:09 -10:00
shbatm
5df46b60e8 Fix flip-flopped substitutions in Custom Version Type Warning message. (#46768) 2021-02-19 03:00:14 +01:00
Matt Zimmerman
da51e23514 Address late smarttub review (#46703)
* _config -> config

* remove unused string

* remove entity tests

* replace unit tests with integration tests using the core

* refactor polling to use asyncio.gather

* remove redundant component init

* remove gather in favor of simple loop

* use async_fire_time_changed instead of async_update_entity

* use hass.config_entries.async_setup instead of calling smarttub.async_setup_entry directly

* replace stray smarttub.async_setup_entry call

* async_unload_entry -> hass.config_entries.async_unload

* remove broken test
2021-02-19 01:18:02 +01:00
HomeAssistant Azure
d9ce7db554 [ci skip] Translation update 2021-02-19 00:03:06 +00:00
Franck Nijhof
52a9a66d0f Upgrade cryptography to 3.3.2 (#46759) 2021-02-18 10:30:54 -10:00
Eric Severance
76e5f86b76 Add @esev as codeowner for wemo (#46756) 2021-02-18 19:08:48 +01:00
Ellis Michael
8b97f62a8e Allow LIFX bulbs to fade color even when off (#46596)
LIFX bulbs have the capability to fade their color attributes even while the bulb is off. When the bulb is later turned on, the fade will continue as if the bulb was on all along.
2021-02-18 18:40:16 +01:00
Franck Nijhof
3353c63f8f Upgrade sentry-sdk to 0.20.3 (#46754) 2021-02-18 18:25:15 +01:00
Franck Nijhof
01ebb156a0 Add selectors to Home Assistant service definitions (#46733)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2021-02-18 18:19:49 +01:00
Franck Nijhof
782863ca87 Ensure pre-commit's hassfest triggers on service file changes (#46753) 2021-02-18 18:17:09 +01:00
Franck Nijhof
b6f374b507 Add selectors to Twente Milieu service definitions (#46748) 2021-02-18 18:05:03 +01:00
Franck Nijhof
113059c1c7 Add selectors to HomeKit service definitions (#46745) 2021-02-18 17:32:48 +01:00
AdmiralStipe
e000b9c813 Added Slovenian language (sl-si) to Microsoft TTS (#46720) 2021-02-18 17:16:45 +01:00
Franck Nijhof
a80921ab65 Minor service definition tweaks (#46741) 2021-02-18 17:14:36 +01:00
Franck Nijhof
b9d5b3c34e Add selectors to Conversation, Image Processing and Number service definitions (#46746) 2021-02-18 17:13:59 +01:00
Franck Nijhof
8b69608242 Add selectors to Browser, Recorder, Shopping List service definitions (#46749) 2021-02-18 17:06:25 +01:00
Franck Nijhof
208af0367a Add selectors to Toon service definitions (#46750) 2021-02-18 17:02:45 +01:00
Franck Nijhof
81c7b3b9c9 Add selectors to Media Player service definitions (#46739) 2021-02-18 17:02:18 +01:00
Franck Nijhof
a164a6cf80 Add selectors to Hue service definitions (#46747) 2021-02-18 17:01:29 +01:00
Philip Allgaier
cdc4f634d1 Fix typo in Tesla Powerwall strings (#46752) 2021-02-18 17:01:22 +01:00
uvjustin
3c7db7bd5b Skip repeated segment in stream recorder (#46701)
* Skip repeated segment in stream recorder

* Allow for multiple overlap
2021-02-18 17:00:26 +01:00
Franck Nijhof
a5ac338c74 Add selectors to Timer service definitions (#46744) 2021-02-18 16:54:20 +01:00
Franck Nijhof
4b6b03e33e Add selectors to Lock service definitions (#46743) 2021-02-18 16:51:13 +01:00
Franck Nijhof
e57bfe05d5 Add selectors to Color Extractor service definitions (#46742) 2021-02-18 16:43:34 +01:00
Franck Nijhof
cd6a83f009 Add selectors to MQTT service definitions (#46738) 2021-02-18 16:37:15 +01:00
Franck Nijhof
3f96ebeae5 Add selectors to Logger, System Log & Logbook service definitions (#46740) 2021-02-18 16:33:29 +01:00
Franck Nijhof
62e0949ea9 Add selectors to Z-Wave JS service definitions (#46737) 2021-02-18 16:24:04 +01:00
Franck Nijhof
0f4433ce14 Add advanced selectors to Climate service definitions (#46736) 2021-02-18 16:23:10 +01:00
Franck Nijhof
b4136c3585 Add selectors to WLED service definitions (#46731) 2021-02-18 16:16:13 +01:00
Franck Nijhof
c0cdc0fe79 Add advanced selectors to Light service definitions (#46732) 2021-02-18 16:15:16 +01:00
Franck Nijhof
1d62bf8875 Add selectors to Script service definitions (#46730) 2021-02-18 16:14:16 +01:00
Franck Nijhof
74720d4afd Add selectors to Vacuum service definitions (#46728) 2021-02-18 16:13:52 +01:00
Tobias Sauerwein
bfa171f802 Add selectors to Netatmo services (#46574)
* Add selectors

* Fix schedul selector

* Update homeassistant/components/netatmo/services.yaml

Co-authored-by: Bram Kragten <mail@bramkragten.nl>

* Update homeassistant/components/netatmo/services.yaml

Co-authored-by: Bram Kragten <mail@bramkragten.nl>

* Update services.yaml

* Added required field

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2021-02-18 15:01:54 +01:00
Jesse Campbell
12477c5e46 Fix missing color switch specific device class for Z-Wave JS driver >6.3 (#46718) 2021-02-18 07:58:43 -05:00
Franck Nijhof
616e8f6a65 Add selectors to Scene service definitions (#46729) 2021-02-18 13:56:15 +01:00
Allen Porter
88d143a644 Add discontinuity support to HLS streams and fix nest expiring stream urls (#46683)
* Support HLS stream discontinuity.

* Clarify discontinuity comments

* Signal a stream discontinuity on restart due to stream error

* Apply suggestions from code review

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>

* Simplify stream discontinuity logic
2021-02-18 20:26:02 +08:00
Franck Nijhof
62cfe24ed4 Add advanced service parameter flag (#46727) 2021-02-18 12:59:46 +01:00
Franck Nijhof
82934b31f8 Add selectors to Counter service definitions (#46633) 2021-02-18 12:59:29 +01:00
Álvaro Fernández Rojas
4083b90138 ubus: switch to pypi library (#46690)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2021-02-18 12:33:21 +01:00
Franck Nijhof
0181cbb312 Upgrade and constrain httplib2>=0.19.0 (#46725) 2021-02-18 12:31:07 +01:00
Franck Nijhof
399777cfa8 Add selectors to Alarm Control Panel service definitions (#46626) 2021-02-18 12:26:05 +01:00
Franck Nijhof
ae643bfaf3 Add selectors to Climate service definitions (#46632) 2021-02-18 12:25:55 +01:00
Franck Nijhof
bc1cb8f0a0 Add selectors to Automation service definitions (#46629) 2021-02-18 12:25:25 +01:00
Franck Nijhof
e45fc4562b Add selectors to Cover service definitions (#46634)
Co-authored-by: Tobias Sauerwein <cgtobi@users.noreply.github.com>
2021-02-18 12:25:16 +01:00
Franck Nijhof
2dfbd4fbcf Add selectors to Fan service definitions (#46639) 2021-02-18 12:24:58 +01:00
Franck Nijhof
4e93a0c774 Add selectors to Downloader service definitions (#46638) 2021-02-18 12:24:50 +01:00
Franck Nijhof
c8c3ce4172 Add selectors to Switch service definitions (#46635) 2021-02-18 12:24:42 +01:00
Franck Nijhof
dec2eb36fd Add selectors to Camera service definitions (#46630) 2021-02-18 12:24:04 +01:00
Franck Nijhof
9f3fdb1b68 Add selectors to Alert service definitions (#46627) 2021-02-18 12:23:50 +01:00
Franck Nijhof
da662c4890 Add selectors to Input * service definitions (#46652) 2021-02-18 12:23:30 +01:00
J. Nick Koston
39785c5cef Switch ssdp to be async by using async_upnp_client for scanning (#46554)
SSDP scans no longer runs in the executor

This is an interim step that converts the async_upnp_client
response to netdisco's object to ensure fully backwards
compatibility
2021-02-18 11:00:11 +01:00
uvjustin
e9334347eb Bump pylutron 0.2.7 (#46717) 2021-02-18 07:54:10 +01:00
HomeAssistant Azure
28ffa97635 [ci skip] Translation update 2021-02-18 00:07:45 +00:00
Eric Severance
2ac075bb37 Perform wemo state update quickly after a timeout (#46702)
* Perform state update quickly after a timeout

* with async_timeout.timeout(...) -> async with async_timeout.timeout(...)
2021-02-18 00:38:08 +01:00
Eric Severance
8bee3cda37 Centralize wemo exception handling (#46705) 2021-02-17 23:36:39 +01:00
J. Nick Koston
b2df9aaaf1 Update zha to use new fan entity model (#45758)
* Update zha to use new fan entity model

* fixes

* tweaks for zha

* pylint

* augment test cover
2021-02-17 13:03:11 -05:00
Gaetan Semet
4ab0151fb1 Discover HRT4-ZW / SRT321 SetPoint in zwave_js (#46625)
Missing a specific class to allow discovery of the setpoint command.

Fix #46570

Signed-off-by: Gaetan Semet <gaetan@xeberon.net>
2021-02-17 15:06:16 +01:00
Tobias Sauerwein
1e9483a0e9 Bump RMVtransport to v0.3.0 (#46691) 2021-02-17 13:23:15 +01:00
Eric Severance
eb3e5cb67f Remove calls to wemo.reconnect_with_device (#46646) 2021-02-17 13:17:31 +01:00
Eric Severance
f7c0fc5553 Increase async_timeout for wemo update polling (#46649) 2021-02-17 13:17:16 +01:00
tkdrob
facbd73130 Clean up xbee (#46549) 2021-02-17 13:15:13 +01:00
ollo69
fb73768164 Fix Tuya Option Flow tests (#46651) 2021-02-17 10:43:12 +01:00
Allen Porter
efb172cedd Fix flaky stream tests due to race in idle timeout callback (#46687) 2021-02-17 01:05:50 -08:00
badguy99
971e27dd80 Home connect use consts (#46659)
* Use more consts

* black

* re-black with black, version 20.8b1
2021-02-17 09:44:37 +01:00
starkillerOG
ddf1f88b65 Fix multiple motion blinds gateways (#46622)
local variable multicast was undefined for a second or more gateway that was setup.
2021-02-17 00:25:00 -08:00
Eric Severance
94131df5e0 Remove exception handling for AttributeError in wemo (#46674) 2021-02-17 00:07:22 -08:00
Ilja Leiko
8c72cb6163 Add sensors to fetch Habitica tasks (#38910)
* Adding sensors to fetch habitica tasks

* PR changes and rebase

* Fixing pylint

* Fixing failed test dependancy

* Generating requirements

* Apply suggestions from code review

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

* PR changes

* Update homeassistant/components/habitica/config_flow.py

Thank you, @MartinHjelmare

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

* PR Changes

* Fix failing test

* Update tests/components/habitica/test_config_flow.py

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

* Fixing linting and imports

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-17 09:04:11 +01:00
Allen Porter
56f32196bd Add back block_until_done calls removed in PR 46610 (#46680) 2021-02-16 22:05:20 -08:00
Paulus Schoutsen
b956a571f4 Fix Cloud Google/Alexa check (#46681) 2021-02-17 06:49:53 +01:00
David McClosky
58f6db0127 Fix media_pause in vlc_telnet (#46675)
The underlying python-telnet-vlc pause() function toggles play/pause, so
we need to check our state before calling it.
2021-02-17 06:39:46 +01:00
Matt Zimmerman
58499946ed Add SmartTub integration (#37775)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-16 19:37:56 -10:00
Allen Porter
4236f6e5d4 Fix stream keepalive on startup (#46640)
This was accidentally dropped in a previous PR that refactored the interaction
between stream and camera. This is difficult to test from the existing
preload stream tests, so leaving untested for now.
2021-02-16 20:46:44 -08:00
HomeAssistant Azure
318cbf2913 [ci skip] Translation update 2021-02-17 00:08:46 +00:00
Ville Skyttä
b38af0821b Fix version of pip in tox (#46656) 2021-02-16 12:26:41 -10:00
Eric Severance
e4496ed1e3 Fix KeyError in comfoconnect percentage (#46654) 2021-02-16 11:07:18 -10:00
Allen Porter
aaecd91407 Fix exception in stream idle callback (#46642)
* Fix exception in stream idle callback

Fix bug where idle timeout callback fails if the stream previously exited.

* Add a test for stream idle timeout after stream is stopped.

* Add clarifying comment to idle timer clear method

* Clear hls timer only on stop
2021-02-16 12:10:26 -08:00
marecabo
c45ce86e53 Do not provide icon if device class is set in ESPHome config (#46650) 2021-02-16 20:36:32 +01:00
Mark Coombes
960b5b7d86 Fix climate hold bug in ecobee (#46613) 2021-02-16 07:06:20 -10:00
Allen Porter
08201d146b Separate HLS logic out of core StreamOutput to prepare for discontinuity (#46610)
Separate the HLS stream view logic out of StreamOutput since the hls
stream view is about to get more complex to track discontinuities. This
makes the idle timeout, shutdown, and coupling between hls and record
more explicit.
2021-02-16 06:59:43 -08:00
tkdrob
68e78a2ddc Remove unnecessary constants from universal (#46537) 2021-02-16 09:49:31 -05:00
Martin Hjelmare
f0e9ef421c Fix vlc_telnet state update (#46628)
* Clean up

* Add debug logs

* Fix info lookup

* Handle more errors

* Guard get length and time
2021-02-16 15:48:06 +01:00
starkillerOG
9d8ba6af96 Use update coordinator for Xioami Miio subdevices (#46251)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-16 15:28:25 +01:00
tkdrob
add0d9d3eb Use core constants for yeelight (#46552) 2021-02-16 09:00:09 -05:00
David McClosky
713544e5eb Bump python-vlc-telnet to 2.0.1 (#46608)
Includes corresponding Home Assistant changes to avoid introducing
regressions.
2021-02-16 12:32:53 +01:00
Franck Nijhof
a6912277eb Remove defunct CoinMarketCap integration (#46615) 2021-02-16 11:00:08 +01:00
Joakim Plate
0bfcd5e1ee Use explicit open/close for covers (#46602) 2021-02-16 10:26:38 +01:00
Bram Kragten
6986fa4eb6 Add target to services.yaml (#46410)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-02-16 09:35:27 +01:00
J. Nick Koston
20d93b4b29 Remove support for migrating pre-config entry homekit (#46616)
HomeKit pairings and accessory ids from versions 0.109 and earlier are no longer
migrated on upgrade. Users upgrading directly to 2021.3 from 0.109
and older should upgrade to 2021.2 first if they wish to preserve
HomeKit configuration and avoid re-pairing the bridge.

This change does not affect upgrades from 0.110 and later.
2021-02-16 08:37:43 +01:00
marecabo
1e172dedf6 Add device_class attribute to ESPHome sensor entities (#46595) 2021-02-15 20:19:31 -10:00
ollo69
3c26235e78 Bump tuyaha to 0.0.10 and fix set temperature issues (#45732) 2021-02-15 16:20:45 -10:00
HomeAssistant Azure
1bb535aa67 [ci skip] Translation update 2021-02-16 00:03:57 +00:00
tkdrob
2a7d2868be Use core constants for xiaomi_aqara (#46551) 2021-02-16 00:14:27 +01:00
Franck Nijhof
ea47e5d8af Upgrade sentry-sdk to 0.20.2 (#46590) 2021-02-15 22:02:58 +01:00
J. Nick Koston
6f4df7e52e Use shared clientsession for sense (#46419) 2021-02-15 10:35:58 -10:00
Kevin Fronczak
e3ae3cfb83 Upgrade blinkpy to 0.17.0 (#46581) 2021-02-15 20:24:42 +01:00
starkillerOG
2f9fda73f4 Add config flow to Xiaomi Miio switch (#46179) 2021-02-15 20:11:27 +01:00
Joakim Sørensen
68809e9f43 Fix issue with timeout and error response (#46584) 2021-02-15 20:08:08 +01:00
Allen Porter
89aaeb3c35 Refactor stream worker responsibilities for segmenting into a separate class (#46563)
* Remove stream_worker dependencies on Stream

Removee stream_worker dependencies on Stream and split out the logic
for writing segments to a stream buffer.

* Stop calling internal stream methods

* Update homeassistant/components/stream/worker.py

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>

* Reuse self._outputs when creating new streams

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>
2021-02-15 09:52:37 -08:00
Niels Mündler
f2ca4acff0 Limit fronius error messages on failed connection (#45824)
* Do not print several error messages on failed connection

* Change wrapping of exception, implement available

* Simplify exception flow

* Remove unnecessary init

* Add available property to actual entities

* Rebase and formatting
2021-02-15 18:28:28 +01:00
Joakim Sørensen
886067a327 Add websocket handlers to hassio (#46571) 2021-02-15 18:18:45 +01:00
Shay Levy
a5d943b5f1 MQTT cover Bugfixes (#46479)
* MQTT cover Bugfixes

* Remove period
2021-02-15 17:33:42 +01:00
uvjustin
9917bb76fb Use httpx in generic camera (#46576)
* Use httpx in generic camera

* Remove commented out code
2021-02-15 16:37:53 +01:00
J. Nick Koston
c5b9ad83c2 Log ffmpeg errors for homekit cameras (#46545) 2021-02-15 12:39:51 +01:00
Lukáš Polívka
bed29fd4b1 Convert better from byte value to percentage in futurenow (#45042)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-02-15 12:33:13 +01:00
Erik Montnemery
c8e04ee960 Bump hatasmota to 0.2.9 (#46561) 2021-02-15 12:16:28 +01:00
Erik Montnemery
5a907ebafc Remove @home-assistant/core from MQTT codeowners (#46562) 2021-02-15 11:51:56 +01:00
Allen Porter
3f4828f5e1 Add additional stream HLS payload tests (#46517)
* Add tests for HLS playlist view details

* Add tests for hls playlist payloads

* Update tests/components/stream/test_hls.py

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>

* Update tests/components/stream/test_hls.py

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>

* Update tests/components/stream/test_hls.py

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>

* Update tests/components/stream/test_hls.py

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>

* Update tests/components/stream/test_hls.py

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>

* Update tests/components/stream/test_hls.py

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>

* Update tests/components/stream/test_hls.py

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>

Co-authored-by: uvjustin <46082645+uvjustin@users.noreply.github.com>
2021-02-14 20:32:37 -08:00
Raman Gupta
cfdaadf5d9 Allow users to set device class for universal media player (#46550) 2021-02-14 17:05:23 -10:00
tkdrob
06c8fc6ef1 Use core constants for wemo and whois (#46548) 2021-02-14 20:14:48 -05:00
Raman Gupta
a3b733f1ec Add additional supported feature support to universal media player (#44711)
* add additional supported feature support to universal media player

* add missing services
2021-02-14 19:35:14 -05:00
HomeAssistant Azure
0af634a9f8 [ci skip] Translation update 2021-02-15 00:14:36 +00:00
J. Nick Koston
12abe5707d Fix typing on tuya fan percentage (#46541) 2021-02-14 17:05:31 -05:00
tkdrob
7e88487800 Use core constants for wemo (#46544) 2021-02-14 17:01:53 -05:00
tkdrob
a5f372018c Use core constants for volvooncall (#46543) 2021-02-14 17:01:18 -05:00
tkdrob
f1c792b4c8 Use core constants for uvc (#46538) 2021-02-14 22:21:55 +01:00
J. Nick Koston
aa061e5818 Fix variable name from script refactoring (#46503) 2021-02-14 10:52:18 -10:00
tkdrob
1444afbe5a Use core constants for vasttrafik (#46539) 2021-02-14 21:47:08 +01:00
J. Nick Koston
c9df42b69a Add support for pre-filtering events to the event bus (#46371) 2021-02-14 09:42:55 -10:00
Anders Melchiorsen
f8f86fbe48 Do not trigger when template is true at startup (#46423) 2021-02-14 19:54:11 +01:00
jan iversen
855bd653b4 Update modbus test harness (#44892)
* Update test harness to allow discovery_info testing.

This is a needed update, before the whole config is converted
to the new structure, because it allows test of both the old
and new configuration style.

The following changes have been made:
- Combine test functions into a single base_test.
- Prepare for new mock by combining the 2 common test functions into one.
- Change mock to be only modbusHub
- Do not replace whole modbus class, but only the class that
  connects to pymodbus (modbusHub). This allows test of modbus
  configurations and not only component configurations, and is needed
  when testing discovery activated platform.
- Add test of climate.
  Warning this is merely test of discovery,
  the real cover tests still needs to be added.
- Add test of cover.
  Warning this is merely test of discovery,
  the real cover tests still needs to be added.

* Update comment for old config

* Do not use hass.data, but instead patch pymodbus library.

* Add test of configuration (old/new way as available).

* Move assert to test function.

Make assert more understandable by removing it from the helper.

add base_config_test (check just calls base_test) to make it clear if
test is wanted or just controlling the config.

* use setup_component to load Modbus since it is an integration.

* Optimized flow in test helper.
2021-02-14 17:40:30 +01:00
javicalle
9777608861 Add myself to RFLink codeowners (#46511) 2021-02-14 16:24:00 +01:00
Tom Parker-Shemilt
27d16af36b Don't allow recursive secrets loading (#41812)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-14 14:23:31 +01:00
tkdrob
a5a45f29e2 Cleanup unused loggers (#46510) 2021-02-14 13:46:58 +01:00
Allen Porter
10e88cd23d Improve nest defense against broken event loop on shutdown (#46494) 2021-02-14 13:36:05 +01:00
kpine
dfa973f9ef Add barrier covers to zwave_js integration (#46379) 2021-02-14 13:24:29 +01:00
Andrey Kupreychik
accba85e35 Add keenetic_ndms2 config flow (#38353) 2021-02-14 13:09:19 +01:00
tkdrob
2c3a2bd35e Clean up template (#46509) 2021-02-14 12:16:30 +01:00
Khole
811e1cc3e6 Add hive hub 360 sensors (#46320) 2021-02-14 11:39:31 +01:00
tkdrob
3ea02e646d Use core constants for trend (#46521) 2021-02-14 11:30:40 +01:00
tkdrob
294d3c6529 Use core constants for thethingsnetwork (#46520) 2021-02-14 11:28:55 +01:00
tkdrob
854504cccc Use core constants for switcher_kis (#46507) 2021-02-14 10:21:53 +01:00
tkdrob
c76758f775 Use core constants for temper (#46508) 2021-02-14 10:21:02 +01:00
MatthewFlamm
7a401d3d5d Fix missing condition in nws (#46513) 2021-02-13 17:35:57 -10:00
J. Nick Koston
1845f69729 Update tuya for new fan entity model (#45870) 2021-02-13 16:23:19 -10:00
HomeAssistant Azure
17a4678906 [ci skip] Translation update 2021-02-14 00:06:28 +00:00
tkdrob
dfe173d619 Use core constants for rmvtransport (#46502) 2021-02-13 18:22:28 -05:00
tkdrob
5db4d78dc7 Use core constants for rpi_rf (#46500) 2021-02-13 18:21:42 -05:00
tkdrob
84488b9c28 Use core constants for sma (#46501) 2021-02-13 18:21:15 -05:00
Franck Nijhof
7148071be8 Improve Elgato code quality (#46505) 2021-02-13 23:50:25 +01:00
Álvaro Fernández Rojas
eecf07d7df Add AEMET OpenData integration (#45074)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-13 21:53:28 +01:00
J. Nick Koston
2f40f44670 Update HAP-python to 3.3.0 for homekit (#46497)
Changes: https://github.com/ikalchev/HAP-python/compare/v3.2.0...v3.3.0
2021-02-13 20:30:55 +01:00
ollo69
f38b06ed6d Add Asuswrt Config Flow and Scanner Entities (#46468)
* Add Asuswrt config flow (#43948)

* Add AsusWrt Scanner Entity (#44759)

* Add Scanner Entity

- device tracker entity changed from "DeviceScanner" to "ScannerEntity"
- sensors recoded to use "router" class
- config entry review to allow multiple entity (for future use)

* Force checks

* Removed new option and change sensors

* Update test_sensor.py

* Requested changes

* Removed router unique-id

* Update last_activity attr only when available

* Add Options for AsusWRT Scanner Entity (#44808)

* Add Asuswrt config flow (#43948)

* Add AsusWrt Scanner Entity (#44759)

* Add Scanner Entity

- device tracker entity changed from "DeviceScanner" to "ScannerEntity"
- sensors recoded to use "router" class
- config entry review to allow multiple entity (for future use)

* Force checks

* Removed new option and change sensors

* Update test_sensor.py

* Requested changes

* Removed router unique-id

* Update last_activity attr only when available

* Add Options for Scanner Entity

* Fix isort

* Removed "Track New" option

* Add Options for Scanner Entity

* Fix isort

* Removed "Track New" option

* Add test for all the options in the config flow
2021-02-13 19:17:06 +01:00
Shay Levy
6f261a09b0 Remove deprecated xfinity integration (#46484) 2021-02-13 14:07:55 +01:00
Shay Levy
52c5bc0a99 Remove deprecated Synology integration (#46482) 2021-02-13 13:23:40 +01:00
Franck Nijhof
bc1daf1802 None optional hass typing in FlowHandler (#46462)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-13 13:21:37 +01:00
Rob Bierbooms
1244fb4152 Bump dsmr_parser to 0.28, configure keep_alive_interval (#46464) 2021-02-13 13:19:38 +01:00
tkdrob
13b881acfc Use core constants for simplepush (#46465) 2021-02-13 13:07:11 +01:00
tkdrob
621c8e700b Use core constants for starline (#46471) 2021-02-13 12:33:13 +01:00
Maciej Bieniek
b8584cab5d Remove unnecessary gethostbyname() from Shelly integration (#46483) 2021-02-13 12:27:54 +01:00
tkdrob
820a260252 Use core constants for homeassistant triggers (#46472) 2021-02-13 12:07:42 +01:00
tkdrob
2ecac6550f Use core constants for dynalite (#46044) 2021-02-13 12:06:20 +01:00
On Freund
1a8cdba9af Gracefully handle missing A/V info in Onkyo integration (#46228)
* Gracefully handle missing A/V info

* Do not attempt to query A/V info if unsupported

* Rename _parse_onkyo_tuple
2021-02-13 12:03:49 +01:00
HomeAssistant Azure
8bacfcec50 [ci skip] Translation update 2021-02-13 00:03:13 +00:00
tkdrob
ae45d7dade Use core constants for rflink (#46440) 2021-02-12 23:32:56 +01:00
tkdrob
da4cb6d294 Use core constants for somfy (#46466) 2021-02-12 23:25:15 +01:00
J. Nick Koston
bc8a52038b Fix homekit migration not being awaited (#46460) 2021-02-12 08:45:19 -10:00
Franck Nijhof
dd8d4471ec Postponed evaluation of annotations for integrations (#46455) 2021-02-12 18:54:00 +01:00
Maciej Bieniek
061d9c5293 Bump brother library to version 0.2.1 (#46421) 2021-02-12 18:11:35 +01:00
Franck Nijhof
362a1cd9bd Upgrade sentry-sdk to 0.20.1 (#46456) 2021-02-12 17:59:08 +01:00
Erik Montnemery
f1714dd541 Make some Area and EntityRegistry member functions callbacks (#46433) 2021-02-12 17:00:35 +01:00
jan iversen
8418489345 Allow Modbus "old" config or discovery_info as configuration (#46445) 2021-02-12 16:33:18 +01:00
tkdrob
f929aa222f Use core constants for roomba (#46441) 2021-02-12 16:09:36 +01:00
Christophe Painchaud
c3b460920e Enable TCP KEEPALIVE to RFLink for dead connection detection (#46438)
RFLink compoment when used over TCP protocol suffers a major issue : it doesn't
know when connection is timeout or lost because there is no keepalive mechanism
so it can stay disconnected forever.
I wrote a small patch for the underlying 'python-rflink' library which will enable
TCP KEEPPAlive. On HASSIO side it will just add an optional argument in yml file
which will propagate to python-rflink caller.
2021-02-12 15:58:59 +01:00
David Dix
a8beae3c51 Add apple tv remote delay command (#46301)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-12 14:58:01 +01:00
Robert Kingston
479ff92acb Fix cmus remote disconnections (#40284)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-12 13:31:36 +01:00
Marcel van der Veldt
b7dd9bf58f Enhance platform discovery for zwave_js (#46355) 2021-02-12 13:29:11 +01:00
tkdrob
74f5f8976f Use core constants for rpi_gpio (#46442) 2021-02-12 12:15:30 +01:00
Erik Montnemery
190a9f66cb Improve MQTT timeout print (#46398) 2021-02-12 11:43:44 +01:00
tkdrob
0d2f5cf7ed Use core constants for plugwise (#46414) 2021-02-12 11:42:34 +01:00
Franck Nijhof
9b7c39d20b Postponed evaluation of annotations in core (#46434)
* Postponed evaluation of annotations in core

* Remove unneeded future
2021-02-12 10:58:20 +01:00
tkdrob
910c034613 Use core constants for recollect_waste (#46416) 2021-02-12 09:28:11 +01:00
Joakim Plate
a67b598971 Correct errors found on post merge review in philips_js (#46428)
* Correct missed review changes

* Adjust return value for device trigger

* Drop cannot connect

* Always assume there is a unique id

* No need to yield

* Update homeassistant/components/philips_js/media_player.py

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

* Move typing to init

* Adjust typing instead of returning lambda

* Explicity return None

* Coerce into int

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-12 02:35:29 +01:00
HomeAssistant Azure
ee04473e85 [ci skip] Translation update 2021-02-12 00:02:46 +00:00
chriss158
34a491f826 Install libpcap-dev for devcontainer (#46106) 2021-02-11 13:17:49 -10:00
Joakim Plate
8dc06e612f Add config flow to philips_js (#45784)
* Add config flow to philips_js

* Adjust name of entry to contain serial

* Use device id in event rather than entity id

* Adjust turn on text

* Deprecate all fields

* Be somewhat more explicit in typing

* Switch to direct coordinator access

* Refactor the pluggable action

* Adjust tests a bit

* Minor adjustment

* More adjustments

* Add missing await in update coordinator

* Be more lenient to lack of system info

* Use constant for trigger type and simplify

* Apply suggestions from code review

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

Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-11 21:37:53 +01:00
Czapla
14a64ea970 Add generic_thermostat unique ID parameter (#46399)
* Add generic_thermostat unique ID parameter

* Add tests for unique id

* Fix flake8
2021-02-11 19:46:58 +00:00
Erik Montnemery
26e7916367 Migrate mobile_app to RestoreEntity (#46391) 2021-02-11 20:18:03 +01:00
tkdrob
70e23402a9 Use core constants for ohmconnect (#46413) 2021-02-11 13:56:50 -05:00
Martin
eb0d1bb673 Improve knx fan implementation (#46404) 2021-02-11 07:55:17 -10:00
tkdrob
fd177441b3 Use core constants for nmap_tracker (#46402) 2021-02-11 17:45:26 +01:00
tkdrob
c95f401e2e Use core constants for nissan_leaf (#46401) 2021-02-11 17:44:39 +01:00
Erik Montnemery
ed31cc363b Wait for registries to load at startup (#46265)
* Wait for registries to load at startup

* Don't decorate new functions with @bind_hass

* Fix typing errors in zwave_js

* Load registries in async_test_home_assistant

* Tweak

* Typo

* Tweak

* Explicitly silence mypy errors

* Fix tests

* Fix more tests

* Fix test

* Improve docstring

* Wait for registries to load
2021-02-11 17:36:19 +01:00
Anders Melchiorsen
888c9e120d Raise ConditionError for time errors (#46250) 2021-02-11 17:29:17 +01:00
Steve Dwyer
5ce49c62b1 Allow MQTT template light floating point transition (#46385)
Allow to use floating point values for the transition time of the MQTT
template light.
2021-02-11 14:57:27 +01:00
tkdrob
b1a7bfee14 Clean up kira integration constants (#46390) 2021-02-11 07:59:09 -05:00
tkdrob
c75e63dc95 Use core constants for modbus (#46388) 2021-02-11 07:58:16 -05:00
tkdrob
b85ecc0bd2 Use core constants for mqtt (#46389) 2021-02-11 13:38:33 +01:00
Franck Nijhof
c10bf079f7 Merge pull request #46383 from home-assistant/rc 2021-02-11 12:52:44 +01:00
tkdrob
1b61b5c10b Clean up kira integration (#46292) 2021-02-11 11:04:11 +01:00
Shay Levy
4034a274f7 Fix Shelly relay device set to light appliance type (#46181) 2021-02-11 10:40:54 +01:00
Shay Levy
6015161dab Fix Shelly relay device set to light appliance type (#46181) 2021-02-11 10:40:03 +01:00
Franck Nijhof
953491d509 Bumped version to 2021.2.3 2021-02-11 10:38:21 +01:00
Paulus Schoutsen
b5061d0232 Restore Google/Alexa extra significant change checks (#46335) 2021-02-11 10:37:50 +01:00
Bram Kragten
291746334a Add already_in_progress string to roku config flow (#46333) 2021-02-11 10:37:47 +01:00
J. Nick Koston
9f839b8c61 Add reauth support for tesla (#46307) 2021-02-11 10:37:43 +01:00
Marcel van der Veldt
70af3e4776 Add guards for missing value in binary_sensor platform of zwave_js integration (#46293) 2021-02-11 10:37:40 +01:00
Greg Dowling
1c2f72a453 Bump roonapi to 0.0.32 (#46286) 2021-02-11 10:37:36 +01:00
J. Nick Koston
bf2a34600a Fix Lutron Integration Protocol reconnect logic (#46264) 2021-02-11 10:37:33 +01:00
J. Nick Koston
b5bdd7f2cf Update powerwall for new authentication requirements (#46254)
Co-authored-by: badguy99 <61918526+badguy99@users.noreply.github.com>
2021-02-11 10:37:29 +01:00
J.P. Hutchins
30ddfd837a Revert transmission to check torrent lists by name rather than object (#46190) 2021-02-11 10:37:26 +01:00
ehendrix23
d2d2bed16b Bump pymyq to 3.0.1 (#46079)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-11 10:37:22 +01:00
Alan Tse
db557a094c Use oauthv3 for Tesla (#45766) 2021-02-11 10:37:18 +01:00
Anders Melchiorsen
1f5fb8f28a Raise ConditionError for template errors (#46245) 2021-02-11 10:30:09 +01:00
tkdrob
e013ad2413 Use core constants for microsoft (#46369) 2021-02-11 10:25:43 +01:00
J. Nick Koston
f9f4c0aeed Fix explict return in tesla config flow (#46377) 2021-02-11 10:24:31 +01:00
tkdrob
29d8b8a22f Some code cleanups for ESPHome (#46367) 2021-02-11 10:19:39 +01:00
tkdrob
379f5455e5 Use core constants for lovelace (#46368) 2021-02-11 10:13:18 +01:00
Mike Keesey
f549ec5ec9 Use activity ids for unique_id for Harmony switches (#46139) 2021-02-10 21:50:27 -10:00
Leonardo Figueiro
3ffa42e56a Update WiLight Cover Fan Light (#46366) 2021-02-10 21:25:42 -10:00
tkdrob
56adc9dadb Use core constants for lcn (#46348) 2021-02-10 21:22:32 -05:00
tkdrob
af2fa17e8e Use core constants for local_file (#46349) 2021-02-10 21:21:35 -05:00
tkdrob
7f8fa7feaf Use core constants for logi_circle (#46359) 2021-02-10 21:20:40 -05:00
HomeAssistant Azure
8007391244 [ci skip] Translation update 2021-02-11 00:02:56 +00:00
Leonardo Figueiro
6182fedf3f Update wilight tests for new fan entity model (#46358) 2021-02-10 13:09:03 -10:00
J. Nick Koston
281fbe1dfa Update wilight for new fan entity model (#45869) 2021-02-10 12:49:52 -10:00
tkdrob
d8a2e0e051 Remove unnecessary variables from logbook (#46350) 2021-02-10 12:17:37 -10:00
Maciej Bieniek
fdd8159955 Fix SNMP engine memory leak in Brother integration (#46272)
* Fix SNMP engine memory leak

* Fix pylint error
2021-02-10 22:32:48 +01:00
uvjustin
acde33dbbc Keep 1 extra segment around after playlist removal (#46310)
* Keep 1 extra segment around after playlist removal

* Remove segments length check
2021-02-10 15:51:16 -05:00
ehendrix23
9bc3c6c130 Bump pymyq to 3.0.1 (#46079)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-10 10:30:52 -10:00
J. Nick Koston
c59b1c72c5 Add reauth support for tesla (#46307) 2021-02-10 20:55:06 +01:00
J.P. Hutchins
67ab86443e Revert transmission to check torrent lists by name rather than object (#46190) 2021-02-10 20:53:31 +01:00
J. Nick Koston
884df40951 Update powerwall for new authentication requirements (#46254)
Co-authored-by: badguy99 <61918526+badguy99@users.noreply.github.com>
2021-02-10 20:50:38 +01:00
J. Nick Koston
2e2eab662b Fix Lutron Integration Protocol reconnect logic (#46264) 2021-02-10 20:48:15 +01:00
Erik Montnemery
fc4fc48763 Bump hatasmota to 0.2.8 (#46340) 2021-02-10 20:42:34 +01:00
Leonardo Figueiro
2db102e023 Add WiLight Cover (#46065)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-10 09:08:39 -10:00
Alan Tse
cdd78316c4 Use oauthv3 for Tesla (#45766) 2021-02-10 08:01:24 -10:00
Paulus Schoutsen
538df17a28 Restore Google/Alexa extra significant change checks (#46335) 2021-02-10 16:30:29 +01:00
Marcel van der Veldt
74647e1fa8 Add guards for missing value in binary_sensor platform of zwave_js integration (#46293) 2021-02-10 10:30:16 -05:00
Joakim Sørensen
917a616ce1 Replace parse_version with AwesomeVersion (#46329) 2021-02-10 15:58:26 +01:00
Joakim Sørensen
dbb98e6cac Replace LooseVersion with AwesomeVersion (#46330) 2021-02-10 15:26:38 +01:00
Joakim Sørensen
ea4ad85488 Replace StrictVersion with AwesomeVersion (#46331) 2021-02-10 15:25:44 +01:00
Bram Kragten
7928cda080 Add already_in_progress string to roku config flow (#46333) 2021-02-10 15:25:24 +01:00
tkdrob
ad72715212 Use core constants for konnected (#46322) 2021-02-10 08:57:53 -05:00
Franck Nijhof
b7e11347d5 Remove defunct Crime Reports integration (#46312) 2021-02-10 14:56:54 +01:00
Erik Montnemery
c66d9ea25c Hide volume control for cast devices with fixed volume (#46328) 2021-02-10 08:39:10 -05:00
tkdrob
ad400d91bc Use core constants for sensor integration (#46290) 2021-02-10 08:36:05 -05:00
tkdrob
6e1f3b7861 Use core constants for joaoapps_join (#46291) 2021-02-10 08:35:11 -05:00
Franck Nijhof
22389043eb Remove base_url fallback (#46316) 2021-02-10 14:31:11 +01:00
Ville Skyttä
a6358430b4 Fix deprecated asyncio.wait use with coroutines (#44981)
https://docs.python.org/3/library/asyncio-task.html#asyncio-example-wait-coroutine
2021-02-10 14:16:58 +01:00
Bram Kragten
4b493c5ab9 Add target to service call API (#45898)
* Add target to service call API

* Fix _async_call_service_step

* CONF_SERVICE_ENTITY_ID overrules target

* Move merging up before processing schema

* Restore services.yaml

* Add test
2021-02-10 12:42:28 +01:00
Shay Levy
7d2d98fc3c Revert multiple interfaces (#46300) 2021-02-10 12:38:16 +01:00
Erik Montnemery
bfd5a62bad Fix typo (#46321) 2021-02-10 11:31:51 +01:00
uvjustin
1fea24502c Bump pyav version to 8.03 (#46315) 2021-02-10 18:14:03 +08:00
Erik Montnemery
78b7fbf7b1 Fix race in EntityRegistry.async_device_modified (#46319) 2021-02-10 10:50:44 +01:00
Greg Dowling
b0b81246f0 Bump roonapi to 0.0.32 (#46286) 2021-02-10 10:27:25 +01:00
Martin
175f2f0275 Add fan platform to knx (#46161) 2021-02-09 22:09:34 -10:00
Allen Porter
26f455223b Update nest stream URLs expiration (#46311) 2021-02-09 23:53:34 -08:00
Allen Porter
00aebec90d Fix bug in test found by manual log inspection (#46309) 2021-02-09 21:59:49 -08:00
HomeAssistant Azure
5fcb948e28 [ci skip] Translation update 2021-02-10 00:05:10 +00:00
Khole
3381e2f65a Convert Hive to Async (#46117)
* Convert Hive to Async

* Update Refresh System

* Update load platform to Async

* Changes from review feedback

* Review Round 2

* Updated service

* Updated dict keys

* Convert Hive to Async

* Update Refresh System

* Update load platform to Async

* Changes from review feedback

* Review Round 2

* Updated service

* Updated dict keys

* Convert Hive to Async

* Update Refresh System

* Update load platform to Async

* Changes from review feedback

* Review Round 2

* Updated service

* Updated dict keys

* Updated Refresh System
2021-02-09 22:03:49 +01:00
tkdrob
6f4cb18fa8 Use core constants for here_travel_time (#46246) 2021-02-09 20:23:46 +01:00
tkdrob
a26cf7aeec Remove unnecessary variable definition in firmata (#46172) 2021-02-09 20:23:02 +01:00
bsmappee
1c1b2f497a bump pysmappee (#46270) 2021-02-09 20:21:51 +01:00
tkdrob
57ce182959 Remove unnecessary constant from ihc (#46268) 2021-02-09 20:21:04 +01:00
tkdrob
f46dc3c48e Use core constants for elkm1 (#46091) 2021-02-09 20:20:20 +01:00
tkdrob
c69c493cf9 Use core constants for image_processing (#46269) 2021-02-09 08:03:14 -05:00
tkdrob
da67cde369 Use core constants for homematic (#46248) 2021-02-09 12:02:53 +01:00
Anders Melchiorsen
f27066e773 Raise ConditionError for state errors (#46244) 2021-02-09 09:46:36 +01:00
J. Nick Koston
6a62ebb6a4 Add BPUP (push updates) support to bond (#45550) 2021-02-09 09:43:38 +01:00
Maciej Bieniek
2fc1c19a45 Allow to setup of a previously discovered sleeping Shelly device (#46124)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-02-09 09:28:40 +01:00
Robert Svensson
20f45f8ab9 Improve deCONZ tests by using aioclient_mock rather than patching web requests (#45927)
* Don't patch web requests, use aioclient_mock instead

* Remove stale prints

* Remove tests for old way of loading platforms

* Remove unused imports
2021-02-09 08:31:29 +01:00
Allen Porter
b33753f334 Move camera timeouts to constants (#46262)
Addresses feedback from pr #45431.  Also removes an redundant `create_stream` timeout.
2021-02-08 21:21:14 -08:00
Allen Porter
2bcf87b980 Change the API boundary between camera and stream with initial improvement for nest expiring stream urls (#45431)
* Change the API boundary between stream and camera

Shift more of the stream lifecycle management to the camera.  The motivation is to support stream urls that expire
giving the camera the ability to change the stream once it is created.

* Document stream lifecycle and simplify stream/camera interaction

* Reorder create_stream function to reduce diffs

* Increase test coverage for camera_sdm.py

* Fix ffmpeg typo.

* Add a stream identifier for each stream, managed by camera

* Remove stream record service

* Update homeassistant/components/stream/__init__.py

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

* Unroll changes to Stream interface back into camera component

* Fix preload stream to actually start the background worker

* Reduce unncessary diffs for readability

* Remove redundant camera stream start code

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-08 19:53:28 -08:00
Pascal Reeb
889baef456 Add DHCP discovery support to Nuki integration (#46032) 2021-02-08 17:11:27 -10:00
HomeAssistant Azure
936ee7d733 [ci skip] Translation update 2021-02-09 00:07:22 +00:00
J. Nick Koston
6563c37ab1 Add support for generic lights to bond (#46193) 2021-02-09 00:39:21 +01:00
J. Nick Koston
93fafedf72 Cleanup bond identifiers and device info (#46192) 2021-02-09 00:37:32 +01:00
Erik Montnemery
58b4a91a5b Test that variables are passed to wait_for_trigger script action (#46221) 2021-02-09 00:34:18 +01:00
tkdrob
c602c619a2 Use core constants for hikvision (#46247) 2021-02-09 00:13:58 +01:00
J. Nick Koston
6467eff09c Fix incorrect current temperature for homekit water heaters (#46076) 2021-02-08 23:23:02 +01:00
J. Nick Koston
dc26fd5149 Ensure creating an index that already exists is forgiving for postgresql (#46185)
Unlikely sqlite and mysql, postgresql throws ProgrammingError instead
of InternalError or OperationalError when trying to create an index
that already exists.
2021-02-08 23:22:38 +01:00
tkdrob
6b340415b2 Use core constants for greeneye_monitor (#46238) 2021-02-08 22:53:46 +01:00
tkdrob
c2302784c2 Use core constants for helpers (#46240) 2021-02-08 22:53:17 +01:00
tkdrob
00bbf8c3a2 Use core constants for group component (#46239) 2021-02-08 22:52:28 +01:00
J. Nick Koston
c0a1fc2916 Handle empty mylink response at startup (#46241) 2021-02-08 22:51:46 +01:00
Álvaro Fernández Rojas
fcae840641 Fix Tado Power and Link binary sensors (#46235)
Power and Link aren't converted from strings to booleans by python-tado, so we
need to properly parse before assigning the string value to binary sensors.

Fixes: 067f2d0098 ("Add tado zone binary sensors (#44576)")
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2021-02-08 22:49:46 +01:00
J. Nick Koston
71d7ae5992 Downgrade and improve lutron caseta LIP error message (#46236) 2021-02-08 22:48:02 +01:00
Marcel van der Veldt
829131fe51 Update zwave_js discovery scheme for boolean sensors in the Alarm CC (#46085) 2021-02-08 11:57:22 -05:00
Marcel van der Veldt
be779d8712 update discovery scheme for zwave_js light platform (#46082) 2021-02-08 11:56:19 -05:00
Paulus Schoutsen
e27619fe50 Allow discovery info accessible from CORS enabled domains (#46226) 2021-02-08 17:19:55 +01:00
Álvaro Fernández Rojas
1b194e3b2f Add noltari to Tado code owners (#46216) 2021-02-08 11:08:13 -05:00
Bram Kragten
86fe5d0561 Update frontend to 20210208.0 (#46225) 2021-02-08 16:42:33 +01:00
Allen Porter
dca6a93898 Centralize keepalive logic in Stream class (#45850)
* Remove dependencies on keepalive from StremaOutput and stream_worker

Pull logic from StreamOutput and stream_worker into the Stream
class, unifying keepalive and idle timeout logic. This prepares
for future changes to preserve hls state across stream url changes.
2021-02-08 07:19:41 -08:00
Paulus Schoutsen
e20a814926 Call setup during devcontainer create (#46224) 2021-02-08 16:16:40 +01:00
Shay Levy
81c88cd639 Enhance MQTT cover platform (#46059)
* Enhance MQTT cover platform

Allow combining of position and state of MQTT cover
Add template and fix optimistic in set tilt position
Add tests

* Add abbreviations

* Add tests and stopped state

* Cleanup & fix range for templates

* Apply suggestions from code review

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2021-02-08 16:02:12 +01:00
Greg Dowling
8f4ea3818d Add unavailable to Vera (#46064) 2021-02-08 15:25:54 +01:00
Henco Appel
b1ffe429cd Fix BT Smarthub device tracker (#44813) 2021-02-08 15:24:18 +01:00
Joeri
2811e39c5c Add entity specific force_update for DSMR (#46111) 2021-02-08 15:18:36 +01:00
Franck Nijhof
48808978c4 Upgrade pre-commit to 2.10.1 (#46211) 2021-02-08 15:05:11 +01:00
Martin Hjelmare
568180632e Fix sync oath2 scaffold template (#46219) 2021-02-08 15:00:17 +01:00
Bram Kragten
6f446cf627 Add my component (#46058)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-08 14:44:46 +01:00
Anders Melchiorsen
48002f47f4 Use caplog fixture for log capturing (#46214) 2021-02-08 14:33:57 +01:00
Erik Montnemery
0780e52ca4 Support templates in event triggers (#46207)
* Support templates in event triggers

* Don't validate trigger schemas twice
2021-02-08 14:06:27 +01:00
Matteo Agnoletto
eaa2d371a7 Add select selector for blueprints (#45803)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-02-08 14:03:26 +01:00
Erik Montnemery
2744d64a3e Pass variables to state trigger templates (#46208)
* Pass variables to state trigger templates

* Remove non working test
2021-02-08 13:22:01 +01:00
Erik Montnemery
9d9c4b47ee Pass variables to numeric state trigger templates (#46209) 2021-02-08 13:21:31 +01:00
tkdrob
92e5bf9786 Use core constants for google (#46210) 2021-02-08 12:24:48 +01:00
Ville Skyttä
82607977ef Various type hint improvements (#46144) 2021-02-08 11:59:46 +01:00
tkdrob
54dce1c505 Use core constants for fleetgo (#46200) 2021-02-08 11:47:30 +01:00
Fabian Affolter
5a4e1eeb0e Upgrade praw to 7.1.4 (#46202) 2021-02-08 11:46:58 +01:00
Hmmbob
a23e05d1f6 Fix Google translate TTS by bumping gTTS from 2.2.1 to 2.2.2 (#46110) 2021-02-08 11:43:30 +01:00
tkdrob
87c36d6b6b Use core constants for google_assistant (#46204) 2021-02-08 11:36:59 +01:00
tkdrob
5faf463205 Use core constants for frontend component (#46203) 2021-02-08 11:36:45 +01:00
tkdrob
9b0955b67e Use core constants for flux (#46201) 2021-02-08 11:26:57 +01:00
Matthias Alphart
e7ca0ff71a Enable KNX auto_reconnect for auto-discovered connections (#46178) 2021-02-08 11:23:50 +01:00
Erik Montnemery
f99c27c6d4 Remove unneeded from_state from device triggers (#45152) 2021-02-08 11:09:45 +01:00
Per Sandström
8efb5eea4d Bump python-verisure to version 1.7.2 (#46177) 2021-02-08 11:00:23 +01:00
Erik Montnemery
047f16772f Support templating MQTT triggers (#45614)
* Add support for limited templates (no HASS access)

* Pass variables to automation triggers

* Support templates in MQTT triggers

* Spelling

* Handle trigger referenced by variables

* Raise on unsupported function in limited templates

* Validate MQTT trigger schema in MQTT device trigger

* Add trigger_variables to automation config schema

* Don't print stacktrace when setting up trigger throws

* Make pylint happy

* Add trigger_variables to variables

* Add debug prints, document limited template

* Add tests

* Validate MQTT trigger topic early when possible

* Improve valid_subscribe_topic_template
2021-02-08 10:50:38 +01:00
Anders Melchiorsen
b9b1caf4d7 Raise ConditionError for numeric_state errors (#45923) 2021-02-08 10:47:57 +01:00
Paulus Schoutsen
9e07910ab0 Mark entities as unavailable when they are removed but are still registered (#45528)
* Mark entities as unavailable when they are removed but are still registered

* Add sync_entity_lifecycle to collection helper

* Remove debug print

* Lint

* Fix tests

* Fix tests

* Update zha

* Update zone

* Fix tests

* Update hyperion

* Update rfxtrx

* Fix tests

* Pass force_remove=True from integrations

Co-authored-by: Erik <erik@montnemery.com>
2021-02-08 10:45:46 +01:00
Aaron Godfrey
aa005af266 Fix dyson service name in services.yaml (#46176) 2021-02-08 10:39:33 +01:00
dependabot[bot]
c7a9571920 Bump actions/stale from v3.0.15 to v3.0.16 (#46196) 2021-02-08 10:06:38 +01:00
dependabot[bot]
75519d2d6c Bump actions/cache from v2 to v2.1.4 (#46197)
Bumps [actions/cache](https://github.com/actions/cache) from v2 to v2.1.4.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2...26968a09c0ea4f3e233fdddbafd1166051a095f6)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-08 09:59:07 +01:00
tkdrob
352bba1f15 Use core constants for efergy (#46090) 2021-02-08 09:45:05 +01:00
Adam Outler
840891e4f4 Increase skybell scan time to reduce timeouts (#46169) 2021-02-08 09:37:23 +01:00
Erik Montnemery
28ef3f68f3 Add media_player device triggers (#45430)
* Add media player device triggers

* Update tests
2021-02-08 09:36:14 +01:00
Fabian Affolter
ca87bf49b6 Upgrade praw to 7.1.3 (#46073) 2021-02-08 09:34:12 +01:00
tkdrob
04c1578f15 Use core constants for file integration (#46171) 2021-02-08 09:32:01 +01:00
tkdrob
5755598c95 Use core constants for fixer (#46173) 2021-02-08 09:31:02 +01:00
tkdrob
66ecd2e0f2 Remove unused config_flows (#46188) 2021-02-08 08:32:24 +01:00
Daniel Shokouhi
d02b78c634 Revert "Convert ozw climate values to correct units (#45369)" (#46163)
This reverts commit 1b6ee8301a.
2021-02-08 07:05:10 +01:00
HomeAssistant Azure
aa00c62302 [ci skip] Translation update 2021-02-08 00:07:01 +00:00
tkdrob
8e06fa017d Use core constants for emulated_hue (#46092) 2021-02-07 13:52:48 -05:00
tkdrob
19e9515bec Use core constants for ffmpeg_motion (#46137) 2021-02-07 13:47:16 -05:00
tkdrob
74053b5f2d Use core constants for envisalink (#46136) 2021-02-07 13:28:40 -05:00
Matthias Alphart
94eb31025c xknx 0.16.3 (#46128) 2021-02-07 01:27:58 +01:00
HomeAssistant Azure
818501216e [ci skip] Translation update 2021-02-07 00:06:57 +00:00
Robert Svensson
618fcda821 Simplify UniFi entry configuration data (#45759)
* Simplify configuration structure by removing the controller key

* Fix flake8

* Fix review comments

* Don't use migrate_entry mechanism to flatten configuration
Keep legacy configuration when creating new entries as well
2021-02-06 21:32:18 +01:00
Pierre Ståhl
cefde8721d Add new features to Apple TV media player (#45828) 2021-02-06 10:29:48 -10:00
Robert Svensson
60e3fce7dc Convert old deCONZ groups unique ids (#46093)
* Convert old groups unique ids
Work around for walrus operator not working properly :/

* Remove CONF_GROUP_ID_BASE once entities unique id are updated

* Don't use migrate_entry mechanism to update unique_ids of groups

* Remove walrus operator :(

* Fix review comments

* Walrusify assignment to old_unique_id
2021-02-06 14:32:17 +01:00
Steven Rollason
08163a848c Fix downloader path validation on subdir (#46061) 2021-02-06 14:05:50 +01:00
Marcel van der Veldt
242ff045b9 Handle missing value in all platforms of zwave_js (#46081) 2021-02-06 14:02:03 +01:00
Erik Montnemery
fb68bf85ae Don't defer formatting of log messages (#44873)
* Make fast logging optional

* Remove fast logging support
2021-02-06 13:40:15 +01:00
Robert Svensson
94ecb792ec Use async_update_entry rather than updating config_entry.data directly in Axis (#46078)
Don't step version in migrate_entry to support rollbacking
2021-02-06 13:17:52 +01:00
J. Nick Koston
a74ae3585a Fix backwards compatiblity with fan update to new model (#45951)
* Fix backwards compatiblity with fans update to new model

There were some non-speeds and devices that report a none
speed. These problems were discovered when updating zha
tasmota and vesync to the new model in #45407

* Update coverage

* fix check
2021-02-06 12:48:18 +01:00
Erik Montnemery
369616a6c3 Exclude disabled rfxtrx entities from async_entries_for_device (#46102) 2021-02-06 12:19:41 +01:00
Raman Gupta
af4e6f856f Use better names for zwave_js platforms that are self describing (#46083)
* use better names for platforms that are self describing

* add missing light change

* fix tests

* only use value_name in sensors and binary_sensors
2021-02-06 12:08:25 +01:00
ehendrix23
ee98ea89dd Bump aioharmony from 0.2.6 to 0.2.7 (#46075) 2021-02-05 23:55:21 -10:00
Erik Montnemery
8a7e0241ab Fix race in script wait for trigger step (#46055)
* Fix race in script wait for trigger step

* Update script.py

* Update script.py
2021-02-06 10:01:30 +01:00
djtimca
f2d9e6f70c Add sensor platform for Aurora integration (#43148)
* Removed pylint disable on unused after updating CI files that were out of date.
* Pylint still fails due to bug on DOMAIN import. Added disable check.
* Addressed PR comments
* Added import for ClientError to test_config_flow.py

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-02-05 23:05:39 -08:00
HomeAssistant Azure
ce159d7db3 [ci skip] Translation update 2021-02-06 00:07:22 +00:00
Raman Gupta
33169cf8cd Fix zwave_js Notification CC sensors and binary sensors (#46072)
* only include property key name in sensor name if it exists

* add endpoint to binary_sensor and sensor notification CC entities if > 0

* refactor to have helper method generate name

* change default behavior of generate_name

* return value for notification sensor when we can't find the state

* store generated name
2021-02-05 23:36:42 +01:00
Franck Nijhof
67392338da Activate manual ZHA config flow when no comports detected (#46077) 2021-02-05 17:23:47 -05:00
Robert Svensson
434b4dfa58 Improve deCONZ logbook to be more robust in different situations (#46063) 2021-02-05 23:07:12 +01:00
Sergio Conde Gómez
2c74befd4f Fix foscam to work again with non-admin accounts and make RTSP port configurable again (#45975)
* Do not require admin account for foscam cameras.

Foscam cameras require admin account for getting the MAC address,
requiring an admin account in the integration is not desirable as
an operator one is good enough (and a good practice).

Old entries using the MAC address as unique_id are migrated to the
new unique_id format so everything is consistent.

Also fixed unhandled invalid responses from the camera in the
config flow process.

* Make RTSP port configurable again as some cameras reports wrong port

* Remove periods from new log lines

* Set new Config Flow version to 2 and adjust the entity migration

* Create a proper error message for the InvalidResponse exception

* Change crafted unique_id to use entry_id in the entity

* Abort if same host and port is already configured

* Fix entry tracking to use entry_id instead of unique_id

* Remove unique_id from mocked config entry in tests
2021-02-05 22:39:31 +01:00
functionpointer
c01e01f797 MySensors config flow (#45421)
* MySensors: Add type annotations

Adds a bunch of type annotations that were created
while understanding the code.

* MySensors: Change GatewayId to string

In preparation for config flow.
The GatewayId used to be id(gateway).

With config flows, every gateway will have its own
ConfigEntry. Every ConfigEntry has a unique id.
Thus we would have two separate but one-to-one related ID systems.

This commit removes this unneeded duplication by using the id of the ConfigEntry
as GatewayId.

* MySensors: Add unique_id to all entities

This allows entities to work well with the frontend.

* MySensors: Add device_info to all entities

Entities belonging to the same node_id will now by grouped as a device.

* MySensors: clean up device.py a bit

* MySensors: Add config flow support

With this change the MySensors can be fully configured from the GUI.

Legacy configuration.yaml configs will be migrated by reading them once.
Note that custom node names are not migrated. Users will have to re-enter
the names in the front-end.
Since there is no straight-forward way to configure global settings,
all previously global settings are now per-gateway. These settings include:
- MQTT retain
- optimistic
- persistence enable
- MySensors version

When a MySensors integration is loaded, it works as follows:
1. __init__.async_setup_entry is called
2. for every platform, async_forward_entry_setup is called
3. the platform's async_setup_entry is called
4. __init__.setup_mysensors_platform is called
5. the entity's constructor (e.g. MySensorsCover) is called
6. the created entity is stored in a dict in the hass object

* MySensors: Fix linter errors

* MySensors: Remove unused import

* MySensors: Feedback from @MartinHjelmare

* MySensors: Multi-step config flow

* MySensors: More feedback

* MySensors: Move all storage in hass object under DOMAIN

The integration now stores everything under hass.data["mysensors"]
instead of using several top level keys.

* MySensors: await shutdown of gateway instead of creating a task

* MySensors: Rename Ethernet to TCP

* MySensors: Absolute imports and cosmetic changes

* MySensors: fix gw_stop

* MySensors: Allow user to specify persistence file

* MySensors: Nicer log message

* MySensors: Add lots of unit tests

* MySensors: Fix legacy import of persistence file name

Turns out tests help to find bugs :D

* MySensors: Improve test coverage

* MySensors: Use json persistence files by default

* MySensors: Code style improvements

* MySensors: Stop adding attributes to existing objects

This commit removes the extra attributes that were being
added to the gateway objects from pymysensors.

Most attributes were easy to remove, except for the gateway id.
The MySensorsDevice class needs the gateway id as it is part of its DevId
as well as the unique_id and device_info.
Most MySensorsDevices actually end up being Entities.
Entities have access to their ConfigEntry via self.platform.config_entry.

However, the device_tracker platform does not become an Entity.
For this reason, the gateway id is not fetched from self.plaform but
given as an argument.

Additionally, MySensorsDevices expose the address of the gateway
(CONF_DEVICE). Entities can easily fetch this information via self.platform,
but the device_tracker cannot. This commit chooses to remove the gateway
address from device_tracker. While this could in theory break some automations,
the simplicity of this solution was deemed worth it.
The alternative of adding the entire ConfigEntry as an argument to MySensorsDevices
is not viable, because device_tracker is initialized by the async_setup_scanner function
that isn't supplied a ConfigEntry. It only gets discovery_info.
Adding the entire ConfigEntry doesn't seem appropriate for this edge case.

* MySensors: Fix gw_stop and the translations

* MySensors: Fix incorrect function calls

* MySensors: Fewer comments in const.py

* MySensors: Remove union from _get_gateway and remove id from try_connect

* MySensors: Deprecate nodes option in configuration.yaml

* MySensors: Use version parser from packaging

* MySensors: Remove prefix from unique_id and change some private property names

* MySensors: Change _get_gateway function signature

* MySensors: add packaging==20.8 for the version parser

* MySensors: Rename some stuff

* MySensors: use pytest.mark.parametrize

* MySensors: Clean up test cases

* MySensors: Remove unneeded parameter from devices

* Revert "MySensors: add packaging==20.8 for the version parser"

This reverts commit 6b200ee01a3c0eee98176380bdd0b73e5a25b2dd.

* MySensors: Use core interface for testing configuration.yaml import

* MySensors: Fix test_init

* MySensors: Rename a few variables

* MySensors: cosmetic changes

* MySensors: Update strings.json

* MySensors: Still more feedback from @MartinHjelmare

* MySensors: Remove unused strings

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

* MySensors: Fix typo and remove another unused string

* MySensors: More strings.json

* MySensors: Fix gateway ready handler

* MySensors: Add duplicate detection to config flows

* MySensors: Deal with non-existing topics and ports.

Includes unit tests for these cases.

* MySensors: Use awesomeversion instead of packaging

* Add string already_configured

* MySensors: Abort config flow when config is found to be invalid while importing

* MySensors: Copy all error messages to also be abort messages

All error strings may now also be used as an abort reason,
so the strings should be defined

* Use string references

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-05 22:13:57 +01:00
Robert Svensson
0d620eb7c3 Add unique id to UniFi config entries using the unique id of the site it is controlling (#45737)
* Add unique id to UniFi config entries using the unique id of the site it is controlling

* Fix failing test
2021-02-05 19:38:08 +01:00
Marc Mueller
55f9d98523 Fix deprecated method isAlive() (#46062) 2021-02-05 19:12:23 +01:00
Johan Nenzén
55f81a8a04 Address Plaato post merge review (#46024) 2021-02-05 18:28:06 +01:00
Robert Svensson
ae2c7e4c74 Improve UniFi tests (#45871) 2021-02-05 16:31:47 +01:00
Jaroslav Hanslík
7144c5f316 Fix demo number entity (#45991) 2021-02-05 15:08:28 +01:00
tkdrob
6fdb12c09d Use core constants for bluetooth_tracker (#46041) 2021-02-05 15:07:17 +01:00
tkdrob
9a570d7c32 Use core constants for bmw_connected_drive (#46042) 2021-02-05 08:02:28 -05:00
Greg Dowling
e01ca40d56 Force Vera refresh after starting subscription (#46001)
* Force vera refresh after starting subscription.

* Request refresh on device load.

* Update init test.
2021-02-05 13:20:15 +01:00
Yuval Aboulafia
2a0c36589f Centralize some Airly constants (#45985) 2021-02-05 12:41:36 +01:00
tkdrob
725dcb5cac Use core constants for doods (#46043) 2021-02-05 12:17:46 +01:00
Aaron Bach
6404f91d00 Standardize AirVisual helper method in config flow (#45999)
* Standardize AirVisual helper method in config flow

* Code review
2021-02-05 10:51:55 +01:00
Nathan Spencer
92886cafe9 Fix zwave_js cover control for Up/Down and Open/Close (#45965)
* Fix issue with control of cover when the target value is Up/Down instead of Open/Close

* Adjust open/close/stop cover control to account for no Open/Up or Close/Down targets

* Revert back to using values of 0/99 to close/open a cover since it is supported by all covers

* Replace RELEASE_BUTTON with False and remove unused PRESS_BUTTON in zwave_js cover
2021-02-05 10:48:47 +01:00
tkdrob
2b17ba1dc4 User core constants for deutsche_bahn (#46028) 2021-02-05 10:29:59 +01:00
tkdrob
6e9aa254d5 Use core constants for delijn (#46027) 2021-02-04 21:43:04 -05:00
tkdrob
bcefbe2dca Use core constants for automation (#46016) 2021-02-04 21:41:43 -05:00
J. Nick Koston
374aa3aee1 Fix homekit options not being prefilled (#45926)
* Fix homekit options not being prefilled

When changing homekit options, the existing ones
were not being prefilled on the form.

* hide camera screen if no cameras
2021-02-05 02:39:07 +01:00
obelix05
d1b7d25a5d Prevent fritzbox callmonitor phonebook_id 0 from being ignored (#45990) 2021-02-05 02:31:47 +01:00
HomeAssistant Azure
c6bd5b1b71 [ci skip] Translation update 2021-02-05 00:03:54 +00:00
J. Nick Koston
01e73911d6 Do not listen for dhcp packets if the filter cannot be setup (#46006) 2021-02-05 00:36:55 +01:00
Fabian Affolter
097a4e6b59 Upgrade praw to 7.1.2 (#46012) 2021-02-04 23:42:10 +01:00
Fabian Affolter
62de921422 Upgrade slixmpp to 1.7.0 (#46019) 2021-02-04 23:41:24 +01:00
J. Nick Koston
b9f9de0c1d dhcp does not need promisc mode. Disable it in scapy (#46018) 2021-02-04 23:39:44 +01:00
tkdrob
60268e63d9 Use core constants for aws (#46017) 2021-02-04 23:36:35 +01:00
tkdrob
5d3dcff7c9 Use core constants for asuswrt (#46015) 2021-02-04 23:34:39 +01:00
Fabian Affolter
c7febacd9f Upgrade holidays to 0.10.5.2 (#46013) 2021-02-04 23:32:56 +01:00
Martin Hjelmare
912b816117 Bump zwave-js-server-python to 0.17.2 (#46010) 2021-02-04 20:44:40 +01:00
DeadEnd
7b280bdbe7 Fix Local Media in Media Browser (#45987)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-02-04 17:02:56 +01:00
Joakim Sørensen
56b8e82a69 Bump awesomeversion from 21.2.0 to 21.2.2 (#45993) 2021-02-04 16:45:59 +01:00
Martin Hjelmare
b80c1688ad Bump zwave-js-server-python to 0.17.1 (#45988) 2021-02-04 16:29:41 +01:00
Martin Weinelt
61a987061e Don't log missing mpd artwork inappropriately (#45908)
This can get unnecessarily spammy and doesn't represent an actual
actionable issue.

Fixes: #45235
2021-02-04 08:18:51 -05:00
Maciej Bieniek
134b1d3f63 Fix entities device_info property in Harmony integration (#45964) 2021-02-04 08:16:09 -05:00
Joakim Sørensen
1a74709757 Throw error in hassfest when integration is missing version (#45976) 2021-02-04 13:31:17 +01:00
tkdrob
9c6c2a77ab Use core constants for amazon polly (#45938) 2021-02-04 07:06:09 -05:00
tkdrob
d44c941efe Use core constants for alexa (#45937) 2021-02-04 07:05:56 -05:00
tkdrob
8625b772e3 Use core constants for alert (#45935) 2021-02-04 07:05:46 -05:00
Joakim Sørensen
afa7fd923a Update yarnpkg GPG key (#45973) 2021-02-04 12:51:38 +01:00
Erik Montnemery
dd150bb797 Allow manual configuration of ignored singleton config entries (#45161)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-04 11:08:10 +01:00
Shay Levy
fefe4a2021 Fix exception in Shelly sleeping device that switches to polling (#45930) 2021-02-04 11:07:30 +01:00
Joakim Sørensen
7e9500e465 Use bootstrap in devcontainer (#45968) 2021-02-04 10:41:28 +01:00
Joakim Sørensen
06e6005fbb Add warning to custom integrations without version (#45919)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-02-04 09:59:41 +01:00
olijouve
8256acb8ef Fix onvif ConnectionResetError (#45899)
Fix "ConnectionResetError: Cannot write to closing transport" error we can have on lots of chinese cams(like Goke GK7102 based IP cameras)
Those non full onvif compliant cams can "crash" when calling non implemented functions like events or ptz and they are likely react by closing transport, leaving the request in a uncatched error state.

My camera used to fail on setup, and now it run nicely with that simple fix.
2021-02-04 09:25:35 +01:00
Christopher Gozdziewski
1b6ee8301a Convert ozw climate values to correct units (#45369)
* Convert ozw climate values to correct units

* Remove debugger logging

* Fix black code formatting

* Remove extra spaces

* Add method descriptions and change to use setpoint

* Fix build and respond to comments

* Remove self from convert_units call

* Move method to top

* Move method outside class

* Add blank lines

* Fix test to use farenheit

* Update another value to farenheit

* Change to celsius

* Another test fix

* test fix

* Fix a value

* missed one

* Add unit test for convert_units

* fix unit test import

* Add new line to end of test file

* fix convert units import

* Reorder imports

* Grab const from different import

Co-authored-by: Trevor <tboyce021@gmail.com>
2021-02-04 08:32:43 +01:00
denes44
14d914e300 Enable emulated_hue setting XY color and transition time by client (#45844)
* Enable setting XY color and transition time by client

* New test for setting XY color value

* Correct block outdent

* New test for setting transition time value

* Fixed commented out code
2021-02-03 15:35:27 -10:00
Philip Allgaier
5a0715d388 Consistent spelling of IT abbreviations / protocol / format names (#45913) 2021-02-04 01:43:07 +01:00
Philip Allgaier
44914c01ac Fix typo in Roomba strings (#45928) 2021-02-03 14:26:32 -10:00
tkdrob
04f39d7dd4 Use core constants for command_line auth provider (#45907) 2021-02-03 19:19:22 -05:00
HomeAssistant Azure
adf38f7074 [ci skip] Translation update 2021-02-04 00:06:54 +00:00
David F. Mulcahey
51e695fd45 add api to refresh topology (#44840) 2021-02-03 15:35:05 -05:00
Niccolo Zapponi
a775b79d4b Add support for iCloud 2FA (#45818)
* Add support for iCloud 2FA

* Updated dependency for iCloud

* Updated dependency and logic fix

* Added logic for handling incorrect 2FA code

* Bug fix on failing test

* Added myself to codeowners

* Added check for 2FA on setup

* Updated error message
2021-02-03 19:18:31 +01:00
Brandon Rothweiler
4b208746e5 Add Mazda Connected Services integration (#45768) 2021-02-03 17:38:12 +01:00
Berni Moses
a584ad5ac3 Fix duplicate lg_soundbar entities and disable polling (#42044)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-03 17:06:02 +01:00
badguy99
6458ff774f Homeconnect remote states (#45610)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-03 17:05:20 +01:00
Shay Levy
0875f654c8 Add support for Shelly battery operated devices (#45406)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-03 17:03:22 +01:00
Keith Lamprecht
fcc14933d0 Add transitiontime to hue scene service (#45785) 2021-02-03 15:42:52 +01:00
Joakim Sørensen
90973f471f Add integration name to the deprecation warnings (#45901) 2021-02-03 14:40:11 +01:00
Tobias Sauerwein
5615ab4c25 Add support for climate setpoint thermostats to zwave_js (#45890) 2021-02-03 13:59:19 +01:00
Marcel van der Veldt
9998fe3684 Update discovery scheme for Meter CC in zwave_js integration (#45897) 2021-02-03 13:08:00 +01:00
Jesse Campbell
eaa9fff3ba Remove v4 multilevel transitional currentValue workaround in zwave_js (#45884)
* Remove v4 multilevel transitional currentValue workaround

This was only needed because the get-after-set was reporting a
transitional currentValue instead of the final one.
zwave-js v6.1.1 removes the get-after-set functionality completely, so
this is no longer required (and breaks status reporting entirely)

* Fix tests to check currentValue instead of targetValue as well
2021-02-03 12:02:49 +01:00
Paulus Schoutsen
40ba182144 Upgrade Z-Wave JS Python to 0.17.0 (#45895) 2021-02-03 11:58:46 +01:00
Paulus Schoutsen
a2ec1a47d5 Mark Z-Wave as deprecated (#45896) 2021-02-03 11:54:00 +01:00
Paulus Schoutsen
959ed6d077 Update translations 2021-02-03 11:46:49 +01:00
Pascal Vizeli
45ac6df76f Update docker base image 2021.02.0 (#45889) 2021-02-03 10:41:02 +01:00
jjlawren
048f36c77e Bump plexapi to 3.4.1 (#45878) 2021-02-03 08:44:34 +01:00
Quentame
d9dba1b7ab Bump Freebox to 0.0.9 (#45837)
* Bump Freebox to 0.0.9

* Remove @SNoof85 from code owners

* Module is now freebox_api
2021-02-02 22:57:06 +01:00
Bram Kragten
bf9b3bf9db Update frontend to 20210127.7 (#45874) 2021-02-02 22:45:51 +01:00
Martin Hjelmare
524b9e7b1f Use new zwave_js client (#45872)
* Use new zwave_js client

* Remove client callbacks

* Clean up on connect and on disconnect

* Clean log

* Add stop listen to unsubscribe callbacks

* Fix most tests

* Adapt to new listen interface

* Fix most tests

* Remove stale connection state feature

* Bump zwave-js-server-python to 0.16.0

* Clean up disconnect
2021-02-02 20:59:56 +01:00
Marcel van der Veldt
2e98cfb9ab Guard for missing value (#45867)
* guard for missing value

* update comment
2021-02-02 19:57:08 +01:00
Martin Hjelmare
c93fec34b3 Fix zwave_js sensor device class attribute error (#45863) 2021-02-02 16:25:43 +01:00
Fabian Affolter
811bbb7acb Upgrade emoji to 1.2.0 (#45847) 2021-02-02 15:56:56 +01:00
Fabian Affolter
63cc2517dd Upgrade watchdog to 1.0.2 (#45848) 2021-02-02 15:53:03 +01:00
Martin Hjelmare
6e205965ee Fix zwave_js device remove test (#45864) 2021-02-02 15:28:21 +01:00
Fabian Affolter
e9b2d33ad8 Upgrade pytz to >=2021.1 (#45839) 2021-02-02 15:18:58 +01:00
Fabian Affolter
7ff4281b6d Upgrade jinja2 to >=2.11.3 (#45843) 2021-02-02 15:10:54 +01:00
Thomas Friedel
0382c93283 Enable Osramlightify again (#45849) 2021-02-02 14:45:02 +01:00
J. Nick Koston
d417ee2732 Add fan speed percentage support to google assistant (#45835) 2021-02-02 14:39:07 +01:00
Daniel Pereira
a96a80e78d Update alexa/const.py to reflect docs (#45806)
The current docs say the Alexa integration is compatible with languages not currently present in the conf validator.

See: https://www.home-assistant.io/integrations/alexa.smart_home/#alexa-locale
2021-02-02 14:38:13 +01:00
J. Nick Koston
463a32819c Ensure homekit never picks a port that another config entry uses (#45433) 2021-02-02 14:30:38 +01:00
Raman Gupta
a64ad50b27 Remove zwave_js devices that the controller is no longer connected to on initialization (#45853)
* Remove zwave_js devices that the controller is no longer connected to on initialization

* remove extra line break

* fix test

* Clean up

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

* Lint

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-02 10:30:12 +01:00
Marcel van der Veldt
0e3ba532c7 Update zwave_js discovery schema for light platform (#45861) 2021-02-02 10:18:44 +01:00
Tom Harris
b3e2f8f904 Add Insteon entities in event loop (#45829) 2021-02-01 23:17:17 -10:00
Marcel van der Veldt
0feda9ce63 Fix sensor discovery for zwave_js integration (#45834)
Co-authored-by: Raman Gupta <7243222+raman325@users.noreply.github.com>
2021-02-02 10:06:09 +01:00
Raman Gupta
8d9b66e23d Add current humidity to zwave_js climate platform (#45857) 2021-02-02 09:41:00 +01:00
Raman Gupta
3ef7bd6b73 Add notification events to zwave_js integration (#45827)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-02-02 09:37:42 +01:00
Erik Montnemery
411c0a9685 Improve MQTT JSON light to allow non-ambiguous states (#45522) 2021-02-02 09:36:00 +01:00
michaeldavie
aea8636c7e Fix environment_canada high/low temperature display in evenings. (#45855) 2021-02-02 08:23:26 +01:00
Fabian Affolter
60d4dadcb6 Upgrade sqlalchemy to 1.3.23 (#45845) 2021-02-01 16:03:51 -10:00
Aidan Timson
3a77ef02e4 Add sensors to Lyric integration (#45791)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-01 15:51:20 -10:00
Aidan Timson
253ae3f423 Lyric Code Improvements (#45819)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-01 14:09:25 -10:00
Fabian Affolter
f2286d4811 Upgrade TwitterAPI to 2.6.5 (#45842) 2021-02-01 19:01:39 -05:00
Fabian Affolter
d38d8a542d Upgrade colorlog to 4.7.2 (#45840) 2021-02-01 19:01:19 -05:00
Marcel van der Veldt
b4559a172c Add value notification events to zwave_js integration (#45814) 2021-02-01 23:47:58 +01:00
Alessandro Pilotti
8222eb5e3e Allow Influxdb CA path in verify_ssl (#45270) 2021-02-01 23:29:31 +01:00
Aaron Bach
3bdf962838 Add ability to configure AirVisual with city/state/country in UI (#44116) 2021-02-01 11:38:03 -10:00
Raman Gupta
197c857e1f Search all endpoints for value in zwave_js (#45809)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-02-01 14:46:06 -05:00
Maciej Bieniek
776b1395de Bump brother library to version 0.2.0 (#45832) 2021-02-01 20:43:43 +01:00
Michael
c90588d35d Correct synology_dsm CPU sensor's naming and measurement unit (#45500) 2021-02-01 07:15:34 -10:00
Johan Nenzén
285bd3aa91 Add support for Keg and Airlock to Plaato using polling API (#34760)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-02-01 07:12:56 -10:00
Robert Svensson
83a75b02ea Code quality improvements to UniFi integration (#45794)
* Do less inside try statements

* Replace controller id with config entry id since it doesn't serve a purpose anymore

* Improve how controller connection state is communicated in the client and device tracker
Remove the need to disable arguments-differ lint

* Remove broad exception handling from config flow
I'm not sure there ever was a reason for this more than to catch all exceptions

* Replace site string with constant for SSDP title_placeholders

* Unload platforms in the defacto way

* Noone reads the method descriptions

* Improve file descriptions
2021-02-01 17:55:16 +01:00
Allen Porter
2136b3013f Increase test coverage for stream worker (#44161)
Co-authored-by: Justin Wong <46082645+uvjustin@users.noreply.github.com>
2021-02-01 17:48:49 +01:00
Tobias Bielohlawek
6e67b943da Remove Nuimo integration (#45600) 2021-02-01 16:58:00 +01:00
Joakim Sørensen
374817fbaa Bump awesomeversion from 21.1.6 to 21.2.0 (#45821) 2021-02-01 16:54:25 +01:00
Chris
a8cf377ed7 Add stop_cover service for zwave_js (#45805) 2021-02-01 16:46:36 +01:00
J. Nick Koston
9f59515bb8 Fix shutdown deadlock with run_callback_threadsafe (#45807) 2021-02-01 10:54:39 +01:00
Martin Hjelmare
31a84555b9 Bump zwave-js-server-python to 0.15.0 (#45813) 2021-02-01 10:54:07 +01:00
J. Nick Koston
e0bf18986b Fix missing async for lutron_caseta timeout (#45812) 2021-02-01 10:15:20 +01:00
Sly Gryphon
91a54eecb3 Add izone control zone (#43984) 2021-02-01 09:48:50 +01:00
Raman Gupta
0b63510cab Add zwave_js binary sensors property name for Notification CC (#45810) 2021-02-01 09:45:24 +01:00
Ville Skyttä
2ffdc4694a Remove misleading "for" from custom integration warning message (#45811) 2021-02-01 08:36:06 +01:00
Pierre Ståhl
03928dbe55 Bump pyatv to 0.7.6 (#45799) 2021-02-01 08:34:55 +01:00
Mick Vleeshouwer
1d94c10bb5 Change via_hub to via_device (#45804) 2021-01-31 20:55:18 -10:00
Marcel van der Veldt
3e080f88c6 Bump zwave-js-server-python to 0.14.2 (#45800) 2021-01-31 17:14:20 -05:00
J. Nick Koston
385b7e17ef Move homekit accessory creation to async (#45788) 2021-01-31 11:36:19 -10:00
J. Nick Koston
73d7d80731 Add timeout to lutron_caseta to prevent it blocking startup (#45769) 2021-01-31 21:43:00 +01:00
J. Nick Koston
852af7e372 Update homekit for new async library changes (#45731) 2021-01-31 21:40:24 +01:00
J. Nick Koston
dac9626112 Resolve homekit cover adjustment slowness (#45730) 2021-01-31 21:39:35 +01:00
J. Nick Koston
8be357ff4f Ensure lutron_caseta is only discovered once (#45792) 2021-01-31 21:38:08 +01:00
Matthias Alphart
868e530cbb Prevent AttributError for uninitilized KNX ClimateMode (#45793) 2021-01-31 20:56:42 +01:00
Michael
e506d8616f Fix polling and update of camera state for synology_dsm (#43683)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-01-31 09:22:46 -10:00
Franck Nijhof
c74ddf4720 Upgrade pre-commit to 2.10.0 (#45777) 2021-01-31 08:00:49 -10:00
Franck Nijhof
f1d3af1a13 Add WLED unload entry result correctly (#45783) 2021-01-31 07:59:39 -10:00
Aidan Timson
2d10c83150 Honeywell Lyric Integration (#39695)
Co-authored-by: J. Nick Koston <nick@koston.org>
2021-01-31 07:51:31 -10:00
Vladimír Záhradník
ee55223065 SSDP response decode: replace invalid utf-8 characters (#42681)
* SSDP response decode: replace invalid utf-8 characters

* Add test to validate replaced data

Co-authored-by: Joakim Plate <elupus@ecce.se>
2021-01-31 17:59:14 +01:00
Erik Montnemery
ca43b3a8bb Bump pychromecast to 8.0.0 (#45776) 2021-01-31 16:35:29 +01:00
Franck Nijhof
78934af6e6 Disable Osramlightify, upstream package is missing (#45775) 2021-01-31 13:50:48 +01:00
J. Nick Koston
f372bcf306 Update insteon to use new fan entity model (#45767) 2021-01-31 12:13:55 +01:00
MtK
275946b96d Bump ROVA package requirement (#45755) 2021-01-31 11:30:26 +01:00
J. Nick Koston
ea7aa6af59 Update dyson for the new fan entity model (#45762)
* Update dyson for the new fan entity model

* Fix test

* tweak

* fix

* adj

* Update homeassistant/components/dyson/fan.py

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

* move percentage is None block

* move percentage is None block

* no need to list comp

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-01-31 10:26:02 +01:00
Bram Kragten
6b44636344 Update frontend to 20210127.6 (#45760) 2021-01-31 00:51:33 +01:00
Ville Skyttä
d13b58a4e6 Upgrade mypy to 0.800 (#45485)
* Upgrade mypy to 0.800

https://mypy-lang.blogspot.com/2021/01/mypy-0800-released.html

* Fix issues flagged by mypy 0.800

* Add overloads + small changes

* Apply grammar

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-01-30 22:33:53 +01:00
Franck Nijhof
e43cee163f Fix typo in issue form 2021-01-30 21:36:13 +01:00
Franck Nijhof
da29855967 Enable issue form as default 2021-01-30 21:32:46 +01:00
Franck Nijhof
27407c1160 Tiny tweaks to issue form 2021-01-30 21:24:56 +01:00
Franck Nijhof
726bc6210b Tiny tweaks to issue form 2021-01-30 21:21:57 +01:00
Paulus Schoutsen
8a6469cfce newline 2021-01-30 21:17:36 +01:00
Franck Nijhof
63fb8307fb Add initial GitHub Issue Form (#45752) 2021-01-30 21:10:42 +01:00
Guliver
b00086ca1f Use fixed due date only for comparison in todoist (#43300) 2021-01-30 17:21:04 +01:00
J. Nick Koston
88c4031e57 Fix exception when a unifi config entry is ignored (#45735)
* Fix exception when a unifi config entry is ignored

* Fix existing test
2021-01-30 16:45:46 +01:00
Anders Melchiorsen
1fd3a86239 Upgrade pysonos to 0.0.40 (#45743) 2021-01-30 15:38:43 +01:00
Joakim Sørensen
0964393002 Bump awesomeversion from 21.1.3 to 21.1.6 (#45738) 2021-01-30 14:09:16 +01:00
Jens Østergaard Nielsen
b80571519b IHC service functions support for multiple IHC controllers (#44626)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-01-30 12:46:50 +01:00
J. Nick Koston
d81017f62e Use DataUpdateCoordinator for solaredge (#45734)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-01-30 09:56:51 +01:00
Aaron Bach
6bf59dbeab Add significant change support to binary_sensor (#45677)
* Add significant change support to binary_sensor
2021-01-30 09:04:35 +01:00
Aaron Bach
85e6bc581f Add significant change support to lock (#45726) 2021-01-30 09:03:54 +01:00
Nathan Tilley
07a4422a70 Implement person significant change (#45713) 2021-01-30 08:05:58 +01:00
Ryan Fleming
8a112721fa Fix feedback from UVC (#45630)
* Fixing feedback from UVC

* Couple of fixes
2021-01-30 08:00:27 +01:00
Paulus Schoutsen
87d40ff815 Do not cache frontend files during dev (#45698) 2021-01-30 00:05:06 +01:00
chpego
41e2e5043b Upgrade youtube_dl to version 2021.01.24.1 (#45724)
* Upgrade youtube_dl to version 2021.01.24.1

* Update requirements_all.txt
2021-01-29 23:14:17 +01:00
Pascal Reeb
f07ffee535 Advanced testing for Nuki config flow (#45721) 2021-01-29 17:01:25 -05:00
Patrik
adf8873e56 Remove ggravlingen from codeowners (#45723) 2021-01-29 17:00:27 -05:00
Aaron Bach
14c2053841 Bump simplisafe-python to 9.6.4 (#45716)
* Bump simplisafe-python to 9.6.4

* Fix imports
2021-01-29 13:30:21 -07:00
Philip Allgaier
84f506efb7 Set default position value for cover action (#45670)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-01-29 21:11:12 +01:00
Martin Hjelmare
ace5b58337 Fix ozw init tests (#45718) 2021-01-29 20:58:57 +01:00
Bram Kragten
df00f32dfc Updated frontend to 20210127.5 (#45714) 2021-01-29 20:12:03 +01:00
Paul Daumlechner
48e899ca3a Add reboot_gateway service to Velux (#43198) 2021-01-29 20:07:58 +01:00
cristian-vescan
0fe3d6ea81 Added Romanian voice to Google Cloud TTS (#45704)
See https://cloud.google.com/text-to-speech/docs/voices
2021-01-29 20:02:04 +01:00
Joakim Plate
d4f186078c During tests we can run with lowest rounds (#45710) 2021-01-29 19:57:14 +01:00
Kendell R
fbffea6b61 Add unit of measurement and icon for sleep score (#45705) 2021-01-29 19:22:44 +01:00
Robert Svensson
97fd05eb9f Allow new UniFi flows to update existing entries if host and site match (#45668) 2021-01-29 18:14:39 +01:00
Joakim Plate
af68d5fb41 Use a fully mocked credential (#45707) 2021-01-29 17:58:25 +01:00
Martin Hjelmare
bcc9add0b4 Fix mqtt check in ozw (#45709) 2021-01-29 17:57:39 +01:00
Paulus Schoutsen
b2789621bd Updates to dev container (#45706) 2021-01-29 17:47:54 +01:00
J. Nick Koston
5f9a1d105c Improve HomeKit Accessory Mode UX (#45402) 2021-01-29 09:57:13 -06:00
Aleksander Żarczyński
bc3610c8e1 Add patch method to rest switch component (#45663) 2021-01-29 16:03:00 +01:00
Pieter Mulder
c1586f97db Only show matching caldav events in calendar (#45701) 2021-01-29 15:25:01 +01:00
bsmappee
3f67f9e09c Bump pysmappee to 0.2.16 (#45699) 2021-01-29 15:01:55 +01:00
Pascal Vizeli
b8ff112920 Update docker base image 2021.01.1 (#45697) 2021-01-29 12:53:35 +01:00
GeoffAtHome
da713e206d Add override duration for genius hub switches (#45558) 2021-01-29 12:44:56 +01:00
Steven Looman
71c169c84f Address late review comments for upnp (#45696) 2021-01-29 12:27:57 +01:00
Pascal Reeb
ba55f1ff4b Add config flow for nuki (#45664)
* implemented config_flow for nuki component

* warn -> warning

* exception handling & config_flow tests

* gen_requirements_all

* Update config_flow.py

Co-authored-by: Pascal Vizeli <pascal.vizeli@syshack.ch>
2021-01-29 11:05:13 +01:00
Paulus Schoutsen
b74cbb2a59 Bump crpytography to 3.3.1 (#45691) 2021-01-29 10:33:44 +01:00
Steven Looman
25c5c6aec9 Refactoring upnp component (#43646) 2021-01-29 10:23:34 +01:00
aizerin
f080af698d Use pure rgb and allow to set only brightness for fibaro (#45673)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-01-29 09:36:52 +01:00
Paulus Schoutsen
fb884e3afd Update bootstrap script (#45692) 2021-01-29 09:19:32 +01:00
J. Nick Koston
c6105900f6 Update httpcore to prevent unhandled exception on dropped connection (#45667)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-01-29 09:11:24 +01:00
Tom Harris
aacf6bd100 Fix formatting IntEnum as hex in 3.8.x (#45686) 2021-01-29 09:07:18 +01:00
Dermot Duffy
c66a892233 Remove YAML support from Hyperion integration (#45690) 2021-01-29 09:05:00 +01:00
Aaron Bach
4f3b10d661 Stop Tile setup on invalid auth (#45683) 2021-01-29 08:57:36 +01:00
Martin
c7db2c35b7 Add vicare heat pump sensors (#41413) 2021-01-29 08:55:51 +01:00
Guido Schmitz
8b3156ea82 Use new fixtures in devolo Home Control tests (#45669) 2021-01-29 03:14:39 +01:00
Bram Kragten
eb370e9494 Update frontend to 20210127.3 (#45679) 2021-01-29 00:46:28 +01:00
Aaron Bach
1edae8cd48 Add last_lost_timestamp attribute to Tile (#45681) 2021-01-28 16:39:06 -07:00
Aaron Bach
73cce8e8e2 Replace strange "dict logic" in AirVisual pollutant level sensors (2 of 2) (#44903)
* Replace strange "dict logic" in AirVisual main pollutant sensor

* Move methods outside of class

* Cleanup
2021-01-28 16:32:21 -07:00
Julian Löhr
7bc8060122 Add reauthentication flow to fritzbox integration (#45587) 2021-01-29 00:08:59 +01:00
Marcel van der Veldt
8bcb4092df Fix removing nodes in zwave_js integration (#45676) 2021-01-28 23:45:36 +01:00
J. Nick Koston
e7ddaec468 Update esphome to use new fan entity model (#45590) 2021-01-28 17:25:08 +01:00
J. Nick Koston
d148f9aa85 Update comfoconnect to use new fan entity model (#45593) 2021-01-28 17:23:10 +01:00
jjlawren
d7e0391e03 Allow Plex playback using provided playqueue ID (#45580) 2021-01-28 17:21:31 +01:00
Guido Schmitz
8065ece0bd Add first set of tests to devolo Home Control integration (#42527)
* Add first two testcases

* Remove repetition

* Add first two testcases

* Remove repetition

* Add connection error test case

* add test_setup_entry_credentials_valid

* First attempt to use fixtures

* Use markers

* Optimize patch

* Optimize marker use

* Always patch mydevolo

* Add first two testcases

* Remove repetition

* Add first two testcases

* Remove repetition

* Add connection error test case

* add test_setup_entry_credentials_valid

* First attempt to use fixtures

* Use markers

* Optimize patch

* Optimize marker use

* Always patch mydevolo

* Add unload entry test case

* Catch up with reality

* Use unittest patch

* Use core interface to start tests

* Use entry state

* Consistently assert entry state

* Patch class instead of init

Co-authored-by: Markus Bong <2Fake1987@gmail.com>
2021-01-28 17:14:33 +01:00
J. Nick Koston
0da4034179 Ensure history LazyState state value is always a string (#45644)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-01-28 16:05:02 +01:00
J. Nick Koston
fdcf1fccf8 Update vesync to use new fan entity model (#45585) 2021-01-28 16:02:38 +01:00
Tobias Sauerwein
a4c8cb6f84 Unregister webhook if it can't be established successfully (#42791) 2021-01-28 15:30:10 +01:00
J. Nick Koston
f0e4510213 Update lutron_caseta to use new fan entity model (#45540) 2021-01-28 08:17:16 -06:00
Maciej Bieniek
92efe4f491 Bump gios library (#45639) 2021-01-28 13:28:39 +01:00
J. Nick Koston
3ff75eee53 Update homekit to use new fan entity model (#45549) 2021-01-28 12:38:18 +01:00
Fabian Affolter
f1c24939f3 Upgrade beautifulsoup4 to 4.9.3 (#45619) 2021-01-28 12:06:36 +01:00
Joakim Plate
38d2cacf7a Support blocking trusted network from new ip (#44630)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-01-28 12:06:20 +01:00
Fabian Affolter
e4a7692610 Upgrade pyyaml to 5.4.1 (CVE-2020-14343) (#45624) 2021-01-28 12:05:09 +01:00
J. Nick Koston
ab1d42950a Update homekit_controller to use new fan entity model (#45547) 2021-01-28 11:43:43 +01:00
J. Nick Koston
babfef829d Add support for percentage speeds and preset modes to template fan (#45478) 2021-01-28 10:44:36 +01:00
J. Nick Koston
22e44e4ba4 Update zwave to use new fan entity model (#45541)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-01-28 10:35:01 +01:00
J. Nick Koston
ee592350b3 Update isy994 to use new fan entity model (#45536) 2021-01-28 10:23:55 +01:00
J. Nick Koston
85e463d507 Update bond to use new fan entity model (#45534) 2021-01-28 10:23:12 +01:00
J. Nick Koston
0693d8a064 Update zwave_js to use new fan entity model (#45543) 2021-01-28 10:15:24 +01:00
J. Nick Koston
3896e81db7 Update smartthings to use new fan entity model (#45592) 2021-01-28 10:09:16 +01:00
J. Nick Koston
0441960ffd Update wemo to use new fan entity model (#45582) 2021-01-28 10:06:18 +01:00
J. Nick Koston
0ec068667f Update lutron_caseta manufacturer string (#45637)
Use the string that Lutron uses so it can be automatched
to the Lutron app via homekit
2021-01-28 09:40:48 +01:00
J. Nick Koston
e43d865112 Update ozw to use new fan entity model (#45577) 2021-01-28 09:40:10 +01:00
Paulus Schoutsen
92e084cee1 Include relative path in tts get url (#45623)
* Include relative path in tts get url

* Always cal get_url when requested
2021-01-28 09:33:18 +01:00
Marc Mueller
7673f57248 Add additional error handling for automation script run (#45613) 2021-01-28 09:26:41 +01:00
Erik Montnemery
5711d61b38 Bump hatasmota to 0.2.7 (#45625) 2021-01-28 08:55:22 +01:00
J. Nick Koston
068d1b5eb8 Separate fan speeds into percentages and presets modes (#45407)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: John Carr <john.carr@unrouted.co.uk>
2021-01-27 17:44:36 -06:00
Julian Engelhardt
3f948e027a Clean tcp tests (#41673)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-01-27 22:37:59 +01:00
Franck Nijhof
0338f5bccf Bump version to 2021.3.0dev0 (#45617) 2021-01-27 21:12:38 +01:00
2375 changed files with 68995 additions and 18295 deletions

View File

@@ -23,6 +23,8 @@ omit =
homeassistant/components/adguard/sensor.py
homeassistant/components/adguard/switch.py
homeassistant/components/ads/*
homeassistant/components/aemet/abstract_aemet_sensor.py
homeassistant/components/aemet/weather_update_coordinator.py
homeassistant/components/aftership/sensor.py
homeassistant/components/agent_dvr/__init__.py
homeassistant/components/agent_dvr/alarm_control_panel.py
@@ -67,11 +69,14 @@ omit =
homeassistant/components/arwn/sensor.py
homeassistant/components/asterisk_cdr/mailbox.py
homeassistant/components/asterisk_mbox/*
homeassistant/components/asuswrt/__init__.py
homeassistant/components/asuswrt/router.py
homeassistant/components/aten_pe/*
homeassistant/components/atome/*
homeassistant/components/aurora/__init__.py
homeassistant/components/aurora/binary_sensor.py
homeassistant/components/aurora/const.py
homeassistant/components/aurora/sensor.py
homeassistant/components/aurora_abb_powerone/sensor.py
homeassistant/components/avea/light.py
homeassistant/components/avion/light.py
@@ -140,6 +145,7 @@ omit =
homeassistant/components/clickatell/notify.py
homeassistant/components/clicksend/notify.py
homeassistant/components/clicksend_tts/notify.py
homeassistant/components/climacell/weather.py
homeassistant/components/cmus/media_player.py
homeassistant/components/co2signal/*
homeassistant/components/coinbase/*
@@ -156,7 +162,6 @@ omit =
homeassistant/components/coolmaster/const.py
homeassistant/components/cppm_tracker/device_tracker.py
homeassistant/components/cpuspeed/sensor.py
homeassistant/components/crimereports/sensor.py
homeassistant/components/cups/sensor.py
homeassistant/components/currencylayer/sensor.py
homeassistant/components/daikin/*
@@ -172,7 +177,6 @@ omit =
homeassistant/components/denonavr/media_player.py
homeassistant/components/denonavr/receiver.py
homeassistant/components/deutsche_bahn/sensor.py
homeassistant/components/devolo_home_control/__init__.py
homeassistant/components/devolo_home_control/binary_sensor.py
homeassistant/components/devolo_home_control/climate.py
homeassistant/components/devolo_home_control/const.py
@@ -268,6 +272,8 @@ omit =
homeassistant/components/evohome/*
homeassistant/components/ezviz/*
homeassistant/components/familyhub/camera.py
homeassistant/components/faa_delays/__init__.py
homeassistant/components/faa_delays/binary_sensor.py
homeassistant/components/fastdotcom/*
homeassistant/components/ffmpeg/camera.py
homeassistant/components/fibaro/*
@@ -358,7 +364,9 @@ omit =
homeassistant/components/guardian/sensor.py
homeassistant/components/guardian/switch.py
homeassistant/components/guardian/util.py
homeassistant/components/habitica/*
homeassistant/components/habitica/__init__.py
homeassistant/components/habitica/const.py
homeassistant/components/habitica/sensor.py
homeassistant/components/hangouts/*
homeassistant/components/hangouts/__init__.py
homeassistant/components/hangouts/const.py
@@ -463,7 +471,11 @@ omit =
homeassistant/components/kaiterra/*
homeassistant/components/kankun/switch.py
homeassistant/components/keba/*
homeassistant/components/keenetic_ndms2/__init__.py
homeassistant/components/keenetic_ndms2/binary_sensor.py
homeassistant/components/keenetic_ndms2/const.py
homeassistant/components/keenetic_ndms2/device_tracker.py
homeassistant/components/keenetic_ndms2/router.py
homeassistant/components/kef/*
homeassistant/components/keyboard/*
homeassistant/components/keyboard_remote/*
@@ -519,6 +531,10 @@ omit =
homeassistant/components/lutron_caseta/switch.py
homeassistant/components/lw12wifi/light.py
homeassistant/components/lyft/sensor.py
homeassistant/components/lyric/__init__.py
homeassistant/components/lyric/api.py
homeassistant/components/lyric/climate.py
homeassistant/components/lyric/sensor.py
homeassistant/components/magicseaweed/sensor.py
homeassistant/components/mailgun/notify.py
homeassistant/components/map/*
@@ -560,6 +576,7 @@ omit =
homeassistant/components/mochad/*
homeassistant/components/modbus/climate.py
homeassistant/components/modbus/cover.py
homeassistant/components/modbus/modbus.py
homeassistant/components/modbus/switch.py
homeassistant/components/modbus/sensor.py
homeassistant/components/modem_callerid/sensor.py
@@ -571,11 +588,27 @@ omit =
homeassistant/components/mpd/media_player.py
homeassistant/components/mqtt_room/sensor.py
homeassistant/components/msteams/notify.py
homeassistant/components/mullvad/__init__.py
homeassistant/components/mullvad/binary_sensor.py
homeassistant/components/nest/const.py
homeassistant/components/mvglive/sensor.py
homeassistant/components/mychevy/*
homeassistant/components/mycroft/*
homeassistant/components/mycroft/notify.py
homeassistant/components/mysensors/*
homeassistant/components/mysensors/__init__.py
homeassistant/components/mysensors/binary_sensor.py
homeassistant/components/mysensors/climate.py
homeassistant/components/mysensors/const.py
homeassistant/components/mysensors/cover.py
homeassistant/components/mysensors/device.py
homeassistant/components/mysensors/device_tracker.py
homeassistant/components/mysensors/gateway.py
homeassistant/components/mysensors/handler.py
homeassistant/components/mysensors/helpers.py
homeassistant/components/mysensors/light.py
homeassistant/components/mysensors/notify.py
homeassistant/components/mysensors/sensor.py
homeassistant/components/mysensors/switch.py
homeassistant/components/mystrom/binary_sensor.py
homeassistant/components/mystrom/light.py
homeassistant/components/mystrom/switch.py
@@ -621,7 +654,8 @@ omit =
homeassistant/components/norway_air/air_quality.py
homeassistant/components/notify_events/notify.py
homeassistant/components/nsw_fuel_station/sensor.py
homeassistant/components/nuimo_controller/*
homeassistant/components/nuki/__init__.py
homeassistant/components/nuki/const.py
homeassistant/components/nuki/lock.py
homeassistant/components/nut/sensor.py
homeassistant/components/nx584/alarm_control_panel.py
@@ -687,6 +721,7 @@ omit =
homeassistant/components/pandora/media_player.py
homeassistant/components/pcal9535a/*
homeassistant/components/pencom/switch.py
homeassistant/components/philips_js/__init__.py
homeassistant/components/philips_js/media_player.py
homeassistant/components/pi_hole/sensor.py
homeassistant/components/pi4ioe5v9xxxx/binary_sensor.py
@@ -699,7 +734,11 @@ omit =
homeassistant/components/ping/device_tracker.py
homeassistant/components/pioneer/media_player.py
homeassistant/components/pjlink/media_player.py
homeassistant/components/plaato/*
homeassistant/components/plaato/__init__.py
homeassistant/components/plaato/binary_sensor.py
homeassistant/components/plaato/const.py
homeassistant/components/plaato/entity.py
homeassistant/components/plaato/sensor.py
homeassistant/components/plex/media_player.py
homeassistant/components/plum_lightpad/light.py
homeassistant/components/pocketcasts/sensor.py
@@ -754,6 +793,8 @@ omit =
homeassistant/components/rest/switch.py
homeassistant/components/ring/camera.py
homeassistant/components/ripple/sensor.py
homeassistant/components/rituals_perfume_genie/switch.py
homeassistant/components/rituals_perfume_genie/__init__.py
homeassistant/components/rocketchat/notify.py
homeassistant/components/roomba/binary_sensor.py
homeassistant/components/roomba/braava.py
@@ -876,7 +917,6 @@ omit =
homeassistant/components/switcher_kis/switch.py
homeassistant/components/switchmate/switch.py
homeassistant/components/syncthru/sensor.py
homeassistant/components/synology/camera.py
homeassistant/components/synology_chat/notify.py
homeassistant/components/synology_dsm/__init__.py
homeassistant/components/synology_dsm/binary_sensor.py
@@ -944,7 +984,10 @@ omit =
homeassistant/components/toon/sensor.py
homeassistant/components/toon/switch.py
homeassistant/components/torque/sensor.py
homeassistant/components/totalconnect/*
homeassistant/components/totalconnect/__init__.py
homeassistant/components/totalconnect/alarm_control_panel.py
homeassistant/components/totalconnect/binary_sensor.py
homeassistant/components/totalconnect/const.py
homeassistant/components/touchline/climate.py
homeassistant/components/tplink/common.py
homeassistant/components/tplink/switch.py
@@ -963,7 +1006,14 @@ omit =
homeassistant/components/transmission/const.py
homeassistant/components/transmission/errors.py
homeassistant/components/travisci/sensor.py
homeassistant/components/tuya/*
homeassistant/components/tuya/__init__.py
homeassistant/components/tuya/climate.py
homeassistant/components/tuya/const.py
homeassistant/components/tuya/cover.py
homeassistant/components/tuya/fan.py
homeassistant/components/tuya/light.py
homeassistant/components/tuya/scene.py
homeassistant/components/tuya/switch.py
homeassistant/components/twentemilieu/const.py
homeassistant/components/twentemilieu/sensor.py
homeassistant/components/twilio_call/notify.py
@@ -1001,6 +1051,7 @@ omit =
homeassistant/components/vesync/common.py
homeassistant/components/vesync/const.py
homeassistant/components/vesync/fan.py
homeassistant/components/vesync/light.py
homeassistant/components/vesync/switch.py
homeassistant/components/viaggiatreno/sensor.py
homeassistant/components/vicare/*
@@ -1043,7 +1094,6 @@ omit =
homeassistant/components/xbox/sensor.py
homeassistant/components/xbox_live/sensor.py
homeassistant/components/xeoma/camera.py
homeassistant/components/xfinity/device_tracker.py
homeassistant/components/xiaomi/camera.py
homeassistant/components/xiaomi_aqara/__init__.py
homeassistant/components/xiaomi_aqara/binary_sensor.py
@@ -1056,6 +1106,7 @@ omit =
homeassistant/components/xiaomi_miio/__init__.py
homeassistant/components/xiaomi_miio/air_quality.py
homeassistant/components/xiaomi_miio/alarm_control_panel.py
homeassistant/components/xiaomi_miio/device.py
homeassistant/components/xiaomi_miio/device_tracker.py
homeassistant/components/xiaomi_miio/fan.py
homeassistant/components/xiaomi_miio/gateway.py

View File

@@ -2,13 +2,14 @@
"name": "Home Assistant Dev",
"context": "..",
"dockerFile": "../Dockerfile.dev",
"postCreateCommand": "mkdir -p config && pip3 install -e .",
"postCreateCommand": "script/setup",
"postStartCommand": "script/bootstrap",
"containerEnv": { "DEVCONTAINER": "1" },
"appPort": 8123,
"runArgs": ["-e", "GIT_EDITOR=code --wait"],
"extensions": [
"ms-python.vscode-pylance",
"visualstudioexptteam.vscodeintellicode",
"ms-azure-devops.azure-pipelines",
"redhat.vscode-yaml",
"esbenp.prettier-vscode"
],
@@ -19,12 +20,11 @@
"python.linting.enabled": true,
"python.formatting.provider": "black",
"python.testing.pytestArgs": ["--no-cov"],
"python.testing.pytestEnabled": true,
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"files.trimTrailingWhitespace": true,
"terminal.integrated.shell.linux": "/bin/bash",
"terminal.integrated.shell.linux": "/usr/bin/zsh",
"yaml.customTags": [
"!input scalar",
"!secret scalar",

View File

@@ -1,53 +0,0 @@
---
name: Report a bug with Home Assistant Core
about: Report an issue with Home Assistant Core
---
<!-- READ THIS FIRST:
- If you need additional help with this template, please refer to https://www.home-assistant.io/help/reporting_issues/
- Make sure you are running the latest version of Home Assistant before reporting an issue: https://github.com/home-assistant/core/releases
- Do not report issues for integrations if you are using custom components or integrations.
- Provide as many details as possible. Paste logs, configuration samples and code into the backticks.
DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed without comment.
-->
## The problem
<!--
Describe the issue you are experiencing here to communicate to the
maintainers. Tell us what you were trying to do and what happened.
-->
## Environment
<!--
Provide details about the versions you are using, which helps us to reproduce
and find the issue quicker. Version information is found in the
Home Assistant frontend: Configuration -> Info.
-->
- Home Assistant Core release with the issue:
- Last working Home Assistant Core release (if known):
- Operating environment (OS/Container/Supervised/Core):
- Integration causing this issue:
- Link to integration documentation on our website:
## Problem-relevant `configuration.yaml`
<!--
An example configuration that caused the problem for you. Fill this out even
if it seems unimportant to you. Please be sure to remove personal information
like passwords, private URLs and other credentials.
-->
```yaml
```
## Traceback/Error logs
<!--
If you come across any trace or error logs, please provide them.
-->
```txt
```
## Additional information

102
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,102 @@
name: Report an issue with Home Assistant Core
about: Report an issue with Home Assistant Core.
title: ""
issue_body: true
body:
- type: markdown
attributes:
value: |
This issue form is for reporting bugs only!
If you have a feature or enhancement request, please use the [feature request][fr] section of our [Community Forum][fr].
[fr]: https://community.home-assistant.io/c/feature-requests
- type: textarea
validations:
required: true
attributes:
label: The problem
description: >-
Describe the issue you are experiencing here to communicate to the
maintainers. Tell us what you were trying to do and what happened.
Provide a clear and concise description of what the problem is.
- type: markdown
attributes:
value: |
## Environment
- type: input
validations:
required: true
attributes:
label: What is version of Home Assistant Core has the issue?
placeholder: core-
description: >
Can be found in the Configuration panel -> Info.
- type: input
attributes:
label: What was the last working version of Home Assistant Core?
placeholder: core-
description: >
If known, otherwise leave blank.
- type: dropdown
validations:
required: true
attributes:
label: What type of installation are you running?
description: >
If you don't know, you can find it in: Configuration panel -> Info.
options:
- Home Assistant OS
- Home Assistant Container
- Home Assistant Supervised
- Home Assistant Core
- type: input
attributes:
label: Integration causing the issue
description: >
The name of the integration, for example, Automation or Philips Hue.
- type: input
attributes:
label: Link to integration documentation on our website
placeholder: "https://www.home-assistant.io/integrations/..."
description: |
Providing a link [to the documentation][docs] help us categorizing the
issue, while providing a useful reference at the same time.
[docs]: https://www.home-assistant.io/integrations
- type: markdown
attributes:
value: |
# Details
- type: textarea
attributes:
label: Example YAML snippet
description: |
If this issue has an example piece of YAML that can help reproducing this problem, please provide.
This can be an piece of YAML from, e.g., an automation, script, scene or configuration.
value: |
```yaml
# Put your YAML below this line
```
- type: textarea
attributes:
label: Anything in the logs that might be useful for us?
description: For example, error message, or stack traces.
value: |
```txt
# Put your logs below this line
```
- type: markdown
attributes:
value: |
## Additional information
- type: markdown
attributes:
value: >
If you have any additional information for us, use the field below.
Please note, you can attach screenshots or screen recordings here, by
dragging and dropping files in the field below.

View File

@@ -30,7 +30,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -52,7 +52,7 @@ jobs:
pip install -r requirements.txt -r requirements_test.txt
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -79,7 +79,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -95,7 +95,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -124,7 +124,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -140,7 +140,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -169,7 +169,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -185,7 +185,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -236,7 +236,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -252,7 +252,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -284,7 +284,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -300,7 +300,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -332,7 +332,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -348,7 +348,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -377,7 +377,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -393,7 +393,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -425,7 +425,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -441,7 +441,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -481,7 +481,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -497,7 +497,7 @@ jobs:
exit 1
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: |
@@ -528,7 +528,7 @@ jobs:
uses: actions/checkout@v2
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -560,7 +560,7 @@ jobs:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -591,7 +591,7 @@ jobs:
uses: actions/checkout@v2
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -630,7 +630,7 @@ jobs:
uses: actions/checkout@v2
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -664,7 +664,7 @@ jobs:
uses: actions/checkout@v2
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -700,7 +700,7 @@ jobs:
uses: actions/checkout@v2
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-
@@ -760,7 +760,7 @@ jobs:
uses: actions/checkout@v2
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache@v2
uses: actions/cache@v2.1.4
with:
path: venv
key: >-

View File

@@ -16,7 +16,7 @@ jobs:
# - No PRs marked as no-stale
# - No issues marked as no-stale or help-wanted
- name: 90 days stale issues & PRs policy
uses: actions/stale@v3.0.15
uses: actions/stale@v3.0.17
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 90
@@ -53,7 +53,7 @@ jobs:
# - No PRs marked as no-stale or new-integrations
# - No issues (-1)
- name: 30 days stale PRs policy
uses: actions/stale@v3.0.15
uses: actions/stale@v3.0.17
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30
@@ -78,7 +78,7 @@ jobs:
# - No Issues marked as no-stale or help-wanted
# - No PRs (-1)
- name: Needs more information stale issues policy
uses: actions/stale@v3.0.15
uses: actions/stale@v3.0.17
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
only-labels: "needs-more-information"

View File

@@ -59,8 +59,8 @@ repos:
rev: v1.24.2
hooks:
- id: yamllint
- repo: https://github.com/prettier/prettier
rev: 2.0.4
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.2.1
hooks:
- id: prettier
stages: [manual]
@@ -90,4 +90,4 @@ repos:
pass_filenames: false
language: script
types: [text]
files: ^(homeassistant/.+/(manifest|strings)\.json|\.coveragerc)$
files: ^(homeassistant/.+/(manifest|strings)\.json|\.coveragerc|homeassistant/.+/services\.yaml)$

View File

@@ -24,6 +24,7 @@ homeassistant/components/accuweather/* @bieniu
homeassistant/components/acmeda/* @atmurray
homeassistant/components/adguard/* @frenck
homeassistant/components/advantage_air/* @Bre77
homeassistant/components/aemet/* @noltari
homeassistant/components/agent_dvr/* @ispysoftware
homeassistant/components/airly/* @bieniu
homeassistant/components/airnow/* @asymworks
@@ -82,6 +83,7 @@ homeassistant/components/circuit/* @braam
homeassistant/components/cisco_ios/* @fbradyirl
homeassistant/components/cisco_mobility_express/* @fbradyirl
homeassistant/components/cisco_webex_teams/* @fbradyirl
homeassistant/components/climacell/* @raman325
homeassistant/components/cloud/* @home-assistant/cloud
homeassistant/components/cloudflare/* @ludeeus @ctalkington
homeassistant/components/color_extractor/* @GenericStudent
@@ -144,6 +146,7 @@ homeassistant/components/esphome/* @OttoWinter
homeassistant/components/essent/* @TheLastProject
homeassistant/components/evohome/* @zxdavb
homeassistant/components/ezviz/* @baqs
homeassistant/components/faa_delays/* @ntilley905
homeassistant/components/fastdotcom/* @rohankapoorcom
homeassistant/components/file/* @fabaff
homeassistant/components/filter/* @dgomes
@@ -158,7 +161,7 @@ homeassistant/components/flunearyou/* @bachya
homeassistant/components/forked_daapd/* @uvjustin
homeassistant/components/fortios/* @kimfrellsen
homeassistant/components/foscam/* @skgsergio
homeassistant/components/freebox/* @snoof85 @Quentame
homeassistant/components/freebox/* @hacf-fr @Quentame
homeassistant/components/fronius/* @nielstron
homeassistant/components/frontend/* @home-assistant/frontend
homeassistant/components/garmin_connect/* @cyberjunky
@@ -181,6 +184,7 @@ homeassistant/components/griddy/* @bdraco
homeassistant/components/group/* @home-assistant/core
homeassistant/components/growatt_server/* @indykoning
homeassistant/components/guardian/* @bachya
homeassistant/components/habitica/* @ASMfreaK @leikoilja
homeassistant/components/harmony/* @ehendrix23 @bramkragten @bdraco @mkeesey
homeassistant/components/hassio/* @home-assistant/supervisor
homeassistant/components/hdmi_cec/* @newAM
@@ -241,6 +245,7 @@ homeassistant/components/keba/* @dannerph
homeassistant/components/keenetic_ndms2/* @foxel
homeassistant/components/kef/* @basnijholt
homeassistant/components/keyboard_remote/* @bendavid
homeassistant/components/kmtronic/* @dgomes
homeassistant/components/knx/* @Julius2342 @farmio @marvin-w
homeassistant/components/kodi/* @OnFreund @cgtobi
homeassistant/components/konnected/* @heythisisnate @kit-klein
@@ -250,6 +255,8 @@ homeassistant/components/launch_library/* @ludeeus
homeassistant/components/lcn/* @alengwenus
homeassistant/components/life360/* @pnbruckner
homeassistant/components/linux_battery/* @fabaff
homeassistant/components/litejet/* @joncar
homeassistant/components/litterrobot/* @natekspencer
homeassistant/components/local_ip/* @issacg
homeassistant/components/logger/* @home-assistant/core
homeassistant/components/logi_circle/* @evanjd
@@ -260,8 +267,10 @@ homeassistant/components/luftdaten/* @fabaff
homeassistant/components/lupusec/* @majuss
homeassistant/components/lutron/* @JonGilmore
homeassistant/components/lutron_caseta/* @swails @bdraco
homeassistant/components/lyric/* @timmo001
homeassistant/components/mastodon/* @fabaff
homeassistant/components/matrix/* @tinloaf
homeassistant/components/mazda/* @bdr99
homeassistant/components/mcp23017/* @jardiamj
homeassistant/components/media_source/* @hunterjm
homeassistant/components/mediaroom/* @dgomes
@@ -283,10 +292,12 @@ homeassistant/components/monoprice/* @etsinko @OnFreund
homeassistant/components/moon/* @fabaff
homeassistant/components/motion_blinds/* @starkillerOG
homeassistant/components/mpd/* @fabaff
homeassistant/components/mqtt/* @home-assistant/core @emontnemery
homeassistant/components/mqtt/* @emontnemery
homeassistant/components/msteams/* @peroyvind
homeassistant/components/mullvad/* @meichthys
homeassistant/components/my/* @home-assistant/core
homeassistant/components/myq/* @bdraco
homeassistant/components/mysensors/* @MartinHjelmare
homeassistant/components/mysensors/* @MartinHjelmare @functionpointer
homeassistant/components/mystrom/* @fabaff
homeassistant/components/neato/* @dshokouhi @Santobert
homeassistant/components/nederlandse_spoorwegen/* @YarmoM
@@ -310,7 +321,7 @@ homeassistant/components/notion/* @bachya
homeassistant/components/nsw_fuel_station/* @nickw444
homeassistant/components/nsw_rural_fire_service_feed/* @exxamalte
homeassistant/components/nuheat/* @bdraco
homeassistant/components/nuki/* @pschmitt @pvizeli
homeassistant/components/nuki/* @pschmitt @pvizeli @pree
homeassistant/components/numato/* @clssn
homeassistant/components/number/* @home-assistant/core @Shulyaka
homeassistant/components/nut/* @bdraco
@@ -374,9 +385,11 @@ homeassistant/components/random/* @fabaff
homeassistant/components/recollect_waste/* @bachya
homeassistant/components/rejseplanen/* @DarkFox
homeassistant/components/repetier/* @MTrab
homeassistant/components/rflink/* @javicalle
homeassistant/components/rfxtrx/* @danielhiversen @elupus @RobBie1221
homeassistant/components/ring/* @balloob
homeassistant/components/risco/* @OnFreund
homeassistant/components/rituals_perfume_genie/* @milanmeu
homeassistant/components/rmvtransport/* @cgtobi
homeassistant/components/roku/* @ctalkington
homeassistant/components/roomba/* @pschmitt @cyr-ius @shenxn
@@ -416,6 +429,7 @@ homeassistant/components/smappee/* @bsmappee
homeassistant/components/smart_meter_texas/* @grahamwetzler
homeassistant/components/smarthab/* @outadoc
homeassistant/components/smartthings/* @andrewsayre
homeassistant/components/smarttub/* @mdz
homeassistant/components/smarty/* @z0mbieprocess
homeassistant/components/sms/* @ocalvo
homeassistant/components/smtp/* @fabaff
@@ -442,6 +456,7 @@ homeassistant/components/stiebel_eltron/* @fucm
homeassistant/components/stookalert/* @fwestenberg
homeassistant/components/stream/* @hunterjm @uvjustin
homeassistant/components/stt/* @pvizeli
homeassistant/components/subaru/* @G-Two
homeassistant/components/suez_water/* @ooii
homeassistant/components/sun/* @Swamp-Ig
homeassistant/components/supla/* @mwegrzynek
@@ -455,7 +470,7 @@ homeassistant/components/syncthru/* @nielstron
homeassistant/components/synology_dsm/* @hacf-fr @Quentame @mib1185
homeassistant/components/synology_srm/* @aerialls
homeassistant/components/syslog/* @fabaff
homeassistant/components/tado/* @michaelarnauts @bdraco
homeassistant/components/tado/* @michaelarnauts @bdraco @noltari
homeassistant/components/tag/* @balloob @dmulcahey
homeassistant/components/tahoma/* @philklei
homeassistant/components/tankerkoenig/* @guillempages
@@ -477,7 +492,6 @@ homeassistant/components/toon/* @frenck
homeassistant/components/totalconnect/* @austinmroczek
homeassistant/components/tplink/* @rytilahti @thegardenmonkey
homeassistant/components/traccar/* @ludeeus
homeassistant/components/tradfri/* @ggravlingen
homeassistant/components/trafikverket_train/* @endor-force
homeassistant/components/trafikverket_weatherstation/* @endor-force
homeassistant/components/transmission/* @engrbm87 @JPHutchins
@@ -485,6 +499,7 @@ homeassistant/components/tts/* @pvizeli
homeassistant/components/tuya/* @ollo69
homeassistant/components/twentemilieu/* @frenck
homeassistant/components/twinkly/* @dr1rrb
homeassistant/components/ubus/* @noltari
homeassistant/components/unifi/* @Kane610
homeassistant/components/unifiled/* @florisvdk
homeassistant/components/upb/* @gwww
@@ -506,7 +521,7 @@ homeassistant/components/vicare/* @oischinger
homeassistant/components/vilfo/* @ManneW
homeassistant/components/vivotek/* @HarlemSquirrel
homeassistant/components/vizio/* @raman325
homeassistant/components/vlc_telnet/* @rodripf
homeassistant/components/vlc_telnet/* @rodripf @dmcc
homeassistant/components/volkszaehler/* @fabaff
homeassistant/components/volumio/* @OnFreund
homeassistant/components/waqi/* @andrey-git
@@ -514,6 +529,7 @@ homeassistant/components/watson_tts/* @rutkai
homeassistant/components/weather/* @fabaff
homeassistant/components/webostv/* @bendavid
homeassistant/components/websocket_api/* @home-assistant/core
homeassistant/components/wemo/* @esev
homeassistant/components/wiffi/* @mampfes
homeassistant/components/wilight/* @leofig-rj
homeassistant/components/withings/* @vangorra
@@ -523,7 +539,6 @@ homeassistant/components/workday/* @fabaff
homeassistant/components/worldclock/* @fabaff
homeassistant/components/xbox/* @hunterjm
homeassistant/components/xbox_live/* @MartinHjelmare
homeassistant/components/xfinity/* @cisasteelersfan
homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi
homeassistant/components/xiaomi_miio/* @rytilahti @syssi @starkillerOG
homeassistant/components/xiaomi_tv/* @simse

View File

@@ -1,7 +1,11 @@
FROM mcr.microsoft.com/vscode/devcontainers/python:0-3.8
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN \
apt-get update && apt-get install -y --no-install-recommends \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
libudev-dev \
libavformat-dev \
libavcodec-dev \
@@ -10,6 +14,7 @@ RUN \
libswscale-dev \
libswresample-dev \
libavfilter-dev \
libpcap-dev \
git \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

View File

@@ -114,10 +114,12 @@ stages:
pool:
vmImage: 'ubuntu-latest'
strategy:
maxParallel: 15
maxParallel: 17
matrix:
qemux86-64:
buildMachine: 'qemux86-64'
generic-x86-64:
buildMachine: 'generic-x86-64'
intel-nuc:
buildMachine: 'intel-nuc'
qemux86:

View File

@@ -1,4 +1,6 @@
"""Provide an authentication layer for Home Assistant."""
from __future__ import annotations
import asyncio
from collections import OrderedDict
from datetime import timedelta
@@ -24,11 +26,19 @@ _ProviderKey = Tuple[str, Optional[str]]
_ProviderDict = Dict[_ProviderKey, AuthProvider]
class InvalidAuthError(Exception):
"""Raised when a authentication error occurs."""
class InvalidProvider(Exception):
"""Authentication provider not found."""
async def auth_manager_from_config(
hass: HomeAssistant,
provider_configs: List[Dict[str, Any]],
module_configs: List[Dict[str, Any]],
) -> "AuthManager":
) -> AuthManager:
"""Initialize an auth manager from config.
CORE_CONFIG_SCHEMA will make sure do duplicated auth providers or
@@ -68,7 +78,7 @@ async def auth_manager_from_config(
class AuthManagerFlowManager(data_entry_flow.FlowManager):
"""Manage authentication flows."""
def __init__(self, hass: HomeAssistant, auth_manager: "AuthManager"):
def __init__(self, hass: HomeAssistant, auth_manager: AuthManager):
"""Init auth manager flows."""
super().__init__(hass)
self.auth_manager = auth_manager
@@ -96,7 +106,7 @@ class AuthManagerFlowManager(data_entry_flow.FlowManager):
return result
# we got final result
if isinstance(result["data"], models.User):
if isinstance(result["data"], models.Credentials):
result["result"] = result["data"]
return result
@@ -120,11 +130,12 @@ class AuthManagerFlowManager(data_entry_flow.FlowManager):
modules = await self.auth_manager.async_get_enabled_mfa(user)
if modules:
flow.credential = credentials
flow.user = user
flow.available_mfa_modules = modules
return await flow.async_step_select_mfa_module()
result["result"] = await self.auth_manager.async_get_or_create_user(credentials)
result["result"] = credentials
return result
@@ -156,7 +167,7 @@ class AuthManager:
return list(self._mfa_modules.values())
def get_auth_provider(
self, provider_type: str, provider_id: str
self, provider_type: str, provider_id: Optional[str]
) -> Optional[AuthProvider]:
"""Return an auth provider, None if not found."""
return self._providers.get((provider_type, provider_id))
@@ -367,6 +378,7 @@ class AuthManager:
client_icon: Optional[str] = None,
token_type: Optional[str] = None,
access_token_expiration: timedelta = ACCESS_TOKEN_EXPIRATION,
credential: Optional[models.Credentials] = None,
) -> models.RefreshToken:
"""Create a new refresh token for a user."""
if not user.is_active:
@@ -415,6 +427,7 @@ class AuthManager:
client_icon,
token_type,
access_token_expiration,
credential,
)
async def async_get_refresh_token(
@@ -440,6 +453,8 @@ class AuthManager:
self, refresh_token: models.RefreshToken, remote_ip: Optional[str] = None
) -> str:
"""Create a new access token."""
self.async_validate_refresh_token(refresh_token, remote_ip)
self._store.async_log_refresh_token_usage(refresh_token, remote_ip)
now = dt_util.utcnow()
@@ -453,6 +468,40 @@ class AuthManager:
algorithm="HS256",
).decode()
@callback
def _async_resolve_provider(
self, refresh_token: models.RefreshToken
) -> Optional[AuthProvider]:
"""Get the auth provider for the given refresh token.
Raises an exception if the expected provider is no longer available or return
None if no provider was expected for this refresh token.
"""
if refresh_token.credential is None:
return None
provider = self.get_auth_provider(
refresh_token.credential.auth_provider_type,
refresh_token.credential.auth_provider_id,
)
if provider is None:
raise InvalidProvider(
f"Auth provider {refresh_token.credential.auth_provider_type}, {refresh_token.credential.auth_provider_id} not available"
)
return provider
@callback
def async_validate_refresh_token(
self, refresh_token: models.RefreshToken, remote_ip: Optional[str] = None
) -> None:
"""Validate that a refresh token is usable.
Will raise InvalidAuthError on errors.
"""
provider = self._async_resolve_provider(refresh_token)
if provider:
provider.async_validate_refresh_token(refresh_token, remote_ip)
async def async_validate_access_token(
self, token: str
) -> Optional[models.RefreshToken]:

View File

@@ -208,6 +208,7 @@ class AuthStore:
client_icon: Optional[str] = None,
token_type: str = models.TOKEN_TYPE_NORMAL,
access_token_expiration: timedelta = ACCESS_TOKEN_EXPIRATION,
credential: Optional[models.Credentials] = None,
) -> models.RefreshToken:
"""Create a new token for a user."""
kwargs: Dict[str, Any] = {
@@ -215,6 +216,7 @@ class AuthStore:
"client_id": client_id,
"token_type": token_type,
"access_token_expiration": access_token_expiration,
"credential": credential,
}
if client_name:
kwargs["client_name"] = client_name
@@ -309,6 +311,7 @@ class AuthStore:
users: Dict[str, models.User] = OrderedDict()
groups: Dict[str, models.Group] = OrderedDict()
credentials: Dict[str, models.Credentials] = OrderedDict()
# Soft-migrating data as we load. We are going to make sure we have a
# read only group and an admin group. There are two states that we can
@@ -415,15 +418,15 @@ class AuthStore:
)
for cred_dict in data["credentials"]:
users[cred_dict["user_id"]].credentials.append(
models.Credentials(
id=cred_dict["id"],
is_new=False,
auth_provider_type=cred_dict["auth_provider_type"],
auth_provider_id=cred_dict["auth_provider_id"],
data=cred_dict["data"],
)
credential = models.Credentials(
id=cred_dict["id"],
is_new=False,
auth_provider_type=cred_dict["auth_provider_type"],
auth_provider_id=cred_dict["auth_provider_id"],
data=cred_dict["data"],
)
credentials[cred_dict["id"]] = credential
users[cred_dict["user_id"]].credentials.append(credential)
for rt_dict in data["refresh_tokens"]:
# Filter out the old keys that don't have jwt_key (pre-0.76)
@@ -469,6 +472,8 @@ class AuthStore:
jwt_key=rt_dict["jwt_key"],
last_used_at=last_used_at,
last_used_ip=rt_dict.get("last_used_ip"),
credential=credentials.get(rt_dict.get("credential_id")),
version=rt_dict.get("version"),
)
users[rt_dict["user_id"]].refresh_tokens[token.id] = token
@@ -542,6 +547,10 @@ class AuthStore:
if refresh_token.last_used_at
else None,
"last_used_ip": refresh_token.last_used_ip,
"credential_id": refresh_token.credential.id
if refresh_token.credential
else None,
"version": refresh_token.version,
}
for user in self._users.values()
for refresh_token in user.refresh_tokens.values()

View File

@@ -1,4 +1,6 @@
"""Pluggable auth modules for Home Assistant."""
from __future__ import annotations
import importlib
import logging
import types
@@ -66,7 +68,7 @@ class MultiFactorAuthModule:
"""Return a voluptuous schema to define mfa auth module's input."""
raise NotImplementedError
async def async_setup_flow(self, user_id: str) -> "SetupFlow":
async def async_setup_flow(self, user_id: str) -> SetupFlow:
"""Return a data entry flow handler for setup module.
Mfa module should extend SetupFlow

View File

@@ -198,7 +198,7 @@ class TotpSetupFlow(SetupFlow):
errors: Dict[str, str] = {}
if user_input:
verified = await self.hass.async_add_executor_job( # type: ignore
verified = await self.hass.async_add_executor_job(
pyotp.TOTP(self._ota_secret).verify, user_input["code"]
)
if verified:

View File

@@ -6,6 +6,7 @@ import uuid
import attr
from homeassistant.const import __version__
from homeassistant.util import dt as dt_util
from . import permissions as perm_mdl
@@ -106,6 +107,10 @@ class RefreshToken:
last_used_at: Optional[datetime] = attr.ib(default=None)
last_used_ip: Optional[str] = attr.ib(default=None)
credential: Optional["Credentials"] = attr.ib(default=None)
version: Optional[str] = attr.ib(default=__version__)
@attr.s(slots=True)
class Credentials:

View File

@@ -1,4 +1,6 @@
"""Auth providers for Home Assistant."""
from __future__ import annotations
import importlib
import logging
import types
@@ -16,7 +18,7 @@ from homeassistant.util.decorator import Registry
from ..auth_store import AuthStore
from ..const import MFA_SESSION_EXPIRATION
from ..models import Credentials, User, UserMeta
from ..models import Credentials, RefreshToken, User, UserMeta
_LOGGER = logging.getLogger(__name__)
DATA_REQS = "auth_prov_reqs_processed"
@@ -92,7 +94,7 @@ class AuthProvider:
# Implement by extending class
async def async_login_flow(self, context: Optional[Dict]) -> "LoginFlow":
async def async_login_flow(self, context: Optional[Dict]) -> LoginFlow:
"""Return the data flow for logging in with auth provider.
Auth provider should extend LoginFlow and return an instance.
@@ -117,6 +119,16 @@ class AuthProvider:
async def async_initialize(self) -> None:
"""Initialize the auth provider."""
@callback
def async_validate_refresh_token(
self, refresh_token: RefreshToken, remote_ip: Optional[str] = None
) -> None:
"""Verify a refresh token is still valid.
Optional hook for an auth provider to verify validity of a refresh token.
Should raise InvalidAuthError on errors.
"""
async def auth_provider_from_config(
hass: HomeAssistant, store: AuthStore, config: Dict[str, Any]
@@ -182,6 +194,7 @@ class LoginFlow(data_entry_flow.FlowHandler):
self.created_at = dt_util.utcnow()
self.invalid_mfa_times = 0
self.user: Optional[User] = None
self.credential: Optional[Credentials] = None
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None
@@ -222,6 +235,7 @@ class LoginFlow(data_entry_flow.FlowHandler):
self, user_input: Optional[Dict[str, str]] = None
) -> Dict[str, Any]:
"""Handle the step of mfa validation."""
assert self.credential
assert self.user
errors = {}
@@ -257,7 +271,7 @@ class LoginFlow(data_entry_flow.FlowHandler):
return self.async_abort(reason="too_many_retry")
if not errors:
return await self.async_finish(self.user)
return await self.async_finish(self.credential)
description_placeholders: Dict[str, Optional[str]] = {
"mfa_module_name": auth_module.name,

View File

@@ -8,12 +8,12 @@ from typing import Any, Dict, Optional, cast
import voluptuous as vol
from homeassistant.const import CONF_COMMAND
from homeassistant.exceptions import HomeAssistantError
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
from ..models import Credentials, UserMeta
CONF_COMMAND = "command"
CONF_ARGS = "args"
CONF_META = "meta"

View File

@@ -1,4 +1,6 @@
"""Home Assistant auth provider."""
from __future__ import annotations
import asyncio
import base64
from collections import OrderedDict
@@ -31,7 +33,7 @@ CONFIG_SCHEMA = vol.All(AUTH_PROVIDER_SCHEMA, _disallow_id)
@callback
def async_get_provider(hass: HomeAssistant) -> "HassAuthProvider":
def async_get_provider(hass: HomeAssistant) -> HassAuthProvider:
"""Get the provider."""
for prv in hass.auth.auth_providers:
if prv.type == "homeassistant":

View File

@@ -8,13 +8,12 @@ from typing import Any, Dict, Optional, cast
import voluptuous as vol
from homeassistant.core import HomeAssistant, callback
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.config_validation as cv
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
from .. import AuthManager
from ..models import Credentials, User, UserMeta
from ..models import Credentials, UserMeta
AUTH_PROVIDER_TYPE = "legacy_api_password"
CONF_API_PASSWORD = "api_password"
@@ -30,23 +29,6 @@ class InvalidAuthError(HomeAssistantError):
"""Raised when submitting invalid authentication."""
async def async_validate_password(hass: HomeAssistant, password: str) -> Optional[User]:
"""Return a user if password is valid. None if not."""
auth = cast(AuthManager, hass.auth) # type: ignore
providers = auth.get_auth_providers(AUTH_PROVIDER_TYPE)
if not providers:
raise ValueError("Legacy API password provider not found")
try:
provider = cast(LegacyApiPasswordAuthProvider, providers[0])
provider.async_validate_login(password)
return await auth.async_get_or_create_user(
await provider.async_get_or_create_credentials({})
)
except InvalidAuthError:
return None
@AUTH_PROVIDERS.register(AUTH_PROVIDER_TYPE)
class LegacyApiPasswordAuthProvider(AuthProvider):
"""An auth provider support legacy api_password."""

View File

@@ -3,7 +3,14 @@
It shows list of users if access from trusted network.
Abort login flow if not access from trusted network.
"""
from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network, ip_network
from ipaddress import (
IPv4Address,
IPv4Network,
IPv6Address,
IPv6Network,
ip_address,
ip_network,
)
from typing import Any, Dict, List, Optional, Union, cast
import voluptuous as vol
@@ -13,7 +20,8 @@ from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.config_validation as cv
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
from ..models import Credentials, UserMeta
from .. import InvalidAuthError
from ..models import Credentials, RefreshToken, UserMeta
IPAddress = Union[IPv4Address, IPv6Address]
IPNetwork = Union[IPv4Network, IPv6Network]
@@ -46,10 +54,6 @@ CONFIG_SCHEMA = AUTH_PROVIDER_SCHEMA.extend(
)
class InvalidAuthError(HomeAssistantError):
"""Raised when try to access from untrusted networks."""
class InvalidUserError(HomeAssistantError):
"""Raised when try to login as invalid user."""
@@ -163,6 +167,17 @@ class TrustedNetworksAuthProvider(AuthProvider):
):
raise InvalidAuthError("Not in trusted_networks")
@callback
def async_validate_refresh_token(
self, refresh_token: RefreshToken, remote_ip: Optional[str] = None
) -> None:
"""Verify a refresh token is still valid."""
if remote_ip is None:
raise InvalidAuthError(
"Unknown remote ip can't be used for trusted network provider."
)
self.async_validate_access(ip_address(remote_ip))
class TrustedNetworksLoginFlow(LoginFlow):
"""Handler for the login flow."""

View File

@@ -17,6 +17,7 @@ from homeassistant import config as conf_util, config_entries, core, loader
from homeassistant.components import http
from homeassistant.const import REQUIRED_NEXT_PYTHON_DATE, REQUIRED_NEXT_PYTHON_VER
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import area_registry, device_registry, entity_registry
from homeassistant.helpers.typing import ConfigType
from homeassistant.setup import (
DATA_SETUP,
@@ -510,10 +511,12 @@ async def _async_set_up_integrations(
stage_2_domains = domains_to_setup - logging_domains - debuggers - stage_1_domains
# Kick off loading the registries. They don't need to be awaited.
asyncio.create_task(hass.helpers.device_registry.async_get_registry())
asyncio.create_task(hass.helpers.entity_registry.async_get_registry())
asyncio.create_task(hass.helpers.area_registry.async_get_registry())
# Load the registries
await asyncio.gather(
device_registry.async_load(hass),
entity_registry.async_load(hass),
area_registry.async_load(hass),
)
# Start setup
if stage_1_domains:

View File

@@ -13,6 +13,7 @@ from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_REAUTH
from homeassistant.const import (
ATTR_ATTRIBUTION,
ATTR_DATE,
ATTR_DEVICE_ID,
ATTR_ENTITY_ID,
ATTR_TIME,
CONF_PASSWORD,
@@ -32,7 +33,6 @@ SERVICE_SETTINGS = "change_setting"
SERVICE_CAPTURE_IMAGE = "capture_image"
SERVICE_TRIGGER_AUTOMATION = "trigger_automation"
ATTR_DEVICE_ID = "device_id"
ATTR_DEVICE_NAME = "device_name"
ATTR_DEVICE_TYPE = "device_type"
ATTR_EVENT_CODE = "event_code"

View File

@@ -1,7 +1,7 @@
{
"config": {
"abort": {
"reauth_successful": "La riautenticazione ha avuto successo",
"reauth_successful": "La nuova autenticazione \u00e8 stata eseguita correttamente",
"single_instance_allowed": "Gi\u00e0 configurato. \u00c8 possibile una sola configurazione."
},
"error": {

View File

@@ -1,9 +1,20 @@
{
"config": {
"abort": {
"single_instance_allowed": "\ud558\ub098\uc758 Abode \ub9cc \uad6c\uc131\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4."
"reauth_successful": "\uc7ac\uc778\uc99d\uc5d0 \uc131\uacf5\ud588\uc2b5\ub2c8\ub2e4",
"single_instance_allowed": "\uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ud558\ub098\uc758 \uad6c\uc131\ub9cc \uac00\ub2a5\ud569\ub2c8\ub2e4."
},
"error": {
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4",
"invalid_auth": "\uc778\uc99d\uc774 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"step": {
"reauth_confirm": {
"data": {
"password": "\ube44\ubc00\ubc88\ud638",
"username": "\uc774\uba54\uc77c"
}
},
"user": {
"data": {
"password": "\ube44\ubc00\ubc88\ud638",

View File

@@ -1,6 +1,7 @@
{
"config": {
"abort": {
"reauth_successful": "Herauthenticatie was succesvol",
"single_instance_allowed": "Slechts een enkele configuratie van Abode is toegestaan."
},
"error": {
@@ -12,9 +13,14 @@
"mfa": {
"data": {
"mfa_code": "MFA-code (6-cijfers)"
}
},
"title": "Voer uw MFA-code voor Abode in"
},
"reauth_confirm": {
"data": {
"password": "Wachtwoord",
"username": "E-mail"
},
"title": "Vul uw Abode-inloggegevens in"
},
"user": {

View File

@@ -6,7 +6,7 @@
},
"error": {
"cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.",
"invalid_auth": "\u041d\u0435\u0432\u0435\u0440\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f.",
"invalid_auth": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.",
"invalid_mfa_code": "\u041d\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434 MFA."
},
"step": {

View File

@@ -17,6 +17,7 @@ from homeassistant.components.weather import (
)
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_ICON,
CONCENTRATION_PARTS_PER_CUBIC_METER,
DEVICE_CLASS_TEMPERATURE,
LENGTH_FEET,
@@ -33,7 +34,6 @@ from homeassistant.const import (
)
ATTRIBUTION = "Data provided by AccuWeather"
ATTR_ICON = "icon"
ATTR_FORECAST = CONF_FORECAST = "forecast"
ATTR_LABEL = "label"
ATTR_UNIT_IMPERIAL = "Imperial"

View File

@@ -2,7 +2,7 @@
"domain": "accuweather",
"name": "AccuWeather",
"documentation": "https://www.home-assistant.io/integrations/accuweather/",
"requirements": ["accuweather==0.0.11"],
"requirements": ["accuweather==0.1.0"],
"codeowners": ["@bieniu"],
"config_flow": true,
"quality_scale": "platinum"

View File

@@ -1,9 +1,29 @@
{
"config": {
"abort": {
"single_instance_allowed": "\uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ud558\ub098\uc758 \uad6c\uc131\ub9cc \uac00\ub2a5\ud569\ub2c8\ub2e4."
},
"error": {
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4",
"invalid_api_key": "API \ud0a4\uac00 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {
"api_key": "API \ud0a4",
"latitude": "\uc704\ub3c4",
"longitude": "\uacbd\ub3c4",
"name": "\uc774\ub984"
},
"description": "\uad6c\uc131\uc5d0 \ub300\ud55c \ub3c4\uc6c0\uc774 \ud544\uc694\ud55c \uacbd\uc6b0 \ub2e4\uc74c\uc744 \ucc38\uc870\ud574\uc8fc\uc138\uc694:\nhttps://www.home-assistant.io/integrations/accuweather/\n\n\uc77c\ubd80 \uc13c\uc11c\ub294 \uae30\ubcf8\uc801\uc73c\ub85c \ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uc5f0\ub3d9 \uad6c\uc131 \ud6c4 \uad6c\uc131\uc694\uc18c \ub808\uc9c0\uc2a4\ud2b8\ub9ac\uc5d0\uc11c \ud65c\uc131\ud654\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\uc77c\uae30\uc608\ubcf4\ub294 \uae30\ubcf8\uc801\uc73c\ub85c \ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uc5f0\ub3d9 \uc635\uc158\uc5d0\uc11c \ud65c\uc131\ud654\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4."
}
}
},
"options": {
"step": {
"user": {
"description": "\ubb34\ub8cc \ubc84\uc804\uc758 AccuWeather API \ud0a4\ub85c \uc77c\uae30\uc608\ubcf4\ub97c \ud65c\uc131\ud654\ud55c \uacbd\uc6b0 \uc81c\ud55c\uc0ac\ud56d\uc73c\ub85c \uc778\ud574 \uc5c5\ub370\uc774\ud2b8\ub294 40 \ubd84\uc774 \uc544\ub2cc 80 \ubd84\ub9c8\ub2e4 \uc218\ud589\ub429\ub2c8\ub2e4."
}
}
}
}

View File

@@ -9,6 +9,7 @@ from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.const import (
CONF_FILENAME,
CONF_NAME,
CONF_TIMEOUT,
STATE_OFF,
STATE_ON,
STATE_UNKNOWN,
@@ -17,7 +18,6 @@ import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
CONF_TIMEOUT = "timeout"
CONF_WRITE_TIMEOUT = "write_timeout"
DEFAULT_NAME = "Acer Projector"
@@ -74,7 +74,6 @@ class AcerSwitch(SwitchEntity):
def __init__(self, serial_port, name, timeout, write_timeout, **kwargs):
"""Init of the Acer projector."""
self.ser = serial.Serial(
port=serial_port, timeout=timeout, write_timeout=write_timeout, **kwargs
)
@@ -90,7 +89,6 @@ class AcerSwitch(SwitchEntity):
def _write_read(self, msg):
"""Write to the projector and read the return."""
ret = ""
# Sometimes the projector won't answer for no reason or the projector
# was disconnected during runtime.

View File

@@ -32,7 +32,7 @@ class AcmedaBase(entity.Entity):
device.id, remove_config_entry_id=self.registry_entry.config_entry_id
)
await self.async_remove()
await self.async_remove(force_remove=True)
async def async_added_to_hass(self):
"""Entity has been added to hass."""

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"no_devices_found": "\ub124\ud2b8\uc6cc\ud06c\uc5d0\uc11c \uae30\uae30\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"no_devices_found": "Geen apparaten gevonden op het netwerk"
},
"step": {
"user": {
"data": {

View File

@@ -2,7 +2,10 @@
"config": {
"abort": {
"existing_instance_updated": "\uae30\uc874 \uad6c\uc131\uc744 \uc5c5\ub370\uc774\ud2b8\ud588\uc2b5\ub2c8\ub2e4.",
"single_instance_allowed": "\ud558\ub098\uc758 AdGuard Home \ub9cc \uad6c\uc131\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4."
"single_instance_allowed": "\uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ud558\ub098\uc758 \uad6c\uc131\ub9cc \uac00\ub2a5\ud569\ub2c8\ub2e4."
},
"error": {
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4"
},
"step": {
"hassio_confirm": {
@@ -14,9 +17,9 @@
"host": "\ud638\uc2a4\ud2b8",
"password": "\ube44\ubc00\ubc88\ud638",
"port": "\ud3ec\ud2b8",
"ssl": "AdGuard Home \uc740 SSL \uc778\uc99d\uc11c\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4",
"ssl": "SSL \uc778\uc99d\uc11c \uc0ac\uc6a9",
"username": "\uc0ac\uc6a9\uc790 \uc774\ub984",
"verify_ssl": "AdGuard Home \uc740 \uc62c\ubc14\ub978 \uc778\uc99d\uc11c\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4"
"verify_ssl": "SSL \uc778\uc99d\uc11c \ud655\uc778"
},
"description": "\ubaa8\ub2c8\ud130\ub9c1 \ubc0f \uc81c\uc5b4\uac00 \uac00\ub2a5\ud558\ub3c4\ub85d AdGuard Home \uc778\uc2a4\ud134\uc2a4\ub97c \uc124\uc815\ud574\uc8fc\uc138\uc694."
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "\uae30\uae30\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"error": {
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {
"ip_address": "IP \uc8fc\uc18c",
"port": "\ud3ec\ud2b8"
}
}
}
}
}

View File

@@ -3,9 +3,13 @@
"abort": {
"already_configured": "Apparaat is al geconfigureerd"
},
"error": {
"cannot_connect": "Kan geen verbinding maken"
},
"step": {
"user": {
"data": {
"ip_address": "IP-adres",
"port": "Poort"
},
"description": "Maak verbinding met de API van uw Advantage Air-tablet voor wandmontage.",

View File

@@ -0,0 +1,61 @@
"""The AEMET OpenData component."""
import asyncio
import logging
from aemet_opendata.interface import AEMET
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
from homeassistant.core import HomeAssistant
from .const import COMPONENTS, DOMAIN, ENTRY_NAME, ENTRY_WEATHER_COORDINATOR
from .weather_update_coordinator import WeatherUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
async def async_setup(hass: HomeAssistant, config: dict) -> bool:
"""Set up the AEMET OpenData component."""
hass.data.setdefault(DOMAIN, {})
return True
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
"""Set up AEMET OpenData as config entry."""
name = config_entry.data[CONF_NAME]
api_key = config_entry.data[CONF_API_KEY]
latitude = config_entry.data[CONF_LATITUDE]
longitude = config_entry.data[CONF_LONGITUDE]
aemet = AEMET(api_key)
weather_coordinator = WeatherUpdateCoordinator(hass, aemet, latitude, longitude)
await weather_coordinator.async_refresh()
hass.data[DOMAIN][config_entry.entry_id] = {
ENTRY_NAME: name,
ENTRY_WEATHER_COORDINATOR: weather_coordinator,
}
for component in COMPONENTS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(config_entry, component)
)
return True
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry):
"""Unload a config entry."""
unload_ok = all(
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(config_entry, component)
for component in COMPONENTS
]
)
)
if unload_ok:
hass.data[DOMAIN].pop(config_entry.entry_id)
return unload_ok

View File

@@ -0,0 +1,57 @@
"""Abstraction form AEMET OpenData sensors."""
from homeassistant.const import ATTR_ATTRIBUTION
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import ATTRIBUTION, SENSOR_DEVICE_CLASS, SENSOR_NAME, SENSOR_UNIT
from .weather_update_coordinator import WeatherUpdateCoordinator
class AbstractAemetSensor(CoordinatorEntity):
"""Abstract class for an AEMET OpenData sensor."""
def __init__(
self,
name,
unique_id,
sensor_type,
sensor_configuration,
coordinator: WeatherUpdateCoordinator,
):
"""Initialize the sensor."""
super().__init__(coordinator)
self._name = name
self._unique_id = unique_id
self._sensor_type = sensor_type
self._sensor_name = sensor_configuration[SENSOR_NAME]
self._unit_of_measurement = sensor_configuration.get(SENSOR_UNIT)
self._device_class = sensor_configuration.get(SENSOR_DEVICE_CLASS)
@property
def name(self):
"""Return the name of the sensor."""
return f"{self._name} {self._sensor_name}"
@property
def unique_id(self):
"""Return a unique_id for this entity."""
return self._unique_id
@property
def attribution(self):
"""Return the attribution."""
return ATTRIBUTION
@property
def device_class(self):
"""Return the device_class."""
return self._device_class
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self._unit_of_measurement
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {ATTR_ATTRIBUTION: ATTRIBUTION}

View File

@@ -0,0 +1,58 @@
"""Config flow for AEMET OpenData."""
from aemet_opendata import AEMET
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
import homeassistant.helpers.config_validation as cv
from .const import DEFAULT_NAME
from .const import DOMAIN # pylint:disable=unused-import
class AemetConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Config flow for AEMET OpenData."""
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
async def async_step_user(self, user_input=None):
"""Handle a flow initialized by the user."""
errors = {}
if user_input is not None:
latitude = user_input[CONF_LATITUDE]
longitude = user_input[CONF_LONGITUDE]
await self.async_set_unique_id(f"{latitude}-{longitude}")
self._abort_if_unique_id_configured()
api_online = await _is_aemet_api_online(self.hass, user_input[CONF_API_KEY])
if not api_online:
errors["base"] = "invalid_api_key"
if not errors:
return self.async_create_entry(
title=user_input[CONF_NAME], data=user_input
)
schema = vol.Schema(
{
vol.Required(CONF_API_KEY): str,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): str,
vol.Optional(
CONF_LATITUDE, default=self.hass.config.latitude
): cv.latitude,
vol.Optional(
CONF_LONGITUDE, default=self.hass.config.longitude
): cv.longitude,
}
)
return self.async_show_form(step_id="user", data_schema=schema, errors=errors)
async def _is_aemet_api_online(hass, api_key):
aemet = AEMET(api_key)
return await hass.async_add_executor_job(
aemet.get_conventional_observation_stations, False
)

View File

@@ -0,0 +1,326 @@
"""Constant values for the AEMET OpenData component."""
from homeassistant.components.weather import (
ATTR_CONDITION_CLEAR_NIGHT,
ATTR_CONDITION_CLOUDY,
ATTR_CONDITION_FOG,
ATTR_CONDITION_LIGHTNING,
ATTR_CONDITION_LIGHTNING_RAINY,
ATTR_CONDITION_PARTLYCLOUDY,
ATTR_CONDITION_POURING,
ATTR_CONDITION_RAINY,
ATTR_CONDITION_SNOWY,
ATTR_CONDITION_SUNNY,
ATTR_FORECAST_CONDITION,
ATTR_FORECAST_PRECIPITATION,
ATTR_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_FORECAST_TEMP,
ATTR_FORECAST_TEMP_LOW,
ATTR_FORECAST_TIME,
ATTR_FORECAST_WIND_BEARING,
ATTR_FORECAST_WIND_SPEED,
)
from homeassistant.const import (
DEGREE,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_TEMPERATURE,
DEVICE_CLASS_TIMESTAMP,
PERCENTAGE,
PRECIPITATION_MILLIMETERS_PER_HOUR,
PRESSURE_HPA,
SPEED_KILOMETERS_PER_HOUR,
TEMP_CELSIUS,
)
ATTRIBUTION = "Powered by AEMET OpenData"
COMPONENTS = ["sensor", "weather"]
DEFAULT_NAME = "AEMET"
DOMAIN = "aemet"
ENTRY_NAME = "name"
ENTRY_WEATHER_COORDINATOR = "weather_coordinator"
UPDATE_LISTENER = "update_listener"
SENSOR_NAME = "sensor_name"
SENSOR_UNIT = "sensor_unit"
SENSOR_DEVICE_CLASS = "sensor_device_class"
ATTR_API_CONDITION = "condition"
ATTR_API_FORECAST_DAILY = "forecast-daily"
ATTR_API_FORECAST_HOURLY = "forecast-hourly"
ATTR_API_HUMIDITY = "humidity"
ATTR_API_PRESSURE = "pressure"
ATTR_API_RAIN = "rain"
ATTR_API_RAIN_PROB = "rain-probability"
ATTR_API_SNOW = "snow"
ATTR_API_SNOW_PROB = "snow-probability"
ATTR_API_STATION_ID = "station-id"
ATTR_API_STATION_NAME = "station-name"
ATTR_API_STATION_TIMESTAMP = "station-timestamp"
ATTR_API_STORM_PROB = "storm-probability"
ATTR_API_TEMPERATURE = "temperature"
ATTR_API_TEMPERATURE_FEELING = "temperature-feeling"
ATTR_API_TOWN_ID = "town-id"
ATTR_API_TOWN_NAME = "town-name"
ATTR_API_TOWN_TIMESTAMP = "town-timestamp"
ATTR_API_WIND_BEARING = "wind-bearing"
ATTR_API_WIND_MAX_SPEED = "wind-max-speed"
ATTR_API_WIND_SPEED = "wind-speed"
CONDITIONS_MAP = {
ATTR_CONDITION_CLEAR_NIGHT: {
"11n", # Despejado (de noche)
},
ATTR_CONDITION_CLOUDY: {
"14", # Nuboso
"14n", # Nuboso (de noche)
"15", # Muy nuboso
"15n", # Muy nuboso (de noche)
"16", # Cubierto
"16n", # Cubierto (de noche)
"17", # Nubes altas
"17n", # Nubes altas (de noche)
},
ATTR_CONDITION_FOG: {
"81", # Niebla
"81n", # Niebla (de noche)
"82", # Bruma - Neblina
"82n", # Bruma - Neblina (de noche)
},
ATTR_CONDITION_LIGHTNING: {
"51", # Intervalos nubosos con tormenta
"51n", # Intervalos nubosos con tormenta (de noche)
"52", # Nuboso con tormenta
"52n", # Nuboso con tormenta (de noche)
"53", # Muy nuboso con tormenta
"53n", # Muy nuboso con tormenta (de noche)
"54", # Cubierto con tormenta
"54n", # Cubierto con tormenta (de noche)
},
ATTR_CONDITION_LIGHTNING_RAINY: {
"61", # Intervalos nubosos con tormenta y lluvia escasa
"61n", # Intervalos nubosos con tormenta y lluvia escasa (de noche)
"62", # Nuboso con tormenta y lluvia escasa
"62n", # Nuboso con tormenta y lluvia escasa (de noche)
"63", # Muy nuboso con tormenta y lluvia escasa
"63n", # Muy nuboso con tormenta y lluvia escasa (de noche)
"64", # Cubierto con tormenta y lluvia escasa
"64n", # Cubierto con tormenta y lluvia escasa (de noche)
},
ATTR_CONDITION_PARTLYCLOUDY: {
"12", # Poco nuboso
"12n", # Poco nuboso (de noche)
"13", # Intervalos nubosos
"13n", # Intervalos nubosos (de noche)
},
ATTR_CONDITION_POURING: {
"27", # Chubascos
"27n", # Chubascos (de noche)
},
ATTR_CONDITION_RAINY: {
"23", # Intervalos nubosos con lluvia
"23n", # Intervalos nubosos con lluvia (de noche)
"24", # Nuboso con lluvia
"24n", # Nuboso con lluvia (de noche)
"25", # Muy nuboso con lluvia
"25n", # Muy nuboso con lluvia (de noche)
"26", # Cubierto con lluvia
"26n", # Cubierto con lluvia (de noche)
"43", # Intervalos nubosos con lluvia escasa
"43n", # Intervalos nubosos con lluvia escasa (de noche)
"44", # Nuboso con lluvia escasa
"44n", # Nuboso con lluvia escasa (de noche)
"45", # Muy nuboso con lluvia escasa
"45n", # Muy nuboso con lluvia escasa (de noche)
"46", # Cubierto con lluvia escasa
"46n", # Cubierto con lluvia escasa (de noche)
},
ATTR_CONDITION_SNOWY: {
"33", # Intervalos nubosos con nieve
"33n", # Intervalos nubosos con nieve (de noche)
"34", # Nuboso con nieve
"34n", # Nuboso con nieve (de noche)
"35", # Muy nuboso con nieve
"35n", # Muy nuboso con nieve (de noche)
"36", # Cubierto con nieve
"36n", # Cubierto con nieve (de noche)
"71", # Intervalos nubosos con nieve escasa
"71n", # Intervalos nubosos con nieve escasa (de noche)
"72", # Nuboso con nieve escasa
"72n", # Nuboso con nieve escasa (de noche)
"73", # Muy nuboso con nieve escasa
"73n", # Muy nuboso con nieve escasa (de noche)
"74", # Cubierto con nieve escasa
"74n", # Cubierto con nieve escasa (de noche)
},
ATTR_CONDITION_SUNNY: {
"11", # Despejado
},
}
FORECAST_MONITORED_CONDITIONS = [
ATTR_FORECAST_CONDITION,
ATTR_FORECAST_PRECIPITATION,
ATTR_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_FORECAST_TEMP,
ATTR_FORECAST_TEMP_LOW,
ATTR_FORECAST_TIME,
ATTR_FORECAST_WIND_BEARING,
ATTR_FORECAST_WIND_SPEED,
]
MONITORED_CONDITIONS = [
ATTR_API_CONDITION,
ATTR_API_HUMIDITY,
ATTR_API_PRESSURE,
ATTR_API_RAIN,
ATTR_API_RAIN_PROB,
ATTR_API_SNOW,
ATTR_API_SNOW_PROB,
ATTR_API_STATION_ID,
ATTR_API_STATION_NAME,
ATTR_API_STATION_TIMESTAMP,
ATTR_API_STORM_PROB,
ATTR_API_TEMPERATURE,
ATTR_API_TEMPERATURE_FEELING,
ATTR_API_TOWN_ID,
ATTR_API_TOWN_NAME,
ATTR_API_TOWN_TIMESTAMP,
ATTR_API_WIND_BEARING,
ATTR_API_WIND_MAX_SPEED,
ATTR_API_WIND_SPEED,
]
FORECAST_MODE_DAILY = "daily"
FORECAST_MODE_HOURLY = "hourly"
FORECAST_MODES = [
FORECAST_MODE_DAILY,
FORECAST_MODE_HOURLY,
]
FORECAST_MODE_ATTR_API = {
FORECAST_MODE_DAILY: ATTR_API_FORECAST_DAILY,
FORECAST_MODE_HOURLY: ATTR_API_FORECAST_HOURLY,
}
FORECAST_SENSOR_TYPES = {
ATTR_FORECAST_CONDITION: {
SENSOR_NAME: "Condition",
},
ATTR_FORECAST_PRECIPITATION: {
SENSOR_NAME: "Precipitation",
SENSOR_UNIT: PRECIPITATION_MILLIMETERS_PER_HOUR,
},
ATTR_FORECAST_PRECIPITATION_PROBABILITY: {
SENSOR_NAME: "Precipitation probability",
SENSOR_UNIT: PERCENTAGE,
},
ATTR_FORECAST_TEMP: {
SENSOR_NAME: "Temperature",
SENSOR_UNIT: TEMP_CELSIUS,
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
},
ATTR_FORECAST_TEMP_LOW: {
SENSOR_NAME: "Temperature Low",
SENSOR_UNIT: TEMP_CELSIUS,
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
},
ATTR_FORECAST_TIME: {
SENSOR_NAME: "Time",
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP,
},
ATTR_FORECAST_WIND_BEARING: {
SENSOR_NAME: "Wind bearing",
SENSOR_UNIT: DEGREE,
},
ATTR_FORECAST_WIND_SPEED: {
SENSOR_NAME: "Wind speed",
SENSOR_UNIT: SPEED_KILOMETERS_PER_HOUR,
},
}
WEATHER_SENSOR_TYPES = {
ATTR_API_CONDITION: {
SENSOR_NAME: "Condition",
},
ATTR_API_HUMIDITY: {
SENSOR_NAME: "Humidity",
SENSOR_UNIT: PERCENTAGE,
SENSOR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY,
},
ATTR_API_PRESSURE: {
SENSOR_NAME: "Pressure",
SENSOR_UNIT: PRESSURE_HPA,
SENSOR_DEVICE_CLASS: DEVICE_CLASS_PRESSURE,
},
ATTR_API_RAIN: {
SENSOR_NAME: "Rain",
SENSOR_UNIT: PRECIPITATION_MILLIMETERS_PER_HOUR,
},
ATTR_API_RAIN_PROB: {
SENSOR_NAME: "Rain probability",
SENSOR_UNIT: PERCENTAGE,
},
ATTR_API_SNOW: {
SENSOR_NAME: "Snow",
SENSOR_UNIT: PRECIPITATION_MILLIMETERS_PER_HOUR,
},
ATTR_API_SNOW_PROB: {
SENSOR_NAME: "Snow probability",
SENSOR_UNIT: PERCENTAGE,
},
ATTR_API_STATION_ID: {
SENSOR_NAME: "Station ID",
},
ATTR_API_STATION_NAME: {
SENSOR_NAME: "Station name",
},
ATTR_API_STATION_TIMESTAMP: {
SENSOR_NAME: "Station timestamp",
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP,
},
ATTR_API_STORM_PROB: {
SENSOR_NAME: "Storm probability",
SENSOR_UNIT: PERCENTAGE,
},
ATTR_API_TEMPERATURE: {
SENSOR_NAME: "Temperature",
SENSOR_UNIT: TEMP_CELSIUS,
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
},
ATTR_API_TEMPERATURE_FEELING: {
SENSOR_NAME: "Temperature feeling",
SENSOR_UNIT: TEMP_CELSIUS,
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
},
ATTR_API_TOWN_ID: {
SENSOR_NAME: "Town ID",
},
ATTR_API_TOWN_NAME: {
SENSOR_NAME: "Town name",
},
ATTR_API_TOWN_TIMESTAMP: {
SENSOR_NAME: "Town timestamp",
SENSOR_DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP,
},
ATTR_API_WIND_BEARING: {
SENSOR_NAME: "Wind bearing",
SENSOR_UNIT: DEGREE,
},
ATTR_API_WIND_MAX_SPEED: {
SENSOR_NAME: "Wind max speed",
SENSOR_UNIT: SPEED_KILOMETERS_PER_HOUR,
},
ATTR_API_WIND_SPEED: {
SENSOR_NAME: "Wind speed",
SENSOR_UNIT: SPEED_KILOMETERS_PER_HOUR,
},
}
WIND_BEARING_MAP = {
"C": None,
"N": 0.0,
"NE": 45.0,
"E": 90.0,
"SE": 135.0,
"S": 180.0,
"SO": 225.0,
"O": 270.0,
"NO": 315.0,
}

View File

@@ -0,0 +1,8 @@
{
"domain": "aemet",
"name": "AEMET OpenData",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/aemet",
"requirements": ["AEMET-OpenData==0.1.8"],
"codeowners": ["@noltari"]
}

View File

@@ -0,0 +1,114 @@
"""Support for the AEMET OpenData service."""
from .abstract_aemet_sensor import AbstractAemetSensor
from .const import (
DOMAIN,
ENTRY_NAME,
ENTRY_WEATHER_COORDINATOR,
FORECAST_MODE_ATTR_API,
FORECAST_MODE_DAILY,
FORECAST_MODES,
FORECAST_MONITORED_CONDITIONS,
FORECAST_SENSOR_TYPES,
MONITORED_CONDITIONS,
WEATHER_SENSOR_TYPES,
)
from .weather_update_coordinator import WeatherUpdateCoordinator
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up AEMET OpenData sensor entities based on a config entry."""
domain_data = hass.data[DOMAIN][config_entry.entry_id]
name = domain_data[ENTRY_NAME]
weather_coordinator = domain_data[ENTRY_WEATHER_COORDINATOR]
weather_sensor_types = WEATHER_SENSOR_TYPES
forecast_sensor_types = FORECAST_SENSOR_TYPES
entities = []
for sensor_type in MONITORED_CONDITIONS:
unique_id = f"{config_entry.unique_id}-{sensor_type}"
entities.append(
AemetSensor(
name,
unique_id,
sensor_type,
weather_sensor_types[sensor_type],
weather_coordinator,
)
)
for mode in FORECAST_MODES:
name = f"{domain_data[ENTRY_NAME]} {mode}"
for sensor_type in FORECAST_MONITORED_CONDITIONS:
unique_id = f"{config_entry.unique_id}-forecast-{mode}-{sensor_type}"
entities.append(
AemetForecastSensor(
f"{name} Forecast",
unique_id,
sensor_type,
forecast_sensor_types[sensor_type],
weather_coordinator,
mode,
)
)
async_add_entities(entities)
class AemetSensor(AbstractAemetSensor):
"""Implementation of an AEMET OpenData sensor."""
def __init__(
self,
name,
unique_id,
sensor_type,
sensor_configuration,
weather_coordinator: WeatherUpdateCoordinator,
):
"""Initialize the sensor."""
super().__init__(
name, unique_id, sensor_type, sensor_configuration, weather_coordinator
)
self._weather_coordinator = weather_coordinator
@property
def state(self):
"""Return the state of the device."""
return self._weather_coordinator.data.get(self._sensor_type)
class AemetForecastSensor(AbstractAemetSensor):
"""Implementation of an AEMET OpenData forecast sensor."""
def __init__(
self,
name,
unique_id,
sensor_type,
sensor_configuration,
weather_coordinator: WeatherUpdateCoordinator,
forecast_mode,
):
"""Initialize the sensor."""
super().__init__(
name, unique_id, sensor_type, sensor_configuration, weather_coordinator
)
self._weather_coordinator = weather_coordinator
self._forecast_mode = forecast_mode
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
return self._forecast_mode == FORECAST_MODE_DAILY
@property
def state(self):
"""Return the state of the device."""
forecasts = self._weather_coordinator.data.get(
FORECAST_MODE_ATTR_API[self._forecast_mode]
)
if forecasts:
return forecasts[0].get(self._sensor_type)
return None

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]"
},
"error": {
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]"
},
"step": {
"user": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]",
"name": "Name of the integration"
},
"description": "Set up AEMET OpenData integration. To generate API key go to https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "La ubicaci\u00f3 ja est\u00e0 configurada"
},
"error": {
"invalid_api_key": "Clau API inv\u00e0lida"
},
"step": {
"user": {
"data": {
"api_key": "Clau API",
"latitude": "Latitud",
"longitude": "Longitud",
"name": "Nom de la integraci\u00f3"
},
"description": "Configura la integraci\u00f3 d'AEMET OpenData. Per generar la clau API, v\u00e9s a https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "Um\u00edst\u011bn\u00ed je ji\u017e nastaveno"
},
"error": {
"invalid_api_key": "Neplatn\u00fd kl\u00ed\u010d API"
},
"step": {
"user": {
"data": {
"api_key": "Kl\u00ed\u010d API",
"latitude": "Zem\u011bpisn\u00e1 \u0161\u00ed\u0159ka",
"longitude": "Zem\u011bpisn\u00e1 d\u00e9lka",
"name": "N\u00e1zev integrace"
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "Location is already configured"
},
"error": {
"invalid_api_key": "Invalid API key"
},
"step": {
"user": {
"data": {
"api_key": "API Key",
"latitude": "Latitude",
"longitude": "Longitude",
"name": "Name of the integration"
},
"description": "Set up AEMET OpenData integration. To generate API key go to https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "La ubicaci\u00f3n ya est\u00e1 configurada"
},
"error": {
"invalid_api_key": "Clave API no v\u00e1lida"
},
"step": {
"user": {
"data": {
"api_key": "Clave API",
"latitude": "Latitud",
"longitude": "Longitud",
"name": "Nombre de la integraci\u00f3n"
},
"description": "Configurar la integraci\u00f3n de AEMET OpenData. Para generar la clave API, ve a https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "Asukoht on juba m\u00e4\u00e4ratud"
},
"error": {
"invalid_api_key": "Vale API v\u00f5ti"
},
"step": {
"user": {
"data": {
"api_key": "API v\u00f5ti",
"latitude": "Laiuskraad",
"longitude": "Pikkuskraad",
"name": "Sidumise nimi"
},
"description": "Seadista AEMET OpenData sidumine. API v\u00f5tme loomiseks mine aadressile https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "L'emplacement est d\u00e9j\u00e0 configur\u00e9"
},
"error": {
"invalid_api_key": "Cl\u00e9 API invalide"
},
"step": {
"user": {
"data": {
"api_key": "Cl\u00e9 d'API",
"latitude": "Latitude",
"longitude": "Longitude",
"name": "Nom de l'int\u00e9gration"
},
"description": "Configurez l'int\u00e9gration AEMET OpenData. Pour g\u00e9n\u00e9rer la cl\u00e9 API, acc\u00e9dez \u00e0 https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "La posizione \u00e8 gi\u00e0 configurata"
},
"error": {
"invalid_api_key": "Chiave API non valida"
},
"step": {
"user": {
"data": {
"api_key": "Chiave API",
"latitude": "Latitudine",
"longitude": "Logitudine",
"name": "Nome dell'integrazione"
},
"description": "Imposta l'integrazione di AEMET OpenData. Per generare la chiave API, vai su https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,21 @@
{
"config": {
"abort": {
"already_configured": "\uc704\uce58\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
},
"error": {
"invalid_api_key": "API \ud0a4\uac00 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {
"api_key": "API \ud0a4",
"latitude": "\uc704\ub3c4",
"longitude": "\uacbd\ub3c4",
"name": "\ud1b5\ud569 \uad6c\uc131\uc694\uc18c \uc774\ub984"
},
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,21 @@
{
"config": {
"abort": {
"already_configured": "Locatie is al geconfigureerd."
},
"error": {
"invalid_api_key": "Ongeldige API-sleutel"
},
"step": {
"user": {
"data": {
"api_key": "API-sleutel",
"latitude": "Breedtegraad",
"longitude": "Lengtegraad",
"name": "Naam van de integratie"
},
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "Plasseringen er allerede konfigurert"
},
"error": {
"invalid_api_key": "Ugyldig API-n\u00f8kkel"
},
"step": {
"user": {
"data": {
"api_key": "API-n\u00f8kkel",
"latitude": "Breddegrad",
"longitude": "Lengdegrad",
"name": "Navnet p\u00e5 integrasjonen"
},
"description": "Sett opp AEMET OpenData-integrasjon. For \u00e5 generere API-n\u00f8kkel, g\u00e5 til https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "Lokalizacja jest ju\u017c skonfigurowana"
},
"error": {
"invalid_api_key": "Nieprawid\u0142owy klucz API"
},
"step": {
"user": {
"data": {
"api_key": "Klucz API",
"latitude": "Szeroko\u015b\u0107 geograficzna",
"longitude": "D\u0142ugo\u015b\u0107 geograficzna",
"name": "Nazwa integracji"
},
"description": "Skonfiguruj integracj\u0119 AEMET OpenData. Aby wygenerowa\u0107 klucz API, przejd\u017a do https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430."
},
"error": {
"invalid_api_key": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 API."
},
"step": {
"user": {
"data": {
"api_key": "\u041a\u043b\u044e\u0447 API",
"latitude": "\u0428\u0438\u0440\u043e\u0442\u0430",
"longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430",
"name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435"
},
"description": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 Home Assistant \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 AEMET OpenData. \u0427\u0442\u043e\u0431\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 https://opendata.aemet.es/centrodedescargas/altaUsuario.",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"config": {
"abort": {
"already_configured": "\u5ea7\u6a19\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210"
},
"error": {
"invalid_api_key": "API \u5bc6\u9470\u7121\u6548"
},
"step": {
"user": {
"data": {
"api_key": "API \u5bc6\u9470",
"latitude": "\u7def\u5ea6",
"longitude": "\u7d93\u5ea6",
"name": "\u6574\u5408\u540d\u7a31"
},
"description": "\u6b32\u8a2d\u5b9a AEMET OpenData \u6574\u5408\u3002\u8acb\u81f3 https://opendata.aemet.es/centrodedescargas/altaUsuario \u7522\u751f API \u5bc6\u9470",
"title": "AEMET OpenData"
}
}
}
}

View File

@@ -0,0 +1,113 @@
"""Support for the AEMET OpenData service."""
from homeassistant.components.weather import WeatherEntity
from homeassistant.const import TEMP_CELSIUS
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import (
ATTR_API_CONDITION,
ATTR_API_HUMIDITY,
ATTR_API_PRESSURE,
ATTR_API_TEMPERATURE,
ATTR_API_WIND_BEARING,
ATTR_API_WIND_SPEED,
ATTRIBUTION,
DOMAIN,
ENTRY_NAME,
ENTRY_WEATHER_COORDINATOR,
FORECAST_MODE_ATTR_API,
FORECAST_MODE_DAILY,
FORECAST_MODES,
)
from .weather_update_coordinator import WeatherUpdateCoordinator
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up AEMET OpenData weather entity based on a config entry."""
domain_data = hass.data[DOMAIN][config_entry.entry_id]
weather_coordinator = domain_data[ENTRY_WEATHER_COORDINATOR]
entities = []
for mode in FORECAST_MODES:
name = f"{domain_data[ENTRY_NAME]} {mode}"
unique_id = f"{config_entry.unique_id} {mode}"
entities.append(AemetWeather(name, unique_id, weather_coordinator, mode))
if entities:
async_add_entities(entities, False)
class AemetWeather(CoordinatorEntity, WeatherEntity):
"""Implementation of an AEMET OpenData sensor."""
def __init__(
self,
name,
unique_id,
coordinator: WeatherUpdateCoordinator,
forecast_mode,
):
"""Initialize the sensor."""
super().__init__(coordinator)
self._name = name
self._unique_id = unique_id
self._forecast_mode = forecast_mode
@property
def attribution(self):
"""Return the attribution."""
return ATTRIBUTION
@property
def condition(self):
"""Return the current condition."""
return self.coordinator.data[ATTR_API_CONDITION]
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
return self._forecast_mode == FORECAST_MODE_DAILY
@property
def forecast(self):
"""Return the forecast array."""
return self.coordinator.data[FORECAST_MODE_ATTR_API[self._forecast_mode]]
@property
def humidity(self):
"""Return the humidity."""
return self.coordinator.data[ATTR_API_HUMIDITY]
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def pressure(self):
"""Return the pressure."""
return self.coordinator.data[ATTR_API_PRESSURE]
@property
def temperature(self):
"""Return the temperature."""
return self.coordinator.data[ATTR_API_TEMPERATURE]
@property
def temperature_unit(self):
"""Return the unit of measurement."""
return TEMP_CELSIUS
@property
def unique_id(self):
"""Return a unique_id for this entity."""
return self._unique_id
@property
def wind_bearing(self):
"""Return the temperature."""
return self.coordinator.data[ATTR_API_WIND_BEARING]
@property
def wind_speed(self):
"""Return the temperature."""
return self.coordinator.data[ATTR_API_WIND_SPEED]

View File

@@ -0,0 +1,637 @@
"""Weather data coordinator for the AEMET OpenData service."""
from dataclasses import dataclass, field
from datetime import timedelta
import logging
from aemet_opendata.const import (
AEMET_ATTR_DATE,
AEMET_ATTR_DAY,
AEMET_ATTR_DIRECTION,
AEMET_ATTR_ELABORATED,
AEMET_ATTR_FORECAST,
AEMET_ATTR_HUMIDITY,
AEMET_ATTR_ID,
AEMET_ATTR_IDEMA,
AEMET_ATTR_MAX,
AEMET_ATTR_MIN,
AEMET_ATTR_NAME,
AEMET_ATTR_PRECIPITATION,
AEMET_ATTR_PRECIPITATION_PROBABILITY,
AEMET_ATTR_SKY_STATE,
AEMET_ATTR_SNOW,
AEMET_ATTR_SNOW_PROBABILITY,
AEMET_ATTR_SPEED,
AEMET_ATTR_STATION_DATE,
AEMET_ATTR_STATION_HUMIDITY,
AEMET_ATTR_STATION_LOCATION,
AEMET_ATTR_STATION_PRESSURE_SEA,
AEMET_ATTR_STATION_TEMPERATURE,
AEMET_ATTR_STORM_PROBABILITY,
AEMET_ATTR_TEMPERATURE,
AEMET_ATTR_TEMPERATURE_FEELING,
AEMET_ATTR_WIND,
AEMET_ATTR_WIND_GUST,
ATTR_DATA,
)
from aemet_opendata.helpers import (
get_forecast_day_value,
get_forecast_hour_value,
get_forecast_interval_value,
)
import async_timeout
from homeassistant.components.weather import (
ATTR_FORECAST_CONDITION,
ATTR_FORECAST_PRECIPITATION,
ATTR_FORECAST_PRECIPITATION_PROBABILITY,
ATTR_FORECAST_TEMP,
ATTR_FORECAST_TEMP_LOW,
ATTR_FORECAST_TIME,
ATTR_FORECAST_WIND_BEARING,
ATTR_FORECAST_WIND_SPEED,
)
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util import dt as dt_util
from .const import (
ATTR_API_CONDITION,
ATTR_API_FORECAST_DAILY,
ATTR_API_FORECAST_HOURLY,
ATTR_API_HUMIDITY,
ATTR_API_PRESSURE,
ATTR_API_RAIN,
ATTR_API_RAIN_PROB,
ATTR_API_SNOW,
ATTR_API_SNOW_PROB,
ATTR_API_STATION_ID,
ATTR_API_STATION_NAME,
ATTR_API_STATION_TIMESTAMP,
ATTR_API_STORM_PROB,
ATTR_API_TEMPERATURE,
ATTR_API_TEMPERATURE_FEELING,
ATTR_API_TOWN_ID,
ATTR_API_TOWN_NAME,
ATTR_API_TOWN_TIMESTAMP,
ATTR_API_WIND_BEARING,
ATTR_API_WIND_MAX_SPEED,
ATTR_API_WIND_SPEED,
CONDITIONS_MAP,
DOMAIN,
WIND_BEARING_MAP,
)
_LOGGER = logging.getLogger(__name__)
WEATHER_UPDATE_INTERVAL = timedelta(minutes=10)
def format_condition(condition: str) -> str:
"""Return condition from dict CONDITIONS_MAP."""
for key, value in CONDITIONS_MAP.items():
if condition in value:
return key
_LOGGER.error('condition "%s" not found in CONDITIONS_MAP', condition)
return condition
def format_float(value) -> float:
"""Try converting string to float."""
try:
return float(value)
except ValueError:
return None
def format_int(value) -> int:
"""Try converting string to int."""
try:
return int(value)
except ValueError:
return None
class TownNotFound(UpdateFailed):
"""Raised when town is not found."""
class WeatherUpdateCoordinator(DataUpdateCoordinator):
"""Weather data update coordinator."""
def __init__(self, hass, aemet, latitude, longitude):
"""Initialize coordinator."""
super().__init__(
hass, _LOGGER, name=DOMAIN, update_interval=WEATHER_UPDATE_INTERVAL
)
self._aemet = aemet
self._station = None
self._town = None
self._latitude = latitude
self._longitude = longitude
self._data = {
"daily": None,
"hourly": None,
"station": None,
}
async def _async_update_data(self):
data = {}
with async_timeout.timeout(120):
weather_response = await self._get_aemet_weather()
data = self._convert_weather_response(weather_response)
return data
async def _get_aemet_weather(self):
"""Poll weather data from AEMET OpenData."""
weather = await self.hass.async_add_executor_job(self._get_weather_and_forecast)
return weather
def _get_weather_station(self):
if not self._station:
self._station = (
self._aemet.get_conventional_observation_station_by_coordinates(
self._latitude, self._longitude
)
)
if self._station:
_LOGGER.debug(
"station found for coordinates [%s, %s]: %s",
self._latitude,
self._longitude,
self._station,
)
if not self._station:
_LOGGER.debug(
"station not found for coordinates [%s, %s]",
self._latitude,
self._longitude,
)
return self._station
def _get_weather_town(self):
if not self._town:
self._town = self._aemet.get_town_by_coordinates(
self._latitude, self._longitude
)
if self._town:
_LOGGER.debug(
"town found for coordinates [%s, %s]: %s",
self._latitude,
self._longitude,
self._town,
)
if not self._town:
_LOGGER.error(
"town not found for coordinates [%s, %s]",
self._latitude,
self._longitude,
)
raise TownNotFound
return self._town
def _get_weather_and_forecast(self):
"""Get weather and forecast data from AEMET OpenData."""
self._get_weather_town()
daily = self._aemet.get_specific_forecast_town_daily(self._town[AEMET_ATTR_ID])
if not daily:
_LOGGER.error(
'error fetching daily data for town "%s"', self._town[AEMET_ATTR_ID]
)
hourly = self._aemet.get_specific_forecast_town_hourly(
self._town[AEMET_ATTR_ID]
)
if not hourly:
_LOGGER.error(
'error fetching hourly data for town "%s"', self._town[AEMET_ATTR_ID]
)
station = None
if self._get_weather_station():
station = self._aemet.get_conventional_observation_station_data(
self._station[AEMET_ATTR_IDEMA]
)
if not station:
_LOGGER.error(
'error fetching data for station "%s"',
self._station[AEMET_ATTR_IDEMA],
)
if daily:
self._data["daily"] = daily
if hourly:
self._data["hourly"] = hourly
if station:
self._data["station"] = station
return AemetWeather(
self._data["daily"],
self._data["hourly"],
self._data["station"],
)
def _convert_weather_response(self, weather_response):
"""Format the weather response correctly."""
if not weather_response or not weather_response.hourly:
return None
elaborated = dt_util.parse_datetime(
weather_response.hourly[ATTR_DATA][0][AEMET_ATTR_ELABORATED]
)
now = dt_util.now()
hour = now.hour
# Get current day
day = None
for cur_day in weather_response.hourly[ATTR_DATA][0][AEMET_ATTR_FORECAST][
AEMET_ATTR_DAY
]:
cur_day_date = dt_util.parse_datetime(cur_day[AEMET_ATTR_DATE])
if now.date() == cur_day_date.date():
day = cur_day
break
# Get station data
station_data = None
if weather_response.station:
station_data = weather_response.station[ATTR_DATA][-1]
condition = None
humidity = None
pressure = None
rain = None
rain_prob = None
snow = None
snow_prob = None
station_id = None
station_name = None
station_timestamp = None
storm_prob = None
temperature = None
temperature_feeling = None
town_id = None
town_name = None
town_timestamp = dt_util.as_utc(elaborated)
wind_bearing = None
wind_max_speed = None
wind_speed = None
# Get weather values
if day:
condition = self._get_condition(day, hour)
humidity = self._get_humidity(day, hour)
rain = self._get_rain(day, hour)
rain_prob = self._get_rain_prob(day, hour)
snow = self._get_snow(day, hour)
snow_prob = self._get_snow_prob(day, hour)
station_id = self._get_station_id()
station_name = self._get_station_name()
storm_prob = self._get_storm_prob(day, hour)
temperature = self._get_temperature(day, hour)
temperature_feeling = self._get_temperature_feeling(day, hour)
town_id = self._get_town_id()
town_name = self._get_town_name()
wind_bearing = self._get_wind_bearing(day, hour)
wind_max_speed = self._get_wind_max_speed(day, hour)
wind_speed = self._get_wind_speed(day, hour)
# Overwrite weather values with closest station data (if present)
if station_data:
if AEMET_ATTR_STATION_DATE in station_data:
station_dt = dt_util.parse_datetime(
station_data[AEMET_ATTR_STATION_DATE] + "Z"
)
station_timestamp = dt_util.as_utc(station_dt).isoformat()
if AEMET_ATTR_STATION_HUMIDITY in station_data:
humidity = format_float(station_data[AEMET_ATTR_STATION_HUMIDITY])
if AEMET_ATTR_STATION_PRESSURE_SEA in station_data:
pressure = format_float(station_data[AEMET_ATTR_STATION_PRESSURE_SEA])
if AEMET_ATTR_STATION_TEMPERATURE in station_data:
temperature = format_float(station_data[AEMET_ATTR_STATION_TEMPERATURE])
# Get forecast from weather data
forecast_daily = self._get_daily_forecast_from_weather_response(
weather_response, now
)
forecast_hourly = self._get_hourly_forecast_from_weather_response(
weather_response, now
)
return {
ATTR_API_CONDITION: condition,
ATTR_API_FORECAST_DAILY: forecast_daily,
ATTR_API_FORECAST_HOURLY: forecast_hourly,
ATTR_API_HUMIDITY: humidity,
ATTR_API_TEMPERATURE: temperature,
ATTR_API_TEMPERATURE_FEELING: temperature_feeling,
ATTR_API_PRESSURE: pressure,
ATTR_API_RAIN: rain,
ATTR_API_RAIN_PROB: rain_prob,
ATTR_API_SNOW: snow,
ATTR_API_SNOW_PROB: snow_prob,
ATTR_API_STATION_ID: station_id,
ATTR_API_STATION_NAME: station_name,
ATTR_API_STATION_TIMESTAMP: station_timestamp,
ATTR_API_STORM_PROB: storm_prob,
ATTR_API_TOWN_ID: town_id,
ATTR_API_TOWN_NAME: town_name,
ATTR_API_TOWN_TIMESTAMP: town_timestamp,
ATTR_API_WIND_BEARING: wind_bearing,
ATTR_API_WIND_MAX_SPEED: wind_max_speed,
ATTR_API_WIND_SPEED: wind_speed,
}
def _get_daily_forecast_from_weather_response(self, weather_response, now):
if weather_response.daily:
parse = False
forecast = []
for day in weather_response.daily[ATTR_DATA][0][AEMET_ATTR_FORECAST][
AEMET_ATTR_DAY
]:
day_date = dt_util.parse_datetime(day[AEMET_ATTR_DATE])
if now.date() == day_date.date():
parse = True
if parse:
cur_forecast = self._convert_forecast_day(day_date, day)
if cur_forecast:
forecast.append(cur_forecast)
return forecast
return None
def _get_hourly_forecast_from_weather_response(self, weather_response, now):
if weather_response.hourly:
parse = False
hour = now.hour
forecast = []
for day in weather_response.hourly[ATTR_DATA][0][AEMET_ATTR_FORECAST][
AEMET_ATTR_DAY
]:
day_date = dt_util.parse_datetime(day[AEMET_ATTR_DATE])
hour_start = 0
if now.date() == day_date.date():
parse = True
hour_start = now.hour
if parse:
for hour in range(hour_start, 24):
cur_forecast = self._convert_forecast_hour(day_date, day, hour)
if cur_forecast:
forecast.append(cur_forecast)
return forecast
return None
def _convert_forecast_day(self, date, day):
condition = self._get_condition_day(day)
if not condition:
return None
return {
ATTR_FORECAST_CONDITION: condition,
ATTR_FORECAST_PRECIPITATION_PROBABILITY: self._get_precipitation_prob_day(
day
),
ATTR_FORECAST_TEMP: self._get_temperature_day(day),
ATTR_FORECAST_TEMP_LOW: self._get_temperature_low_day(day),
ATTR_FORECAST_TIME: dt_util.as_utc(date),
ATTR_FORECAST_WIND_SPEED: self._get_wind_speed_day(day),
ATTR_FORECAST_WIND_BEARING: self._get_wind_bearing_day(day),
}
def _convert_forecast_hour(self, date, day, hour):
condition = self._get_condition(day, hour)
if not condition:
return None
forecast_dt = date.replace(hour=hour, minute=0, second=0)
return {
ATTR_FORECAST_CONDITION: condition,
ATTR_FORECAST_PRECIPITATION: self._calc_precipitation(day, hour),
ATTR_FORECAST_PRECIPITATION_PROBABILITY: self._calc_precipitation_prob(
day, hour
),
ATTR_FORECAST_TEMP: self._get_temperature(day, hour),
ATTR_FORECAST_TIME: dt_util.as_utc(forecast_dt),
ATTR_FORECAST_WIND_SPEED: self._get_wind_speed(day, hour),
ATTR_FORECAST_WIND_BEARING: self._get_wind_bearing(day, hour),
}
def _calc_precipitation(self, day, hour):
"""Calculate the precipitation."""
rain_value = self._get_rain(day, hour)
if not rain_value:
rain_value = 0
snow_value = self._get_snow(day, hour)
if not snow_value:
snow_value = 0
if round(rain_value + snow_value, 1) == 0:
return None
return round(rain_value + snow_value, 1)
def _calc_precipitation_prob(self, day, hour):
"""Calculate the precipitation probability (hour)."""
rain_value = self._get_rain_prob(day, hour)
if not rain_value:
rain_value = 0
snow_value = self._get_snow_prob(day, hour)
if not snow_value:
snow_value = 0
if rain_value == 0 and snow_value == 0:
return None
return max(rain_value, snow_value)
@staticmethod
def _get_condition(day_data, hour):
"""Get weather condition (hour) from weather data."""
val = get_forecast_hour_value(day_data[AEMET_ATTR_SKY_STATE], hour)
if val:
return format_condition(val)
return None
@staticmethod
def _get_condition_day(day_data):
"""Get weather condition (day) from weather data."""
val = get_forecast_day_value(day_data[AEMET_ATTR_SKY_STATE])
if val:
return format_condition(val)
return None
@staticmethod
def _get_humidity(day_data, hour):
"""Get humidity from weather data."""
val = get_forecast_hour_value(day_data[AEMET_ATTR_HUMIDITY], hour)
if val:
return format_int(val)
return None
@staticmethod
def _get_precipitation_prob_day(day_data):
"""Get humidity from weather data."""
val = get_forecast_day_value(day_data[AEMET_ATTR_PRECIPITATION_PROBABILITY])
if val:
return format_int(val)
return None
@staticmethod
def _get_rain(day_data, hour):
"""Get rain from weather data."""
val = get_forecast_hour_value(day_data[AEMET_ATTR_PRECIPITATION], hour)
if val:
return format_float(val)
return None
@staticmethod
def _get_rain_prob(day_data, hour):
"""Get rain probability from weather data."""
val = get_forecast_interval_value(
day_data[AEMET_ATTR_PRECIPITATION_PROBABILITY], hour
)
if val:
return format_int(val)
return None
@staticmethod
def _get_snow(day_data, hour):
"""Get snow from weather data."""
val = get_forecast_hour_value(day_data[AEMET_ATTR_SNOW], hour)
if val:
return format_float(val)
return None
@staticmethod
def _get_snow_prob(day_data, hour):
"""Get snow probability from weather data."""
val = get_forecast_interval_value(day_data[AEMET_ATTR_SNOW_PROBABILITY], hour)
if val:
return format_int(val)
return None
def _get_station_id(self):
"""Get station ID from weather data."""
if self._station:
return self._station[AEMET_ATTR_IDEMA]
return None
def _get_station_name(self):
"""Get station name from weather data."""
if self._station:
return self._station[AEMET_ATTR_STATION_LOCATION]
return None
@staticmethod
def _get_storm_prob(day_data, hour):
"""Get storm probability from weather data."""
val = get_forecast_interval_value(day_data[AEMET_ATTR_STORM_PROBABILITY], hour)
if val:
return format_int(val)
return None
@staticmethod
def _get_temperature(day_data, hour):
"""Get temperature (hour) from weather data."""
val = get_forecast_hour_value(day_data[AEMET_ATTR_TEMPERATURE], hour)
if val:
return format_int(val)
return None
@staticmethod
def _get_temperature_day(day_data):
"""Get temperature (day) from weather data."""
val = get_forecast_day_value(
day_data[AEMET_ATTR_TEMPERATURE], key=AEMET_ATTR_MAX
)
if val:
return format_int(val)
return None
@staticmethod
def _get_temperature_low_day(day_data):
"""Get temperature (day) from weather data."""
val = get_forecast_day_value(
day_data[AEMET_ATTR_TEMPERATURE], key=AEMET_ATTR_MIN
)
if val:
return format_int(val)
return None
@staticmethod
def _get_temperature_feeling(day_data, hour):
"""Get temperature from weather data."""
val = get_forecast_hour_value(day_data[AEMET_ATTR_TEMPERATURE_FEELING], hour)
if val:
return format_int(val)
return None
def _get_town_id(self):
"""Get town ID from weather data."""
if self._town:
return self._town[AEMET_ATTR_ID]
return None
def _get_town_name(self):
"""Get town name from weather data."""
if self._town:
return self._town[AEMET_ATTR_NAME]
return None
@staticmethod
def _get_wind_bearing(day_data, hour):
"""Get wind bearing (hour) from weather data."""
val = get_forecast_hour_value(
day_data[AEMET_ATTR_WIND_GUST], hour, key=AEMET_ATTR_DIRECTION
)[0]
if val in WIND_BEARING_MAP:
return WIND_BEARING_MAP[val]
_LOGGER.error("%s not found in Wind Bearing map", val)
return None
@staticmethod
def _get_wind_bearing_day(day_data):
"""Get wind bearing (day) from weather data."""
val = get_forecast_day_value(
day_data[AEMET_ATTR_WIND], key=AEMET_ATTR_DIRECTION
)
if val in WIND_BEARING_MAP:
return WIND_BEARING_MAP[val]
_LOGGER.error("%s not found in Wind Bearing map", val)
return None
@staticmethod
def _get_wind_max_speed(day_data, hour):
"""Get wind max speed from weather data."""
val = get_forecast_hour_value(day_data[AEMET_ATTR_WIND_GUST], hour)
if val:
return format_int(val)
return None
@staticmethod
def _get_wind_speed(day_data, hour):
"""Get wind speed (hour) from weather data."""
val = get_forecast_hour_value(
day_data[AEMET_ATTR_WIND_GUST], hour, key=AEMET_ATTR_SPEED
)[0]
if val:
return format_int(val)
return None
@staticmethod
def _get_wind_speed_day(day_data):
"""Get wind speed (day) from weather data."""
val = get_forecast_day_value(day_data[AEMET_ATTR_WIND], key=AEMET_ATTR_SPEED)
if val:
return format_int(val)
return None
@dataclass
class AemetWeather:
"""Class to harmonize weather data model."""
daily: dict = field(default_factory=dict)
hourly: dict = field(default_factory=dict)
station: dict = field(default_factory=dict)

View File

@@ -1,6 +1,4 @@
"""Config flow to configure Agent devices."""
import logging
from agent import AgentConnectionError, AgentError
from agent.a import Agent
import voluptuous as vol
@@ -13,7 +11,6 @@ from .const import DOMAIN, SERVER_URL # pylint:disable=unused-import
from .helpers import generate_url
DEFAULT_PORT = 8090
_LOGGER = logging.getLogger(__name__)
class AgentFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):

View File

@@ -4,7 +4,8 @@
"already_configured": "\uae30\uae30\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"error": {
"already_in_progress": "\uae30\uae30 \uad6c\uc131\uc774 \uc774\ubbf8 \uc9c4\ud589 \uc911\uc785\ub2c8\ub2e4."
"already_in_progress": "\uae30\uae30 \uad6c\uc131\uc774 \uc774\ubbf8 \uc9c4\ud589 \uc911\uc785\ub2c8\ub2e4",
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {

View File

@@ -4,6 +4,7 @@
"already_configured": "Apparaat is al geconfigureerd"
},
"error": {
"already_in_progress": "De configuratiestroom is al aan de gang",
"cannot_connect": "Kan geen verbinding maken"
},
"step": {

View File

@@ -2,7 +2,10 @@
from datetime import timedelta
import logging
from homeassistant.const import CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
from homeassistant.const import (
ATTR_ATTRIBUTION,
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
)
from homeassistant.helpers.config_validation import ( # noqa: F401
PLATFORM_SCHEMA,
PLATFORM_SCHEMA_BASE,
@@ -13,7 +16,6 @@ from homeassistant.helpers.entity_component import EntityComponent
_LOGGER = logging.getLogger(__name__)
ATTR_AQI = "air_quality_index"
ATTR_ATTRIBUTION = "attribution"
ATTR_CO2 = "carbon_dioxide"
ATTR_CO = "carbon_monoxide"
ATTR_N2O = "nitrogen_oxide"

View File

@@ -1,4 +1,4 @@
"""The Airly component."""
"""The Airly integration."""
import asyncio
from datetime import timedelta
import logging

View File

@@ -19,14 +19,13 @@ from .const import (
ATTR_API_PM25,
ATTR_API_PM25_LIMIT,
ATTR_API_PM25_PERCENT,
ATTRIBUTION,
DEFAULT_NAME,
DOMAIN,
LABEL_ADVICE,
MANUFACTURER,
)
ATTRIBUTION = "Data provided by Airly"
LABEL_ADVICE = "advice"
LABEL_AQI_DESCRIPTION = f"{ATTR_AQI}_description"
LABEL_AQI_LEVEL = f"{ATTR_AQI}_level"
LABEL_PM_2_5_LIMIT = f"{ATTR_PM_2_5}_limit"

View File

@@ -1,4 +1,5 @@
"""Constants for Airly integration."""
ATTR_API_ADVICE = "ADVICE"
ATTR_API_CAQI = "CAQI"
ATTR_API_CAQI_DESCRIPTION = "DESCRIPTION"
@@ -13,9 +14,15 @@ ATTR_API_PM25_LIMIT = "PM25_LIMIT"
ATTR_API_PM25_PERCENT = "PM25_PERCENT"
ATTR_API_PRESSURE = "PRESSURE"
ATTR_API_TEMPERATURE = "TEMPERATURE"
ATTR_LABEL = "label"
ATTR_UNIT = "unit"
ATTRIBUTION = "Data provided by Airly"
CONF_USE_NEAREST = "use_nearest"
DEFAULT_NAME = "Airly"
DOMAIN = "airly"
LABEL_ADVICE = "advice"
MANUFACTURER = "Airly sp. z o.o."
MAX_REQUESTS_PER_DAY = 100
NO_AIRLY_SENSORS = "There are no Airly sensors in this area yet."

View File

@@ -2,6 +2,7 @@
from homeassistant.const import (
ATTR_ATTRIBUTION,
ATTR_DEVICE_CLASS,
ATTR_ICON,
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONF_NAME,
DEVICE_CLASS_HUMIDITY,
@@ -18,17 +19,14 @@ from .const import (
ATTR_API_PM1,
ATTR_API_PRESSURE,
ATTR_API_TEMPERATURE,
ATTR_LABEL,
ATTR_UNIT,
ATTRIBUTION,
DEFAULT_NAME,
DOMAIN,
MANUFACTURER,
)
ATTRIBUTION = "Data provided by Airly"
ATTR_ICON = "icon"
ATTR_LABEL = "label"
ATTR_UNIT = "unit"
PARALLEL_UPDATES = 1
SENSOR_TYPES = {

View File

@@ -1,9 +1,10 @@
{
"config": {
"abort": {
"already_configured": "\uc774 \uc88c\ud45c\uc5d0 \ub300\ud55c Airly \ud1b5\ud569 \uad6c\uc131\uc694\uc18c\ub294 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
"already_configured": "\uc704\uce58\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
},
"error": {
"invalid_api_key": "API \ud0a4\uac00 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4",
"wrong_location": "\uc774 \uc9c0\uc5ed\uc5d0\ub294 Airly \uce21\uc815 \uc2a4\ud14c\uc774\uc158\uc774 \uc5c6\uc2b5\ub2c8\ub2e4."
},
"step": {
@@ -12,7 +13,7 @@
"api_key": "API \ud0a4",
"latitude": "\uc704\ub3c4",
"longitude": "\uacbd\ub3c4",
"name": "\ud1b5\ud569 \uad6c\uc131\uc694\uc18c\uc758 \uc774\ub984"
"name": "\uc774\ub984"
},
"description": "Airly \uacf5\uae30 \ud488\uc9c8 \ud1b5\ud569 \uad6c\uc131\uc694\uc18c\ub97c \uc124\uc815\ud569\ub2c8\ub2e4. API \ud0a4\ub97c \uc0dd\uc131\ud558\ub824\uba74 https://developer.airly.eu/register \ub85c \uc774\ub3d9\ud574\uc8fc\uc138\uc694",
"title": "Airly"

View File

@@ -2,6 +2,7 @@
from homeassistant.const import (
ATTR_ATTRIBUTION,
ATTR_DEVICE_CLASS,
ATTR_ICON,
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_MILLION,
)
@@ -20,7 +21,6 @@ from .const import (
ATTRIBUTION = "Data provided by AirNow"
ATTR_ICON = "icon"
ATTR_LABEL = "label"
ATTR_UNIT = "unit"

View File

@@ -0,0 +1,21 @@
{
"config": {
"abort": {
"already_configured": "\uae30\uae30\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"error": {
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4",
"invalid_auth": "\uc778\uc99d\uc774 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4",
"unknown": "\uc608\uc0c1\uce58 \ubabb\ud55c \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {
"api_key": "API \ud0a4",
"latitude": "\uc704\ub3c4",
"longitude": "\uacbd\ub3c4"
}
}
}
}
}

View File

@@ -0,0 +1,24 @@
{
"config": {
"abort": {
"already_configured": "Apparaat is al geconfigureerd"
},
"error": {
"cannot_connect": "Kan geen verbinding maken",
"invalid_auth": "Ongeldige authenticatie",
"invalid_location": "Geen resultaten gevonden voor die locatie",
"unknown": "Onverwachte fout"
},
"step": {
"user": {
"data": {
"api_key": "API-sleutel",
"latitude": "Breedtegraad",
"longitude": "Lengtegraad"
},
"title": "AirNow"
}
}
},
"title": "AirNow"
}

View File

@@ -5,7 +5,7 @@
},
"error": {
"cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.",
"invalid_auth": "\u041d\u0435\u0432\u0435\u0440\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f.",
"invalid_auth": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.",
"invalid_location": "\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e.",
"unknown": "\u041d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430."
},

View File

@@ -23,6 +23,7 @@ from homeassistant.const import (
CONF_STATE,
)
from homeassistant.core import callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client, config_validation as cv
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
@@ -37,7 +38,7 @@ from .const import (
CONF_INTEGRATION_TYPE,
DATA_COORDINATOR,
DOMAIN,
INTEGRATION_TYPE_GEOGRAPHY,
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
INTEGRATION_TYPE_NODE_PRO,
LOGGER,
)
@@ -145,7 +146,7 @@ def _standardize_geography_config_entry(hass, config_entry):
# If the config entry data doesn't contain the integration type, add it:
entry_updates["data"] = {
**config_entry.data,
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY,
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY_COORDS,
}
if not entry_updates:
@@ -232,7 +233,6 @@ async def async_setup_entry(hass, config_entry):
update_method=async_update_data,
)
hass.data[DOMAIN][DATA_COORDINATOR][config_entry.entry_id] = coordinator
async_sync_geo_coordinator_update_intervals(
hass, config_entry.data[CONF_API_KEY]
)
@@ -262,9 +262,11 @@ async def async_setup_entry(hass, config_entry):
update_method=async_update_data,
)
hass.data[DOMAIN][DATA_COORDINATOR][config_entry.entry_id] = coordinator
await coordinator.async_refresh()
if not coordinator.last_update_success:
raise ConfigEntryNotReady
hass.data[DOMAIN][DATA_COORDINATOR][config_entry.entry_id] = coordinator
for component in PLATFORMS:
hass.async_create_task(
@@ -299,10 +301,14 @@ async def async_migrate_entry(hass, config_entry):
# For any geographies that remain, create a new config entry for each one:
for geography in geographies:
if CONF_LATITUDE in geography:
source = "geography_by_coords"
else:
source = "geography_by_name"
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": "geography"},
context={"source": source},
data={CONF_API_KEY: config_entry.data[CONF_API_KEY], **geography},
)
)
@@ -327,7 +333,10 @@ async def async_unload_entry(hass, config_entry):
remove_listener = hass.data[DOMAIN][DATA_LISTENER].pop(config_entry.entry_id)
remove_listener()
if config_entry.data[CONF_INTEGRATION_TYPE] == INTEGRATION_TYPE_GEOGRAPHY:
if (
config_entry.data[CONF_INTEGRATION_TYPE]
== INTEGRATION_TYPE_GEOGRAPHY_COORDS
):
# Re-calculate the update interval period for any remaining consumers of
# this API key:
async_sync_geo_coordinator_update_intervals(

View File

@@ -2,7 +2,12 @@
import asyncio
from pyairvisual import CloudAPI, NodeSamba
from pyairvisual.errors import InvalidKeyError, NodeProError
from pyairvisual.errors import (
AirVisualError,
InvalidKeyError,
NodeProError,
NotFoundError,
)
import voluptuous as vol
from homeassistant import config_entries
@@ -13,20 +18,46 @@ from homeassistant.const import (
CONF_LONGITUDE,
CONF_PASSWORD,
CONF_SHOW_ON_MAP,
CONF_STATE,
)
from homeassistant.core import callback
from homeassistant.helpers import aiohttp_client, config_validation as cv
from . import async_get_geography_id
from .const import ( # pylint: disable=unused-import
CONF_GEOGRAPHIES,
CONF_CITY,
CONF_COUNTRY,
CONF_INTEGRATION_TYPE,
DOMAIN,
INTEGRATION_TYPE_GEOGRAPHY,
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
INTEGRATION_TYPE_GEOGRAPHY_NAME,
INTEGRATION_TYPE_NODE_PRO,
LOGGER,
)
API_KEY_DATA_SCHEMA = vol.Schema({vol.Required(CONF_API_KEY): cv.string})
GEOGRAPHY_NAME_SCHEMA = API_KEY_DATA_SCHEMA.extend(
{
vol.Required(CONF_CITY): cv.string,
vol.Required(CONF_STATE): cv.string,
vol.Required(CONF_COUNTRY): cv.string,
}
)
NODE_PRO_SCHEMA = vol.Schema(
{vol.Required(CONF_IP_ADDRESS): str, vol.Required(CONF_PASSWORD): cv.string}
)
PICK_INTEGRATION_TYPE_SCHEMA = vol.Schema(
{
vol.Required("type"): vol.In(
[
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
INTEGRATION_TYPE_GEOGRAPHY_NAME,
INTEGRATION_TYPE_NODE_PRO,
]
)
}
)
class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle an AirVisual config flow."""
@@ -36,16 +67,13 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
def __init__(self):
"""Initialize the config flow."""
self._entry_data_for_reauth = None
self._geo_id = None
self._latitude = None
self._longitude = None
self.api_key_data_schema = vol.Schema({vol.Required(CONF_API_KEY): str})
@property
def geography_schema(self):
def geography_coords_schema(self):
"""Return the data schema for the cloud API."""
return self.api_key_data_schema.extend(
return API_KEY_DATA_SCHEMA.extend(
{
vol.Required(
CONF_LATITUDE, default=self.hass.config.latitude
@@ -56,24 +84,72 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
}
)
@property
def pick_integration_type_schema(self):
"""Return the data schema for picking the integration type."""
return vol.Schema(
{
vol.Required("type"): vol.In(
[INTEGRATION_TYPE_GEOGRAPHY, INTEGRATION_TYPE_NODE_PRO]
)
}
async def _async_finish_geography(self, user_input, integration_type):
"""Validate a Cloud API key."""
websession = aiohttp_client.async_get_clientsession(self.hass)
cloud_api = CloudAPI(user_input[CONF_API_KEY], session=websession)
# If this is the first (and only the first) time we've seen this API key, check
# that it's valid:
valid_keys = self.hass.data.setdefault("airvisual_checked_api_keys", set())
valid_keys_lock = self.hass.data.setdefault(
"airvisual_checked_api_keys_lock", asyncio.Lock()
)
@property
def node_pro_schema(self):
"""Return the data schema for a Node/Pro."""
return vol.Schema(
{vol.Required(CONF_IP_ADDRESS): str, vol.Required(CONF_PASSWORD): str}
if integration_type == INTEGRATION_TYPE_GEOGRAPHY_COORDS:
coro = cloud_api.air_quality.nearest_city()
error_schema = self.geography_coords_schema
error_step = "geography_by_coords"
else:
coro = cloud_api.air_quality.city(
user_input[CONF_CITY], user_input[CONF_STATE], user_input[CONF_COUNTRY]
)
error_schema = GEOGRAPHY_NAME_SCHEMA
error_step = "geography_by_name"
async with valid_keys_lock:
if user_input[CONF_API_KEY] not in valid_keys:
try:
await coro
except InvalidKeyError:
return self.async_show_form(
step_id=error_step,
data_schema=error_schema,
errors={CONF_API_KEY: "invalid_api_key"},
)
except NotFoundError:
return self.async_show_form(
step_id=error_step,
data_schema=error_schema,
errors={CONF_CITY: "location_not_found"},
)
except AirVisualError as err:
LOGGER.error(err)
return self.async_show_form(
step_id=error_step,
data_schema=error_schema,
errors={"base": "unknown"},
)
valid_keys.add(user_input[CONF_API_KEY])
existing_entry = await self.async_set_unique_id(self._geo_id)
if existing_entry:
self.hass.config_entries.async_update_entry(existing_entry, data=user_input)
return self.async_abort(reason="reauth_successful")
return self.async_create_entry(
title=f"Cloud API ({self._geo_id})",
data={**user_input, CONF_INTEGRATION_TYPE: integration_type},
)
async def _async_init_geography(self, user_input, integration_type):
"""Handle the initialization of the integration via the cloud API."""
self._geo_id = async_get_geography_id(user_input)
await self._async_set_unique_id(self._geo_id)
self._abort_if_unique_id_configured()
return await self._async_finish_geography(user_input, integration_type)
async def _async_set_unique_id(self, unique_id):
"""Set the unique ID of the config flow and abort if it already exists."""
await self.async_set_unique_id(unique_id)
@@ -85,73 +161,32 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Define the config flow to handle options."""
return AirVisualOptionsFlowHandler(config_entry)
async def async_step_geography(self, user_input=None):
"""Handle the initialization of the integration via the cloud API."""
async def async_step_geography_by_coords(self, user_input=None):
"""Handle the initialization of the cloud API based on latitude/longitude."""
if not user_input:
return self.async_show_form(
step_id="geography", data_schema=self.geography_schema
step_id="geography_by_coords", data_schema=self.geography_coords_schema
)
self._geo_id = async_get_geography_id(user_input)
await self._async_set_unique_id(self._geo_id)
self._abort_if_unique_id_configured()
# Find older config entries without unique ID:
for entry in self._async_current_entries():
if entry.version != 1:
continue
if any(
self._geo_id == async_get_geography_id(geography)
for geography in entry.data[CONF_GEOGRAPHIES]
):
return self.async_abort(reason="already_configured")
return await self.async_step_geography_finish(
user_input, "geography", self.geography_schema
return await self._async_init_geography(
user_input, INTEGRATION_TYPE_GEOGRAPHY_COORDS
)
async def async_step_geography_finish(self, user_input, error_step, error_schema):
"""Validate a Cloud API key."""
websession = aiohttp_client.async_get_clientsession(self.hass)
cloud_api = CloudAPI(user_input[CONF_API_KEY], session=websession)
async def async_step_geography_by_name(self, user_input=None):
"""Handle the initialization of the cloud API based on city/state/country."""
if not user_input:
return self.async_show_form(
step_id="geography_by_name", data_schema=GEOGRAPHY_NAME_SCHEMA
)
# If this is the first (and only the first) time we've seen this API key, check
# that it's valid:
valid_keys = self.hass.data.setdefault("airvisual_checked_api_keys", set())
valid_keys_lock = self.hass.data.setdefault(
"airvisual_checked_api_keys_lock", asyncio.Lock()
)
async with valid_keys_lock:
if user_input[CONF_API_KEY] not in valid_keys:
try:
await cloud_api.air_quality.nearest_city()
except InvalidKeyError:
return self.async_show_form(
step_id=error_step,
data_schema=error_schema,
errors={CONF_API_KEY: "invalid_api_key"},
)
valid_keys.add(user_input[CONF_API_KEY])
existing_entry = await self.async_set_unique_id(self._geo_id)
if existing_entry:
self.hass.config_entries.async_update_entry(existing_entry, data=user_input)
return self.async_abort(reason="reauth_successful")
return self.async_create_entry(
title=f"Cloud API ({self._geo_id})",
data={**user_input, CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY},
return await self._async_init_geography(
user_input, INTEGRATION_TYPE_GEOGRAPHY_NAME
)
async def async_step_node_pro(self, user_input=None):
"""Handle the initialization of the integration with a Node/Pro."""
if not user_input:
return self.async_show_form(
step_id="node_pro", data_schema=self.node_pro_schema
)
return self.async_show_form(step_id="node_pro", data_schema=NODE_PRO_SCHEMA)
await self._async_set_unique_id(user_input[CONF_IP_ADDRESS])
@@ -163,7 +198,7 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
LOGGER.error("Error connecting to Node/Pro unit: %s", err)
return self.async_show_form(
step_id="node_pro",
data_schema=self.node_pro_schema,
data_schema=NODE_PRO_SCHEMA,
errors={CONF_IP_ADDRESS: "cannot_connect"},
)
@@ -176,39 +211,34 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
async def async_step_reauth(self, data):
"""Handle configuration by re-auth."""
self._entry_data_for_reauth = data
self._geo_id = async_get_geography_id(data)
self._latitude = data[CONF_LATITUDE]
self._longitude = data[CONF_LONGITUDE]
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(self, user_input=None):
"""Handle re-auth completion."""
if not user_input:
return self.async_show_form(
step_id="reauth_confirm", data_schema=self.api_key_data_schema
step_id="reauth_confirm", data_schema=API_KEY_DATA_SCHEMA
)
conf = {
CONF_API_KEY: user_input[CONF_API_KEY],
CONF_LATITUDE: self._latitude,
CONF_LONGITUDE: self._longitude,
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY,
}
conf = {CONF_API_KEY: user_input[CONF_API_KEY], **self._entry_data_for_reauth}
return await self.async_step_geography_finish(
conf, "reauth_confirm", self.api_key_data_schema
return await self._async_finish_geography(
conf, self._entry_data_for_reauth[CONF_INTEGRATION_TYPE]
)
async def async_step_user(self, user_input=None):
"""Handle the start of the config flow."""
if not user_input:
return self.async_show_form(
step_id="user", data_schema=self.pick_integration_type_schema
step_id="user", data_schema=PICK_INTEGRATION_TYPE_SCHEMA
)
if user_input["type"] == INTEGRATION_TYPE_GEOGRAPHY:
return await self.async_step_geography()
if user_input["type"] == INTEGRATION_TYPE_GEOGRAPHY_COORDS:
return await self.async_step_geography_by_coords()
if user_input["type"] == INTEGRATION_TYPE_GEOGRAPHY_NAME:
return await self.async_step_geography_by_name()
return await self.async_step_node_pro()

View File

@@ -4,7 +4,8 @@ import logging
DOMAIN = "airvisual"
LOGGER = logging.getLogger(__package__)
INTEGRATION_TYPE_GEOGRAPHY = "Geographical Location"
INTEGRATION_TYPE_GEOGRAPHY_COORDS = "Geographical Location by Latitude/Longitude"
INTEGRATION_TYPE_GEOGRAPHY_NAME = "Geographical Location by Name"
INTEGRATION_TYPE_NODE_PRO = "AirVisual Node/Pro"
CONF_CITY = "city"

View File

@@ -1,6 +1,4 @@
"""Support for AirVisual air quality sensors."""
from logging import getLogger
from homeassistant.const import (
ATTR_LATITUDE,
ATTR_LONGITUDE,
@@ -27,11 +25,10 @@ from .const import (
CONF_INTEGRATION_TYPE,
DATA_COORDINATOR,
DOMAIN,
INTEGRATION_TYPE_GEOGRAPHY,
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
INTEGRATION_TYPE_GEOGRAPHY_NAME,
)
_LOGGER = getLogger(__name__)
ATTR_CITY = "city"
ATTR_COUNTRY = "country"
ATTR_POLLUTANT_SYMBOL = "pollutant_symbol"
@@ -58,14 +55,23 @@ NODE_PRO_SENSORS = [
(SENSOR_KIND_TEMPERATURE, "Temperature", DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS),
]
POLLUTANT_MAPPING = {
"co": {"label": "Carbon Monoxide", "unit": CONCENTRATION_PARTS_PER_MILLION},
"n2": {"label": "Nitrogen Dioxide", "unit": CONCENTRATION_PARTS_PER_BILLION},
"o3": {"label": "Ozone", "unit": CONCENTRATION_PARTS_PER_BILLION},
"p1": {"label": "PM10", "unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
"p2": {"label": "PM2.5", "unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
"s2": {"label": "Sulfur Dioxide", "unit": CONCENTRATION_PARTS_PER_BILLION},
}
@callback
def async_get_pollutant_label(symbol):
"""Get a pollutant's label based on its symbol."""
if symbol == "co":
return "Carbon Monoxide"
if symbol == "n2":
return "Nitrogen Dioxide"
if symbol == "o3":
return "Ozone"
if symbol == "p1":
return "PM10"
if symbol == "p2":
return "PM2.5"
if symbol == "s2":
return "Sulfur Dioxide"
return symbol
@callback
@@ -84,11 +90,32 @@ def async_get_pollutant_level_info(value):
return ("Hazardous", "mdi:biohazard")
@callback
def async_get_pollutant_unit(symbol):
"""Get a pollutant's unit based on its symbol."""
if symbol == "co":
return CONCENTRATION_PARTS_PER_MILLION
if symbol == "n2":
return CONCENTRATION_PARTS_PER_BILLION
if symbol == "o3":
return CONCENTRATION_PARTS_PER_BILLION
if symbol == "p1":
return CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
if symbol == "p2":
return CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
if symbol == "s2":
return CONCENTRATION_PARTS_PER_BILLION
return None
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up AirVisual sensors based on a config entry."""
coordinator = hass.data[DOMAIN][DATA_COORDINATOR][config_entry.entry_id]
if config_entry.data[CONF_INTEGRATION_TYPE] == INTEGRATION_TYPE_GEOGRAPHY:
if config_entry.data[CONF_INTEGRATION_TYPE] in [
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
INTEGRATION_TYPE_GEOGRAPHY_NAME,
]:
sensors = [
AirVisualGeographySensor(
coordinator,
@@ -173,25 +200,40 @@ class AirVisualGeographySensor(AirVisualEntity):
self._state = data[f"aqi{self._locale}"]
elif self._kind == SENSOR_KIND_POLLUTANT:
symbol = data[f"main{self._locale}"]
self._state = POLLUTANT_MAPPING[symbol]["label"]
self._state = async_get_pollutant_label(symbol)
self._attrs.update(
{
ATTR_POLLUTANT_SYMBOL: symbol,
ATTR_POLLUTANT_UNIT: POLLUTANT_MAPPING[symbol]["unit"],
ATTR_POLLUTANT_UNIT: async_get_pollutant_unit(symbol),
}
)
if CONF_LATITUDE in self._config_entry.data:
if self._config_entry.options[CONF_SHOW_ON_MAP]:
self._attrs[ATTR_LATITUDE] = self._config_entry.data[CONF_LATITUDE]
self._attrs[ATTR_LONGITUDE] = self._config_entry.data[CONF_LONGITUDE]
self._attrs.pop("lati", None)
self._attrs.pop("long", None)
else:
self._attrs["lati"] = self._config_entry.data[CONF_LATITUDE]
self._attrs["long"] = self._config_entry.data[CONF_LONGITUDE]
self._attrs.pop(ATTR_LATITUDE, None)
self._attrs.pop(ATTR_LONGITUDE, None)
# Displaying the geography on the map relies upon putting the latitude/longitude
# in the entity attributes with "latitude" and "longitude" as the keys.
# Conversely, we can hide the location on the map by using other keys, like
# "lati" and "long".
#
# We use any coordinates in the config entry and, in the case of a geography by
# name, we fall back to the latitude longitude provided in the coordinator data:
latitude = self._config_entry.data.get(
CONF_LATITUDE,
self.coordinator.data["location"]["coordinates"][1],
)
longitude = self._config_entry.data.get(
CONF_LONGITUDE,
self.coordinator.data["location"]["coordinates"][0],
)
if self._config_entry.options[CONF_SHOW_ON_MAP]:
self._attrs[ATTR_LATITUDE] = latitude
self._attrs[ATTR_LONGITUDE] = longitude
self._attrs.pop("lati", None)
self._attrs.pop("long", None)
else:
self._attrs["lati"] = latitude
self._attrs["long"] = longitude
self._attrs.pop(ATTR_LATITUDE, None)
self._attrs.pop(ATTR_LONGITUDE, None)
class AirVisualNodeProSensor(AirVisualEntity):

View File

@@ -1,15 +1,25 @@
{
"config": {
"step": {
"geography": {
"geography_by_coords": {
"title": "Configure a Geography",
"description": "Use the AirVisual cloud API to monitor a geographical location.",
"description": "Use the AirVisual cloud API to monitor a latitude/longitude.",
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]"
}
},
"geography_by_name": {
"title": "Configure a Geography",
"description": "Use the AirVisual cloud API to monitor a city/state/country.",
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"city": "City",
"country": "Country",
"state": "state"
}
},
"node_pro": {
"title": "Configure an AirVisual Node/Pro",
"description": "Monitor a personal AirVisual unit. The password can be retrieved from the unit's UI.",
@@ -26,17 +36,13 @@
},
"user": {
"title": "Configure AirVisual",
"description": "Pick what type of AirVisual data you want to monitor.",
"data": {
"cloud_api": "Geographical Location",
"node_pro": "AirVisual Node Pro",
"type": "Integration Type"
}
"description": "Pick what type of AirVisual data you want to monitor."
}
},
"error": {
"general_error": "[%key:common::config_flow::error::unknown%]",
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]",
"location_not_found": "Location not found",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"abort": {

View File

@@ -17,6 +17,20 @@
"longitude": "Zem\u011bpisn\u00e1 d\u00e9lka"
}
},
"geography_by_coords": {
"data": {
"api_key": "Kl\u00ed\u010d API",
"latitude": "Zem\u011bpisn\u00e1 \u0161\u00ed\u0159ka",
"longitude": "Zem\u011bpisn\u00e1 d\u00e9lka"
}
},
"geography_by_name": {
"data": {
"api_key": "Kl\u00ed\u010d API",
"city": "M\u011bsto",
"country": "Zem\u011b"
}
},
"node_pro": {
"data": {
"ip_address": "Hostitel",

View File

@@ -7,7 +7,8 @@
"error": {
"cannot_connect": "Verbindung fehlgeschlagen",
"general_error": "Unerwarteter Fehler",
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel"
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel",
"location_not_found": "Standort nicht gefunden"
},
"step": {
"geography": {
@@ -16,8 +17,28 @@
"latitude": "Breitengrad",
"longitude": "L\u00e4ngengrad"
},
"description": "Verwende die AirVisual Cloud API, um einen geografischen Standort zu \u00fcberwachen.",
"title": "Konfigurieren Sie eine Geografie"
},
"geography_by_coords": {
"data": {
"api_key": "API-Schl\u00fcssel",
"latitude": "Breitengrad",
"longitude": "L\u00e4ngengrad"
},
"description": "Verwende die AirVisual Cloud API, um einen L\u00e4ngengrad/Breitengrad zu \u00fcberwachen.",
"title": "Konfiguriere einen Standort"
},
"geography_by_name": {
"data": {
"api_key": "API-Schl\u00fcssel",
"city": "Stadt",
"country": "Land",
"state": "Bundesland"
},
"description": "Verwende die AirVisual Cloud API, um ein(e) Stadt/Bundesland/Land zu \u00fcberwachen.",
"title": "Konfiguriere einen Standort"
},
"node_pro": {
"data": {
"ip_address": "Host",
@@ -29,7 +50,8 @@
"reauth_confirm": {
"data": {
"api_key": "API-Key"
}
},
"title": "AirVisual erneut authentifizieren"
},
"user": {
"data": {

View File

@@ -7,7 +7,8 @@
"error": {
"cannot_connect": "Failed to connect",
"general_error": "Unexpected error",
"invalid_api_key": "Invalid API key"
"invalid_api_key": "Invalid API key",
"location_not_found": "Location not found"
},
"step": {
"geography": {
@@ -25,7 +26,17 @@
"latitude": "Latitude",
"longitude": "Longitude"
},
"description": "Use the AirVisual cloud API to monitor a geographical location.",
"description": "Use the AirVisual cloud API to monitor a latitude/longitude.",
"title": "Configure a Geography"
},
"geography_by_name": {
"data": {
"api_key": "API Key",
"city": "City",
"country": "Country",
"state": "state"
},
"description": "Use the AirVisual cloud API to monitor a city/state/country.",
"title": "Configure a Geography"
},
"node_pro": {
@@ -63,4 +74,4 @@
}
}
}
}
}

View File

@@ -7,7 +7,8 @@
"error": {
"cannot_connect": "No se pudo conectar",
"general_error": "Se ha producido un error desconocido.",
"invalid_api_key": "Se proporciona una clave API no v\u00e1lida."
"invalid_api_key": "Se proporciona una clave API no v\u00e1lida.",
"location_not_found": "Ubicaci\u00f3n no encontrada"
},
"step": {
"geography": {
@@ -19,6 +20,25 @@
"description": "Utilizar la API en la nube de AirVisual para monitorizar una ubicaci\u00f3n geogr\u00e1fica.",
"title": "Configurar una Geograf\u00eda"
},
"geography_by_coords": {
"data": {
"api_key": "Clave API",
"latitude": "Latitud",
"longitude": "Longitud"
},
"description": "Utilice la API de la nube de AirVisual para supervisar una latitud/longitud.",
"title": "Configurar una geograf\u00eda"
},
"geography_by_name": {
"data": {
"api_key": "Clave API",
"city": "Ciudad",
"country": "Pa\u00eds",
"state": "estado"
},
"description": "Utilice la API de la nube de AirVisual para supervisar una ciudad/estado/pa\u00eds.",
"title": "Configurar una geograf\u00eda"
},
"node_pro": {
"data": {
"ip_address": "Direcci\u00f3n IP/Nombre de host de la Unidad",

View File

@@ -17,7 +17,7 @@
"latitude": "Laiuskraad",
"longitude": "Pikkuskraad"
},
"description": "Kasutage AirVisual pilve API-t geograafilise asukoha j\u00e4lgimiseks.",
"description": "Kasuta AirVisual pilve API-t geograafilise asukoha j\u00e4lgimiseks.",
"title": "Seadista Geography"
},
"geography_by_coords": {

View File

@@ -7,7 +7,8 @@
"error": {
"cannot_connect": "\u00c9chec de connexion",
"general_error": "Erreur inattendue",
"invalid_api_key": "Cl\u00e9 API invalide"
"invalid_api_key": "Cl\u00e9 API invalide",
"location_not_found": "Emplacement introuvable"
},
"step": {
"geography": {
@@ -19,6 +20,25 @@
"description": "Utilisez l'API cloud AirVisual pour surveiller une position g\u00e9ographique.",
"title": "Configurer une g\u00e9ographie"
},
"geography_by_coords": {
"data": {
"api_key": "Clef d'API",
"latitude": "Latitude",
"longitude": "Longitude"
},
"description": "Utilisez l'API cloud AirVisual pour surveiller une latitude / longitude.",
"title": "Configurer un lieu g\u00e9ographique"
},
"geography_by_name": {
"data": {
"api_key": "Clef d'API",
"city": "Ville",
"country": "Pays",
"state": "Etat"
},
"description": "Utilisez l'API cloud AirVisual pour surveiller une ville / un \u00e9tat / un pays.",
"title": "Configurer un lieu g\u00e9ographique"
},
"node_pro": {
"data": {
"ip_address": "H\u00f4te",

View File

@@ -2,12 +2,13 @@
"config": {
"abort": {
"already_configured": "La posizione \u00e8 gi\u00e0 configurata o Node/Pro ID sono gi\u00e0 registrati.",
"reauth_successful": "La riautenticazione ha avuto successo"
"reauth_successful": "La nuova autenticazione \u00e8 stata eseguita correttamente"
},
"error": {
"cannot_connect": "Impossibile connettersi",
"general_error": "Errore imprevisto",
"invalid_api_key": "Chiave API non valida"
"invalid_api_key": "Chiave API non valida",
"location_not_found": "Posizione non trovata"
},
"step": {
"geography": {
@@ -19,6 +20,25 @@
"description": "Utilizzare l'API di AirVisual cloud per monitorare una posizione geografica.",
"title": "Configurare una Geografia"
},
"geography_by_coords": {
"data": {
"api_key": "Chiave API",
"latitude": "Latitudine",
"longitude": "Logitudine"
},
"description": "Usa l'API cloud di AirVisual per monitorare una latitudine/longitudine.",
"title": "Configurare un'area geografica"
},
"geography_by_name": {
"data": {
"api_key": "Chiave API",
"city": "Citt\u00e0",
"country": "Nazione",
"state": "Stato"
},
"description": "Usa l'API cloud di AirVisual per monitorare una citt\u00e0/stato/paese.",
"title": "Configurare un'area geografica"
},
"node_pro": {
"data": {
"ip_address": "Host",

View File

@@ -1,11 +1,13 @@
{
"config": {
"abort": {
"already_configured": "\uc88c\ud45c\uac12 \ub610\ub294 Node/Pro ID \uac00 \uc774\ubbf8 \ub4f1\ub85d\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
"already_configured": "Node/Pro ID \uac00 \uc774\ubbf8 \ub4f1\ub85d\ub418\uc5c8\uac70\ub098 \uc704\uce58\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4.",
"reauth_successful": "\uc7ac\uc778\uc99d\uc5d0 \uc131\uacf5\ud588\uc2b5\ub2c8\ub2e4"
},
"error": {
"general_error": "\uc54c \uc218 \uc5c6\ub294 \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4.",
"invalid_api_key": "API \ud0a4\uac00 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4",
"general_error": "\uc608\uc0c1\uce58 \ubabb\ud55c \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4",
"invalid_api_key": "API \ud0a4\uac00 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"step": {
"geography": {
@@ -17,14 +19,31 @@
"description": "AirVisual \ud074\ub77c\uc6b0\ub4dc API \ub97c \uc0ac\uc6a9\ud558\uc5ec \uc9c0\ub9ac\uc801 \uc704\uce58\ub97c \ubaa8\ub2c8\ud130\ub9c1\ud569\ub2c8\ub2e4.",
"title": "\uc9c0\ub9ac\uc801 \uc704\uce58 \uad6c\uc131\ud558\uae30"
},
"geography_by_coords": {
"data": {
"api_key": "API \ud0a4",
"latitude": "\uc704\ub3c4",
"longitude": "\uacbd\ub3c4"
}
},
"geography_by_name": {
"data": {
"api_key": "API \ud0a4"
}
},
"node_pro": {
"data": {
"ip_address": "\uae30\uae30 IP \uc8fc\uc18c/\ud638\uc2a4\ud2b8 \uc774\ub984",
"ip_address": "\ud638\uc2a4\ud2b8",
"password": "\ube44\ubc00\ubc88\ud638"
},
"description": "\uc0ac\uc6a9\uc790\uc758 AirVisual \uae30\uae30\ub97c \ubaa8\ub2c8\ud130\ub9c1\ud569\ub2c8\ub2e4. \uae30\uae30\uc758 UI \uc5d0\uc11c \ube44\ubc00\ubc88\ud638\ub97c \ucc3e\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",
"title": "AirVisual Node/Pro \uad6c\uc131\ud558\uae30"
},
"reauth_confirm": {
"data": {
"api_key": "API \ud0a4"
}
},
"user": {
"data": {
"cloud_api": "\uc9c0\ub9ac\uc801 \uc704\uce58",

View File

@@ -1,12 +1,14 @@
{
"config": {
"abort": {
"already_configured": "Deze co\u00f6rdinaten of Node / Pro ID zijn al geregistreerd."
"already_configured": "Deze co\u00f6rdinaten of Node / Pro ID zijn al geregistreerd.",
"reauth_successful": "Herauthenticatie was succesvol"
},
"error": {
"cannot_connect": "Kan geen verbinding maken",
"general_error": "Er is een onbekende fout opgetreden.",
"invalid_api_key": "Ongeldige API-sleutel"
"invalid_api_key": "Ongeldige API-sleutel",
"location_not_found": "Locatie niet gevonden"
},
"step": {
"geography": {
@@ -18,6 +20,21 @@
"description": "Gebruik de AirVisual cloud API om een geografische locatie te bewaken.",
"title": "Configureer een geografie"
},
"geography_by_coords": {
"data": {
"api_key": "API-sleutel",
"latitude": "Breedtegraad",
"longitude": "Lengtegraad"
}
},
"geography_by_name": {
"data": {
"api_key": "API-sleutel",
"city": "Stad",
"country": "Land"
},
"description": "Gebruik de AirVisual-cloud-API om een stad/staat/land te bewaken."
},
"node_pro": {
"data": {
"ip_address": "IP adres/hostname van component",

View File

@@ -7,7 +7,8 @@
"error": {
"cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.",
"general_error": "\u041d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430.",
"invalid_api_key": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 API."
"invalid_api_key": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 API.",
"location_not_found": "\u041c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e."
},
"step": {
"geography": {
@@ -19,6 +20,25 @@
"description": "\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0433\u043e API AirVisual.",
"title": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f"
},
"geography_by_coords": {
"data": {
"api_key": "\u041a\u043b\u044e\u0447 API",
"latitude": "\u0428\u0438\u0440\u043e\u0442\u0430",
"longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430"
},
"description": "\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0439 API AirVisual \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0448\u0438\u0440\u043e\u0442\u044b/\u0434\u043e\u043b\u0433\u043e\u0442\u044b.",
"title": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f"
},
"geography_by_name": {
"data": {
"api_key": "\u041a\u043b\u044e\u0447 API",
"city": "\u0413\u043e\u0440\u043e\u0434",
"country": "\u0421\u0442\u0440\u0430\u043d\u0430",
"state": "\u0448\u0442\u0430\u0442"
},
"description": "\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0439 API AirVisual \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0433\u043e\u0440\u043e\u0434\u0430/\u0448\u0442\u0430\u0442\u0430/\u0441\u0442\u0440\u0430\u043d\u044b.",
"title": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f"
},
"node_pro": {
"data": {
"ip_address": "\u0425\u043e\u0441\u0442",

View File

@@ -21,7 +21,8 @@
"data": {
"cloud_api": "Geografisk Plats",
"type": "Integrationstyp"
}
},
"title": "Konfigurera AirVisual"
}
}
}

View File

@@ -132,14 +132,12 @@ async def async_attach_trigger(
) -> CALLBACK_TYPE:
"""Attach a trigger."""
config = TRIGGER_SCHEMA(config)
from_state = None
if config[CONF_TYPE] == "triggered":
to_state = STATE_ALARM_TRIGGERED
elif config[CONF_TYPE] == "disarmed":
to_state = STATE_ALARM_DISARMED
elif config[CONF_TYPE] == "arming":
from_state = STATE_ALARM_DISARMED
to_state = STATE_ALARM_ARMING
elif config[CONF_TYPE] == "armed_home":
to_state = STATE_ALARM_ARMED_HOME
@@ -153,8 +151,6 @@ async def async_attach_trigger(
CONF_ENTITY_ID: config[CONF_ENTITY_ID],
state_trigger.CONF_TO: to_state,
}
if from_state:
state_config[state_trigger.CONF_FROM] = from_state
state_config = state_trigger.TRIGGER_SCHEMA(state_config)
return await state_trigger.async_attach_trigger(
hass, state_config, action, automation_info, platform_type="device"

View File

@@ -1,61 +1,74 @@
# Describes the format for available alarm control panel services
alarm_disarm:
name: Disarm
description: Send the alarm the command for disarm.
target:
fields:
entity_id:
description: Name of alarm control panel to disarm.
example: "alarm_control_panel.downstairs"
code:
name: Code
description: An optional code to disarm the alarm control panel with.
example: "1234"
selector:
text:
alarm_arm_custom_bypass:
name: Arm with custom bypass
description: Send arm custom bypass command.
target:
fields:
entity_id:
description: Name of alarm control panel to arm custom bypass.
example: "alarm_control_panel.downstairs"
code:
description: An optional code to arm custom bypass the alarm control panel with.
name: Code
description:
An optional code to arm custom bypass the alarm control panel with.
example: "1234"
selector:
text:
alarm_arm_home:
name: Arm home
description: Send the alarm the command for arm home.
target:
fields:
entity_id:
description: Name of alarm control panel to arm home.
example: "alarm_control_panel.downstairs"
code:
name: Code
description: An optional code to arm home the alarm control panel with.
example: "1234"
selector:
text:
alarm_arm_away:
name: Arm away
description: Send the alarm the command for arm away.
target:
fields:
entity_id:
description: Name of alarm control panel to arm away.
example: "alarm_control_panel.downstairs"
code:
name: Code
description: An optional code to arm away the alarm control panel with.
example: "1234"
selector:
text:
alarm_arm_night:
name: Arm night
description: Send the alarm the command for arm night.
target:
fields:
entity_id:
description: Name of alarm control panel to arm night.
example: "alarm_control_panel.downstairs"
code:
name: Code
description: An optional code to arm night the alarm control panel with.
example: "1234"
selector:
text:
alarm_trigger:
name: Trigger
description: Send the alarm the command for trigger.
target:
fields:
entity_id:
description: Name of alarm control panel to trigger.
example: "alarm_control_panel.downstairs"
code:
name: Code
description: An optional code to trigger the alarm control panel with.
example: "1234"
selector:
text:

View File

@@ -1,11 +1,14 @@
{
"config": {
"abort": {
"already_configured": "\uc7a5\uce58\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4."
"already_configured": "\uae30\uae30\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"create_entry": {
"default": "AlarmDecoder\uc5d0 \uc131\uacf5\uc801\uc73c\ub85c \uc5f0\uacb0\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
},
"error": {
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4"
},
"step": {
"protocol": {
"data": {

View File

@@ -14,6 +14,7 @@ from homeassistant.const import (
ATTR_ENTITY_ID,
CONF_ENTITY_ID,
CONF_NAME,
CONF_REPEAT,
CONF_STATE,
SERVICE_TOGGLE,
SERVICE_TURN_OFF,
@@ -33,7 +34,6 @@ DOMAIN = "alert"
CONF_CAN_ACK = "can_acknowledge"
CONF_NOTIFIERS = "notifiers"
CONF_REPEAT = "repeat"
CONF_SKIP_FIRST = "skip_first"
CONF_ALERT_MESSAGE = "message"
CONF_DONE_MESSAGE = "done_message"

View File

@@ -1,18 +1,14 @@
toggle:
name: Toggle
description: Toggle alert's notifications.
fields:
entity_id:
description: Name of the alert to toggle.
example: alert.garage_door_open
target:
turn_off:
name: Turn off
description: Silence alert's notifications.
fields:
entity_id:
description: Name of the alert to silence.
example: alert.garage_door_open
target:
turn_on:
name: Turn on
description: Reset alert's notifications.
fields:
entity_id:
description: Name of the alert to reset.
example: alert.garage_door_open
target:

View File

@@ -1,7 +1,12 @@
"""Support for Alexa skill service end point."""
import voluptuous as vol
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_NAME
from homeassistant.const import (
CONF_CLIENT_ID,
CONF_CLIENT_SECRET,
CONF_NAME,
CONF_PASSWORD,
)
from homeassistant.helpers import config_validation as cv, entityfilter
from . import flash_briefings, intent, smart_home_http
@@ -14,7 +19,6 @@ from .const import (
CONF_ENTITY_CONFIG,
CONF_FILTER,
CONF_LOCALE,
CONF_PASSWORD,
CONF_SUPPORTED_LOCALES,
CONF_TEXT,
CONF_TITLE,

View File

@@ -46,7 +46,6 @@ from .const import (
API_THERMOSTAT_MODES,
API_THERMOSTAT_PRESETS,
DATE_FORMAT,
PERCENTAGE_FAN_MAP,
Inputs,
)
from .errors import UnsupportedProperty
@@ -668,9 +667,7 @@ class AlexaPercentageController(AlexaCapability):
raise UnsupportedProperty(name)
if self.entity.domain == fan.DOMAIN:
speed = self.entity.attributes.get(fan.ATTR_SPEED)
return PERCENTAGE_FAN_MAP.get(speed, 0)
return self.entity.attributes.get(fan.ATTR_PERCENTAGE) or 0
if self.entity.domain == cover.DOMAIN:
return self.entity.attributes.get(cover.ATTR_CURRENT_POSITION, 0)
@@ -1155,9 +1152,7 @@ class AlexaPowerLevelController(AlexaCapability):
raise UnsupportedProperty(name)
if self.entity.domain == fan.DOMAIN:
speed = self.entity.attributes.get(fan.ATTR_SPEED)
return PERCENTAGE_FAN_MAP.get(speed)
return self.entity.attributes.get(fan.ATTR_PERCENTAGE) or 0
return None

View File

@@ -1,7 +1,6 @@
"""Constants for the Alexa integration."""
from collections import OrderedDict
from homeassistant.components import fan
from homeassistant.components.climate import const as climate
from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT
@@ -19,7 +18,6 @@ CONF_FILTER = "filter"
CONF_ENTITY_CONFIG = "entity_config"
CONF_ENDPOINT = "endpoint"
CONF_LOCALE = "locale"
CONF_PASSWORD = "password"
ATTR_UID = "uid"
ATTR_UPDATE_DATE = "updateDate"
@@ -53,10 +51,13 @@ CONF_SUPPORTED_LOCALES = (
"en-US",
"es-ES",
"es-MX",
"es-US",
"fr-CA",
"fr-FR",
"hi-IN",
"it-IT",
"ja-JP",
"pt-BR",
)
API_TEMP_UNITS = {TEMP_FAHRENHEIT: "FAHRENHEIT", TEMP_CELSIUS: "CELSIUS"}
@@ -78,13 +79,6 @@ API_THERMOSTAT_MODES = OrderedDict(
API_THERMOSTAT_MODES_CUSTOM = {climate.HVAC_MODE_DRY: "DEHUMIDIFY"}
API_THERMOSTAT_PRESETS = {climate.PRESET_ECO: "ECO"}
PERCENTAGE_FAN_MAP = {
fan.SPEED_OFF: 0,
fan.SPEED_LOW: 33,
fan.SPEED_MEDIUM: 66,
fan.SPEED_HIGH: 100,
}
class Cause:
"""Possible causes for property changes.

View File

@@ -5,7 +5,7 @@ import logging
import uuid
from homeassistant.components import http
from homeassistant.const import HTTP_NOT_FOUND, HTTP_UNAUTHORIZED
from homeassistant.const import CONF_PASSWORD, HTTP_NOT_FOUND, HTTP_UNAUTHORIZED
from homeassistant.core import callback
from homeassistant.helpers import template
import homeassistant.util.dt as dt_util
@@ -20,7 +20,6 @@ from .const import (
ATTR_UPDATE_DATE,
CONF_AUDIO,
CONF_DISPLAY_URL,
CONF_PASSWORD,
CONF_TEXT,
CONF_TITLE,
CONF_UID,

View File

@@ -54,7 +54,6 @@ from .const import (
API_THERMOSTAT_MODES,
API_THERMOSTAT_MODES_CUSTOM,
API_THERMOSTAT_PRESETS,
PERCENTAGE_FAN_MAP,
Cause,
Inputs,
)
@@ -360,17 +359,9 @@ async def async_api_set_percentage(hass, config, directive, context):
data = {ATTR_ENTITY_ID: entity.entity_id}
if entity.domain == fan.DOMAIN:
service = fan.SERVICE_SET_SPEED
speed = "off"
service = fan.SERVICE_SET_PERCENTAGE
percentage = int(directive.payload["percentage"])
if percentage <= 33:
speed = "low"
elif percentage <= 66:
speed = "medium"
elif percentage <= 100:
speed = "high"
data[fan.ATTR_SPEED] = speed
data[fan.ATTR_PERCENTAGE] = percentage
await hass.services.async_call(
entity.domain, service, data, blocking=False, context=context
@@ -388,22 +379,12 @@ async def async_api_adjust_percentage(hass, config, directive, context):
data = {ATTR_ENTITY_ID: entity.entity_id}
if entity.domain == fan.DOMAIN:
service = fan.SERVICE_SET_SPEED
speed = entity.attributes.get(fan.ATTR_SPEED)
current = PERCENTAGE_FAN_MAP.get(speed, 100)
service = fan.SERVICE_SET_PERCENTAGE
current = entity.attributes.get(fan.ATTR_PERCENTAGE) or 0
# set percentage
percentage = max(0, percentage_delta + current)
speed = "off"
if percentage <= 33:
speed = "low"
elif percentage <= 66:
speed = "medium"
elif percentage <= 100:
speed = "high"
data[fan.ATTR_SPEED] = speed
percentage = min(100, max(0, percentage_delta + current))
data[fan.ATTR_PERCENTAGE] = percentage
await hass.services.async_call(
entity.domain, service, data, blocking=False, context=context
@@ -854,18 +835,9 @@ async def async_api_set_power_level(hass, config, directive, context):
data = {ATTR_ENTITY_ID: entity.entity_id}
if entity.domain == fan.DOMAIN:
service = fan.SERVICE_SET_SPEED
speed = "off"
service = fan.SERVICE_SET_PERCENTAGE
percentage = int(directive.payload["powerLevel"])
if percentage <= 33:
speed = "low"
elif percentage <= 66:
speed = "medium"
else:
speed = "high"
data[fan.ATTR_SPEED] = speed
data[fan.ATTR_PERCENTAGE] = percentage
await hass.services.async_call(
entity.domain, service, data, blocking=False, context=context
@@ -883,22 +855,12 @@ async def async_api_adjust_power_level(hass, config, directive, context):
data = {ATTR_ENTITY_ID: entity.entity_id}
if entity.domain == fan.DOMAIN:
service = fan.SERVICE_SET_SPEED
speed = entity.attributes.get(fan.ATTR_SPEED)
current = PERCENTAGE_FAN_MAP.get(speed, 100)
service = fan.SERVICE_SET_PERCENTAGE
current = entity.attributes.get(fan.ATTR_PERCENTAGE) or 0
# set percentage
percentage = max(0, percentage_delta + current)
speed = "off"
if percentage <= 33:
speed = "low"
elif percentage <= 66:
speed = "medium"
else:
speed = "high"
data[fan.ATTR_SPEED] = speed
percentage = min(100, max(0, percentage_delta + current))
data[fan.ATTR_PERCENTAGE] = percentage
await hass.services.async_call(
entity.domain, service, data, blocking=False, context=context

View File

@@ -8,7 +8,7 @@ import aiohttp
import async_timeout
from homeassistant.const import HTTP_ACCEPTED, MATCH_ALL, STATE_ON
from homeassistant.core import State
from homeassistant.core import HomeAssistant, State, callback
from homeassistant.helpers.significant_change import create_checker
import homeassistant.util.dt as dt_util
@@ -28,7 +28,20 @@ async def async_enable_proactive_mode(hass, smart_home_config):
# Validate we can get access token.
await smart_home_config.async_get_access_token()
checker = await create_checker(hass, DOMAIN)
@callback
def extra_significant_check(
hass: HomeAssistant,
old_state: str,
old_attrs: dict,
old_extra_arg: dict,
new_state: str,
new_attrs: dict,
new_extra_arg: dict,
):
"""Check if the serialized data has changed."""
return old_extra_arg is not None and old_extra_arg != new_extra_arg
checker = await create_checker(hass, DOMAIN, extra_significant_check)
async def async_entity_state_listener(
changed_entity: str,
@@ -70,15 +83,22 @@ async def async_enable_proactive_mode(hass, smart_home_config):
if not should_report and not should_doorbell:
return
if not checker.async_is_significant_change(new_state):
return
if should_doorbell:
should_report = False
if should_report:
alexa_properties = list(alexa_changed_entity.serialize_properties())
else:
alexa_properties = None
if not checker.async_is_significant_change(
new_state, extra_arg=alexa_properties
):
return
if should_report:
await async_send_changereport_message(
hass, smart_home_config, alexa_changed_entity
hass, smart_home_config, alexa_changed_entity, alexa_properties
)
elif should_doorbell:
@@ -92,7 +112,7 @@ async def async_enable_proactive_mode(hass, smart_home_config):
async def async_send_changereport_message(
hass, config, alexa_entity, *, invalidate_access_token=True
hass, config, alexa_entity, alexa_properties, *, invalidate_access_token=True
):
"""Send a ChangeReport message for an Alexa entity.
@@ -107,7 +127,7 @@ async def async_send_changereport_message(
payload = {
API_CHANGE: {
"cause": {"type": Cause.APP_INTERACTION},
"properties": list(alexa_entity.serialize_properties()),
"properties": alexa_properties,
}
}
@@ -146,7 +166,7 @@ async def async_send_changereport_message(
):
config.async_invalidate_access_token()
return await async_send_changereport_message(
hass, config, alexa_entity, invalidate_access_token=False
hass, config, alexa_entity, alexa_properties, invalidate_access_token=False
)
_LOGGER.error(

View File

@@ -1,9 +1,10 @@
{
"config": {
"abort": {
"cannot_connect": "Almond \uc11c\ubc84\uc5d0 \uc5f0\uacb0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.",
"missing_configuration": "Almond \uc124\uc815 \ubc29\ubc95\uc5d0 \ub300\ud55c \uc124\uba85\uc11c\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.",
"no_url_available": "\uac00\ub2a5\ud55c URL\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. \uc774 \uc5d0\ub7ec\uc5d0 \ub300\ud55c \uc815\ubcf4\ub294 \ub3c4\uc6c0\ub9d0 \uc139\uc158\uc744 \ud655\uc778\ud558\uc138\uc694({docs_url})"
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4",
"missing_configuration": "\uad6c\uc131\uc694\uc18c\uac00 \uad6c\uc131\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \uc124\uba85\uc11c\ub97c \ucc38\uace0\ud574\uc8fc\uc138\uc694.",
"no_url_available": "\uc0ac\uc6a9 \uac00\ub2a5\ud55c URL\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. \uc774 \uc624\ub958\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \ub0b4\uc6a9\uc740 [\ub3c4\uc6c0\ub9d0 \uc139\uc158]({docs_url}) \uc744(\ub97c) \ucc38\uc870\ud574\uc8fc\uc138\uc694.",
"single_instance_allowed": "\uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ud558\ub098\uc758 \uad6c\uc131\ub9cc \uac00\ub2a5\ud569\ub2c8\ub2e4."
},
"step": {
"hassio_confirm": {

View File

@@ -6,6 +6,7 @@ import botocore
import voluptuous as vol
from homeassistant.components.tts import PLATFORM_SCHEMA, Provider
from homeassistant.const import ATTR_CREDENTIALS, CONF_PROFILE_NAME
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
@@ -13,8 +14,6 @@ _LOGGER = logging.getLogger(__name__)
CONF_REGION = "region_name"
CONF_ACCESS_KEY_ID = "aws_access_key_id"
CONF_SECRET_ACCESS_KEY = "aws_secret_access_key"
CONF_PROFILE_NAME = "profile_name"
ATTR_CREDENTIALS = "credentials"
DEFAULT_REGION = "us-east-1"
SUPPORTED_REGIONS = [

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