Compare commits

...

920 Commits

Author SHA1 Message Date
Paulus Schoutsen
f3de8b9f28 Merge pull request #54249 from home-assistant/rc 2021-08-07 23:19:11 -07:00
Paulus Schoutsen
fe9808926e Fix formatting (#54247) 2021-08-07 22:04:03 -07:00
Paulus Schoutsen
f458f330a5 Bumped version to 2021.8.4 2021-08-07 21:34:56 -07:00
Allen Porter
fb6aca4f8b Pin google-cloud-pubsub to an older version (#54239)
Pin google-cloud-pubsub to an older version, since newer versions have a
pin that is incompatible with the existing grpcio pin already in package_constraints.txt
2021-08-07 21:34:52 -07:00
Dermot Duffy
724f11bb0d Don't block motionEye setup on NoURLAvailableError (#54225)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-08-07 21:34:52 -07:00
carstenschroeder
13ded1e5b2 Bugfix: Bring back unique IDs for ADS covers after #52488 (#54212) 2021-08-07 21:34:51 -07:00
jan iversen
5dcf5edae0 Add parameter to delay sending of requests in modbus (#54203) 2021-08-07 21:34:50 -07:00
Mk4242
56d0ef34fd Update const.py (#54195)
Remove extra attribute for FlowTemperature sensor, which prevents the ebusd integration from initialising
2021-08-07 21:34:50 -07:00
jan iversen
94e26df6d3 Solve missing automatic update of struct configuration in modbus (#54193) 2021-08-07 21:34:49 -07:00
Robert Hillis
3a17e22982 Fix androidtv media_image_hash (#54188) 2021-08-07 21:34:48 -07:00
Trinnik
1934159fd0 Fix update entity prior to adding (#54015) 2021-08-07 21:34:48 -07:00
Maciej Bieniek
4fbe713079 Add missing motor_speed sensor for Xiaomi Miio humidifier CA1 and CB1 (#54202) 2021-08-07 20:55:01 -07:00
Paulus Schoutsen
9155274c6e Merge pull request #54175 from home-assistant/rc 2021-08-06 13:27:37 -07:00
Paulus Schoutsen
cb775029e0 Bumped version to 2021.8.3 2021-08-06 12:55:59 -07:00
J. Nick Koston
011cda5fc4 Bump zeroconf to 0.33.4 to ensure zeroconf can startup when ipv6 is disabled (#54165)
Changelog: https://github.com/jstasiak/python-zeroconf/compare/0.33.3...0.33.4
2021-08-06 12:55:56 -07:00
J. Nick Koston
d580036dfb Fetch interface index from network integration instead of socket.if_nametoindex in zeroconf (#54152) 2021-08-06 12:55:55 -07:00
Michael
15e9310a01 Fix sensor PLATFORM_SCHEMA for ebox and enphase_envoy (#54142)
* Fix sensor PLATFORM_SCHEMA

* fix pylint
2021-08-06 12:55:55 -07:00
Niccolo Zapponi
93a2e2849c Handle software version being None when setting up HomeKit accessories (#54130)
* Convert all HomeKit service info to string prior to checking for max length

* Added check for None software version

* Added test case for numeric version number

* Update tests/components/homekit/test_accessories.py

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

* Fix style & none version test

* Fix test

* revert other change since it should be covered by the format_sw_version fix

Co-authored-by: J. Nick Koston <nick@koston.org>
2021-08-06 12:55:39 -07:00
Oscar Calvo
07f8236e6f Gracefully handle additional GSM errors (#54114) 2021-08-06 12:53:53 -07:00
Paulus Schoutsen
a07048aacf Merge pull request #54117 from home-assistant/rc 2021-08-05 23:18:48 -07:00
Paulus Schoutsen
890d190612 Fix constant 2021-08-05 23:15:20 -07:00
Paulus Schoutsen
b00173705e Bumped version to 2021.8.2 2021-08-05 20:49:03 -07:00
J. Nick Koston
374ccaae47 Bump zeroconf to 0.33.3 (#54108) 2021-08-05 20:48:58 -07:00
J. Nick Koston
fa4ec926ce Increase time before scene and script HomeKit entities are reset (#54105) 2021-08-05 20:48:57 -07:00
Simone Chemelli
e37bf733bd Two fixes (#54102) 2021-08-05 20:48:56 -07:00
Shay Levy
52f7f203d2 Fix Shelly last_reset (#54101) 2021-08-05 20:48:55 -07:00
Paulus Schoutsen
557e1862d5 Packages to support config platforms (#54085) 2021-08-05 20:48:54 -07:00
puddly
fbfb77b900 Bump up ZHA dependencies (#54079) 2021-08-05 20:48:53 -07:00
J. Nick Koston
bc548050f1 Handle empty software version when setting up HomeKit (#54068)
Fixes #54059 Fixes #54024
2021-08-05 20:48:43 -07:00
Franck Nijhof
5c9d7edadd Add missing device class to SAJ energy sensors (#54048) 2021-08-05 20:47:38 -07:00
Nathan Spencer
6544a32319 Bump pylitterbot to 2021.8.0 (#54000) 2021-08-05 20:47:37 -07:00
Paulus Schoutsen
5e9081e323 Merge pull request #54012 from home-assistant/rc 2021-08-04 20:22:17 -07:00
Paulus Schoutsen
436d0e0fb4 Bumped version to 2021.8.1 2021-08-04 17:05:41 -07:00
Bram Kragten
72032edaec Update frontend to 20210804.0 (#53997) 2021-08-04 17:05:12 -07:00
jjlawren
14621fc445 Fix empty sonos_group entity attribute on startup (#53985) 2021-08-04 17:05:11 -07:00
Simone Chemelli
ef55a8d2e2 Fix divider for Fritz sensors (#53980) 2021-08-04 17:05:10 -07:00
G Johansson
82b2ae8e91 Fix coordinator not defined in yale_smart_alarm (#53973)
* Bugfix coordinator not defined

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-08-04 17:05:09 -07:00
Michael
01299ddd20 Fix attr_unit_of_measurement in update of apcupsd entity (#53947) 2021-08-04 17:05:09 -07:00
jan iversen
fcc82d26a4 Add temporary fix to modbus to solve upstream problem (#53857) 2021-08-04 17:05:07 -07:00
Alex Henry
16b5544104 Fix Panasonic Viera TV going unavailable when turned off (#53788) 2021-08-04 17:05:06 -07:00
Franck Nijhof
f0f4c13cbe Merge pull request #53930 from home-assistant/rc 2021-08-04 11:21:42 +02:00
Franck Nijhof
4de3f031cc Bumped version to 2021.8.0 2021-08-04 10:46:20 +02:00
Joakim Sørensen
9ec516e1d4 Address review comments for 53918 (#53927) 2021-08-04 10:46:00 +02:00
Paulus Schoutsen
38df475936 Bumped version to 2021.8.0b10 2021-08-03 21:04:22 -07:00
Bram Kragten
af81dda1e2 Update frontend to 20210803.2 (#53923) 2021-08-03 21:03:43 -07:00
Martin Hjelmare
4fdd354745 Limit zwave_js meter sensor last reset (#53921) 2021-08-03 21:03:42 -07:00
Joakim Sørensen
0342c0da33 Limit API usage for Uptime Robot (#53918) 2021-08-03 21:03:42 -07:00
Paulus Schoutsen
7a8676dc83 Handle Shelly get name on uninitialized device (#53917) 2021-08-03 21:03:41 -07:00
J. Nick Koston
54ac889362 Enforce maximum length for HomeKit characteristics (#53913) 2021-08-03 21:03:01 -07:00
Aaron Bach
4e2c174741 Handle scenario where SimpliSafe code is falsey (#53912) 2021-08-03 20:59:54 -07:00
Maciej Bieniek
e4fd43ed7c Use SelectEntityDescription for Xiaomi Miio integration (#53907)
* Use SelectEntityDescription

* Use SelectEntityDescription

* Remove service field from XiaomiMiioSelectDescription class

* Fix typo

* Use lowercase for options
2021-08-03 20:58:48 -07:00
Greg Dowling
07604e60e5 Bump pyroon to 0.0.38 (#53906) 2021-08-03 20:50:46 -07:00
Jesse Hills
922c0dc8be Bump aioesphomeapi to 6.0.1 (#53905) 2021-08-03 20:50:45 -07:00
Joakim Sørensen
30497eff0e Add user to homeassistant system health (#53902) 2021-08-03 20:50:45 -07:00
Paulus Schoutsen
5536da18a6 Bumped version to 2021.8.0b9 2021-08-02 21:41:32 -07:00
Paulus Schoutsen
120122ffe2 Bump frontend to 20210803.0 (#53897) 2021-08-02 21:41:24 -07:00
Aaron Bach
8b7bdc9b67 Only show a SimpliSafe code entry when one exists (#53894) 2021-08-02 21:41:23 -07:00
Chris
d74ca25291 Handle powerConsumption reports with null value (#53888) 2021-08-02 21:41:22 -07:00
Paulus Schoutsen
be6cb2e792 Bump aiohue to 2.6.1 (#53887) 2021-08-02 21:41:22 -07:00
Otto Winter
f7e448c8b2 ESPHome implement light color modes (#53854) 2021-08-02 21:41:21 -07:00
Paulus Schoutsen
2e1f42937d Bumped version to 2021.8.0b8 2021-08-02 10:53:52 -07:00
Jc2k
92cc51370d Fix watts unit for homekit_controller power sensors (#53877) 2021-08-02 10:53:44 -07:00
Paulus Schoutsen
a97e480d82 Bump frontend to 20210802.0 (#53876) 2021-08-02 10:53:44 -07:00
Joakim Sørensen
66711219c7 Fix issue when data is None (#53875) 2021-08-02 10:53:43 -07:00
Franck Nijhof
b0f6e8c40a Fix growat server config entry missing URL key (#53867) 2021-08-02 10:53:42 -07:00
Franck Nijhof
df20d69fd2 Add measurement state class to ZHA power devices (#53866) 2021-08-02 10:53:42 -07:00
Franck Nijhof
249fb51d2f Fix cloud accountlinking replacing token data (#53865) 2021-08-02 10:53:41 -07:00
Franck Nijhof
e35b5dd7c1 Add RPi.GPIO dependency to rpi_rf integration (#53858) 2021-08-02 10:53:40 -07:00
jan iversen
bebd495e74 Allow combinations write_coil/read_coils and write_coils/read_coil for modbus switch (#53856) 2021-08-02 10:53:40 -07:00
Joakim Sørensen
d56636ed37 Add base energy analytics (#53855) 2021-08-02 10:53:39 -07:00
Michael
e9b672c0b4 Fix crash when AVM FRITZ!SmartHome devices are unreachable (#53809) 2021-08-02 10:53:38 -07:00
Daniel Hjelseth Høyer
5f8f1ae695 Add STATE_CLASS_MEASUREMENT to Tibber (#53802) 2021-08-02 10:53:38 -07:00
Michael
2e441d8b7c Fix TP-Link smart strip devices (#53799) 2021-08-02 10:53:37 -07:00
René Klomp
31af17f7f7 Bump pysma to 0.6.5 (#53792) 2021-08-02 10:53:37 -07:00
Felipe Martins Diel
91af3b0502 Fix entry setup for Broadlink SP4 sensors (#53765) 2021-08-02 10:53:36 -07:00
Emilv2
1a1efecdba Fix missing default reconnect interval in dsmr (#53760) 2021-08-02 10:53:35 -07:00
Vinny Furia
1c30967f6f Fix Radiothermostat hold value updates (#53656) 2021-08-02 10:53:34 -07:00
Paulus Schoutsen
ab4ed128cc Bumped version to 2021.8.0b7 2021-08-01 21:00:14 -07:00
Jc2k
3d6ba793f7 Fix error in homekit_controller causing some entities to get an incorrect unique id (#53848) 2021-08-01 21:00:09 -07:00
Chris
9cee9d9d8a Add energy consumption sensors to smartthings devices (#53759) 2021-08-01 21:00:08 -07:00
GitHub Action
e093e0bf10 [ci skip] Translation update 2021-08-01 20:41:03 -07:00
Paulus Schoutsen
1019bb059d Bumped version to 2021.8.0b6 2021-08-01 15:07:34 -07:00
Bram Kragten
ec35b92052 Update frontend to 20210801.0 (#53841) 2021-08-01 15:07:23 -07:00
Robert Hillis
cb2103d96c Fix file path error in nfandroidtv (#53814) 2021-08-01 15:07:22 -07:00
Maciej Bieniek
3f7ddb4706 Clean Xiaomi Miio humidifier services (#53806) 2021-08-01 15:07:22 -07:00
B-Hartley
fd0ae7ab36 ForecastSolar - power production now w not k w (#53797) 2021-08-01 15:07:21 -07:00
Maciej Bieniek
fc5c30775d Remove led from Xiaomi Miio humidifier features (#53796) 2021-08-01 15:07:20 -07:00
Andreas Brett
0948eafb93 Fix onkyo UnboundLocalError (#53793)
audio_information_raw and video_information_raw were in some cases used before being assigned

error: UnboundLocalError: local variable 'video_information_raw' referenced before assignment
2021-08-01 15:07:20 -07:00
Maciej Bieniek
31869cbb12 Fix name migration of the Xiaomi Miio humidifier (#53790) 2021-08-01 15:07:19 -07:00
Michael
2297c0b58b Do not block setup of TP-Link when device unreachable (#53770) 2021-08-01 15:07:18 -07:00
Paulus Schoutsen
e0fc14f82c Bumped version to 2021.8.0b5 2021-07-30 14:15:42 -07:00
Paulus Schoutsen
cd3390e012 Bump Hue and only fire events for button presses (#53781)
* Bump Hue and only fire events for button presses

* Fix tests
2021-07-30 14:15:32 -07:00
Bram Kragten
af96c5d60c Update frontend to 20210730.0 (#53778) 2021-07-30 14:15:31 -07:00
Aaron Bach
9f0f40dac6 Fix parsing of non-string values in Slack data (#53775) 2021-07-30 14:15:31 -07:00
Jan Bouwhuis
958df580a9 Fix Xiaomi-miio humidifier write the state back when turning on or off (#53771) 2021-07-30 14:15:30 -07:00
Maciej Bieniek
0aee659ee9 Fix Xiaomi Miio humidifier mode change (#53757) 2021-07-30 14:15:29 -07:00
J. Nick Koston
423fb910b5 Bump HAP-python to 3.6.0 (#53754) 2021-07-30 14:15:28 -07:00
Joakim Sørensen
fc8af9af8e Revert "Rename snapshot -> backup" (#53751)
This reverts commit 9806bda272.
2021-07-30 14:15:27 -07:00
Paulus Schoutsen
a75c7d52c9 Cost sensor handle consumption sensor in Wh (#53746) 2021-07-30 14:15:27 -07:00
uvjustin
dac968bf32 Fix non monotonic dts error in stream (#53712)
* Use defaultdict for TimestampValidator._last_dts

* Combine filters

* Allow PeekIterator to be updated while preserving buffer

* Fix peek edge case

* Readd is_valid filter to video only iterator
2021-07-30 14:15:26 -07:00
Paulus Schoutsen
447901c223 Bumped version to 2021.8.0b4 2021-07-29 23:35:09 -07:00
Paulus Schoutsen
9dcd3f6626 Add energy attributes to Fronius (#53741)
* Add energy attributes to Fronius

* Add solar

* Add power

* Only add last reset for total meter entities

* Only add last reset for total solar entities

* Create different entity descriptions per key

* only return the entity description for energy total

* Use correct key

* Meter devices keep it real

* keys start with energy_real

* Also device key starts with

* Lint
2021-07-29 23:35:03 -07:00
Jan Bouwhuis
d34bd8ad1e Fix Xiaomi-miio switch platform setup (#53739) 2021-07-29 23:35:02 -07:00
Jan Bouwhuis
83e4e4f769 Fix Xiaomi humidifier name migration (#53738) 2021-07-29 23:35:01 -07:00
Michael
128dc07fa5 Apply left suggestions #53596 for TP-Link (#53737) 2021-07-29 23:35:00 -07:00
Brandon Rothweiler
d2dfdd81ad Only allow one Mazda vehicle status request at a time (#53736) 2021-07-29 23:35:00 -07:00
Michael
0442827b9e Fix exception handling in DataUpdateCoordinator in TP-Link (#53734)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-07-29 23:34:59 -07:00
Alexei Chetroi
37c3062874 Bump up ZHA dependencies (#53732) 2021-07-29 23:34:58 -07:00
Robert Svensson
bfacff5d78 Add energy device class to deCONZ consumption sensors (#53731) 2021-07-29 23:34:57 -07:00
Michael
d54621e778 Extract smartthings switch energy attributes into sensors (#53719) 2021-07-29 23:34:57 -07:00
Ryan Johnson
716c3f69ca Bump pyatv to 0.8.2 (#53659) 2021-07-29 23:34:56 -07:00
Paulus Schoutsen
630a1fb36c Bumped version to 2021.8.0b3 2021-07-29 14:27:55 -07:00
Paulus Schoutsen
54eeebfd20 Revert "Allow uploading large snapshots (#53528)" (#53729)
This reverts commit cdce14d63d.
2021-07-29 14:27:47 -07:00
Franck Nijhof
a671a0ccac Fix effect selector of light.turn_on service (#53726) 2021-07-29 14:27:46 -07:00
Martin Hjelmare
8cf0182f2f Fix zwave_js current and voltage meter sensor device class (#53723) 2021-07-29 14:27:45 -07:00
Franck Nijhof
f1400b03bb Fix DSMR reconnecting loop without timeout (#53722) 2021-07-29 14:27:45 -07:00
Paulus Schoutsen
6dc00d3d87 Bumped version to 2021.8.0b2 2021-07-29 12:35:50 -07:00
Franck Nijhof
bf6133534d Fix SolarEdge statistics; missing device_class (#53720) 2021-07-29 12:35:25 -07:00
Paulus Schoutsen
b1758e1fcc Bump frontend to 20210729.0 (#53717) 2021-07-29 12:35:24 -07:00
Martin Hjelmare
cc0aa32f3e Fix zwave_js meter sensor state class (#53716) 2021-07-29 12:35:23 -07:00
Franck Nijhof
dc2494f0a0 Add state class support to DSMR Reader (#53715) 2021-07-29 12:35:23 -07:00
Simone Chemelli
4b2a1ec694 Add last reset to Shelly's energy entities (#53710) 2021-07-29 12:35:22 -07:00
Michael
b2187022c4 Set state class measurement also for Total Energy for AVM Fritz!Smarthome devices (#53707) 2021-07-29 12:35:21 -07:00
Martin Hjelmare
c6f588fc08 Revert "Add Automate Pulse Hub v2 support (#39501)" (#53704) 2021-07-29 12:35:20 -07:00
Daniel Hjelseth Høyer
462e3a3d0d Integration. Add device class, last_reset, state_class (#53698)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-29 12:35:20 -07:00
Daniel Hjelseth Høyer
aa179a1ad9 Energy round (#53696)
* Energy. Round cost

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Energy. Round cost

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Update homeassistant/components/energy/sensor.py

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

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-29 12:35:19 -07:00
Daniel Hjelseth Høyer
1117158bd0 Surepetcare, bug fix (#53695) 2021-07-29 12:35:18 -07:00
Andrew55529
6ced0153df Fix problem with telegram_bot (#53690) 2021-07-29 12:35:17 -07:00
Gerard
7f314e17de Bump bimmer_connected to 0.7.16 to fix parking light issue (#53687) 2021-07-29 12:35:17 -07:00
Robert Svensson
9ad29ae75c Only disable a device if all associated config entries are disabled (#53681) 2021-07-29 12:35:16 -07:00
Maciej Bieniek
43a89dc452 Fix last_reset_topic config replaces state_topic for sensor platform (#53677) 2021-07-29 12:35:15 -07:00
Allen Porter
268f0dd62f Bump nest to version 0.3.5 (#53672)
Fix runtime type assertions, Fixes Issue #53652
2021-07-29 12:35:15 -07:00
Eric Severance
d7768f13c1 pyWeMo version bump (0.6.6) (#53671) 2021-07-29 12:35:14 -07:00
J. Nick Koston
db8aa4658a Skip each ssdp listener that fails to bind (#53670) 2021-07-29 12:35:13 -07:00
Raman Gupta
d19d487b21 Add energy support for zwave_js meter CC entities (#53665)
* Add energy support for zwave_js meter CC entities

* shrink

* comments

* comments

* comments

* Move attributes

* Add tests

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-29 12:35:13 -07:00
Aaron Bach
2aeecba64c Fix unhandled exception with Guardian paired sensor coordinators (#53663) 2021-07-29 12:35:12 -07:00
Diogo Gomes
b3367d8b3f Prosegur code quality improvements (#53647) 2021-07-29 12:35:11 -07:00
Raman Gupta
7e6856ace8 Add enabled attribute to zwave_js discovery model (#53645)
* Add attribute to zwave_js discovery model

* Fix binary sensor entity enabled logic

* Add tests
2021-07-29 12:35:10 -07:00
Michael
b5f0c2cef4 Move TP-Link power and energy switch attributes to sensors (#53596)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2021-07-29 12:35:10 -07:00
Stephen Beechen
2ffc779f3d Allow uploading large snapshots (#53528)
Co-authored-by: Pascal Vizeli <pascal.vizeli@syshack.ch>
2021-07-29 12:35:09 -07:00
Paulus Schoutsen
75dc55418b Bumped version to 2021.8.0b1 2021-07-28 22:06:24 -07:00
J. Nick Koston
384ddbafab Add device class energy and last reset to sense (#53667) 2021-07-28 22:06:11 -07:00
J. Nick Koston
5483300668 Bump aiolip to 1.1.6 to fix timeout with ident (#53660) 2021-07-28 22:06:11 -07:00
Paulus Schoutsen
c9d355a8a4 Add last reset to Shelly (#53654) 2021-07-28 22:06:10 -07:00
Paulus Schoutsen
fce7417ed1 Add last reset to enphase sensors (#53653) 2021-07-28 22:06:09 -07:00
J. Nick Koston
f13d7f189a Fix invalid homekit state when arming (#53646)
- Maybe fixes #48538
2021-07-28 22:06:09 -07:00
Raman Gupta
3265c7b8d8 Add zwave_js.reset_meter service (#53390)
* Add zwave_js.meter_reset service

* fix log statement

* Add endpoint attribute to service call and rename service

* Make service an entity service

* remove endpoint from service description
2021-07-28 22:06:08 -07:00
epenet
a3a687f037 Add renault integration (#39605) 2021-07-28 21:44:43 +02:00
Franck Nijhof
743308ec92 Bumped version to 2021.8.0b0 2021-07-28 21:26:51 +02:00
Milan Meulemans
7bd46b7705 Tado, setup to return False and not ConfigEntryNotReady on RuntimeError (#53637) 2021-07-28 21:25:44 +02:00
Otto Winter
67ac87e915 Fix missing supported_features when only custom presets for ESPHome (#53632) 2021-07-28 21:20:26 +02:00
jan iversen
19245a5b63 Add CameraEntityDescription to camera integration (#53636) 2021-07-28 21:09:45 +02:00
J. Nick Koston
c53e7bc8c2 Only declare powerwall login failure after 5 attempts (#53635) 2021-07-28 21:09:08 +02:00
Paulus Schoutsen
0e1eef5737 Bump frontend to 20210728.0 (#53634) 2021-07-28 20:41:27 +02:00
Robert Hillis
86b126c34a Use entity class attributes for cmus (#53458) 2021-07-28 19:39:58 +02:00
stefano055415
3f7cc176a8 Add climate support to Freedompro (#52720)
* Update Freedompro

* fix code and add test

* add check for unsupported mode

* add code for unsupported hvac_mode

* HVAC_INVERT_MAP and fix test

* change params hass to session

* set const and add ValueError

* fix ValueError text
2021-07-28 19:27:31 +02:00
jjlawren
9111fb60d7 Include advertise_addr in Sonos logs when used (#53617) 2021-07-28 19:19:09 +02:00
Milan Meulemans
1b96288799 Fix Yale Smart Alarm strings (#53627) 2021-07-28 19:09:48 +02:00
Matthias Alphart
4e4bb2e5a8 Test KNX events (#53433)
* test knx_event

* use async_capture_events
2021-07-28 19:04:11 +02:00
Milan Meulemans
03308b62c1 Remove CONNECTION_CLASS from Yale Smart Alarm ConfigFlow (#53629) 2021-07-28 18:58:45 +02:00
Daniel Hjelseth Høyer
deb47517ca Upgrade ns-api to 3.0.5 (#53620) 2021-07-28 18:58:15 +02:00
Frederic Seiler
52df6a6558 Add deCONZ support for Legrand Self-e ZGP switches (#53008)
* Add deCONZ support for Legrand Self-e ZGP switches

Legrand Self-e ZLGP17 (0 677 23L)
Legrand Self-e ZLGP18 (0 677 24L)

* Add the 4 scenes switch (ZLGP15)

and update the model name of the toggle switch

* Update events
2021-07-28 12:54:19 -04:00
Felipe Martins Diel
419bcd939b Fix broadlink creating duplicate unique IDs (2) (#53622) 2021-07-28 18:53:34 +02:00
Bram Kragten
4df56bad9e Remove currency from energy, use core config (#53615)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-07-28 08:49:55 -07:00
J. Nick Koston
babd9f048f Bump zeroconf to 0.33.2 (#53625)
- Changelog: https://github.com/jstasiak/python-zeroconf/compare/0.33.1...0.33.2
2021-07-28 08:49:43 -07:00
Stefan Agner
8d652b28e2 Add Khadas VIM3 (#53616)
* Add Khadas VIM3

Add Khadas VIM3 machine. VIM3 is based on Amlogic A311D SoC with
2xCortex-A53 and 4xCortex-A73.

* Use latest builder which supports khadas-vim3
2021-07-28 14:19:21 +02:00
Jesse Hills
ec5d55dc30 Auto reset on value going back to 0 in ESPHome (#53592)
* ESPHome - Auto reset on value going back to 0

* Remove logging lines

* Remove useless stuff

* Move callback to sensor class
Wrap `track_change_event` in `async_on_remove`

* Convert to using internal callbacks and RestoreEntity

* Don't document fixmes?

* Review fixes

* Review fixes

Co-authored-by: Otto winter <otto@otto-winter.com>
2021-07-28 13:56:45 +02:00
Franck Nijhof
ef6fc5bfa4 Merge branch 'master' into dev 2021-07-28 13:36:10 +02:00
Maciej Bieniek
c81371f82b Clean device initialization log for Xiaomi Miio humidifiers (#53612) 2021-07-28 12:03:24 +02:00
Milan Meulemans
6299f58bd7 Remove Rituals DiffuserSwitch extra_state_attributes (#53611) 2021-07-28 11:52:55 +02:00
Marc Mueller
553521a76b Add mixin classes for required keys in EntityDescription (#53610) 2021-07-28 11:50:13 +02:00
Maciej Bieniek
6d13466f8a Remove unnecessary init_integration() call in NAM tests (#53609) 2021-07-28 11:23:57 +02:00
Jan Bouwhuis
781015fb19 Xiaomi_Miio Humidifier rework (#52366)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Maciej Bieniek <bieniu@users.noreply.github.com>
Co-authored-by: Teemu R. <tpr@iki.fi>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-28 10:52:43 +02:00
Pascal Vizeli
f3e7fb5798 Pin pandas to 1.3.0 (#53607)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-28 10:30:05 +02:00
Maciej Bieniek
648e649718 Use SensorEntityDescription in AccuWeather integration (#53604)
* Use SensorEntityDescription

* Add missing type for entity_description

* Use tuples instead of lists

* Suggested change
2021-07-28 10:26:14 +02:00
Allen Porter
d58151034c Combine some stream test mocks (#53600)
Combine MockFlushPart with the FakePyAvContainer since the container is
effectively a mock AvOutput. This simulates the behavior of the call to
mux and close that actually write to the memory file.
2021-07-28 10:20:51 +02:00
Marc Mueller
10bfc78365 Fix missing encoding with open() (#53593)
* Fix missing encoding with open()

* Fix tests

* Improve open - frontend
2021-07-28 09:41:45 +02:00
Allen Porter
1c20eb3263 Skip 'None' values when restoring climate scenes (#53484) 2021-07-28 09:16:23 +02:00
Allen Porter
68945e8814 Enable strict static type checking for nest integration (#53535) 2021-07-28 09:12:32 +02:00
Richard T. Schaefer
9e219d9b6e Add this variable for use by automation and script templates (#52774) 2021-07-28 09:09:13 +02:00
Dermot Duffy
1aec069f3a Use the new EntityDescription for motionEye switches (#53536) 2021-07-28 09:06:41 +02:00
Franck Nijhof
1968b95829 Add currency core configuration (#53541)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-07-28 08:55:58 +02:00
Aaron Bach
514d97f144 Enforce strict typing for ReCollect Waste (#53356) 2021-07-28 08:51:40 +02:00
Paulus Schoutsen
9c33818392 Improve CO2Signal error handling (#53602)
* Improve CO2Signal error handling

* Update homeassistant/components/co2signal/sensor.py

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

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-28 08:43:24 +02:00
jjlawren
d865577187 Bump plexapi to 4.7.0 (#53597) 2021-07-28 08:26:26 +02:00
Maciej Bieniek
9b67605b8a Use SensorEntityDescription in GIOS integration (#53581) 2021-07-28 08:21:00 +02:00
Marc Mueller
b7f1f2330a Use EntityDescription - netatmo (#53568)
* Use EntityDescription - netatmo

* Add coverage exclude

* Fix coverage exclude comment
2021-07-28 08:18:59 +02:00
Allen Porter
b3b5ee10b1 Fix mypy type for timestamp validator (#53598) 2021-07-27 22:04:59 -07:00
Joakim Sørensen
85c1614204 Add currency to location data (#53575) 2021-07-27 21:05:16 -07:00
Bram Kragten
127c9fc877 Add statistics support for SMA energy sensors (#53589) 2021-07-28 01:48:22 +02:00
Paulus Schoutsen
a004a0dd4f Bump frontend to 20210727.0 (#53591) 2021-07-28 01:48:04 +02:00
Raman Gupta
73bc0267e9 Add DeviceRegistry template functions (#53131) 2021-07-27 18:55:55 -04:00
Marc Mueller
14c257e1b7 Use EntityDescription - melcloud (#53572)
* Use EntityDescription - melcloud

* Fix pylint errors

* Fix test

* Fix coverage exclude comments
2021-07-28 00:07:14 +02:00
Marc Mueller
3908aabc13 Use EntityDescription - climacell (#53573)
* Use EntityDescription - climacell

* Fix tests

* Fix coverage ignore comment
2021-07-27 23:47:29 +02:00
Marc Mueller
dd849c4eab Use EntityDescription - dwd_weather_warnings (#53580) 2021-07-27 22:52:50 +02:00
Marc Mueller
ac837cd76e Use EntityDescription - ondilo_ico (#53579) 2021-07-27 22:51:32 +02:00
Joakim Sørensen
9806bda272 Rename snapshot -> backup (#51629) 2021-07-27 22:43:05 +02:00
Kuzj
d0b9d82287 Refactor bme280, add SPI support (#48775)
* bme280 refactoring, add SPI support

* isort, requirements

* __init_.py add to .coveragerc

* Re-run CI jobs

* const.py to .coveragerc

* Add support for IoT class in manifest

* Keepalive

* review suggestions

* scan_interval with coordinator

* black, isort

* coordinator review suggestions

* Set device_class

* review suggestions

* review suggestions

* review suggestions

* review suggestions

* review suggestions

* review suggestions

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

* add bme280spi to commented requirements

* run script.gen_requirements_all

* black

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-27 16:29:43 -04:00
Diogo Gomes
7ad7cdad3d Add Prosegur Alarms (#44679)
Co-authored-by: Franck Nijhof <frenck@frenck.dev>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-27 22:19:58 +02:00
Aaron Bach
f92ba75791 Enforce strict typing for SimpliSafe (#53417) 2021-07-27 22:11:54 +02:00
Paulus Schoutsen
f71980a634 Create stats for all sensors that have % unit and are measurement (#53576) 2021-07-27 21:56:34 +02:00
Ron Klinkien
3488053648 Remove garmin_connect integration (#52808)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-27 21:49:49 +02:00
Aaron Bach
e04b2c2e35 Bump pyairvisual to 5.0.9 (#53578) 2021-07-27 21:39:58 +02:00
Simone Chemelli
5a6be2370b Replace util.get_local_ip in favor of components.network.async_get_source_ip() - part 3 (#53424) 2021-07-27 21:19:29 +02:00
J. Nick Koston
f3bf0fdb09 Bump yalexs to 1.1.13 to fix august doorsense offline at startup (#53574) 2021-07-27 21:17:17 +02:00
Felipe Martins Diel
43d3b6c2a2 Move the coordinator logic to the BroadlinkEntity class (#53571) 2021-07-27 13:53:29 -05:00
Matthew Gottlieb
37c841956f Allow removing workday holidays by name (#52700) 2021-07-27 20:28:04 +02:00
Robert Hillis
54a3c1a217 Use entity class attributes for clementine (#53405) 2021-07-27 20:18:58 +02:00
Marc Mueller
f599c5a39e Use EntityDescription - tibber (#53569) 2021-07-27 20:13:48 +02:00
Robert Hillis
13443310fe Use entity class attributes for Cast (#53348) 2021-07-27 20:03:13 +02:00
Marc Mueller
736577abef Use EntityDescription - skybell (#53564)
* Use EntityDescription - skybell

* Fix typing
2021-07-27 19:51:07 +02:00
Martin Hjelmare
a133eae88e Add more mysensors sensor attributes (#53566) 2021-07-27 19:48:37 +02:00
Matthias Alphart
27d42e0cd8 KNX: Support for HS-color lights (#53538) 2021-07-27 19:36:46 +02:00
Yuxiang Zhu
ce663f629c Fix various zeroconf IPv6 compatibility issues (#53505) 2021-07-27 19:31:51 +02:00
Marc Mueller
64a3c669ce Use EntityDescription - rova (#53531)
* Use EntityDescription - rova

* Fix pylint protected-access

* Changes after review
2021-07-27 19:12:17 +02:00
Maciej Bieniek
9607864c29 Bump gios library to version 2.0 (#53557)
* Bump gios library

* Fix pylint error
2021-07-27 19:10:38 +02:00
J. Nick Koston
84a7a5fd32 Split color temp and color into separate HomeKit services when a light supports both (#53471) 2021-07-27 10:10:05 -07:00
Marc Mueller
a1e692798f Use EntityDescription - ebox (#53565) 2021-07-27 19:06:50 +02:00
Johan Smits
9e9165f4ac Bump matrix-client to 0.4.0 (#53508) 2021-07-27 18:30:43 +02:00
Marc Mueller
6847c6dbbc Use EntityDescription - rainbird (#53560)
* Use EntityDescription - rainbird

* Add additional type hints
2021-07-27 18:06:46 +02:00
Allen Porter
022ba31999 Refactor the logic for peeking into the start of the stream (#52699)
* Reset dts validator when container is reset

* Reuse existing dts_validator when disabling audio stream

* Refactor peek logic at the start of a stream

Add a PeekingIterator to support rewinding an iterator so that the code
for adjusting audio streams and start pts can be inlined in the worker.

* Simplification and readability improvements

* Remove unnecessary verbiage from comments and pydoc

* Address pylint errors

* Remove rewind function and just mux the first packet separately

* More cleanup after removing rewind()

* Skip check to self._buffer on every iteration
2021-07-27 08:53:42 -07:00
Franck Nijhof
f1eb35b1a5 Use entity descriptions classes in Forecast.Solar (#53553) 2021-07-27 17:45:47 +02:00
Marc Mueller
72a98550b6 Use EntityDescription - epsonworkforce (#53556) 2021-07-27 17:45:25 +02:00
gjong
9f495fd200 Add initial version for the YouLess integration (#41942)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-27 17:42:15 +02:00
Maciej Bieniek
ea9d312b45 Use SensorEntityDescription in Brother integration (#53558) 2021-07-27 17:26:47 +02:00
Marc Mueller
0552b9c783 Use EntityDescription - glances (#53559) 2021-07-27 17:24:18 +02:00
jjlawren
214920f486 Ignore Sonos Boost devices during discovery v2 (#53358) 2021-07-27 09:50:46 -05:00
Marc Mueller
268ade6b76 Use EntityDescription - metoffice (#53555) 2021-07-27 16:22:01 +02:00
Milan Meulemans
e3df4f8795 Upgrade Rituals Perfume Genie to quality level "silver" (#53550) 2021-07-27 14:46:51 +02:00
Franck Nijhof
27e69037d4 Use entity descriptions classes in DSMR (#53549) 2021-07-27 14:44:58 +02:00
Milan Meulemans
b51c666817 Replace ServiceCallType with ServiceCall in lcn services (#53547) 2021-07-27 14:16:01 +02:00
Peter Nijssen
e037d3a16f Update spider integration to support HEM (#53397)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-27 12:58:33 +02:00
Robert Svensson
93899e981f UniFi lies about the client being noted, using the real note instead if it exists (#53542) 2021-07-27 12:35:16 +02:00
Milan Meulemans
348d7a5622 Remove incorrect use of ConfigType in config flows (#53544) 2021-07-27 12:33:17 +02:00
Milan Meulemans
0471b27179 Replace HomeAssistantType with HomeAssistant (#53545) 2021-07-27 12:30:56 +02:00
Maciej Bieniek
ca020e1f87 Use SensorEntityDescription in Nettigo Air Monitor (#53539) 2021-07-27 12:12:15 +02:00
Maciej Bieniek
c0e84a7b32 Use SensorEntityDescription in Airly integration (#53540) 2021-07-27 12:08:31 +02:00
Eric Severance
4506b41022 Use SensorEntityDescription for wemo (#53537) 2021-07-27 12:05:21 +02:00
Aaron Bach
f4a7292f08 Enforce strict typing for Tile (#53410) 2021-07-27 11:51:57 +02:00
Milan Meulemans
7103835d15 Enable strict typing for Rituals Perfume Genie (#53543)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-27 11:50:47 +02:00
Jesse Hills
18bf0762b5 Add select entities to ESPHome (#53526)
Co-authored-by: Otto Winter <otto@otto-winter.com>
2021-07-27 11:45:04 +02:00
Aaron Bach
a6b34924be Enforce strict typing for RainMachine (#53414) 2021-07-27 10:45:44 +02:00
Aaron Bach
5483ab0cda Enforce strict typing for Flu Near You (#53407) 2021-07-27 10:42:51 +02:00
Matt Zimmerman
d7d859fc86 Update nexia to 0.9.11 (#53534) 2021-07-27 10:40:20 +02:00
Eric Severance
7119285201 Clean wemo sensor attributes (#53532)
* Wemo: Use the available property instead of returning unavailable from state property

* Nit: s/_insight_device_key/_insight_params_key

* Use insight_params_key for generating unique_id
2021-07-27 07:18:05 +02:00
Franck Nijhof
d4d791e0a1 Ensure Jewish Calendar returns an iso formatted timestamp (#52722) 2021-07-26 20:23:25 -07:00
GitHub Action
2b3148296c [ci skip] Translation update 2021-07-27 00:12:20 +00:00
BreakingBread0
20b66faa6d Add MFA Capability to Tesla Integration (#53245)
* Adds MFA Capability to Tesla Integration

* Add "(Optional)" to MFA Code

* Update homeassistant/components/tesla/translations/de.json

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

* Update en.json

* Revert "Update en.json"

This reverts commit 825685c3a230f54094c10c86d7b82f4c81979064.

Co-authored-by: J. Nick Koston <nick@koston.org>
2021-07-27 01:46:49 +02:00
Marc Mueller
3e08e50050 Use EntityDescription - nws (#53523)
* Use EntityDescription - nws

* Bugfix

* Bugfix 2
2021-07-27 01:46:01 +02:00
Allen Porter
6376b4be5c Increase static type coverage for nest integration (#53475)
Co-authored-by: Mick Vleeshouwer <mick@imick.nl>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-27 01:43:52 +02:00
Franck Nijhof
d4c4263730 Adjust typing of _attr_extra_state_attributes (#53529) 2021-07-27 01:25:22 +02:00
Milan Meulemans
8ff3b2a2f6 Upgrade pyrituals to 0.0.6 (#53527) 2021-07-27 00:49:55 +02:00
Milan Meulemans
b26e65d7e5 Fix Rituals Perfume Genie sensors icons (#53517) 2021-07-27 00:47:06 +02:00
Tobias Sauerwein
31079a05b3 Address late review comments on Netatmo (#53524) 2021-07-27 00:42:36 +02:00
Franck Nijhof
0b44265232 Add description classes to entity components (#53521)
* Add description classes to entity components

* An -> A

* Add StateVacuumEntityDescription
2021-07-27 00:22:21 +02:00
Bram Kragten
7cb3414517 Update frontend to 20210726.0 (#53522) 2021-07-26 23:56:40 +02:00
Oxan van Leeuwen
2127314f9e Fix typo in codeowners (#53520) 2021-07-26 23:33:15 +02:00
Matthias Alphart
c1c6c54b45 xknx 0.18.9 (#53519) 2021-07-26 23:18:20 +02:00
Jc2k
1681bbe5a5 Make sure that vocolinc flowerbud humidity sensor is exposed (via homekit_controller) (#53518)
* Make sure that vocolinc flowerbud humidity sensor is exposed

* Was a no-op to request these from humidifier, so remove them

* Fix typo
2021-07-26 16:11:27 -05:00
Franck Nijhof
ee452d415d Add SensorEntityDescription class (#53357) 2021-07-26 22:00:43 +02:00
jjlawren
88cffc86bb Add crossfade control support to Sonos (#53228) 2021-07-26 21:58:13 +02:00
Robert Hillis
aee48dbcb3 Use entity class attributes for cloud (#53445) 2021-07-26 21:23:32 +02:00
jan iversen
cfb0def718 Change integration modbus to use _attr variables (#53511) 2021-07-26 21:20:34 +02:00
Anton Tolchanov
80aaebb761 Rename Prometheus metrics to conform with naming guidelines (#50156) 2021-07-26 20:52:30 +02:00
micha91
f4d65e3751 Musiccast grouping fixes (#52339)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-26 20:48:20 +02:00
Dermot Duffy
23b64cd496 Bump motioneye-client version to v0.3.11 (#53504) 2021-07-26 20:43:22 +02:00
Paulus Schoutsen
962ddf664c Add country code to co2signal state attributes (#53512) 2021-07-26 11:10:39 -07:00
Franck Nijhof
f28d8fae2f Mark energy integration as internal (#53513) 2021-07-26 10:21:40 -07:00
Bram Kragten
fcc6ea7497 Add energy integration (#52001)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Erik <erik@montnemery.com>
2021-07-26 09:37:37 -07:00
Raman Gupta
4b189bd8c5 Add zwave_js WS API commands to get statistics (#53393)
* Add zwave_js WS API commands to get statistics

* update function name

* move nested functions to top level functions
2021-07-26 11:59:16 -04:00
Eric Severance
a6331d85ed Support energy/power sensors in the WeMo component (#53419) 2021-07-26 08:50:22 -07:00
Jc2k
9a000a1183 Support controlling Flowerbud spray level via homekit_controller (#53493) 2021-07-26 10:46:36 -05:00
Daniel Hjelseth Høyer
d58a02a647 Broadlink, remove attr_current_power_w and add sensor (#53342) 2021-07-26 08:42:19 -07:00
Simone Chemelli
37d6824ed4 Increase pool max size for urllib3 in Fritz integration (#53461) 2021-07-26 16:44:58 +02:00
Simone Chemelli
2025afe14b Add MAC to SamsungTV when missing (#53479)
* Add MAC when missing

* Fix I/O

* Add test for missing MAC address
2021-07-26 16:43:05 +02:00
Marc Mueller
46c3495ae0 Update pylint to 2.9.5 (#53496) 2021-07-26 16:17:15 +02:00
Jc2k
af8f594939 Address late review of homekit_controller (#53492)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-26 15:32:16 +02:00
broadcasttechie
ad730524c8 Reduce min scan interval to 10s for InfluxDB (#53276) 2021-07-26 14:32:42 +02:00
Marc Mueller
882c323551 Update pyupgrade to v2.23.0 (#53495) 2021-07-26 14:21:30 +02:00
Michael
ebfdfd172b Add state class measurement to sensors where suitable for Synology DSM (#53468) 2021-07-26 11:42:52 +02:00
Franck Nijhof
01c8114e93 Add WLED playlist support (#53381)
Co-authored-by: Anders Melchiorsen <amelchio@nogoto.net>
2021-07-26 11:15:49 +02:00
Joakim Sørensen
3a5347f69e Handle serverTime change (#53490) 2021-07-26 11:01:58 +02:00
Franck Nijhof
fbe576e93a Deprecate wled.preset service (#53383) 2021-07-26 11:01:02 +02:00
Otto Winter
51e4f66b82 Fix ESPHome services when .storage cleared (#53488) 2021-07-26 09:33:06 +02:00
J. Nick Koston
25229a9670 Allow zeroconf name change if there is another Home Assistant running on the local network (#53476)
* Allow zeroconf name change if there is another Home Assistant running on the local network

* Remove unused try/except
2021-07-26 09:27:49 +02:00
dependabot[bot]
3b96085716 Bump codecov/codecov-action from 2.0.1 to 2.0.2 (#53487)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 2.0.1 to 2.0.2.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v2.0.1...v2.0.2)

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-26 08:44:32 +02:00
jjlawren
550a6f159e Reduce repetitive noise in Sonos debug logs (#53352) 2021-07-26 00:54:38 -05:00
J. Nick Koston
c18b626d67 Fix flakey august pubnub test (#53474) 2021-07-25 21:14:38 -07:00
Alexei Chetroi
505dd500cb Bump up ZHA dependencies (#53472)
* Bump up ZHA dependencies

* Fix ZHA WS API tests
2021-07-25 22:09:40 -04:00
GitHub Action
c6ee058c0d [ci skip] Translation update 2021-07-26 00:10:23 +00:00
jan iversen
15ec9fbf6c Late review comment in edl21 (#53464)
* Late review comment.

* Review comment.

* pylint.

* Update homeassistant/components/edl21/sensor.py

* Callback typing.

* Complete typing

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-25 18:59:14 -04:00
David Kendall
f3ba71748b Feature/google calendar read only support (#52790)
* feat(google): Added support for read only access in google calendar.

By default the current read/write access will be given, but the user has the option to set read only access which stops the add event service from registering

* fix(google): Updated documentation link

* docs(google-calendar): Added style fixes

* feat(calendar-google): Updated scopes to be defined on enum property.

This was done as a MR suggestion to simplify the code.

* feat(calendar-google):Removed constants no longer needed.

* feat(calendar-google): Reduced scope check to minimum.

* style: Fixed style issues
2021-07-25 12:33:21 -07:00
Dermot Duffy
5e6853b9e1 Codereview fixes. (#53452) 2021-07-25 22:23:11 +03:00
G Johansson
5741a59d08 Bugfix package 0.3.4 (#53470) 2021-07-25 22:17:45 +03:00
Aidan Timson
d18ca62f60 Bump aioambient to 1.2.4 (#53467) 2021-07-25 12:23:38 -06:00
Dermot Duffy
5189172b80 Pass clientsession. (#53455) 2021-07-25 19:58:50 +02:00
Simone Chemelli
33af2602af Fix wan/device uptime and add state_class to counters for Fritz (#52574)
* Fix wan/device uptime, add state_class to counters

* Rebase + cleanup + adapt to final fritzconnection

* Bump fritzconnection library

* Missing bump
2021-07-25 20:43:31 +03:00
Daniel Hjelseth Høyer
ff8affdd04 Address late review of Adax (#53456)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2021-07-25 12:32:50 +02:00
Aidan Timson
c8d2fc1e04 Fix System Bridge unique key for filesystem sensors (#53446) 2021-07-25 12:31:16 +02:00
Robert Hillis
7e59f3160b Use entity class attributes for climacell (#53444) 2021-07-25 02:19:08 -04:00
GitHub Action
c1b18f4867 [ci skip] Translation update 2021-07-25 00:12:45 +00:00
Shay Levy
68bf6194e1 Add myself to webOS TV codeowners (#53428) 2021-07-24 21:45:24 +02:00
G Johansson
a5eb2ac7b7 Bump yalesmartalarmclient to 0.3.4 (#53431) 2021-07-24 21:13:06 +02:00
G Johansson
f0d5ae2fec Add yale_smart_alarm config flow and coordinator (#50850)
* config flow and coordinator

* comply with pylint

* Remove pylint errors

* Update test coverage yale smart alarm

* Update test config_flow

* Fix test already configured

* Second try test already configured

* Fixes config flow and tests

* Conform pylint errors coordinator

* Fix various review remarks

* Correct entity unique id

* Fix unique id and migrate entries

* Remove lock code

* Remove code from test

* Expand code coverage config flow test

* Add more constants

* Add test new requirements

* Minor corrections

* Resolve conflict alarm schema

* Change logger

* Changed from review

* Fix isort error

* Fix flake error

* Ignore mypy errors

* Corrections from PR review no 2

* Corrections from PR review no 3

* Added tests and fix pylint error

* Corrections from PR review no 4

* Corrections from PR review no 5

* Corrections from PR review no 6

* Corrections from PR review no 6_2

* Corrections from PR review no 7

* Corrections from PR review no 8

* Minor last changes for PR

* Update homeassistant/components/yale_smart_alarm/coordinator.py

Co-authored-by: Raman Gupta <7243222+raman325@users.noreply.github.com>
2021-07-24 13:55:43 -04:00
J. Nick Koston
0f15d2bf19 Ensure HomeKit accessories are started again after reset (#53372) 2021-07-24 16:31:30 +02:00
Bram Gerritsen
87e41e807c Add support for Velux light devices (#49338)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-24 15:52:14 +02:00
David Beitey
ea1ec91c9c Upgrade open-garage to 0.1.5 (#53412) 2021-07-24 15:49:39 +02:00
Matthias Alphart
993756e90a Test KNX select (#53371)
* test KNX select

* cover everything

* Update tests/components/knx/test_select.py
2021-07-24 15:25:58 +02:00
Aaron Bach
54ace4cdd4 Enforce strict typing for OpenUV (#53409)
* Enforce strict typing for OpenUV

* Linting

* Fix tests
2021-07-24 14:50:01 +02:00
Michael
5c86cc502f Bump to py-synologydsm-api 1.0.3 (#53402) 2021-07-24 14:44:50 +02:00
Bouwe Westerdijk
e65283389d Update Plugwise config_flow once more (#53423) 2021-07-24 14:28:33 +02:00
J. Nick Koston
6d493a848c Ensure PyPI packages can still be installed on high latency connections (#53365) 2021-07-24 14:07:10 +02:00
Matthias Alphart
745314b115 Test KNX services (#53367) 2021-07-24 14:03:04 +02:00
Robert Hillis
16e8373fdd Use entity class attributes for advantage_air (#52498)
* Use entity class attributes for advantage_air

* update

* tweak

* tweak

* use update listeners
2021-07-24 13:00:41 +02:00
Jon Caruana
72a3860361 Add transition to LiteJet (#47657) 2021-07-24 12:43:10 +02:00
Samuel Tardieu
0f78004ede Add missing string interpolation (#53422) 2021-07-24 12:13:21 +02:00
Dermot Duffy
ffa7962a37 Fix motionEye switch refresh bug (#53413) 2021-07-24 12:12:27 +02:00
Robert Hillis
4b393f215d Use entity class attributes for asuswrt (#52685)
* Use entity class attributes for asuswrt

* fix

* tweak
2021-07-24 11:55:54 +02:00
Jc2k
0db160e372 Handle homekit accessories where the pairing flag is wrong (#53385) 2021-07-23 20:03:44 -10:00
Guido Schmitz
bf3a16eed4 Use class attributes in devolo Home Control (#53360) 2021-07-23 21:48:32 -07:00
GitHub Action
7fa8586b17 [ci skip] Translation update 2021-07-24 00:08:57 +00:00
Paulus Schoutsen
c49decb7f0 Convert CO2Signal to data update coordinator and add fossil fuel percentage (#53370)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Daniel Hjelseth Høyer <mail@dahoiv.net>
2021-07-23 14:35:11 -07:00
Robert Svensson
d0bef97453 Handle situations where action is part of a deCONZ event but has the value None (#53373)
* Handle situations where action is part of an event but has the value None

* Cover more possible permutations of what a bad action string is
2021-07-23 21:43:00 +02:00
Robert Svensson
0d5e480397 Fix Gira and Jung models not working as deCONZ device triggers (#53394) 2021-07-23 21:18:19 +02:00
Aaron Bach
4b353917f5 Enforce strict typing for Notion (#53355)
* Enforce strict typing for Notion

* Code review
2021-07-23 13:00:02 -06:00
Jc2k
91018d0451 Add support for power data from Koogeek SW2 via homekit_controller (#53378) 2021-07-23 07:37:18 -10:00
Franck Nijhof
d8887a97e3 Upgrade debugpy to 1.4.0 (#53284) 2021-07-23 12:57:36 -04:00
Børge Nordli
87165d6133 Support group events for AC switches and binary sensors. Fixes #53065. (#53384)
* Support group events for AC switches and binary sensors. Fixes #53065.

* Review comments
2021-07-23 18:45:31 +02:00
Raman Gupta
952cb964c8 Add new input to zwave_js.multicast_set_value service (#53369)
* Tweak Z-Wave JS service and WS API commands

* Revert WS API change so it can be split out

* Add keywords
2021-07-23 10:35:44 -04:00
Raman Gupta
9ee7e55f10 Send initial status in zwave_js WS API cmds to subscribe to updates (#53386) 2021-07-23 10:34:49 -04:00
Franck Nijhof
0d38ee7378 Upgrade wled to 0.8.0 (#53376) 2021-07-23 14:03:46 +02:00
Michael
42e8a7c842 Move Fritzbox power, energy and temperature switch attributes to sensors (#52562)
* deprecate switch entity properties

* Add last_reset to FritzBoxEnergySensor

* Remove obsolet temperature attribute
2021-07-23 13:06:30 +02:00
Dermot Duffy
dee5d8903c Add motionEye switches (#52491) 2021-07-22 23:17:39 -07:00
Robert Hillis
1d44bfcfb6 Use entity class attributes for Cert expiry (#53363)
* Use entity class attributes for cert_expiry

* Use entity class attributes for cert_expiry
2021-07-23 07:54:06 +02:00
Tobias Sauerwein
0b6e1d3d82 Bump version (#53359) 2021-07-22 22:01:24 -04:00
GitHub Action
969be5c539 [ci skip] Translation update 2021-07-23 00:12:05 +00:00
Anders Melchiorsen
e85b0ec052 Move Sonos to upstream SoCo (#53351) 2021-07-23 00:40:30 +02:00
J. Nick Koston
bfdbb93d2d Bump HAP-python to 3.5.2 (#53362) 2021-07-22 12:06:37 -10:00
Franck Nijhof
c875ff8648 Store JSON in database in compact format (#53364)
* Store JSON in database in compact format

* Fix logbook
2021-07-22 12:05:59 -10:00
Robert Hillis
12503d548b Use entity class attributes for canary (#53333)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-22 22:40:32 +02:00
Hans Oischinger
84dc6af760 Update to PyVicare 1.0 (#53281) 2021-07-22 21:56:38 +02:00
Paulus Schoutsen
0b71055989 Do not automatically add title to strings.json (#53350) 2021-07-22 21:11:10 +02:00
Simone Chemelli
75f7d3d696 Replace util.get_local_ip in favor of components.network.async_get_source_ip() - part 1 (#52980) 2021-07-22 08:12:33 -10:00
Tom Harris
3461f61f9f Create APIs for Insteon panel (#49785) 2021-07-22 08:11:36 -10:00
Aaron Bach
032cae772a Bump aionotion to 3.0.2 (#53354) 2021-07-22 12:04:27 -06:00
jjlawren
0707792bec Handle more Sonos snapshot restore scenarios (#53277) 2021-07-22 08:04:02 -10:00
Simone Chemelli
b2528e97b6 Making Pytest default for VS code (#53203) 2021-07-22 09:30:54 -07:00
Ian Harcombe
74023fce21 Fix for issue #53031 (#53343)
Logs from issue #53031 show that not only ints are appearing in the values for the forecast data now, so change the check from just for int, to see whether the value has a "value" attribute before dereferencing it.
2021-07-22 09:24:47 -07:00
Guido Schmitz
c9c1c62d67 Add state class and last reset to consumption sensor in devolo Home Control (#53337)
* Add state class and last reset

* Use STATE_CLASS_MEASUREMENT
2021-07-22 09:24:06 -07:00
Michael
24e07bc154 Fritzbox enable temp sensor (#52558) 2021-07-22 09:19:39 -07:00
Paulus Schoutsen
ccfe32257e Merge pull request #53305 from home-assistant/rc 2021-07-22 09:10:35 -07:00
Franck Nijhof
258162d933 Upgrade wled to 0.7.3 (#53340) 2021-07-22 16:35:19 +02:00
Marc Mueller
f778467d63 Use NamedTuple - rainbird (#53329)
* Use NamedTuple - rainbird

* Apply suggestions from code review

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

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-22 15:29:50 +02:00
Robert Hillis
d371ab9deb Use entity class attributes for caldav (#53332) 2021-07-22 14:47:30 +02:00
sillyfrog
d3e77e00e1 Add Automate Pulse Hub v2 support (#39501)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Sillyfrog <sillyfrog@users.noreply.github.com>
2021-07-22 14:40:33 +02:00
Sergiy Maysak
f009b1442f Switch wirelesstag to use cloud push (#50984) 2021-07-22 13:40:39 +02:00
Guido Schmitz
ff781583fc Remove energy attributes from switch platform in devolo Home Control (#53335) 2021-07-22 12:59:39 +02:00
J. Nick Koston
009f34bfed Add a homekit.unpair service to forcefully remove pairings (#53303)
- Sometimes homekit will go unresponsive because a pairing for a specific
  device is missing. To avoid deleting the config entry and recreating
  it, which can be a painful process if there are many bridged entities,
  the homekit.unpair service allows forceful removal of the pairings so
  the accessory can be paired again.
2021-07-22 12:44:36 +02:00
Marc Mueller
80c535f02e Use NamedTuple - rova (#53292)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-22 12:26:50 +02:00
Rami Mosleh
1a450c2084 Speedtestdotnet code cleanup and type hints (#52533) 2021-07-22 12:25:54 +02:00
Marc Mueller
7768f53281 Use NamedTuple - brother (#53330) 2021-07-22 10:36:29 +02:00
Jan Bouwhuis
9753500f5e Disable speeds for first gen Xiaomi_miio air purifiers (#52772)
* Disable speeds for first gen air purifiers

* Remove test code line

* remove OPERATION_MODES_AIRPURIFIER list
2021-07-22 08:57:29 +02:00
Robert Hillis
804499968e Use entity class attributes for Bluesound (#53033)
* Use entity class attributes for bluesound

* rework

* tweak

* tweak
2021-07-22 08:51:14 +02:00
J. Nick Koston
4df928c188 Add support for updating the ISY ip address from discovery (#53290)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-22 08:38:55 +02:00
Paulus Schoutsen
ce382a39d0 Block title in strings.json unless internal or allowed (#53304) 2021-07-22 08:37:33 +02:00
Raman Gupta
b9a6ce77d1 Bump zwave-js-server-python to 0.28.0 (#53302) 2021-07-22 02:37:10 -04:00
Aaron Bach
1bde914075 Ensure Guardian is strictly typed (#53253) 2021-07-21 23:01:05 -07:00
Paulus Schoutsen
d4ef0be6e9 Bumped version to 2021.7.4 2021-07-21 22:55:47 -07:00
J. Nick Koston
464986921e Fix homekit locks not being created from when setup from the UI (#53301) 2021-07-21 22:55:36 -07:00
Steven Looman
bffef87103 Upgrade to async-upnp-client==0.19.1 (#53288) 2021-07-21 22:55:35 -07:00
Paulus Schoutsen
df72eb7ebb Correctly detect is not home (#53279) 2021-07-21 22:55:34 -07:00
Anders Melchiorsen
a0411aab4b Upgrade pysonos to 0.0.53 (#53137) 2021-07-21 22:55:34 -07:00
Ben
5e4f02b0f9 Bump surepy to 0.7.0 (#53123) 2021-07-21 22:55:33 -07:00
J. Nick Koston
255d5a5339 Bump nexia to 0.9.10 to fix asair login (#53122) 2021-07-21 22:55:32 -07:00
Aaron Bach
ffe0d72667 Bump simplisafe-python to 11.0.2 (#53121)
* Bump simplisafe-python to 11.0.2

* Fix CI
2021-07-21 22:55:31 -07:00
Robert Svensson
f3cb202136 More restrictive state updates of UniFi uptime sensor (#53111)
* More restrictive state updates of uptime sensor

* Remove commented out old version of uptime test
2021-07-21 22:55:30 -07:00
jgriff2
1c05329b5d Fix remote rpi gpio input type (#53108)
* Fix issue #45770 - Change sensor from Button to DigitalInput

* Change references from button to sensor
2021-07-21 22:55:29 -07:00
Eric Severance
8a009f1374 Handle all WeMo ensure_long_press_virtual_device exceptions (#53094)
* Handle all exceptions around the WeMo ensure_long_press_virtual_device method

* Don't use a bare exception

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

* Log exception

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-21 22:55:29 -07:00
Robert Svensson
6eb2fd7603 Fix groups reporting incorrect supported color modes (#53088) 2021-07-21 22:55:28 -07:00
jan iversen
0e297c288f Allow pymodbus to reconnect in running system (not startup) (#53020)
Allow pymodbus to reconnect (not during startup).
2021-07-21 22:55:27 -07:00
Marc Mueller
560bde94ef Use NamedTuple - epsonworkforce (#53295) 2021-07-21 22:28:02 -07:00
Marc Mueller
551c117717 Use NamedTuple - ondilo_ico (#53296) 2021-07-21 22:27:31 -07:00
Marc Mueller
5c3fb77660 Use NamedTuple - glances (#53297) 2021-07-21 22:27:01 -07:00
Marc Mueller
f5480481cd Use NamedTuple - metoffice (#53294) 2021-07-21 22:25:38 -07:00
Marc Mueller
d98e580c3c Use NamedTuple - nws (#53293) 2021-07-21 22:24:07 -07:00
J. Nick Koston
e78a62c802 Fix homekit locks not being created from when setup from the UI (#53301) 2021-07-21 22:22:06 -07:00
Paulus Schoutsen
596179d180 Avoid dataclass incompat with mock spec (#53298) 2021-07-22 02:12:14 +02:00
GitHub Action
ecf0d4398d [ci skip] Translation update 2021-07-22 00:10:31 +00:00
Paulus Schoutsen
edf42bab25 Migrate forecast solar to v2 (#53259) 2021-07-21 15:04:30 -07:00
Matthias Alphart
9f14b2cef5 Test KNX switch (#53289) 2021-07-21 15:04:14 -07:00
Paulus Schoutsen
86752516ee Add WS API to access solar forecast data (#53264)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-21 23:48:21 +02:00
Tobias Sauerwein
583deada83 Add type annotations for Netatmo (#52811) 2021-07-21 14:36:57 -07:00
J. Nick Koston
84c482441d Use None instead of STATE_UNKNOWN in template lock (#53286) 2021-07-21 14:29:41 -07:00
Steven Looman
34b1ab5f5c Upgrade to async-upnp-client==0.19.1 (#53288) 2021-07-21 14:29:27 -07:00
Franck Nijhof
cfd69de5a7 Upgrade PyNaCl to 1.4.0 (#53287) 2021-07-21 14:28:22 -07:00
RenierM26
f3d95501d9 Add refresh after turning switch on or off and type annotations to ezviz (#52469) 2021-07-21 23:15:47 +02:00
Aaron Bach
8d9345c407 Add missing type annotations to Airvisual (#52615) 2021-07-21 22:18:08 +02:00
cnico
6636e5b737 Flipr integration (#46582)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: cnico <>
2021-07-21 21:35:44 +02:00
Robert Hillis
3eb3c2824c Refactor goalzero (#53282) 2021-07-21 20:52:17 +02:00
Marc Mueller
fd2f15b7c7 Add new unit constants (#53258)
* Add new unit constant - MHz

* Add new unit constants - precipitation (in, in/h)
2021-07-21 12:14:47 -06:00
Paulus Schoutsen
ba00c786b0 Correctly detect is not home (#53279) 2021-07-21 19:45:07 +02:00
jan iversen
217c625c9b Convert ebox to use NamedTuple (#53272)
* Convert to use NamedTuple.

* Convert to NamedTuple.

* Use _attr variables.

* Review comments.
2021-07-21 19:43:33 +02:00
jan iversen
aed7cb9120 Convert skybell to use NamedTuple (#53269)
* Convert to NamedTuple.

* Second version.

* Use names instead of index.

* Review comments.

* Add meta variable.

* Review comment.

* Review comments.
2021-07-21 19:42:30 +02:00
Robert Hillis
a1df3519db Use entity class attributes for Bsblan (#53165) 2021-07-21 19:37:12 +02:00
Simone Chemelli
db1a8e9336 Fix similar network names for Fritz (#53278) 2021-07-21 19:31:51 +02:00
Marc Mueller
2d48d273a7 Fix incorrect unit (#53274) 2021-07-21 10:12:32 -07:00
Maciej Bieniek
772cbd59d7 Improve typing in Shelly integration (#52544) 2021-07-21 10:11:44 -07:00
Michael
f128bc9ef8 Add reauth flow to Synology DSM (#53204) 2021-07-21 09:16:27 -07:00
Robert Hillis
800f7fe3a5 Use entity class attributes for Broadlink (#53058)
* Clanup broadlink

* rework

* tweak

* fix using wrong attribute

* tweak

* revert device info
2021-07-21 15:27:52 +02:00
Robert Hillis
0803b2aecd Use entity class attributes for arest (#52678) 2021-07-21 14:32:42 +02:00
Robert Hillis
668437741a Use entity class attributes for Bmw connected drive (#53054)
* Use entity class attributes for bmw_connected_driv

* forgot the icon
2021-07-21 14:09:54 +02:00
Robert Hillis
7fef87691a Use entity class attributes for airvisual (#52503)
* Use entity class attributes for airvisual

* fix

* rework

* tweaks

* finish

* remove overriden available attribute

* rework
2021-07-21 14:07:26 +02:00
Robert Hillis
462db1b4b2 Add config flow to nfandroidtv (#51280)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-21 13:31:54 +02:00
Robert Hillis
02a7a2464a Use entity class attributes for atag (#52686) 2021-07-21 11:33:44 +02:00
Robert Hillis
81c4d95afe Use entity class attributes for arduino (#52677)
* Use entity class attributes for arduino

* Revert state

* tweak

* tweak
2021-07-21 11:31:50 +02:00
Daniel Hjelseth Høyer
e9ce3c57cd Adax heaters (#50998)
Co-authored-by: G Johansson <62932417+gjohansson-ST@users.noreply.github.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-21 10:25:46 +02:00
muppet3000
18ec0544b9 Allow for alternative external Growatt servers (#53102) 2021-07-21 10:16:02 +02:00
Franck Nijhof
4546e14674 Fix MQTT to allow setting an unknown Select state (#53227) 2021-07-21 10:02:07 +02:00
Daniel Hjelseth Høyer
9b2d98f027 Tibber, use nameclass (#53242) 2021-07-21 08:56:29 +02:00
Paulus Schoutsen
5e059c7f55 Fix lint on dev (#53265) 2021-07-21 08:55:34 +02:00
Robert Hillis
930db7167e Code quality improvements for goalzero (#53260) 2021-07-21 08:53:53 +02:00
Daniel Hjelseth Høyer
2cf930f3bd Netatmo, use nameclass (#53247) 2021-07-21 08:46:01 +02:00
jan iversen
7306503756 Calculate count automatically in modbus platforms (#53116) 2021-07-20 22:49:54 -07:00
jan iversen
2e2b340b1e Set modbus entity to non-available unless scan_interval=0 (#53155) 2021-07-20 22:48:02 -07:00
Daniel Hjelseth Høyer
8a72e8df79 Convert Mill consumption attributes to sensors (#52311) 2021-07-20 22:41:08 -07:00
Raman Gupta
90765132cc Make additional input for zwave_js device triggers optional (#53134) 2021-07-20 22:08:08 -07:00
Joakim Plate
8a7cb389ed Drop support for fan speeds and support reverse (#53105) 2021-07-20 22:07:15 -07:00
J. Nick Koston
fe89603ee7 Update homekit lock to support locking, unlocking, jammed (#52819) 2021-07-20 21:55:19 -07:00
J. Nick Koston
564a505486 Update homekit controller lock to support locking, unlocking, jammed (#52821) 2021-07-20 23:55:04 -05:00
J. Nick Koston
ee242764a1 Update template lock to support locking, unlocking, jammed (#52817) 2021-07-20 21:50:21 -07:00
J. Nick Koston
5d85983b09 Update google assistant locks to support locking, unlocking, jammed (#52820) 2021-07-20 23:49:05 -05:00
J. Nick Koston
bfe3ef0980 Update august to support locking, unlocking, jammed (#52814) 2021-07-20 21:48:15 -07:00
J. Nick Koston
0ce071e0a4 Bump httpx to 0.18.2 (#53257) 2021-07-20 21:47:13 -07:00
J. Nick Koston
f20602e11d Auto recreate HomeKit TVs when the sources are out of sync (#53208) 2021-07-20 21:46:39 -07:00
J. Nick Koston
2a65c5f93c Recreate HomeKit accessories when calling the reset_accessory service (#53199) 2021-07-20 21:45:21 -07:00
J. Nick Koston
4d122fc366 Update alexa lock to support locking, unlocking, jammed (#52841) 2021-07-20 23:21:05 -05:00
jan iversen
8f61efe714 Correct typing in edl21 and activate mypy. (#53188) 2021-07-20 21:53:56 -05:00
Aaron Bach
56efee4603 Ensure Ambient PWS is strictly typed (#53251)
* Ensure Ambient PWS is strictly typed

* Fix typing
2021-07-20 21:52:05 -05:00
Nathan Spencer
9d3bc0632f Bump pylitterbot to 2021.7.2 (#53254)
* Bump pylitterbot to 2021.7.1

* Bump pylitterbot dependency to 2021.7.2 which unpins Authlib and httpx dependencies
2021-07-20 15:47:37 -10:00
Steven Looman
72bc748081 Avoid supplemental discovery of ignored upnp entry (#53250) 2021-07-20 15:46:33 -10:00
GitHub Action
9d93f8b6d1 [ci skip] Translation update 2021-07-21 00:11:58 +00:00
Brett
6ee82e1031 Advantage Air add zone temperature sensors (#51941)
* Create AdvantageAirZoneTemp

* Disable by default

* Add test coverage

* add state_class

* Use entity class attributes

* Match code style of PR #52498
2021-07-20 19:38:50 -04:00
Aaron Bach
0fd88e7e66 Type _attr_extra_state_attributes as a MutableMapping (#52616)
* Type extra_state_attributes as a MutableMapping

* Update homeassistant/helpers/entity.py

Co-authored-by: Ruslan Sayfutdinov <ruslan@sayfutdinov.com>

* Update homeassistant/helpers/entity.py

Co-authored-by: Ruslan Sayfutdinov <ruslan@sayfutdinov.com>
2021-07-20 15:41:03 -06:00
jtitley
0b8b45818d Update BlinkStick to 1.2.0 (#52244)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-20 22:57:47 +02:00
Robert Hillis
a9b9c4f13c Add extra state attributes to goalzero (#52932)
* Add extra state attributes to goalzero

* tweak
2021-07-20 22:26:52 +02:00
Franck Nijhof
059a9bc8ed Fix modbus setting string as temperature in climate platform (#53249) 2021-07-20 22:03:10 +02:00
web-dc
034251f006 Update requirement of homematicip_cloud component to v1.0.1 (#51407)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Sascha Schiegg <s.schiegg@s-schiegg.com>
2021-07-20 20:28:43 +02:00
PeteRager
5ccbac5ff6 Fix alert infinite loop on repeat interval of 0 (#52628)
* #4851 - Infinite loop on repeat interval of 0

Notification will enter an infinite loop when the repeat interval is specified as zero and it is the last repeat configured.  When this occurs avoid the infinite loop and log a warning message.  Note: I encountered this issue when routing SMS to Twilio and quickly sent thousands of text messages.

* Update __init__.py

* Remove runtime check since configuration input is now blocked

* Tweak comment

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-20 20:23:22 +02:00
jjlawren
a2fbc4218d Cleanup regroup handling in Sonos (#53241)
Check event before creating coroutine
Remove unnecessary regrouping dispatcher
Update typing to reflect actual behavior
Add optimizations for polling mode
2021-07-20 20:21:48 +02:00
jan iversen
8c43e5c736 Correct set_temperature in modbus climate (#52923) 2021-07-20 20:19:26 +02:00
Daniel Hjelseth Høyer
a14bde8187 Melcloud use NamedTuple (#53234)
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2021-07-20 20:18:09 +02:00
Marc Mueller
6be30b0289 Use unit constants (#53244)
* Powerwall - use POWER_KILO_WATT constant

* Use constants firtz sensor
2021-07-20 20:08:39 +02:00
Daniel Hjelseth Høyer
a05392fbf2 Tibber, remove yaml support (#53235) 2021-07-20 20:07:06 +02:00
Marc Mueller
074d762664 Rename and reorganize electric unit constants (#53243) 2021-07-20 20:06:23 +02:00
Raman Gupta
6e88428f95 Fix typing for climacell dataclass (#53240) 2021-07-20 19:31:55 +02:00
Daniel Hjelseth Høyer
165e1917ea Address late review of Ambiclimate, code clean up (#53231)
* Ambiclimate, code clean up

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Update homeassistant/components/ambiclimate/climate.py

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

* Update homeassistant/components/ambiclimate/climate.py

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

* Update homeassistant/components/ambiclimate/config_flow.py

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

* Update homeassistant/components/ambiclimate/climate.py

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

* import

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-20 18:57:40 +02:00
Paulus Schoutsen
1ed7b00b71 Add last reset and state class to rainforest eagle (#52951) 2021-07-20 18:39:14 +02:00
Simone Chemelli
1746103e0e Add friendly name to Fritz profile switches (#53190) 2021-07-20 18:38:16 +02:00
jan iversen
193d1b945b Add typing in dynalite and activate mypy (#53238)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-20 18:28:31 +02:00
J. Nick Koston
9b705ad6df Update lock entity to support locking, unlocking, jammed (#51455) 2021-07-20 18:12:56 +02:00
Daniel Hjelseth Høyer
0cc4231ac2 Tibber use dataclass (#53233)
* Tibber, use dataclass

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Tibber, use dataclass

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2021-07-20 17:57:35 +02:00
Daniel Hjelseth Høyer
2b9b346a28 Address late review of Co2 signal (#53232) 2021-07-20 17:52:22 +02:00
Allen Porter
1fe2d0f9c8 Address style issues in nest typing (#53236)
* Add additional types for config flow

Fixing style errors introduced by partial typing in pr #53214

* Address typing style errors

Make all functions fully typed, follow up to pr #53214
2021-07-20 17:41:48 +02:00
jan iversen
f819be7acc Correct typing in Insteon and activate mypy (#53222) 2021-07-20 17:26:00 +02:00
Marc Mueller
c578541a82 Add new electrical unit constants (mV + mA) (#53158) 2021-07-20 15:57:11 +02:00
Robert Hillis
08f03c95d2 Use entity class attributes for Brunt (#53164) 2021-07-20 14:18:09 +02:00
Marc Mueller
a56485a8c5 Revert new unit types (#53226) 2021-07-20 14:13:51 +02:00
Franck Nijhof
b4a50f5459 Add unique ID support to light, cover and media player groups (#53225) 2021-07-20 13:56:23 +02:00
jan iversen
51dd95ce35 Review comments on earlier merge. (#53221) 2021-07-20 13:00:07 +02:00
Daniel Hjelseth Høyer
d17776af87 Tibber, accumulated reward (#53195)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2021-07-20 12:28:50 +02:00
Robert Hillis
79a418f1bc Use entity class attributes for Brottsplatskartan (#53163) 2021-07-20 12:20:56 +02:00
Marc Mueller
5d2ce19746 Update python-typing-update to v0.3.5 (#53223)
* Update python-typing-update to 0.3.5

* Update typing
2021-07-20 11:31:48 +02:00
Robert Hillis
cd37c2492b Use entity class attributes for acer_projector (#52432)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2021-07-20 11:13:59 +02:00
Raman Gupta
05fa220703 Add support for options in zwave_js.set_value service (#53212) 2021-07-20 10:31:12 +02:00
jan iversen
e7ccd1a549 Correct typing and activate mypy. (#53217) 2021-07-20 10:53:24 +03:00
Eric Severance
ab36ac7a94 Handle all WeMo ensure_long_press_virtual_device exceptions (#53094)
* Handle all exceptions around the WeMo ensure_long_press_virtual_device method

* Don't use a bare exception

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

* Log exception

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-20 09:20:47 +02:00
dependabot[bot]
e453871c68 Bump codecov/codecov-action from 1.5.2 to 2.0.1 (#53216)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1.5.2 to 2.0.1.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v1.5.2...v2.0.1)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-20 09:37:36 +03:00
Alexei Chetroi
c9ae141eab Mark ZHA Light methods as a callbacks (#53170)
* ZHA Light.set_level is safe to run in the loop

* Fix tests.
2021-07-20 09:33:45 +03:00
Kyle Niewiada
7659197154 Increase interval to stop Connection reset by peer (#53202) 2021-07-20 08:15:11 +02:00
Allen Porter
c2a2f50316 mypy cleanup for homeassistant.components.nest (#53214) 2021-07-20 07:59:31 +02:00
jan iversen
78a8ba99f9 Upgrade modbus to quality level "silver". (#53186) 2021-07-19 23:57:28 -05:00
jan iversen
19a282255b Remove duplicate functions in modbus climate/sensor. (#53141)
Convert all data types correctly for climate.
2021-07-19 23:52:58 -05:00
Simone Chemelli
18bc2f95c8 Small log addition for samsungtv (#53206) 2021-07-19 23:41:30 -05:00
Matthias Alphart
e8d7952880 Refactor KNX tests (#53183)
* refactor tests for KNX

- implement KNXTestKit class for convenient setup and assertion of KNX telegrams
- add fixture returning an instance of KNXTestKit with automatic cleanup test

* add tests for expose default attribute

- fix expose edge case not covered by #53046

* use asyncio.Queue instead of AsyncMock.call_args_list

for better readability

* get xknx from Mock instead of hass.data

* fix type annotations

* add injection methods for incoming telegrams

* rest read-response in expose
2021-07-19 23:39:19 -05:00
Daniel Hjelseth Høyer
f0b28c90bf Co2signal configflow (#53193)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2021-07-19 21:30:00 -07:00
Raman Gupta
562aa74c77 Switch to dataclass from dictionary for climacell sensor definitions (#53168)
* Switch to dataclass from dictionary for climacell sensor definitions

* fix post_init

* fix dataclass and add test

* Update homeassistant/components/climacell/sensor.py

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

* Update homeassistant/components/climacell/const.py

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

* simplify logic

* use tuple

* simplify unit of measurement and use class attributes

* Switch from UnitT to str

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2021-07-20 00:22:41 -04:00
Marc Mueller
7711ac901c Fix issues after pylint update (#53205) 2021-07-19 20:22:13 -07:00
GitHub Action
ac9e4cb2f2 [ci skip] Translation update 2021-07-20 00:11:11 +00:00
RDFurman
450fdc91e4 Add honeywell config flow (#50731)
* Upgrade honeywell from platform to integration

* Add codeowner and run code formatter

* Add sensors for current indoor temp and humidity

* Fix tests and away temp

* Spring cleaning of honeywell tests

* Add config flow to honeywell integration

* Add config flow test

* Tie in honeywell service update

* Simplify config flow and add import

* Remove unnecessary platform schema

* Clean up based on PR comments

* Use new helper method

* Force single device and fix linter errors

* Address PR feedback

* Update translations

* Change string key and remove logger message

* Always add first device

* Fix test assertion

* Put PLATFORM_SCHEMA back

* Skip code coverage check on honeywell init

* add some tests for honeywell

* Make retry async

* Make device private

* Use _attr_ instead of properties

* Code cleanup from PR feedback

* Fix test and cleanup code

* Make description better

Co-authored-by: Matt Zimmerman <mdz@alcor.net>
2021-07-19 09:44:02 -10:00
Robert Hillis
f5b3118d3c Use entity class attributes for buienradar (#53166) 2021-07-19 21:22:20 +02:00
Robert Hillis
8527179c0e Use entity class attributes for bme280 (#53035)
* Use entity class attributes for bme280

* add back device class oops

* tweak
2021-07-19 22:19:36 +03:00
Michael
1b478ba02e Remove yaml support from Synology DSM (#53197) 2021-07-19 19:39:32 +02:00
jan iversen
d4589894fe Correct typing in bsblan and activate mypy (#53153) 2021-07-19 19:30:52 +02:00
Franck Nijhof
3d40fdf2c6 Upgrade holidays to 0.11.2 (#53191) 2021-07-19 19:01:19 +02:00
Franck Nijhof
8743a03f14 Upgrade numpy to 1.21.1 (#53194) 2021-07-19 19:00:37 +02:00
jjlawren
225732d00e Remove I/O in Plex tests (#53196) 2021-07-19 18:50:04 +02:00
Franck Nijhof
dd8ec04e58 Upgrade black to 21.7b0 (#53192) 2021-07-19 18:03:02 +02:00
Robert Hillis
3c6f0d11a6 Use entity class attributes for Citybikes (#53167)
* Use entity class attributes for citybikes

* tweak
2021-07-19 18:02:09 +02:00
Aaron Bach
bf4ca2d68d Modify AirVisual states to be translatable (#53133)
* Modify AirVisual states to be translatable

* Make constant names consistent
2021-07-19 18:01:36 +02:00
jan iversen
0865917eeb Activate mypy in aurora (#53150) 2021-07-19 17:59:41 +02:00
Robert Hillis
019568869d Use entity class attributes for avea (#52695)
* Use entity class attributes for avea

* fix pylint

* redo brightness

* redo brightness
2021-07-19 17:50:26 +02:00
jan iversen
0b60b86917 Correct typing in azure_devops and activate mypy (#53152)
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2021-07-19 17:45:03 +02:00
Clifford Roche
327208c943 Bugfix current temperature in gree climate (#53149)
* Bugfix current temperature gree climate

* Retry build

* Update from the review
2021-07-19 17:07:15 +02:00
Marc Mueller
f6b162bc39 Add pylint CodeStyle extension (#53147) 2021-07-19 06:57:06 -07:00
Marc Mueller
c35b5a1c64 Add sound pressure unit constants (dB + dBa) (#53159) 2021-07-19 06:54:38 -07:00
Shay Levy
ea6e325762 Add Switcher config flow discovery support (#52316) 2021-07-19 06:28:40 -07:00
jan iversen
51d16202ab Correct typing in control4 and activate mypy (#53156)
* Correct typing and activate mypy.

* Review comments.:wq
2021-07-19 14:14:09 +02:00
jan iversen
0802dd4293 Activate mypy for eafm (#53184) 2021-07-19 13:05:13 +02:00
jan iversen
78ef02f4d9 Allow pymodbus to reconnect in running system (not startup) (#53020)
Allow pymodbus to reconnect (not during startup).
2021-07-19 13:01:50 +02:00
J. Nick Koston
12b29e2895 Bump zeroconf to 0.33.1 (#53179) 2021-07-19 12:10:32 +02:00
J. Nick Koston
671e838085 Execute scripts from HomeKit (#53106) 2021-07-19 12:07:12 +02:00
Robert Hillis
7b27725ec1 Cleanup redundant coveragerc entries (#53171) 2021-07-19 12:00:38 +02:00
J. Nick Koston
f51cb110d3 Run pyupgrade on homekit config_flow (#53180)
- The original PR was run though the CI before the new pyupgrade
2021-07-18 23:33:08 -10:00
Arto Jantunen
bf0b19b05e Add CO2 and efficiency sensors to Vallox (#48923)
* Add Vallox efficiency sensor

* Add Vallox CO2 sensor

* Use the CO2 device class for the Vallox CO2 sensor
2021-07-19 10:56:26 +02:00
Robert Svensson
d12110556f More restrictive state updates of UniFi uptime sensor (#53111)
* More restrictive state updates of uptime sensor

* Remove commented out old version of uptime test
2021-07-19 10:54:31 +02:00
Allen Porter
3cff15ae2f Bump google-nest-sdm to 0.3.0 (#53172)
The primary update is to have additional static type checking with mypy
2021-07-19 10:50:22 +02:00
Ville Skyttä
470f2dd73f Upgrade pyupgrade to 2.21.2, apply its changes (#52987) 2021-07-19 10:46:09 +02:00
Robert Svensson
c96f01df1f Fix groups reporting incorrect supported color modes (#53088) 2021-07-19 10:32:21 +02:00
J. Nick Koston
bf831267cf Bump zeroconf to 0.33.0 (#53174)
- Changelog: https://github.com/jstasiak/python-zeroconf/compare/0.32.1...0.33.0
2021-07-19 10:22:12 +02:00
jan iversen
235f4476e8 Please mypy. (#53142) 2021-07-19 08:29:26 +02:00
J. Nick Koston
f24576b08d Show the name of the domain in HomeKit when selecting to include (#53169) 2021-07-18 17:55:56 -10:00
Brett
eeb01e638a Add _attr_state_class (#52815) 2021-07-18 20:03:46 -05:00
Robert Hillis
6b97a5ba8e Fix hisense_aehw4a1 test exclusion (#53084)
* Fix hisense_aehw4a1 test coverage

* add back __init__

* remove from hassfest

Co-authored-by: Chris Talkington <chris@talkingtontech.com>
2021-07-18 19:17:36 -05:00
GitHub Action
531733da7b [ci skip] Translation update 2021-07-19 00:09:50 +00:00
Roman Shtylman
cb6f9878c4 Update pylutron-caseta to 0.11.0 (#53160) 2021-07-18 13:07:38 -10:00
Robert Hillis
c5fe01a466 Use entity class attributes for blinkt (#52893)
* Use entity class attributes for blinkt

* tweak

* tweak

* remove redundant properties
2021-07-18 17:21:40 -04:00
Robert Hillis
73976d2a26 Use entity class attributes for Blink (#52891)
* Use entity class attributes for blink

* rework

* revert extra state attributes
2021-07-18 17:21:12 -04:00
Robert Hillis
0cf95bb0c2 Use entity class attributes for arwn (#52683) 2021-07-18 17:19:25 -04:00
jgriff2
bacb6c6b14 Fix remote rpi gpio input type (#53108)
* Fix issue #45770 - Change sensor from Button to DigitalInput

* Change references from button to sensor
2021-07-18 17:13:13 -04:00
Aaron Bach
a8ea214f2e Bump simplisafe-python to 11.0.2 (#53121)
* Bump simplisafe-python to 11.0.2

* Fix CI
2021-07-18 17:12:05 -04:00
J. Nick Koston
236738c455 Add support for tilt only covers to HomeKit (#53130) 2021-07-18 10:17:58 -10:00
Robert Hillis
cb1eab6c24 Use entity class attributes for bosch_shc (#53057) 2021-07-18 15:10:42 -05:00
Robert Hillis
284e13464d Fix home plus control coverage (#53087)
* Fix home_plus_control test coverage

* add back api, switch
2021-07-18 14:56:54 -05:00
Robert Hillis
fe22d5a675 Fix home_connect test coverage (#53086)
* Fix home_connect test coverage

* remove from hassfest exclusions
2021-07-18 14:54:43 -05:00
Clifford Roche
56d66434b3 Bump greeclimate to 0.11.8 (#53148) 2021-07-18 14:51:02 -05:00
J. Nick Koston
0804959f11 Bump nexia to 0.9.10 to fix asair login (#53122) 2021-07-18 09:37:34 -10:00
J. Nick Koston
6c05e2746d Improve error message when HomeKit does not support an entity (#53129) 2021-07-18 09:27:25 -10:00
Anders Melchiorsen
61056afe0d Upgrade pysonos to 0.0.53 (#53137) 2021-07-18 19:00:02 +02:00
Marc Mueller
71a8ae3016 Add new unit types for better type checking (#53124)
* Add new unit types
* Update helper functions
* Update components
* Update lcn climate
2021-07-18 14:43:47 +02:00
Ben
78f4a49b73 Bump surepy to 0.7.0 (#53123) 2021-07-18 08:49:07 +02:00
Clifford Roche
b63e38f538 Add more Gree switches (#49629)
* Support additional switch for gree devices

* Undo some changes not related to review

* Retry build

* Back to Gree 0.11.7
2021-07-18 08:24:09 +02:00
GitHub Action
8f3166a955 [ci skip] Translation update 2021-07-18 00:10:14 +00:00
Brett
7fe3f78c24 Bump library version for Advantage Air (#52813)
* Bump library version

* Bump version to 0.2.5

* Add tests to cover this edge case
2021-07-17 14:45:29 +03:00
kpine
24cc5c8a0a Replace local Barrier CC constants with library enums (#53109) 2021-07-17 02:54:11 -04:00
GitHub Action
e6e1118dd4 [ci skip] Translation update 2021-07-17 00:09:24 +00:00
jjlawren
0277a645f1 Log source of discovery in Sonos (#53101) 2021-07-16 11:12:01 -10:00
Robert Hillis
4fceac00b1 Use entity class attributes for Bond (#53055) 2021-07-16 11:06:18 -10:00
Simone Chemelli
b13119884c Fix units for Fritz network sensors (#53026) 2021-07-16 11:01:00 -07:00
Bouwe Westerdijk
669883d416 Update Plugwise Config Flow (#47563)
Co-authored-by: Tom Scholten <git@scholten.nu>
2021-07-16 06:46:23 -10:00
p4p3r
9d79c4f617 Add On/Off as target values for zwave_js cover stop action (#52881)
* Add On/Off as target values for stop cover

Certain ZWave Cover devices use On/Off instead of the more common
Open/Close and Up/Down targets for movement.
Adding On/Off to the targets used to stop the cover during movement.
Fixes issue #51963

* Add test for updated zwave_js stop cover logic
2021-07-16 15:48:35 +02:00
stefano055415
6672962f2b Add fan support to Freedompro (#52724)
* Update Freedompro

* Update Freedompro fix async_turn_on

* fix test end fix comments

* add property is_on

* add percent to fan freedompro

* fix name rotationSpeed to rotation_speed

* fix code SUPPORT_SET_SPEED
2021-07-16 15:14:37 +02:00
Aaron David Schneider
3d3db4b044 Replace fritz profile switches by per device parental control switches (#52721)
* removes old profile switches and add new switches based on new method

* use Ellipsis instead of pass

* refactor async_add_profile_switches

* - add forgotten update_ha_state
- add notimplemtederror for devicebase

* Update homeassistant/components/fritz/common.py

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

* Update homeassistant/components/fritz/common.py

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

* comments

* fix for devices that were not connected

* Update homeassistant/components/fritz/common.py

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

* Update homeassistant/components/fritz/switch.py

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

Co-authored-by: J. Nick Koston <nick@koston.org>
2021-07-16 13:38:37 +02:00
Robert Hillis
7d52c30e36 Revert "Fix google test coverage (#53060)" (#53085)
This reverts commit 4075e83732.
2021-07-16 07:13:34 -04:00
stefano055415
1a1fcb94f9 Add cover support to Freedompro (#52723)
* Update Freedompro

* add new test and fix code

* fix test and add support open and close
2021-07-16 11:56:05 +02:00
Hmmbob
31074ef6b8 Update name from "generic" to "generic camera" (#53080) 2021-07-16 11:46:47 +02:00
Guido Schmitz
268c7ef768 Rewrite mocking in devolo Home Control tests (#53011)
* Rework mocking

* Instantiate properties
2021-07-16 11:40:08 +02:00
Franck Nijhof
bcab1414f8 Merge pull request #53076 from home-assistant/rc
2021.7.3
2021-07-16 10:28:42 +02:00
Franck Nijhof
ae40ba6a74 Bumped version to 2021.7.3 2021-07-16 09:46:32 +02:00
Erik Montnemery
1295daa10e Add light white parameter to light/services.yaml (#53075) 2021-07-16 09:45:54 +02:00
Vincent Le Bourlot
a6ad08f5b6 Increase polling interval to prevent reaching daily limit (#53066)
* increase polling interval to prevent reaching daily limit

* update test accordingly
2021-07-16 09:45:50 +02:00
Paulus Schoutsen
c5070da20e Expose Spotify as a service (#53063) 2021-07-16 09:45:46 +02:00
da-anda
2da660b76e Fix knx expose feature not correctly falling back to default value (#53046) 2021-07-16 09:45:43 +02:00
Eduard van Valkenburg
acf705a958 Another SIA fix for timestamp not present. (#53045) 2021-07-16 09:45:40 +02:00
Daniel Hjelseth Høyer
4802157146 Co2signal, set SCAN_INTERVAL (#53023)
* limit co2signal, wip

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* limit co2signal

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* limit co2signal

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2021-07-16 09:45:36 +02:00
Eduard van Valkenburg
c90fa90faf fix for timestamp not present in SIA (#53015) 2021-07-16 09:45:33 +02:00
Andre Lengwenus
762f5a5d18 Bump pypck to 0.7.10 (#53013) 2021-07-16 09:45:29 +02:00
Peter Nijssen
3050d9350a Update pyrainbird to 0.4.3 (#52990) 2021-07-16 09:45:25 +02:00
René Klomp
4e2042b63d Bump pysma to 0.6.4 (#52973) 2021-07-16 09:45:22 +02:00
Tom Harris
4ddfaf41ee Fix issue connecting to Insteon Hub v2 (#52970) 2021-07-16 09:45:17 +02:00
jjlawren
f17ed626bb More graceful exception handling in Plex library sensors (#52969) 2021-07-16 09:44:37 +02:00
Ron Klinkien
cea22a9d5e Bump python-fireservicerota to 0.0.43 (#52966) 2021-07-16 09:42:13 +02:00
J. Nick Koston
ddf563c247 Add OUIs for legacy samsungtv (#52928) 2021-07-16 09:40:58 +02:00
J. Nick Koston
d2e82edb58 Handle dhcp packets without a hostname (#52882)
* Handle dhcp packets without a hostname

- Since some integrations only match on OUI we want to
  make sure they still see devices that do not request
  a specific hostname

* Update tests/components/dhcp/test_init.py

* Update homeassistant/components/dhcp/__init__.py

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

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-16 09:37:22 +02:00
Doug Hoffman
47b5866d85 Bump pyatv to 0.8.1 (#52849)
* Bump pyatv to 0.8.1

* Update apple_tv tests for new create_session location

* Update test_user_adds_unusable_device to try device with no services

pyatv >=0.8.0 considers AirPlay a valid service and no longer fails under the previous conditions.
2021-07-16 09:37:19 +02:00
jan iversen
1d67e66538 only allow one active call in each platform. (#52823) 2021-07-16 09:37:15 +02:00
jan iversen
29fb5e0cb2 copy() --> deepcopy(). (#52794) 2021-07-16 09:37:12 +02:00
puddly
8bd73709a7 Update ZHA to support zigpy 0.34.0 device initialization (#52610)
* Handle `None` node descriptors

* Skip loading uninitialized devices

* Fix unit test incorrectly handling unset cluster `ep_attribute`

* Revert filtering devices by status during startup
2021-07-16 09:37:07 +02:00
Erik Montnemery
c6e1f8878d Add light white parameter to light/services.yaml (#53075) 2021-07-16 09:03:28 +02:00
René Klomp
da7b292855 Use Utility Meter configured name as friendly name (#53051) 2021-07-15 20:58:32 -07:00
Robert Hillis
4075e83732 Fix google test coverage (#53060) 2021-07-15 20:56:57 -07:00
GitHub Action
62a2efaf27 [ci skip] Translation update 2021-07-16 00:10:34 +00:00
Vincent Le Bourlot
cf647c5d20 Increase polling interval to prevent reaching daily limit (#53066)
* increase polling interval to prevent reaching daily limit

* update test accordingly
2021-07-15 17:24:54 -04:00
Paulus Schoutsen
989839a1a9 Generate const files for config flow scaffolds (#53064) 2021-07-15 19:57:06 +02:00
Paulus Schoutsen
d30ed05f30 Expose Spotify as a service (#53063) 2021-07-15 10:27:18 -07:00
Robert Hillis
c7b61fd8ce Use entity class attributes for androidtv (#52531)
* Use entity class attributes for androidtv

* fix

* fix pylint

* fix
2021-07-15 15:35:42 +02:00
Robert Hillis
35cab74be6 Use entity class attributes for Bloomsky (#53030)
Co-authored-by: Tobias Sauerwein <cgtobi@users.noreply.github.com>
2021-07-15 15:29:12 +02:00
Robert Hillis
00741d4273 Use entity class attributes for agent_dvr (#52501)
* Use entity class attributes for agent_dvr

* Apply suggestions from code review

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

* rework

Co-authored-by: Milan Meulemans <milan.meulemans@live.be>
2021-07-15 14:57:51 +02:00
J. Nick Koston
19b4d2e4d2 Add OUIs for legacy samsungtv (#52928) 2021-07-15 14:43:35 +02:00
da-anda
6fe38eadf2 Fix knx expose feature not correctly falling back to default value (#53046) 2021-07-15 14:41:04 +02:00
Joakim Sørensen
519efd2723 Handle missing peername (#53052)
* Handle missing peername

* Add test
2021-07-15 14:16:30 +02:00
Robert Hillis
6c476b5c1e Use entity class attributes for Bmp280 (#53036) 2021-07-15 12:35:47 +02:00
Jan Bouwhuis
c9eab10134 Add MQTT humidifier platform integration (#52828)
* New mqtt humidifier platform

* Add humidifier platform

* Leave out humidity step

* Use humidity in constant for payload reset

* change TARGET_HUMIDITY_RESET payload name

* _attr_max_humidity not assigned correctly

* _target_humidity_range has a zero base

* align CONF_TARGET_HUMIDITY_MIN and MAX  with model

* shorter topics for humidity_range

* Converts float to int from template

* new humidifier abbreviations

* Add common module to support tests

* Add tests

* Addtional testing

* Always require target_humidity_command_topic

* Typo

* use available_modes to align entity model

* use avail_modes not modes to avoid conflict

* typo target_humidity_value_template

* Allign modes and templates with climate platform

* mode_state_template

* target_humidity_state_template

* Typo in platform name

* Remove humidity_range feature and common lib

* Update homeassistant/components/mqtt/humidifier.py

Use vol.In, not regex

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

* black

* Update homeassistant/components/mqtt/humidifier.py

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

* Use round to convert float to target humidity

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2021-07-15 11:12:23 +02:00
Robert Hillis
8ce4d647c3 Use entity class attributes for arcam_fmj (#52675)
* Use entity class attributes for arcam_fmj

* fix
2021-07-15 10:19:18 +02:00
Robert Hillis
eee3aa3b6f Use entity class attributes for bme680 (#53037)
* Use entity class attributes for bme680

* fix
2021-07-15 10:00:47 +02:00
stefano055415
a057fd93bb Add lock support Freedompro (#52725)
* change _attr_unique_id to unique_id and resolve conflict

* add test state updates from the API

* optimizer code test

* fix test

* fix comments and add test device registry
2021-07-15 09:31:50 +02:00
Eduard van Valkenburg
f07d64c813 Another SIA fix for timestamp not present. (#53045) 2021-07-15 09:31:17 +02:00
Robert Hillis
5ff9c3e611 Clean up freedompro (#52992) 2021-07-15 09:27:31 +02:00
dependabot[bot]
82256b2588 Bump actions/stale from 3.0.19 to 4 (#53042)
Bumps [actions/stale](https://github.com/actions/stale) from 3.0.19 to 4.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v3.0.19...v4)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-15 09:43:07 +03:00
Franck Nijhof
a5cdc0157b Remove deprecated YAML configuration from Buienradar (#52939) 2021-07-15 08:31:17 +02:00
Tom Brien
db97fd3d5b Support user-defined base currency for Coinbase exchange rate sensors (#52879) 2021-07-14 21:50:23 -07:00
Daniel Hjelseth Høyer
f152369944 Use entity class attributes for Co2signal (#53032) 2021-07-14 21:47:24 -07:00
Daniel Hjelseth Høyer
fbad453c89 Pylint 2.9.3 (#52972)
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2021-07-14 21:44:57 -07:00
GitHub Action
db8db18b54 [ci skip] Translation update 2021-07-15 00:09:25 +00:00
Raman Gupta
dd908caeba Add zwave_js device triggers (#51968)
* Initial support for zwave_js device triggers

* lint

* Add node status changed trigger

* comments

* create helper function and simplify trigger logic

* simplify code

* fix exception

* remove unused type ignore

* switch to append to make future changes easier

* make exception consistent

* Add state config schema validation

* comment

* remove 0 from falsy check

* increase test coverage

* typos

* Add central scene and scene activation value notification triggers

* reorder things for readability and enumerate node statuses

* Add support for Basic CC value notifications

* fix schemas since additional fields on triggers aren't very flexible

* pylint

* remove extra logger statement

* fix comment

* dont use get when we know key will be available in dict

* tweak text

* use better schema for required extra fields that are ints

* rename trigger types to make them easier to parse

* fix strings

* missed renaming of one trigger type

* typo

* Fix strings

* reduce complexity

* Use Al's suggestion for strings

* add additional failure test cases

* remove errant logging statement

* make CC required

* raise vol.Invalid when value ID isn't legit to prepare for next PR

* Use helper function

* fix tests

* black
2021-07-14 14:14:36 -04:00
Raman Gupta
4d711898c7 Add missing test coverage for sirens (#53014) 2021-07-14 20:04:04 +02:00
Eduard van Valkenburg
7e16d38fc8 fix for timestamp not present in SIA (#53015) 2021-07-14 20:01:16 +02:00
Andre Lengwenus
49d109a969 Bump pypck to 0.7.10 (#53013) 2021-07-14 19:59:11 +02:00
Daniel Hjelseth Høyer
2740e56fd4 Co2signal, set SCAN_INTERVAL (#53023)
* limit co2signal, wip

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* limit co2signal

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* limit co2signal

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2021-07-14 19:58:02 +02:00
Raman Gupta
1f15181522 Add support for Z-Wave JS siren (#52948)
* Add support for Z-Wave JS siren

* Add additional device class to discovery

* fix docstring

* Remove device class specific part of discovery schema

* rename test

* switch to entry.async_on_remove

* Fix logic based on #52971

* Use constants to unblock PR

* Add support to set volume level

* Update homeassistant/components/zwave_js/siren.py

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

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-14 10:14:13 -04:00
Erik Montnemery
e541bcd54d Update statistics meta data on entity_id change (#52755) 2021-07-14 13:23:11 +02:00
Franck Nijhof
8c36f5c627 Deprecate Lyft integration (#53005) 2021-07-14 12:07:00 +02:00
Erik Montnemery
ddc788bf8e Include future statistics in history/list_statistic_ids (#52942)
* Include future statistics in history/list_statistic_ids

* Improve tests
2021-07-14 11:54:55 +02:00
J. Nick Koston
30d465e9dd Update homekit to use network integration (#52946) 2021-07-14 11:44:58 +02:00
jan iversen
c360d6009c copy() --> deepcopy(). (#52794) 2021-07-14 11:00:16 +02:00
Franck Nijhof
2c3f3d7bda Remove defunct Weather Underground integration (#52999) 2021-07-14 10:55:06 +02:00
Franck Nijhof
03dd2e326c Remove flume for allowed ignore coverage violations (#53001) 2021-07-14 10:54:52 +02:00
Doug Hoffman
88fb30af11 Bump pyatv to 0.8.1 (#52849)
* Bump pyatv to 0.8.1

* Update apple_tv tests for new create_session location

* Update test_user_adds_unusable_device to try device with no services

pyatv >=0.8.0 considers AirPlay a valid service and no longer fails under the previous conditions.
2021-07-14 10:45:47 +02:00
Raman Gupta
f13a15f2a6 Make zwave_js value updated event logic more performant (#52997) 2021-07-14 08:56:10 +02:00
GitHub Action
7b7062dded [ci skip] Translation update 2021-07-14 00:10:16 +00:00
Peter Nijssen
9cd6a9626e Update pyrainbird to 0.4.3 (#52990) 2021-07-13 18:10:23 -04:00
Robert Hillis
d76607e945 Use entity class attributes for august (#52744) 2021-07-13 09:56:34 -10:00
jan iversen
12ac666459 only allow one active call in each platform. (#52823) 2021-07-13 21:45:42 +02:00
Erik Montnemery
19d3aa71ad Enable basic type checking for recorder (#52440)
* Enable basic type checking for recorder

* Tweak
2021-07-13 21:21:45 +02:00
Tom Harris
960684346f Fix issue connecting to Insteon Hub v2 (#52970) 2021-07-13 20:27:04 +02:00
jjlawren
f39f087b10 More graceful exception handling in Plex library sensors (#52969) 2021-07-13 20:22:31 +02:00
Ron Klinkien
ff56ede960 Bump python-fireservicerota to 0.0.43 (#52966) 2021-07-13 20:21:50 +02:00
Raman Gupta
794571efdd Add missing device classes for climacell sensors (#52979) 2021-07-13 20:13:56 +02:00
Robert Hillis
7f0eff8230 Use entity class attributes for Blackbird (#52889)
* Use entity class attributes for blackbird

* rework

* undo media_title
2021-07-13 20:08:22 +02:00
Robert Hillis
2b65501ca7 Use entity class attributes for aquostv (#52670)
* Use entity class attributes for aquostv

* fix

* fix

* Tweak

* tweak
2021-07-13 20:06:41 +02:00
Raman Gupta
026ca4e4e4 Additional fixes for siren platform (#52971) 2021-07-13 10:56:41 -07:00
Erik Montnemery
777fec62a5 Set device class for climacell temperature sensors (#52965) 2021-07-13 13:35:55 -04:00
René Klomp
23b0633ae2 Bump pysma to 0.6.4 (#52973) 2021-07-13 19:33:53 +02:00
Robert Hillis
3d419d1e8a Fix flume converagerc (#52975) 2021-07-13 19:32:55 +02:00
puddly
987c7a289a Update ZHA to support zigpy 0.34.0 device initialization (#52610)
* Handle `None` node descriptors

* Skip loading uninitialized devices

* Fix unit test incorrectly handling unset cluster `ep_attribute`

* Revert filtering devices by status during startup
2021-07-13 19:31:17 +02:00
stefano055415
7aaa08f153 Add binary_sensor support to Freedompro (#52717)
* Update Freedompro

* change _attr_unique_id with unique_id
2021-07-13 18:37:09 +02:00
Robert Hillis
55b0d562ce Use entity class attributes for automation (#52694)
* Use entity class attributes for automation

* tweak
2021-07-13 15:01:43 +02:00
Erik Montnemery
e563dc0d7b Set device_class on additional temperature sensors (#52960)
* Set device_class on additional temperature sensors

* Apply suggestions from code review

Co-authored-by: Tobias Sauerwein <cgtobi@users.noreply.github.com>

* Set device class for greeneye_monitor sensor

* Set device class for bme280 and bme680 sensor

Co-authored-by: Tobias Sauerwein <cgtobi@users.noreply.github.com>
2021-07-13 14:20:47 +02:00
stefano055415
96f6e0e4a4 Add sensor support to Freedompro (#52726)
* Update Freedompro

* Update tests/components/freedompro/test_sensor.py

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

* add new test for sensor and add unit_of measurement and state_class

* add test state updates from the API

* optimizer code test

* optimizer code sensor

* Update homeassistant/components/freedompro/sensor.py

* Fix imports

* Update homeassistant/components/freedompro/sensor.py

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

* Update homeassistant/components/freedompro/sensor.py

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

* Update homeassistant/components/freedompro/sensor.py

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

Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-13 13:59:34 +02:00
Shulyaka
e9948100a7 Add generic hygrostat integration (#36759)
* generic_hygrostat: new integration
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: jan Iversen <jancasacondor@gmail.com>
2021-07-13 13:25:29 +02:00
Erik Montnemery
3408912ded Improve docstring for async_get_device_class_lookup (#52921) 2021-07-13 10:55:18 +02:00
Raman Gupta
30def802fc Validate tone is valid when processing siren.turn_on service call (#52953)
* Validate tone is valid when processing siren.turn_on service call

* Better message
2021-07-13 10:42:35 +02:00
Lincoln Kirchoff
ac39607ae9 Fix modbus climate precision configuration variable (#52651)
* Updated precision to follow the tenths, halves, whole notation used by
other home assistant climate modules. Added the precision @property so
that home assistant can handle this rounding in the frontend, rather
than in the _async_read_register() method.

* Fixed a pylinter error for periods in user-facing log messages, and
updated `precision` defaults in components/modbus/__init__.py to be
consistent with an error case, using `PRECISION_WHOLE`.

* revert changes to `precision:` configuration variable
instead, the climate `precision()` function will infer whether or not
to display in whole or tenths. halves will be unsupported, which should
be fine.

* re-added missing line that was removed

* revert change to use self._input_type instead of CALL_TYPE_REGISTER_HOLDING
2021-07-13 10:36:54 +02:00
Erik Montnemery
c5556a091e Return empty when listing statistic_ids for unsupported statistic (#52954) 2021-07-13 10:35:55 +02:00
Raman Gupta
9cbf88d944 Switch to using entry.async_on_remove (#52952) 2021-07-13 10:31:49 +02:00
J. Nick Koston
a021d7d628 Expose async_get_source_ip in the network integration (#52901)
* Expose async_get_source_ip in the network integration

* Handle source ip on disabled interface

* add coverage
2021-07-13 10:26:00 +02:00
stefano055415
d09035db2a Add switch support to Freedompro (#52727)
* Update Freedompro

* add test state updates from the API

* fix test switch

* fix test
2021-07-13 09:41:52 +02:00
Erik Montnemery
b49fb1f657 Minor test coverage improvement of mfi and zwave sensors (#52935) 2021-07-13 08:38:31 +02:00
Raman Gupta
4a058503ca Change behavior of Z-Wave JS services (#52941)
* Change behavior of Z-Wave JS services

* pop parameters in for loop

* Update logger message
2021-07-13 01:02:36 -04:00
Raman Gupta
e915f5be53 Handle FailedCommand exceptions in zwave_js WS API (#52461)
* Handle zwave-js errors in WS API

* Unsubscribe callbacks when zwave-js error is caught

* fix tests

* simplify unsub logic

* add tests

* add kwargs to be safe

* use existing msg format

* switch to generic failed command handling

* remove unneeded constant

* Update homeassistant/components/zwave_js/api.py

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

* Update homeassistant/components/zwave_js/api.py

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

* fix

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-13 00:13:43 -04:00
Raman Gupta
92e4013f73 Fix siren turn on parameter filtering (#52947)
* Fix siren turn on parameter filtering

* fix test
2021-07-12 22:18:04 -04:00
GitHub Action
6723942bf8 [ci skip] Translation update 2021-07-13 00:13:03 +00:00
Tobias Sauerwein
4afede9e08 Add schedule selector for Netatmo (#52909)
Co-authored-by: Joakim Sørensen <hi@ludeeus.dev>
2021-07-12 15:27:48 -07:00
Robert Hillis
fe5abf1a87 Use entity class attributes for aqualogic (#52668) 2021-07-13 00:22:50 +02:00
Ville Skyttä
9864f2ef8b String formatting cleanups (#52937) 2021-07-13 00:12:55 +02:00
Paulus Schoutsen
f4359f98b3 Merge pull request #52936 from home-assistant/rc 2021-07-12 14:38:48 -07:00
jjlawren
2970931d8d Use entity class attributes for Plex (#52617) 2021-07-12 23:01:58 +02:00
Paulus Schoutsen
e095b9a1b9 Bumped version to 2021.7.2 2021-07-12 13:57:47 -07:00
jjlawren
86589b401b Bump pysonos to 0.0.52 (#52934) 2021-07-12 13:57:22 -07:00
J. Nick Koston
0b04e0d5da Fix recorder purge with sqlite3 < 3.32.0 (#52929) 2021-07-12 13:57:21 -07:00
Tom Harris
3301783c57 Bump pyinsteon to 1.0.11 (#52927) 2021-07-12 13:57:20 -07:00
Daniel Hjelseth Høyer
fd848911a6 Surepetcare, fix set_lock_state (#52912)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2021-07-12 13:57:20 -07:00
Raman Gupta
ed200ee4fd Bump zwave-js-server-python to 0.27.1 (#52885) 2021-07-12 13:57:19 -07:00
Robert Svensson
2a5b447bfd Prefer using xy over hs when supported by light (#52883) 2021-07-12 13:57:18 -07:00
Joakim Sørensen
d1eadd28b2 Bump pyhaversion to 21.7.0 (#52880) 2021-07-12 13:57:17 -07:00
J. Nick Koston
725a021c2e Bump aiohomekit to 0.5.1 to solve performance regression (#52878)
- Changelog: https://github.com/Jc2k/aiohomekit/compare/0.5.0...0.5.1

- Note that #52759 will need to be cherry-picked under this commit
2021-07-12 13:57:17 -07:00
Joakim Plate
279c34f606 Update arcam lib to 0.7.0 (#52829) 2021-07-12 13:57:16 -07:00
Alexei Chetroi
4e82659f3a Bump up ZHA depdencies (#52818) 2021-07-12 13:57:15 -07:00
Ron Klinkien
320ca40124 Bump python-fireservicerota to 0.0.42 (#52807) 2021-07-12 13:57:15 -07:00
J. Nick Koston
798f3eada2 Add the Trane brand to nexia (#52805) 2021-07-12 13:57:14 -07:00
Simone Chemelli
473f109428 Fix Neato parameter for token refresh (#52785)
* Fix param

* cleanup
2021-07-12 13:57:13 -07:00
Otto Winter
f7c65e7c8b Fix ESPHome Camera not merging image packets (#52783) 2021-07-12 13:57:12 -07:00
Brandon Rothweiler
df3c8586b5 Upgrade pymazda to 0.2.0 (#52775) 2021-07-12 13:57:12 -07:00
Robert Svensson
ce20ca7bb6 Bump dependency to properly handle current and voltage not being reported on some zhapower endpoints (#52764) 2021-07-12 13:57:11 -07:00
J. Nick Koston
87d4544531 Send ssdp requests to ipv4 broadcast as well (#52760)
* Send ssdp requests to 255.255.255.255 as well

- This matches pysonos behavior and may fix reports of
  inability to discover some sonos devices
  https://github.com/amelchio/pysonos/blob/master/pysonos/discovery.py#L120

* Update homeassistant/components/ssdp/__init__.py
2021-07-12 13:57:10 -07:00
Jc2k
763f8ac6a8 Support certain homekit devices that emit invalid JSON (#52759) 2021-07-12 13:57:10 -07:00
J. Nick Koston
8af63cd9a0 Fix nexia thermostats humidify without dehumidify support (#52758) 2021-07-12 13:57:09 -07:00
Jc2k
f4fa0d7789 Fix homebridge devices becoming unavailable frequently (#52753)
Update to aiohomekit 0.4.3 and make sure service type UUID is normalised before comparison

Co-authored-by: J. Nick Koston <nick@koston.org>
2021-07-12 13:57:08 -07:00
apaperclip
757388cc31 Remove scale calculation for climacell cloud cover (#52752) 2021-07-12 13:57:07 -07:00
J. Nick Koston
edf517681c Add zeroconf discovery to Sonos (#52655) 2021-07-12 13:57:07 -07:00
jjlawren
f447adc5b6 Ignore Sonos Boost devices during discovery (#52845) 2021-07-12 13:56:36 -07:00
Otto Winter
4d16cda957 ESPHome enable static type checking (#52348) 2021-07-12 22:56:10 +02:00
Robert Hillis
9b2107b71f Use entity class attributes for Blebox (#52890)
* Use entity class attributes for blebox

* rework

* Apply suggestions from code review

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

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-12 22:52:38 +02:00
jjlawren
ab5fd70988 Bump pysonos to 0.0.52 (#52934) 2021-07-12 13:50:51 -07:00
Robert Hillis
7ef4bd53ec Use entity class attributes for Blockchain (#52894)
* Use entity class attributes for blockchain

* rework

* tweak
2021-07-12 22:49:38 +02:00
Robert Hillis
adb5fd5a03 Use entity class attributes for bbox (#52838)
* Use entity class attributes for bbox

* tweak
2021-07-12 22:47:58 +02:00
Erik Montnemery
9b8a776001 Set device_class on temperature sensors A-E (#49524)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-12 22:45:29 +02:00
J. Nick Koston
0099b54489 Fix recorder purge with sqlite3 < 3.32.0 (#52929) 2021-07-12 22:03:13 +02:00
J. Nick Koston
e6ea9f4708 Fix nexia thermostats humidify without dehumidify support (#52758) 2021-07-12 21:39:51 +02:00
bwduncan
ee52706f03 Poll Nissan servers for battery updates (#44826) 2021-07-12 08:57:08 -10:00
Erik Montnemery
d1f3c20079 Set device_class on temperature sensors L-Q (#52919) 2021-07-12 20:41:45 +02:00
Milan Meulemans
0a3aab935a Use properties instead of raw data in the rituals integration (#52587) 2021-07-12 20:40:16 +02:00
Erik Montnemery
3e09787d85 Set device_class on temperature sensors F-K (#52918)
* Set device_class on temperature sensors F-K

* Fix juicenet sensor
2021-07-12 20:32:55 +02:00
jan iversen
646862ec96 Add array write to turn_on/off in modbus switch/fan/light (#52582) 2021-07-12 11:22:53 -07:00
Ron Klinkien
8f8935c859 Bump python-fireservicerota to 0.0.42 (#52807) 2021-07-12 11:21:10 -07:00
Erik Montnemery
5e472f2c06 Improve typing of Tasmota (1/3) (#52746) 2021-07-12 20:14:03 +02:00
jan iversen
5caf170c78 Correct Wrong "raise" in modbus validators. (#52924) 2021-07-12 11:06:31 -07:00
Franck Nijhof
5c200581b6 Upgrade sentry-sdk to 1.3.0 (#52926) 2021-07-12 20:03:40 +02:00
Tom Harris
ec8f11f1e3 Bump pyinsteon to 1.0.11 (#52927) 2021-07-12 20:02:56 +02:00
Erik Montnemery
2e44e256f0 Improve typing of Tasmota (3/3) (#52748) 2021-07-12 19:17:44 +02:00
Erik Montnemery
1a74fd7a14 Set device_class on temperature sensors R-Z (#52920) 2021-07-12 18:53:52 +02:00
Robert Hillis
ad0ccc1b70 Use entity class attributes for apple_tv (#52664)
* Use entity class attributes for apple_tv

* fix pylint

* tweak
2021-07-12 18:29:34 +02:00
Erik Montnemery
8c812bc25c Improve typing of Tasmota (2/3) (#52747)
* Improve typing of Tasmota (2/3)

* Add more typing, add TasmotaOnOffEntity

* Address review comments
2021-07-12 18:27:11 +02:00
J. Nick Koston
98109caee9 Add zeroconf discovery to Sonos (#52655) 2021-07-12 18:24:12 +02:00
J. Nick Koston
6a5dcf0869 Handle dhcp packets without a hostname (#52882)
* Handle dhcp packets without a hostname

- Since some integrations only match on OUI we want to
  make sure they still see devices that do not request
  a specific hostname

* Update tests/components/dhcp/test_init.py

* Update homeassistant/components/dhcp/__init__.py

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

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-12 17:25:16 +02:00
Tobias Sauerwein
40549d9d2f Add some type hints for webhook component (#52895)
* Add some type hints

* Fix type hint

* Address comment

* Make pylint happy
2021-07-12 17:24:56 +02:00
jjlawren
2b6a3716e8 Ignore Sonos Boost devices during discovery (#52845) 2021-07-12 17:09:45 +02:00
Tom Brien
9308fa28e7 Improve testing of option flow in Coinbase (#52870) 2021-07-12 16:46:54 +02:00
J. Nick Koston
0f6a0f6bcd Add the Trane brand to nexia (#52805) 2021-07-12 16:30:54 +02:00
J. Nick Koston
a810c1ff08 Bump aiohomekit to 0.5.1 to solve performance regression (#52878)
- Changelog: https://github.com/Jc2k/aiohomekit/compare/0.5.0...0.5.1

- Note that #52759 will need to be cherry-picked under this commit
2021-07-12 16:13:07 +02:00
Robert Hillis
11edbcabc8 Use entity class attributes for Bitcoin (#52887)
* Use entity class attributes for bitcoin

* rework

* fix

* tweak
2021-07-12 16:03:27 +02:00
Daniel Hjelseth Høyer
900eab5a68 Surepetcare, fix set_lock_state (#52912)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2021-07-12 15:57:26 +02:00
dependabot[bot]
96e78631fc Bump dessant/lock-threads from 2.0.3 to 2.1.1 (#52899)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-12 11:44:35 +02:00
Robert Hillis
01afd141c6 Use entity class attributes for Bizkaibus (#52888) 2021-07-12 10:37:14 +02:00
Marc Mueller
5d2e5d2612 Import Protocol from typing (#52848) 2021-07-12 10:35:17 +02:00
Robert Hillis
a1d6e12c45 Use entity class attributes for Bh1750 (#52886)
* Use entity class attributes for bh1750

* rework
2021-07-12 10:20:15 +02:00
Robert Hillis
12555d09d6 Use entity class attributes for Blinksticklight (#52892)
* Use entity class attributes for blinksticklight

* rework

* remove self._serial
2021-07-12 09:48:42 +02:00
Simone Chemelli
13c142a402 Fix Soundbar exclusion from SamsungTV (#51023)
* Improved check

* Fix tests

* Fix logic and tests

* Update tests
2021-07-12 08:58:53 +02:00
Robert Svensson
fd6b5ed072 Prefer using xy over hs when supported by light (#52883) 2021-07-12 08:17:50 +02:00
jan iversen
2ecfd74fa4 Add more data_types to modbus (#52423)
* Add more data_types.

* Use new struct when writing temperature.
2021-07-12 07:58:45 +02:00
Ville Skyttä
91a2b96da0 Implement stable unique id for Huawei LTE, requires credentials on setup (#49878) 2021-07-11 21:25:00 -07:00
Raman Gupta
e652ef51a1 Initial support for zwave_js device conditions (#52003) 2021-07-11 21:22:33 -07:00
GitHub Action
2ddaf746e6 [ci skip] Translation update 2021-07-12 00:09:46 +00:00
Leszek Swirski
e556722281 Add device classes to homematicip_cloud cover (#52793)
Make HMIP covers report a SHUTTER/BLIND/GARAGE device_class (as
appropriate).
2021-07-11 18:51:28 -04:00
J. Nick Koston
574cb03acc Send ssdp requests to ipv4 broadcast as well (#52760)
* Send ssdp requests to 255.255.255.255 as well

- This matches pysonos behavior and may fix reports of
  inability to discover some sonos devices
  https://github.com/amelchio/pysonos/blob/master/pysonos/discovery.py#L120

* Update homeassistant/components/ssdp/__init__.py
2021-07-11 17:03:48 -04:00
Raman Gupta
0f076610fd Add siren platform (#48309)
* Add siren platform

* add more supported flags and an ability to set siren duration

* tone can be int or string

* fix typing

* fix typehinting

* fix typehints

* implement a proposed approach based on discussion

* Address comments

* fix tests

* Small fix

* Update homeassistant/components/demo/siren.py

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

* Update homeassistant/components/demo/siren.py

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

* Update homeassistant/components/demo/siren.py

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

* Update homeassistant/components/demo/siren.py

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

* Update homeassistant/components/demo/siren.py

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

* typing

* use class attributes

* fix naming

* remove device from service description

* Filter out params from turn on service

* fix tests

* fix bugs and tests

* add test

* Combine is_on test with turn on/off/toggle service tests

* Update homeassistant/components/siren/__init__.py

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

* fix filtering of turn_on attributes

* none check

* remove services and attributes for volume level, default duration, and default tone

* Update homeassistant/components/siren/__init__.py

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

* Update homeassistant/components/siren/__init__.py

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

* Update homeassistant/components/siren/__init__.py

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

* import final

* Update homeassistant/components/siren/__init__.py

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

* Fix typing and used TypedDict for service parameters

* remove is_on function

* remove class name redundancy

* remove extra service descriptions

* switch to positive_int

* fix schema for tone

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-11 16:51:11 -04:00
EddyK69
11d7efb785 Add AllTrips sensors for BMW Connected Drive (#50420)
* Add AllTrips sensors for BMW Connected Drive

Added several new AllTrips sensors and some optional extra AllTrips sensors (disabled by default)

* Fix for failed checks

* Fix for failed check (black)

* Code tidying

Changed code after useful comments ;)
2021-07-11 16:47:32 -04:00
Robert Hillis
c865a1876e Use entity class attributes for arlo (#52681)
* Use entity class attributes for arlo

* revert sensor
2021-07-11 16:45:05 -04:00
Robert Hillis
9b577e830d Use entity class attributes for azure_devops (#52698) 2021-07-11 16:42:52 -04:00
Robert Hillis
5849a97150 Use entity class attributes for Beewi smartclim (#52839)
* Use entity class attributes for beewi_smartclim

* rework
2021-07-11 16:41:14 -04:00
Robert Hillis
77c68cb507 Use entity class attributes for bayesian (#52831) 2021-07-11 16:37:41 -04:00
Robert Hillis
d01227f141 Use entity class attributes for bbb_gpio (#52837) 2021-07-11 16:35:36 -04:00
Joakim Sørensen
d7b2ec80b2 Bump pyhaversion to 21.7.0 (#52880) 2021-07-11 16:33:03 -04:00
Raman Gupta
f234da6379 Bump zwave-js-server-python to 0.27.1 (#52885) 2021-07-11 16:27:46 -04:00
Paulus Schoutsen
2317b7343f Rename preview task to run (#52857) 2021-07-11 07:14:50 -07:00
GitHub Action
b484969b09 [ci skip] Translation update 2021-07-11 00:09:40 +00:00
Marc Mueller
b5cec353cc Fix pylint issue with stream component c-extension (#52847)
* Rename 'extension-pkg-whitelist' setting to 'extension-pkg-allow-list'
* Add 'av.stream' and 'av.audio.stream'
* Replace 'Any' type hint
2021-07-10 22:58:37 +02:00
Joakim Plate
dd648f5c9c Update arcam lib to 0.7.0 (#52829) 2021-07-10 22:31:42 +02:00
Alexei Chetroi
fb7b202251 Bump up ZHA depdencies (#52818) 2021-07-09 22:37:56 -04:00
GitHub Action
b347226820 [ci skip] Translation update 2021-07-10 00:09:24 +00:00
Simone Chemelli
bbff9622a7 Fix Neato parameter for token refresh (#52785)
* Fix param

* cleanup
2021-07-09 13:12:51 -04:00
Chris
92ab471f7b Add transition support to zwave_js lights (#52160)
* Add transition support to zwave_js lights

* Add transition support to color_switch lights

* simplify and add tests

* fix logic

* add check for color transition to add SUPPORT_TRANSITON supported features

* Use new metadata property

* Use new metadata property

* update tests and device state dump json files

* fix file perms

* update tests and fixtures with new metadata

* update test

* update test

* update tests for color transitions

* check for color tansitions as well

* more tests

* fix color transtions

* remove unneed default

* set add_to_watched_value_ids to false

* set transition default

* properly set default

* update tests

* make sure transition is an int

* suggested changes

* Update homeassistant/components/zwave_js/light.py

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

* Update homeassistant/components/zwave_js/light.py

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

* Update homeassistant/components/zwave_js/light.py

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

* Update homeassistant/components/zwave_js/light.py

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

* Update homeassistant/components/zwave_js/light.py

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

* formatting

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-07-09 12:15:20 -04:00
stefano055415
1e6229dd7b Add device info to Freedompro (#52715)
* Update Freedompro

* Update homeassistant/components/freedompro/light.py

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

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-09 16:36:13 +02:00
Robert Svensson
2787dc9e97 Bump dependency to properly handle current and voltage not being reported on some zhapower endpoints (#52764) 2021-07-09 11:54:40 +02:00
Jc2k
7e2ef8f0c7 Support certain homekit devices that emit invalid JSON (#52759) 2021-07-09 11:51:46 +02:00
Otto Winter
07e2a7245f Fix ESPHome Camera not merging image packets (#52783) 2021-07-09 11:38:38 +02:00
Brandon Rothweiler
2eb531b8c8 Upgrade pymazda to 0.2.0 (#52775) 2021-07-09 07:55:26 +02:00
GitHub Action
f7e4db512f [ci skip] Translation update 2021-07-09 00:09:30 +00:00
Jc2k
5b257d2be8 Fix homebridge devices becoming unavailable frequently (#52753)
Update to aiohomekit 0.4.3 and make sure service type UUID is normalised before comparison

Co-authored-by: J. Nick Koston <nick@koston.org>
2021-07-08 17:26:25 +01:00
apaperclip
49181d6ba8 Remove scale calculation for climacell cloud cover (#52752) 2021-07-08 12:10:05 -04:00
Jon Gilmore
eb735b6162 Bump pylutron to 0.2.8 fixing python 3.9 incompatibility (#52702) 2021-07-08 15:18:08 +02:00
Robert Hillis
922ef3f2f3 Use entity class attributes for aurora (#52690)
* Use entity class attributes for aurora

* fix
2021-07-08 15:06:00 +02:00
Tom Matheussen
293690e3d8 Fix KNX Fan features (#52732)
* Fan entity should return support features

* Revert "Fan entity should return support features"

This reverts commit 3ad0e87708fbf1847aaa26e3bc76fcac365a1640.

* Restore supported_features for KNX fan
2021-07-08 15:05:43 +02:00
Niels Mündler
f069fbdb25 Upgrade Fronius dependency to 0.5.3 (#52737)
supports more values of new Gen24 type of fronius device
2021-07-08 14:45:34 +02:00
Jesse Hills
94e15b3eea Esphome fix camera image (#52738) 2021-07-08 14:44:49 +02:00
jan iversen
fe1f7ba316 Add check for _client existence in modbus (#52719) 2021-07-08 11:58:51 +02:00
jjlawren
578c897161 Ignore unused keys from Sonos device properties callback (#52660)
* Ignore known but unused keys from device callback

* Fix bug, add test
2021-07-08 11:56:50 +02:00
Robert Hillis
1c11b247e4 Use entity class attributes for apcupsd (#52662) 2021-07-08 11:55:26 +02:00
Robert Hillis
7d0751df8a Use entity class attributes for anthemav (#52602) 2021-07-08 11:42:07 +02:00
Stefan Agner
1dd4ba5fcd Fix precipitation calculation for hourly forecast (#52676)
It seems that hourly forecast have precipitation in 3h blocks.
2021-07-08 11:39:56 +02:00
Andre Lengwenus
abca7deadb Hint for str type instead of explicitly casting to str (#52712) 2021-07-08 10:42:27 +02:00
Franck Nijhof
62c7e5408b Ensure Forecast.Solar returns an iso formatted timestamp (#52669) 2021-07-08 10:09:30 +02:00
avee87
5ff7c7708d Use iso-formatted times in MetOffice weather forecast (#52672)
* Fixed raw datetime in MetOffice weather forecast

* Use datetime in sensor attribute
2021-07-08 10:01:06 +02:00
Robert Hillis
c4d8d1dc8e Use entity class attributes for Aten pe (#52687)
* Use entity class attributes for aten_pe

* Use entity class attributes for atag
2021-07-08 10:39:53 +03:00
Tobias Sauerwein
cb0a7589ce Use class properties in netatmo (#52705) 2021-07-08 09:30:54 +02:00
Robert Hillis
71b14b51b4 Use entity class attributes for aurora_abb_power (#52692) 2021-07-08 09:22:54 +02:00
uvjustin
b021e2ee8c Move recorder.py import to runtime (#52682) 2021-07-08 09:20:27 +02:00
Robert Hillis
5b49107007 Use entity class attributes for avion (#52696) 2021-07-08 09:16:47 +02:00
jjlawren
dabb50f7ee Warn if interface_addr remains in Sonos configuration (#52652) 2021-07-08 09:15:56 +02:00
Eric Severance
4e85bdd67c pyWeMo version bump (0.6.5) (#52701) 2021-07-08 09:11:56 +02:00
Robert Hillis
4e848f60c4 Use entity class attributes for anel_pwrctrl (#52594)
* Use entity class attributes for anel_pwrctrl

* Tweak
2021-07-07 22:12:17 -04:00
GitHub Action
b5a6d05778 [ci skip] Translation update 2021-07-08 00:13:44 +00:00
Aaron Bach
f3c464786c Bump simplisafe-python to 11.0.1 (#52684) 2021-07-07 19:45:39 -04:00
Aaron Bach
aa022d4c52 Add missing type annotations to ReCollect Waste (#52600) 2021-07-07 17:40:03 -05:00
Aaron Bach
f44a13970a Add missing type annotations to Notion (#52599) 2021-07-07 17:39:52 -05:00
Aaron Bach
50d56fd755 Add missing type annotations to Guardian (#52598) 2021-07-07 17:39:34 -05:00
Allen Porter
e895b6cd42 Refactor decompression timestamp validation logic in stream component (#52462)
* Refactor dts validation logic into a separate function

Create a decompression timestamp validation function to move the logic out of
the worker into a separate class. This also uses the python itertools.chain
to chain together the initial packets with the remaining packets in the
container iterator, removing additional inline if statements.

* Reset dts validator when container is reset

* Fix typo in a comment

* Reuse existing dts_validator when disabling audio stream
2021-07-07 15:29:15 -07:00
Shay Levy
02d8d25d1d Fix Waze Travel Time tests (#52663) 2021-07-07 23:56:02 +03:00
Simone Chemelli
5c82776411 Fix Fritz default consider home value (#52648) 2021-07-07 20:19:31 +02:00
Joakim Sørensen
351b67ffb1 Handle KeyError when accessing device information (#52650) 2021-07-07 20:18:43 +02:00
Anaïs Betts
cd7f366501 Fix service registration typo in Nuki integration (#52631) 2021-07-07 17:25:52 +02:00
Pascal Vizeli
b2ee4894f1 Bump opencv to 4.5.2.54 (#52630) 2021-07-07 16:43:19 +02:00
Bram Kragten
e2b1cdafc9 Update frontend to 20210707.0 (#52624) 2021-07-07 10:43:45 +02:00
Chris
45fbc18eb0 Fix mysensors rgb light (#52604)
* remove assert self._white as not all RGB will have a white channel

* suggested change

* Update homeassistant/components/mysensors/light.py

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

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2021-07-07 10:34:14 +02:00
Franck Nijhof
c5d806fdbe Fix broadlink creating duplicate unique IDs (#52621) 2021-07-07 09:46:59 +02:00
J. Nick Koston
1ba5c1c9fb Fix deadlock at shutdown with python 3.9 (#52613) 2021-07-07 09:23:24 +02:00
Alexei Chetroi
88cd7f481d Bump up ZHA dependencies (#52611) 2021-07-07 08:30:48 +02:00
GitHub Action
0c5ce9cac2 [ci skip] Translation update 2021-07-07 00:11:57 +00:00
Pascal Vizeli
16f1647ad0 Python 3.9.6 / Base image 2021.07.0 (#52605) 2021-07-06 23:39:25 +02:00
Aaron Bach
9fb05736e4 Add type annotations to Ambient PWS (#52596) 2021-07-06 20:19:58 +02:00
Aaron Bach
2f1af9a254 Remove unnecessary async_setup method for Guardian (#52597) 2021-07-06 20:19:41 +02:00
Thibaut
5c07fb51a2 Update Somfy to reduce calls to /site entrypoint (#51572)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-06 18:48:48 +02:00
Shay Levy
f5c3444072 Fix Sensibo timeout exceptions (#52513) 2021-07-06 18:34:56 +02:00
J. Nick Koston
e1e3f68d0b Revert nmap_tracker to 2021.6 version (#52573)
* Revert nmap_tracker to 2021.6 version

- Its unlikely we will be able to solve #52565 before release

* hassfest
2021-07-06 18:28:23 +02:00
Aaron Bach
40ad25df4c Fresh attempt at SimpliSafe auto-relogin (#52567)
* Fresh attempt at SimpliSafe auto-relogin

* Fix tests
2021-07-06 18:21:25 +02:00
Erik Montnemery
6c8de16fbc Enable basic type checking for fan (#52471) 2021-07-06 18:21:00 +02:00
Franck Nijhof
8fce858a76 Upgrade numpy to 1.21.0 (#52586) 2021-07-06 18:11:22 +02:00
Maciej Bieniek
62c3b3bdfe Use HA location name as name in GIOS integration (#52585) 2021-07-06 17:52:22 +02:00
Erik Montnemery
3d7fd83ad4 Add home-assistant/core as codeowner for the template integration (#52592) 2021-07-06 17:35:11 +02:00
Robert Svensson
605f65b75d Make use of entry id rather than unique id when storing deconz entry in hass.data (#52584)
* Make use of entry id rather than unique id when storing entry in hass data

* Update homeassistant/components/deconz/services.py

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

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-06 17:18:54 +02:00
Erik Montnemery
7ba1fdea70 Bump hatasmota to 0.2.20 (#52591) 2021-07-06 18:13:45 +03:00
Raman Gupta
81fe3583c9 Don't raise when setting HVAC mode without a mode ZwaveValue (#52444)
* Don't raise an error when setting HVAC mode without a value

* change logic based on discord convo and add tests

* tweak
2021-07-06 16:33:07 +02:00
Robert Hillis
6e779855f7 Clean up alarmdecoder (#52517)
* Clean up alarmdecoder

* fix

* try again

* tweak
2021-07-06 16:18:00 +02:00
ondras12345
07bda0973e Fix update of Xiaomi Miio vacuum taking too long (#52539)
Home assistant log would get spammed with messages like
Update of vacuum.vacuum_name is taking over 10 seconds
every 20 seconds if the vacuum was not reachable through the network.

See #52353
2021-07-06 16:03:54 +02:00
Simone Chemelli
046eb1690a Fix Fritz Wi-Fi 6 networks with same name as other Wi-Fi (#52588) 2021-07-06 15:49:22 +02:00
Simone Chemelli
a70dae0843 Enable strict typing for Fritz (#50668)
Co-authored-by: Ruslan Sayfutdinov <ruslan@sayfutdinov.com>
2021-07-06 15:06:32 +02:00
RenierM26
12082736a8 Add type annotations to init and coordinator. Minor cleanups. (#52506) 2021-07-06 14:55:34 +02:00
Erik Montnemery
4d32e1ed01 Minor improvements of MQTT typing (#52578)
* Minor improvements of MQTT typing

* Tweak
2021-07-06 14:38:48 +02:00
Maciej Bieniek
dc72c6c606 Improve config entry title for GIOS integration (#52583)
* Improve GIOS config entry title

* Usonly station name as title
2021-07-06 14:04:00 +02:00
Erik Montnemery
b645560633 Minor improvements of util.percentage typing (#52581) 2021-07-06 13:29:39 +02:00
Pascal Vizeli
94aa292c9b Wheels v2021.07.0 (#52580) 2021-07-06 12:49:46 +02:00
Maciej Bieniek
669aca9585 Bump gios to version 1.0.2 (#52576) 2021-07-06 12:32:17 +02:00
Bram Kragten
33577e1bfc Update frontend to 20210706.0 (#52577) 2021-07-06 11:52:53 +02:00
Andre Lengwenus
e16ef10af5 Add type hints to LCN (#52509)
* Add type hints to LCN

* Fix requested review changes
2021-07-06 09:54:35 +02:00
Franck Nijhof
b496469a2f Fix unavailable entity capable of triggering non-numerical warning in Threshold sensor (#52563) 2021-07-06 09:33:00 +02:00
Robert Hillis
2a48fe5199 Use entity class attributes for aladdin_connect (#52516)
* Use entity class attributes for aladdin_connect

* fix

* fix

* fix pylint
2021-07-06 08:47:49 +02:00
Raman Gupta
a70e8a65fa Bump pyeight version to 0.1.9 (#52568) 2021-07-06 02:41:23 -04:00
GitHub Action
d249530ed1 [ci skip] Translation update 2021-07-06 00:09:29 +00:00
Shay Levy
2aacb6b99f Disable flaky shell_command test (#52564) 2021-07-06 00:24:09 +03:00
J. Nick Koston
3191fef8d6 Update the ip/port in the homekit_controller config entry when it changes (#52554) 2021-07-05 15:16:49 -05:00
René Klomp
7d87efc996 Bump pysma version to 0.6.2 (#52553) 2021-07-05 22:04:55 +02:00
J. Nick Koston
f74049e018 Bump aiohomekit to 0.4.2 (#52560)
- Changelog: https://github.com/Jc2k/aiohomekit/compare/0.4.1...0.4.2

- Fixes: #52548
2021-07-05 22:00:57 +02:00
Alexei Chetroi
f58b231bbd Bump up zha dependencies (#52555) 2021-07-05 14:00:32 -04:00
Tom Brien
a4b97f7dcb Update list of supported Coinbase wallet currencies (#52545) 2021-07-05 16:22:41 +02:00
J. Nick Koston
34782557b7 Bump zeroconf to 0.32.1 (#52547)
- Changelog: https://github.com/jstasiak/python-zeroconf/compare/0.32.0...0.32.1

- Fixes #52384
2021-07-05 09:17:11 -05:00
Franck Nijhof
74029a0948 Fix Statistics recorder migration path by dropping in pairs (#52453) 2021-07-05 13:34:40 +02:00
Franck Nijhof
5e9127ef7a Remove problematic/redudant db migration happning schema 15 (#52541) 2021-07-05 13:28:01 +02:00
Tobias Sauerwein
f9c7137d02 Use dataclasses in netatmo data handler (#52537)
* Switch to using dataclasses

* Clean up

* Update homeassistant/components/netatmo/data_handler.py
2021-07-05 13:05:18 +02:00
Robert Hillis
4cac85e3f5 Use entity class attributes for ads (#52488)
* Use entity class attributes for ads

* fix

* Update homeassistant/components/ads/cover.py

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

Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2021-07-05 12:03:16 +02:00
Yuval Aboulafia
323088ff63 Fully type Tag component (#52540) 2021-07-05 11:54:00 +02:00
jan iversen
1cb298948f Fix MODBUS connection type rtuovertcp does not connect (#52505)
* Correct host -> framer.

* Use function pointer
2021-07-05 11:45:50 +02:00
RenierM26
2e4f513526 Add type annotations and shorten sensor names on ezviz sensor platforms (#52475)
* Add basic typing and change name on sensor platforms.

* Complete type annotations for all functions.
2021-07-05 11:40:13 +02:00
Aaron Bach
64e63dedf6 Revert "Force SimpliSafe to reauthenticate with a password (#51528)" (#52484)
This reverts commit 549f779b06.
2021-07-05 11:38:31 +02:00
Robert Hillis
5367a036d2 Use entity class attributes for accuweather (#52431) 2021-07-05 11:36:04 +02:00
Erik Montnemery
1cc8280959 Enable basic type checking for the homeassistant component (#52464)
* Enable basic type checking for the homeassistant component

* Tweak
2021-07-05 11:26:31 +02:00
Erik Montnemery
600bea2459 Enable basic type checking for Google cast (#52434)
* Enable basic type checking for Google cast

* tweak
2021-07-05 11:14:41 +02:00
Robert Hillis
05b35cd98a Rename goalzero sensor (#52452) 2021-07-05 11:05:53 +02:00
Shay Levy
6fc5a6a065 Fix CI failing due to Shell Command exception (#52483) 2021-07-05 10:38:55 +02:00
Robert Hillis
6d9628423c Use entity class attributes for aftership (#52500)
* Use entity class attributes for aftership

* Tweaks

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-05 10:37:00 +02:00
Erik Montnemery
79ee112490 Enable basic type checking for mqtt (#52463)
* Enable basic type checking for mqtt

* Tweak
2021-07-05 10:33:12 +02:00
Robert Hillis
5321151799 Use entity class attributes for abode (#52427)
* Use entity class attributes for abode

* Apply suggestions from code review

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

* move from base class

* fix

* Undo light supported features

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-05 10:31:11 +02:00
Chris Talkington
cacd803a93 Enable basic typing for roku (#52478)
* enable basic typing for roku

* Update mypy.ini

* Update media_player.py

* Create coordinator.py

* Update __init__.py

* Update media_player.py

* Update remote.py

* Update media_player.py

* Update coordinator.py

* Update coordinator.py

* Update remote.py

* Update entity.py

* Update coordinator.py

* Update config_flow.py

* Update entity.py

* Update const.py

* Update const.py

* Update const.py

* Update entity.py

* Update entity.py

* Update entity.py

* Update test_media_player.py

* Update test_remote.py
2021-07-05 10:27:52 +02:00
Yuval Aboulafia
0e7cd02d17 Add type checking and entity attributes for Fast.com (#52524)
* Cleanup fast.com (typing, attrs)

* Adress review

* fixes
2021-07-05 10:19:37 +02:00
Robert Hillis
e9453bb344 Use entity class attributes for alert (#52518) 2021-07-05 09:42:39 +02:00
Robert Hillis
e2b89e4650 Use entity class attributes for alpha_vantage (#52520)
* Use entity class attributes for alpha_vantage

* tweak

* clean up
2021-07-05 09:37:09 +02:00
Robert Hillis
4463d50711 Use entity class attributes for aemet (#52499) 2021-07-05 07:53:16 +02:00
Robert Hillis
3a2a688170 Use entity class attributes for ambiclimate (#52521)
* Use entity class attributes for ambiclimate

* tweak

* move some stuff
2021-07-05 07:51:10 +02:00
GitHub Action
abc9b01ede [ci skip] Translation update 2021-07-05 00:09:10 +00:00
Aaron Bach
5ce4de7bbb Migrate AirVisual air_quality platform to sensor platform (#52349)
* Migrate AirVisual air_quality platform sensors

* Remove redundancy

* Cleanup

* Properly set available

* Unwind config_entry -> entry name change

* More unwinding

* Rename

* Update homeassistant/components/airvisual/sensor.py

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

* Code review

* Linting

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-04 12:16:06 -06:00
Maciej Bieniek
bdf247faaa Migrate GIOS air_quality platform to sensor (#52295) 2021-07-04 11:54:07 -05:00
J. Nick Koston
27295d8f58 Remove empty hosts and excludes from nmap configuration (#52489) 2021-07-04 11:40:33 -05:00
Robert Hillis
8ccb338a9b Use entity class attributes for airnow (#52502) 2021-07-04 11:33:52 -05:00
J. Nick Koston
cfe2017dd9 Bump HAP-python to 3.5.1 (#52508)
- Fixes additional cases of invalid mdns hostnames
2021-07-04 17:16:42 +03:00
RenierM26
73c6aa701f Add basic typing to ezviz camera platform (#52492)
* Add basic typing to camera platform. Small cleanups.

* Add full typing to all functions
2021-07-04 13:16:27 +02:00
Guido Schmitz
77a06e01f7 Update devolo-home-control-api (#52497) 2021-07-04 11:56:16 +03:00
Raman Gupta
8f186957ea Mark entities for dead zwave_js nodes as unavailable (#48017)
* Don't create any devices or entities for dead zwave_js nodes

* mark entities for dead nodes as unavailable

* add test

* watch for node status updates

* update tests to handle node status changes as well
2021-07-03 22:06:07 -04:00
GitHub Action
378b5f75ec [ci skip] Translation update 2021-07-04 00:09:33 +00:00
Aaron Bach
d980dd8d59 Deprecate YAML config for Ambient PWs (2021.9.0 removal) (#52459) 2021-07-03 14:45:51 -05:00
Erik Montnemery
628eafaf68 Enable basic type checking for script (#52476) 2021-07-03 19:35:36 +03:00
Aaron Bach
e29c75a68e Remove redundant property definitions in Tile (#52448) 2021-07-03 11:29:52 -05:00
Aaron Bach
8c0559cc57 Remove redundant property definitions in RainMachine (#52456)
* Remove redundant property definitions in RainMachine

* Incorrect attribute name
2021-07-03 11:23:52 -05:00
Aaron Bach
413c3afa12 Remove redundant property definitions in SimpliSafe (#52458)
* Remove redundant property definitions in SimpliSafe

* Remove useless init
2021-07-03 11:16:55 -05:00
Aaron Bach
513bcbc02b Replace custom listener with helper in SimpliSafe (#52457) 2021-07-03 11:01:41 -05:00
Erik Montnemery
14dd6478d1 Enable basic type checking for trace (#52468) 2021-07-03 17:52:31 +02:00
Erik Montnemery
b3b377ac8b Enable basic type checking for gogogate2 (#52467)
* Enable basic type checking for gogogate2

* Tweak

* Update homeassistant/components/gogogate2/common.py

Co-authored-by: Ruslan Sayfutdinov <ruslan@sayfutdinov.com>

* Tweak

Co-authored-by: Ruslan Sayfutdinov <ruslan@sayfutdinov.com>
2021-07-03 16:06:42 +01:00
Erik Montnemery
44b44b5bd6 Enable basic type checking for climate (#52470)
* Enable basic type checking for climate

* Tweak
2021-07-03 16:06:12 +01:00
J. Nick Koston
f52d838b7a Bump aiohomekit to 0.4.1 (#52472)
- Fixes mdns queries being sent with the original case received on the wire
  Some responders were case sensitive and needed the original case sent

- Reduces mdns traffic
2021-07-03 17:01:41 +02:00
Maciej Bieniek
0cb61b628d Improve typing in Sony Bravia TV integration (#52438)
* Strict typing

* Variables typing

* Suggested change

* Fix pylint

* Use suppress instead of try..except

* Remove unused variables

* Suggested change

* Fix pylint

* Fix typing for unique_id
2021-07-03 14:37:54 +01:00
Simone Chemelli
69b9a9c4ee Merge fritzbox_netmonitor integration into fritz (#52264)
* Merge netmonitor integration

* cleanup additional files

* Use attrs instead of properties

* Add state_class to relevant sensors

* Update homeassistant/components/fritz/sensor.py

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

* Update homeassistant/components/fritz/sensor.py

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

* Update homeassistant/components/fritz/sensor.py

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

* Update homeassistant/components/fritz/sensor.py

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

* Update homeassistant/components/fritz/sensor.py

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

* Update homeassistant/components/fritz/sensor.py

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

* mypy fix + small cleanup

* Round, GB and icons

* Update homeassistant/components/fritz/sensor.py

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

* remove state_class from no-reset counters

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-03 16:26:43 +03:00
GitHub Action
4b7442412a [ci skip] Translation update 2021-07-03 00:09:34 +00:00
Aaron Bach
40b629cd06 Replace custom listener with helper in ReCollect Waste (#52445) 2021-07-02 15:23:17 -06:00
Franck Nijhof
b91b553ce5 Abort existing reauth flow on entry removal (#52407) 2021-07-02 20:56:51 +02:00
Franck Nijhof
7f3f6757ea Fix Statistics recorder migration order (#52449) 2021-07-02 20:55:40 +02:00
Simone Chemelli
8347cf3731 Fix Fritz call deflection list (#52443) 2021-07-02 19:21:05 +02:00
Guido Schmitz
8c7ef5b1b9 Add static typing to devolo_home_control (#52396) 2021-07-02 18:37:18 +02:00
Aaron Bach
e435ac6fcd Remove redundant property definitions in ReCollect Waste (#52368)
* Remove redundant property definitions in ReCollect Waste

* Code review

* Code review
2021-07-02 11:14:29 -05:00
Shay Levy
1eb27f7ccc Demo: remove deprecated switch entity properties (#52424)
* Demo: deprecate switch entity properties

* Fix emulated_kasa test
2021-07-02 17:50:57 +02:00
Robert Hillis
5cd4471c67 Add sensor platform to goalzero (#49835)
* Add sensor platform to goalzero

* Tweak

* Remove unused DATA_SCHEMA

* Simplify

* Remove last_reset

* Update on reload
2021-07-02 17:43:37 +02:00
J. Nick Koston
a3f1489785 Import track_new_devices and scan_interval from yaml for nmap_tracker (#52409)
* Import track_new_devices and scan_interval from yaml for nmap_tracker

* Import track_new_devices and scan_interval from yaml for nmap_tracker

* Import track_new_devices and scan_interval from yaml for nmap_tracker

* tests

* translate

* tweak

* adjust

* save indent

* pylint

* There are two CONF_SCAN_INTERVAL constants

* adjust name -- there are TWO CONF_SCAN_INTERVAL constants

* remove CONF_SCAN_INTERVAL/CONF_TRACK_NEW from user flow

* assert it does not appear in the user step
2021-07-02 17:24:43 +02:00
Erik Montnemery
98fdb00bc7 Enable basic type checking for Tasmota (#52435) 2021-07-02 16:45:38 +02:00
Erik Montnemery
ed25e6fada Correct recorder table arguments (#52436) 2021-07-02 16:28:16 +02:00
Erik Montnemery
11fd9d9525 Avoid duplicated database queries when fetching statistics (#52433) 2021-07-02 15:40:54 +02:00
Milan Meulemans
7b940d2382 Fix typo in forecast_solar strings (#52430) 2021-07-02 15:09:36 +02:00
Franck Nijhof
dec08e2e44 Upgrade aioimaplib to 0.9.0 (#52422) 2021-07-02 14:10:32 +02:00
Erik Montnemery
24ae05b734 Drop statistic_id and source columns from statistics table (#52417)
* Drop statistic_id and source columns from statistics table

* Remove useless double drop of statistics table

* Update homeassistant/components/recorder/models.py

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

* black

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-02 13:17:00 +02:00
Joakim Plate
d339e3bd8c Reject trusted network access from proxies (#52388) 2021-07-02 11:49:42 +02:00
Tobias Sauerwein
7291228e16 Remove boilerplate code in favour of attributes in Netatmo integration (#52395)
* Make use of attributes

* Add suggestions

* Update homeassistant/components/netatmo/sensor.py

Co-authored-by: Daniel Hjelseth Høyer <mail@dahoiv.net>

* Update homeassistant/components/netatmo/sensor.py

Co-authored-by: Daniel Hjelseth Høyer <mail@dahoiv.net>

Co-authored-by: Daniel Hjelseth Høyer <mail@dahoiv.net>
2021-07-02 11:36:37 +02:00
Sören Krollmann
2ed1efc3a3 Add rainbird set_rain_delay service (#52369)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-02 11:20:00 +02:00
Tom Brien
b3a625593e Add update listener to Coinbase (#52404)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2021-07-02 11:15:05 +02:00
Tobias Sauerwein
14d3286b21 Clean up netatmo sensor data processing (#52403) 2021-07-02 10:08:54 +02:00
Erik Montnemery
16d2dcbfb2 Improve sensor statistics tests (#52386) 2021-07-02 09:51:47 +02:00
Aaron Bach
887753e06d Remove redundant property definitions in OpenUV (#52379)
* Remove redundant property definitions in OpenUV

* Update homeassistant/components/openuv/__init__.py

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

* Code review

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-02 09:47:49 +02:00
Aaron Bach
6fa312d476 Remove redundant property definitions in Guardian (#52361)
* Remove redundant property definitions in Guardian

* Update incorrect attributes
2021-07-02 07:49:05 +02:00
Raman Gupta
9d04ba2804 Bump eight sleep dependency to fix bug (#52408) 2021-07-02 07:36:48 +02:00
GitHub Action
ad20b5ced0 [ci skip] Translation update 2021-07-02 00:11:25 +00:00
Franck Nijhof
a85ba1b34c Upgrade wled to 0.7.1 (#52405) 2021-07-02 00:30:33 +02:00
René Klomp
d6ed5dac8b Bump pysma to 0.6.1 (#52401) 2021-07-01 21:32:46 +02:00
Yuval Aboulafia
1337dfed8c Use attributes instead of properties for uptime (#52398)
* Use attributes instead of properties for uptime

* add missing types
2021-07-01 21:31:30 +02:00
Alexei Chetroi
8e846164a4 Bump up ZHA dependencies (#52374)
* Bump up ZHA dependencies

* Fix broken tests

* Update tests/components/zha/common.py

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

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-07-01 14:05:55 -04:00
Erik Montnemery
520b500165 Fix MQTT cover optimistic mode (#52392)
* Fix MQTT cover optimistic mode

* Add test
2021-07-01 17:34:59 +02:00
posixx
312531988a Vacation Mode on Alarm Panels (#45980)
Co-authored-by: Nathan Tilley <nathan@tilley.xyz>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Khole Jones <ktech6@outlook.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2021-07-01 17:26:32 +02:00
Erik Montnemery
57fbb1c3d9 Fix sensor statistics collection with empty states (#52393) 2021-07-01 14:53:03 +02:00
Erik Montnemery
2097ab76f5 Allow combining value_template and position_template for template cover (#52383) 2021-07-01 14:09:48 +02:00
Alexei Chetroi
7f309b4e6e Add support for Formaldehyde and VOC level sensors (#52232) 2021-07-01 07:34:09 -04:00
Franck Nijhof
451b976458 Demo: Explicitly return None when no extra state attribute set (#52390) 2021-07-01 12:43:37 +02:00
Lars
c1c078c3d5 Bump pyfritzhome to 6.2.0 (#52345) 2021-07-01 12:14:37 +02:00
Aaron Bach
60ea219101 Remove redundant property definitions in Notion (#52367)
* Remove redundant property definitions in Notion

* Code review
2021-07-01 11:24:19 +02:00
Dermot Duffy
2868fef7d4 Add motion detection support to motionEye (#49665) 2021-07-01 11:22:43 +02:00
Aaron Bach
7bd8e2aa55 Remove redundant property definitions in Flu Near You (#52377) 2021-07-01 11:04:39 +02:00
Aaron Bach
8f70b5c183 Fix missing default latitude/longitude/elevation in OpenUV config flow (#52380) 2021-07-01 10:35:14 +02:00
Bruce Sheplan
f8eb07444b Add screenlogic reconnect (#52022)
Co-authored-by: Kevin Worrel <37058192+dieselrabbit@users.noreply.github.com>
2021-07-01 10:11:01 +02:00
Frederik Bolding
72b55d1830 Bump bt_proximity (#52364) 2021-07-01 07:48:29 +02:00
Aaron Bach
f98a5cc233 Remove redundant property definitions in IQVIA (#52378) 2021-07-01 07:31:46 +02:00
GitHub Action
86f46753c9 [ci skip] Translation update 2021-07-01 00:12:17 +00:00
Aaron Bach
cb2b6f5ff4 Remove redundant property definitions in Ambient PWS (#52350) 2021-07-01 00:30:54 +02:00
Tobias Sauerwein
b4e550dee2 Bump pyatmo to v5.2.0 (#52365)
* Bump pyatmo to v5.2.0

* Revert formatting changes
2021-07-01 00:19:22 +02:00
Franck Nijhof
04e631ed1f Remove deprecated YAML configuration from VeSync (#52358) 2021-06-30 16:29:44 -04:00
Franck Nijhof
635cf59909 Remove deprecated YAML configuration from Abode (#52357) 2021-06-30 16:28:57 -04:00
Yuval Aboulafia
4a94ed8f5a Use attrs instead of property for Jewish Calendar (#52333)
* Use attrs instead of property for Jewish Calendar

* clean time sensor class

* move type and prefix up

* revert is_on attribute
2021-06-30 22:24:19 +03:00
J. Nick Koston
63c727ac6c Update homekit_controller to use async zeroconf (#52330) 2021-06-30 18:09:19 +02:00
Franck Nijhof
1862cdf52e Bump version to 2021.8.0dev0 (#52346) 2021-06-30 18:06:33 +02:00
2495 changed files with 68829 additions and 25194 deletions

View File

@@ -20,6 +20,8 @@ omit =
homeassistant/components/acmeda/helpers.py
homeassistant/components/acmeda/hub.py
homeassistant/components/acmeda/sensor.py
homeassistant/components/adax/__init__.py
homeassistant/components/adax/climate.py
homeassistant/components/adguard/__init__.py
homeassistant/components/adguard/const.py
homeassistant/components/adguard/sensor.py
@@ -35,7 +37,6 @@ omit =
homeassistant/components/airnow/__init__.py
homeassistant/components/airnow/sensor.py
homeassistant/components/airvisual/__init__.py
homeassistant/components/airvisual/air_quality.py
homeassistant/components/airvisual/sensor.py
homeassistant/components/aladdin_connect/*
homeassistant/components/alarmdecoder/__init__.py
@@ -105,6 +106,8 @@ omit =
homeassistant/components/bloomsky/*
homeassistant/components/bluesound/*
homeassistant/components/bluetooth_tracker/*
homeassistant/components/bme280/__init__.py
homeassistant/components/bme280/const.py
homeassistant/components/bme280/sensor.py
homeassistant/components/bme680/sensor.py
homeassistant/components/bmp280/sensor.py
@@ -131,9 +134,7 @@ omit =
homeassistant/components/brottsplatskartan/sensor.py
homeassistant/components/browser/*
homeassistant/components/brunt/cover.py
homeassistant/components/bsblan/__init__.py
homeassistant/components/bsblan/climate.py
homeassistant/components/bsblan/const.py
homeassistant/components/bt_home_hub_5/device_tracker.py
homeassistant/components/bt_smarthub/device_tracker.py
homeassistant/components/buienradar/sensor.py
@@ -153,7 +154,6 @@ omit =
homeassistant/components/clicksend/notify.py
homeassistant/components/clicksend_tts/notify.py
homeassistant/components/cmus/media_player.py
homeassistant/components/co2signal/*
homeassistant/components/coinbase/sensor.py
homeassistant/components/comed_hourly_pricing/sensor.py
homeassistant/components/comfoconnect/fan.py
@@ -275,6 +275,7 @@ omit =
homeassistant/components/esphome/fan.py
homeassistant/components/esphome/light.py
homeassistant/components/esphome/number.py
homeassistant/components/esphome/select.py
homeassistant/components/esphome/sensor.py
homeassistant/components/esphome/switch.py
homeassistant/components/essent/sensor.py
@@ -320,7 +321,8 @@ omit =
homeassistant/components/flick_electric/const.py
homeassistant/components/flick_electric/sensor.py
homeassistant/components/flock/notify.py
homeassistant/components/flume/*
homeassistant/components/flume/__init__.py
homeassistant/components/flume/sensor.py
homeassistant/components/flunearyou/__init__.py
homeassistant/components/flunearyou/sensor.py
homeassistant/components/flux_led/light.py
@@ -348,7 +350,6 @@ omit =
homeassistant/components/fritzbox_callmonitor/const.py
homeassistant/components/fritzbox_callmonitor/base.py
homeassistant/components/fritzbox_callmonitor/sensor.py
homeassistant/components/fritzbox_netmonitor/sensor.py
homeassistant/components/fronius/sensor.py
homeassistant/components/frontier_silicon/media_player.py
homeassistant/components/futurenow/light.py
@@ -356,12 +357,9 @@ omit =
homeassistant/components/garages_amsterdam/__init__.py
homeassistant/components/garages_amsterdam/binary_sensor.py
homeassistant/components/garages_amsterdam/sensor.py
homeassistant/components/garmin_connect/__init__.py
homeassistant/components/garmin_connect/const.py
homeassistant/components/garmin_connect/sensor.py
homeassistant/components/garmin_connect/alarm_util.py
homeassistant/components/gc100/*
homeassistant/components/geniushub/*
homeassistant/components/generic_hygrostat/*
homeassistant/components/github/sensor.py
homeassistant/components/gitlab_ci/sensor.py
homeassistant/components/gitter/sensor.py
@@ -372,6 +370,7 @@ omit =
homeassistant/components/goalfeed/*
homeassistant/components/goalzero/__init__.py
homeassistant/components/goalzero/binary_sensor.py
homeassistant/components/goalzero/sensor.py
homeassistant/components/goalzero/switch.py
homeassistant/components/google/*
homeassistant/components/google_cloud/tts.py
@@ -398,10 +397,6 @@ omit =
homeassistant/components/habitica/const.py
homeassistant/components/habitica/sensor.py
homeassistant/components/hangouts/*
homeassistant/components/hangouts/__init__.py
homeassistant/components/hangouts/const.py
homeassistant/components/hangouts/hangouts_bot.py
homeassistant/components/hangouts/hangups_utils.py
homeassistant/components/harman_kardon_avr/media_player.py
homeassistant/components/harmony/const.py
homeassistant/components/harmony/data.py
@@ -415,7 +410,8 @@ omit =
homeassistant/components/heatmiser/climate.py
homeassistant/components/hikvision/binary_sensor.py
homeassistant/components/hikvisioncam/switch.py
homeassistant/components/hisense_aehw4a1/*
homeassistant/components/hisense_aehw4a1/__init__.py
homeassistant/components/hisense_aehw4a1/climate.py
homeassistant/components/hitron_coda/device_tracker.py
homeassistant/components/hive/__init__.py
homeassistant/components/hive/climate.py
@@ -426,15 +422,18 @@ omit =
homeassistant/components/hive/water_heater.py
homeassistant/components/hlk_sw16/__init__.py
homeassistant/components/hlk_sw16/switch.py
homeassistant/components/home_connect/*
homeassistant/components/home_connect/__init__.py
homeassistant/components/home_connect/api.py
homeassistant/components/home_connect/binary_sensor.py
homeassistant/components/home_connect/entity.py
homeassistant/components/home_connect/light.py
homeassistant/components/home_connect/sensor.py
homeassistant/components/home_connect/switch.py
homeassistant/components/homematic/*
homeassistant/components/homematic/climate.py
homeassistant/components/homematic/cover.py
homeassistant/components/homematic/notify.py
homeassistant/components/home_plus_control/api.py
homeassistant/components/home_plus_control/helpers.py
homeassistant/components/home_plus_control/switch.py
homeassistant/components/homeworks/*
homeassistant/components/honeywell/__init__.py
homeassistant/components/honeywell/climate.py
homeassistant/components/horizon/media_player.py
homeassistant/components/hp_ilo/sensor.py
@@ -525,8 +524,6 @@ omit =
homeassistant/components/kira/*
homeassistant/components/kiwi/lock.py
homeassistant/components/knx/*
homeassistant/components/knx/climate.py
homeassistant/components/knx/cover.py
homeassistant/components/kodi/__init__.py
homeassistant/components/kodi/browse_media.py
homeassistant/components/kodi/const.py
@@ -624,6 +621,7 @@ omit =
homeassistant/components/mill/__init__.py
homeassistant/components/mill/climate.py
homeassistant/components/mill/const.py
homeassistant/components/mill/sensor.py
homeassistant/components/minecraft_server/__init__.py
homeassistant/components/minecraft_server/binary_sensor.py
homeassistant/components/minecraft_server/const.py
@@ -633,8 +631,12 @@ omit =
homeassistant/components/mitemp_bt/sensor.py
homeassistant/components/mjpeg/camera.py
homeassistant/components/mochad/*
homeassistant/components/modbus/base_platform.py
homeassistant/components/modbus/binary_sensor.py
homeassistant/components/modbus/cover.py
homeassistant/components/modbus/climate.py
homeassistant/components/modbus/modbus.py
homeassistant/components/modbus/validators.py
homeassistant/components/modem_callerid/sensor.py
homeassistant/components/motion_blinds/__init__.py
homeassistant/components/motion_blinds/const.py
@@ -652,7 +654,6 @@ omit =
homeassistant/components/mvglive/sensor.py
homeassistant/components/mychevy/*
homeassistant/components/mycroft/*
homeassistant/components/mycroft/notify.py
homeassistant/components/mysensors/__init__.py
homeassistant/components/mysensors/binary_sensor.py
homeassistant/components/mysensors/climate.py
@@ -687,7 +688,9 @@ omit =
homeassistant/components/netgear_lte/*
homeassistant/components/netio/switch.py
homeassistant/components/neurio_energy/sensor.py
homeassistant/components/nexia/climate.py
homeassistant/components/nextcloud/*
homeassistant/components/nfandroidtv/__init__.py
homeassistant/components/nfandroidtv/notify.py
homeassistant/components/niko_home_control/light.py
homeassistant/components/nilu/air_quality.py
@@ -823,8 +826,6 @@ omit =
homeassistant/components/radarr/sensor.py
homeassistant/components/radiotherm/climate.py
homeassistant/components/rainbird/*
homeassistant/components/rainbird/sensor.py
homeassistant/components/rainbird/switch.py
homeassistant/components/raincloud/*
homeassistant/components/rainmachine/__init__.py
homeassistant/components/rainmachine/binary_sensor.py
@@ -871,7 +872,6 @@ omit =
homeassistant/components/rova/sensor.py
homeassistant/components/rpi_camera/*
homeassistant/components/rpi_gpio/*
homeassistant/components/rpi_gpio/cover.py
homeassistant/components/rpi_gpio_pwm/light.py
homeassistant/components/rpi_pfio/*
homeassistant/components/rpi_rf/switch.py
@@ -891,7 +891,6 @@ omit =
homeassistant/components/screenlogic/services.py
homeassistant/components/screenlogic/switch.py
homeassistant/components/scsgate/*
homeassistant/components/scsgate/cover.py
homeassistant/components/sendgrid/notify.py
homeassistant/components/sense/*
homeassistant/components/sensehat/light.py
@@ -969,7 +968,6 @@ omit =
homeassistant/components/sonos/*
homeassistant/components/sony_projector/switch.py
homeassistant/components/spc/*
homeassistant/components/speedtestdotnet/*
homeassistant/components/spider/*
homeassistant/components/splunk/*
homeassistant/components/spotify/__init__.py
@@ -994,8 +992,6 @@ omit =
homeassistant/components/swiss_public_transport/sensor.py
homeassistant/components/swisscom/device_tracker.py
homeassistant/components/switchbot/switch.py
homeassistant/components/switcher_kis/sensor.py
homeassistant/components/switcher_kis/switch.py
homeassistant/components/switchmate/switch.py
homeassistant/components/syncthing/__init__.py
homeassistant/components/syncthing/sensor.py
@@ -1016,7 +1012,6 @@ omit =
homeassistant/components/system_bridge/sensor.py
homeassistant/components/systemmonitor/sensor.py
homeassistant/components/tado/*
homeassistant/components/tado/device_tracker.py
homeassistant/components/tahoma/*
homeassistant/components/tank_utility/sensor.py
homeassistant/components/tankerkoenig/*
@@ -1084,9 +1079,6 @@ omit =
homeassistant/components/traccar/const.py
homeassistant/components/trackr/device_tracker.py
homeassistant/components/tradfri/*
homeassistant/components/tradfri/light.py
homeassistant/components/tradfri/cover.py
homeassistant/components/tradfri/base_class.py
homeassistant/components/trafikverket_train/sensor.py
homeassistant/components/trafikverket_weatherstation/sensor.py
homeassistant/components/transmission/sensor.py
@@ -1207,20 +1199,29 @@ omit =
homeassistant/components/xiaomi_miio/device_tracker.py
homeassistant/components/xiaomi_miio/fan.py
homeassistant/components/xiaomi_miio/gateway.py
homeassistant/components/xiaomi_miio/humidifier.py
homeassistant/components/xiaomi_miio/light.py
homeassistant/components/xiaomi_miio/number.py
homeassistant/components/xiaomi_miio/remote.py
homeassistant/components/xiaomi_miio/select.py
homeassistant/components/xiaomi_miio/sensor.py
homeassistant/components/xiaomi_miio/switch.py
homeassistant/components/xiaomi_miio/vacuum.py
homeassistant/components/xiaomi_tv/media_player.py
homeassistant/components/xmpp/notify.py
homeassistant/components/xs1/*
homeassistant/components/yale_smart_alarm/__init__.py
homeassistant/components/yale_smart_alarm/alarm_control_panel.py
homeassistant/components/yale_smart_alarm/const.py
homeassistant/components/yale_smart_alarm/coordinator.py
homeassistant/components/yamaha_musiccast/__init__.py
homeassistant/components/yamaha_musiccast/media_player.py
homeassistant/components/yandex_transport/*
homeassistant/components/yeelightsunflower/light.py
homeassistant/components/yi/camera.py
homeassistant/components/youless/__init__.py
homeassistant/components/youless/const.py
homeassistant/components/youless/sensor.py
homeassistant/components/zabbix/*
homeassistant/components/zamg/sensor.py
homeassistant/components/zamg/weather.py

View File

@@ -115,7 +115,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build base image
uses: home-assistant/builder@2021.06.2
uses: home-assistant/builder@2021.07.0
with:
args: |
$BUILD_ARGS \
@@ -134,6 +134,7 @@ jobs:
machine:
- generic-x86-64
- intel-nuc
- khadas-vim3
- odroid-c2
- odroid-c4
- odroid-n2
@@ -167,7 +168,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build base image
uses: home-assistant/builder@2021.06.2
uses: home-assistant/builder@2021.07.0
with:
args: |
$BUILD_ARGS \

View File

@@ -740,4 +740,4 @@ jobs:
coverage report --fail-under=94
coverage xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1.5.2
uses: codecov/codecov-action@v2.0.2

View File

@@ -9,7 +9,7 @@ jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2.0.3
- uses: dessant/lock-threads@v2.1.1
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: "30"

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.19
uses: actions/stale@v4
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.19
uses: actions/stale@v4
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.19
uses: actions/stale@v4
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
only-labels: "needs-more-information"

View File

@@ -81,7 +81,7 @@ jobs:
name: requirements_diff
- name: Build wheels
uses: home-assistant/wheels@2021.06.0
uses: home-assistant/wheels@2021.07.0
with:
tag: ${{ matrix.tag }}
arch: ${{ matrix.arch }}
@@ -150,7 +150,7 @@ jobs:
done
- name: Build wheels
uses: home-assistant/wheels@2021.06.0
uses: home-assistant/wheels@2021.07.0
with:
tag: ${{ matrix.tag }}
arch: ${{ matrix.arch }}

View File

@@ -1,11 +1,11 @@
repos:
- repo: https://github.com/asottile/pyupgrade
rev: v2.16.0
rev: v2.23.0
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/psf/black
rev: 21.6b0
rev: 21.7b0
hooks:
- id: black
args:
@@ -70,7 +70,7 @@ repos:
- id: prettier
stages: [manual]
- repo: https://github.com/cdce8p/python-typing-update
rev: v0.3.3
rev: v0.3.5
hooks:
# Run `python-typing-update` hook manually from time to time
# to update python typing syntax.

View File

@@ -9,15 +9,18 @@ homeassistant.components.actiontec.*
homeassistant.components.aftership.*
homeassistant.components.air_quality.*
homeassistant.components.airly.*
homeassistant.components.airvisual.*
homeassistant.components.aladdin_connect.*
homeassistant.components.alarm_control_panel.*
homeassistant.components.amazon_polly.*
homeassistant.components.ambee.*
homeassistant.components.ambient_station.*
homeassistant.components.ampio.*
homeassistant.components.automation.*
homeassistant.components.binary_sensor.*
homeassistant.components.bluetooth_tracker.*
homeassistant.components.bond.*
homeassistant.components.braviatv.*
homeassistant.components.brother.*
homeassistant.components.calendar.*
homeassistant.components.camera.*
@@ -25,17 +28,24 @@ homeassistant.components.canary.*
homeassistant.components.cover.*
homeassistant.components.device_automation.*
homeassistant.components.device_tracker.*
homeassistant.components.devolo_home_control.*
homeassistant.components.dnsip.*
homeassistant.components.dsmr.*
homeassistant.components.dunehd.*
homeassistant.components.elgato.*
homeassistant.components.esphome.*
homeassistant.components.energy.*
homeassistant.components.fastdotcom.*
homeassistant.components.fitbit.*
homeassistant.components.flunearyou.*
homeassistant.components.forecast_solar.*
homeassistant.components.fritzbox.*
homeassistant.components.frontend.*
homeassistant.components.fritz.*
homeassistant.components.geo_location.*
homeassistant.components.gios.*
homeassistant.components.group.*
homeassistant.components.guardian.*
homeassistant.components.history.*
homeassistant.components.homeassistant.triggers.event
homeassistant.components.http.*
@@ -45,6 +55,7 @@ homeassistant.components.image_processing.*
homeassistant.components.integration.*
homeassistant.components.knx.*
homeassistant.components.kraken.*
homeassistant.components.lcn.*
homeassistant.components.light.*
homeassistant.components.local_ip.*
homeassistant.components.lock.*
@@ -52,30 +63,43 @@ homeassistant.components.mailbox.*
homeassistant.components.media_player.*
homeassistant.components.mysensors.*
homeassistant.components.nam.*
homeassistant.components.nest.*
homeassistant.components.netatmo.*
homeassistant.components.network.*
homeassistant.components.no_ip.*
homeassistant.components.notify.*
homeassistant.components.notion.*
homeassistant.components.number.*
homeassistant.components.onewire.*
homeassistant.components.openuv.*
homeassistant.components.persistent_notification.*
homeassistant.components.pi_hole.*
homeassistant.components.proximity.*
homeassistant.components.rainmachine.*
homeassistant.components.recollect_waste.*
homeassistant.components.recorder.purge
homeassistant.components.recorder.repack
homeassistant.components.recorder.statistics
homeassistant.components.remote.*
homeassistant.components.renault.*
homeassistant.components.rituals_perfume_genie.*
homeassistant.components.scene.*
homeassistant.components.select.*
homeassistant.components.sensor.*
homeassistant.components.shelly.*
homeassistant.components.simplisafe.*
homeassistant.components.slack.*
homeassistant.components.sonos.media_player
homeassistant.components.ssdp.*
homeassistant.components.stream.*
homeassistant.components.sun.*
homeassistant.components.switch.*
homeassistant.components.switcher_kis.*
homeassistant.components.synology_dsm.*
homeassistant.components.systemmonitor.*
homeassistant.components.tag.*
homeassistant.components.tcp.*
homeassistant.components.tile.*
homeassistant.components.tts.*
homeassistant.components.upcloud.*
homeassistant.components.uptime.*

15
.vscode/tasks.json vendored
View File

@@ -2,13 +2,10 @@
"version": "2.0.0",
"tasks": [
{
"label": "Preview",
"label": "Run Home Assistant Core",
"type": "shell",
"command": "hass -c ./config",
"group": {
"kind": "test",
"isDefault": true
},
"group": "test",
"presentation": {
"reveal": "always",
"panel": "new"
@@ -19,7 +16,9 @@
"label": "Pytest",
"type": "shell",
"command": "pytest --timeout=10 tests",
"dependsOn": ["Install all Test Requirements"],
"dependsOn": [
"Install all Test Requirements"
],
"group": {
"kind": "test",
"isDefault": true
@@ -48,7 +47,9 @@
"label": "Pylint",
"type": "shell",
"command": "pylint homeassistant",
"dependsOn": ["Install all Requirements"],
"dependsOn": [
"Install all Requirements"
],
"group": {
"kind": "test",
"isDefault": true

View File

@@ -22,6 +22,7 @@ homeassistant/scripts/check_config.py @kellerza
homeassistant/components/abode/* @shred86
homeassistant/components/accuweather/* @bieniu
homeassistant/components/acmeda/* @atmurray
homeassistant/components/adax/* @danielhiversen
homeassistant/components/adguard/* @frenck
homeassistant/components/advantage_air/* @Bre77
homeassistant/components/aemet/* @noltari
@@ -97,7 +98,7 @@ homeassistant/components/configurator/* @home-assistant/core
homeassistant/components/control4/* @lawtancool
homeassistant/components/conversation/* @home-assistant/core
homeassistant/components/coolmaster/* @OnFreund
homeassistant/components/coronavirus/* @home_assistant/core
homeassistant/components/coronavirus/* @home-assistant/core
homeassistant/components/counter/* @fabaff
homeassistant/components/cover/* @home-assistant/core
homeassistant/components/cpuspeed/* @fabaff
@@ -139,6 +140,7 @@ homeassistant/components/emby/* @mezz64
homeassistant/components/emoncms/* @borpin
homeassistant/components/emonitor/* @bdraco
homeassistant/components/emulated_kasa/* @kbickar
homeassistant/components/energy/* @home-assistant/core
homeassistant/components/enigma2/* @fbradyirl
homeassistant/components/enocean/* @bdurrer
homeassistant/components/enphase_envoy/* @gtdiehl
@@ -160,6 +162,7 @@ homeassistant/components/fireservicerota/* @cyberjunky
homeassistant/components/firmata/* @DaAwesomeP
homeassistant/components/fixer/* @fabaff
homeassistant/components/flick_electric/* @ZephireNZ
homeassistant/components/flipr/* @cnico
homeassistant/components/flo/* @dmulcahey
homeassistant/components/flock/* @fabaff
homeassistant/components/flume/* @ChrisMandich @bdraco
@@ -175,8 +178,8 @@ homeassistant/components/fritzbox/* @mib1185
homeassistant/components/fronius/* @nielstron
homeassistant/components/frontend/* @home-assistant/frontend
homeassistant/components/garages_amsterdam/* @klaasnicolaas
homeassistant/components/garmin_connect/* @cyberjunky
homeassistant/components/gdacs/* @exxamalte
homeassistant/components/generic_hygrostat/* @Shulyaka
homeassistant/components/geniushub/* @zxdavb
homeassistant/components/geo_json_events/* @exxamalte
homeassistant/components/geo_rss_events/* @exxamalte
@@ -213,6 +216,7 @@ homeassistant/components/homeassistant/* @home-assistant/core
homeassistant/components/homekit/* @bdraco
homeassistant/components/homekit_controller/* @Jc2k @bdraco
homeassistant/components/homematic/* @pvizeli @danielperna84
homeassistant/components/honeywell/* @rdfurman
homeassistant/components/http/* @home-assistant/core
homeassistant/components/huawei_lte/* @scop @fphammerle
homeassistant/components/huawei_router/* @abmantis
@@ -329,6 +333,7 @@ homeassistant/components/netdata/* @fabaff
homeassistant/components/nexia/* @bdraco
homeassistant/components/nextbus/* @vividboarder
homeassistant/components/nextcloud/* @meichthys
homeassistant/components/nfandroidtv/* @tkdrob
homeassistant/components/nightscout/* @marciogranzotto
homeassistant/components/nilu/* @hfurubotten
homeassistant/components/nissan_leaf/* @filcole
@@ -384,6 +389,7 @@ homeassistant/components/powerwall/* @bdraco @jrester
homeassistant/components/profiler/* @bdraco
homeassistant/components/progettihwsw/* @ardaseremet
homeassistant/components/prometheus/* @knyar
homeassistant/components/prosegur/* @dgomes
homeassistant/components/proxmoxve/* @k4ds3 @jhollowe @Corbeno
homeassistant/components/ps4/* @ktnrg45
homeassistant/components/push/* @dgomes
@@ -404,6 +410,7 @@ homeassistant/components/rainmachine/* @bachya
homeassistant/components/random/* @fabaff
homeassistant/components/recollect_waste/* @bachya
homeassistant/components/rejseplanen/* @DarkFox
homeassistant/components/renault/* @epenet
homeassistant/components/repetier/* @MTrab
homeassistant/components/rflink/* @javicalle
homeassistant/components/rfxtrx/* @danielhiversen @elupus @RobBie1221
@@ -442,6 +449,7 @@ homeassistant/components/sighthound/* @robmarkcole
homeassistant/components/signal_messenger/* @bbernhard
homeassistant/components/simplisafe/* @bachya
homeassistant/components/sinch/* @bendikrb
homeassistant/components/siren/* @home-assistant/core @raman325
homeassistant/components/sisyphus/* @jkeljo
homeassistant/components/sky_hub/* @rogerselwyn
homeassistant/components/slack/* @bachya
@@ -502,7 +510,7 @@ homeassistant/components/tapsaff/* @bazwilliams
homeassistant/components/tasmota/* @emontnemery
homeassistant/components/tautulli/* @ludeeus
homeassistant/components/tellduslive/* @fredrike
homeassistant/components/template/* @PhracturedBlue @tetienne
homeassistant/components/template/* @PhracturedBlue @tetienne @home-assistant/core
homeassistant/components/tesla/* @zabuldon @alandtse
homeassistant/components/tfiac/* @fredrike @mellado
homeassistant/components/thethingsnetwork/* @fabaff
@@ -554,11 +562,12 @@ homeassistant/components/wallbox/* @hesselonline
homeassistant/components/waqi/* @andrey-git
homeassistant/components/watson_tts/* @rutkai
homeassistant/components/weather/* @fabaff
homeassistant/components/webostv/* @bendavid
homeassistant/components/webostv/* @bendavid @thecode
homeassistant/components/websocket_api/* @home-assistant/core
homeassistant/components/wemo/* @esev
homeassistant/components/wiffi/* @mampfes
homeassistant/components/wilight/* @leofig-rj
homeassistant/components/wirelesstag/* @sergeymaysak
homeassistant/components/withings/* @vangorra
homeassistant/components/wled/* @frenck
homeassistant/components/wolflink/* @adamkrol93
@@ -576,6 +585,7 @@ homeassistant/components/yandex_transport/* @rishatik92 @devbis
homeassistant/components/yeelight/* @rytilahti @zewelor @shenxn
homeassistant/components/yeelightsunflower/* @lindsaymarkward
homeassistant/components/yi/* @bachya
homeassistant/components/youless/* @gjong
homeassistant/components/zeroconf/* @bdraco
homeassistant/components/zerproc/* @emlove
homeassistant/components/zha/* @dmulcahey @adminiuga

View File

@@ -2,11 +2,11 @@
"image": "homeassistant/{arch}-homeassistant",
"shadow_repository": "ghcr.io/home-assistant",
"build_from": {
"aarch64": "ghcr.io/home-assistant/aarch64-homeassistant-base:2021.06.2",
"armhf": "ghcr.io/home-assistant/armhf-homeassistant-base:2021.06.2",
"armv7": "ghcr.io/home-assistant/armv7-homeassistant-base:2021.06.2",
"amd64": "ghcr.io/home-assistant/amd64-homeassistant-base:2021.06.2",
"i386": "ghcr.io/home-assistant/i386-homeassistant-base:2021.06.2"
"aarch64": "ghcr.io/home-assistant/aarch64-homeassistant-base:2021.07.0",
"armhf": "ghcr.io/home-assistant/armhf-homeassistant-base:2021.07.0",
"armv7": "ghcr.io/home-assistant/armv7-homeassistant-base:2021.07.0",
"amd64": "ghcr.io/home-assistant/amd64-homeassistant-base:2021.07.0",
"i386": "ghcr.io/home-assistant/i386-homeassistant-base:2021.07.0"
},
"labels": {
"io.hass.type": "core",

View File

@@ -146,8 +146,8 @@ def daemonize() -> None:
# redirect standard file descriptors to devnull
# pylint: disable=consider-using-with
infd = open(os.devnull)
outfd = open(os.devnull, "a+")
infd = open(os.devnull, encoding="utf8")
outfd = open(os.devnull, "a+", encoding="utf8")
sys.stdout.flush()
sys.stderr.flush()
os.dup2(infd.fileno(), sys.stdin.fileno())
@@ -159,7 +159,7 @@ def check_pid(pid_file: str) -> None:
"""Check that Home Assistant is not already running."""
# Check pid file
try:
with open(pid_file) as file:
with open(pid_file, encoding="utf8") as file:
pid = int(file.readline())
except OSError:
# PID File does not exist
@@ -182,7 +182,7 @@ def write_pid(pid_file: str) -> None:
"""Create a PID File."""
pid = os.getpid()
try:
with open(pid_file, "w") as file:
with open(pid_file, "w", encoding="utf8") as file:
file.write(str(pid))
except OSError:
print(f"Fatal Error: Unable to write pid file {pid_file}")

View File

@@ -1,7 +1,7 @@
"""Auth provider that validates credentials via an external command."""
from __future__ import annotations
import asyncio.subprocess
import asyncio
import collections
from collections.abc import Mapping
import logging
@@ -64,7 +64,7 @@ class CommandLineAuthProvider(AuthProvider):
"""Validate a username and password."""
env = {"username": username, "password": password}
try:
process = await asyncio.subprocess.create_subprocess_exec( # pylint: disable=no-member
process = await asyncio.create_subprocess_exec(
self.config[CONF_COMMAND],
*self.config[CONF_ARGS],
env=env,

View File

@@ -1,5 +1,4 @@
"""Support for the Abode Security System."""
from copy import deepcopy
from functools import partial
from abodepy import Abode
@@ -8,7 +7,6 @@ import abodepy.helpers.timeline as TIMELINE
from requests.exceptions import ConnectTimeout, HTTPError
import voluptuous as vol
from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import (
ATTR_ATTRIBUTION,
ATTR_DATE,
@@ -44,22 +42,7 @@ ATTR_APP_TYPE = "app_type"
ATTR_EVENT_BY = "event_by"
ATTR_VALUE = "value"
CONFIG_SCHEMA = vol.Schema(
vol.All(
# Deprecated in Home Assistant 2021.6
cv.deprecated(DOMAIN),
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_POLLING, default=False): cv.boolean,
}
)
},
),
extra=vol.ALLOW_EXTRA,
)
CONFIG_SCHEMA = cv.deprecated(DOMAIN)
CHANGE_SETTING_SCHEMA = vol.Schema(
{vol.Required(ATTR_SETTING): cv.string, vol.Required(ATTR_VALUE): cv.string}
@@ -92,22 +75,6 @@ class AbodeSystem:
self.logout_listener = None
async def async_setup(hass, config):
"""Set up Abode integration."""
if DOMAIN not in config:
return True
conf = config[DOMAIN]
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=deepcopy(conf)
)
)
return True
async def async_setup_entry(hass, config_entry):
"""Set up Abode integration from a config entry."""
username = config_entry.data.get(CONF_USERNAME)
@@ -284,17 +251,13 @@ class AbodeEntity(Entity):
"""Initialize Abode entity."""
self._data = data
self._available = True
self._attr_should_poll = data.polling
@property
def available(self):
"""Return the available state."""
return self._available
@property
def should_poll(self):
"""Return the polling state."""
return self._data.polling
async def async_added_to_hass(self):
"""Subscribe to Abode connection status updates."""
await self.hass.async_add_executor_job(
@@ -324,6 +287,8 @@ class AbodeDevice(AbodeEntity):
"""Initialize Abode device."""
super().__init__(data)
self._device = device
self._attr_name = device.name
self._attr_unique_id = device.device_uuid
async def async_added_to_hass(self):
"""Subscribe to device events."""
@@ -345,11 +310,6 @@ class AbodeDevice(AbodeEntity):
"""Update device state."""
self._device.refresh()
@property
def name(self):
"""Return the name of the device."""
return self._device.name
@property
def extra_state_attributes(self):
"""Return the state attributes."""
@@ -361,11 +321,6 @@ class AbodeDevice(AbodeEntity):
"device_type": self._device.type,
}
@property
def unique_id(self):
"""Return a unique ID to use for this device."""
return self._device.device_uuid
@property
def device_info(self):
"""Return device registry information for this entity."""
@@ -388,22 +343,13 @@ class AbodeAutomation(AbodeEntity):
"""Initialize for Abode automation."""
super().__init__(data)
self._automation = automation
self._attr_name = automation.name
self._attr_unique_id = automation.automation_id
self._attr_extra_state_attributes = {
ATTR_ATTRIBUTION: ATTRIBUTION,
"type": "CUE automation",
}
def update(self):
"""Update automation state."""
self._automation.refresh()
@property
def name(self):
"""Return the name of the automation."""
return self._automation.name
@property
def extra_state_attributes(self):
"""Return the state attributes."""
return {ATTR_ATTRIBUTION: ATTRIBUTION, "type": "CUE automation"}
@property
def unique_id(self):
"""Return a unique ID to use for this automation."""
return self._automation.automation_id

View File

@@ -28,10 +28,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class AbodeAlarm(AbodeDevice, alarm.AlarmControlPanelEntity):
"""An alarm_control_panel implementation for Abode."""
@property
def icon(self):
"""Return the icon."""
return ICON
_attr_icon = ICON
_attr_code_arm_required = False
_attr_supported_features = SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY
@property
def state(self):
@@ -46,16 +45,6 @@ class AbodeAlarm(AbodeDevice, alarm.AlarmControlPanelEntity):
state = None
return state
@property
def code_arm_required(self):
"""Whether the code is required for arm actions."""
return False
@property
def supported_features(self) -> int:
"""Return the list of supported features."""
return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._device.set_standby()

View File

@@ -158,13 +158,3 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
self._password = user_input[CONF_PASSWORD]
return await self._async_abode_login(step_id="reauth_confirm")
async def async_step_import(self, import_config):
"""Import a config entry from configuration.yaml."""
if self._async_current_entries():
LOGGER.warning("Already configured; Only a single configuration possible")
return self.async_abort(reason="single_instance_allowed")
self._polling = import_config.get(CONF_POLLING, False)
return await self.async_step_user(import_config)

View File

@@ -41,23 +41,15 @@ class AbodeSensor(AbodeDevice, SensorEntity):
"""Initialize a sensor for an Abode device."""
super().__init__(data, device)
self._sensor_type = sensor_type
self._name = f"{self._device.name} {SENSOR_TYPES[self._sensor_type][0]}"
self._device_class = SENSOR_TYPES[self._sensor_type][1]
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def device_class(self):
"""Return the device class."""
return self._device_class
@property
def unique_id(self):
"""Return a unique ID to use for this device."""
return f"{self._device.device_uuid}-{self._sensor_type}"
self._attr_name = f"{device.name} {SENSOR_TYPES[sensor_type][0]}"
self._attr_device_class = SENSOR_TYPES[self._sensor_type][1]
self._attr_unique_id = f"{device.device_uuid}-{sensor_type}"
if self._sensor_type == CONST.TEMP_STATUS_KEY:
self._attr_unit_of_measurement = device.temp_unit
elif self._sensor_type == CONST.HUMI_STATUS_KEY:
self._attr_unit_of_measurement = device.humidity_unit
elif self._sensor_type == CONST.LUX_STATUS_KEY:
self._attr_unit_of_measurement = device.lux_unit
@property
def state(self):
@@ -68,13 +60,3 @@ class AbodeSensor(AbodeDevice, SensorEntity):
return self._device.humidity
if self._sensor_type == CONST.LUX_STATUS_KEY:
return self._device.lux
@property
def unit_of_measurement(self):
"""Return the units of measurement."""
if self._sensor_type == CONST.TEMP_STATUS_KEY:
return self._device.temp_unit
if self._sensor_type == CONST.HUMI_STATUS_KEY:
return self._device.humidity_unit
if self._sensor_type == CONST.LUX_STATUS_KEY:
return self._device.lux_unit

View File

@@ -48,6 +48,8 @@ class AbodeSwitch(AbodeDevice, SwitchEntity):
class AbodeAutomationSwitch(AbodeAutomation, SwitchEntity):
"""A switch implementation for Abode automations."""
_attr_icon = ICON
async def async_added_to_hass(self):
"""Set up trigger automation service."""
await super().async_added_to_hass()
@@ -73,8 +75,3 @@ class AbodeAutomationSwitch(AbodeAutomation, SwitchEntity):
def is_on(self):
"""Return True if the automation is enabled."""
return self._automation.is_enabled
@property
def icon(self):
"""Return the robot icon to match Home Assistant automations."""
return ICON

View File

@@ -26,7 +26,7 @@
"user": {
"data": {
"password": "Passwort",
"username": "E-Mail-Adresse"
"username": "E-Mail"
},
"title": "Gib deine Abode-Anmeldeinformationen ein"
}

View File

@@ -1,9 +1,12 @@
{
"config": {
"abort": {
"reauth_successful": "La reautenticaci\u00f3n fue exitosa",
"single_instance_allowed": "Solo se permite una \u00fanica configuraci\u00f3n de Abode."
},
"error": {
"cannot_connect": "No se pudo conectar",
"invalid_auth": "Autenticaci\u00f3n inv\u00e1lida",
"invalid_mfa_code": "C\u00f3digo MFA no v\u00e1lido"
},
"step": {
@@ -15,7 +18,8 @@
},
"reauth_confirm": {
"data": {
"password": "Contrase\u00f1a"
"password": "Contrase\u00f1a",
"username": "Correo electr\u00f3nico"
},
"title": "Complete su informaci\u00f3n de inicio de sesi\u00f3n de Abode"
},

View File

@@ -20,7 +20,8 @@
"data": {
"password": "Jelsz\u00f3",
"username": "E-mail"
}
},
"title": "T\u00f6ltse ki az Abode bejelentkez\u00e9si adatait"
},
"user": {
"data": {

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
from typing import Final
from homeassistant.components.sensor import ATTR_STATE_CLASS, STATE_CLASS_MEASUREMENT
from homeassistant.components.sensor import STATE_CLASS_MEASUREMENT
from homeassistant.components.weather import (
ATTR_CONDITION_CLEAR_NIGHT,
ATTR_CONDITION_CLOUDY,
@@ -21,8 +21,6 @@ from homeassistant.components.weather import (
ATTR_CONDITION_WINDY,
)
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_ICON,
CONCENTRATION_PARTS_PER_CUBIC_METER,
DEVICE_CLASS_TEMPERATURE,
LENGTH_FEET,
@@ -38,16 +36,12 @@ from homeassistant.const import (
UV_INDEX,
)
from .model import SensorDescription
from .model import AccuWeatherSensorDescription
API_IMPERIAL: Final = "Imperial"
API_METRIC: Final = "Metric"
ATTRIBUTION: Final = "Data provided by AccuWeather"
ATTR_ENABLED: Final = "enabled"
ATTR_FORECAST: Final = "forecast"
ATTR_LABEL: Final = "label"
ATTR_UNIT_IMPERIAL: Final = "unit_imperial"
ATTR_UNIT_METRIC: Final = "unit_metric"
CONF_FORECAST: Final = "forecast"
DOMAIN: Final = "accuweather"
MANUFACTURER: Final = "AccuWeather, Inc."
@@ -71,276 +65,263 @@ CONDITION_CLASSES: Final[dict[str, list[int]]] = {
ATTR_CONDITION_WINDY: [32],
}
FORECAST_SENSOR_TYPES: Final[dict[str, SensorDescription]] = {
"CloudCoverDay": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-cloudy",
ATTR_LABEL: "Cloud Cover Day",
ATTR_UNIT_METRIC: PERCENTAGE,
ATTR_UNIT_IMPERIAL: PERCENTAGE,
ATTR_ENABLED: False,
},
"CloudCoverNight": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-cloudy",
ATTR_LABEL: "Cloud Cover Night",
ATTR_UNIT_METRIC: PERCENTAGE,
ATTR_UNIT_IMPERIAL: PERCENTAGE,
ATTR_ENABLED: False,
},
"Grass": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:grass",
ATTR_LABEL: "Grass Pollen",
ATTR_UNIT_METRIC: CONCENTRATION_PARTS_PER_CUBIC_METER,
ATTR_UNIT_IMPERIAL: CONCENTRATION_PARTS_PER_CUBIC_METER,
ATTR_ENABLED: False,
},
"HoursOfSun": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-partly-cloudy",
ATTR_LABEL: "Hours Of Sun",
ATTR_UNIT_METRIC: TIME_HOURS,
ATTR_UNIT_IMPERIAL: TIME_HOURS,
ATTR_ENABLED: True,
},
"Mold": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:blur",
ATTR_LABEL: "Mold Pollen",
ATTR_UNIT_METRIC: CONCENTRATION_PARTS_PER_CUBIC_METER,
ATTR_UNIT_IMPERIAL: CONCENTRATION_PARTS_PER_CUBIC_METER,
ATTR_ENABLED: False,
},
"Ozone": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:vector-triangle",
ATTR_LABEL: "Ozone",
ATTR_UNIT_METRIC: None,
ATTR_UNIT_IMPERIAL: None,
ATTR_ENABLED: False,
},
"Ragweed": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:sprout",
ATTR_LABEL: "Ragweed Pollen",
ATTR_UNIT_METRIC: CONCENTRATION_PARTS_PER_CUBIC_METER,
ATTR_UNIT_IMPERIAL: CONCENTRATION_PARTS_PER_CUBIC_METER,
ATTR_ENABLED: False,
},
"RealFeelTemperatureMax": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "RealFeel Temperature Max",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: True,
},
"RealFeelTemperatureMin": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "RealFeel Temperature Min",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: True,
},
"RealFeelTemperatureShadeMax": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "RealFeel Temperature Shade Max",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: False,
},
"RealFeelTemperatureShadeMin": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "RealFeel Temperature Shade Min",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: False,
},
"ThunderstormProbabilityDay": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-lightning",
ATTR_LABEL: "Thunderstorm Probability Day",
ATTR_UNIT_METRIC: PERCENTAGE,
ATTR_UNIT_IMPERIAL: PERCENTAGE,
ATTR_ENABLED: True,
},
"ThunderstormProbabilityNight": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-lightning",
ATTR_LABEL: "Thunderstorm Probability Night",
ATTR_UNIT_METRIC: PERCENTAGE,
ATTR_UNIT_IMPERIAL: PERCENTAGE,
ATTR_ENABLED: True,
},
"Tree": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:tree-outline",
ATTR_LABEL: "Tree Pollen",
ATTR_UNIT_METRIC: CONCENTRATION_PARTS_PER_CUBIC_METER,
ATTR_UNIT_IMPERIAL: CONCENTRATION_PARTS_PER_CUBIC_METER,
ATTR_ENABLED: False,
},
"UVIndex": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-sunny",
ATTR_LABEL: "UV Index",
ATTR_UNIT_METRIC: UV_INDEX,
ATTR_UNIT_IMPERIAL: UV_INDEX,
ATTR_ENABLED: True,
},
"WindGustDay": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-windy",
ATTR_LABEL: "Wind Gust Day",
ATTR_UNIT_METRIC: SPEED_KILOMETERS_PER_HOUR,
ATTR_UNIT_IMPERIAL: SPEED_MILES_PER_HOUR,
ATTR_ENABLED: False,
},
"WindGustNight": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-windy",
ATTR_LABEL: "Wind Gust Night",
ATTR_UNIT_METRIC: SPEED_KILOMETERS_PER_HOUR,
ATTR_UNIT_IMPERIAL: SPEED_MILES_PER_HOUR,
ATTR_ENABLED: False,
},
"WindDay": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-windy",
ATTR_LABEL: "Wind Day",
ATTR_UNIT_METRIC: SPEED_KILOMETERS_PER_HOUR,
ATTR_UNIT_IMPERIAL: SPEED_MILES_PER_HOUR,
ATTR_ENABLED: True,
},
"WindNight": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-windy",
ATTR_LABEL: "Wind Night",
ATTR_UNIT_METRIC: SPEED_KILOMETERS_PER_HOUR,
ATTR_UNIT_IMPERIAL: SPEED_MILES_PER_HOUR,
ATTR_ENABLED: True,
},
}
FORECAST_SENSOR_TYPES: Final[tuple[AccuWeatherSensorDescription, ...]] = (
AccuWeatherSensorDescription(
key="CloudCoverDay",
icon="mdi:weather-cloudy",
name="Cloud Cover Day",
unit_metric=PERCENTAGE,
unit_imperial=PERCENTAGE,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="CloudCoverNight",
icon="mdi:weather-cloudy",
name="Cloud Cover Night",
unit_metric=PERCENTAGE,
unit_imperial=PERCENTAGE,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="Grass",
icon="mdi:grass",
name="Grass Pollen",
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="HoursOfSun",
icon="mdi:weather-partly-cloudy",
name="Hours Of Sun",
unit_metric=TIME_HOURS,
unit_imperial=TIME_HOURS,
),
AccuWeatherSensorDescription(
key="Mold",
icon="mdi:blur",
name="Mold Pollen",
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="Ozone",
icon="mdi:vector-triangle",
name="Ozone",
unit_metric=None,
unit_imperial=None,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="Ragweed",
icon="mdi:sprout",
name="Ragweed Pollen",
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="RealFeelTemperatureMax",
device_class=DEVICE_CLASS_TEMPERATURE,
name="RealFeel Temperature Max",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
),
AccuWeatherSensorDescription(
key="RealFeelTemperatureMin",
device_class=DEVICE_CLASS_TEMPERATURE,
name="RealFeel Temperature Min",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
),
AccuWeatherSensorDescription(
key="RealFeelTemperatureShadeMax",
device_class=DEVICE_CLASS_TEMPERATURE,
name="RealFeel Temperature Shade Max",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="RealFeelTemperatureShadeMin",
device_class=DEVICE_CLASS_TEMPERATURE,
name="RealFeel Temperature Shade Min",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="ThunderstormProbabilityDay",
icon="mdi:weather-lightning",
name="Thunderstorm Probability Day",
unit_metric=PERCENTAGE,
unit_imperial=PERCENTAGE,
),
AccuWeatherSensorDescription(
key="ThunderstormProbabilityNight",
icon="mdi:weather-lightning",
name="Thunderstorm Probability Night",
unit_metric=PERCENTAGE,
unit_imperial=PERCENTAGE,
),
AccuWeatherSensorDescription(
key="Tree",
icon="mdi:tree-outline",
name="Tree Pollen",
unit_metric=CONCENTRATION_PARTS_PER_CUBIC_METER,
unit_imperial=CONCENTRATION_PARTS_PER_CUBIC_METER,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="UVIndex",
icon="mdi:weather-sunny",
name="UV Index",
unit_metric=UV_INDEX,
unit_imperial=UV_INDEX,
),
AccuWeatherSensorDescription(
key="WindGustDay",
icon="mdi:weather-windy",
name="Wind Gust Day",
unit_metric=SPEED_KILOMETERS_PER_HOUR,
unit_imperial=SPEED_MILES_PER_HOUR,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="WindGustNight",
icon="mdi:weather-windy",
name="Wind Gust Night",
unit_metric=SPEED_KILOMETERS_PER_HOUR,
unit_imperial=SPEED_MILES_PER_HOUR,
entity_registry_enabled_default=False,
),
AccuWeatherSensorDescription(
key="WindDay",
icon="mdi:weather-windy",
name="Wind Day",
unit_metric=SPEED_KILOMETERS_PER_HOUR,
unit_imperial=SPEED_MILES_PER_HOUR,
),
AccuWeatherSensorDescription(
key="WindNight",
icon="mdi:weather-windy",
name="Wind Night",
unit_metric=SPEED_KILOMETERS_PER_HOUR,
unit_imperial=SPEED_MILES_PER_HOUR,
),
)
SENSOR_TYPES: Final[dict[str, SensorDescription]] = {
"ApparentTemperature": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "Apparent Temperature",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: False,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"Ceiling": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-fog",
ATTR_LABEL: "Cloud Ceiling",
ATTR_UNIT_METRIC: LENGTH_METERS,
ATTR_UNIT_IMPERIAL: LENGTH_FEET,
ATTR_ENABLED: True,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"CloudCover": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-cloudy",
ATTR_LABEL: "Cloud Cover",
ATTR_UNIT_METRIC: PERCENTAGE,
ATTR_UNIT_IMPERIAL: PERCENTAGE,
ATTR_ENABLED: False,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"DewPoint": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "Dew Point",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: False,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"RealFeelTemperature": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "RealFeel Temperature",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: True,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"RealFeelTemperatureShade": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "RealFeel Temperature Shade",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: False,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"Precipitation": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-rainy",
ATTR_LABEL: "Precipitation",
ATTR_UNIT_METRIC: LENGTH_MILLIMETERS,
ATTR_UNIT_IMPERIAL: LENGTH_INCHES,
ATTR_ENABLED: True,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"PressureTendency": {
ATTR_DEVICE_CLASS: "accuweather__pressure_tendency",
ATTR_ICON: "mdi:gauge",
ATTR_LABEL: "Pressure Tendency",
ATTR_UNIT_METRIC: None,
ATTR_UNIT_IMPERIAL: None,
ATTR_ENABLED: True,
},
"UVIndex": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-sunny",
ATTR_LABEL: "UV Index",
ATTR_UNIT_METRIC: UV_INDEX,
ATTR_UNIT_IMPERIAL: UV_INDEX,
ATTR_ENABLED: True,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"WetBulbTemperature": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "Wet Bulb Temperature",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: False,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"WindChillTemperature": {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: None,
ATTR_LABEL: "Wind Chill Temperature",
ATTR_UNIT_METRIC: TEMP_CELSIUS,
ATTR_UNIT_IMPERIAL: TEMP_FAHRENHEIT,
ATTR_ENABLED: False,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"Wind": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-windy",
ATTR_LABEL: "Wind",
ATTR_UNIT_METRIC: SPEED_KILOMETERS_PER_HOUR,
ATTR_UNIT_IMPERIAL: SPEED_MILES_PER_HOUR,
ATTR_ENABLED: True,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
"WindGust": {
ATTR_DEVICE_CLASS: None,
ATTR_ICON: "mdi:weather-windy",
ATTR_LABEL: "Wind Gust",
ATTR_UNIT_METRIC: SPEED_KILOMETERS_PER_HOUR,
ATTR_UNIT_IMPERIAL: SPEED_MILES_PER_HOUR,
ATTR_ENABLED: False,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
},
}
SENSOR_TYPES: Final[tuple[AccuWeatherSensorDescription, ...]] = (
AccuWeatherSensorDescription(
key="ApparentTemperature",
device_class=DEVICE_CLASS_TEMPERATURE,
name="Apparent Temperature",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
entity_registry_enabled_default=False,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="Ceiling",
icon="mdi:weather-fog",
name="Cloud Ceiling",
unit_metric=LENGTH_METERS,
unit_imperial=LENGTH_FEET,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="CloudCover",
icon="mdi:weather-cloudy",
name="Cloud Cover",
unit_metric=PERCENTAGE,
unit_imperial=PERCENTAGE,
entity_registry_enabled_default=False,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="DewPoint",
device_class=DEVICE_CLASS_TEMPERATURE,
name="Dew Point",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
entity_registry_enabled_default=False,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="RealFeelTemperature",
device_class=DEVICE_CLASS_TEMPERATURE,
name="RealFeel Temperature",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="RealFeelTemperatureShade",
device_class=DEVICE_CLASS_TEMPERATURE,
name="RealFeel Temperature Shade",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
entity_registry_enabled_default=False,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="Precipitation",
icon="mdi:weather-rainy",
name="Precipitation",
unit_metric=LENGTH_MILLIMETERS,
unit_imperial=LENGTH_INCHES,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="PressureTendency",
device_class="accuweather__pressure_tendency",
icon="mdi:gauge",
name="Pressure Tendency",
unit_metric=None,
unit_imperial=None,
),
AccuWeatherSensorDescription(
key="UVIndex",
icon="mdi:weather-sunny",
name="UV Index",
unit_metric=UV_INDEX,
unit_imperial=UV_INDEX,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="WetBulbTemperature",
device_class=DEVICE_CLASS_TEMPERATURE,
name="Wet Bulb Temperature",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
entity_registry_enabled_default=False,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="WindChillTemperature",
device_class=DEVICE_CLASS_TEMPERATURE,
name="Wind Chill Temperature",
unit_metric=TEMP_CELSIUS,
unit_imperial=TEMP_FAHRENHEIT,
entity_registry_enabled_default=False,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="Wind",
icon="mdi:weather-windy",
name="Wind",
unit_metric=SPEED_KILOMETERS_PER_HOUR,
unit_imperial=SPEED_MILES_PER_HOUR,
state_class=STATE_CLASS_MEASUREMENT,
),
AccuWeatherSensorDescription(
key="WindGust",
icon="mdi:weather-windy",
name="Wind Gust",
unit_metric=SPEED_KILOMETERS_PER_HOUR,
unit_imperial=SPEED_MILES_PER_HOUR,
entity_registry_enabled_default=False,
state_class=STATE_CLASS_MEASUREMENT,
),
)

View File

@@ -1,16 +1,14 @@
"""Type definitions for AccuWeather integration."""
from __future__ import annotations
from typing import TypedDict
from dataclasses import dataclass
from homeassistant.components.sensor import SensorEntityDescription
class SensorDescription(TypedDict, total=False):
"""Sensor description class."""
@dataclass
class AccuWeatherSensorDescription(SensorEntityDescription):
"""Class describing AccuWeather sensor entities."""
device_class: str | None
icon: str | None
label: str
unit_metric: str | None
unit_imperial: str | None
enabled: bool
state_class: str | None
unit_metric: str | None = None
unit_imperial: str | None = None

View File

@@ -3,17 +3,10 @@ from __future__ import annotations
from typing import Any, cast
from homeassistant.components.sensor import ATTR_STATE_CLASS, SensorEntity
from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ATTRIBUTION,
ATTR_DEVICE_CLASS,
ATTR_ICON,
CONF_NAME,
DEVICE_CLASS_TEMPERATURE,
)
from homeassistant.const import ATTR_ATTRIBUTION, CONF_NAME, DEVICE_CLASS_TEMPERATURE
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@@ -22,11 +15,7 @@ from . import AccuWeatherDataUpdateCoordinator
from .const import (
API_IMPERIAL,
API_METRIC,
ATTR_ENABLED,
ATTR_FORECAST,
ATTR_LABEL,
ATTR_UNIT_IMPERIAL,
ATTR_UNIT_METRIC,
ATTRIBUTION,
DOMAIN,
FORECAST_SENSOR_TYPES,
@@ -35,6 +24,7 @@ from .const import (
NAME,
SENSOR_TYPES,
)
from .model import AccuWeatherSensorDescription
PARALLEL_UPDATES = 1
@@ -48,17 +38,19 @@ async def async_setup_entry(
coordinator: AccuWeatherDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
sensors: list[AccuWeatherSensor] = []
for sensor in SENSOR_TYPES:
sensors.append(AccuWeatherSensor(name, sensor, coordinator))
for description in SENSOR_TYPES:
sensors.append(AccuWeatherSensor(name, coordinator, description))
if coordinator.forecast:
for sensor in FORECAST_SENSOR_TYPES:
for description in FORECAST_SENSOR_TYPES:
for day in range(MAX_FORECAST_DAYS + 1):
# Some air quality/allergy sensors are only available for certain
# locations.
if sensor in coordinator.data[ATTR_FORECAST][0]:
if description.key in coordinator.data[ATTR_FORECAST][0]:
sensors.append(
AccuWeatherSensor(name, sensor, coordinator, forecast_day=day)
AccuWeatherSensor(
name, coordinator, description, forecast_day=day
)
)
async_add_entities(sensors)
@@ -68,119 +60,107 @@ class AccuWeatherSensor(CoordinatorEntity, SensorEntity):
"""Define an AccuWeather entity."""
coordinator: AccuWeatherDataUpdateCoordinator
entity_description: AccuWeatherSensorDescription
def __init__(
self,
name: str,
kind: str,
coordinator: AccuWeatherDataUpdateCoordinator,
description: AccuWeatherSensorDescription,
forecast_day: int | None = None,
) -> None:
"""Initialize."""
super().__init__(coordinator)
self._sensor_data = _get_sensor_data(coordinator.data, forecast_day, kind)
if forecast_day is None:
self._description = SENSOR_TYPES[kind]
else:
self._description = FORECAST_SENSOR_TYPES[kind]
self._unit_system = API_METRIC if coordinator.is_metric else API_IMPERIAL
self._name = name
self.kind = kind
self._device_class = None
self.entity_description = description
self._sensor_data = _get_sensor_data(
coordinator.data, forecast_day, description.key
)
self._attrs = {ATTR_ATTRIBUTION: ATTRIBUTION}
self.forecast_day = forecast_day
self._attr_state_class = self._description.get(ATTR_STATE_CLASS)
@property
def name(self) -> str:
"""Return the name."""
if self.forecast_day is not None:
return f"{self._name} {self._description[ATTR_LABEL]} {self.forecast_day}d"
return f"{self._name} {self._description[ATTR_LABEL]}"
@property
def unique_id(self) -> str:
"""Return a unique_id for this entity."""
if self.forecast_day is not None:
return f"{self.coordinator.location_key}-{self.kind}-{self.forecast_day}".lower()
return f"{self.coordinator.location_key}-{self.kind}".lower()
@property
def device_info(self) -> DeviceInfo:
"""Return the device info."""
return {
"identifiers": {(DOMAIN, self.coordinator.location_key)},
if forecast_day is not None:
self._attr_name = f"{name} {description.name} {forecast_day}d"
self._attr_unique_id = (
f"{coordinator.location_key}-{description.key}-{forecast_day}".lower()
)
else:
self._attr_name = f"{name} {description.name}"
self._attr_unique_id = (
f"{coordinator.location_key}-{description.key}".lower()
)
if coordinator.is_metric:
self._unit_system = API_METRIC
self._attr_unit_of_measurement = description.unit_metric
else:
self._unit_system = API_IMPERIAL
self._attr_unit_of_measurement = description.unit_imperial
self._attr_device_info = {
"identifiers": {(DOMAIN, coordinator.location_key)},
"name": NAME,
"manufacturer": MANUFACTURER,
"entry_type": "service",
}
self.forecast_day = forecast_day
@property
def state(self) -> StateType:
"""Return the state."""
if self.forecast_day is not None:
if self._description["device_class"] == DEVICE_CLASS_TEMPERATURE:
if self.entity_description.device_class == DEVICE_CLASS_TEMPERATURE:
return cast(float, self._sensor_data["Value"])
if self.kind == "UVIndex":
if self.entity_description.key == "UVIndex":
return cast(int, self._sensor_data["Value"])
if self.kind in ["Grass", "Mold", "Ragweed", "Tree", "Ozone"]:
if self.entity_description.key in ("Grass", "Mold", "Ragweed", "Tree", "Ozone"):
return cast(int, self._sensor_data["Value"])
if self.kind == "Ceiling":
if self.entity_description.key == "Ceiling":
return round(self._sensor_data[self._unit_system]["Value"])
if self.kind == "PressureTendency":
if self.entity_description.key == "PressureTendency":
return cast(str, self._sensor_data["LocalizedText"].lower())
if self._description["device_class"] == DEVICE_CLASS_TEMPERATURE:
if self.entity_description.device_class == DEVICE_CLASS_TEMPERATURE:
return cast(float, self._sensor_data[self._unit_system]["Value"])
if self.kind == "Precipitation":
if self.entity_description.key == "Precipitation":
return cast(float, self._sensor_data[self._unit_system]["Value"])
if self.kind in ["Wind", "WindGust"]:
if self.entity_description.key in ("Wind", "WindGust"):
return cast(float, self._sensor_data["Speed"][self._unit_system]["Value"])
if self.kind in ["WindDay", "WindNight", "WindGustDay", "WindGustNight"]:
if self.entity_description.key in (
"WindDay",
"WindNight",
"WindGustDay",
"WindGustNight",
):
return cast(StateType, self._sensor_data["Speed"]["Value"])
return cast(StateType, self._sensor_data)
@property
def icon(self) -> str | None:
"""Return the icon."""
return self._description[ATTR_ICON]
@property
def device_class(self) -> str | None:
"""Return the device_class."""
return self._description[ATTR_DEVICE_CLASS]
@property
def unit_of_measurement(self) -> str | None:
"""Return the unit the value is expressed in."""
if self.coordinator.is_metric:
return self._description[ATTR_UNIT_METRIC]
return self._description[ATTR_UNIT_IMPERIAL]
@property
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes."""
if self.forecast_day is not None:
if self.kind in ["WindDay", "WindNight", "WindGustDay", "WindGustNight"]:
if self.entity_description.key in (
"WindDay",
"WindNight",
"WindGustDay",
"WindGustNight",
):
self._attrs["direction"] = self._sensor_data["Direction"]["English"]
elif self.kind in ["Grass", "Mold", "Ragweed", "Tree", "UVIndex", "Ozone"]:
elif self.entity_description.key in (
"Grass",
"Mold",
"Ozone",
"Ragweed",
"Tree",
"UVIndex",
):
self._attrs["level"] = self._sensor_data["Category"]
return self._attrs
if self.kind == "UVIndex":
if self.entity_description.key == "UVIndex":
self._attrs["level"] = self.coordinator.data["UVIndexText"]
elif self.kind == "Precipitation":
elif self.entity_description.key == "Precipitation":
self._attrs["type"] = self.coordinator.data["PrecipitationType"]
return self._attrs
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
return self._description[ATTR_ENABLED]
@callback
def _handle_coordinator_update(self) -> None:
"""Handle data update."""
self._sensor_data = _get_sensor_data(
self.coordinator.data, self.forecast_day, self.kind
self.coordinator.data, self.forecast_day, self.entity_description.key
)
self.async_write_ha_state()

View File

@@ -0,0 +1,30 @@
{
"config": {
"error": {
"requests_exceeded": "\u062a\u0645 \u062a\u062c\u0627\u0648\u0632 \u0627\u0644\u0639\u062f\u062f \u0627\u0644\u0645\u0633\u0645\u0648\u062d \u0628\u0647 \u0645\u0646 \u0627\u0644\u0637\u0644\u0628\u0627\u062a \u0625\u0644\u0649 Accuweather API. \u0639\u0644\u064a\u0643 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631 \u0623\u0648 \u062a\u063a\u064a\u064a\u0631 \u0645\u0641\u062a\u0627\u062d API."
},
"step": {
"user": {
"description": "\u0625\u0630\u0627 \u0643\u0646\u062a \u0628\u062d\u0627\u062c\u0629 \u0625\u0644\u0649 \u0645\u0633\u0627\u0639\u062f\u0629 \u0641\u064a \u0627\u0644\u062a\u0643\u0648\u064a\u0646 \u060c \u0641\u0642\u0645 \u0628\u0625\u0644\u0642\u0627\u0621 \u0646\u0638\u0631\u0629 \u0647\u0646\u0627: https://www.home-assistant.io/integrations/accuweather/ \n\n \u0644\u0627 \u064a\u062a\u0645 \u062a\u0645\u0643\u064a\u0646 \u0628\u0639\u0636 \u0623\u062c\u0647\u0632\u0629 \u0627\u0644\u0627\u0633\u062a\u0634\u0639\u0627\u0631 \u0628\u0634\u0643\u0644 \u0627\u0641\u062a\u0631\u0627\u0636\u064a. \u064a\u0645\u0643\u0646\u0643 \u062a\u0645\u0643\u064a\u0646\u0647\u0645 \u0641\u064a \u0633\u062c\u0644 \u0627\u0644\u0643\u064a\u0627\u0646 \u0628\u0639\u062f \u062a\u0643\u0648\u064a\u0646 \u0627\u0644\u062a\u0643\u0627\u0645\u0644.\n \u0644\u0627 \u064a\u062a\u0645 \u062a\u0645\u0643\u064a\u0646 \u062a\u0648\u0642\u0639\u0627\u062a \u0627\u0644\u0637\u0642\u0633 \u0627\u0641\u062a\u0631\u0627\u0636\u064a\u064b\u0627. \u064a\u0645\u0643\u0646\u0643 \u062a\u0645\u0643\u064a\u0646\u0647 \u0641\u064a \u062e\u064a\u0627\u0631\u0627\u062a \u0627\u0644\u062a\u0643\u0627\u0645\u0644.",
"title": "AccuWeather"
}
}
},
"options": {
"step": {
"user": {
"data": {
"forecast": "\u0627\u0644\u0646\u0634\u0631\u0629 \u0627\u0644\u062c\u0648\u064a\u0629"
},
"description": "\u0646\u0638\u0631\u064b\u0627 \u0644\u0642\u064a\u0648\u062f \u0627\u0644\u0625\u0635\u062f\u0627\u0631 \u0627\u0644\u0645\u062c\u0627\u0646\u064a \u0645\u0646 \u0645\u0641\u062a\u0627\u062d AccuWeather API \u060c \u0639\u0646\u062f \u062a\u0645\u0643\u064a\u0646 \u0627\u0644\u062a\u0646\u0628\u0624 \u0628\u0627\u0644\u0637\u0642\u0633 \u060c \u0633\u064a\u062a\u0645 \u0625\u062c\u0631\u0627\u0621 \u062a\u062d\u062f\u064a\u062b\u0627\u062a \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0643\u0644 80 \u062f\u0642\u064a\u0642\u0629 \u0628\u062f\u0644\u0627\u064b \u0645\u0646 \u0643\u0644 40 \u062f\u0642\u064a\u0642\u0629.",
"title": "\u062e\u064a\u0627\u0631\u0627\u062a AccuWeather"
}
}
},
"system_health": {
"info": {
"can_reach_server": "\u0627\u0644\u0648\u0635\u0648\u0644 \u0625\u0644\u0649 \u062e\u0627\u062f\u0645 AccuWeather",
"remaining_requests": "\u0627\u0644\u0637\u0644\u0628\u0627\u062a \u0627\u0644\u0645\u062a\u0628\u0642\u064a\u0629 \u0627\u0644\u0645\u0633\u0645\u0648\u062d \u0628\u0647\u0627"
}
}
}

View File

@@ -6,7 +6,7 @@
"error": {
"cannot_connect": "Verbindung fehlgeschlagen",
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel",
"requests_exceeded": "Die zul\u00e4ssige Anzahl von Anforderungen an die Accuweather-API wurde \u00fcberschritten. Sie m\u00fcssen warten oder den API-Schl\u00fcssel \u00e4ndern."
"requests_exceeded": "Die zul\u00e4ssige Anzahl von Anforderungen an die Accuweather-API wurde \u00fcberschritten. Du musst warten oder den API-Schl\u00fcssel \u00e4ndern."
},
"step": {
"user": {

View File

@@ -1,6 +1,11 @@
{
"config": {
"abort": {
"single_instance_allowed": "Ya configurado. Solo es posible una \u00fanica configuraci\u00f3n."
},
"error": {
"cannot_connect": "No se pudo conectar",
"invalid_api_key": "Clave de API no v\u00e1lida",
"requests_exceeded": "Se super\u00f3 el n\u00famero permitido de solicitudes a la API de Accuweather. Tiene que esperar o cambiar la clave de API."
},
"step": {

View File

@@ -14,8 +14,22 @@
"latitude": "\u05e7\u05d5 \u05e8\u05d5\u05d7\u05d1",
"longitude": "\u05e7\u05d5 \u05d0\u05d5\u05e8\u05da",
"name": "\u05e9\u05dd"
}
},
"title": "AccuWeather"
}
}
},
"options": {
"step": {
"user": {
"description": "\u05d1\u05e9\u05dc \u05de\u05d2\u05d1\u05dc\u05d5\u05ea \u05d4\u05d2\u05d9\u05e8\u05e1\u05d4 \u05d4\u05d7\u05d9\u05e0\u05de\u05d9\u05ea \u05e9\u05dc \u05de\u05e4\u05ea\u05d7 \u05d4-API \u05e9\u05dc AccuWeather, \u05db\u05d0\u05e9\u05e8 \u05ea\u05e4\u05e2\u05d9\u05dc \u05ea\u05d7\u05d6\u05d9\u05ea \u05de\u05d6\u05d2 \u05d0\u05d5\u05d5\u05d9\u05e8, \u05e2\u05d3\u05db\u05d5\u05e0\u05d9 \u05e0\u05ea\u05d5\u05e0\u05d9\u05dd \u05d9\u05d1\u05d5\u05e6\u05e2\u05d5 \u05db\u05dc 80 \u05d3\u05e7\u05d5\u05ea \u05d1\u05de\u05e7\u05d5\u05dd \u05db\u05dc 40 \u05d3\u05e7\u05d5\u05ea.",
"title": "\u05d0\u05e4\u05e9\u05e8\u05d5\u05d9\u05d5\u05ea AccuWeather"
}
}
},
"system_health": {
"info": {
"can_reach_server": "\u05d4\u05e9\u05d2\u05ea \u05e9\u05e8\u05ea AccuWeather"
}
}
}

View File

@@ -25,5 +25,11 @@
"title": "AccuWeather be\u00e1ll\u00edt\u00e1sok"
}
}
},
"system_health": {
"info": {
"can_reach_server": "\u00c9rje el az AccuWeather szervert",
"remaining_requests": "Fennmarad\u00f3 enged\u00e9lyezett k\u00e9r\u00e9sek"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"state": {
"accuweather__pressure_tendency": {
"falling": "\u0647\u0628\u0648\u0637",
"rising": "\u0627\u0631\u062a\u0641\u0627\u0639",
"steady": "\u062b\u0627\u0628\u062a"
}
}
}

View File

@@ -19,7 +19,6 @@ from homeassistant.components.weather import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME, TEMP_CELSIUS, TEMP_FAHRENHEIT
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util.dt import utc_from_timestamp
@@ -60,29 +59,15 @@ class AccuWeatherEntity(CoordinatorEntity, WeatherEntity):
) -> None:
"""Initialize."""
super().__init__(coordinator)
self._name = name
self._unit_system = API_METRIC if self.coordinator.is_metric else API_IMPERIAL
@property
def name(self) -> str:
"""Return the name."""
return self._name
@property
def attribution(self) -> str:
"""Return the attribution."""
return ATTRIBUTION
@property
def unique_id(self) -> str:
"""Return a unique_id for this entity."""
return self.coordinator.location_key
@property
def device_info(self) -> DeviceInfo:
"""Return the device info."""
return {
"identifiers": {(DOMAIN, self.coordinator.location_key)},
self._unit_system = API_METRIC if coordinator.is_metric else API_IMPERIAL
self._attr_name = name
self._attr_unique_id = coordinator.location_key
self._attr_temperature_unit = (
TEMP_CELSIUS if coordinator.is_metric else TEMP_FAHRENHEIT
)
self._attr_attribution = ATTRIBUTION
self._attr_device_info = {
"identifiers": {(DOMAIN, coordinator.location_key)},
"name": NAME,
"manufacturer": MANUFACTURER,
"entry_type": "service",
@@ -107,11 +92,6 @@ class AccuWeatherEntity(CoordinatorEntity, WeatherEntity):
float, self.coordinator.data["Temperature"][self._unit_system]["Value"]
)
@property
def temperature_unit(self) -> str:
"""Return the unit of measurement."""
return TEMP_CELSIUS if self.coordinator.is_metric else TEMP_FAHRENHEIT
@property
def pressure(self) -> float:
"""Return the pressure."""

View File

@@ -67,6 +67,8 @@ def setup_platform(
class AcerSwitch(SwitchEntity):
"""Represents an Acer Projector as a switch."""
_attr_icon = ICON
def __init__(
self,
serial_port: str,
@@ -79,9 +81,7 @@ class AcerSwitch(SwitchEntity):
port=serial_port, timeout=timeout, write_timeout=write_timeout
)
self._serial_port = serial_port
self._name = name
self._state = False
self._available = False
self._attr_name = name
self._attributes = {
LAMP_HOURS: STATE_UNKNOWN,
INPUT_SOURCE: STATE_UNKNOWN,
@@ -116,57 +116,33 @@ class AcerSwitch(SwitchEntity):
return match.group(1)
return STATE_UNKNOWN
@property
def available(self) -> bool:
"""Return if projector is available."""
return self._available
@property
def name(self) -> str:
"""Return name of the projector."""
return self._name
@property
def icon(self) -> str:
"""Return the icon."""
return ICON
@property
def is_on(self) -> bool:
"""Return if the projector is turned on."""
return self._state
@property
def extra_state_attributes(self) -> dict[str, str]:
"""Return state attributes."""
return self._attributes
def update(self) -> None:
"""Get the latest state from the projector."""
awns = self._write_read_format(CMD_DICT[LAMP])
if awns == "Lamp 1":
self._state = True
self._available = True
self._attr_is_on = True
self._attr_available = True
elif awns == "Lamp 0":
self._state = False
self._available = True
self._attr_is_on = False
self._attr_available = True
else:
self._available = False
self._attr_available = False
for key in self._attributes:
msg = CMD_DICT.get(key)
if msg:
awns = self._write_read_format(msg)
self._attributes[key] = awns
self._attr_extra_state_attributes = self._attributes
def turn_on(self, **kwargs: Any) -> None:
"""Turn the projector on."""
msg = CMD_DICT[STATE_ON]
self._write_read(msg)
self._state = True
self._attr_is_on = True
def turn_off(self, **kwargs: Any) -> None:
"""Turn the projector off."""
msg = CMD_DICT[STATE_OFF]
self._write_read(msg)
self._state = False
self._attr_is_on = False

View File

@@ -0,0 +1,18 @@
"""The Adax integration."""
from __future__ import annotations
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
PLATFORMS = ["climate"]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Adax from a config entry."""
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@@ -0,0 +1,152 @@
"""Support for Adax wifi-enabled home heaters."""
from __future__ import annotations
import logging
from typing import Any
from adax import Adax
from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import (
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
SUPPORT_TARGET_TEMPERATURE,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_TEMPERATURE,
CONF_PASSWORD,
PRECISION_WHOLE,
TEMP_CELSIUS,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import ACCOUNT_ID
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Adax thermostat with config flow."""
adax_data_handler = Adax(
entry.data[ACCOUNT_ID],
entry.data[CONF_PASSWORD],
websession=async_get_clientsession(hass),
)
async_add_entities(
AdaxDevice(room, adax_data_handler)
for room in await adax_data_handler.get_rooms()
)
class AdaxDevice(ClimateEntity):
"""Representation of a heater."""
def __init__(self, heater_data: dict[str, Any], adax_data_handler: Adax) -> None:
"""Initialize the heater."""
self._heater_data = heater_data
self._adax_data_handler = adax_data_handler
@property
def supported_features(self) -> int:
"""Return the list of supported features."""
return SUPPORT_TARGET_TEMPERATURE
@property
def unique_id(self) -> str:
"""Return a unique ID."""
return f"{self._heater_data['homeId']}_{self._heater_data['id']}"
@property
def name(self) -> str:
"""Return the name of the device, if any."""
return self._heater_data["name"]
@property
def hvac_mode(self) -> str:
"""Return hvac operation ie. heat, cool mode."""
if self._heater_data["heatingEnabled"]:
return HVAC_MODE_HEAT
return HVAC_MODE_OFF
@property
def icon(self) -> str:
"""Return nice icon for heater."""
if self.hvac_mode == HVAC_MODE_HEAT:
return "mdi:radiator"
return "mdi:radiator-off"
@property
def hvac_modes(self) -> list[str]:
"""Return the list of available hvac operation modes."""
return [HVAC_MODE_HEAT, HVAC_MODE_OFF]
async def async_set_hvac_mode(self, hvac_mode: str) -> None:
"""Set hvac mode."""
if hvac_mode == HVAC_MODE_HEAT:
temperature = max(
self.min_temp, self._heater_data.get("targetTemperature", self.min_temp)
)
await self._adax_data_handler.set_room_target_temperature(
self._heater_data["id"], temperature, True
)
elif hvac_mode == HVAC_MODE_OFF:
await self._adax_data_handler.set_room_target_temperature(
self._heater_data["id"], self.min_temp, False
)
else:
return
await self._adax_data_handler.update()
@property
def temperature_unit(self) -> str:
"""Return the unit of measurement which this device uses."""
return TEMP_CELSIUS
@property
def min_temp(self) -> int:
"""Return the minimum temperature."""
return 5
@property
def max_temp(self) -> int:
"""Return the maximum temperature."""
return 35
@property
def current_temperature(self) -> float | None:
"""Return the current temperature."""
return self._heater_data.get("temperature")
@property
def target_temperature(self) -> int | None:
"""Return the temperature we try to reach."""
return self._heater_data.get("targetTemperature")
@property
def target_temperature_step(self) -> int:
"""Return the supported step of target temperature."""
return PRECISION_WHOLE
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
temperature = kwargs.get(ATTR_TEMPERATURE)
if temperature is None:
return
await self._adax_data_handler.set_room_target_temperature(
self._heater_data["id"], temperature, True
)
async def async_update(self) -> None:
"""Get the latest data."""
for room in await self._adax_data_handler.get_rooms():
if room["id"] == self._heater_data["id"]:
self._heater_data = room
return

View File

@@ -0,0 +1,73 @@
"""Config flow for Adax integration."""
from __future__ import annotations
import logging
from typing import Any
import adax
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_PASSWORD
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResult
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import ACCOUNT_ID, DOMAIN
_LOGGER = logging.getLogger(__name__)
STEP_USER_DATA_SCHEMA = vol.Schema(
{vol.Required(ACCOUNT_ID): int, vol.Required(CONF_PASSWORD): str}
)
async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> None:
"""Validate the user input allows us to connect."""
account_id = data[ACCOUNT_ID]
password = data[CONF_PASSWORD].replace(" ", "")
token = await adax.get_adax_token(
async_get_clientsession(hass), account_id, password
)
if token is None:
_LOGGER.info("Adax: Failed to login to retrieve token")
raise CannotConnect
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Adax."""
VERSION = 1
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle the initial step."""
if user_input is None:
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA
)
errors = {}
await self.async_set_unique_id(user_input[ACCOUNT_ID])
self._abort_if_unique_id_configured()
try:
await validate_input(self.hass, user_input)
except CannotConnect:
errors["base"] = "cannot_connect"
else:
return self.async_create_entry(
title=user_input[ACCOUNT_ID], data=user_input
)
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
)
class CannotConnect(HomeAssistantError):
"""Error to indicate we cannot connect."""

View File

@@ -0,0 +1,5 @@
"""Constants for the Adax integration."""
from typing import Final
ACCOUNT_ID: Final = "account_id"
DOMAIN: Final = "adax"

View File

@@ -0,0 +1,13 @@
{
"domain": "adax",
"name": "Adax",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/adax",
"requirements": [
"adax==0.0.1"
],
"codeowners": [
"@danielhiversen"
],
"iot_class": "cloud_polling"
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"step": {
"user": {
"data": {
"account_id": "Account ID",
"password": "[%key:common::config_flow::data::password%]"
}
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "El dispositiu ja est\u00e0 configurat"
},
"error": {
"cannot_connect": "Ha fallat la connexi\u00f3",
"invalid_auth": "Autenticaci\u00f3 inv\u00e0lida"
},
"step": {
"user": {
"data": {
"account_id": "ID del compte",
"host": "Amfitri\u00f3",
"password": "Contrasenya"
}
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"abort": {
"already_configured": "Za\u0159\u00edzen\u00ed je ji\u017e nastaveno"
},
"error": {
"cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit",
"invalid_auth": "Neplatn\u00e9 ov\u011b\u0159en\u00ed"
},
"step": {
"user": {
"data": {
"host": "Hostitel",
"password": "Heslo"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "Ger\u00e4t ist bereits konfiguriert"
},
"error": {
"cannot_connect": "Verbindung fehlgeschlagen",
"invalid_auth": "Ung\u00fcltige Authentifizierung"
},
"step": {
"user": {
"data": {
"account_id": "Konto-ID",
"host": "Host",
"password": "Passwort"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "Device is already configured"
},
"error": {
"cannot_connect": "Failed to connect",
"invalid_auth": "Invalid authentication"
},
"step": {
"user": {
"data": {
"account_id": "Account ID",
"host": "Host",
"password": "Password"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "Seade on juba h\u00e4\u00e4lestatud"
},
"error": {
"cannot_connect": "\u00dchendamine nurjus",
"invalid_auth": "Tuvastamise viga"
},
"step": {
"user": {
"data": {
"account_id": "Konto ID",
"host": "Host",
"password": "Salas\u00f5na"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "L'appareil est d\u00e9j\u00e0 configur\u00e9"
},
"error": {
"cannot_connect": "\u00c9chec de connexion",
"invalid_auth": "Authentification invalide"
},
"step": {
"user": {
"data": {
"account_id": "identifiant de compte",
"host": "H\u00f4te",
"password": "Mot de passe"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "\u05ea\u05e6\u05d5\u05e8\u05ea \u05d4\u05d4\u05ea\u05e7\u05df \u05db\u05d1\u05e8 \u05e0\u05e7\u05d1\u05e2\u05d4"
},
"error": {
"cannot_connect": "\u05d4\u05d4\u05ea\u05d7\u05d1\u05e8\u05d5\u05ea \u05e0\u05db\u05e9\u05dc\u05d4",
"invalid_auth": "\u05d0\u05d9\u05de\u05d5\u05ea \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9"
},
"step": {
"user": {
"data": {
"account_id": "\u05de\u05d6\u05d4\u05d4 \u05d7\u05e9\u05d1\u05d5\u05df",
"host": "\u05de\u05d0\u05e8\u05d7",
"password": "\u05e1\u05d9\u05e1\u05de\u05d4"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "Il dispositivo \u00e8 gi\u00e0 configurato"
},
"error": {
"cannot_connect": "Impossibile connettersi",
"invalid_auth": "Autenticazione non valida"
},
"step": {
"user": {
"data": {
"account_id": "ID account",
"host": "Host",
"password": "Password"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "Apparaat is al geconfigureerd"
},
"error": {
"cannot_connect": "Kan geen verbinding maken",
"invalid_auth": "Ongeldige authenticatie"
},
"step": {
"user": {
"data": {
"account_id": "Account ID",
"host": "Host",
"password": "Wachtwoord"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "Urz\u0105dzenie jest ju\u017c skonfigurowane"
},
"error": {
"cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia",
"invalid_auth": "Niepoprawne uwierzytelnienie"
},
"step": {
"user": {
"data": {
"account_id": "Identyfikator konta",
"host": "Nazwa hosta lub adres IP",
"password": "Has\u0142o"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "\u042d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 Home Assistant."
},
"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": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438."
},
"step": {
"user": {
"data": {
"account_id": "ID \u0443\u0447\u0451\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438",
"host": "\u0425\u043e\u0441\u0442",
"password": "\u041f\u0430\u0440\u043e\u043b\u044c"
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"config": {
"abort": {
"already_configured": "\u88dd\u7f6e\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210"
},
"error": {
"cannot_connect": "\u9023\u7dda\u5931\u6557",
"invalid_auth": "\u9a57\u8b49\u78bc\u7121\u6548"
},
"step": {
"user": {
"data": {
"account_id": "\u5e33\u865f ID",
"host": "\u4e3b\u6a5f\u7aef",
"password": "\u5bc6\u78bc"
}
}
}
}
}

View File

@@ -17,7 +17,7 @@
"host": "Host",
"password": "Passwort",
"port": "Port",
"ssl": "AdGuard Home verwendet ein SSL-Zertifikat",
"ssl": "Verwendet ein SSL-Zertifikat",
"username": "Benutzername",
"verify_ssl": "SSL-Zertifikat \u00fcberpr\u00fcfen"
},

View File

@@ -1,9 +1,16 @@
{
"config": {
"abort": {
"already_configured": "A szolg\u00e1ltat\u00e1s m\u00e1r konfigur\u00e1lva van"
},
"error": {
"cannot_connect": "Sikertelen csatlakoz\u00e1s"
},
"step": {
"hassio_confirm": {
"description": "Be szeretn\u00e9 \u00e1ll\u00edtani a Home Assistant-ot, hogy csatlakozzon az AdGuard Home-hoz, amelyet a kieg\u00e9sz\u00edt\u0151 biztos\u00edt: {addon} ?",
"title": "Az AdGuard Home a Home Assistant kieg\u00e9sz\u00edt\u0151 seg\u00edts\u00e9g\u00e9vel"
},
"user": {
"data": {
"host": "Hoszt",

View File

@@ -1,6 +1,7 @@
{
"config": {
"abort": {
"already_configured": "Layanan sudah dikonfigurasi",
"existing_instance_updated": "Memperbarui konfigurasi yang ada."
},
"error": {

View File

@@ -268,15 +268,17 @@ class AdsHub:
class AdsEntity(Entity):
"""Representation of ADS entity."""
_attr_should_poll = False
def __init__(self, ads_hub, name, ads_var):
"""Initialize ADS binary sensor."""
self._name = name
self._unique_id = ads_var
self._state_dict = {}
self._state_dict[STATE_KEY_STATE] = None
self._ads_hub = ads_hub
self._ads_var = ads_var
self._event = None
self._attr_unique_id = ads_var
self._attr_name = name
async def async_initialize_device(
self, ads_var, plctype, state_key=STATE_KEY_STATE, factor=None
@@ -311,21 +313,6 @@ class AdsEntity(Entity):
_LOGGER.debug("Variable %s: Timeout during first update", ads_var)
@property
def name(self):
"""Return the default name of the binary sensor."""
return self._name
@property
def unique_id(self):
"""Return an unique identifier for this entity."""
return self._unique_id
@property
def should_poll(self):
"""Return False because entity pushes its state to HA."""
return False
@property
def available(self):
def available(self) -> bool:
"""Return False if state has not been updated yet."""
return self._state_dict[STATE_KEY_STATE] is not None

View File

@@ -40,18 +40,13 @@ class AdsBinarySensor(AdsEntity, BinarySensorEntity):
def __init__(self, ads_hub, name, ads_var, device_class):
"""Initialize ADS binary sensor."""
super().__init__(ads_hub, name, ads_var)
self._device_class = device_class or DEVICE_CLASS_MOVING
self._attr_device_class = device_class or DEVICE_CLASS_MOVING
async def async_added_to_hass(self):
"""Register device notification."""
await self.async_initialize_device(self._ads_var, self._ads_hub.PLCTYPE_BOOL)
@property
def is_on(self):
def is_on(self) -> bool:
"""Return True if the entity is on."""
return self._state_dict[STATE_KEY_STATE]
@property
def device_class(self):
"""Return the device class."""
return self._device_class

View File

@@ -91,13 +91,13 @@ class AdsCover(AdsEntity, CoverEntity):
):
"""Initialize AdsCover entity."""
super().__init__(ads_hub, name, ads_var_is_closed)
if self._ads_var is None:
if self._attr_unique_id is None:
if ads_var_position is not None:
self._unique_id = ads_var_position
self._attr_unique_id = ads_var_position
elif ads_var_pos_set is not None:
self._unique_id = ads_var_pos_set
self._attr_unique_id = ads_var_pos_set
elif ads_var_open is not None:
self._unique_id = ads_var_open
self._attr_unique_id = ads_var_open
self._state_dict[STATE_KEY_POSITION] = None
self._ads_var_position = ads_var_position
@@ -105,7 +105,12 @@ class AdsCover(AdsEntity, CoverEntity):
self._ads_var_open = ads_var_open
self._ads_var_close = ads_var_close
self._ads_var_stop = ads_var_stop
self._device_class = device_class
self._attr_device_class = device_class
self._attr_supported_features = SUPPORT_OPEN | SUPPORT_CLOSE
if ads_var_stop is not None:
self._attr_supported_features |= SUPPORT_STOP
if ads_var_pos_set is not None:
self._attr_supported_features |= SUPPORT_SET_POSITION
async def async_added_to_hass(self):
"""Register device notification."""
@@ -119,11 +124,6 @@ class AdsCover(AdsEntity, CoverEntity):
self._ads_var_position, self._ads_hub.PLCTYPE_BYTE, STATE_KEY_POSITION
)
@property
def device_class(self):
"""Return the class of this cover."""
return self._device_class
@property
def is_closed(self):
"""Return if the cover is closed."""
@@ -138,19 +138,6 @@ class AdsCover(AdsEntity, CoverEntity):
"""Return current position of cover."""
return self._state_dict[STATE_KEY_POSITION]
@property
def supported_features(self):
"""Flag supported features."""
supported_features = SUPPORT_OPEN | SUPPORT_CLOSE
if self._ads_var_stop is not None:
supported_features |= SUPPORT_STOP
if self._ads_var_pos_set is not None:
supported_features |= SUPPORT_SET_POSITION
return supported_features
def stop_cover(self, **kwargs):
"""Fire the stop action."""
if self._ads_var_stop:
@@ -185,7 +172,7 @@ class AdsCover(AdsEntity, CoverEntity):
self.set_cover_position(position=0)
@property
def available(self):
def available(self) -> bool:
"""Return False if state has not been updated yet."""
if self._ads_var is not None or self._ads_var_position is not None:
return (

View File

@@ -1,4 +1,6 @@
"""Support for ADS light sources."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.components.light import (
@@ -48,6 +50,8 @@ class AdsLight(AdsEntity, LightEntity):
super().__init__(ads_hub, name, ads_var_enable)
self._state_dict[STATE_KEY_BRIGHTNESS] = None
self._ads_var_brightness = ads_var_brightness
if ads_var_brightness is not None:
self._attr_supported_features = SUPPORT_BRIGHTNESS
async def async_added_to_hass(self):
"""Register device notification."""
@@ -61,19 +65,12 @@ class AdsLight(AdsEntity, LightEntity):
)
@property
def brightness(self):
def brightness(self) -> int | None:
"""Return the brightness of the light (0..255)."""
return self._state_dict[STATE_KEY_BRIGHTNESS]
@property
def supported_features(self):
"""Flag supported features."""
if self._ads_var_brightness is not None:
return SUPPORT_BRIGHTNESS
return 0
@property
def is_on(self):
def is_on(self) -> bool:
"""Return True if the entity is on."""
return self._state_dict[STATE_KEY_STATE]

View File

@@ -5,6 +5,7 @@ from homeassistant.components import ads
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.const import CONF_NAME, CONF_UNIT_OF_MEASUREMENT
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import StateType
from . import CONF_ADS_FACTOR, CONF_ADS_TYPE, CONF_ADS_VAR, STATE_KEY_STATE, AdsEntity
@@ -49,7 +50,7 @@ class AdsSensor(AdsEntity, SensorEntity):
def __init__(self, ads_hub, ads_var, ads_type, name, unit_of_measurement, factor):
"""Initialize AdsSensor entity."""
super().__init__(ads_hub, name, ads_var)
self._unit_of_measurement = unit_of_measurement
self._attr_unit_of_measurement = unit_of_measurement
self._ads_type = ads_type
self._factor = factor
@@ -63,11 +64,6 @@ class AdsSensor(AdsEntity, SensorEntity):
)
@property
def state(self):
def state(self) -> StateType:
"""Return the state of the device."""
return self._state_dict[STATE_KEY_STATE]
@property
def unit_of_measurement(self):
"""Return the unit of measurement."""
return self._unit_of_measurement

View File

@@ -35,7 +35,7 @@ class AdsSwitch(AdsEntity, SwitchEntity):
await self.async_initialize_device(self._ads_var, self._ads_hub.PLCTYPE_BOOL)
@property
def is_on(self):
def is_on(self) -> bool:
"""Return True if the entity is on."""
return self._state_dict[STATE_KEY_STATE]

View File

@@ -35,15 +35,13 @@ class AdvantageAirZoneFilter(AdvantageAirEntity, BinarySensorEntity):
_attr_device_class = DEVICE_CLASS_PROBLEM
@property
def name(self):
"""Return the name."""
return f'{self._ac["name"]} Filter'
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-filter'
def __init__(self, instance, ac_key):
"""Initialize an Advantage Air Filter."""
super().__init__(instance, ac_key)
self._attr_name = f'{self._ac["name"]} Filter'
self._attr_unique_id = (
f'{self.coordinator.data["system"]["rid"]}-{ac_key}-filter'
)
@property
def is_on(self):
@@ -56,15 +54,13 @@ class AdvantageAirZoneMotion(AdvantageAirEntity, BinarySensorEntity):
_attr_device_class = DEVICE_CLASS_MOTION
@property
def name(self):
"""Return the name."""
return f'{self._zone["name"]} Motion'
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}-motion'
def __init__(self, instance, ac_key, zone_key):
"""Initialize an Advantage Air Zone Motion."""
super().__init__(instance, ac_key, zone_key)
self._attr_name = f'{self._zone["name"]} Motion'
self._attr_unique_id = (
f'{self.coordinator.data["system"]["rid"]}-{ac_key}-{zone_key}-motion'
)
@property
def is_on(self):
@@ -77,15 +73,13 @@ class AdvantageAirZoneMyZone(AdvantageAirEntity, BinarySensorEntity):
_attr_entity_registry_enabled_default = False
@property
def name(self):
"""Return the name."""
return f'{self._zone["name"]} MyZone'
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}-myzone'
def __init__(self, instance, ac_key, zone_key):
"""Initialize an Advantage Air Zone MyZone."""
super().__init__(instance, ac_key, zone_key)
self._attr_name = f'{self._zone["name"]} MyZone'
self._attr_unique_id = (
f'{self.coordinator.data["system"]["rid"]}-{ac_key}-{zone_key}-myzone'
)
@property
def is_on(self):

View File

@@ -1,5 +1,4 @@
"""Climate platform for Advantage Air integration."""
from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import (
FAN_AUTO,
@@ -16,6 +15,7 @@ from homeassistant.components.climate.const import (
SUPPORT_TARGET_TEMPERATURE,
)
from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, TEMP_CELSIUS
from homeassistant.core import callback
from homeassistant.helpers import entity_platform
from .const import (
@@ -84,39 +84,26 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class AdvantageAirClimateEntity(AdvantageAirEntity, ClimateEntity):
"""AdvantageAir Climate class."""
@property
def temperature_unit(self):
"""Return the temperature unit."""
return TEMP_CELSIUS
@property
def target_temperature_step(self):
"""Return the supported temperature step."""
return PRECISION_WHOLE
@property
def max_temp(self):
"""Return the maximum supported temperature."""
return 32
@property
def min_temp(self):
"""Return the minimum supported temperature."""
return 16
_attr_temperature_unit = TEMP_CELSIUS
_attr_target_temperature_step = PRECISION_WHOLE
_attr_max_temp = 32
_attr_min_temp = 16
class AdvantageAirAC(AdvantageAirClimateEntity):
"""AdvantageAir AC unit."""
@property
def name(self):
"""Return the name."""
return self._ac["name"]
_attr_fan_modes = [FAN_AUTO, FAN_LOW, FAN_MEDIUM, FAN_HIGH]
_attr_hvac_modes = AC_HVAC_MODES
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}'
def __init__(self, instance, ac_key):
"""Initialize an AdvantageAir AC unit."""
super().__init__(instance, ac_key)
self._attr_name = self._ac["name"]
self._attr_unique_id = f'{self.coordinator.data["system"]["rid"]}-{ac_key}'
if self._ac.get("myAutoModeEnabled"):
self._attr_hvac_modes = AC_HVAC_MODES + [HVAC_MODE_AUTO]
@property
def target_temperature(self):
@@ -130,28 +117,11 @@ class AdvantageAirAC(AdvantageAirClimateEntity):
return ADVANTAGE_AIR_HVAC_MODES.get(self._ac["mode"])
return HVAC_MODE_OFF
@property
def hvac_modes(self):
"""Return the supported HVAC modes."""
if self._ac.get("myAutoModeEnabled"):
return AC_HVAC_MODES + [HVAC_MODE_AUTO]
return AC_HVAC_MODES
@property
def fan_mode(self):
"""Return the current fan modes."""
return ADVANTAGE_AIR_FAN_MODES.get(self._ac["fan"])
@property
def fan_modes(self):
"""Return the supported fan modes."""
return [FAN_AUTO, FAN_LOW, FAN_MEDIUM, FAN_HIGH]
@property
def supported_features(self):
"""Return the supported features."""
return SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE
async def async_set_hvac_mode(self, hvac_mode):
"""Set the HVAC Mode and State."""
if hvac_mode == HVAC_MODE_OFF:
@@ -185,42 +155,30 @@ class AdvantageAirAC(AdvantageAirClimateEntity):
class AdvantageAirZone(AdvantageAirClimateEntity):
"""AdvantageAir Zone control."""
@property
def name(self):
"""Return the name."""
return self._zone["name"]
_attr_hvac_modes = ZONE_HVAC_MODES
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}'
def __init__(self, instance, ac_key, zone_key):
"""Initialize an AdvantageAir Zone control."""
super().__init__(instance, ac_key, zone_key)
self._attr_name = self._zone["name"]
self._attr_unique_id = (
f'{self.coordinator.data["system"]["rid"]}-{ac_key}-{zone_key}'
)
@property
def current_temperature(self):
"""Return the current temperature."""
return self._zone["measuredTemp"]
async def async_added_to_hass(self):
"""When entity is added to hass."""
self.async_on_remove(self.coordinator.async_add_listener(self._update_callback))
@property
def target_temperature(self):
"""Return the target temperature."""
return self._zone["setTemp"]
@property
def hvac_mode(self):
"""Return the current HVAC modes."""
@callback
def _update_callback(self) -> None:
"""Load data from integration."""
self._attr_current_temperature = self._zone["measuredTemp"]
self._attr_target_temperature = self._zone["setTemp"]
self._attr_hvac_mode = HVAC_MODE_OFF
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
return HVAC_MODE_FAN_ONLY
return HVAC_MODE_OFF
@property
def hvac_modes(self):
"""Return supported HVAC modes."""
return ZONE_HVAC_MODES
@property
def supported_features(self):
"""Return the supported features."""
return SUPPORT_TARGET_TEMPERATURE
self._attr_hvac_mode = HVAC_MODE_FAN_ONLY
self.async_write_ha_state()
async def async_set_hvac_mode(self, hvac_mode):
"""Set the HVAC Mode and State."""

View File

@@ -36,25 +36,16 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class AdvantageAirZoneVent(AdvantageAirEntity, CoverEntity):
"""Advantage Air Cover Class."""
@property
def name(self):
"""Return the name."""
return f'{self._zone["name"]}'
_attr_device_class = DEVICE_CLASS_DAMPER
_attr_supported_features = SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_SET_POSITION
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}'
@property
def device_class(self):
"""Return the device class of the vent."""
return DEVICE_CLASS_DAMPER
@property
def supported_features(self):
"""Return the supported features."""
return SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_SET_POSITION
def __init__(self, instance, ac_key, zone_key):
"""Initialize an Advantage Air Cover Class."""
super().__init__(instance, ac_key, zone_key)
self._attr_name = f'{self._zone["name"]}'
self._attr_unique_id = (
f'{self.coordinator.data["system"]["rid"]}-{ac_key}-{zone_key}'
)
@property
def is_closed(self):

View File

@@ -14,6 +14,13 @@ class AdvantageAirEntity(CoordinatorEntity):
self.async_change = instance["async_change"]
self.ac_key = ac_key
self.zone_key = zone_key
self._attr_device_info = {
"identifiers": {(DOMAIN, self.coordinator.data["system"]["rid"])},
"name": self.coordinator.data["system"]["name"],
"manufacturer": "Advantage Air",
"model": self.coordinator.data["system"]["sysType"],
"sw_version": self.coordinator.data["system"]["myAppRev"],
}
@property
def _ac(self):
@@ -22,14 +29,3 @@ class AdvantageAirEntity(CoordinatorEntity):
@property
def _zone(self):
return self.coordinator.data["aircons"][self.ac_key]["zones"][self.zone_key]
@property
def device_info(self):
"""Return parent device information."""
return {
"identifiers": {(DOMAIN, self.coordinator.data["system"]["rid"])},
"name": self.coordinator.data["system"]["name"],
"manufacturer": "Advantage Air",
"model": self.coordinator.data["system"]["sysType"],
"sw_version": self.coordinator.data["system"]["myAppRev"],
}

View File

@@ -3,8 +3,12 @@
"name": "Advantage Air",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/advantage_air",
"codeowners": ["@Bre77"],
"requirements": ["advantage_air==0.2.1"],
"codeowners": [
"@Bre77"
],
"requirements": [
"advantage_air==0.2.5"
],
"quality_scale": "platinum",
"iot_class": "local_polling"
}
}

View File

@@ -1,8 +1,8 @@
"""Sensor platform for Advantage Air integration."""
import voluptuous as vol
from homeassistant.components.sensor import SensorEntity
from homeassistant.const import PERCENTAGE
from homeassistant.components.sensor import STATE_CLASS_MEASUREMENT, SensorEntity
from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
from homeassistant.helpers import config_validation as cv, entity_platform
from .const import ADVANTAGE_AIR_STATE_OPEN, DOMAIN as ADVANTAGE_AIR_DOMAIN
@@ -25,9 +25,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(AdvantageAirTimeTo(instance, ac_key, "On"))
entities.append(AdvantageAirTimeTo(instance, ac_key, "Off"))
for zone_key, zone in ac_device["zones"].items():
# Only show damper sensors when zone is in temperature control
# Only show damper and temp sensors when zone is in temperature control
if zone["type"] != 0:
entities.append(AdvantageAirZoneVent(instance, ac_key, zone_key))
entities.append(AdvantageAirZoneTemp(instance, ac_key, zone_key))
# Only show wireless signal strength sensors when using wireless sensors
if zone["rssi"] > 0:
entities.append(AdvantageAirZoneSignal(instance, ac_key, zone_key))
@@ -50,17 +51,11 @@ class AdvantageAirTimeTo(AdvantageAirEntity, SensorEntity):
"""Initialize the Advantage Air timer control."""
super().__init__(instance, ac_key)
self.action = action
self._time_key = f"countDownTo{self.action}"
@property
def name(self):
"""Return the name."""
return f'{self._ac["name"]} Time To {self.action}'
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-timeto{self.action}'
self._time_key = f"countDownTo{action}"
self._attr_name = f'{self._ac["name"]} Time To {action}'
self._attr_unique_id = (
f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-timeto{action}'
)
@property
def state(self):
@@ -84,16 +79,15 @@ class AdvantageAirZoneVent(AdvantageAirEntity, SensorEntity):
"""Representation of Advantage Air Zone Vent Sensor."""
_attr_unit_of_measurement = PERCENTAGE
_attr_state_class = STATE_CLASS_MEASUREMENT
@property
def name(self):
"""Return the name."""
return f'{self._zone["name"]} Vent'
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}-vent'
def __init__(self, instance, ac_key, zone_key):
"""Initialize an Advantage Air Zone Vent Sensor."""
super().__init__(instance, ac_key, zone_key=zone_key)
self._attr_name = f'{self._zone["name"]} Vent'
self._attr_unique_id = (
f'{self.coordinator.data["system"]["rid"]}-{ac_key}-{zone_key}-vent'
)
@property
def state(self):
@@ -114,16 +108,15 @@ class AdvantageAirZoneSignal(AdvantageAirEntity, SensorEntity):
"""Representation of Advantage Air Zone wireless signal sensor."""
_attr_unit_of_measurement = PERCENTAGE
_attr_state_class = STATE_CLASS_MEASUREMENT
@property
def name(self):
"""Return the name."""
return f'{self._zone["name"]} Signal'
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}-signal'
def __init__(self, instance, ac_key, zone_key):
"""Initialize an Advantage Air Zone wireless signal sensor."""
super().__init__(instance, ac_key, zone_key=zone_key)
self._attr_name = f'{self._zone["name"]} Signal'
self._attr_unique_id = (
f'{self.coordinator.data["system"]["rid"]}-{ac_key}-{zone_key}-signal'
)
@property
def state(self):
@@ -142,3 +135,23 @@ class AdvantageAirZoneSignal(AdvantageAirEntity, SensorEntity):
if self._zone["rssi"] >= 20:
return "mdi:wifi-strength-1"
return "mdi:wifi-strength-outline"
class AdvantageAirZoneTemp(AdvantageAirEntity, SensorEntity):
"""Representation of Advantage Air Zone wireless signal sensor."""
_attr_unit_of_measurement = TEMP_CELSIUS
_attr_state_class = STATE_CLASS_MEASUREMENT
_attr_icon = "mdi:thermometer"
_attr_entity_registry_enabled_default = False
def __init__(self, instance, ac_key, zone_key):
"""Initialize an Advantage Air Zone Temp Sensor."""
super().__init__(instance, ac_key, zone_key)
self._attr_name = f'{self._zone["name"]} Temperature'
self._attr_unique_id = f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}-temp'
@property
def state(self):
"""Return the current value of the measured temperature."""
return self._zone["measuredTemp"]

View File

@@ -25,26 +25,21 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class AdvantageAirFreshAir(AdvantageAirEntity, ToggleEntity):
"""Representation of Advantage Air fresh air control."""
@property
def name(self):
"""Return the name."""
return f'{self._ac["name"]} Fresh Air'
_attr_icon = "mdi:air-filter"
@property
def unique_id(self):
"""Return a unique id."""
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-freshair'
def __init__(self, instance, ac_key):
"""Initialize an Advantage Air fresh air control."""
super().__init__(instance, ac_key)
self._attr_name = f'{self._ac["name"]} Fresh Air'
self._attr_unique_id = (
f'{self.coordinator.data["system"]["rid"]}-{ac_key}-freshair'
)
@property
def is_on(self):
"""Return the fresh air status."""
return self._ac["freshAirStatus"] == ADVANTAGE_AIR_STATE_ON
@property
def icon(self):
"""Return a representative icon of the fresh air switch."""
return "mdi:air-filter"
async def async_turn_on(self, **kwargs):
"""Turn fresh air on."""
await self.async_change(

View File

@@ -9,10 +9,10 @@
"step": {
"user": {
"data": {
"ip_address": "IP Adresse",
"ip_address": "IP-Adresse",
"port": "Port"
},
"description": "Anschluss an die API Ihres Advantage Air Wandtabletts.",
"description": "Anschluss an die API deines Advantage Air Wandtabletts.",
"title": "Verbinden"
}
}

View File

@@ -66,6 +66,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class AbstractAemetSensor(CoordinatorEntity, SensorEntity):
"""Abstract class for an AEMET OpenData sensor."""
_attr_extra_state_attributes = {ATTR_ATTRIBUTION: ATTRIBUTION}
def __init__(
self,
name,
@@ -80,33 +82,10 @@ class AbstractAemetSensor(CoordinatorEntity, SensorEntity):
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 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 extra_state_attributes(self):
"""Return the state attributes."""
return {ATTR_ATTRIBUTION: ATTRIBUTION}
self._attr_name = f"{self._name} {self._sensor_name}"
self._attr_unique_id = self._unique_id
self._attr_device_class = sensor_configuration.get(SENSOR_DEVICE_CLASS)
self._attr_unit_of_measurement = sensor_configuration.get(SENSOR_UNIT)
class AemetSensor(AbstractAemetSensor):
@@ -150,11 +129,9 @@ class AemetForecastSensor(AbstractAemetSensor):
)
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
self._attr_entity_registry_enabled_default = (
self._forecast_mode == FORECAST_MODE_DAILY
)
@property
def state(self):

View File

@@ -0,0 +1,11 @@
{
"options": {
"step": {
"init": {
"data": {
"station_updates": "\u062c\u0645\u0639 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0645\u0646 \u0645\u062d\u0637\u0627\u062a \u0627\u0644\u0637\u0642\u0633 AEMET"
}
}
}
}
}

View File

@@ -15,7 +15,7 @@
"name": "Name der Integration"
},
"description": "Richte die AEMET OpenData Integration ein. Um den API-Schl\u00fcssel zu generieren, besuche https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "[void]"
"title": "AEMET OpenData"
}
}
},

View File

@@ -18,5 +18,14 @@
"title": "AEMET OpenData"
}
}
},
"options": {
"step": {
"init": {
"data": {
"station_updates": "Recueillir les donn\u00e9es des stations m\u00e9t\u00e9orologiques AEMET"
}
}
}
}
}

View File

@@ -14,8 +14,18 @@
"longitude": "Hossz\u00fas\u00e1g",
"name": "Az integr\u00e1ci\u00f3 neve"
},
"description": "\u00c1ll\u00edtsa be az AEMET OpenData integr\u00e1ci\u00f3t. Az API-kulcs el\u0151\u00e1ll\u00edt\u00e1s\u00e1hoz keresse fel a https://opendata.aemet.es/centrodedescargas/altaUsuario webhelyet.",
"title": "AEMET OpenData"
}
}
},
"options": {
"step": {
"init": {
"data": {
"station_updates": "Gy\u0171jts\u00f6n adatokat az AEMET meteorol\u00f3giai \u00e1llom\u00e1sokr\u00f3l"
}
}
}
}
}

View File

@@ -18,5 +18,14 @@
"title": "AEMET OpenData"
}
}
},
"options": {
"step": {
"init": {
"data": {
"station_updates": "Kumpulkan data dari stasiun cuaca AEMET"
}
}
}
}
}

View File

@@ -39,6 +39,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class AemetWeather(CoordinatorEntity, WeatherEntity):
"""Implementation of an AEMET OpenData sensor."""
_attr_attribution = ATTRIBUTION
_attr_temperature_unit = TEMP_CELSIUS
def __init__(
self,
name,
@@ -48,25 +51,18 @@ class AemetWeather(CoordinatorEntity, WeatherEntity):
):
"""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
self._attr_entity_registry_enabled_default = (
self._forecast_mode == FORECAST_MODE_DAILY
)
self._attr_name = name
self._attr_unique_id = unique_id
@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."""
@@ -77,11 +73,6 @@ class AemetWeather(CoordinatorEntity, WeatherEntity):
"""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."""
@@ -92,16 +83,6 @@ class AemetWeather(CoordinatorEntity, WeatherEntity):
"""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."""

View File

@@ -109,38 +109,26 @@ async def async_setup_platform(
class AfterShipSensor(SensorEntity):
"""Representation of a AfterShip sensor."""
_attr_unit_of_measurement: str = "packages"
_attr_icon: str = ICON
def __init__(self, aftership: Tracking, name: str) -> None:
"""Initialize the sensor."""
self._attributes: dict[str, Any] = {}
self._name: str = name
self._state: int | None = None
self.aftership = aftership
@property
def name(self) -> str:
"""Return the name of the sensor."""
return self._name
self._attr_name = name
@property
def state(self) -> int | None:
"""Return the state of the sensor."""
return self._state
@property
def unit_of_measurement(self) -> str:
"""Return the unit of measurement of this entity, if any."""
return "packages"
@property
def extra_state_attributes(self) -> dict[str, str]:
"""Return attributes for the sensor."""
return self._attributes
@property
def icon(self) -> str:
"""Icon to use in the frontend."""
return ICON
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
self.async_on_remove(

View File

@@ -35,90 +35,60 @@ async def async_setup_entry(
class AgentBaseStation(AlarmControlPanelEntity):
"""Representation of an Agent DVR Alarm Control Panel."""
_attr_icon = ICON
_attr_supported_features = (
SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT
)
def __init__(self, client):
"""Initialize the alarm control panel."""
self._state = None
self._client = client
self._unique_id = f"{client.unique}_CP"
name = CONST_ALARM_CONTROL_PANEL_NAME
self._name = name = f"{client.name} {name}"
@property
def icon(self):
"""Return icon."""
return ICON
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def supported_features(self) -> int:
"""Return the list of supported features."""
return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT
@property
def device_info(self):
"""Return the device info for adding the entity to the agent object."""
return {
"identifiers": {(AGENT_DOMAIN, self._client.unique)},
self._attr_name = f"{client.name} {CONST_ALARM_CONTROL_PANEL_NAME}"
self._attr_unique_id = f"{client.unique}_CP"
self._attr_device_info = {
"identifiers": {(AGENT_DOMAIN, client.unique)},
"manufacturer": "Agent",
"model": CONST_ALARM_CONTROL_PANEL_NAME,
"sw_version": self._client.version,
"sw_version": client.version,
}
async def async_update(self):
"""Update the state of the device."""
await self._client.update()
self._attr_available = self._client.is_available
armed = self._client.is_armed
if armed is None:
self._state = None
self._attr_state = None
return
if armed:
prof = (await self._client.get_active_profile()).lower()
self._state = STATE_ALARM_ARMED_AWAY
self._attr_state = STATE_ALARM_ARMED_AWAY
if prof == CONF_HOME_MODE_NAME:
self._state = STATE_ALARM_ARMED_HOME
self._attr_state = STATE_ALARM_ARMED_HOME
elif prof == CONF_NIGHT_MODE_NAME:
self._state = STATE_ALARM_ARMED_NIGHT
self._attr_state = STATE_ALARM_ARMED_NIGHT
else:
self._state = STATE_ALARM_DISARMED
self._attr_state = STATE_ALARM_DISARMED
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
await self._client.disarm()
self._state = STATE_ALARM_DISARMED
self._attr_state = STATE_ALARM_DISARMED
async def async_alarm_arm_away(self, code=None):
"""Send arm away command. Uses custom mode."""
await self._client.arm()
await self._client.set_active_profile(CONF_AWAY_MODE_NAME)
self._state = STATE_ALARM_ARMED_AWAY
self._attr_state = STATE_ALARM_ARMED_AWAY
async def async_alarm_arm_home(self, code=None):
"""Send arm home command. Uses custom mode."""
await self._client.arm()
await self._client.set_active_profile(CONF_HOME_MODE_NAME)
self._state = STATE_ALARM_ARMED_HOME
self._attr_state = STATE_ALARM_ARMED_HOME
async def async_alarm_arm_night(self, code=None):
"""Send arm night command. Uses custom mode."""
await self._client.arm()
await self._client.set_active_profile(CONF_NIGHT_MODE_NAME)
self._state = STATE_ALARM_ARMED_NIGHT
@property
def name(self):
"""Return the name of the base station."""
return self._name
@property
def available(self) -> bool:
"""Device available."""
return self._client.is_available
@property
def unique_id(self) -> str:
"""Return a unique ID."""
return self._unique_id
self._attr_state = STATE_ALARM_ARMED_NIGHT

View File

@@ -67,31 +67,27 @@ async def async_setup_entry(
class AgentCamera(MjpegCamera):
"""Representation of an Agent Device Stream."""
_attr_supported_features = SUPPORT_ON_OFF
def __init__(self, device):
"""Initialize as a subclass of MjpegCamera."""
self._servername = device.client.name
self.server_url = device.client._server_url
device_info = {
CONF_NAME: device.name,
CONF_MJPEG_URL: f"{self.server_url}{device.mjpeg_image_url}&size={device.mjpegStreamWidth}x{device.mjpegStreamHeight}",
CONF_STILL_IMAGE_URL: f"{self.server_url}{device.still_image_url}&size={device.mjpegStreamWidth}x{device.mjpegStreamHeight}",
CONF_MJPEG_URL: f"{device.client._server_url}{device.mjpeg_image_url}&size={device.mjpegStreamWidth}x{device.mjpegStreamHeight}",
CONF_STILL_IMAGE_URL: f"{device.client._server_url}{device.still_image_url}&size={device.mjpegStreamWidth}x{device.mjpegStreamHeight}",
}
self.device = device
self._removed = False
self._name = f"{self._servername} {device.name}"
self._unique_id = f"{device._client.unique}_{device.typeID}_{device.id}"
self._attr_name = f"{device.client.name} {device.name}"
self._attr_unique_id = f"{device._client.unique}_{device.typeID}_{device.id}"
self._attr_should_poll = True
super().__init__(device_info)
@property
def device_info(self):
"""Return the device info for adding the entity to the agent object."""
return {
"identifiers": {(AGENT_DOMAIN, self._unique_id)},
"name": self._name,
self._attr_device_info = {
"identifiers": {(AGENT_DOMAIN, self.unique_id)},
"name": self.name,
"manufacturer": "Agent",
"model": "Camera",
"sw_version": self.device.client.version,
"sw_version": device.client.version,
}
async def async_update(self):
@@ -99,18 +95,18 @@ class AgentCamera(MjpegCamera):
try:
await self.device.update()
if self._removed:
_LOGGER.debug("%s reacquired", self._name)
_LOGGER.debug("%s reacquired", self.name)
self._removed = False
except AgentError:
# server still available - camera error
if self.device.client.is_available and not self._removed:
_LOGGER.error("%s lost", self._name)
_LOGGER.error("%s lost", self.name)
self._removed = True
@property
def extra_state_attributes(self):
"""Return the Agent DVR camera state attributes."""
return {
self._attr_available = self.device.client.is_available
self._attr_icon = "mdi:camcorder-off"
if self.is_on:
self._attr_icon = "mdi:camcorder"
self._attr_extra_state_attributes = {
ATTR_ATTRIBUTION: ATTRIBUTION,
"editable": False,
"enabled": self.is_on,
@@ -121,11 +117,6 @@ class AgentCamera(MjpegCamera):
"alerts_enabled": self.device.alerts_active,
}
@property
def should_poll(self) -> bool:
"""Update the state periodically."""
return True
@property
def is_recording(self) -> bool:
"""Return whether the monitor is recording."""
@@ -141,43 +132,21 @@ class AgentCamera(MjpegCamera):
"""Return whether the monitor has alerted."""
return self.device.detected
@property
def available(self) -> bool:
"""Return True if entity is available."""
return self.device.client.is_available
@property
def connected(self) -> bool:
"""Return True if entity is connected."""
return self.device.connected
@property
def supported_features(self) -> int:
"""Return supported features."""
return SUPPORT_ON_OFF
@property
def is_on(self) -> bool:
"""Return true if on."""
return self.device.online
@property
def icon(self):
"""Return the icon to use in the frontend, if any."""
if self.is_on:
return "mdi:camcorder"
return "mdi:camcorder-off"
@property
def motion_detection_enabled(self):
"""Return the camera motion detection status."""
return self.device.detector_active
@property
def unique_id(self) -> str:
"""Return a unique identifier for this agent object."""
return self._unique_id
async def async_enable_alerts(self):
"""Enable alerts."""
await self.device.alerts_on()

View File

@@ -13,7 +13,7 @@
"host": "Host",
"port": "Port"
},
"title": "Richten Sie den Agent DVR ein"
"title": "Richte den Agent DVR ein"
}
}
}

View File

@@ -1,7 +1,7 @@
{
"config": {
"abort": {
"already_configured": "\u05d4\u05de\u05db\u05e9\u05d9\u05e8 \u05db\u05d1\u05e8 \u05de\u05d5\u05d2\u05d3\u05e8"
"already_configured": "\u05ea\u05e6\u05d5\u05e8\u05ea \u05d4\u05d4\u05ea\u05e7\u05df \u05db\u05d1\u05e8 \u05e0\u05e7\u05d1\u05e2\u05d4"
},
"error": {
"already_in_progress": "\u05d6\u05e8\u05d9\u05de\u05ea \u05d4\u05ea\u05e6\u05d5\u05e8\u05d4 \u05db\u05d1\u05e8 \u05de\u05ea\u05d1\u05e6\u05e2\u05ea",

View File

@@ -3,10 +3,8 @@ from __future__ import annotations
from typing import Final
from homeassistant.components.sensor import ATTR_STATE_CLASS, STATE_CLASS_MEASUREMENT
from homeassistant.components.sensor import STATE_CLASS_MEASUREMENT
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_ICON,
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_PRESSURE,
@@ -16,7 +14,7 @@ from homeassistant.const import (
TEMP_CELSIUS,
)
from .model import SensorDescription
from .model import AirlySensorEntityDescription
ATTR_API_ADVICE: Final = "ADVICE"
ATTR_API_CAQI: Final = "CAQI"
@@ -31,12 +29,9 @@ ATTR_API_TEMPERATURE: Final = "TEMPERATURE"
ATTR_ADVICE: Final = "advice"
ATTR_DESCRIPTION: Final = "description"
ATTR_LABEL: Final = "label"
ATTR_LEVEL: Final = "level"
ATTR_LIMIT: Final = "limit"
ATTR_PERCENT: Final = "percent"
ATTR_UNIT: Final = "unit"
ATTR_VALUE: Final = "value"
SUFFIX_PERCENT: Final = "PERCENT"
SUFFIX_LIMIT: Final = "LIMIT"
@@ -51,52 +46,54 @@ MAX_UPDATE_INTERVAL: Final = 90
MIN_UPDATE_INTERVAL: Final = 5
NO_AIRLY_SENSORS: Final = "There are no Airly sensors in this area yet."
SENSOR_TYPES: dict[str, SensorDescription] = {
ATTR_API_CAQI: {
ATTR_LABEL: ATTR_API_CAQI,
ATTR_UNIT: "CAQI",
ATTR_VALUE: round,
},
ATTR_API_PM1: {
ATTR_ICON: "mdi:blur",
ATTR_LABEL: ATTR_API_PM1,
ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
ATTR_VALUE: round,
},
ATTR_API_PM25: {
ATTR_ICON: "mdi:blur",
ATTR_LABEL: "PM2.5",
ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
ATTR_VALUE: round,
},
ATTR_API_PM10: {
ATTR_ICON: "mdi:blur",
ATTR_LABEL: ATTR_API_PM10,
ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
ATTR_VALUE: round,
},
ATTR_API_HUMIDITY: {
ATTR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY,
ATTR_LABEL: ATTR_API_HUMIDITY.capitalize(),
ATTR_UNIT: PERCENTAGE,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
ATTR_VALUE: lambda value: round(value, 1),
},
ATTR_API_PRESSURE: {
ATTR_DEVICE_CLASS: DEVICE_CLASS_PRESSURE,
ATTR_LABEL: ATTR_API_PRESSURE.capitalize(),
ATTR_UNIT: PRESSURE_HPA,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
ATTR_VALUE: round,
},
ATTR_API_TEMPERATURE: {
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_LABEL: ATTR_API_TEMPERATURE.capitalize(),
ATTR_UNIT: TEMP_CELSIUS,
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
ATTR_VALUE: lambda value: round(value, 1),
},
}
SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
AirlySensorEntityDescription(
key=ATTR_API_CAQI,
name=ATTR_API_CAQI,
unit_of_measurement="CAQI",
),
AirlySensorEntityDescription(
key=ATTR_API_PM1,
icon="mdi:blur",
name=ATTR_API_PM1,
unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=STATE_CLASS_MEASUREMENT,
),
AirlySensorEntityDescription(
key=ATTR_API_PM25,
icon="mdi:blur",
name="PM2.5",
unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=STATE_CLASS_MEASUREMENT,
),
AirlySensorEntityDescription(
key=ATTR_API_PM10,
icon="mdi:blur",
name=ATTR_API_PM10,
unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=STATE_CLASS_MEASUREMENT,
),
AirlySensorEntityDescription(
key=ATTR_API_HUMIDITY,
device_class=DEVICE_CLASS_HUMIDITY,
name=ATTR_API_HUMIDITY.capitalize(),
unit_of_measurement=PERCENTAGE,
state_class=STATE_CLASS_MEASUREMENT,
value=lambda value: round(value, 1),
),
AirlySensorEntityDescription(
key=ATTR_API_PRESSURE,
device_class=DEVICE_CLASS_PRESSURE,
name=ATTR_API_PRESSURE.capitalize(),
unit_of_measurement=PRESSURE_HPA,
state_class=STATE_CLASS_MEASUREMENT,
),
AirlySensorEntityDescription(
key=ATTR_API_TEMPERATURE,
device_class=DEVICE_CLASS_TEMPERATURE,
name=ATTR_API_TEMPERATURE.capitalize(),
unit_of_measurement=TEMP_CELSIUS,
state_class=STATE_CLASS_MEASUREMENT,
value=lambda value: round(value, 1),
),
)

View File

@@ -1,15 +1,14 @@
"""Type definitions for Airly integration."""
from __future__ import annotations
from typing import Callable, TypedDict
from dataclasses import dataclass
from typing import Callable
from homeassistant.components.sensor import SensorEntityDescription
class SensorDescription(TypedDict, total=False):
"""Sensor description class."""
@dataclass
class AirlySensorEntityDescription(SensorEntityDescription):
"""Class describing Airly sensor entities."""
device_class: str | None
icon: str | None
label: str
unit: str
state_class: str | None
value: Callable
value: Callable = round

View File

@@ -3,16 +3,10 @@ from __future__ import annotations
from typing import Any, cast
from homeassistant.components.sensor import ATTR_STATE_CLASS, SensorEntity
from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ATTRIBUTION,
ATTR_DEVICE_CLASS,
ATTR_ICON,
CONF_NAME,
)
from homeassistant.const import ATTR_ATTRIBUTION, CONF_NAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@@ -27,12 +21,9 @@ from .const import (
ATTR_API_PM10,
ATTR_API_PM25,
ATTR_DESCRIPTION,
ATTR_LABEL,
ATTR_LEVEL,
ATTR_LIMIT,
ATTR_PERCENT,
ATTR_UNIT,
ATTR_VALUE,
ATTRIBUTION,
DEFAULT_NAME,
DOMAIN,
@@ -41,6 +32,7 @@ from .const import (
SUFFIX_LIMIT,
SUFFIX_PERCENT,
)
from .model import AirlySensorEntityDescription
PARALLEL_UPDATES = 1
@@ -54,10 +46,10 @@ async def async_setup_entry(
coordinator = hass.data[DOMAIN][entry.entry_id]
sensors = []
for sensor in SENSOR_TYPES:
for description in SENSOR_TYPES:
# When we use the nearest method, we are not sure which sensors are available
if coordinator.data.get(sensor):
sensors.append(AirlySensor(coordinator, name, sensor))
if coordinator.data.get(description.key):
sensors.append(AirlySensor(coordinator, name, description))
async_add_entities(sensors, False)
@@ -66,47 +58,54 @@ class AirlySensor(CoordinatorEntity, SensorEntity):
"""Define an Airly sensor."""
coordinator: AirlyDataUpdateCoordinator
entity_description: AirlySensorEntityDescription
def __init__(
self, coordinator: AirlyDataUpdateCoordinator, name: str, kind: str
self,
coordinator: AirlyDataUpdateCoordinator,
name: str,
description: AirlySensorEntityDescription,
) -> None:
"""Initialize."""
super().__init__(coordinator)
self._description = description = SENSOR_TYPES[kind]
self._attr_device_class = description.get(ATTR_DEVICE_CLASS)
self._attr_icon = description.get(ATTR_ICON)
self._attr_name = f"{name} {description[ATTR_LABEL]}"
self._attr_state_class = description.get(ATTR_STATE_CLASS)
self._attr_device_info = {
"identifiers": {
(DOMAIN, f"{coordinator.latitude}-{coordinator.longitude}")
},
"name": DEFAULT_NAME,
"manufacturer": MANUFACTURER,
"entry_type": "service",
}
self._attr_name = f"{name} {description.name}"
self._attr_unique_id = (
f"{coordinator.latitude}-{coordinator.longitude}-{kind.lower()}"
f"{coordinator.latitude}-{coordinator.longitude}-{description.key}".lower()
)
self._attr_unit_of_measurement = description.get(ATTR_UNIT)
self._attrs: dict[str, Any] = {ATTR_ATTRIBUTION: ATTRIBUTION}
self.kind = kind
self.entity_description = description
@property
def state(self) -> StateType:
"""Return the state."""
state = self.coordinator.data[self.kind]
return cast(StateType, self._description[ATTR_VALUE](state))
state = self.coordinator.data[self.entity_description.key]
return cast(StateType, self.entity_description.value(state))
@property
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes."""
if self.kind == ATTR_API_CAQI:
if self.entity_description.key == ATTR_API_CAQI:
self._attrs[ATTR_LEVEL] = self.coordinator.data[ATTR_API_CAQI_LEVEL]
self._attrs[ATTR_ADVICE] = self.coordinator.data[ATTR_API_ADVICE]
self._attrs[ATTR_DESCRIPTION] = self.coordinator.data[
ATTR_API_CAQI_DESCRIPTION
]
if self.kind == ATTR_API_PM25:
if self.entity_description.key == ATTR_API_PM25:
self._attrs[ATTR_LIMIT] = self.coordinator.data[
f"{ATTR_API_PM25}_{SUFFIX_LIMIT}"
]
self._attrs[ATTR_PERCENT] = round(
self.coordinator.data[f"{ATTR_API_PM25}_{SUFFIX_PERCENT}"]
)
if self.kind == ATTR_API_PM10:
if self.entity_description.key == ATTR_API_PM10:
self._attrs[ATTR_LIMIT] = self.coordinator.data[
f"{ATTR_API_PM10}_{SUFFIX_LIMIT}"
]
@@ -114,18 +113,3 @@ class AirlySensor(CoordinatorEntity, SensorEntity):
self.coordinator.data[f"{ATTR_API_PM10}_{SUFFIX_PERCENT}"]
)
return self._attrs
@property
def device_info(self) -> DeviceInfo:
"""Return the device info."""
return {
"identifiers": {
(
DOMAIN,
f"{self.coordinator.latitude}-{self.coordinator.longitude}",
)
},
"name": DEFAULT_NAME,
"manufacturer": MANUFACTURER,
"entry_type": "service",
}

View File

@@ -22,6 +22,7 @@
},
"system_health": {
"info": {
"can_reach_server": "\u00c9rje el az Airly szervert",
"requests_per_day": "Enged\u00e9lyezett k\u00e9r\u00e9sek naponta",
"requests_remaining": "Fennmarad\u00f3 enged\u00e9lyezett k\u00e9r\u00e9sek"
}

View File

@@ -67,16 +67,13 @@ class AirNowSensor(CoordinatorEntity, SensorEntity):
"""Initialize."""
super().__init__(coordinator)
self.kind = kind
self._device_class = None
self._state = None
self._icon = None
self._unit_of_measurement = None
self._attrs = {ATTR_ATTRIBUTION: ATTRIBUTION}
@property
def name(self):
"""Return the name."""
return f"AirNow {SENSOR_TYPES[self.kind][ATTR_LABEL]}"
self._attr_name = f"AirNow {SENSOR_TYPES[self.kind][ATTR_LABEL]}"
self._attr_icon = SENSOR_TYPES[self.kind][ATTR_ICON]
self._attr_device_class = SENSOR_TYPES[self.kind][ATTR_DEVICE_CLASS]
self._attr_unit_of_measurement = SENSOR_TYPES[self.kind][ATTR_UNIT]
self._attr_unique_id = f"{self.coordinator.latitude}-{self.coordinator.longitude}-{self.kind.lower()}"
@property
def state(self):
@@ -96,24 +93,3 @@ class AirNowSensor(CoordinatorEntity, SensorEntity):
]
return self._attrs
@property
def icon(self):
"""Return the icon."""
self._icon = SENSOR_TYPES[self.kind][ATTR_ICON]
return self._icon
@property
def device_class(self):
"""Return the device_class."""
return SENSOR_TYPES[self.kind][ATTR_DEVICE_CLASS]
@property
def unique_id(self):
"""Return a unique_id for this entity."""
return f"{self.coordinator.latitude}-{self.coordinator.longitude}-{self.kind.lower()}"
@property
def unit_of_measurement(self):
"""Return the unit the value is expressed in."""
return SENSOR_TYPES[self.kind][ATTR_UNIT]

View File

@@ -1,5 +1,4 @@
{
"title": "AirNow",
"config": {
"step": {
"user": {

View File

@@ -17,7 +17,7 @@
"longitude": "L\u00e4ngengrad",
"radius": "Stationsradius (Meilen; optional)"
},
"description": "Richten Sie die AirNow-Luftqualit\u00e4tsintegration ein. Um den API-Schl\u00fcssel zu generieren, besuchen Sie https://docs.airnowapi.org/account/request/.",
"description": "Richte die AirNow-Luftqualit\u00e4tsintegration ein. Um den API-Schl\u00fcssel zu generieren, besuche https://docs.airnowapi.org/account/request/.",
"title": "AirNow"
}
}

View File

@@ -14,8 +14,10 @@
"data": {
"api_key": "API kulcs",
"latitude": "Sz\u00e9less\u00e9g",
"longitude": "Hossz\u00fas\u00e1g"
"longitude": "Hossz\u00fas\u00e1g",
"radius": "\u00c1llom\u00e1s sugara (m\u00e9rf\u00f6ld; opcion\u00e1lis)"
},
"description": "\u00c1ll\u00edtsa be az AirNow leveg\u0151min\u0151s\u00e9gi integr\u00e1ci\u00f3t. Az API-kulcs el\u0151\u00e1ll\u00edt\u00e1s\u00e1hoz keresse fel a https://docs.airnowapi.org/account/request/ oldalt.",
"title": "AirNow"
}
}

View File

@@ -1,6 +1,10 @@
"""The airvisual component."""
from __future__ import annotations
from collections.abc import Mapping
from datetime import timedelta
from math import ceil
from typing import Any
from pyairvisual import CloudAPI, NodeSamba
from pyairvisual.errors import (
@@ -10,6 +14,7 @@ from pyairvisual.errors import (
NodeProError,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ATTRIBUTION,
CONF_API_KEY,
@@ -20,9 +25,13 @@ from homeassistant.const import (
CONF_SHOW_ON_MAP,
CONF_STATE,
)
from homeassistant.core import callback
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers import aiohttp_client, config_validation as cv
from homeassistant.helpers import (
aiohttp_client,
config_validation as cv,
entity_registry,
)
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
@@ -42,7 +51,7 @@ from .const import (
LOGGER,
)
PLATFORMS = ["air_quality", "sensor"]
PLATFORMS = ["sensor"]
DATA_LISTENER = "listener"
@@ -53,11 +62,8 @@ CONFIG_SCHEMA = cv.deprecated(DOMAIN)
@callback
def async_get_geography_id(geography_dict):
def async_get_geography_id(geography_dict: Mapping[str, Any]) -> str:
"""Generate a unique ID from a geography dict."""
if not geography_dict:
return
if CONF_CITY in geography_dict:
return ", ".join(
(
@@ -72,7 +78,9 @@ def async_get_geography_id(geography_dict):
@callback
def async_get_cloud_api_update_interval(hass, api_key, num_consumers):
def async_get_cloud_api_update_interval(
hass: HomeAssistant, api_key: str, num_consumers: int
) -> timedelta:
"""Get a leveled scan interval for a particular cloud API key.
This will shift based on the number of active consumers, thus keeping the user
@@ -93,18 +101,22 @@ def async_get_cloud_api_update_interval(hass, api_key, num_consumers):
@callback
def async_get_cloud_coordinators_by_api_key(hass, api_key):
def async_get_cloud_coordinators_by_api_key(
hass: HomeAssistant, api_key: str
) -> list[DataUpdateCoordinator]:
"""Get all DataUpdateCoordinator objects related to a particular API key."""
coordinators = []
for entry_id, coordinator in hass.data[DOMAIN][DATA_COORDINATOR].items():
config_entry = hass.config_entries.async_get_entry(entry_id)
if config_entry.data.get(CONF_API_KEY) == api_key:
if config_entry and config_entry.data.get(CONF_API_KEY) == api_key:
coordinators.append(coordinator)
return coordinators
@callback
def async_sync_geo_coordinator_update_intervals(hass, api_key):
def async_sync_geo_coordinator_update_intervals(
hass: HomeAssistant, api_key: str
) -> None:
"""Sync the update interval for geography-based data coordinators (by API key)."""
coordinators = async_get_cloud_coordinators_by_api_key(hass, api_key)
@@ -124,14 +136,10 @@ def async_sync_geo_coordinator_update_intervals(hass, api_key):
coordinator.update_interval = update_interval
async def async_setup(hass, config):
"""Set up the AirVisual component."""
hass.data[DOMAIN] = {DATA_COORDINATOR: {}, DATA_LISTENER: {}}
return True
@callback
def _standardize_geography_config_entry(hass, config_entry):
def _standardize_geography_config_entry(
hass: HomeAssistant, config_entry: ConfigEntry
) -> None:
"""Ensure that geography config entries have appropriate properties."""
entry_updates = {}
@@ -164,9 +172,11 @@ def _standardize_geography_config_entry(hass, config_entry):
@callback
def _standardize_node_pro_config_entry(hass, config_entry):
def _standardize_node_pro_config_entry(
hass: HomeAssistant, config_entry: ConfigEntry
) -> None:
"""Ensure that Node/Pro config entries have appropriate properties."""
entry_updates = {}
entry_updates: dict[str, Any] = {}
if CONF_INTEGRATION_TYPE not in config_entry.data:
# If the config entry data doesn't contain the integration type, add it:
@@ -181,15 +191,17 @@ def _standardize_node_pro_config_entry(hass, config_entry):
hass.config_entries.async_update_entry(config_entry, **entry_updates)
async def async_setup_entry(hass, config_entry):
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up AirVisual as config entry."""
hass.data.setdefault(DOMAIN, {DATA_COORDINATOR: {}, DATA_LISTENER: {}})
if CONF_API_KEY in config_entry.data:
_standardize_geography_config_entry(hass, config_entry)
websession = aiohttp_client.async_get_clientsession(hass)
cloud_api = CloudAPI(config_entry.data[CONF_API_KEY], session=websession)
async def async_update_data():
async def async_update_data() -> dict[str, Any]:
"""Get new data from the API."""
if CONF_CITY in config_entry.data:
api_coro = cloud_api.air_quality.city(
@@ -227,9 +239,22 @@ async def async_setup_entry(hass, config_entry):
config_entry.entry_id
] = config_entry.add_update_listener(async_reload_entry)
else:
# Remove outdated air_quality entities from the entity registry if they exist:
ent_reg = entity_registry.async_get(hass)
for entity_entry in [
e
for e in ent_reg.entities.values()
if e.config_entry_id == config_entry.entry_id
and e.entity_id.startswith("air_quality")
]:
LOGGER.debug(
'Removing deprecated air_quality entity: "%s"', entity_entry.entity_id
)
ent_reg.async_remove(entity_entry.entity_id)
_standardize_node_pro_config_entry(hass, config_entry)
async def async_update_data():
async def async_update_data() -> dict[str, Any]:
"""Get new data from the API."""
try:
async with NodeSamba(
@@ -262,7 +287,7 @@ async def async_setup_entry(hass, config_entry):
return True
async def async_migrate_entry(hass, config_entry):
async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Migrate an old config entry."""
version = config_entry.version
@@ -304,7 +329,7 @@ async def async_migrate_entry(hass, config_entry):
return True
async def async_unload_entry(hass, config_entry):
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Unload an AirVisual config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(
config_entry, PLATFORMS
@@ -325,7 +350,7 @@ async def async_unload_entry(hass, config_entry):
return unload_ok
async def async_reload_entry(hass, config_entry):
async def async_reload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
"""Handle an options update."""
await hass.config_entries.async_reload(config_entry.entry_id)
@@ -333,21 +358,17 @@ async def async_reload_entry(hass, config_entry):
class AirVisualEntity(CoordinatorEntity):
"""Define a generic AirVisual entity."""
def __init__(self, coordinator):
def __init__(self, coordinator: DataUpdateCoordinator) -> None:
"""Initialize."""
super().__init__(coordinator)
self._attrs = {ATTR_ATTRIBUTION: DEFAULT_ATTRIBUTION}
@property
def extra_state_attributes(self):
"""Return the device state attributes."""
return self._attrs
self._attr_extra_state_attributes = {ATTR_ATTRIBUTION: DEFAULT_ATTRIBUTION}
async def async_added_to_hass(self):
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
@callback
def update():
def update() -> None:
"""Update the state."""
self.update_from_latest_data()
self.async_write_ha_state()
@@ -357,6 +378,6 @@ class AirVisualEntity(CoordinatorEntity):
self.update_from_latest_data()
@callback
def update_from_latest_data(self):
def update_from_latest_data(self) -> None:
"""Update the entity from the latest data."""
raise NotImplementedError

View File

@@ -1,108 +0,0 @@
"""Support for AirVisual Node/Pro units."""
from homeassistant.components.air_quality import AirQualityEntity
from homeassistant.core import callback
from . import AirVisualEntity
from .const import (
CONF_INTEGRATION_TYPE,
DATA_COORDINATOR,
DOMAIN,
INTEGRATION_TYPE_NODE_PRO,
)
ATTR_HUMIDITY = "humidity"
ATTR_SENSOR_LIFE = "{0}_sensor_life"
ATTR_VOC = "voc"
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up AirVisual air quality entities based on a config entry."""
# Geography-based AirVisual integrations don't utilize this platform:
if config_entry.data[CONF_INTEGRATION_TYPE] != INTEGRATION_TYPE_NODE_PRO:
return
coordinator = hass.data[DOMAIN][DATA_COORDINATOR][config_entry.entry_id]
async_add_entities([AirVisualNodeProSensor(coordinator)], True)
class AirVisualNodeProSensor(AirVisualEntity, AirQualityEntity):
"""Define a sensor for a AirVisual Node/Pro."""
def __init__(self, airvisual):
"""Initialize."""
super().__init__(airvisual)
self._attr_icon = "mdi:chemical-weapon"
@property
def air_quality_index(self):
"""Return the Air Quality Index (AQI)."""
if self.coordinator.data["settings"]["is_aqi_usa"]:
return self.coordinator.data["measurements"]["aqi_us"]
return self.coordinator.data["measurements"]["aqi_cn"]
@property
def available(self):
"""Return True if entity is available."""
return bool(self.coordinator.data)
@property
def carbon_dioxide(self):
"""Return the CO2 (carbon dioxide) level."""
return self.coordinator.data["measurements"].get("co2")
@property
def device_info(self):
"""Return device registry information for this entity."""
return {
"identifiers": {(DOMAIN, self.coordinator.data["serial_number"])},
"name": self.coordinator.data["settings"]["node_name"],
"manufacturer": "AirVisual",
"model": f'{self.coordinator.data["status"]["model"]}',
"sw_version": (
f'Version {self.coordinator.data["status"]["system_version"]}'
f'{self.coordinator.data["status"]["app_version"]}'
),
}
@property
def name(self):
"""Return the name."""
node_name = self.coordinator.data["settings"]["node_name"]
return f"{node_name} Node/Pro: Air Quality"
@property
def particulate_matter_2_5(self):
"""Return the particulate matter 2.5 level."""
return self.coordinator.data["measurements"].get("pm2_5")
@property
def particulate_matter_10(self):
"""Return the particulate matter 10 level."""
return self.coordinator.data["measurements"].get("pm1_0")
@property
def particulate_matter_0_1(self):
"""Return the particulate matter 0.1 level."""
return self.coordinator.data["measurements"].get("pm0_1")
@property
def unique_id(self):
"""Return a unique, Home Assistant friendly identifier for this entity."""
return self.coordinator.data["serial_number"]
@callback
def update_from_latest_data(self):
"""Update the entity from the latest data."""
self._attrs.update(
{
ATTR_VOC: self.coordinator.data["measurements"].get("voc"),
**{
ATTR_SENSOR_LIFE.format(pollutant): lifespan
for pollutant, lifespan in self.coordinator.data["status"][
"sensor_life"
].items()
},
}
)

View File

@@ -1,4 +1,6 @@
"""Define a config flow manager for AirVisual."""
from __future__ import annotations
import asyncio
from pyairvisual import CloudAPI, NodeSamba
@@ -11,6 +13,7 @@ from pyairvisual.errors import (
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry, OptionsFlow
from homeassistant.const import (
CONF_API_KEY,
CONF_IP_ADDRESS,
@@ -21,6 +24,7 @@ from homeassistant.const import (
CONF_STATE,
)
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers import aiohttp_client, config_validation as cv
from . import async_get_geography_id
@@ -64,13 +68,13 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 2
def __init__(self):
def __init__(self) -> None:
"""Initialize the config flow."""
self._entry_data_for_reauth = None
self._geo_id = None
self._entry_data_for_reauth: dict[str, str] = {}
self._geo_id: str | None = None
@property
def geography_coords_schema(self):
def geography_coords_schema(self) -> vol.Schema:
"""Return the data schema for the cloud API."""
return API_KEY_DATA_SCHEMA.extend(
{
@@ -83,7 +87,9 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
}
)
async def _async_finish_geography(self, user_input, integration_type):
async def _async_finish_geography(
self, user_input: dict[str, str], integration_type: str
) -> FlowResult:
"""Validate a Cloud API key."""
websession = aiohttp_client.async_get_clientsession(self.hass)
cloud_api = CloudAPI(user_input[CONF_API_KEY], session=websession)
@@ -142,25 +148,29 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
data={**user_input, CONF_INTEGRATION_TYPE: integration_type},
)
async def _async_init_geography(self, user_input, integration_type):
async def _async_init_geography(
self, user_input: dict[str, str], integration_type: str
) -> FlowResult:
"""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):
async def _async_set_unique_id(self, unique_id: str) -> None:
"""Set the unique ID of the config flow and abort if it already exists."""
await self.async_set_unique_id(unique_id)
self._abort_if_unique_id_configured()
@staticmethod
@callback
def async_get_options_flow(config_entry):
def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow:
"""Define the config flow to handle options."""
return AirVisualOptionsFlowHandler(config_entry)
async def async_step_geography_by_coords(self, user_input=None):
async def async_step_geography_by_coords(
self, user_input: dict[str, str] | None = None
) -> FlowResult:
"""Handle the initialization of the cloud API based on latitude/longitude."""
if not user_input:
return self.async_show_form(
@@ -171,7 +181,9 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
user_input, INTEGRATION_TYPE_GEOGRAPHY_COORDS
)
async def async_step_geography_by_name(self, user_input=None):
async def async_step_geography_by_name(
self, user_input: dict[str, str] | None = None
) -> FlowResult:
"""Handle the initialization of the cloud API based on city/state/country."""
if not user_input:
return self.async_show_form(
@@ -182,7 +194,9 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
user_input, INTEGRATION_TYPE_GEOGRAPHY_NAME
)
async def async_step_node_pro(self, user_input=None):
async def async_step_node_pro(
self, user_input: dict[str, str] | None = None
) -> FlowResult:
"""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=NODE_PRO_SCHEMA)
@@ -208,13 +222,15 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
data={**user_input, CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_NODE_PRO},
)
async def async_step_reauth(self, data):
async def async_step_reauth(self, data: dict[str, str]) -> FlowResult:
"""Handle configuration by re-auth."""
self._entry_data_for_reauth = data
self._geo_id = async_get_geography_id(data)
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(self, user_input=None):
async def async_step_reauth_confirm(
self, user_input: dict[str, str] | None = None
) -> FlowResult:
"""Handle re-auth completion."""
if not user_input:
return self.async_show_form(
@@ -227,7 +243,9 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
conf, self._entry_data_for_reauth[CONF_INTEGRATION_TYPE]
)
async def async_step_user(self, user_input=None):
async def async_step_user(
self, user_input: dict[str, str] | None = None
) -> FlowResult:
"""Handle the start of the config flow."""
if not user_input:
return self.async_show_form(
@@ -244,11 +262,13 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
class AirVisualOptionsFlowHandler(config_entries.OptionsFlow):
"""Handle an AirVisual options flow."""
def __init__(self, config_entry):
def __init__(self, config_entry: ConfigEntry) -> None:
"""Initialize."""
self.config_entry = config_entry
async def async_step_init(self, user_input=None):
async def async_step_init(
self, user_input: dict[str, str] | None = None
) -> FlowResult:
"""Manage the options."""
if user_input is not None:
return self.async_create_entry(title="", data=user_input)

View File

@@ -3,7 +3,7 @@
"name": "AirVisual",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airvisual",
"requirements": ["pyairvisual==5.0.8"],
"requirements": ["pyairvisual==5.0.9"],
"codeowners": ["@bachya"],
"iot_class": "cloud_polling"
}

View File

@@ -1,5 +1,8 @@
"""Support for AirVisual air quality sensors."""
from __future__ import annotations
from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_LATITUDE,
ATTR_LONGITUDE,
@@ -12,12 +15,16 @@ from homeassistant.const import (
CONF_SHOW_ON_MAP,
CONF_STATE,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_CO2,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE,
PERCENTAGE,
TEMP_CELSIUS,
)
from homeassistant.core import callback
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from . import AirVisualEntity
from .const import (
@@ -36,12 +43,21 @@ ATTR_POLLUTANT_SYMBOL = "pollutant_symbol"
ATTR_POLLUTANT_UNIT = "pollutant_unit"
ATTR_REGION = "region"
SENSOR_KIND_LEVEL = "air_pollution_level"
DEVICE_CLASS_POLLUTANT_LABEL = "airvisual__pollutant_label"
DEVICE_CLASS_POLLUTANT_LEVEL = "airvisual__pollutant_level"
SENSOR_KIND_AQI = "air_quality_index"
SENSOR_KIND_POLLUTANT = "main_pollutant"
SENSOR_KIND_BATTERY_LEVEL = "battery_level"
SENSOR_KIND_CO2 = "carbon_dioxide"
SENSOR_KIND_HUMIDITY = "humidity"
SENSOR_KIND_LEVEL = "air_pollution_level"
SENSOR_KIND_PM_0_1 = "particulate_matter_0_1"
SENSOR_KIND_PM_1_0 = "particulate_matter_1_0"
SENSOR_KIND_PM_2_5 = "particulate_matter_2_5"
SENSOR_KIND_POLLUTANT = "main_pollutant"
SENSOR_KIND_SENSOR_LIFE = "sensor_life"
SENSOR_KIND_TEMPERATURE = "temperature"
SENSOR_KIND_VOC = "voc"
GEOGRAPHY_SENSORS = [
(SENSOR_KIND_LEVEL, "Air Pollution Level", "mdi:gauge", None),
@@ -51,27 +67,74 @@ GEOGRAPHY_SENSORS = [
GEOGRAPHY_SENSOR_LOCALES = {"cn": "Chinese", "us": "U.S."}
NODE_PRO_SENSORS = [
(SENSOR_KIND_BATTERY_LEVEL, "Battery", DEVICE_CLASS_BATTERY, PERCENTAGE),
(SENSOR_KIND_HUMIDITY, "Humidity", DEVICE_CLASS_HUMIDITY, PERCENTAGE),
(SENSOR_KIND_TEMPERATURE, "Temperature", DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS),
(SENSOR_KIND_AQI, "Air Quality Index", None, "mdi:chart-line", "AQI"),
(SENSOR_KIND_BATTERY_LEVEL, "Battery", DEVICE_CLASS_BATTERY, None, PERCENTAGE),
(
SENSOR_KIND_CO2,
"C02",
DEVICE_CLASS_CO2,
None,
CONCENTRATION_PARTS_PER_MILLION,
),
(SENSOR_KIND_HUMIDITY, "Humidity", DEVICE_CLASS_HUMIDITY, None, PERCENTAGE),
(
SENSOR_KIND_PM_0_1,
"PM 0.1",
None,
"mdi:sprinkler",
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
(
SENSOR_KIND_PM_1_0,
"PM 1.0",
None,
"mdi:sprinkler",
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
(
SENSOR_KIND_PM_2_5,
"PM 2.5",
None,
"mdi:sprinkler",
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
(
SENSOR_KIND_TEMPERATURE,
"Temperature",
DEVICE_CLASS_TEMPERATURE,
None,
TEMP_CELSIUS,
),
(
SENSOR_KIND_VOC,
"VOC",
None,
"mdi:sprinkler",
CONCENTRATION_PARTS_PER_MILLION,
),
]
POLLUTANT_LABELS = {
"co": "Carbon Monoxide",
"n2": "Nitrogen Dioxide",
"o3": "Ozone",
"p1": "PM10",
"p2": "PM2.5",
"s2": "Sulfur Dioxide",
}
STATE_POLLUTANT_LABEL_CO = "co"
STATE_POLLUTANT_LABEL_N2 = "n2"
STATE_POLLUTANT_LABEL_O3 = "o3"
STATE_POLLUTANT_LABEL_P1 = "p1"
STATE_POLLUTANT_LABEL_P2 = "p2"
STATE_POLLUTANT_LABEL_S2 = "s2"
STATE_POLLUTANT_LEVEL_GOOD = "good"
STATE_POLLUTANT_LEVEL_MODERATE = "moderate"
STATE_POLLUTANT_LEVEL_UNHEALTHY_SENSITIVE = "unhealthy_sensitive"
STATE_POLLUTANT_LEVEL_UNHEALTHY = "unhealthy"
STATE_POLLUTANT_LEVEL_VERY_UNHEALTHY = "very_unhealthy"
STATE_POLLUTANT_LEVEL_HAZARDOUS = "hazardous"
POLLUTANT_LEVELS = {
(0, 50): ("Good", "mdi:emoticon-excited"),
(51, 100): ("Moderate", "mdi:emoticon-happy"),
(101, 150): ("Unhealthy for sensitive groups", "mdi:emoticon-neutral"),
(151, 200): ("Unhealthy", "mdi:emoticon-sad"),
(201, 300): ("Very unhealthy", "mdi:emoticon-dead"),
(301, 1000): ("Hazardous", "mdi:biohazard"),
(0, 50): (STATE_POLLUTANT_LEVEL_GOOD, "mdi:emoticon-excited"),
(51, 100): (STATE_POLLUTANT_LEVEL_MODERATE, "mdi:emoticon-happy"),
(101, 150): (STATE_POLLUTANT_LEVEL_UNHEALTHY_SENSITIVE, "mdi:emoticon-neutral"),
(151, 200): (STATE_POLLUTANT_LEVEL_UNHEALTHY, "mdi:emoticon-sad"),
(201, 300): (STATE_POLLUTANT_LEVEL_VERY_UNHEALTHY, "mdi:emoticon-dead"),
(301, 1000): (STATE_POLLUTANT_LEVEL_HAZARDOUS, "mdi:biohazard"),
}
POLLUTANT_UNITS = {
@@ -84,10 +147,15 @@ POLLUTANT_UNITS = {
}
async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up AirVisual sensors based on a config entry."""
coordinator = hass.data[DOMAIN][DATA_COORDINATOR][config_entry.entry_id]
sensors: list[AirVisualGeographySensor | AirVisualNodeProSensor]
if config_entry.data[CONF_INTEGRATION_TYPE] in [
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
INTEGRATION_TYPE_GEOGRAPHY_NAME,
@@ -107,8 +175,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
]
else:
sensors = [
AirVisualNodeProSensor(coordinator, kind, name, device_class, unit)
for kind, name, device_class, unit in NODE_PRO_SENSORS
AirVisualNodeProSensor(coordinator, kind, name, device_class, icon, unit)
for kind, name, device_class, icon, unit in NODE_PRO_SENSORS
]
async_add_entities(sensors, True)
@@ -117,53 +185,45 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class AirVisualGeographySensor(AirVisualEntity, SensorEntity):
"""Define an AirVisual sensor related to geography data via the Cloud API."""
def __init__(self, coordinator, config_entry, kind, name, icon, unit, locale):
def __init__(
self,
coordinator: DataUpdateCoordinator,
config_entry: ConfigEntry,
kind: str,
name: str,
icon: str,
unit: str | None,
locale: str,
) -> None:
"""Initialize."""
super().__init__(coordinator)
self._attrs.update(
if kind == SENSOR_KIND_LEVEL:
self._attr_device_class = DEVICE_CLASS_POLLUTANT_LEVEL
elif kind == SENSOR_KIND_POLLUTANT:
self._attr_device_class = DEVICE_CLASS_POLLUTANT_LABEL
self._attr_extra_state_attributes.update(
{
ATTR_CITY: config_entry.data.get(CONF_CITY),
ATTR_STATE: config_entry.data.get(CONF_STATE),
ATTR_COUNTRY: config_entry.data.get(CONF_COUNTRY),
}
)
self._attr_icon = icon
self._attr_name = f"{GEOGRAPHY_SENSOR_LOCALES[locale]} {name}"
self._attr_unique_id = f"{config_entry.unique_id}_{locale}_{kind}"
self._attr_unit_of_measurement = unit
self._config_entry = config_entry
self._kind = kind
self._locale = locale
self._name = name
self._state = None
self._attr_icon = icon
self._attr_unit_of_measurement = unit
@property
def available(self):
"""Return True if entity is available."""
try:
return self.coordinator.last_update_success and bool(
self.coordinator.data["current"]["pollution"]
)
except KeyError:
return False
@property
def name(self):
"""Return the name."""
return f"{GEOGRAPHY_SENSOR_LOCALES[self._locale]} {self._name}"
@property
def state(self):
"""Return the state."""
return self._state
@property
def unique_id(self):
"""Return a unique, Home Assistant friendly identifier for this entity."""
return f"{self._config_entry.unique_id}_{self._locale}_{self._kind}"
def available(self) -> bool:
"""Return if entity is available."""
return super().available and self.coordinator.data["current"]["pollution"]
@callback
def update_from_latest_data(self):
def update_from_latest_data(self) -> None:
"""Update the entity from the latest data."""
try:
data = self.coordinator.data["current"]["pollution"]
@@ -172,17 +232,17 @@ class AirVisualGeographySensor(AirVisualEntity, SensorEntity):
if self._kind == SENSOR_KIND_LEVEL:
aqi = data[f"aqi{self._locale}"]
[(self._state, self._attr_icon)] = [
[(self._attr_state, self._attr_icon)] = [
(name, icon)
for (floor, ceiling), (name, icon) in POLLUTANT_LEVELS.items()
if floor <= aqi <= ceiling
]
elif self._kind == SENSOR_KIND_AQI:
self._state = data[f"aqi{self._locale}"]
self._attr_state = data[f"aqi{self._locale}"]
elif self._kind == SENSOR_KIND_POLLUTANT:
symbol = data[f"main{self._locale}"]
self._state = POLLUTANT_LABELS[symbol]
self._attrs.update(
self._attr_state = symbol
self._attr_extra_state_attributes.update(
{
ATTR_POLLUTANT_SYMBOL: symbol,
ATTR_POLLUTANT_UNIT: POLLUTANT_UNITS[symbol],
@@ -206,33 +266,43 @@ class AirVisualGeographySensor(AirVisualEntity, SensorEntity):
)
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)
self._attr_extra_state_attributes[ATTR_LATITUDE] = latitude
self._attr_extra_state_attributes[ATTR_LONGITUDE] = longitude
self._attr_extra_state_attributes.pop("lati", None)
self._attr_extra_state_attributes.pop("long", None)
else:
self._attrs["lati"] = latitude
self._attrs["long"] = longitude
self._attrs.pop(ATTR_LATITUDE, None)
self._attrs.pop(ATTR_LONGITUDE, None)
self._attr_extra_state_attributes["lati"] = latitude
self._attr_extra_state_attributes["long"] = longitude
self._attr_extra_state_attributes.pop(ATTR_LATITUDE, None)
self._attr_extra_state_attributes.pop(ATTR_LONGITUDE, None)
class AirVisualNodeProSensor(AirVisualEntity, SensorEntity):
"""Define an AirVisual sensor related to a Node/Pro unit."""
def __init__(self, coordinator, kind, name, device_class, unit):
def __init__(
self,
coordinator: DataUpdateCoordinator,
kind: str,
name: str,
device_class: str | None,
icon: str | None,
unit: str,
) -> None:
"""Initialize."""
super().__init__(coordinator)
self._kind = kind
self._name = name
self._state = None
self._attr_device_class = device_class
self._attr_icon = icon
self._attr_name = (
f"{coordinator.data['settings']['node_name']} Node/Pro: {name}"
)
self._attr_unique_id = f"{coordinator.data['serial_number']}_{kind}"
self._attr_unit_of_measurement = unit
self._kind = kind
@property
def device_info(self):
def device_info(self) -> DeviceInfo:
"""Return device registry information for this entity."""
return {
"identifiers": {(DOMAIN, self.coordinator.data["serial_number"])},
@@ -245,28 +315,29 @@ class AirVisualNodeProSensor(AirVisualEntity, SensorEntity):
),
}
@property
def name(self):
"""Return the name."""
node_name = self.coordinator.data["settings"]["node_name"]
return f"{node_name} Node/Pro: {self._name}"
@property
def state(self):
"""Return the state."""
return self._state
@property
def unique_id(self):
"""Return a unique, Home Assistant friendly identifier for this entity."""
return f"{self.coordinator.data['serial_number']}_{self._kind}"
@callback
def update_from_latest_data(self):
def update_from_latest_data(self) -> None:
"""Update the entity from the latest data."""
if self._kind == SENSOR_KIND_BATTERY_LEVEL:
self._state = self.coordinator.data["status"]["battery"]
if self._kind == SENSOR_KIND_AQI:
if self.coordinator.data["settings"]["is_aqi_usa"]:
self._attr_state = self.coordinator.data["measurements"]["aqi_us"]
else:
self._attr_state = self.coordinator.data["measurements"]["aqi_cn"]
elif self._kind == SENSOR_KIND_BATTERY_LEVEL:
self._attr_state = self.coordinator.data["status"]["battery"]
elif self._kind == SENSOR_KIND_CO2:
self._attr_state = self.coordinator.data["measurements"].get("co2")
elif self._kind == SENSOR_KIND_HUMIDITY:
self._state = self.coordinator.data["measurements"].get("humidity")
self._attr_state = self.coordinator.data["measurements"].get("humidity")
elif self._kind == SENSOR_KIND_PM_0_1:
self._attr_state = self.coordinator.data["measurements"].get("pm0_1")
elif self._kind == SENSOR_KIND_PM_1_0:
self._attr_state = self.coordinator.data["measurements"].get("pm1_0")
elif self._kind == SENSOR_KIND_PM_2_5:
self._attr_state = self.coordinator.data["measurements"].get("pm2_5")
elif self._kind == SENSOR_KIND_TEMPERATURE:
self._state = self.coordinator.data["measurements"].get("temperature_C")
self._attr_state = self.coordinator.data["measurements"].get(
"temperature_C"
)
elif self._kind == SENSOR_KIND_VOC:
self._attr_state = self.coordinator.data["measurements"].get("voc")

View File

@@ -0,0 +1,20 @@
{
"state": {
"airvisual__pollutant_label": {
"co": "Carbon Monoxide",
"n2": "Nitrogen Dioxide",
"o3": "Ozone",
"p1": "PM10",
"p2": "PM2.5",
"s2": "Sulfur Dioxide"
},
"airvisual__pollutant_level": {
"good": "Good",
"moderate": "Moderate",
"unhealthy": "Unhealthy",
"unhealthy_sensitive": "Unhealthy for sensitive groups",
"very_unhealthy": "Very unhealthy",
"hazardous": "Hazardous"
}
}
}

View File

@@ -1,7 +1,7 @@
{
"config": {
"abort": {
"already_configured": "Diese Koordinaten oder Node/Pro ID sind bereits registriert.",
"already_configured": "Diese Node/Pro ID oder Standort ist bereits konfiguriert.",
"reauth_successful": "Die erneute Authentifizierung war erfolgreich"
},
"error": {
@@ -35,18 +35,18 @@
"ip_address": "Host",
"password": "Passwort"
},
"description": "\u00dcberwachen Sie eine pers\u00f6nliche AirVisual-Einheit. Das Passwort kann von der Benutzeroberfl\u00e4che des Ger\u00e4ts abgerufen werden.",
"title": "Konfigurieren Sie einen AirVisual Node/Pro"
"description": "\u00dcberwache eine pers\u00f6nliche AirVisual-Einheit. Das Passwort kann von der Benutzeroberfl\u00e4che des Ger\u00e4ts abgerufen werden.",
"title": "Konfiguriere einen AirVisual Node/Pro"
},
"reauth_confirm": {
"data": {
"api_key": "API-Key"
"api_key": "API-Schl\u00fcssel"
},
"title": "AirVisual erneut authentifizieren"
},
"user": {
"description": "W\u00e4hlen Sie aus, welche Art von AirVisual-Daten Sie \u00fcberwachen m\u00f6chten.",
"title": "Konfigurieren Sie AirVisual"
"description": "W\u00e4hle aus, welche Art von AirVisual-Daten du \u00fcberwachen m\u00f6chtest.",
"title": "Konfiguriere AirVisual"
}
}
},
@@ -54,9 +54,9 @@
"step": {
"init": {
"data": {
"show_on_map": "Zeigen Sie die \u00fcberwachte Geografie auf der Karte an"
"show_on_map": "Zeige die \u00fcberwachte Geografie auf der Karte an"
},
"title": "Konfigurieren Sie AirVisual"
"title": "Konfiguriere AirVisual"
}
}
}

View File

@@ -6,7 +6,7 @@
"error": {
"cannot_connect": "\u05d4\u05d4\u05ea\u05d7\u05d1\u05e8\u05d5\u05ea \u05e0\u05db\u05e9\u05dc\u05d4",
"general_error": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05dc\u05ea\u05d9 \u05e6\u05e4\u05d5\u05d9\u05d4",
"invalid_api_key": "\u05de\u05e4\u05ea\u05d7 API \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9 \u05e1\u05d5\u05e4\u05e7",
"invalid_api_key": "\u05de\u05e4\u05ea\u05d7 API \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9",
"location_not_found": "\u05d4\u05de\u05d9\u05e7\u05d5\u05dd \u05dc\u05d0 \u05e0\u05de\u05e6\u05d0"
},
"step": {
@@ -35,5 +35,14 @@
}
}
}
},
"options": {
"step": {
"init": {
"data": {
"show_on_map": "\u05d4\u05e6\u05d2 \u05d2\u05d9\u05d0\u05d5\u05d2\u05e8\u05e4\u05d9\u05d4 \u05de\u05e0\u05d5\u05d8\u05e8\u05ea \u05d1\u05de\u05e4\u05d4"
}
}
}
}
}

View File

@@ -7,7 +7,8 @@
"error": {
"cannot_connect": "Sikertelen csatlakoz\u00e1s",
"general_error": "V\u00e1ratlan hiba t\u00f6rt\u00e9nt",
"invalid_api_key": "\u00c9rv\u00e9nytelen API kulcs"
"invalid_api_key": "\u00c9rv\u00e9nytelen API kulcs",
"location_not_found": "A hely nem tal\u00e1lhat\u00f3"
},
"step": {
"geography_by_coords": {
@@ -15,14 +16,19 @@
"api_key": "API kulcs",
"latitude": "Sz\u00e9less\u00e9g",
"longitude": "Hossz\u00fas\u00e1g"
}
},
"description": "Haszn\u00e1lja az AirVisual felh\u0151 API-t a sz\u00e9less\u00e9g / hossz\u00fas\u00e1g figyel\u00e9s\u00e9hez.",
"title": "Konfigur\u00e1lja a geogr\u00e1fi\u00e1t"
},
"geography_by_name": {
"data": {
"api_key": "API kulcs",
"city": "V\u00e1ros",
"country": "Orsz\u00e1g"
}
"country": "Orsz\u00e1g",
"state": "\u00e1llapot"
},
"description": "Haszn\u00e1lja az AirVisual felh\u0151 API-t egy v\u00e1ros / \u00e1llam / orsz\u00e1g figyel\u00e9s\u00e9hez.",
"title": "Konfigur\u00e1lja a geogr\u00e1fi\u00e1t"
},
"node_pro": {
"data": {
@@ -33,7 +39,8 @@
"reauth_confirm": {
"data": {
"api_key": "API kulcs"
}
},
"title": "Az AirVisual \u00fajb\u00f3li hiteles\u00edt\u00e9se"
}
}
}

View File

@@ -17,7 +17,7 @@
"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.",
"description": "\u0414\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u043f\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0439 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_name": {
@@ -25,9 +25,9 @@
"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"
"state": "\u0428\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.",
"description": "\u0414\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 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0439 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"
},
"node_pro": {

View File

@@ -0,0 +1,20 @@
{
"state": {
"airvisual__pollutant_label": {
"co": "Mon\u00f2xid de carboni",
"n2": "Di\u00f2xid de nitrogen",
"o3": "Oz\u00f3",
"p1": "PM10",
"p2": "PM2.5",
"s2": "Di\u00f2xid de sofre"
},
"airvisual__pollutant_level": {
"good": "Bo",
"hazardous": "Perill\u00f3s",
"moderate": "Moderat",
"unhealthy": "Poc saludable",
"unhealthy_sensitive": "Poc saludable per a grups sensibles",
"very_unhealthy": "Molt poc saludable"
}
}
}

View File

@@ -0,0 +1,20 @@
{
"state": {
"airvisual__pollutant_label": {
"co": "Kohlenmonoxid",
"n2": "Stickstoffdioxid",
"o3": "Ozon",
"p1": "PM10",
"p2": "PM2,5",
"s2": "Schwefeldioxid"
},
"airvisual__pollutant_level": {
"good": "Gut",
"hazardous": "Gef\u00e4hrlich",
"moderate": "M\u00e4\u00dfig",
"unhealthy": "Ungesund",
"unhealthy_sensitive": "Ungesund f\u00fcr sensible Gruppen",
"very_unhealthy": "Sehr ungesund"
}
}
}

View File

@@ -0,0 +1,20 @@
{
"state": {
"airvisual__pollutant_label": {
"co": "Carbon Monoxide",
"n2": "Nitrogen Dioxide",
"o3": "Ozone",
"p1": "PM10",
"p2": "PM2.5",
"s2": "Sulfur Dioxide"
},
"airvisual__pollutant_level": {
"good": "Good",
"hazardous": "Hazardous",
"moderate": "Moderate",
"unhealthy": "Unhealthy",
"unhealthy_sensitive": "Unhealthy for sensitive groups",
"very_unhealthy": "Very unhealthy"
}
}
}

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