Compare commits

..

2203 Commits

Author SHA1 Message Date
Paulus Schoutsen
b1a05e7605 Merge pull request #17578 from home-assistant/rc
0.80.3
2018-10-18 14:55:46 +02:00
Paulus Schoutsen
cd90bb4161 Bumped version to 0.80.3 2018-10-18 13:58:58 +02:00
Paulus Schoutsen
17d0fe02c7 Update snapcast to 2.0.9 (#17573) 2018-10-18 13:58:48 +02:00
Steven Looman
43b140be5e Upgrade async_upnp_client to 0.12.6 (#17560) 2018-10-18 13:58:48 +02:00
Steven Looman
9ded16ccc3 Update to async-upnp-client==0.12.5 (#17401) 2018-10-18 13:58:47 +02:00
Marcel Hoppe
91dc0c3731 update hangups to 0.4.6 and fix Issue #16593 hangouts reconnects. (#17518) 2018-10-18 13:57:04 +02:00
Paulus Schoutsen
6e4a99cec0 Bump frontend to 20181018.0 2018-10-18 13:52:52 +02:00
Paulus Schoutsen
fa196e5889 Merge pull request #17546 from home-assistant/rc
0.80.2
2018-10-17 14:56:58 +02:00
Paulus Schoutsen
9500bb1ac8 Bumped version to 0.80.2 2018-10-17 14:17:56 +02:00
Paulus Schoutsen
b3548f1ead Add another 3 days leeway to give time for payment processing times (#17542) 2018-10-17 14:17:47 +02:00
Kevin Fronczak
f74e976be1 Blink update - fixes #17316 (#17538)
* Updgrae blinkpy to 0.10.0

- Remove status sensor (API endpoint unreliable for this)
- Wifi strength reports in wifi bars rather than dBm (result of new API
endpoint)
- Added unique ids based on serial number

* Update requirements
2018-10-17 14:17:47 +02:00
Nikolay Vasilchuk
dc55718bc3 Fix: Connection pool of Request object is smaller than optimal value (8) (#17483) 2018-10-17 14:17:46 +02:00
Paulus Schoutsen
6551c53e32 Bump frontend to 20181017.0 2018-10-17 14:17:35 +02:00
Paulus Schoutsen
a27d49d022 Update translations 2018-10-17 14:17:33 +02:00
Paulus Schoutsen
4ea71b0602 Merge pull request #17480 from home-assistant/rc
0.80.1
2018-10-15 16:10:50 +02:00
Paulus Schoutsen
708334c0c2 Bumped version to 0.80.1 2018-10-15 15:31:12 +02:00
Paulus Schoutsen
b5272f2bc7 Fix websocket API (#17471) 2018-10-15 15:30:21 +02:00
Pascal Vizeli
80867cc9b7 Bugfix eventstream with EOF on end (#17465) 2018-10-15 15:30:20 +02:00
Tommy Jonsson
f92b392a24 Fix hangout.send_message requiring data key (#17393) 2018-10-15 15:30:20 +02:00
Martin Berg
220054a6c3 Fix arm/disarm calls. (#17381) 2018-10-15 15:30:19 +02:00
Paulus Schoutsen
49a9b61f6f Update frontend to 20181014.0 2018-10-14 19:17:41 +02:00
Paulus Schoutsen
8eb4e77365 Merge pull request #17361 from home-assistant/rc
0.80.0
2018-10-12 16:57:52 +02:00
Paulus Schoutsen
cd29b47924 Bumped version to 0.80.0 2018-10-12 14:59:36 +02:00
Pascal Vizeli
edb3722abd Hass.io auth/sso part2 (#17324)
* Update discovery.py

* Create const.py

* Update auth.py

* Update const.py

* Update const.py

* Update http.py

* Update handler.py

* Update auth.py

* Update auth.py

* Update test_auth.py
2018-10-12 14:59:17 +02:00
Pascal Vizeli
bc036cc2fe Fix auth for hass.io (#17318)
* Update test_auth.py

* Update auth.py

* Update test_auth.py
2018-10-12 14:59:17 +02:00
Martin Hjelmare
8778b707f1 Allow tradfri groups for new imported entries (#17310)
* Clean up leftover config schema option

* Allow import groups via new config yaml setup

* Fix and add test

* Add a test without groups for legacy import

* Change default import groups to False

* Fix I/O in test
2018-10-12 14:59:16 +02:00
Alok Saboo
05ae8f9dd4 Fix samsung bug (#17285) 2018-10-12 14:59:16 +02:00
Nikolay Vasilchuk
d199f57aa8 Logbook: filter by entity and period (#17095)
* Filter logbook by entity_id

* Filter logbook by period

* Simple test

* houndci-bot review

* Tests

* Test fix

* Test Fix
2018-10-12 14:59:15 +02:00
Paulus Schoutsen
f47e080f37 Update translations 2018-10-12 14:58:48 +02:00
Paulus Schoutsen
cfc5ebbfb0 Update frontend 2018-10-12 14:58:23 +02:00
Paulus Schoutsen
fa3f6ca2c7 Bumped version to 0.80.0b5 2018-10-10 14:29:04 +02:00
Paul Annekov
1d78393680 fixed 'on_startup() takes 0 positional arguments but 1 was given' (#17295) 2018-10-10 14:26:34 +02:00
Pascal Vizeli
951d7154b8 Fix hassio discovery (#17275)
* Update discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Fix tests

* fix lint
2018-10-10 14:26:33 +02:00
Pascal Vizeli
3f28b30860 Hassio auth (#17274)
* Create auth.py

* Update auth.py

* Update auth.py

* Update __init__.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Add tests

* Update test_auth.py

* Update auth.py

* Update test_auth.py

* Update auth.py
2018-10-10 14:26:32 +02:00
Paulus Schoutsen
83dec7173c Update translations 2018-10-10 14:25:49 +02:00
Paulus Schoutsen
a8a21ee28d Bumped version to 0.80.0b4 2018-10-09 16:20:39 +02:00
Anders Melchiorsen
1a76603f53 Remove warning on script delay (#17264)
* Remove warning on script delay

* Use suppress
2018-10-09 16:20:31 +02:00
Steven Looman
089e15e046 Add defaults, fixing #17229 (#17261) 2018-10-09 16:20:31 +02:00
Sebastian Muszynski
b59d69f313 Fix ambient light state of the Philips Eyecare Lamp (Closes: #16269) (#17259) 2018-10-09 16:20:30 +02:00
Paulus Schoutsen
eb7db1f763 block external IP (#17248)
* block external IP

* Update __init__.py
2018-10-09 16:20:29 +02:00
Paulus Schoutsen
429f09deb3 Add a webhook automation trigger (#17246) 2018-10-09 16:20:29 +02:00
Paulus Schoutsen
4d3d51635d Bumped version to 0.80.0b3 2018-10-08 16:16:01 +02:00
Malte Franken
a372053eac updated georss-client library to 0.3 (#17239) 2018-10-08 16:15:40 +02:00
Paulus Schoutsen
2e120061b4 Guard for bad device info (#17238) 2018-10-08 16:15:40 +02:00
Paulus Schoutsen
3a6eac216c Fix SPC (#17236) 2018-10-08 16:15:39 +02:00
Otto Winter
6671cbb96d Fix potential MQTT discovery race condition (#17208)
* Fix potential MQTT discovery race condition

* Rename data key
2018-10-08 16:15:39 +02:00
Matt Schmitt
9e386938bb MyQ cover return unknown state if not available (#17207)
* Add additional supported states

* Use get method for lookup

* Return None if unable to get status
2018-10-08 16:15:38 +02:00
Paulus Schoutsen
6be52208fc Prevent accidental device reg override (#17136) 2018-10-08 16:15:38 +02:00
Paulus Schoutsen
bd4ff6fc21 Bumped version to 0.80.0b2 2018-10-07 23:33:46 +02:00
Martin Berg
5fcea074c4 Init sub-components using global var. (#17220) 2018-10-07 23:33:40 +02:00
Per Sandström
7369af0639 Verisure standard config for scan interval (#17192)
* verisure configurable polling

* fix indentation
2018-10-07 23:33:40 +02:00
Anders Melchiorsen
b872cb95c7 Upgrade aiolifx_effects to 0.2.1 (#17188) 2018-10-07 23:33:39 +02:00
cdce8p
3338ebd4c1 Bugfix switch flux - light service call (#17187)
* Bugfix switch flux - light service call

* Change x_val and y_val test
2018-10-07 23:33:38 +02:00
cdce8p
7b176aa7c9 Fix device_tracker service call & cleanup (#17173)
* Bugfix group service - device_tracker

* Cleanup
2018-10-07 23:33:38 +02:00
Paulus Schoutsen
c722091967 Fix data used for logbook (#17172)
* Fix data used for logbook

* Lint
2018-10-07 23:33:38 +02:00
Paulus Schoutsen
4cffef7f2b Update translations 2018-10-07 23:27:57 +02:00
Paulus Schoutsen
31b1b0c044 Update frontend to 20181007.0 2018-10-07 23:27:57 +02:00
Paulus Schoutsen
7a22fbe961 Bumped version to 0.80.0b1 2018-10-05 20:21:27 +02:00
Paulus Schoutsen
738089c57c Fix incorrect yaml in hangouts (#17169) 2018-10-05 20:21:23 +02:00
Paulus Schoutsen
88c0a92857 Bumped version to 0.80.0b0 2018-10-05 17:56:30 +02:00
Paulus Schoutsen
0c770520ed Update translations 2018-10-05 17:50:00 +02:00
Paulus Schoutsen
92e28067d8 Update frontend to 20181005.0 2018-10-05 17:49:27 +02:00
prophit987
d1636dab31 @danielhiversen as codeowner for Tibber (#17154) 2018-10-05 14:55:16 +02:00
prophit987
13aa935147 Discover Danfoss/devolo RS Room Sensor thermostat (#17153)
Allows the Danfoss/Devolo RS Room Sensor thermostat to be discovered as climate device in homeassistant.
This device is defined as GENERIC_TYPE_MULTILEVEL_SENSOR, and not GENERIC_TYPE_THERMOSTAT.
Ref: https://community.home-assistant.io/t/devolo-zwave-thermostat/58739
2018-10-05 14:39:10 +02:00
Paul Annekov
29c3f1618f Fix miflora connection errors during platform setup (#16798)
* possible fix for startup delay

* fixed reported issues

* moved update code into setup

* reverted to previous solution
2018-10-05 13:33:28 +02:00
cdce8p
37a47b5a59 Add faucet, shower, sprinkler, valve to HomeKit (#17145) 2018-10-05 12:43:50 +02:00
Julius Mittenzwei
2e62afabdc Added warning to HomeKit component (#16807)
* added warning if more then 100 devices are added to HomeKit
2018-10-05 12:32:26 +02:00
Rohan Kapoor
a8f5e8699a Fix zoneminder zms_url construction (#17150) 2018-10-05 10:30:08 +02:00
Lewis Juggins
4218efddcd Cleanly stop tradfri on shutdown (#17114)
* Tradfri shutdown fix

* Bump version

* Bump version

* Fix

* Derp

* Remove unnecessary shutdown event
2018-10-05 09:59:34 +02:00
Gerard
aec320dc19 Fix a typo (#17147) 2018-10-05 07:48:40 +02:00
Aaron Bach
acf684de05 Added OpenUV CODEOWNERS info (#17149) 2018-10-04 19:57:52 -06:00
Florian Klien
ce1e8f8ace YesssSMS handling more errors, upgrade to version 0.2.3 (#17052)
* YesssSMS handling more errors, upgrade to version 0.2.1

 - handling missing internet connection nicely
 - disabling login with non-working credentials (website locked account for 1 hour)
 - upgrade to new upstream version of YesssSMS

* notify.yessssms tests

* test requirements

* flake8 fix

* fixing tests, new upstream version 0.2.3

fixing tests based on requested changes, coverage

* removing unmotivated print

* passing exception to ConnectionError and SMSSendingError logger
2018-10-04 17:34:04 -04:00
Per Sandström
b55c7a5ba2 verisure configurable polling (#17144) 2018-10-04 21:41:02 +02:00
cdce8p
52ff232797 Bugfix invalid entity_config parameter HomeKit (#17143) 2018-10-04 20:37:04 +02:00
Paulus Schoutsen
769dda735d Remove discovery (#17070) 2018-10-04 16:04:44 +02:00
Ana Paula Gomes
02bf07d9df Add timeout and fix oscillations on Samsung TV component (#17102)
* Add timeout and fix oscillations

* Adjust code to py3.5.3

* Clean code
2018-10-04 16:02:14 +02:00
Georgi Kirichkov
b92b24e8a4 Webhook component - pass headers to webhook handler (#17091)
* Pass headers to webhook handler

* Refactors webhook component to post Request object instead of data

* Update webhook tests

* Cleanup webhook test and fix a bug in ifttt

* Address code review comments
2018-10-04 15:54:51 +02:00
Paulus Schoutsen
0cfbb9ce91 Allow config entry setup to raise not ready (#17135) 2018-10-04 15:53:50 +02:00
Tsvi Mostovicz
c9976718d4 Take timezone into consideration when calulating Zmanim. Partial fix for #16946 (#17131) 2018-10-04 15:51:56 +02:00
Jason Hu
b61a250321 Fix upnp component l10n error (#17132) 2018-10-04 15:50:42 +02:00
Alok Saboo
ae0dd33e2e Add update service to Google Travel Sensor (#17092)
* Add update service

* Update service name

* Register service only once

* Make hound happy
2018-10-04 14:02:30 +02:00
Daniel Høyer Iversen
0d93bf9a45 Update xiaomi lib (#17129) 2018-10-04 13:24:54 +02:00
Heiko Thiery
178bf736f6 Add new component fritzbox binary_sensor (#17057)
* Add new component fritzbox binary_sensor

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fix failed flake8 test

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* add new file to .coveragerc

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* use wildcard to cover all platforms

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove polling because polling is true by default

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* add blank line to keep imports ordered

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* Minor changes
2018-10-04 12:16:27 +02:00
Paulus Schoutsen
a559c06d6b Make it easier for auth to consume newer formats (#17127) 2018-10-04 10:41:13 +02:00
Jerad Meisner
cc1891ef2b Add time created to persistent notifications. (#17121)
* Add time created to persistent notifications.

* UTC
2018-10-04 10:24:14 +02:00
Daniel Høyer Iversen
05d8c57212 Tibber component and notify (#17062)
* Refactor tibber, and Tibber notify

* update Tibber lib.

* tibber

* Tibber coveragerc

* Tibber upgrade lib

* style

* comments

* use async_get_service

* event
2018-10-04 09:29:49 +02:00
Adam Mills
3abdf217bb Homekit controller reconnect (#17060)
* Add threaded call_later helper

* Reconnect to device when connection fails

* Consolidate connection logs and warn on first
2018-10-04 09:25:05 +02:00
Martin Hjelmare
6a0c9a718e Fix sonos async use (#17099)
* Entry setup wasn't using the async api. Fix this by using correct
  async api.s
* Also use new async executor scheduler in async_added_to_hass.
2018-10-04 09:20:20 +02:00
Ville Skyttä
abd329d707 Upgrade pytest to 3.8.2 (#17125) 2018-10-04 09:03:31 +02:00
Aaron Bach
04fdde0e86 Bumps simplisafe-python to 3.1.2 (#16931)
* Bumps simplisafe-python to 3.0.4

* Updated requirements

* Refresh token logic added

* Member-requested changes

* Removed unused import

* Updated CODEOWNERS

* Bump library to 3.1.2
2018-10-03 21:03:29 -06:00
Michael Wei
2b3019bdf4 Support multiple accounts in Tile, use device identifiers (#17108)
*  Update tile to support multiple accounts

* 🎨 fix indent

* 🐛 fix format string

* 🎨 use .format

* 🎨 fix line indent
2018-10-03 17:22:21 -06:00
Diogo Gomes
cf0147098a Merge pull request #16300 from StevenLooman/igd
Adds discovery and config flow
Breaking change: no longer possible to map ports other than the port used by Home Assistant
2018-10-03 22:55:01 +01:00
mvn23
aeb21596a0 Fix counter restore. (#17101)
Add config option to disable restore (always use initial value on restart).
Add unit tests for restore config option.
2018-10-03 23:12:21 +02:00
Tsvi Mostovicz
cf5f02b347 Fix jewish calendar sensor with language set to english (#17104)
* Add failing testcase for issue #16830

* Fix for #16830
2018-10-03 18:43:25 +02:00
Michael Wei
467a59a6ed Change Tile icon to view-grid (#17098) 2018-10-03 09:59:11 -06:00
Kevin Fronczak
da622abb79 Adding myself as blink codeowner (#17096) 2018-10-03 17:04:31 +02:00
David Bilay
16cbc2d07f Add weather condition code to OpenWeatherMap sensor (#17093) 2018-10-03 16:15:45 +02:00
Anders Melchiorsen
952a1b3513 Smaller steps for Sonos volume up/down (#17080) 2018-10-03 15:09:05 +02:00
Anders Melchiorsen
a5402739b7 Keep the repeat mode when setting Sonos shuffle mode (#17083)
* Keep the repeat mode when setting Sonos shuffle mode

* Fix test
2018-10-03 14:50:13 +02:00
Pascal Vizeli
704c9d8582 Add support for Hass.io discovery feature for Add-ons (#17035)
* Update handler.py

* Update __init__.py

* Update handler.py

* Update __init__.py

* Create discovery.py

* Update handler.py

* Update discovery.py

* Update __init__.py

* Update discovery.py

* Update discovery.py

* Update discovery.py

* Update struct

* Update handler.py

* Update discovery.py

* Update discovery.py

* Update discovery.py

* Update __init__.py

* Update discovery.py

* Update discovery.py

* Update discovery.py

* Update discovery.py

* Update discovery.py

* Update discovery.py

* Update discovery.py

* Update discovery.py

* Update __init__.py

* Update discovery.py

* fix lint

* Update discovery.py

* cleanup old discovery

* Update discovery.py

* Update discovery.py

* Fix lint

* Fix tests

* Write more tests with new functions

* Update test_handler.py

* Create test_discovery.py

* Update conftest.py

* Update test_discovery.py

* Update conftest.py

* Update test_discovery.py

* Update conftest.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Fix test

* Add test

* fix lint

* Update handler.py

* Update discovery.py

* Update test_discovery.py

* fix lint

* Lint
2018-10-03 13:10:38 +02:00
David Peterson
2e5eb4d9dc Add optional headers configuration for scrape (#17085) 2018-10-03 12:47:38 +02:00
Steven Looman
5d693277f0 Fix stale docstrings 2018-10-03 11:27:38 +02:00
Steven Looman
3cb20c7b4d Changes after review by @MartinHjelmare 2018-10-03 11:08:32 +02:00
Paulus Schoutsen
4210835dcd Async response all the things (#17073)
* Use async_response

* Update device_registry.py
2018-10-03 07:53:54 +02:00
Dan Cinnamon
15a160a630 Bump pyenvisalink (#17086) 2018-10-03 06:28:08 +02:00
Kevin Fronczak
c78850a983 Overhaul of Blink platform (#16942)
* Using new methods for blink camera

- Refactored blink platform (breaking change)
- Camera needs to be uniquely enabled in config from now on
- Added motion detection enable/disable to camera platform

* Fix motion detection

- bumped blinkpy to 0.8.1
- Added wifi strength sensor

* Added platform schema to sensor

- Added global variables for brand and attribution to main platform

* Removed blink binary sensor

* Add alarm control panel

* Fixed dependency, added alarm_home

* Update requirements

* Fix lint errors

* Updated throttle times

* Add trigger_camera service (replaced snap_picture)

* Add refresh after camera trigger

* Update blinkpy version

* Wait for valid camera response before returning image

- Motion detection now working!

* Updated for new blinkpy 0.9.0

* Add refresh control and other fixes for new blinkpy release

* Add save video service

* Pushing to force bot to update

* Changed based on first review

- Pass blink as BLINK_DATA instead of DOMAIN
- Remove alarm_arm_home from alarm_control_panel
- Re-add discovery with schema for sensors/binar_sensors
- Change motion_detected to a binary_sensor
- Added camera_armed binary sensor
- Update camera device_state_attributes rather than state_attributes

* Moved blink.py to own folder. Added service hints.

* Updated coveragerc to reflect previous change

* Register services with DOMAIN

- Change device add for loop order in binary_sensor

* Fix lint error

* services.async_register -> services.register
2018-10-03 04:17:14 +02:00
Fabian Affolter
8e3a70e568 Upgrade youtube_dl to 2018.09.26 (#17079) 2018-10-02 22:31:59 +02:00
Thomas Lovén
06340c9875 Allow no movement in vamera.onvif_ptz service (#17065) 2018-10-02 14:36:28 +02:00
Paulus Schoutsen
31dd327c59 Catch possible errors from tradfri (#17068)
* Catch possible errors from tradfri

* Update config_flow.py
2018-10-02 14:35:43 +02:00
Paulus Schoutsen
38e2926a48 Update translations 2018-10-02 14:33:47 +02:00
Paulus Schoutsen
19722a0ef8 bump frontend to 20181002.0 2018-10-02 14:33:30 +02:00
Paulus Schoutsen
a6f8c3f662 Add logging to light updates (#17069) 2018-10-02 13:33:16 +02:00
Thomas Lovén
11d5671ee0 De-syncing binary_sensor.ping (#17056)
* Quick and dirty asyncing of binary_sensor.ping

* Minor changes
2018-10-02 11:43:34 +02:00
Paulus Schoutsen
20601cfc2d Merge branch 'master' into dev 2018-10-02 11:19:25 +02:00
Paulus Schoutsen
07972c84a1 Merge pull request #17067 from home-assistant/rc
0.79.3
2018-10-02 11:17:14 +02:00
cdce8p
7f0a50ce31 async_create_task (#17059)
* async_create_task

* Update google.py
2018-10-02 11:03:09 +02:00
Paulus Schoutsen
03845ef490 Lint 2018-10-02 10:35:15 +02:00
Paulus Schoutsen
37706c2731 Lint 2018-10-02 10:35:00 +02:00
Aaron Bach
71e3047f5c OpenUV: Fixed issue with missing protection window data (#17051) 2018-10-02 10:34:12 +02:00
Charles Garwood
0954eefa9f MJPEG Camera Log Filter Fixes (#17050)
* Move filter to setup platform

* pylint
2018-10-02 10:24:44 +02:00
cdce8p
90f71261c5 Remove service helper (8) (#17055)
* Updated keyboard

* Updated microsoft_face

* Updated ffmpeg

* Updated logger

* Updated components/__init__.py
2018-10-02 10:23:37 +02:00
Malte Franken
13af61e103 GeoRSS events sensor refactored (#16939)
* refactored geo_rss_events sensor to make use of new georss-client library that handles the communication with the rss feed

* fixed lint error
2018-10-02 10:20:51 +02:00
Nicko van Someren
b0b3620b2b Added working support for private storage (#16903)
* Fixed file corruption bugs in private storage code.

* Restoring fixed test case.

* Implemented test suite for utils/json.py

* Added new unit test cases for util/json.py

* Dixed formatting nags

* Fixed more nags from the Hound

* Added doc strings to some very short functions

* Fixing lint's complains about my choice of parts of speach. Sigh.

* Moved atomic save operations down into util/json.py so that all benefit.

Added extra clean-up code to ensure that temporary files are removed in
case of errors.
Updated emulated_hue unit tests to avoid errors.

* Apparently 'e' is not allows as a variable name for an exception...
2018-10-02 10:16:43 +02:00
Paulus Schoutsen
e07b6dfe0b Bumped version to 0.79.3 2018-10-02 09:57:01 +02:00
Paulus Schoutsen
3f5018459f Proactor policy fix (#17066)
* Proactor policy fix

* Backport Proactor policy for <py37
2018-10-02 09:56:54 +02:00
Jason Hu
2feab82396 Use Protractor loop in Windows (#17061)
* Use Protractor loop in Windows

* Add import sys
2018-10-02 09:56:53 +02:00
Paulus Schoutsen
1decba0052 Proactor policy fix (#17066)
* Proactor policy fix

* Backport Proactor policy for <py37
2018-10-02 09:55:37 +02:00
Jason Hu
1667481342 Use Protractor loop in Windows (#17061)
* Use Protractor loop in Windows

* Add import sys
2018-10-02 09:21:02 +02:00
Mathieu Velten
8e276295eb Update pynetgear to 0.4.2 (fix #14752) (#17064) 2018-10-02 09:14:07 +02:00
Sean Wilson
284d4d49c7 Add AquaLogic component (#16763)
* Add missing ups.status states.

* Add missing DISCHRG state.

* AquaLogic work-in-progress

* - Fix dependencies
- Switch updates

* Add support for aqualogic 0.8 features.

* Remove debugging.

* Switch to async updates rather than using polling.

* Rebase

* Fix lint errors

* Fix lint errors

* Fix lint errors

* Fix lint errors

* Fix lint errors.

* Bump aqualogic version to 0.11

* Update .coveragerc

* Remove integration-specific I/O

* Resolve code review issues.

* Fixed init() call.
2018-10-02 07:32:03 +02:00
cdce8p
c3eff5773b Remove alert service helper (#17038) 2018-10-02 00:33:45 +02:00
Daniel Perna
4d471622f6 Update pyhomematic to 0.1.50 (#17048) 2018-10-02 00:02:59 +02:00
SNoof85
90f2990b9e Support code 7 (#17047) 2018-10-01 22:18:56 +02:00
Charles Garwood
b197b8bab3 Suppress urllib3 header parsing error (#17042) 2018-10-01 20:39:40 +02:00
Fabian Affolter
a148f3e2a9 Mind the unit system (fixes #16819) (#16823) 2018-10-01 20:38:41 +02:00
Steven Looman
d732f8eca2 Changes after review by @MartinHjelmare 2018-10-01 19:26:43 +02:00
Nikolay Vasilchuk
b0c1c37cd5 Fix long update 'load_power' and 'in_use' for Xiaomi Zegbee Plug (#16915) 2018-10-01 18:00:48 +02:00
Anders Melchiorsen
4c36ffd0ef Remove error logging when Sonos shuffle_set is not available (#16921)
Error on set_shuffle with UPnP Error 712 received: Play mode not supported from 10.23.2.16
2018-10-01 17:58:04 +02:00
Paulus Schoutsen
fbc1c41673 Logbook context (#16937)
* Convert logbook to use attr

* Add context to events

* Enhance logbook

* Lint

* Fix logbook entry

* Don't use intermediary classes for logbook entries
2018-10-01 16:12:25 +02:00
Paulus Schoutsen
2e6346ca43 Break up websocket 2 (#17028)
* Break up websocket 2

* Lint+Test

* Lintttt

* Rename
2018-10-01 16:09:31 +02:00
Paulus Schoutsen
122e21a3c4 Merge pull request #17041 from home-assistant/rc
0.79.2
2018-10-01 15:50:25 +02:00
Paulus Schoutsen
33a54043e9 Bumped version to 0.79.2 2018-10-01 15:08:56 +02:00
Rohan Kapoor
d09ee8ac82 Fix switch.zoneminder name (#17026) 2018-10-01 15:08:50 +02:00
Paulus Schoutsen
1ca2e5226b Fix MQTT certificates (#16999) 2018-10-01 15:08:50 +02:00
cdce8p
b5e3d8c337 Async syntax (#17033)
* async-syntax-mqtt_room

* async-syntax-alert

* Additional fixes
2018-10-01 14:44:11 +02:00
Josh Anderson
f0fbdd6a26 Send headers with REST switch GET request (#17036) 2018-10-01 14:43:54 +02:00
cdce8p
e5c0e4336d Update coverage to exclude not tested file (#17039) 2018-10-01 14:41:35 +02:00
Paulus Schoutsen
c69a790ede Add Hass.io discovery to MQTT (#16962)
* Add Hass.io discovery to MQTT

* Update en.json

* Update __init__.py

* Update config_flow.py

* Update strings.json

* Update test_config_flow.py

* Lint

* Ensure we don't send bad data in config entry
2018-10-01 14:11:21 +02:00
David De Sloovere
5bc2e78ab4 Bump Enphase_Envoy dependency for older models (#17032) 2018-10-01 14:10:32 +02:00
Heiko Thiery
68bda1c732 Add new device attributes to fritzbox climate (#17027)
* Add new device attributes to fritzbox climate

With Fitz!OS 7 new parameters are introduced.

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* update requirements

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
2018-10-01 12:53:25 +02:00
Timmo
3137099348 🔨 update errors (#17029) 2018-10-01 12:51:39 +02:00
Paulus Schoutsen
22a80cf733 Break up websocket component (#17003)
* Break up websocket component

* Lint
2018-10-01 11:21:00 +02:00
Fabian Affolter
9edf1e5151 Upgrade locationsharinglib to 3.0.3 (#17010)
* Upgrade locationsharinglib to 3.0.3

* Revert change from #16969
2018-10-01 10:55:16 +02:00
Rohan Kapoor
6159f8b0ce Fix switch.zoneminder name (#17026) 2018-10-01 10:53:20 +02:00
Ville Skyttä
d4cde2bfbf Upgrade huawei-lte-api to 1.0.16 (#16972) 2018-10-01 10:52:49 +02:00
Otto Winter
760f822dce Fix MQTT discovery (#17004) 2018-10-01 09:01:40 +02:00
cdce8p
b24f9f5dfa Async syntax 3/8 (#17017)
* Async syntax 3, device_tracker & fan & hassio & image_processing & input

* Pylint fixes
2018-10-01 08:59:45 +02:00
cdce8p
134eeecd65 Async syntax 4/8 (#17018)
* Async syntax 4, media_player & notify

* Pylint fixes
2018-10-01 08:58:21 +02:00
cdce8p
3b5e5cbcd6 Async syntax 5, light & lock & remote & scene & telegram & helpers (#17019) 2018-10-01 08:56:50 +02:00
cdce8p
9e4c8f45d6 Async syntax 6, sensor (#17020) 2018-10-01 08:55:43 +02:00
cdce8p
121dba659c Async syntax 7, switch & tts & vacuum (#17021) 2018-10-01 08:55:00 +02:00
cdce8p
9aaf11de8c Async syntax 8/8 (#17022)
* Async syntax 8

* Pylint fixes
2018-10-01 08:52:42 +02:00
Charles Garwood
ea7b1e4573 Update Z-Wave service descriptions to point to proper log file (#17024) 2018-10-01 08:50:32 +02:00
cdce8p
8444b9ba03 Async syntax 2, camera & climate & config (#17016) 2018-10-01 08:50:05 +02:00
cdce8p
38e371c5d9 Async syntax 1, alarm_control_panel & automation & binary_sensor (#17015) 2018-10-01 08:49:19 +02:00
sander76
750c96709e Homematic cloud device update fix (#17001) 2018-09-30 22:39:25 +02:00
Patrik
940d5fb2ee Add basic support for Tradfri switches (#17007)
* Initial commit

* Sockets have been moved to separate component

* Sockets have been moved to separate component

* Fix const PLATFORM_SCHEMA

* Fix unique id

* Fix async_create_task

* Fix PLATFORM_SCHEMA

* Fix typo

* Remove pylint disable
2018-09-30 22:22:07 +02:00
Paulus Schoutsen
0a2b266742 Fix MQTT certificates (#16999) 2018-09-30 21:36:27 +02:00
Steven Looman
f511920a04 Merge remote-tracking branch 'upstream/dev' into igd 2018-09-30 20:22:10 +02:00
Totoo
1b7bfec247 Google Maps supports battery level and charging. (#16969)
* Google Maps supports battery level and charging.

With 3.0.2 locationsharinglib now the battery level and the charging attributes are available.

* Update google_maps.py

fix too long line error

* Update google_maps.py

Fix multi line import, and line length limit

* Update gen_requirements_all.py

Add locationsharinglib to gen_requirements_all

* update requirements_all

* Last try to fix requirements_all...
2018-09-30 15:17:39 +02:00
Paulus Schoutsen
f5632a5da5 Add webhook + IFTTT example (#16817)
* Add webhook + IFTTT example

* Abort if not externally accessible

* Abort on local url

* Add description to create entry

* Make body optional

* Allow ifttt setup without config

* Add tests

* Lint

* Fix Lint + Tests

* Fix typing
2018-09-30 14:45:48 +02:00
Paulus Schoutsen
1e28c752e1 Merge pull request #16988 from home-assistant/rc
0.79.1
2018-09-30 13:31:29 +02:00
Paulus Schoutsen
677714ecab Bumped version to 0.79.1 2018-09-30 10:22:49 +02:00
Rohan Kapoor
e2aadc3227 Bump zm-py to 0.0.4 (#16979) 2018-09-30 10:22:42 +02:00
Greg Laabs
c45b240026 Fix ISY blocking bug (#16978)
This fix results in `is_on` returning False if the state is unknown (which was a bug in 0.79).
2018-09-30 10:22:42 +02:00
Jason Hu
32d652884b Override unique_id of NestActivityZoneSensor (#16961) 2018-09-30 10:22:41 +02:00
Anders Melchiorsen
3528f8e647 Fix exception during history_stats startup (#16932)
* Fix exception during history_stats startup

* Do not track changes during startup

* Ignore args
2018-09-30 10:22:41 +02:00
Jason Hu
3e6cf8f59f Optimize Ring Sensors platform setup (#16886) 2018-09-30 10:22:41 +02:00
Ville Skyttä
06d959ed43 Upgrade pytest to 3.8.1 (#16980) 2018-09-30 10:20:10 +02:00
Greg Laabs
7f47d601f1 Fix ISY blocking bug (#16978)
This fix results in `is_on` returning False if the state is unknown (which was a bug in 0.79).
2018-09-30 09:21:27 +02:00
Rohan Kapoor
8b1bdda0fa Bump zm-py to 0.0.4 (#16979) 2018-09-30 09:21:07 +02:00
Otto Winter
70ce9bb7bc Add pressure sensor device class (#16965)
* Add pressure sensor device class

* Undo github desktop line exclude
2018-09-29 22:01:04 +02:00
Otto Winter
45fdda3f5d Add unique_id to MQTT fan (#16949) 2018-09-29 21:22:57 +02:00
Anders Melchiorsen
caaf4f5694 Fix exception during history_stats startup (#16932)
* Fix exception during history_stats startup

* Do not track changes during startup

* Ignore args
2018-09-29 21:22:24 +02:00
Otto Winter
3ddad83a84 Add unique_id to MQTT cover (#16950)
* Add unique_id to MQTT cover

* Fix tests
2018-09-29 20:54:57 +02:00
Otto Winter
35b6064581 Convert fan component to config entry (#16951)
* Conver fan component to config entry

* Lint
2018-09-29 20:53:48 +02:00
Jason Hu
c600d28b6a Override unique_id of NestActivityZoneSensor (#16961) 2018-09-29 20:53:02 +02:00
Diogo Gomes
909c3bdd63 Merge pull request #16954 from abmantis/patch-2
Adds @abmantis to CODEOWNERS
2018-09-28 23:05:59 +01:00
Abílio Costa
4b8c38819e Add myself to CODEOWNERS 2018-09-28 22:47:29 +01:00
Jan van Helvoort
7d1960baba Add zwave.network_complete_some_dead event (#16894)
* Add zwave.network_complete_some_dead event

* add missing comma

* typo

* Add SIGNAL_AWAKE_NODES_QUERIED_SOME_DEAD Test

* Add blank lines

* fix linter warnings

Line too long

* remove trailing whitespace

* Change test signal

* Listen to other event
2018-09-28 19:14:57 +02:00
Otto Winter
af89e7c50f Move more MQTT platforms to config entries (#16918)
* Move more MQTT platforms to config entries

* Address comments
2018-09-28 16:57:17 +02:00
Paulus Schoutsen
c93879074b Merge pull request #16940 from home-assistant/rc
0.79.0
2018-09-28 16:51:25 +02:00
Paulus Schoutsen
f476d781ec Version bump to 0.79.0 2018-09-28 15:28:24 +02:00
Anders Melchiorsen
720b05c301 Fix race between script delay and turn_off (#16923) 2018-09-27 22:08:09 -06:00
Otto Winter
c9b6567265 Remove discovered mqtt_json light entity when discovery is cleared (#16906)
* Remove discovered mqtt_json entity device when discovery topic is cleared

* Keep imports ordered
2018-09-28 00:25:51 +02:00
Greg Laabs
9abdbf3db6 Rachio component modernization (#16911)
Add `unique_id` to all rachio entities
Add platform discovery to rachio component
Move config options from switch.rachio platform to the rachio component
2018-09-27 23:17:15 +02:00
cdce8p
f879ac0993 Remove service helper (6) (#16920)
* Update automation

* Update group

* Async_create_task
2018-09-27 23:14:09 +02:00
cdce8p
70b901017f Remove service helper (5) (#16917)
* Update switch

* Update script

* Update light

* Fix tests

* Fix config/script hook

* Async_create_task

* Fix flux switch
2018-09-27 23:13:11 +02:00
Paulus Schoutsen
7bfe0e1c00 Bumped version to 0.79.0b3 2018-09-27 23:10:42 +02:00
Paulus Schoutsen
fb39641eef Handle exception handling websocket command (#16927)
* Handle exception handling websocket command

* lint

* Lint2
2018-09-27 23:10:36 +02:00
Paulus Schoutsen
b7e03f6973 Prevent discovered Tradfri while already configured (#16891)
* Prevent discovered Tradfri while already configured

* Lint
2018-09-27 23:10:35 +02:00
Charles Garwood
7597e30efb Add unique_id to Nest Sensors (#16869)
* Add unique_id

* Add device_info

* Fix typo

* Update __init__.py
2018-09-27 23:10:35 +02:00
Paulus Schoutsen
a7248d4574 Handle exception handling websocket command (#16927)
* Handle exception handling websocket command

* lint

* Lint2
2018-09-27 23:10:07 +02:00
Paulus Schoutsen
51dbc988f9 Update translations 2018-09-27 23:08:04 +02:00
Paulus Schoutsen
71333a15f7 Bump frontend to 20180927.0 2018-09-27 23:08:04 +02:00
Paulus Schoutsen
bac71d3d22 Update translations 2018-09-27 23:04:28 +02:00
Paulus Schoutsen
d77e88645e Bump frontend to 20180927.0 2018-09-27 23:04:03 +02:00
Otto Winter
2d104f95d7 Fix MQTT Config Entry Discovery (#16919) 2018-09-27 22:56:04 +02:00
Paulus Schoutsen
81e21b90c9 Fix auth redirect (#16914)
* Fix auth redirect

* Remove old test
2018-09-27 09:02:50 -07:00
Otto Winter
d1ad2cc225 Make MQTT platforms config entries (#16904)
* Make MQTT platforms config entries

* Fix tests

* Address Comment

* Rework tests

* Undo style auto-reformat style changes
2018-09-27 16:07:56 +02:00
zxdavb
8d65230a36 Add (EU-based) Honeywell evohome CH/DHW controller (#16427)
* Add support for Honeywell evohome CH/DHW systems

More flake8 corrections

Passes Flake8 tests

Almost passed flake8.pylint!

Passed all tox tests

Now it needs serious testing!

Almost ready to submit

BUGFIX: DHW state now functional

More improvements to available()

Solved the DHW temp units problem!

Last minute bug squash

to improve dicts merge

Trying to rebase

fixing more rbase errors

revert to creating HTTP_error_code internally for now

ready to submit PR

Added support for Honeywell evohome CH/DHW systems

* Updated requirements_test_all.txt

* Fix: D401 First line should be in imperative mood

* Remove _LOGGER.info (replace with _LOGGER.debug)

* raise PlatformNotReady when RequestException during setup()

* Revert some LOGGER.debug to LOGGER.warning

* Improved logging levels, and removed some unwanted comments

* Improvments to logging - additional self._status info

* BUGFIX: DHW wrongly showing available = False (and some other tweaks)

* Fix trailing whitespace

* Remove state_attributes override and API_VER code

* Removed heating zones, DHW and heuristics to reduce # lines of code

* Removed some more lines of code

* Removed unused configuration parameters

* Remove some more un-needed lines

* Removed more (uneeded) lines of code & fixed two minor typos

* Improvements to debug logging of available() = False

* Improvements to code, and code clean-up

* Corrected a minor typo

* A small tidy up

* reduces precision of emulated temps floats to 0.1

* Some code improvements as suggested by JeardM

* Rewrite of exception handler

* Removed another unwanted logging in properties

* Remove async_ version of various methods

* moved available heuristics to update()

* Cleanup of code, and re-work linter hints

* fixed a minor documentation typo

* scan_interval is now no longer a configurable option

* Change from Master/Slave to Parent/Child

* Removed the last of the slaves

* Removed the last of the masters

* Move -PARALLEL_UPDATES to .\climate\evohome.py'

* main code moved to climate/evohome.py

* merge EvoEntity into EvoController class

* remove should_poll (for now)

* woops! left a hint in

* removed icon

* only log a WARNING the first time available = False

* cleanup dodgy exception handling

* Tidy up exception handling

* Many changes as suggested by @MartinHjelmare, thanks

* remove hass from init, part 1

* use async_added_to_hass instead of dispatcher_connect

* remove hass from init, part 2 (done)

* add 1-2 arrays, and tidied up some comments

* from dispatcher to async_added_to_hass

* cleaned up some logging, and removed others

* Many changes as request by @MartinHjelmare

* Homage to the lint

* Changed to the HA of doing operating_mode

* Now using update_before_add=True

* reduced logging further still...

* fixed minor lint

* fix a small logic error

* Add device_state_attributes to track actual operating mode

* Clean up doc quotes caused by  previous changes

* Woops! removed some debug lines that shoudln't have stayed in

* Add a complete set of device_state_attributes

* Cleanup some constants

* Remove more legacy code

* domain_data to evo_data & this else should be a finally

* minor change for readability

* Minor change for readability #2

* removed unused code

* small tidy up - no code changes

* fix minor lint

* Correct URLs & descriptions in docstring

* whoops - fixed a typo in docstrings

* remove an unused line of cide & a small tidy-up
2018-09-27 13:29:44 +02:00
Blake Blackshear
2cc6263092 Add new services for set/refresh Z-Wave device values (#16638)
* Add services for getting and setting indicator values for Z-Wave

* Add service to manually refresh Z-Wave node value by value_id

* Remove refresh_indicator service

* Coerce to int

* Add generic set_node_value service

* Remove set_indicator service
2018-09-27 12:34:42 +02:00
emontnemery
ad79dc673d MQTT Light - Do not throw if property is missing from templated MQTT message (#16720)
* Do not throw if property is missing

* Render template once, add debug prints
2018-09-27 11:48:52 +02:00
Paulus Schoutsen
da3342f1aa Update new values coming in for dev registry (#16852)
* Update new values coming in for dev registry

* fix Lint+Test;2C
2018-09-27 11:26:58 +02:00
Anders Melchiorsen
29db43edb2 Ignore Xiaomi hub callbacks during setup (#16910) 2018-09-27 09:44:19 +02:00
Anders Melchiorsen
24e9c62fe7 Upgrade pysonos to 0.0.3 (#16901)
This version has downgraded/removed some logging that we then no
longer have to hide.
2018-09-27 01:09:30 +02:00
Anders Melchiorsen
81d4338b93 Upgrade aiolifx_effects to 0.2.0 (#16900) 2018-09-27 01:08:20 +02:00
Jason Hu
96e5acda1a Optimize Ring Sensors platform setup (#16886) 2018-09-26 15:38:13 -07:00
Anders Melchiorsen
726cf9b1c4 Remove unused import (#16909)
* Remove unused import

* Revert test usage
2018-09-27 00:21:29 +02:00
Paulus Schoutsen
631ecf578e Lint 2018-09-26 23:48:55 +02:00
Paulus Schoutsen
273a7af330 Prevent discovered Tradfri while already configured (#16891)
* Prevent discovered Tradfri while already configured

* Lint
2018-09-26 18:03:25 +02:00
cdce8p
4b674b1d16 Remove unused legacy test helper methods (#16893) 2018-09-26 18:03:13 +02:00
cdce8p
dd45e99302 Remove service helper (4) (#16892)
* Update media_player

* Update lock

* Update notify

* Update remote

* Update scene

* Update vacuum

* Remove timer helpers

* Removed unused legacy helpers
2018-09-26 18:02:05 +02:00
Paulus Schoutsen
d0ddc28f96 Revert file mode write_json (#16897) 2018-09-26 17:58:44 +02:00
Paulus Schoutsen
9ab8f78b19 Don't pass use_env=True (#16896) 2018-09-26 17:20:34 +02:00
Paulus Schoutsen
732009c668 Update translations 2018-09-26 15:39:20 +02:00
Paulus Schoutsen
d20e0f5c95 Update frontend to 20180926.0 2018-09-26 15:39:20 +02:00
cgtobi
98a4b1e9ac Update language strings (#16884) 2018-09-26 13:07:43 +02:00
Nikolay Vasilchuk
917df1af00 Telegram_bot polling support proxy_url and proxy_params (Fix #15746) (#16740)
* Telegram bot polling proxy support

* CI fix

* houndci-bot review fix

* houndci-bot review fix

* CI fix

* Review

* Update polling.py
2018-09-26 11:59:37 +02:00
Blake Blackshear
f13f723a04 Add bitwise operations as template helpers (#16833) 2018-09-26 11:57:16 +02:00
Paulus Schoutsen
7b68f344e3 Bumped version to 0.79.0b2 2018-09-26 11:21:22 +02:00
Paulus Schoutsen
824e59499f Make ring sync again (#16866) 2018-09-26 11:21:10 +02:00
Paulus Schoutsen
ff9377d1d9 Fix MQTT discovery (#16864)
* Fix MQTT discovery

* Update __init__.py
2018-09-26 11:21:09 +02:00
Charles Garwood
cf0d0fb33e Device Registry Support for iOS Sensors (#16862)
* Add device_info property to iOS sensors for device registry

* Remove unused logger import

* Fix spacing

* lint

* Lint
2018-09-26 11:21:09 +02:00
Jason Hu
75c372021d Fix example for long-lived access token WS API (#16882) 2018-09-26 11:20:48 +02:00
Paulus Schoutsen
3aaf619fc3 Update translations 2018-09-26 11:20:07 +02:00
Paulus Schoutsen
e375b63902 Update frontend to 20180926.0 2018-09-26 11:20:00 +02:00
Nicko van Someren
e5861241c7 Added support for private storage. (#16878)
* Addded support for private storage.

Include 'private' flag parameters to the Store class and save_json function.
Updated various authentication and onboarding classes to use private stores.
Fixed unit test for emulated_hue which used a mock patch on save_json().

* Fixed Hound formatting issues not detected by local linting.
2018-09-26 10:24:32 +02:00
Paulus Schoutsen
e205092693 Revert incorrect check (#16883) 2018-09-26 10:15:49 +02:00
cdce8p
fa98a27df7 Remove service helper (2) (#16863)
* alarm_control_panel

* automation

* camera

* climate

* counter

* fan

* Add legacy notes

* Fix tests
2018-09-26 09:49:55 +02:00
Paulus Schoutsen
c899875abb Fix MQTT discovery (#16864)
* Fix MQTT discovery

* Update __init__.py
2018-09-26 09:38:50 +02:00
Charles Garwood
bab079f649 Add unique_id to Nest Sensors (#16869)
* Add unique_id

* Add device_info

* Fix typo

* Update __init__.py
2018-09-26 09:19:47 +02:00
Jason Hu
92a5068977 Use HA native OAuth2 flow for google assistant components (#16848)
* Use HA native OAuth2 flow for google assistant components

* Lint

* Force breaking changes

* Fix CONFIG_SCHEMA
2018-09-26 08:57:55 +02:00
Charles Garwood
3cba2e695c Device Registry Support for iOS Sensors (#16862)
* Add device_info property to iOS sensors for device registry

* Remove unused logger import

* Fix spacing

* lint

* Lint
2018-09-26 08:56:23 +02:00
cdce8p
bfa1c55803 Fix fan_init test (#16865)
* Fix fan_init test

* Readd __init__.py
2018-09-26 08:53:24 +02:00
Paulus Schoutsen
ba2b8512c5 Make ring sync again (#16866) 2018-09-26 08:52:22 +02:00
cdce8p
e2a56721d3 Remove service helper (3) (#16879)
* Update duckdns

* Update google_assistant

* Update group

* Update homematic

* Update image_processing

* Update input_boolean

* Update input_number

* Update input_select

* Update input_text
2018-09-26 08:50:05 +02:00
Martin Mois
672fc61bb2 aiohttp.ClientSession gets proxy information from HTTP_PROXY/HTTPS_PROXY (#16874) 2018-09-26 08:43:09 +02:00
Gerard
6490ec87f3 Upgrade to bimmer_connected 0.5.3 (#16877) 2018-09-26 08:24:59 +02:00
Daniel Høyer Iversen
dc102a96a9 Tibber realtime consumption, Tibber pulse (#16870)
* tibber real time data

* Tibber Pulse, realtime consumption

* update lib
2018-09-26 07:49:09 +02:00
cdce8p
b91a061cef Add missing __init__ test files (#16871) 2018-09-25 23:08:37 +02:00
cdce8p
7eaf8640d0 Update cover tests (#16832)
* Update test_group
* Update test_command_line
* Update test_demo
* Update test_mqtt
* Update test_template
* Remove cover service call helpers
2018-09-25 22:32:05 +02:00
Jedmeng
8e311686d0 Add support for Opple light (#16765)
* Add support for Opple light

* Update docstring

* review fix

* review fix

* review fix
2018-09-25 20:49:37 +02:00
Paulus Schoutsen
5a22e7d211 Fail if dirty (#16839)
* Fail if dirty

* Update check_dirty

* Update text

* Fix comment

* Add -e

* Update dirty script
2018-09-25 20:47:51 +02:00
Paulus Schoutsen
7de0e1e39a Add executor job (#16853) 2018-09-25 20:47:22 +02:00
emontnemery
4501bdb4a0 Remove discovered MQTT cover device when discovery topic is cleared (#16857) 2018-09-25 19:32:42 +02:00
emontnemery
4a265f37e0 Remove discovered MQTT fan device when discovery topic is cleared (#16858) 2018-09-25 19:32:31 +02:00
emontnemery
c3f58b8c74 Remove discovered MQTT lock device when discovery topic is cleared (#16859) 2018-09-25 19:32:25 +02:00
emontnemery
422ccc1a28 Remove discovered MQTT sensor device when discovery topic is cleared (#16860) 2018-09-25 19:32:16 +02:00
emontnemery
eb59f2dd3c Move MQTT discovery removal tests to platform test files (#16861) 2018-09-25 19:32:04 +02:00
Paulus Schoutsen
399040de46 Fix files left behind (#16855)
* Light demo test to not write entity registry

* Fix Manual MQTT alarm control panel
2018-09-25 17:19:46 +02:00
emontnemery
0dbfd77402 Remove discovered MQTT climate device when discovery topic is cleared (#16856) 2018-09-25 17:15:39 +02:00
Paulus Schoutsen
61a2d09342 Bumped version to 0.79.0b1 2018-09-25 15:39:42 +02:00
Paulus Schoutsen
345c886dec Add unique ID and device info to Nest camera (#16846)
* Add unique ID and device info to Nest camera

* Remove sw version
2018-09-25 15:39:36 +02:00
Paulus Schoutsen
b9043ef7a7 Allow MQTT discovery (#16842) 2018-09-25 15:39:36 +02:00
Paulus Schoutsen
356040d506 Support old tradfri config format (#16841) 2018-09-25 15:39:35 +02:00
Rohan Kapoor
0431e38aa2 Bump zm-py to 0.0.3 (#16835) 2018-09-25 15:39:34 +02:00
Paulus Schoutsen
4c32ad3b48 Don't warn but info when on dev mode (#16831) 2018-09-25 15:39:33 +02:00
Tommy Jonsson
bc8d323bdd Add image support to hangouts notifications (#16560)
* add image to services.yaml

* add image support

Add image support to hangouts notification.

* fix indents

* fix line length

* Add data schema

forgot schema

* fix linelength

* use is_allowed_path and better file error handling

* elif not else if

* fix logger error

* fixes

* fix travis errors/warnings

* remove trailing whitespace

* fix travis pylint naming

* new async style

* removed unused async_timeout

* change to image_file/url (#3)

* change to image_file/url

* removed whitespace

* forgot to remove unused urlparse import

* image_file/url in service help
2018-09-25 15:04:43 +02:00
Paulus Schoutsen
a1c914dfeb On removal, only unload config entry if loaded (#16844)
* On removal, only unload config entry if loaded

* Fix test
2018-09-25 14:29:13 +02:00
emontnemery
093285f92f Remove discovered MQTT binary_sensor device when discovery topic is cleared (#16826) 2018-09-25 14:25:03 +02:00
Paulus Schoutsen
9ea5afd109 Add unique ID and device info to Nest camera (#16846)
* Add unique ID and device info to Nest camera

* Remove sw version
2018-09-25 13:47:12 +02:00
Daniel Høyer Iversen
01925fdfff change unknown to None in Netatmo public (#16845) 2018-09-25 13:41:29 +02:00
Paulus Schoutsen
7840b1e387 Fix MQTT leaving files behind (#16840) 2018-09-25 12:22:27 +02:00
Paulus Schoutsen
e4898bb05c Allow MQTT discovery (#16842) 2018-09-25 12:22:14 +02:00
Paulus Schoutsen
f4974f58fe Config entry update data (#16843)
* WIP

* Allow updating data of a config entry
2018-09-25 12:21:11 +02:00
Paulus Schoutsen
2b2502c91c Support old tradfri config format (#16841) 2018-09-25 11:57:32 +02:00
Daniel Winks
4a4c07ac1b GitLab-CI sensor integration addition. (#16561)
* Updates to GitLab Sensor

* Updates to GitLab_CI sensor.

* Added GitLab_CI sensor.

* Updated interval to a more appropriate 300 seconds.

* Added GitLab_CI.py to ommitted files.

* Initial refactor to use python-gitlab PyPI module.

* Fixes to dict parsing.

* Updated required packages for GitLab_CI requirements.

* Updates and refactoring to more closely align with Home-Assistant standards.

* Moved import to init, removed unreachable requests exception.

* Removed references to STATE_UNKNOWN and replaced with None

* Removed extra whitespace

* Changed PLATFORM_SCHEMA and renamed add_devices.

Changed PLATFORM_SCHEMA to use SCAN_INTERVAL and add_devices to add_entities

* Added configurable name, changed logger and removed cruft.

* Removed _status to use _state instead, as both held same value.

* Fixed ATTR_BUILD_BRANCH, removed more extraneous cruft.

* Changed required config keys to dict[key] format.

* Removed extraneous CONF_SCAN_INTERVAL as it's already defined.
2018-09-25 11:18:23 +02:00
GP8x
03bce84c32 Add additional Netatmo public data sensors (#16671)
Update deps
2018-09-25 11:14:42 +02:00
Paulus Schoutsen
4f9fc9b39f Don't create entity registry in tests (#16838) 2018-09-25 10:16:30 +02:00
sander76
069b819679 Add unique_id to homematic_cloud (#16828)
* add unique_id

* add docstring and trigger travis
2018-09-25 10:15:03 +02:00
emontnemery
90197b6ec9 Remove discovered MQTT light device when discovery topic is cleared (#16824) 2018-09-25 09:19:04 +02:00
emontnemery
42790d3e97 Remove discovered MQTT alarm_control_panel device when discovery topic is cleared (#16825) 2018-09-25 08:44:14 +02:00
Paulus Schoutsen
e78f4d1b65 Extract lovelace to it's own component (#16816)
* Extract lovelace to it's own component

* Lint

* Update comment

* Lint

* Lint
2018-09-25 08:39:35 +02:00
Rohan Kapoor
354c8f3409 Bump zm-py to 0.0.3 (#16835) 2018-09-25 07:53:35 +02:00
Paulus Schoutsen
579b77ba4c Don't warn but info when on dev mode (#16831) 2018-09-25 07:52:10 +02:00
randellhodges
b52e8525ac Add mode (daily/hourly) to darksky (#16719)
* added daily mode to darksky and wind_bearing, ozone, and visibility

* Removed dew point and pressure until the standard is updated
2018-09-24 18:09:15 +02:00
Paulus Schoutsen
dc75db6376 Bumped version to 0.80.0.dev0 2018-09-24 12:15:47 +02:00
Paulus Schoutsen
7d68ec1110 Merge branch 'dev' into rc 2018-09-24 12:14:43 +02:00
Paulus Schoutsen
c352b6fa59 Version bump to 0.79.0b0 2018-09-24 12:13:52 +02:00
Paulus Schoutsen
0bd94d8b56 Remove unused translation key 2018-09-24 12:02:26 +02:00
Paulus Schoutsen
3e2a9afff0 Another update translations 2018-09-24 12:01:34 +02:00
Paulus Schoutsen
d4b239d1d4 Update translations 2018-09-24 12:01:01 +02:00
Paulus Schoutsen
b2a9e203f2 Update frontend to 20180924.0 2018-09-24 11:58:03 +02:00
Greg Laabs
dc1534c6d1 Fix some unhandled exceptions due to missing null checks (#16812)
Fixed a couple cases that would produce errors when the ISY node status was None or `-inf`.
2018-09-24 11:43:00 +02:00
Robin Clarke
589554ad16 Allow soundtouch to play https content too (#16713) 2018-09-24 11:16:28 +02:00
Ville Skyttä
33d6c99f19 Add Python 3.7 classifier (#16645) 2018-09-24 11:11:24 +02:00
Daniel Høyer Iversen
1f74adae2a Broadlink service name (#16345)
* Broadlink. slugify service name

* style
2018-09-24 11:10:33 +02:00
Jason Hu
7a77951bb4 Add Notify MFA module (#16314)
* Add Notify MFA

* Fix unit test

* Address review comment, change storage implementation

* Add retry limit to mfa module

* Fix loading

* Fix invalaid login log processing

* Typing

* Change default message template

* Change one-time password to 8 digit

* Refactoring to not save secret

* Bug fixing

* Change async_initialize method name to aysnc_initialize_login_mfa_step

* Address some simple fix code review comment
2018-09-24 11:06:50 +02:00
Thomas Lovén
ad47ece5c6 Allow split component definitions in packages (#16177)
* Allow split component definitions in packages

Two different configuration styles are described in
https://www.home-assistant.io/docs/configuration/devices/#style-2-list-each-device-separately

But only one is allowed in packages according to
https://www.home-assistant.io/docs/configuration/packages/

This change allows "Style 2" configuration in packages.

* Added test for split component definition in packages
2018-09-24 10:17:24 +02:00
emontnemery
5ee4718e24 Remove discovered MQTT Switch device when discovery topic is cleared (#16605)
* Remove discovered device when discovery topic is cleared

* Move entity removal away from mqtt discovery

* Move discovery update to mixin class

* Add testcase

* Review comments
2018-09-24 10:11:49 +02:00
Martin Berg
a5cb4e6c2b Use pyspcwebgw for SPC component (#16214)
* Use pyspcwebgw library.

* Support alarm triggering.

* Update requirements.

* Add pyspcwebgw to test reqs.

* Also update script.

* Use dispatcher.

* Address review feedback.
2018-09-24 10:10:10 +02:00
Baptiste Lecocq
4fd2f773ad Add linky sensor (#16468)
* Add linky component

* Update requirements_all.txt

* Add timeout to pylinky requests

* Make linky platform fail fast
2018-09-24 08:09:34 +02:00
Jason Hu
564ad7e22a Rework chromecast fix (#16804)
* Revert changes of #16471, and fix the platform setup issue

* Fix unit test

* Fix

* Fix comment

* Fix test

* Address review comment

* Address review comment
2018-09-23 23:35:07 +02:00
mvn23
329d9dfc06 Improve opentherm_gw state detection (#16809)
Only show the platform in STATE_HEAT when the boiler is actually heating.
2018-09-23 22:16:24 +02:00
Anders Melchiorsen
2258c56d34 Handle netgear_lte connection errors (#16806) 2018-09-23 18:58:09 +02:00
Daniel Shokouhi
e90abf1007 Set botvac state when offline (#16805) 2018-09-23 12:35:18 +02:00
Paul Biester
eaee55175b Add configurable host for bbox routers (#16778)
* Add configurable host for bbox routers

Add configurable host for bbox router running on non-default IP addresses.

* Fix unused import

Fix unused import which also resolves "line too long"

* Fix wrong import order

* Update validation
2018-09-23 10:37:53 +02:00
huangyupeng
539b86e079 Add Tuya cover state (#16709)
* add cover open and close state

* add tuya cover state

* fix pylint

* fix pylint problem
2018-09-23 10:36:33 +02:00
tadly
127395ae8d Upgrade zeroconf to 0.21.3 (#16789) 2018-09-23 09:50:59 +02:00
Greg Laabs
eca1f050cd Bump sucks (Ecovacs) lib to 0.9.3 (#16803)
* Bump sucks (Ecovacs) lib to 0.9.3

Changed code that was in place as a workaround pre-0.9.2. This version bump fixes a few issues.

* Update requirements_all
2018-09-23 09:43:01 +02:00
Rohan Kapoor
0d681b0ba6 Bump zm-py up to 0.0.2 (#16800) 2018-09-23 09:42:11 +02:00
Daniel Shokouhi
94d38a1c6b Bump pybotvac to 0.0.10 (#16799) 2018-09-23 09:41:45 +02:00
Daniel Høyer Iversen
cfd1aec741 Update Tibber lib (#16795) 2018-09-22 18:25:17 +02:00
Daniel Shokouhi
eec6722cf4 Fix return to base logic for neato (#16776) 2018-09-22 11:34:46 +02:00
Paulus Schoutsen
fce275d29c Merge pull request #16787 from home-assistant/rc
0.78.3
2018-09-22 11:20:29 +02:00
Paulus Schoutsen
5eda5f2f7b Bumped version to 0.78.3 2018-09-22 11:18:54 +02:00
edif30
5ab580ab34 Bump gtts-token to 1.1.2 (#16775)
* bump gtts-token to 1.1.2

* bump gtts-token to 1.1.2

* bump gtts-token to 1.1.2
2018-09-22 11:18:47 +02:00
Paulus Schoutsen
5613816476 Fix Windows loop (#16737)
* Fix Windows loop

* Fix windows Ctrl+C

* Move windows restart handler out of setup_and_run_hass
2018-09-22 09:54:37 +02:00
Gerard
e9c7fe184d Upgrade bimmer_connected to 0.5.2 (#16780) 2018-09-22 08:52:57 +02:00
Fabian Affolter
41bb4760f7 Upgrade restrictedpython to 4.0b5 (#16779) 2018-09-21 23:21:00 +02:00
edif30
ee3f17d5c7 Bump gtts-token to 1.1.2 (#16775)
* bump gtts-token to 1.1.2

* bump gtts-token to 1.1.2

* bump gtts-token to 1.1.2
2018-09-21 21:22:27 +02:00
Malte Franken
18d37ff0fd GeoJSON platform (#16610)
* initial version of geojson platform

* unit tests for geo json platform added; smaller bugfixes and code cleanups

* fixing pylint issues

* moved all code accessing the external feed into separate library; refactored platform and tests to work with that new library

* fixing lint

* small refactorings
2018-09-21 21:15:57 +02:00
Robert Svensson
7fe0d8b2f4 deCONZ cover support (#16759)
deCONZ cover platform for Keen vents
2018-09-21 19:59:20 +02:00
Paulus Schoutsen
8b42d0c471 Add confirmation to Cast/Sonos/iOS config entries (#16769)
* Add confirmation to Cast/Sonos/iOS config entries

* Remove redundant code
2018-09-21 16:34:37 +02:00
Giuseppe
213171769d Refactored units and icons for the Dyson sensors (#14550)
* Refactored units and icons for the Dyson sensors

* Adapted unit tests to the new device names and unit of measurements

* Use None as empty unit of measurement

* Unrelated overall improvements following code review

* Adapted tests to new constructors as per previous commit

* Make sure the sensors have their `hass` attribute set in the test environment
2018-09-21 15:55:07 +02:00
Malte Franken
d5813cf167 Make rest sensor and binary sensor more efficient (#14484)
* create binary sensor even if initial update fails

* fixed broken test assertion

* fixed broken test assertion

* avoid fetching resource twice - manually in the setup_platform and then through add_devices

* raising PlatformNotReady instead of creating the sensor if the initial rest call fails; throttling the update to avoid fetching the same resource again immediately after setting up sensor

* rolled back throttling of the rest update call; can still avoid updating the binary sensor's rest resoure twice; fixed tests

* typo
2018-09-21 15:54:50 +02:00
Paulus Schoutsen
3e59ffb33a Add tradfri device info (#16768) 2018-09-21 14:47:52 +02:00
Maciej Bieniek
a0a54dfd5b Add unique_id to mqtt camera (#16569)
* Add unique_id to mqtt camera

* Remove whitespaces

* Add test for unique_id

* Add blank line
2018-09-21 13:09:54 +02:00
cdce8p
3bfe9e757e Add Carbon Monoxide HomeKit Sensor (#16664) 2018-09-21 12:51:02 +02:00
Alexei Chetroi
9fdf123a2f Zha switch schedule update state (#16621)
* switch.zha: Schedule state update.

if turning switch On or Off operation was successful, then schedule
state update

* switch.zha: Update debug logging.
2018-09-21 12:11:23 +02:00
Evan Bruhn
aeaf694552 Add Logi Circle component, camera and sensor platform (#16540)
* Added Logi Circle platform, camera and sensor

* Integrated with Logo Circle API’s feature detection to exclude sensors not supported by device. Added services for recording livestream and taking a snapshot from the livestream.

* Migrated livestream snapshot and recording functionality out of home assistant components and into the logi circle API wrapper. Added services.yaml entries for logi services.

* Added new Logi sensor types, updated to latest version of `logi_circle` and tidy up in preparation for pull request.

- Renamed `logi_set_mode` to `logi_set_config`.
- Live stream recording and snapshot methods now respect whitelisted path configuration.
- Added `streaming_mode` and `speaker_volume` sensors.
- Moved model-specific turn on/off logic to `logi_circle` library.

* Renamed `logi` component domain to `logi_circle`.

* Updates based on PR feedback

* Added timeout of 15s to logi_circle initial setup requests (login and grabbing cameras).
* Added unique ID (uses MAC address for camera platform, MAC address + sensor type for sensor platform).
* Added battery level and battery charging attributes to camera.
* Removed static attributes from device_state_attributes.
* Replaced STATE_UNKNOWN with None, replaced ‘on’ & ‘off’ with STATE_ON and STATE_OFF.
* Removed redundant SCAN_INTERVAL in sensor, removed redundant hass param from async_setup_platform in camera and sensor.
* Style tweaks.

* Replaced `asyncio.wait_for` with `async_timeout` to be consistent with other components.
2018-09-21 12:00:15 +02:00
Rohan Kapoor
3d1c8ee467 Implement support for complex templates in script delays (#16442)
* Implement support for complex templates in script delays

* Swap out dict instead of collections.Mapping
2018-09-21 11:57:01 +02:00
PhracturedBlue
98b92c78c0 Add Call Data Log platform. Mailboxes no longer require media (#16579)
* Add multiple mailbox support

* Fix extraneous debugging

* Add cdr support

* liniting errors

* Mailbox log messages should mostly be debug.  Fix race condition with initializing CDR

* async decorators to async

* Lint fixes

* Typo

* remove unneeded parameter

* Fix variable names

* Fix async calls from worker thread.  Other minor cleanups

* more variable renames
2018-09-21 11:55:12 +02:00
Paulus Schoutsen
2ac16b12c1 Merge pull request #16770 from home-assistant/rc
0.78.2
2018-09-21 11:40:04 +02:00
Paulus Schoutsen
df67093441 Fix faulty color temp crashing google (#16758)
* Fix faulty color temp crashing google

* Rename

* Print warning for incorrect color temp
2018-09-21 10:51:46 +02:00
Anders Melchiorsen
c475a876ce Upgrade pysonos to 0.0.2 (#16761) 2018-09-21 09:21:56 +02:00
Robert Svensson
90c18d1c15 deCONZ add via_hub attribute for device registry (#16760)
* deCONZ add via_hub attribute for device registry

* A shorter way to get bridgeid
2018-09-21 09:21:44 +02:00
Anders Melchiorsen
78b6439ee6 Use pysonos for Sonos media player (#16753) 2018-09-20 23:50:11 +02:00
Paulus Schoutsen
092c146eae Add option to disable specific integrations (#16757)
* Add option to disable specific integrations

* Lint
2018-09-20 23:46:51 +02:00
Paulus Schoutsen
44a98fb77a Bumped version to 0.78.2 2018-09-20 20:26:25 +02:00
Fabian Affolter
03d93bea34 Upgrade zeroconf to 0.21.2 (#16730) 2018-09-20 20:25:39 +02:00
Fabian Affolter
9dbac9b033 Upgrade zeroconf to 0.21.1 (#16687) 2018-09-20 20:25:38 +02:00
tadly
9e86f0498b Upgrade zeroconf to 0.21.0 (#16647) 2018-09-20 20:25:38 +02:00
Zoé Bőle
03de658d4d Changed save_on_change to default to False (#16744) 2018-09-20 20:24:01 +02:00
Alexei Chetroi
3ea8c25e1f light.zha: Catch exceptions for all commands. (#16752)
Catch exceptions for all operations which may fail because of device
reachibility
More verbose debug logging on operations
2018-09-20 20:23:09 +02:00
Steven Looman
6e01ea5929 Preserve compatibility with original upnp 2018-09-20 18:15:04 +02:00
Pascal Vizeli
c6ccbed828 Small cleanup for slack (#16743) 2018-09-20 15:14:43 +02:00
Paulus Schoutsen
e58836f99f Add subscription info endpoint (#16727)
* Add subscription info endpoint

* Lint

* Lint

* Make decorator

* Lint
2018-09-20 14:53:13 +02:00
Paulus Schoutsen
874225dd67 Merge branch 'master' into dev 2018-09-20 13:57:35 +02:00
Paulus Schoutsen
0d0d5c8c2c Merge pull request #16742 from home-assistant/rc
0.78.1
2018-09-20 13:55:09 +02:00
Paulus Schoutsen
fc6cc22b6d Bump frontend to 20180920.0 2018-09-20 13:09:43 +02:00
Fabian Affolter
39ea9a8c90 Upgrade shodan to 1.10.2 (#16736) 2018-09-20 11:34:37 +02:00
Paulus Schoutsen
c7d5f7698e Bumped version to 0.78.1 2018-09-20 11:32:26 +02:00
Jason Hu
9bbd61cbe4 Upgrade netdisco to 2.1.0 (#16735) 2018-09-20 11:32:16 +02:00
Jason Hu
7a7a164cb8 Handle chromecast CONNECTION_STATUS_DISCONNECTED event (#16732) 2018-09-20 11:32:15 +02:00
Andreas Oberritter
8379567636 SnmpSensor: Fix async_update (#16679) (#16716)
Bugfix provided by awarecan.
2018-09-20 11:32:14 +02:00
Daniel Høyer Iversen
93af3c57ff Avoid calling yr update every second for a minute ones every hour (#16731)
* Avoid calling yr update every second for a minute one every hour

* style
2018-09-20 11:31:05 +02:00
Jason Hu
d1acb0326c Upgrade netdisco to 2.1.0 (#16735) 2018-09-20 11:11:39 +02:00
Fabian Affolter
35005474f8 Upgrade keyring to 15.1.0 (#16734) 2018-09-20 11:11:08 +02:00
Jason Hu
3a45481b5b Handle chromecast CONNECTION_STATUS_DISCONNECTED event (#16732) 2018-09-20 10:48:45 +02:00
Daniel Høyer Iversen
aa7635398a Met.no weather platform (#16582)
* Add met.no weather component

* requirements .coveragerx

* use lib

* style

* style

* renam function to _fetch_data

* Only update once per hour

* style
2018-09-20 10:32:14 +02:00
Fabian Affolter
d3658c4af9 Upgrade zeroconf to 0.21.2 (#16730) 2018-09-20 09:38:35 +02:00
Fabian Affolter
dfe38b4d5a Upgrade youtube_dl to 2018.09.18 (#16729) 2018-09-20 09:37:44 +02:00
Vikram Gorla
fcb84d951e On-demand update of swiss public transport sensor (#16723)
* Sensor values to be updated only when required (only after the train has crossed).
Looking at the documentation on https://transport.opendata.ch/docs.html, delay information is available only on stationboard, so no need to query often if there is no "real"time info.

* Bumping up version of python_opendata_transport to 0.1.4 in order to catch client errors like throttling rejection (HTTP 429)

* pleasing the hound

* bumping python_opendata_transport to 0.1.4
2018-09-20 08:45:16 +02:00
Nikolay Kasyanov
27eede724c Add unique_id to mqtt_json light (#16721)
Applies changes from #16303 to mqtt_json component.
Fixes #16600.
2018-09-20 08:15:17 +02:00
kunago
258beb9cd3 Upgrading librouteros version (#16718) 2018-09-20 07:52:06 +02:00
Charles Garwood
da882672bd Save disabled_by in entity registry (#16699)
* Save disabled_by in entity registry

* Add trailing comma
2018-09-20 00:52:10 +02:00
geekofweek
60dfd68083 MyQ Open State Fix (#16681)
* MyQ Open State Fix

Fixes issues with MyQ reporting an open state

* Update myq.py

* MyQ STATE_OPEN Fix

remove un-needed code
2018-09-19 22:03:47 +02:00
Andreas Oberritter
6e4a6cc069 SnmpSensor: Fix async_update (#16679) (#16716)
Bugfix provided by awarecan.
2018-09-19 22:01:54 +02:00
Paulus Schoutsen
a1c524d372 Config flow tradfri (#16665)
* Fix comments

* Add config flow tests

* Fix Tradfri light tests

* Lint

* Remove import group from config flow

* fix stale comments
2018-09-19 21:21:43 +02:00
Ville Skyttä
3160fa5de8 Make pylint report non-LF linefeeds per the style guidelines (#16601) 2018-09-19 15:51:57 +02:00
Ville Skyttä
d4b7057a3d Use posargs in tox lint env (#16646)
Allows linting specified files or dirs only.
2018-09-19 15:48:04 +02:00
Ville Skyttä
227a1b919b More isort preparations (#16633)
* Adjust config closer to currently established style conventions

* Adjust some imports for better outcome with their comments
2018-09-19 15:40:36 +02:00
Matthias Urlichs
0121e3cb04 Remove usage of "run_until_complete" (#16617)
* De-run_forever()-ization

* Use asyncio.run (or our own implementation on Python <3.7)
* hass.start is only used by tests
* setup_and_run_hass() is now async
* Add "main" async hass.run method
* move SIGINT handling to helpers/signal.py
  * add flag to .run to disable hass's signal handlers
* Teach async_start and async_stop to not step on each other
  (more than necessary)

* shorten over-long lines

* restore missing "import asyncio"

* move run_asyncio to homeassistant.util.async_

* LOGGER: warn => warning

* Add "force" flag to async_stop

only useful for testing

* Add 'attrs==18.2.0' to requirements_all.txt

Required for keeping requirements_test_all.txt in sync, where it is in
turn required to prevent auto-downgrading "attrs" during "pip install"

* Fixes for mypy

* Fix "mock_signal" fixture

* Revert mistaken edit

* Flake8 fixes

* mypy fixes

* pylint fix

* Revert adding attrs== to requirements_test*.txt

solved by using "pip -c"

* Rename "run" to "async_run", as per calling conventions
2018-09-19 15:40:02 +02:00
Paulus Schoutsen
da108f1999 bump frontend to 20180919.0 2018-09-19 15:17:05 +02:00
Pascal Vizeli
d376049a3f Use one regex for Hass.io URL check (#16710) 2018-09-19 12:57:55 +02:00
Ville Skyttä
7f462ba0ec Upgrade mypy to 0.630 (#16674) 2018-09-19 08:58:58 +02:00
Fabien Piuzzi
b7ef4dddb4 Netdata configuration change: Allows multiple elements per group (#16656)
Allows multiple Netdata elements per group
2018-09-19 00:42:09 +02:00
Steven Looman
b72499a949 Fixes after rename 2018-09-18 20:22:33 +02:00
Steven Looman
b770acd9a7 Update requirements_all.txt 2018-09-18 20:21:52 +02:00
Adam Dullage
56b0d2e99f Added support for Starling Bank (#16522)
* Added support for Starling Bank

* Fixing Lint Issues

* Resolving Change Requests

* HTTP Error Handling & Sandbox URL Option

* Update starlingbank Requirement to v1.2

* Minor changes
2018-09-18 15:55:10 +02:00
Maikel Punie
8e7f783da8 Added velbus counter sensors, updated to py-velbus 2.0.20 (#16683) 2018-09-18 15:51:22 +02:00
Fabian Affolter
1913d07c39 Upgrade zeroconf to 0.21.1 (#16687) 2018-09-18 15:49:54 +02:00
Glenn Waters
2a85ed7236 Streamline log messages (#16243) 2018-09-18 15:06:52 +02:00
Fabian Affolter
cba3a5b055 Upgrade paho-mqtt to 1.4.0 (#16688) 2018-09-18 14:59:39 +02:00
Fabian Affolter
d2246d5a4f Fix test 2018-09-18 12:15:55 +02:00
Greg Laabs
72419a1afe Fix Ecovacs vacuums showing "None" for name (#16654)
Was previously checking for a missing key, when should have been checking for the value being None
2018-09-18 08:30:20 +02:00
Fabian Affolter
a7325ebe1f Suppress traceback and log error (#16669) 2018-09-18 07:55:13 +02:00
Aaron Bach
27d50d388f Fixes an AirVisual bug where response data is missing (#16673) 2018-09-17 14:44:18 -06:00
Tsvi Mostovicz
25712f16b3 Jewish calendar sensor (#16393)
* Initial commit for  jewish calendar sensor

* Make check for logging errors into it's own function

* Can't use f-strings as we need to support python3.5

* Implement basic functionality: printing of date

* Update requirements_all.txt

* Allow user to specify date for sensor

* Add hdate to test requirements

* Update to match pull request

* Support date output in hebrew

* Limit languages to english and hebrew

* Add name back to sensor

* Change icon to be calendar-today

* Add multiple sensors

* Fix tests

* Make Hound happy, remove unused imported class

* hdate expects datetime.date not datetime.datetime

* Return sensor name

* Times should be returned as time object, not datetime

* Add myself to codeowners for jewish calendar component

* Return actual reading, not index

* Add more tests. Currently failing.

Will need to update hdate API and version before continuing.

* Fix weekly portion test

* Make all tests pass

* Make travis happy and add a test so it doesnt happen again

* Remove defaults in __init__ method

* Change sensor state variable to local variable in update() method

* Minor changes
2018-09-17 22:43:31 +02:00
Steven Looman
5cb0c92e78 Fix discovery/config entry handlers 2018-09-17 22:25:32 +02:00
Steven Looman
a7a16e4317 Fix tracebacks 2018-09-17 22:15:44 +02:00
Steven Looman
c19665fed4 Rename igd to upnp 2018-09-17 22:10:18 +02:00
Steven Looman
6588dceadd Fix uppercase
Fix translation
2018-09-17 22:09:51 +02:00
Paulus Schoutsen
9e59fc5d05 Merge pull request #16666 from home-assistant/rc
0.78.0
2018-09-17 19:03:37 +02:00
Paulus Schoutsen
366e270e94 Bump frontend to 20180916.0 2018-09-17 18:33:41 +02:00
Paulus Schoutsen
4b30cbbf3b Update translations 2018-09-17 14:18:20 +02:00
Paulus Schoutsen
41ac2a3c73 Bump frontend to 20180917.0 2018-09-17 14:18:04 +02:00
Paulus Schoutsen
b8257866f5 Clean up device update, add via-hub (#16659)
* Clean up device update, add via-hub

* Test loading/saving data

* Lint

* Add to Hue"

* Lint + tests
2018-09-17 13:39:30 +02:00
Paulus Schoutsen
849a93e0a6 Update translations 2018-09-17 10:48:22 +02:00
Paulus Schoutsen
f918d62571 version bump to 0.78.0 2018-09-17 10:48:09 +02:00
damarco
1c251009fe Add zha device entity (#14579)
* Add endpoint entity

* Fix lint error

* Add nwk address as device state attribute

* Change to ZhaDeviceEntity

* Show last_seen only if offline

* Remove obsolete _discover_endpoint_info()
2018-09-17 10:42:21 +02:00
Paulus Schoutsen
201fd4afee Add config entries to connection class (#16618) 2018-09-17 10:12:46 +02:00
Anders Melchiorsen
3e0c6c176a Rework timer delays (#16650)
* Calibrate timer for each tick

* Return of timer out of sync detection
2018-09-17 10:10:50 +02:00
Alexei Chetroi
44fdfdf695 Log raw result of configure_reporting() command. (#16655) 2018-09-17 07:45:44 +02:00
Fabian Affolter
fea1c921fc Fix link to docs (#16652) 2018-09-17 07:45:01 +02:00
Fabian Affolter
5e3e441aa0 Upgrade holidays to 0.9.7 (#16651) 2018-09-17 07:44:23 +02:00
Daniel Perna
a1e6e04a5e Update pyhomematic to 0.1.49 (#16649) 2018-09-16 22:56:01 +02:00
tadly
2002497d09 Upgrade zeroconf to 0.21.0 (#16647) 2018-09-16 22:53:25 +02:00
Daniel Høyer Iversen
baeb791d84 Upgrade Switchmate lib (#16637)
* new version switchmate lib, fix bug, and enable more logging in lib

* new version switchmate lib, fix bug, and enable more logging in lib
2018-09-16 13:58:26 +02:00
Abílio Costa
9c9df793b4 New EDP re:dy component (#16426)
* add new EDP re:dy platform

* lint

* move api code to pypi module; fix lint

* fix lint; remove unused import

* pass aiohttp client session and hass loop to platform

* update requirements_all.txt

* fix docstring lint

* normalize quotes

* use async setup_platform

* improve entities update mechanism

* doc lint

* send update topic only after loading platforms

* lint whitespaces

* mute used-before-assignment pylint false error
2018-09-16 01:17:47 +02:00
Mattias Welponer
05922ac56a Add new devices to HomematicIP Cloud (#16636)
* Add support for outdoor temperature sensor and cleanup

* Add support for rotary handle and water sensor

* Fix comment
2018-09-15 21:28:49 +02:00
Jason Hu
34deaf8849 Add valid_window=1 to TOTP verify (#16625) 2018-09-15 13:28:25 +02:00
Ville Skyttä
cc38981a38 Update developer doc links to developers.home-assistant.io (#16622) 2018-09-15 13:27:37 +02:00
Paulus Schoutsen
18ce5092b4 Bumped version to 0.78.0b3 2018-09-15 12:46:02 +02:00
Paulus Schoutsen
7f7372198a Update translations 2018-09-15 12:45:54 +02:00
Pascal Vizeli
abe61c5529 Rewrite bluetooth le (#16592)
* Rewrite bluetooth le

* Update requirements_all.txt

* Update gen_requirements_all.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py
2018-09-15 12:45:23 +02:00
Jason Hu
b231fa2616 Fix broken bluetooth tracker (#16589) 2018-09-15 12:45:23 +02:00
Jason Hu
336289d7e7 Add retry limit for chromecast connection (#16471) 2018-09-15 12:45:22 +02:00
Rohan Kapoor
19514ea500 Clean up MjpegCamera by removing unnused hass object in __init__ (#16628) 2018-09-15 11:26:29 +02:00
Sören Oldag
00918af94d Upgrade pwmled to 1.3.0 (#16624) 2018-09-15 10:08:52 +02:00
Ville Skyttä
e054e4da1b Small huawei_lte improvements (#16626)
* Add bunch of RouterData tests

* Avoid raising AttributeError from RouterData.__getitem__

* Use new style string formatting

* Use {key: value} instead of dict(key=value)
2018-09-15 10:42:36 +03:00
Rohan Kapoor
0c945d81c8 Add @rohankapoorcom to CODEOWNERS for the zoneminder platform (#16627) 2018-09-15 09:25:21 +02:00
Rohan Kapoor
1ca09ea36f Extracting zoneminder to a new library (#16527)
* Migrating out the zoneminder platform (and camera.zoneminder) to a new library

* Clean up the global variable ZM usage

* Modify camera.zoneminder to use the new Monitor class implementation

* Refactor camera.zoneminder after latest refactor in zm-py

* Implementing changes to switch.zoneminder to use zm-py native methods

* Complete migrating over sensor.zoneminder to the zm-py library

* Tweaking ZoneMinder components from code review

* Linting fixes for the zoneminder components

* Directly assign value when turning on/off in switch.zoneminder
2018-09-15 08:44:48 +02:00
Nate Clark
8ce2d701c2 fix bug where momentary switch with activation low does not reset (#16603) 2018-09-14 13:31:41 -06:00
christopheBfr
9c1a539f90 Adding support for RTDSContactSensor and RTDSMotionSensor in Tahoma … (RTS Alarms sensors and contacts for Somfy Protexiom alarms) (#16609)
* Adding support for RTDSContactSensor and RTDSContactSensor in Tahoma component

* Removing extra blank lines
2018-09-14 13:31:08 -06:00
Steven Looman
ca7911ec47 Set ports (hass -> hass) when no ports have been specified 2018-09-14 21:30:08 +02:00
Alexei Chetroi
0d0bda9658 Switch components.sensor.zha to await syntax. (#16619) 2018-09-14 13:29:10 -06:00
Pascal Vizeli
7705666061 Rewrite bluetooth le (#16592)
* Rewrite bluetooth le

* Update requirements_all.txt

* Update gen_requirements_all.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py

* Update bluetooth_le_tracker.py
2018-09-14 13:49:20 +02:00
Anders Melchiorsen
e82e75baf3 Improve precision of timer ticks (#16598) 2018-09-14 12:28:09 +02:00
Fabian Affolter
481f6e09fa Upgrade python-twitch-client to 0.6.0 (#16602) 2018-09-14 12:08:33 +02:00
Paulus Schoutsen
72e746d240 MQTT config entry (#16594)
* MQTT config entry

* Solely rely on config entry

* Improve wawrning

* Lint

* Lint2
2018-09-14 11:57:31 +02:00
Paulus Schoutsen
05c0717167 Add websocket list APIs for the registries (#16597)
* Add websocket list APIs for the registries

* Remove identifiers

* Fix tests

* Use ordered dict
2018-09-14 11:57:18 +02:00
Ville Skyttä
67b5b5bc85 Add myself to CODEOWNERS for upcloud (#16599) 2018-09-14 08:42:23 +02:00
Harvtronix
d076251b18 Changing z-wave brightness calculation to respect 0x01 and 0x02 byte values (#16420)
* Changing z-wave brightness calculation to respect 0x01 and 0x02 byte
values

* adding additional line breaks to satisfy houndci

* - Update comment style for linter
- Add additional unit test to increase code coverage

* Update zwave.py
2018-09-13 10:38:07 -04:00
Ville Skyttä
e59ba28fe6 Add Huawei LTE router platform, device tracker, and sensor (#16498)
* Add Huawei LTE router platform, device tracker, and sensor

* Add myself to CODEOWNERS for huawei_lte
2018-09-13 10:01:28 +02:00
Sergiy Maysak
f63dba5521 Multiple tag managers for Wireless Sensor Tags. (#16353)
* Added support for multiple tag managers. Fixed typo for signal strength.

* Corrected broken merge.

* Fixed flake8/pylint error.

* Improved docstring.
2018-09-13 09:48:17 +02:00
William Scanlon
f43d9ba680 Support for the Quirky Nimbus (#16520)
* Support for quriky nimbu

* Fixed lint

* fixed some typos
2018-09-13 09:35:40 +02:00
Daniel Høyer Iversen
aec134c47a xiaomi lib 0.10.0 (#16591) 2018-09-13 09:26:46 +02:00
Daniel Høyer Iversen
901dd9acca Update tibber lib version (#16590) 2018-09-13 09:23:33 +02:00
Alexei Chetroi
7a52bbdf24 Allow only_cache parameter in zha.safe_read() (#16553)
* Allow only_cache parameter in zha.safe_read()

* Use cache_only for binary_sensor.zha initial update.

* Use cache_only for fan.zha initial update.

* Use cache_only for sensor.zha initial update.

* Use cache_only for switch.zha initial update.

* Use cache_only for light.zha initial update.

* Refactor cached only read in zha platform.
2018-09-13 09:22:50 +02:00
Alexei Chetroi
f2203e52ef Add configure_reporting() method to zha component (#16487)
* Add zha.configure_reporting() method.

Binds a cluster and configures reporting for the specified attribute.

* git add homeassistant/components/binary_sensor/zha.py

* Refactor sensor.zha to use new 'configure_reporting() method.

* Zha configure reporting - switch (#1)

* use configure_reporting for zha switch

* lint fixes

* Rename variables/classes to properly reflect the content
2018-09-13 09:11:47 +02:00
Jason Hu
1586d3000c Fix broken bluetooth tracker (#16589) 2018-09-13 07:52:31 +02:00
Daniel Perna
d0aeb90c22 Update pyhomematic to 0.1.48 (#16588) 2018-09-13 01:04:15 +02:00
Daniel Høyer Iversen
cb542a90eb Switchmate (#16395)
* Switchmate

* switchmate

* swithcmate

* switchmate

* switchmate

* switchmate

* Make switchmate a bit more robust

* style

* style

* style

* Use external lib for switchmate

* add_entities

* Update requirements_all.txt

* unnecessary string format
2018-09-12 21:10:04 +02:00
Paulus Schoutsen
3824582e68 Add config entry to iOS (#16580)
* Add config entry to iOS

* Add translation
2018-09-12 20:17:52 +02:00
Nate Clark
2682d26f79 Konnected component feature updates (#16479)
* add  config option to invert state of binary_sensor

* Add API endpoint to get state of a Konnected switch
2018-09-12 13:54:38 +02:00
Jason Hu
308b7fb385 Add retry limit for chromecast connection (#16471) 2018-09-12 13:42:54 +02:00
Paulus Schoutsen
a88cda44d9 Bumped version to 0.78.0b2 2018-09-12 13:30:14 +02:00
Zoé Bőle
08100a485a Increasing python-websockets' version number (#16578)
* increasing python-websockets' version number so now it works with python 3.7

* required version for websockets increased to work with Python 3.7

* script/gen_requirements_all.py is done
2018-09-12 13:30:04 +02:00
Jason Hu
4c1b816bb8 Track refresh token last usage information (#16408)
* Extend refresh_token to support last_used_at and last_used_by

* Address code review comment

* Remove unused code

* Add it to websocket response

* Fix typing
2018-09-12 13:30:04 +02:00
Jason Hu
1983361373 Return if refresh token is current used one in WS API (#16575) 2018-09-12 13:29:38 +02:00
Marcel Hoppe
4efe86327d Hangouts help "page" and little bugfix (#16464)
* add 'default_conversations' parameter

* remove the empty message segment at the end of every message

* add 'HangoutsHelp' intent

* add hangouts/intents.py
2018-09-12 13:27:21 +02:00
Jason Hu
ff78a5b04b Track refresh token last usage information (#16408)
* Extend refresh_token to support last_used_at and last_used_by

* Address code review comment

* Remove unused code

* Add it to websocket response

* Fix typing
2018-09-12 13:24:16 +02:00
Paulus Schoutsen
68c21530ca Update frontend to 20180912.0 2018-09-12 13:24:02 +02:00
Paulus Schoutsen
453cbb7c60 Update frontend to 20180912.0 2018-09-12 13:23:50 +02:00
Zoé Bőle
77026a2242 Increasing python-websockets' version number (#16578)
* increasing python-websockets' version number so now it works with python 3.7

* required version for websockets increased to work with Python 3.7

* script/gen_requirements_all.py is done
2018-09-12 12:44:14 +02:00
Alexei Chetroi
501f2b0a93 Update fan.zha platform. (#16551)
* Update fan.zha platform.

switch from asyncio to async def()
catch DeliveryError exceptions
keep previous state, if reading 'fan_mode' attribute fails

* fan.zha: Use None for unknown state.

if we fail to read 'fan_mode' attribute, use None for state
2018-09-12 12:43:06 +02:00
Alexei Chetroi
117ea9e553 Refactor zha/async_device_initialized(). (#16485)
Leverage endpoint.model and endpoint.manufacturer properties
2018-09-12 11:39:23 +02:00
Ville Skyttä
beed82ab12 Upgrade pytest to 3.8.0 and pytest-timeout to 1.3.2 (#16489) 2018-09-12 11:33:26 +02:00
Daniel Perna
601f2df5a7 Notifications for Android TV: Add fontsize and sending images (#16565)
* Add fontsize and image functionality

* woof
2018-09-12 11:22:21 +02:00
Jason Hu
34d369ba26 Return if refresh token is current used one in WS API (#16575) 2018-09-12 09:49:44 +02:00
Daniel Høyer Iversen
e2465da7c2 yr: use async syntax (#16563) 2018-09-12 04:52:01 +02:00
William Scanlon
6bd120ff1d Bump pyeconet (#16571)
* Updated pyeconet to the newest version to deal with econet API change
2018-09-11 21:45:51 -04:00
Aaron Bach
188f5de5ae Fixes an OpenUV bug with the scan interval (#16570) 2018-09-11 17:13:16 -06:00
Paulus Schoutsen
6d33fb2dc8 Bumped version to 0.78.0b1 2018-09-11 21:45:42 +02:00
Paulus Schoutsen
e50fc69c1e Add websocket commands for refresh tokens (#16559)
* Add websocket commands for refresh tokens

* Comment
2018-09-11 21:45:33 +02:00
Paulus Schoutsen
20f06f4eb9 Fix invalid state (#16558)
* Fix invalid state

* Make slightly more efficient in unsubscribing

* Use uuid4"
2018-09-11 21:45:32 +02:00
Paulus Schoutsen
37c8aac76f Fix typo (#16556) 2018-09-11 21:45:32 +02:00
Jason Hu
20e562b816 Long-lived access token (#16453)
* Allow create refresh_token with specific access_token_expiration

* Add token_type, client_name and client_icon

* Add unit test

* Add websocket API to create long-lived access token

* Allow URL use as client_id for long-lived access token

* Remove mutate_refresh_token method

* Use client name as id for long_lived_access_token type refresh token

* Minor change

* Do not allow duplicate client name

* Update docstring

* Remove unnecessary `list`
2018-09-11 21:45:31 +02:00
Zellux Wang
a4cec0b871 Fix arlo intilization when no base station available (#16529)
* Fix arlo intilization when no base station

* Fix pylint for empty camera check

* Fix typo

* Minor change to trigger CI again
2018-09-11 21:44:32 +02:00
vikramgorla
60b45d4ba5 bugfix - incorrect camera type and missing sensors when multiple netatmo cameras (#16490)
fixed get_camera_type as it was originally not consuming any input, was looping with all cameras and the first camera type was retutned, modified to call cameraType using provided camera name.
2018-09-11 21:44:31 +02:00
Tom Harris
1ea8c1ece3 Fix insteon Hub v1 support (#16472)
* Fix support for Hub version 1 (i.e. pre-2014 Hub model 2242)

* Bump insteonplm to 0.14.1

* Code review changes

* Clean up and better document set_default_port

* Simplify set_default_port based on code review

* Remove Callable type import

* Simplify port setup
2018-09-11 21:44:31 +02:00
Paulus Schoutsen
44d210698e Fail fetch auth providers if onboarding required (#16454) 2018-09-11 21:44:30 +02:00
Diogo Gomes
968809c991 Replace api_password in Camera.Push (#16339)
* Use access_token and user provided token instead of api_password

* address comments by @awarecan

* new tests

* add extra checks and test

* lint

* add comment
2018-09-11 21:44:30 +02:00
Paulus Schoutsen
06af76404f Fix invalid state (#16558)
* Fix invalid state

* Make slightly more efficient in unsubscribing

* Use uuid4"
2018-09-11 21:40:35 +02:00
Paulus Schoutsen
b9b8bc678c Update frontend to 20180911.0 2018-09-11 21:37:49 +02:00
Paulus Schoutsen
629c4a0bf5 Update frontend to 20180911.0 2018-09-11 21:37:38 +02:00
Paulus Schoutsen
00d8907c5e Update translations 2018-09-11 21:37:05 +02:00
Paulus Schoutsen
3f06b4eb9b Update translations 2018-09-11 21:36:54 +02:00
Paulus Schoutsen
0db13a99aa Add websocket commands for refresh tokens (#16559)
* Add websocket commands for refresh tokens

* Comment
2018-09-11 09:08:03 -07:00
Paulus Schoutsen
4e3faf6108 Fix typo (#16556) 2018-09-11 12:55:05 +02:00
Jason Hu
9583947012 Long-lived access token (#16453)
* Allow create refresh_token with specific access_token_expiration

* Add token_type, client_name and client_icon

* Add unit test

* Add websocket API to create long-lived access token

* Allow URL use as client_id for long-lived access token

* Remove mutate_refresh_token method

* Use client name as id for long_lived_access_token type refresh token

* Minor change

* Do not allow duplicate client name

* Update docstring

* Remove unnecessary `list`
2018-09-11 12:05:15 +02:00
Jerad Meisner
50fb59477a Store notifications in component. Add ws endpoint for fetching. (#16503)
* Store notifications in component. Add ws endpoint for fetching.

* Comments
2018-09-11 11:39:30 +02:00
Diogo Gomes
20f6cb7cc7 Replace api_password in Camera.Push (#16339)
* Use access_token and user provided token instead of api_password

* address comments by @awarecan

* new tests

* add extra checks and test

* lint

* add comment
2018-09-11 11:30:20 +02:00
Zellux Wang
6b08e6e769 Fix arlo intilization when no base station available (#16529)
* Fix arlo intilization when no base station

* Fix pylint for empty camera check

* Fix typo

* Minor change to trigger CI again
2018-09-11 11:25:38 +02:00
Ville Skyttä
ee696643cd Isort preparations (#16555)
* Don't treat typing as an "in-between" module for import order

That was a < 3.5 era thing.

* Tighten scope of some pylint unused-import disables

To avoid isort moving a top level one around, undesirably broadening its
scope.
2018-09-11 11:21:48 +02:00
cgtobi
a059cc860a Update PyRMVtransport version (#16547)
* Update PyRMVtransport version

* Update requirements.
2018-09-11 05:55:02 +02:00
Paulus Schoutsen
cfe5db4350 Fail fetch auth providers if onboarding required (#16454) 2018-09-10 23:51:40 +02:00
Tom Harris
dcd7b9a529 Fix insteon Hub v1 support (#16472)
* Fix support for Hub version 1 (i.e. pre-2014 Hub model 2242)

* Bump insteonplm to 0.14.1

* Code review changes

* Clean up and better document set_default_port

* Simplify set_default_port based on code review

* Remove Callable type import

* Simplify port setup
2018-09-10 16:54:17 +02:00
mrosseel
f858938ada Make the Qnap sensor more resilient if server is not reachable (#16445)
* add CONF_ALLOW_UNREACHABLE option, retry connection if allowed

* fix linting errors

* Removing the config option, just using PlatformNotReady
2018-09-10 16:19:17 +02:00
vikramgorla
e96635b5c1 bugfix - incorrect camera type and missing sensors when multiple netatmo cameras (#16490)
fixed get_camera_type as it was originally not consuming any input, was looping with all cameras and the first camera type was retutned, modified to call cameraType using provided camera name.
2018-09-10 16:13:05 +02:00
Fabian Affolter
d2d715faa8 Upgrade wakeonlan to 1.1.6 (#16512) 2018-09-10 16:07:31 +02:00
Franck Nijhof
7a5e828f6b Updates documentation repo URL in PR template (#16537) 2018-09-10 14:28:21 +02:00
Paulus Schoutsen
99f7b7f42d Version bump to 0.79.0dev0 2018-09-10 13:46:07 +02:00
Paulus Schoutsen
3f97944f6b Bumped version to 0.78.0b0 2018-09-10 13:44:56 +02:00
Paulus Schoutsen
1d6609e386 Update translations 2018-09-10 13:44:27 +02:00
Paulus Schoutsen
fb15dbf3ba Bump frontend to 20180910.0 2018-09-10 13:44:11 +02:00
Fabian Affolter
c20f147949 Upgrade keyring to 15.0.0 (#16536) 2018-09-10 13:35:47 +02:00
Fabian Affolter
8ed4d732ac Upgrade youtube_dl to 2018.09.10 (#16534) 2018-09-10 13:35:24 +02:00
Louis-Dominique Dubeau
a1578e3c6e Add a base_url configuration setting to tts. (#16478)
* Add a base_url configuration setting to tts.

* Remove the empty string as default value for base_urls

As requested in

https://github.com/home-assistant/home-assistant/pull/16478#pullrequestreview-153526144
2018-09-10 11:50:25 +02:00
Jason Hu
253e787a1b Upgrade aiohttp to 3.4.4 (#16486) 2018-09-10 10:39:51 +02:00
Fabian Affolter
0d7ee9b93b Order imports (#16515) 2018-09-09 14:26:06 +02:00
tadly
d6d4ff6888 adds listener for OnAVStart and OnAVChange (#16495)
With Kodi 18, OnPlay is called before an item actually started playing.
For this OnAVStart and OnAVChange have been introduced.
2018-09-09 09:55:57 +02:00
Jason Hu
4291bdc6b2 Move voluptuous-serialize to core requirement (#16507) 2018-09-09 09:49:51 +02:00
Anders Melchiorsen
7d590a6b93 Update pyHS100 to 0.3.3 (#16502) 2018-09-09 00:34:22 +02:00
Ville Skyttä
e3e3ed42ec Fix Netgear LTESensor docstring (#16501) 2018-09-08 23:22:41 +02:00
Paulus Schoutsen
e7b8d2e6df Update name legacy api password (#16455) 2018-09-08 22:10:42 +02:00
Fabian Affolter
9944c60311 Check if API key is valid and users available (#16494) 2018-09-08 18:33:41 +02:00
Varga Tamas
93143384a8 Restore status attribute for xiaomi_vacuum (#16366)
* Added new states and exposed state/state code received from xiaomi vacuum

* Restore status attribute for xiaomi_vacuum
2018-09-08 18:13:24 +02:00
Florian Werner
8a2bc99f63 Add rate of change to statistics sensor (#15632)
* always export max_age/min_age

* downgrade errors of missing data
on start with empty recorder database these errors are logged multiple times:
ERROR (MainThread) [homeassistant.components.sensor.statistics] mean requires at least one data point
ERROR (MainThread) [homeassistant.components.sensor.statistics] variance requires at least two data points

downgrade them to debug as they are not meaningful to end users

* add change_rate attribute
this calculates the average change rate of all data points

* simplify count, reorder attribute calculation

* reorder initialization

* reorder attribute names

* don't use min/max for min_age/max_age

* add test case

* style

* style

* sort constants

* init variables with None

* add precision config setting

* round to precision

* test round
2018-09-08 01:10:08 +02:00
Steven Looman
6433f2e2e3 Working on igd 2018-09-08 00:24:47 +02:00
Andreas Oberritter
50266e9b91 Support SNMPv3 and asyncio in snmp sensor (#14753)
* snmp sensor: Add asyncio support and reuse SnmpEngine object

* snmp sensor: Support protocol v3

* Fix lint issue
2018-09-07 20:51:18 +02:00
mvn23
7ad094b0a7 Add OpenTherm Gateway climate platform (#16299)
* Initial OpenTherm Gateway support.

* Fix coveragerc and requirements_all*.txt
Overall cleanup and polishing

* Make hound/flake/travis happy

* Basic improvements to comply with Home Assistant's style guidelines
Changed wording from "component" to more appropriate terms where necessary
Fixed small mistakes that snuck in during testing and/or due to my own ignorance ;)

* Fixed overwriting state property

* Fixed a bug with ROOM_SETPOINT_OVRD
Updated dependency pyotgw to latest version

* Remove unit_of_measurement from OpenThermGateway class

* Cleanup after previous commits

* Moved initialisation and configuration from async_setup_platform to async_added_to_hass

* Make travis happy

* Disable polling for this platform
Improve update flow

* Small improvements/optimisations
2018-09-07 18:16:19 +02:00
Fabian Affolter
a5715c48a4 Fix GitHub change to resolve conflicts (#16477) 2018-09-07 14:41:31 +02:00
Andreas Oberritter
d0f9d125a7 Support SNMPv3 and asyncio in snmp switch (#14754)
* snmp switch: Add asyncio support and reuse SnmpEngine object

* snmp switch: Support protocol v3
2018-09-07 13:28:42 +02:00
cpw
80c77b8696 Update radiotherm (#15031)
the two device_state_attributes don't return the current actual state (fan on/off, heat/cool), but rather the mode of the fan or thermostat (generally auto). As such this change makes the actual current state visible to the system, so you can do stuff when the fan turns on, for example. I suspect this is just a bug, but maybe it was intended NOT to be able to see the actual fan state?
2018-09-07 13:21:32 +02:00
Dom
1f73840aab Add Yale Smart Alarm component (#16377)
* Add Smart Alarm Component

* Lint fixes

* Update coverage

* Update coverage with the correct file name

* PR Fixes. Update client version (to include timeouts). Cleaned up clien tcreation and improved authentication failure error. Added state map to replace nasty if blocks.

* PR Fixes. Update client version (to include timeouts). Cleaned up clien tcreation and improved authentication failure error. Added state map to replace nasty if blocks.

* Remove test file added in error.

* PR Fixes
2018-09-07 12:22:10 +02:00
Greg Laabs
fbaa489533 Update license to official GitHub template (#16470)
* Delete LICENSE.md

* Create LICENSE.md
2018-09-07 10:11:51 +02:00
Tsvi Mostovicz
cff9b1bf7e Fix waze_travel_time component startup (#16465)
* Fix waze_travel_time component startup

* Remove @Throttle decorator as per pvizelli's request

* Make the linting gods happy again
2018-09-07 09:55:53 +02:00
Ioan Loosley
ce06229c42 Added Twitch v5 support to the twitch platform (#16428)
* code not working

* did it all all at once

* removing debug stuff

* fixing lint issues

* fixing lint issues

* I am blind

* I felt small(80 by somthing) was to small, especily with lovelace

* fixing silly mistake

* this shouldnt be here

* made some changes

* corrrected client_id

* corrrected client_id

* less returns needed

* Fixing Small bugs and making stuff snake case

* Tweaking
2018-09-06 14:08:39 +02:00
Daniel Høyer Iversen
3acb3a86cf update rfxtrx lib (#16463) 2018-09-06 12:50:55 +02:00
Fabian Affolter
db1bda2975 Upgrade Sphinx to 1.7.8 (#16459) 2018-09-06 12:31:30 +02:00
Fabian Affolter
2640db1522 Upgrade shodan to 1.10.1 (#16460) 2018-09-06 12:31:08 +02:00
PhracturedBlue
cf4b72e00e Fix camera proxy to not require api_password to function (#16450) 2018-09-06 10:51:16 +02:00
Daniel Høyer Iversen
5bd9be6252 switchbot (#16396)
* switchbot

* style

* use switchbot lib

* unnecessary import

* switchbot, rename variable update requirements_all

* add line
2018-09-06 10:02:37 +02:00
kbickar
e1084e3953 Upgrade sense library to 0.4.2 (#16429)
* Added error handling for sense API timeouts

* Moved imports in function

* Moved imports to more appropriate function

* Change exception to custom package version

* Updated sense_energy library to 0.4.2
2018-09-05 08:01:36 +02:00
Jason Hu
3afc983c05 Fix openuv.config_flow unit test (#16419) 2018-09-04 21:18:35 +02:00
Paulus Schoutsen
746f4ac158 Add context to scripts and automations (#16415)
* Add context to script helper

* Update script component

* Add context to automations

* Lint
2018-09-04 21:16:24 +02:00
Paul Annekov
e1501c83f8 Fix Mi Flora median calculation (#16085)
* fixed median was based on 1.5 minute interval, not 1 hour

* ignore median and set state from first value, when previous state was None

* update before add, removed unused 'retries' and 'ble_timeout', check if platform ready

* added missing blank line

* fixed too long line

* using modern python 3.5 features, changed comment to be less verbose

* continuation line fix

* removed DEFAULT_SCAN_INTERVAL in favor of existing SCAN_INTERVAL
2018-09-04 21:03:30 +02:00
Toon Willems
3bd12fcef6 Implement correct state for RFlink cover (#16304)
* implement correct state for rflink cover

* Fix linting error

* invert logic as local testing pointed out it should be reversed

* add period at the end to satisfy the linter
2018-09-04 11:15:02 +02:00
Daniel Høyer Iversen
85658b6dd1 Clean up dlink and some bug fix (#16346)
* Update dlink.py

* style

* style
2018-09-04 10:50:12 +02:00
Rohan Kapoor
e61ac1a4a1 Delegate mqtt topic match validation to the paho mqtt client (#16403)
* Delegate mqtt match topics to the paho mqtt client

* Fixing linting error with importing MQTTMatcher
2018-09-04 10:31:45 +02:00
Robert Svensson
8fa9992589 Service to load new deCONZ devices without restart (#16308)
* New service to load new devices from deCONZ without restarting HASS

* Do not use len to check if list is empty

* Add support for scenes to be updated as well

* Rework refresh devices method

* Fix test
2018-09-04 09:24:42 +02:00
Aaron Bach
f96aee2832 Add config flow for OpenUV (#16159)
* OpenUV config flow in place

* Test folder in place

* Owner-requested comments

* Tests

* More tests

* Owner-requested changes (part 1 of 2)

* Updated requirements

* Owner-requested changes (2 of 2)

* Removed unnecessary import

* Bumping Travis

* Updated requirements

* More requirements

* Updated tests

* Owner-requested changes

* Hound

* Updated docstring
2018-09-04 09:22:44 +02:00
Robert Svensson
7a6facc875 Device and entity registry remove config entry on unload (#16247)
* Test

* Ability to remove device

* Don't remove devices, instead remove config entry from device and entity registries

* Remove print

* Remove is not the same as unload

* Add tests

* Fix hound comment
2018-09-04 09:00:14 +02:00
9R
7ea482cb1d add ExpressBus icon key to sensor.mvg (#16387) 2018-09-04 08:48:03 +02:00
Rene Nulsch
a4aa30fc73 Fix SystemMonitor IP address sensor (#16394) 2018-09-04 08:46:04 +02:00
Russell Cloran
ba63a6abc0 zha: Bump to zigpy 0.2.0/bellows 0.7.0 (#16404) 2018-09-03 22:46:27 -07:00
Daniel Høyer Iversen
2252f4a257 Bug fix for Tibber (#16397) 2018-09-04 01:11:40 +02:00
Pawel
00cba29ae1 Support for playing radio preset by Onkyo media_player (#16258)
* Added support to play radio preset by play media

* Switch radio station by preset for Onkyo

* added SUPPORT_PLAY_MEDIA
2018-09-03 21:40:04 +02:00
Steven Looman
f4a54e2483 Changes after review 2018-09-03 21:16:45 +02:00
Paulus Schoutsen
cd473643fe Merge branch 'master' into dev 2018-09-03 14:17:00 +02:00
Paulus Schoutsen
4063b24ddb Merge pull request #16390 from home-assistant/rc
0.77.3
2018-09-03 14:15:54 +02:00
Paulus Schoutsen
46734b8409 Bumped version to 0.77.3 2018-09-03 13:22:49 +02:00
Paulus Schoutsen
b9c80a6bb3 Update translations 2018-09-03 13:21:47 +02:00
Paulus Schoutsen
a2a447b466 Update translations 2018-09-03 13:21:37 +02:00
Paulus Schoutsen
669b3458b9 Update frontend to 20180903.0 2018-09-03 13:21:16 +02:00
Paulus Schoutsen
bf29cbd381 Update frontend to 20180903.0 2018-09-03 13:20:57 +02:00
Daniel Høyer Iversen
1966597d5e add_entities for switchmate (#16368) 2018-09-02 23:05:48 +02:00
Jason Hu
4685a2cd97 Update server.py (#16375) 2018-09-02 22:17:29 +02:00
Fabian Affolter
78fcea25bb Upgrade attrs to 18.2.0 (#16372) 2018-09-02 19:01:43 +02:00
Fabian Affolter
ac3700d1c4 Upgrade python-telegram-bot to 11.0.0 (#16373) 2018-09-02 19:01:25 +02:00
Totoo
03480dc779 Update discord.py (#16248)
* Update discord.py

* Update discord.py

Fixed ATTR_IMAGES checking, line length, and ATTR_DATA imported. Also fixed missing spaces.

* Update discord.py

Fix E302...
2018-09-02 18:58:31 +02:00
Steven Looman
85c40d29ee Linting 2018-09-02 17:03:31 +02:00
Martin Fuchs
a5cff9877e Add support for Tahoma Lighting Receiver on/off io (#15925)
* Add support for Tahoma light switch

* Clean up attributes and add available method

* Remove else statement
2018-09-02 17:02:51 +02:00
Lev Aronsky
b29c296ced Generic Thermostat: add support for climate.turn_on/climate.turn_off (#16080)
* Added async_turn_on and async_turn_off implementations.

* Added turning on/off tests to generic thermostat

* style

* style

* style
2018-09-02 16:42:08 +02:00
Steven Looman
a4a175440b Move ensure_domain_data 2018-09-02 16:40:39 +02:00
MarcSN311
357e5eadb8 Added 'nomapnt', 'outcurnt', 'loadapnt' fields (#16176)
* Added 'nomapnt', 'outcurnt', 'loadapnt' fields

Also added Ampere and Volt-Ampere to INFERRED_UNITS

* Fix lint issue
2018-09-02 15:51:15 +02:00
Fabian Affolter
52e922171d Upgrade to youtube_dl to 2018.09.01 (#16365) 2018-09-02 14:33:20 +02:00
Fabian Affolter
97695a30f5 Upgrade shodan to 1.10.0 (#16363) 2018-09-02 12:51:56 +02:00
Fabian Affolter
1d12c7b0e7 Upgrade mutagen to 1.41.1 (#16361) 2018-09-02 12:51:36 +02:00
Fabian Affolter
15ad82b9bd Upgrade qnapstats to 0.2.7 (#16360) 2018-09-02 12:51:25 +02:00
Fabian Affolter
03fb2b32a6 Upgrade Sphinx to 1.7.7 (#16359) 2018-09-02 12:51:07 +02:00
Jason Hu
87eb6cd25a Upgrade hbmqtt to 0.9.4 (#16356)
* Upgrade to hbmqtt 0.9.4

* Lint

* Typo
2018-09-02 12:50:30 +02:00
Tod Schmidt
3797b6b012 Snips: Added special slot values, session_id and slotname_raw (#16185)
* Added special slot values, site_id, session_id, and slotname_raw

* Update snips.py
2018-09-02 00:01:11 +02:00
Jesse Rizzo
2b0b431a2a Update to EnvoyReader 0.2, support for more hardware (#16212)
* Add support for older Envoy models

* Stop requiring envoy model name in config

* Update to envoy_reader0.2

* Minor formatting fixes

* run script/gen_requirements_all.py

* Minor formatting fixes

* Change some strings to constants, use getattr to call function
2018-09-01 23:45:47 +02:00
Maciej Bieniek
e75a1690d1 Add unique_id to MQTT Light (#16303)
* Add unique_id

* Delete whitespaces
2018-09-01 23:37:03 +02:00
Joshi
444df5b09a Add support for sound_mode for Yamaha rxv media_player (#16352) 2018-09-01 23:34:38 +02:00
Daniel Høyer Iversen
b31890c4cb Handle netatmo exception (#16344) 2018-09-01 23:30:34 +02:00
Steven Looman
8bec4a55d1 Working on igd 2018-09-01 21:20:15 +02:00
Phil Bruckner
a5d95dfbdc Make last_seen attribute a timezone aware datetime in UTC (#16348)
The last_seen attribute was a datetime in the local timezone but with
no tzinfo (i.e., a "naive" datetime.) When state changes occurred it
would be printed incorrectly in homeassistant.log because
homeassistant.util.dt.as_local assumes any datetime without tzinfo is
UTC. Also most, if not all, datetime attributes are timezone aware in
UTC. So use homeassistant.util.dt.as_utc (which assumes a naive
datetime is local) to convert last_seen to a timezone aware datetime
in UTC.
2018-09-01 18:49:03 +02:00
Steven Looman
50f63ed4c5 Fix not being able to re-add IGD when removed 2018-09-01 18:13:45 +02:00
Philipp Temminghoff
901cfef78e Support Sonos Beam HDMI input (#16340) 2018-09-01 16:02:38 +02:00
Daniel Perna
2c7d6ee6b5 Fix missing humidity sensor (#16337) 2018-09-01 10:40:16 +02:00
Steven Looman
c9e34e236d Prevent error message when component is actually ok 2018-09-01 10:14:21 +02:00
Steven Looman
38318ed15f Ensure config_flow is imported 2018-09-01 10:09:22 +02:00
Steven Looman
553d3c0179 Merge remote-tracking branch 'upstream/dev' into igd 2018-09-01 10:01:12 +02:00
Tom Harris
d3791fa45d Add Cover to the Insteon component (#16215)
* Create cover platform

* Create insteon cover platform

* Bump insteonplm to 0.13.0

* Change async_add_devices to async_add_entities

* Missing doc string

* Simplify open and set_position

* Flake8

* Bump insteonplm to 0.13.1

* Code review changes

* Flake8 updates
2018-08-31 23:56:26 +02:00
Matt Schmitt
fa81385b5c Add unique ID (#16323) 2018-08-31 16:47:37 +02:00
thomaslian
7d852a985c Upgrade Adafruit-DHT to 1.3.4 (#16327)
* Update dht.py

* Update requirements_all.txt
2018-08-31 16:47:10 +02:00
Paulus Schoutsen
976626d0ab Merge pull request #16324 from home-assistant/rc
0.77.2
2018-08-31 13:59:48 +02:00
Paulus Schoutsen
d705375a9a Update translations 2018-08-31 13:23:57 +02:00
Paulus Schoutsen
5e8a1496d7 Update translations 2018-08-31 13:23:22 +02:00
Paulus Schoutsen
bc618af193 Bumped version to 0.77.2 2018-08-31 13:17:24 +02:00
Malte Franken
0e076fb9e7 avoid error in debug log mode and rss entry without title (#16316) 2018-08-31 13:12:17 +02:00
Anders Melchiorsen
16a58bd1cf Fix LIFX effects (#16309) 2018-08-31 13:12:16 +02:00
lamiskin
8be7a0a9b9 Correct wemo static device discovery issue. (#16292)
A recent change caused an issue if a single static wemo device is offline and could not be reached, then the whole component would not initialize (and therefore all other wemo devices are not added).
2018-08-31 13:12:16 +02:00
Paulus Schoutsen
232076b41d Update frontend to 20180831.0 2018-08-31 12:59:57 +02:00
Paulus Schoutsen
efa9c82c38 Update frontend to 20180831.0 2018-08-31 12:59:39 +02:00
lamiskin
93f45779c6 Correct wemo static device discovery issue. (#16292)
A recent change caused an issue if a single static wemo device is offline and could not be reached, then the whole component would not initialize (and therefore all other wemo devices are not added).
2018-08-31 12:57:07 +02:00
Malte Franken
26d39d39ea avoid error in debug log mode and rss entry without title (#16316) 2018-08-31 12:54:25 +02:00
Anders Melchiorsen
b43c47cb17 Fix LIFX effects (#16309) 2018-08-31 10:17:11 +02:00
PhracturedBlue
67d8db2c9f Use asterisk_mbox 0.5.0 client (#16296) 2018-08-30 18:44:37 +02:00
Teemu R
3cbf8e4f87 Bump songpal dependency (#16297)
Fixes #14936
2018-08-30 18:21:37 +02:00
Steven Looman
20879726b0 Working on IGD 2018-08-30 17:41:11 +02:00
Malte Franken
f20a3313b0 Geo Location component (#15953)
* initial working version of a geo location component and georss platform

* ensure that custom attributes don't override built-in ones

* bugfixes and tests

* fixing tests because of introduction of new component using same fixture

* improving test cases

* removing potentially unavailable attribute from debug message output

* completing test suite

* cleaning up debug messages; sorting entries in group view by distance

* ability to define the desired state attribute and corresponding unit of measurement; sort devices in group by configured state; find centroid for map if event is defined by polygon; updated tests

* sort entries in group; code clean-ups

* fixing indentation

* added requirements of new component and platform

* fixed various lint issues

* fixed more lint issues

* introducing demo geo location platform; refactored geo location component and geo rss platform to fit

* removing geo rss events platform; added unit tests for geo location platform and demo platform

* reverting change in debug message for feedreader to avoid confusion with new geo location component

* updated requirements after removing georss platform

* removed unused imports

* fixing a lint issue and a test case

* simplifying component code; moving code into demo platform; fixing tests

* removed grouping from demo platform; small refactorings

* automating the entity id generation (the use of an entity namespace achieves the same thing)

* undoing changes made for the georss platform

* simplified test cases

* small tweaks to test case

* rounding all state attribute values

* fixing lint; removing distance from state attributes

* fixed test

* renamed add_devices to add_entities; tweaked test to gain more control over the timed update in the demo platform

* reusing utcnow variable instead of patched method

* fixed test by avoiding to make assumptions about order of list of entity ids

* adding test for the geo location event class
2018-08-30 13:58:23 +02:00
Robbie Trencheny
54c3f4f001 Fix spelling mistake in recorder migration [ci skip] 2018-08-29 14:59:48 -07:00
Paulus Schoutsen
7289d5b656 Merge branch 'master' into dev 2018-08-29 23:37:53 +02:00
Paulus Schoutsen
e77344f029 Merge pull request #16284 from home-assistant/rc
0.77.1
2018-08-29 23:33:53 +02:00
Paulus Schoutsen
60438067f8 Bumped version to 0.77.1 2018-08-29 23:22:56 +02:00
Conrad Juhl Andersen
9062de0704 Fix error when vacuum is idling (#16282) 2018-08-29 23:22:44 +02:00
Sebastian Muszynski
64453638bb Fix data_key override by parent class (#16278) 2018-08-29 23:22:43 +02:00
Paulus Schoutsen
5f1282a4ab Bump frontend to 20180829.1 2018-08-29 23:22:21 +02:00
Robert Svensson
645c3a67d8 Fix so that entities are properly unloaded with config entry (#16281) 2018-08-29 23:18:20 +02:00
Conrad Juhl Andersen
88f72a654a Fix error when vacuum is idling (#16282) 2018-08-29 23:17:18 +02:00
Paulus Schoutsen
87df102772 Bump frontend to 20180829.1 2018-08-29 22:59:55 +02:00
Sebastian Muszynski
25ee8e551c Fix data_key override by parent class (#16278) 2018-08-29 22:29:34 +02:00
Steven Looman
3db766e2ec Merge remote-tracking branch 'upstream/dev' into igd 2018-08-29 21:19:27 +02:00
Steven Looman
1eac6408f5 Working on IGD 2018-08-29 21:19:04 +02:00
Pavel Pletenev
99d48795b9 Add support for Habitica (#15744)
* Added support for Habitica

Second refactoring
Moved all config to component.
Sensors are autodiscovered.
Signed-off-by: delphi <cpp.create@gmail.com>

* Apply requested changes

Signed-off-by: delphi <cpp.create@gmail.com>

* Made event fire async. Made `sensors` config implicit and opt-out-style.

Signed-off-by: delphi <cpp.create@gmail.com>

* Removed unneeded check and await.

Signed-off-by: delphi <cpp.create@gmail.com>

* Moved into separate component package and added service.yaml

Signed-off-by: delphi <cpp.create@gmail.com>

* Fix coveralls

Signed-off-by: delphi <cpp.create@gmail.com>
2018-08-29 21:13:01 +02:00
Jason Hu
5681fa8f07 Nest Thermostat has software version (#16275) 2018-08-29 13:00:40 -06:00
Paulus Schoutsen
867d17b03d Add Hue device info (#16267)
* Add Hue device info

* Set with tuples

* Fix tests
2018-08-29 17:04:04 +02:00
Paulus Schoutsen
7751dd7535 Add device info Nest (#16265)
* Add device info Nest

* Sets
2018-08-29 16:44:10 +02:00
Paulus Schoutsen
16a885824d Add device info for sonos (#16263)
* Add device info for sonos

* Sets
2018-08-29 16:27:08 +02:00
Paulus Schoutsen
3934f7bf3a Add device info to Chromecast (#16261) 2018-08-29 15:46:09 +02:00
cgtobi
96cf6d59a3 Replace Authorization by Authentication (#16259) 2018-08-29 15:43:01 +02:00
Diogo Gomes
d46a1a266d bump version (#16262) 2018-08-29 15:32:47 +02:00
Matt Schmitt
aaa1ebeed5 Add support for discrete states to MyQ cover (#16251)
* Add discrete states and update dependency

* Add translation dict
2018-08-29 14:33:09 +02:00
Daniel Høyer Iversen
18ba50bc2d Switchmate (#15535)
* Switchmate

* switchmate

* swithcmate

* switchmate

* switchmate

* fix comments

* Update switchmate.py

* change error log
2018-08-29 12:56:15 +02:00
Paulus Schoutsen
3df8840fee Version bump to 0.78.0.dev0 2018-08-29 12:20:05 +02:00
Paulus Schoutsen
630b5df59a Merge branch 'master' into dev 2018-08-29 12:19:30 +02:00
Paulus Schoutsen
9db15aab92 Merge pull request #16256 from home-assistant/rc
0.77
2018-08-29 12:10:44 +02:00
Paulus Schoutsen
f01e1ef0aa Version bump to 0.77.0 2018-08-29 10:29:51 +02:00
Robert Svensson
b5919ce92c def device shouldnt call it self but self._device (#16255) 2018-08-29 10:29:24 +02:00
Jason Hu
f9b1fb5906 Tweak MFA login flow (#16254)
* Tweak MFA login flow

* Fix typo
2018-08-29 10:29:24 +02:00
Paulus Schoutsen
9238261e17 Update translations 2018-08-29 10:28:44 +02:00
Paulus Schoutsen
e8801ee22f Update translations 2018-08-29 10:28:34 +02:00
Paulus Schoutsen
8ec109d255 Bump frontend to 20180829.0 2018-08-29 10:28:11 +02:00
Paulus Schoutsen
74c0429437 Bump frontend to 20180829.0 2018-08-29 10:27:34 +02:00
Jason Hu
563588651c Tweak MFA login flow (#16254)
* Tweak MFA login flow

* Fix typo
2018-08-29 10:16:54 +02:00
Robert Svensson
63614a477a def device shouldnt call it self but self._device (#16255) 2018-08-29 10:07:32 +02:00
Paulus Schoutsen
2ea2bcab77 Bumped version to 0.77.0b4 2018-08-28 20:59:38 +02:00
Jason Hu
8d38016b0c Blow up startup if init auth providers or modules failed (#16240)
* Blow up startup if init auth providers or modules failed

* Delete core.entity_registry
2018-08-28 20:59:30 +02:00
Jason Hu
d994d6bfad Change log level to error when auth provider failed loading (#16235) 2018-08-28 20:59:29 +02:00
Paulus Schoutsen
573f5de148 Avoid insecure pycryptodome (#16238) 2018-08-28 20:57:46 +02:00
Paulus Schoutsen
667f9c6fe4 Package loadable: compare case insensitive (#16234) 2018-08-28 20:57:46 +02:00
Paulus Schoutsen
f708292015 Warning missed a space (#16233) 2018-08-28 20:57:45 +02:00
Paulus Schoutsen
c50a7deb92 Fix hangouts (#16232) 2018-08-28 20:57:45 +02:00
Paulus Schoutsen
11fcffda4c Update translations 2018-08-28 20:56:12 +02:00
Paulus Schoutsen
f891d0f5be Update translations 2018-08-28 20:55:58 +02:00
Jason Hu
257b8b9b80 Blow up startup if init auth providers or modules failed (#16240)
* Blow up startup if init auth providers or modules failed

* Delete core.entity_registry
2018-08-28 20:54:01 +02:00
Paulus Schoutsen
9a786e449b Fix hangouts (#16232) 2018-08-28 15:44:06 +02:00
Paulus Schoutsen
09dc4d663d Improve package loadable (#16237)
* Add caching to package loadable

* Fix tests

* Improve package loadable

* Lint

* Typing
2018-08-28 12:52:18 +02:00
Paulus Schoutsen
12709ceaa3 Avoid insecure pycryptodome (#16238) 2018-08-28 12:49:50 +02:00
Jason Hu
67df162bcc Change log level to error when auth provider failed loading (#16235) 2018-08-28 11:23:58 +02:00
Paulus Schoutsen
a14980716d Package loadable: compare case insensitive (#16234) 2018-08-28 10:53:12 +02:00
Paulus Schoutsen
376d4e4fa0 Warning missed a space (#16233) 2018-08-28 09:32:50 +02:00
Paulus Schoutsen
e9cc359abe Bumped version to 0.77.0b3 2018-08-28 00:38:23 +02:00
Paulus Schoutsen
9b01972b41 Update trusted networks flow (#16227)
* Update the trusted networks flow

* Fix tests

* Remove errors
2018-08-28 00:38:08 +02:00
Paulus Schoutsen
3e65009ea9 Fix device telldus (#16224) 2018-08-28 00:38:08 +02:00
Marcel Hoppe
a953601abd rewrite hangouts to use intents instead of commands (#16220)
* rewrite hangouts to use intents instead of commands

* small fixes

* remove configured_hangouts check and CONFIG_SCHEMA

* Lint

* add import from .config_flow
2018-08-28 00:38:07 +02:00
Paulus Schoutsen
2744702f9b Change auth warning (#16216) 2018-08-28 00:38:07 +02:00
Dan Klaffenbach
9c7d4381a1 homematic: Make device avilable again when UNREACH becomes False (#16202) 2018-08-28 00:38:06 +02:00
Paulus Schoutsen
5397c0d73a Update trusted networks flow (#16227)
* Update the trusted networks flow

* Fix tests

* Remove errors
2018-08-28 00:37:15 +02:00
Robert Svensson
8ab31fe139 Store devices as dict instead of list (#16229)
* Store devices as dict instead of list

* Use OrderedDict
2018-08-28 00:37:04 +02:00
Marcel Hoppe
45649824ca rewrite hangouts to use intents instead of commands (#16220)
* rewrite hangouts to use intents instead of commands

* small fixes

* remove configured_hangouts check and CONFIG_SCHEMA

* Lint

* add import from .config_flow
2018-08-28 00:20:12 +02:00
Paulus Schoutsen
914436f3d5 Bump frontend to 20180827.0 2018-08-27 22:28:37 +02:00
Paulus Schoutsen
6f0c30ff84 Bump frontend to 20180827.0 2018-08-27 22:28:17 +02:00
Fabian Affolter
943260fcd6 Upgrade alpha_vantage to 2.1.0 (#16217) 2018-08-27 22:00:20 +02:00
Paulus Schoutsen
24aa580b63 Fix device telldus (#16224) 2018-08-27 21:56:28 +02:00
Daniel Bowman
8435d2f53d openalpr flag WITH_TEST should be WITH_TESTS (#16218)
Removes warning from openalpr build and saves a few seconds from build
time as tests weren't being bypassed as intended
2018-08-27 17:17:43 +02:00
Fabian Affolter
c51170ef6d Add Volkszaehler sensor (#16188)
* Add Volkszaehler sensor

* Update icons

* Improve code
2018-08-27 15:05:36 +02:00
Paulus Schoutsen
9d491f5322 Change auth warning (#16216) 2018-08-27 10:37:03 +02:00
Paulus Schoutsen
adb5579690 Update translations 2018-08-27 10:17:10 +02:00
Paulus Schoutsen
94662620e2 Update translations 2018-08-27 10:16:59 +02:00
Paulus Schoutsen
f1e378bff8 Add new translations 2018-08-27 09:48:17 +02:00
Julian Kahnert
2e9db1f5c4 Fix geizhals price parsing (#15990)
* fix geizhals price parsing

* Fix lint issue

* switch to the geizhals pypi package

* throttle updates

* update geizhals version

* initialize empty device

* minor changes to trigger another TravisCI test

* device => _device

* bump geizhals version
2018-08-27 09:39:11 +02:00
Hunter Horsman
dec2d8d5b0 Add device_tracker.bluetooth_update service (#15252)
* Add device_tracker.bluetooth_update service

Will immediately scan for Bluetooth devices outside of the interval timer. Allows for less frequent scanning, with scanning on demand via automation.

* remove excess whitespace per bot comments

* Refactored update_bluetooth to call new function update_bluetooth_once

* Change service name to bluetooth_tracker_update to reflect platform name

* Reformat for line length

* Linting fix, pydoc, first line should end with a period

* Fixed a method call, and removed some more unsused parameters
2018-08-27 09:08:23 +02:00
Jonas Karlsson
a439690bd7 Rewrite of Trafikverket weather - Multiple sensor types supported (#15935)
* Added precipitation type from API

Enables users to see type of precipitation.
Value returned from API is a string in swedish.

* Corrected tox verification errors

Correction of tox findings

* Missed in tox - fixed

* Hound witespace fix

* Updated comment to trigger travis rebuild

Travis tox failed due to problem with tox build process. 
Correcting in a comment to trigger retry in travis..

* Try to retrigger travis/tox successful rebuild

* Cleaning

* Cleaning more

* Trafikverket rebuilt for library

Extended pytrafikverket with weather sensor collction
Changed behaviour of sensor component to use pytrafikverket.
Added more sensors.

User need to change config to use new version.
 [] Documentation needs to be updated

* Cleaned up based on Martins input

Appreciate the feedback
2018-08-27 06:19:51 +02:00
Maikel Punie
5d7a2f92df Add temperature sensors to the velbus component (#16203)
* Added support for velbus temperature sensors

* Bumped the required version

* updated requirements_all.txt

* Auto review comments fixed

* Updated after comments

* Updated after comments

* Fix travis

* Fix travis
2018-08-27 06:06:46 +02:00
Paulus Schoutsen
8413101148 Bumped version to 0.77.0b2 2018-08-26 22:53:20 +02:00
Paulus Schoutsen
8fb66c351e Add new translations 2018-08-26 22:53:08 +02:00
Paulus Schoutsen
16ad9c2ae6 Update translations 2018-08-26 22:53:08 +02:00
Paulus Schoutsen
4da719f43c Update translations 2018-08-26 22:52:21 +02:00
Robert Svensson
2ad938ed44 Revert changes to platforms using self.device (#16209)
* Revert tank_utility

* Fix Soundtouch

* Fix Plex

* Fix Emby

* Fix Radiotherm

* Fix Juicenet

* Fix Qwikswitch

* Fix Xiaomi miio

* Fix Nest

* Fix Tellduslive

* Fix KNX
2018-08-26 22:51:19 +02:00
Penny Wood
969b15a297 Update aiohttp to version 3.4.0. (#16198) 2018-08-26 22:51:18 +02:00
Marcel Hoppe
c8449d8f8a remove hangouts.users state, simplifies hangouts.conversations (#16191) 2018-08-26 22:51:18 +02:00
PhracturedBlue
6992a6fe6d Handle exception from pillow (#16190) 2018-08-26 22:51:17 +02:00
Jason Hu
2ece671bfd Add Time-based Onetime Password Multi-factor Authentication Module (#16129)
* Add Time-based Onetime Password Multi-factor Auth

Add TOTP setup flow, generate QR code

* Resolve rebase issue

* Use svg instead png for QR code

* Lint and typing

* Fix translation

* Load totp auth module by default

* use <svg> tag instead markdown image

* Update strings

* Cleanup
2018-08-26 22:51:17 +02:00
Matt Hamilton
c13e5fcb92 Replace pbkdf2 with bcrypt (#16071)
* Replace pbkdf2 with bcrypt

bcrypt isn't inherently better than pbkdf2, but everything "just works"
out of the box.

  * the hash verification routine now only computes one hash per call
  * a per-user salt is built into the hash as opposed to the current
  global salt
  * bcrypt.checkpw() is immune to timing attacks regardless of input
  * hash strength is a function of real time benchmarks and a
  "difficulty" level, meaning we won't have to ever update the iteration
  count

* WIP: add hash upgrade mechanism

* WIP: clarify decode issue

* remove stale testing code

* Fix test

* Ensure incorrect legacy passwords fail

* Add better invalid legacy password test

* Lint

* Run tests in async scope
2018-08-26 22:51:16 +02:00
Matt Hamilton
bacecb4249 Replace pbkdf2 with bcrypt (#16071)
* Replace pbkdf2 with bcrypt

bcrypt isn't inherently better than pbkdf2, but everything "just works"
out of the box.

  * the hash verification routine now only computes one hash per call
  * a per-user salt is built into the hash as opposed to the current
  global salt
  * bcrypt.checkpw() is immune to timing attacks regardless of input
  * hash strength is a function of real time benchmarks and a
  "difficulty" level, meaning we won't have to ever update the iteration
  count

* WIP: add hash upgrade mechanism

* WIP: clarify decode issue

* remove stale testing code

* Fix test

* Ensure incorrect legacy passwords fail

* Add better invalid legacy password test

* Lint

* Run tests in async scope
2018-08-26 22:50:31 +02:00
Jason Hu
47755fb1e9 Add Time-based Onetime Password Multi-factor Authentication Module (#16129)
* Add Time-based Onetime Password Multi-factor Auth

Add TOTP setup flow, generate QR code

* Resolve rebase issue

* Use svg instead png for QR code

* Lint and typing

* Fix translation

* Load totp auth module by default

* use <svg> tag instead markdown image

* Update strings

* Cleanup
2018-08-26 22:38:52 +02:00
Penny Wood
69d104bcb6 Update aiohttp to version 3.4.0. (#16198) 2018-08-26 21:35:06 +02:00
Paulus Schoutsen
3783d1ce90 Update frontend to 20180826.0 2018-08-26 21:30:29 +02:00
Paulus Schoutsen
b043ac0f7f Update frontend to 20180826.0 2018-08-26 21:30:14 +02:00
PhracturedBlue
499bb3f4a2 Handle exception from pillow (#16190) 2018-08-26 21:29:15 +02:00
Marcel Hoppe
d166f2da80 remove hangouts.users state, simplifies hangouts.conversations (#16191) 2018-08-26 21:28:42 +02:00
Antoine GRÉA
3032de1dc1 Inconsistent entity_id when multiple sensors (#16205)
* Inconsistent entity_id when multiple sensors

I am submitting a change to fix a [bug](https://github.com/home-assistant/home-assistant/issues/16204) for when there are several sensors for the same hostname. For example I want to track my IPv4 and IPv6 address. It creates two entities that regularly switch ids based on the order they get initialized.

To fix this I comform to the way other componnents have addressed the issue by adding an optional `name` attribute.

* Line too long

* Removing trailing whitespace
2018-08-26 21:27:03 +02:00
Robert Svensson
5341785aae Revert changes to platforms using self.device (#16209)
* Revert tank_utility

* Fix Soundtouch

* Fix Plex

* Fix Emby

* Fix Radiotherm

* Fix Juicenet

* Fix Qwikswitch

* Fix Xiaomi miio

* Fix Nest

* Fix Tellduslive

* Fix KNX
2018-08-26 21:25:39 +02:00
Martin Fuchs
289b1802fd Add battery warning, rssi level and check for availability (#16193) 2018-08-26 21:20:34 +02:00
Fabian Affolter
0da3e73765 Upgrade sqlalchemy to 1.2.11 (#16192) 2018-08-26 12:28:44 +02:00
Dan Klaffenbach
0a7055d475 homematic: Make device avilable again when UNREACH becomes False (#16202) 2018-08-26 12:00:20 +02:00
Matthias Urlichs
a1ce14e70f MQTT: Log transmitted as well as received messages (#16195) 2018-08-26 10:04:51 +02:00
Thomas Delaet
2f2bcf0058 update python-velbus library version (#16194) 2018-08-25 20:42:26 +02:00
djm300
f929c38e98 Zoneminder SSL fix (#16157)
* Update zoneminder.py

Added a verify_ssl parameter for zoneminder

* PEP8 fixup

* PEP8 indenting fix

* Fix lint issue

* Remove whitespace
2018-08-25 11:21:57 +02:00
Paulus Schoutsen
9ffcd2d86a Bumped version to 0.77.0b1 2018-08-25 11:16:01 +02:00
Jason Hu
66a8bede12 Default load trusted_network auth provider if configured trusted networks (#16184) 2018-08-25 11:15:55 +02:00
Jason Hu
c2891b9905 Tweak log level for bearer token warning (#16182) 2018-08-25 11:15:54 +02:00
Paulus Schoutsen
b8c272258e Fix hangouts (#16180) 2018-08-25 11:15:54 +02:00
Nate Clark
4cb9ac72b4 fix error message for cv.matches_regex (#16175) 2018-08-25 11:15:53 +02:00
Robert Svensson
cf8bd92d4d Device registry store config entry (#16152)
* Allow device registry to optionally store config entries

* Connections and identifiers are now sets with tupels

* Make config entries mandatory

* Fix duplicate keys in test

* Rename device to device_info

* Entity platform should only create device entries if config_entry_id exists

* Fix Soundtouch tests

* Revert soundtouch to use self.device

* Fix baloobs comments

* Correct type in test
2018-08-25 11:15:53 +02:00
Nate Clark
90b2257347 Decouple Konnected entity setup from discovery (#16146)
* decouple entity setup from discovery

* validate that device_id is a full MAC address
2018-08-25 11:15:52 +02:00
Jason Hu
914d90a2bc Add multi-factor auth module setup flow (#16141)
* Add mfa setup flow

* Lint

* Address code review comment

* Fix unit test

* Add assertion for WS response ordering

* Missed a return

* Remove setup_schema from MFA base class

* Move auth.util.validate_current_user -> webscoket_api.ws_require_user
2018-08-25 11:15:52 +02:00
Robert Svensson
e567b2281d deCONZ - Support device registry (#16115)
Add support for device registry in deCONZ component
2018-08-25 11:15:51 +02:00
Paulus Schoutsen
bb6567f84c Bump frontend to 20180825.0 2018-08-25 11:15:19 +02:00
Paulus Schoutsen
617802653f Bump frontend to 20180825.0 2018-08-25 11:15:01 +02:00
Jason Hu
26a485d43c Default load trusted_network auth provider if configured trusted networks (#16184) 2018-08-25 11:09:48 +02:00
Paulus Schoutsen
456aa5a2b2 Fix hangouts (#16180) 2018-08-25 11:01:32 +02:00
Robert Svensson
97173f495c Device registry store config entry (#16152)
* Allow device registry to optionally store config entries

* Connections and identifiers are now sets with tupels

* Make config entries mandatory

* Fix duplicate keys in test

* Rename device to device_info

* Entity platform should only create device entries if config_entry_id exists

* Fix Soundtouch tests

* Revert soundtouch to use self.device

* Fix baloobs comments

* Correct type in test
2018-08-25 10:59:28 +02:00
Jason Hu
24a8d60566 Tweak log level for bearer token warning (#16182) 2018-08-25 07:57:36 +02:00
Fabian Affolter
69cea6001f Add 'moon_phase' to Dark Sky sensor (#16179) 2018-08-24 17:05:53 -06:00
Nate Clark
647b3ff0fe Decouple Konnected entity setup from discovery (#16146)
* decouple entity setup from discovery

* validate that device_id is a full MAC address
2018-08-24 23:29:25 +02:00
Nate Clark
84365cde07 fix error message for cv.matches_regex (#16175) 2018-08-24 23:27:12 +02:00
Robert Svensson
e91a1529e4 deCONZ - Support device registry (#16115)
Add support for device registry in deCONZ component
2018-08-24 19:37:22 +02:00
Jason Hu
e8775ba2b4 Add multi-factor auth module setup flow (#16141)
* Add mfa setup flow

* Lint

* Address code review comment

* Fix unit test

* Add assertion for WS response ordering

* Missed a return

* Remove setup_schema from MFA base class

* Move auth.util.validate_current_user -> webscoket_api.ws_require_user
2018-08-24 10:17:43 -07:00
Paulus Schoutsen
4f8fec6494 Bumped version to 0.77.0b0 2018-08-24 17:03:05 +02:00
Paulus Schoutsen
57979faa9c Merge remote-tracking branch 'origin/master' into dev 2018-08-24 17:02:44 +02:00
Paulus Schoutsen
994b829cb4 add_devices -> add_entities (#16171)
* add_devices -> add_entities

* Lint

* PyLint

* Revert external method in scsgate
2018-08-24 16:37:30 +02:00
Robert Svensson
37fd438717 deCONZ - Allow sub second light transitions (#16170)
Solves https://github.com/home-assistant/home-assistant/issues/16075
2018-08-24 16:15:28 +02:00
Adam Mills
5e301dd599 Hangouts localization typo fix (#16174) 2018-08-24 16:13:58 +02:00
Paulus Schoutsen
3d5b3fb6ff Update translations 2018-08-24 15:54:47 +02:00
Paulus Schoutsen
6c5f98668e Bump frontend to 20180824.0 2018-08-24 15:54:04 +02:00
Steven Looman
e73f31d829 Merge remote-tracking branch 'upstream/dev' into igd 2018-08-24 15:25:07 +02:00
Marcel Hoppe
ef0eab0f40 Hangouts (#16049)
* add a component for hangouts

* add a notify component for hangouts

* add an extra message as title

* add support to listen to all conversations hangouts has

* move hangouts to package and add parameter documentation

* update .coveragerc and requirements_all.txt

* makes linter happy again

* bugfix

* add conversations parameter to command words

* Move the resolution of conversation names to conversations in own a function

* typo

* rename group of exclusion form 'id' to 'id or name'

* refactoring and use config_flow

* makes linter happy again

* remove unused imports

* fix not working regex commands

* fix translations

* cleanup

* remove step_init

* remove logging entry

* clean up events

* move constant

* remove unsed import

* add new files to .converagerc

* isort imports

* add hangouts_utils to ignored packages

* upadte doc and format

* fix I/O not in executor jon

* rename SERVICE_UPDATE_USERS_AND_CONVERSATIONS to SERVICE_UPDATE

* move EVENT_HANGOUTS_{CONNECTED,DISCONNECTED} to dispatcher

* add config flow tests

* Update tox.ini
2018-08-24 10:39:35 +02:00
Ville Skyttä
dd9d53c83e Update pydocstyle to 2.1.1 and flake8-docstrings to 1.3.0 (#14557)
* Update pydocstyle to 2.1.1 and flake8-docstrings to 1.3.0

* Pydocstyle D401 fixes
2018-08-24 10:28:43 +02:00
Ville Skyttä
89d856d147 Spelling fixes (#16150) 2018-08-23 22:56:18 +02:00
Paulus Schoutsen
156c6e2025 Remove commented out API password from default config (#16147) 2018-08-23 22:16:31 +02:00
Paulus Schoutsen
d21d7cef4c Enable auth by default 🙈 (#16107)
* Enable auth by default

* Only default legacy_api_password if api_password set

* Tweak bool check

* typing
2018-08-23 13:38:08 +02:00
Paulus Schoutsen
249981de96 Prevent legacy api password with empty password (#16127)
* Prevent legacy api password with empty password

* Typing
2018-08-23 12:56:01 +02:00
squidwardy
8e173f1658 Add support for JS modules in custom panels (#16096)
* Added backend support for JavaScript modules in custom panels.

* Fixed test_panel_custom.py

* Delete core.entity_registry

* Update panel_custom.py

* Corrected panel_custom.py with module_url.

* Rebase

* Missed elif

* Add vol.Exclusive module_url

* Correct vol.Exclusive usage

* Test for js module

* Corrected line continuation indentation

* Added webcomponent path to exclusive group

* Corrected line length

* Line break

* Test for conflicting url options

* Self -> hass fix

* Fix self -> hass again

* Use assert_setup_component

* Setup missing

* Correct test

* Fix again

* Fix

* Mising async

* Fix

* test real

* Test real

* Final

* check

* Final check

* safety

* Final commit and check

* Removed unused dependencies

* Test for multiple url options in config
2018-08-23 11:14:18 +02:00
Diogo Gomes
ced5eeacc2 Adds support for routers implementing IGDv2 (#16108)
* Adds support for IGDv2

* bump pyupnp_async

* bump pyupnp_async

* better debug

* fix test
2018-08-23 10:54:02 +02:00
JC Connell
4155e8a31f Add support for NOAA tide information (new PR) (#15947)
* Adding noaa-tides changes to new branch.

* Fix typo in .coverageac

* Incorporate @MartinHjelmare and @fabaff changes.

* Disable pylint error and add error message for unavailable station.

* Two spaces before inline comments

* Increment py_noaa version to 0.3.0

* Updated requirements.py

* Minor changes
2018-08-23 00:21:46 +02:00
Eduard van Valkenburg
4ad76d8916 Upgrade brunt package (#16130)
* Bumped package version to fix a bug with Python before 3.6

* update of package version in requirements_all
2018-08-22 20:12:54 +02:00
Sebastian Muszynski
478eb48e93 Fix the protocol v2 data_key of several aqara devices (#16112)
* Fix the protocol v2 data_key of several aqara devices

* Incorporate review
2018-08-22 15:29:43 +02:00
Fabian Affolter
d8ae079757 Upgrade youtube_dl to 2018.08.22 (#16125) 2018-08-22 13:55:48 +02:00
Fabian Affolter
b0c2d24997 Upgrade numpy to 1.15.1 (#16126) 2018-08-22 13:55:11 +02:00
Paulus Schoutsen
2e6cb2235c Check correctly if package is loadable (#16121) 2018-08-22 12:17:14 +02:00
Robert Svensson
0009be595c Device Registry (#15980)
* First draft

* Generate device id

* No obscure registry

* Dont store config_entry_id in device

* Storage

* Small mistake on rebase

* Do storage more like entity registry

* Improve device identification

* Add tests

* Remove deconz device support from PR

* Fix hound comments, voff!

* Fix comments and clean up

* Fix proper indentation

* Fix pydoc issues

* Fix mochad component to not use self.device

* Fix mochad light platform to not use self.device

* Fix TankUtilitySensor to not use self.device

* Fix Soundtouch to not use self.device

* Fix Plex to not use self.device

* Fix Emby to not use self.device

* Fix Heatmiser to not use self.device

* Fix Wemo lights to not use self.device

* Fix Lifx to not use self.device

* Fix Radiotherm to not use self.device

* Fix Juicenet to not use self.device

* Fix Qwikswitch to not use self.device

* Fix Xiaomi miio to not use self.device

* Fix Nest to not use self.device

* Fix Tellduslive to not use self.device

* Fix Knx to not use self.device

* Clean up a small mistake in soundtouch

* Fix comment from Ballob

* Fix bad indentation

* Fix indentatin

* Lint

* Remove unused variable

* Lint
2018-08-22 10:46:37 +02:00
Jason Hu
7e7f9bc6ac Add multi-factor authentication modules (#15489)
* Get user after login flow finished

* Add multi factor authentication support

* Typings
2018-08-22 09:52:34 +02:00
Jerad Meisner
ae63980152 Remove unit_of_measurement from climate entities (#16012)
* Remove unit_of_measurement from climate base class.

* Updated google_assistant component and tests to use core temp units.

* Fixes

* Convert Alexa component to use core temp units for climate entities.

* Fix tests.

* Converted prometheus component.

* Remove unit_of_measurement from homekit thermostat tests.

* Small fix.
2018-08-22 09:17:29 +02:00
Tom Harris
a31501d99e Merge insteon_plm and insteon_local to insteon component (#16102)
* Implement X10

* Add X10 after add_device_callback

* Ref device by id not hex and add x10OnOffSwitch name

* X10 services and add sensor device

* Correctly reference X10_HOUSECODE_SCHEMA

* Log adding of X10 devices

* Add X10 All Units Off, All Lights On and All Lights Off devices

* Correct ref to X10 states vs devices

* Add X10 All Units Off, All Lights On and All Lights Off devices

* Correct X10 config

* Debug x10 device additions

* Config x10 from bool to housecode char

* Pass PLM to X10 device create

* Remove PLM to call to add_x10_device

* Unconfuse x10 config and method names

* Correct spelling of x10_all_lights_off_housecode

* Bump insteonplm to 0.10.0 to support X10

* Add host to config options

* Add username and password to config for hub connectivity

* Add username and password to config for hub

* Convert port to int if host is defined

* Add KeypadLinc

* Update config schema to require either port or host

* Solidify Hub and PLM configuration to ensure proper settings

* Update hub schema

* Bump insteonplm version

* Fix pylint and flake issues

* Bump insteonplm to 0.12.1

* Merge insteon_plm and insteon_local to insteon

* Rename insteon_plm to insteon

* Bump insteonplm to 0.12.2

* Flake8 cleanup

* Update .coveragerc for insteon_plm, insteon_local and insteon changes

* Add persistent notification

* Fix reference to insteon_plm

* Fix indentation

* Shorten message and fix grammer

* Add comment to remove in release 0.90

* Hound fix
2018-08-22 09:09:04 +02:00
Fabian Affolter
6864a44b5a Upgrade sendgrid to 5.6.0 (#16111) 2018-08-22 07:16:21 +02:00
Fabian Affolter
523af4fbca Upgrade shodan to 1.9.1 (#16113) 2018-08-22 07:15:56 +02:00
Dan Klaffenbach
b9733d0d99 homematic: Add homematic.put_paramset service (#16024)
Service to call putParamset method of XML-RPC API
2018-08-22 00:20:26 +02:00
Sebastian Muszynski
7ed8ed83e3 Bump python-miio version (#16110) 2018-08-21 21:25:48 +02:00
Fabian Affolter
0e1fb74e1b Minor updates (#16106) 2018-08-21 21:25:16 +02:00
Jason Hu
1ce51bfbd6 Refactoring login flow (#16104)
* Abstract LoginFlow

* Lint and typings
2018-08-21 11:03:38 -07:00
Paulus Schoutsen
cdb8361050 Add support for revoking refresh tokens (#16095)
* Add support for revoking refresh tokens

* Lint

* Split revoke logic in own method

* Simplify

* Update docs
2018-08-21 11:02:55 -07:00
Jason Hu
00c6f56cc8 Allow finish_flow callback to change data entry result type (#16100)
* Allow finish_flow callback to change data entry result type

* Add unit test
2018-08-21 10:48:24 -07:00
Paulus Schoutsen
b26506ad4a Use new session when fetching remote urls (#16093) 2018-08-21 19:03:46 +02:00
Paulus Schoutsen
7bb5344942 Remove homeassistant.remote (#16099)
* Remove homeassistant.remote

* Use direct import for API

* Fix docstring
2018-08-21 15:49:58 +02:00
Krasimir Zhelev
ae5c4c7e13 Upgrade afsapi to 0.0.4, prevents aiohttp session close message, Fixes #13099 (#16098) 2018-08-21 15:30:40 +02:00
Flip Hess
507e8f8f12 Add verify ssl to generic camera (#15949)
* Add verify_ssl option to generic camera

* Remove flake8 errors

* Add test for ssl verification on and off

* Fix lint errors
2018-08-21 15:29:11 +02:00
Paulus Schoutsen
5a15b2c036 Merge pull request #16094 from home-assistant/rc
0.76.2
2018-08-21 12:20:06 +02:00
Paulus Schoutsen
977d86e7ca Bumped version to 0.76.2 2018-08-21 11:43:14 +02:00
Paulus Schoutsen
bd776c84bc Forgiving add index in migration (#16092) 2018-08-21 11:43:08 +02:00
Paulus Schoutsen
68cd65567d Forgiving add index in migration (#16092) 2018-08-21 11:41:52 +02:00
Ville Skyttä
ef07460792 Upgrade pytest to 3.7.2 (#16091) 2018-08-21 10:56:28 +02:00
Jason Hu
f84a31871e Get user after login flow finished (#16047)
* Get user after login flow finished

* Add optional parameter 'type' to /auth/login_flow

* Update __init__.py
2018-08-21 10:18:04 +02:00
Daniel Perna
b1ba11510b Update pyhomematic to 0.1.47 (#16083) 2018-08-20 23:43:04 +02:00
Daniel Høyer Iversen
439f7978c3 fritzdect change to current_power_w (#16079) 2018-08-20 22:42:48 +02:00
Andrey Kupreychik
85a724e289 Bumped NDMS2 client library to 0.0.4 to get compatible with python 3.5 (#16077) 2018-08-20 18:51:25 +02:00
Greg Laabs
df6239e0fc Add ecovacs component (#15520)
* Ecovacs Deebot vacuums

* All core features implemented

Getting fan speed and locating the vac are still unsupported until sucks adds support

* Move init queries to the added_to_hass method

* Adding support for subscribing to events from the sucks library

This support does not exist in sucks yet; this commit serves as a sort of TDD approach of what such support COULD look like.

* Add OverloadUT as ecovacs code owner

* Full support for Ecovacs vacuums (Deebot)

* Add requirements

* Linting fixes

* Make API Device ID random on each boot

* Fix unique ID

Never worked before, as it should have been looking for a key, not an attribute

* Fix random string generation to work in Python 3.5 (thanks, Travis!)

* Add new files to .coveragerc

* Code review changes

(Will require a sucks version bump in a coming commit; waiting for it to release)

* Bump sucks to 0.9.1 now that it has released

* Update requirements_all.txt as well

* Bump sucks version to fix lifespan value errors

* Revert to sucks 0.9.1 and include a fix for a bug in that release

Sucks is being slow to release currently, so doing this so we can get a version out the door.

* Switch state_attributes to device_state_attributes
2018-08-20 17:42:53 +02:00
Paulus Schoutsen
1be61df9c0 Add recent context (#15989)
* Add recent context

* Add async_set_context to components not using new services
2018-08-20 17:39:53 +02:00
Paulus Schoutsen
d1e1b9b38a Deprecated stuff (#16019)
* Use async with for locks

* Fix regex in template test

* Close session correctly

* Use correct current_task method

* push camera cleanup

* Lint

* Revert current_task

* Update websocket_api.py

* Mock executor_job betteR

* Fix async_create_task mock
2018-08-20 16:34:18 +02:00
Tim Bailey
975befd136 TpLink Device Tracker Error (#15918)
* Fix 'Error setting up platform tplink' error when a scanner fails even if another scanner would succeed

* Try to fix tox errors

* Adjust code based on PR comments
2018-08-20 14:34:52 +02:00
Oleksii Serdiuk
a708a81fa8 openuv: Add Current UV Level to list of conditions (#16042)
Calculated from UV index, based on table from
https://www.openuv.io/kb/uv-index-levels-colors
2018-08-20 14:22:41 +02:00
Paulus Schoutsen
18d19fde0b Alexa: context + log events (#16023) 2018-08-20 14:18:07 +02:00
Kevin Siml
1f0d113688 Update pushsafer.py (#16060) 2018-08-20 14:11:52 +02:00
Paulus Schoutsen
121abb450a Use aiohttp web.AppRunner (#16020)
* Use aiohttp web.AppRunner

* Stop site
2018-08-20 14:03:35 +02:00
Paulus Schoutsen
1be388c587 Update frontend to 20180820.0 2018-08-20 11:52:47 +02:00
Paulus Schoutsen
994e2b6624 Update frontend to 20180820.0 2018-08-20 11:52:36 +02:00
Ville Skyttä
dbd0763f83 Grammar and spelling fixes (#16065) 2018-08-19 22:29:08 +02:00
Paulus Schoutsen
e1b2e00cf6 Merge pull request #16064 from home-assistant/rc
0.76.1
2018-08-19 20:07:44 +02:00
Paulus Schoutsen
3c5e62d47e Column syntax fix + Add a file if migration in progress (#16061)
* Add a file if migration in progress

* Warning

* Convert message for migration to warning
2018-08-19 19:01:11 +02:00
Paulus Schoutsen
3be301fac9 Bumped version to 0.76.1 2018-08-19 18:58:21 +02:00
Paulus Schoutsen
9c3251b5f0 Add notify platforms to loaded components (#16063) 2018-08-19 18:58:13 +02:00
huangyupeng
cb44607e96 Tuya fix login problem and add login platform param (#16058)
* add a platform param to distinguish different app's account.

* fix requirements
2018-08-19 18:58:12 +02:00
Paulus Schoutsen
1c8ef4e196 Add forgiving add column (#16057)
* Add forgiving add column

* Lint
2018-08-19 18:58:12 +02:00
Paulus Schoutsen
9e1fa7ef42 Column syntax fix + Add a file if migration in progress (#16061)
* Add a file if migration in progress

* Warning

* Convert message for migration to warning
2018-08-19 18:57:06 +02:00
Paulus Schoutsen
7c95e96ce8 Add notify platforms to loaded components (#16063) 2018-08-19 18:56:31 +02:00
huangyupeng
21b88f2fe8 Tuya fix login problem and add login platform param (#16058)
* add a platform param to distinguish different app's account.

* fix requirements
2018-08-19 18:55:10 +02:00
Paulus Schoutsen
81d3161a5e Add forgiving add column (#16057)
* Add forgiving add column

* Lint
2018-08-19 17:22:09 +02:00
Dan Klaffenbach
8beb349e88 vacuum/xiaomi_miio: Expose "sensor_dirty_left" attribute (#16003) 2018-08-19 13:57:28 +02:00
Daniel Shokouhi
c105045dab Update neato to support new StateVacuumDevice (#16035)
* Update neato to support new vacuum states

* Remove changes submitted in error

* Lint

* Review comments and fix resume cleaning

* Lint
2018-08-18 20:20:32 +02:00
Paulus Schoutsen
b901a26c47 Attempt to fix flaky TTS test (#16025) 2018-08-18 13:35:51 +02:00
Paulus Schoutsen
8ec550d6e0 Storage entity registry (#16018)
* Split out storage delayed write

* Update code using delayed save

* Fix tests

* Fix typing test

* Add callback decorator

* Migrate entity registry to storage helper

* Make double loading protection easier

* Lint

* Fix tests

* Ordered Dict
2018-08-18 13:34:33 +02:00
Paulus Schoutsen
6827256586 Bump frontend to 20180818.0 2018-08-18 11:15:46 +02:00
Paulus Schoutsen
ef193b0f64 Bump frontend to 20180818.0 2018-08-18 11:15:33 +02:00
Ed Marshall
e782e2c0f3 Handle missing mpd capabilities (#15945)
* Handle missing mpd capabilities

It is possible to configure mpd without volume or playlist support.
Gracefully degrade when either of these features appears to be missing.

Resolves: #14459, #15927

* Use longer name for exception

* Only return support flags post-connection

* Small consistency fixes to mpd.py for review.
2018-08-18 09:54:23 +02:00
Wim Haanstra
ec2e94425e Update RitAssist to support maximum speed and current address (#16037)
Update RitAssist dependency to 0.9.2 so we support fetching the current maximum speed and address for a device.
2018-08-18 09:40:29 +02:00
Diogo Gomes
9f0adc16ad Merge pull request #16031 from StevenLooman/dev
Upgrade to async_upnp_client==0.12.4
2018-08-17 22:36:03 +01:00
Steven Looman
fa88d918b1 Upgrade to async_upnp_client==0.12.4 2018-08-17 21:29:31 +02:00
Steven Looman
839b58c600 Working on IGD 2018-08-17 21:28:29 +02:00
Steven Looman
71d00062e5 Upgrade to async_upnp_client 0.12.4 2018-08-17 21:25:08 +02:00
Ville Skyttä
3800f00564 Disable assuming Optional type for values with None default (#16029)
https://www.python.org/dev/peps/pep-0484/#union-types
"Type checkers should move towards requiring the optional type to be
made explicit."
2018-08-17 20:22:49 +02:00
Paulus Schoutsen
2ad0bd4036 Split out storage delay save (#16017)
* Split out storage delayed write

* Update code using delayed save

* Fix tests

* Fix typing test

* Add callback decorator
2018-08-17 20:18:21 +02:00
Paulus Schoutsen
70412fc0ba Merge pull request #16027 from home-assistant/rc
0.76.0
2018-08-17 18:41:40 +02:00
Paulus Schoutsen
e4425e6a37 Version 0.76.0 2018-08-17 17:23:20 +02:00
Fabian Affolter
fdbab3e20c Upgrade sendgrid to 5.5.0 (#16021) 2018-08-17 16:39:41 +02:00
Anders Melchiorsen
f2e399ccf3 Update SoCo to 0.16 (#16007) 2018-08-17 07:41:56 +02:00
Martin Hjelmare
07840f5397 Fix check config packages key error (#15840)
* Fix packages deletion in check_config script

* The config key for packages is not present if core config validation
  failed. We need to do a safe dict deletion using dict.pop.

* Add check_config test for bad core config
2018-08-17 05:28:00 +02:00
Paulus Schoutsen
c09e7e620f Bumped version to 0.76.0b5 2018-08-16 23:02:34 +02:00
Paulus Schoutsen
92e26495da Disable the DLNA component discovery (#16006) 2018-08-16 23:02:26 +02:00
Steven Looman
061859cc4d Fix message "Updating dlna_dmr media_player took longer than ..." (#16005) 2018-08-16 23:02:26 +02:00
Steven Looman
45452e510c Fix message "Updating dlna_dmr media_player took longer than ..." (#16005) 2018-08-16 22:42:11 +02:00
Paulus Schoutsen
279ead2085 Disable the DLNA component discovery (#16006) 2018-08-16 22:41:44 +02:00
Ville Skyttä
649f17fe47 Add type hints to homeassistant.auth (#15853)
* Always load users in auth store before use

* Use namedtuple instead of dict for user meta

* Ignore auth store tokens with invalid created_at

* Add type hints to homeassistant.auth
2018-08-16 22:25:41 +02:00
Alexxander0
e9e5bce10c BMW Connected drive: option to disable the services (#15993)
* Update __init__.py

* Update bmw_connected_drive.py

* Update __init__.py

* Update bmw_connected_drive.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update bmw_connected_drive.py
2018-08-16 22:19:29 +02:00
Paulus Schoutsen
e41ce1d6ec Bump frontend to 20180816.1 2018-08-16 22:18:10 +02:00
Paulus Schoutsen
bc21a1b944 Bump frontend to 20180816.1 2018-08-16 22:17:55 +02:00
Paulus Schoutsen
834077190f Clean up input-datetime (#16000) 2018-08-16 22:17:14 +02:00
Steven Looman
80f98b9ea2 Fix message "Updating dlna_dmr media_player took longer than ..." 2018-08-16 22:14:13 +02:00
Max Prokhorov
2a210607d3 Wemo custom ports and network errors handling (#14516)
* Update wemo component

* Support custom ports in static addresses
* Handle device_from_description exceptions
* Process static addresses before doing discovery
* Fail on inaccessable static address
* str.format instead of old formatting

* Validate static host[:port] earlier

* Fix comment formatting

* slice looks ambiguous in the log, keep voluptuous exception path intact
2018-08-16 08:14:54 -06:00
Paulus Schoutsen
1ff1639cef More entity service (#15998)
* Camera use entity service

* Convert climate services

* Convert light

* Convert media player

* Migrate fan
2018-08-16 14:28:59 +02:00
Paulus Schoutsen
5eccfc2604 Bumped version to 0.76.0b4 2018-08-16 14:26:52 +02:00
Paulus Schoutsen
2469bc7e2e Fix Nest async from sync (#15997) 2018-08-16 14:26:44 +02:00
Martin Hjelmare
d540a084dd Fix mysensors connection task blocking setup (#15938)
* Fix mysensors connection task blocking setup

* Schedule the connection task without having the core track the task
  to avoid blocking setup.
* Cancel the connection task, if not cancelled already, when
  home assistant stops.

* Use done instead of cancelled
2018-08-16 14:26:44 +02:00
Paulus Schoutsen
11eb29f520 Bump frontend to 20180816.0 2018-08-16 14:22:01 +02:00
Paulus Schoutsen
e4d41fe313 Bump frontend to 20180816.0 2018-08-16 14:21:49 +02:00
Martin Hjelmare
b5e7414be2 Fix mysensors connection task blocking setup (#15938)
* Fix mysensors connection task blocking setup

* Schedule the connection task without having the core track the task
  to avoid blocking setup.
* Cancel the connection task, if not cancelled already, when
  home assistant stops.

* Use done instead of cancelled
2018-08-16 14:19:42 +02:00
Paulus Schoutsen
83b0ef4e26 Fix Nest async from sync (#15997) 2018-08-16 13:46:43 +02:00
Paulus Schoutsen
b682e48e12 Entity service (#15991)
* Add entity service helper

* Use entity service helper

* Context
2018-08-16 09:50:11 +02:00
Josh Shoemaker
e52ba87af1 Upgrade aladdin_connect to 0.3 and provide Unique ID (#15986)
* Upgrade aladdin_connect to 0.2 and set unique_id

* update code to be Python 3.5 compatible
2018-08-16 07:18:29 +02:00
Paulus Schoutsen
6da0ae4d23 Bumped version to 0.76.0b3 2018-08-15 10:55:03 +02:00
Jason Hu
f8051a5698 Fix 0.76 beta2 hassio token issue (#15987) 2018-08-15 10:53:39 +02:00
Jason Hu
2306d14b5d Teak mqtt error message for 0.76 release (#15983) 2018-08-15 10:53:38 +02:00
Paulus Schoutsen
4035880003 Update translations 2018-08-15 10:52:27 +02:00
Paulus Schoutsen
9cfbd067d3 Update translations 2018-08-15 10:52:06 +02:00
Fabian Affolter
39fd70231f Upgrade psutil to 5.4.7 (#15982) 2018-08-15 10:47:58 +02:00
Jason Hu
dc460f4d6a Fix 0.76 beta2 hassio token issue (#15987) 2018-08-15 09:56:05 +02:00
Jason Hu
c31035d348 Teak mqtt error message for 0.76 release (#15983) 2018-08-15 08:09:19 +02:00
Fabian Affolter
555184a4b7 Update Glances sensor (#15981)
* Refactor Glances sensor

* Add glances_api to requirements_all.txt

* Add support for version as configuration option
2018-08-15 07:49:34 +02:00
Paulus Schoutsen
e64e84ad7a Bumped version to 0.76.0b2 2018-08-14 22:06:57 +02:00
Paulus Schoutsen
1777270aa2 Pin crypto (#15978)
* Pin crypto

* Fix PyJWT import once
2018-08-14 22:06:44 +02:00
Paulus Schoutsen
f5df567d09 Use JWT for access tokens (#15972)
* Use JWT for access tokens

* Update requirements

* Improvements
2018-08-14 22:06:44 +02:00
Paulus Schoutsen
899c2057b7 Switch to intermediate Mozilla cert profile (#15957)
* Allow choosing intermediate SSL profile

* Fix tests
2018-08-14 22:06:43 +02:00
Jason Hu
1b384c322a Remove remote.API from core.Config (#15951)
* Use core.ApiConfig replace remote.API in core.Config

* Move ApiConfig to http
2018-08-14 22:06:43 +02:00
Daniel Bowman
f4e84fbf84 remove-phantomjs-from-docker (#15936) 2018-08-14 22:06:42 +02:00
Khalid
d393380122 Fix issue when reading worxlandroid pin code (#15930)
Fixes #14050
2018-08-14 22:06:41 +02:00
Jason Hu
d0e4c95bbc MQTT embedded broker has to set its own password. (#15929) 2018-08-14 22:06:41 +02:00
Jason Hu
34e1f1b6da Add context to login flow (#15914)
* Add context to login flow

* source -> context

* Fix unit test

* Update comment
2018-08-14 22:06:40 +02:00
kbickar
6d432d19fe Added error handling for sense API timeouts (#15789)
* Added error handling for sense API timeouts

* Moved imports in function

* Moved imports to more appropriate function

* Change exception to custom package version
2018-08-14 22:06:40 +02:00
Paulus Schoutsen
486efa9aba Pin crypto (#15978)
* Pin crypto

* Fix PyJWT import once
2018-08-14 22:02:01 +02:00
Daniel Bowman
0ad9fcd8a0 Add -j$(nproc) make option to speed up build time (#15928)
Adding `-j$(nproc)` reduces build time on the external dependencies by
approximately 25%.
2018-08-14 21:28:29 +02:00
Nate Clark
c7f7912bca adds support for momentary and beep/blink switches (#15973) 2018-08-14 21:15:33 +02:00
Paulus Schoutsen
e776f88eec Use JWT for access tokens (#15972)
* Use JWT for access tokens

* Update requirements

* Improvements
2018-08-14 21:14:12 +02:00
kbickar
ee5d49a033 Added error handling for sense API timeouts (#15789)
* Added error handling for sense API timeouts

* Moved imports in function

* Moved imports to more appropriate function

* Change exception to custom package version
2018-08-14 15:50:44 +02:00
Sean Dague
051903d30c Update waterfurnace library to 0.7, add reconnect logic (#15657)
One of the features of the waterfurnace 0.7 is timingout out stuck
connections on the websocket (which tends to happen after 48 - 96
hours of operation). This requires the homeassistant component to
catch and reconnect under these circumstances. This has turned out to
be pretty robust in preventing stuck sockets over the last month.
2018-08-14 07:49:04 -04:00
Paulus Schoutsen
91e1ae035e Remove warning (#15969) 2018-08-14 12:29:55 +02:00
Fabian Affolter
10a2ecd1d6 Make setup fail if location is not available (#15967)
* Make setup fail if location is not available

* Lint
2018-08-14 12:29:31 +02:00
Khalid
800eb4d86a Fix issue when reading worxlandroid pin code (#15930)
Fixes #14050
2018-08-14 11:55:40 +02:00
Daniel Bowman
e3a2e58623 remove-phantomjs-from-docker (#15936) 2018-08-14 11:53:08 +02:00
Colin Frei
ea073b5e87 Remove unnecessary log (#15966) 2018-08-14 11:46:41 +02:00
cgtobi
619d01150f Fix google calendar documentation link. (#15968) 2018-08-14 11:44:27 +02:00
Paulus Schoutsen
6540d2e073 Switch to intermediate Mozilla cert profile (#15957)
* Allow choosing intermediate SSL profile

* Fix tests
2018-08-14 08:20:17 +02:00
Daniel Perna
69b694ff26 HomeMatic: Enable entity registry (#15950)
* Set unique ID

* Excluding setups that resolve names

* Added support for resolvenames again
2018-08-14 07:43:16 +02:00
Paulus Schoutsen
9e21765173 Bumped version to 0.76.0b1 2018-08-13 23:17:30 +02:00
Paulus Schoutsen
c0830f1c20 Deprecate remote.api (#15955) 2018-08-13 23:17:21 +02:00
Martin Hjelmare
985f96662e Upgrade pymysensors to 0.17.0 (#15942) 2018-08-13 23:17:21 +02:00
Paulus Schoutsen
e0229b799d Update frontend to 20180813.0 2018-08-13 23:11:56 +02:00
Paulus Schoutsen
3fbb56d5fb Update frontend to 20180813.0 2018-08-13 23:11:22 +02:00
Conrad Juhl Andersen
3a60c8bbed Update Xiaomi Vacuum to new StateVacuumDevice (#15643)
* Add support for states

* Woof?

* Fixed some errors

* VacuumDevice -> StateVacuumDevice

* VacuumDevice -> StateVacuumDevice

* Added split of start and pause
2018-08-13 22:50:23 +02:00
Colin Frei
f411fb89e6 Netatmo public (#15684)
* Add a sensor for netatmo public data

* A bit of cleanup before submitting pull request

* Add netatmo_public file to .coveragerc, as per pull request template instructions

* Fixes for tox complaining

* make calculations simpler, based on review feedback

* explicitly pass required_data parameter to netatmo API

* remove unnecessary spaces

* remove debug code

* code style fix
2018-08-13 22:44:20 +02:00
Paulus Schoutsen
1b5cfa7331 Deprecate remote.api (#15955) 2018-08-13 22:39:13 +02:00
Charles Garwood
39647a15ae Add monitored conditions for Unifi device_tracker (#15888)
* Add support for monitored_conditions for attributes

* Update unifi tests

* Add list of available attrs
2018-08-13 21:18:25 +02:00
Matthew Garrett
ba2e43600e Merge pull request #15959 from mjg59/eufy
Bump python-lakeside dependency
2018-08-13 10:53:44 -07:00
Matthew Garrett
c998a55fe7 Bump python-lakeside dependency
This should fix https://github.com/home-assistant/home-assistant/issues/15374
2018-08-13 10:39:48 -07:00
Jason Hu
da8f93dca2 Add trusted networks auth provider (#15812)
* Add context to login flow

* Add trusted networks auth provider

* source -> context
2018-08-13 12:40:06 +02:00
Jason Hu
50daef9a52 Add context to login flow (#15914)
* Add context to login flow

* source -> context

* Fix unit test

* Update comment
2018-08-13 11:27:18 +02:00
Jason Hu
45f12dd3c7 MQTT embedded broker has to set its own password. (#15929) 2018-08-13 11:26:06 +02:00
Hovo (Luke)
6aee535d7c Allow wait template to run the remainder of the script (#15836)
* Adding new feature to allow a wait template to run the remainer of the script on timeout

* Styling changes

* Fixing file permissions, adding test for new code

* changed variable name, refactored script to pass information into async_set_timeout

* Changing the default behaviour to continue to run the script after timeout
2018-08-13 11:23:27 +02:00
Fabian Affolter
2342709803 Upgrade beautifulsoup4 to 4.6.3 (#15946) 2018-08-13 10:52:47 +02:00
Jason Hu
272be7cdae Remove remote.API from core.Config (#15951)
* Use core.ApiConfig replace remote.API in core.Config

* Move ApiConfig to http
2018-08-13 09:26:20 +02:00
Sebastian Muszynski
31fbfed0a6 Fix magic cube support of the Aqara LAN Protocol V2 (#15940) 2018-08-13 08:17:15 +02:00
Lev Aronsky
b7486e5605 Fixed race condition in Generic Thermostat (#15784)
* Fixed race condition in Generic Thermostat

* Added a comment to clarify the meaning of the `time` argument.
2018-08-12 22:28:47 +02:00
Martin Hjelmare
e8218c4b29 Upgrade pymysensors to 0.17.0 (#15942) 2018-08-12 20:22:54 +02:00
Thom Troy
d3fed52254 Eph ember support operation modes (#15820)
* add operation mode support for climate.EphEmber

* fix linting errors from py3.5

* remove STATE_ALL_DAY and cleanup some code based on review

* use explicit None return with get

* fix none return
2018-08-12 17:48:15 +02:00
Paulus Schoutsen
1205eaaa22 Version bump to 0.77.0dev0 2018-08-11 08:59:46 +02:00
Paulus Schoutsen
69934a9598 Bumped version to 0.76.0b0 2018-08-11 08:58:52 +02:00
Paulus Schoutsen
f24773933c Update frontend to 20180811.0 2018-08-11 08:58:20 +02:00
Franck Nijhof
e17e080639 ✏️ Corrects typo in code comments (#15923)
`MomematicIP` -> `HomematicIP`
2018-08-11 08:47:41 +02:00
cgtobi
055e35b297 Add RMV public transport sensor (#15814)
* Add new public transport sensor for RMV (Rhein-Main area).

* Add required module.

* Fix naming problem.

* Add unit test.

* Update dependency version to 0.0.5.

* Add new requirements.

* Fix variable name.

* Fix issues pointed out in review.

* Remove unnecessary code.

* Fix linter error.

* Fix config value validation.

* Replace minutes as state by departure timestamp. (see ##14983)

* More work on the timestamp. (see ##14983)

* Revert timestamp work until #14983 gets merged.

* Simplify product validation.

* Remove redundant code.

* Address code change requests.

* Address more code change requests.

* Address even more code change requests.

* Simplify destination check.

* Fix linter problem.

* Bump dependency version to 0.0.7.

* Name variable more explicit.

* Only query once a minute.

* Update test case.

* Fix config validation.

* Remove unneeded import.
2018-08-10 19:35:09 +02:00
Robert Svensson
81604a9326 deCONZ - Add support for sirens (#15896)
* Add support for sirenes

* Too quick...

* Fix test

* Use siren instead of sirene
2018-08-10 19:22:12 +02:00
Paulus Schoutsen
a0e9f9f218 Merge remote-tracking branch 'origin/master' into dev 2018-08-10 18:10:56 +02:00
Paulus Schoutsen
0ab3e7a92a Add IndieAuth 4.2.2 redirect uri at client id (#15911)
* Add IndieAuth 4.2.2 redirect uri at client id

* Fix tests

* Add comment

* Limit to first 10kB of each page
2018-08-10 18:09:42 +02:00
Paulus Schoutsen
9512bb9587 Add and restore context in recorder (#15859) 2018-08-10 18:09:01 +02:00
Adam Mills
da916d7b27 Fix bug in translations upload script (#15922) 2018-08-10 11:35:01 -04:00
clayton craft
b370b6a4e4 Update radiotherm to 1.4.1 (#15910) 2018-08-10 16:10:19 +02:00
Ville Skyttä
1911168855 Misc cleanups (#15907)
* device_tracker.huawei_router: Pylint logging-not-lazy fix

* sensor.irish_rail_transport: Clean up redundant self.info test
2018-08-10 16:09:08 +02:00
Joe Lu
f98629b895 Update August component to use py-august:0.6.0 (#15916) 2018-08-10 07:27:49 +02:00
Ville Skyttä
dc01b17260 Some typing related fixes (#15899)
* Fix FlowManager.async_init handler type

It's not a Callable, but typically a key pointing to one in a dict.

* Mark pip_kwargs return type hint as Any-valued dict

install_package takes other than str args too.
2018-08-09 22:53:12 +02:00
Benoit Louy
ef61c0c3a4 Add PJLink media player platform (#15083)
* add pjlink media player component

* retrieve pjlink device name from projector if name isn't specified in configuration

* update .coveragerc

* fix style

* add missing docstrings

* address PR comments from @MartinHjelmare

* fix code style

* use snake case string for source names

* add missing period at the end of comment string

* rewrite method as function

* revert to use source name provided by projector
2018-08-09 19:58:16 +02:00
mountainsandcode
664eae72d1 Add realtime true/false switch for Waze (#15228) 2018-08-09 16:27:29 +02:00
rafale77
86658f310d Fix for multiple camera switches naming of entity (#14028)
* Fix for multiple camera switches naming of entity

appended camera name to the switch entity name.

* Update amcrest.py

* Update amcrest.py

* Update amcrest.py

* Update amcrest.py

* Update amcrest.py

* Update amcrest.py

* Update amcrest.py

* Update amcrest.py

* Update amcrest.py

* Update amcrest.py

* Update amcrest.py

* Add digest authentification

* Update rest_command.py

* Update config.py

* Update rest_command.py

* Update config.py
2018-08-09 15:59:23 +02:00
Mattias Welponer
a29f867908 Add HomematicIP Cloud smoke detector device (#15621)
* Add smoke detector device

* Remove not needed __init__ functions
2018-08-09 14:43:13 +02:00
Paulus Schoutsen
28de2d6f75 Merge pull request #15903 from home-assistant/rc
0.75.3
2018-08-09 14:34:31 +02:00
Paulus Schoutsen
37d98474d5 Bumped version to 0.75.3 2018-08-09 13:41:24 +02:00
Jason Hu
5116f02290 Fix downgrade hassio cannot get refresh_token issue (#15874)
* Fix downgrade hassio issue

* Update __init__.py
2018-08-09 13:38:52 +02:00
Jason Hu
2233d7ca98 Fix downgrade hassio cannot get refresh_token issue (#15874)
* Fix downgrade hassio issue

* Update __init__.py
2018-08-09 13:31:48 +02:00
Jason Hu
f58425dd3c Refactor data entry flow (#15883)
* Refactoring data_entry_flow and config_entry_flow

Move SOURCE_* to config_entries
Change data_entry_flow.FlowManager.async_init() source param default
 to None
Change this first step_id as source or init if source is None
_BaseFlowManagerView pass in SOURCE_USER as default source

* First step of data entry flow decided by _async_create_flow() now

* Lint

* Change helpers.config_entry_flow.DiscoveryFlowHandler default step

* Change FlowManager.async_init source param to context dict param
2018-08-09 13:24:14 +02:00
Fabian Affolter
39d19f2183 Upgrade locationsharinglib to 2.0.11 (#15902) 2018-08-09 13:05:28 +02:00
Paulus Schoutsen
99c4c65f69 Add auth/authorize endpoint (#15887) 2018-08-09 09:27:54 +02:00
Fabian Affolter
61901496ec Upgrade pylast to 2.4.0 (#15886) 2018-08-08 22:32:21 +02:00
Steven Looman
0ab65f1ac5 Follow changes to netdisco, separating DLNA into DLNA_DMS and DLNA_DMR (#15877)
* Follow changes to netdisco, separating DLNA into DLNA_DMS and DLNA_DMR

* No uppercase for names of netdisco discoverables
2018-08-08 11:54:22 +02:00
Fabian Affolter
debdc707e9 Upgrade netdisco to 2.0.0 (#15885) 2018-08-08 11:53:43 +02:00
DubhAd
fcc918a146 Update based upon forum post (#15876)
Based upon [this post](https://community.home-assistant.io/t/device-tracker-ping-on-windows-not-working-solved/61474/3) it looks like we've found why people couldn't get the ping tracker working on Windows.
2018-08-07 18:12:36 +02:00
Fabian Affolter
b6bc0097b8 Upgrade requests_mock to 1.5.2 (#15867) 2018-08-07 16:12:16 +02:00
Fabian Affolter
d556edae31 Upgrade Sphinx to 1.7.6 (#15868) 2018-08-07 16:12:01 +02:00
Fabian Affolter
1fb2ea70c2 Upgrade asynctest to 0.12.2 (#15869) 2018-08-07 16:11:47 +02:00
Ville Skyttä
4cbcb4c3a2 Upgrade pylint to 2.1.1 (#15872) 2018-08-07 16:09:19 +02:00
Paulus Schoutsen
d071df0dec Do not make internet connection during tests (#15858)
* Do not make internet connection

* Small improvement
2018-08-07 09:27:40 +02:00
cdce8p
f09f153014 Fix HomeKit test (#15860)
* Don't raise NotImplementedError during test
2018-08-07 09:26:58 +02:00
Fabian Affolter
1d8678c431 Upgrade pysnmp to 4.4.5 (#15854) 2018-08-07 09:13:01 +02:00
Fabian Affolter
51c30980df Upgrade holidays to 0.9.6 (#15831) 2018-08-07 09:12:09 +02:00
Fabian Affolter
cb20c9b1ea Revert "Upgrade requests_mock to 1.5.2"
This reverts commit a7db2ebbe1.
2018-08-07 09:02:54 +02:00
Fabian Affolter
a7db2ebbe1 Upgrade requests_mock to 1.5.2 2018-08-07 09:01:32 +02:00
Robin
61721478f3 Add facebox auth (#15439)
* Adds auth

* Update facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Remove TIMEOUT

* Update test_facebox.py

* fix lint

* Update facebox.py

* Update test_facebox.py

* Update facebox.py

* Adds check_box_health

* Adds test auth

* Update test_facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Ups coverage

* Update test_facebox.py

* Update facebox.py

* Update test_facebox.py

* Update facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py
2018-08-07 07:30:36 +02:00
Paulus Schoutsen
47fa928425 Bumped version to 0.76.0.dev0 2018-08-06 13:01:32 +02:00
Paulus Schoutsen
10a7accd00 Merge branch 'master' into dev 2018-08-06 13:01:04 +02:00
Paulus Schoutsen
527585ff9c Merge pull request #15856 from home-assistant/rc
0.75.2
2018-08-06 12:59:54 +02:00
Paulus Schoutsen
2f15a40e97 Bumped version to 0.75.2 2018-08-06 12:38:01 +02:00
Dan Cinnamon
ccef9a3e43 Fix envisalink reconnect (#15832)
* Fix logic for handling connection lost/reconnect

* Fixed line length issue.
2018-08-06 12:37:45 +02:00
Fabian Affolter
479dfd1710 Upgrade voluptuous to 0.11.5 (#15830) 2018-08-06 12:37:45 +02:00
Paulus Schoutsen
34ad4bd32d Fix requirements 2018-08-06 12:37:28 +02:00
psike
6031801206 Fix error when Series missing 'episodeFileCount' or 'episodeCount' (#15824)
* Fix error when Series missing 'episodeFileCount' or 'episodeCount'

* Update sonarr.py

* Update sonarr.py
2018-08-06 12:18:36 +02:00
John Arild Berentsen
9cfe0db3c8 Add different pop 012501 ID (#15838) 2018-08-06 11:10:26 +02:00
Jason Hu
8ef2cfa364 Try to fix coveralls unstable result (#15800)
* Create one tox env for code coverage report

pytest-cov generated report in project root folder, not tox env folder.

* Add cov tox env to travis

* Coveralls seems expecting all build jobs upload

* Only upload coverage after cov env success
2018-08-06 10:51:37 +02:00
Jason Hu
12e69202f8 Change to call_service async_stop non-blocking to allow service call finish (#15803)
* Call later sync_stop to allow service call finish

* Change to use non-blocking service all for restart and stop
2018-08-06 10:25:37 +02:00
ahobsonsayers
e4b2ae29bd Fix bt_home_hub_5 device tracker (#15096)
* Fix bt_home_hub_5 device tracker

Updated BT Home Hub 5 device tracker component to get it working again. The old parsing method of the DNS table has been broken for a while causing the component to fail to get connected devices. A new parsing method has been implemened and fixes all previous issues.

* Moved part of code to a published PyPi library

* Fixed Violations

* Fixed bugs in device tracker

* Moved API Specific Code to PyPi Repository

* Updated to fit requested changes, removed test as it is no longer valid and updated requirement_all.txt

* Update to fit style requirements and remove redundant code

* Removed Unnecessary Comment
2018-08-06 07:38:02 +02:00
Ryan Davies
ac4674fdb0 Add max_gps_accuracy option to Google Maps (#15833)
* Google Maps - Add max_gps_accuracy option

* Remove else statement and add continue
2018-08-06 07:17:21 +02:00
Fabian Affolter
f86702e8ab Upgrade shodan to 1.9.0 (#15839) 2018-08-05 22:48:14 +02:00
mattwing
9a84f8b763 Remove 'volume' from return dict (#15842)
https://github.com/home-assistant/home-assistant/issues/15271

intraday results do not return the volume. See https://www.alphavantage.co/documentation/#intraday
2018-08-05 22:11:51 +02:00
Dan Cinnamon
6a32b9bf87 Fix envisalink reconnect (#15832)
* Fix logic for handling connection lost/reconnect

* Fixed line length issue.
2018-08-05 18:51:23 +02:00
Steven Looman
b152becbe0 Add media_player.dlna_dmr component (#14749)
* Add media_player.dlna_dmr component

* PEP 492

* Move DIDL-template up

* Remove max_volume-override option

* Remove picky_device support

* Use DEFAULT_NAME

* Make supported_features static

* Remove unneeded argument

* Proper module-docstring

* Add http dependency

* Remove additional_configuration options, no longer used

* Change default name to 'DLNA Digital Media Renderer'

* Use python-didl-lite for DIDL-Lite-xml construction/parsing

* Handle NOT_IMPLEMENTED for UPnP state variables RelativeTimePosition and CurrentMediaDuration

* Use UPnP-UDN for unique_id

* Proper handling of upnp events

* Keeping flake8 happy

* Update requirements_all.txt

* Make UDN optional

* Ensure NotifyView is started, before using it

* Only subscribe to services we're interested in

* Don't update state_variables if value has not been changed + minor refactoring

* Improve play_media, follow flow of DLNA more closely

* Hopefully fix ClientOSError problems

* Flake8 fixes

* Keep pylint happy

* Catch errors and report gracefully

* Update async_upnp_client to 0.11.0

* Don't be so noisy

* Define/use constants for HTTP status codes

* Add discovery entry for dlna_dmr

* More robustness with regard to state variable not being set (yet)

* Keep privates hidden

* Handle NOT_IMPLEMENTED for CurrentTrackMetaData state variable

* Fixes in async_upnp_client + renew UPnP subscriptions regularly

* Not too eager

* Refactor duplicate code to _current_transport_actions and improve parsing of actions

* Support RC:1 to RC:3 and AVT:1 to AVT:3

* Moved DLNA-specifics to async_upnp_client.dlna.DmrDevice

* Use our own HTTP server to listen for events.

* More clear and explicit log message for easier troubleshooting

* Follow changes by hass, fixes traceback

* Fix not being able to do next

* Changes after review by @MartinHjelmare

* Linting

* Use homeassistant.util.get_local_ip

* Moved upnp event handling to async_upnp_client

* Keeping pylint happy

* Changes after review by @MartinHjelmare
2018-08-05 14:41:18 +02:00
Fabian Affolter
c41aa12d1d Upgrade youtube_dl to 2018.08.04 (#15837) 2018-08-05 13:29:06 +02:00
Thomas Delaet
8a81ee3b4f Velbus auto-discovery (#13742)
* remove velbus fan and light platforms

these platforms should not be there since they can be created with template components based on switch platform

* use latest version of python-velbus which supports auto-discovery of modules

* fix linting errors

* fix linting errors

* fix linting errors

* address review comments from @MartinHjelmare

* update based on automatic feedback

* fix linting errors

* update dependency

* syntax corrections

* fix lint warning

* split out common functionality in VelbusEntity
use sync methods for loading platforms
support unique_ids so that entities are registred in entity registry

* fix linting errors

* fix linting errors

* fix linting errors

* integrate review comments (common functionality in VelbusEntity class)

* rename DOMAIN import to VELBUS_DOMAIN

* revert change created by requirements script

* regen
2018-08-05 10:47:17 +02:00
fucm
5e1836f3a2 Add support for 2 Tahoma IO awning covers (#15660)
* Add Tahoma io:VerticalExteriorAwningIOComponent and io:HorizontalAwningIOComponent

* Fix position of horizontal awning cover

* Add timestamps for lock time

* Adjust open-close actions for horizontal awning cover

* Fix stop action for io:RollerShutterGenericIOComponent

* Remove redundant information

* Use get for dict lookup
2018-08-05 10:44:57 +02:00
Fabian Affolter
9ea3be4dc1 Upgrade voluptuous to 0.11.5 (#15830) 2018-08-04 17:46:14 -07:00
Martin Hjelmare
bce47eb9a4 Fix frontend requirements after bump (#15829) 2018-08-04 22:35:41 +02:00
Pascal Vizeli
018bd8544c Fix lint with wrong frontend version inside requirements_test_all 2018-08-04 22:26:13 +02:00
Pascal Vizeli
bfb9f2a00b Fix lint with wrong frontend version inside requirements_all 2018-08-04 22:24:17 +02:00
Paulus Schoutsen
3f8c91d77c Merge pull request #15823 from home-assistant/rc
0.75.1
2018-08-04 15:26:51 +02:00
Paulus Schoutsen
ef5095cf53 Bumped version to 0.75.1 2018-08-04 15:24:44 +02:00
Daniel Høyer Iversen
5015071816 Fix rfxtrx device id matching (#15819)
* Issue #15773

Fix PT2262 devices are incorrectly matched in rfxtrx component

* style
2018-08-04 15:24:34 +02:00
superpuffin
b110a80fbd Upgrade Adafruit-DHT to 1.3.3 (#15706)
* Change to newer pip package

The package Adafruit_Python_DHT==1.3.2 was broken and would not install, breaking DHT sensor support in Home assistant. It has since been fixed in Adafruit-DHT==1.3.3.

See: https://github.com/adafruit/Adafruit_Python_DHT/issues/99

* Update requirements_all.txt

New or updated dependencies have been added to `requirements_all.txt` by running `script/gen_requirements_all.py`.

* Comment out Adafruit-DHT

Adafruit_Python_DHT changed name to Adafruit-DHT, which still need pyx support breaking our CI, need to be comment out.

* Update requirements_all.txt
2018-08-04 15:24:33 +02:00
Daniel Høyer Iversen
c7a8f1143c Fix rfxtrx device id matching (#15819)
* Issue #15773

Fix PT2262 devices are incorrectly matched in rfxtrx component

* style
2018-08-04 15:23:57 +02:00
Ville Skyttä
dbe44c076e Upgrade pytest to 3.7.1 and pytest-timeout to 1.3.1 (#15809) 2018-08-04 15:22:37 +02:00
Ville Skyttä
3246b49a45 Upgrade pylint to 2.1.0 (#15811)
* Upgrade pylint to 2.1.0

* Remove no longer needed pylint disables
2018-08-04 15:22:22 +02:00
Paulus Schoutsen
c482d48fde Bump frontend to 20180804.0 2018-08-04 15:21:32 +02:00
Paulus Schoutsen
0c7d46927e Bump frontend to 20180804.0 2018-08-04 15:21:11 +02:00
Paulus Schoutsen
7d9f8b0d4c Merge pull request #15806 from home-assistant/rc
0.75.0
2018-08-03 16:45:24 +02:00
Paulus Schoutsen
b8981b2675 Merge remote-tracking branch 'origin/master' into rc 2018-08-03 14:25:36 +02:00
Jason Hu
f6935b5d27 Upgrade voluptuous-serialize to 2.0.0 (#15763)
* Upgrade voluptuous-serialize to 2.0.0

* Change to 2.0.0
2018-08-03 05:23:26 -07:00
Paulus Schoutsen
6028db21ab Bumped version to 0.75.0 2018-08-03 14:23:12 +02:00
Paulus Schoutsen
c63fd974fb Return True from Nest setup (#15797) 2018-08-03 14:22:40 +02:00
Robert Svensson
cdb86ed154 Only report color temp when in the correct color mode (#15791) 2018-08-03 14:22:40 +02:00
Bryan York
0f844311c9 Fix Min/Max Kelvin color temp attribute for Google (#15697)
* Fix Min/Max Kelvin color temp attribute for Google

Max Kelvin is actually Min Mireds and vice-versa. K = 1000000 / mireds

* Update test_smart_home.py

* Update test_trait.py
2018-08-03 14:22:39 +02:00
Robert Svensson
91e8680fc5 Only report color temp when in the correct color mode (#15791) 2018-08-03 13:56:54 +02:00
Jason Hu
6f2000f5e2 Make sure use_x_forward_for and trusted_proxies must config together (#15804)
* Make sure use_x_forward_for and trusted_proxies must config together

* Fix unit test
2018-08-03 13:52:34 +02:00
Paulus Schoutsen
8d2359026c Bump frontend to 20180803.0 2018-08-03 13:48:48 +02:00
Paulus Schoutsen
ee180c51cf Bump frontend to 20180803.0 2018-08-03 13:48:32 +02:00
Conrad Juhl Andersen
b63312ff2e Vacuum component: start_pause to individual start and pause commands. (#15751)
* Add start and pause to StateVacuumDevice, move start_pause to VacuumDevice

* Updated demo vacuum and tests

* Add a few more tests
2018-08-02 19:49:38 -07:00
Paulus Schoutsen
59f8a73676 Return True from Nest setup (#15797) 2018-08-02 16:36:37 -06:00
Jesse Rizzo
affd4e7df3 Add Enphase Envoy component (#15081)
* add enphase envoy component

* Add Enphase Envoy component for energy monitoring

* Fix formatting problems

* Fix formatting errors

* Fix formatting errors

* Fix formatting errors

* Change unit of measurement to W or Wh. Return sensor states as integers

* Fix formatting errors

* Fix formatting errors

* Fix formatting errors

* Move import json to update function

* Fix formatting. Add file to .coveragerc

* Add new component to requirements_all.txt

* Move API call to third party library on PyPi

* Refactor

* Run gen_requirements_all.py

* Minor refactor

* Fix indentation

* Fix indentation
2018-08-02 23:14:43 +02:00
Bryan York
38928c4c0e Fix Min/Max Kelvin color temp attribute for Google (#15697)
* Fix Min/Max Kelvin color temp attribute for Google

Max Kelvin is actually Min Mireds and vice-versa. K = 1000000 / mireds

* Update test_smart_home.py

* Update test_trait.py
2018-08-02 22:09:19 +02:00
Diogo Gomes
48af5116b3 Update pymediaroom to 0.6.4 (#15786)
* Dependency version bump

* bump version
2018-08-02 20:13:48 +02:00
Paulus Schoutsen
a5112f317d Update frontend to 20180802.0 2018-08-02 14:23:56 +02:00
Paulus Schoutsen
eb5f6efb43 Update frontend to 20180802.0 2018-08-02 14:23:40 +02:00
Paulus Schoutsen
3ed47b05a5 Update translations 2018-08-02 13:43:36 +02:00
Paulus Schoutsen
7972d6a0c6 Update translations 2018-08-02 13:42:45 +02:00
Paulus Schoutsen
163cd72b7a Bumped version to 0.75.0b1 2018-08-02 12:23:36 +02:00
Aaron Bach
bdea9e1333 Add support for OpenUV binary sensors and sensors (#15769)
* Initial commit

* Adjusted ownership and coverage

* Member-requested changes

* Updated Ozone to a value, not an index

* Verbiage update
2018-08-02 07:42:12 +02:00
Wim Haanstra
2f8d66ef2b RitAssist / FleetGO support (#15780)
* RitAssist / FleetGO support

* Fix lint issue
Add to .coveragerc
2018-08-02 07:01:40 +02:00
Jason Hu
589b23b7e2 Revert "Add support for STATE_AUTO of generic_thermostat (#15678)" (#15783)
This reverts commit 2e5131bb21.
2018-08-01 10:04:41 -07:00
Niklas
2e5131bb21 Add support for STATE_AUTO of generic_thermostat (#15678)
Add support for STATE_AUTO of generic_thermostat
2018-08-01 08:07:27 -07:00
Conrad Juhl Andersen
2ff5b4ce95 Add support for STATES of vacuums (#15573)
* Vacuum: Added support for STATES

* Added debug logging and corrected state order

* typo

* Fix travis error, STATE = STATE for readability

* status -> state

* Changed to Entity instead of ToogleEntity

* Updated some vacuums

* Revert changes

* Revert Changes

* added SUPPORT_STATE

* Woof?

* Implement on/off if STATE not supported

* Moved new state vaccum to Class StateVacuumDevice

* Error: I should go to bed

* Moved around methods for easier reading

* Added StateVacuumDevice demo vacuum

* Added tests for StateVacuumDevice demo vacuum

* Fix styling errors

* Refactored to BaseVaccum

* Vacuum will now go back to dock

* Class BaseVacuum is for internal use only

* return -> await

* return -> await
2018-08-01 05:51:38 -07:00
Robert Svensson
f8a478946e deCONZ - support for power plugs (#15752)
* Initial commit for deCONZ switch support

* Fix hound comment

* Fix martins comment; platforms shouldn't depend on another platform

* Fix existing tests

* New tests

* Clean up unnecessary methods

* Bump requirement to v43

* Added device state attributes to light
2018-08-01 11:03:08 +02:00
Oscar Tin Yiu Lai
623f6c841b Expose internal states and fixed on/off state of Dyson Fans (#15716)
* exposing internal state and fixed onoff state

* fixed styling

* revert file mode changes

* removed self type hints

* better unit test and changed the way to return attributes

* made wolfie happy
2018-07-31 21:38:34 -07:00
Ioan Loosley
0b6f2f5b91 Opensky altitude (#15273)
* Added Altitude to opensky

* decided to take all metadata

* Final Tidy

* More formatting

* moving CONF_ALTITUDE to platform

* Moved CONF_ALTITUDE to platform
2018-07-31 21:45:18 +02:00
Mathieu Velten
3445dc1f00 Update pynetgear to 0.4.1 (bugfixes) (#15768) 2018-07-31 21:40:13 +02:00
Fabian Affolter
a11c2a0bd8 Fix docstrings (#15770) 2018-07-31 21:39:37 +02:00
Diogo Gomes
95da41aa15 This component API has been decomissioned on the 31st of May 2018 by Telstra (#15757)
See #15668
2018-07-31 21:27:43 +02:00
Fabian Affolter
27401f4975 Upgrade Mastodon.py to 1.3.1 (#15766) 2018-07-31 21:17:55 +02:00
Scott Albertson
d902a9f279 Add a "Reviewed by Hound" badge (#15767) 2018-07-31 21:17:33 +02:00
priiduonu
03847e6c41 Round precipitation forecast to 1 decimal place (#15759)
The OWM returns precipitation forecast values as they are submitted to their network. It can lead to values like `0.0025000000000004 mm` which does not make sense and messes up the display card. This PR rounds the value to 1 decimal place.
2018-07-31 19:18:11 +02:00
Fabian Affolter
a4f9602405 Convert wind speed to km/h (fixes #15710) (#15740)
* Convert wind speed to km/h (fixes #15710)

* Round speed
2018-07-31 19:11:29 +02:00
John Arild Berentsen
5f214ffa98 Update pyozw to 0.4.9 (#15758)
* update pyozw to 0.4.8

* add requirements_all.txt

* use 0.4.9
2018-07-31 15:14:14 +01:00
Andrey
8ee3b535ef Add disallow_untyped_calls to mypy check. (#15661)
* Add disallow_untyped_calls to mypy check.

* Fix generator
2018-07-31 15:00:17 +01:00
Andrey Kupreychik
951372491c Fixed NDMS for latest firmware (#15511)
* Fixed NDMS for latest firmware.
Now using telnet instead of Web Interface

* Using external library for NDMS interactions

* updated requirements_all

* renamed `mac` to `device` back

* Using generators for name and attributes fetching
2018-07-31 11:14:49 +02:00
Jason Hu
eeb79476de Decouple login flow view and data entry flow view (#15715) 2018-07-30 21:59:18 -07:00
Aaron Bach
1b2d0e7a6f Better handling of Yi camera being disconnected (#15754)
* Better handling of Yi camera being disconnected

* Handling video processing as well

* Cleanup

* Member-requested changes

* Member-requested changes
2018-07-30 21:56:52 -07:00
Teemu R
3208ad27ac Add kodi unique id based on discovery (#15093)
* kodi add unique id based on discovery

* initialize unique_id to None

* use netdisco-extracted mac_address

* use an uuid instead of mac for real uniqueness

* add missing docstring

* verify that there is no entity already for the given unique id

* whitespace fix
2018-07-30 17:09:38 +02:00
superpuffin
cf87b76b0c Upgrade Adafruit-DHT to 1.3.3 (#15706)
* Change to newer pip package

The package Adafruit_Python_DHT==1.3.2 was broken and would not install, breaking DHT sensor support in Home assistant. It has since been fixed in Adafruit-DHT==1.3.3.

See: https://github.com/adafruit/Adafruit_Python_DHT/issues/99

* Update requirements_all.txt

New or updated dependencies have been added to `requirements_all.txt` by running `script/gen_requirements_all.py`.

* Comment out Adafruit-DHT

Adafruit_Python_DHT changed name to Adafruit-DHT, which still need pyx support breaking our CI, need to be comment out.

* Update requirements_all.txt
2018-07-30 15:15:13 +01:00
Paulus Schoutsen
5e71f0f0d7 Bumped version to 0.75.0b0 2018-07-30 13:45:43 +02:00
Paulus Schoutsen
be61e2e714 Merge branch 'dev' into rc 2018-07-30 13:45:35 +02:00
Jason Hu
1e5596b594 Remove self type hints (#15732)
* Remove self type hints

* Lint
2018-07-30 12:44:31 +01:00
Dan Faulknor
744c277123 Add other wemo motion sensor identifier (#15627)
* Add other motion sensor identifier

* Fix order
2018-07-30 10:38:49 +02:00
David Straub
460bb69ade Add mvglive option to store multiple departures in attributes (#15454)
* MVG Live sensor: add option to store multiple departures in attributes

* Fix lint error

* mvglive: take into account timeoffset in API call

* Prevent exception if departure list is empty

* Rename state_attributes -> device_state_attributes
2018-07-30 10:32:39 +02:00
Josh Shoemaker
8dbe78a21a Add Genie Aladdin Connect cover component (#15699)
* Add Genie Aladdin Connect cover component

* Fix lines being too long

* Fix issues found in review

* remove Unknown state, use None instead

* Fixed requirements_all
2018-07-30 07:19:34 +02:00
Juha Niemi
3959f82030 Make FutureNow light remember last brightness when turning on (#15733)
* Remember last brightness value and use it on turn_on()

* Pyfnip-0.2 now returns state reliably, no manual changes needed.

* Split too long line of code

* Updated pyfnip library version
2018-07-30 07:09:59 +02:00
starkillerOG
48ba13bc6c Denonavr version push to 0.7.5 (#15743)
* Version push to 0.7.5

Improve logger warning

* Denonavr v.0.7.5
2018-07-29 15:42:23 -07:00
Fabian Affolter
681082a3ad Various updates (#15738) 2018-07-29 23:39:01 +02:00
Fabian Affolter
4013a90f33 Upgrade pyowm to 2.9.0 (#15736) 2018-07-29 23:37:38 +02:00
Fabian Affolter
316ef89541 Upgrade youtube_dl to 2018.07.29 (#15734) 2018-07-29 23:37:10 +02:00
Fabian Affolter
a8dd81e986 Upgrade voluptuous to 0.11.3 (#15735) 2018-07-29 23:36:28 +02:00
Fabian Affolter
4b257c3d01 Upgrade sqlalchemy to 1.2.10 (#15737) 2018-07-29 23:35:47 +02:00
Fabian Affolter
491bc006b2 Upgrade mutagen to 1.41.0 (#15739) 2018-07-29 23:35:27 +02:00
Fabian Affolter
28ad0017e1 Upgrade beautifulsoup4 to 4.6.1 (#15727) 2018-07-29 19:55:49 +02:00
Peter Nijssen
5849381dfb Upgrade spiderpy to 1.2.0 (#15729) 2018-07-29 19:49:36 +02:00
Fabian Affolter
baa974a487 Upgrade numpy to 1.15.0 (#15722) 2018-07-29 08:46:20 +02:00
Fabian Affolter
1a97ba1b46 Upgrade youtube_dl to 2018.07.21 (#15718) 2018-07-29 08:46:06 +02:00
Alexander Hardwicke
1d68f4e279 Command Line Sensor - json_attributes (#15679)
* Add tests to command_line for json_attrs

* Add json_attrs to command_line

* Remove whitespace on blank line

* Stick to <80 row length

* Use collections.Mapping, not dict

* Rename *attrs to *attributes

* Remove extraneous + for string concat

* Test multiple keys

* Add test

Makes sure the sensor's attributes don't contain a value for a missing key,
even if we want that key.

* Test that unwanted keys are skipped

* Remove additional log line

* Update tests for log changes

* Fix ordering
2018-07-29 08:37:34 +02:00
Jonathan Keljo
a2b793c61b Add a component for Sisyphus Kinetic Art Tables (#14472)
* Add a component for Sisyphus Kinetic Art Tables

The [Sisyphus Kinetic Art Table](https://sisyphus-industries.com/) uses a
steel ball to draw intricate patterns in sand, thrown into sharp relief by a
ring of LED lights around the outside.

This component enables basic control of these tables through Home Assistant.

* Fix lints

* Docstrings, other lints

* More lints

* Yet more.

* Feedback

* Lint

* Missed one piece of feedback

* - Use async_added_to_hass in media player
- async_schedule_update_ha_state in listeners
- constants for supported features
- subscripting for required keys
- asyncio.wait
- update to sisyphus-control with passed-in session

* Update requirements

* lint
2018-07-29 07:34:43 +02:00
Jason Hu
93d6fb8c60 Break up components/auth (#15713) 2018-07-28 17:54:26 -07:00
Paulus Schoutsen
c7f4bdafc0 Context (#15674)
* Add context

* Add context to switch/light services

* Test set_state API

* Lint

* Fix tests

* Do not include context yet in comparison

* Do not pass in loop

* Fix Z-Wave tests

* Add websocket test without user
2018-07-28 17:53:37 -07:00
Jens Østergaard Nielsen
867f80715e Remove IHC XML Element from discovery data (#15719) 2018-07-28 19:37:12 +02:00
Alan Fischer
29e668e887 Upgrade pyvera to 0.2.44 (#15708) 2018-07-28 19:17:04 +02:00
JC Connell
944f4f7c05 Add Magicseaweed API support (#15132)
* Added support for magicseaweed surf forecasting

* Added support for magicseaweed surf forecasting

* Added support for magicseaweed surf forecasting

* Incorporate @bachya requested changes.

* Adding support for magicseaweed package.

* Run tests and fix errors.

* Incorporate @balloob requested changes.

* Attempt to fix pylint error e1101.

* Two spaces before inline comments

* Add @MartinHjelmare & @balloob requested changes.

* Remove MagicSeaweedData object inheritance.

* Fix variable logic.
2018-07-27 23:48:56 +02:00
Richard Orr
cd6544d32a Add support for alarm_control_panel to MQTT Discovery. (#15689) 2018-07-27 17:16:49 +02:00
Jason Hu
b2f4bbf93b Only log change to use access token warning once (#15690) 2018-07-27 15:53:46 +02:00
Juha Niemi
a99b4472a8 Add support for P5 FutureNow light platform (#15662)
* Added support for FutureNow light platform and relay/dimmer units

* Pinned specific version for requirement

* Added support for FutureNow light platform and relay/dimmer units

* Added futurenow.py to .coveragerc.

* Minor fixes and enhancements as requested in the code review.

* Minor fixes and enhancements as requested in the code review.

* Use device_config's value directly as it's validated as boolean.

* Simplify state check.

* Fixed brightness update that was broken in previous commit.
2018-07-27 11:11:32 +02:00
Peter Nijssen
33f3e72dda Add spider power plug component (#15682)
* Add spider power plug component

* rounding down the numbers

* ability to throttle the API

* updated to the lastest api

* resolved an issue within the API
2018-07-26 21:43:20 -07:00
Aaron Bach
e30510a688 Fixes a bug with showing a subset of Pollen index conditions (#15694) 2018-07-26 12:31:44 -06:00
Paulus Schoutsen
974fe4d923 Fix frontend tests 2018-07-26 10:25:57 +02:00
Paulus Schoutsen
feb8aff46b Bump frontend to 20180726.0 2018-07-26 09:38:10 +02:00
Ville Skyttä
eee9b50b70 Upgrade pylint to 2.0.1 (#15683)
* Upgrade pylint to 2.0.1

* Pylint 2 bad-whitespace fix

* Pylint 2 possibly-unused-variable fixes

* Pylint 2 try-except-raise fixes

* Disable pylint fixme for todoist for now

https://github.com/PyCQA/pylint/pull/2320

* Disable pylint 2 useless-return for now

https://github.com/PyCQA/pylint/issues/2300

* Disable pylint 2 invalid-name for type variables for now

https://github.com/PyCQA/pylint/issues/1290

* Disable pylint 2 not-an-iterable for now

https://github.com/PyCQA/pylint/issues/2311

* Pylint 2 unsubscriptable-object workarounds

* Disable intentional pylint 2 assignment-from-nones

* Disable pylint 2 unsupported-membership-test apparent false positives

* Disable pylint 2 assignment-from-no-return apparent false positives

* Disable pylint 2 comparison-with-callable false positives

https://github.com/PyCQA/pylint/issues/2306
2018-07-26 08:55:42 +02:00
Jason Hu
9fb8bc8991 Allow Nest Cam turn on/off (#15681)
* Allow Nest Cam turn on/off

* Don't raise Error

* Remove unnecessary state update
2018-07-25 23:17:38 +02:00
Ville Skyttä
1c42caba76 Pylint 2 useless-return fixes (#15677) 2018-07-25 19:35:57 +02:00
Paulus Schoutsen
9d59bfbe00 0.74.2 (#15671)
* Fix CORS duplicate registration (#15670)

* Bumped version to 0.74.2
2018-07-25 13:09:32 +02:00
Eduard van Valkenburg
95dc06cca6 Add Brunt Cover Device (#15653)
* New Brunt Branch

* Some small changes and updates based on review.
2018-07-25 12:17:12 +02:00
Peter Nijssen
9ecbf86fa0 Add spider thermostat (#15499)
* add spider thermostats

* Added load_platform. Added operation dictionary. Minor improvements

* loop over spider components for load_platform

* added empty dict to load_platform. changed add_devices

* moved logic to the API

* fix requirements_all.txt

* minor code improvements
2018-07-25 11:51:48 +02:00
Paulus Schoutsen
588fd1923f Bumped version to 0.74.2 2018-07-25 11:37:17 +02:00
Paulus Schoutsen
2824efd505 Fix CORS duplicate registration (#15670) 2018-07-25 11:37:11 +02:00
Paulus Schoutsen
169c8d793a Fix CORS duplicate registration (#15670) 2018-07-25 11:36:44 +02:00
Ville Skyttä
68f03dcc67 Auth typing improvements (#15640)
* Always return bytes from auth.providers.homeassistant.hash_password

Good for interface cleanliness, typing etc.

* Add some homeassistant auth provider type annotations
2018-07-25 11:36:03 +02:00
Ville Skyttä
397f551e6d Import collections abstract base classes from collections.abc (#15649)
Accessing them directly through collections is deprecated since 3.7, and
will no longer work in 3.8.
2018-07-25 11:35:22 +02:00
Jerad Meisner
cbb5d34167 Added user credentials to current_user ws endpoint. (#15558)
* Added user credentials to current_user ws endpoint.

* Comments. Added another test.

* Return list of credentials.
2018-07-25 10:34:18 +02:00
Daniel Kalmar
0cc9798c8f Allow defining default turn-on values for lights in the profiles file. (#15493)
* Allow defining default turn-on values for lights in the profiles file.

* Mock out file operations in unit test.

* Fix unit test flakiness.

* Avoid unnecessary copy
2018-07-24 20:29:59 +02:00
Jason Hu
45a7ca62ae Add turn_on/off service to camera (#15051)
* Add turn_on/off to camera

* Add turn_on/off supported features to camera.

Add turn_on/off service implementation to camera, add turn_on/off
 supported features and services to Demo camera.

* Add camera supported_features tests

* Resolve code review comment

* Fix unit test

* Use async_add_executor_job

* Address review comment, change DemoCamera to local push

* Rewrite tests/components/camera/test_demo

* raise HTTPError instead return response
2018-07-24 10:13:26 -07:00
Giuseppe
2eb125e90e Downgrade netatmo warning log to info (#15652) 2018-07-24 18:35:57 +02:00
Paulus Schoutsen
264c618b11 Bump frontend to 20180724.0 2018-07-24 14:16:25 +02:00
Paulus Schoutsen
d9cf8fcfe8 Allow changing entity ID (#15637)
* Allow changing entity ID

* Add support to websocket command

* Address comments

* Error handling
2018-07-24 14:12:53 +02:00
Paulus Schoutsen
5e9c1098c0 Merge pull request #15651 from home-assistant/rc
0.74.1
2018-07-24 13:43:25 +02:00
Paulus Schoutsen
d65bd7b7ea Bumped version to 0.74.1 2018-07-24 11:20:13 +02:00
Paulus Schoutsen
45a5ae1f23 Cast/Sonos: create config entry if manually configured (#15630)
* Cast/Sonos: create config entry if manually configured

* Add test for helper
2018-07-24 11:20:07 +02:00
Jason Hu
3eda6db227 Frontend component should auto load auth coomponent (#15606) 2018-07-24 11:20:07 +02:00
Anders Melchiorsen
58f287f551 Use case insensitive comparison for Sonos model check (#15604) 2018-07-24 11:20:07 +02:00
cdce8p
f62f64311d Bugfix HomeKit name and serial_number (#15600)
* Bugfix HomeKit name and serial_number

* Revert serial_number changes
2018-07-24 11:20:06 +02:00
Jan Collijs
fbeaa57604 Update smappy library version (#15636)
Adding latest smappy lib version

Updated smappy library version
2018-07-24 10:41:24 +02:00
huangyupeng
c1f5ead61d Add Tuya cover and scene platform (#15587)
* Add Tuya cover platform

* Add Tuya cover and scene

* fix description

* remove scene default method
2018-07-24 10:29:43 +02:00
Jason Hu
d7690c5fda Add ipban for failed login attempt in new login flow (#15551)
* Add ipban for failed login attempt in new login flow

* Address review comment

* Use decorator to clean up code
2018-07-24 10:09:52 +02:00
Cheong Yip
45c35ceb2b Fix typo asayn_init instead of async_init (#15645) 2018-07-23 20:19:01 -06:00
Daniel Shokouhi
bc481fa366 Update Neato library to allow for dynamic endpoints (#15639) 2018-07-24 00:46:12 +02:00
John Arild Berentsen
1b94fe3613 Add ability to set Zwave protection commandclass (#15390)
* Add API for protection commandclass

* Adjusting

* tests

* Spelling

* Missed flake8

* Period

* spelling

* Review changes

* removing additional .keys()

* period

* Move i/o out into executor pool

* Move i/o out into executor pool

* Forgot get method

* Do it right... I feel stupid

* Long lines

* Merging
2018-07-23 15:31:12 +02:00
Paulus Schoutsen
3204501174 Cast/Sonos: create config entry if manually configured (#15630)
* Cast/Sonos: create config entry if manually configured

* Add test for helper
2018-07-23 15:08:03 +02:00
Pascal Vizeli
f3dfc433c2 Fix aiohttp connection reset errors (#15577)
* Fix aiohttp connection reset errors

* Update aiohttp_client.py

* Update aiohttp_client.py

* Update __init__.py

* Update mjpeg.py

* Update mjpeg.py

* Update ffmpeg.py

* Update ffmpeg.py

* Update ffmpeg.py

* Update proxy.py

* Update __init__.py

* Update aiohttp_client.py

* Update aiohttp_client.py

* Update proxy.py

* Update proxy.py

* Fix await inside coroutine

* Fix async syntax

* Lint
2018-07-23 14:36:36 +02:00
Paulus Schoutsen
8213b1476f WIP: Hass.io sent token to supervisor (#15536)
Hass.io sent token to supervisor
2018-07-23 14:14:57 +02:00
Paulus Schoutsen
4e7dbf9ce5 Allow system users to refresh tokens (#15574) 2018-07-23 14:06:09 +02:00
Paulus Schoutsen
ea2ff6aae3 Use async_create_task (#15633)
* Use async_create_task

* Fix test
2018-07-23 14:05:38 +02:00
starkillerOG
50b6c5948d Suppress error between 00:00 and 01:00 (#15555)
* Suppress error between 00:00 and 01:00

Suppress an error that often occers between 00:00 and 01:00 CE(S)T during that time, probably because buienradar.nl is then updating its forcast for the next day. The API does not always work between these times (in the middle of the night).

* white space & import

* unnecessary brackets
2018-07-23 12:37:23 +02:00
Muhammad Sheraz Lodhi
3acbd5a769 The tense is wrong (#15614)
Instead of spent, we should be using spend :)
2018-07-23 12:31:54 +02:00
Anders Melchiorsen
fddfb9e412 Refresh Sonos source list on changes (#15605) 2018-07-23 12:31:03 +02:00
Anders Melchiorsen
1325682d82 Use case insensitive comparison for Sonos model check (#15604) 2018-07-23 12:29:37 +02:00
Andrey
140a874917 Add typing to homeassistant/*.py and homeassistant/util/ (#15569)
* Add typing to homeassistant/*.py and homeassistant/util/

* Fix wrong merge

* Restore iterable in OrderedSet

* Fix tests
2018-07-23 10:24:39 +02:00
Ville Skyttä
b7c336a687 Pylint cleanups (#15626)
* Pylint 2 no-else-return fixes

* Remove unneeded abstract-class-not-used pylint disable
2018-07-23 10:16:05 +02:00
Ville Skyttä
a38c0d6d15 Upgrade mypy to 0.620 (#15612) 2018-07-22 13:37:26 +02:00
Paulus Schoutsen
75f40ccb06 Remove entity picture of Tuya entity (#15611) 2018-07-22 12:10:32 +02:00
cdce8p
4de847f84e Bugfix HomeKit name and serial_number (#15600)
* Bugfix HomeKit name and serial_number

* Revert serial_number changes
2018-07-22 09:51:42 +02:00
Jason Hu
33f1577dac Frontend component should auto load auth coomponent (#15606) 2018-07-22 09:49:58 +02:00
Anders Melchiorsen
ef3a83048c Throttle unavailability warnings for tplink light/switch (#15591) 2018-07-22 00:51:45 +02:00
Daniel Perna
ae2ee8f006 Update pyhomematic, fixes #15054, #15190 (#15603) 2018-07-22 00:18:50 +02:00
digiblur
6f6d86c700 Add relay addr & chan config to alarmdecoder zones (#15242)
Add relay addr & chan config to alarmdecoder zones
2018-07-21 17:31:07 +02:00
Anders Melchiorsen
d1b16e287c Add unique_id to netgear_lte sensors (#15584) 2018-07-21 10:14:56 +02:00
Ryan Davies
ee8a815e6b Allow MQTT Switch to have an optional state configuration (#15430)
Switches by default use the payload_on and payload_off configuration parameters to specify both the payload the switch should send for a state but also what will be returned for the current state - which isnt always the same
As a toggle switch might always send an ON or TOGGLE to toggle the switch, but still receive an ON or an OFF for the state topic - This change allows for splitting them apart
2018-07-20 23:04:06 +02:00
Paulus Schoutsen
7bc2362e33 Merge branch 'master' into dev 2018-07-20 15:19:06 +02:00
Eugenio Panadero
9a8389060c fix aiohttp InvalidURL exception when fetching media player image (#15572)
* fix aiohttp InvalidURL exception when fetching media player image

The first call for the HA proxy (`/api/media_player_proxy/media_player.kodi?token=...&cache=...`)
is receiving relative urls that are failing, this is a simple fix to precede the base_url when hostname is None.

* fix import location and sort stdlib imports
2018-07-20 15:18:02 +02:00
Paulus Schoutsen
da3366859d Merge pull request #15570 from home-assistant/rc
0.74
2018-07-20 15:11:18 +02:00
Teemu R
200c0a8778 light.tplink: initialize min & max mireds only once, avoid i/o outside update (#15571)
* light.tplink: initialize min & max mireds only once, avoid i/o outside update

* revert the index change

* fix indent, sorry for overwriting your fix, balloob
2018-07-20 14:40:38 +02:00
Teemu R
5cf9cd686c light.tplink: initialize min & max mireds only once, avoid i/o outside update (#15571)
* light.tplink: initialize min & max mireds only once, avoid i/o outside update

* revert the index change

* fix indent, sorry for overwriting your fix, balloob
2018-07-20 14:40:10 +02:00
Paulus Schoutsen
8e659baf25 Bumped version to 0.74.0 2018-07-20 12:44:15 +02:00
Jason Hu
2aa54ce22b Reset failed login attempts counter when login success (#15564) 2018-07-20 12:33:21 +02:00
Paulus Schoutsen
eff334a1d0 Remove relative time from state machine (#15560) 2018-07-20 12:32:45 +02:00
Paulus Schoutsen
b3bed7fb37 Allow auth providers to influence is_active (#15557)
* Allow auth providers to influence is_active

* Fix auth script test
2018-07-20 12:32:44 +02:00
Martin Hjelmare
61b3822374 Upgrade pymysensors to 0.16.0 (#15554) 2018-07-20 12:32:44 +02:00
Paulus Schoutsen
9fb04b5280 Update the frontend to 20180720.0 2018-07-20 12:30:32 +02:00
Paulus Schoutsen
3341c5cf21 Update the frontend to 20180720.0 2018-07-20 12:30:10 +02:00
Jason Hu
f1286f8e6b Reset failed login attempts counter when login success (#15564) 2018-07-20 12:09:48 +02:00
huangyupeng
f2a99e83cd Add Tuya fan support (#15525)
* Add Tuya fan platform

* Add Tuya fan platform

* fix as review required
2018-07-20 11:23:09 +02:00
Ville Skyttä
2f7b79764a More pylint 2 fixes (#15565)
## Description:

More fixes flagged by pylint 2 that don't hurt to have before the actual pylint 2 upgrade (which I'll submit soon).

## Checklist:
  - [ ] The code change is tested and works locally.
  - [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
2018-07-20 11:45:20 +03:00
Paulus Schoutsen
ea18e06b08 Remove relative time from state machine (#15560) 2018-07-19 23:12:17 +02:00
Martin Hjelmare
a0193e8e42 Upgrade pymysensors to 0.16.0 (#15554) 2018-07-19 22:52:03 +02:00
Paulus Schoutsen
2fcacbff23 Allow auth providers to influence is_active (#15557)
* Allow auth providers to influence is_active

* Fix auth script test
2018-07-19 22:10:36 +02:00
William Scanlon
a42288d056 Upgrade to simplisafe-python v2 to use new SimpliSafe API (#15542)
* Upgrade to simplisafe-python v2 to use new SimpliSafe API
2018-07-19 13:13:46 -04:00
Paulus Schoutsen
7aa2a9e506 Bumped version to 0.74.0b4 2018-07-19 12:26:15 +02:00
Paulus Schoutsen
2fc0d83085 Allow CORS requests to token endpoint (#15519)
* Allow CORS requests to token endpoint

* Tests

* Fuck emulated hue

* Clean up

* Only cors existing methods
2018-07-19 12:26:08 +02:00
Paulus Schoutsen
ca0d4226aa Decouple emulated hue from http server (#15530) 2018-07-19 12:25:47 +02:00
Paulus Schoutsen
dff2e4ebc2 Don't be so strict client-side (#15546) 2018-07-19 12:23:14 +02:00
Jerad Meisner
9c337bc621 Added WS endpoint for changing homeassistant password. (#15527)
* Added WS endpoint for changing homeassistant password.

* Remove change password helper. Don't require current password.

* Restore current password verification.

* Added tests.

* Use correct send method
2018-07-19 12:23:14 +02:00
Paulus Schoutsen
5a1360678b Bump frontend to 20180719.0 2018-07-19 10:55:33 +02:00
Paulus Schoutsen
33ee91a748 Bump frontend to 20180719.0 2018-07-19 10:52:28 +02:00
Jerad Meisner
396895d077 Added WS endpoint for changing homeassistant password. (#15527)
* Added WS endpoint for changing homeassistant password.

* Remove change password helper. Don't require current password.

* Restore current password verification.

* Added tests.

* Use correct send method
2018-07-19 09:39:51 +02:00
Paulus Schoutsen
8b04d48ffd Update config entry id in entity registry (#15531) 2018-07-19 08:37:13 +02:00
Paulus Schoutsen
2a76a0852f Allow CORS requests to token endpoint (#15519)
* Allow CORS requests to token endpoint

* Tests

* Fuck emulated hue

* Clean up

* Only cors existing methods
2018-07-19 08:37:00 +02:00
quthla
22d961de70 Update reading when device is added (#15548) 2018-07-18 23:39:37 +02:00
Paulus Schoutsen
4650366f07 Don't be so strict client-side (#15546) 2018-07-18 23:00:26 +02:00
Paulus Schoutsen
7b8ad64ba5 Bumped version to 0.74.0b3 2018-07-18 17:41:36 +02:00
Jason Hu
e64761b15e Disallow use insecure_example auth provider in configuration.yml (#15504)
* Disallow use insecure_example auth provider in configuration.yml

* Add unit test for auth provider config validate
2018-07-18 17:41:22 +02:00
Paulus Schoutsen
61273ff606 Bump frontend to 20180718.0 2018-07-18 17:34:28 +02:00
Paulus Schoutsen
dfe17491f8 Bump frontend to 20180718.0 2018-07-18 17:34:16 +02:00
Giel Janssens
a8c7425e17 Update pyatmo (#15540) 2018-07-18 16:58:45 +02:00
Tom Harris
e5f0da75e2 Mini-Remote events (#15523)
* Add event handler to capture binary sensor on messages

* Log event trigger

* Log event firing

* Capture platform correctly

* Fix test for platform eq binary_sensor

* Create sensor events

* Add light and battery sensors

* Bump insteonplm version to 0.11.6

* Fix naming of BUTTON_PRESSED_STATE_NAME

* Fix naming of fire event methods

* Add logging

* Add DOMAIN definition

* Get state name from plm.devices

* Remove stale reference to button ID

* Fix reference to state name

* Remove incorrect ref to self

* Log remote button pressed event

* Change mode to button_mode and fix values to array

* Rename CONF_MODE to CONF_BUTTON_MODE

* Log platform create with mode

* Properly assign button_mode to track mode

* Implement is_on

* Change mini-remotes to events only

* Remove button_mode config option

* Fix reference to _fire_button_on_off_event

* Bump insteon version to 0.11.7

* Flake8 clean up

* Flake8 cleanup

* Use % format in logging per pylint

* Code review updates

* Resolve conflict

* Lint
2018-07-18 16:11:54 +02:00
fucm
6834e00be6 Add support for Tahoma Soke Sensor (#15441) 2018-07-18 12:38:34 +02:00
John Arild Berentsen
26375a3014 Make RS room thermostat discoverable (#15451)
* Make RS room thermostat discoverable

* Reversed generic type name
2018-07-18 12:20:02 +02:00
Daniel Shokouhi
06c3f756b1 Implement locate service for neato (#15467)
* Implement locate service for neato

* Hound
2018-07-18 12:19:38 +02:00
Mattias Welponer
9c5bbfe96d Cleanup of HomematicIP Cloud code (#15475)
* Check if device supports lowBat and shows it only if battery is low

* Show empty battery icon if lowBat is true

* Default return None

* Sabotage attribute and icon if device has this feature

* Bug fix and cleanup

* Use dedicated function for security state

* Cleanup of sensor attributes and icons

* Empty
2018-07-18 12:19:08 +02:00
Anders Melchiorsen
e427f9ee38 RFC: Only use supported light properties (#15484)
* Only use supported light properties

* Fix tests
2018-07-18 12:18:22 +02:00
Andrey
e62e2bb131 Make sure that only pypi dependencies are used (#15490) 2018-07-18 12:16:27 +02:00
Ville Skyttä
bf17ed0917 More pylint 2 fixes (#15516)
* Pylint 2 useless-import-alias fixes

* Pylint 2 chained-comparison fixes

* Pylint 2 consider-using-get fixes

* Pylint 2 len-as-condition fixes
2018-07-18 11:54:27 +02:00
Pascal Vizeli
058081b1f5 Moon translate (#15498)
* Translate moon

* Create strings.moon.json

* Update moon.py

* Update strings.moon.json

* Update test_moon.py
2018-07-18 10:54:54 +02:00
Paulus Schoutsen
98722e10fc Decouple emulated hue from http server (#15530) 2018-07-18 10:47:06 +02:00
Ville Skyttä
2781796d9c Remove some unused imports (#15529) 2018-07-18 10:46:14 +02:00
Andrey
24d2261060 Add check_untyped_defs (#15510)
* Add check_untyped_defs

* Change to regular if-else
2018-07-18 00:28:44 +02:00
lich
7d7c2104ea Customizable command timeout (#15442)
* Customizable command timeout

* Change string to int

* update the tests. Do the same thing on the binary_sensor.command_line.
2018-07-17 22:58:30 +02:00
Dario Iacampo
4ab502a691 Support latest tplink Archer D9 Firmware version / Device Scanner (#15356)
* Support latest tplink Archer D9 Firmware version / Device Scanner

* tplink integration on pypi package

* initialize the client only once

* remove unnecessary instance attributes
2018-07-17 22:47:32 +02:00
huangyupeng
9292d9255c Add Tuya climate platform (#15500)
* Add Tuya climate platform

* fix as review required

* fix as review required
2018-07-17 20:33:54 +02:00
Jason Hu
2022d39339 Disallow use insecure_example auth provider in configuration.yml (#15504)
* Disallow use insecure_example auth provider in configuration.yml

* Add unit test for auth provider config validate
2018-07-17 19:36:33 +02:00
Ville Skyttä
e31dd4404e Pylint 2 fixes (#15487)
* pylint 2 inline disable syntax fixes

* pylint 2 logging-not-lazy fixes

* pylint 2 consider-using-in fixes

* Revert pylint 2 inline disable syntax fixes addressing unused-imports

Will have a go at removing more unused imports altogether first.
2018-07-17 19:34:29 +02:00
Paulus Schoutsen
5dc29bd2c3 Bumped version to 0.74.0b2 2018-07-17 10:59:07 +02:00
Paulus Schoutsen
20c316bce4 Bump frontend to 20180717.0 2018-07-17 10:58:58 +02:00
Matthew Garrett
8b475f45e9 Update HomeKit module code (#15502)
This fixes a bunch of bugs, including issues with concurrency in devices
that present multiple accessories, devices that insist on the TLV entries
being in the order that Apple use, and handling devices that send headers
and data in separate chunks. This should improve compatibility with
a whole bunch of HomeKit devices.
2018-07-17 10:58:51 +02:00
Paulus Schoutsen
a4318682f7 Add onboarding support (#15492)
* Add onboarding support

* Lint

* Address comments

* Mark user step as done if owner user already created
2018-07-17 10:58:51 +02:00
Paulus Schoutsen
a14d8057ed Add current user WS command (#15485) 2018-07-17 10:58:50 +02:00
Paulus Schoutsen
d2f4bce6c0 Bump frontend to 20180717.0 2018-07-17 10:57:05 +02:00
Paulus Schoutsen
b0a3207454 Add onboarding support (#15492)
* Add onboarding support

* Lint

* Address comments

* Mark user step as done if owner user already created
2018-07-17 10:49:15 +02:00
Matthew Garrett
db3cdb288e Update HomeKit module code (#15502)
This fixes a bunch of bugs, including issues with concurrency in devices
that present multiple accessories, devices that insist on the TLV entries
being in the order that Apple use, and handling devices that send headers
and data in separate chunks. This should improve compatibility with
a whole bunch of HomeKit devices.
2018-07-17 10:06:06 +02:00
Paulus Schoutsen
8797cb78a9 Add current user WS command (#15485) 2018-07-17 09:24:51 +02:00
Luke Fritz
7eb5cd1267 Bump pyarlo==0.2.0, fixes #15486 (#15503) 2018-07-17 07:56:50 +02:00
squirtbrnr
0b2aff61bb Delay setup of waze travel time component (#15455)
* delay setup of component

Copied the necessary lines of code from the google travel time component to fix the setup delay in waze travel time component.  Previously it was only watching the homeassistant start event on the bus, but doing nothing with it.

* Update waze_travel_time.py

* Update waze_travel_time.py
2018-07-16 22:50:56 -06:00
Paulus Schoutsen
55f8b0a2f5 Bumped version to 0.74.0b1 2018-07-16 22:14:51 +02:00
Paulus Schoutsen
bb37300a48 Merge branch 'master' into rc 2018-07-16 22:14:45 +02:00
Paulus Schoutsen
0f12b37977 0.73.2 - security release (#15494)
* Extract SSL context creation to helper (#15483)

* Extract SSL context creation to helper

* Lint

* Bumped version to 0.73.2
2018-07-16 22:13:12 +02:00
Paulus Schoutsen
ad4cba70a0 Extract SSL context creation to helper (#15483)
* Extract SSL context creation to helper

* Lint
2018-07-16 10:32:07 +02:00
Paulus Schoutsen
dd7890c848 Version bump to 0.75.0.dev0 2018-07-16 08:52:37 +02:00
Paulus Schoutsen
7f18739267 Bumped version to 0.74.0b0 2018-07-16 08:51:52 +02:00
Paulus Schoutsen
a1b478b3ac Version bump to 0.74.0.dev0 2018-07-16 08:51:37 +02:00
Paulus Schoutsen
edf1f44668 Bump frontend to 20180716.0 2018-07-16 08:50:21 +02:00
Anders Melchiorsen
60f780cc37 Update limitlessled to 1.1.2 (#15481) 2018-07-15 23:24:35 +02:00
Anders Melchiorsen
7d0cc7e26c Fix flux_led turning on with color or effect (#15472) 2018-07-15 23:18:52 +02:00
Paulus Schoutsen
864a254071 Aware comments (#15480)
* Make sure we cannot deactivate the owner

* Use different error code when trying to fetch token for inactive user
2018-07-15 23:09:05 +02:00
Andrey
5995c6a2ac Switch to own packaged version of pygtfs (#15040) 2018-07-15 21:32:20 +02:00
Paulus Schoutsen
ed0cfc4f31 Add user via cmd line creates owner (#15470)
* Add user via cmd line creates owner

* Ensure access tokens are not verified for inactive users

* Stale print

* Lint
2018-07-15 20:46:15 +02:00
Mattias Welponer
6db069881b Update homematicip_cloud with enum states (#15460)
* Update to next version with enum states

* Change to generic dimmer class

* Update of requirement files

* Update to hmip lib to v0.9.7

* Missing update of requirements files

* Cleanup of icon properties
2018-07-15 02:59:19 +02:00
huangyupeng
ca4f69f557 Add Tuya light platform (#15444)
* add tuya light platform

* fix as review required
2018-07-15 02:48:32 +02:00
Ville Skyttä
37ccf87516 Remove unnecessary executable permissions (#15469) 2018-07-14 23:03:36 +02:00
Tom Harris
201c9fed77 Implement is_on (#15459)
* Implement is_on

* Remove var
2018-07-14 11:04:00 +02:00
Daniel Perna
3b5775573b Add IPPassageSensor (HmIP-SPDR) (#15458) 2018-07-14 02:31:51 +02:00
Jason Antman
6e22a0e4d9 Fix ZWave RGBW lights not producing color without explicit white_value (#15412)
* Fix ZWave RGBW lights not producing color without explicit white_value (#13930)

* simplify conditional in previous commit (#13930)

* ZwaveColorLight - only zero _white if white_value not specified in call (#13930)
2018-07-14 00:54:15 +02:00
Mattias Welponer
ce5b4cd51e Add HomematicIP Cloud dimmer light device (#15456)
* Add dimmable light device

* Add imports

* Fix float and int conversion
2018-07-13 23:25:11 +02:00
Paulus Schoutsen
538236de8f Fix formatting pylint comments in test (#15450) 2018-07-13 23:02:23 +02:00
Fabian Affolter
1007bb83aa Upgrade keyring to 13.2.1 (#15453) 2018-07-13 20:02:13 +02:00
Fabian Affolter
79955a5785 Catch the ValueError if the bulb was in the wrong mode (#15434) 2018-07-13 20:01:57 +02:00
Andrey
e60f9ca392 More typing (#15449)
## Description:

More typing improvements.

Switch to using `mypy.ini` for flexibility

Add `warn_return_any` check except in `homeassistant.util.yaml` that does typing hacks. Fix some type annotations as resulting from this check and ignore others were fixing is hard.

## Checklist:
  - [x] The code change is tested and works locally.
  - [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
2018-07-13 20:14:45 +03:00
Paulus Schoutsen
ae581694ac Bump frontend to 20180713.0 2018-07-13 15:33:33 +02:00
Paulus Schoutsen
70fe463ef0 User management (#15420)
* User management

* Lint

* Fix dict

* Reuse data instance

* OrderedDict all the way
2018-07-13 15:31:20 +02:00
Paulus Schoutsen
84858f5c19 Fix comment formatting (#15447) 2018-07-13 15:05:55 +02:00
Ville Skyttä
a6ba5ec1c8 upgrade-mypy (#14904)
* Upgrade mypy to 0.600

* Upgrade mypy to 0.610

* Typing improvements

* remove unneeded or

* remove merge artifact

* Update loader.py
2018-07-13 13:49:24 +02:00
Andrey
c2fe0d0120 Make typing checks more strict (#14429)
## Description:

Make typing checks more strict: add `--strict-optional` flag that forbids implicit None return type. This flag will become default in the next version of mypy (0.600)

Add `homeassistant/util/` to checked dirs.

## Checklist:
  - [x] The code change is tested and works locally.
  - [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
2018-07-13 13:24:51 +03:00
Paulus Schoutsen
b6ca03ce47 Reorg auth (#15443) 2018-07-13 11:43:08 +02:00
Andrey
23f1b49e55 Add python 3.8-dev to travis and tox (#15347)
* Add Python 3.8-dev tox tests.

* Allow failures on 3.8-dev

* Allow failures on 3.8-dev take2

* Only run on pushes to dev
2018-07-13 11:37:03 +02:00
Jason Hu
6e3ec97acf Include request.path in legacy api password warning message (#15438) 2018-07-13 09:19:13 +02:00
Mattias Welponer
4a6afc5614 Add HomematicIP alarm control panel (#15342)
* Add HomematicIP security zone

* Update access point tests

* Fix state if not armed and coments

* Add comment for the empty state_attributes

* Fix comment

* Fix spelling
2018-07-13 03:57:41 +02:00
Anders Melchiorsen
b557c17f76 Make LimitlessLED color/temperature attributes mutually exclusive (#15298) 2018-07-12 17:17:00 +02:00
Matthew Garrett
c587536547 Ignore some HomeKit devices (#15316)
There are some devices that speak HomeKit that we shouldn't expose. Some
bridges (such as the Hue) provide reduced functionality over HomeKit and
have a functional native API, so should be ignored. We also shouldn't
offer to configure the built-in Home Assistant HomeKit bridge.
2018-07-12 11:52:37 +02:00
Daniel Perna
4c6394b307 Fix HomeMatic variables (#15417)
* Update __init__.py

* Update requirements_all.txt
2018-07-12 11:49:39 +02:00
Paulus Schoutsen
534233388c Merge branch 'master' into dev 2018-07-12 11:47:10 +02:00
huangyupeng
43b31e88ba Add Tuya component and switch support (#15399)
* support for tuya platform

* support tuya platform

* lint fix

* change dependency

* add tuya platform support

* remove tuya platform except switch. fix code as required

* fix the code as review required

* fix as required

* fix a mistake
2018-07-12 10:19:35 +02:00
Marcelo Moreira de Mello
6197fe0121 Change Ring binary_sensor frequency polling to avoid rate limit exceeded errors (#15414) 2018-07-11 09:27:22 +02:00
Paulus Schoutsen
1f6331c69d Fix credentials lookup (#15409) 2018-07-10 20:33:03 +02:00
Philipp Schmitt
fd568d77c7 Fix liveboxplaytv empty channel list (#15404) 2018-07-10 15:51:37 +02:00
Anders Melchiorsen
f32098abe4 Fix confused brightness of xiaomi_aqara gateway light (#15314) 2018-07-10 13:26:42 +02:00
Joakim Sørensen
b65d7daed8 removed unused return (#15402) 2018-07-10 13:19:32 +02:00
Giuseppe
9ea0c409e6 Improve NetAtmo sensors update logic (#14866)
* Added a "last update" sensor that could be used by automations + cosmetic changes

* Improved the update logic of sensor data

The platform is now continuously adjusting the refresh interval
in order to synchronize with the expected next update from the
NetAtmo cloud. This significantly improves reaction time of
automations while keeping the refresh time to the recommended
value (10 minutes).

* Linting

* Incorporated the advanced Throttle class to support adaptive
throttling, as opposed to integrating it in the core framework.

Following code review, it was suggested to implement the
specialised Throttle class in this platform instead of making a
change in the general util package. Except that the required change
(about 4 LoC) is part of the only relevant piece of code of that
class, therefore this commit includes a full copy of the Throttle
class from homeassistant.util, plus the extra feature to support
adaptive throttling.

* Cosmetic changes on the introduced "last updated" sensor

* Alternate implementation for the adaptive throttling

Ensure the updates from the cloud are throttled and adapted to the
last update time provided by NetAtmo, without using the Throttle
decorator. Similar logic and similar usage of a lock to protect
the execution of the remote update.

* Linting
2018-07-10 12:30:48 +02:00
Paulus Schoutsen
2ee62b10bc Bump frontend to 20180710.0 2018-07-10 12:01:52 +02:00
Paulus Schoutsen
dbdd0a1f56 Expire auth code after 10 minutes (#15381) 2018-07-10 11:20:22 +02:00
Robin
df8c59406b Add Facebox teach service (#14998)
* Adds service

* Address pylint

* Update facebox.py

* patch tests

* Update facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Adds total_matched_faces

* Update test_facebox.py

* Update facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Remove fixtures

Removes the fixtures which were causing `setup` to fail, replace with `@patch`

* Fix teach service test and lint issues
2018-07-10 03:11:39 +02:00
Joakim Sørensen
c5a2ffbcb9 Add Cloudflare DNS component. (#15388)
* Add Cloudflare DNS component

* Removed man

* Update .coveragerc

* Update cloudflare.py

* Update cloudflare.py

* Changed records to be required

* Fix typos, update order and other minor changes
2018-07-09 23:11:54 +02:00
hanzoh
e62bb299ff Add new voices to Amazon Polly (#15320) 2018-07-09 23:01:17 +02:00
Daniel Perna
6ee8d9bd65 Update ha-philipsjs to 0.0.5 (#15378)
* Update requirements_all.txt

* Update philips_js.py
2018-07-09 21:35:06 +02:00
Ville Skyttä
14a34f8c4b Remove some unneeded pylint import-error disables (#15386) 2018-07-09 21:34:27 +02:00
Ville Skyttä
3b93fa80be Add httplib2 to h.c.google requirements (#15385) 2018-07-09 21:33:58 +02:00
Paulus Schoutsen
57977bcef3 Bump frontend to 20180709.0 2018-07-09 18:26:51 +02:00
Paulus Schoutsen
0d4841cbea Use IndieAuth for client ID (#15369)
* Use IndieAuth for client ID

* Lint

* Lint & Fix tests

* Allow local IP addresses

* Update comment
2018-07-09 18:24:46 +02:00
Fabian Affolter
f7d7d825b0 Efergy (#15380)
* Update format

* Use string formatting
2018-07-09 14:39:28 +02:00
iliketoprogram14
1d1408b98d Fixed issue 15340. alexa/smart_home module can now skip properties that aren't supported in the current state, eg lowerSetpoint in Heat mode or targetSetpoint in Eco mode for Nest devices. (#15352) 2018-07-09 11:44:50 +02:00
starkillerOG
b9eb0081cd Add sound mode support (#14910)
* Add sound mode support

* continuation line indent

* indentation

* indentation

* Remove option to configure sound_mode_dict

* Sound mode support

- removed the sound_mode_raw propertie because it was not used, (still available through self._sound_mode_raw (as device attribute for automations and diagnostics)

* Detect sound mode support from device

Removed the config option to indicate if sound mode is supported.
Added detection if sound mode is supported from the receiver itself.
Pushed denonavr library to V.0.7.4

* Pushed denonavr to v.0.7.4
2018-07-09 11:39:41 +02:00
Paul Klingelhuber
287b1bce15 Add support for multi-channel enocean switches (D2-01-12 profile) (#14548) 2018-07-09 11:05:25 +02:00
Diogo Gomes
ec3d2e97e8 fix camera.push API overwrite (#15334)
* fix camera.push API overwrite

* dont search in the component dictionary, but in hour own

* remove error message

* hound
2018-07-09 11:04:51 +02:00
Mattias Welponer
1ff329d9d6 Add HomematicIP Cloud light power consumption and energie attributes (#15343)
* Add power consumption and energie attributes

* Fix lint

* Change attribute name and include kwh
2018-07-09 05:37:59 +02:00
sjabby
703d71c064 Frontend: Allow overriding default url when added to home screen (#15368)
Frontend: Allow overriding default url when added to home screen
2018-07-08 22:45:01 +02:00
Paulus Schoutsen
a2a4c633f3 Merge branch 'rc' 2018-07-08 17:35:59 +02:00
Paulus Schoutsen
e6dd4f6e13 Bumped version to 0.73.1 2018-07-08 17:35:30 +02:00
Paulus Schoutsen
b327ea2023 Bump frontend to 20180708.0 2018-07-08 17:31:03 +02:00
Paulus Schoutsen
b333dba875 Bump frontend to 20180708.0 2018-07-08 17:25:15 +02:00
Andrey
02238b6412 Add python 3.7 to travis and tox (#14523)
* Add python 3.7 to travis and tox

* Use pyyaml from github

* Don't version constraints

* Fix version tag

* Change to new pyyaml release

* Python 3.7 requires xenial

* Fix namespace detection

* Use correct RegEx type

* Update pexpect to 4.6

* Use correct validation for dictionaries

* Disable Py37 incompatible packages

* Upgrade all pexpect to 4.6

* Add explicit None as default param
2018-07-07 10:48:02 -04:00
Tommy Jonsson
bd62248841 Add original message as dialogflow_query parameter (#15304)
So you can access for example sessionId as {{ dialogflow_query.sessionId }} in intent templates.
2018-07-07 11:10:43 +02:00
Ville Skyttä
dabbd7bd63 Upgrade pytest to 3.6.3 (#15332) 2018-07-07 11:06:49 +02:00
Fabian Affolter
b5c7afcf75 Upgrade keyring to 13.2.0 (#15322) 2018-07-07 11:06:00 +02:00
Fabian Affolter
f8f8da959a Upgrade youtube_dl to 2018.07.04 (#15323) 2018-07-07 11:05:44 +02:00
Mattias Welponer
9970965718 Add HomematicIP Cloud Config Flow and Entries loading (#14861)
* Add HomematicIP Cloud to config flow

* Inititial trial for config_flow

* Integrations text files

* Load and write config_flow and init homematicip_cloud

* Split into dedicated files

* Ceanup of text messages

* Working config_flow

* Move imports inside a function

* Enable laoding even no accesspoints are defined

* Revert unnecassary changes in CONFIG_SCHEMA

* Better error handling

* fix flask8

* Migration to async for token generation

* A few fixes

* Simplify config_flow

* Bump version to 9.6 with renamed package

* Requirements file

* First fixes after review

* Implement async_step_import

* Cleanup for Config Flow

* First tests for homematicip_cloud setup

* Remove config_flow tests

* Really remove all things

* Fix comment

* Update picture

* Add support for async_setup_entry to switch and climate platform

* Update path of the config_flow picture

* Refactoring for better tesability

* Further tests implemented

* Move 3th party lib inside function

* Fix lint

* Update requirments_test_all.txt file

* UPdate of requirments_test_all.txt did not work

* Furder cleanup in websocket connection

* Remove a test for the hap

* Revert "Remove a test for the hap"

This reverts commit 968d58cba1.

* First tests implemented for config_flow

* Fix lint

* Rework of client registration process

* Implemented tests for config_flow 100% coverage

* Cleanup

* Cleanup comments and code

* Try to fix import problem

* Add homematicip to the test env requirements
2018-07-06 17:05:34 -04:00
Paulus Schoutsen
a1d8b0e9b3 Merge pull request #15330 from home-assistant/rc
0.73
2018-07-06 16:41:09 -04:00
Paulus Schoutsen
1e7cfc04af Bumped version to 0.73.0 2018-07-06 22:31:09 +02:00
Luke Fritz
0f1bcfd63b Add additional sensors for Arlo Baby camera (#15074)
* Add additional sensors for Arlo Baby camera

* Fix linter errors

* Fix linter error

* Add tests for Arlo sensors

* Fix linter errors

* Bump pyarlo dependency to 0.1.9

* Remove unnecessary AttributeError except

* Fix module reference error in py35

* Fix test

* Address PR review concerns

* Convert to standalone pytest methods

* Fix linter errors

* Fix linter errors

* Fix linter errors

* Fix test

* Remove redundant check, fix async test

* Fix linter error

* Added check for total_cameras sensor, added additional attribute tests

* Add missing docstring
2018-07-06 10:26:03 +02:00
Aaron Bach
f65c3940ae Fix exception when parts of Pollen.com can't be reached (#15296)
Fix exception when parts of Pollen.com can't be reached
2018-07-04 17:30:15 -06:00
Paulus Schoutsen
46de89e1a3 Bumped version to 0.73.0b6 2018-07-04 12:11:52 -04:00
Paulus Schoutsen
852526e10a Bump frontend to 20180704.0 2018-07-04 12:11:39 -04:00
Paulus Schoutsen
91d6d0df84 Bump frontend to 20180704.0 2018-07-04 12:11:24 -04:00
Paulus Schoutsen
cb129bd207 Add system generated users (#15291)
* Add system generated users

* Fix typing
2018-07-04 11:50:08 -04:00
Marcelo Moreira de Mello
a6e9dc81aa Added support to HTTPS URLs on SynologyDSM (#15270)
* Added support to HTTPS URLs on SynologyDSM

* Bumped python-synology to 0.1.1

* Makes lint happy

* Added attribution to Synology and fixed 3rd library version

* Fixed requirements_all.txt

* Makes SynologyDSM defaults to 5001 using SSL
2018-07-04 07:46:01 +02:00
Diogo Gomes
5f7ac09a74 Added Push Camera (#15151)
* Added push camera

* add camera.push

* Address comments and add tests

* auff auff

* trip time made no sense

* travis lint

* Mock dependency

* hound

* long line

* long line

* better mocking

* remove blank image

* no more need to mock dependency

* remove import

* cleanup

* no longer needed

* unused constant

* address @pvizeli review

* add force_update

* Revert "add force_update"

This reverts commit e203785ea8.

* rename parameter
2018-07-04 07:44:47 +02:00
cdce8p
42775142f8 Fix yeelight light brightness integer (#15290) 2018-07-03 20:50:13 -06:00
Aaron Bach
2525fc52b3 Update Tile platform to be async (#15073)
* Updated

* Updated requirements

* Added expired session handling

* Changes

* Member-requested changes

* Bump to 2.0.2

* Bumping requirements

* Better exception handling and tidying

* Move asyncio stuff to HASS built-ins

* Revising re-initi

* Hound

* Hound
2018-07-03 20:41:54 -06:00
Paulus Schoutsen
07dde62e70 Bumped version to 0.73.0b5 2018-07-03 14:58:31 -04:00
Paulus Schoutsen
cb458b7745 Bump frontend to 20180703.1 2018-07-03 14:58:27 -04:00
Paulus Schoutsen
b2df199674 Bump frontend to 20180703.1 2018-07-03 14:51:57 -04:00
Paulus Schoutsen
857c58c4b7 Disable the calendar panel (#15282) 2018-07-03 13:20:42 -04:00
Paulus Schoutsen
b82371f44b Bumped version to 0.73.0b4 2018-07-03 11:11:14 -04:00
Paulus Schoutsen
1c525968d1 Bump frontend to 20180703.0 2018-07-03 11:10:07 -04:00
Paulus Schoutsen
5ec61e4649 Bump frontend to 20180703.0 2018-07-03 11:03:23 -04:00
Andrey
184d0a99c0 Switch to own packaged version of suds-passworddigest (#15261) 2018-07-03 12:43:24 +02:00
Fabian Affolter
232f56de62 Add support for new API (fixes #14911) (#15279) 2018-07-03 12:30:56 +02:00
Diogo Gomes
66e33c7979 Merge pull request #13390 from nielstron/filter-band-pass
Adds a range filter to the Filter Sensor
2018-07-03 11:01:34 +01:00
nielstron
6420ab5535 Remove default none from filter sensor 2018-07-03 11:06:52 +02:00
Fabian Affolter
ed3fe1cc6f Add isort configuration (#15278) 2018-07-03 09:47:14 +02:00
pepeEL
cd1cfd7e8e New device to support option MY in somfy (#15272)
New device to support option MY in somfy
2018-07-03 08:39:42 +02:00
Paul Stenius
31e23ebae2 expose climate current temperature in prometeus metrics (#15232)
* expose climate current temperature in prometeus metrics

* import ATTR_CURRENT_TEMPERATURE from climate instead of const

* remove duplicated ATTR_CURRENT_TEMPERATURE from const

* fix ATTR_CURRENT_TEMPERATURE import
2018-07-02 18:03:46 -04:00
nielstron
fb65276daf Remove math.inf as bounds 2018-07-03 00:00:46 +02:00
Robert Svensson
bedd2d7e41 deCONZ - new sensor attribute 'on' and new sensor GenericFlag (#15247)
* New sensor attribute 'on'
* New sensor GenericFlag
2018-07-02 23:14:38 +02:00
Fabian Affolter
120111ceee Upgrade keyring to 13.1.0 (#15268) 2018-07-02 23:03:56 +02:00
shker
e6390b8e41 Fix python-miio 0.4 compatibility of the xiaomi miio device tracker (#15244) 2018-07-02 22:33:40 +02:00
Paulus Schoutsen
d7fd9247a9 Bumped version to 0.73.0b3 2018-07-02 14:44:15 -04:00
Paulus Schoutsen
0dc155c4d3 Bump frontend to 20180702.1 2018-07-02 14:44:11 -04:00
Paulus Schoutsen
0feb4c5439 Bump frontend to 20180702.1 2018-07-02 14:43:31 -04:00
Diogo Gomes
f3588a8782 Update image_processing async (#15082)
* scan() -> async_job

* added async_scan
2018-07-02 16:57:52 +02:00
William Scanlon
2145ac5e46 Added support for Duke Energy smart meters (#15165)
* Added support for Duke Energy smart meters

* Fixed hound

* Added function docstring

* Moved strings to constants, implemented unique_id, and cleaned up setup.

* Added doc string.

* Fixed review issues.

* Updated pydukenergy to 0.0.6 and set update interval to 2 hours

* Updated requirements_all
2018-07-02 16:55:34 +02:00
Paulus Schoutsen
c39e6b9618 Bumped version to 0.73.0b2 2018-07-02 08:57:26 -04:00
Paulus Schoutsen
855cbc0aed Update frontend to 20180702.0 2018-07-02 08:56:45 -04:00
Paulus Schoutsen
00c366d7ea Update frontend to 20180702.0 2018-07-02 08:56:37 -04:00
Paulus Schoutsen
3c3a53a137 Update translations 2018-07-02 08:53:47 -04:00
Paulus Schoutsen
dd59054003 Update translations 2018-07-02 08:53:33 -04:00
David Worsham
36f566a529 Fix Roomba exception (#15262)
* Fix Roomba exception

* Switch to single quotes
2018-07-02 14:12:25 +02:00
Ville Skyttä
4d93a9fd38 Pass tox posargs to pylint (#15226) 2018-07-02 12:47:20 +03:00
Klaudiusz Staniek
d3df96a8de Added setting cover tilt position in scene (#15255)
## Description:
This feature adds possibly of setting tilt_position in scene for covers.

**Related issue (if applicable):** fixes #<home-assistant issue number goes here>

**Pull request in [home-assistant.github.io](https://github.com/home-assistant/home-assistant.github.io) with documentation (if applicable):** home-assistant/home-assistant.github.io#<home-assistant.github.io PR number goes here>

## Example entry for `configuration.yaml` (if applicable):
```yaml
scene:
  - name: Close Cover Tilt
    entities:
      cover.c_office_north:
        tilt_position: 0

  - name: Open Cover Tilt
    entities:
      cover.c_office_north:
        tilt_position: 100
```

## Checklist:
  - [x] The code change is tested and works locally.
  - [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**

If user exposed functionality or configuration variables are added/changed:
  - [ ] Documentation added/updated in [home-assistant.github.io](https://github.com/home-assistant/home-assistant.github.io)

If the code communicates with devices, web services, or third-party tools:
  - [ ] New dependencies have been added to the `REQUIREMENTS` variable ([example][ex-requir]).
  - [ ] New dependencies are only imported inside functions that use them ([example][ex-import]).
  - [ ] New or updated dependencies have been added to `requirements_all.txt` by running `script/gen_requirements_all.py`.
  - [ ] New files were added to `.coveragerc`.

If the code does not interact with devices:
  - [ ] Tests have been added to verify that the new code works.

[ex-requir]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard.py#L14
[ex-import]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard.py#L54
2018-07-02 12:44:36 +03:00
Andrey
6c77702dcc Switch to own packaged version of pylgnetcast (#15042)
## Description:

Switch to own packaged version of pylgnetcast

Request to make a pypi package didn't get any response: https://github.com/wokar/pylgnetcast/issues/1

**Related issue (if applicable):** #7069
2018-07-02 10:57:26 +03:00
Steven Conaway
86165750ff Fix typo in Docker files (#15256) 2018-07-02 07:02:09 +02:00
Jason Hu
63b28aa39d By default to use access_token if hass.auth.active (#15212)
* Force to use access_token if hass.auth.active

* Not allow Basic auth with api_password if hass.auth.active

* Block websocket api_password auth when hass.auth.active

* Add legacy_api_password auth provider

* lint

* lint
2018-07-01 21:53:38 -04:00
Paulus Schoutsen
279fd39677 Bumped version to 0.73.0b1 2018-07-01 13:40:55 -04:00
cdce8p
c978281d1e Revert some changes to setup.py (#15248) 2018-07-01 13:40:48 -04:00
Jason Hu
311a44007c Fix an issue when user's nest developer account don't have permission (#15237) 2018-07-01 13:40:48 -04:00
Anders Melchiorsen
47401739ea Make LIFX color/temperature attributes mutually exclusive (#15234) 2018-07-01 13:40:48 -04:00
Jason Hu
11ba7cc8ce Only create front-end client_id once (#15214)
* Only create frontend client_id once

* Check user and client_id before create refresh token

* Lint

* Follow code review comment

* Minor clenaup

* Update doc string
2018-07-01 13:40:47 -04:00
Andy Castille
c3ad30ec87 Rachio webhooks (#15111)
* Make fewer requests to the Rachio API

* BREAKING: Rewrite Rachio component
2018-07-01 13:40:47 -04:00
Jason Hu
a64a66dd62 Only create front-end client_id once (#15214)
* Only create frontend client_id once

* Check user and client_id before create refresh token

* Lint

* Follow code review comment

* Minor clenaup

* Update doc string
2018-07-01 13:36:50 -04:00
Anders Melchiorsen
dffe36761d Make LIFX color/temperature attributes mutually exclusive (#15234) 2018-07-01 13:06:30 -04:00
Jason Hu
0a186650bf Fix an issue when user's nest developer account don't have permission (#15237) 2018-07-01 13:04:12 -04:00
Fabian Affolter
6c77c9d372 Upgrade WazeRouteCalculator to 0.6 (#15251) 2018-07-01 13:02:02 -04:00
Fabian Affolter
4a4b9180d8 Upgrade sqlalchemy to 1.2.9 (#15250) 2018-07-01 13:01:48 -04:00
Paulus Schoutsen
5d6db9a915 Bump frontend to 20180701.0 2018-07-01 13:00:48 -04:00
Paulus Schoutsen
235282e335 Bump frontend to 20180701.0 2018-07-01 13:00:34 -04:00
Ville Skyttä
6f582dcf24 Lint cleanups (#15243)
* Remove some unused imports

* Fix a flake8 E271
2018-07-01 11:57:01 -04:00
Andy Castille
9db8759317 Rachio webhooks (#15111)
* Make fewer requests to the Rachio API

* BREAKING: Rewrite Rachio component
2018-07-01 11:54:51 -04:00
David Thulke
136cc1d44d allow extra slot values in intents (#15246) 2018-07-01 11:51:40 -04:00
cdce8p
4c258ce08b Revert some changes to setup.py (#15248) 2018-07-01 11:48:54 -04:00
Leonardo Brondani Schenkel
3c04b0756f deconz: proper fix light.turn_off with transition (#15227)
Previous commit d4f7dfa successfully fixed the bug in which lights
would not turn off if a transition was specified, however if 'bri' is not
present in the payload of the PUT request set to deCONZ, then any
'transitiontime' ends up being ignored. This commit addresses the
unintended side effect by reintroducing 'bri', resulting in the following
payload:

{ "on": false, "bri": 0, "transitiontime": ... }
2018-07-01 12:32:48 +02:00
Yevgeniy
c0229ebb77 Add precipitations to Openweathermap daily forecast mode (#15240)
* Add precipitations to daily forecast mode

* Remove line breaks
2018-07-01 11:54:24 +02:00
Ville Skyttä
cfe7c0aa01 Upgrade pytest to 3.6.2 (#15241) 2018-07-01 10:40:23 +02:00
Jason Hu
f874efb224 By default to use access_token if hass.auth.active (#15212)
* Force to use access_token if hass.auth.active

* Not allow Basic auth with api_password if hass.auth.active

* Block websocket api_password auth when hass.auth.active

* Add legacy_api_password auth provider

* lint

* lint
2018-06-30 22:31:36 -04:00
cdce8p
3da4642194 Use async syntax for cover platforms (#15230) 2018-06-30 18:10:59 +02:00
Fabian Affolter
0aad056ca7 Fix typos (#15233) 2018-06-30 17:12:00 +02:00
Carl Chan
c5ceb40598 Add additional parameters to NUT UPS sensor (#15066)
* Update nut.py

Added input.frequency and a number of output parameters.

* Update nut.py

Fixed formatting issues
Added "devices" fields

* Separated "device.description" line to two lines.

* Update nut.py

Removed device.* sensors
2018-06-30 14:57:48 +02:00
pepeEL
27a37e2013 Add new RTS device (#15116)
* Add new RTS device

Add new RTS Somfy device as cover-ExteriorVenetianBlindRTSComponent

* add next device

add next device
2018-06-30 14:56:43 +02:00
Leonardo Brondani Schenkel
10d1e81f10 deconz: fix light.turn_off with transition (#15222)
When light.turn_off is invoked with a transition, the following payload was
sent to deCONZ via PUT to /light/N/state:

{ "bri": 0, "transitiontime": transition }

However, on recent versions of deCONZ (latest is 2.05.31 at the time of
writing) this does not turn off the light, just sets it to minimum brightness
level (brightness is clamped to minimum level the light supports without
turning it off).

This commit makes the code send this payload instead:

{ "on": false, "transitiontime": transition }

This works as intended and the light does transition to the 'off' state.
This change was tested with Philips Hue colored lights, IKEA colored lights
and IKEA white spectrum lights: they were all able to be turned off
successfully with the new payload, and none of them could be turned off with
the old payload.
2018-06-30 00:59:10 +02:00
Paulus Schoutsen
56bbadb501 Version bump to 0.73.0b0 2018-06-29 18:06:32 -04:00
Paulus Schoutsen
fa79aead9a Bumped version to 0.74.0b0 2018-06-29 18:04:00 -04:00
Paulus Schoutsen
24fec3e826 Merge remote-tracking branch 'origin/master' into dev 2018-06-29 18:01:40 -04:00
Daniel Shokouhi
2524dca7bf Use cached states for neato when possible (#15218) 2018-06-29 17:27:18 -04:00
Sebastian Muszynski
56f17b8651 Fix 'AirQualityMonitorStatus' object has no attribute ‘time_state’ (#15216) 2018-06-29 17:26:48 -04:00
Vignesh Venkat
49623d2dad Update python-wink to 1.9.1 (#15215)
Fixes a bug for when GE Z-Wave fan speeds are adjusted using the
wink app.
2018-06-29 17:26:06 -04:00
Anders Melchiorsen
66479dc2e5 Update eternalegypt (#15180)
* Update eternalegypt to 0.0.2

* Share websession

* Renames
2018-06-29 17:25:49 -04:00
Paulus Schoutsen
bbbec5a056 Bump frontend to 20180629.1 2018-06-29 17:21:54 -04:00
Hmmbob
94b55efef3 Stop supporting deprecated TLS ciphers (#15217)
* Stop supporting deprecated TLS ciphers

* Lint
2018-06-29 17:18:44 -04:00
Colin O'Dell
fd38caa287 X-Forwarded-For improvements and bug fixes (#15204)
* Use new trusted_proxies setting for X-Forwarded-For whitelist

* Only use the last IP in the header

Per Wikipedia (https://en.wikipedia.org/wiki/X-Forwarded-For#Format):

 > The last IP address is always the IP address that connects to the last proxy,
 > which means it is the most reliable source of information.

* Add two additional tests

* Ignore nonsense header values instead of failing
2018-06-29 16:27:06 -04:00
Sriram Vaidyanathan
c61a652c90 Fixed Indentation error (#15210)
* Fixed Indentation error

* Update xiaomi.py
2018-06-29 16:23:14 +02:00
cdce8p
e3e014bccc Fix zwave climate operation mode mappings (#15162) 2018-06-29 16:09:46 +02:00
Paulus Schoutsen
26590e244c Migrate home assistant auth provider to use storage helper (#15200) 2018-06-29 00:02:45 -04:00
Paulus Schoutsen
39971ee919 Make sure we check access token expiration (#15207)
* Make sure we check access token expiration

* Use correct access token websocket
2018-06-29 00:02:33 -04:00
Paulus Schoutsen
2205090795 Storage auth (#15192)
* Support parallel loading

* Add storage mock

* Store auth

* Fix tests
2018-06-28 22:14:26 -04:00
Alex Barcelo
a277470363 Adding 'namespace' for prometheus metrics (#13738)
* Updating prometheus client version

* Using `entity_filter` as filter mechanism

* New optional `namespace` configuration
2018-06-28 16:49:33 +02:00
Colin O'Dell
19f2bbf52f Only use the X-Forwarded-For header if connection is from a trusted network (#15182)
See https://github.com/home-assistant/home-assistant/issues/14345#issuecomment-400854569
2018-06-28 09:16:11 -04:00
Pascal Vizeli
dbb786c548 DarkSky weather / Fix states (#15174)
* DarkSky weather / Fix states

* fix lint

* fix tests
2018-06-28 12:23:32 +02:00
Daniel Shokouhi
4fbe3bb070 Finalize BotVac D7 Support And Further Reduce Cloud Calls (#15161)
* Finalize BotVac D7 Support And Further Reduce Cloud Calls

* Lint

* Lint Again

* Implement requested changes

* Hound

* Lint
2018-06-27 22:55:27 +02:00
MizterB
9066ac44fe Philips Hue Scene Activation: Simplified scene lookup logic, improved error handling (#15175)
* Simplified scene lookup logic, improved error handling

* Lint
2018-06-27 15:22:29 -04:00
Paulus Schoutsen
742144f401 Warn when using custom components (#15172)
* Warn when using custom components

* Update text
2018-06-27 15:21:32 -04:00
Paulus Schoutsen
c0b6a857f7 Version bump to 20180627.0 2018-06-27 14:20:24 -04:00
Tom Harris
d6dee62c92 Add Mini remote support to insteon_plm (#15152)
* Add mini-remote

* Bump insteonplm version to 0.11.3 to support mini-remotes
2018-06-27 12:19:56 +02:00
Fabian Affolter
41017f10a3 Upgrade sendgrid to 5.4.1 (#15166) 2018-06-27 12:12:02 +02:00
Fabian Affolter
ba50a5c329 Upgrade keyring to 13.0.0 (#15167) 2018-06-27 12:11:41 +02:00
Fabian Affolter
4208bb457d Upgrade youtube_dl to 2018.06.25 (#15168) 2018-06-27 12:11:26 +02:00
Matt Snyder
15af6b1ad9 Address inconsistent behavior on flux_led component (#14713)
* Address inconsistent behavior between different controllers.
Correct issue with comparison that was preventing white value slider from being shown.

* Add white mode for Flux LED

* Call _bulb.turnOn() after bulb properties have been set to prevent immediate on action

* Only use existing brightness if rgb is None to prevent unexpected recalculation of passed rgb values.

* Remove blank line

* Undo change so current brightness is used in all cases.
2018-06-26 21:23:57 +02:00
Robert Kiss
3921dc77a6 Add SSL peer certificate support to HTTP server (#15043)
* adding SSL peer certificate support to HTTP server

* remove unnecessary exception block
2018-06-26 11:44:08 -04:00
Matt LeBrun
0094fd5c34 Add channel changing support to SamsungTV component (#14451)
Add channel changing support to SamsungTV component
2018-06-26 16:22:10 +02:00
Paulus Schoutsen
d58e401812 Merge pull request #15149 from home-assistant/rc
0.72.1
2018-06-25 17:25:44 -04:00
Paulus Schoutsen
c79c94550f Return None to indicate no config found (#15147)
* Return None to indicate no config found

* Fix tests
2018-06-25 17:21:38 -04:00
Paulus Schoutsen
9b950f5192 Bumped version to 0.72.1 2018-06-25 16:59:14 -04:00
Jason Hu
2520fddbdf Bump python-nest to 4.0.3 (#15098)
Resolve network reconnect issue
2018-06-25 16:59:00 -04:00
Paulus Schoutsen
3f21966ec9 Fix cast config (#15143) 2018-06-25 16:58:27 -04:00
Jason Hu
69502163bd Skip nest security state sensor if no Nest Cam exists (#15112) 2018-06-25 16:57:27 -04:00
Aaron Bach
893e0f8db6 Fix socket bug with Yi in 0.72 (#15109)
* Fixes BrokenPipeError exceptions with Yi (#15108)

* Make sure to close the socket
2018-06-25 16:57:26 -04:00
Jason Hu
1c8b52f630 Prevent Nest component setup crash due insufficient permission. (#14966)
* Prevent Nest component setup crash due insufficient permission.

* Trigger CI

* Better error handle and address code review comments

* Lint

* Tiny wording adjust

* Notify user if async_setup_entry failed

* Return False if exception occurred in NestDevice.initialize
2018-06-25 16:57:26 -04:00
Jason Hu
6e4fb7a937 Prevent Nest component setup crash due insufficient permission. (#14966)
* Prevent Nest component setup crash due insufficient permission.

* Trigger CI

* Better error handle and address code review comments

* Lint

* Tiny wording adjust

* Notify user if async_setup_entry failed

* Return False if exception occurred in NestDevice.initialize
2018-06-25 16:06:00 -04:00
Paulus Schoutsen
ab1939f56f Bump frontend to 20180625.0 2018-06-25 16:04:30 -04:00
Paulus Schoutsen
15507df407 Bump frontend to 20180625.0 2018-06-25 16:04:17 -04:00
Paulus Schoutsen
46ea28a4f8 Fix cast config (#15143) 2018-06-25 15:59:05 -04:00
Sriram Vaidyanathan
c8458fd7c5 Update xiaomi.py (#15136)
* Update xiaomi.py

Minor logic fix for Xiaofang cameras.

* Removed whitespace

* Removed whitespace
2018-06-25 13:14:36 -04:00
Jason Hu
e681a7929c Skip nest security state sensor if no Nest Cam exists (#15112) 2018-06-25 13:13:41 -04:00
Martin Hjelmare
b2d37ccef6 Fix mysensors climate supported features (#15110) 2018-06-25 13:06:12 -04:00
Luc Touraille
9dd2c36de4 Update aiofreepybox to fix HTTPS connection issues (#15104)
The previous version of aiofreepybox was not working with custom
domain names, which uses a Let's Encrypt certificates. Also, it
was not working with the default domain name when connecting to
Freebox v6. This should be fixed in aiofreepybox 0.0.4.

See https://github.com/stilllman/freepybox/pull/1,
https://github.com/stilllman/freepybox/pull/3 and
https://github.com/stilllman/freepybox/issues/2 for more info.
2018-06-25 13:05:33 -04:00
Ville Skyttä
b92350fb55 Lint cleanup (#15103)
* Remove unneeded inline pylint disables

* Remove unneeded noqa's

* Use symbol names instead of message ids in inline pylint disables
2018-06-25 13:05:07 -04:00
Jason Hu
6c0fc65eaf Bump python-nest to 4.0.3 (#15098)
Resolve network reconnect issue
2018-06-25 13:04:32 -04:00
Pascal Vizeli
42ba2a68ce Revert "Add language to dark sky weather component" (#15142)
* Revert "Fix #14919. Should throw exception when camera stream closed by frontend (#15028)"

This reverts commit 508d0459a7.

* Revert "Fix pylintrc section order and option placements (#15120)"

This reverts commit dbae410cf4.

* Revert "Add storage helper and migrate config entries (#15045)"

This reverts commit ae51dc08bf.

* Revert "Add language to dark sky weather component (#15130)"

This reverts commit 672a3c7178.
2018-06-25 19:04:07 +02:00
Jason Hu
508d0459a7 Fix #14919. Should throw exception when camera stream closed by frontend (#15028)
* Fix #14919. Should throw exception when camera stream closed by frontend

* Re-trigger CI

* pythonic re-raise
2018-06-25 13:03:39 -04:00
Ville Skyttä
dbae410cf4 Fix pylintrc section order and option placements (#15120) 2018-06-25 12:55:03 -04:00
Paulus Schoutsen
ae51dc08bf Add storage helper and migrate config entries (#15045)
* Add storage helper

* Migrate config entries to use the storage helper

* Make sure tests do not do I/O

* Lint

* Add versions to stored data

* Add more instance variables

* Make migrator load config if nothing to migrate

* Address comments
2018-06-25 12:53:49 -04:00
Pascal Vizeli
672a3c7178 Add language to dark sky weather component (#15130)
* Add language to dark sky weather component

* Update darksky.py
2018-06-25 08:35:44 -06:00
cdce8p
f8bc3411ad PyPi: Fix description and setup.cfg (#15107)
* Fix description and extend use of setup.cfg

* Fix lint
2018-06-25 09:57:26 -04:00
Adam Mills
038168c417 Support for Homekit Controller climate devices (#15057)
* Support for Homekit Controller climate devices

* Handle stale state when operating mode off
2018-06-25 09:45:26 -04:00
dreizehnelf
73034c933e Add discovery support to mqtt climate component. (#15085)
* Add discovery support to mqtt climate component.

* - Fix flake8 error (./homeassistant/components/climate/mqtt.py:130:1: D202 No blank lines allowed after function docstring)
- Fix test error (since climate component was expected not to work - changed it to "lock" component, which also does not have MQTT discovery support yet)

* Fix old assert statement to reflect new lock component usage

* Change invalid MQTT discovery component type from 'lock' to 'timer', since contrary to the documentation the lock component is properly supported when using MQTT discovery.

* Make configuration of invalid MQTT config component a single point of entry to prevent missing the assertion later in the code when changing.

* Add new testcases to cover not-yet-covered code paths in https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/climate/mqtt.py
2018-06-25 15:13:19 +02:00
b3nj1
d3ceb9080c MQTT Alarm Control Panel: add retain option for publishing for cases... (#15134)
* MQTT Alarm Control Panel: add retain option for publishing for cases where receiver is asleep

* MQTT Alarm Control Panel: add retain option for publishing for cases where receiver is asleep

* MQTT Alarm Control Panel: add retain option for publishing for cases where receiver is asleep
2018-06-25 14:04:16 +02:00
Martin Hjelmare
3893d8a876 Reorganize mysensors (#15123)
* Move mysensors.py to package

* Move mysensors component to package

* Split code into multiple modules.

* Update coveragerc
2018-06-25 13:58:16 +02:00
Tom Harris
05924a2868 Bump insteonplm version to 0.11.2 (#15133)
* Bump insteonplm version to 0.11.2

* Gratuitous commit to force travis again.

* Reverse change made to force Travis CI
2018-06-25 13:46:55 +02:00
Aaron Bach
021d08a9c4 Make sure Yi utilizes existing event loop (#15131) 2018-06-24 19:09:08 -06:00
Robert Svensson
5a71a22fb9 deCONZ small improvements (#15128)
* Make sure that bridge id is available for config entry

* Fix so deconz reports proper color values

* Bump dependency to v39
2018-06-24 15:48:59 -06:00
Aaron Bach
6064932e2e Make Pollen.com platform async (#14963)
* Most of the work in place

* Final touches

* Small style updates

* Owner-requested changes

* Member-requested changes
2018-06-24 11:04:31 -06:00
Marcelo Moreira de Mello
9de7034d0e Added attribute attribution to Digital Ocean component (#15114) 2018-06-24 13:36:27 +02:00
Andrey
96d5684a89 Switch to pypi version of pybotvac (#15115) 2018-06-24 11:06:25 +02:00
Aaron Bach
91962e2681 Fix socket bug with Yi in 0.72 (#15109)
* Fixes BrokenPipeError exceptions with Yi (#15108)

* Make sure to close the socket
2018-06-23 13:22:48 -06:00
Paulus Schoutsen
ee31f89049 Merge branch 'master' into dev 2018-06-22 13:40:53 -04:00
Paulus Schoutsen
370c3f28b8 Merge pull request #15088 from home-assistant/rc
0.72
2018-06-22 13:38:44 -04:00
Paulus Schoutsen
66110a7d57 Bump frontend to 20180622.1 2018-06-22 12:48:01 -04:00
Paulus Schoutsen
c419cbb46f Bump frontend to 20180622.1 2018-06-22 12:46:45 -04:00
Paulus Schoutsen
a02d7989d5 Use older syntax for version bump 2018-06-22 11:07:26 -04:00
Paulus Schoutsen
7325847fa9 Bumped version to 0.72.0 2018-06-22 10:24:45 -04:00
Paulus Schoutsen
124495dd84 Update frontend to 20180622.0 2018-06-22 10:24:38 -04:00
Paulus Schoutsen
0c01f3a0fe Update frontend to 20180622.0 2018-06-22 10:24:04 -04:00
Paulus Schoutsen
0ea2d99910 Bumped version to 0.72.0b9 2018-06-21 17:39:02 -04:00
Paulus Schoutsen
6456f66b47 Frontend bump to 20180621.2 2018-06-21 17:38:57 -04:00
Paulus Schoutsen
94eee6d069 Frontend bump to 20180621.2 2018-06-21 17:38:44 -04:00
Paulus Schoutsen
6e5a2a77ab Bumped version to 0.72.0b8 2018-06-21 17:27:08 -04:00
Paulus Schoutsen
35b609dd8b Allow writing commit with version bump 2018-06-21 17:27:01 -04:00
Paulus Schoutsen
0df99f8762 Bump frontend to 20180621.1 2018-06-21 17:22:08 -04:00
Paulus Schoutsen
6781ecf159 Bump frontend to 20180621.1 2018-06-21 17:15:16 -04:00
Paulus Schoutsen
a4b843eb2d Version bump to 0.72.0b7 2018-06-21 15:02:29 -04:00
Daniel Shokouhi
302717e8a1 Update Neato Library And Reduce Cloud Calls (#15072)
* Update Neato library to 0.0.6 and reduce the amount of calls to the cloud

* Remove file commited in error

* Lint
2018-06-21 15:02:13 -04:00
Bob Clough
617647c5fd Fix MQTT Light with RGB and Brightness (#15053)
* Fix MQTT Light with RGB and Brightness

When an MQTT light is given an RGB and Brightness topic, the RGB
is scaled by the brightness *as well* as the brightness being set

This causes 255,0,0 at 50% brightness to be sent as 127,0,0 at 50%
brightness, which ends up as 63,0,0 after the RGB bulb has applied
its brightness scaling.

Fixes the same issue in mqtt, mqtt-json and mqtt-template.

Related Issue: #13725

* Add comment to mqtt_json as well
2018-06-21 15:00:06 -04:00
Tom Harris
4b5d578c08 X10 (#14741)
* Implement X10

* Add X10 after add_device_callback

* Ref device by id not hex and add x10OnOffSwitch name

* X10 services and add sensor device

* Correctly reference X10_HOUSECODE_SCHEMA

* Log adding of X10 devices

* Add X10 All Units Off, All Lights On and All Lights Off devices

* Correct ref to X10 states vs devices

* Add X10 All Units Off, All Lights On and All Lights Off devices

* Correct X10 config

* Debug x10 device additions

* Config x10 from bool to housecode char

* Pass PLM to X10 device create

* Remove PLM to call to add_x10_device

* Unconfuse x10 config and method names

* Correct spelling of x10_all_lights_off_housecode

* Bump insteonplm to 0.10.0 to support X10
2018-06-21 15:00:06 -04:00
Bob Clough
bfc55137ea Fix MQTT Light with RGB and Brightness (#15053)
* Fix MQTT Light with RGB and Brightness

When an MQTT light is given an RGB and Brightness topic, the RGB
is scaled by the brightness *as well* as the brightness being set

This causes 255,0,0 at 50% brightness to be sent as 127,0,0 at 50%
brightness, which ends up as 63,0,0 after the RGB bulb has applied
its brightness scaling.

Fixes the same issue in mqtt, mqtt-json and mqtt-template.

Related Issue: #13725

* Add comment to mqtt_json as well
2018-06-21 14:59:02 -04:00
Paulus Schoutsen
e98e7e2751 Update frontend to 20180621.0 2018-06-21 14:57:19 -04:00
Paulus Schoutsen
b687de879c Update frontend to 20180621.0 2018-06-21 14:57:08 -04:00
Martin Hjelmare
4048ad36a8 Add script to run monkeytype typing on test suite (#14440)
* The monkeytype script takes an optional argument to specify a test
  module or directory to run. Otherwise the whole test suite will run.
* Add monkeytype sqlite db to gitignore.
2018-06-21 15:06:05 +02:00
hanzoh
8c2f0e3b30 Homematic: Add optional port for resolvenames via JSON (#15029)
* Add optional JSON port
2018-06-21 14:52:02 +02:00
Daniel Shokouhi
6cabbd2592 Update Neato Library And Reduce Cloud Calls (#15072)
* Update Neato library to 0.0.6 and reduce the amount of calls to the cloud

* Remove file commited in error

* Lint
2018-06-20 21:46:15 -04:00
Daniel Perna
8d22754a06 Update pyhomematic to 0.1.44 (#15069)
* Update __init__.py

* Update requirements_all.txt
2018-06-20 21:44:50 -04:00
Tom Harris
be6d1b5e94 X10 (#14741)
* Implement X10

* Add X10 after add_device_callback

* Ref device by id not hex and add x10OnOffSwitch name

* X10 services and add sensor device

* Correctly reference X10_HOUSECODE_SCHEMA

* Log adding of X10 devices

* Add X10 All Units Off, All Lights On and All Lights Off devices

* Correct ref to X10 states vs devices

* Add X10 All Units Off, All Lights On and All Lights Off devices

* Correct X10 config

* Debug x10 device additions

* Config x10 from bool to housecode char

* Pass PLM to X10 device create

* Remove PLM to call to add_x10_device

* Unconfuse x10 config and method names

* Correct spelling of x10_all_lights_off_housecode

* Bump insteonplm to 0.10.0 to support X10
2018-06-20 21:44:05 -04:00
Paulus Schoutsen
c84f1d7d33 Version bump to 0.72.0b6 2018-06-20 15:13:33 -04:00
Paulus Schoutsen
49845d9398 Rename experimental UI to lovelace (#15065)
* Rename experimental UI to lovelace

* Bump frontend to 20180620.0
2018-06-20 15:13:22 -04:00
Paulus Schoutsen
895306f822 Rename experimental UI to lovelace (#15065)
* Rename experimental UI to lovelace

* Bump frontend to 20180620.0
2018-06-20 15:13:08 -04:00
Thibault Cohen
a729742757 Fix tplink max/min kelvin for temperature adjustment (#15020) 2018-06-20 19:29:36 +02:00
William Scanlon
6bc03ee763 Python wink update (#15048)
* Updated python-wink to 1.9.0

* Added support for groups of Wink shades.
2018-06-20 09:41:28 -04:00
Dejan Dakić
75580dfade Upgraded librouteros since it has support for authenticatoin in new RouterOS. (#15056) 2018-06-20 09:15:40 +02:00
Marcelo Moreira de Mello
1f8699d9b4 Upgrade pyarlo to 0.1.8 to support Arlo Baby monitor (#15060) 2018-06-20 07:50:38 +02:00
gstorer
fca5d55b43 Update pywemo to version 0.4.28. (#15052) 2018-06-19 11:16:31 -04:00
Paulus Schoutsen
659616a4eb Version bump to 0.72.0b5 2018-06-19 10:58:57 -04:00
Paulus Schoutsen
3b4f7b4f5d Update frontend to 20180619.0 2018-06-19 10:56:44 -04:00
Paulus Schoutsen
62432ced90 Update frontend to 20180619.0 2018-06-19 10:56:33 -04:00
Raoul Teeuwen
27873b4457 Update condition.py (#15021)
* Update condition.py

Added code that writes to warning-log what entity causes a problem when 'value cannot be processed as a number', making troubleshooting easier.

* Make a one-line warning
2018-06-19 13:26:52 +02:00
Andrey
1e7333eeb6 Switch to own packaged version of pyflic (#15041) 2018-06-19 10:31:21 +02:00
Andrey
7cd620d30f Switch upstream adafruit package (#15038) 2018-06-19 10:30:43 +02:00
Fabian Affolter
7a180ac205 Update loopenergy link to docs (#15050) 2018-06-19 09:56:29 +02:00
Hate-Usernames
153ccda853 Patch save_json (#15046) 2018-06-18 21:34:36 -04:00
Jeff Irion
067e4f6d9a Show running apps as sources for Fire TV (#15033)
* Show running apps as sources for Fire TV

* Fix unnecessary 'else' after 'return' (no-else-return)

* Remove 'pylint: disable=unused-argument'

* cleanup
2018-06-18 18:13:50 +02:00
Fabian Affolter
9d6ce609f9 Upgrade requests to 2.19.1 (#15019) 2018-06-18 18:13:21 +02:00
Paulus Schoutsen
9800b74a6d Version bump to 0.72.0b4 2018-06-18 10:00:47 -04:00
Paulus Schoutsen
ef5b2a2492 Version bump to 0.72.0b3 2018-06-18 10:00:24 -04:00
Pascal Vizeli
60179a1cbb Bugfix empty entity lists (#15035)
* Bugfix empty entity lists

* Add tests

* Update test_entity_platform.py

* Update entity_platform.py
2018-06-18 09:59:58 -04:00
Paulus Schoutsen
e0cea2d18d Make zone entries work without radius (#15032) 2018-06-18 09:59:58 -04:00
Fabian Affolter
e29dfa8609 Upgrade aiohttp to 3.3.2 (#15025) 2018-06-18 09:59:57 -04:00
Martin Hjelmare
ef39bca52e Fix linode I/O in state property (#15010)
* Fix linode I/O in state property

* Move update of all attrs to update
2018-06-18 09:58:58 -04:00
Paulus Schoutsen
5a3ea74a26 Bump frontend to 20180618.0 2018-06-18 09:58:35 -04:00
Paulus Schoutsen
8869617890 Bump frontend to 20180618.0 2018-06-18 09:58:16 -04:00
Pascal Vizeli
62f970e486 Bugfix empty entity lists (#15035)
* Bugfix empty entity lists

* Add tests

* Update test_entity_platform.py

* Update entity_platform.py
2018-06-18 09:22:52 -04:00
Martin Hjelmare
f9a21dbfda Fix linode I/O in state property (#15010)
* Fix linode I/O in state property

* Move update of all attrs to update
2018-06-18 09:21:41 -04:00
Pascal Vizeli
86c6b4d8e3 Fix panel URL authentication for Hass.io (#15024)
* Update http.py

* Update http.py

* fix tests

* Update test_http.py
2018-06-18 07:26:41 +02:00
Jeff Irion
7bfa81c592 Improve volume support for Vizio Smartcast (#14981)
* Improve volume support for Vizio Smartcast

* Vizio: avoid an error when 'self._device.get_current_volume()' returns 'None'

* Improve volume support for Vizio Smartcast

* Vizio: avoid an error when 'self._device.get_current_volume()' returns 'None'

* First line should end with a period
2018-06-17 22:06:53 -06:00
gstorer
d07e40c483 Expose Wemo component availability to home assistant (#14995)
* Expose Wemo component availability to home assistant

* Do not add availability feature to dimmer - it works differently

* Brain fade, deleted completely the wrong thing.

Revert "Do not add availability feature to dimmer - it works differently"

This reverts commit f64e717981.

* (2nd attempt) Do not add availability feature to dimmer - it works differently
2018-06-17 22:05:14 -06:00
Kees Schollaart
0e7e58f172 Update PostNL unit of measure to align with UPS (#15023)
I'm using both the UPS and PostNL package trackers. I'd like to have the unit of measure to be the same, now they appear in two different graphs in the history view. 

If we prefer ```package(s)``` over ```package``` then I'll do a PR for [this line](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/sensor/ups.py#L81)
2018-06-17 21:57:08 -06:00
Paulus Schoutsen
cbdfc95cc8 Make zone entries work without radius (#15032) 2018-06-17 21:55:35 -06:00
Paulus Schoutsen
1642502a70 Update translations 2018-06-17 23:05:10 -04:00
Paulus Schoutsen
33ebd99068 Update translations 2018-06-17 23:04:52 -04:00
Fabian Affolter
9c17e95fc5 Upgrade aiohttp to 3.3.2 (#15025) 2018-06-17 20:24:11 -04:00
Matt Schmitt
1533bc1e1f Add support for Homekit battery service (#14288) 2018-06-17 20:54:34 +02:00
Pascal Vizeli
da3695dccc Update test_http.py 2018-06-17 20:37:46 +02:00
Pascal Vizeli
40c8f5f70e Fix panel URL authentication for Hass.io (#15024)
* Update http.py

* Update http.py

* fix tests

* Update test_http.py
2018-06-17 20:34:47 +02:00
Fabian Affolter
3ceee66e1b Remove typing (#15018) 2018-06-17 19:13:39 +02:00
Andrey
6b908b6f4e Switch nuimo to a hopefully working pypi version (#15006) 2018-06-17 09:41:49 -04:00
Fabian Affolter
a74b081d44 Upgrade youtube_dl to 2018.06.14 (#15013) 2018-06-17 09:41:06 -04:00
Fabian Affolter
bc8093c73b Upgrade numpy to 1.14.5 (#15015) 2018-06-17 09:39:27 -04:00
Fabian Affolter
ca2712506b Update to hole to 0.3.0 (#15014) 2018-06-17 09:38:56 -04:00
Fabian Affolter
c871e8da5d Upgrade netdisco to 1.5.0 (#15016) 2018-06-17 09:38:00 -04:00
Matt Schmitt
722c27f1e2 HomeKit style clean up (#14793) 2018-06-17 13:37:44 +02:00
Andrey
e3fcf46566 Switch to own packaged version of braviarc (#15009) 2018-06-17 13:07:10 +02:00
Andrey
1117371b31 Switch to own packaged version of anel_pwrctrl (#15011) 2018-06-17 13:05:25 +02:00
Petro31
addca54118 Add entity support to Waze Travel Time (#14934)
Current version only supports latitude and longitude or an address for the origin and destination fields. This update allows those fields to use entity IDs of device_tracker, zone, and sensor.
2018-06-17 07:13:47 +02:00
Paulus Schoutsen
471d6e45eb Version bump to 0.72.0b2 2018-06-16 22:37:13 -04:00
Paulus Schoutsen
7238205adb Frontend bump to 20180617.0 2018-06-16 22:36:51 -04:00
Paulus Schoutsen
3db5d5bbf9 Frontend bump to 20180617.0 2018-06-16 22:35:19 -04:00
Paulus Schoutsen
65970a2248 Version bump to 0.72.0b1 2018-06-16 17:36:35 -04:00
Paulus Schoutsen
5d82f48c02 Add experimental UI backend (#15002)
* Add experimental UI

* Add test

* Lint
2018-06-16 17:36:10 -04:00
Teemu R
8e185bc300 Bump pyhs100 version (#15001)
Fixes #13925
2018-06-16 17:36:10 -04:00
Andrey
a013908115 Switch to own packaged version of spotipy (#14997) 2018-06-16 17:36:09 -04:00
Sebastian Muszynski
bdf6257640 Remove load power attribute for channel USB (#14996)
* Remove load power attribute for channel USB

* Fix format
2018-06-16 17:36:09 -04:00
Paulus Schoutsen
1f50e335fa Bump frontend to 20180616.0 2018-06-16 17:35:52 -04:00
Paulus Schoutsen
1375adfeab Bump frontend to 20180616.0 2018-06-16 17:32:49 -04:00
Paulus Schoutsen
00cbdffa12 Add experimental UI backend (#15002)
* Add experimental UI

* Add test

* Lint
2018-06-16 17:12:03 -04:00
Sebastian Muszynski
c5f012c85a Remove load power attribute for channel USB (#14996)
* Remove load power attribute for channel USB

* Fix format
2018-06-16 15:53:25 -04:00
Andrey
656eae288e Switch to own packaged version of spotipy (#14997) 2018-06-16 15:52:23 -04:00
Teemu R
5898307715 Bump pyhs100 version (#15001)
Fixes #13925
2018-06-16 15:52:03 -04:00
Paulus Schoutsen
9b0efdc8c8 Version bump to 0.73.0.dev0 2018-06-16 10:51:55 -04:00
Paulus Schoutsen
87f9f17335 Version bump to 0.72.0b0 2018-06-16 10:51:07 -04:00
Paulus Schoutsen
f101f6b7cb Merge remote-tracking branch 'origin/master' into dev 2018-06-16 10:50:43 -04:00
Jason Hu
abf07b60f0 Refactoring camera component to use async/await syntax. (#14990)
* Refactoring camera component to use async/await syntax

Also updated camera demo platform to encourage use of async

* Code review
2018-06-16 10:49:11 -04:00
Paulus Schoutsen
0b114f0755 Do not mount deps folder when running in virtual env (#14993)
* Do not mount deps folder when inside virtual env

* Add tests

* Fix package test
2018-06-16 10:48:41 -04:00
Marcelo Moreira de Mello
3ee8f58fdf Upgraded RainCloudy to version 0.0.5 (#14986) 2018-06-16 06:58:18 -04:00
Marcelo Moreira de Mello
ff4da05267 Upgraded python-amcrest to 1.2.3 (#14988) 2018-06-16 06:57:58 -04:00
Marcelo Moreira de Mello
17308a2730 Upgraded PyArlo to 0.1.7 (#14987) 2018-06-16 06:57:27 -04:00
cdce8p
7d9bce2153 Fix extended package support (#14980)
* Fix package recurive merge bug

* Fixed extended package support
2018-06-16 06:55:32 -04:00
Marcelo Moreira de Mello
2839f0ff5f Upgrade ring_doorbell to 0.2.1 to fix oauth issues (#14984)
* Upgraded to ring_doorbell to 0.2.1 to fix oauth issues

* Updated unittest to cover Ring oauth
2018-06-16 08:58:39 +02:00
Johan Bloemberg
2ec295a6f8 Add availability to Rflink entities. (#14977) 2018-06-16 00:26:48 +02:00
Ville Skyttä
4bd7a7eee3 Remove inline pylint disables for messages disabled in pylintrc (#14978) 2018-06-16 00:15:46 +02:00
c727
d0cbbe6141 Return ISO formated datetime in forecast (#14975)
* Return ISO formated datetime in forecast

* Lint
2018-06-15 17:09:01 -04:00
John Mihalic
9efa31ef9f Eight Sleep add REM type, Update async syntax, Catch API quirks (#14937) 2018-06-15 15:24:09 -04:00
Paulus Schoutsen
8a777f6e78 Show notification when user configures Nest client_id/secret (#14970)
* Show notification when user configures Nest client_id/secret

* Lint
2018-06-15 15:19:58 -04:00
Robert Svensson
ac13a2736b Deconz make groups configurable (#14704)
* Make groups configurable

* Config flow and tests in place

* Fix too long line
2018-06-15 14:31:22 -04:00
Albert Lee
940577e105 Fix binary_sensor.skybell state update when there are no events (#14927) 2018-06-15 14:30:35 -04:00
Sriram Vaidyanathan
c917470836 Xiaomi Cameras - multiple models (#14244)
* Added support for Xiaofang Camera

* Added entry for Xiaofang 1080p camera

* Code fix

* Minor comment fix

* Updated coveragerc for Xiaomi cameras

* Added Xiaomi Camera

Added Xiaomi Camera to accommodate multiple models like Yi, Xiaofang, etc.

* Minor code fix

* Minor code fix

* Added model property

* Update xiaomi.py

* Minor code fix

* Update xiaomi.py

* Update xiaomi.py

* Minor code fix

* Package requirement fix due to Version conflict

* To fix conflicts

* Update package_constraints.txt

* Minor fix

* Update xiaomi.py

* Update xiaomi.py

Changes made per comment

* Update xiaomi.py

* Don't update on add.
2018-06-15 14:27:52 -04:00
Paulus Schoutsen
47a344f3a1 Bump frontend to 20180615.0 2018-06-15 13:46:31 -04:00
Paulus Schoutsen
f744a29d9d Add calendar panel, add tests (#14973) 2018-06-15 13:37:46 -04:00
Thibault Cohen
3cd4cb741c Add Calendar API endpoint to get events (#14702)
* Add Calendar API endpoint to get events

* Set default event color

* Fix PR comments

* Fix PR comments

* Fix PR comments

* Remote local.py file

* Use iso 8601

* Fix lint

* Fix PR comments

* Fix PR comments

* Add Support for todoist and demo calendar

* Todoist events are allday events

* Add calendar demo api endpoint test

* Register only one api endpoint for calendar

* Rename demo calendar
2018-06-15 11:16:31 -04:00
Paulus Schoutsen
1128104281 Adhere to scan_interval in platforms when setup via config entry (#14969) 2018-06-15 16:59:13 +02:00
Aaron Bach
d6d685a483 Fix smappee component - "Error on device update" (#14883) 2018-06-14 19:35:53 -06:00
Paulus Schoutsen
2c6e6c2a6f Add config entry for Sonos + Cast (#14955)
* Add config entry for Sonos

* Lint

* Use add_job

* Add Cast config entry

* Lint

* Rename DOMAIN import

* Mock pychromecast in test
2018-06-14 15:17:54 -04:00
Benedict Aas
c8e0de19b6 add relative time option to simulated sensors (#14038)
By default simulated sensors are relative to when they're activated,
instead we make this togglable with this new option 'relative_to_epoch',
and instead they become relative to 1970-01-01 00:00:00.
2018-06-14 14:06:49 -04:00
Paulus Schoutsen
b2440a6d95 Fix tests (#14959)
* Fix tests

* Lint
2018-06-14 11:57:09 -04:00
ruohan.chen
c36c3f0d64 Add support for ZhongHong HVAC Controllers (#14552)
* first blood for ZhongHong HVAC Controller

* add requirements

* requirements_all.txt updated

* add zhong_hong.py to coveragerc

* add comments

* unique_id add platform name

* zhong_hong_hvac version bump to 1.0.1

* improve some coding style to match the project standard

* zhong_hong_hvac version bump to 1.0.4

* zhong_hong_hvac version require 1.0.7

* update requirements by script/gen_requirements_all.py

* zhong_hong_hvac version bump to 1.0.8

* fix startup problem

* remove unused import

* zhong_hong_hvac version bump to 1.0.9

- operation_mode: cold -> cool

* start hub listen event when all climate entities is ready

* use dispatcher to setup hub

* var name change

SIGNAL_DEVICE_SETTED_UP -> SIGNAL_DEVICE_ADDED

* async problem fix

* bugfix: set_operation_mode forget to use upper case

* stringify the exception instead of print full stack of traceback

* avoid to call str(exception) explicity

* remove unnecessary try...except clause

* remove unused import
2018-06-14 09:47:17 -04:00
Aaron Bach
0e7d284c83 Make AirVisual platform async + other adjustments (#14943)
* Changes complete

* Updated requirements

* Add support for scan_interval

* Small style update

* Owner-requested changes
2018-06-14 09:30:47 -04:00
Nick Whyte
cdd111df49 Add sensor.nsw_fuel_station component (#14757)
* Add sensor.nsw_fuel_station component

* bump dependency

* PR Changes

* flake8

* Use MockPrice

* Fix requirements

* Fix tests

* line length

* wip

* Handle errors and show persistent notification

* update tests

* Address @MartinHjelmare's comments

* Fetch station name from API

* Update tests

* Update requirements

* Address comments
2018-06-14 13:56:04 +02:00
Robin
cccd0deb65 Fix Facebox face data parsing (#14951)
* Adds parse_faces

* Update facebox.py
2018-06-13 21:02:46 +02:00
Paulus Schoutsen
e014a84215 Nest config flow (#14921)
* Move nest to dir based component

* Add config flow for Nest

* Load Nest platforms via config entry

* Add tests for Nest config flow

* Import existing access tokens as config entries

* Lint

* Update coverage

* Update translation

* Fix tests

* Address strings

* Use python-nest token resolution

* Lint

* Do not do I/O inside constructor

* Lint

* Update test requirements
2018-06-13 11:14:52 -04:00
Aaron Bach
d549e26a9b Make Yi platform async (#14944)
* Conversion complete

* Updated requirements

* Got rid of 3.6-specific syntax

* Removed more 3.6-specific syntax

* Contributor-requested changes
2018-06-13 11:00:33 -04:00
Marius
08adfd87f7 Add unique_id for mqtt binary sensor (#14929)
* Added unique_id for mqtt binary sensor

* Added missing mqtt message fire in test
2018-06-13 16:20:38 +02:00
Vignesh Venkat
65b0ec6615 Update python-wink to 1.8.0 (#14894)
* wink: Update to python-wink 1.8.0

This pulls in a patch to expose the GE Z-Wave in wall fan switch
as a fan component instead of a light dimmer switch component.

* Update requirements_all.txt
2018-06-13 07:09:42 -04:00
Ville Skyttä
cb646e48d0 Upgrade pylint to 1.9.2 (#14916) 2018-06-13 07:08:39 -04:00
ArrayLabs
fecce206a9 Myq update from 0.0.8 to 0.0.11 (#14947)
* Update requirements_all.txt

Update myq from 0.0.8 to 0.0.11

* Update myq.py

Update myq from 0.0.8 to 0.0.11
2018-06-13 08:02:27 +02:00
Aaron Bach
176ef411de Add scan_interval to RainMachine (#14945) 2018-06-13 07:30:06 +02:00
Pawel
2ac23c8be6 Epson projector support (#14841)
* Epson projector support. Version based on external library

* Epson projector support. Version based on external library

* modified epson according to MartinHjelmare review.
Added description of cmode to services.yaml

* renamed EPSON_SCHEMA to epson_schema

* removed method of getting cmode property

* removed unnecessary checks
change name of cmode service

* renamed SERVICE_ATTR_CMODE to SERVICE_SELECT_CMODE
2018-06-13 07:28:59 +02:00
Hate-Usernames
a373793029 pytradfri 5.5.1: Improved 3rd party bulb support (#14887)
* Bump pytradfri version

* Update light component

* Add tests

* lint

* Docstring typos

* Blank line

* lint

* 5.5.1

* Fix tests on py3.5
2018-06-13 07:17:52 +02:00
Paulus Schoutsen
3153b0c8fc Bump frontend to 20180613.0 2018-06-12 21:20:23 -04:00
Ing. Jaroslav Šafka
89d008d1f3 Fix snapcast uuid to be more unique (#14925)
Current uuid is ok when using only 1 snapserver
New uuid is needed when using multiple snapserver

Because the client can connect to more snapservers and
then uuid based on client MAC is not enough
2018-06-12 15:46:53 +02:00
Christoph Gerneth
6755ae2605 Add support for KIWI Door Locks (#14485)
* initial commit for kiwi door locks

bugfixes

improved attribute display

flake8

more style adjustments

* added session handling

flake8

* added requirements_all

reordered imports and flake8

attempt to pelase a very picky linter

also pleasing pylint now :)

* re-try the build

* added kiwi.py to .coveragerc

* reorganized datetime handling and attribute naming

* created pypi package for door lock library

* updated requirements_all.txt

* code review changes

* added async lock state reset for locking state

* refactored lat/lon attribute updates

* initial locked state changed from undefined to locked

* refactored is_locked property check

* handling authentication exception in setup_platform

* added more check in setup_platform

* code review changes: return type in setup_platform

* fixed logging issue

* event handling in main thread

* updated kiwiki-client to version 0.1.1

* renamed alias e to exc
2018-06-12 12:36:02 +02:00
Jason Hu
c18033ba85 Use cv.time_period instead of cv.time_period_str (#14938) 2018-06-12 09:32:13 +02:00
Marcelo Moreira de Mello
cdc5388dc9 Refactored Arlo component and enhanced Arlo API queries and times (#14823)
* start arlo refactoring

* Refactored Arlo Hub to avoid uncessary and duplicated GETs to Arlo API

* Refactored Arlo camera component to avoid duplicate queries

* Added debug and error messages when video is not found

* Transformed Arlo Control Panel to Sync

* Makes linter happy

* Uses total_seconds() for scan_interval

* Added callback and fixed scan_interval issue

* Disable multiple tries and supported custom modes set in Arlo

* Bump PyArlo version to 0.1.4

* Makes lint happy

* Removed ArloHub object and added some tweaks

* Fixed hub_refresh method

* Makes lint happy

* Ajusted async syntax and added callbacks decorators

* Bump PyArlo version to 0.1.6 to include some enhacements

* Refined code
2018-06-12 08:01:26 +02:00
Ong Vairoj
be4776d039 Add more test cases for samsungtv (#14900)
More test cases to cover retry logic added in 58a1c3839
2018-06-12 07:33:21 +02:00
Jason Hu
30111ea417 Upgrade python-nest, add security_state sensor, nest.set_mode service set ETA as well (#14901) 2018-06-12 07:28:16 +02:00
Erik Eriksson
576c806e86 Update mqtt_eventstream.py (#14923)
* Update mqtt_eventstream.py

Remove a line setting an internal state mqtt_eventstream.initialized to True since:
1. No other platform is doing this
2. This will create an annoying entity/item in the user interface which the user will have to explicitly hide

* Update mqtt_eventstream.py
2018-06-11 15:29:04 +02:00
Matt Snyder
1c561eaf0d Add support for multiple Doorbird stations (#13994) 2018-06-10 19:02:44 +02:00
Ben Lebherz
1da30032a0 Add support for the Unitymedia Horizon HD Recorder (#14275)
* added new platform for the Unitymedia Horizon HD Recorder

* improve connection handling of the horizon platform

* remove unneeded parameters and fix spelling in the horizon platform

* abort or raise exception if connection to the device could not be established

* remove channel/source list and SELECT_SOURCE feature

* remove useless type check after cast and use a try block instead

* abort or raise exception if reconnect to device fails

* remove protocol specific code and restructure sending logic accordingly

* fix indentation to be pep8 complaint

* remove unused methods/properties

* fix unnecessary pylint commands and use a return to abert outside of setup_platform

* directly access config values
2018-06-10 15:38:55 +02:00
Nate Clark
d5bbb6ffd2 Add api_host option to Konnected config (#14896) 2018-06-10 13:50:25 +02:00
Dan Klaffenbach
b4e5695bbd Bump to denonavr 0.7.3 (#14907)
Closes #14792

See #14794
2018-06-10 13:00:14 +02:00
Yevgeniy
716ab0433f Added daily and hourly modes to Openweathermap (#14875)
* Added daily and hourly modes

Added wind speed and bearing to forecast

* Fix mixed spaces and tabs

* Fix lint

* Fix pylint

* Revert one attribution, order alphabetically
2018-06-10 12:35:10 +02:00
Fabian Affolter
7d9ef97bda Upgrade pylast to 2.3.0 (#14888) 2018-06-10 11:38:35 +02:00
Fabian Affolter
703b4354e0 Upgrade python-mystrom to 0.4.4 (#14889) 2018-06-10 11:38:23 +02:00
Fabian Affolter
ce0ca7ff90 Upgrade sendgrid to 5.4.0 (#14891) 2018-06-10 11:38:11 +02:00
Fabian Affolter
54e87836f6 Upgrade psutil to 5.4.6 (#14892) 2018-06-10 11:37:58 +02:00
Fabian Affolter
5f4aa6d2ba Upgrade python_opendata_transport to 0.1.3 (#14905) 2018-06-10 11:37:44 +02:00
Fabian Affolter
dc447a75c6 Upgrade pyuptimerobot to 0.0.5 2018-06-10 10:58:45 +02:00
Joakim Sørensen
ce7e9e36dd Add Uptime Robot sensor (#14631)
* Added Uptime Robot sensor

* added newline at the end and corrected doclink

* Added changes form @cdce8p

* Convert to binary_sensor

* updated requirements

* moved to correct dir

* Update uptimerobot.py
2018-06-10 10:28:53 +02:00
Aaron Bach
8aca2e84dc Make RainMachine async (#14879)
* Make RainMachine async

* Updated requirements

* Dispatcher adjustments

* Small verbiage change

* Member-requested changes

* Style consistency

* Updated requirements
2018-06-10 10:23:07 +02:00
Fabian Affolter
f3e55ce330 Allow different identifiers for the CPU temperature (fixes #10104) (#14898) 2018-06-10 08:39:48 +02:00
Ing. Jaroslav Šafka
20caeb5383 Add entity registry support to media_player.snapcast (#14895)
Unique id for client is generated from prefix 'snapcast_client_'
and MAC address

Unique id for group is generated from prefix 'snapcast_group_'
and UUID provided by snapcast library
2018-06-10 08:31:42 +02:00
hanzoh
bc0d0751b9 Add missing mapping of RotaryHandleSensorIP states (#14885) 2018-06-09 16:12:42 +02:00
John Arild Berentsen
5393b073fe Discover Qubino ZMHTDx smart meter switches (#14884) 2018-06-09 15:34:36 +02:00
Ong Vairoj
d7b7370c82 Samsung TV can't turn off after idle period (#14587)
When Samsung TV is idle for a period of time after issued a command,
subsequent 'turn_off' command won't turn off the TV. The issue is seen
in Samsung models with websocket as discussed in #12302.

== Reproducible Steps
1. Turn on TV (either via HA or directly).
2. Issue some commands e.g. volume ups / downs.
3. Wait for ~1 minute.
4. Issue turn_off command via HA. TV won't turn off.
5. Issue subsequent turn off commands won't turn off TV still.
6. However, issue some other commands e.g. volume ups / downs multiple
times in a row and then turn_off will turn off the TV.

== Root Cause
The underlying websocket connection opened by samsungctl get closed
after some idle time. There was no retry mechanism so issued commands
would intermittently fail but the subsequent one would succeed when
`_remote` get recreated. With `turn_off()`, however, there is an
additional call to `self.get_remote().close()` which indirectly caused
new connection to be created and then closed immediately. This causes the
component to stuck in failure mode when turn_off command is repeatly
issued.

== The Fix
Recreate the connection and retry the command if connection is closed
to avoid silent failures due to connection closed. Also set `_remote`
to None after calling close() to put it in correct state.

This fix eliminates intermittent command failure and failure mode in
turn_off().
2018-06-09 09:22:34 -04:00
vandenberghev
5f65f67f1e Removed semicolon 2018-06-09 12:37:06 +02:00
Malte Franken
f242418986 UVC camera platform handling unavailable NVR or cameras better (#14864)
* fixed tests: using correct camera configuration now and error handling tests must be separated out to ensure that the setup_component call is actually executed

* better error handling during setup; raising PlatformNotReady in likely recoverable cases; added tests
2018-06-09 07:22:17 +02:00
Jason Hu
d3d9d9ebf2 Add color_status sensor for Nest Protect (#14868) 2018-06-09 07:16:11 +02:00
Paulus Schoutsen
8ceb57752b Merge pull request #14876 from home-assistant/rc
0.71.0
2018-06-08 18:07:39 -04:00
Paulus Schoutsen
bd1af8c3d8 Version bump to 0.71.0 2018-06-08 16:57:59 -04:00
Paulus Schoutsen
6af995026b Add support for new hass.io panel (#14873) 2018-06-08 16:50:19 -04:00
Paulus Schoutsen
19a30b0ce6 Version bump to 0.71.0b1 2018-06-08 15:04:58 -04:00
Robert Svensson
9a659a5d1d Zone - Hass configuration name is optional (#14449)
* Hass configuration name is optional

* Check explicitly if name is none

* Reverted back to old logic for zones configured in configuration.yaml, where many zones can have the same name

* New test to verify use case of allowing multiple zones having the same name

* Fix too long line
2018-06-08 15:04:42 -04:00
Paulus Schoutsen
1cfd770b95 Use hass iconset (#14185) 2018-06-08 15:04:41 -04:00
Paulus Schoutsen
3fda97eed7 Bump frontend to 20180608.0b0 2018-06-08 15:04:28 -04:00
Anders Melchiorsen
b657cff6ba Add netgear_lte component (#14687)
* Add netgear_lte component

* Improvements after review

* Allow multiple notify targets

* Require default notify target
2018-06-08 07:46:34 +02:00
Mal Curtis
e3fba79126 Disable volume control for Onkyo when unavailable (Closes: #14774) (#14863) 2018-06-08 07:45:21 +02:00
Diogo Gomes
bb0068908d Fix unit conversion (#14730)
* reviewing this code min_temp and max_temp are always present and always in celsius

* revert change (preserve unit conversion)

* revert (due to unit conversion)

* self

* clean

* cleaner
2018-06-07 22:44:07 -04:00
Robert Svensson
0748466ffc Zone - Hass configuration name is optional (#14449)
* Hass configuration name is optional

* Check explicitly if name is none

* Reverted back to old logic for zones configured in configuration.yaml, where many zones can have the same name

* New test to verify use case of allowing multiple zones having the same name

* Fix too long line
2018-06-07 17:06:13 -04:00
Dale Higgs
fe018fd58c Add set_default_level to logger (#14703)
* Add set_default_service to logger

* Fix 2-line lint error

* Add set_default_level to services.yaml

* Add tests for set_default_level

* Remove function and add else when setting default
2018-06-07 17:03:04 -04:00
Steve Edson
10317a0f71 Rename Hive hub friendly name (#14747)
Right now, "Hub Status" is very generic, I didn't know what component it was coming from, and the only way to tell was searching the source code to find the reference.
2018-06-07 16:57:07 -04:00
Alexei Chetroi
87d55834be zha: handle "step_with_on_off" cluster command in LevelListener. (#14756) 2018-06-07 16:56:07 -04:00
Sebastian Muszynski
d4cc806cd5 Fix door/window sensor support of the Xiaomi Aqara LAN protocol V2 (Closes: #14775) (#14777) 2018-06-07 16:55:18 -04:00
Sergiy Maysak
1a7e8c88a3 Wireless tags platform (#13495)
* Initial version of wirelesstags platform support.

* Pinned wirelesstagpy, generated requirements_all.

* Fixed temperature units in imperial units systems, make binary events more tags specific.

* Lowercased tag name during entity_id generation.

* Fixed: tag_id template for tag_binary_events, support of light sensor for homebridge.

* Minor style cleanup.

* Removed state, define_name, icon. Reworked async arm/disarm update. Removed static attrs. Introduced available property. Custom events contains components name now. Cleaned dedundant items from schema definition.

* Removed comment and beep duration from attributes. Minor cleanup of documentation comment.

* Ignoring Wemo switches linked in iOS app.

* Reworked passing data from platform to components using signals.
2018-06-07 16:30:20 -04:00
Paulus Schoutsen
90a51160c4 Don't run unnecessary methods in executor pool (#14853)
* Don't run unnecessary methods in executor pool

* Lint

* Lint 2
2018-06-07 15:31:21 -04:00
Fabian Affolter
50321a29b5 Catch ConnectionError (fixes #14241) (#14748) 2018-06-07 20:25:26 +02:00
Paulus Schoutsen
67d137cfd5 Store config entry id in entity registry (#14851)
* Store config entry id in entity registry

* Lint
2018-06-07 20:23:09 +02:00
Philip Rosenberg-Watt
bb4d1773d3 Add min_temp and max_temp to MQTT climate device (#14690)
* Add min_temp and max_temp to MQTT climate device

* Add unit tests

* Remove blank line

* Fix unit tests & temp return values

* PEP-8 fixes

* Remove unused import
2018-06-07 13:50:12 -04:00
Fabian Affolter
a6c1192bfc Upgrade aiohttp to 3.3.0 (#14766) 2018-06-07 13:49:14 -04:00
Matthew Treinish
d14d2fe588 Add IBM Watson IoT Platform component (#13664)
This commit adds a new history component for the IBM Watson IoT
Platform. The IBM Watson IoT Platform allows for tracking of devices
and analytics on top of the device data. This new component allows
users to have home assistant automatically populate a watson iot
platform board with device data from devices managed by home assistant.
2018-06-07 13:43:51 -04:00
starkillerOG
f696331563 Add general sound mode support (#14729)
* Media player: general sound mode support

* General sound mode support

* White spaces

* Add sound mode support to demo media player

* white space

* remove unnessesary code
2018-06-07 10:57:45 -04:00
Anders Melchiorsen
6b2b92a732 Improvements to LIFX reliability (#14848)
* Improve fault tolerance of LIFX initialization

* Update aiolifx to 0.6.3

* Use list comprehension
2018-06-07 10:06:29 -04:00
Fabian Affolter
83ce9450f7 Upgrade Mastodon.py to 1.3.0 (#14858) 2018-06-07 10:04:58 -04:00
Paulus Schoutsen
0b405c33c4 Update Hue flow title (#14852) 2018-06-07 16:00:42 +02:00
Paulus Schoutsen
bf74cab7af Fix non awaited test (#14854) 2018-06-07 15:58:54 +02:00
Paulus Schoutsen
d8adb4bdb0 Bump frontend to 20180607.0 2018-06-06 22:42:01 -04:00
nielstron
33990badcd Fixed Rangefilter constructor call 2018-06-06 20:40:56 +02:00
nielstron
8061f15aec Removal of windows size and precision for range filter 2018-06-06 20:40:55 +02:00
nielstron
25f7c31911 Fixed wrong bound assignment on values below the lower bound 2018-06-06 20:40:54 +02:00
nielstron
bb98331ba4 Fix doctring newline and handle ha.state string-being 2018-06-06 20:40:53 +02:00
nielstron
07d139b3a8 Fix wrong comparison 2018-06-06 20:40:53 +02:00
nielstron
f4ef8fd1bc Changes for new FilterState construct 2018-06-06 20:40:52 +02:00
nielstron
ba836c2e36 Fix indent 2018-06-06 20:40:52 +02:00
nielstron
a0ab356936 Renamed to range filter 2018-06-06 20:40:51 +02:00
nielstron
734a83c657 Removed default values and fixed description in sensor.filter 2018-06-06 20:40:50 +02:00
nielstron
b42f4012d1 Fixed test 2018-06-06 20:40:50 +02:00
nielstron
8501312292 Reordered attribute order 2018-06-06 20:40:49 +02:00
nielstron
3faed2edc1 Add test for new band_pass filter 2018-06-06 20:40:49 +02:00
nielstron
bc70619b17 Added bandpass filter
Allows values in a given range
2018-06-06 20:40:48 +02:00
Sebastian Muszynski
bef15264b7 Ignore the mistaken long_both_click event of the 86sw (Closes: #14802) (#14808) 2018-06-06 19:51:59 +02:00
Roman
6d26915c69 Feature/gearbest library update (Closes: #14813) (#14833) 2018-06-06 11:38:50 +02:00
Paulus Schoutsen
fa2e6ada26 Route themes and translations over websocket (#14828) 2018-06-06 10:12:43 +02:00
Paulus Schoutsen
a6880c452f Migrate entity registry to using websocket (#14830)
* Migrate to using websocket

* Lint
2018-06-06 10:08:36 +02:00
Diogo Gomes
4bccb0d2a1 Merge pull request #14831 from home-assistant/sim-sensor
Limit sensor.simulated to 3 decimals (fixes #14773)
2018-06-05 21:06:11 +01:00
Luc Touraille
103639455c Add Freebox device tracker (#12727)
* Add a device tracker for Freebox routers

* Automatic setup of Freebox device tracker based on discovery

* Make the Freebox device tracker asynchronous
2018-06-05 20:38:50 +02:00
Thomas Krüger
549abd9c7e Improved Fritz!Box thermostat support (#14789) 2018-06-05 20:06:25 +02:00
Fabian Affolter
f1aba5511f Limit to 3 decimals (fixes #14773) 2018-06-05 19:44:41 +02:00
Simon Nørager Sørensen
21d05a8b4d Fixes an issue in Xiaomi TV platform that would some TVs not sleep correctly (#14829) 2018-06-05 19:13:16 +02:00
Mischa Gruber
cb6c869c2f Action parameter doesn't longer have to be the first parameter (#14815)
* Action parameter doesn't longer have to be the first parameter

* Minified code upon suggestion
2018-06-05 18:15:34 +02:00
Hugo Dupras
640e499964 netatmo api is now in pip as pyatmo (#14824)
Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>
2018-06-05 11:55:53 -04:00
Paulus Schoutsen
b3b4f7468d Further cleanup frontend (#14805)
* Remove registering panels

* Remove unused image

* Lint
2018-06-05 10:50:16 -04:00
Paulus Schoutsen
ad9621ebe5 Use hass iconset (#14185) 2018-06-05 10:49:54 -04:00
Sebastian Muszynski
e370d523ec Bump python-miio version (Closes: #13749) (#14796)
* Bump python-miio version

* Fix Xiaomi Power Strip V1 support (Closes: #13749)
2018-06-04 23:50:18 +02:00
vandenberghev
61a41bb8fc Fix issue #14426: [homeassistant.components.sensor] smappee: Error on device update!
https://github.com/home-assistant/home-assistant/issues/14426
2018-06-04 20:08:17 +02:00
vandenberghev
2da6d3c223 Merge branch 'dev' of https://github.com/home-assistant/home-assistant into dev
# Conflicts:
#	homeassistant/components/sensor/smappee.py
2018-06-04 19:44:04 +02:00
Fabian Affolter
816efa02d1 Use pihole module to get data (#14809) 2018-06-04 18:49:26 +02:00
Fabian Affolter
bd1b1a9ff9 Update syntax (#14812) 2018-06-04 14:44:55 +02:00
quthla
1d23f7f900 Allow Kodi live streams to be recognized as paused (#14623) 2018-06-04 12:24:28 +01:00
Sebastian Muszynski
39843a73de Add additional 86sw model identifier of the LAN protocol V2 (#14799) 2018-06-04 07:39:50 +02:00
Diogo Gomes
aec425d1f6 Weather Platform - IPMA (#14716)
* initial commit

* lint

* update with pyipma

* Added test

* Added test

* lint

* missing dep

* address comments

* lint

* make sure list is iterable

* don't bother with list

* mock dependency

* no need to add test requirements

* last correction
2018-06-03 23:01:48 +02:00
Paulus Schoutsen
855ed2b4e4 Version bump to 0.72.0.dev0 2018-06-03 16:54:23 -04:00
Paulus Schoutsen
2dc40fe16e Version bump to 0.71.0b0 2018-06-03 16:53:48 -04:00
Paulus Schoutsen
bf8376ddcb Merge remote-tracking branch 'origin/master' into dev 2018-06-03 16:53:17 -04:00
Mattias Welponer
8f696193f0 Add homematicip_cloud illuminance sensor (#14720)
* Add iluminance sensor and device_class for sensors

* Fix lint
2018-06-03 18:48:51 +02:00
Paulus Schoutsen
70edb2492a Version bump to 20180603.0 2018-06-03 12:29:57 -04:00
quthla
e35d4beb95 Fix media_title empty when title is empty but label is set (#14791) 2018-06-03 09:27:17 -04:00
quthla
919b431a24 Add Kodi OnResume event (#14790) 2018-06-03 09:26:23 -04:00
Jason Woodford
7f59a8ea0c Update total-connect-client to 0.18 for Honeywell Lynx Touch-Wifi support (#14778) 2018-06-03 13:55:49 +02:00
Sebastian Muszynski
1ac3f0da63 Ignore the mistaken long_click event of the 86sw (Closes: #14694) (#14785) 2018-06-03 11:54:03 +02:00
Jason Hu
12e679c14d Assign device class to nest sensors (#14746)
* Assign device class to nest sensors

sensor/nest.NestSensor => /nest.NestSensorDevice,
so that BinarySensor platform do not reference Sensor platform anymore

* Resolve code review comment

* Follow code review comment
2018-06-03 03:54:48 +02:00
Fabian Affolter
28ef94c3fa Update syntax (#14772) 2018-06-02 15:08:10 +02:00
Fabian Affolter
27df4cca6c Upgrade shodan to 1.8.1 (#14760) 2018-06-02 08:34:47 -04:00
Fabian Affolter
a8413249c2 Upgrade sqlalchemy to 1.2.8 (#14765) 2018-06-02 08:34:30 -04:00
Fabian Affolter
f2dacb2570 Upgrade youtube_dl to 2018.06.02 (#14763) 2018-06-02 08:33:48 -04:00
Fabian Affolter
5aaf81f2c9 Upgrade Sphinx to 1.7.5 (#14764) 2018-06-02 08:31:43 -04:00
Fabian Affolter
b86cd325fe Update syntax (#14770) 2018-06-02 08:31:06 -04:00
Fabian Affolter
74b7dabf2d Update syntax (#14768) 2018-06-02 08:30:54 -04:00
Fabian Affolter
1ce4c2092a Update syntax (#14771) 2018-06-02 08:30:07 -04:00
Fabian Affolter
875e05ff38 Remove swagger file (#14762) 2018-06-02 08:29:38 -04:00
Mick Vleeshouwer
fe0e49db4b Update postnl api to 1.0.2 (#14769) 2018-06-02 13:45:48 +02:00
Fabian Affolter
ad86e68c1e Update syntax of platform random (#14767) 2018-06-02 12:00:01 +02:00
Tristan Caulfield
e7985c970b Upgrade directpy to 0.5 (#14750)
* Version Requirement bump

Bump required version to 0.5 to allow component to work with Genie Mini clients using the clientAddr variable.

* Ran script/gen_requirements_all.py as requested.
2018-06-02 09:30:15 +02:00
austinlg96
cfac537f51 Added option to block Osram Lightify individual lights in the same way that groups can be (#14470) 2018-06-02 09:23:51 +02:00
Fabian Affolter
d6e76969cc Tweak about the requirements 2018-06-01 23:33:04 +02:00
Fabian Affolter
77dca8272c Upgrade blockchain to 1.4.4 (#14738) 2018-06-01 19:41:35 +02:00
Fabian Affolter
3b8ee196be Update syntax (#14742) 2018-06-01 19:41:20 +02:00
michaeldavie
4935043f4a Add battery attribute to Sensibo (#14735)
* Added battery attribute

* Simplify current_battery
2018-06-01 19:41:04 +02:00
Matt Schmitt
f5d74e07d5 Add support for outlets in HomeKit (#14628) 2018-06-01 18:04:54 +02:00
Paulus Schoutsen
0a724a5473 Update frontend 2018-06-01 10:52:25 -04:00
Jason Hu
cba8333a13 Change nest to cloud push (#14656)
* Change nest component to Cloud Push

Change sensors.nest, binary_sensors.nest and climate.nest to push mode
nest camera still need poll to update snapshot image
Also change nest component to async

* Flake8 lint

* Fix async_notify_errors, it is not a coroutine

* Fix pylint

* Fix pylint, function name should shall shorter than 32

* Use dispatcher helper instead event bus

* Use async_update_ha_state(True)

* Refactoring load_platform

Move service registration into async_setup_nest(),
 resolve an issue that before the first time configuration done,
 set_mode service should not be registered

* Fix an issue that authorization failure may leave a blocked thread

* Pylinting

* async_nest_update_callback => async_update_state to avoid confusion

* Move signal handler register to async_added_to_hass

* Better handle nest api error

* Remove unnecessary register for binary_sensor

* Remove unused import

* Upgrade to python-nest 4.0.1

Fix a thread race condition issue

* Address my own comments

* Address my own comment
2018-06-01 10:44:58 -04:00
Anders Melchiorsen
fcbc399809 Disallow automation.trigger without entity_id (#14724) 2018-06-01 10:27:12 -04:00
Paulus Schoutsen
f6eb9e79d5 Custom panel (#14708)
* Add support for custom panels in JS

* Allow specifying JS custom panels

* Add trust external option

* Fix tests

* Do I/O outside event loop

* Change config to avoid breaking change
2018-06-01 10:06:17 -04:00
roiff
ab3717af76 Homekit Thermostat: Better support for temperature ranges (#14679)
* Support for obtaining temperature range
* Fallback to Defaults
* Fixed unit conversion
* Added test
2018-06-01 13:49:16 +02:00
Pierre Ståhl
6cd69b413c Bump pyatv to 0.3.10 (#14736)
* Bump pyatv to 0.3.10

* Update requirements_all.txt
2018-06-01 08:41:40 +02:00
Fabian Affolter
de56a0d021 Upgrade shodan to 1.8.0 (#14717) 2018-06-01 08:40:27 +02:00
glenn20
99fdd3e358 Add device_descriptor and device_name to keyboard event (#14642)
* Add device_descriptor and device_name to keyboard event

This allows automations to identify which device has generated the
keypress. This is especially useful for bluetooth remotes to control different
devices.

* Remove line breaks

* Fix
2018-06-01 00:32:09 +02:00
Paulus Schoutsen
9a3107aa66 Merge pull request #14727 from home-assistant/rc
0.70.1
2018-05-31 18:11:34 -04:00
Paulus Schoutsen
d31e01b877 Revert "Remove simplepush.io (#14358)"
This reverts commit 612a37b2dd.
2018-05-31 18:11:15 -04:00
Paulus Schoutsen
f8c8900297 Merge pull request #14728 from home-assistant/reinstate-simplepush
Revert "Remove simplepush.io (#14358)"
2018-05-31 18:09:50 -04:00
Paulus Schoutsen
ed9cf994c2 Revert "Remove simplepush.io (#14358)"
This reverts commit 612a37b2dd.
2018-05-31 17:58:03 -04:00
Paulus Schoutsen
d4a4938fce Version bump to 0.70.1 2018-05-31 17:27:55 -04:00
Paulus Schoutsen
f7f0138cff Bump frontend to 20180531.0 2018-05-31 17:27:44 -04:00
Marius
753ffdaffd Fix Eco mode display on Nest (#14706)
* Fix Eco mode display on Nest

* Fix Hound problems
2018-05-31 17:27:35 -04:00
Otto Winter
40aba3d785 MQTT Cover Fix Assumed State (#14672) 2018-05-31 17:27:35 -04:00
Anders Melchiorsen
64f157a036 Ignore unsupported Sonos favorite lists (#14665) 2018-05-31 17:27:35 -04:00
MizterB
0eddd287c5 Update Hue platform to aiohue 1.5.0, and re-implement logic for duplicate scene names. (#14653) 2018-05-31 17:27:34 -04:00
Marius
f32b50cb80 Fix Eco mode display on Nest (#14706)
* Fix Eco mode display on Nest

* Fix Hound problems
2018-05-31 17:26:59 -04:00
Paulus Schoutsen
a58a566ae8 Bump frontend to 20180531.0 2018-05-31 17:25:35 -04:00
Diogo Gomes
2f1d40e014 Merge pull request #14721 from PhilRW/climate-constants
Change climate default limits to constants
2018-05-31 22:19:25 +01:00
Fabian Affolter
14ee6178f9 Add Flock notification platform (#14533)
* Add Flock notification platform

* Use async syntax and move session and loop
2018-05-31 23:07:50 +02:00
Philip Rosenberg-Watt
753fe8279b Remove deprecated comments 2018-05-31 13:59:26 -06:00
Philip Rosenberg-Watt
cc264f415e Fix PEP-8 issues 2018-05-31 11:32:31 -06:00
Philip Rosenberg-Watt
dae90abb34 Change climate default limits to constants
Min and max temp and humidity are now defined in climate __init__.py
and are available for import in subclasses.
2018-05-31 11:23:04 -06:00
Aaron Bach
60f692c7bb Fixes (and stabilizes) some incorrect zone codes in RainMachine (#14719)
* Fixes (and stabilizes) some incorrect zone codes

* Fixed a misspelling
2018-05-31 18:55:50 +02:00
c727
7094d6d61e Change ACP code_format to None|"Number"|"Any" (#14686) 2018-05-31 14:31:40 +02:00
Paulus Schoutsen
08fc73aa20 Bump to 0.71.0.dev0 2018-05-30 11:19:27 -04:00
Michael Nosthoff
c14e41f431 Netatmo Sensor: Implement device_class (#14634)
added device_class and removed icon for temperature and humidity.
2018-05-30 10:53:35 -04:00
cdce8p
f1f4d80f24 Homekit Bugfixes (#14689)
* Fix async bug
* Fix debounce bug
2018-05-30 12:39:27 +02:00
Paulus Schoutsen
e746b92e0e Fix deprecated code (#14681) 2018-05-29 23:14:58 +02:00
cdce8p
7d2563eb1f Update HAP-python to 2.2.2 (#14674)
* Pass driver to accessory
* Added 'hk_driver' fixture for tests
2018-05-29 22:43:26 +02:00
Aaron Bach
084b3287ab Add sensors and services to RainMachine (#14326)
* Starting to add attributes

* All attributes added to programs

* Basic zone attributes in place

* Added advanced properties for zones

* We shouldn't calculate the MAC with every entity

* Small fixes

* Basic framework for push in play

* I THINK IT'S WORKING

* Some state cleanup

* Restart

* Restart part 2

* Added stub for service schema

* Update

* Added services

* Small service description update

* Lint

* Updated CODEOWNERS

* Moving to async methods

* Fixed coverage test

* Lint

* Removed unnecessary hass reference

* Lint

* Lint

* Round 1 of Owner-requested changes

* Round 2 of Owner-requested changes

* Round 3 of Owner-requested changes

* Round 4 (final for now) of Owner-requested changes

* Hound

* Updated package requirements

* Lint

* Collaborator-requested changes

* Collaborator-requested changes

* More small tweaks

* One more small tweak

* Bumping Travis and Coveralls
2018-05-29 21:02:16 +02:00
Thibault Cohen
4105429639 Add asyncio support for Ebox (#14183)
* Fix Ebox sensor

* Fix #14183 comments

* Update ebox.py

* Update ebox.py

* Continue fixing comments
2018-05-29 10:23:12 -04:00
Robert Svensson
8c93b484c4 deCONZ - Option to load or not to load clip sensors on start (#14480)
* Option to load or not to load clip sensors on start

* Full flow

* Fix config flow and add tests

* Fix attribute dark reporting properly

* Imported and properly configured deCONZ shouldn't need extra input to create config entry
2018-05-29 10:09:53 -04:00
Fabian Affolter
3b38de63ea Allow user-defined sensors (#14613)
* Allow user-defined sensors

* Require element for resources

* Don't use .get()
2018-05-29 10:03:00 -04:00
Alexei Chetroi
eff1d1f14e zha: fix temperature rounding for ZHA temperature sensors. (#14669) 2018-05-29 09:05:07 -04:00
Otto Winter
fcb60d472e MQTT Cover Fix Assumed State (#14672) 2018-05-29 09:03:45 -04:00
Anders Melchiorsen
f2a2f2cca5 Ignore unsupported Sonos favorite lists (#14665) 2018-05-29 10:15:30 +02:00
Paulus Schoutsen
8c7f0669c6 Allow hassio frontend development (#14675)
* Allow hassio frontend development

* Fix tests
2018-05-29 08:51:08 +02:00
Matthew Garrett
d36c7c3de7 Increase Eufy's requirement on lakeside (#14671)
python-lakeside was broken with at least some versions of the Python
protobuf code, so bump the requirement to a fixed version.
2018-05-29 08:42:27 +02:00
Bakkoda
79efb0e607 Update mfi.py (#14667)
Add ability to read door sensor states from the mPort.
2018-05-29 07:51:14 +02:00
Robert Accettura
9bc26e93a4 Add pin pad to alarm panel (#14178)
* Add pin pad to alarm panel

* Add pin pad to alarm panel

* Update regex

* Update regex

* Update regex

* Add pin pad to alarm panel

* Add pin pad to alarm panel

* Add pin pad to alarm panel

* Add pin pad to alarm panel

* Fix typos

* Fix typos

* Fix typos

* Add pin pad to alarm panel

* Fix errors
2018-05-29 07:50:27 +02:00
Andrey
6c3e2021df Give unknown zwave nodes a better name (#14353)
* Give unknown zwave nodes a better name

* Update util.py
2018-05-28 21:49:38 -04:00
Enrico Berndt
07255a29b4 Add tv channel and volume level for philips js API 5 (#14276)
* PhilipsTV API 5: Added tv channel change and setting of volume level.

* set_volume only sets volume via api now and nothing else.
2018-05-28 10:41:51 -04:00
Alexei Chetroi
144bb3492a zha/light: Properly parse currentX and currentY on async_update() (#14605) 2018-05-28 10:32:47 -04:00
cdce8p
6f4dd7b057 Improve Homekit media_player options (#14637)
* Optimize imports

* Optimize name

* Optimize config schema

* Rename mode to feature

* Replace mode with feature_list
2018-05-28 10:26:33 -04:00
David F. Mulcahey
27f3285d17 Force update ZHA electrical sensor (#14649)
* force state update because we have a real reading

* hound

* docstring
2018-05-28 10:22:29 -04:00
MizterB
9a87e62e0e Update Hue platform to aiohue 1.5.0, and re-implement logic for duplicate scene names. (#14653) 2018-05-28 10:21:00 -04:00
koreth
9044a9157f Reduce log churn from Envisalink binary sensors (#14659)
The Envisalink binary sensor was logging events with a relative
timestamp that updated every time it polled, so even when nothing
new was happening, the event log would be full of meaningless
state changes. Modify the sensor code to use an absolute time
which stays stable when there isn't new activity.
2018-05-28 10:19:03 -04:00
Michaël Arnauts
799ae894a8 Remove docker prereqs scripts that only install a package. Add informational message for this. (#14661) 2018-05-28 10:17:01 -04:00
Fabian Affolter
bff1e1ff6c Upgrade python_opendata_transport to 0.1.0 (#14652) 2018-05-28 08:17:10 +02:00
Fabian Affolter
cc2437614b Upgrade youtube_dl to 2018.05.26 (#14654) 2018-05-28 08:16:55 +02:00
Paulus Schoutsen
0700886d1a Merge pull request #14657 from home-assistant/rc
0.70.0
2018-05-27 20:22:19 -04:00
Paulus Schoutsen
cd0e321668 Version bump to 0.70.0 2018-05-27 17:18:53 -04:00
Paulus Schoutsen
94a82ab7dc Allow Hass.io panel dir (#14655) 2018-05-27 17:18:16 -04:00
Paulus Schoutsen
b6e4a7771a Allow Hass.io panel dir (#14655) 2018-05-27 17:17:19 -04:00
Fabian Affolter
13859388c1 Upgrade locationsharinglib to 2.0.7 (#14640) 2018-05-27 20:16:47 +02:00
Fabian Affolter
2f4c5f949b Use constants (#14647) 2018-05-27 20:16:30 +02:00
Fabian Affolter
36e8157268 Upgrade TwitterAPI to 2.5.4 (#14639) 2018-05-27 15:46:58 +02:00
Fabian Affolter
2d88f47795 Upgrade gitterpy to 0.1.7 (#14643) 2018-05-27 15:45:43 +02:00
Jason Hu
5acfe5da68 Upgrade python-nest to 4.0.0 (#14638)
* Upgrade python-nest to 4.0.0

Drop in replace to use nest stream API
Didn't change any logic from HA side

* Update requirements_all.txt
2018-05-27 11:31:05 +02:00
Fabian Affolter
5f9e4ae136 Upgrade luftdaten to 0.2.0 (#14620) 2018-05-27 09:53:53 +02:00
Paulus Schoutsen
a9b0f92afe Version bump to 0.70.0b7 2018-05-26 20:02:54 -04:00
Paulus Schoutsen
07b2728380 Bump frontend to 20180526.4 2018-05-26 20:02:36 -04:00
Paulus Schoutsen
a5e66ce6ba Bump frontend to 20180526.4 2018-05-26 20:02:24 -04:00
David F. Mulcahey
eae9726bec Add electrical measurement sensor to ZHA (#14561)
* Add electrical measurement sensor

* correct state update

* hound fix

* zha: Add metering sensor (#14562)

* Add IlluminanceMeasurementSensor to ZHA (#14563)

* add IlluminanceMeasurementSensor

* address review comment

* Fix whitespace error during merge

* Add electrical measurement sensor

* correct state update

* hound / flake8
2018-05-26 22:50:05 +02:00
guillaume1410
c425afe50e Adding ryobi garage door opener (#14618)
* Initial component for Ryobi cover

* Initial component for Ryobi cover

* Adding Ryobi cover

* Adding Ryobi cover

* Adding Ryobi cover

* Minor changes

* Remove import
2018-05-26 22:46:53 +02:00
Paulus Schoutsen
a5b9e59cee Version bump to 0.70.0b6 2018-05-26 14:30:03 -04:00
Paulus Schoutsen
fb447cab82 Bump frontend to 20180526.3 2018-05-26 14:29:53 -04:00
Paulus Schoutsen
bcde57bff8 Bump frontend to 20180526.3 2018-05-26 14:29:26 -04:00
David Ryan
dfd7ef1fce Add Hydrawise component (#14055)
* Added the Hydrawise component.

* Fixed lint errors.

* Multiple changes due to review comments addressed.

* Simplified boolean test. Passes pylint.

* Need hydrawiser package version 0.1.1.

* Added a docstring to the device_class method.

* Addressed all review comments from MartinHjelmare.

* Changed keys to single quote. Removed unnecessary duplicate method.

* Removed unused imports.

* Changed state to lowercase snakecase.

* Changes & fixes from review comments.
2018-05-26 18:42:52 +02:00
Paulus Schoutsen
6b9addfeea Update release script 2018-05-26 11:54:50 -04:00
Paulus Schoutsen
6c62f7231b Version bump to 0.70.0b5 2018-05-26 11:53:57 -04:00
Paulus Schoutsen
52c21a53b3 Bump frontend to 20180526.2 2018-05-26 11:53:44 -04:00
Paulus Schoutsen
fdb250d86c Bump frontend to 20180526.2 2018-05-26 11:53:36 -04:00
Fabian Affolter
8de56cfc10 Upgrade speedtest-cli to 2.0.2 (#14633) 2018-05-26 17:35:16 +02:00
Mattias Welponer
7ea25cd360 Add homematicip cloud climate platform (#14388)
* Add support for climatic devices

* Update requirements_all

* Change icon to mdi:thermostat

* Update of homematicip-rest-api lib version

* Remove all mode or state relevant things - will come later

* Add current_operation again to see proper status

* Remove STATE_PERFORMANCE import

* Remove trailing whitespace

* Update requirements file
2018-05-26 16:03:53 +02:00
Paulus Schoutsen
c9498d9f09 Version bump to 0.70.0b4 2018-05-26 08:35:18 -04:00
Paulus Schoutsen
2f0435ebd8 No longer use backports for ffmpeg (#14626) 2018-05-26 08:34:56 -04:00
Paulus Schoutsen
19351fc429 Use libsodium18 (#14624) 2018-05-26 08:34:55 -04:00
Paulus Schoutsen
bfc16428da Bump frontend to 20180526.1 2018-05-26 08:34:40 -04:00
Paulus Schoutsen
41fc44b27c Bump frontend to 20180526.1 2018-05-26 08:33:22 -04:00
Max Muth
a55fbd2be7 Add services for adding and removing items to shopping list (#14574) 2018-05-26 13:53:48 +02:00
Marcelo Moreira de Mello
28d6910e56 Added UDP and parallel streams support to Iperf3 (#14629) 2018-05-26 13:43:31 +02:00
Lorenz Schmid
edfc54b2eb Added option to connect via SSL for OpenWRT(luci) device tracker (#14627)
* Added option to connect via HTTPS for OpenWRT(luci) device tracker

* Use string formatting

* Update quotes

* Remove whitespace
2018-05-26 09:51:21 +02:00
cdce8p
6ceafabd78 Extend package support (#14611) 2018-05-25 16:41:50 -04:00
Paulus Schoutsen
48972c7570 No longer use backports for ffmpeg (#14626) 2018-05-25 13:49:45 -04:00
Paulus Schoutsen
bf3ead3359 Use libsodium18 (#14624) 2018-05-25 11:32:45 -04:00
Marius Kotlarz
b4f8d52fb1 Add configurable decimal rounding of display value for CoinMarketCap sensor and upgrade to 5.0.3 (#14437) (#14604) 2018-05-25 15:39:04 +02:00
Matt Schmitt
143be49c66 Add HomeKit support for automations (#14595) 2018-05-25 11:38:48 +02:00
Matt Schmitt
a9f19a16ee Add HomeKit support for media players (#14446) 2018-05-25 11:37:20 +02:00
Nik Klever
d53a8c0823 Adding illumination sensor (#14615)
* Adding illumination sensor

Adding Illumination sensor of 1wire device DS2438 (DEVICE_SENSOR type 26) according to [OWFS API](http://owfs.org/index.php?page=ds2438)

* Correcting typo illumination -> illuminance
2018-05-25 10:29:20 +02:00
bastshoes
6e5c541a00 Add support container status for Glances on RPi3 (#14529)
* Add support container status for Glances on RPi3

Glances on RPi3 return different container status. 
```
"containers": [
        {
            "Status": "Up 2 hours",
            "name": "HASS",
            "io": {
                "iow": 0,
                "time_since_update": 5.1789350509643555,
                "cumulative_ior": 94208,
                "ior": 0,
                "cumulative_iow": 4096
            },
```
This small PR adds support dealing with this differences.

* Making line shorter

* Fixing indentation

* Fix lint error

* Fix ident

* Fix intend
2018-05-25 09:58:53 +02:00
Gregory Benner
2cd127921a Update pyrainbird (#14617) 2018-05-25 06:39:41 +02:00
Paulus Schoutsen
43d2e436b9 Version bump to 0.70.0b3 2018-05-24 14:25:15 -04:00
Paulus Schoutsen
ef35b8d428 Fix hue discovery popping up (#14614)
* Fix hue discovery popping up

* Fix result

* Fix tests
2018-05-24 14:24:58 -04:00
Tom Harris
69e86c29a6 Bump insteonplm version to fix device hanging (#14582)
* Update inteonplm to 0.9.2

* Change to force Travis CI

* Change to force Travis CI
2018-05-24 14:24:58 -04:00
Greg Laabs
a4d45c46e8 Fix ISY moisure sensors showing unknown until a leak is detected (#14496)
* Fix ISY leak sensors always showing UNKNOWN until a leak is detected

Added some logic that handles both moisture sensors and door/window sensors

* Handle edge case of leak sensor status update after ISY reboot

If a leak sensor is unknown, due to a recent reboot of the ISY, the status will get updated to dry upon the first heartbeat. This status update is the only way that a leak sensor's status changes without an accompanying Control event, so we need to watch for it.

* Fixes from overnight testing

State was checking the incorrect parameter, and wasn't calling schedule update

* Remove leftover debug log line

* Remove unnecessary pylint instruction

* Remove access of protected property

We can't cast _.status directly to a bool for some unknown reason (possibly with the VarEvents library), but casting to an int then bool does work.
2018-05-24 14:24:57 -04:00
Paulus Schoutsen
45d1d30a8b Update frontend to 20180524.0 2018-05-24 14:24:37 -04:00
Paulus Schoutsen
fa9b9105a8 Fix hue discovery popping up (#14614)
* Fix hue discovery popping up

* Fix result

* Fix tests
2018-05-24 14:24:14 -04:00
Paulus Schoutsen
4fb4838bde Update frontend to 20180524.0 2018-05-24 13:08:12 -04:00
Robert Beal
3a487e54a2 Upgrade linode-api to 4.1.9b1 (#13863) (#14610) 2018-05-24 17:16:35 +02:00
Marcelo Moreira de Mello
36da82aa8d Add Iperf3 client sensor (#14213) 2018-05-24 09:25:27 +02:00
Aaron Bach
5205354cb7 Adds a device class of 'garage' to MyQ covers (#14602) 2018-05-24 07:58:35 +02:00
Jason Hu
3498234448 Add Nest away binary sensor and eta sensor (#14406) 2018-05-23 21:40:33 +02:00
Charles Garwood
c13ebacce1 Remove nma component (#14594)
* Remove nma component

* Update .coveragerc
2018-05-23 20:36:51 +02:00
Fabian Affolter
ad49942201 Upgrade TwitterAPI to 2.5.3 (#14596) 2018-05-23 16:47:58 +02:00
SchumyHao
82770faad7 Add Xiaomi Aqara Lock support (#14419) 2018-05-22 10:40:11 +02:00
Fabian Affolter
a2f9fdf339 Add new transmission sensor types (#14530) 2018-05-22 10:06:14 +02:00
Malte Franken
a2decdaaa3 NUT sensor enhancements (#14570) (Fixes #14324)
* removed default value from required parameter; raising PlatformNotReady when connection to nut unavailable; output human-readable state name by default

* removed superfluous sensor name part; showing human-readable form and raw value of current status in more info dialog

* introduced a new virtual sensor type based on the raw status value but used to display a human-readable form of the status

* renamed method

* format string instead of concatenation

* revert the change to the device state attributes - only output the human-readable status without the raw value
2018-05-22 09:34:02 +02:00
Julian Knauer
72a1b7ae3f Lagute LW-12 Wifi LED control (#13307)
* Added platform lw12wifi for Lagute LW-12 Wifi Lights

Supported features:
* RGB colors
* Variable brightness
* 29 effects
* Changing transitions speed for animated effects

* Added lw12wifi to the list of omitted files to test

* Added lw12 module as new requirement for lw12wifi platform

* Added configuration example docstring for platform lw12wifi

* Updating code according to review in PR:

* Removed unused imports: enum, socket.
* Unused and not imported feature SUPPORT_FLASH was removed.
* Unused import lw12 in setup_platform method removed.
* Fixed indention for valuptuous.
* Changed check if effect is None.
* Removed personal debug output.
* Blocking function are not async anymore.

* Further improvements to satisfy PR.

* Unused import asyncio removed.
* Fixed: Return value and docstring no match up for `assumed_state`.

* Check if the set effect is supported, otherwise revert to normal light.

* Added describing missing docstrings to all functions.

* Adopted code to work with HS color setting.

* Syntactical change in comment.

* Removed redefinition of DOMAIN.

* Refactored lw12 controller setup: removed requirement for host and port in LW12Wifi class.

* Rewritten supported feature setup to a more static  expression.

* Removed unused rgb_color property

* Fixed typo in comment for set_light_option

* Changed RGB option validation schema

* Removed instance properties as config options

* Removed optional settings to be more inline with code style.

* Removed unused option from config example

* Removal of unused import

* Added property to disable state polling for this entity.

* Raise an exception if an unknown effect was selected.

* Fixed an issue with the check for known effects.

* As we do not need to set a default, use simple accessing by key.

* Log if an unknown effect was selected.

* Added link to future documentation.
2018-05-22 09:25:10 +02:00
Marcelo Moreira de Mello
2753dd0c5e Removed attribute current_time from Raincloudy sensors to avoid being triggered by recorder component (#14584) 2018-05-22 08:19:45 +02:00
Daniel Perna
118c49ecaa Update pyhomematic to 0.1.43 (#14583)
* Update __init__.py

* Update requirements_all.txt
2018-05-22 01:50:08 +02:00
Tom Harris
0d9b3bea10 Bump insteonplm version to fix device hanging (#14582)
* Update inteonplm to 0.9.2

* Change to force Travis CI

* Change to force Travis CI
2018-05-22 01:46:20 +02:00
Greg Laabs
23afdec767 Fix ISY moisure sensors showing unknown until a leak is detected (#14496)
* Fix ISY leak sensors always showing UNKNOWN until a leak is detected

Added some logic that handles both moisture sensors and door/window sensors

* Handle edge case of leak sensor status update after ISY reboot

If a leak sensor is unknown, due to a recent reboot of the ISY, the status will get updated to dry upon the first heartbeat. This status update is the only way that a leak sensor's status changes without an accompanying Control event, so we need to watch for it.

* Fixes from overnight testing

State was checking the incorrect parameter, and wasn't calling schedule update

* Remove leftover debug log line

* Remove unnecessary pylint instruction

* Remove access of protected property

We can't cast _.status directly to a bool for some unknown reason (possibly with the VarEvents library), but casting to an int then bool does work.
2018-05-21 21:00:01 +02:00
Paulus Schoutsen
4671bd95c6 Version bump to 0.70.0b2 2018-05-21 11:10:53 -04:00
Marco Orovecchia
1bc916927c fix nanoleaf aurora lights min and max temperature (#14571)
* fixed nanoleaf aurora lights min and max temperature

* review changes
2018-05-21 11:10:36 -04:00
cdce8p
2f8865d6cb Homekit style cleanup (#14556)
* Style cleanup

* Sorted imports
* Harmonized service calls

* Test improvements

* Small update
2018-05-21 11:10:35 -04:00
Martin Hjelmare
cfdea8d20f Wait for future mysensors gateway ready (#14398)
* Wait for future mysensors gateway ready

* Add an asyncio future that is done when the gateway reports the
  gateway ready message, I_GATEWAY_READY.
* This will make sure that the gateway is ready before home assistant
  fires the home assistant start event. Automations can now send
  messages to the gateway when home assistant is started.
* Use async timeout to wait max 15 seconds for ready gateway.

* Address comments
2018-05-21 11:10:35 -04:00
Marco Orovecchia
6e941af9b2 fix nanoleaf aurora lights min and max temperature (#14571)
* fixed nanoleaf aurora lights min and max temperature

* review changes
2018-05-21 11:02:50 -04:00
Paulus Schoutsen
ba9bb90cf7 Update frontend to 20180521.0 2018-05-21 11:01:47 -04:00
Paulus Schoutsen
2ff61786bc Update frontend to 20180521.0 2018-05-21 11:01:35 -04:00
Russell Cloran
9791c6b21b zha: Bump to zigpy-xbee 0.1.1 (#14566) 2018-05-20 21:57:09 -07:00
David F. Mulcahey
a183043d5d Add IlluminanceMeasurementSensor to ZHA (#14563)
* add IlluminanceMeasurementSensor

* address review comment

* Fix whitespace error during merge
2018-05-20 21:56:41 -07:00
cdce8p
0589379de5 Homekit style cleanup (#14556)
* Style cleanup

* Sorted imports
* Harmonized service calls

* Test improvements

* Small update
2018-05-20 22:25:53 -04:00
damarco
ee7e59fe68 zha: Set default binary_sensor state to false (#14553) 2018-05-20 16:14:18 -07:00
David F. Mulcahey
b489519930 zha: Add metering sensor (#14562) 2018-05-20 16:01:56 -07:00
David F. Mulcahey
4395217031 zha: Don't poll switch devices (#14560) 2018-05-20 16:00:51 -07:00
Marco Orovecchia
c8ad9c4daa Add auto discovery for nanoleaf aurora lights (#14301)
* auto discovery added for nanoleaf aurora lights

* changes requested by review

* visual indentation

* line too long

* hide autocreated config
2018-05-20 20:53:57 +02:00
Oliver
c050eb4100 Pushed to version 0.7.2 of denonavr (#14551) 2018-05-20 09:50:12 +02:00
Martin Hjelmare
c8a53c564a Wait for future mysensors gateway ready (#14398)
* Wait for future mysensors gateway ready

* Add an asyncio future that is done when the gateway reports the
  gateway ready message, I_GATEWAY_READY.
* This will make sure that the gateway is ready before home assistant
  fires the home assistant start event. Automations can now send
  messages to the gateway when home assistant is started.
* Use async timeout to wait max 15 seconds for ready gateway.

* Address comments
2018-05-19 18:33:52 -04:00
Kerwin Bryant
c316d5b0b9 Add support to ignore a xiaomi aqara gateway (#14428) 2018-05-19 22:36:47 +02:00
Fabian Affolter
e88fc33eef Fix sensor name (fixes #14535) (#14541) 2018-05-19 17:14:53 +02:00
Paulus Schoutsen
8854efd685 Version bump to 0.70.0b1 2018-05-19 10:45:18 -04:00
Paulus Schoutsen
b0e850ba5d Bump frontend to 20180519.0 2018-05-19 10:45:03 -04:00
Paulus Schoutsen
74f1f08ab5 Bump frontend to 20180519.0 2018-05-19 10:44:54 -04:00
Greg Dowling
aa51bb6cb9 Bump pyvera version (improve stability of poll loop). (#14540) 2018-05-19 10:49:52 +02:00
Fabian Affolter
8deb462471 Upgrade restrictedpython to 4.0b4 (#14537) 2018-05-19 10:05:02 +02:00
Fabian Affolter
46dc9322a2 Upgrade keyring to 12.2.1 (#14521) 2018-05-19 10:04:42 +02:00
Fabian Affolter
daf8143d01 Upgrade youtube_dl to 2018.05.18 (#14519) 2018-05-19 10:04:20 +02:00
Fabian Affolter
54dfe045b2 Upgrade aiohttp to 3.2.1 (#14517)
* Upgrade aiohttp to 3.2.1

* Upgrade async_timeout to 3.0.0

* Update the order of the requirements
2018-05-19 10:04:00 +02:00
Paulus Schoutsen
f2dfc84d52 Version bump to 0.70.0b0 2018-05-18 19:31:16 -04:00
Paulus Schoutsen
e55f7ebf81 Merge branch 'master' into dev 2018-05-18 19:30:48 -04:00
Paulus Schoutsen
8d06469efe Bump frontend to 20180518.1 2018-05-18 18:15:49 -04:00
Fabian Affolter
c1127133ea Set certifi to >=2018.04.16 (#14536) 2018-05-18 18:14:40 -04:00
Sean Dague
25970027c6 Update mychevy to 0.4.0 (#14372)
After 2 months of being offline, the my.chevy website seems to be
working again. Some data structures changed in the mean time. The new
library will handle multiple cars. This involves a breaking change in
slug urls for devices where these now include the car make, model, and
year in them.

Discovery has to be delayed until after the initial site login to get
the car metadata.
2018-05-18 13:37:43 -04:00
Greg Laabs
d7640e6ec3 Fix some ISY sensors not getting detected as binary sensors (#14497)
Sensors that were defined via sensor_string were not getting properly identified as binary sensors when they had a uom defining them as binary (the other three methods of detecting binary sensors worked though.)
2018-05-18 08:42:09 -07:00
cdce8p
12e76ef7c1 Update HAP-python to 2.1.0 (#14528) 2018-05-18 16:32:57 +02:00
hanzoh
d36996c8f0 Add Homematic IP RotaryHandleSensor support (#14522)
* Add Homematic IP RotaryHandleSensor support

HmIP-SRH was in the RotaryHandleSensor class and threw errors that LOWBAT and ERROR could not be found (they are LOW_BAT and SABOTAGE).

* Revert REQUIREMENTS change
2018-05-18 16:20:30 +02:00
Fabian Affolter
e929f45ab8 Set pytz to >=2018.04 (#14520) 2018-05-18 09:42:41 -04:00
cdce8p
4c328baaa6 Add code to HomeKit lock (#14524) 2018-05-18 13:52:52 +02:00
Fabian Affolter
cc5edf69e3 Show warning if no locations are shared (fixes #14177) (#14511) 2018-05-18 09:04:47 +02:00
Matt Snyder
909f2448ca Flux bug fix (#14476)
* Simplify conditionals.

* Send white_value on service call.

* Remove extra blank line

* Further simplification of conditionals

* Requested changes

* Do not call getRgb if not needed

* Update log message
2018-05-18 08:50:57 +02:00
Diogo Gomes
97076aa3fd Fix probability_threshold in binary_sensor.bayesian (#14512) (Closes: #14362) 2018-05-18 07:48:16 +02:00
Malte Franken
a3777c4ea8 Feedreader configurable update interval and max entries (#14487) 2018-05-18 07:25:08 +02:00
Paulus Schoutsen
1c3293ac85 Update frontend to 20180518.0 (#14510)
* Update frontend to 20180517.0

* Update requirements

* Bump frontend to 20180518.0
2018-05-17 21:29:37 -04:00
thelittlefireman
f06a0ba373 Bump locationsharinglib to 2.0.2 (#14359)
* Bump locationsharinglib to 2.0.2

* Bump locationsharinglib to 2.0.2
2018-05-17 23:06:39 +02:00
Anders Melchiorsen
9afc2634c6 Adjust LimitlessLED properties for running effects (#14481) 2018-05-17 20:54:25 +02:00
Nate Clark
ed3efc8712 Konnected component follow up (#14491)
* make device_discovered synchronous

* small fixes from code review

* use dispatcher to update sensor state

* update switch state based on response from the device

* interpolate entity_id into dispatcher signal

* cleanup lint

* change coroutine to callback
2018-05-17 20:19:05 +02:00
Mike
144524fbbb Update hitron_coda.py (#14506)
missed a typo that wasn't caught with testing since I don't have a Rogers router.
2018-05-17 19:44:01 +02:00
ChristianKuehnel
298d31e42b New Sensor FinTS (#14334) 2018-05-17 02:45:47 +02:00
Paulus Schoutsen
3e7d4fc902 Bump frontend to 20180516.1 2018-05-16 09:39:14 -04:00
Paulus Schoutsen
64223cea72 Update frontend to 20180516.0 2018-05-16 09:01:30 -04:00
Nathan Henrie
1053473111 Add stdout and stderr to debug output for shell_command (#14465) 2018-05-16 13:47:41 +02:00
Matt Schmitt
25dcddfeef Add HomeKit support for fans (#14351) 2018-05-16 13:15:59 +02:00
Ville Skyttä
e20f88c143 Use "Returns" consistently to avoid being treated as section (#14448)
Otherwise, by side effect, results in error D413 by recent pydocstyle.
2018-05-16 10:01:48 +02:00
William Scanlon
1533a68c06 Added option to invert aREST pin switch logic for active low relays (#14467)
* Added option to invert aREST pin switch logic for active low relays

* Fixed line lengths

* Changed naming and set optional invert default value.

* Fixed line length

* Removed default from get
2018-05-16 09:58:49 +02:00
Greg Laabs
5ff5c73e2b "unavailable" Media players should be considered off in Universal player (#14466)
The Universal media player inherits the states of the first child player that is not in some sort of "Off" state (including idle.) It was not considering the "unavailable" state to be off. Now it does.
2018-05-16 08:00:57 +02:00
Anders Melchiorsen
6ba49e12a2 Improve handling of offline Sonos devices (#14479) 2018-05-16 07:35:43 +02:00
nordlead2005
852ce9f990 Added temperature (apparent) high/low, deprecated max/min (#12233) 2018-05-15 21:26:41 +02:00
Paulus Schoutsen
df69680d24 Don't add a url to built-in panels (#14456)
* Don't add a url to built-in panels

* Add url_path back

* Lint

* Frontend bump to 20180515.0

* Fix tests
2018-05-15 14:47:46 -04:00
Gerard
2e7b5dcd19 BMW code cleanup (#14424)
* Some cleanup for BMW sensors

* Changed dict sort

* Updates based on review and Travis
2018-05-15 20:47:32 +02:00
Malte Franken
e49e0b5a13 Make Feedreader component more extendable (#14342)
* moved regular updates definition to own method to be able to override behaviour in subclass

* moved filter by max entries to own method to be able to override behaviour in subclass

* event type used when firing events to the bus now based on variable to be able to override behaviour in subclass

* feed id introduced instead of url for storing meta-data about the feed to be able to fetch the same feed from different configs with different filtering rules applied

* keep the status of the last update; continue processing the entries retrieved even if a recoverable error was detected while fetching the feed

* added test cases for feedreader component

* better explanation around breaking change

* fixing lint issues and hound violations

* fixing lint issue

* using assert_called_once_with instead of assert_called_once to make it compatible with python 3.5
2018-05-15 20:43:26 +02:00
Nate Clark
de50d5d9c1 Add Konnected component with support for discovery, binary sensor and switch (#13670)
* Add Konnected component with support for discovery, binary sensor, and switch

Co-authored-by: Eitan Mosenkis <eitan@mosenkis.net>

* Use more built-in constants from const.py

* Fix switch actuation with low-level trigger

* Quiet logging; Improve schema validation.

* Execute sync request outside of event loop

* Whitespace cleanup

* Cleanup config validation; async device setup

* Update API endpoint for Konnected 2.2.0 changes

* Update async coroutines via @OttoWinter

* Make backwards compatible with Konnected < 2.2.0

* Add constants suggested by @syssi

* Add to CODEOWNERS

* Remove TODO comment
2018-05-15 19:58:00 +02:00
c727
612a37b2dd Remove simplepush.io (#14358) 2018-05-15 16:57:51 +02:00
Diogo Gomes
d47006c98f Optimistic MQTT light (#14401)
* Restores light state, case the light is optimistic

* lint

* hound

* hound

* Added mqtt_json

* hound

* added mqtt_template

* lint

* cleanup

* use ATTR
2018-05-15 12:25:50 +02:00
Sebastian Muszynski
16bf10b1a2 Don't poll the Samsung Family hub camera (#14473) 2018-05-15 08:50:07 +02:00
William Scanlon
710533ae8a Minor Wink fixes (#14468)
* Updated Wink light supported feature to reflect what features a given light support.

* Fix typo in wink climate
2018-05-15 07:53:12 +02:00
Matthew Garrett
11c57f9345 Bump lakeside version (#14471)
This should fix a couple of issues with T1013 bulbs, and also handle
accounts that contain unknown devices.
2018-05-15 07:51:32 +02:00
Martin Hjelmare
7562b4164b Fix key error upon missing node (#14460)
* This is needed after gateway ready message generates an update while
  persistence is off, or while the gateway node hasn't been presented
  yet.
2018-05-14 22:52:44 +02:00
Gregory Benner
cf44b77225 Samsung Family hub camera component (#14458)
* add familyhub.py camera

* fix import and REQUIREMENTS

* add to coveragerc

* fix formatting to make houndci-bot happy

* ran scripts/gen_requirements_all.py

* use CONF_IP_ADDRESS

* Revert "ran scripts/gen_requirements_all.py"

This reverts commit 3a38681d8a.

* fix library name

* add missing docstrings and enable polling

* Sort imports
2018-05-14 22:52:35 +02:00
Matt Schmitt
44e9783c7c Add support for direction to fan template (#14371)
* Initial commit

* Update and add tests
2018-05-14 22:37:49 +02:00
Fabian Affolter
1b5c02ff67 Upgrade pygatt to 3.2.0 (#14447) 2018-05-14 21:52:54 +02:00
Russell Cloran
2f74ffcf81 zha: Fix cluster class check in single-cluster device type (#14303)
zigpy now allows custom devices, which might mean that devices have cluster
objects which are not instances of the default, but may be instances of
sub-classes of the default. This fixes the check for finding single-cluster
device entities to handle sub-classes properly.
2018-05-14 16:50:09 +02:00
Fabian Affolter
954e4796b8 Use ATTR_NAME from const.py (#14450) 2018-05-14 13:05:52 +02:00
Fabian Affolter
fb501282cc Add SpaceAPI support (#14204)
* Add SpaceAPI support

* Changes according PR comments

* Add tests

* Remove print

* Minor changes
2018-05-14 09:13:59 +02:00
Robert Svensson
c06351f2a9 Bump requirement to pydeconz v38 (#14452) 2018-05-14 08:41:17 +02:00
Johann Kellerman
6b9c65c9ce Allow qwikswitch sensors as part of devices (#14454) 2018-05-14 08:40:25 +02:00
Philip Rosenberg-Watt
8ae3caa292 Add priority and cycles to LaMetric (#14414)
* Add priority and cycles to LaMetric

Priority can be "info", "warning" (default), or "critical" and
cycles is the number of times the message is displayed. If cycles
is set to 0 we get a persistent notification that has to be dismissed
manually.

* Fix for schema and style

* Fix for style
2018-05-13 18:04:21 +02:00
Fabian Affolter
391e3196ea Upgrade distro to 1.3.0 (#14436) 2018-05-13 18:01:10 +02:00
Fabian Affolter
cb709931e4 Upgrade youtube_dl to 2018.05.09 (#14438) 2018-05-13 18:00:37 +02:00
Fabian Affolter
a750f8444e Upgrade Sphinx to 1.7.4 (#14439) 2018-05-13 18:00:08 +02:00
Fabian Affolter
a5bff4cd8d Upgrade python-telegram-bot to 10.1.0 (#14441) 2018-05-13 17:59:25 +02:00
Fabian Affolter
e0bc894cbb Upgrade pyota to 2.0.5 (#14442)
* Use constants

* Upgrade pyota to 2.0.5
2018-05-13 17:58:57 +02:00
Fabian Affolter
3ec56d55c5 Upgrade requests_mock to 1.5 (#14444) 2018-05-13 17:58:18 +02:00
Martin Hjelmare
b904a4e770 Remove universal wheel setting (#14445)
* Home assistant should not build a universal wheel since we don't
  support Python 2.
2018-05-13 17:57:52 +02:00
Ville Skyttä
146a9492ec Clean up some Python 3.4 remnants (#14433) 2018-05-13 17:56:42 +02:00
cdce8p
e5d714ef52 Fix fan service description (#14423) 2018-05-13 14:41:42 +02:00
Ville Skyttä
4d63baf705 Invoke pytest instead of py.test per upstream recommendation, #dropthedot (#14434)
http://blog.pytest.org/2016/whats-new-in-pytest-30/
https://twitter.com/hashtag/dropthedot
2018-05-13 12:11:55 +02:00
Ville Skyttä
234bf1f0ea Spelling, grammar etc fixes (#14432)
* Spelling, grammar etc fixes

* s/an api data/data of an api/
2018-05-13 12:09:28 +02:00
Ville Skyttä
843789528e Remove extra quotes from docstrings (#14431) 2018-05-13 11:06:15 +02:00
Krasimir Chariyski
ea2c073612 Add Bulgarian to Google TTS (#14422) 2018-05-12 17:46:00 -04:00
Andrey
d1228d5cf4 Look at registry before pulling zwave config values (#14408)
* Look at registry before deciding on ID for zwave values

* Reuse the new function
2018-05-12 17:45:36 -04:00
Andrey
7aec098a05 Bring back typing check. Meanwhile just for homeassistant/*.py (#14410)
* Bring back typing check. Meanwhile just for homeassistant/.py

* Change follow-imports to silent. Add a few more checks.
2018-05-12 17:44:53 -04:00
Ville Skyttä
70af7e5fad Update pylint to 1.8.4 (#14421) 2018-05-12 22:22:20 +02:00
Daniel Høyer Iversen
99e272fc8d Upgrade PyXiaomiGatewa to 0.9.3 (#14420) (Closes: #14417) 2018-05-12 21:12:53 +02:00
cdce8p
990f476ac9 Homekit test cleanup (#14416) 2018-05-12 17:10:19 +02:00
Paulus Schoutsen
9abc13aaa6 Merge pull request #14413 from home-assistant/rc
0.69.1
2018-05-12 09:35:30 -04:00
Paulus Schoutsen
d17186a8b7 Version bump to 0.69.1 2018-05-12 09:34:28 -04:00
Lukas Barth
6fedad7890 Fix waiting for setup that never happens (#14346) 2018-05-12 09:34:13 -04:00
Sebastian Muszynski
b371bf700f Bump PyXiaomiGateway version (#14412) 2018-05-12 15:09:48 +02:00
damarco
01ce43ec7c Use None as initial state in zha component (#14389)
* Return None if state is unknown

* Use None as initial state
2018-05-12 14:41:44 +02:00
Lukas Barth
b903bbc042 Fix waiting for setup that never happens (#14346) 2018-05-12 10:30:21 +02:00
Martin Hjelmare
304137e7ff Fix name of tox pylint env (#14402) 2018-05-12 10:07:10 +02:00
Matthew Treinish
e80628d45b Bump pycmus version (#14395)
This commit bumps the pycmus version used by the cmus component. There
was a bug in the previous version used, 1.0.0, when running in local
mode. This was caused by a mtreinish/pycmus#1 and also was reported in
the home-assistant forums (but not as an issue):

https://community.home-assistant.io/t/cant-install-cmus-component/7961

Version 0.1.1 of pycmus fixes this issue so it should work properly for
users running cmus and home-assistant on the same machine.
2018-05-12 07:51:48 +02:00
Sebastian Muszynski
d6b81fb345 Xiaomi Aqara: Add new cube model (sensor_cube.aqgl01) (#14393) 2018-05-11 22:40:32 +02:00
Paulus Schoutsen
c5cac04e54 Merge pull request #14392 from home-assistant/rc
0.69
2018-05-11 12:38:08 -04:00
Matt Schmitt
621c653fed Allow HomeKit name to be customized (#14159) 2018-05-11 14:22:45 +02:00
Malte Franken
48d70e520f more detailed error message (#14385) 2018-05-11 12:28:28 +02:00
Robin
528ad56530 Adds facebox (#14356)
* Adds facebox

* Update .coveragerc

* Remove facebox

* Add test of faces attribute

* Add event test

* Adds more tests

* Adds tests to increase coverage

* Rename MOCK_FACES to MOCK_FACE

* Adds STATE_UNKNOWN
2018-05-11 09:57:00 +02:00
Martin Hjelmare
be3b227a87 Make mysensors component async (#13641)
* Make mysensors component async

* Use async dispatcher and discovery.
* Run I/O in executor.
* Make mysensors actuator methods async.
* Upgrade pymysensors to 0.13.0.
* Use async serial gateway.
* Use async TCP gateway.
* Use async mqtt gateway.

* Start gateway before hass start event

* Make sure gateway is started after discovery of persistent devices
  and after corresponding platforms have been loaded.
* Don't wait to start gateway until after hass start.

* Bump pymysensors to 0.14.0
2018-05-11 09:39:18 +02:00
damarco
ef8fc1f201 Update sensor state before adding device (#14357) 2018-05-10 22:32:16 -07:00
Paulus Schoutsen
8c0b45af1e Version bump to 0.69.0 2018-05-10 22:40:04 -04:00
Paulus Schoutsen
3b39ab5b94 Remove domain expiry sensor (#14381) 2018-05-10 22:39:35 -04:00
cdce8p
8fcf085829 Rewritten HomeKit tests (#14377)
* Use pytest fixtures and parametrize
* Use async
2018-05-11 01:21:59 +02:00
Abílio Costa
6843893d9f Add "framerate" parameter to generic camera (#14079)
* add "framerate" parameter to generic camera

* fix lint
2018-05-11 00:22:02 +02:00
damarco
e963fc5acf Add support for pressure sensors (#14361) 2018-05-10 23:55:32 +02:00
Paulus Schoutsen
bc664c276c Bump frontend to 20180510.1 2018-05-10 17:38:41 -04:00
Paulus Schoutsen
f192ef8219 Remove domain expiry sensor (#14381) 2018-05-10 23:13:00 +02:00
damarco
db31cdf075 Fix binary_sensor device_state_attributes (#14375) 2018-05-10 21:28:57 +02:00
Andrey
f168226be9 Update to sensibo 1.0.3 with better error reporting (#14380) 2018-05-10 21:11:02 +02:00
Paulus Schoutsen
ea01b127c2 Add local auth provider (#14365)
* Add local auth provider

* Lint

* Docstring
2018-05-10 14:09:22 -04:00
damarco
6e831138b4 Fix binary_sensor async_update (#14376) 2018-05-10 10:59:23 -07:00
Pascal Vizeli
eb2671f4bb Update .coveragerc (#14368) 2018-05-10 13:18:13 +02:00
cdce8p
8d017b7678 script/lint: Ensure there are files to test with pylint (#14363) 2018-05-10 12:47:04 +02:00
Paulus Schoutsen
5ec7fc7ddb Backend tweaks to make authorization work (#14339)
* Backend tweaks to make authorization work

* Lint

* Add test

* Validate redirect uris

* Fix tests

* Fix tests

* Lint
2018-05-10 10:38:11 +02:00
Teemu R
0f3ec94fba debug++ for multiple volume controls (#14349)
Be less noisy for those who have more volume controls than one, mentioned in #13022.
2018-05-09 13:44:42 +02:00
Fabian Affolter
2c566072f5 Upgrade keyring to 12.2.0 and keyrings.alt to 3.1 (#14355) 2018-05-09 11:31:18 +02:00
Nash Kaminski
cf8562a030 Support control of away mode and hold mode in Venstar component. Correctly detect humidifiers. (#14256)
* Implement support for away mode and hold mode in Venstar component

* Fix Venstar humidifier capability detection

* Add option to configure humidifier control in Venstar component

* style fix: add missing space and resolve pylint issues

* Remove quotes
2018-05-09 11:26:29 +02:00
Mal Curtis
a91c1bc668 Add zone 3 for Onkyo media player (#14295)
* Add zone 3 for Onkyo media player

* CR Updates

* Fix travis lint errors
2018-05-08 22:33:38 -04:00
Paulus Schoutsen
f406fd57ac Version bump to 0.69.0b3 2018-05-08 20:55:35 -04:00
Anders Melchiorsen
2d0e3c1402 Ignore NaN values for influxdb (#14347)
* Ignore NaN values for influxdb

* Catch TypeError
2018-05-08 20:55:12 -04:00
Paulus Schoutsen
01ec4a7afd Bump frontend to 20180509.0 2018-05-08 20:54:49 -04:00
Anders Melchiorsen
d43e6a2888 Ignore NaN values for influxdb (#14347)
* Ignore NaN values for influxdb

* Catch TypeError
2018-05-08 20:54:38 -04:00
Paulus Schoutsen
50cea77887 Bump frontend to 20180509.0 2018-05-08 20:48:46 -04:00
Mario Di Raimondo
6231394614 Waze Travel Time: optional inclusive/exclusive filters (#14000)
* Waze Travel Time: optional inclusive/exclusive filters

Added optional `inc_filter` and `excl_filter' params that allow to refine the reported routes: the first is not always the best/desired. A simple case-insensitive filtering (no regular expression) is used.

* fix line lenght

* fix spaces

* Rename var

* Fix typo

* Fix missing var
2018-05-09 00:35:03 +02:00
Aaron Bach
f516cc7dc6 Adds useful attributes to RainMachine programs and zones (#14087)
* Starting to add attributes

* All attributes added to programs

* Basic zone attributes in place

* Added advanced properties for zones

* Working to move common logic into component + dispatcher

* We shouldn't calculate the MAC with every entity

* Small fixes

* Small adjustments

* Owner-requested changes

* Restart

* Restart part 2

* Added ID attribute to each switch

* Collaborator-requested changes
2018-05-08 18:10:03 -04:00
Evgeniy
9c7523d7b0 Improving icloud device tracker (#14078)
* Improving icloud device tracker

* Adding config validations for new values

* Adding config validations for new values

* Moving icloud specific setup to platform schema. Setting default in platform schema.
2018-05-08 23:42:57 +02:00
Andrey
10505d542a Make sure zwave nodes/entities enter the registry is proper state. (#14251)
* When zwave node's info is parsed remove it and re-add back.

* Delay value entity if not ready

* If node is ready consider it parsed even if manufacturer/product are missing.

* Add annotations
2018-05-08 15:30:28 -04:00
Nick Whyte
e12994a0cd Fix BOM weather '-' value (#14042) 2018-05-08 13:35:55 -04:00
stephanerosi
ff01aa40c9 Add help for conversation/process service (#14323)
* Add help for conversation/process service

* Add logging to debug text received when service is called

* Move conversation to specific folder
2018-05-08 13:24:27 -04:00
Paulus Schoutsen
6199e50e80 Fix Insteon PLM coverage 2018-05-08 11:55:04 -04:00
Tod Schmidt
c664c20165 Snips: Added slot values for siteId and probability (#14315)
* Added solt values for siteId and probability

* Update snips.py

* Update test_snips.py
2018-05-08 11:43:31 -04:00
David Broadfoot
eb551a6d5a Gogogate2 0.1.1 (#14294)
* Gogogate2 - bump version

Uses latest version of library which ensures commands to device are idempotent

* Update requirements_all

* Expose sensor temperature

* update version

* import attribute

* Set temperature

* Remove temperature attribute

Removed temperature attribute until it can be re-implemented as a separate sensor.

* Update ordering

* Fix copy-&-paste issue
2018-05-08 11:42:18 -04:00
m4dmin
4343659742 add 2 devices (#14321)
* add 2 devices

io:RollerShutterUnoIOComponent
io:ExteriorVenetianBlindIOComponent

* add 2 devices

* Update tahoma.py

* Fix hounci-bot violation

* Fixed Travis CI build failure

./homeassistant/components/cover/tahoma.py:83:13: E125 continuation line with same indent as next logical line

* Fixed Travis CI build failure

E125 continuation line with same indent as next logical line

* Fixed Travis CI build failure

E127 continuation line over-indented for visual indent

* Fix indent

* Change check
2018-05-08 13:43:07 +02:00
Mattias Welponer
230bd3929c Add more homematicip cloud components (#14084)
* Add support for shutter contact and motion detector device

* Add support for power switch devices

* Add support for light switch device

* Cleanup binary_switch and light platform

* Update comment
2018-05-08 09:57:51 +02:00
Gerard
ba7333e804 Add sensors for BMW electric cars (#14293)
* Add sensors for electric cars

* Updates based on review of @MartinHjelmare

* Fix Travis error

* Another fix for Travis
2018-05-08 09:52:21 +02:00
Mike
48b13cc865 Update hitron_coda.py to fix login for Shaw modems (#14306)
I have a Hitron modem provided by Shaw communications rather than from Rogers as the Docs specify for this device_tracker but it seems like the api/code is all the same except that the login failed due to the password being passed as "pws" instead of "pwd". Making that one character change allowed HASS to read the connected device details from my Hitron modem. If this difference is actually one that stands between the Rogers-provided Hitron modems and the Shaw-provided variant, I am happy to create another device-tracker file for the Shaw modem. I just figured I would go with the simplest solution first.
2018-05-08 09:26:46 +02:00
Aaron Bach
e7c7b9b2a9 Adds unique ID to Roku for entity registry inclusion (#14325)
* Adds unique ID to Roku for entity registry inclusion

* Owner-requested changes
2018-05-07 13:18:51 -04:00
Paulus Schoutsen
8d24541ffe Version bump to 0.69.0b2 2018-05-07 13:12:54 -04:00
Paulus Schoutsen
b1eb35ee11 Ignore more loading errors (#14331) 2018-05-07 13:12:43 -04:00
Paulus Schoutsen
c7166241f7 Ignore more loading errors (#14331) 2018-05-07 13:12:12 -04:00
Paulus Schoutsen
a4e1615127 Version bump to 0.69.0b1 2018-05-07 10:05:34 -04:00
Javier Gonel
3e5d76efb2 fix(hbmqtt): partial packets breaking hbmqtt (#14329)
This issue was fixed in hbmqtt/issues#95 that was released in hbmqtt 0.9.2
2018-05-07 10:01:23 -04:00
Paulus Schoutsen
6a74fa344d Revert custom component loading logic (#14327)
* Revert custom component loading logic

* Lint

* Fix tests

* Guard for infinite inserts into sys.path
2018-05-07 10:01:22 -04:00
Paulus Schoutsen
c4ec2e3434 Fix module names for custom components (#14317)
* Fix module names for custom components

* Also set __package__ correctly

* bla

* Remove print
2018-05-07 10:01:22 -04:00
cdce8p
c48986a467 Add debounce to move_cover (#14314)
* Add debounce to move_cover

* Fix spelling mistake
2018-05-07 10:01:22 -04:00
Justin Loutsenhizer
ab621808bd Add missing 'sensor' to ABODE_PLATFORMS (#14313)
This fixes missing light, humidity, temperature sensors from abode component.
2018-05-07 10:01:21 -04:00
Paulus Schoutsen
5c88e897af Update netdisco to 1.4.1 2018-05-07 10:01:06 -04:00
Paulus Schoutsen
6318178a8b Update netdisco to 1.4.1 2018-05-07 10:00:54 -04:00
Javier Gonel
a2b8ad50f2 fix(hbmqtt): partial packets breaking hbmqtt (#14329)
This issue was fixed in hbmqtt/issues#95 that was released in hbmqtt 0.9.2
2018-05-07 09:52:33 -04:00
Paulus Schoutsen
5c95c53c6c Revert custom component loading logic (#14327)
* Revert custom component loading logic

* Lint

* Fix tests

* Guard for infinite inserts into sys.path
2018-05-07 11:25:48 +02:00
Jerad Meisner
e60d066514 Converted SABnzbd to a component (#12915)
* Converted SABnzbd to a component

* fixed async issues

* Made sabnzbd scan interval static. More async fixes.

* Sabnzbd component code cleanup

* Skip sensor platform setup if discovery_info is None
2018-05-07 09:35:55 +02:00
cdce8p
91fe6e4e56 Add debounce to move_cover (#14314)
* Add debounce to move_cover

* Fix spelling mistake
2018-05-06 20:55:38 -04:00
Paulus Schoutsen
34727be5ac Fix module names for custom components (#14317)
* Fix module names for custom components

* Also set __package__ correctly

* bla

* Remove print
2018-05-06 20:54:56 -04:00
Justin Loutsenhizer
107769ab81 Add missing 'sensor' to ABODE_PLATFORMS (#14313)
This fixes missing light, humidity, temperature sensors from abode component.
2018-05-06 19:18:26 +02:00
Russell Cloran
63cc179ea2 zha: Bump to zigpy 0.1.0 (#14305) 2018-05-06 11:17:05 +02:00
thepotoo
2bb1a95098 Add unique_id to MQTT switch (#13719) 2018-05-06 08:21:02 +02:00
Paulus Schoutsen
f3411f8db2 Version bump to 0.70.0.dev0 2018-05-05 11:42:32 -04:00
Paulus Schoutsen
1e31af77de Version bump to 0.69.0b0 2018-05-05 11:41:55 -04:00
Paulus Schoutsen
2326312bee Merge branch 'master' into dev 2018-05-05 11:41:29 -04:00
Paulus Schoutsen
83e342daf2 Update frontend to 20180505.0 2018-05-05 11:35:42 -04:00
Paulus Schoutsen
a4b69833d4 Update translations 2018-05-05 11:35:02 -04:00
Tom Harris
64ba2c63c7 Add All-Linking capabilities (#14065)
* Setup all-linking service

* Remove extra line

* Remove linefeed and tab escape chars

* Add services delete_all_link, load_all_link_database and print_all_link_database

* Check if reload is set

* Confirm entity is InsteonPLMEntity before attempting to load or print ALDB

* Debug load and print ALDB

* Debug print aldb

* Debug print_aldb

* Get entity via platform

* Track Insteon entities in component

* Store entity list in hass.data

* Add entity to hass.data

* Add ref to hass in InsteonPLMEntity

* Pass hass correctly to InsteonPLMBinarySensor

* Fix reference to ALDBStatus.PARTIAL

* Print ALDB record as string

* Get ALDB record from memory address

* Reformat ALDB log output

* Add print_im_aldb service

* Remove reference to self in print_aldb_to_log

* Remove reference to self in print_aldb_to_log

* Fix spelling issue with load_all_link_database service

* Bump insteonplm to 0.9.1

* Changes from code review

* Code review changes

* Fix syntax error

* Correct reference to cv.boolean and update requirements

* Update requirements

* Fix flake8 errors

* Reload as boolean test

* Remove hass from entity init
2018-05-05 11:15:20 -04:00
Ron Šmeral
2e8eaf40f7 Onkyo: SUPPORT_VOLUME_STEP (#14299) 2018-05-05 17:06:32 +02:00
Robin
b9e893184a Refactor ImageProcessingFaceEntity (#14296)
* Refactor ImageProcessingFaceEntity

* Replace STATE_UNKNOWN with None
2018-05-05 16:57:53 +02:00
Jason Kingsbury
4d085882d5 Add support for max_volume (#13822)
* onkyo: add support for max volume range

* onkyo: make flake8 happy

* onkyo: fix PEP8 D205 on line 181

* onkyo: use range for max_volume configuration

* onkyo: fix line too long
2018-05-05 10:30:54 -04:00
Jesse Newland
f6e29a6647 Add domain to labels and count state changes to Prometheus (#14253)
* Add domain to labels

* Count state changes
2018-05-05 10:23:01 -04:00
Jesse Newland
1a936220e9 Add alarmdotcom sensor status (#14254)
* bump to match Xorso/pyalarmdotcom#9

* Load additional status attributes

* missed a spot
2018-05-05 10:21:58 -04:00
Robert Svensson
8410b63d9c deCONZ add new device without restart (#14221)
* Add new device without restarting hass

* Remove debug prints

* Fix copy paste error

* Fix comments from balloob
Add tests to verify signalling with new added devices

* Fix hound comments
Add test to verify when new sensor is added

* Fix tests

* Unload entry should unsubscribe all deconz dispatchers

* Make sure mock setup also creates unsub in hass data

* Fix copy paste issue

* Lint
2018-05-05 10:11:00 -04:00
Lukas Barth
af8cd63838 Matrix Chatbot (#13355)
* Add first version of the Matrix bot

* It's a stupid but necessary change…

* Dont list it twice

* All hail the linter!

* More linter-pleasing

* Use the correct user ID

* Add expression commands

* Add tests for new validators

* Fix room alias handling

* Wording

* Defer setup

* Simplify commands

* Handle exceptions

* Update requirements

* Review

* Move login back to constructor

* Fix review comments
2018-05-05 10:00:36 -04:00
cdce8p
95d27bd1fa Sensor device classes (#14282)
* Added light device class, moved device classes to const

* Removed unnecessary icons

* Replace 'lux' with 'lx'

* Fix comment

* Changed device_class name
2018-05-05 09:37:40 -04:00
blackwind
ec3ce4c80d Publish attributes unconditionally (#14179)
* Publish attributes unconditionally

Because the attribute publish command was previously hidden behind `if val:`, falsy values like False and 0.0 weren't being published, thereby making Statestream -- particularly in the case of booleans, where the first True would be retained indefinitely -- a completely worthless indicator of state.

* Change bool test to False to confirm falsy values pass
2018-05-05 09:31:39 -04:00
Nick Whyte
5ade84d75f BOM Weather throttle fix (#14234) 2018-05-05 11:17:27 +02:00
Fabian Affolter
75bf483071 Upgrade astral to 1.6.1 (#14297) 2018-05-05 10:45:09 +02:00
Diogo Gomes
354470469f Fix filter sensor missing window_size argument (#14252)
* missing window_size argument

* test throttle filter configuration
2018-05-05 03:10:08 +02:00
Matt Schmitt
255a85ad02 HomeKit: Support triggered state for alarm_control_panel (#14285) 2018-05-05 00:09:16 +02:00
cdce8p
bb76ba67f3 Homekit: Changed device_class requirement Humidity Sensor (#14277) 2018-05-04 22:48:38 +02:00
Fabian Affolter
7900ba30bf Upgrade holidays to 0.9.5 (#14274) 2018-05-04 17:09:05 +02:00
cdce8p
e37fd5b132 Update HAP-python to 2.0.0 (#14278)
* Fixed async (added 'async_add_job' and 'add_job')

* Driver status

* Use pyhap category constants

* Changed 'set_broker' to 'set_driver'

* Changed loader method names

* Use 'serv.configure_char'

* Use 'self.set_info_service'

* Use 'self.add_preload_service'

* Fix hound issue

* Updated HAP-python to 2.0.0
2018-05-04 16:46:00 +02:00
Fabian Affolter
f98525acbf Upgrade attrs to 18.1.0 (#14281) 2018-05-04 08:58:34 -04:00
Otto Winter
36cf2125ce Issue Template Fix CRLF (#14283) 2018-05-04 13:49:13 +02:00
Boyi C
c80b752d0e fix check config not working after #14211 (#14259) 2018-05-04 12:29:07 +02:00
Anders Melchiorsen
fa0ad7b317 Color fixes for Wink lights (#14263) 2018-05-04 12:28:56 +02:00
Fabian Affolter
b49d98407c Remove feature request 2018-05-04 10:56:35 +02:00
Fabian Affolter
5f8f6666e6 Update issue templates 2018-05-04 10:55:55 +02:00
Fabian Affolter
54ccbbcb64 Update issue templates 2018-05-04 10:54:55 +02:00
Fabian Affolter
a7a3cff0f1 Update issue templates 2018-05-04 10:52:20 +02:00
Fabian Affolter
9859840b9c Update issue templates 2018-05-04 10:48:13 +02:00
cdce8p
8cabec7ac1 Fix ZWave light brightness (#14261)
* Fix ZWave light brightness
* The brightness should always be an integer
* Changed to round
2018-05-03 23:28:03 +02:00
Paulus Schoutsen
15e75b07d8 Allow fetching media player covers via websocket connection (#14233)
Lint
2018-05-03 22:03:26 +02:00
Paulus Schoutsen
58257af289 Add fetching camera thumbnails over websocket (#14231)
* Add fetching camera thumbnails over websocket

* Lint
2018-05-03 22:02:59 +02:00
Erik Eriksson
4ecce2598a Re-enable eliqonline requirement (#14265) 2018-05-03 19:54:37 +02:00
cdce8p
e68b52d50d Demo Sensor - Added device_class support (#14269) 2018-05-03 19:51:36 +02:00
roiff
c9de2f015b HomeKit - Climate: power state on/off support (#14082)
* add power state  support on off
* Added check for current operation mode
* Extended 'set_heat_cool'
* Added tests
2018-05-03 18:22:43 +02:00
giangvo
ef4498ec27 Issue/add template fans (#12027)
* add template fan

* add-template: address PR comments

* add-template: remove unused import

* add-template: revert async_track_state_change change

* add-template: use yield from

* Revert "add-template: use yield from"

This reverts commit 1e053714a7.

* add-template: use yield

* add-template: remove unused import

* add-template: remove async_add_job usages

* use components

* add-template: use async/await

* add-template: fix style

* add-template: remove str()

* address pr comments

* fix style
2018-05-02 17:45:31 -04:00
Diogo Gomes
c851dfa2c7 Restores switch state, case the switch is optimistic (#14151)
* Add restore_state to optimistic switch

* no need to schedule update

* test added

* lint

* new async syntax

* lint
2018-05-02 17:29:07 -04:00
Mark Coombes
64b9fbd8d9 Add prereqs for HomeKit Controller (#14172) 2018-05-02 16:28:43 -04:00
Andrey
f72d568374 Add unique_id to zwave node entity (#14201)
* Add unique_id to zwave node entity

* Wait 30s before adding zwave node if its unique_id is not ready

* Use only node_id in unique_id. Update name, manufacturer, and product attributes on node update.
2018-05-02 16:10:26 -04:00
Per Osbäck
351e8921fa python_openzwave update config service (#12060)
* update python-openzwave to 4.1.0

* add service which updates the configuration files from github

* 0.4.3
2018-05-02 15:06:09 -04:00
Mick Vleeshouwer
b66be59598 Add PostNL sensor (Dutch Postal Services) (#12366)
* Add basic PostNL sensor (WIP)

* Update PostNL sensor

* Bump version

* Small updates to PostNL package based on feedback

* Remove unused import

* Pass api to sensor

* Refactor based on feedback

* Update based on feedback

* Fix feedback

* Clean up

* Bugfiix

* Bugfix

* SCAN_INTERVAL fix

* Remove unused import

* Refactor for new wrapper implementation

* Update postnl package requirement

* Change throttle logic

* Update package version

* Add new line

* Minor changes

* Change refresh time to 30 minutes

* Update requirements_all.txt
2018-05-02 14:37:41 -04:00
Otto Winter
14c7fa8882 WUnderground unique ids (#13311)
* WUnderground unique_id

* Remove async_generate_entity_id

* Lint

* Address comment
2018-05-02 14:23:07 -04:00
Mathieu Velten
ce98dfe395 Add support for tracking devices on Netgear access points (#13331)
* Netgear: add support for tracking devices on access points

* Netgear: add SSL support and autodetection
2018-05-02 09:38:24 -04:00
Anders Melchiorsen
bf056b6f01 Fix Hue color state for missing xy (#14230) 2018-05-02 09:25:08 -04:00
Sebastian Muszynski
8b13658d3b Improve config schema of the blackbird component (#14007)
* Import moved, return values removed and redundant log message removed

* Improve config schema of the blackbird component

* Tests updated

* Handle updated

* Schema fixed
2018-05-02 09:21:50 -04:00
Diogo Gomes
e968b1a0f4 UPnP code cleanup (#14235)
* missing async calls

* lint

* cleanup
2018-05-02 09:15:30 -04:00
Mohamad Tarbin
6453ea4e61 Add Social Blade Sensor (#14060)
* Adding Dominion Energy Sensor

* Update : remove white spacves and set the update time to be daily

* Update : update spacing as per hound suggestions, Move imports

* Update :  Fix  Travis CI build errors

* Update Documentations on method levels

* Update Documentations on method levels

* Update Documentations on method levels

* Add Exception Handeling if login failed, add PLATFORM_SCHEMA

* Add Exception Handeling if login failed, add PLATFORM_SCHEMA

* Add Exception Handeling if login failed, add PLATFORM_SCHEMA

* Update dominionenergy.py

* Adding Selenium to requirements_all.txt

* Checking the username/password while setup

* Checking the username/password while setup

* removing extra white space

* Update : Adding the Platform only if credentials works

* Update : Add PlatformNotReady exception

* Update : Add PlatformNotReady exception

* Update .coveragerc

* Remove change

* Adding USCIS component

* Adding Line after the class DOC

* Update : Extract USCIS logic code to Component

* Update : Extract USCIS logic code to Component

* Adding CURRENT_STATUS

* Change Error handling, remove date from attributes

* Update the Version for USCIS

* Add Social Blade Sensor

* Update class documentation

* Update coverage and requirements_all

* Update : houndci error with intent

* Update : Add coverage

* Update uscis.py

* Add comments

* Add comments

* Delete dominionenergy.py

* Update requirements_all.txt

* Update .coveragerc

* Update .coveragerc

* Update .coveragerc

* Update : update after code review

* Fix remaining issues
2018-05-01 22:27:20 +02:00
Matt Snyder
c2d00be91e Allow independent control of white level on flux_led component (#13985)
* Allow independent control of white level on flux_led component.

Also preserve brightness on color change.

* Limit white value support to RGBW mode.

* Requested changes.

* Correct liniting issues

* Formatting
2018-05-01 15:38:45 -04:00
Otto Winter
e4655a7e63 Add MQTT Sensor device_class (#14033)
* Add MQTT Sensor device_class

* Add test
2018-05-01 15:38:08 -04:00
Aaron Bach
7a05471912 Converts RainMachine to hub model (part 2) (#14225)
* Converts RainMachine to hub model (part 2)

* Small style adjustments for consistency

* Moving MAC calculation to one-time call in component

* Removing unneeded attribute

* Bumping Travis

* Lint
2018-05-01 15:36:43 -04:00
escoand
8d5c3a2b91 add volumio discovery (#14220)
* add volumio discovery

* add missing library

* Update volumio.py
2018-05-01 15:20:38 -04:00
corneyl
2f0fc0934f Buienradar improvements: continuous sensors and unique ID's (#13249)
* Force update continuous sensors when new measurement available.

* Added unique ID's based on coordinates, sensor type and client name.

* Fixed over-indentation (hound review)

* Revert "Added unique ID's based on coordinates, sensor type and client name."

This reverts commit 3345e67a15.

* Fix lint errors.

* Re-added unique ID's based on location.

* Removed wrong error logging.

* Removed creating UUID from unique id

* Lint
2018-05-01 15:06:41 -04:00
Paulus Schoutsen
83d300fd11 Custom component loading cleanup (#14211)
* Clean up custom component loading

* Fix some tests

* Fix some stuff

* Make imports work again

* Fix tests

* Remove debug print

* Lint
2018-05-01 20:57:30 +02:00
Ville Skyttä
5d96751168 panasonic_viera: Provide unique_id from SSDP UDN, if available (#13541) 2018-05-01 14:54:06 -04:00
NovapaX
38560cda1c Allow to set a desired update interval for camera_proxy_stream view (#13350)
* allow to set a desired update interval for camera_proxy_stream view

* lint

* refactor into a seperate method.
Keep the handle_async_mjpeg_stream method to be overridden by platforms
so they can keep proxying the direct streams from the camera

* change descriptions

* consolidate

* lint

* travis

* async/await and force min stream interval for fallback stream.

* guard clause. Let the method raise error on interval.

* is is not =

* what to except when you're excepting

* raise ValueError, remove unnecessary 500 response
2018-05-01 14:49:33 -04:00
blackwind
bf53cbe08d Support setting explicit mute value for Panasonic Viera TV (#13954)
* Use module's methods instead of API calls

* Use module's methods instead of API calls for media commands
2018-05-01 14:41:36 -04:00
Ruben
b00f771541 Add more parameters for DSMR sensor (#13967)
* Add more parameters for DSMR component

* Add suiting icon for power failure

* Add suiting icon for swells & sags

* Fix tab indentation -> spaces

* Fix too long lines (PEP8)
2018-05-01 14:40:48 -04:00
Otto Winter
9bc8f6649b Template Sensor add device_class support (#14034)
* Template Sensor Device Class Support

* Lint

* Add tests
2018-05-01 14:32:44 -04:00
Fabian Affolter
b0cccbfd9f Upgrade mypy to 0.590 (#14207) 2018-05-01 14:14:28 -04:00
Simon Hörrle
e78497789b Change the divisor for total consumption output (#14215)
According to my observations, the "switch_energy" value displayed by Pyfritzhome is the sum of Wh over the last week since measurement.
As a result, the correct divisor for representing output as kWh would be 1000 instead of 10000.
2018-05-01 14:13:35 -04:00
Paulus Schoutsen
d82693b460 Allow easy extension of websocket API (#14186)
* Allow easy extension of websocket API

* Lint

* Move panel test to frontend

* Register websocket commands

* Simplify test

* Lint
2018-05-01 13:35:23 -04:00
Paulus Schoutsen
cdd45e7878 Foundation for users (#13968)
* Add initial user foundation to Home Assistant

* Address comments

* Address comments

* Allow non-ascii passwords

* One more utf-8 hmac compare digest

* Add new line
2018-05-01 18:20:41 +02:00
sander76
b994c10d7f HomematicIP cloud: Add logic to check accesspoint connection state (#14203)
* Add logic to check accesspoint connection state

* lint

* changes as per @balloobs comments.

* pylint fix
2018-05-01 11:01:13 -04:00
Russell Cloran
9d4d1c8233 zha: Clean up binary_sensor listener registration/state updates (#14197)
- Instead of registering listeners in the entity __init__, do it in
   async_added_to_hass to avoid errors updating an entity which isn't fully
   set up yet
 - Change from schedule_update_ha_state to async_schedule_update_ha_state
2018-05-01 08:55:25 -04:00
Diogo Gomes
a4e0c9c251 Fixes #14169 (Upgrade pyupnp-async to 0.1.0.2) (#14210)
* Fixes #14169 (upstream version bump)

* bump pyupnp-async version
2018-05-01 08:51:47 -04:00
Philipp Schmitt
626d6df545 Update CODEOWNERS (#14214) 2018-05-01 10:14:33 +02:00
Paulus Schoutsen
12dff5baa8 Add room hint support to Google Assistant cloud (#14180) 2018-04-30 21:05:29 +02:00
Paulus Schoutsen
d1460de89b Merge pull request #14199 from home-assistant/rc
0.68.1
2018-04-30 14:04:29 -04:00
Paulus Schoutsen
c23cc0e827 Disable eliqonline requirement (#14156)
* Disable eliqonline requirement

* Disable pylint import error
2018-04-30 13:46:47 -04:00
Paulus Schoutsen
c704ceaeb7 Version bump to 0.68.1 2018-04-30 13:37:12 -04:00
Paulus Schoutsen
daeccfe764 Fix poorly formatted automations (#14196) 2018-04-30 13:36:56 -04:00
Otto Winter
7f1b591fbb Improve chromecast disconnection logic (#14190)
* Attempt Cast Fix

* Cleanup
2018-04-30 13:36:55 -04:00
Paulus Schoutsen
aba143ac9f Do not sync entities with an empty name (#14181) 2018-04-30 13:36:55 -04:00
cdce8p
03c34804bc Added CONF_IP_ADDRESS to HomeKit (#14163) 2018-04-30 13:36:54 -04:00
Matthew Garrett
f2a17a5462 Fix Python 3.6 compatibility for HomeKit controller (#14160)
Python 3.6's http client passes an additional argument to _send_output,
so add that to the function definition.
2018-04-30 13:36:54 -04:00
Anders Melchiorsen
b5bae17c66 Revert Hue color state to be xy-based (#14154) 2018-04-30 13:36:54 -04:00
Anders Melchiorsen
52a48b3ac9 Improve precision of Hue color state (#14113) 2018-04-30 13:36:53 -04:00
Anders Melchiorsen
a06f61034c Fix color setting of tplink lights (#14108) 2018-04-30 13:36:53 -04:00
mvn23
6e0a3abf66 Fix TypeError on round(self.humidity) (fixes #13116) (#14174)
* Fix TypeError on round(self.humidity)

Some weather platforms postpone the first data fetch for a while on init. As a result round(self.humidity is called before it is assigned a value, producing an error. This is a fix for that.

* Rewrite to avoid false negative evaluation

As per the suggestion from @OttoWinter, rewrite to avoid matching e.g. 0.0 as false.
2018-04-30 13:27:45 -04:00
Mahesh Subramaniya
eceece866d Updating darksky default update interval to 5 mins (#14195)
With Darksky allowing only 1000 API requests per day, 2 minutes retry seems to be bit closer to running over the limit and actually it did for 5 days in my account. Hence proposing a change to 5 minutes to keep the API happy and also it doesn't hurt to check the weather for every 5 mins than 2 mins someone lives in Jupiter :-P
2018-04-30 11:48:51 -04:00
Paulus Schoutsen
853a16938b Fix poorly formatted automations (#14196) 2018-04-30 09:56:42 -04:00
Paulus Schoutsen
5dcad89a0d Do not sync entities with an empty name (#14181) 2018-04-30 09:18:18 -04:00
cdce8p
46c260fd85 Added CONF_IP_ADDRESS to HomeKit (#14163) 2018-04-30 08:58:17 -04:00
Otto Winter
76c9c0179b Improve chromecast disconnection logic (#14190)
* Attempt Cast Fix

* Cleanup
2018-04-30 08:46:44 -04:00
Fabian Affolter
d7eced95fa Upgrade numpy to 1.14.3 (#14187) 2018-04-30 09:28:00 +02:00
Russell Cloran
02a12a0bb4 zha: Support remotes/buttons (#12528) 2018-04-29 23:31:27 -07:00
Anders Melchiorsen
30d987f59f Revert Hue color state to be xy-based (#14154) 2018-04-30 00:49:19 +02:00
Jens Østergaard Nielsen
aa8bd37143 Added update_interval to maxcube (#14143) 2018-04-29 20:57:57 +02:00
Paulus Schoutsen
4c0024fd97 Another coverage fix 2018-04-29 14:15:39 -04:00
Paulus Schoutsen
74320306a1 Add mitemp_bt to coverage 2018-04-29 14:08:33 -04:00
Hate-Usernames
113bdc493a Allow transitioning to colour temp for tradfri (#14157) 2018-04-29 16:54:44 +01:00
escoand
8e7f500f28 Add precipitation to OpenWeatherMap forecast (#13971)
* add initial precipitation support

* move attr to component

* remove blank line

* add forecast attributes to platform and update demo

* add tests

* break long lines

* calc lower temp correctly

* move all new attributes to component

* convert temp low only when existing
2018-04-29 17:50:49 +02:00
Fabian Affolter
d352dee9b7 Upgrade netdisco to 1.4.0 (#14152) 2018-04-29 16:21:46 +02:00
Kane610
3fd4987baf deCONZ allow unloading of config entry (#14115)
* Working but incomplete

* Remove events on unload

* Add unload test

* Fix failing sensor test

* Improve unload test

* Move DeconzEvent to init

* Fix visual under-indentation
2018-04-29 10:16:20 -04:00
Matthew Garrett
ef48a7ca2c Fix Python 3.6 compatibility for HomeKit controller (#14160)
Python 3.6's http client passes an additional argument to _send_output,
so add that to the function definition.
2018-04-29 09:46:36 +02:00
Paulus Schoutsen
fd038b6de9 Disable eliqonline requirement (#14156)
* Disable eliqonline requirement

* Disable pylint import error
2018-04-28 20:15:00 -04:00
Otto Winter
a4bf421044 Convert more files to async/await syntax (#14142)
* Move more files to async/await syntax

* Attempt Work around pylint bug

Using lazytox :P
2018-04-28 19:26:20 -04:00
Otto Winter
a0b14c2913 Light mqtt_json: Add HS color support (#14029)
* Light mqtt_json HS color support

* Lint

* Catch float ValueError
2018-04-29 00:33:10 +02:00
engrbm87
44ddc6ba62 deluge-components-update (#14016) 2018-04-29 00:16:22 +02:00
Gabe
07f94eaa92 Fixed datetime values (#14153) 2018-04-29 00:12:40 +02:00
Fabian Affolter
4205dc0f7c Upgrade psutil to 5.4.5 (#14135) 2018-04-28 23:17:38 +02:00
Matt Schmitt
2091f86e25 Clean up HomeKit accessory information characteristics (#14114)
* Update accessory information characteristics
* Add firmware revision characteristic
2018-04-28 23:17:30 +02:00
Fabian Affolter
84f163252a Upgrade youtube_dl to 2018.04.25 (#14136) 2018-04-28 23:17:10 +02:00
Fabian Affolter
9a9161477f Upgrade python-telegram-bot to 10.0.2 (#14144) 2018-04-28 23:16:51 +02:00
Fabian Affolter
449085313b Upgrade tapsaff to 0.2.0 (#14137) 2018-04-28 23:16:34 +02:00
Fabian Affolter
95f2ad2299 Upgrade sqlalchemy to 1.2.7 (#14138) 2018-04-28 23:16:01 +02:00
Fabian Affolter
7bdd4dd960 Upgrade pylast to 2.2.0 (#14139) 2018-04-28 23:15:32 +02:00
Anders Melchiorsen
e6d4501ee3 Fix color setting of tplink lights (#14108) 2018-04-28 17:12:11 -04:00
Paulus Schoutsen
93fe61bf13 System log: make firing event optional (#14102)
* Syste log: make firing event optional

* Add test

* Lint

* Doc string
2018-04-28 17:09:38 -04:00
Charles Garwood
b352b761f3 Bump pyvizio to 0.0.3 (#14147)
* Bumping pyvizio version

* Bump pyvizio version
2018-04-28 21:05:27 +02:00
Marcus
8d87b9fed5 Logitech Pop support for emulated_hue component (#12833)
* Update hue_api.py

add dummy group handler for logitech-pop

* Update __init__.py

add HueGroupView for logitech pop

* Update __init__.py

removed whitespace on blankline

* fix line limit and space

* fix indents

* fix more docstring and formatting issues.

* fix more whitespace issues

* Fix pylint issue
2018-04-28 20:39:21 +02:00
Fabian Affolter
ea5c336ab4 Upgrade restrictedpython to 4.0b3 (#14140) 2018-04-28 19:21:37 +02:00
Maciej Bieniek
c78e8eb578 Add support for light sensors with 'lx' unit to HomeKit (#14131)
* add support for light sensors with lx unit

* add test for light sensor with 'lx' unit
2018-04-28 17:14:34 +02:00
Aaron Bach
8bc497ba1d Move RainMachine to component/hub model (#14085)
* Moves RainMachine to component/hub model

* Updated requirements

* Updated coverage

* Hound violations

* Collaborator-requested changes

* Small formatting updates

* Removed references to remote API

* Collaborator-requested changes

* Collaborator-requested changes

* Fixed attribution
2018-04-28 15:46:58 +02:00
Fabian Affolter
1d41321f8f Upgrade colorlog to 3.1.4 (#14132) 2018-04-28 14:03:09 +02:00
ratcash
00706ad90c Support Xiaomi Mijia Bluetooth Wireless Temperature and Humidity Sensor (#13955) 2018-04-28 13:35:51 +02:00
Colin O'Dell
2749ca4ef4 Update QNAP lib to 0.2.6; handle null temps gracefully (#14117)
There's one particular QNAP model which sometimes return empty/null temperatures
for certain disks. This commit ensures that this model can be integrated with HASS
without causing KeyErrors or other exceptions - if this edge case is hit, the
sensor will simply show `0` instead.
2018-04-28 12:39:45 +02:00
Sebastian Muszynski
58ae8d91f9 Fix the optional friendly name of the Yeelight (Closes: #14088) (#14110) 2018-04-28 12:35:19 +02:00
Paulus Schoutsen
9d34e8c266 Merge pull request #14124 from home-assistant/rc
0.68
2018-04-27 21:44:39 -04:00
Matthew Garrett
7da1d75707 Change Eufy brightness handling (#14111)
Eufy device state isn't reported if the bulb is off, so avoid stamping on
the previous values if the bulb isn't going to give us useful information.
In addition, improve handling of bulb turn on if we aren't provided with a
brightness - this should avoid the bulb tending to end up with a brightness of
1 after power cycling.
2018-04-27 16:41:06 -04:00
Matthew Garrett
7e39a5c4d5 Change Eufy brightness handling (#14111)
Eufy device state isn't reported if the bulb is off, so avoid stamping on
the previous values if the bulb isn't going to give us useful information.
In addition, improve handling of bulb turn on if we aren't provided with a
brightness - this should avoid the bulb tending to end up with a brightness of
1 after power cycling.
2018-04-27 16:39:06 -04:00
Paulus Schoutsen
9fb2bf72f9 Version bump to 0.68.0 2018-04-27 15:35:20 -04:00
GotoCode
c42c668815 Updated list of AWS regions for Amazon Polly (#14097)
Fixes #14052
2018-04-27 15:34:57 -04:00
Daniel Høyer Iversen
9d0251cfeb Fix timezone issue when calculating min/max values in tibber #14009 (#14080)
* fix timezone issue in tibber #14009

* remove debug print
2018-04-27 15:34:57 -04:00
Daniel Høyer Iversen
403a546bdc Upgrade broadlink lib (#14074) 2018-04-27 15:34:57 -04:00
Anders Melchiorsen
0b350993b5 Improve precision of Hue color state (#14113) 2018-04-27 13:18:58 +02:00
Otto Winter
9d1f9fe204 Improve MQTT topic validation (#14099)
* Improve MQTT topic validation

* Fix test

* Improve length check
2018-04-27 13:15:45 +02:00
Kane610
4b06392442 Zone component config entry support (#14059)
* Initial commit

* Add error handling to config flow
Change unique identifyer to name
Clean up hound comments

* Ensure hass home zone is created with correct entity id
Fix failing tests

* Fix rest of tests

* Move zone tests to zone folder
Create config flow tests

* Add possibility to unload entry

* Use hass.data instead of globas

* Don't calculate configures zones every loop iteration

* No need to know about home zone during setup of entry

* Only use name as title

* Don't cache hass home zone

* Add new tests for setup and setup entry

* Break out functionality from init to zone.py

* Make hass home zone be created directly

* Make sure that config flow doesn't override hass home zone

* A newline was missing in const

* Configured zones shall not be imported
Removed config flow import functionality
Improved tests
2018-04-26 17:59:22 -04:00
Paulus Schoutsen
833508fbbb Version bump to 0.68.0b2 2018-04-26 16:39:42 -04:00
Paulus Schoutsen
1b71ce32e4 Bump frontend to 20180426 2018-04-26 16:39:27 -04:00
Paulus Schoutsen
f5de2b9e5b Bump frontend to 20180426 2018-04-26 16:39:14 -04:00
Robin
3e18078700 Adds update file_path service to local_file camera (#13976)
* WIP: Add update_file service to local_file camera

* Add event on update

* Update local_file.py

* Update services.yaml

* Fix indent

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update local_file.py

* Update test_local_file.py

* Update local_file.py

* Adds file_path to device_state_attributes

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update local_file.py

* Update test_local_file.py

* fixed test_update_file_path

* Update local_file.py

* Update test_local_file.py

* Update test_local_file.py

* Update services.yaml

* Update local_file.py

* Update local_file.py

* Update test_local_file.py

* Update local_file.py
2018-04-26 15:01:58 -04:00
GotoCode
ff7b51259e Updated list of AWS regions for Amazon Polly (#14097)
Fixes #14052
2018-04-26 19:35:28 +02:00
Daniel Perna
47e143d5a1 Update pyhomematic to 0.1.42 (#14095)
* Updated pyhomematic to 0.1.42

* Updated pyhomematic to 0.1.42
2018-04-26 19:30:28 +02:00
Daniel Høyer Iversen
d7f7735490 Fix timezone issue when calculating min/max values in tibber #14009 (#14080)
* fix timezone issue in tibber #14009

* remove debug print
2018-04-26 09:49:35 +02:00
Mattias Welponer
8c2dedab52 Re-implement HomematicIP cloud to async (#13468)
* Recode to async version of homematicip-rest-api

* Remove blank line

* Cleanup of access point status class

* Fix to loong line

* Fix import errors

* Bugfix missing wait the _retry_task for sleep command

* Update comment

* Updates after review

* Small updates of logging and property name

* Fix DOMAIN and revert back to lowercase snakecase strings

* Fix intention and tripple double quotes

* Fix travis build

* Remove unnecessary state attributes

* Fix optional name in configuration

* Further reduction of state attributes
2018-04-25 15:57:44 -04:00
Anders Melchiorsen
241a0793bb Add Sonos device attribute with grouping information (#13553) 2018-04-25 20:31:42 +02:00
c727
a94864c86f Modify weather components for "new" frontend card (#14076)
* Enable weather condition for all forecasts (OWM)

* Remove entity_picture from BR

* Remove summary texts from Dark Sky

* Update test_darksky.py
2018-04-25 12:37:57 +02:00
Mitko Masarliev
f23f9465d3 New sensor domain expiry (#14067)
* domain expiry

* domain expiry

* domain expiry

* scan interval

* change host to domain
2018-04-25 12:33:47 +02:00
Thijs de Jong
558b659f7c Add devices to Tahoma (#14075) 2018-04-25 07:09:45 +02:00
Kerwin Bryant
0a0d34d394 Support new Xiaomi Aqara device model names and LAN protocol 2.0 (#13540) 2018-04-25 07:05:00 +02:00
Paulus Schoutsen
c49751542f Version bump to 0.68.0b1 2018-04-24 23:19:33 -04:00
Mark Coombes
2e3a27e418 Update device classes for contact sensor HomeKit (#14051) 2018-04-24 23:19:16 -04:00
Matthew Garrett
7566bb5aed Handle HomeKit configuration failure more cleanly (#14041)
* Handle HomeKit configuration failure more cleanly

Add support for handling cases where HomeKit configuration fails, and give
the user more information about what to do.

* Don't consume the exception for a homekit.UnknownError

If we get an UnknownError then we should alert the user but also still
generate the backtrace so there's actually something for them to file in
a bug report.
2018-04-24 23:19:16 -04:00
Otto Winter
fc1f6ee0f0 Revert cast platform polling mode (#14027) 2018-04-24 23:19:16 -04:00
Matt Schmitt
cb839eff0f HomeKit Alarm Control Panel Code Exception Fix (#14025)
* Catch exception for KeyError
* Use get and added test
2018-04-24 23:19:15 -04:00
Paulus Schoutsen
2bc87bfcf0 Order the output of the automation editor (#14019)
* Order the output of the automation editor

* Lint
2018-04-24 23:19:15 -04:00
Johann Kellerman
44be80145b Qwikswitch binary sensors (#14008) 2018-04-24 23:19:15 -04:00
Paulus Schoutsen
8cb1e17ad8 Bump frontend to 20180425.0 2018-04-24 23:18:46 -04:00
Paulus Schoutsen
75fffb6a86 Bump frontend to 20180425.0 2018-04-24 23:18:28 -04:00
stephanerosi
4e97954bbe Remove excessive debugging in webostv module (#14056) 2018-04-24 22:45:57 -04:00
Daniel Høyer Iversen
18137733f9 Upgrade broadlink lib (#14074) 2018-04-24 22:45:16 -04:00
thelittlefireman
ca29224846 Bump locationsharinglib to 1.2.2 (#14070)
* Bump locationsharinglib to 1.2.2

* Bump locationsharinglib to 1.2.2
2018-04-24 18:46:17 +02:00
John Mihalic
31554e8368 Bump pyEight version to update API & reduce connection issues (#14058) 2018-04-23 22:43:59 +02:00
Paulus Schoutsen
5ed73fecd3 Order the output of the automation editor (#14019)
* Order the output of the automation editor

* Lint
2018-04-23 13:47:06 -04:00
Kane610
8a10fcd985 deCONZ use forward entry setup (#13990)
* Use forward entry setup with light platform

* Move sensor to forward entry setup

* Use forward entry setup with binary sensors

* Use forward entry setup with scene platform

* Remove import of unused functionality

* Move deconz setup in to setup entry
Create initial negative tests for setup entry

* Fix hound comment

* Improved tests

* Add test for scene platform

* Add test for binary sensor platform

* Add test for light platform

* Add test for light platform

* Add test for sensor platform

* Fix hound comment

* More asserts on sensor types
2018-04-23 12:00:16 -04:00
Mark Coombes
5fe4053021 Update device classes for contact sensor HomeKit (#14051) 2018-04-23 13:52:39 +02:00
Matthew Garrett
e4cb3af76d Handle HomeKit configuration failure more cleanly (#14041)
* Handle HomeKit configuration failure more cleanly

Add support for handling cases where HomeKit configuration fails, and give
the user more information about what to do.

* Don't consume the exception for a homekit.UnknownError

If we get an UnknownError then we should alert the user but also still
generate the backtrace so there's actually something for them to file in
a bug report.
2018-04-22 16:38:01 -04:00
Otto Winter
7f634c6ed0 Revert cast platform polling mode (#14027) 2018-04-22 16:32:15 -04:00
Paulus Schoutsen
5d3471269a Show a notification when a config entry is discovered (#14022)
* Show a notification when a config entry is discovered

* update comment

* Inline functions

* Lint
2018-04-22 21:00:24 +02:00
Stijn Tintel
1fbc650871 device_tracker.ubus: catch ConnectionError (#14045)
When an OpenWrt device monitored via ubus is offline, this causes the
log to be flooded with several exceptions. Avoid this by catching
requests.exceptions.ConnectionError in addition to
requests.exceptions.Timeout.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2018-04-22 12:55:45 +02:00
David Broadfoot
86374ad809 bump gogogate2 version (#14044)
* bump gogogate2 version

* Update - requirements_all
2018-04-22 12:54:48 +02:00
Ryan Bahm
c2bee496e2 Add Accuracy to Google Location Sharing (#14039)
* Update locationsharinglib to 1.2.1 and add accuracy.

* Change indents to match HA style
2018-04-22 08:42:18 +02:00
Matt Schmitt
51f55bddb7 HomeKit Alarm Control Panel Code Exception Fix (#14025)
* Catch exception for KeyError
* Use get and added test
2018-04-21 16:16:46 +02:00
Daniel Høyer Iversen
4c23a61853 upgrade rfxtrx lib, dimming support for Lighting3 (#14026) 2018-04-21 10:54:11 +02:00
Jon Maddox
f12ff6f297 Expose the condition code on condition sensors (#14011)
* expose the condition code on condition sensors

* 💄

* like thisss duh

* add test for condition_code

* It’s a string
2018-04-21 10:20:33 +02:00
Aaron Bach
cb490780c9 Pollen.com: Added attributes on top 3 allergens (#14018) 2018-04-21 10:16:52 +02:00
Johann Kellerman
6ccb83584e Qwikswitch binary sensors (#14008) 2018-04-21 08:34:42 +02:00
Paulus Schoutsen
2b53729708 Version bump to 0.68.0b0 2018-04-20 10:58:43 -04:00
Paulus Schoutsen
a566804f7f Merge branch 'dev' into rc 2018-04-20 10:58:25 -04:00
Paulus Schoutsen
2a5fac3b9d Add sensor device classes (#14010) 2018-04-20 15:38:27 +02:00
Rohan Kapoor
8459b241a2 Upgrade pylutron-caseta to 0.5.0 to reestablish connections (#14013)
* Upgrade pylutron-caseta to 0.5.0 to reestablish connections

* Upgrade pylutron-caseta to 0.5.0 in requirements_all.txt
2018-04-20 15:35:56 +02:00
Daniel Høyer Iversen
825f94f47f Tibber available (#13865)
* Tibber available

* Tibber available

* Tibber

* Tibber
2018-04-20 11:45:11 +02:00
Sebastian Muszynski
8ef2abfca7 Log an error instead of raising an exception (#14006) 2018-04-20 08:45:28 +02:00
ChristianKuehnel
2372419d42 Upgraded miflora library to version 0.4.0 (#14005) 2018-04-20 08:43:44 +02:00
Paulus Schoutsen
27f3081b74 Update frontend to 20180420.0 2018-04-19 22:16:48 -04:00
Paulus Schoutsen
13e72f48a8 Disable ebox requirement (#14003)
* Disable ebox requirement

* Lint
2018-04-19 14:06:49 -04:00
Pascal Hahn
9fcbe68fac Add Homematic HmIP-SWO-PR weather sensor support (#13904) 2018-04-19 12:48:21 +02:00
Sebastian Muszynski
0999129f48 Useless code removed (#13996) 2018-04-19 11:42:40 +02:00
Viorel Stirbu
3180c8b0fb Add support for Sensirion SHT31 temperature/humidity sensor (#12952) 2018-04-19 11:37:30 +02:00
koolsb
37cd63ea5a Add blackbird media player component (#13549) 2018-04-19 11:35:38 +02:00
koolsb
3dc70436f1 Add additional receiver for Onkyo zone 2 (#13551) 2018-04-19 11:31:50 +02:00
Sebastian Muszynski
674682e88f Support for multiple MAX!Cube LAN gateways added (#13517) 2018-04-19 09:11:38 +02:00
thelittlefireman
ba7fccba34 Bump locationsharinglib to 1.2.1 (#13980)
* Bump locationsharinglib to 1.2.1

*  Bump locationsharinglib to 1.2.1
2018-04-18 15:59:48 -04:00
Adam Mills
ccba858ae1 Fix for Lokalise backend misinterpretation of keys (#13986)
The Lokalise server has a bug that the internal portion of key
references was misinterpreted as a symfony key, and was getting auto
converted by the convert placeholders feature. Since we don't use this
we're turning it off to work around the bug.
2018-04-18 15:58:47 -04:00
Paulus Schoutsen
b0a3d084fb Version bump to 20180418.0 2018-04-18 15:58:14 -04:00
NovapaX
45eb611007 renaming icons (#13982)
* renaming icons

* remove mdi:robot-vacuum

* fix other vacuums
2018-04-18 15:46:44 -04:00
Michael Wei
0eb3e49880 Alexa thermostat fails to properly parse 'value' field for climate (#13958)
* Fix thermostat payload issue

* fix test payload

* style issue

* handle both string and value object
2018-04-18 14:19:05 -04:00
Kane610
c5cb28d41f deCONZ migrate setup fully to config entry (#13679)
* Initial working config entry with discovery

* No need for else

* Make sure that imported config doesnt exist as a config entry

* Improve checks to make sure there is only instance of deconz

* Fix tests and add new tests

* Follow upstream changes
Fix case when discovery started ongoing config entry and user completes setup  from other path it was possible to complete discovered config entry as well

* Add test to make sure link doesn't bypass any check for only allowing one config entry

* Dont use len to determine an empty sequence

* Cleanup

* Allways get bridgeid to use as unique identifier for bridge
2018-04-18 10:27:44 -04:00
Ben Randall
7d43ad6a37 Colorlog windows fix (#13929)
* Fix colorlog on windows

Modified the way logging is initialized to fix two things.
1. If the import of `colorlog` fails the logs will still be formatted
   using the expected HASS log format.
2. Ensure that `logging.basicConfig` is called AFTER `colorlog` is
   imported so that the default handler generated will be writing to the
   wrapped stream generated when `colorama` is initialized.  This allows
   colored logging to work on Windows.

Added support for a `--log-no-color` command line switch in the event
that someone just wants to disable colored log output entirely.

* Fix line lengths

* Switch default value
2018-04-18 10:18:44 -04:00
Nick Whyte
b589dbf26c Support basic covers with open/close/stop services HomeKit (#13819)
* Support basic covers with open/close/stop services
* Support optional stop
* Tests
2018-04-18 14:39:58 +02:00
Sebastian Muszynski
23b97b9105 Params of the send command can be a list now (#13905) 2018-04-18 14:38:44 +02:00
stephanerosi
f11d4319d2 Fix typo an coding style (#13970) 2018-04-18 12:43:55 +02:00
Mister Wil
4ba58d0760 Bump skybellpy version to 0.1.2 (#13974) 2018-04-18 10:10:32 +02:00
Paulus Schoutsen
2cb9e2dc7c Merge pull request #13975 from home-assistant/rc
0.67.1
2018-04-17 23:19:45 -04:00
Paulus Schoutsen
c076dbe7e4 Revert "Upgrade pyqwikswitch to 0.71 (#13920)"
This reverts commit 6fa60c464b.
2018-04-17 22:59:36 -04:00
Paulus Schoutsen
e7aea5c571 Version bump to 0.67.1 2018-04-17 22:37:40 -04:00
Aaron Bach
24ec8c545b Bumped pypollencom to 1.1.2 (#13959)
* Bumped pypollencom to 1.1.2

* Updated requirements_all.txt
2018-04-17 22:37:25 -04:00
Thibault Cohen
6c456ade6a Update pyfido to 2.1.1 (#13947) 2018-04-17 22:37:24 -04:00
Thibault Cohen
e9b997de3e Update pyhydroquebec to 2.2.2 (#13946) 2018-04-17 22:37:24 -04:00
Paulus Schoutsen
53506821d4 Upgrade somecomfort to 0.5.2 (#13940) 2018-04-17 22:37:23 -04:00
Johann Kellerman
6fa60c464b Upgrade pyqwikswitch to 0.71 (#13920) 2018-04-17 22:36:07 -04:00
Sebastian Muszynski
fadff1855f Import operation modes from air humidifier (#13908) 2018-04-17 22:34:40 -04:00
Daniel Høyer Iversen
652063537b Fix call to parent broadlink switch (#13906)
* Broadlink switch, fixes issue #13799

* slugify
2018-04-17 22:34:40 -04:00
Sebastian Muszynski
bcd8a69dfc Missing property decorator added (#13889) 2018-04-17 22:34:40 -04:00
Paulus Schoutsen
663aeb11dc Fix race condition for component loaded before listening (#13887)
* Fix race condition for component loaded before listening

* async/await syntax
2018-04-17 22:34:39 -04:00
Kyle Niewiada
727ab956cf Fix #13846 Double underscore in bluetooth address (#13884) 2018-04-17 22:34:39 -04:00
Paulus Schoutsen
26c76e3399 Prevent vesync doing I/O in event loop (#13862) 2018-04-17 22:34:39 -04:00
Kane610
0adb240fd6 Fix so it is possible to ignore discovered config entry handlers (#13741)
* Fix so it is possible to ignore discovered config entry handlers

* Improve efficiency
2018-04-17 22:34:38 -04:00
David Broadfoot
e836674a30 Fix Gogogate2 'available' attribute (#13728)
* Fixed bug -  unable to set base readaonly property

* PR fixes

* Added line
2018-04-17 22:34:38 -04:00
Aaron Bach
65b8f9764a Bumped pypollencom to 1.1.2 (#13959)
* Bumped pypollencom to 1.1.2

* Updated requirements_all.txt
2018-04-17 20:03:22 +02:00
Kane610
1a9ea11665 Bump deCONZ requirement to v36 (#13960) 2018-04-17 20:00:53 +02:00
Daniel Høyer Iversen
08f545d67b Fix call to parent broadlink switch (#13906)
* Broadlink switch, fixes issue #13799

* slugify
2018-04-17 17:40:52 +02:00
ChristianKuehnel
e472436b84 Add services for bmw_connected_drive (#13497)
* implemented services for bmw remote services

* added vin to attributes of tracker
* moved component to new package
* added service description

* fixed static analysis warnings

* implemented first set of code reviews

* removed locking related services

* fixed static analysis warnings

* removed excess blank lines

* refactoring of setup() to resolve warning
"Cell variable bimmer defined in loop (cell-var-from-loop)"

* added missing docstring

* added service to update all vehicles from the server

* implemented changes requested in code review

* added check if invalid vin is entered
2018-04-17 17:37:00 +02:00
Paulus Schoutsen
783e9a5f8c Update frontend to 20180417 2018-04-17 10:17:58 -04:00
Tod Schmidt
f4b1a8e42d Added web view for TTS to get url (#13882)
* Added web view for to get url

* Added web view for TTS to get url

* Added web view for TTS to get url

* Added web view for TTS to get url

* Fixed test

* added auth

* Update __init__.py
2018-04-17 15:24:54 +02:00
Dmitry Avramenko
3b44f91395 Added FB messenger broadcast api to notify.facebook component (#12459)
* Added ability to use FB messenger broadcast api. use 'BROADCAST' keyword for first target in the facebook notifiy component to enable.

* Added ability to use FB messenger broadcast api. use 'BROADCAST' keyword for first target in the facebook notifiy component to enable.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Added ability for broadcast messaging for facebook messenger notify platform.

* Update facebook.py

* Update facebook.py

* Update facebook.py

* Update facebook.py
2018-04-17 14:23:41 +02:00
Fabian Affolter
cff3bed1f0 Upgrade youtube_dl to 2018.04.16 (#13937) 2018-04-17 13:32:44 +02:00
Fabian Affolter
9fe43714c6 Upgrade aiohttp to 3.1.3 (#13938) 2018-04-17 13:32:16 +02:00
Robin
569f5c111f Adds SigFox sensor (#13731)
* Create sigfox.py

* Create test_sigfox.py

* Update .coveragerc

* Fix lints

* Fix logger message string

* More lints

* Address reviewer comments

* edit exception handling

* Update sigfox.py

* Update sigfox.py

* Update sigfox.py

* Update sigfox.py
2018-04-17 13:08:32 +02:00
Heiko Thiery
9487bd455a Add AVM fritzbox smarthome component (#10688)
* initial commit

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fix failed flake8 tests

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* add fritzhome files to .coveragerc

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fix wrong module import

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove too general exception

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* incorporate review comments

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove blank line

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fix wrong import

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fix issue with operations

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* incorporate review comments

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove unused attributes

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* adapt to supported_features

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* change checking of kwargs to canonical way

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove unused self._state

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* Don't overwrite the platform domain

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* Remove parenthesis from import without line break

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* Do not pass hass to the components on init

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* Remove check for available in current_operation

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* Remove redundant logging message

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* Add blank line between standard and hass imports

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* Use states from base climate component

Also add the new state STATE_MANUAL to the base.

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* add reconnect when access failed

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* add device specific attributes

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* group the imports from the same module

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* change domain data to fritz instance

This let us use the fritz instance to reconnect from platform without accessing
protected attributes.

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fix typo

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* rename platform from fritzhome to fritzbox

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* Add device_state_attributes

Add attributes to have compatiblity to fritzdect.

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* add support for multiple fritzboxes

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fix pylint issues

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fixed pyfritzhome version

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fix import

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* fix component name in requirements_all.txt

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* upgrade pyfritzhome to 0.3.7

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* rename platform/component also in .coveragerc

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* use DEFAULT_HOST when no host is in dict

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* add config schema for dict

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove check

The check since since the config scheme takes case.

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* add check for empty devices

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* use standard attribute from base class

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove STATE_MANUAL from operation list

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove set DEFAULT_HOST

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* don't pass hass to the SwitchDevice

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove unsed DEFAULT_HOST

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* refactored device attributes

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* add info output if no fritzbox is configured

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* small fixes according review comment

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove unneeded default value

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove non required code from try..except block

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* line break for line that is too long

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>

* remove too many empty lines

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
2018-04-17 12:40:36 +02:00
karlkar
f2d4dd25f0 Update of python-mpd2 (#13921) 2018-04-17 11:55:35 +02:00
stephanerosi
998d8c1771 Implement play media to set a channel based on (by priority): (#13934)
- exact channel number
 - exact channel name
 - similar channel name temp
2018-04-17 11:50:26 +02:00
Sebastian Muszynski
add0afe31a Xiaomi MiIO Device Tracker: Unused variable removed (#13948)
* Unused variable removed and pinning added to be in sync with all xiaomi_miio components

* requirements_all.txt updated
2018-04-17 11:45:19 +02:00
Paulus Schoutsen
534aa0e4b5 Add data entry flow helper (#13935)
* Extract data entry flows HTTP views into helper

* Remove use of domain

* Lint

* Fix tests

* Update doc
2018-04-17 11:44:32 +02:00
Paulus Schoutsen
6e9669c18d Upgrade somecomfort to 0.5.2 (#13940) 2018-04-17 05:24:20 +02:00
Diogo Gomes
8fdeebc50d Cleanup on exit (#13918)
* Cleanup on exit

* lint

* version bump

* pymediaroom version bump

* address @kellerza comment

* avoid None in the _name
2018-04-16 22:21:39 -04:00
Thibault Cohen
d0d61d1b5f Update pyfido to 2.1.1 (#13947) 2018-04-16 22:16:28 -04:00
Fabian Affolter
e8ad36feb6 Upgrade alpha_vantage to 2.0.0 (#13943) 2018-04-16 22:16:12 -04:00
Thibault Cohen
9da239178c Update pyhydroquebec to 2.2.2 (#13946) 2018-04-17 02:52:56 +02:00
Fabien Piuzzi
acdba7a27c Updated foobot_async package version (#13942)
Fix #13886
2018-04-16 21:35:24 +02:00
Khole
e0c5b44994 Hive R3 update (#13357)
* Rebase

* Update version number to 0.2.14

* Remove Blank Line

* Added period to docstring

* Update Tox Fix

* Removed Lines
2018-04-16 21:00:13 +02:00
Lincoln Kirchoff
595600dea5 Add support for new platform: climate.modbus (#12224)
* Added support for a new platform: climate.modbus

* Made changes based on code review.

* Made changes based on code review

* Made changes that were recommended in the pull request review.

* Fixed spacing line 144

* Added docstrings for the added helper functions.

* Fixed set_temperature() function to use a variable local to the function for the target temp.

* Fixed lint formatting error

* Modified logic when checking the target temperature, as well as fixing the setup_platform function
2018-04-16 20:31:25 +02:00
Paxy
ad212d8dd4 Broadlink Sensor - switch to connection-less mode (#13761)
* Broadlink Sensor - switch to connection-less mode

Solved the issue with broadlink sensor that occurs when short connection loss with RM2/3 is present on poor WiFi networks.

* Update broadlink.py

* Update broadlink.py

* Update broadlink.py

* Update broadlink.py

* Update broadlink.py

* Update broadlink.py

* Update broadlink.py
2018-04-16 12:06:41 +02:00
Marco
86709427b6 Fixed Capsman data not being used (#13917) 2018-04-16 09:54:57 +02:00
stephanerosi
36a663adeb Add extra attributes for device scanner, Nmap and Unifi (IP, SSID, etc.) (#13673)
* Start of development

* Add extra attributes from unifi scanner

* Store IP of the device in the state attributes with nmap

* Allow not defining get_extra_attributes method in derived classes
2018-04-16 08:20:58 +02:00
Johann Kellerman
517fb2e983 Upgrade pyqwikswitch to 0.71 (#13920) 2018-04-15 22:19:15 +02:00
Benedict Aas
9677bc081e Add more math functions to templates (#13915)
We make `sin`, `cos`, `tan`, and `sqrt` functions, and the `pi`, `tau`,
and `e` constants available in templates.
2018-04-15 18:51:45 +02:00
Josh Anderson
c69f37500a Restore typeerror check for units sans energy tracking (#13824) 2018-04-15 15:25:30 +02:00
escoand
cd8935cbd2 Fritzbox netmonitor name (#13903)
* Addd name to netmonitor

* import conf_name
2018-04-15 15:20:37 +02:00
Sebastian Muszynski
2f26b0084f Import operation modes from air humidifier (#13908) 2018-04-15 15:19:28 +02:00
Kyle Niewiada
2bff03836b Fix #13846 Double underscore in bluetooth address (#13884) 2018-04-15 13:59:10 +02:00
Matthew Garrett
390086bb7e Eufy colour bulb updates (#13895)
* Fix up Eufy handling of colour lights

The Eufy colour lights have separate colour and temperature modes, and give
much less light output when in colour mode. Brightness is also handled in
a slightly confusing way, which means that state must be maintained in
order to avoid switching the light between modes by accident. Add some
additional handling for that.

* Bump the lakeside version

This version has important bugfixes for colour bulbs.

* Hound fixes
2018-04-15 09:54:02 +02:00
Pascal Vizeli
c018071218 Revert "Update yweather.py" (#13900)
* Revert "Add unique_id for BMW ConnectedDrive (#13888)"

This reverts commit 9014e26845.

* Revert "Added snips service descriptions (#13883)"

This reverts commit 1c4da0c4a6.

* Revert "Fix race condition for component loaded before listening (#13887)"

This reverts commit bba997e484.

* Revert "Missing property decorator added (#13889)"

This reverts commit bf98b793c5.

* Revert "Update frontend to 20180414.0"

This reverts commit 1617fbea4c.

* Revert "Further untangle data entry flow (#13855)"

This reverts commit 4d44c0feff.

* Revert "add support for Kodi discovery (#13790)"

This reverts commit 5a5dad689b.

* Revert "Update yweather.py (#13851)"

This reverts commit c3388d63a1.
2018-04-15 09:50:44 +02:00
Gerard
9014e26845 Add unique_id for BMW ConnectedDrive (#13888)
* Add unique_id for BMW ConnectedDrive

* Changed some comments
2018-04-15 05:15:52 +02:00
Tod Schmidt
1c4da0c4a6 Added snips service descriptions (#13883)
* Added snips service descriptions.

* Added snips service descriptions.
2018-04-15 00:07:55 +02:00
Paulus Schoutsen
bba997e484 Fix race condition for component loaded before listening (#13887)
* Fix race condition for component loaded before listening

* async/await syntax
2018-04-14 17:58:45 -04:00
Sebastian Muszynski
bf98b793c5 Missing property decorator added (#13889) 2018-04-14 23:53:35 +02:00
Paulus Schoutsen
1617fbea4c Update frontend to 20180414.0 2018-04-14 14:41:21 -04:00
Paulus Schoutsen
4d44c0feff Further untangle data entry flow (#13855)
* Further untangle data entry flow

* Fix test

* Remove helper class
2018-04-14 14:38:24 -04:00
escoand
5a5dad689b add support for Kodi discovery (#13790)
* add support for Kodi discovery

* remove "too many blank lines"

* register service only once

* optimize "workflow"
2018-04-14 08:31:12 -04:00
TheCellMC
c3388d63a1 Update yweather.py (#13851)
* Update yweather.py

* Update yweather.py

* Update yweather.py

* Update yweather.py
2018-04-14 10:32:44 +02:00
Paulus Schoutsen
ee6acadae2 Prevent vesync doing I/O in event loop (#13862) 2018-04-14 10:31:03 +02:00
dersger
80a3220b88 Avoid unnecessary cast state updates (#13770)
* Avoid unnecessary cast state updates

* Add test

* Fixed bad syntax

* Fixed imports

* Fixed test
2018-04-13 22:22:02 -04:00
Mohamad Tarbin
99ded8a0a6 Adding USCIS component (#13764)
* Adding USCIS component

* Adding Line after the class DOC

* Update : Extract USCIS logic code to Component

* Update : Extract USCIS logic code to Component

* Adding CURRENT_STATUS

* Change Error handling, remove date from attributes

* Update the Version for USCIS

* Update uscis.py
2018-04-13 21:54:23 -04:00
geekofweek
c6c166645d bump python-ecobee-api version to 0.0.18 (#13854)
* bump python-ecobee-api version to 0.0.18

* Update requirements_all.txt
2018-04-13 21:36:46 -04:00
Paulus Schoutsen
0daf38d18c Version bump to 0.68.0.dev0 2018-04-13 18:02:51 -04:00
Paulus Schoutsen
5ec30ce1e6 Merge branch 'master' into dev 2018-04-13 18:02:15 -04:00
Paulus Schoutsen
fb91b05051 Merge pull request #13856 from home-assistant/rc
0.67.0
2018-04-13 17:59:39 -04:00
Paulus Schoutsen
c36c2be372 Version bump to 0.67.0 2018-04-13 16:52:50 -04:00
Paulus Schoutsen
598f093bf0 Add authentication to error log endpoint (#13836) 2018-04-13 16:52:22 -04:00
stephanerosi
b9306a5e52 Channel up/down for LiveTV and next/previous for other apps (#13829) 2018-04-13 16:52:21 -04:00
Matthew Garrett
ac2298189e Add support for controlling homekit lights and switches (#13346)
* Add support for controlling homekit lights and switches

This adds support for controlling lights and switches that expose a HomeKit
control interface, avoiding the requirement to implement protocol-specific
components.

* Comment out the homekit requirement

This needs to build native code, so leave it commented for now

* Review updates

* Make HomeKit auto-discovery optional

Add an "enable" argument to the discovery component and add a list of
optional devices types (currently just HomeKit) to discover

* Further review comments

* Update requirements_all.txt

* Fix houndci complaints

* Further review updates

* Final review fixup

* Lint fixups

* Fix discovery tests

* Further review updates
2018-04-13 19:25:35 +02:00
Paulus Schoutsen
60508f7215 Extract config flow to own module (#13840)
* Extract config flow to own module

* Lint

* fix lint

* fix typo

* ConfigFlowHandler -> FlowHandler

* Rename to data_entry_flow
2018-04-13 10:14:53 -04:00
Diogo Gomes
ddd2003629 initialize queue before filtering (#13842) 2018-04-13 14:25:03 +02:00
Paulus Schoutsen
20ababec3e Add authentication to error log endpoint (#13836) 2018-04-13 13:32:05 +02:00
Mark Coombes
d3b261a25d Add support for deCONZ daylight sensor (#13479)
* Add support for deCONZ daylight sensor

Bump pydeconz to 34

* Remove 'daylight' reason from async u
2018-04-13 08:58:57 +02:00
Fabian Affolter
3906250c9e Update example (fixes #13834) (#13839) 2018-04-13 08:50:58 +02:00
Diogo Gomes
22a1b99e57 UPnP async (#13666)
* moved from miniupnpc to pyupnp-async

* update requirements

* Tests added

* hound

* update requirements_test_all.txt

* update gen_requirements_all.py

* addresses @pvizeli requested changes

* address review comments
2018-04-13 00:22:52 +02:00
Mister Wil
62dc737ea3 Abode better events (#13809)
* Push abodepy version to 0.13.0

* Bump to 0.13.1. Now uses a cache to store the generated UUID.

* Reorganize to not be a dumb dumb.
2018-04-12 22:27:23 +02:00
Mark Coombes
993866a314 Support Garage Doors in HomeKit (#13796) 2018-04-12 18:08:48 +02:00
xTCx
51bdd06d1f Clicksend: Added support for multiple recipients (#13812)
* Clicksend: Added support for multiple recipients

* Removed whitespace
2018-04-12 16:13:31 +02:00
stephanerosi
d2804b0a27 Channel up/down for LiveTV and next/previous for other apps (#13829) 2018-04-12 15:44:56 +02:00
Yonsm
c863b9614c Support CO2/PM2.5/Light sensors in HomeKit (#13804)
* Support co2/light/air sensor in HomeKit
* Add tests
* Added tests
* changed device_class lux to light
2018-04-12 15:01:41 +02:00
Paulus Schoutsen
f47572d3c0 Allow platform unloading (#13784)
* Allow platform unloading

* Add tests

* Add last test
2018-04-12 14:28:54 +02:00
Paulus Schoutsen
9bd29589d5 Version bump to 0.67.0b1 2018-04-12 08:22:07 -04:00
Marco Orovecchia
f29904f1b5 Rename from aurora light to nanoleaf_aurora (#13831) 2018-04-12 08:21:52 -04:00
Anders Melchiorsen
234495ed05 Fix too green color conversion (#13828)
* Prepare test

* Fix too green color conversion

* Fix remaining tests
2018-04-12 08:21:52 -04:00
Adam Mills
09dbd94467 iglo hs color fix (#13808) 2018-04-12 08:21:51 -04:00
Paulus Schoutsen
bd58a0de7d Remove vendor lookup for mac addresses (#13788)
* Remove vendor lookup for mac addresses

* Fix tests
2018-04-12 08:21:51 -04:00
cdce8p
dd7e6edf61 HomeKit type_cover fix (#13832)
* Removed char_position_state
* Changed service call
2018-04-12 13:19:21 +02:00
Marco Orovecchia
b752ca3bef Rename from aurora light to nanoleaf_aurora (#13831) 2018-04-12 09:24:07 +02:00
Anders Melchiorsen
9c1bc18def Fix too green color conversion (#13828)
* Prepare test

* Fix too green color conversion

* Fix remaining tests
2018-04-11 20:58:57 -04:00
cdce8p
2a5751c09d Homekit refactor (#13707) 2018-04-11 22:24:14 +02:00
Matthew Garrett
8d48164f25 Add support for Eufy bulbs and switches (#13773)
* Add support for Eufy bulbs and switches

Add support for driving bulbs and switches from the Eufy range.

* Fix hound checks

* Satisfy pylint

* Handle review comments

* Review updates and test fixes

* PyLint is a bit too aggressive
2018-04-10 21:38:23 -04:00
Daniel Perna
b2695e498d Update pyhomematic to 0.1.41 (#13814)
* Update requirements_all.txt

* Update __init__.py
2018-04-10 23:33:56 +02:00
Daniel Høyer Iversen
16a1a4e0b1 Tibber lib update (#13811) 2018-04-10 22:12:55 +02:00
Wojtek
191e32f6cf Update yweather.py (#13802)
Map clear-night string to 31 value.
2018-04-10 21:11:45 +02:00
Toby Gray
978a79d369 device_tracker.ubus: Handle devices not running DHCP (#13579) 2018-04-10 20:38:36 +02:00
Adam Mills
cf88d8a1b9 iglo hs color fix (#13808) 2018-04-10 14:11:00 -04:00
Russell Cloran
2707d35a86 Update bellows to 0.5.2 (#13800) 2018-04-10 00:12:22 -07:00
Michael Kutý
7ea776dff4 Fix bad metrics format for short metrics. (#13778) 2018-04-10 08:20:47 +02:00
Johann Kellerman
bd93f10d3c script/lazytox: Ensure Flake8 passes for tests/ (#13794) 2018-04-09 21:24:50 -04:00
citruz
c8a464d8f9 Updated beacontools to 1.2.3 (#13792) 2018-04-09 21:24:18 -04:00
Paulus Schoutsen
5ac52b74e0 Remove vendor lookup for mac addresses (#13788)
* Remove vendor lookup for mac addresses

* Fix tests
2018-04-09 21:21:26 -04:00
Johann Kellerman
7595401dcb Qwikswitch Entity Register (#13791)
* Entity Register

* feedback
2018-04-10 01:24:06 +02:00
cdce8p
ae4e792651 Improved upgradeability HomeKit security_systems (#13783) 2018-04-09 22:57:10 +02:00
Sean Wilson
2b86059fd0 Add missing DISCHRG state (#13787)
* Add missing ups.status states.

* Add missing DISCHRG state.
2018-04-09 19:38:57 +02:00
Tod Schmidt
e593117ab6 Snips sounds (#13746)
* Added feedback sound configuration

* Added feedback sound configuration

* Cleaned up feedback off

* Cleaned up whitespace

* Moved feedback pus to helper funx

* Async

* Used async_mock_service for tests

* Lint
2018-04-09 11:46:27 -04:00
Phil Kates
c61611d2b4 Add Homekit locks support (#13625)
* homekit: Add locks support
* Improved upgradeability
2018-04-09 16:23:49 +02:00
Paulus Schoutsen
73de749411 Use config entry to setup platforms (#13752)
* Use config entry to setup platforms

* Rename to async_forward_entry

* Add tests

* Catch if platform not exists for entry
2018-04-09 10:09:08 -04:00
Yonsm
cb51553c2d Support binary_sensor and device_tracker in HomeKit (#13735)
* Support binary_sensor and device_tracker for HomeKit
* Add test for get_accessory and binary sensor
* Test service.display_name and char_detected.display_name
* Split test to improve speed
2018-04-09 15:32:28 +02:00
Erik Eriksson
8beb9c2b28 Only flag media position as updated when it really has (#13737) 2018-04-09 00:12:46 -04:00
Sebastian Muszynski
70649dfe22 Device type mapping introduced to avoid breaking change (#13765) 2018-04-08 22:00:47 +02:00
Johann Kellerman
b01dceaff2 Qwikswitch sensors (#13622) 2018-04-08 21:59:19 +02:00
Robin
ef16c53e46 Check valid file on get_size (#13756)
Addresses https://github.com/home-assistant/home-assistant/issues/13754
2018-04-08 11:32:49 +02:00
Paulus Schoutsen
40d7857f3b Prepare entity component for config entries (#13730)
* Prepare entity component for config entries

* Return in time
2018-04-07 23:04:50 -04:00
Otto Winter
81b1d08d35 Add MQTT Sensor unique_id (#13318)
* Add MQTT Sensor unique_id

* Add test

* Update comment
2018-04-07 22:32:09 -04:00
Fabian Affolter
99f4509c2b Upgrade netdisco to 1.3.1 (#13744) 2018-04-07 17:19:55 -04:00
Kane610
f915a1c809 Fix so it is possible to ignore discovered config entry handlers (#13741)
* Fix so it is possible to ignore discovered config entry handlers

* Improve efficiency
2018-04-07 17:18:49 -04:00
dangyuluo
6cd599b7df Throw an error when invalid device_mode is given (#13739)
* Throw an error when invalid device_mode is given

* Fix lint issue, typo and error msg

* Fix error msg
2018-04-07 21:47:56 +02:00
Fabian Affolter
435b49fb96 Reset permission (#13743) 2018-04-07 19:11:48 +02:00
Diogo Gomes
3084ac1625 Update CODEOWNERS (sensor.filter, sensor.upnp) (#13736) 2018-04-07 13:44:08 +02:00
shred86
2bf17cba8e Brightness conversion for Abode dimmers (#13711)
With AbodePy 0.12.3, dimmers will now work but a conversion of the brightness is required. Additionally, when a brightness value of 100 is sent to Abode, 99 is returned causing AbodePy to throw an error so this component will send 99 instead of 100.

Keeps the brightness value sent and returned from the device response consistent. However, during initialization and when a device refresh is received, Abode can return 100 thus we'll convert that case back to 99.
2018-04-07 11:15:35 +02:00
Fabian Affolter
ca3cc27e40 Upgrade sqlalchemy to 1.2.6 (#13733) 2018-04-07 10:41:35 +02:00
Fabian Affolter
fbb8a54c39 Upgrade aiohttp to 3.1.2 (#13732) 2018-04-07 10:40:34 +02:00
thrawnarn
b0fd2342db Bluesound bugfix status 595 and await (#13727)
* 595 fix

* Await fixes and last 595 fix

* Lint

* Made internal exception class

* Fix lint issue
2018-04-07 10:09:09 +02:00
David Broadfoot
58f3690ef6 Fix Gogogate2 'available' attribute (#13728)
* Fixed bug -  unable to set base readaonly property

* PR fixes

* Added line
2018-04-07 05:48:53 +02:00
Diogo Gomes
286476f0d6 Initialise filter_sensor with historical values (#13075)
* Initialise filter with historical values
Added get_last_state_changes()

* fix test

* Major changes to accommodate history + time_SMA

# Conflicts:
#	homeassistant/components/sensor/filter.py

* hail the hound!

* lint fixed

* less debug

* ups

* get state from the proper entity

* sensible default

* No defaults in get_last_state_changes

* list_reverseiterator instead of list

* prev_state to state

* Initialise filter with historical values
Added get_last_state_changes()

* fix test

* Major changes to accommodate history + time_SMA

# Conflicts:
#	homeassistant/components/sensor/filter.py

* hail the hound!

* lint fixed

* less debug

* ups

* get state from the proper entity

* sensible default

* No defaults in get_last_state_changes

* list_reverseiterator instead of list

* prev_state to state

* update

* added window_unit

* replace isinstance with window_unit
2018-04-06 21:59:55 -04:00
Henrik Nicolaisen
fdf93d1829 added support for smappee water sensors (#12831)
* added support for smappee water sensors

* fixed lint error and wrong location_id

* fixed lint error

* Use string formatting
2018-04-06 23:14:31 +02:00
cdce8p
262ea14e5a Add timeout / debounce (for brightness and others) (#13534)
* Add async timeout feature

* Decorator for setter methods to limit service calls to HA
* Changed to async
* Use async_call_later
* Use lastargs, async_add_job

* Use dict for lastargs

* Updated tests to stop patch
2018-04-06 23:11:53 +02:00
Juggels
c77d013f43 Allow use of date_string in service call (#13256)
* Allow use of date_string in service call

* Add stricter validation, fix descriptions
2018-04-06 22:23:40 +02:00
cgtobi
48fe2d18e8 Add option to ignore availability in google calendar events (#13714) 2018-04-06 21:48:50 +02:00
Fabian Affolter
3394916a68 Update docstrings (#13720) 2018-04-06 18:06:47 +02:00
cdce8p
85487612d5 Update Homekit to 1.1.9 (#13716)
* Version bump to HAP-python==1.1.9

* Updated types and tests
2018-04-06 10:20:59 -04:00
Vincent Van Den Berghe
29e659cf4c Fixed SI units for current consumption 2018-03-13 22:20:56 +01:00
2382 changed files with 95649 additions and 31543 deletions

View File

@@ -4,6 +4,8 @@ source = homeassistant
omit =
homeassistant/__main__.py
homeassistant/scripts/*.py
homeassistant/util/async.py
homeassistant/monkey_patch.py
homeassistant/helpers/typing.py
homeassistant/helpers/signal.py
@@ -26,10 +28,13 @@ omit =
homeassistant/components/apple_tv.py
homeassistant/components/*/apple_tv.py
homeassistant/components/aqualogic.py
homeassistant/components/*/aqualogic.py
homeassistant/components/arduino.py
homeassistant/components/*/arduino.py
homeassistant/components/bmw_connected_drive.py
homeassistant/components/bmw_connected_drive/*.py
homeassistant/components/*/bmw_connected_drive.py
homeassistant/components/android_ip_webcam.py
@@ -40,6 +45,7 @@ omit =
homeassistant/components/asterisk_mbox.py
homeassistant/components/*/asterisk_mbox.py
homeassistant/components/*/asterisk_cdr.py
homeassistant/components/august.py
homeassistant/components/*/august.py
@@ -50,7 +56,7 @@ omit =
homeassistant/components/bbb_gpio.py
homeassistant/components/*/bbb_gpio.py
homeassistant/components/blink.py
homeassistant/components/blink/*
homeassistant/components/*/blink.py
homeassistant/components/bloomsky.py
@@ -59,6 +65,11 @@ omit =
homeassistant/components/coinbase.py
homeassistant/components/sensor/coinbase.py
homeassistant/components/cast/*
homeassistant/components/*/cast.py
homeassistant/components/cloudflare.py
homeassistant/components/comfoconnect.py
homeassistant/components/*/comfoconnect.py
@@ -85,6 +96,9 @@ omit =
homeassistant/components/ecobee.py
homeassistant/components/*/ecobee.py
homeassistant/components/edp_redy.py
homeassistant/components/*/edp_redy.py
homeassistant/components/egardia.py
homeassistant/components/*/egardia.py
@@ -94,32 +108,64 @@ omit =
homeassistant/components/envisalink.py
homeassistant/components/*/envisalink.py
homeassistant/components/evohome.py
homeassistant/components/*/evohome.py
homeassistant/components/fritzbox.py
homeassistant/components/*/fritzbox.py
homeassistant/components/ecovacs.py
homeassistant/components/*/ecovacs.py
homeassistant/components/eufy.py
homeassistant/components/*/eufy.py
homeassistant/components/gc100.py
homeassistant/components/*/gc100.py
homeassistant/components/google.py
homeassistant/components/*/google.py
homeassistant/components/habitica/*
homeassistant/components/*/habitica.py
homeassistant/components/hangouts/__init__.py
homeassistant/components/hangouts/const.py
homeassistant/components/hangouts/hangouts_bot.py
homeassistant/components/hangouts/hangups_utils.py
homeassistant/components/hangouts/intents.py
homeassistant/components/*/hangouts.py
homeassistant/components/hdmi_cec.py
homeassistant/components/*/hdmi_cec.py
homeassistant/components/hive.py
homeassistant/components/*/hive.py
homeassistant/components/homekit_controller/__init__.py
homeassistant/components/*/homekit_controller.py
homeassistant/components/homematic/__init__.py
homeassistant/components/*/homematic.py
homeassistant/components/homematicip_cloud.py
homeassistant/components/*/homematicip_cloud.py
homeassistant/components/huawei_lte.py
homeassistant/components/*/huawei_lte.py
homeassistant/components/hydrawise.py
homeassistant/components/*/hydrawise.py
homeassistant/components/ihc/*
homeassistant/components/*/ihc.py
homeassistant/components/insteon/*
homeassistant/components/*/insteon.py
homeassistant/components/insteon_local.py
homeassistant/components/*/insteon_local.py
homeassistant/components/insteon_plm.py
homeassistant/components/*/insteon_plm.py
homeassistant/components/ios.py
homeassistant/components/*/ios.py
@@ -142,12 +188,18 @@ omit =
homeassistant/components/knx.py
homeassistant/components/*/knx.py
homeassistant/components/konnected.py
homeassistant/components/*/konnected.py
homeassistant/components/lametric.py
homeassistant/components/*/lametric.py
homeassistant/components/linode.py
homeassistant/components/*/linode.py
homeassistant/components/logi_circle.py
homeassistant/components/*/logi_circle.py
homeassistant/components/lutron.py
homeassistant/components/*/lutron.py
@@ -157,6 +209,9 @@ omit =
homeassistant/components/mailgun.py
homeassistant/components/*/mailgun.py
homeassistant/components/matrix.py
homeassistant/components/*/matrix.py
homeassistant/components/maxcube.py
homeassistant/components/*/maxcube.py
@@ -169,29 +224,35 @@ omit =
homeassistant/components/mychevy.py
homeassistant/components/*/mychevy.py
homeassistant/components/mysensors.py
homeassistant/components/mysensors/*
homeassistant/components/*/mysensors.py
homeassistant/components/neato.py
homeassistant/components/*/neato.py
homeassistant/components/nest.py
homeassistant/components/nest/__init__.py
homeassistant/components/*/nest.py
homeassistant/components/netatmo.py
homeassistant/components/*/netatmo.py
homeassistant/components/netgear_lte.py
homeassistant/components/*/netgear_lte.py
homeassistant/components/octoprint.py
homeassistant/components/*/octoprint.py
homeassistant/components/opencv.py
homeassistant/components/*/opencv.py
homeassistant/components/openuv/__init__.py
homeassistant/components/*/openuv.py
homeassistant/components/pilight.py
homeassistant/components/*/pilight.py
homeassistant/components/qwikswitch.py
homeassistant/components/*/qwikswitch.py
homeassistant/components/switch/qwikswitch.py
homeassistant/components/light/qwikswitch.py
homeassistant/components/rachio.py
homeassistant/components/*/rachio.py
@@ -199,6 +260,9 @@ omit =
homeassistant/components/raincloud.py
homeassistant/components/*/raincloud.py
homeassistant/components/rainmachine/*
homeassistant/components/*/rainmachine.py
homeassistant/components/raspihats.py
homeassistant/components/*/raspihats.py
@@ -211,18 +275,27 @@ omit =
homeassistant/components/rpi_pfio.py
homeassistant/components/*/rpi_pfio.py
homeassistant/components/sabnzbd.py
homeassistant/components/*/sabnzbd.py
homeassistant/components/satel_integra.py
homeassistant/components/*/satel_integra.py
homeassistant/components/scsgate.py
homeassistant/components/*/scsgate.py
homeassistant/components/sisyphus.py
homeassistant/components/*/sisyphus.py
homeassistant/components/skybell.py
homeassistant/components/*/skybell.py
homeassistant/components/smappee.py
homeassistant/components/*/smappee.py
homeassistant/components/sonos/__init__.py
homeassistant/components/*/sonos.py
homeassistant/components/tado.py
homeassistant/components/*/tado.py
@@ -243,6 +316,9 @@ omit =
homeassistant/components/*/thinkingcleaner.py
homeassistant/components/tibber/*
homeassistant/components/*/tibber.py
homeassistant/components/toon.py
homeassistant/components/*/toon.py
@@ -285,6 +361,9 @@ omit =
homeassistant/components/wink/*
homeassistant/components/*/wink.py
homeassistant/components/wirelesstag.py
homeassistant/components/*/wirelesstag.py
homeassistant/components/xiaomi_aqara.py
homeassistant/components/*/xiaomi_aqara.py
@@ -303,6 +382,12 @@ omit =
homeassistant/components/zoneminder.py
homeassistant/components/*/zoneminder.py
homeassistant/components/tuya.py
homeassistant/components/*/tuya.py
homeassistant/components/spider.py
homeassistant/components/*/spider.py
homeassistant/components/alarm_control_panel/alarmdotcom.py
homeassistant/components/alarm_control_panel/canary.py
homeassistant/components/alarm_control_panel/concord232.py
@@ -312,6 +397,7 @@ omit =
homeassistant/components/alarm_control_panel/nx584.py
homeassistant/components/alarm_control_panel/simplisafe.py
homeassistant/components/alarm_control_panel/totalconnect.py
homeassistant/components/alarm_control_panel/yale_smart_alarm.py
homeassistant/components/apiai.py
homeassistant/components/binary_sensor/arest.py
homeassistant/components/binary_sensor/concord232.py
@@ -322,11 +408,13 @@ omit =
homeassistant/components/binary_sensor/ping.py
homeassistant/components/binary_sensor/rest.py
homeassistant/components/binary_sensor/tapsaff.py
homeassistant/components/binary_sensor/uptimerobot.py
homeassistant/components/browser.py
homeassistant/components/calendar/caldav.py
homeassistant/components/calendar/todoist.py
homeassistant/components/camera/bloomsky.py
homeassistant/components/camera/canary.py
homeassistant/components/camera/familyhub.py
homeassistant/components/camera/ffmpeg.py
homeassistant/components/camera/foscam.py
homeassistant/components/camera/mjpeg.py
@@ -336,6 +424,7 @@ omit =
homeassistant/components/camera/rpi_camera.py
homeassistant/components/camera/synology.py
homeassistant/components/camera/xeoma.py
homeassistant/components/camera/xiaomi.py
homeassistant/components/camera/yi.py
homeassistant/components/climate/econet.py
homeassistant/components/climate/ephember.py
@@ -346,11 +435,15 @@ omit =
homeassistant/components/climate/honeywell.py
homeassistant/components/climate/knx.py
homeassistant/components/climate/oem.py
homeassistant/components/climate/opentherm_gw.py
homeassistant/components/climate/proliphix.py
homeassistant/components/climate/radiotherm.py
homeassistant/components/climate/sensibo.py
homeassistant/components/climate/touchline.py
homeassistant/components/climate/venstar.py
homeassistant/components/climate/zhong_hong.py
homeassistant/components/cover/aladdin_connect.py
homeassistant/components/cover/brunt.py
homeassistant/components/cover/garadget.py
homeassistant/components/cover/gogogate2.py
homeassistant/components/cover/homematic.py
@@ -358,6 +451,7 @@ omit =
homeassistant/components/cover/myq.py
homeassistant/components/cover/opengarage.py
homeassistant/components/cover/rpi_gpio.py
homeassistant/components/cover/ryobi_gdo.py
homeassistant/components/cover/scsgate.py
homeassistant/components/device_tracker/actiontec.py
homeassistant/components/device_tracker/aruba.py
@@ -369,6 +463,7 @@ omit =
homeassistant/components/device_tracker/bt_home_hub_5.py
homeassistant/components/device_tracker/cisco_ios.py
homeassistant/components/device_tracker/ddwrt.py
homeassistant/components/device_tracker/freebox.py
homeassistant/components/device_tracker/fritz.py
homeassistant/components/device_tracker/google_maps.py
homeassistant/components/device_tracker/gpslogger.py
@@ -383,6 +478,7 @@ omit =
homeassistant/components/device_tracker/netgear.py
homeassistant/components/device_tracker/nmap_tracker.py
homeassistant/components/device_tracker/ping.py
homeassistant/components/device_tracker/ritassist.py
homeassistant/components/device_tracker/sky_hub.py
homeassistant/components/device_tracker/snmp.py
homeassistant/components/device_tracker/swisscom.py
@@ -397,7 +493,6 @@ omit =
homeassistant/components/emoncms_history.py
homeassistant/components/emulated_hue/upnp.py
homeassistant/components/fan/mqtt.py
homeassistant/components/feedreader.py
homeassistant/components/folder_watcher.py
homeassistant/components/foursquare.py
homeassistant/components/goalfeed.py
@@ -407,13 +502,13 @@ omit =
homeassistant/components/image_processing/seven_segments.py
homeassistant/components/keyboard_remote.py
homeassistant/components/keyboard.py
homeassistant/components/light/aurora.py
homeassistant/components/light/avion.py
homeassistant/components/light/blinksticklight.py
homeassistant/components/light/blinkt.py
homeassistant/components/light/decora_wifi.py
homeassistant/components/light/decora.py
homeassistant/components/light/flux_led.py
homeassistant/components/light/futurenow.py
homeassistant/components/light/greenwave.py
homeassistant/components/light/hue.py
homeassistant/components/light/hyperion.py
@@ -421,7 +516,10 @@ omit =
homeassistant/components/light/lifx_legacy.py
homeassistant/components/light/lifx.py
homeassistant/components/light/limitlessled.py
homeassistant/components/light/lw12wifi.py
homeassistant/components/light/mystrom.py
homeassistant/components/light/nanoleaf_aurora.py
homeassistant/components/light/opple.py
homeassistant/components/light/osramlightify.py
homeassistant/components/light/piglow.py
homeassistant/components/light/rpi_gpio_pwm.py
@@ -434,6 +532,7 @@ omit =
homeassistant/components/light/yeelightsunflower.py
homeassistant/components/light/zengge.py
homeassistant/components/lirc.py
homeassistant/components/lock/kiwi.py
homeassistant/components/lock/lockitron.py
homeassistant/components/lock/nello.py
homeassistant/components/lock/nuki.py
@@ -444,19 +543,21 @@ omit =
homeassistant/components/media_player/aquostv.py
homeassistant/components/media_player/bluesound.py
homeassistant/components/media_player/braviatv.py
homeassistant/components/media_player/cast.py
homeassistant/components/media_player/channels.py
homeassistant/components/media_player/clementine.py
homeassistant/components/media_player/cmus.py
homeassistant/components/media_player/denon.py
homeassistant/components/media_player/denonavr.py
homeassistant/components/media_player/directv.py
homeassistant/components/media_player/dlna_dmr.py
homeassistant/components/media_player/dunehd.py
homeassistant/components/media_player/emby.py
homeassistant/components/media_player/epson.py
homeassistant/components/media_player/firetv.py
homeassistant/components/media_player/frontier_silicon.py
homeassistant/components/media_player/gpmdp.py
homeassistant/components/media_player/gstreamer.py
homeassistant/components/media_player/horizon.py
homeassistant/components/media_player/itunes.py
homeassistant/components/media_player/kodi.py
homeassistant/components/media_player/lg_netcast.py
@@ -472,13 +573,13 @@ omit =
homeassistant/components/media_player/pandora.py
homeassistant/components/media_player/philips_js.py
homeassistant/components/media_player/pioneer.py
homeassistant/components/media_player/pjlink.py
homeassistant/components/media_player/plex.py
homeassistant/components/media_player/roku.py
homeassistant/components/media_player/russound_rio.py
homeassistant/components/media_player/russound_rnet.py
homeassistant/components/media_player/snapcast.py
homeassistant/components/media_player/songpal.py
homeassistant/components/media_player/sonos.py
homeassistant/components/media_player/spotify.py
homeassistant/components/media_player/squeezebox.py
homeassistant/components/media_player/ue_smart_radio.py
@@ -495,9 +596,10 @@ omit =
homeassistant/components/notify/aws_sqs.py
homeassistant/components/notify/ciscospark.py
homeassistant/components/notify/clickatell.py
homeassistant/components/notify/clicksend_tts.py
homeassistant/components/notify/clicksend.py
homeassistant/components/notify/clicksend_tts.py
homeassistant/components/notify/discord.py
homeassistant/components/notify/flock.py
homeassistant/components/notify/free_mobile.py
homeassistant/components/notify/gntp.py
homeassistant/components/notify/group.py
@@ -507,11 +609,9 @@ omit =
homeassistant/components/notify/lannouncer.py
homeassistant/components/notify/llamalab_automate.py
homeassistant/components/notify/mastodon.py
homeassistant/components/notify/matrix.py
homeassistant/components/notify/message_bird.py
homeassistant/components/notify/mycroft.py
homeassistant/components/notify/nfandroidtv.py
homeassistant/components/notify/nma.py
homeassistant/components/notify/prowl.py
homeassistant/components/notify/pushbullet.py
homeassistant/components/notify/pushetta.py
@@ -530,7 +630,6 @@ omit =
homeassistant/components/notify/telstra.py
homeassistant/components/notify/twitter.py
homeassistant/components/notify/xmpp.py
homeassistant/components/notify/yessssms.py
homeassistant/components/nuimo_controller.py
homeassistant/components/prometheus.py
homeassistant/components/rainbird.py
@@ -565,18 +664,22 @@ omit =
homeassistant/components/sensor/discogs.py
homeassistant/components/sensor/dnsip.py
homeassistant/components/sensor/dovado.py
homeassistant/components/sensor/domain_expiry.py
homeassistant/components/sensor/dte_energy_bridge.py
homeassistant/components/sensor/dublin_bus_transport.py
homeassistant/components/sensor/duke_energy.py
homeassistant/components/sensor/dwd_weather_warnings.py
homeassistant/components/sensor/ebox.py
homeassistant/components/sensor/eddystone_temperature.py
homeassistant/components/sensor/eliqonline.py
homeassistant/components/sensor/emoncms.py
homeassistant/components/sensor/enphase_envoy.py
homeassistant/components/sensor/envirophat.py
homeassistant/components/sensor/etherscan.py
homeassistant/components/sensor/fastdotcom.py
homeassistant/components/sensor/fedex.py
homeassistant/components/sensor/filesize.py
homeassistant/components/sensor/fints.py
homeassistant/components/sensor/fitbit.py
homeassistant/components/sensor/fixer.py
homeassistant/components/sensor/folder.py
@@ -585,6 +688,7 @@ omit =
homeassistant/components/sensor/fritzbox_netmonitor.py
homeassistant/components/sensor/gearbest.py
homeassistant/components/sensor/geizhals.py
homeassistant/components/sensor/gitlab_ci.py
homeassistant/components/sensor/gitter.py
homeassistant/components/sensor/glances.py
homeassistant/components/sensor/google_travel_time.py
@@ -593,26 +697,35 @@ omit =
homeassistant/components/sensor/haveibeenpwned.py
homeassistant/components/sensor/hp_ilo.py
homeassistant/components/sensor/htu21d.py
homeassistant/components/sensor/upnp.py
homeassistant/components/sensor/imap_email_content.py
homeassistant/components/sensor/imap.py
homeassistant/components/sensor/influxdb.py
homeassistant/components/sensor/iperf3.py
homeassistant/components/sensor/irish_rail_transport.py
homeassistant/components/sensor/kwb.py
homeassistant/components/sensor/lacrosse.py
homeassistant/components/sensor/lastfm.py
homeassistant/components/sensor/linky.py
homeassistant/components/sensor/linux_battery.py
homeassistant/components/sensor/loopenergy.py
homeassistant/components/sensor/luftdaten.py
homeassistant/components/sensor/lyft.py
homeassistant/components/sensor/magicseaweed.py
homeassistant/components/sensor/metoffice.py
homeassistant/components/sensor/miflora.py
homeassistant/components/sensor/mitemp_bt.py
homeassistant/components/sensor/modem_callerid.py
homeassistant/components/sensor/mopar.py
homeassistant/components/sensor/mqtt_room.py
homeassistant/components/sensor/mvglive.py
homeassistant/components/sensor/nederlandse_spoorwegen.py
homeassistant/components/sensor/netatmo_public.py
homeassistant/components/sensor/netdata.py
homeassistant/components/sensor/netdata_public.py
homeassistant/components/sensor/neurio_energy.py
homeassistant/components/sensor/noaa_tides.py
homeassistant/components/sensor/nsw_fuel_station.py
homeassistant/components/sensor/nut.py
homeassistant/components/sensor/nzbget.py
homeassistant/components/sensor/ohmconnect.py
@@ -626,6 +739,7 @@ omit =
homeassistant/components/sensor/plex.py
homeassistant/components/sensor/pocketcasts.py
homeassistant/components/sensor/pollen.py
homeassistant/components/sensor/postnl.py
homeassistant/components/sensor/pushbullet.py
homeassistant/components/sensor/pvoutput.py
homeassistant/components/sensor/pyload.py
@@ -633,21 +747,24 @@ omit =
homeassistant/components/sensor/radarr.py
homeassistant/components/sensor/rainbird.py
homeassistant/components/sensor/ripple.py
homeassistant/components/sensor/sabnzbd.py
homeassistant/components/sensor/scrape.py
homeassistant/components/sensor/sense.py
homeassistant/components/sensor/sensehat.py
homeassistant/components/sensor/serial_pm.py
homeassistant/components/sensor/serial.py
homeassistant/components/sensor/sht31.py
homeassistant/components/sensor/shodan.py
homeassistant/components/sensor/sigfox.py
homeassistant/components/sensor/simulated.py
homeassistant/components/sensor/skybeacon.py
homeassistant/components/sensor/sma.py
homeassistant/components/sensor/snmp.py
homeassistant/components/sensor/sochain.py
homeassistant/components/sensor/socialblade.py
homeassistant/components/sensor/sonarr.py
homeassistant/components/sensor/speedtest.py
homeassistant/components/sensor/spotcrime.py
homeassistant/components/sensor/starlingbank.py
homeassistant/components/sensor/steam_online.py
homeassistant/components/sensor/supervisord.py
homeassistant/components/sensor/swiss_hydrological_data.py
@@ -659,7 +776,6 @@ omit =
homeassistant/components/sensor/tank_utility.py
homeassistant/components/sensor/ted5000.py
homeassistant/components/sensor/temper.py
homeassistant/components/sensor/tibber.py
homeassistant/components/sensor/time_date.py
homeassistant/components/sensor/torque.py
homeassistant/components/sensor/trafikverket_weatherstation.py
@@ -667,10 +783,11 @@ omit =
homeassistant/components/sensor/travisci.py
homeassistant/components/sensor/twitch.py
homeassistant/components/sensor/uber.py
homeassistant/components/sensor/upnp.py
homeassistant/components/sensor/ups.py
homeassistant/components/sensor/uscis.py
homeassistant/components/sensor/vasttrafik.py
homeassistant/components/sensor/viaggiatreno.py
homeassistant/components/sensor/volkszaehler.py
homeassistant/components/sensor/waqi.py
homeassistant/components/sensor/waze_travel_time.py
homeassistant/components/sensor/whois.py
@@ -698,10 +815,11 @@ omit =
homeassistant/components/switch/orvibo.py
homeassistant/components/switch/pulseaudio_loopback.py
homeassistant/components/switch/rainbird.py
homeassistant/components/switch/rainmachine.py
homeassistant/components/switch/rest.py
homeassistant/components/switch/rpi_rf.py
homeassistant/components/switch/snmp.py
homeassistant/components/switch/switchbot.py
homeassistant/components/switch/switchmate.py
homeassistant/components/switch/telnet.py
homeassistant/components/switch/tplink.py
homeassistant/components/switch/transmission.py
@@ -714,9 +832,11 @@ omit =
homeassistant/components/tts/picotts.py
homeassistant/components/vacuum/mqtt.py
homeassistant/components/vacuum/roomba.py
homeassistant/components/watson_iot.py
homeassistant/components/weather/bom.py
homeassistant/components/weather/buienradar.py
homeassistant/components/weather/darksky.py
homeassistant/components/weather/met.py
homeassistant/components/weather/metoffice.py
homeassistant/components/weather/openweathermap.py
homeassistant/components/weather/zamg.py

50
.github/ISSUE_TEMPLATE/Bug_report.md vendored Normal file
View File

@@ -0,0 +1,50 @@
---
name: Bug report
about: Create a report to help us improve
---
<!-- READ THIS FIRST:
- If you need additional help with this template please refer to https://www.home-assistant.io/help/reporting_issues/
- Make sure you are running the latest version of Home Assistant before reporting an issue: https://github.com/home-assistant/home-assistant/releases
- Do not report issues for components if you are using custom components: files in <config-dir>/custom_components
- This is for bugs only. Feature and enhancement requests should go in our community forum: https://community.home-assistant.io/c/feature-requests
- Provide as many details as possible. Paste logs, configuration sample and code into the backticks. Do not delete any text from this template!
-->
**Home Assistant release with the issue:**
<!--
- Frontend -> Developer tools -> Info
- Or use this command: hass --version
-->
**Last working Home Assistant release (if known):**
**Operating environment (Hass.io/Docker/Windows/etc.):**
<!--
Please provide details about your environment.
-->
**Component/platform:**
<!--
Please add the link to the documentation at https://www.home-assistant.io/components/ of the component/platform in question.
-->
**Description of problem:**
**Problem-relevant `configuration.yaml` entries and (fill out even if it seems unimportant):**
```yaml
```
**Traceback (if applicable):**
```
```
**Additional information:**

View File

@@ -3,7 +3,7 @@
**Related issue (if applicable):** fixes #<home-assistant issue number goes here>
**Pull request in [home-assistant.github.io](https://github.com/home-assistant/home-assistant.github.io) with documentation (if applicable):** home-assistant/home-assistant.github.io#<home-assistant.github.io PR number goes here>
**Pull request in [home-assistant.io](https://github.com/home-assistant/home-assistant.io) with documentation (if applicable):** home-assistant/home-assistant.io#<home-assistant.io PR number goes here>
## Example entry for `configuration.yaml` (if applicable):
```yaml
@@ -15,12 +15,12 @@
- [ ] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
If user exposed functionality or configuration variables are added/changed:
- [ ] Documentation added/updated in [home-assistant.github.io](https://github.com/home-assistant/home-assistant.github.io)
- [ ] Documentation added/updated in [home-assistant.io](https://github.com/home-assistant/home-assistant.io)
If the code communicates with devices, web services, or third-party tools:
- [ ] New dependencies have been added to the `REQUIREMENTS` variable ([example][ex-requir]).
- [ ] New dependencies are only imported inside functions that use them ([example][ex-import]).
- [ ] New dependencies have been added to `requirements_all.txt` by running `script/gen_requirements_all.py`.
- [ ] New or updated dependencies have been added to `requirements_all.txt` by running `script/gen_requirements_all.py`.
- [ ] New files were added to `.coveragerc`.
If the code does not interact with devices:

3
.gitignore vendored
View File

@@ -107,3 +107,6 @@ desktop.ini
# Secrets
.lokalise_token
# monkeytype
monkeytype.sqlite3

2
.isort.cfg Normal file
View File

@@ -0,0 +1,2 @@
[settings]
multi_line_output=4

View File

@@ -10,17 +10,24 @@ matrix:
env: TOXENV=lint
- python: "3.5.3"
env: TOXENV=pylint
# - python: "3.5"
# env: TOXENV=typing
- python: "3.5.3"
env: TOXENV=py35
env: TOXENV=typing
- python: "3.5.3"
env: TOXENV=cov
after_success: coveralls
- python: "3.6"
env: TOXENV=py36
# - python: "3.6-dev"
# env: TOXENV=py36
# allow_failures:
# - python: "3.5"
# env: TOXENV=typing
- python: "3.7"
env: TOXENV=py37
dist: xenial
- python: "3.8-dev"
env: TOXENV=py38
dist: xenial
if: branch = dev AND type = push
allow_failures:
- python: "3.8-dev"
env: TOXENV=py38
dist: xenial
cache:
directories:
@@ -31,7 +38,7 @@ script: travis_wait 30 tox --develop
services:
- docker
before_deploy:
- docker pull lokalise/lokalise-cli@sha256:79b3108211ed1fcc9f7b09a011bfc53c240fc2f3b7fa7f0c8390f593271b4cd7
- docker pull lokalise/lokalise-cli@sha256:2198814ebddfda56ee041a4b427521757dd57f75415ea9693696a64c550cef21
deploy:
skip_cleanup: true
provider: script
@@ -39,4 +46,3 @@ deploy:
on:
branch: dev
condition: $TOXENV = lint
after_success: coveralls

View File

@@ -41,6 +41,7 @@ homeassistant/components/hassio.py @home-assistant/hassio
# Individual components
homeassistant/components/alarm_control_panel/egardia.py @jeroenterheerdt
homeassistant/components/alarm_control_panel/manual_mqtt.py @colinodell
homeassistant/components/alarm_control_panel/simplisafe.py @bachya
homeassistant/components/binary_sensor/hikvision.py @mezz64
homeassistant/components/bmw_connected_drive.py @ChristianKuehnel
homeassistant/components/camera/yi.py @bachya
@@ -50,46 +51,71 @@ homeassistant/components/climate/sensibo.py @andrey-git
homeassistant/components/cover/group.py @cdce8p
homeassistant/components/cover/template.py @PhracturedBlue
homeassistant/components/device_tracker/automatic.py @armills
homeassistant/components/device_tracker/huawei_router.py @abmantis
homeassistant/components/device_tracker/tile.py @bachya
homeassistant/components/history_graph.py @andrey-git
homeassistant/components/light/lifx.py @amelchio
homeassistant/components/light/lifx_legacy.py @amelchio
homeassistant/components/light/tplink.py @rytilahti
homeassistant/components/light/yeelight.py @rytilahti
homeassistant/components/lock/nello.py @pschmitt
homeassistant/components/lock/nuki.py @pschmitt
homeassistant/components/media_player/emby.py @mezz64
homeassistant/components/media_player/kodi.py @armills
homeassistant/components/media_player/liveboxplaytv.py @pschmitt
homeassistant/components/media_player/mediaroom.py @dgomes
homeassistant/components/media_player/monoprice.py @etsinko
homeassistant/components/media_player/sonos.py @amelchio
homeassistant/components/media_player/xiaomi_tv.py @fattdev
homeassistant/components/media_player/yamaha_musiccast.py @jalmeroth
homeassistant/components/plant.py @ChristianKuehnel
homeassistant/components/scene/lifx_cloud.py @amelchio
homeassistant/components/sensor/airvisual.py @bachya
homeassistant/components/sensor/filter.py @dgomes
homeassistant/components/sensor/gearbest.py @HerrHofrat
homeassistant/components/sensor/irish_rail_transport.py @ttroy50
homeassistant/components/sensor/jewish_calendar.py @tsvi
homeassistant/components/sensor/miflora.py @danielhiversen @ChristianKuehnel
homeassistant/components/sensor/nsw_fuel_station.py @nickw444
homeassistant/components/sensor/pollen.py @bachya
homeassistant/components/sensor/qnap.py @colinodell
homeassistant/components/sensor/sma.py @kellerza
homeassistant/components/sensor/sql.py @dgomes
homeassistant/components/sensor/sytadin.py @gautric
homeassistant/components/sensor/tibber.py @danielhiversen
homeassistant/components/sensor/waqi.py @andrey-git
homeassistant/components/switch/rainmachine.py @bachya
homeassistant/components/switch/tplink.py @rytilahti
homeassistant/components/vacuum/roomba.py @pschmitt
homeassistant/components/xiaomi_aqara.py @danielhiversen @syssi
homeassistant/components/*/axis.py @kane610
homeassistant/components/blink/* @fronzbot
homeassistant/components/*/blink.py @fronzbot
homeassistant/components/*/bmw_connected_drive.py @ChristianKuehnel
homeassistant/components/*/broadlink.py @danielhiversen
homeassistant/components/*/deconz.py @kane610
homeassistant/components/ecovacs.py @OverloadUT
homeassistant/components/*/ecovacs.py @OverloadUT
homeassistant/components/edp_redy.py @abmantis
homeassistant/components/*/edp_redy.py @abmantis
homeassistant/components/eight_sleep.py @mezz64
homeassistant/components/*/eight_sleep.py @mezz64
homeassistant/components/hive.py @Rendili @KJonline
homeassistant/components/*/hive.py @Rendili @KJonline
homeassistant/components/homekit/* @cdce8p
homeassistant/components/huawei_lte.py @scop
homeassistant/components/*/huawei_lte.py @scop
homeassistant/components/knx.py @Julius2342
homeassistant/components/*/knx.py @Julius2342
homeassistant/components/konnected.py @heythisisnate
homeassistant/components/*/konnected.py @heythisisnate
homeassistant/components/matrix.py @tinloaf
homeassistant/components/*/matrix.py @tinloaf
homeassistant/components/openuv/* @bachya
homeassistant/components/*/openuv.py @bachya
homeassistant/components/qwikswitch.py @kellerza
homeassistant/components/*/qwikswitch.py @kellerza
homeassistant/components/rainmachine/* @bachya
homeassistant/components/*/rainmachine.py @bachya
homeassistant/components/*/rfxtrx.py @danielhiversen
homeassistant/components/tahoma.py @philklei
homeassistant/components/*/tahoma.py @philklei
@@ -97,10 +123,16 @@ homeassistant/components/tesla.py @zabuldon
homeassistant/components/*/tesla.py @zabuldon
homeassistant/components/tellduslive.py @molobrakos @fredrike
homeassistant/components/*/tellduslive.py @molobrakos @fredrike
homeassistant/components/tibber/* @danielhiversen
homeassistant/components/*/tibber.py @danielhiversen
homeassistant/components/*/tradfri.py @ggravlingen
homeassistant/components/upcloud.py @scop
homeassistant/components/*/upcloud.py @scop
homeassistant/components/velux.py @Julius2342
homeassistant/components/*/velux.py @Julius2342
homeassistant/components/*/xiaomi_aqara.py @danielhiversen @syssi
homeassistant/components/*/xiaomi_miio.py @rytilahti @syssi
homeassistant/components/zoneminder.py @rohankapoorcom
homeassistant/components/*/zoneminder.py @rohankapoorcom
homeassistant/scripts/check_config.py @kellerza

View File

@@ -1,6 +1,6 @@
# Contributing to Home Assistant
Everybody is invited and welcome to contribute to Home Assistant. There is a lot to do...if you are not a developer perhaps you would like to help with the documentation on [home-assistant.io](https://home-assistant.io/)? If you are a developer and have devices in your home which aren't working with Home Assistant yet, why not spent a couple of hours and help to integrate them?
Everybody is invited and welcome to contribute to Home Assistant. There is a lot to do...if you are not a developer perhaps you would like to help with the documentation on [home-assistant.io](https://home-assistant.io/)? If you are a developer and have devices in your home which aren't working with Home Assistant yet, why not spend a couple of hours and help to integrate them?
The process is straight-forward.
@@ -10,5 +10,5 @@ The process is straight-forward.
- Ensure tests work.
- Create a Pull Request against the [**dev**](https://github.com/home-assistant/home-assistant/tree/dev) branch of Home Assistant.
Still interested? Then you should take a peek at the [developer documentation](https://home-assistant.io/developers/) to get more details.
Still interested? Then you should take a peek at the [developer documentation](https://developers.home-assistant.io/) to get more details.

View File

@@ -10,8 +10,8 @@ LABEL maintainer="Paulus Schoutsen <Paulus@PaulusSchoutsen.nl>"
#ENV INSTALL_OPENALPR no
#ENV INSTALL_FFMPEG no
#ENV INSTALL_LIBCEC no
#ENV INSTALL_PHANTOMJS no
#ENV INSTALL_SSOCR no
#ENV INSTALL_IPERF3 no
VOLUME /config

View File

@@ -1,194 +1,201 @@
Apache License
==============
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
_Version 2.0, January 2004_
_&lt;<http://www.apache.org/licenses/>&gt;_
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
### Terms and Conditions for use, reproduction, and distribution
1. Definitions.
#### 1. Definitions
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
License” shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
“Licensor” shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
“Legal Entity” shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, “control” means **(i)** the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
outstanding shares, or **(iii)** beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
“You” (or “Your”) shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
“Source” form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
“Object” form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
Work shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
“Derivative Works” shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
Contribution” shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
“submitted” means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as “Not a Contribution.”
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
#### 2. Grant of Copyright License
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
#### 3. Grant of Patent License
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
#### 4. Redistribution
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
this License; and
* **(b)** You must cause any modified files to carry prominent notices stating that You
changed the files; and
* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
#### 5. Submission of Contributions
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
#### 6. Trademarks
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
#### 7. Disclaimer of Warranty
END OF TERMS AND CONDITIONS
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
APPENDIX: How to apply the Apache License to your work.
#### 8. Limitation of Liability
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
Copyright [yyyy] [name of copyright owner]
#### 9. Accepting Warranty or Additional Liability
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
http://www.apache.org/licenses/LICENSE-2.0
_END OF TERMS AND CONDITIONS_
### APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets `[]` replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same “printed page” as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,5 +1,5 @@
Home Assistant |Build Status| |Coverage Status| |Chat Status|
=============================================================
Home Assistant |Build Status| |Coverage Status| |Chat Status| |Reviewed by Hound|
=================================================================================
Home Assistant is a home automation platform running on Python 3. It is able to track and control all devices at home and offer a platform for automating control.
@@ -21,8 +21,8 @@ Featured integrations
|screenshot-components|
The system is built using a modular approach so support for other devices or actions can be implemented easily. See also the `section on architecture <https://home-assistant.io/developers/architecture/>`__ and the `section on creating your own
components <https://home-assistant.io/developers/creating_components/>`__.
The system is built using a modular approach so support for other devices or actions can be implemented easily. See also the `section on architecture <https://developers.home-assistant.io/docs/en/architecture_index.html>`__ and the `section on creating your own
components <https://developers.home-assistant.io/docs/en/creating_component_index.html>`__.
If you run into issues while using Home Assistant or during development
of a component, check the `Home Assistant help section <https://home-assistant.io/help/>`__ of our website for further help and information.
@@ -33,6 +33,8 @@ of a component, check the `Home Assistant help section <https://home-assistant.i
:target: https://coveralls.io/r/home-assistant/home-assistant?branch=master
.. |Chat Status| image:: https://img.shields.io/discord/330944238910963714.svg
:target: https://discord.gg/c5DvZ4e
.. |Reviewed by Hound| image:: https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg
:target: https://houndci.com
.. |screenshot-states| image:: https://raw.github.com/home-assistant/home-assistant/master/docs/screenshots.png
:target: https://home-assistant.io/demo/
.. |screenshot-components| image:: https://raw.github.com/home-assistant/home-assistant/dev/docs/screenshot-components.png

View File

@@ -60,14 +60,6 @@ loader module
:undoc-members:
:show-inheritance:
remote module
---------------------------
.. automodule:: homeassistant.remote
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------

View File

@@ -19,4 +19,4 @@ Indices and tables
* :ref:`modindex`
* :ref:`search`
.. _Home Assistant developers: https://home-assistant.io/developers/
.. _Home Assistant developers: https://developers.home-assistant.io/

View File

@@ -1,606 +0,0 @@
swagger: '2.0'
info:
title: Home Assistant
description: Home Assistant REST API
version: "1.0.1"
# the domain of the service
host: localhost:8123
# array of all schemes that your API supports
schemes:
- http
- https
securityDefinitions:
#api_key:
# type: apiKey
# description: API password
# name: api_password
# in: query
api_key:
type: apiKey
description: API password
name: x-ha-access
in: header
# will be prefixed to all paths
basePath: /api
consumes:
- application/json
produces:
- application/json
paths:
/:
get:
summary: API alive message
description: Returns message if API is up and running.
tags:
- Core
security:
- api_key: []
responses:
200:
description: API is up and running
schema:
$ref: '#/definitions/Message'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/config:
get:
summary: API alive message
description: Returns the current configuration as JSON.
tags:
- Core
security:
- api_key: []
responses:
200:
description: Current configuration
schema:
$ref: '#/definitions/ApiConfig'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/discovery_info:
get:
summary: Basic information about Home Assistant instance
tags:
- Core
responses:
200:
description: Basic information
schema:
$ref: '#/definitions/DiscoveryInfo'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/bootstrap:
get:
summary: Returns all data needed to bootstrap Home Assistant.
tags:
- Core
security:
- api_key: []
responses:
200:
description: Bootstrap information
schema:
$ref: '#/definitions/BootstrapInfo'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/events:
get:
summary: Array of event objects.
description: Returns an array of event objects. Each event object contain event name and listener count.
tags:
- Events
security:
- api_key: []
responses:
200:
description: Events
schema:
type: array
items:
$ref: '#/definitions/Event'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/services:
get:
summary: Array of service objects.
description: Returns an array of service objects. Each object contains the domain and which services it contains.
tags:
- Services
security:
- api_key: []
responses:
200:
description: Services
schema:
type: array
items:
$ref: '#/definitions/Service'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/history:
get:
summary: Array of state changes in the past.
description: Returns an array of state changes in the past. Each object contains further detail for the entities.
tags:
- State
security:
- api_key: []
responses:
200:
description: State changes
schema:
type: array
items:
$ref: '#/definitions/History'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/states:
get:
summary: Array of state objects.
description: |
Returns an array of state objects. Each state has the following attributes: entity_id, state, last_changed and attributes.
tags:
- State
security:
- api_key: []
responses:
200:
description: States
schema:
type: array
items:
$ref: '#/definitions/State'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/states/{entity_id}:
get:
summary: Specific state object.
description: |
Returns a state object for specified entity_id.
tags:
- State
security:
- api_key: []
parameters:
- name: entity_id
in: path
description: entity_id of the entity to query
required: true
type: string
responses:
200:
description: State
schema:
$ref: '#/definitions/State'
404:
description: Not found
schema:
$ref: '#/definitions/Message'
default:
description: Error
schema:
$ref: '#/definitions/Message'
post:
description: |
Updates or creates the current state of an entity.
tags:
- State
consumes:
- application/json
parameters:
- name: entity_id
in: path
description: entity_id to set the state of
required: true
type: string
- $ref: '#/parameters/State'
responses:
200:
description: State of existing entity was set
schema:
$ref: '#/definitions/State'
201:
description: State of new entity was set
schema:
$ref: '#/definitions/State'
headers:
location:
type: string
description: location of the new entity
default:
description: Error
schema:
$ref: '#/definitions/Message'
/error_log:
get:
summary: Error log
description: |
Retrieve all errors logged during the current session of Home Assistant as a plaintext response.
tags:
- Core
security:
- api_key: []
produces:
- text/plain
responses:
200:
description: Plain text error log
default:
description: Error
schema:
$ref: '#/definitions/Message'
/camera_proxy/camera.{entity_id}:
get:
summary: Camera image.
description: |
Returns the data (image) from the specified camera entity_id.
tags:
- Camera
security:
- api_key: []
produces:
- image/jpeg
parameters:
- name: entity_id
in: path
description: entity_id of the camera to query
required: true
type: string
responses:
200:
description: Camera image
schema:
type: file
default:
description: Error
schema:
$ref: '#/definitions/Message'
/events/{event_type}:
post:
description: |
Fires an event with event_type
tags:
- Events
security:
- api_key: []
consumes:
- application/json
parameters:
- name: event_type
in: path
description: event_type to fire event with
required: true
type: string
- $ref: '#/parameters/EventData'
responses:
200:
description: Response message
schema:
$ref: '#/definitions/Message'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/services/{domain}/{service}:
post:
description: |
Calls a service within a specific domain. Will return when the service has been executed or 10 seconds has past, whichever comes first.
tags:
- Services
security:
- api_key: []
consumes:
- application/json
parameters:
- name: domain
in: path
description: domain of the service
required: true
type: string
- name: service
in: path
description: service to call
required: true
type: string
- $ref: '#/parameters/ServiceData'
responses:
200:
description: List of states that have changed while the service was being executed. The result will include any changed states that changed while the service was being executed, even if their change was the result of something else happening in the system.
schema:
type: array
items:
$ref: '#/definitions/State'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/template:
post:
description: |
Render a Home Assistant template.
tags:
- Template
security:
- api_key: []
consumes:
- application/json
produces:
- text/plain
parameters:
- $ref: '#/parameters/Template'
responses:
200:
description: Returns the rendered template in plain text.
schema:
type: string
default:
description: Error
schema:
$ref: '#/definitions/Message'
/event_forwarding:
post:
description: |
Setup event forwarding to another Home Assistant instance.
tags:
- Core
security:
- api_key: []
consumes:
- application/json
parameters:
- $ref: '#/parameters/EventForwarding'
responses:
200:
description: It will return a message if event forwarding was setup successful.
schema:
$ref: '#/definitions/Message'
default:
description: Error
schema:
$ref: '#/definitions/Message'
delete:
description: |
Cancel event forwarding to another Home Assistant instance.
tags:
- Core
consumes:
- application/json
parameters:
- $ref: '#/parameters/EventForwarding'
responses:
200:
description: It will return a message if event forwarding was cancelled successful.
schema:
$ref: '#/definitions/Message'
default:
description: Error
schema:
$ref: '#/definitions/Message'
/stream:
get:
summary: Server-sent events
description: The server-sent events feature is a one-way channel from your Home Assistant server to a client which is acting as a consumer.
tags:
- Core
- Events
security:
- api_key: []
produces:
- text/event-stream
parameters:
- name: restrict
in: query
description: comma-separated list of event_types to filter
required: false
type: string
responses:
default:
description: Stream of events
schema:
type: object
x-events:
state_changed:
type: object
properties:
entity_id:
type: string
old_state:
$ref: '#/definitions/State'
new_state:
$ref: '#/definitions/State'
definitions:
ApiConfig:
type: object
properties:
components:
type: array
description: List of component types
items:
type: string
description: Component type
latitude:
type: number
format: float
description: Latitude of Home Assistant server
longitude:
type: number
format: float
description: Longitude of Home Assistant server
location_name:
type: string
unit_system:
type: object
properties:
length:
type: string
mass:
type: string
temperature:
type: string
volume:
type: string
time_zone:
type: string
version:
type: string
DiscoveryInfo:
type: object
properties:
base_url:
type: string
location_name:
type: string
requires_api_password:
type: boolean
version:
type: string
BootstrapInfo:
type: object
properties:
config:
$ref: '#/definitions/ApiConfig'
events:
type: array
items:
$ref: '#/definitions/Event'
services:
type: array
items:
$ref: '#/definitions/Service'
states:
type: array
items:
$ref: '#/definitions/State'
Event:
type: object
properties:
event:
type: string
listener_count:
type: integer
Service:
type: object
properties:
domain:
type: string
services:
type: object
additionalProperties:
$ref: '#/definitions/DomainService'
DomainService:
type: object
properties:
description:
type: string
fields:
type: object
description: Object with service fields that can be called
State:
type: object
properties:
attributes:
$ref: '#/definitions/StateAttributes'
state:
type: string
entity_id:
type: string
last_changed:
type: string
format: date-time
StateAttributes:
type: object
additionalProperties:
type: string
History:
allOf:
- $ref: '#/definitions/State'
- type: object
properties:
last_updated:
type: string
format: date-time
Message:
type: object
properties:
message:
type: string
parameters:
State:
name: body
in: body
description: State parameter
required: false
schema:
type: object
required:
- state
properties:
attributes:
$ref: '#/definitions/StateAttributes'
state:
type: string
EventData:
name: body
in: body
description: event_data
required: false
schema:
type: object
ServiceData:
name: body
in: body
description: service_data
required: false
schema:
type: object
Template:
name: body
in: body
description: Template to render
required: true
schema:
type: object
required:
- template
properties:
template:
description: Jinja2 template string
type: string
EventForwarding:
name: body
in: body
description: Event Forwarding parameter
required: true
schema:
type: object
required:
- host
- api_password
properties:
host:
type: string
api_password:
type: string
port:
type: integer

View File

@@ -7,8 +7,8 @@ import platform
import subprocess
import sys
import threading
from typing import List, Dict, Any # noqa pylint: disable=unused-import
from typing import Optional, List
from homeassistant import monkey_patch
from homeassistant.const import (
@@ -19,15 +19,34 @@ from homeassistant.const import (
)
def attempt_use_uvloop():
def set_loop() -> None:
"""Attempt to use uvloop."""
import asyncio
from asyncio.events import BaseDefaultEventLoopPolicy
try:
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
except ImportError:
pass
policy = None
if sys.platform == 'win32':
if hasattr(asyncio, 'WindowsProactorEventLoopPolicy'):
# pylint: disable=no-member
policy = asyncio.WindowsProactorEventLoopPolicy()
else:
class ProactorPolicy(BaseDefaultEventLoopPolicy):
"""Event loop policy to create proactor loops."""
_loop_factory = asyncio.ProactorEventLoop
policy = ProactorPolicy()
else:
try:
import uvloop
except ImportError:
pass
else:
policy = uvloop.EventLoopPolicy()
if policy is not None:
asyncio.set_event_loop_policy(policy)
def validate_python() -> None:
@@ -126,6 +145,10 @@ def get_arguments() -> argparse.Namespace:
default=None,
help='Log file to write to. If not set, CONFIG/home-assistant.log '
'is used')
parser.add_argument(
'--log-no-color',
action='store_true',
help="Disable color logs")
parser.add_argument(
'--runner',
action='store_true',
@@ -235,47 +258,36 @@ def cmdline() -> List[str]:
return [arg for arg in sys.argv if arg != '--daemon']
def setup_and_run_hass(config_dir: str,
args: argparse.Namespace) -> Optional[int]:
async def setup_and_run_hass(config_dir: str,
args: argparse.Namespace) -> int:
"""Set up HASS and run."""
from homeassistant import bootstrap
from homeassistant import bootstrap, core
# Run a simple daemon runner process on Windows to handle restarts
if os.name == 'nt' and '--runner' not in sys.argv:
nt_args = cmdline() + ['--runner']
while True:
try:
subprocess.check_call(nt_args)
sys.exit(0)
except subprocess.CalledProcessError as exc:
if exc.returncode != RESTART_EXIT_CODE:
sys.exit(exc.returncode)
hass = core.HomeAssistant()
if args.demo_mode:
config = {
'frontend': {},
'demo': {}
}
hass = bootstrap.from_config_dict(
config, config_dir=config_dir, verbose=args.verbose,
} # type: Dict[str, Any]
bootstrap.async_from_config_dict(
config, hass, config_dir=config_dir, verbose=args.verbose,
skip_pip=args.skip_pip, log_rotate_days=args.log_rotate_days,
log_file=args.log_file)
log_file=args.log_file, log_no_color=args.log_no_color)
else:
config_file = ensure_config_file(config_dir)
print('Config directory:', config_dir)
hass = bootstrap.from_config_file(
config_file, verbose=args.verbose, skip_pip=args.skip_pip,
log_rotate_days=args.log_rotate_days, log_file=args.log_file)
if hass is None:
return None
await bootstrap.async_from_config_file(
config_file, hass, verbose=args.verbose, skip_pip=args.skip_pip,
log_rotate_days=args.log_rotate_days, log_file=args.log_file,
log_no_color=args.log_no_color)
if args.open_ui:
# Imported here to avoid importing asyncio before monkey patch
from homeassistant.util.async_ import run_callback_threadsafe
def open_browser(event):
"""Open the webinterface in a browser."""
def open_browser(_: Any) -> None:
"""Open the web interface in a browser."""
if hass.config.api is not None:
import webbrowser
webbrowser.open(hass.config.api.base_url)
@@ -286,7 +298,7 @@ def setup_and_run_hass(config_dir: str,
EVENT_HOMEASSISTANT_START, open_browser
)
return hass.start()
return await hass.async_run()
def try_to_restart() -> None:
@@ -341,7 +353,20 @@ def main() -> int:
monkey_patch.disable_c_asyncio()
monkey_patch.patch_weakref_tasks()
attempt_use_uvloop()
set_loop()
# Run a simple daemon runner process on Windows to handle restarts
if os.name == 'nt' and '--runner' not in sys.argv:
nt_args = cmdline() + ['--runner']
while True:
try:
subprocess.check_call(nt_args)
sys.exit(0)
except KeyboardInterrupt:
sys.exit(0)
except subprocess.CalledProcessError as exc:
if exc.returncode != RESTART_EXIT_CODE:
sys.exit(exc.returncode)
args = get_arguments()
@@ -360,11 +385,12 @@ def main() -> int:
if args.pid_file:
write_pid(args.pid_file)
exit_code = setup_and_run_hass(config_dir, args)
from homeassistant.util.async_ import asyncio_run
exit_code = asyncio_run(setup_and_run_hass(config_dir, args))
if exit_code == RESTART_EXIT_CODE and not args.runner:
try_to_restart()
return exit_code
return exit_code # type: ignore # mypy cannot yet infer it
if __name__ == "__main__":

View File

@@ -0,0 +1,420 @@
"""Provide an authentication layer for Home Assistant."""
import asyncio
import logging
from collections import OrderedDict
from datetime import timedelta
from typing import Any, Dict, List, Optional, Tuple, cast
import jwt
from homeassistant import data_entry_flow
from homeassistant.auth.const import ACCESS_TOKEN_EXPIRATION
from homeassistant.core import callback, HomeAssistant
from homeassistant.util import dt as dt_util
from . import auth_store, models
from .mfa_modules import auth_mfa_module_from_config, MultiFactorAuthModule
from .providers import auth_provider_from_config, AuthProvider, LoginFlow
_LOGGER = logging.getLogger(__name__)
_MfaModuleDict = Dict[str, MultiFactorAuthModule]
_ProviderKey = Tuple[str, Optional[str]]
_ProviderDict = Dict[_ProviderKey, AuthProvider]
async def auth_manager_from_config(
hass: HomeAssistant,
provider_configs: List[Dict[str, Any]],
module_configs: List[Dict[str, Any]]) -> 'AuthManager':
"""Initialize an auth manager from config.
CORE_CONFIG_SCHEMA will make sure do duplicated auth providers or
mfa modules exist in configs.
"""
store = auth_store.AuthStore(hass)
if provider_configs:
providers = await asyncio.gather(
*[auth_provider_from_config(hass, store, config)
for config in provider_configs])
else:
providers = ()
# So returned auth providers are in same order as config
provider_hash = OrderedDict() # type: _ProviderDict
for provider in providers:
key = (provider.type, provider.id)
provider_hash[key] = provider
if module_configs:
modules = await asyncio.gather(
*[auth_mfa_module_from_config(hass, config)
for config in module_configs])
else:
modules = ()
# So returned auth modules are in same order as config
module_hash = OrderedDict() # type: _MfaModuleDict
for module in modules:
module_hash[module.id] = module
manager = AuthManager(hass, store, provider_hash, module_hash)
return manager
class AuthManager:
"""Manage the authentication for Home Assistant."""
def __init__(self, hass: HomeAssistant, store: auth_store.AuthStore,
providers: _ProviderDict, mfa_modules: _MfaModuleDict) \
-> None:
"""Initialize the auth manager."""
self.hass = hass
self._store = store
self._providers = providers
self._mfa_modules = mfa_modules
self.login_flow = data_entry_flow.FlowManager(
hass, self._async_create_login_flow,
self._async_finish_login_flow)
@property
def active(self) -> bool:
"""Return if any auth providers are registered."""
return bool(self._providers)
@property
def support_legacy(self) -> bool:
"""
Return if legacy_api_password auth providers are registered.
Should be removed when we removed legacy_api_password auth providers.
"""
for provider_type, _ in self._providers:
if provider_type == 'legacy_api_password':
return True
return False
@property
def auth_providers(self) -> List[AuthProvider]:
"""Return a list of available auth providers."""
return list(self._providers.values())
@property
def auth_mfa_modules(self) -> List[MultiFactorAuthModule]:
"""Return a list of available auth modules."""
return list(self._mfa_modules.values())
def get_auth_mfa_module(self, module_id: str) \
-> Optional[MultiFactorAuthModule]:
"""Return an multi-factor auth module, None if not found."""
return self._mfa_modules.get(module_id)
async def async_get_users(self) -> List[models.User]:
"""Retrieve all users."""
return await self._store.async_get_users()
async def async_get_user(self, user_id: str) -> Optional[models.User]:
"""Retrieve a user."""
return await self._store.async_get_user(user_id)
async def async_get_user_by_credentials(
self, credentials: models.Credentials) -> Optional[models.User]:
"""Get a user by credential, return None if not found."""
for user in await self.async_get_users():
for creds in user.credentials:
if creds.id == credentials.id:
return user
return None
async def async_create_system_user(self, name: str) -> models.User:
"""Create a system user."""
return await self._store.async_create_user(
name=name,
system_generated=True,
is_active=True,
)
async def async_create_user(self, name: str) -> models.User:
"""Create a user."""
kwargs = {
'name': name,
'is_active': True,
} # type: Dict[str, Any]
if await self._user_should_be_owner():
kwargs['is_owner'] = True
return await self._store.async_create_user(**kwargs)
async def async_get_or_create_user(self, credentials: models.Credentials) \
-> models.User:
"""Get or create a user."""
if not credentials.is_new:
user = await self.async_get_user_by_credentials(credentials)
if user is None:
raise ValueError('Unable to find the user.')
else:
return user
auth_provider = self._async_get_auth_provider(credentials)
if auth_provider is None:
raise RuntimeError('Credential with unknown provider encountered')
info = await auth_provider.async_user_meta_for_credentials(
credentials)
return await self._store.async_create_user(
credentials=credentials,
name=info.name,
is_active=info.is_active,
)
async def async_link_user(self, user: models.User,
credentials: models.Credentials) -> None:
"""Link credentials to an existing user."""
await self._store.async_link_user(user, credentials)
async def async_remove_user(self, user: models.User) -> None:
"""Remove a user."""
tasks = [
self.async_remove_credentials(credentials)
for credentials in user.credentials
]
if tasks:
await asyncio.wait(tasks)
await self._store.async_remove_user(user)
async def async_activate_user(self, user: models.User) -> None:
"""Activate a user."""
await self._store.async_activate_user(user)
async def async_deactivate_user(self, user: models.User) -> None:
"""Deactivate a user."""
if user.is_owner:
raise ValueError('Unable to deactive the owner')
await self._store.async_deactivate_user(user)
async def async_remove_credentials(
self, credentials: models.Credentials) -> None:
"""Remove credentials."""
provider = self._async_get_auth_provider(credentials)
if (provider is not None and
hasattr(provider, 'async_will_remove_credentials')):
# https://github.com/python/mypy/issues/1424
await provider.async_will_remove_credentials( # type: ignore
credentials)
await self._store.async_remove_credentials(credentials)
async def async_enable_user_mfa(self, user: models.User,
mfa_module_id: str, data: Any) -> None:
"""Enable a multi-factor auth module for user."""
if user.system_generated:
raise ValueError('System generated users cannot enable '
'multi-factor auth module.')
module = self.get_auth_mfa_module(mfa_module_id)
if module is None:
raise ValueError('Unable find multi-factor auth module: {}'
.format(mfa_module_id))
await module.async_setup_user(user.id, data)
async def async_disable_user_mfa(self, user: models.User,
mfa_module_id: str) -> None:
"""Disable a multi-factor auth module for user."""
if user.system_generated:
raise ValueError('System generated users cannot disable '
'multi-factor auth module.')
module = self.get_auth_mfa_module(mfa_module_id)
if module is None:
raise ValueError('Unable find multi-factor auth module: {}'
.format(mfa_module_id))
await module.async_depose_user(user.id)
async def async_get_enabled_mfa(self, user: models.User) -> Dict[str, str]:
"""List enabled mfa modules for user."""
modules = OrderedDict() # type: Dict[str, str]
for module_id, module in self._mfa_modules.items():
if await module.async_is_user_setup(user.id):
modules[module_id] = module.name
return modules
async def async_create_refresh_token(
self, user: models.User, client_id: Optional[str] = None,
client_name: Optional[str] = None,
client_icon: Optional[str] = None,
token_type: Optional[str] = None,
access_token_expiration: timedelta = ACCESS_TOKEN_EXPIRATION) \
-> models.RefreshToken:
"""Create a new refresh token for a user."""
if not user.is_active:
raise ValueError('User is not active')
if user.system_generated and client_id is not None:
raise ValueError(
'System generated users cannot have refresh tokens connected '
'to a client.')
if token_type is None:
if user.system_generated:
token_type = models.TOKEN_TYPE_SYSTEM
else:
token_type = models.TOKEN_TYPE_NORMAL
if user.system_generated != (token_type == models.TOKEN_TYPE_SYSTEM):
raise ValueError(
'System generated users can only have system type '
'refresh tokens')
if token_type == models.TOKEN_TYPE_NORMAL and client_id is None:
raise ValueError('Client is required to generate a refresh token.')
if (token_type == models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN and
client_name is None):
raise ValueError('Client_name is required for long-lived access '
'token')
if token_type == models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN:
for token in user.refresh_tokens.values():
if (token.client_name == client_name and token.token_type ==
models.TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN):
# Each client_name can only have one
# long_lived_access_token type of refresh token
raise ValueError('{} already exists'.format(client_name))
return await self._store.async_create_refresh_token(
user, client_id, client_name, client_icon,
token_type, access_token_expiration)
async def async_get_refresh_token(
self, token_id: str) -> Optional[models.RefreshToken]:
"""Get refresh token by id."""
return await self._store.async_get_refresh_token(token_id)
async def async_get_refresh_token_by_token(
self, token: str) -> Optional[models.RefreshToken]:
"""Get refresh token by token."""
return await self._store.async_get_refresh_token_by_token(token)
async def async_remove_refresh_token(self,
refresh_token: models.RefreshToken) \
-> None:
"""Delete a refresh token."""
await self._store.async_remove_refresh_token(refresh_token)
@callback
def async_create_access_token(self,
refresh_token: models.RefreshToken,
remote_ip: Optional[str] = None) -> str:
"""Create a new access token."""
self._store.async_log_refresh_token_usage(refresh_token, remote_ip)
# pylint: disable=no-self-use
now = dt_util.utcnow()
return jwt.encode({
'iss': refresh_token.id,
'iat': now,
'exp': now + refresh_token.access_token_expiration,
}, refresh_token.jwt_key, algorithm='HS256').decode()
async def async_validate_access_token(
self, token: str) -> Optional[models.RefreshToken]:
"""Return refresh token if an access token is valid."""
try:
unverif_claims = jwt.decode(token, verify=False)
except jwt.InvalidTokenError:
return None
refresh_token = await self.async_get_refresh_token(
cast(str, unverif_claims.get('iss')))
if refresh_token is None:
jwt_key = ''
issuer = ''
else:
jwt_key = refresh_token.jwt_key
issuer = refresh_token.id
try:
jwt.decode(
token,
jwt_key,
leeway=10,
issuer=issuer,
algorithms=['HS256']
)
except jwt.InvalidTokenError:
return None
if refresh_token is None or not refresh_token.user.is_active:
return None
return refresh_token
async def _async_create_login_flow(
self, handler: _ProviderKey, *, context: Optional[Dict],
data: Optional[Any]) -> data_entry_flow.FlowHandler:
"""Create a login flow."""
auth_provider = self._providers[handler]
return await auth_provider.async_login_flow(context)
async def _async_finish_login_flow(
self, flow: LoginFlow, result: Dict[str, Any]) \
-> Dict[str, Any]:
"""Return a user as result of login flow."""
if result['type'] != data_entry_flow.RESULT_TYPE_CREATE_ENTRY:
return result
# we got final result
if isinstance(result['data'], models.User):
result['result'] = result['data']
return result
auth_provider = self._providers[result['handler']]
credentials = await auth_provider.async_get_or_create_credentials(
result['data'])
if flow.context is not None and flow.context.get('credential_only'):
result['result'] = credentials
return result
# multi-factor module cannot enabled for new credential
# which has not linked to a user yet
if auth_provider.support_mfa and not credentials.is_new:
user = await self.async_get_user_by_credentials(credentials)
if user is not None:
modules = await self.async_get_enabled_mfa(user)
if modules:
flow.user = user
flow.available_mfa_modules = modules
return await flow.async_step_select_mfa_module()
result['result'] = await self.async_get_or_create_user(credentials)
return result
@callback
def _async_get_auth_provider(
self, credentials: models.Credentials) -> Optional[AuthProvider]:
"""Get auth provider from a set of credentials."""
auth_provider_key = (credentials.auth_provider_type,
credentials.auth_provider_id)
return self._providers.get(auth_provider_key)
async def _user_should_be_owner(self) -> bool:
"""Determine if user should be owner.
A user should be an owner if it is the first non-system user that is
being created.
"""
for user in await self._store.async_get_users():
if not user.system_generated:
return False
return True

View File

@@ -0,0 +1,357 @@
"""Storage for auth models."""
from collections import OrderedDict
from datetime import timedelta
import hmac
from logging import getLogger
from typing import Any, Dict, List, Optional # noqa: F401
from homeassistant.auth.const import ACCESS_TOKEN_EXPIRATION
from homeassistant.core import HomeAssistant, callback
from homeassistant.util import dt as dt_util
from . import models
STORAGE_VERSION = 1
STORAGE_KEY = 'auth'
class AuthStore:
"""Stores authentication info.
Any mutation to an object should happen inside the auth store.
The auth store is lazy. It won't load the data from disk until a method is
called that needs it.
"""
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the auth store."""
self.hass = hass
self._users = None # type: Optional[Dict[str, models.User]]
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY,
private=True)
async def async_get_users(self) -> List[models.User]:
"""Retrieve all users."""
if self._users is None:
await self._async_load()
assert self._users is not None
return list(self._users.values())
async def async_get_user(self, user_id: str) -> Optional[models.User]:
"""Retrieve a user by id."""
if self._users is None:
await self._async_load()
assert self._users is not None
return self._users.get(user_id)
async def async_create_user(
self, name: Optional[str], is_owner: Optional[bool] = None,
is_active: Optional[bool] = None,
system_generated: Optional[bool] = None,
credentials: Optional[models.Credentials] = None) -> models.User:
"""Create a new user."""
if self._users is None:
await self._async_load()
assert self._users is not None
kwargs = {
'name': name
} # type: Dict[str, Any]
if is_owner is not None:
kwargs['is_owner'] = is_owner
if is_active is not None:
kwargs['is_active'] = is_active
if system_generated is not None:
kwargs['system_generated'] = system_generated
new_user = models.User(**kwargs)
self._users[new_user.id] = new_user
if credentials is None:
self._async_schedule_save()
return new_user
# Saving is done inside the link.
await self.async_link_user(new_user, credentials)
return new_user
async def async_link_user(self, user: models.User,
credentials: models.Credentials) -> None:
"""Add credentials to an existing user."""
user.credentials.append(credentials)
self._async_schedule_save()
credentials.is_new = False
async def async_remove_user(self, user: models.User) -> None:
"""Remove a user."""
if self._users is None:
await self._async_load()
assert self._users is not None
self._users.pop(user.id)
self._async_schedule_save()
async def async_activate_user(self, user: models.User) -> None:
"""Activate a user."""
user.is_active = True
self._async_schedule_save()
async def async_deactivate_user(self, user: models.User) -> None:
"""Activate a user."""
user.is_active = False
self._async_schedule_save()
async def async_remove_credentials(
self, credentials: models.Credentials) -> None:
"""Remove credentials."""
if self._users is None:
await self._async_load()
assert self._users is not None
for user in self._users.values():
found = None
for index, cred in enumerate(user.credentials):
if cred is credentials:
found = index
break
if found is not None:
user.credentials.pop(found)
break
self._async_schedule_save()
async def async_create_refresh_token(
self, user: models.User, client_id: Optional[str] = None,
client_name: Optional[str] = None,
client_icon: Optional[str] = None,
token_type: str = models.TOKEN_TYPE_NORMAL,
access_token_expiration: timedelta = ACCESS_TOKEN_EXPIRATION) \
-> models.RefreshToken:
"""Create a new token for a user."""
kwargs = {
'user': user,
'client_id': client_id,
'token_type': token_type,
'access_token_expiration': access_token_expiration
} # type: Dict[str, Any]
if client_name:
kwargs['client_name'] = client_name
if client_icon:
kwargs['client_icon'] = client_icon
refresh_token = models.RefreshToken(**kwargs)
user.refresh_tokens[refresh_token.id] = refresh_token
self._async_schedule_save()
return refresh_token
async def async_remove_refresh_token(
self, refresh_token: models.RefreshToken) -> None:
"""Remove a refresh token."""
if self._users is None:
await self._async_load()
assert self._users is not None
for user in self._users.values():
if user.refresh_tokens.pop(refresh_token.id, None):
self._async_schedule_save()
break
async def async_get_refresh_token(
self, token_id: str) -> Optional[models.RefreshToken]:
"""Get refresh token by id."""
if self._users is None:
await self._async_load()
assert self._users is not None
for user in self._users.values():
refresh_token = user.refresh_tokens.get(token_id)
if refresh_token is not None:
return refresh_token
return None
async def async_get_refresh_token_by_token(
self, token: str) -> Optional[models.RefreshToken]:
"""Get refresh token by token."""
if self._users is None:
await self._async_load()
assert self._users is not None
found = None
for user in self._users.values():
for refresh_token in user.refresh_tokens.values():
if hmac.compare_digest(refresh_token.token, token):
found = refresh_token
return found
@callback
def async_log_refresh_token_usage(
self, refresh_token: models.RefreshToken,
remote_ip: Optional[str] = None) -> None:
"""Update refresh token last used information."""
refresh_token.last_used_at = dt_util.utcnow()
refresh_token.last_used_ip = remote_ip
self._async_schedule_save()
async def _async_load(self) -> None:
"""Load the users."""
data = await self._store.async_load()
# Make sure that we're not overriding data if 2 loads happened at the
# same time
if self._users is not None:
return
if data is None:
self._set_defaults()
return
users = OrderedDict() # type: Dict[str, models.User]
# When creating objects we mention each attribute explicetely. This
# prevents crashing if user rolls back HA version after a new property
# was added.
for user_dict in data['users']:
users[user_dict['id']] = models.User(
name=user_dict['name'],
id=user_dict['id'],
is_owner=user_dict['is_owner'],
is_active=user_dict['is_active'],
system_generated=user_dict['system_generated'],
)
for cred_dict in data['credentials']:
users[cred_dict['user_id']].credentials.append(models.Credentials(
id=cred_dict['id'],
is_new=False,
auth_provider_type=cred_dict['auth_provider_type'],
auth_provider_id=cred_dict['auth_provider_id'],
data=cred_dict['data'],
))
for rt_dict in data['refresh_tokens']:
# Filter out the old keys that don't have jwt_key (pre-0.76)
if 'jwt_key' not in rt_dict:
continue
created_at = dt_util.parse_datetime(rt_dict['created_at'])
if created_at is None:
getLogger(__name__).error(
'Ignoring refresh token %(id)s with invalid created_at '
'%(created_at)s for user_id %(user_id)s', rt_dict)
continue
token_type = rt_dict.get('token_type')
if token_type is None:
if rt_dict['client_id'] is None:
token_type = models.TOKEN_TYPE_SYSTEM
else:
token_type = models.TOKEN_TYPE_NORMAL
# old refresh_token don't have last_used_at (pre-0.78)
last_used_at_str = rt_dict.get('last_used_at')
if last_used_at_str:
last_used_at = dt_util.parse_datetime(last_used_at_str)
else:
last_used_at = None
token = models.RefreshToken(
id=rt_dict['id'],
user=users[rt_dict['user_id']],
client_id=rt_dict['client_id'],
# use dict.get to keep backward compatibility
client_name=rt_dict.get('client_name'),
client_icon=rt_dict.get('client_icon'),
token_type=token_type,
created_at=created_at,
access_token_expiration=timedelta(
seconds=rt_dict['access_token_expiration']),
token=rt_dict['token'],
jwt_key=rt_dict['jwt_key'],
last_used_at=last_used_at,
last_used_ip=rt_dict.get('last_used_ip'),
)
users[rt_dict['user_id']].refresh_tokens[token.id] = token
self._users = users
@callback
def _async_schedule_save(self) -> None:
"""Save users."""
if self._users is None:
return
self._store.async_delay_save(self._data_to_save, 1)
@callback
def _data_to_save(self) -> Dict:
"""Return the data to store."""
assert self._users is not None
users = [
{
'id': user.id,
'is_owner': user.is_owner,
'is_active': user.is_active,
'name': user.name,
'system_generated': user.system_generated,
}
for user in self._users.values()
]
credentials = [
{
'id': credential.id,
'user_id': user.id,
'auth_provider_type': credential.auth_provider_type,
'auth_provider_id': credential.auth_provider_id,
'data': credential.data,
}
for user in self._users.values()
for credential in user.credentials
]
refresh_tokens = [
{
'id': refresh_token.id,
'user_id': user.id,
'client_id': refresh_token.client_id,
'client_name': refresh_token.client_name,
'client_icon': refresh_token.client_icon,
'token_type': refresh_token.token_type,
'created_at': refresh_token.created_at.isoformat(),
'access_token_expiration':
refresh_token.access_token_expiration.total_seconds(),
'token': refresh_token.token,
'jwt_key': refresh_token.jwt_key,
'last_used_at':
refresh_token.last_used_at.isoformat()
if refresh_token.last_used_at else None,
'last_used_ip': refresh_token.last_used_ip,
}
for user in self._users.values()
for refresh_token in user.refresh_tokens.values()
]
return {
'users': users,
'credentials': credentials,
'refresh_tokens': refresh_tokens,
}
def _set_defaults(self) -> None:
"""Set default values for auth store."""
self._users = OrderedDict() # type: Dict[str, models.User]

View File

@@ -0,0 +1,5 @@
"""Constants for the auth module."""
from datetime import timedelta
ACCESS_TOKEN_EXPIRATION = timedelta(minutes=30)
MFA_SESSION_EXPIRATION = timedelta(minutes=5)

View File

@@ -0,0 +1,175 @@
"""Plugable auth modules for Home Assistant."""
import importlib
import logging
import types
from typing import Any, Dict, Optional
import voluptuous as vol
from voluptuous.humanize import humanize_error
from homeassistant import requirements, data_entry_flow
from homeassistant.const import CONF_ID, CONF_NAME, CONF_TYPE
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.util.decorator import Registry
MULTI_FACTOR_AUTH_MODULES = Registry()
MULTI_FACTOR_AUTH_MODULE_SCHEMA = vol.Schema({
vol.Required(CONF_TYPE): str,
vol.Optional(CONF_NAME): str,
# Specify ID if you have two mfa auth module for same type.
vol.Optional(CONF_ID): str,
}, extra=vol.ALLOW_EXTRA)
DATA_REQS = 'mfa_auth_module_reqs_processed'
_LOGGER = logging.getLogger(__name__)
class MultiFactorAuthModule:
"""Multi-factor Auth Module of validation function."""
DEFAULT_TITLE = 'Unnamed auth module'
MAX_RETRY_TIME = 3
def __init__(self, hass: HomeAssistant, config: Dict[str, Any]) -> None:
"""Initialize an auth module."""
self.hass = hass
self.config = config
@property
def id(self) -> str: # pylint: disable=invalid-name
"""Return id of the auth module.
Default is same as type
"""
return self.config.get(CONF_ID, self.type)
@property
def type(self) -> str:
"""Return type of the module."""
return self.config[CONF_TYPE] # type: ignore
@property
def name(self) -> str:
"""Return the name of the auth module."""
return self.config.get(CONF_NAME, self.DEFAULT_TITLE)
# Implement by extending class
@property
def input_schema(self) -> vol.Schema:
"""Return a voluptuous schema to define mfa auth module's input."""
raise NotImplementedError
async def async_setup_flow(self, user_id: str) -> 'SetupFlow':
"""Return a data entry flow handler for setup module.
Mfa module should extend SetupFlow
"""
raise NotImplementedError
async def async_setup_user(self, user_id: str, setup_data: Any) -> Any:
"""Set up user for mfa auth module."""
raise NotImplementedError
async def async_depose_user(self, user_id: str) -> None:
"""Remove user from mfa module."""
raise NotImplementedError
async def async_is_user_setup(self, user_id: str) -> bool:
"""Return whether user is setup."""
raise NotImplementedError
async def async_validate(
self, user_id: str, user_input: Dict[str, Any]) -> bool:
"""Return True if validation passed."""
raise NotImplementedError
class SetupFlow(data_entry_flow.FlowHandler):
"""Handler for the setup flow."""
def __init__(self, auth_module: MultiFactorAuthModule,
setup_schema: vol.Schema,
user_id: str) -> None:
"""Initialize the setup flow."""
self._auth_module = auth_module
self._setup_schema = setup_schema
self._user_id = user_id
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Handle the first step of setup flow.
Return self.async_show_form(step_id='init') if user_input == None.
Return self.async_create_entry(data={'result': result}) if finish.
"""
errors = {} # type: Dict[str, str]
if user_input:
result = await self._auth_module.async_setup_user(
self._user_id, user_input)
return self.async_create_entry(
title=self._auth_module.name,
data={'result': result}
)
return self.async_show_form(
step_id='init',
data_schema=self._setup_schema,
errors=errors
)
async def auth_mfa_module_from_config(
hass: HomeAssistant, config: Dict[str, Any]) \
-> MultiFactorAuthModule:
"""Initialize an auth module from a config."""
module_name = config[CONF_TYPE]
module = await _load_mfa_module(hass, module_name)
try:
config = module.CONFIG_SCHEMA(config) # type: ignore
except vol.Invalid as err:
_LOGGER.error('Invalid configuration for multi-factor module %s: %s',
module_name, humanize_error(config, err))
raise
return MULTI_FACTOR_AUTH_MODULES[module_name](hass, config) # type: ignore
async def _load_mfa_module(hass: HomeAssistant, module_name: str) \
-> types.ModuleType:
"""Load an mfa auth module."""
module_path = 'homeassistant.auth.mfa_modules.{}'.format(module_name)
try:
module = importlib.import_module(module_path)
except ImportError as err:
_LOGGER.error('Unable to load mfa module %s: %s', module_name, err)
raise HomeAssistantError('Unable to load mfa module {}: {}'.format(
module_name, err))
if hass.config.skip_pip or not hasattr(module, 'REQUIREMENTS'):
return module
processed = hass.data.get(DATA_REQS)
if processed and module_name in processed:
return module
processed = hass.data[DATA_REQS] = set()
# https://github.com/python/mypy/issues/1424
req_success = await requirements.async_process_requirements(
hass, module_path, module.REQUIREMENTS) # type: ignore
if not req_success:
raise HomeAssistantError(
'Unable to process requirements of mfa module {}'.format(
module_name))
processed.add(module_name)
return module

View File

@@ -0,0 +1,89 @@
"""Example auth module."""
import logging
from typing import Any, Dict
import voluptuous as vol
from homeassistant.core import HomeAssistant
from . import MultiFactorAuthModule, MULTI_FACTOR_AUTH_MODULES, \
MULTI_FACTOR_AUTH_MODULE_SCHEMA, SetupFlow
CONFIG_SCHEMA = MULTI_FACTOR_AUTH_MODULE_SCHEMA.extend({
vol.Required('data'): [vol.Schema({
vol.Required('user_id'): str,
vol.Required('pin'): str,
})]
}, extra=vol.PREVENT_EXTRA)
_LOGGER = logging.getLogger(__name__)
@MULTI_FACTOR_AUTH_MODULES.register('insecure_example')
class InsecureExampleModule(MultiFactorAuthModule):
"""Example auth module validate pin."""
DEFAULT_TITLE = 'Insecure Personal Identify Number'
def __init__(self, hass: HomeAssistant, config: Dict[str, Any]) -> None:
"""Initialize the user data store."""
super().__init__(hass, config)
self._data = config['data']
@property
def input_schema(self) -> vol.Schema:
"""Validate login flow input data."""
return vol.Schema({'pin': str})
@property
def setup_schema(self) -> vol.Schema:
"""Validate async_setup_user input data."""
return vol.Schema({'pin': str})
async def async_setup_flow(self, user_id: str) -> SetupFlow:
"""Return a data entry flow handler for setup module.
Mfa module should extend SetupFlow
"""
return SetupFlow(self, self.setup_schema, user_id)
async def async_setup_user(self, user_id: str, setup_data: Any) -> Any:
"""Set up user to use mfa module."""
# data shall has been validate in caller
pin = setup_data['pin']
for data in self._data:
if data['user_id'] == user_id:
# already setup, override
data['pin'] = pin
return
self._data.append({'user_id': user_id, 'pin': pin})
async def async_depose_user(self, user_id: str) -> None:
"""Remove user from mfa module."""
found = None
for data in self._data:
if data['user_id'] == user_id:
found = data
break
if found:
self._data.remove(found)
async def async_is_user_setup(self, user_id: str) -> bool:
"""Return whether user is setup."""
for data in self._data:
if data['user_id'] == user_id:
return True
return False
async def async_validate(
self, user_id: str, user_input: Dict[str, Any]) -> bool:
"""Return True if validation passed."""
for data in self._data:
if data['user_id'] == user_id:
# user_input has been validate in caller
if data['pin'] == user_input['pin']:
return True
return False

View File

@@ -0,0 +1,325 @@
"""HMAC-based One-time Password auth module.
Sending HOTP through notify service
"""
import logging
from collections import OrderedDict
from typing import Any, Dict, Optional, Tuple, List # noqa: F401
import attr
import voluptuous as vol
from homeassistant.const import CONF_EXCLUDE, CONF_INCLUDE
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from . import MultiFactorAuthModule, MULTI_FACTOR_AUTH_MODULES, \
MULTI_FACTOR_AUTH_MODULE_SCHEMA, SetupFlow
REQUIREMENTS = ['pyotp==2.2.6']
CONF_MESSAGE = 'message'
CONFIG_SCHEMA = MULTI_FACTOR_AUTH_MODULE_SCHEMA.extend({
vol.Optional(CONF_INCLUDE): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_EXCLUDE): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_MESSAGE,
default='{} is your Home Assistant login code'): str
}, extra=vol.PREVENT_EXTRA)
STORAGE_VERSION = 1
STORAGE_KEY = 'auth_module.notify'
STORAGE_USERS = 'users'
STORAGE_USER_ID = 'user_id'
INPUT_FIELD_CODE = 'code'
_LOGGER = logging.getLogger(__name__)
def _generate_secret() -> str:
"""Generate a secret."""
import pyotp
return str(pyotp.random_base32())
def _generate_random() -> int:
"""Generate a 8 digit number."""
import pyotp
return int(pyotp.random_base32(length=8, chars=list('1234567890')))
def _generate_otp(secret: str, count: int) -> str:
"""Generate one time password."""
import pyotp
return str(pyotp.HOTP(secret).at(count))
def _verify_otp(secret: str, otp: str, count: int) -> bool:
"""Verify one time password."""
import pyotp
return bool(pyotp.HOTP(secret).verify(otp, count))
@attr.s(slots=True)
class NotifySetting:
"""Store notify setting for one user."""
secret = attr.ib(type=str, factory=_generate_secret) # not persistent
counter = attr.ib(type=int, factory=_generate_random) # not persistent
notify_service = attr.ib(type=Optional[str], default=None)
target = attr.ib(type=Optional[str], default=None)
_UsersDict = Dict[str, NotifySetting]
@MULTI_FACTOR_AUTH_MODULES.register('notify')
class NotifyAuthModule(MultiFactorAuthModule):
"""Auth module send hmac-based one time password by notify service."""
DEFAULT_TITLE = 'Notify One-Time Password'
def __init__(self, hass: HomeAssistant, config: Dict[str, Any]) -> None:
"""Initialize the user data store."""
super().__init__(hass, config)
self._user_settings = None # type: Optional[_UsersDict]
self._user_store = hass.helpers.storage.Store(
STORAGE_VERSION, STORAGE_KEY, private=True)
self._include = config.get(CONF_INCLUDE, [])
self._exclude = config.get(CONF_EXCLUDE, [])
self._message_template = config[CONF_MESSAGE]
@property
def input_schema(self) -> vol.Schema:
"""Validate login flow input data."""
return vol.Schema({INPUT_FIELD_CODE: str})
async def _async_load(self) -> None:
"""Load stored data."""
data = await self._user_store.async_load()
if data is None:
data = {STORAGE_USERS: {}}
self._user_settings = {
user_id: NotifySetting(**setting)
for user_id, setting in data.get(STORAGE_USERS, {}).items()
}
async def _async_save(self) -> None:
"""Save data."""
if self._user_settings is None:
return
await self._user_store.async_save({STORAGE_USERS: {
user_id: attr.asdict(
notify_setting, filter=attr.filters.exclude(
attr.fields(NotifySetting).secret,
attr.fields(NotifySetting).counter,
))
for user_id, notify_setting
in self._user_settings.items()
}})
@callback
def aync_get_available_notify_services(self) -> List[str]:
"""Return list of notify services."""
unordered_services = set()
for service in self.hass.services.async_services().get('notify', {}):
if service not in self._exclude:
unordered_services.add(service)
if self._include:
unordered_services &= set(self._include)
return sorted(unordered_services)
async def async_setup_flow(self, user_id: str) -> SetupFlow:
"""Return a data entry flow handler for setup module.
Mfa module should extend SetupFlow
"""
return NotifySetupFlow(
self, self.input_schema, user_id,
self.aync_get_available_notify_services())
async def async_setup_user(self, user_id: str, setup_data: Any) -> Any:
"""Set up auth module for user."""
if self._user_settings is None:
await self._async_load()
assert self._user_settings is not None
self._user_settings[user_id] = NotifySetting(
notify_service=setup_data.get('notify_service'),
target=setup_data.get('target'),
)
await self._async_save()
async def async_depose_user(self, user_id: str) -> None:
"""Depose auth module for user."""
if self._user_settings is None:
await self._async_load()
assert self._user_settings is not None
if self._user_settings.pop(user_id, None):
await self._async_save()
async def async_is_user_setup(self, user_id: str) -> bool:
"""Return whether user is setup."""
if self._user_settings is None:
await self._async_load()
assert self._user_settings is not None
return user_id in self._user_settings
async def async_validate(
self, user_id: str, user_input: Dict[str, Any]) -> bool:
"""Return True if validation passed."""
if self._user_settings is None:
await self._async_load()
assert self._user_settings is not None
notify_setting = self._user_settings.get(user_id, None)
if notify_setting is None:
return False
# user_input has been validate in caller
return await self.hass.async_add_executor_job(
_verify_otp, notify_setting.secret,
user_input.get(INPUT_FIELD_CODE, ''),
notify_setting.counter)
async def async_initialize_login_mfa_step(self, user_id: str) -> None:
"""Generate code and notify user."""
if self._user_settings is None:
await self._async_load()
assert self._user_settings is not None
notify_setting = self._user_settings.get(user_id, None)
if notify_setting is None:
raise ValueError('Cannot find user_id')
def generate_secret_and_one_time_password() -> str:
"""Generate and send one time password."""
assert notify_setting
# secret and counter are not persistent
notify_setting.secret = _generate_secret()
notify_setting.counter = _generate_random()
return _generate_otp(
notify_setting.secret, notify_setting.counter)
code = await self.hass.async_add_executor_job(
generate_secret_and_one_time_password)
await self.async_notify_user(user_id, code)
async def async_notify_user(self, user_id: str, code: str) -> None:
"""Send code by user's notify service."""
if self._user_settings is None:
await self._async_load()
assert self._user_settings is not None
notify_setting = self._user_settings.get(user_id, None)
if notify_setting is None:
_LOGGER.error('Cannot find user %s', user_id)
return
await self.async_notify( # type: ignore
code, notify_setting.notify_service, notify_setting.target)
async def async_notify(self, code: str, notify_service: str,
target: Optional[str] = None) -> None:
"""Send code by notify service."""
data = {'message': self._message_template.format(code)}
if target:
data['target'] = [target]
await self.hass.services.async_call('notify', notify_service, data)
class NotifySetupFlow(SetupFlow):
"""Handler for the setup flow."""
def __init__(self, auth_module: NotifyAuthModule,
setup_schema: vol.Schema,
user_id: str,
available_notify_services: List[str]) -> None:
"""Initialize the setup flow."""
super().__init__(auth_module, setup_schema, user_id)
# to fix typing complaint
self._auth_module = auth_module # type: NotifyAuthModule
self._available_notify_services = available_notify_services
self._secret = None # type: Optional[str]
self._count = None # type: Optional[int]
self._notify_service = None # type: Optional[str]
self._target = None # type: Optional[str]
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Let user select available notify services."""
errors = {} # type: Dict[str, str]
hass = self._auth_module.hass
if user_input:
self._notify_service = user_input['notify_service']
self._target = user_input.get('target')
self._secret = await hass.async_add_executor_job(_generate_secret)
self._count = await hass.async_add_executor_job(_generate_random)
return await self.async_step_setup()
if not self._available_notify_services:
return self.async_abort(reason='no_available_service')
schema = OrderedDict() # type: Dict[str, Any]
schema['notify_service'] = vol.In(self._available_notify_services)
schema['target'] = vol.Optional(str)
return self.async_show_form(
step_id='init',
data_schema=vol.Schema(schema),
errors=errors
)
async def async_step_setup(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Verify user can recevie one-time password."""
errors = {} # type: Dict[str, str]
hass = self._auth_module.hass
if user_input:
verified = await hass.async_add_executor_job(
_verify_otp, self._secret, user_input['code'], self._count)
if verified:
await self._auth_module.async_setup_user(
self._user_id, {
'notify_service': self._notify_service,
'target': self._target,
})
return self.async_create_entry(
title=self._auth_module.name,
data={}
)
errors['base'] = 'invalid_code'
# generate code every time, no retry logic
assert self._secret and self._count
code = await hass.async_add_executor_job(
_generate_otp, self._secret, self._count)
assert self._notify_service
await self._auth_module.async_notify(
code, self._notify_service, self._target)
return self.async_show_form(
step_id='setup',
data_schema=self._setup_schema,
description_placeholders={'notify_service': self._notify_service},
errors=errors,
)

View File

@@ -0,0 +1,214 @@
"""Time-based One Time Password auth module."""
import logging
from io import BytesIO
from typing import Any, Dict, Optional, Tuple # noqa: F401
import voluptuous as vol
from homeassistant.auth.models import User
from homeassistant.core import HomeAssistant
from . import MultiFactorAuthModule, MULTI_FACTOR_AUTH_MODULES, \
MULTI_FACTOR_AUTH_MODULE_SCHEMA, SetupFlow
REQUIREMENTS = ['pyotp==2.2.6', 'PyQRCode==1.2.1']
CONFIG_SCHEMA = MULTI_FACTOR_AUTH_MODULE_SCHEMA.extend({
}, extra=vol.PREVENT_EXTRA)
STORAGE_VERSION = 1
STORAGE_KEY = 'auth_module.totp'
STORAGE_USERS = 'users'
STORAGE_USER_ID = 'user_id'
STORAGE_OTA_SECRET = 'ota_secret'
INPUT_FIELD_CODE = 'code'
DUMMY_SECRET = 'FPPTH34D4E3MI2HG'
_LOGGER = logging.getLogger(__name__)
def _generate_qr_code(data: str) -> str:
"""Generate a base64 PNG string represent QR Code image of data."""
import pyqrcode
qr_code = pyqrcode.create(data)
with BytesIO() as buffer:
qr_code.svg(file=buffer, scale=4)
return '{}'.format(
buffer.getvalue().decode("ascii").replace('\n', '')
.replace('<?xml version="1.0" encoding="UTF-8"?>'
'<svg xmlns="http://www.w3.org/2000/svg"', '<svg')
)
def _generate_secret_and_qr_code(username: str) -> Tuple[str, str, str]:
"""Generate a secret, url, and QR code."""
import pyotp
ota_secret = pyotp.random_base32()
url = pyotp.totp.TOTP(ota_secret).provisioning_uri(
username, issuer_name="Home Assistant")
image = _generate_qr_code(url)
return ota_secret, url, image
@MULTI_FACTOR_AUTH_MODULES.register('totp')
class TotpAuthModule(MultiFactorAuthModule):
"""Auth module validate time-based one time password."""
DEFAULT_TITLE = 'Time-based One Time Password'
MAX_RETRY_TIME = 5
def __init__(self, hass: HomeAssistant, config: Dict[str, Any]) -> None:
"""Initialize the user data store."""
super().__init__(hass, config)
self._users = None # type: Optional[Dict[str, str]]
self._user_store = hass.helpers.storage.Store(
STORAGE_VERSION, STORAGE_KEY, private=True)
@property
def input_schema(self) -> vol.Schema:
"""Validate login flow input data."""
return vol.Schema({INPUT_FIELD_CODE: str})
async def _async_load(self) -> None:
"""Load stored data."""
data = await self._user_store.async_load()
if data is None:
data = {STORAGE_USERS: {}}
self._users = data.get(STORAGE_USERS, {})
async def _async_save(self) -> None:
"""Save data."""
await self._user_store.async_save({STORAGE_USERS: self._users})
def _add_ota_secret(self, user_id: str,
secret: Optional[str] = None) -> str:
"""Create a ota_secret for user."""
import pyotp
ota_secret = secret or pyotp.random_base32() # type: str
self._users[user_id] = ota_secret # type: ignore
return ota_secret
async def async_setup_flow(self, user_id: str) -> SetupFlow:
"""Return a data entry flow handler for setup module.
Mfa module should extend SetupFlow
"""
user = await self.hass.auth.async_get_user(user_id) # type: ignore
return TotpSetupFlow(self, self.input_schema, user)
async def async_setup_user(self, user_id: str, setup_data: Any) -> str:
"""Set up auth module for user."""
if self._users is None:
await self._async_load()
result = await self.hass.async_add_executor_job(
self._add_ota_secret, user_id, setup_data.get('secret'))
await self._async_save()
return result
async def async_depose_user(self, user_id: str) -> None:
"""Depose auth module for user."""
if self._users is None:
await self._async_load()
if self._users.pop(user_id, None): # type: ignore
await self._async_save()
async def async_is_user_setup(self, user_id: str) -> bool:
"""Return whether user is setup."""
if self._users is None:
await self._async_load()
return user_id in self._users # type: ignore
async def async_validate(
self, user_id: str, user_input: Dict[str, Any]) -> bool:
"""Return True if validation passed."""
if self._users is None:
await self._async_load()
# user_input has been validate in caller
# set INPUT_FIELD_CODE as vol.Required is not user friendly
return await self.hass.async_add_executor_job(
self._validate_2fa, user_id, user_input.get(INPUT_FIELD_CODE, ''))
def _validate_2fa(self, user_id: str, code: str) -> bool:
"""Validate two factor authentication code."""
import pyotp
ota_secret = self._users.get(user_id) # type: ignore
if ota_secret is None:
# even we cannot find user, we still do verify
# to make timing the same as if user was found.
pyotp.TOTP(DUMMY_SECRET).verify(code, valid_window=1)
return False
return bool(pyotp.TOTP(ota_secret).verify(code, valid_window=1))
class TotpSetupFlow(SetupFlow):
"""Handler for the setup flow."""
def __init__(self, auth_module: TotpAuthModule,
setup_schema: vol.Schema,
user: User) -> None:
"""Initialize the setup flow."""
super().__init__(auth_module, setup_schema, user.id)
# to fix typing complaint
self._auth_module = auth_module # type: TotpAuthModule
self._user = user
self._ota_secret = None # type: Optional[str]
self._url = None # type Optional[str]
self._image = None # type Optional[str]
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Handle the first step of setup flow.
Return self.async_show_form(step_id='init') if user_input == None.
Return self.async_create_entry(data={'result': result}) if finish.
"""
import pyotp
errors = {} # type: Dict[str, str]
if user_input:
verified = await self.hass.async_add_executor_job( # type: ignore
pyotp.TOTP(self._ota_secret).verify, user_input['code'])
if verified:
result = await self._auth_module.async_setup_user(
self._user_id, {'secret': self._ota_secret})
return self.async_create_entry(
title=self._auth_module.name,
data={'result': result}
)
errors['base'] = 'invalid_code'
else:
hass = self._auth_module.hass
self._ota_secret, self._url, self._image = \
await hass.async_add_executor_job( # type: ignore
_generate_secret_and_qr_code, str(self._user.name))
return self.async_show_form(
step_id='init',
data_schema=self._setup_schema,
description_placeholders={
'code': self._ota_secret,
'url': self._url,
'qr_code': self._image
},
errors=errors
)

View File

@@ -0,0 +1,75 @@
"""Auth models."""
from datetime import datetime, timedelta
from typing import Dict, List, NamedTuple, Optional # noqa: F401
import uuid
import attr
from homeassistant.util import dt as dt_util
from .util import generate_secret
TOKEN_TYPE_NORMAL = 'normal'
TOKEN_TYPE_SYSTEM = 'system'
TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN = 'long_lived_access_token'
@attr.s(slots=True)
class User:
"""A user."""
name = attr.ib(type=str) # type: Optional[str]
id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex)
is_owner = attr.ib(type=bool, default=False)
is_active = attr.ib(type=bool, default=False)
system_generated = attr.ib(type=bool, default=False)
# List of credentials of a user.
credentials = attr.ib(
type=list, factory=list, cmp=False
) # type: List[Credentials]
# Tokens associated with a user.
refresh_tokens = attr.ib(
type=dict, factory=dict, cmp=False
) # type: Dict[str, RefreshToken]
@attr.s(slots=True)
class RefreshToken:
"""RefreshToken for a user to grant new access tokens."""
user = attr.ib(type=User)
client_id = attr.ib(type=Optional[str])
access_token_expiration = attr.ib(type=timedelta)
client_name = attr.ib(type=Optional[str], default=None)
client_icon = attr.ib(type=Optional[str], default=None)
token_type = attr.ib(type=str, default=TOKEN_TYPE_NORMAL,
validator=attr.validators.in_((
TOKEN_TYPE_NORMAL, TOKEN_TYPE_SYSTEM,
TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN)))
id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex)
created_at = attr.ib(type=datetime, factory=dt_util.utcnow)
token = attr.ib(type=str, factory=lambda: generate_secret(64))
jwt_key = attr.ib(type=str, factory=lambda: generate_secret(64))
last_used_at = attr.ib(type=Optional[datetime], default=None)
last_used_ip = attr.ib(type=Optional[str], default=None)
@attr.s(slots=True)
class Credentials:
"""Credentials for a user on an auth provider."""
auth_provider_type = attr.ib(type=str)
auth_provider_id = attr.ib(type=Optional[str])
# Allow the auth provider to store data to represent their auth.
data = attr.ib(type=dict)
id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex)
is_new = attr.ib(type=bool, default=True)
UserMeta = NamedTuple("UserMeta",
[('name', Optional[str]), ('is_active', bool)])

View File

@@ -0,0 +1,268 @@
"""Auth providers for Home Assistant."""
import importlib
import logging
import types
from typing import Any, Dict, List, Optional
import voluptuous as vol
from voluptuous.humanize import humanize_error
from homeassistant import data_entry_flow, requirements
from homeassistant.core import callback, HomeAssistant
from homeassistant.const import CONF_ID, CONF_NAME, CONF_TYPE
from homeassistant.exceptions import HomeAssistantError
from homeassistant.util import dt as dt_util
from homeassistant.util.decorator import Registry
from ..auth_store import AuthStore
from ..const import MFA_SESSION_EXPIRATION
from ..models import Credentials, User, UserMeta # noqa: F401
_LOGGER = logging.getLogger(__name__)
DATA_REQS = 'auth_prov_reqs_processed'
AUTH_PROVIDERS = Registry()
AUTH_PROVIDER_SCHEMA = vol.Schema({
vol.Required(CONF_TYPE): str,
vol.Optional(CONF_NAME): str,
# Specify ID if you have two auth providers for same type.
vol.Optional(CONF_ID): str,
}, extra=vol.ALLOW_EXTRA)
class AuthProvider:
"""Provider of user authentication."""
DEFAULT_TITLE = 'Unnamed auth provider'
def __init__(self, hass: HomeAssistant, store: AuthStore,
config: Dict[str, Any]) -> None:
"""Initialize an auth provider."""
self.hass = hass
self.store = store
self.config = config
@property
def id(self) -> Optional[str]: # pylint: disable=invalid-name
"""Return id of the auth provider.
Optional, can be None.
"""
return self.config.get(CONF_ID)
@property
def type(self) -> str:
"""Return type of the provider."""
return self.config[CONF_TYPE] # type: ignore
@property
def name(self) -> str:
"""Return the name of the auth provider."""
return self.config.get(CONF_NAME, self.DEFAULT_TITLE)
@property
def support_mfa(self) -> bool:
"""Return whether multi-factor auth supported by the auth provider."""
return True
async def async_credentials(self) -> List[Credentials]:
"""Return all credentials of this provider."""
users = await self.store.async_get_users()
return [
credentials
for user in users
for credentials in user.credentials
if (credentials.auth_provider_type == self.type and
credentials.auth_provider_id == self.id)
]
@callback
def async_create_credentials(self, data: Dict[str, str]) -> Credentials:
"""Create credentials."""
return Credentials(
auth_provider_type=self.type,
auth_provider_id=self.id,
data=data,
)
# Implement by extending class
async def async_login_flow(self, context: Optional[Dict]) -> 'LoginFlow':
"""Return the data flow for logging in with auth provider.
Auth provider should extend LoginFlow and return an instance.
"""
raise NotImplementedError
async def async_get_or_create_credentials(
self, flow_result: Dict[str, str]) -> Credentials:
"""Get credentials based on the flow result."""
raise NotImplementedError
async def async_user_meta_for_credentials(
self, credentials: Credentials) -> UserMeta:
"""Return extra user metadata for credentials.
Will be used to populate info when creating a new user.
"""
raise NotImplementedError
async def auth_provider_from_config(
hass: HomeAssistant, store: AuthStore,
config: Dict[str, Any]) -> AuthProvider:
"""Initialize an auth provider from a config."""
provider_name = config[CONF_TYPE]
module = await load_auth_provider_module(hass, provider_name)
try:
config = module.CONFIG_SCHEMA(config) # type: ignore
except vol.Invalid as err:
_LOGGER.error('Invalid configuration for auth provider %s: %s',
provider_name, humanize_error(config, err))
raise
return AUTH_PROVIDERS[provider_name](hass, store, config) # type: ignore
async def load_auth_provider_module(
hass: HomeAssistant, provider: str) -> types.ModuleType:
"""Load an auth provider."""
try:
module = importlib.import_module(
'homeassistant.auth.providers.{}'.format(provider))
except ImportError as err:
_LOGGER.error('Unable to load auth provider %s: %s', provider, err)
raise HomeAssistantError('Unable to load auth provider {}: {}'.format(
provider, err))
if hass.config.skip_pip or not hasattr(module, 'REQUIREMENTS'):
return module
processed = hass.data.get(DATA_REQS)
if processed is None:
processed = hass.data[DATA_REQS] = set()
elif provider in processed:
return module
# https://github.com/python/mypy/issues/1424
reqs = module.REQUIREMENTS # type: ignore
req_success = await requirements.async_process_requirements(
hass, 'auth provider {}'.format(provider), reqs)
if not req_success:
raise HomeAssistantError(
'Unable to process requirements of auth provider {}'.format(
provider))
processed.add(provider)
return module
class LoginFlow(data_entry_flow.FlowHandler):
"""Handler for the login flow."""
def __init__(self, auth_provider: AuthProvider) -> None:
"""Initialize the login flow."""
self._auth_provider = auth_provider
self._auth_module_id = None # type: Optional[str]
self._auth_manager = auth_provider.hass.auth # type: ignore
self.available_mfa_modules = {} # type: Dict[str, str]
self.created_at = dt_util.utcnow()
self.invalid_mfa_times = 0
self.user = None # type: Optional[User]
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Handle the first step of login flow.
Return self.async_show_form(step_id='init') if user_input == None.
Return await self.async_finish(flow_result) if login init step pass.
"""
raise NotImplementedError
async def async_step_select_mfa_module(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Handle the step of select mfa module."""
errors = {}
if user_input is not None:
auth_module = user_input.get('multi_factor_auth_module')
if auth_module in self.available_mfa_modules:
self._auth_module_id = auth_module
return await self.async_step_mfa()
errors['base'] = 'invalid_auth_module'
if len(self.available_mfa_modules) == 1:
self._auth_module_id = list(self.available_mfa_modules.keys())[0]
return await self.async_step_mfa()
return self.async_show_form(
step_id='select_mfa_module',
data_schema=vol.Schema({
'multi_factor_auth_module': vol.In(self.available_mfa_modules)
}),
errors=errors,
)
async def async_step_mfa(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Handle the step of mfa validation."""
assert self.user
errors = {}
auth_module = self._auth_manager.get_auth_mfa_module(
self._auth_module_id)
if auth_module is None:
# Given an invalid input to async_step_select_mfa_module
# will show invalid_auth_module error
return await self.async_step_select_mfa_module(user_input={})
if user_input is None and hasattr(auth_module,
'async_initialize_login_mfa_step'):
await auth_module.async_initialize_login_mfa_step(self.user.id)
if user_input is not None:
expires = self.created_at + MFA_SESSION_EXPIRATION
if dt_util.utcnow() > expires:
return self.async_abort(
reason='login_expired'
)
result = await auth_module.async_validate(
self.user.id, user_input)
if not result:
errors['base'] = 'invalid_code'
self.invalid_mfa_times += 1
if self.invalid_mfa_times >= auth_module.MAX_RETRY_TIME > 0:
return self.async_abort(
reason='too_many_retry'
)
if not errors:
return await self.async_finish(self.user)
description_placeholders = {
'mfa_module_name': auth_module.name,
'mfa_module_id': auth_module.id,
} # type: Dict[str, Optional[str]]
return self.async_show_form(
step_id='mfa',
data_schema=auth_module.input_schema,
description_placeholders=description_placeholders,
errors=errors,
)
async def async_finish(self, flow_result: Any) -> Dict:
"""Handle the pass of login flow."""
return self.async_create_entry(
title=self._auth_provider.name,
data=flow_result
)

View File

@@ -0,0 +1,274 @@
"""Home Assistant auth provider."""
import base64
from collections import OrderedDict
import hashlib
import hmac
from typing import Any, Dict, List, Optional, cast
import bcrypt
import voluptuous as vol
from homeassistant.const import CONF_ID
from homeassistant.core import callback, HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.util.async_ import run_coroutine_threadsafe
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
from ..models import Credentials, UserMeta
from ..util import generate_secret
STORAGE_VERSION = 1
STORAGE_KEY = 'auth_provider.homeassistant'
def _disallow_id(conf: Dict[str, Any]) -> Dict[str, Any]:
"""Disallow ID in config."""
if CONF_ID in conf:
raise vol.Invalid(
'ID is not allowed for the homeassistant auth provider.')
return conf
CONFIG_SCHEMA = vol.All(AUTH_PROVIDER_SCHEMA, _disallow_id)
class InvalidAuth(HomeAssistantError):
"""Raised when we encounter invalid authentication."""
class InvalidUser(HomeAssistantError):
"""Raised when invalid user is specified.
Will not be raised when validating authentication.
"""
class Data:
"""Hold the user data."""
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the user data store."""
self.hass = hass
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY,
private=True)
self._data = None # type: Optional[Dict[str, Any]]
async def async_load(self) -> None:
"""Load stored data."""
data = await self._store.async_load()
if data is None:
data = {
'salt': generate_secret(),
'users': []
}
self._data = data
@property
def users(self) -> List[Dict[str, str]]:
"""Return users."""
return self._data['users'] # type: ignore
def validate_login(self, username: str, password: str) -> None:
"""Validate a username and password.
Raises InvalidAuth if auth invalid.
"""
dummy = b'$2b$12$CiuFGszHx9eNHxPuQcwBWez4CwDTOcLTX5CbOpV6gef2nYuXkY7BO'
found = None
# Compare all users to avoid timing attacks.
for user in self.users:
if username == user['username']:
found = user
if found is None:
# check a hash to make timing the same as if user was found
bcrypt.checkpw(b'foo',
dummy)
raise InvalidAuth
user_hash = base64.b64decode(found['password'])
# if the hash is not a bcrypt hash...
# provide a transparant upgrade for old pbkdf2 hash format
if not (user_hash.startswith(b'$2a$')
or user_hash.startswith(b'$2b$')
or user_hash.startswith(b'$2x$')
or user_hash.startswith(b'$2y$')):
# IMPORTANT! validate the login, bail if invalid
hashed = self.legacy_hash_password(password)
if not hmac.compare_digest(hashed, user_hash):
raise InvalidAuth
# then re-hash the valid password with bcrypt
self.change_password(found['username'], password)
run_coroutine_threadsafe(
self.async_save(), self.hass.loop
).result()
user_hash = base64.b64decode(found['password'])
# bcrypt.checkpw is timing-safe
if not bcrypt.checkpw(password.encode(),
user_hash):
raise InvalidAuth
def legacy_hash_password(self, password: str,
for_storage: bool = False) -> bytes:
"""LEGACY password encoding."""
# We're no longer storing salts in data, but if one exists we
# should be able to retrieve it.
salt = self._data['salt'].encode() # type: ignore
hashed = hashlib.pbkdf2_hmac('sha512', password.encode(), salt, 100000)
if for_storage:
hashed = base64.b64encode(hashed)
return hashed
# pylint: disable=no-self-use
def hash_password(self, password: str, for_storage: bool = False) -> bytes:
"""Encode a password."""
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12)) \
# type: bytes
if for_storage:
hashed = base64.b64encode(hashed)
return hashed
def add_auth(self, username: str, password: str) -> None:
"""Add a new authenticated user/pass."""
if any(user['username'] == username for user in self.users):
raise InvalidUser
self.users.append({
'username': username,
'password': self.hash_password(password, True).decode(),
})
@callback
def async_remove_auth(self, username: str) -> None:
"""Remove authentication."""
index = None
for i, user in enumerate(self.users):
if user['username'] == username:
index = i
break
if index is None:
raise InvalidUser
self.users.pop(index)
def change_password(self, username: str, new_password: str) -> None:
"""Update the password.
Raises InvalidUser if user cannot be found.
"""
for user in self.users:
if user['username'] == username:
user['password'] = self.hash_password(
new_password, True).decode()
break
else:
raise InvalidUser
async def async_save(self) -> None:
"""Save data."""
await self._store.async_save(self._data)
@AUTH_PROVIDERS.register('homeassistant')
class HassAuthProvider(AuthProvider):
"""Auth provider based on a local storage of users in HASS config dir."""
DEFAULT_TITLE = 'Home Assistant Local'
data = None
async def async_initialize(self) -> None:
"""Initialize the auth provider."""
if self.data is not None:
return
self.data = Data(self.hass)
await self.data.async_load()
async def async_login_flow(
self, context: Optional[Dict]) -> LoginFlow:
"""Return a flow to login."""
return HassLoginFlow(self)
async def async_validate_login(self, username: str, password: str) -> None:
"""Validate a username and password."""
if self.data is None:
await self.async_initialize()
assert self.data is not None
await self.hass.async_add_executor_job(
self.data.validate_login, username, password)
async def async_get_or_create_credentials(
self, flow_result: Dict[str, str]) -> Credentials:
"""Get credentials based on the flow result."""
username = flow_result['username']
for credential in await self.async_credentials():
if credential.data['username'] == username:
return credential
# Create new credentials.
return self.async_create_credentials({
'username': username
})
async def async_user_meta_for_credentials(
self, credentials: Credentials) -> UserMeta:
"""Get extra info for this credential."""
return UserMeta(name=credentials.data['username'], is_active=True)
async def async_will_remove_credentials(
self, credentials: Credentials) -> None:
"""When credentials get removed, also remove the auth."""
if self.data is None:
await self.async_initialize()
assert self.data is not None
try:
self.data.async_remove_auth(credentials.data['username'])
await self.data.async_save()
except InvalidUser:
# Can happen if somehow we didn't clean up a credential
pass
class HassLoginFlow(LoginFlow):
"""Handler for the login flow."""
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Handle the step of the form."""
errors = {}
if user_input is not None:
try:
await cast(HassAuthProvider, self._auth_provider)\
.async_validate_login(user_input['username'],
user_input['password'])
except InvalidAuth:
errors['base'] = 'invalid_auth'
if not errors:
user_input.pop('password')
return await self.async_finish(user_input)
schema = OrderedDict() # type: Dict[str, type]
schema['username'] = str
schema['password'] = str
return self.async_show_form(
step_id='init',
data_schema=vol.Schema(schema),
errors=errors,
)

View File

@@ -0,0 +1,120 @@
"""Example auth provider."""
from collections import OrderedDict
import hmac
from typing import Any, Dict, Optional, cast
import voluptuous as vol
from homeassistant.exceptions import HomeAssistantError
from homeassistant.core import callback
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
from ..models import Credentials, UserMeta
USER_SCHEMA = vol.Schema({
vol.Required('username'): str,
vol.Required('password'): str,
vol.Optional('name'): str,
})
CONFIG_SCHEMA = AUTH_PROVIDER_SCHEMA.extend({
vol.Required('users'): [USER_SCHEMA]
}, extra=vol.PREVENT_EXTRA)
class InvalidAuthError(HomeAssistantError):
"""Raised when submitting invalid authentication."""
@AUTH_PROVIDERS.register('insecure_example')
class ExampleAuthProvider(AuthProvider):
"""Example auth provider based on hardcoded usernames and passwords."""
async def async_login_flow(self, context: Optional[Dict]) -> LoginFlow:
"""Return a flow to login."""
return ExampleLoginFlow(self)
@callback
def async_validate_login(self, username: str, password: str) -> None:
"""Validate a username and password."""
user = None
# Compare all users to avoid timing attacks.
for usr in self.config['users']:
if hmac.compare_digest(username.encode('utf-8'),
usr['username'].encode('utf-8')):
user = usr
if user is None:
# Do one more compare to make timing the same as if user was found.
hmac.compare_digest(password.encode('utf-8'),
password.encode('utf-8'))
raise InvalidAuthError
if not hmac.compare_digest(user['password'].encode('utf-8'),
password.encode('utf-8')):
raise InvalidAuthError
async def async_get_or_create_credentials(
self, flow_result: Dict[str, str]) -> Credentials:
"""Get credentials based on the flow result."""
username = flow_result['username']
for credential in await self.async_credentials():
if credential.data['username'] == username:
return credential
# Create new credentials.
return self.async_create_credentials({
'username': username
})
async def async_user_meta_for_credentials(
self, credentials: Credentials) -> UserMeta:
"""Return extra user metadata for credentials.
Will be used to populate info when creating a new user.
"""
username = credentials.data['username']
name = None
for user in self.config['users']:
if user['username'] == username:
name = user.get('name')
break
return UserMeta(name=name, is_active=True)
class ExampleLoginFlow(LoginFlow):
"""Handler for the login flow."""
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Handle the step of the form."""
errors = {}
if user_input is not None:
try:
cast(ExampleAuthProvider, self._auth_provider)\
.async_validate_login(user_input['username'],
user_input['password'])
except InvalidAuthError:
errors['base'] = 'invalid_auth'
if not errors:
user_input.pop('password')
return await self.async_finish(user_input)
schema = OrderedDict() # type: Dict[str, type]
schema['username'] = str
schema['password'] = str
return self.async_show_form(
step_id='init',
data_schema=vol.Schema(schema),
errors=errors,
)

View File

@@ -0,0 +1,101 @@
"""
Support Legacy API password auth provider.
It will be removed when auth system production ready
"""
import hmac
from typing import Any, Dict, Optional, cast
import voluptuous as vol
from homeassistant.components.http import HomeAssistantHTTP # noqa: F401
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
from ..models import Credentials, UserMeta
USER_SCHEMA = vol.Schema({
vol.Required('username'): str,
})
CONFIG_SCHEMA = AUTH_PROVIDER_SCHEMA.extend({
}, extra=vol.PREVENT_EXTRA)
LEGACY_USER_NAME = 'Legacy API password user'
class InvalidAuthError(HomeAssistantError):
"""Raised when submitting invalid authentication."""
@AUTH_PROVIDERS.register('legacy_api_password')
class LegacyApiPasswordAuthProvider(AuthProvider):
"""Example auth provider based on hardcoded usernames and passwords."""
DEFAULT_TITLE = 'Legacy API Password'
async def async_login_flow(self, context: Optional[Dict]) -> LoginFlow:
"""Return a flow to login."""
return LegacyLoginFlow(self)
@callback
def async_validate_login(self, password: str) -> None:
"""Validate a username and password."""
hass_http = getattr(self.hass, 'http', None) # type: HomeAssistantHTTP
if not hmac.compare_digest(hass_http.api_password.encode('utf-8'),
password.encode('utf-8')):
raise InvalidAuthError
async def async_get_or_create_credentials(
self, flow_result: Dict[str, str]) -> Credentials:
"""Return credentials for this login."""
credentials = await self.async_credentials()
if credentials:
return credentials[0]
return self.async_create_credentials({})
async def async_user_meta_for_credentials(
self, credentials: Credentials) -> UserMeta:
"""
Return info for the user.
Will be used to populate info when creating a new user.
"""
return UserMeta(name=LEGACY_USER_NAME, is_active=True)
class LegacyLoginFlow(LoginFlow):
"""Handler for the login flow."""
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Handle the step of the form."""
errors = {}
hass_http = getattr(self.hass, 'http', None)
if hass_http is None or not hass_http.api_password:
return self.async_abort(
reason='no_api_password_set'
)
if user_input is not None:
try:
cast(LegacyApiPasswordAuthProvider, self._auth_provider)\
.async_validate_login(user_input['password'])
except InvalidAuthError:
errors['base'] = 'invalid_auth'
if not errors:
return await self.async_finish({})
return self.async_show_form(
step_id='init',
data_schema=vol.Schema({'password': str}),
errors=errors,
)

View File

@@ -0,0 +1,129 @@
"""Trusted Networks auth provider.
It shows list of users if access from trusted network.
Abort login flow if not access from trusted network.
"""
from typing import Any, Dict, Optional, cast
import voluptuous as vol
from homeassistant.components.http import HomeAssistantHTTP # noqa: F401
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
from ..models import Credentials, UserMeta
CONFIG_SCHEMA = AUTH_PROVIDER_SCHEMA.extend({
}, extra=vol.PREVENT_EXTRA)
class InvalidAuthError(HomeAssistantError):
"""Raised when try to access from untrusted networks."""
class InvalidUserError(HomeAssistantError):
"""Raised when try to login as invalid user."""
@AUTH_PROVIDERS.register('trusted_networks')
class TrustedNetworksAuthProvider(AuthProvider):
"""Trusted Networks auth provider.
Allow passwordless access from trusted network.
"""
DEFAULT_TITLE = 'Trusted Networks'
@property
def support_mfa(self) -> bool:
"""Trusted Networks auth provider does not support MFA."""
return False
async def async_login_flow(self, context: Optional[Dict]) -> LoginFlow:
"""Return a flow to login."""
assert context is not None
users = await self.store.async_get_users()
available_users = {user.id: user.name
for user in users
if not user.system_generated and user.is_active}
return TrustedNetworksLoginFlow(
self, cast(str, context.get('ip_address')), available_users)
async def async_get_or_create_credentials(
self, flow_result: Dict[str, str]) -> Credentials:
"""Get credentials based on the flow result."""
user_id = flow_result['user']
users = await self.store.async_get_users()
for user in users:
if (not user.system_generated and
user.is_active and
user.id == user_id):
for credential in await self.async_credentials():
if credential.data['user_id'] == user_id:
return credential
cred = self.async_create_credentials({'user_id': user_id})
await self.store.async_link_user(user, cred)
return cred
# We only allow login as exist user
raise InvalidUserError
async def async_user_meta_for_credentials(
self, credentials: Credentials) -> UserMeta:
"""Return extra user metadata for credentials.
Trusted network auth provider should never create new user.
"""
raise NotImplementedError
@callback
def async_validate_access(self, ip_address: str) -> None:
"""Make sure the access from trusted networks.
Raise InvalidAuthError if not.
Raise InvalidAuthError if trusted_networks is not configured.
"""
hass_http = getattr(self.hass, 'http', None) # type: HomeAssistantHTTP
if not hass_http or not hass_http.trusted_networks:
raise InvalidAuthError('trusted_networks is not configured')
if not any(ip_address in trusted_network for trusted_network
in hass_http.trusted_networks):
raise InvalidAuthError('Not in trusted_networks')
class TrustedNetworksLoginFlow(LoginFlow):
"""Handler for the login flow."""
def __init__(self, auth_provider: TrustedNetworksAuthProvider,
ip_address: str, available_users: Dict[str, Optional[str]]) \
-> None:
"""Initialize the login flow."""
super().__init__(auth_provider)
self._available_users = available_users
self._ip_address = ip_address
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
"""Handle the step of the form."""
try:
cast(TrustedNetworksAuthProvider, self._auth_provider)\
.async_validate_access(self._ip_address)
except InvalidAuthError:
return self.async_abort(
reason='not_whitelisted'
)
if user_input is not None:
return await self.async_finish(user_input)
return self.async_show_form(
step_id='init',
data_schema=vol.Schema({'user': vol.In(self._available_users)}),
)

View File

@@ -0,0 +1,13 @@
"""Auth utils."""
import binascii
import os
def generate_secret(entropy: int = 32) -> str:
"""Generate a secret.
Backport of secrets.token_hex from Python 3.6
Event loop friendly.
"""
return binascii.hexlify(os.urandom(entropy)).decode('ascii')

View File

@@ -1,27 +1,23 @@
"""Provide methods to bootstrap a Home Assistant instance."""
import asyncio
import logging
import logging.handlers
import os
import sys
from time import time
from collections import OrderedDict
from typing import Any, Optional, Dict
import voluptuous as vol
from homeassistant import (
core, config as conf_util, config_entries, loader,
components as core_components)
core, config as conf_util, config_entries, components as core_components)
from homeassistant.components import persistent_notification
from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE
from homeassistant.setup import async_setup_component
from homeassistant.util.logging import AsyncHandler
from homeassistant.util.package import async_get_user_site, get_user_site
from homeassistant.util.package import async_get_user_site, is_virtual_env
from homeassistant.util.yaml import clear_secret_cache
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.signal import async_register_signal_handling
_LOGGER = logging.getLogger(__name__)
@@ -30,9 +26,8 @@ ERROR_LOG_FILENAME = 'home-assistant.log'
# hass.data key for logging information.
DATA_LOGGING = 'logging'
FIRST_INIT_COMPONENT = set((
'system_log', 'recorder', 'mqtt', 'mqtt_eventstream', 'logger',
'introduction', 'frontend', 'history'))
FIRST_INIT_COMPONENT = {'system_log', 'recorder', 'mqtt', 'mqtt_eventstream',
'logger', 'introduction', 'frontend', 'history'}
def from_config_dict(config: Dict[str, Any],
@@ -42,7 +37,8 @@ def from_config_dict(config: Dict[str, Any],
verbose: bool = False,
skip_pip: bool = False,
log_rotate_days: Any = None,
log_file: Any = None) \
log_file: Any = None,
log_no_color: bool = False) \
-> Optional[core.HomeAssistant]:
"""Try to configure Home Assistant from a configuration dictionary.
@@ -53,28 +49,28 @@ def from_config_dict(config: Dict[str, Any],
if config_dir is not None:
config_dir = os.path.abspath(config_dir)
hass.config.config_dir = config_dir
hass.loop.run_until_complete(
async_mount_local_lib_path(config_dir, hass.loop))
if not is_virtual_env():
hass.loop.run_until_complete(
async_mount_local_lib_path(config_dir))
# run task
hass = hass.loop.run_until_complete(
async_from_config_dict(
config, hass, config_dir, enable_log, verbose, skip_pip,
log_rotate_days, log_file)
log_rotate_days, log_file, log_no_color)
)
return hass
@asyncio.coroutine
def async_from_config_dict(config: Dict[str, Any],
hass: core.HomeAssistant,
config_dir: Optional[str] = None,
enable_log: bool = True,
verbose: bool = False,
skip_pip: bool = False,
log_rotate_days: Any = None,
log_file: Any = None) \
async def async_from_config_dict(config: Dict[str, Any],
hass: core.HomeAssistant,
config_dir: Optional[str] = None,
enable_log: bool = True,
verbose: bool = False,
skip_pip: bool = False,
log_rotate_days: Any = None,
log_file: Any = None,
log_no_color: bool = False) \
-> Optional[core.HomeAssistant]:
"""Try to configure Home Assistant from a configuration dictionary.
@@ -84,32 +80,40 @@ def async_from_config_dict(config: Dict[str, Any],
start = time()
if enable_log:
async_enable_logging(hass, verbose, log_rotate_days, log_file)
async_enable_logging(hass, verbose, log_rotate_days, log_file,
log_no_color)
core_config = config.get(core.DOMAIN, {})
has_api_password = bool((config.get('http') or {}).get('api_password'))
has_trusted_networks = bool((config.get('http') or {})
.get('trusted_networks'))
try:
yield from conf_util.async_process_ha_core_config(hass, core_config)
except vol.Invalid as ex:
conf_util.async_log_exception(ex, 'homeassistant', core_config, hass)
await conf_util.async_process_ha_core_config(
hass, core_config, has_api_password, has_trusted_networks)
except vol.Invalid as config_err:
conf_util.async_log_exception(
config_err, 'homeassistant', core_config, hass)
return None
except HomeAssistantError:
_LOGGER.error("Home Assistant core failed to initialize. "
"Further initialization aborted")
return None
yield from hass.async_add_job(conf_util.process_ha_config_upgrade, hass)
await hass.async_add_executor_job(
conf_util.process_ha_config_upgrade, hass)
hass.config.skip_pip = skip_pip
if skip_pip:
_LOGGER.warning("Skipping pip installation of required modules. "
"This may cause issues")
if not loader.PREPARED:
yield from hass.async_add_job(loader.prepare, hass)
# Make a copy because we are mutating it.
config = OrderedDict(config)
# Merge packages
conf_util.merge_packages_config(
config, core_config.get(conf_util.CONF_PACKAGES, {}))
hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))
# Ensure we have no None values after merge
for key, value in config.items():
@@ -117,7 +121,7 @@ def async_from_config_dict(config: Dict[str, Any],
config[key] = {}
hass.config_entries = config_entries.ConfigEntries(hass, config)
yield from hass.config_entries.async_load()
await hass.config_entries.async_load()
# Filter out the repeating and common config section [homeassistant]
components = set(key.split(' ')[0] for key in config.keys()
@@ -125,14 +129,13 @@ def async_from_config_dict(config: Dict[str, Any],
components.update(hass.config_entries.async_domains())
# setup components
# pylint: disable=not-an-iterable
res = yield from core_components.async_setup(hass, config)
res = await core_components.async_setup(hass, config)
if not res:
_LOGGER.error("Home Assistant core failed to initialize. "
"further initialization aborted")
"Further initialization aborted")
return hass
yield from persistent_notification.async_setup(hass, config)
await persistent_notification.async_setup(hass, config)
_LOGGER.info("Home Assistant core initialized")
@@ -140,22 +143,21 @@ def async_from_config_dict(config: Dict[str, Any],
for component in components:
if component not in FIRST_INIT_COMPONENT:
continue
hass.async_add_job(async_setup_component(hass, component, config))
hass.async_create_task(async_setup_component(hass, component, config))
yield from hass.async_block_till_done()
await hass.async_block_till_done()
# stage 2
for component in components:
if component in FIRST_INIT_COMPONENT:
continue
hass.async_add_job(async_setup_component(hass, component, config))
hass.async_create_task(async_setup_component(hass, component, config))
yield from hass.async_block_till_done()
await hass.async_block_till_done()
stop = time()
_LOGGER.info("Home Assistant initialized in %.2fs", stop-start)
async_register_signal_handling(hass)
return hass
@@ -164,7 +166,9 @@ def from_config_file(config_path: str,
verbose: bool = False,
skip_pip: bool = True,
log_rotate_days: Any = None,
log_file: Any = None):
log_file: Any = None,
log_no_color: bool = False)\
-> Optional[core.HomeAssistant]:
"""Read the configuration file and try to start all the functionality.
Will add functionality to 'hass' parameter if given,
@@ -176,19 +180,21 @@ def from_config_file(config_path: str,
# run task
hass = hass.loop.run_until_complete(
async_from_config_file(
config_path, hass, verbose, skip_pip, log_rotate_days, log_file)
config_path, hass, verbose, skip_pip,
log_rotate_days, log_file, log_no_color)
)
return hass
@asyncio.coroutine
def async_from_config_file(config_path: str,
hass: core.HomeAssistant,
verbose: bool = False,
skip_pip: bool = True,
log_rotate_days: Any = None,
log_file: Any = None):
async def async_from_config_file(config_path: str,
hass: core.HomeAssistant,
verbose: bool = False,
skip_pip: bool = True,
log_rotate_days: Any = None,
log_file: Any = None,
log_no_color: bool = False)\
-> Optional[core.HomeAssistant]:
"""Read the configuration file and try to start all the functionality.
Will add functionality to 'hass' parameter.
@@ -197,12 +203,15 @@ def async_from_config_file(config_path: str,
# Set config dir to directory holding config file
config_dir = os.path.abspath(os.path.dirname(config_path))
hass.config.config_dir = config_dir
yield from async_mount_local_lib_path(config_dir, hass.loop)
async_enable_logging(hass, verbose, log_rotate_days, log_file)
if not is_virtual_env():
await async_mount_local_lib_path(config_dir)
async_enable_logging(hass, verbose, log_rotate_days, log_file,
log_no_color)
try:
config_dict = yield from hass.async_add_job(
config_dict = await hass.async_add_executor_job(
conf_util.load_yaml_config_file, config_path)
except HomeAssistantError as err:
_LOGGER.error("Error loading %s: %s", config_path, err)
@@ -210,46 +219,56 @@ def async_from_config_file(config_path: str,
finally:
clear_secret_cache()
hass = yield from async_from_config_dict(
return await async_from_config_dict(
config_dict, hass, enable_log=False, skip_pip=skip_pip)
return hass
@core.callback
def async_enable_logging(hass: core.HomeAssistant, verbose: bool = False,
log_rotate_days=None, log_file=None) -> None:
def async_enable_logging(hass: core.HomeAssistant,
verbose: bool = False,
log_rotate_days: Optional[int] = None,
log_file: Optional[str] = None,
log_no_color: bool = False) -> None:
"""Set up the logging.
This method must be run in the event loop.
"""
logging.basicConfig(level=logging.INFO)
fmt = ("%(asctime)s %(levelname)s (%(threadName)s) "
"[%(name)s] %(message)s")
colorfmt = "%(log_color)s{}%(reset)s".format(fmt)
datefmt = '%Y-%m-%d %H:%M:%S'
if not log_no_color:
try:
from colorlog import ColoredFormatter
# basicConfig must be called after importing colorlog in order to
# ensure that the handlers it sets up wraps the correct streams.
logging.basicConfig(level=logging.INFO)
colorfmt = "%(log_color)s{}%(reset)s".format(fmt)
logging.getLogger().handlers[0].setFormatter(ColoredFormatter(
colorfmt,
datefmt=datefmt,
reset=True,
log_colors={
'DEBUG': 'cyan',
'INFO': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'red',
}
))
except ImportError:
pass
# If the above initialization failed for any reason, setup the default
# formatting. If the above succeeds, this wil result in a no-op.
logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO)
# Suppress overly verbose logs from libraries that aren't helpful
logging.getLogger('requests').setLevel(logging.WARNING)
logging.getLogger('urllib3').setLevel(logging.WARNING)
logging.getLogger('aiohttp.access').setLevel(logging.WARNING)
try:
from colorlog import ColoredFormatter
logging.getLogger().handlers[0].setFormatter(ColoredFormatter(
colorfmt,
datefmt=datefmt,
reset=True,
log_colors={
'DEBUG': 'cyan',
'INFO': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'red',
}
))
except ImportError:
pass
# Log errors to a file if we have write access to file or config dir
if log_file is None:
err_log_path = hass.config.path(ERROR_LOG_FILENAME)
@@ -266,7 +285,8 @@ def async_enable_logging(hass: core.HomeAssistant, verbose: bool = False,
if log_rotate_days:
err_handler = logging.handlers.TimedRotatingFileHandler(
err_log_path, when='midnight', backupCount=log_rotate_days)
err_log_path, when='midnight',
backupCount=log_rotate_days) # type: logging.FileHandler
else:
err_handler = logging.FileHandler(
err_log_path, mode='w', delay=True)
@@ -276,44 +296,32 @@ def async_enable_logging(hass: core.HomeAssistant, verbose: bool = False,
async_handler = AsyncHandler(hass.loop, err_handler)
@asyncio.coroutine
def async_stop_async_handler(event):
async def async_stop_async_handler(_: Any) -> None:
"""Cleanup async handler."""
logging.getLogger('').removeHandler(async_handler)
yield from async_handler.async_close(blocking=True)
logging.getLogger('').removeHandler(async_handler) # type: ignore
await async_handler.async_close(blocking=True)
hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_CLOSE, async_stop_async_handler)
logger = logging.getLogger('')
logger.addHandler(async_handler)
logger.addHandler(async_handler) # type: ignore
logger.setLevel(logging.INFO)
# Save the log file location for access by other components.
hass.data[DATA_LOGGING] = err_log_path
else:
_LOGGER.error(
"Unable to setup error log %s (access denied)", err_log_path)
"Unable to set up error log %s (access denied)", err_log_path)
def mount_local_lib_path(config_dir: str) -> str:
"""Add local library to Python Path."""
deps_dir = os.path.join(config_dir, 'deps')
lib_dir = get_user_site(deps_dir)
if lib_dir not in sys.path:
sys.path.insert(0, lib_dir)
return deps_dir
@asyncio.coroutine
def async_mount_local_lib_path(config_dir: str,
loop: asyncio.AbstractEventLoop) -> str:
async def async_mount_local_lib_path(config_dir: str) -> str:
"""Add local library to Python Path.
This function is a coroutine.
"""
deps_dir = os.path.join(config_dir, 'deps')
lib_dir = yield from async_get_user_site(deps_dir, loop=loop)
lib_dir = await async_get_user_site(deps_dir)
if lib_dir not in sys.path:
sys.path.insert(0, lib_dir)
return deps_dir

View File

@@ -10,6 +10,7 @@ Component design guidelines:
import asyncio
import itertools as it
import logging
from typing import Awaitable
import homeassistant.core as ha
import homeassistant.config as conf_util
@@ -58,61 +59,9 @@ def is_on(hass, entity_id=None):
return False
def turn_on(hass, entity_id=None, **service_data):
"""Turn specified entity on if possible."""
if entity_id is not None:
service_data[ATTR_ENTITY_ID] = entity_id
hass.services.call(ha.DOMAIN, SERVICE_TURN_ON, service_data)
def turn_off(hass, entity_id=None, **service_data):
"""Turn specified entity off."""
if entity_id is not None:
service_data[ATTR_ENTITY_ID] = entity_id
hass.services.call(ha.DOMAIN, SERVICE_TURN_OFF, service_data)
def toggle(hass, entity_id=None, **service_data):
"""Toggle specified entity."""
if entity_id is not None:
service_data[ATTR_ENTITY_ID] = entity_id
hass.services.call(ha.DOMAIN, SERVICE_TOGGLE, service_data)
def stop(hass):
"""Stop Home Assistant."""
hass.services.call(ha.DOMAIN, SERVICE_HOMEASSISTANT_STOP)
def restart(hass):
"""Stop Home Assistant."""
hass.services.call(ha.DOMAIN, SERVICE_HOMEASSISTANT_RESTART)
def check_config(hass):
"""Check the config files."""
hass.services.call(ha.DOMAIN, SERVICE_CHECK_CONFIG)
def reload_core_config(hass):
"""Reload the core config."""
hass.services.call(ha.DOMAIN, SERVICE_RELOAD_CORE_CONFIG)
@asyncio.coroutine
def async_reload_core_config(hass):
"""Reload the core config."""
yield from hass.services.async_call(ha.DOMAIN, SERVICE_RELOAD_CORE_CONFIG)
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass: ha.HomeAssistant, config: dict) -> Awaitable[bool]:
"""Set up general services related to Home Assistant."""
@asyncio.coroutine
def async_handle_turn_service(service):
async def async_handle_turn_service(service):
"""Handle calls to homeassistant.turn_on/off."""
entity_ids = extract_entity_ids(hass, service)
@@ -147,7 +96,7 @@ def async_setup(hass, config):
tasks.append(hass.services.async_call(
domain, service.service, data, blocking))
yield from asyncio.wait(tasks, loop=hass.loop)
await asyncio.wait(tasks, loop=hass.loop)
hass.services.async_register(
ha.DOMAIN, SERVICE_TURN_OFF, async_handle_turn_service)
@@ -163,15 +112,14 @@ def async_setup(hass, config):
hass.helpers.intent.async_register(intent.ServiceIntentHandler(
intent.INTENT_TOGGLE, ha.DOMAIN, SERVICE_TOGGLE, "Toggled {}"))
@asyncio.coroutine
def async_handle_core_service(call):
async def async_handle_core_service(call):
"""Service handler for handling core services."""
if call.service == SERVICE_HOMEASSISTANT_STOP:
hass.async_add_job(hass.async_stop())
hass.async_create_task(hass.async_stop())
return
try:
errors = yield from conf_util.async_check_ha_config_file(hass)
errors = await conf_util.async_check_ha_config_file(hass)
except HomeAssistantError:
return
@@ -183,7 +131,7 @@ def async_setup(hass, config):
return
if call.service == SERVICE_HOMEASSISTANT_RESTART:
hass.async_add_job(hass.async_stop(RESTART_EXIT_CODE))
hass.async_create_task(hass.async_stop(RESTART_EXIT_CODE))
hass.services.async_register(
ha.DOMAIN, SERVICE_HOMEASSISTANT_STOP, async_handle_core_service)
@@ -192,16 +140,15 @@ def async_setup(hass, config):
hass.services.async_register(
ha.DOMAIN, SERVICE_CHECK_CONFIG, async_handle_core_service)
@asyncio.coroutine
def async_handle_reload_config(call):
async def async_handle_reload_config(call):
"""Service handler for reloading core config."""
try:
conf = yield from conf_util.async_hass_config_yaml(hass)
conf = await conf_util.async_hass_config_yaml(hass)
except HomeAssistantError as err:
_LOGGER.error(err)
return
yield from conf_util.async_process_ha_core_config(
await conf_util.async_process_ha_core_config(
hass, conf.get(ha.DOMAIN) or {})
hass.services.async_register(

View File

@@ -4,7 +4,6 @@ This component provides basic support for Abode Home Security system.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/abode/
"""
import asyncio
import logging
from functools import partial
from requests.exceptions import HTTPError, ConnectTimeout
@@ -19,7 +18,7 @@ from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import discovery
from homeassistant.helpers.entity import Entity
REQUIREMENTS = ['abodepy==0.12.3']
REQUIREMENTS = ['abodepy==0.13.1']
_LOGGER = logging.getLogger(__name__)
@@ -27,6 +26,7 @@ CONF_ATTRIBUTION = "Data provided by goabode.com"
CONF_POLLING = 'polling'
DOMAIN = 'abode'
DEFAULT_CACHEDB = './abodepy_cache.pickle'
NOTIFICATION_ID = 'abode_notification'
NOTIFICATION_TITLE = 'Abode Security Setup'
@@ -80,19 +80,20 @@ TRIGGER_SCHEMA = vol.Schema({
ABODE_PLATFORMS = [
'alarm_control_panel', 'binary_sensor', 'lock', 'switch', 'cover',
'camera', 'light'
'camera', 'light', 'sensor'
]
class AbodeSystem(object):
class AbodeSystem:
"""Abode System class."""
def __init__(self, username, password, name, polling, exclude, lights):
def __init__(self, username, password, cache,
name, polling, exclude, lights):
"""Initialize the system."""
import abodepy
self.abode = abodepy.Abode(
username, password, auto_login=True, get_devices=True,
get_automations=True)
get_automations=True, cache_path=cache)
self.name = name
self.polling = polling
self.exclude = exclude
@@ -129,8 +130,9 @@ def setup(hass, config):
lights = conf.get(CONF_LIGHTS)
try:
cache = hass.config.path(DEFAULT_CACHEDB)
hass.data[DOMAIN] = AbodeSystem(
username, password, name, polling, exclude, lights)
username, password, cache, name, polling, exclude, lights)
except (AbodeException, ConnectTimeout, HTTPError) as ex:
_LOGGER.error("Unable to connect to Abode: %s", str(ex))
@@ -258,8 +260,7 @@ class AbodeDevice(Entity):
self._data = data
self._device = device
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Subscribe Abode events."""
self.hass.async_add_job(
self._data.abode.events.add_device_callback,
@@ -305,8 +306,7 @@ class AbodeAutomation(Entity):
self._automation = automation
self._event = event
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Subscribe Abode events."""
if self._event:
self.hass.async_add_job(

View File

@@ -110,7 +110,7 @@ NotificationItem = namedtuple(
)
class AdsHub(object):
class AdsHub:
"""Representation of an ADS connection."""
def __init__(self, ads_client):

View File

@@ -4,7 +4,6 @@ Component to interface with an alarm control panel.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel/
"""
import asyncio
from datetime import timedelta
import logging
@@ -14,7 +13,6 @@ from homeassistant.const import (
ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, SERVICE_ALARM_TRIGGER,
SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY,
SERVICE_ALARM_ARM_NIGHT, SERVICE_ALARM_ARM_CUSTOM_BYPASS)
from homeassistant.loader import bind_hass
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
@@ -26,134 +24,57 @@ ATTR_CHANGED_BY = 'changed_by'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
SERVICE_TO_METHOD = {
SERVICE_ALARM_DISARM: 'alarm_disarm',
SERVICE_ALARM_ARM_HOME: 'alarm_arm_home',
SERVICE_ALARM_ARM_AWAY: 'alarm_arm_away',
SERVICE_ALARM_ARM_NIGHT: 'alarm_arm_night',
SERVICE_ALARM_ARM_CUSTOM_BYPASS: 'alarm_arm_custom_bypass',
SERVICE_ALARM_TRIGGER: 'alarm_trigger'
}
ATTR_TO_PROPERTY = [
ATTR_CODE,
ATTR_CODE_FORMAT
]
ALARM_SERVICE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
vol.Optional(ATTR_CODE): cv.string,
})
@bind_hass
def alarm_disarm(hass, code=None, entity_id=None):
"""Send the alarm the command for disarm."""
data = {}
if code:
data[ATTR_CODE] = code
if entity_id:
data[ATTR_ENTITY_ID] = entity_id
hass.services.call(DOMAIN, SERVICE_ALARM_DISARM, data)
@bind_hass
def alarm_arm_home(hass, code=None, entity_id=None):
"""Send the alarm the command for arm home."""
data = {}
if code:
data[ATTR_CODE] = code
if entity_id:
data[ATTR_ENTITY_ID] = entity_id
hass.services.call(DOMAIN, SERVICE_ALARM_ARM_HOME, data)
@bind_hass
def alarm_arm_away(hass, code=None, entity_id=None):
"""Send the alarm the command for arm away."""
data = {}
if code:
data[ATTR_CODE] = code
if entity_id:
data[ATTR_ENTITY_ID] = entity_id
hass.services.call(DOMAIN, SERVICE_ALARM_ARM_AWAY, data)
@bind_hass
def alarm_arm_night(hass, code=None, entity_id=None):
"""Send the alarm the command for arm night."""
data = {}
if code:
data[ATTR_CODE] = code
if entity_id:
data[ATTR_ENTITY_ID] = entity_id
hass.services.call(DOMAIN, SERVICE_ALARM_ARM_NIGHT, data)
@bind_hass
def alarm_trigger(hass, code=None, entity_id=None):
"""Send the alarm the command for trigger."""
data = {}
if code:
data[ATTR_CODE] = code
if entity_id:
data[ATTR_ENTITY_ID] = entity_id
hass.services.call(DOMAIN, SERVICE_ALARM_TRIGGER, data)
@bind_hass
def alarm_arm_custom_bypass(hass, code=None, entity_id=None):
"""Send the alarm the command for arm custom bypass."""
data = {}
if code:
data[ATTR_CODE] = code
if entity_id:
data[ATTR_ENTITY_ID] = entity_id
hass.services.call(DOMAIN, SERVICE_ALARM_ARM_CUSTOM_BYPASS, data)
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Track states and offer events for sensors."""
component = EntityComponent(
component = hass.data[DOMAIN] = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
yield from component.async_setup(config)
await component.async_setup(config)
@asyncio.coroutine
def async_alarm_service_handler(service):
"""Map services to methods on Alarm."""
target_alarms = component.async_extract_from_service(service)
code = service.data.get(ATTR_CODE)
method = "async_{}".format(SERVICE_TO_METHOD[service.service])
update_tasks = []
for alarm in target_alarms:
yield from getattr(alarm, method)(code)
if not alarm.should_poll:
continue
update_tasks.append(alarm.async_update_ha_state(True))
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
for service in SERVICE_TO_METHOD:
hass.services.async_register(
DOMAIN, service, async_alarm_service_handler,
schema=ALARM_SERVICE_SCHEMA)
component.async_register_entity_service(
SERVICE_ALARM_DISARM, ALARM_SERVICE_SCHEMA,
'async_alarm_disarm'
)
component.async_register_entity_service(
SERVICE_ALARM_ARM_HOME, ALARM_SERVICE_SCHEMA,
'async_alarm_arm_home'
)
component.async_register_entity_service(
SERVICE_ALARM_ARM_AWAY, ALARM_SERVICE_SCHEMA,
'async_alarm_arm_away'
)
component.async_register_entity_service(
SERVICE_ALARM_ARM_NIGHT, ALARM_SERVICE_SCHEMA,
'async_alarm_arm_night'
)
component.async_register_entity_service(
SERVICE_ALARM_ARM_CUSTOM_BYPASS, ALARM_SERVICE_SCHEMA,
'async_alarm_arm_custom_bypass'
)
component.async_register_entity_service(
SERVICE_ALARM_TRIGGER, ALARM_SERVICE_SCHEMA,
'async_alarm_trigger'
)
return True
async def async_setup_entry(hass, entry):
"""Set up a config entry."""
return await hass.data[DOMAIN].async_setup_entry(entry)
async def async_unload_entry(hass, entry):
"""Unload a config entry."""
return await hass.data[DOMAIN].async_unload_entry(entry)
# pylint: disable=no-self-use
class AlarmControlPanel(Entity):
"""An abstract class for alarm control devices."""
@@ -177,7 +98,7 @@ class AlarmControlPanel(Entity):
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_job(self.alarm_disarm, code)
return self.hass.async_add_executor_job(self.alarm_disarm, code)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
@@ -188,7 +109,7 @@ class AlarmControlPanel(Entity):
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_job(self.alarm_arm_home, code)
return self.hass.async_add_executor_job(self.alarm_arm_home, code)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
@@ -199,7 +120,7 @@ class AlarmControlPanel(Entity):
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_job(self.alarm_arm_away, code)
return self.hass.async_add_executor_job(self.alarm_arm_away, code)
def alarm_arm_night(self, code=None):
"""Send arm night command."""
@@ -210,7 +131,7 @@ class AlarmControlPanel(Entity):
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_job(self.alarm_arm_night, code)
return self.hass.async_add_executor_job(self.alarm_arm_night, code)
def alarm_trigger(self, code=None):
"""Send alarm trigger command."""
@@ -221,7 +142,7 @@ class AlarmControlPanel(Entity):
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_job(self.alarm_trigger, code)
return self.hass.async_add_executor_job(self.alarm_trigger, code)
def alarm_arm_custom_bypass(self, code=None):
"""Send arm custom bypass command."""
@@ -232,7 +153,8 @@ class AlarmControlPanel(Entity):
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_job(self.alarm_arm_custom_bypass, code)
return self.hass.async_add_executor_job(
self.alarm_arm_custom_bypass, code)
@property
def state_attributes(self):

View File

@@ -20,7 +20,7 @@ _LOGGER = logging.getLogger(__name__)
ICON = 'mdi:security'
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up an alarm control panel for an Abode device."""
data = hass.data[ABODE_DOMAIN]
@@ -28,7 +28,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
data.devices.extend(alarm_devices)
add_devices(alarm_devices)
add_entities(alarm_devices)
class AbodeAlarm(AbodeDevice, AlarmControlPanel):

View File

@@ -4,7 +4,6 @@ Support for AlarmDecoder-based alarm control panels (Honeywell/DSC).
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.alarmdecoder/
"""
import asyncio
import logging
import voluptuous as vol
@@ -26,10 +25,10 @@ ALARM_TOGGLE_CHIME_SCHEMA = vol.Schema({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up for AlarmDecoder alarm panels."""
device = AlarmDecoderAlarmPanel()
add_devices([device])
add_entities([device])
def alarm_toggle_chime_handler(service):
"""Register toggle chime handler."""
@@ -59,8 +58,7 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
self._ready = None
self._zone_bypassed = None
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Register callbacks."""
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_PANEL_MESSAGE, self._message_callback)
@@ -100,8 +98,8 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return the regex for code format or None if no code is required."""
return '^\\d{4,6}$'
"""Return one or more digits/characters."""
return 'Number'
@property
def state(self):

View File

@@ -4,8 +4,8 @@ Interfaces with Alarm.com alarm control panels.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.alarmdotcom/
"""
import asyncio
import logging
import re
import voluptuous as vol
@@ -17,7 +17,7 @@ from homeassistant.const import (
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyalarmdotcom==0.3.1']
REQUIREMENTS = ['pyalarmdotcom==0.3.2']
_LOGGER = logging.getLogger(__name__)
@@ -31,8 +31,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up a Alarm.com control panel."""
name = config.get(CONF_NAME)
code = config.get(CONF_CODE)
@@ -40,8 +40,8 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
password = config.get(CONF_PASSWORD)
alarmdotcom = AlarmDotCom(hass, name, code, username, password)
yield from alarmdotcom.async_login()
async_add_devices([alarmdotcom])
await alarmdotcom.async_login()
async_add_entities([alarmdotcom])
class AlarmDotCom(alarm.AlarmControlPanel):
@@ -61,15 +61,13 @@ class AlarmDotCom(alarm.AlarmControlPanel):
self._alarm = Alarmdotcom(
username, password, self._websession, hass.loop)
@asyncio.coroutine
def async_login(self):
async def async_login(self):
"""Login to Alarm.com."""
yield from self._alarm.async_login()
await self._alarm.async_login()
@asyncio.coroutine
def async_update(self):
async def async_update(self):
"""Fetch the latest state."""
yield from self._alarm.async_update()
await self._alarm.async_update()
return self._alarm.state
@property
@@ -79,37 +77,45 @@ class AlarmDotCom(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return one or more characters if code is defined."""
return None if self._code is None else '.+'
"""Return one or more digits/characters."""
if self._code is None:
return None
if isinstance(self._code, str) and re.search('^\\d+$', self._code):
return 'Number'
return 'Any'
@property
def state(self):
"""Return the state of the device."""
if self._alarm.state.lower() == 'disarmed':
return STATE_ALARM_DISARMED
elif self._alarm.state.lower() == 'armed stay':
if self._alarm.state.lower() == 'armed stay':
return STATE_ALARM_ARMED_HOME
elif self._alarm.state.lower() == 'armed away':
if self._alarm.state.lower() == 'armed away':
return STATE_ALARM_ARMED_AWAY
return STATE_UNKNOWN
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'sensor_status': self._alarm.sensor_status
}
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
if self._validate_code(code):
yield from self._alarm.async_alarm_disarm()
await self._alarm.async_alarm_disarm()
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
async def async_alarm_arm_home(self, code=None):
"""Send arm hom command."""
if self._validate_code(code):
yield from self._alarm.async_alarm_arm_home()
await self._alarm.async_alarm_arm_home()
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
if self._validate_code(code):
yield from self._alarm.async_alarm_arm_away()
await self._alarm.async_alarm_arm_away()
def _validate_code(self, code):
"""Validate given code."""

View File

@@ -4,15 +4,17 @@ Support for Arlo Alarm Control Panels.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.arlo/
"""
import asyncio
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.components.alarm_control_panel import (
AlarmControlPanel, PLATFORM_SCHEMA)
from homeassistant.components.arlo import (DATA_ARLO, CONF_ATTRIBUTION)
from homeassistant.components.arlo import (
DATA_ARLO, CONF_ATTRIBUTION, SIGNAL_UPDATE_ARLO)
from homeassistant.const import (
ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED)
@@ -36,21 +38,20 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Arlo Alarm Control Panels."""
data = hass.data[DATA_ARLO]
arlo = hass.data[DATA_ARLO]
if not data.base_stations:
if not arlo.base_stations:
return
home_mode_name = config.get(CONF_HOME_MODE_NAME)
away_mode_name = config.get(CONF_AWAY_MODE_NAME)
base_stations = []
for base_station in data.base_stations:
for base_station in arlo.base_stations:
base_stations.append(ArloBaseStation(base_station, home_mode_name,
away_mode_name))
async_add_devices(base_stations, True)
add_entities(base_stations, True)
class ArloBaseStation(AlarmControlPanel):
@@ -68,6 +69,16 @@ class ArloBaseStation(AlarmControlPanel):
"""Return icon."""
return ICON
async def async_added_to_hass(self):
"""Register callbacks."""
async_dispatcher_connect(
self.hass, SIGNAL_UPDATE_ARLO, self._update_callback)
@callback
def _update_callback(self):
"""Call update method."""
self.async_schedule_update_ha_state(True)
@property
def state(self):
"""Return the state of the device."""
@@ -75,30 +86,22 @@ class ArloBaseStation(AlarmControlPanel):
def update(self):
"""Update the state of the device."""
# PyArlo sometimes returns None for mode. So retry 3 times before
# returning None.
num_retries = 3
i = 0
while i < num_retries:
mode = self._base_station.mode
if mode:
self._state = self._get_state_from_mode(mode)
return
i += 1
self._state = None
_LOGGER.debug("Updating Arlo Alarm Control Panel %s", self.name)
mode = self._base_station.mode
if mode:
self._state = self._get_state_from_mode(mode)
else:
self._state = None
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
self._base_station.mode = DISARMED
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
async def async_alarm_arm_away(self, code=None):
"""Send arm away command. Uses custom mode."""
self._base_station.mode = self._away_mode_name
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
async def async_alarm_arm_home(self, code=None):
"""Send arm home command. Uses custom mode."""
self._base_station.mode = self._home_mode_name
@@ -119,10 +122,10 @@ class ArloBaseStation(AlarmControlPanel):
"""Convert Arlo mode to Home Assistant state."""
if mode == ARMED:
return STATE_ALARM_ARMED_AWAY
elif mode == DISARMED:
if mode == DISARMED:
return STATE_ALARM_DISARMED
elif mode == self._home_mode_name:
if mode == self._home_mode_name:
return STATE_ALARM_ARMED_HOME
elif mode == self._away_mode_name:
if mode == self._away_mode_name:
return STATE_ALARM_ARMED_AWAY
return None
return mode

View File

@@ -0,0 +1,92 @@
"""
Support for Blink Alarm Control Panel.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.blink/
"""
import logging
from homeassistant.components.alarm_control_panel import AlarmControlPanel
from homeassistant.components.blink import (
BLINK_DATA, DEFAULT_ATTRIBUTION)
from homeassistant.const import (
ATTR_ATTRIBUTION, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_AWAY)
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['blink']
ICON = 'mdi:security'
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Arlo Alarm Control Panels."""
if discovery_info is None:
return
data = hass.data[BLINK_DATA]
# Current version of blinkpy API only supports one sync module. When
# support for additional models is added, the sync module name should
# come from the API.
sync_modules = []
sync_modules.append(BlinkSyncModule(data, 'sync'))
add_entities(sync_modules, True)
class BlinkSyncModule(AlarmControlPanel):
"""Representation of a Blink Alarm Control Panel."""
def __init__(self, data, name):
"""Initialize the alarm control panel."""
self.data = data
self.sync = data.sync
self._name = name
self._state = None
@property
def unique_id(self):
"""Return the unique id for the sync module."""
return self.sync.serial
@property
def icon(self):
"""Return icon."""
return ICON
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def name(self):
"""Return the name of the panel."""
return "{} {}".format(BLINK_DATA, self._name)
@property
def device_state_attributes(self):
"""Return the state attributes."""
attr = self.sync.attributes
attr['network_info'] = self.data.networks
attr[ATTR_ATTRIBUTION] = DEFAULT_ATTRIBUTION
return attr
def update(self):
"""Update the state of the device."""
_LOGGER.debug("Updating Blink Alarm Control Panel %s", self._name)
self.data.refresh()
mode = self.sync.arm
if mode:
self._state = STATE_ALARM_ARMED_AWAY
else:
self._state = STATE_ALARM_DISARMED
def alarm_disarm(self, code=None):
"""Send disarm command."""
self.sync.arm = False
self.sync.refresh()
def alarm_arm_away(self, code=None):
"""Send arm command."""
self.sync.arm = True
self.sync.refresh()

View File

@@ -16,7 +16,7 @@ DEPENDENCIES = ['canary']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Canary alarms."""
data = hass.data[DATA_CANARY]
devices = []
@@ -24,7 +24,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
for location in data.locations:
devices.append(CanaryAlarm(data, location.location_id))
add_devices(devices, True)
add_entities(devices, True)
class CanaryAlarm(AlarmControlPanel):
@@ -55,9 +55,9 @@ class CanaryAlarm(AlarmControlPanel):
mode = location.mode
if mode.name == LOCATION_MODE_AWAY:
return STATE_ALARM_ARMED_AWAY
elif mode.name == LOCATION_MODE_HOME:
if mode.name == LOCATION_MODE_HOME:
return STATE_ALARM_ARMED_HOME
elif mode.name == LOCATION_MODE_NIGHT:
if mode.name == LOCATION_MODE_NIGHT:
return STATE_ALARM_ARMED_NIGHT
return None

View File

@@ -35,7 +35,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Concord232 alarm control panel platform."""
name = config.get(CONF_NAME)
host = config.get(CONF_HOST)
@@ -44,7 +44,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
url = 'http://{}:{}'.format(host, port)
try:
add_devices([Concord232Alarm(hass, url, name)])
add_entities([Concord232Alarm(hass, url, name)])
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to Concord232: %s", str(ex))
return
@@ -80,7 +80,7 @@ class Concord232Alarm(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return the characters if code is defined."""
return '[0-9]{4}([0-9]{2})?'
return 'Number'
@property
def state(self):

View File

@@ -5,7 +5,7 @@ For more details about this platform, please refer to the documentation
https://home-assistant.io/components/demo/
"""
import datetime
import homeassistant.components.alarm_control_panel.manual as manual
from homeassistant.components.alarm_control_panel import manual
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_CUSTOM_BYPASS,
STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT,
@@ -13,9 +13,9 @@ from homeassistant.const import (
CONF_PENDING_TIME, CONF_TRIGGER_TIME)
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Demo alarm control panel platform."""
add_devices([
add_entities([
manual.ManualAlarm(hass, 'Alarm', '1234', None, False, {
STATE_ALARM_ARMED_AWAY: {
CONF_DELAY_TIME: datetime.timedelta(seconds=0),

View File

@@ -4,7 +4,6 @@ Interfaces with Egardia/Woonveilig alarm control panel.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.egardia/
"""
import asyncio
import logging
import requests
@@ -34,7 +33,7 @@ STATES = {
}
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Egardia platform."""
if discovery_info is None:
return
@@ -45,7 +44,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
discovery_info.get(CONF_REPORT_SERVER_CODES),
discovery_info[CONF_REPORT_SERVER_PORT])
# add egardia alarm device
add_devices([device], True)
add_entities([device], True)
class EgardiaAlarm(alarm.AlarmControlPanel):
@@ -61,8 +60,7 @@ class EgardiaAlarm(alarm.AlarmControlPanel):
self._rs_codes = rs_codes
self._rs_port = rs_port
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Add Egardiaserver callback if enabled."""
if self._rs_enabled:
_LOGGER.debug("Registering callback to Egardiaserver")

View File

@@ -4,7 +4,6 @@ Support for Envisalink-based alarm control panels (Honeywell/DSC).
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.envisalink/
"""
import asyncio
import logging
import voluptuous as vol
@@ -32,8 +31,8 @@ ALARM_KEYPRESS_SCHEMA = vol.Schema({
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Perform the setup for Envisalink alarm panels."""
configured_partitions = discovery_info['partitions']
code = discovery_info[CONF_CODE]
@@ -53,7 +52,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
)
devices.append(device)
async_add_devices(devices)
async_add_entities(devices)
@callback
def alarm_keypress_handler(service):
@@ -87,8 +86,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
_LOGGER.debug("Setting up alarm: %s", alarm_name)
super().__init__(alarm_name, info, controller)
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Register callbacks."""
async_dispatcher_connect(
self.hass, SIGNAL_KEYPAD_UPDATE, self._update_callback)
@@ -106,7 +104,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
"""Regex for code format or None if no code is required."""
if self._code:
return None
return '^\\d{4,6}$'
return 'Number'
@property
def state(self):
@@ -127,8 +125,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
state = STATE_ALARM_DISARMED
return state
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
if code:
self.hass.data[DATA_EVL].disarm_partition(
@@ -137,8 +134,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
self.hass.data[DATA_EVL].disarm_partition(
str(self._code), self._partition_number)
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
if code:
self.hass.data[DATA_EVL].arm_stay_partition(
@@ -147,8 +143,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
self.hass.data[DATA_EVL].arm_stay_partition(
str(self._code), self._partition_number)
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
if code:
self.hass.data[DATA_EVL].arm_away_partition(
@@ -157,8 +152,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
self.hass.data[DATA_EVL].arm_away_partition(
str(self._code), self._partition_number)
@asyncio.coroutine
def async_alarm_trigger(self, code=None):
async def async_alarm_trigger(self, code=None):
"""Alarm trigger command. Will be used to trigger a panic alarm."""
self.hass.data[DATA_EVL].panic_alarm(self._panic_type)

View File

@@ -0,0 +1,83 @@
"""
Support for HomematicIP Cloud alarm control panel.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.homematicip_cloud/
"""
import logging
from homeassistant.components.alarm_control_panel import AlarmControlPanel
from homeassistant.components.homematicip_cloud import (
HMIPC_HAPID, HomematicipGenericDevice)
from homeassistant.components.homematicip_cloud import DOMAIN as HMIPC_DOMAIN
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED)
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['homematicip_cloud']
HMIP_ZONE_AWAY = 'EXTERNAL'
HMIP_ZONE_HOME = 'INTERNAL'
async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None):
"""Set up the HomematicIP Cloud alarm control devices."""
pass
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the HomematicIP alarm control panel from a config entry."""
from homematicip.aio.group import AsyncSecurityZoneGroup
home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = []
for group in home.groups:
if isinstance(group, AsyncSecurityZoneGroup):
devices.append(HomematicipSecurityZone(home, group))
if devices:
async_add_entities(devices)
class HomematicipSecurityZone(HomematicipGenericDevice, AlarmControlPanel):
"""Representation of an HomematicIP Cloud security zone group."""
def __init__(self, home, device):
"""Initialize the security zone group."""
device.modelType = 'Group-SecurityZone'
device.windowState = ''
super().__init__(home, device)
@property
def state(self):
"""Return the state of the device."""
from homematicip.base.enums import WindowState
if self._device.active:
if (self._device.sabotage or self._device.motionDetected or
self._device.windowState == WindowState.OPEN):
return STATE_ALARM_TRIGGERED
active = self._home.get_security_zones_activation()
if active == (True, True):
return STATE_ALARM_ARMED_AWAY
if active == (False, True):
return STATE_ALARM_ARMED_HOME
return STATE_ALARM_DISARMED
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
await self._home.set_security_zones_activation(False, False)
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
await self._home.set_security_zones_activation(True, False)
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
await self._home.set_security_zones_activation(True, True)

View File

@@ -40,7 +40,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up an iAlarm control panel."""
name = config.get(CONF_NAME)
username = config.get(CONF_USERNAME)
@@ -49,7 +49,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
url = 'http://{}'.format(host)
ialarm = IAlarmPanel(name, username, password, url)
add_devices([ialarm], True)
add_entities([ialarm], True)
class IAlarmPanel(alarm.AlarmControlPanel):

View File

@@ -5,6 +5,7 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.ifttt/
"""
import logging
import re
import voluptuous as vol
@@ -58,7 +59,7 @@ PUSH_ALARM_STATE_SERVICE_SCHEMA = vol.Schema({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up a control panel managed through IFTTT."""
if DATA_IFTTT_ALARM not in hass.data:
hass.data[DATA_IFTTT_ALARM] = []
@@ -74,7 +75,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
alarmpanel = IFTTTAlarmPanel(name, code, event_away, event_home,
event_night, event_disarm, optimistic)
hass.data[DATA_IFTTT_ALARM].append(alarmpanel)
add_devices([alarmpanel])
add_entities([alarmpanel])
async def push_state_update(service):
"""Set the service state as device state attribute."""
@@ -124,8 +125,12 @@ class IFTTTAlarmPanel(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return one or more characters."""
return None if self._code is None else '.+'
"""Return one or more digits/characters."""
if self._code is None:
return None
if isinstance(self._code, str) and re.search('^\\d+$', self._code):
return 'Number'
return 'Any'
def alarm_disarm(self, code=None):
"""Send disarm command."""

View File

@@ -7,6 +7,7 @@ https://home-assistant.io/components/alarm_control_panel.manual/
import copy
import datetime
import logging
import re
import voluptuous as vol
@@ -102,9 +103,9 @@ PLATFORM_SCHEMA = vol.Schema(vol.All({
}, _state_validator))
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the manual alarm platform."""
add_devices([ManualAlarm(
add_entities([ManualAlarm(
hass,
config[CONF_NAME],
config.get(CONF_CODE),
@@ -201,8 +202,12 @@ class ManualAlarm(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return one or more characters."""
return None if self._code is None else '.+'
"""Return one or more digits/characters."""
if self._code is None:
return None
if isinstance(self._code, str) and re.search('^\\d+$', self._code):
return 'Number'
return 'Any'
def alarm_disarm(self, code=None):
"""Send disarm command."""

View File

@@ -4,10 +4,10 @@ Support for manual alarms controllable via MQTT.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.manual_mqtt/
"""
import asyncio
import copy
import datetime
import logging
import re
import voluptuous as vol
@@ -18,7 +18,7 @@ from homeassistant.const import (
STATE_ALARM_DISARMED, STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED,
CONF_PLATFORM, CONF_NAME, CONF_CODE, CONF_DELAY_TIME, CONF_PENDING_TIME,
CONF_TRIGGER_TIME, CONF_DISARM_AFTER_TRIGGER)
import homeassistant.components.mqtt as mqtt
from homeassistant.components import mqtt
from homeassistant.helpers.event import async_track_state_change
from homeassistant.core import callback
@@ -122,9 +122,9 @@ PLATFORM_SCHEMA = vol.Schema(vol.All(mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
}), _state_validator))
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the manual MQTT alarm platform."""
add_devices([ManualMQTTAlarm(
add_entities([ManualMQTTAlarm(
hass,
config[CONF_NAME],
config.get(CONF_CODE),
@@ -237,8 +237,12 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return one or more characters."""
return None if self._code is None else '.+'
"""Return one or more digits/characters."""
if self._code is None:
return None
if isinstance(self._code, str) and re.search('^\\d+$', self._code):
return 'Number'
return 'Any'
def alarm_disarm(self, code=None):
"""Send disarm command."""
@@ -358,8 +362,8 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
return mqtt.async_subscribe(
self.hass, self._command_topic, message_received, self._qos)
@asyncio.coroutine
def _async_state_changed_listener(self, entity_id, old_state, new_state):
async def _async_state_changed_listener(self, entity_id, old_state,
new_state):
"""Publish state change to MQTT."""
mqtt.async_publish(
self.hass, self._state_topic, new_state.state, self._qos, True)

View File

@@ -4,23 +4,26 @@ This platform enables the possibility to control a MQTT alarm.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.mqtt/
"""
import asyncio
import logging
import re
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.components.alarm_control_panel as alarm
import homeassistant.components.mqtt as mqtt
from homeassistant.components import mqtt
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, STATE_UNKNOWN,
CONF_NAME, CONF_CODE)
from homeassistant.components.mqtt import (
CONF_AVAILABILITY_TOPIC, CONF_STATE_TOPIC, CONF_COMMAND_TOPIC,
CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_QOS,
MqttAvailability)
ATTR_DISCOVERY_HASH, CONF_AVAILABILITY_TOPIC, CONF_STATE_TOPIC,
CONF_COMMAND_TOPIC, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE,
CONF_QOS, CONF_RETAIN, MqttAvailability, MqttDiscoveryUpdate)
from homeassistant.components.mqtt.discovery import MQTT_DISCOVERY_NEW
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.typing import HomeAssistantType, ConfigType
_LOGGER = logging.getLogger(__name__)
@@ -45,46 +48,72 @@ PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
}).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema)
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
async def async_setup_platform(hass: HomeAssistantType, config: ConfigType,
async_add_entities, discovery_info=None):
"""Set up MQTT alarm control panel through configuration.yaml."""
await _async_setup_entity(hass, config, async_add_entities)
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up MQTT alarm control panel dynamically through MQTT discovery."""
async def async_discover(discovery_payload):
"""Discover and add an MQTT alarm control panel."""
config = PLATFORM_SCHEMA(discovery_payload)
await _async_setup_entity(hass, config, async_add_entities,
discovery_payload[ATTR_DISCOVERY_HASH])
async_dispatcher_connect(
hass, MQTT_DISCOVERY_NEW.format(alarm.DOMAIN, 'mqtt'),
async_discover)
async def _async_setup_entity(hass, config, async_add_entities,
discovery_hash=None):
"""Set up the MQTT Alarm Control Panel platform."""
async_add_devices([MqttAlarm(
async_add_entities([MqttAlarm(
config.get(CONF_NAME),
config.get(CONF_STATE_TOPIC),
config.get(CONF_COMMAND_TOPIC),
config.get(CONF_QOS),
config.get(CONF_RETAIN),
config.get(CONF_PAYLOAD_DISARM),
config.get(CONF_PAYLOAD_ARM_HOME),
config.get(CONF_PAYLOAD_ARM_AWAY),
config.get(CONF_CODE),
config.get(CONF_AVAILABILITY_TOPIC),
config.get(CONF_PAYLOAD_AVAILABLE),
config.get(CONF_PAYLOAD_NOT_AVAILABLE))])
config.get(CONF_PAYLOAD_NOT_AVAILABLE),
discovery_hash,)])
class MqttAlarm(MqttAvailability, alarm.AlarmControlPanel):
class MqttAlarm(MqttAvailability, MqttDiscoveryUpdate,
alarm.AlarmControlPanel):
"""Representation of a MQTT alarm status."""
def __init__(self, name, state_topic, command_topic, qos, payload_disarm,
payload_arm_home, payload_arm_away, code, availability_topic,
payload_available, payload_not_available):
def __init__(self, name, state_topic, command_topic, qos, retain,
payload_disarm, payload_arm_home, payload_arm_away, code,
availability_topic, payload_available, payload_not_available,
discovery_hash):
"""Init the MQTT Alarm Control Panel."""
super().__init__(availability_topic, qos, payload_available,
payload_not_available)
MqttAvailability.__init__(self, availability_topic, qos,
payload_available, payload_not_available)
MqttDiscoveryUpdate.__init__(self, discovery_hash)
self._state = STATE_UNKNOWN
self._name = name
self._state_topic = state_topic
self._command_topic = command_topic
self._qos = qos
self._retain = retain
self._payload_disarm = payload_disarm
self._payload_arm_home = payload_arm_home
self._payload_arm_away = payload_arm_away
self._code = code
self._discovery_hash = discovery_hash
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Subscribe mqtt events."""
yield from super().async_added_to_hass()
await MqttAvailability.async_added_to_hass(self)
await MqttDiscoveryUpdate.async_added_to_hass(self)
@callback
def message_received(topic, payload, qos):
@@ -97,7 +126,7 @@ class MqttAlarm(MqttAvailability, alarm.AlarmControlPanel):
self._state = payload
self.async_schedule_update_ha_state()
yield from mqtt.async_subscribe(
await mqtt.async_subscribe(
self.hass, self._state_topic, message_received, self._qos)
@property
@@ -117,11 +146,14 @@ class MqttAlarm(MqttAvailability, alarm.AlarmControlPanel):
@property
def code_format(self):
"""One or more characters if code is defined."""
return None if self._code is None else '.+'
"""Return one or more digits/characters."""
if self._code is None:
return None
if isinstance(self._code, str) and re.search('^\\d+$', self._code):
return 'Number'
return 'Any'
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
async def async_alarm_disarm(self, code=None):
"""Send disarm command.
This method is a coroutine.
@@ -129,10 +161,10 @@ class MqttAlarm(MqttAvailability, alarm.AlarmControlPanel):
if not self._validate_code(code, 'disarming'):
return
mqtt.async_publish(
self.hass, self._command_topic, self._payload_disarm, self._qos)
self.hass, self._command_topic, self._payload_disarm, self._qos,
self._retain)
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
async def async_alarm_arm_home(self, code=None):
"""Send arm home command.
This method is a coroutine.
@@ -140,10 +172,10 @@ class MqttAlarm(MqttAvailability, alarm.AlarmControlPanel):
if not self._validate_code(code, 'arming home'):
return
mqtt.async_publish(
self.hass, self._command_topic, self._payload_arm_home, self._qos)
self.hass, self._command_topic, self._payload_arm_home, self._qos,
self._retain)
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
async def async_alarm_arm_away(self, code=None):
"""Send arm away command.
This method is a coroutine.
@@ -151,7 +183,8 @@ class MqttAlarm(MqttAvailability, alarm.AlarmControlPanel):
if not self._validate_code(code, 'arming away'):
return
mqtt.async_publish(
self.hass, self._command_topic, self._payload_arm_away, self._qos)
self.hass, self._command_topic, self._payload_arm_away, self._qos,
self._retain)
def _validate_code(self, code, state):
"""Validate given code."""

View File

@@ -31,7 +31,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the NX584 platform."""
name = config.get(CONF_NAME)
host = config.get(CONF_HOST)
@@ -40,7 +40,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
url = 'http://{}:{}'.format(host, port)
try:
add_devices([NX584Alarm(hass, url, name)])
add_entities([NX584Alarm(hass, url, name)])
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to NX584: %s", str(ex))
return False
@@ -69,8 +69,8 @@ class NX584Alarm(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return che characters if code is defined."""
return '[0-9]{4}([0-9]{2})?'
"""Return one or more digits/characters."""
return 'Number'
@property
def state(self):

View File

@@ -4,7 +4,6 @@ Support for Satel Integra alarm, using ETHM module: https://www.satel.pl/en/ .
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.satel_integra/
"""
import asyncio
import logging
import homeassistant.components.alarm_control_panel as alarm
@@ -18,15 +17,15 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['satel_integra']
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up for Satel Integra alarm panels."""
if not discovery_info:
return
device = SatelIntegraAlarmPanel(
"Alarm Panel", discovery_info.get(CONF_ARM_HOME_MODE))
async_add_devices([device])
async_add_entities([device])
class SatelIntegraAlarmPanel(alarm.AlarmControlPanel):
@@ -38,8 +37,7 @@ class SatelIntegraAlarmPanel(alarm.AlarmControlPanel):
self._state = None
self._arm_home_mode = arm_home_mode
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Register callbacks."""
async_dispatcher_connect(
self.hass, SIGNAL_PANEL_MESSAGE, self._message_callback)
@@ -66,28 +64,25 @@ class SatelIntegraAlarmPanel(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return the regex for code format or None if no code is required."""
return '^\\d{4,6}$'
return 'Number'
@property
def state(self):
"""Return the state of the device."""
return self._state
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
if code:
yield from self.hass.data[DATA_SATEL].disarm(code)
await self.hass.data[DATA_SATEL].disarm(code)
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
if code:
yield from self.hass.data[DATA_SATEL].arm(code)
await self.hass.data[DATA_SATEL].arm(code)
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
if code:
yield from self.hass.data[DATA_SATEL].arm(
await self.hass.data[DATA_SATEL].arm(
code, self._arm_home_mode)

View File

@@ -5,137 +5,121 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.simplisafe/
"""
import logging
import re
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.components.alarm_control_panel import (
PLATFORM_SCHEMA, AlarmControlPanel)
from homeassistant.const import (
CONF_CODE, CONF_NAME, CONF_PASSWORD, CONF_USERNAME,
EVENT_HOMEASSISTANT_STOP, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED, STATE_UNKNOWN)
import homeassistant.helpers.config_validation as cv
CONF_CODE, CONF_NAME, CONF_PASSWORD, CONF_USERNAME, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED)
from homeassistant.helpers import aiohttp_client, config_validation as cv
from homeassistant.util.json import load_json, save_json
REQUIREMENTS = ['simplisafe-python==1.0.5']
REQUIREMENTS = ['simplisafe-python==3.1.2']
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'SimpliSafe'
DOMAIN = 'simplisafe'
ATTR_ALARM_ACTIVE = "alarm_active"
ATTR_TEMPERATURE = "temperature"
NOTIFICATION_ID = 'simplisafe_notification'
NOTIFICATION_TITLE = 'SimpliSafe Setup'
DATA_FILE = '.simplisafe'
DEFAULT_NAME = 'SimpliSafe'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Optional(CONF_CODE): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_CODE): cv.string,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None):
"""Set up the SimpliSafe platform."""
from simplipy.api import SimpliSafeApiInterface, get_systems
from simplipy import API
from simplipy.errors import SimplipyError
username = config[CONF_USERNAME]
password = config[CONF_PASSWORD]
name = config.get(CONF_NAME)
code = config.get(CONF_CODE)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
simplisafe = SimpliSafeApiInterface()
status = simplisafe.set_credentials(username, password)
if status:
hass.data[DOMAIN] = simplisafe
locations = get_systems(simplisafe)
for location in locations:
add_devices([SimpliSafeAlarm(location, name, code)])
else:
message = 'Failed to log into SimpliSafe. Check credentials.'
_LOGGER.error(message)
hass.components.persistent_notification.create(
message,
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
websession = aiohttp_client.async_get_clientsession(hass)
def logout(event):
"""Logout of the SimpliSafe API."""
hass.data[DOMAIN].logout()
config_data = await hass.async_add_executor_job(
load_json, hass.config.path(DATA_FILE))
hass.bus.listen(EVENT_HOMEASSISTANT_STOP, logout)
try:
if config_data:
try:
simplisafe = await API.login_via_token(
config_data['refresh_token'], websession)
_LOGGER.debug('Logging in with refresh token')
except SimplipyError:
_LOGGER.info('Refresh token expired; attempting credentials')
simplisafe = await API.login_via_credentials(
username, password, websession)
else:
simplisafe = await API.login_via_credentials(
username, password, websession)
_LOGGER.debug('Logging in with credentials')
except SimplipyError as err:
_LOGGER.error("There was an error during setup: %s", err)
return
config_data = {'refresh_token': simplisafe.refresh_token}
await hass.async_add_executor_job(
save_json, hass.config.path(DATA_FILE), config_data)
systems = await simplisafe.get_systems()
async_add_entities(
[SimpliSafeAlarm(system, name, code) for system in systems], True)
class SimpliSafeAlarm(alarm.AlarmControlPanel):
class SimpliSafeAlarm(AlarmControlPanel):
"""Representation of a SimpliSafe alarm."""
def __init__(self, simplisafe, name, code):
def __init__(self, system, name, code):
"""Initialize the SimpliSafe alarm."""
self.simplisafe = simplisafe
self._name = name
self._attrs = {}
self._code = str(code) if code else None
self._name = name
self._system = system
self._state = None
@property
def unique_id(self):
"""Return the unique ID."""
return self._system.system_id
@property
def name(self):
"""Return the name of the device."""
if self._name is not None:
if self._name:
return self._name
return 'Alarm {}'.format(self.simplisafe.location_id())
return 'Alarm {}'.format(self._system.system_id)
@property
def code_format(self):
"""Return one or more characters if code is defined."""
return None if self._code is None else '.+'
"""Return one or more digits/characters."""
if not self._code:
return None
if isinstance(self._code, str) and re.search('^\\d+$', self._code):
return 'Number'
return 'Any'
@property
def state(self):
"""Return the state of the device."""
status = self.simplisafe.state()
if status == 'off':
state = STATE_ALARM_DISARMED
elif status == 'home':
state = STATE_ALARM_ARMED_HOME
elif status == 'away':
state = STATE_ALARM_ARMED_AWAY
else:
state = STATE_UNKNOWN
return state
return self._state
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'alarm': self.simplisafe.alarm(),
'co': self.simplisafe.carbon_monoxide(),
'fire': self.simplisafe.fire(),
'flood': self.simplisafe.flood(),
'last_event': self.simplisafe.last_event(),
'temperature': self.simplisafe.temperature(),
}
def update(self):
"""Update alarm status."""
self.simplisafe.update()
def alarm_disarm(self, code=None):
"""Send disarm command."""
if not self._validate_code(code, 'disarming'):
return
self.simplisafe.set_state('off')
_LOGGER.info("SimpliSafe alarm disarming")
def alarm_arm_home(self, code=None):
"""Send arm home command."""
if not self._validate_code(code, 'arming home'):
return
self.simplisafe.set_state('home')
_LOGGER.info("SimpliSafe alarm arming home")
def alarm_arm_away(self, code=None):
"""Send arm away command."""
if not self._validate_code(code, 'arming away'):
return
self.simplisafe.set_state('away')
_LOGGER.info("SimpliSafe alarm arming away")
return self._attrs
def _validate_code(self, code, state):
"""Validate given code."""
@@ -143,3 +127,46 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
if not check:
_LOGGER.warning("Wrong code entered for %s", state)
return check
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
if not self._validate_code(code, 'disarming'):
return
await self._system.set_off()
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
if not self._validate_code(code, 'arming home'):
return
await self._system.set_home()
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
if not self._validate_code(code, 'arming away'):
return
await self._system.set_away()
async def async_update(self):
"""Update alarm status."""
await self._system.update()
if self._system.state == self._system.SystemStates.off:
self._state = STATE_ALARM_DISARMED
elif self._system.state in (
self._system.SystemStates.home,
self._system.SystemStates.home_count):
self._state = STATE_ALARM_ARMED_HOME
elif self._system.state in (
self._system.SystemStates.away,
self._system.SystemStates.away_count,
self._system.SystemStates.exit_delay):
self._state = STATE_ALARM_ARMED_AWAY
else:
self._state = None
self._attrs[ATTR_ALARM_ACTIVE] = self._system.alarm_going_off
if self._system.temperature:
self._attrs[ATTR_TEMPERATURE] = self._system.temperature

View File

@@ -4,70 +4,63 @@ Support for Vanderbilt (formerly Siemens) SPC alarm systems.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.spc/
"""
import asyncio
import logging
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.spc import (
ATTR_DISCOVER_AREAS, DATA_API, DATA_REGISTRY, SpcWebGateway)
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.core import callback
from homeassistant.components.spc import (DATA_API, SIGNAL_UPDATE_ALARM)
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_UNKNOWN)
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED)
_LOGGER = logging.getLogger(__name__)
SPC_AREA_MODE_TO_STATE = {
'0': STATE_ALARM_DISARMED,
'1': STATE_ALARM_ARMED_HOME,
'3': STATE_ALARM_ARMED_AWAY,
}
def _get_alarm_state(spc_mode):
def _get_alarm_state(area):
"""Get the alarm state."""
return SPC_AREA_MODE_TO_STATE.get(spc_mode, STATE_UNKNOWN)
from pyspcwebgw.const import AreaMode
if area.verified_alarm:
return STATE_ALARM_TRIGGERED
mode_to_state = {
AreaMode.UNSET: STATE_ALARM_DISARMED,
AreaMode.PART_SET_A: STATE_ALARM_ARMED_HOME,
AreaMode.PART_SET_B: STATE_ALARM_ARMED_NIGHT,
AreaMode.FULL_SET: STATE_ALARM_ARMED_AWAY,
}
return mode_to_state.get(area.mode)
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the SPC alarm control panel platform."""
if (discovery_info is None or
discovery_info[ATTR_DISCOVER_AREAS] is None):
if discovery_info is None:
return
api = hass.data[DATA_API]
devices = [SpcAlarm(api, area)
for area in discovery_info[ATTR_DISCOVER_AREAS]]
async_add_devices(devices)
async_add_entities([SpcAlarm(area=area, api=api)
for area in api.areas.values()])
class SpcAlarm(alarm.AlarmControlPanel):
"""Representation of the SPC alarm panel."""
def __init__(self, api, area):
def __init__(self, area, api):
"""Initialize the SPC alarm panel."""
self._area_id = area['id']
self._name = area['name']
self._state = _get_alarm_state(area['mode'])
if self._state == STATE_ALARM_DISARMED:
self._changed_by = area.get('last_unset_user_name', 'unknown')
else:
self._changed_by = area.get('last_set_user_name', 'unknown')
self._area = area
self._api = api
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Call for adding new entities."""
self.hass.data[DATA_REGISTRY].register_alarm_device(
self._area_id, self)
async_dispatcher_connect(self.hass,
SIGNAL_UPDATE_ALARM.format(self._area.id),
self._update_callback)
@asyncio.coroutine
def async_update_from_spc(self, state, extra):
"""Update the alarm panel with a new state."""
self._state = state
self._changed_by = extra.get('changed_by', 'unknown')
self.async_schedule_update_ha_state()
@callback
def _update_callback(self):
"""Call update method."""
self.async_schedule_update_ha_state(True)
@property
def should_poll(self):
@@ -77,32 +70,38 @@ class SpcAlarm(alarm.AlarmControlPanel):
@property
def name(self):
"""Return the name of the device."""
return self._name
return self._area.name
@property
def changed_by(self):
"""Return the user the last change was triggered by."""
return self._changed_by
return self._area.last_changed_by
@property
def state(self):
"""Return the state of the device."""
return self._state
return _get_alarm_state(self._area)
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
yield from self._api.send_area_command(
self._area_id, SpcWebGateway.AREA_COMMAND_UNSET)
from pyspcwebgw.const import AreaMode
await self._api.change_mode(area=self._area,
new_mode=AreaMode.UNSET)
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
yield from self._api.send_area_command(
self._area_id, SpcWebGateway.AREA_COMMAND_PART_SET)
from pyspcwebgw.const import AreaMode
await self._api.change_mode(area=self._area,
new_mode=AreaMode.PART_SET_A)
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
async def async_alarm_arm_night(self, code=None):
"""Send arm home command."""
from pyspcwebgw.const import AreaMode
await self._api.change_mode(area=self._area,
new_mode=AreaMode.PART_SET_B)
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
yield from self._api.send_area_command(
self._area_id, SpcWebGateway.AREA_COMMAND_SET)
from pyspcwebgw.const import AreaMode
await self._api.change_mode(area=self._area,
new_mode=AreaMode.FULL_SET)

View File

@@ -18,7 +18,7 @@ from homeassistant.const import (
STATE_ALARM_ARMED_CUSTOM_BYPASS)
REQUIREMENTS = ['total_connect_client==0.17']
REQUIREMENTS = ['total_connect_client==0.18']
_LOGGER = logging.getLogger(__name__)
@@ -31,14 +31,14 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up a TotalConnect control panel."""
name = config.get(CONF_NAME)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
total_connect = TotalConnect(name, username, password)
add_devices([total_connect], True)
add_entities([total_connect], True)
class TotalConnect(alarm.AlarmControlPanel):

View File

@@ -17,13 +17,13 @@ from homeassistant.const import (
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Verisure platform."""
alarms = []
if int(hub.config.get(CONF_ALARM, 1)):
hub.update_overview()
alarms.append(VerisureAlarm())
add_devices(alarms)
add_entities(alarms)
def set_arm_state(state, code=None):
@@ -60,8 +60,8 @@ class VerisureAlarm(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return the code format as regex."""
return '^\\d{%s}$' % self._digits
"""Return one or more digits/characters."""
return 'Number'
@property
def changed_by(self):

View File

@@ -4,7 +4,6 @@ Interfaces with Wink Cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.wink/
"""
import asyncio
import logging
import homeassistant.components.alarm_control_panel as alarm
@@ -20,7 +19,7 @@ DEPENDENCIES = ['wink']
STATE_ALARM_PRIVACY = 'Private'
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Wink platform."""
import pywink
@@ -32,14 +31,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
except AttributeError:
_id = camera.object_id() + camera.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_devices([WinkCameraDevice(camera, hass)])
add_entities([WinkCameraDevice(camera, hass)])
class WinkCameraDevice(WinkDevice, alarm.AlarmControlPanel):
"""Representation a Wink camera alarm."""
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['alarm_control_panel'].append(self)

View File

@@ -0,0 +1,98 @@
"""
Yale Smart Alarm client for interacting with the Yale Smart Alarm System API.
For more details about this platform, please refer to the documentation at
https://www.home-assistant.io/components/alarm_control_panel.yale_smart_alarm
"""
import logging
import voluptuous as vol
from homeassistant.components.alarm_control_panel import (
AlarmControlPanel, PLATFORM_SCHEMA)
from homeassistant.const import (
CONF_PASSWORD, CONF_USERNAME, CONF_NAME,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['yalesmartalarmclient==0.1.4']
CONF_AREA_ID = 'area_id'
DEFAULT_NAME = 'Yale Smart Alarm'
DEFAULT_AREA_ID = '1'
_LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_AREA_ID, default=DEFAULT_AREA_ID): cv.string,
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the alarm platform."""
name = config[CONF_NAME]
username = config[CONF_USERNAME]
password = config[CONF_PASSWORD]
area_id = config[CONF_AREA_ID]
from yalesmartalarmclient.client import (
YaleSmartAlarmClient, AuthenticationError)
try:
client = YaleSmartAlarmClient(username, password, area_id)
except AuthenticationError:
_LOGGER.error("Authentication failed. Check credentials")
return
add_entities([YaleAlarmDevice(name, client)], True)
class YaleAlarmDevice(AlarmControlPanel):
"""Represent a Yale Smart Alarm."""
def __init__(self, name, client):
"""Initialize the Yale Alarm Device."""
self._name = name
self._client = client
self._state = None
from yalesmartalarmclient.client import (YALE_STATE_DISARM,
YALE_STATE_ARM_PARTIAL,
YALE_STATE_ARM_FULL)
self._state_map = {
YALE_STATE_DISARM: STATE_ALARM_DISARMED,
YALE_STATE_ARM_PARTIAL: STATE_ALARM_ARMED_HOME,
YALE_STATE_ARM_FULL: STATE_ALARM_ARMED_AWAY
}
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def state(self):
"""Return the state of the device."""
return self._state
def update(self):
"""Return the state of the device."""
armed_status = self._client.get_armed_status()
self._state = self._state_map.get(armed_status)
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._client.disarm()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self._client.arm_partial()
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self._client.arm_full()

View File

@@ -34,6 +34,8 @@ CONF_ZONE_NAME = 'name'
CONF_ZONE_TYPE = 'type'
CONF_ZONE_RFID = 'rfid'
CONF_ZONES = 'zones'
CONF_RELAY_ADDR = 'relayaddr'
CONF_RELAY_CHAN = 'relaychan'
DEFAULT_DEVICE_TYPE = 'socket'
DEFAULT_DEVICE_HOST = 'localhost'
@@ -53,6 +55,7 @@ SIGNAL_PANEL_DISARM = 'alarmdecoder.panel_disarm'
SIGNAL_ZONE_FAULT = 'alarmdecoder.zone_fault'
SIGNAL_ZONE_RESTORE = 'alarmdecoder.zone_restore'
SIGNAL_RFX_MESSAGE = 'alarmdecoder.rfx_message'
SIGNAL_REL_MESSAGE = 'alarmdecoder.rel_message'
DEVICE_SOCKET_SCHEMA = vol.Schema({
vol.Required(CONF_DEVICE_TYPE): 'socket',
@@ -71,7 +74,11 @@ ZONE_SCHEMA = vol.Schema({
vol.Required(CONF_ZONE_NAME): cv.string,
vol.Optional(CONF_ZONE_TYPE,
default=DEFAULT_ZONE_TYPE): vol.Any(DEVICE_CLASSES_SCHEMA),
vol.Optional(CONF_ZONE_RFID): cv.string})
vol.Optional(CONF_ZONE_RFID): cv.string,
vol.Inclusive(CONF_RELAY_ADDR, 'relaylocation',
'Relay address and channel must exist together'): cv.byte,
vol.Inclusive(CONF_RELAY_CHAN, 'relaylocation',
'Relay address and channel must exist together'): cv.byte})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
@@ -153,6 +160,11 @@ def setup(hass, config):
hass.helpers.dispatcher.dispatcher_send(
SIGNAL_ZONE_RESTORE, zone)
def handle_rel_message(sender, message):
"""Handle relay message from AlarmDecoder."""
hass.helpers.dispatcher.dispatcher_send(
SIGNAL_REL_MESSAGE, message)
controller = False
if device_type == 'socket':
host = device.get(CONF_DEVICE_HOST)
@@ -171,6 +183,7 @@ def setup(hass, config):
controller.on_zone_fault += zone_fault_callback
controller.on_zone_restore += zone_restore_callback
controller.on_close += handle_closed_connection
controller.on_relay_changed += handle_rel_message
hass.data[DATA_AD] = controller

View File

@@ -10,7 +10,8 @@ import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.components.notify import (
ATTR_MESSAGE, DOMAIN as DOMAIN_NOTIFY)
from homeassistant.const import (
CONF_ENTITY_ID, STATE_IDLE, CONF_NAME, CONF_STATE, STATE_ON, STATE_OFF,
SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE, ATTR_ENTITY_ID)
@@ -59,64 +60,24 @@ def is_on(hass, entity_id):
return hass.states.is_state(entity_id, STATE_ON)
def turn_on(hass, entity_id):
"""Reset the alert."""
hass.add_job(async_turn_on, hass, entity_id)
@callback
def async_turn_on(hass, entity_id):
"""Async reset the alert."""
data = {ATTR_ENTITY_ID: entity_id}
hass.async_add_job(
hass.services.async_call(DOMAIN, SERVICE_TURN_ON, data))
def turn_off(hass, entity_id):
"""Acknowledge alert."""
hass.add_job(async_turn_off, hass, entity_id)
@callback
def async_turn_off(hass, entity_id):
"""Async acknowledge the alert."""
data = {ATTR_ENTITY_ID: entity_id}
hass.async_add_job(
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF, data))
def toggle(hass, entity_id):
"""Toggle acknowledgement of alert."""
hass.add_job(async_toggle, hass, entity_id)
@callback
def async_toggle(hass, entity_id):
"""Async toggle acknowledgement of alert."""
data = {ATTR_ENTITY_ID: entity_id}
hass.async_add_job(
hass.services.async_call(DOMAIN, SERVICE_TOGGLE, data))
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Set up the Alert component."""
alerts = config.get(DOMAIN)
all_alerts = {}
@asyncio.coroutine
def async_handle_alert_service(service_call):
async def async_handle_alert_service(service_call):
"""Handle calls to alert services."""
alert_ids = service.extract_entity_ids(hass, service_call)
for alert_id in alert_ids:
alert = all_alerts[alert_id]
alert.async_set_context(service_call.context)
if service_call.service == SERVICE_TURN_ON:
yield from alert.async_turn_on()
await alert.async_turn_on()
elif service_call.service == SERVICE_TOGGLE:
yield from alert.async_toggle()
await alert.async_toggle()
else:
yield from alert.async_turn_off()
await alert.async_turn_off()
# Setup alerts
for entity_id, alert in alerts.items():
@@ -140,7 +101,7 @@ def async_setup(hass, config):
tasks = [alert.async_update_ha_state() for alert in all_alerts.values()]
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
await asyncio.wait(tasks, loop=hass.loop)
return True
@@ -195,17 +156,15 @@ class Alert(ToggleEntity):
"""Hide the alert when it is not firing."""
return not self._can_ack or not self._firing
@asyncio.coroutine
def watched_entity_change(self, entity, from_state, to_state):
async def watched_entity_change(self, entity, from_state, to_state):
"""Determine if the alert should start or stop."""
_LOGGER.debug("Watched entity (%s) has changed", entity)
if to_state.state == self._alert_state and not self._firing:
yield from self.begin_alerting()
await self.begin_alerting()
if to_state.state != self._alert_state and self._firing:
yield from self.end_alerting()
await self.end_alerting()
@asyncio.coroutine
def begin_alerting(self):
async def begin_alerting(self):
"""Begin the alert procedures."""
_LOGGER.debug("Beginning Alert: %s", self._name)
self._ack = False
@@ -213,25 +172,23 @@ class Alert(ToggleEntity):
self._next_delay = 0
if not self._skip_first:
yield from self._notify()
await self._notify()
else:
yield from self._schedule_notify()
await self._schedule_notify()
self.hass.async_add_job(self.async_update_ha_state)
self.async_schedule_update_ha_state()
@asyncio.coroutine
def end_alerting(self):
async def end_alerting(self):
"""End the alert procedures."""
_LOGGER.debug("Ending Alert: %s", self._name)
self._cancel()
self._ack = False
self._firing = False
if self._done_message and self._send_done_message:
yield from self._notify_done_message()
self.hass.async_add_job(self.async_update_ha_state)
await self._notify_done_message()
self.async_schedule_update_ha_state()
@asyncio.coroutine
def _schedule_notify(self):
async def _schedule_notify(self):
"""Schedule a notification."""
delay = self._delay[self._next_delay]
next_msg = datetime.now() + delay
@@ -239,8 +196,7 @@ class Alert(ToggleEntity):
event.async_track_point_in_time(self.hass, self._notify, next_msg)
self._next_delay = min(self._next_delay + 1, len(self._delay) - 1)
@asyncio.coroutine
def _notify(self, *args):
async def _notify(self, *args):
"""Send the alert notification."""
if not self._firing:
return
@@ -249,36 +205,32 @@ class Alert(ToggleEntity):
_LOGGER.info("Alerting: %s", self._name)
self._send_done_message = True
for target in self._notifiers:
yield from self.hass.services.async_call(
'notify', target, {'message': self._name})
yield from self._schedule_notify()
await self.hass.services.async_call(
DOMAIN_NOTIFY, target, {ATTR_MESSAGE: self._name})
await self._schedule_notify()
@asyncio.coroutine
def _notify_done_message(self, *args):
async def _notify_done_message(self, *args):
"""Send notification of complete alert."""
_LOGGER.info("Alerting: %s", self._done_message)
self._send_done_message = False
for target in self._notifiers:
yield from self.hass.services.async_call(
'notify', target, {'message': self._done_message})
await self.hass.services.async_call(
DOMAIN_NOTIFY, target, {ATTR_MESSAGE: self._done_message})
@asyncio.coroutine
def async_turn_on(self, **kwargs):
async def async_turn_on(self, **kwargs):
"""Async Unacknowledge alert."""
_LOGGER.debug("Reset Alert: %s", self._name)
self._ack = False
yield from self.async_update_ha_state()
await self.async_update_ha_state()
@asyncio.coroutine
def async_turn_off(self, **kwargs):
async def async_turn_off(self, **kwargs):
"""Async Acknowledge alert."""
_LOGGER.debug("Acknowledged Alert: %s", self._name)
self._ack = True
yield from self.async_update_ha_state()
await self.async_update_ha_state()
@asyncio.coroutine
def async_toggle(self, **kwargs):
async def async_toggle(self, **kwargs):
"""Async toggle alert."""
if self._ack:
return self.async_turn_on()
return self.async_turn_off()
return await self.async_turn_on()
return await self.async_turn_off()

View File

@@ -4,7 +4,6 @@ Support for Alexa skill service end point.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alexa/
"""
import asyncio
import logging
import voluptuous as vol
@@ -53,8 +52,7 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Activate Alexa component."""
config = config.get(DOMAIN, {})
flash_briefings_config = config.get(CONF_FLASH_BRIEFINGS)

View File

@@ -4,7 +4,6 @@ Support for Alexa skill service end point.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alexa/
"""
import asyncio
import enum
import logging
@@ -59,16 +58,15 @@ class AlexaIntentsView(http.HomeAssistantView):
url = INTENTS_API_ENDPOINT
name = 'api:alexa'
@asyncio.coroutine
def post(self, request):
async def post(self, request):
"""Handle Alexa."""
hass = request.app['hass']
message = yield from request.json()
message = await request.json()
_LOGGER.debug("Received Alexa request: %s", message)
try:
response = yield from async_handle_message(hass, message)
response = await async_handle_message(hass, message)
return b'' if response is None else self.json(response)
except UnknownRequest as err:
_LOGGER.warning(str(err))
@@ -101,8 +99,7 @@ def intent_error_response(hass, message, error):
return alexa_response.as_dict()
@asyncio.coroutine
def async_handle_message(hass, message):
async def async_handle_message(hass, message):
"""Handle an Alexa intent.
Raises:
@@ -120,20 +117,18 @@ def async_handle_message(hass, message):
if not handler:
raise UnknownRequest('Received unknown request {}'.format(req_type))
return (yield from handler(hass, message))
return await handler(hass, message)
@HANDLERS.register('SessionEndedRequest')
@asyncio.coroutine
def async_handle_session_end(hass, message):
async def async_handle_session_end(hass, message):
"""Handle a session end request."""
return None
@HANDLERS.register('IntentRequest')
@HANDLERS.register('LaunchRequest')
@asyncio.coroutine
def async_handle_intent(hass, message):
async def async_handle_intent(hass, message):
"""Handle an intent request.
Raises:
@@ -153,7 +148,7 @@ def async_handle_intent(hass, message):
else:
intent_name = alexa_intent_info['name']
intent_response = yield from intent.async_handle(
intent_response = await intent.async_handle(
hass, DOMAIN, intent_name,
{key: {'value': value} for key, value
in alexa_response.variables.items()})
@@ -210,7 +205,7 @@ def resolve_slot_synonyms(key, request):
return resolved_value
class AlexaResponse(object):
class AlexaResponse:
"""Help generating the response for Alexa."""
def __init__(self, hass, intent_info):

View File

@@ -1,5 +1,4 @@
"""Support for alexa Smart Home Skill API."""
import asyncio
import logging
import math
from datetime import datetime
@@ -13,12 +12,13 @@ import homeassistant.util.color as color_util
from homeassistant.util.temperature import convert as convert_temperature
from homeassistant.util.decorator import Registry
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_TEMPERATURE, CONF_NAME,
SERVICE_LOCK, SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PAUSE,
SERVICE_MEDIA_PLAY, SERVICE_MEDIA_PREVIOUS_TRACK, SERVICE_MEDIA_STOP,
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_TEMPERATURE,
ATTR_UNIT_OF_MEASUREMENT, CONF_NAME, SERVICE_LOCK,
SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PAUSE, SERVICE_MEDIA_PLAY,
SERVICE_MEDIA_PREVIOUS_TRACK, SERVICE_MEDIA_STOP,
SERVICE_SET_COVER_POSITION, SERVICE_TURN_OFF, SERVICE_TURN_ON,
SERVICE_UNLOCK, SERVICE_VOLUME_SET, TEMP_FAHRENHEIT, TEMP_CELSIUS,
CONF_UNIT_OF_MEASUREMENT, STATE_LOCKED, STATE_UNLOCKED, STATE_ON)
STATE_LOCKED, STATE_UNLOCKED, STATE_ON)
from .const import CONF_FILTER, CONF_ENTITY_CONFIG
@@ -53,9 +53,10 @@ CONF_DISPLAY_CATEGORIES = 'display_categories'
HANDLERS = Registry()
ENTITY_ADAPTERS = Registry()
EVENT_ALEXA_SMART_HOME = 'alexa_smart_home'
class _DisplayCategory(object):
class _DisplayCategory:
"""Possible display categories for Discovery response.
https://developer.amazon.com/docs/device-apis/alexa-discovery.html#display-categories
@@ -107,7 +108,6 @@ class _DisplayCategory(object):
THERMOSTAT = "THERMOSTAT"
# Indicates the endpoint is a television.
# pylint: disable=invalid-name
TV = "TV"
@@ -154,13 +154,14 @@ class _UnsupportedProperty(Exception):
"""This entity does not support the requested Smart Home API property."""
class _AlexaEntity(object):
class _AlexaEntity:
"""An adaptation of an entity, expressed in Alexa's terms.
The API handlers should manipulate entities only through this interface.
"""
def __init__(self, config, entity):
def __init__(self, hass, config, entity):
self.hass = hass
self.config = config
self.entity = entity
self.entity_conf = config.entity_config.get(entity.entity_id, {})
@@ -209,7 +210,7 @@ class _AlexaEntity(object):
raise NotImplementedError
class _AlexaInterface(object):
class _AlexaInterface:
def __init__(self, entity):
self.entity = entity
@@ -271,11 +272,14 @@ class _AlexaInterface(object):
"""Return properties serialized for an API response."""
for prop in self.properties_supported():
prop_name = prop['name']
yield {
'name': prop_name,
'namespace': self.name(),
'value': self.get_property(prop_name),
}
# pylint: disable=assignment-from-no-return
prop_value = self.get_property(prop_name)
if prop_value is not None:
yield {
'name': prop_name,
'namespace': self.name(),
'value': prop_value,
}
class _AlexaPowerController(_AlexaInterface):
@@ -313,7 +317,7 @@ class _AlexaLockController(_AlexaInterface):
if self.entity.state == STATE_LOCKED:
return 'LOCKED'
elif self.entity.state == STATE_UNLOCKED:
if self.entity.state == STATE_UNLOCKED:
return 'UNLOCKED'
return 'JAMMED'
@@ -381,6 +385,10 @@ class _AlexaInputController(_AlexaInterface):
class _AlexaTemperatureSensor(_AlexaInterface):
def __init__(self, hass, entity):
_AlexaInterface.__init__(self, entity)
self.hass = hass
def name(self):
return 'Alexa.TemperatureSensor'
@@ -394,9 +402,10 @@ class _AlexaTemperatureSensor(_AlexaInterface):
if name != 'temperature':
raise _UnsupportedProperty(name)
unit = self.entity.attributes[CONF_UNIT_OF_MEASUREMENT]
unit = self.entity.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
temp = self.entity.state
if self.entity.domain == climate.DOMAIN:
unit = self.hass.config.units.temperature_unit
temp = self.entity.attributes.get(
climate.ATTR_CURRENT_TEMPERATURE)
return {
@@ -406,6 +415,10 @@ class _AlexaTemperatureSensor(_AlexaInterface):
class _AlexaThermostatController(_AlexaInterface):
def __init__(self, hass, entity):
_AlexaInterface.__init__(self, entity)
self.hass = hass
def name(self):
return 'Alexa.ThermostatController'
@@ -436,17 +449,19 @@ class _AlexaThermostatController(_AlexaInterface):
raise _UnsupportedProperty(name)
return mode
unit = self.entity.attributes[CONF_UNIT_OF_MEASUREMENT]
temp = None
unit = self.hass.config.units.temperature_unit
if name == 'targetSetpoint':
temp = self.entity.attributes.get(ATTR_TEMPERATURE)
temp = self.entity.attributes.get(climate.ATTR_TEMPERATURE)
elif name == 'lowerSetpoint':
temp = self.entity.attributes.get(climate.ATTR_TARGET_TEMP_LOW)
elif name == 'upperSetpoint':
temp = self.entity.attributes.get(climate.ATTR_TARGET_TEMP_HIGH)
if temp is None:
else:
raise _UnsupportedProperty(name)
if temp is None:
return None
return {
'value': float(temp),
'scale': API_TEMP_UNITS[unit],
@@ -485,8 +500,8 @@ class _ClimateCapabilities(_AlexaEntity):
return [_DisplayCategory.THERMOSTAT]
def interfaces(self):
yield _AlexaThermostatController(self.entity)
yield _AlexaTemperatureSensor(self.entity)
yield _AlexaThermostatController(self.hass, self.entity)
yield _AlexaTemperatureSensor(self.hass, self.entity)
@ENTITY_ADAPTERS.register(cover.DOMAIN)
@@ -603,14 +618,14 @@ class _SensorCapabilities(_AlexaEntity):
def interfaces(self):
attrs = self.entity.attributes
if attrs.get(CONF_UNIT_OF_MEASUREMENT) in (
if attrs.get(ATTR_UNIT_OF_MEASUREMENT) in (
TEMP_FAHRENHEIT,
TEMP_CELSIUS,
):
yield _AlexaTemperatureSensor(self.entity)
yield _AlexaTemperatureSensor(self.hass, self.entity)
class _Cause(object):
class _Cause:
"""Possible causes for property changes.
https://developer.amazon.com/docs/smarthome/state-reporting-for-a-smart-home-skill.html#cause-object
@@ -679,8 +694,7 @@ class SmartHomeView(http.HomeAssistantView):
"""Initialize."""
self.smart_home_config = smart_home_config
@asyncio.coroutine
def post(self, request):
async def post(self, request):
"""Handle Alexa Smart Home requests.
The Smart Home API requires the endpoint to be implemented in AWS
@@ -688,34 +702,57 @@ class SmartHomeView(http.HomeAssistantView):
the response.
"""
hass = request.app['hass']
message = yield from request.json()
message = await request.json()
_LOGGER.debug("Received Alexa Smart Home request: %s", message)
response = yield from async_handle_message(
response = await async_handle_message(
hass, self.smart_home_config, message)
_LOGGER.debug("Sending Alexa Smart Home response: %s", response)
return b'' if response is None else self.json(response)
@asyncio.coroutine
def async_handle_message(hass, config, message):
async def async_handle_message(hass, config, request, context=None):
"""Handle incoming API messages."""
assert message[API_DIRECTIVE][API_HEADER]['payloadVersion'] == '3'
assert request[API_DIRECTIVE][API_HEADER]['payloadVersion'] == '3'
if context is None:
context = ha.Context()
# Read head data
message = message[API_DIRECTIVE]
namespace = message[API_HEADER]['namespace']
name = message[API_HEADER]['name']
request = request[API_DIRECTIVE]
namespace = request[API_HEADER]['namespace']
name = request[API_HEADER]['name']
# Do we support this API request?
funct_ref = HANDLERS.get((namespace, name))
if not funct_ref:
if funct_ref:
response = await funct_ref(hass, config, request, context)
else:
_LOGGER.warning(
"Unsupported API request %s/%s", namespace, name)
return api_error(message)
response = api_error(request)
return (yield from funct_ref(hass, config, message))
request_info = {
'namespace': namespace,
'name': name,
}
if API_ENDPOINT in request and 'endpointId' in request[API_ENDPOINT]:
request_info['entity_id'] = \
request[API_ENDPOINT]['endpointId'].replace('#', '.')
response_header = response[API_EVENT][API_HEADER]
hass.bus.async_fire(EVENT_ALEXA_SMART_HOME, {
'request': request_info,
'response': {
'namespace': response_header['namespace'],
'name': response_header['name'],
}
}, context=context)
return response
def api_message(request,
@@ -779,8 +816,7 @@ def api_error(request,
@HANDLERS.register(('Alexa.Discovery', 'Discover'))
@asyncio.coroutine
def async_api_discovery(hass, config, request):
async def async_api_discovery(hass, config, request, context):
"""Create a API formatted discovery response.
Async friendly.
@@ -795,7 +831,7 @@ def async_api_discovery(hass, config, request):
if entity.domain not in ENTITY_ADAPTERS:
continue
alexa_entity = ENTITY_ADAPTERS[entity.domain](config, entity)
alexa_entity = ENTITY_ADAPTERS[entity.domain](hass, config, entity)
endpoint = {
'displayCategories': alexa_entity.display_categories(),
@@ -822,8 +858,7 @@ def async_api_discovery(hass, config, request):
def extract_entity(funct):
"""Decorate for extract entity object from request."""
@asyncio.coroutine
def async_api_entity_wrapper(hass, config, request):
async def async_api_entity_wrapper(hass, config, request, context):
"""Process a turn on request."""
entity_id = request[API_ENDPOINT]['endpointId'].replace('#', '.')
@@ -834,15 +869,14 @@ def extract_entity(funct):
request[API_HEADER]['name'], entity_id)
return api_error(request, error_type='NO_SUCH_ENDPOINT')
return (yield from funct(hass, config, request, entity))
return await funct(hass, config, request, context, entity)
return async_api_entity_wrapper
@HANDLERS.register(('Alexa.PowerController', 'TurnOn'))
@extract_entity
@asyncio.coroutine
def async_api_turn_on(hass, config, request, entity):
async def async_api_turn_on(hass, config, request, context, entity):
"""Process a turn on request."""
domain = entity.domain
if entity.domain == group.DOMAIN:
@@ -852,17 +886,16 @@ def async_api_turn_on(hass, config, request, entity):
if entity.domain == cover.DOMAIN:
service = cover.SERVICE_OPEN_COVER
yield from hass.services.async_call(domain, service, {
await hass.services.async_call(domain, service, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False)
}, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.PowerController', 'TurnOff'))
@extract_entity
@asyncio.coroutine
def async_api_turn_off(hass, config, request, entity):
async def async_api_turn_off(hass, config, request, context, entity):
"""Process a turn off request."""
domain = entity.domain
if entity.domain == group.DOMAIN:
@@ -872,32 +905,30 @@ def async_api_turn_off(hass, config, request, entity):
if entity.domain == cover.DOMAIN:
service = cover.SERVICE_CLOSE_COVER
yield from hass.services.async_call(domain, service, {
await hass.services.async_call(domain, service, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False)
}, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.BrightnessController', 'SetBrightness'))
@extract_entity
@asyncio.coroutine
def async_api_set_brightness(hass, config, request, entity):
async def async_api_set_brightness(hass, config, request, context, entity):
"""Process a set brightness request."""
brightness = int(request[API_PAYLOAD]['brightness'])
yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_BRIGHTNESS_PCT: brightness,
}, blocking=False)
}, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.BrightnessController', 'AdjustBrightness'))
@extract_entity
@asyncio.coroutine
def async_api_adjust_brightness(hass, config, request, entity):
async def async_api_adjust_brightness(hass, config, request, context, entity):
"""Process an adjust brightness request."""
brightness_delta = int(request[API_PAYLOAD]['brightnessDelta'])
@@ -910,18 +941,17 @@ def async_api_adjust_brightness(hass, config, request, entity):
# set brightness
brightness = max(0, brightness_delta + current)
yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_BRIGHTNESS_PCT: brightness,
}, blocking=False)
}, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.ColorController', 'SetColor'))
@extract_entity
@asyncio.coroutine
def async_api_set_color(hass, config, request, entity):
async def async_api_set_color(hass, config, request, context, entity):
"""Process a set color request."""
rgb = color_util.color_hsb_to_RGB(
float(request[API_PAYLOAD]['color']['hue']),
@@ -929,25 +959,25 @@ def async_api_set_color(hass, config, request, entity):
float(request[API_PAYLOAD]['color']['brightness'])
)
yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_RGB_COLOR: rgb,
}, blocking=False)
}, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.ColorTemperatureController', 'SetColorTemperature'))
@extract_entity
@asyncio.coroutine
def async_api_set_color_temperature(hass, config, request, entity):
async def async_api_set_color_temperature(hass, config, request, context,
entity):
"""Process a set color temperature request."""
kelvin = int(request[API_PAYLOAD]['colorTemperatureInKelvin'])
yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_KELVIN: kelvin,
}, blocking=False)
}, blocking=False, context=context)
return api_message(request)
@@ -955,17 +985,17 @@ def async_api_set_color_temperature(hass, config, request, entity):
@HANDLERS.register(
('Alexa.ColorTemperatureController', 'DecreaseColorTemperature'))
@extract_entity
@asyncio.coroutine
def async_api_decrease_color_temp(hass, config, request, entity):
async def async_api_decrease_color_temp(hass, config, request, context,
entity):
"""Process a decrease color temperature request."""
current = int(entity.attributes.get(light.ATTR_COLOR_TEMP))
max_mireds = int(entity.attributes.get(light.ATTR_MAX_MIREDS))
value = min(max_mireds, current + 50)
yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_COLOR_TEMP: value,
}, blocking=False)
}, blocking=False, context=context)
return api_message(request)
@@ -973,31 +1003,30 @@ def async_api_decrease_color_temp(hass, config, request, entity):
@HANDLERS.register(
('Alexa.ColorTemperatureController', 'IncreaseColorTemperature'))
@extract_entity
@asyncio.coroutine
def async_api_increase_color_temp(hass, config, request, entity):
async def async_api_increase_color_temp(hass, config, request, context,
entity):
"""Process an increase color temperature request."""
current = int(entity.attributes.get(light.ATTR_COLOR_TEMP))
min_mireds = int(entity.attributes.get(light.ATTR_MIN_MIREDS))
value = max(min_mireds, current - 50)
yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_COLOR_TEMP: value,
}, blocking=False)
}, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.SceneController', 'Activate'))
@extract_entity
@asyncio.coroutine
def async_api_activate(hass, config, request, entity):
async def async_api_activate(hass, config, request, context, entity):
"""Process an activate request."""
domain = entity.domain
yield from hass.services.async_call(domain, SERVICE_TURN_ON, {
await hass.services.async_call(domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False)
}, blocking=False, context=context)
payload = {
'cause': {'type': _Cause.VOICE_INTERACTION},
@@ -1014,14 +1043,13 @@ def async_api_activate(hass, config, request, entity):
@HANDLERS.register(('Alexa.SceneController', 'Deactivate'))
@extract_entity
@asyncio.coroutine
def async_api_deactivate(hass, config, request, entity):
async def async_api_deactivate(hass, config, request, context, entity):
"""Process a deactivate request."""
domain = entity.domain
yield from hass.services.async_call(domain, SERVICE_TURN_OFF, {
await hass.services.async_call(domain, SERVICE_TURN_OFF, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False)
}, blocking=False, context=context)
payload = {
'cause': {'type': _Cause.VOICE_INTERACTION},
@@ -1038,8 +1066,7 @@ def async_api_deactivate(hass, config, request, entity):
@HANDLERS.register(('Alexa.PercentageController', 'SetPercentage'))
@extract_entity
@asyncio.coroutine
def async_api_set_percentage(hass, config, request, entity):
async def async_api_set_percentage(hass, config, request, context, entity):
"""Process a set percentage request."""
percentage = int(request[API_PAYLOAD]['percentage'])
service = None
@@ -1061,16 +1088,15 @@ def async_api_set_percentage(hass, config, request, entity):
service = SERVICE_SET_COVER_POSITION
data[cover.ATTR_POSITION] = percentage
yield from hass.services.async_call(
entity.domain, service, data, blocking=False)
await hass.services.async_call(
entity.domain, service, data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.PercentageController', 'AdjustPercentage'))
@extract_entity
@asyncio.coroutine
def async_api_adjust_percentage(hass, config, request, entity):
async def async_api_adjust_percentage(hass, config, request, context, entity):
"""Process an adjust percentage request."""
percentage_delta = int(request[API_PAYLOAD]['percentageDelta'])
service = None
@@ -1109,20 +1135,19 @@ def async_api_adjust_percentage(hass, config, request, entity):
data[cover.ATTR_POSITION] = max(0, percentage_delta + current)
yield from hass.services.async_call(
entity.domain, service, data, blocking=False)
await hass.services.async_call(
entity.domain, service, data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.LockController', 'Lock'))
@extract_entity
@asyncio.coroutine
def async_api_lock(hass, config, request, entity):
async def async_api_lock(hass, config, request, context, entity):
"""Process a lock request."""
yield from hass.services.async_call(entity.domain, SERVICE_LOCK, {
await hass.services.async_call(entity.domain, SERVICE_LOCK, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False)
}, blocking=False, context=context)
# Alexa expects a lockState in the response, we don't know the actual
# lockState at this point but assume it is locked. It is reported
@@ -1139,20 +1164,18 @@ def async_api_lock(hass, config, request, entity):
# Not supported by Alexa yet
@HANDLERS.register(('Alexa.LockController', 'Unlock'))
@extract_entity
@asyncio.coroutine
def async_api_unlock(hass, config, request, entity):
async def async_api_unlock(hass, config, request, context, entity):
"""Process an unlock request."""
yield from hass.services.async_call(entity.domain, SERVICE_UNLOCK, {
await hass.services.async_call(entity.domain, SERVICE_UNLOCK, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False)
}, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.Speaker', 'SetVolume'))
@extract_entity
@asyncio.coroutine
def async_api_set_volume(hass, config, request, entity):
async def async_api_set_volume(hass, config, request, context, entity):
"""Process a set volume request."""
volume = round(float(request[API_PAYLOAD]['volume'] / 100), 2)
@@ -1161,17 +1184,16 @@ def async_api_set_volume(hass, config, request, entity):
media_player.ATTR_MEDIA_VOLUME_LEVEL: volume,
}
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, SERVICE_VOLUME_SET,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.InputController', 'SelectInput'))
@extract_entity
@asyncio.coroutine
def async_api_select_input(hass, config, request, entity):
async def async_api_select_input(hass, config, request, context, entity):
"""Process a set input request."""
media_input = request[API_PAYLOAD]['input']
@@ -1195,17 +1217,16 @@ def async_api_select_input(hass, config, request, entity):
media_player.ATTR_INPUT_SOURCE: media_input,
}
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, media_player.SERVICE_SELECT_SOURCE,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.Speaker', 'AdjustVolume'))
@extract_entity
@asyncio.coroutine
def async_api_adjust_volume(hass, config, request, entity):
async def async_api_adjust_volume(hass, config, request, context, entity):
"""Process an adjust volume request."""
volume_delta = int(request[API_PAYLOAD]['volume'])
@@ -1224,17 +1245,16 @@ def async_api_adjust_volume(hass, config, request, entity):
media_player.ATTR_MEDIA_VOLUME_LEVEL: volume,
}
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, media_player.SERVICE_VOLUME_SET,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.StepSpeaker', 'AdjustVolume'))
@extract_entity
@asyncio.coroutine
def async_api_adjust_volume_step(hass, config, request, entity):
async def async_api_adjust_volume_step(hass, config, request, context, entity):
"""Process an adjust volume step request."""
# media_player volume up/down service does not support specifying steps
# each component handles it differently e.g. via config.
@@ -1247,13 +1267,13 @@ def async_api_adjust_volume_step(hass, config, request, entity):
}
if volume_step > 0:
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, media_player.SERVICE_VOLUME_UP,
data, blocking=False)
data, blocking=False, context=context)
elif volume_step < 0:
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, media_player.SERVICE_VOLUME_DOWN,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
@@ -1261,8 +1281,7 @@ def async_api_adjust_volume_step(hass, config, request, entity):
@HANDLERS.register(('Alexa.StepSpeaker', 'SetMute'))
@HANDLERS.register(('Alexa.Speaker', 'SetMute'))
@extract_entity
@asyncio.coroutine
def async_api_set_mute(hass, config, request, entity):
async def async_api_set_mute(hass, config, request, context, entity):
"""Process a set mute request."""
mute = bool(request[API_PAYLOAD]['mute'])
@@ -1271,98 +1290,94 @@ def async_api_set_mute(hass, config, request, entity):
media_player.ATTR_MEDIA_VOLUME_MUTED: mute,
}
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, media_player.SERVICE_VOLUME_MUTE,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.PlaybackController', 'Play'))
@extract_entity
@asyncio.coroutine
def async_api_play(hass, config, request, entity):
async def async_api_play(hass, config, request, context, entity):
"""Process a play request."""
data = {
ATTR_ENTITY_ID: entity.entity_id
}
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_PLAY,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.PlaybackController', 'Pause'))
@extract_entity
@asyncio.coroutine
def async_api_pause(hass, config, request, entity):
async def async_api_pause(hass, config, request, context, entity):
"""Process a pause request."""
data = {
ATTR_ENTITY_ID: entity.entity_id
}
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_PAUSE,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.PlaybackController', 'Stop'))
@extract_entity
@asyncio.coroutine
def async_api_stop(hass, config, request, entity):
async def async_api_stop(hass, config, request, context, entity):
"""Process a stop request."""
data = {
ATTR_ENTITY_ID: entity.entity_id
}
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_STOP,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.PlaybackController', 'Next'))
@extract_entity
@asyncio.coroutine
def async_api_next(hass, config, request, entity):
async def async_api_next(hass, config, request, context, entity):
"""Process a next request."""
data = {
ATTR_ENTITY_ID: entity.entity_id
}
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_NEXT_TRACK,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa.PlaybackController', 'Previous'))
@extract_entity
@asyncio.coroutine
def async_api_previous(hass, config, request, entity):
async def async_api_previous(hass, config, request, context, entity):
"""Process a previous request."""
data = {
ATTR_ENTITY_ID: entity.entity_id
}
yield from hass.services.async_call(
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_PREVIOUS_TRACK,
data, blocking=False)
data, blocking=False, context=context)
return api_message(request)
def api_error_temp_range(request, temp, min_temp, max_temp, unit):
def api_error_temp_range(hass, request, temp, min_temp, max_temp):
"""Create temperature value out of range API error response.
Async friendly.
"""
unit = hass.config.units.temperature_unit
temp_range = {
'minimumValue': {
'value': min_temp,
@@ -1383,8 +1398,9 @@ def api_error_temp_range(request, temp, min_temp, max_temp, unit):
)
def temperature_from_object(temp_obj, to_unit, interval=False):
def temperature_from_object(hass, temp_obj, interval=False):
"""Get temperature from Temperature object in requested unit."""
to_unit = hass.config.units.temperature_unit
from_unit = TEMP_CELSIUS
temp = float(temp_obj['value'])
@@ -1400,9 +1416,8 @@ def temperature_from_object(temp_obj, to_unit, interval=False):
@HANDLERS.register(('Alexa.ThermostatController', 'SetTargetTemperature'))
@extract_entity
async def async_api_set_target_temp(hass, config, request, entity):
async def async_api_set_target_temp(hass, config, request, context, entity):
"""Process a set target temperature request."""
unit = entity.attributes[CONF_UNIT_OF_MEASUREMENT]
min_temp = entity.attributes.get(climate.ATTR_MIN_TEMP)
max_temp = entity.attributes.get(climate.ATTR_MAX_TEMP)
@@ -1412,48 +1427,45 @@ async def async_api_set_target_temp(hass, config, request, entity):
payload = request[API_PAYLOAD]
if 'targetSetpoint' in payload:
temp = temperature_from_object(
payload['targetSetpoint'], unit)
temp = temperature_from_object(hass, payload['targetSetpoint'])
if temp < min_temp or temp > max_temp:
return api_error_temp_range(
request, temp, min_temp, max_temp, unit)
hass, request, temp, min_temp, max_temp)
data[ATTR_TEMPERATURE] = temp
if 'lowerSetpoint' in payload:
temp_low = temperature_from_object(
payload['lowerSetpoint'], unit)
temp_low = temperature_from_object(hass, payload['lowerSetpoint'])
if temp_low < min_temp or temp_low > max_temp:
return api_error_temp_range(
request, temp_low, min_temp, max_temp, unit)
hass, request, temp_low, min_temp, max_temp)
data[climate.ATTR_TARGET_TEMP_LOW] = temp_low
if 'upperSetpoint' in payload:
temp_high = temperature_from_object(
payload['upperSetpoint'], unit)
temp_high = temperature_from_object(hass, payload['upperSetpoint'])
if temp_high < min_temp or temp_high > max_temp:
return api_error_temp_range(
request, temp_high, min_temp, max_temp, unit)
hass, request, temp_high, min_temp, max_temp)
data[climate.ATTR_TARGET_TEMP_HIGH] = temp_high
await hass.services.async_call(
entity.domain, climate.SERVICE_SET_TEMPERATURE, data, blocking=False)
entity.domain, climate.SERVICE_SET_TEMPERATURE, data, blocking=False,
context=context)
return api_message(request)
@HANDLERS.register(('Alexa.ThermostatController', 'AdjustTargetTemperature'))
@extract_entity
async def async_api_adjust_target_temp(hass, config, request, entity):
async def async_api_adjust_target_temp(hass, config, request, context, entity):
"""Process an adjust target temperature request."""
unit = entity.attributes[CONF_UNIT_OF_MEASUREMENT]
min_temp = entity.attributes.get(climate.ATTR_MIN_TEMP)
max_temp = entity.attributes.get(climate.ATTR_MAX_TEMP)
temp_delta = temperature_from_object(
request[API_PAYLOAD]['targetSetpointDelta'], unit, interval=True)
hass, request[API_PAYLOAD]['targetSetpointDelta'], interval=True)
target_temp = float(entity.attributes.get(ATTR_TEMPERATURE)) + temp_delta
if target_temp < min_temp or target_temp > max_temp:
return api_error_temp_range(
request, target_temp, min_temp, max_temp, unit)
hass, request, target_temp, min_temp, max_temp)
data = {
ATTR_ENTITY_ID: entity.entity_id,
@@ -1461,21 +1473,21 @@ async def async_api_adjust_target_temp(hass, config, request, entity):
}
await hass.services.async_call(
entity.domain, climate.SERVICE_SET_TEMPERATURE, data, blocking=False)
entity.domain, climate.SERVICE_SET_TEMPERATURE, data, blocking=False,
context=context)
return api_message(request)
@HANDLERS.register(('Alexa.ThermostatController', 'SetThermostatMode'))
@extract_entity
async def async_api_set_thermostat_mode(hass, config, request, entity):
async def async_api_set_thermostat_mode(hass, config, request, context,
entity):
"""Process a set thermostat mode request."""
mode = request[API_PAYLOAD]['thermostatMode']
mode = mode if isinstance(mode, str) else mode['value']
operation_list = entity.attributes.get(climate.ATTR_OPERATION_LIST)
# Work around a pylint false positive due to
# https://github.com/PyCQA/pylint/issues/1830
# pylint: disable=stop-iteration-return
ha_mode = next(
(k for k, v in API_THERMOSTAT_MODES.items() if v == mode),
None
@@ -1496,17 +1508,16 @@ async def async_api_set_thermostat_mode(hass, config, request, entity):
await hass.services.async_call(
entity.domain, climate.SERVICE_SET_OPERATION_MODE, data,
blocking=False)
blocking=False, context=context)
return api_message(request)
@HANDLERS.register(('Alexa', 'ReportState'))
@extract_entity
@asyncio.coroutine
def async_api_reportstate(hass, config, request, entity):
async def async_api_reportstate(hass, config, request, context, entity):
"""Process a ReportState request."""
alexa_entity = ENTITY_ADAPTERS[entity.domain](config, entity)
alexa_entity = ENTITY_ADAPTERS[entity.domain](hass, config, entity)
properties = []
for interface in alexa_entity.interfaces():
properties.extend(interface.serialize_properties())
@@ -1516,3 +1527,8 @@ def async_api_reportstate(hass, config, request, entity):
name='StateReport',
context={'properties': properties}
)
def turned_off_response(message):
"""Return a device turned off response."""
return api_error(message[API_DIRECTIVE], error_type='BRIDGE_UNREACHABLE')

View File

@@ -18,7 +18,7 @@ from homeassistant.const import (
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['amcrest==1.2.2']
REQUIREMENTS = ['amcrest==1.2.3']
DEPENDENCIES = ['ffmpeg']
_LOGGER = logging.getLogger(__name__)
@@ -164,7 +164,7 @@ def setup(hass, config):
return True
class AmcrestDevice(object):
class AmcrestDevice:
"""Representation of a base Amcrest discovery device."""
def __init__(self, camera, name, authentication, ffmpeg_arguments,

View File

@@ -149,16 +149,14 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Set up the IP Webcam component."""
from pydroid_ipcam import PyDroidIPCam
webcams = hass.data[DATA_IP_WEBCAM] = {}
websession = async_get_clientsession(hass)
@asyncio.coroutine
def async_setup_ipcamera(cam_config):
async def async_setup_ipcamera(cam_config):
"""Set up an IP camera."""
host = cam_config[CONF_HOST]
username = cam_config.get(CONF_USERNAME)
@@ -188,16 +186,15 @@ def async_setup(hass, config):
if motion is None:
motion = 'motion_active' in cam.enabled_sensors
@asyncio.coroutine
def async_update_data(now):
async def async_update_data(now):
"""Update data from IP camera in SCAN_INTERVAL."""
yield from cam.update()
await cam.update()
async_dispatcher_send(hass, SIGNAL_UPDATE_DATA, host)
async_track_point_in_utc_time(
hass, async_update_data, utcnow() + interval)
yield from async_update_data(None)
await async_update_data(None)
# Load platforms
webcams[host] = cam
@@ -214,11 +211,11 @@ def async_setup(hass, config):
CONF_PASSWORD: password
})
hass.async_add_job(discovery.async_load_platform(
hass.async_create_task(discovery.async_load_platform(
hass, 'camera', 'mjpeg', mjpeg_camera, config))
if sensors:
hass.async_add_job(discovery.async_load_platform(
hass.async_create_task(discovery.async_load_platform(
hass, 'sensor', DOMAIN, {
CONF_NAME: name,
CONF_HOST: host,
@@ -226,7 +223,7 @@ def async_setup(hass, config):
}, config))
if switches:
hass.async_add_job(discovery.async_load_platform(
hass.async_create_task(discovery.async_load_platform(
hass, 'switch', DOMAIN, {
CONF_NAME: name,
CONF_HOST: host,
@@ -234,7 +231,7 @@ def async_setup(hass, config):
}, config))
if motion:
hass.async_add_job(discovery.async_load_platform(
hass.async_create_task(discovery.async_load_platform(
hass, 'binary_sensor', DOMAIN, {
CONF_HOST: host,
CONF_NAME: name,
@@ -242,7 +239,7 @@ def async_setup(hass, config):
tasks = [async_setup_ipcamera(conf) for conf in config[DOMAIN]]
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
await asyncio.wait(tasks, loop=hass.loop)
return True
@@ -255,8 +252,7 @@ class AndroidIPCamEntity(Entity):
self._host = host
self._ipcam = ipcam
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Register update dispatcher."""
@callback
def async_ipcam_update(host):

View File

@@ -58,7 +58,7 @@ def setup(hass, config):
return True
class APCUPSdData(object):
class APCUPSdData:
"""Stores the data retrieved from APCUPSd.
For each entity to use, acts as the single point responsible for fetching

View File

@@ -2,7 +2,7 @@
Rest API for Home Assistant.
For more details about the RESTful API, please refer to the documentation at
https://home-assistant.io/developers/api/
https://developers.home-assistant.io/docs/en/external_api_rest.html
"""
import asyncio
import json
@@ -11,31 +11,34 @@ import logging
from aiohttp import web
import async_timeout
import homeassistant.core as ha
import homeassistant.remote as rem
from homeassistant.bootstrap import DATA_LOGGING
from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP, EVENT_TIME_CHANGED,
HTTP_BAD_REQUEST, HTTP_CREATED, HTTP_NOT_FOUND,
MATCH_ALL, URL_API, URL_API_COMPONENTS,
URL_API_CONFIG, URL_API_DISCOVERY_INFO, URL_API_ERROR_LOG,
URL_API_EVENTS, URL_API_SERVICES,
URL_API_STATES, URL_API_STATES_ENTITY, URL_API_STREAM, URL_API_TEMPLATE,
__version__)
from homeassistant.exceptions import TemplateError
from homeassistant.helpers.state import AsyncTrackStates
from homeassistant.helpers.service import async_get_all_descriptions
from homeassistant.helpers import template
from homeassistant.components.http import HomeAssistantView
from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP, EVENT_TIME_CHANGED, HTTP_BAD_REQUEST,
HTTP_CREATED, HTTP_NOT_FOUND, MATCH_ALL, URL_API, URL_API_COMPONENTS,
URL_API_CONFIG, URL_API_DISCOVERY_INFO, URL_API_ERROR_LOG, URL_API_EVENTS,
URL_API_SERVICES, URL_API_STATES, URL_API_STATES_ENTITY, URL_API_STREAM,
URL_API_TEMPLATE, __version__)
import homeassistant.core as ha
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import template
from homeassistant.helpers.service import async_get_all_descriptions
from homeassistant.helpers.state import AsyncTrackStates
from homeassistant.helpers.json import JSONEncoder
_LOGGER = logging.getLogger(__name__)
ATTR_BASE_URL = 'base_url'
ATTR_LOCATION_NAME = 'location_name'
ATTR_REQUIRES_API_PASSWORD = 'requires_api_password'
ATTR_VERSION = 'version'
DOMAIN = 'api'
DEPENDENCIES = ['http']
STREAM_PING_PAYLOAD = "ping"
STREAM_PING_PAYLOAD = 'ping'
STREAM_PING_INTERVAL = 50 # seconds
_LOGGER = logging.getLogger(__name__)
def setup(hass, config):
"""Register the API with the HTTP interface."""
@@ -52,9 +55,8 @@ def setup(hass, config):
hass.http.register_view(APIComponentsView)
hass.http.register_view(APITemplateView)
log_path = hass.data.get(DATA_LOGGING, None)
if log_path:
hass.http.register_static_path(URL_API_ERROR_LOG, log_path, False)
if DATA_LOGGING in hass.data:
hass.http.register_view(APIErrorLog)
return True
@@ -63,24 +65,22 @@ class APIStatusView(HomeAssistantView):
"""View to handle Status requests."""
url = URL_API
name = "api:status"
name = 'api:status'
@ha.callback
def get(self, request):
"""Retrieve if API is running."""
return self.json_message('API running.')
return self.json_message("API running.")
class APIEventStream(HomeAssistantView):
"""View to handle EventStream requests."""
url = URL_API_STREAM
name = "api:stream"
name = 'api:stream'
@asyncio.coroutine
def get(self, request):
async def get(self, request):
"""Provide a streaming interface for the event bus."""
# pylint: disable=no-self-use
hass = request.app['hass']
stop_obj = object()
to_write = asyncio.Queue(loop=hass.loop)
@@ -89,8 +89,7 @@ class APIEventStream(HomeAssistantView):
if restrict:
restrict = restrict.split(',') + [EVENT_HOMEASSISTANT_STOP]
@asyncio.coroutine
def forward_events(event):
async def forward_events(event):
"""Forward events to the open request."""
if event.event_type == EVENT_TIME_CHANGED:
return
@@ -98,56 +97,58 @@ class APIEventStream(HomeAssistantView):
if restrict and event.event_type not in restrict:
return
_LOGGER.debug('STREAM %s FORWARDING %s', id(stop_obj), event)
_LOGGER.debug("STREAM %s FORWARDING %s", id(stop_obj), event)
if event.event_type == EVENT_HOMEASSISTANT_STOP:
data = stop_obj
else:
data = json.dumps(event, cls=rem.JSONEncoder)
data = json.dumps(event, cls=JSONEncoder)
yield from to_write.put(data)
await to_write.put(data)
response = web.StreamResponse()
response.content_type = 'text/event-stream'
yield from response.prepare(request)
await response.prepare(request)
unsub_stream = hass.bus.async_listen(MATCH_ALL, forward_events)
try:
_LOGGER.debug('STREAM %s ATTACHED', id(stop_obj))
_LOGGER.debug("STREAM %s ATTACHED", id(stop_obj))
# Fire off one message so browsers fire open event right away
yield from to_write.put(STREAM_PING_PAYLOAD)
await to_write.put(STREAM_PING_PAYLOAD)
while True:
try:
with async_timeout.timeout(STREAM_PING_INTERVAL,
loop=hass.loop):
payload = yield from to_write.get()
payload = await to_write.get()
if payload is stop_obj:
break
msg = "data: {}\n\n".format(payload)
_LOGGER.debug('STREAM %s WRITING %s', id(stop_obj),
msg.strip())
yield from response.write(msg.encode("UTF-8"))
_LOGGER.debug(
"STREAM %s WRITING %s", id(stop_obj), msg.strip())
await response.write(msg.encode('UTF-8'))
except asyncio.TimeoutError:
yield from to_write.put(STREAM_PING_PAYLOAD)
await to_write.put(STREAM_PING_PAYLOAD)
except asyncio.CancelledError:
_LOGGER.debug('STREAM %s ABORT', id(stop_obj))
_LOGGER.debug("STREAM %s ABORT", id(stop_obj))
finally:
_LOGGER.debug('STREAM %s RESPONSE CLOSED', id(stop_obj))
_LOGGER.debug("STREAM %s RESPONSE CLOSED", id(stop_obj))
unsub_stream()
return response
class APIConfigView(HomeAssistantView):
"""View to handle Config requests."""
"""View to handle Configuration requests."""
url = URL_API_CONFIG
name = "api:config"
name = 'api:config'
@ha.callback
def get(self, request):
@@ -156,22 +157,22 @@ class APIConfigView(HomeAssistantView):
class APIDiscoveryView(HomeAssistantView):
"""View to provide discovery info."""
"""View to provide Discovery information."""
requires_auth = False
url = URL_API_DISCOVERY_INFO
name = "api:discovery"
name = 'api:discovery'
@ha.callback
def get(self, request):
"""Get discovery info."""
"""Get discovery information."""
hass = request.app['hass']
needs_auth = hass.config.api.api_password is not None
return self.json({
'base_url': hass.config.api.base_url,
'location_name': hass.config.location_name,
'requires_api_password': needs_auth,
'version': __version__
ATTR_BASE_URL: hass.config.api.base_url,
ATTR_LOCATION_NAME: hass.config.location_name,
ATTR_REQUIRES_API_PASSWORD: needs_auth,
ATTR_VERSION: __version__,
})
@@ -190,8 +191,8 @@ class APIStatesView(HomeAssistantView):
class APIEntityStateView(HomeAssistantView):
"""View to handle EntityState requests."""
url = "/api/states/{entity_id}"
name = "api:entity-state"
url = '/api/states/{entity_id}'
name = 'api:entity-state'
@ha.callback
def get(self, request, entity_id):
@@ -199,22 +200,21 @@ class APIEntityStateView(HomeAssistantView):
state = request.app['hass'].states.get(entity_id)
if state:
return self.json(state)
return self.json_message('Entity not found', HTTP_NOT_FOUND)
return self.json_message("Entity not found.", HTTP_NOT_FOUND)
@asyncio.coroutine
def post(self, request, entity_id):
async def post(self, request, entity_id):
"""Update state of entity."""
hass = request.app['hass']
try:
data = yield from request.json()
data = await request.json()
except ValueError:
return self.json_message('Invalid JSON specified',
HTTP_BAD_REQUEST)
return self.json_message(
"Invalid JSON specified.", HTTP_BAD_REQUEST)
new_state = data.get('state')
if new_state is None:
return self.json_message('No state specified', HTTP_BAD_REQUEST)
return self.json_message("No state specified.", HTTP_BAD_REQUEST)
attributes = data.get('attributes')
force_update = data.get('force_update', False)
@@ -222,7 +222,8 @@ class APIEntityStateView(HomeAssistantView):
is_new_state = hass.states.get(entity_id) is None
# Write state
hass.states.async_set(entity_id, new_state, attributes, force_update)
hass.states.async_set(entity_id, new_state, attributes, force_update,
self.context(request))
# Read the state back for our response
status_code = HTTP_CREATED if is_new_state else 200
@@ -236,15 +237,15 @@ class APIEntityStateView(HomeAssistantView):
def delete(self, request, entity_id):
"""Remove entity."""
if request.app['hass'].states.async_remove(entity_id):
return self.json_message('Entity removed')
return self.json_message('Entity not found', HTTP_NOT_FOUND)
return self.json_message("Entity removed.")
return self.json_message("Entity not found.", HTTP_NOT_FOUND)
class APIEventListenersView(HomeAssistantView):
"""View to handle EventListeners requests."""
url = URL_API_EVENTS
name = "api:event-listeners"
name = 'api:event-listeners'
@ha.callback
def get(self, request):
@@ -256,21 +257,20 @@ class APIEventView(HomeAssistantView):
"""View to handle Event requests."""
url = '/api/events/{event_type}'
name = "api:event"
name = 'api:event'
@asyncio.coroutine
def post(self, request, event_type):
async def post(self, request, event_type):
"""Fire events."""
body = yield from request.text()
body = await request.text()
try:
event_data = json.loads(body) if body else None
except ValueError:
return self.json_message('Event data should be valid JSON',
HTTP_BAD_REQUEST)
return self.json_message(
"Event data should be valid JSON.", HTTP_BAD_REQUEST)
if event_data is not None and not isinstance(event_data, dict):
return self.json_message('Event data should be a JSON object',
HTTP_BAD_REQUEST)
return self.json_message(
"Event data should be a JSON object", HTTP_BAD_REQUEST)
# Special case handling for event STATE_CHANGED
# We will try to convert state dicts back to State objects
@@ -281,8 +281,9 @@ class APIEventView(HomeAssistantView):
if state:
event_data[key] = state
request.app['hass'].bus.async_fire(event_type, event_data,
ha.EventOrigin.remote)
request.app['hass'].bus.async_fire(
event_type, event_data, ha.EventOrigin.remote,
self.context(request))
return self.json_message("Event {} fired.".format(event_type))
@@ -291,37 +292,36 @@ class APIServicesView(HomeAssistantView):
"""View to handle Services requests."""
url = URL_API_SERVICES
name = "api:services"
name = 'api:services'
@asyncio.coroutine
def get(self, request):
async def get(self, request):
"""Get registered services."""
services = yield from async_services_json(request.app['hass'])
services = await async_services_json(request.app['hass'])
return self.json(services)
class APIDomainServicesView(HomeAssistantView):
"""View to handle DomainServices requests."""
url = "/api/services/{domain}/{service}"
name = "api:domain-services"
url = '/api/services/{domain}/{service}'
name = 'api:domain-services'
@asyncio.coroutine
def post(self, request, domain, service):
async def post(self, request, domain, service):
"""Call a service.
Returns a list of changed states.
"""
hass = request.app['hass']
body = yield from request.text()
body = await request.text()
try:
data = json.loads(body) if body else None
except ValueError:
return self.json_message('Data should be valid JSON',
HTTP_BAD_REQUEST)
return self.json_message(
"Data should be valid JSON.", HTTP_BAD_REQUEST)
with AsyncTrackStates(hass) as changed_states:
yield from hass.services.async_call(domain, service, data, True)
await hass.services.async_call(
domain, service, data, True, self.context(request))
return self.json(changed_states)
@@ -330,7 +330,7 @@ class APIComponentsView(HomeAssistantView):
"""View to handle Components requests."""
url = URL_API_COMPONENTS
name = "api:components"
name = 'api:components'
@ha.callback
def get(self, request):
@@ -339,32 +339,41 @@ class APIComponentsView(HomeAssistantView):
class APITemplateView(HomeAssistantView):
"""View to handle requests."""
"""View to handle Template requests."""
url = URL_API_TEMPLATE
name = "api:template"
name = 'api:template'
@asyncio.coroutine
def post(self, request):
async def post(self, request):
"""Render a template."""
try:
data = yield from request.json()
data = await request.json()
tpl = template.Template(data['template'], request.app['hass'])
return tpl.async_render(data.get('variables'))
except (ValueError, TemplateError) as ex:
return self.json_message('Error rendering template: {}'.format(ex),
HTTP_BAD_REQUEST)
return self.json_message(
"Error rendering template: {}".format(ex), HTTP_BAD_REQUEST)
@asyncio.coroutine
def async_services_json(hass):
class APIErrorLog(HomeAssistantView):
"""View to fetch the API error log."""
url = URL_API_ERROR_LOG
name = 'api:error_log'
async def get(self, request):
"""Retrieve API error log."""
return web.FileResponse(request.app['hass'].data[DATA_LOGGING])
async def async_services_json(hass):
"""Generate services data to JSONify."""
descriptions = yield from async_get_all_descriptions(hass)
return [{"domain": key, "services": value}
descriptions = await async_get_all_descriptions(hass)
return [{'domain': key, 'services': value}
for key, value in descriptions.items()]
def async_events_json(hass):
"""Generate event data to JSONify."""
return [{"event": key, "listener_count": value}
return [{'event': key, 'listener_count': value}
for key, value in hass.bus.async_listeners().items()]

View File

@@ -6,7 +6,6 @@ https://home-assistant.io/components/apple_tv/
"""
import asyncio
import logging
from typing import Sequence, TypeVar, Union
import voluptuous as vol
@@ -17,7 +16,7 @@ from homeassistant.helpers import discovery
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyatv==0.3.9']
REQUIREMENTS = ['pyatv==0.3.10']
_LOGGER = logging.getLogger(__name__)
@@ -45,7 +44,7 @@ NOTIFICATION_AUTH_TITLE = 'Apple TV Authentication'
NOTIFICATION_SCAN_ID = 'apple_tv_scan_notification'
NOTIFICATION_SCAN_TITLE = 'Apple TV Scan'
T = TypeVar('T')
T = TypeVar('T') # pylint: disable=invalid-name
# This version of ensure_list interprets an empty dict as no value
@@ -78,14 +77,13 @@ def request_configuration(hass, config, atv, credentials):
"""Request configuration steps from the user."""
configurator = hass.components.configurator
@asyncio.coroutine
def configuration_callback(callback_data):
async def configuration_callback(callback_data):
"""Handle the submitted configuration."""
from pyatv import exceptions
pin = callback_data.get('pin')
try:
yield from atv.airplay.finish_authentication(pin)
await atv.airplay.finish_authentication(pin)
hass.components.persistent_notification.async_create(
'Authentication succeeded!<br /><br />Add the following '
'to credentials: in your apple_tv configuration:<br /><br />'
@@ -109,11 +107,10 @@ def request_configuration(hass, config, atv, credentials):
)
@asyncio.coroutine
def scan_for_apple_tvs(hass):
async def scan_for_apple_tvs(hass):
"""Scan for devices and present a notification of the ones found."""
import pyatv
atvs = yield from pyatv.scan_for_apple_tvs(hass.loop, timeout=3)
atvs = await pyatv.scan_for_apple_tvs(hass.loop, timeout=3)
devices = []
for atv in atvs:
@@ -133,14 +130,12 @@ def scan_for_apple_tvs(hass):
notification_id=NOTIFICATION_SCAN_ID)
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Set up the Apple TV component."""
if DATA_APPLE_TV not in hass.data:
hass.data[DATA_APPLE_TV] = {}
@asyncio.coroutine
def async_service_handler(service):
async def async_service_handler(service):
"""Handle service calls."""
entity_ids = service.data.get(ATTR_ENTITY_ID)
@@ -159,17 +154,16 @@ def async_setup(hass, config):
continue
atv = device.atv
credentials = yield from atv.airplay.generate_credentials()
yield from atv.airplay.load_credentials(credentials)
credentials = await atv.airplay.generate_credentials()
await atv.airplay.load_credentials(credentials)
_LOGGER.debug('Generated new credentials: %s', credentials)
yield from atv.airplay.start_authentication()
await atv.airplay.start_authentication()
hass.async_add_job(request_configuration,
hass, config, atv, credentials)
@asyncio.coroutine
def atv_discovered(service, info):
async def atv_discovered(service, info):
"""Set up an Apple TV that was auto discovered."""
yield from _setup_atv(hass, {
await _setup_atv(hass, {
CONF_NAME: info['name'],
CONF_HOST: info['host'],
CONF_LOGIN_ID: info['properties']['hG'],
@@ -180,7 +174,7 @@ def async_setup(hass, config):
tasks = [_setup_atv(hass, conf) for conf in config.get(DOMAIN, [])]
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
await asyncio.wait(tasks, loop=hass.loop)
hass.services.async_register(
DOMAIN, SERVICE_SCAN, async_service_handler,
@@ -193,8 +187,7 @@ def async_setup(hass, config):
return True
@asyncio.coroutine
def _setup_atv(hass, atv_config):
async def _setup_atv(hass, atv_config):
"""Set up an Apple TV."""
import pyatv
name = atv_config.get(CONF_NAME)
@@ -210,7 +203,7 @@ def _setup_atv(hass, atv_config):
session = async_get_clientsession(hass)
atv = pyatv.connect_to_apple_tv(details, hass.loop, session=session)
if credentials:
yield from atv.airplay.load_credentials(credentials)
await atv.airplay.load_credentials(credentials)
power = AppleTVPowerManager(hass, atv, start_off)
hass.data[DATA_APPLE_TV][host] = {
@@ -218,10 +211,10 @@ def _setup_atv(hass, atv_config):
ATTR_POWER: power
}
hass.async_add_job(discovery.async_load_platform(
hass.async_create_task(discovery.async_load_platform(
hass, 'media_player', DOMAIN, atv_config))
hass.async_add_job(discovery.async_load_platform(
hass.async_create_task(discovery.async_load_platform(
hass, 'remote', DOMAIN, atv_config))
@@ -259,4 +252,4 @@ class AppleTVPowerManager:
self.atv.push_updater.start()
for listener in self.listeners:
self.hass.async_add_job(listener.async_update_ha_state())
self.hass.async_create_task(listener.async_update_ha_state())

View File

@@ -0,0 +1,95 @@
"""
Support for AquaLogic component.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/aqualogic/
"""
from datetime import timedelta
import logging
import time
import threading
import voluptuous as vol
from homeassistant.const import (CONF_HOST, CONF_PORT,
EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP)
from homeassistant.helpers import config_validation as cv
REQUIREMENTS = ["aqualogic==1.0"]
_LOGGER = logging.getLogger(__name__)
DOMAIN = "aqualogic"
UPDATE_TOPIC = DOMAIN + "_update"
CONF_UNIT = "unit"
RECONNECT_INTERVAL = timedelta(seconds=10)
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PORT): cv.port
}),
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Set up AquaLogic platform."""
host = config[DOMAIN][CONF_HOST]
port = config[DOMAIN][CONF_PORT]
processor = AquaLogicProcessor(hass, host, port)
hass.data[DOMAIN] = processor
hass.bus.listen_once(EVENT_HOMEASSISTANT_START,
processor.start_listen)
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP,
processor.shutdown)
_LOGGER.debug("AquaLogicProcessor %s:%i initialized", host, port)
return True
class AquaLogicProcessor(threading.Thread):
"""AquaLogic event processor thread."""
def __init__(self, hass, host, port):
"""Initialize the data object."""
super().__init__(daemon=True)
self._hass = hass
self._host = host
self._port = port
self._shutdown = False
self._panel = None
def start_listen(self, event):
"""Start event-processing thread."""
_LOGGER.debug("Event processing thread started")
self.start()
def shutdown(self, event):
"""Signal shutdown of processing event."""
_LOGGER.debug("Event processing signaled exit")
self._shutdown = True
def data_changed(self, panel):
"""Aqualogic data changed callback."""
self._hass.helpers.dispatcher.dispatcher_send(UPDATE_TOPIC)
def run(self):
"""Event thread."""
from aqualogic.core import AquaLogic
while True:
self._panel = AquaLogic()
self._panel.connect(self._host, self._port)
self._panel.process(self.data_changed)
if self._shutdown:
return
_LOGGER.error("Connection to %s:%d lost",
self._host, self._port)
time.sleep(RECONNECT_INTERVAL.seconds)
@property
def panel(self):
"""Retrieve the AquaLogic object."""
return self._panel

View File

@@ -62,7 +62,7 @@ def setup(hass, config):
return True
class ArduinoBoard(object):
class ArduinoBoard:
"""Representation of an Arduino board."""
def __init__(self, port):

View File

@@ -5,14 +5,18 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/arlo/
"""
import logging
from datetime import timedelta
import voluptuous as vol
from requests.exceptions import HTTPError, ConnectTimeout
from homeassistant.helpers import config_validation as cv
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD
from homeassistant.const import (
CONF_USERNAME, CONF_PASSWORD, CONF_SCAN_INTERVAL)
from homeassistant.helpers.event import track_time_interval
from homeassistant.helpers.dispatcher import dispatcher_send
REQUIREMENTS = ['pyarlo==0.1.2']
REQUIREMENTS = ['pyarlo==0.2.0']
_LOGGER = logging.getLogger(__name__)
@@ -25,10 +29,16 @@ DOMAIN = 'arlo'
NOTIFICATION_ID = 'arlo_notification'
NOTIFICATION_TITLE = 'Arlo Component Setup'
SCAN_INTERVAL = timedelta(seconds=60)
SIGNAL_UPDATE_ARLO = "arlo_update"
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL):
cv.time_period,
}),
}, extra=vol.ALLOW_EXTRA)
@@ -38,6 +48,7 @@ def setup(hass, config):
conf = config[DOMAIN]
username = conf.get(CONF_USERNAME)
password = conf.get(CONF_PASSWORD)
scan_interval = conf.get(CONF_SCAN_INTERVAL)
try:
from pyarlo import PyArlo
@@ -45,7 +56,19 @@ def setup(hass, config):
arlo = PyArlo(username, password, preload=False)
if not arlo.is_connected:
return False
# assign refresh period to base station thread
arlo_base_station = next((
station for station in arlo.base_stations), None)
if arlo_base_station is not None:
arlo_base_station.refresh_rate = scan_interval.total_seconds()
elif not arlo.cameras:
_LOGGER.error("No Arlo camera or base station available.")
return False
hass.data[DATA_ARLO] = arlo
except (ConnectTimeout, HTTPError) as ex:
_LOGGER.error("Unable to connect to Netgear Arlo: %s", str(ex))
hass.components.persistent_notification.create(
@@ -55,4 +78,17 @@ def setup(hass, config):
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
def hub_refresh(event_time):
"""Call ArloHub to refresh information."""
_LOGGER.info("Updating Arlo Hub component")
hass.data[DATA_ARLO].update(update_cameras=True,
update_base_station=True)
dispatcher_send(hass, SIGNAL_UPDATE_ARLO)
# register service
hass.services.register(DOMAIN, 'update', hub_refresh)
# register scan interval for ArloHub
track_time_interval(hass, hub_refresh, scan_interval)
return True

View File

@@ -13,16 +13,19 @@ from homeassistant.core import callback
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, async_dispatcher_send)
async_dispatcher_send, dispatcher_connect)
REQUIREMENTS = ['asterisk_mbox==0.4.0']
REQUIREMENTS = ['asterisk_mbox==0.5.0']
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'asterisk_mbox'
SIGNAL_DISCOVER_PLATFORM = "asterisk_mbox.discover_platform"
SIGNAL_MESSAGE_REQUEST = 'asterisk_mbox.message_request'
SIGNAL_MESSAGE_UPDATE = 'asterisk_mbox.message_updated'
SIGNAL_CDR_UPDATE = 'asterisk_mbox.message_updated'
SIGNAL_CDR_REQUEST = 'asterisk_mbox.message_request'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
@@ -41,41 +44,79 @@ def setup(hass, config):
port = conf.get(CONF_PORT)
password = conf.get(CONF_PASSWORD)
hass.data[DOMAIN] = AsteriskData(hass, host, port, password)
discovery.load_platform(hass, 'mailbox', DOMAIN, {}, config)
hass.data[DOMAIN] = AsteriskData(hass, host, port, password, config)
return True
class AsteriskData(object):
class AsteriskData:
"""Store Asterisk mailbox data."""
def __init__(self, hass, host, port, password):
def __init__(self, hass, host, port, password, config):
"""Init the Asterisk data object."""
from asterisk_mbox import Client as asteriskClient
self.hass = hass
self.client = asteriskClient(host, port, password, self.handle_data)
self.messages = []
self.config = config
self.messages = None
self.cdr = None
async_dispatcher_connect(
dispatcher_connect(
self.hass, SIGNAL_MESSAGE_REQUEST, self._request_messages)
dispatcher_connect(
self.hass, SIGNAL_CDR_REQUEST, self._request_cdr)
dispatcher_connect(
self.hass, SIGNAL_DISCOVER_PLATFORM, self._discover_platform)
# Only connect after signal connection to ensure we don't miss any
self.client = asteriskClient(host, port, password, self.handle_data)
@callback
def _discover_platform(self, component):
_LOGGER.debug("Adding mailbox %s", component)
self.hass.async_create_task(discovery.async_load_platform(
self.hass, "mailbox", component, {}, self.config))
@callback
def handle_data(self, command, msg):
"""Handle changes to the mailbox."""
from asterisk_mbox.commands import CMD_MESSAGE_LIST
from asterisk_mbox.commands import (CMD_MESSAGE_LIST,
CMD_MESSAGE_CDR_AVAILABLE,
CMD_MESSAGE_CDR)
if command == CMD_MESSAGE_LIST:
_LOGGER.debug("AsteriskVM sent updated message list")
_LOGGER.debug("AsteriskVM sent updated message list: Len %d",
len(msg))
old_messages = self.messages
self.messages = sorted(
msg, key=lambda item: item['info']['origtime'], reverse=True)
async_dispatcher_send(
self.hass, SIGNAL_MESSAGE_UPDATE, self.messages)
if not isinstance(old_messages, list):
async_dispatcher_send(self.hass, SIGNAL_DISCOVER_PLATFORM,
DOMAIN)
async_dispatcher_send(self.hass, SIGNAL_MESSAGE_UPDATE,
self.messages)
elif command == CMD_MESSAGE_CDR:
_LOGGER.debug("AsteriskVM sent updated CDR list: Len %d",
len(msg.get('entries', [])))
self.cdr = msg['entries']
async_dispatcher_send(self.hass, SIGNAL_CDR_UPDATE, self.cdr)
elif command == CMD_MESSAGE_CDR_AVAILABLE:
if not isinstance(self.cdr, list):
_LOGGER.debug("AsteriskVM adding CDR platform")
self.cdr = []
async_dispatcher_send(self.hass, SIGNAL_DISCOVER_PLATFORM,
"asterisk_cdr")
async_dispatcher_send(self.hass, SIGNAL_CDR_REQUEST)
else:
_LOGGER.debug("AsteriskVM sent unknown message '%d' len: %d",
command, len(msg))
@callback
def _request_messages(self):
"""Handle changes to the mailbox."""
_LOGGER.debug("Requesting message list")
self.client.messages()
@callback
def _request_cdr(self):
"""Handle changes to the CDR."""
_LOGGER.debug("Requesting CDR list")
self.client.get_cdr()

View File

@@ -21,7 +21,7 @@ _LOGGER = logging.getLogger(__name__)
_CONFIGURING = {}
REQUIREMENTS = ['py-august==0.4.0']
REQUIREMENTS = ['py-august==0.6.0']
DEFAULT_TIMEOUT = 10
ACTIVITY_FETCH_LIMIT = 10
@@ -123,9 +123,9 @@ def setup_august(hass, config, api, authenticator):
discovery.load_platform(hass, component, DOMAIN, {}, config)
return True
elif state == AuthenticationState.BAD_PASSWORD:
if state == AuthenticationState.BAD_PASSWORD:
return False
elif state == AuthenticationState.REQUIRES_VALIDATION:
if state == AuthenticationState.REQUIRES_VALIDATION:
request_configuration(hass, config, api, authenticator)
return True

View File

@@ -0,0 +1,7 @@
{
"mfa_setup": {
"totp": {
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "No hi ha serveis de notificaci\u00f3 disponibles."
},
"error": {
"invalid_code": "Codi inv\u00e0lid, si us plau torni a provar-ho."
},
"step": {
"init": {
"description": "Seleccioneu un dels serveis de notificaci\u00f3:",
"title": "Configureu una contrasenya d'un sol \u00fas a trav\u00e9s del component de notificacions"
},
"setup": {
"description": "**notify.{notify_service}** ha enviat una contrasenya d'un sol \u00fas. Introdu\u00efu-la a continuaci\u00f3:",
"title": "Verifiqueu la configuraci\u00f3"
}
},
"title": "Contrasenya d'un sol \u00fas del servei de notificacions"
},
"totp": {
"error": {
"invalid_code": "Codi inv\u00e0lid, si us plau torni a provar-ho. Si obteniu aquest error repetidament, assegureu-vos que la data i hora de Home Assistant sigui correcta i precisa."
},
"step": {
"init": {
"description": "Per activar la verificaci\u00f3 en dos passos mitjan\u00e7ant contrasenyes d'un sol \u00fas basades en temps, escanegeu el codi QR amb la vostre aplicaci\u00f3 de verificaci\u00f3. Si no en teniu cap, us recomanem [Google Authenticator](https://support.google.com/accounts/answer/1066447) o b\u00e9 [Authy](https://authy.com/). \n\n {qr_code} \n \nDespr\u00e9s d'escanejar el codi QR, introdu\u00efu el codi de sis d\u00edgits proporcionat per l'aplicaci\u00f3. Si teniu problemes per escanejar el codi QR, feu una configuraci\u00f3 manual amb el codi **`{code}`**.",
"title": "Configureu la verificaci\u00f3 en dos passos utilitzant TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Keine Benachrichtigungsdienste verf\u00fcgbar."
},
"error": {
"invalid_code": "Ung\u00fcltiger Code, bitte versuche es erneut."
},
"step": {
"init": {
"description": "Bitte w\u00e4hle einen der Benachrichtigungsdienste:",
"title": "Einmal Passwort f\u00fcr Notify einrichten"
},
"setup": {
"description": "Ein Einmal-Passwort wurde per ** notify gesendet. {notify_service} **. Bitte gebe es unten ein:",
"title": "\u00dcberpr\u00fcfe das Setup"
}
},
"title": "Benachrichtig f\u00fcr One-Time Password"
},
"totp": {
"error": {
"invalid_code": "Ung\u00fcltiger Code, bitte versuche es erneut. Wenn du diesen Fehler regelm\u00e4\u00dfig erhalten, stelle sicher, dass die Uhr deines Home Assistant-Systems korrekt ist."
},
"step": {
"init": {
"description": "Um die Zwei-Faktor-Authentifizierung mit zeitbasierten Einmalpassw\u00f6rtern zu aktivieren, scanne den QR-Code mit Ihrer Authentifizierungs-App. Wenn du keine hast, empfehlen wir entweder [Google Authenticator] (https://support.google.com/accounts/answer/1066447) oder [Authy] (https://authy.com/). \n\n {qr_code} \n \nNachdem du den Code gescannt hast, gebe den sechsstelligen Code aus der App ein, um das Setup zu \u00fcberpr\u00fcfen. Wenn es Probleme beim Scannen des QR-Codes gibt, f\u00fchre ein manuelles Setup mit dem Code ** ` {code} ` ** durch.",
"title": "Richte die Zwei-Faktor-Authentifizierung mit TOTP ein"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "No notification services available."
},
"error": {
"invalid_code": "Invalid code, please try again."
},
"step": {
"init": {
"description": "Please select one of the notification services:",
"title": "Set up one-time password delivered by notify component"
},
"setup": {
"description": "A one-time password has been sent via **notify.{notify_service}**. Please enter it below:",
"title": "Verify setup"
}
},
"title": "Notify One-Time Password"
},
"totp": {
"error": {
"invalid_code": "Invalid code, please try again. If you get this error consistently, please make sure the clock of your Home Assistant system is accurate."
},
"step": {
"init": {
"description": "To activate two factor authentication using time-based one-time passwords, scan the QR code with your authentication app. If you don't have one, we recommend either [Google Authenticator](https://support.google.com/accounts/answer/1066447) or [Authy](https://authy.com/).\n\n{qr_code}\n\nAfter scanning the code, enter the six digit code from your app to verify the setup. If you have problems scanning the QR code, do a manual setup with code **`{code}`**.",
"title": "Set up two-factor authentication using TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,12 @@
{
"mfa_setup": {
"totp": {
"step": {
"init": {
"title": "Configurar la autenticaci\u00f3n de dos factores mediante TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Aucun service de notification disponible."
},
"error": {
"invalid_code": "Code invalide. Veuillez essayer \u00e0 nouveau."
},
"step": {
"init": {
"description": "Veuillez s\u00e9lectionner l'un des services de notification:",
"title": "Configurer un mot de passe \u00e0 usage unique d\u00e9livr\u00e9 par le composant notify"
},
"setup": {
"description": "Un mot de passe unique a \u00e9t\u00e9 envoy\u00e9 par **notify.{notify_service}**. Veuillez le saisir ci-dessous :",
"title": "V\u00e9rifier la configuration"
}
},
"title": "Notifier un mot de passe unique"
},
"totp": {
"error": {
"invalid_code": "Code invalide. Veuillez essayez \u00e0 nouveau. Si cette erreur persiste, assurez-vous que l'horloge de votre syst\u00e8me Home Assistant est correcte."
},
"step": {
"init": {
"description": "Pour activer l'authentification \u00e0 deux facteurs \u00e0 l'aide de mots de passe \u00e0 utilisation unique bas\u00e9s sur l'heure, num\u00e9risez le code QR avec votre application d'authentification. Si vous n'en avez pas, nous vous recommandons d'utiliser [Google Authenticator] (https://support.google.com/accounts/answer/1066447) ou [Authy] (https://authy.com/). \n\n {qr_code} \n \n Apr\u00e8s avoir num\u00e9ris\u00e9 le code, entrez le code \u00e0 six chiffres de votre application pour v\u00e9rifier la configuration. Si vous rencontrez des probl\u00e8mes lors de l\u2019analyse du code QR, effectuez une configuration manuelle avec le code ** ` {code} ` **.",
"title": "Configurer une authentification \u00e0 deux facteurs \u00e0 l'aide de TOTP"
}
},
"title": "TOTP (Mot de passe \u00e0 utilisation unique bas\u00e9 sur le temps)"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "\u05d0\u05d9\u05df \u05e9\u05d9\u05e8\u05d5\u05ea\u05d9 notify \u05d6\u05de\u05d9\u05e0\u05d9\u05dd."
},
"error": {
"invalid_code": "\u05e7\u05d5\u05d3 \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9, \u05d0\u05e0\u05d0 \u05e0\u05e1\u05d4 \u05e9\u05d5\u05d1."
},
"step": {
"init": {
"description": "\u05d1\u05d7\u05e8 \u05d0\u05ea \u05d0\u05d7\u05d3 \u05de\u05e9\u05e8\u05d5\u05ea\u05d9 notify",
"title": "\u05d4\u05d2\u05d3\u05e8 \u05e1\u05d9\u05e1\u05de\u05d4 \u05d7\u05d3 \u05e4\u05e2\u05de\u05d9\u05ea \u05d4\u05e0\u05e9\u05dc\u05d7\u05ea \u05e2\u05dc \u05d9\u05d3\u05d9 \u05e8\u05db\u05d9\u05d1 notify"
},
"setup": {
"description": "\u05e1\u05d9\u05e1\u05de\u05d4 \u05d7\u05d3 \u05e4\u05e2\u05de\u05d9\u05ea \u05e0\u05e9\u05dc\u05d7\u05d4 \u05e2\u05dc \u05d9\u05d3\u05d9 **{notify_service}**. \u05d4\u05d6\u05df \u05d0\u05d5\u05ea\u05d4 \u05dc\u05de\u05d8\u05d4:",
"title": "\u05d0\u05d9\u05de\u05d5\u05ea \u05d4\u05d4\u05ea\u05e7\u05e0\u05d4"
}
},
"title": "\u05dc\u05d4\u05d5\u05d3\u05d9\u05e2 \u200b\u200b\u05e2\u05dc \u05e1\u05d9\u05e1\u05de\u05d4 \u05d7\u05d3 \u05e4\u05e2\u05de\u05d9\u05ea"
},
"totp": {
"error": {
"invalid_code": "\u05e7\u05d5\u05d3 \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9, \u05d0\u05e0\u05d0 \u05e0\u05e1\u05d4 \u05e9\u05d5\u05d1. \u05d0\u05dd \u05d0\u05ea\u05d4 \u05de\u05e7\u05d1\u05dc \u05d0\u05ea \u05d4\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d4\u05d6\u05d5 \u05d1\u05d0\u05d5\u05e4\u05df \u05e2\u05e7\u05d1\u05d9, \u05d5\u05d3\u05d0 \u05e9\u05d4\u05e9\u05e2\u05d5\u05df \u05e9\u05dc \u05de\u05e2\u05e8\u05db\u05ea \u05d4 - Home Assistant \u05e9\u05dc\u05da \u05de\u05d3\u05d5\u05d9\u05e7."
},
"step": {
"init": {
"description": "\u05db\u05d3\u05d9 \u05dc\u05d4\u05e4\u05e2\u05d9\u05dc \u05d0\u05d9\u05de\u05d5\u05ea \u05d3\u05d5 \u05e9\u05dc\u05d1\u05d9 \u05d1\u05d0\u05de\u05e6\u05e2\u05d5\u05ea \u05e1\u05d9\u05e1\u05de\u05d0\u05d5\u05ea \u05d7\u05d3 \u05e4\u05e2\u05de\u05d9\u05d5\u05ea \u05de\u05d1\u05d5\u05e1\u05e1\u05d5\u05ea \u05d6\u05de\u05df, \u05e1\u05e8\u05d5\u05e7 \u05d0\u05ea \u05e7\u05d5\u05d3 QR \u05e2\u05dd \u05d9\u05d9\u05e9\u05d5\u05dd \u05d4\u05d0\u05d9\u05de\u05d5\u05ea \u05e9\u05dc\u05da. \u05d0\u05dd \u05d0\u05d9\u05df \u05dc\u05da \u05d7\u05e9\u05d1\u05d5\u05df \u05db\u05d6\u05d4, \u05d0\u05e0\u05d5 \u05de\u05de\u05dc\u05d9\u05e6\u05d9\u05dd \u05e2\u05dc [Google Authenticator] (https://support.google.com/accounts/answer/1066447) \u05d0\u05d5 [Authy] (https://authy.com/). \n\n {qr_code} \n \n \u05dc\u05d0\u05d7\u05e8 \u05e1\u05e8\u05d9\u05e7\u05ea \u05d4\u05e7\u05d5\u05d3, \u05d4\u05d6\u05df \u05d0\u05ea \u05d4\u05e7\u05d5\u05d3 \u05d1\u05df \u05e9\u05e9 \u05d4\u05e1\u05e4\u05e8\u05d5\u05ea \u05de\u05d4\u05d0\u05e4\u05dc\u05d9\u05e7\u05e6\u05d9\u05d4 \u05e9\u05dc\u05da \u05db\u05d3\u05d9 \u05dc\u05d0\u05de\u05ea \u05d0\u05ea \u05d4\u05d4\u05d2\u05d3\u05e8\u05d4. \u05d0\u05dd \u05d0\u05ea\u05d4 \u05e0\u05ea\u05e7\u05dc \u05d1\u05d1\u05e2\u05d9\u05d5\u05ea \u05d1\u05e1\u05e8\u05d9\u05e7\u05ea \u05e7\u05d5\u05d3 QR, \u05d1\u05e6\u05e2 \u05d4\u05d2\u05d3\u05e8\u05d4 \u05d9\u05d3\u05e0\u05d9\u05ea \u05e2\u05dd \u05e7\u05d5\u05d3 **`{code}`**.",
"title": "\u05d4\u05d2\u05d3\u05e8 \u05d0\u05d9\u05de\u05d5\u05ea \u05d3\u05d5 \u05e9\u05dc\u05d1\u05d9 \u05d1\u05d0\u05de\u05e6\u05e2\u05d5\u05ea TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,32 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Nincs el\u00e9rhet\u0151 \u00e9rtes\u00edt\u00e9si szolg\u00e1ltat\u00e1s."
},
"error": {
"invalid_code": "\u00c9rv\u00e9nytelen k\u00f3d, pr\u00f3b\u00e1ld \u00fajra."
},
"step": {
"init": {
"description": "V\u00e1lassz \u00e9rtes\u00edt\u00e9si szolg\u00e1ltat\u00e1st:"
},
"setup": {
"title": "Be\u00e1ll\u00edt\u00e1s ellen\u0151rz\u00e9se"
}
}
},
"totp": {
"error": {
"invalid_code": "\u00c9rv\u00e9nytelen k\u00f3d, pr\u00f3b\u00e1ld \u00fajra. Ha ez a hiba folyamatosan el\u0151fordul, akkor gy\u0151z\u0151dj meg r\u00f3la, hogy a Home Assistant rendszered \u00f3r\u00e1ja pontosan j\u00e1r."
},
"step": {
"init": {
"description": "Ahhoz, hogy haszn\u00e1lhasd a k\u00e9tfaktoros hiteles\u00edt\u00e9st id\u0151alap\u00fa egyszeri jelszavakkal, szkenneld be a QR k\u00f3dot a hiteles\u00edt\u00e9si applik\u00e1ci\u00f3ddal. Ha m\u00e9g nincsen, akkor a [Google Hiteles\u00edt\u0151](https://support.google.com/accounts/answer/1066447)t vagy az [Authy](https://authy.com/)-t aj\u00e1nljuk.\n\n{qr_code}\n\nA k\u00f3d beolvas\u00e1sa ut\u00e1n add meg a hat sz\u00e1mjegy\u0171 k\u00f3dot az applik\u00e1ci\u00f3b\u00f3l a telep\u00edt\u00e9s ellen\u0151rz\u00e9s\u00e9hez. Ha probl\u00e9m\u00e1ba \u00fctk\u00f6z\u00f6l a QR k\u00f3d beolvas\u00e1s\u00e1n\u00e1l, akkor ind\u00edts egy k\u00e9zi be\u00e1ll\u00edt\u00e1st a **`{code}`** k\u00f3ddal.",
"title": "K\u00e9tfaktoros hiteles\u00edt\u00e9s be\u00e1ll\u00edt\u00e1sa TOTP haszn\u00e1lat\u00e1val"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,16 @@
{
"mfa_setup": {
"totp": {
"error": {
"invalid_code": "Kode salah, coba lagi. Jika Anda mendapatkan kesalahan ini secara konsisten, pastikan jam pada sistem Home Assistant anda akurat."
},
"step": {
"init": {
"description": "Untuk mengaktifkan otentikasi dua faktor menggunakan password satu kali berbasis waktu, pindai kode QR dengan aplikasi otentikasi Anda. Jika Anda tidak memilikinya, kami menyarankan [Google Authenticator] (https://support.google.com/accounts/answer/1066447) atau [Authy] (https://authy.com/). \n\n {qr_code} \n \n Setelah memindai kode, masukkan kode enam digit dari aplikasi Anda untuk memverifikasi pengaturan. Jika Anda mengalami masalah saat memindai kode QR, lakukan pengaturan manual dengan kode ** ` {code} ` **.",
"title": "Siapkan otentikasi dua faktor menggunakan TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,13 @@
{
"mfa_setup": {
"totp": {
"step": {
"init": {
"description": "Per attivare l'autenticazione a due fattori utilizzando password monouso basate sul tempo, eseguire la scansione del codice QR con l'app di autenticazione. Se non ne hai uno, ti consigliamo [Google Authenticator] (https://support.google.com/accounts/answer/1066447) o [Authy] (https://authy.com/). \n\n {qr_code} \n \n Dopo aver scansionato il codice, inserisci il codice a sei cifre dalla tua app per verificare la configurazione. Se riscontri problemi con la scansione del codice QR, esegui una configurazione manuale con codice ** ` {code} ` **.",
"title": "Imposta l'autenticazione a due fattori usando TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "\uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc54c\ub9bc \uc11c\ube44\uc2a4\uac00 \uc5c6\uc2b5\ub2c8\ub2e4."
},
"error": {
"invalid_code": "\uc798\ubabb\ub41c \ucf54\ub4dc\uc785\ub2c8\ub2e4. \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694."
},
"step": {
"init": {
"description": "\uc54c\ub9bc \uc11c\ube44\uc2a4 \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud574\uc8fc\uc138\uc694:",
"title": "\uc54c\ub9bc \uad6c\uc131\uc694\uc18c\uac00 \uc81c\uacf5\ud558\ub294 \uc77c\ud68c\uc6a9 \ube44\ubc00\ubc88\ud638 \uc124\uc815"
},
"setup": {
"description": "**notify.{notify_service}** \uc5d0\uc11c \uc77c\ud68c\uc6a9 \ube44\ubc00\ubc88\ud638\ub97c \ubcf4\ub0c8\uc2b5\ub2c8\ub2e4. \uc544\ub798\uc758 \uacf5\ub780\uc5d0 \uc785\ub825\ud574 \uc8fc\uc138\uc694:",
"title": "\uc124\uc815 \ud655\uc778"
}
},
"title": "\uc77c\ud68c\uc6a9 \ube44\ubc00\ubc88\ud638 \uc54c\ub9bc"
},
"totp": {
"error": {
"invalid_code": "\uc798\ubabb\ub41c \ucf54\ub4dc \uc785\ub2c8\ub2e4. \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694. \uc774 \uc624\ub958\uac00 \uc9c0\uc18d\uc801\uc73c\ub85c \ubc1c\uc0dd\ud55c\ub2e4\uba74 Home Assistant \uc758 \uc2dc\uac04\uc124\uc815\uc774 \uc62c\ubc14\ub978\uc9c0 \ud655\uc778\ud574\ubcf4\uc138\uc694."
},
"step": {
"init": {
"description": "\uc2dc\uac04 \uae30\ubc18\uc758 \uc77c\ud68c\uc6a9 \ube44\ubc00\ubc88\ud638\ub97c \uc0ac\uc6a9\ud558\ub294 2\ub2e8\uacc4 \uc778\uc99d\uc744 \ud558\ub824\uba74 \uc778\uc99d\uc6a9 \uc571\uc744 \uc774\uc6a9\ud574\uc11c QR \ucf54\ub4dc\ub97c \uc2a4\uce94\ud574 \uc8fc\uc138\uc694. \uc778\uc99d\uc6a9 \uc571\uc740 [Google OTP](https://support.google.com/accounts/answer/1066447) \ub610\ub294 [Authy](https://authy.com/) \ub97c \ucd94\ucc9c\ub4dc\ub9bd\ub2c8\ub2e4.\n\n{qr_code}\n\n\uc2a4\uce94 \ud6c4\uc5d0 \uc0dd\uc131\ub41c 6\uc790\ub9ac \ucf54\ub4dc\ub97c \uc785\ub825\ud574\uc11c \uc124\uc815\uc744 \ud655\uc778\ud558\uc138\uc694. QR \ucf54\ub4dc \uc2a4\uce94\uc5d0 \ubb38\uc81c\uac00 \uc788\ub2e4\uba74, **`{code}`** \ucf54\ub4dc\ub85c \uc9c1\uc811 \uc124\uc815\ud574\ubcf4\uc138\uc694.",
"title": "TOTP \ub97c \uc0ac\uc6a9\ud558\uc5ec 2\ub2e8\uacc4 \uc778\uc99d \uad6c\uc131"
}
},
"title": "TOTP (\uc2dc\uac04 \uae30\ubc18 OTP)"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Keen Notifikatioun's D\u00e9ngscht disponibel."
},
"error": {
"invalid_code": "Ong\u00ebltege Code, prob\u00e9iert w.e.g. nach emol."
},
"step": {
"init": {
"description": "Wielt w.e.g. een Notifikatioun's D\u00e9ngscht aus:",
"title": "Eemolegt Passwuert ariichte wat vun engem Notifikatioun's Komponente versch\u00e9ckt g\u00ebtt"
},
"setup": {
"description": "Een eemolegt Passwuert ass vun **notify.{notify_service}** gesch\u00e9ckt ginn. Gitt et w.e.g hei \u00ebnnen dr\u00ebnner an:",
"title": "Astellungen iwwerpr\u00e9iwen"
}
},
"title": "Eemolegt Passwuert Notifikatioun"
},
"totp": {
"error": {
"invalid_code": "Ong\u00ebltege Login, prob\u00e9iert w.e.g. nach emol. Falls d\u00ebse Feeler Message \u00ebmmer er\u00ebm optr\u00ebtt dann iwwerpr\u00e9ift op d'Z\u00e4it vum Home Assistant System richteg ass."
},
"step": {
"init": {
"description": "Fir d'Zwee-Faktor-Authentifikatioun m\u00ebttels engem Z\u00e4it bas\u00e9ierten eemolege Passwuert z'aktiv\u00e9ieren, scannt de QR Code mat enger Authentifikatioun's App.\nFalls dir keng hutt, recommand\u00e9iere mir entweder [Google Authenticator](https://support.google.com/accounts/answer/1066447) oder [Authy](https://authy.com/).\n\n{qr_code}\n\nNodeems de Code gescannt ass, gitt de sechs stellege Code vun der App a fir d'Konfiguratioun z'iwwerpr\u00e9iwen. Am Fall vu Problemer fir de QR Code ze scannen, gitt de folgende Code **`{code}`** a fir ee manuelle Setup.",
"title": "Zwee Faktor Authentifikatioun mat TOTP konfigur\u00e9ieren"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Geen meldingsservices beschikbaar."
},
"error": {
"invalid_code": "Ongeldige code, probeer opnieuw."
},
"step": {
"init": {
"description": "Selecteer een van de meldingsdiensten:",
"title": "Stel een \u00e9\u00e9nmalig wachtwoord in dat wordt afgegeven door een meldingscomponent"
},
"setup": {
"description": "Een \u00e9\u00e9nmalig wachtwoord is verzonden via **notify. {notify_service}**. Voer het hieronder in:",
"title": "Controleer de instellingen"
}
},
"title": "Eenmalig wachtwoord melden"
},
"totp": {
"error": {
"invalid_code": "Ongeldige code, probeer het opnieuw. Als u deze fout blijft krijgen, controleer dan of de klok van uw Home Assistant systeem correct is ingesteld."
},
"step": {
"init": {
"description": "Voor het activeren van twee-factor-authenticatie via tijdgebonden eenmalige wachtwoorden: scan de QR code met uw authenticatie-app. Als u nog geen app heeft, adviseren we [Google Authenticator (https://support.google.com/accounts/answer/1066447) of [Authy](https://authy.com/).\n\n{qr_code}\n\nNa het scannen van de code voert u de zescijferige code uit uw app in om de instelling te controleren. Als u problemen heeft met het scannen van de QR-code, voert u een handmatige configuratie uit met code **`{code}`**.",
"title": "Configureer twee-factor-authenticatie via TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,16 @@
{
"mfa_setup": {
"totp": {
"error": {
"invalid_code": "Ugyldig kode, pr\u00f8v igjen. Dersom du heile tida f\u00e5r denne feilen, m\u00e5 du s\u00f8rge for at klokka p\u00e5 Home Assistant-systemet ditt er n\u00f8yaktig."
},
"step": {
"init": {
"description": "For \u00e5 aktivere tofaktorautentisering ved hjelp av tidsbaserte eingangspassord, skann QR-koden med autentiseringsappen din. Dersom du ikkje har ein, vil vi r\u00e5de deg til \u00e5 bruke anten [Google Authenticator] (https://support.google.com/accounts/answer/1066447) eller [Authy] (https://authy.com/). \n\n {qr_code} \n \nN\u00e5r du har skanna koda, skriv du inn den sekssifra koda fr\u00e5 appen din for \u00e5 stadfeste oppsettet. Dersom du har problemer med \u00e5 skanne QR-koda, gjer du eit manuelt oppsett med kode ** ` {code} ` **.",
"title": "Konfigurer to-faktor-autentisering ved hjelp av TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Ingen varslingstjenester er tilgjengelig."
},
"error": {
"invalid_code": "Ugyldig kode, vennligst pr\u00f8v igjen."
},
"step": {
"init": {
"description": "Vennligst velg en av varslingstjenestene:",
"title": "Sett opp engangspassord levert av varsel komponent"
},
"setup": {
"description": "Et engangspassord har blitt sendt via **notify.{notify_service}**. Vennligst skriv det inn nedenfor:",
"title": "Bekreft oppsettet"
}
},
"title": "Varsle engangspassord"
},
"totp": {
"error": {
"invalid_code": "Ugyldig kode, pr\u00f8v igjen. Hvis du f\u00e5r denne feilen konsekvent, m\u00e5 du s\u00f8rge for at klokken p\u00e5 Home Assistant systemet er riktig."
},
"step": {
"init": {
"description": "For \u00e5 aktivere tofaktorautentisering ved hjelp av tidsbaserte engangspassord, skann QR-koden med autentiseringsappen din. Hvis du ikke har en, kan vi anbefale enten [Google Authenticator](https://support.google.com/accounts/answer/1066447) eller [Authy](https://authy.com/). \n\n {qr_code} \n \nEtter at du har skannet koden, skriver du inn den seks-sifrede koden fra appen din for \u00e5 kontrollere oppsettet. Dersom du har problemer med \u00e5 skanne QR-koden kan du taste inn f\u00f8lgende kode manuelt: **`{code}`**.",
"title": "Konfigurer tofaktorautentisering ved hjelp av TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Brak dost\u0119pnych us\u0142ug powiadamiania."
},
"error": {
"invalid_code": "Nieprawid\u0142owy kod, spr\u00f3buj ponownie."
},
"step": {
"init": {
"description": "Prosz\u0119 wybra\u0107 jedn\u0105 z us\u0142ugi powiadamiania:",
"title": "Skonfiguruj has\u0142o jednorazowe dostarczone przez komponent powiadomie\u0144"
},
"setup": {
"description": "Has\u0142o jednorazowe zosta\u0142o wys\u0142ane przez **notify.{notify_service}**. Wpisz je poni\u017cej:",
"title": "Sprawd\u017a konfiguracj\u0119"
}
},
"title": "Powiadomienie z has\u0142em jednorazowym"
},
"totp": {
"error": {
"invalid_code": "Nieprawid\u0142owy kod, spr\u00f3buj ponownie. Je\u015bli b\u0142\u0105d b\u0119dzie si\u0119 powtarza\u0142, upewnij si\u0119, \u017ce czas zegara systemu Home Assistant jest prawid\u0142owy."
},
"step": {
"init": {
"description": "Aby aktywowa\u0107 uwierzytelnianie dwusk\u0142adnikowe przy u\u017cyciu jednorazowych hase\u0142 opartych na czasie, zeskanuj kod QR za pomoc\u0105 aplikacji uwierzytelniaj\u0105cej. Je\u015bli jej nie masz, polecamy [Google Authenticator](https://support.google.com/accounts/answer/1066447) lub [Authy](https://authy.com/).\n\n{qr_code} \n \nPo zeskanowaniu kodu wprowad\u017a sze\u015bciocyfrowy kod z aplikacji, aby zweryfikowa\u0107 konfiguracj\u0119. Je\u015bli masz problemy z zeskanowaniem kodu QR, wykonaj r\u0119czn\u0105 konfiguracj\u0119 z kodem **`{code}`**.",
"title": "Skonfiguruj uwierzytelnianie dwusk\u0142adnikowe za pomoc\u0105 hase\u0142 jednorazowych opartych na czasie"
}
},
"title": "Has\u0142a jednorazowe oparte na czasie"
}
}
}

View File

@@ -0,0 +1,15 @@
{
"mfa_setup": {
"totp": {
"error": {
"invalid_code": "C\u00f3digo inv\u00e1lido, por favor tente novamente. Se voc\u00ea obtiver este erro de forma consistente, certifique-se de que o rel\u00f3gio do sistema Home Assistant esteja correto."
},
"step": {
"init": {
"title": "Configure a autentica\u00e7\u00e3o de dois fatores usando o TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Nenhum servi\u00e7o de notifica\u00e7\u00e3o dispon\u00edvel."
},
"error": {
"invalid_code": "C\u00f3digo inv\u00e1lido, por favor tente novamente."
},
"step": {
"init": {
"description": "Por favor, selecione um dos servi\u00e7os de notifica\u00e7\u00e3o:",
"title": "Configurar uma palavra passe entregue pela componente de notifica\u00e7\u00e3o"
},
"setup": {
"description": "Foi enviada uma palavra passe atrav\u00e9s de **notify.{notify_service}**. Por favor, insira-a:",
"title": "Verificar a configura\u00e7\u00e3o"
}
},
"title": "Notificar palavra passe de uso \u00fanico"
},
"totp": {
"error": {
"invalid_code": "C\u00f3digo inv\u00e1lido, por favor, tente novamente. Se receber este erro constantemente, por favor, certifique-se de que o rel\u00f3gio do sistema que hospeda o Home Assistent \u00e9 preciso."
},
"step": {
"init": {
"description": "Para ativar a autentica\u00e7\u00e3o com dois fatores utilizando passwords unicas temporais (OTP), ler o c\u00f3digo QR com a sua aplica\u00e7\u00e3o de autentica\u00e7\u00e3o. Se voc\u00ea n\u00e3o tiver uma, recomendamos [Google Authenticator](https://support.google.com/accounts/answer/1066447) ou [Authy](https://authy.com/).\n\n{qr_code}\n\nDepois de ler o c\u00f3digo, introduza o c\u00f3digo de seis d\u00edgitos fornecido pela sua aplica\u00e7\u00e3o para verificar a configura\u00e7\u00e3o. Se tiver problemas a ler o c\u00f3digo QR, fa\u00e7a uma configura\u00e7\u00e3o manual com o c\u00f3digo **`{c\u00f3digo}`**.",
"title": "Configurar autentica\u00e7\u00e3o com dois fatores usando TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "\u041d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0441\u043b\u0443\u0436\u0431 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439."
},
"error": {
"invalid_code": "\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434, \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443."
},
"step": {
"init": {
"description": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043e\u0434\u043d\u0443 \u0438\u0437 \u0441\u043b\u0443\u0436\u0431 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439:",
"title": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043e\u0434\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u044b\u0445 \u043f\u0430\u0440\u043e\u043b\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439"
},
"setup": {
"description": "\u041e\u0434\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d \u0447\u0435\u0440\u0435\u0437 **notify.{notify_service}**. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0435\u0433\u043e \u043d\u0438\u0436\u0435:",
"title": "\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443"
}
},
"title": "\u0414\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u043e\u0434\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u044b\u0445 \u043f\u0430\u0440\u043e\u043b\u0435\u0439"
},
"totp": {
"error": {
"invalid_code": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430. \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0435 \u044d\u0442\u0443 \u043e\u0448\u0438\u0431\u043a\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0447\u0430\u0441\u044b \u0432 \u0432\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 Home Assistant \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f."
},
"step": {
"init": {
"description": "\u0427\u0442\u043e\u0431\u044b \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0443\u044e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0434\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u044b\u0445 \u043f\u0430\u0440\u043e\u043b\u0435\u0439, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043e\u0442\u0441\u043a\u0430\u043d\u0438\u0440\u0443\u0439\u0442\u0435 QR-\u043a\u043e\u0434 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u043e\u0434\u043b\u0438\u043d\u043d\u043e\u0441\u0442\u0438. \u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0433\u043e \u043d\u0435\u0442, \u043c\u044b \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0431\u043e [Google Authenticator](https://support.google.com/accounts/answer/1066447), \u043b\u0438\u0431\u043e [Authy](https://authy.com/). \n\n {qr_code} \n \n\u041f\u043e\u0441\u043b\u0435 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f QR-\u043a\u043e\u0434\u0430 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0448\u0435\u0441\u0442\u0438\u0437\u043d\u0430\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438\u0437 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443. \u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u043e \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c QR-\u043a\u043e\u0434\u0430, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0434\u0430 **`{code}`**.",
"title": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Ni na voljo storitev obve\u0161\u010danja."
},
"error": {
"invalid_code": "Neveljavna koda, poskusite znova."
},
"step": {
"init": {
"description": "Prosimo, izberite eno od storitev obve\u0161\u010danja:",
"title": "Nastavite enkratno geslo, ki ga dostavite z obvestilno komponento"
},
"setup": {
"description": "Enkratno geslo je poslal **notify.{notify_service} **. Vnesite ga spodaj:",
"title": "Preverite nastavitev"
}
},
"title": "Obvesti Enkratno Geslo"
},
"totp": {
"error": {
"invalid_code": "Neveljavna koda, prosimo, poskusite znova. \u010ce dobite to sporo\u010dilo ve\u010dkrat, prosimo poskrbite, da bo ura va\u0161ega Home Assistenta to\u010dna."
},
"step": {
"init": {
"description": "\u010ce \u017eelite aktivirati preverjanje pristnosti dveh faktorjev z enkratnimi gesli, ki temeljijo na \u010dasu, skenirajte kodo QR s svojo aplikacijo za preverjanje pristnosti. \u010ce je nimate, priporo\u010damo bodisi [Google Authenticator] (https://support.google.com/accounts/answer/1066447) ali [Authy] (https://authy.com/). \n\n {qr_code} \n \n Po skeniranju kode vnesite \u0161estmestno kodo iz aplikacije, da preverite nastavitev. \u010ce imate te\u017eave pri skeniranju kode QR, naredite ro\u010dno nastavitev s kodo ** ` {code} ` **.",
"title": "Nastavite dvofaktorsko avtentifikacijo s pomo\u010djo TOTP-ja"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Inga tillg\u00e4ngliga meddelande tj\u00e4nster."
},
"error": {
"invalid_code": "Ogiltig kod, var god f\u00f6rs\u00f6k igen."
},
"step": {
"init": {
"description": "Var god v\u00e4lj en av notifieringstj\u00e4nsterna:",
"title": "Konfigurera ett eng\u00e5ngsl\u00f6senord levererat genom notifieringskomponenten"
},
"setup": {
"description": "Ett eng\u00e5ngsl\u00f6senord har skickats av **notify.{notify_service}**. V\u00e4nligen ange det nedan:",
"title": "Verifiera inst\u00e4llningen"
}
},
"title": "Meddela eng\u00e5ngsl\u00f6senord"
},
"totp": {
"error": {
"invalid_code": "Ogiltig kod, f\u00f6rs\u00f6k igen. Om du flera g\u00e5nger i rad f\u00e5r detta fel, se till att klockan i din Home Assistant \u00e4r korrekt inst\u00e4lld."
},
"step": {
"init": {
"description": "F\u00f6r att aktivera tv\u00e5faktorsautentisering som anv\u00e4nder tidsbaserade eng\u00e5ngsl\u00f6senord, skanna QR-koden med din autentiseringsapp. Om du inte har en, rekommenderar vi antingen [Google Authenticator] (https://support.google.com/accounts/answer/1066447) eller [Authy] (https://authy.com/). \n\n{qr_code} \n\nN\u00e4r du har skannat koden anger du den sexsiffriga koden fr\u00e5n din app f\u00f6r att verifiera inst\u00e4llningen. Om du har problem med att skanna QR-koden, g\u00f6r en manuell inst\u00e4llning med kod ** ` {code} ` **.",
"title": "St\u00e4ll in tv\u00e5faktorsautentisering med TOTP"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"mfa_setup": {
"notify": {
"error": {
"invalid_code": "\u041d\u0435\u0432\u0456\u0440\u043d\u0438\u0439 \u043a\u043e\u0434, \u0441\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0449\u0435 \u0440\u0430\u0437."
}
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "\u6ca1\u6709\u53ef\u7528\u7684\u901a\u77e5\u670d\u52a1\u3002"
},
"error": {
"invalid_code": "\u4ee3\u7801\u65e0\u6548\uff0c\u8bf7\u518d\u8bd5\u4e00\u6b21\u3002"
},
"step": {
"init": {
"description": "\u8bf7\u4ece\u4e0b\u9762\u9009\u62e9\u4e00\u4e2a\u901a\u77e5\u670d\u52a1\uff1a",
"title": "\u8bbe\u7f6e\u7531\u901a\u77e5\u7ec4\u4ef6\u4f20\u9012\u7684\u4e00\u6b21\u6027\u5bc6\u7801"
},
"setup": {
"description": "\u4e00\u6b21\u6027\u5bc6\u7801\u5df2\u7531 **notify.{notify_service}** \u53d1\u9001\u3002\u8bf7\u5728\u4e0b\u9762\u8f93\u5165\uff1a",
"title": "\u9a8c\u8bc1\u8bbe\u7f6e"
}
},
"title": "\u4e00\u6b21\u6027\u5bc6\u7801\u901a\u77e5"
},
"totp": {
"error": {
"invalid_code": "\u53e3\u4ee4\u65e0\u6548\uff0c\u8bf7\u91cd\u65b0\u8f93\u5165\u3002\u5982\u679c\u9519\u8bef\u53cd\u590d\u51fa\u73b0\uff0c\u8bf7\u786e\u4fdd Home Assistant \u7cfb\u7edf\u7684\u65f6\u95f4\u51c6\u786e\u65e0\u8bef\u3002"
},
"step": {
"init": {
"description": "\u8981\u6fc0\u6d3b\u57fa\u4e8e\u65f6\u95f4\u52a8\u6001\u53e3\u4ee4\u7684\u53cc\u91cd\u8ba4\u8bc1\uff0c\u8bf7\u7528\u8eab\u4efd\u9a8c\u8bc1\u5e94\u7528\u626b\u63cf\u4ee5\u4e0b\u4e8c\u7ef4\u7801\u3002\u5982\u679c\u60a8\u8fd8\u6ca1\u6709\u8eab\u4efd\u9a8c\u8bc1\u5e94\u7528\uff0c\u63a8\u8350\u4f7f\u7528 [Google \u8eab\u4efd\u9a8c\u8bc1\u5668](https://support.google.com/accounts/answer/1066447) \u6216 [Authy](https://authy.com/)\u3002\n\n{qr_code}\n\n\u626b\u63cf\u4e8c\u7ef4\u7801\u4ee5\u540e\uff0c\u8f93\u5165\u5e94\u7528\u4e0a\u7684\u516d\u4f4d\u6570\u5b57\u53e3\u4ee4\u6765\u9a8c\u8bc1\u914d\u7f6e\u3002\u5982\u679c\u5728\u626b\u63cf\u4e8c\u7ef4\u7801\u65f6\u9047\u5230\u95ee\u9898\uff0c\u8bf7\u4f7f\u7528\u4ee3\u7801 **`{code}`** \u624b\u52a8\u914d\u7f6e\u3002",
"title": "\u7528\u65f6\u95f4\u52a8\u6001\u53e3\u4ee4\u8bbe\u7f6e\u53cc\u91cd\u8ba4\u8bc1"
}
},
"title": "\u65f6\u95f4\u52a8\u6001\u53e3\u4ee4"
}
}
}

View File

@@ -0,0 +1,35 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "\u6c92\u6709\u53ef\u7528\u7684\u901a\u77e5\u670d\u52d9\u3002"
},
"error": {
"invalid_code": "\u9a57\u8b49\u78bc\u7121\u6548\uff0c\u8acb\u518d\u8a66\u4e00\u6b21\u3002"
},
"step": {
"init": {
"description": "\u8acb\u9078\u64c7\u4e00\u9805\u901a\u77e5\u670d\u52d9\uff1a",
"title": "\u8a2d\u5b9a\u4e00\u6b21\u6027\u5bc6\u78bc\u50b3\u9001\u7d44\u4ef6"
},
"setup": {
"description": "\u4e00\u6b21\u6027\u5bc6\u78bc\u5df2\u900f\u904e **notify.{notify_service}** \u50b3\u9001\u3002\u8acb\u65bc\u4e0b\u65b9\u8f38\u5165\uff1a",
"title": "\u9a57\u8b49\u8a2d\u5b9a"
}
},
"title": "\u901a\u77e5\u4e00\u6b21\u6027\u5bc6\u78bc"
},
"totp": {
"error": {
"invalid_code": "\u9a57\u8b49\u78bc\u7121\u6548\uff0c\u8acb\u518d\u8a66\u4e00\u6b21\u3002\u5047\u5982\u932f\u8aa4\u6301\u7e8c\u767c\u751f\uff0c\u8acb\u5148\u78ba\u5b9a\u60a8\u7684 Home Assistant \u7cfb\u7d71\u4e0a\u7684\u6642\u9593\u8a2d\u5b9a\u6b63\u78ba\u5f8c\uff0c\u518d\u8a66\u4e00\u6b21\u3002"
},
"step": {
"init": {
"description": "\u6b32\u555f\u7528\u4e00\u6b21\u6027\u4e14\u5177\u6642\u6548\u6027\u7684\u5bc6\u78bc\u4e4b\u5169\u6b65\u9a5f\u9a57\u8b49\u529f\u80fd\uff0c\u8acb\u4f7f\u7528\u60a8\u7684\u9a57\u8b49 App \u6383\u7784\u4e0b\u65b9\u7684 QR code \u3002\u5018\u82e5\u60a8\u5c1a\u672a\u5b89\u88dd\u4efb\u4f55 App\uff0c\u63a8\u85a6\u60a8\u4f7f\u7528 [Google Authenticator](https://support.google.com/accounts/answer/1066447) \u6216 [Authy](https://authy.com/)\u3002\n\n{qr_code}\n\n\u65bc\u641c\u5c0b\u4e4b\u5f8c\uff0c\u8f38\u5165 App \u4e2d\u7684\u516d\u4f4d\u6578\u5b57\u9032\u884c\u8a2d\u5b9a\u9a57\u8b49\u3002\u5047\u5982\u641c\u5c0b\u51fa\u73fe\u554f\u984c\uff0c\u8acb\u624b\u52d5\u8f38\u5165\u4ee5\u4e0b\u9a57\u8b49\u78bc **`{code}`**\u3002",
"title": "\u4f7f\u7528 TOTP \u8a2d\u5b9a\u5169\u6b65\u9a5f\u9a57\u8b49"
}
},
"title": "TOTP"
}
}
}

View File

@@ -0,0 +1,515 @@
"""Component to allow users to login and get tokens.
# POST /auth/token
This is an OAuth2 endpoint for granting tokens. We currently support the grant
types "authorization_code" and "refresh_token". Because we follow the OAuth2
spec, data should be send in formatted as x-www-form-urlencoded. Examples will
be in JSON as it's more readable.
## Grant type authorization_code
Exchange the authorization code retrieved from the login flow for tokens.
{
"client_id": "https://hassbian.local:8123/",
"grant_type": "authorization_code",
"code": "411ee2f916e648d691e937ae9344681e"
}
Return value will be the access and refresh tokens. The access token will have
a limited expiration. New access tokens can be requested using the refresh
token.
{
"access_token": "ABCDEFGH",
"expires_in": 1800,
"refresh_token": "IJKLMNOPQRST",
"token_type": "Bearer"
}
## Grant type refresh_token
Request a new access token using a refresh token.
{
"client_id": "https://hassbian.local:8123/",
"grant_type": "refresh_token",
"refresh_token": "IJKLMNOPQRST"
}
Return value will be a new access token. The access token will have
a limited expiration.
{
"access_token": "ABCDEFGH",
"expires_in": 1800,
"token_type": "Bearer"
}
## Revoking a refresh token
It is also possible to revoke a refresh token and all access tokens that have
ever been granted by that refresh token. Response code will ALWAYS be 200.
{
"token": "IJKLMNOPQRST",
"action": "revoke"
}
# Websocket API
## Get current user
Send websocket command `auth/current_user` will return current user of the
active websocket connection.
{
"id": 10,
"type": "auth/current_user",
}
The result payload likes
{
"id": 10,
"type": "result",
"success": true,
"result": {
"id": "USER_ID",
"name": "John Doe",
"is_owner': true,
"credentials": [
{
"auth_provider_type": "homeassistant",
"auth_provider_id": null
}
],
"mfa_modules": [
{
"id": "totp",
"name": "TOTP",
"enabled": true,
}
]
}
}
## Create a long-lived access token
Send websocket command `auth/long_lived_access_token` will create
a long-lived access token for current user. Access token will not be saved in
Home Assistant. User need to record the token in secure place.
{
"id": 11,
"type": "auth/long_lived_access_token",
"client_name": "GPS Logger",
"lifespan": 365
}
Result will be a long-lived access token:
{
"id": 11,
"type": "result",
"success": true,
"result": "ABCDEFGH"
}
"""
import logging
import uuid
from datetime import timedelta
from aiohttp import web
import voluptuous as vol
from homeassistant.auth.models import User, Credentials, \
TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN
from homeassistant.components import websocket_api
from homeassistant.components.http import KEY_REAL_IP
from homeassistant.components.http.ban import log_invalid_auth
from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.components.http.view import HomeAssistantView
from homeassistant.core import callback, HomeAssistant
from homeassistant.util import dt as dt_util
from . import indieauth
from . import login_flow
from . import mfa_setup_flow
DOMAIN = 'auth'
DEPENDENCIES = ['http']
WS_TYPE_CURRENT_USER = 'auth/current_user'
SCHEMA_WS_CURRENT_USER = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_CURRENT_USER,
})
WS_TYPE_LONG_LIVED_ACCESS_TOKEN = 'auth/long_lived_access_token'
SCHEMA_WS_LONG_LIVED_ACCESS_TOKEN = \
websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_LONG_LIVED_ACCESS_TOKEN,
vol.Required('lifespan'): int, # days
vol.Required('client_name'): str,
vol.Optional('client_icon'): str,
})
WS_TYPE_REFRESH_TOKENS = 'auth/refresh_tokens'
SCHEMA_WS_REFRESH_TOKENS = \
websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_REFRESH_TOKENS,
})
WS_TYPE_DELETE_REFRESH_TOKEN = 'auth/delete_refresh_token'
SCHEMA_WS_DELETE_REFRESH_TOKEN = \
websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_DELETE_REFRESH_TOKEN,
vol.Required('refresh_token_id'): str,
})
RESULT_TYPE_CREDENTIALS = 'credentials'
RESULT_TYPE_USER = 'user'
_LOGGER = logging.getLogger(__name__)
async def async_setup(hass, config):
"""Component to allow users to login."""
store_result, retrieve_result = _create_auth_code_store()
hass.http.register_view(TokenView(retrieve_result))
hass.http.register_view(LinkUserView(retrieve_result))
hass.components.websocket_api.async_register_command(
WS_TYPE_CURRENT_USER, websocket_current_user,
SCHEMA_WS_CURRENT_USER
)
hass.components.websocket_api.async_register_command(
WS_TYPE_LONG_LIVED_ACCESS_TOKEN,
websocket_create_long_lived_access_token,
SCHEMA_WS_LONG_LIVED_ACCESS_TOKEN
)
hass.components.websocket_api.async_register_command(
WS_TYPE_REFRESH_TOKENS,
websocket_refresh_tokens,
SCHEMA_WS_REFRESH_TOKENS
)
hass.components.websocket_api.async_register_command(
WS_TYPE_DELETE_REFRESH_TOKEN,
websocket_delete_refresh_token,
SCHEMA_WS_DELETE_REFRESH_TOKEN
)
await login_flow.async_setup(hass, store_result)
await mfa_setup_flow.async_setup(hass)
return True
class TokenView(HomeAssistantView):
"""View to issue or revoke tokens."""
url = '/auth/token'
name = 'api:auth:token'
requires_auth = False
cors_allowed = True
def __init__(self, retrieve_user):
"""Initialize the token view."""
self._retrieve_user = retrieve_user
@log_invalid_auth
async def post(self, request):
"""Grant a token."""
hass = request.app['hass']
data = await request.post()
grant_type = data.get('grant_type')
# IndieAuth 6.3.5
# The revocation endpoint is the same as the token endpoint.
# The revocation request includes an additional parameter,
# action=revoke.
if data.get('action') == 'revoke':
return await self._async_handle_revoke_token(hass, data)
if grant_type == 'authorization_code':
return await self._async_handle_auth_code(
hass, data, str(request[KEY_REAL_IP]))
if grant_type == 'refresh_token':
return await self._async_handle_refresh_token(
hass, data, str(request[KEY_REAL_IP]))
return self.json({
'error': 'unsupported_grant_type',
}, status_code=400)
async def _async_handle_revoke_token(self, hass, data):
"""Handle revoke token request."""
# OAuth 2.0 Token Revocation [RFC7009]
# 2.2 The authorization server responds with HTTP status code 200
# if the token has been revoked successfully or if the client
# submitted an invalid token.
token = data.get('token')
if token is None:
return web.Response(status=200)
refresh_token = await hass.auth.async_get_refresh_token_by_token(token)
if refresh_token is None:
return web.Response(status=200)
await hass.auth.async_remove_refresh_token(refresh_token)
return web.Response(status=200)
async def _async_handle_auth_code(self, hass, data, remote_addr):
"""Handle authorization code request."""
client_id = data.get('client_id')
if client_id is None or not indieauth.verify_client_id(client_id):
return self.json({
'error': 'invalid_request',
'error_description': 'Invalid client id',
}, status_code=400)
code = data.get('code')
if code is None:
return self.json({
'error': 'invalid_request',
'error_description': 'Invalid code',
}, status_code=400)
user = self._retrieve_user(client_id, RESULT_TYPE_USER, code)
if user is None or not isinstance(user, User):
return self.json({
'error': 'invalid_request',
'error_description': 'Invalid code',
}, status_code=400)
# refresh user
user = await hass.auth.async_get_user(user.id)
if not user.is_active:
return self.json({
'error': 'access_denied',
'error_description': 'User is not active',
}, status_code=403)
refresh_token = await hass.auth.async_create_refresh_token(user,
client_id)
access_token = hass.auth.async_create_access_token(
refresh_token, remote_addr)
return self.json({
'access_token': access_token,
'token_type': 'Bearer',
'refresh_token': refresh_token.token,
'expires_in':
int(refresh_token.access_token_expiration.total_seconds()),
})
async def _async_handle_refresh_token(self, hass, data, remote_addr):
"""Handle authorization code request."""
client_id = data.get('client_id')
if client_id is not None and not indieauth.verify_client_id(client_id):
return self.json({
'error': 'invalid_request',
'error_description': 'Invalid client id',
}, status_code=400)
token = data.get('refresh_token')
if token is None:
return self.json({
'error': 'invalid_request',
}, status_code=400)
refresh_token = await hass.auth.async_get_refresh_token_by_token(token)
if refresh_token is None:
return self.json({
'error': 'invalid_grant',
}, status_code=400)
if refresh_token.client_id != client_id:
return self.json({
'error': 'invalid_request',
}, status_code=400)
access_token = hass.auth.async_create_access_token(
refresh_token, remote_addr)
return self.json({
'access_token': access_token,
'token_type': 'Bearer',
'expires_in':
int(refresh_token.access_token_expiration.total_seconds()),
})
class LinkUserView(HomeAssistantView):
"""View to link existing users to new credentials."""
url = '/auth/link_user'
name = 'api:auth:link_user'
def __init__(self, retrieve_credentials):
"""Initialize the link user view."""
self._retrieve_credentials = retrieve_credentials
@RequestDataValidator(vol.Schema({
'code': str,
'client_id': str,
}))
async def post(self, request, data):
"""Link a user."""
hass = request.app['hass']
user = request['hass_user']
credentials = self._retrieve_credentials(
data['client_id'], RESULT_TYPE_CREDENTIALS, data['code'])
if credentials is None:
return self.json_message('Invalid code', status_code=400)
await hass.auth.async_link_user(user, credentials)
return self.json_message('User linked')
@callback
def _create_auth_code_store():
"""Create an in memory store."""
temp_results = {}
@callback
def store_result(client_id, result):
"""Store flow result and return a code to retrieve it."""
if isinstance(result, User):
result_type = RESULT_TYPE_USER
elif isinstance(result, Credentials):
result_type = RESULT_TYPE_CREDENTIALS
else:
raise ValueError('result has to be either User or Credentials')
code = uuid.uuid4().hex
temp_results[(client_id, result_type, code)] = \
(dt_util.utcnow(), result_type, result)
return code
@callback
def retrieve_result(client_id, result_type, code):
"""Retrieve flow result."""
key = (client_id, result_type, code)
if key not in temp_results:
return None
created, _, result = temp_results.pop(key)
# OAuth 4.2.1
# The authorization code MUST expire shortly after it is issued to
# mitigate the risk of leaks. A maximum authorization code lifetime of
# 10 minutes is RECOMMENDED.
if dt_util.utcnow() - created < timedelta(minutes=10):
return result
return None
return store_result, retrieve_result
@websocket_api.ws_require_user()
@callback
def websocket_current_user(
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg):
"""Return the current user."""
async def async_get_current_user(user):
"""Get current user."""
enabled_modules = await hass.auth.async_get_enabled_mfa(user)
connection.send_message(
websocket_api.result_message(msg['id'], {
'id': user.id,
'name': user.name,
'is_owner': user.is_owner,
'credentials': [{'auth_provider_type': c.auth_provider_type,
'auth_provider_id': c.auth_provider_id}
for c in user.credentials],
'mfa_modules': [{
'id': module.id,
'name': module.name,
'enabled': module.id in enabled_modules,
} for module in hass.auth.auth_mfa_modules],
}))
hass.async_create_task(async_get_current_user(connection.user))
@websocket_api.ws_require_user()
@callback
def websocket_create_long_lived_access_token(
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg):
"""Create or a long-lived access token."""
async def async_create_long_lived_access_token(user):
"""Create or a long-lived access token."""
refresh_token = await hass.auth.async_create_refresh_token(
user,
client_name=msg['client_name'],
client_icon=msg.get('client_icon'),
token_type=TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN,
access_token_expiration=timedelta(days=msg['lifespan']))
access_token = hass.auth.async_create_access_token(
refresh_token)
connection.send_message(
websocket_api.result_message(msg['id'], access_token))
hass.async_create_task(
async_create_long_lived_access_token(connection.user))
@websocket_api.ws_require_user()
@callback
def websocket_refresh_tokens(
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg):
"""Return metadata of users refresh tokens."""
current_id = connection.refresh_token_id
connection.send_message(websocket_api.result_message(msg['id'], [{
'id': refresh.id,
'client_id': refresh.client_id,
'client_name': refresh.client_name,
'client_icon': refresh.client_icon,
'type': refresh.token_type,
'created_at': refresh.created_at,
'is_current': refresh.id == current_id,
'last_used_at': refresh.last_used_at,
'last_used_ip': refresh.last_used_ip,
} for refresh in connection.user.refresh_tokens.values()]))
@websocket_api.ws_require_user()
@callback
def websocket_delete_refresh_token(
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg):
"""Handle a delete refresh token request."""
async def async_delete_refresh_token(user, refresh_token_id):
"""Delete a refresh token."""
refresh_token = connection.user.refresh_tokens.get(refresh_token_id)
if refresh_token is None:
return websocket_api.error_message(
msg['id'], 'invalid_token_id', 'Received invalid token')
await hass.auth.async_remove_refresh_token(refresh_token)
connection.send_message(
websocket_api.result_message(msg['id'], {}))
hass.async_create_task(
async_delete_refresh_token(connection.user, msg['refresh_token_id']))

View File

@@ -0,0 +1,180 @@
"""Helpers to resolve client ID/secret."""
import asyncio
from ipaddress import ip_address
from html.parser import HTMLParser
from urllib.parse import urlparse, urljoin
import aiohttp
from aiohttp.client_exceptions import ClientError
from homeassistant.util.network import is_local
async def verify_redirect_uri(hass, client_id, redirect_uri):
"""Verify that the client and redirect uri match."""
try:
client_id_parts = _parse_client_id(client_id)
except ValueError:
return False
redirect_parts = _parse_url(redirect_uri)
# Verify redirect url and client url have same scheme and domain.
is_valid = (
client_id_parts.scheme == redirect_parts.scheme and
client_id_parts.netloc == redirect_parts.netloc
)
if is_valid:
return True
# IndieAuth 4.2.2 allows for redirect_uri to be on different domain
# but needs to be specified in link tag when fetching `client_id`.
redirect_uris = await fetch_redirect_uris(hass, client_id)
return redirect_uri in redirect_uris
class LinkTagParser(HTMLParser):
"""Parser to find link tags."""
def __init__(self, rel):
"""Initialize a link tag parser."""
super().__init__()
self.rel = rel
self.found = []
def handle_starttag(self, tag, attrs):
"""Handle finding a start tag."""
if tag != 'link':
return
attrs = dict(attrs)
if attrs.get('rel') == self.rel:
self.found.append(attrs.get('href'))
async def fetch_redirect_uris(hass, url):
"""Find link tag with redirect_uri values.
IndieAuth 4.2.2
The client SHOULD publish one or more <link> tags or Link HTTP headers with
a rel attribute of redirect_uri at the client_id URL.
We limit to the first 10kB of the page.
We do not implement extracting redirect uris from headers.
"""
parser = LinkTagParser('redirect_uri')
chunks = 0
try:
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=5) as resp:
async for data in resp.content.iter_chunked(1024):
parser.feed(data.decode())
chunks += 1
if chunks == 10:
break
except (asyncio.TimeoutError, ClientError):
pass
# Authorization endpoints verifying that a redirect_uri is allowed for use
# by a client MUST look for an exact match of the given redirect_uri in the
# request against the list of redirect_uris discovered after resolving any
# relative URLs.
return [urljoin(url, found) for found in parser.found]
def verify_client_id(client_id):
"""Verify that the client id is valid."""
try:
_parse_client_id(client_id)
return True
except ValueError:
return False
def _parse_url(url):
"""Parse a url in parts and canonicalize according to IndieAuth."""
parts = urlparse(url)
# Canonicalize a url according to IndieAuth 3.2.
# SHOULD convert the hostname to lowercase
parts = parts._replace(netloc=parts.netloc.lower())
# If a URL with no path component is ever encountered,
# it MUST be treated as if it had the path /.
if parts.path == '':
parts = parts._replace(path='/')
return parts
def _parse_client_id(client_id):
"""Test if client id is a valid URL according to IndieAuth section 3.2.
https://indieauth.spec.indieweb.org/#client-identifier
"""
parts = _parse_url(client_id)
# Client identifier URLs
# MUST have either an https or http scheme
if parts.scheme not in ('http', 'https'):
raise ValueError()
# MUST contain a path component
# Handled by url canonicalization.
# MUST NOT contain single-dot or double-dot path segments
if any(segment in ('.', '..') for segment in parts.path.split('/')):
raise ValueError(
'Client ID cannot contain single-dot or double-dot path segments')
# MUST NOT contain a fragment component
if parts.fragment != '':
raise ValueError('Client ID cannot contain a fragment')
# MUST NOT contain a username or password component
if parts.username is not None:
raise ValueError('Client ID cannot contain username')
if parts.password is not None:
raise ValueError('Client ID cannot contain password')
# MAY contain a port
try:
# parts raises ValueError when port cannot be parsed as int
parts.port
except ValueError:
raise ValueError('Client ID contains invalid port')
# Additionally, hostnames
# MUST be domain names or a loopback interface and
# MUST NOT be IPv4 or IPv6 addresses except for IPv4 127.0.0.1
# or IPv6 [::1]
# We are not goint to follow the spec here. We are going to allow
# any internal network IP to be used inside a client id.
address = None
try:
netloc = parts.netloc
# Strip the [, ] from ipv6 addresses before parsing
if netloc[0] == '[' and netloc[-1] == ']':
netloc = netloc[1:-1]
address = ip_address(netloc)
except ValueError:
# Not an ip address
pass
if address is None or is_local(address):
return parts
raise ValueError('Hostname should be a domain name or local IP address')

View File

@@ -0,0 +1,247 @@
"""HTTP views handle login flow.
# GET /auth/providers
Return a list of auth providers. Example:
[
{
"name": "Local",
"id": null,
"type": "local_provider",
}
]
# POST /auth/login_flow
Create a login flow. Will return the first step of the flow.
Pass in parameter 'client_id' and 'redirect_url' validate by indieauth.
Pass in parameter 'handler' to specify the auth provider to use. Auth providers
are identified by type and id.
And optional parameter 'type' has to set as 'link_user' if login flow used for
link credential to exist user. Default 'type' is 'authorize'.
{
"client_id": "https://hassbian.local:8123/",
"handler": ["local_provider", null],
"redirect_url": "https://hassbian.local:8123/",
"type': "authorize"
}
Return value will be a step in a data entry flow. See the docs for data entry
flow for details.
{
"data_schema": [
{"name": "username", "type": "string"},
{"name": "password", "type": "string"}
],
"errors": {},
"flow_id": "8f7e42faab604bcab7ac43c44ca34d58",
"handler": ["insecure_example", null],
"step_id": "init",
"type": "form"
}
# POST /auth/login_flow/{flow_id}
Progress the flow. Most flows will be 1 page, but could optionally add extra
login challenges, like TFA. Once the flow has finished, the returned step will
have type "create_entry" and "result" key will contain an authorization code.
The authorization code associated with an authorized user by default, it will
associate with an credential if "type" set to "link_user" in
"/auth/login_flow"
{
"flow_id": "8f7e42faab604bcab7ac43c44ca34d58",
"handler": ["insecure_example", null],
"result": "411ee2f916e648d691e937ae9344681e",
"title": "Example",
"type": "create_entry",
"version": 1
}
"""
from aiohttp import web
import voluptuous as vol
from homeassistant import data_entry_flow
from homeassistant.components.http import KEY_REAL_IP
from homeassistant.components.http.ban import process_wrong_login, \
log_invalid_auth
from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.components.http.view import HomeAssistantView
from . import indieauth
async def async_setup(hass, store_result):
"""Component to allow users to login."""
hass.http.register_view(AuthProvidersView)
hass.http.register_view(LoginFlowIndexView(hass.auth.login_flow))
hass.http.register_view(
LoginFlowResourceView(hass.auth.login_flow, store_result))
class AuthProvidersView(HomeAssistantView):
"""View to get available auth providers."""
url = '/auth/providers'
name = 'api:auth:providers'
requires_auth = False
async def get(self, request):
"""Get available auth providers."""
hass = request.app['hass']
if not hass.components.onboarding.async_is_onboarded():
return self.json_message(
message='Onboarding not finished',
status_code=400,
message_code='onboarding_required'
)
return self.json([{
'name': provider.name,
'id': provider.id,
'type': provider.type,
} for provider in hass.auth.auth_providers])
def _prepare_result_json(result):
"""Convert result to JSON."""
if result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY:
data = result.copy()
data.pop('result')
data.pop('data')
return data
if result['type'] != data_entry_flow.RESULT_TYPE_FORM:
return result
import voluptuous_serialize
data = result.copy()
schema = data['data_schema']
if schema is None:
data['data_schema'] = []
else:
data['data_schema'] = voluptuous_serialize.convert(schema)
return data
class LoginFlowIndexView(HomeAssistantView):
"""View to create a config flow."""
url = '/auth/login_flow'
name = 'api:auth:login_flow'
requires_auth = False
def __init__(self, flow_mgr):
"""Initialize the flow manager index view."""
self._flow_mgr = flow_mgr
async def get(self, request):
"""Do not allow index of flows in progress."""
return web.Response(status=405)
@RequestDataValidator(vol.Schema({
vol.Required('client_id'): str,
vol.Required('handler'): vol.Any(str, list),
vol.Required('redirect_uri'): str,
vol.Optional('type', default='authorize'): str,
}))
@log_invalid_auth
async def post(self, request, data):
"""Create a new login flow."""
if not await indieauth.verify_redirect_uri(
request.app['hass'], data['client_id'], data['redirect_uri']):
return self.json_message('invalid client id or redirect uri', 400)
if isinstance(data['handler'], list):
handler = tuple(data['handler'])
else:
handler = data['handler']
try:
result = await self._flow_mgr.async_init(
handler, context={
'ip_address': request[KEY_REAL_IP],
'credential_only': data.get('type') == 'link_user',
})
except data_entry_flow.UnknownHandler:
return self.json_message('Invalid handler specified', 404)
except data_entry_flow.UnknownStep:
return self.json_message('Handler does not support init', 400)
return self.json(_prepare_result_json(result))
class LoginFlowResourceView(HomeAssistantView):
"""View to interact with the flow manager."""
url = '/auth/login_flow/{flow_id}'
name = 'api:auth:login_flow:resource'
requires_auth = False
def __init__(self, flow_mgr, store_result):
"""Initialize the login flow resource view."""
self._flow_mgr = flow_mgr
self._store_result = store_result
async def get(self, request):
"""Do not allow getting status of a flow in progress."""
return self.json_message('Invalid flow specified', 404)
@RequestDataValidator(vol.Schema({
'client_id': str
}, extra=vol.ALLOW_EXTRA))
@log_invalid_auth
async def post(self, request, flow_id, data):
"""Handle progressing a login flow request."""
client_id = data.pop('client_id')
if not indieauth.verify_client_id(client_id):
return self.json_message('Invalid client id', 400)
try:
# do not allow change ip during login flow
for flow in self._flow_mgr.async_progress():
if (flow['flow_id'] == flow_id and
flow['context']['ip_address'] !=
request.get(KEY_REAL_IP)):
return self.json_message('IP address changed', 400)
result = await self._flow_mgr.async_configure(flow_id, data)
except data_entry_flow.UnknownFlow:
return self.json_message('Invalid flow specified', 404)
except vol.Invalid:
return self.json_message('User input malformed', 400)
if result['type'] != data_entry_flow.RESULT_TYPE_CREATE_ENTRY:
# @log_invalid_auth does not work here since it returns HTTP 200
# need manually log failed login attempts
if (result.get('errors') is not None and
result['errors'].get('base') in ['invalid_auth',
'invalid_code']):
await process_wrong_login(request)
return self.json(_prepare_result_json(result))
result.pop('data')
result['result'] = self._store_result(client_id, result['result'])
return self.json(result)
async def delete(self, request, flow_id):
"""Cancel a flow in progress."""
try:
self._flow_mgr.async_abort(flow_id)
except data_entry_flow.UnknownFlow:
return self.json_message('Invalid flow specified', 404)
return self.json_message('Flow aborted')

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