Compare commits

..

1705 Commits

Author SHA1 Message Date
Paulus Schoutsen
eb3355b05d Merge pull request #22420 from home-assistant/rc
0.90.2
2019-03-26 14:26:59 -07:00
mvn23
24ba434e6a Improve opentherm gw startup (#22121)
* Improve fix in c90f0d5 (#22106). Schedule connect coroutine directly on the loop rather than waiting for EVENT_HOMEASSISTANT_START.

* Remove unused import.
2019-03-26 14:25:47 -07:00
mvn23
ddefb74215 Fix TypeError in current_temperature if no temperature is known. (#22112)
Don't set opentherm_gw climate temperatures to 0 on init.
2019-03-26 14:25:47 -07:00
mvn23
42e75dc45c Fix opentherm_gw blocks HA startup when gateway unreachable. (#22106) 2019-03-26 14:25:46 -07:00
mvn23
44dc85204c Bump pyotgw to 0.4b2 (#21973) 2019-03-26 14:25:16 -07:00
Paulus Schoutsen
ab1f1316ba Bumped version to 0.90.2 2019-03-26 07:40:10 -07:00
Jason Hunter
8a6d9cc0e4 reset unsub to None on timeout (#22404) 2019-03-26 07:39:59 -07:00
Pascal Vizeli
fac214828d Enable hass.io panel without ping (#22388)
* Enable hass.io panel without ping

* fix tests
2019-03-26 07:39:58 -07:00
Pascal Vizeli
a2508b4f52 Update hass-nabucasa & fix state (#22385)
* Update hass-nabucasa & fix state

* Fix lint
2019-03-26 07:39:56 -07:00
Jason Hunter
24a55834f9 Prefer TCP for RTSP streams (#22338)
## Description:

For RTSP streams, set the `prefer_tcp` FFMPEG flag.  This should resolve some of the "green feed" issues that some users are reporting, likely due to packets being lost over UDP on their network.

Resources: [FFMPEG protocols documentation](https://ffmpeg.org/ffmpeg-protocols.html#rtsp)

## Checklist:
  - [x] The code change is tested and works locally.
  - [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
  - [x] There is no commented out code in this PR.
2019-03-26 07:39:55 -07:00
ktnrg45
4d0a28fa56 Fix ps4 no creds with additional device (#22300)
* Fix no creds with additional device.

* Update config_flow.py
2019-03-26 07:39:54 -07:00
Paulus Schoutsen
ae2153f1fc Merge pull request #22265 from home-assistant/rc
0.90.1
2019-03-21 14:24:28 -07:00
Pascal Vizeli
8085e9206a Update hass-nabucasa 0.10 (#22267) 2019-03-21 14:21:37 -07:00
Paulus Schoutsen
ff93591aaf Lint 2019-03-21 13:22:08 -07:00
Pascal Vizeli
8a314d7da0 Update Hass-NabuCasa 0.9 (#22258) 2019-03-21 13:06:15 -07:00
Andrew Sayre
f47a50aa24 Fix validate webhook requirements (#22248) 2019-03-21 13:06:13 -07:00
Michaël Arnauts
b2bb70b5aa Allow on/off on tado climate component. (#22242)
* Allow on/off on tado climate component. Bump python-tado version. Patch from @wmalgadey

* Revert wrongly change in tado device tracker
2019-03-21 13:05:46 -07:00
Jason Hunter
56cbe8a73f Stream fixes (#22238)
* fix issues with out of order packets, and empty first packet on some IP camera models

* do not skip the first packet
2019-03-21 13:05:09 -07:00
Paulus Schoutsen
0f730310a4 Bumped version to 0.90.1 2019-03-21 13:03:40 -07:00
Karim Roukoz
1aab284012 Bump total-connect-client to 0.25, fixing issue with Total Connect (#22230)
* Bump total-connect-client to 0.25

* Bump version in requirements_all.txt
2019-03-21 13:03:25 -07:00
Alexei Chetroi
a84ba90c9e Fix ZHA force polled entities. (#22222)
## Description:
Fix "force_polled" ZHA entities.

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

[ex-requir]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard/__init__.py#L14
[ex-import]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard/__init__.py#L23
2019-03-21 13:02:35 -07:00
Paulus Schoutsen
ee1c270c89 Updated frontend to 20190321.0 2019-03-21 12:57:47 -07:00
Paulus Schoutsen
937eba3dbe Merge pull request #22216 from home-assistant/rc
0.90.0
2019-03-20 10:16:24 -07:00
Paulus Schoutsen
9d8054e6e2 Bumped version to 0.90.0 2019-03-20 07:51:23 -07:00
Penny Wood
d4cd39e43e Fixed typing errors (#22207) 2019-03-20 07:51:14 -07:00
Paulus Schoutsen
1bf49ce5a3 Updated frontend to 20190320.0 2019-03-20 07:50:24 -07:00
Paulus Schoutsen
7cf1f4f9fe Bumped version to 0.90.0b7 2019-03-19 16:48:31 -07:00
Paulus Schoutsen
268d129ea9 Updated frontend to 20190319.1 2019-03-19 16:36:11 -07:00
Paulus Schoutsen
b8f246356a Bumped version to 0.90.0b6 2019-03-19 11:41:08 -07:00
Paulus Schoutsen
e6ffc790f2 Always load Hass.io component on Hass.io (#22185)
* Always load Hass.io component on Hass.io

* Lint

* Lint
2019-03-19 11:40:49 -07:00
Pascal Vizeli
b85189e699 Update Hass-NabuCasa 0.8 (#22177) 2019-03-19 11:40:48 -07:00
uchagani
f202114ead bump total_connect_client to 0.24 (#22166) 2019-03-19 11:40:06 -07:00
Paulus Schoutsen
fff6927f9c Updated frontend to 20190319.0 2019-03-19 11:38:16 -07:00
Paulus Schoutsen
ad0ec66353 Bumped version to 0.90.0b5 2019-03-18 17:04:49 -07:00
Franck Nijhof
592edd10ef Upgrade toonapilib to 3.2.2 + lower interval (#22160) 2019-03-18 17:04:43 -07:00
Pascal Vizeli
d75d75e49f Remove config check over supervisor (#22156)
* Remove config check over supervisor

* Fix lint

* Fix tests
2019-03-18 17:04:42 -07:00
Jason Hunter
1c9b750e36 Fix resetting access token on streams with keepalive (#22148) 2019-03-18 17:04:41 -07:00
WebSpider
33a7075883 Bump tado version (#22145)
* Bump python-tado, new API endpoint

* Change references of old API endpoint to new

* Update REQUIREMENTS
2019-03-18 17:04:40 -07:00
Paulus Schoutsen
cc00f3cd2e Allow non-admins to listen to certain events (#22137) 2019-03-18 17:04:39 -07:00
Jason Hu
22624715a9 Remove hass.config from aws_lambda notify payload (#22125) 2019-03-18 17:04:38 -07:00
Paulus Schoutsen
c37dcacf54 Updated frontend to 20190318.0 2019-03-18 16:54:31 -07:00
Paulus Schoutsen
872ee3eb21 Bumped version to 0.90.0b4 2019-03-16 23:26:48 -07:00
Jason Hunter
f218564185 delete previously removed service option from services yaml (#22123) 2019-03-16 23:26:17 -07:00
Paulus Schoutsen
16ac1d4600 Updated frontend to 20190316.0 2019-03-16 23:25:57 -07:00
Paulus Schoutsen
7b224dde23 Bumped version to 0.90.0b3 2019-03-15 23:20:19 -07:00
Jason Hunter
7a88c58ffa Beta Fix: FFMPEG and Stream component (#22091)
* remove stream_source from ffmpeg and onvif and add to generic ip cam

* fix tests
2019-03-15 23:19:52 -07:00
Paulus Schoutsen
68d1a5322a Prevent cloud remote UI when using 127.0.0.1 as trusted network (#22093)
* Prevent cloud remote UI when using trusted networks

* Limit to 127.0.0.1 trusted network

* Update error msg

* Disable ipv6 loopback
2019-03-15 23:19:26 -07:00
Jeff Irion
a46b64d227 Bump androidtv to 0.0.12 (#22072) 2019-03-15 23:19:26 -07:00
Paulus Schoutsen
5924479272 Updated frontend to 20190315.1 2019-03-15 23:19:09 -07:00
Paulus Schoutsen
aa81819683 Fix func 2019-03-15 11:12:12 -07:00
Paulus Schoutsen
ff6b86b5a8 Bumped version to 0.90.0b2 2019-03-15 10:59:55 -07:00
Paulus Schoutsen
3d404c43c8 Fix more test 2019-03-15 10:59:50 -07:00
Paulus Schoutsen
b18aef8d31 Fix test 2019-03-15 10:59:50 -07:00
Pascal Vizeli
ac1aeb35a6 Binary Sensor for Remote UI & Fix timezone (#22076)
* Binary Sensor for Remote UI

* Fix lint

* Revert make hass public

* Add tests
2019-03-15 10:59:27 -07:00
Jason Hu
3ec8b5a170 Correct context (#22061) 2019-03-15 10:59:26 -07:00
Paulus Schoutsen
8f10345468 Return config entry ID after creation (#22060) 2019-03-15 10:59:25 -07:00
Robbie Trencheny
0029dc3813 Mobile App: Expose Cloud Remote UI FQDN in registration response (#22055)
* Add a callback to get the cloud remote UI FQDN

* Expose Cloud Remote UI FQDN in the registration response

* Return a URL instead of FQDN
2019-03-15 10:59:25 -07:00
Robbie Trencheny
11ebb3f24e Mobile App: Discovery to default configuration.yaml, zeroconf to default_config (#22028)
* Move discovery into default configuration.yaml

* Add zeroconf to default_config
2019-03-15 10:59:25 -07:00
Robbie Trencheny
4835fb2c57 Mobile App: Enable loading via discovery (surprise inside!) (#22027)
![](http://funpeep.com/wp-content/uploads/2014/04/Cute-White-Cat-Wallpaper.jpg)
2019-03-15 10:59:23 -07:00
Jeff Irion
25a7f71ec2 Bump androidtv to 0.0.11 (#22025) 2019-03-15 10:59:22 -07:00
Robbie Trencheny
f0b7d76e26 Mobile App: Sensors (#21854)
## Description:

**Related issue (if applicable):** fixes #21782

## Checklist:
  - [x] The code change is tested and works locally.
  - [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
  - [x] There is no commented out code in this PR.
2019-03-15 10:57:24 -07:00
Robbie Trencheny
f7dcfe28b6 Mobile App: Register devices into the registry (#21856)
* Register devices into the registry

* Switch to device ID instead of webhook ID

* Rearchitect mobile_app to support config entries

* Kill DATA_REGISTRATIONS by migrating registrations into config entries

* Fix tests

* Improve how we get the config_entry_id

* Remove single_instance_allowed

* Simplify setup_registration

* Move webhook registering functions into __init__.py since they are only ever used once

* Kill get_registration websocket command

* Support description_placeholders in async_abort

* Add link to mobile_app implementing apps in abort dialog

* Store config entry and device registry entry in hass.data instead of looking it up

* Add testing to ensure that the config entry is created at registration

* Fix busted async_abort test

* Remove unnecessary check for entry is None
2019-03-15 10:57:00 -07:00
Robbie Trencheny
3fd1e8d382 Mobile App: Update Location schema updates & device ID generation (#21849)
* Update location schema

* Generate a random device ID at registration time for later use with device_tracker.see

* Remove host name from device_tracker.see payload

* Drop consider_home from the payload

* Remove stale consider_home in schema

* Remove source_type
2019-03-15 10:56:36 -07:00
Robbie Trencheny
c67113ad55 Mobile App: Support rendering multiple templates at once (#21851)
* Support rendering multiple templates at once

* Only catch TemplateError and dont log the error
2019-03-15 10:56:06 -07:00
Robbie Trencheny
b336322e9e Mobile App: Require encryption for registrations that support it (#21852)
## Description:

**Related issue (if applicable):** fixes #21758

## Checklist:
  - [x] The code change is tested and works locally.
  - [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
  - [x] There is no commented out code in this PR.
2019-03-15 10:55:45 -07:00
Paulus Schoutsen
9e6a7a6357 Updated frontend to 20190315.0 2019-03-15 10:49:13 -07:00
Paulus Schoutsen
fb895bba80 Bumped version to 0.90.0b1 2019-03-14 16:25:00 -07:00
Pascal Vizeli
707d32495b Fix Google Assistant User with Cloud (#22042)
* Fix Google Assistant User with Cloud

* Fix User Agent ID

* respell

* Fix object

* Fix tests

* fix lint

* Fix lint
2019-03-14 16:19:19 -07:00
Jason Hu
7057958e3e Fix lifx light async error (#22031) 2019-03-14 16:19:19 -07:00
emontnemery
90c878a7ed Update additional platforms to use new MQTT message callback (#22030)
* Move additional platforms to new MQTT callback

* Fix automation.mqtt
2019-03-14 16:19:18 -07:00
cgtobi
c78e332df3 Bring back the boiler status (#22021) 2019-03-14 16:19:18 -07:00
Phil Hawthorne
42c9472a74 Remove UTF8 decoding for Waze (#22020)
Removes the UFT8 decoding for the Waze sensor, which broke in 0.89

Fixes #21739
2019-03-14 16:19:17 -07:00
Paulus Schoutsen
07022c46f2 Version bump to 0.90.0b0 2019-03-13 13:03:58 -07:00
Paulus Schoutsen
b601fa52ba Bumped version to 0.89.0b0 2019-03-13 13:02:55 -07:00
Paulus Schoutsen
ce5efcdb26 Merge branch 'master' into dev 2019-03-13 13:02:26 -07:00
Gijs Reichert
1ffc0e3c7c Check updated_date for list and pick first (#22008) 2019-03-13 13:00:58 -07:00
Isabella Gross Alström
2dcd9d94c8 Allow all success status codes in REST notify response (#22011)
For example Discord webhooks returns a 204 success code as response, which gets logged as an error in the log, even though it is successful.
Update the allowed statuses to accept all 2xx responses as successful.
2019-03-13 13:00:08 -07:00
Andrew Sayre
83243e95d3 Remove default temp unit (#22012) 2019-03-13 12:59:37 -07:00
emontnemery
5957e4b75b Pass Message object to MQTT message callbacks (#21959)
* Pass Message object to MQTT message callbacks

* Improve method of detecting deprecated msg callback

* Fix mysensors

* Fixup

* Review comments

* Fix merge error
2019-03-13 12:58:20 -07:00
Paulus Schoutsen
50ec3d7de5 Update translations 2019-03-13 12:57:00 -07:00
Paulus Schoutsen
d0c8f6de56 Updated frontend to 20190313.0 2019-03-13 12:57:00 -07:00
Marco Orovecchia
cac8e34841 Nanoleaf availability check (#21945)
* Added availability check for nanoleaf lights

* pylint errors fixed

* pynanoleaf bump
2019-03-13 12:54:15 -07:00
Jc2k
deb66bb748 HomeKit controller light - remove code that can never execute (#21951) 2019-03-13 12:53:33 -07:00
beavis9k
eed1168fa1 fix error in LutronButton init if Button doesn't have a type (#21921) 2019-03-13 12:52:45 -07:00
Anders Melchiorsen
de2c7a9567 Wait for Sonos regrouping in service calls (#22006) 2019-03-13 12:51:41 -07:00
Anders Melchiorsen
fe5e4b5b9b Avoid playing queue pollution with Sonos unjoin (#22004) 2019-03-13 12:51:08 -07:00
Pascal Vizeli
186b48e2eb Bump NabuCasa library to 0.5 (#22010) 2019-03-13 16:45:26 +01:00
Aaron Bach
a71394a0ce Add program/zone enable/disable services to RainMachine (#21785) 2019-03-13 08:20:13 -06:00
Aaron Bach
897862fca4 Add availability and next run datetime to RainMachine switches (#21786) 2019-03-13 08:19:26 -06:00
endor
18daee9af6 Tellstick sensor configuration cleanup (#21402)
* Cleaned up named sensor handling for future

Breaking change for tellstick sensor configuration.

* Fixed linting of long lines and closing bracket

Linting warning for long line and not using best practice for visual indentation of closing bracket.
Who's a good boy..

* Whitespace on line was not cleaned.

* Removed spaces to clean up

* More.. whitespace. Sloppy.

* Constants from const, altered loops, added dictionary for sensor names.

* Fixed whitespace

* Inverted condition and created guard clause

* Changed condition from not ... in to not in.

* Fixed bad indentation on L91 and 92
2019-03-13 12:20:15 +01:00
Jeff Irion
007bf2bcb5 Rename 'firetv' to 'androidtv' and add Android TV functionality (#21944)
* Working on adding androidtv functionality to firetv component

* 'should_poll' must return True

* Change 'properties' to 'device_properties'

* Also mention 'Android TV' in services.yaml

* Use GitHub for 'androidtv' requirement

* Add 'androidtv==0.0.10' to requirements, remove 'firetv==1.0.9'

* Add 'GET_PROPERTIES' adb command option; use pypi for REQUIREMENTS

* Rename integration from 'firetv' to 'androidtv'

* Change default name to 'Android TV'

* Rename integration from 'firetv' to 'androidtv'

* Change firetv to androidtv in .coveragerc

* Change firetv to androidtv in requirements_all.txt

* Remove 'DEFAULT_APPS'
2019-03-13 11:18:59 +01:00
Jason Hu
e5da7a0014 Add breaking change section to PR template (#21994) 2019-03-13 10:54:30 +01:00
Anders Melchiorsen
c8692fe70c Use asyncio lock (#21985) 2019-03-13 10:17:09 +01:00
Daniel Perna
0162e2abe5 Update pyhomematic to 0.1.58 (#21989) 2019-03-13 08:56:59 +01:00
Paulus Schoutsen
c15f433c3e Add a service require_admin wrapper (#21953)
* Add a service require_admin wrapper

* Allow it to be used as a decorator

* Lint

* Add comment

* Add docstring

* Update syntax
2019-03-12 22:09:50 -07:00
Robbie Trencheny
bf839687ad Mobile App: Registration schema improvements (#21850)
* Update registration schema to add os_name (required) and make app_name required

* Ensure that a provided app_component is valid and available

* Ensure that component DEPENDENCIES declares mobile_app

* Update homeassistant/helpers/config_validation.py

* Standardize error responses

* Dont generalize REGISTER_BAD_COMPONENT

* Fix tests after merge
2019-03-12 22:04:27 -07:00
Diogo Gomes
a99d83390e Centrally define Energy Units (kWh and Wh) (#21719)
* centralize energy units kWh and Wh

* lint
2019-03-12 18:46:41 -07:00
Jc2k
c0b859d8da Set homekit controller entity as unavailable if new connections fail (#21901)
* Set entity as unavailable if new connections fail

* Fix docstring
2019-03-12 18:45:34 -07:00
Daniel Shokouhi
d66cc9befa Add stream source for amcrest component (#21983) 2019-03-12 21:40:24 -04:00
Jc2k
e618e2f348 Fix error introduced by #21933 (#21988) 2019-03-12 18:37:33 -07:00
Robbie Trencheny
9428ed7690 Use .get to ensure we dont get KeyError (#21993) 2019-03-12 18:00:18 -07:00
emontnemery
ce1fe06193 Write state directly in all MQTT platforms (#21971) 2019-03-12 14:46:48 -07:00
Paulus Schoutsen
f8921f84d7 skip flaky test (#21981) 2019-03-12 14:19:11 -07:00
Jc2k
2b1b47bfdd homekit_controller: Bump homekit to 0.13.0 (#21965)
* Bump homekit to 0.13.0

* Update gen_requirements_all.py

* Escape values used in TESTS_REQUIREMENTS
2019-03-12 21:54:08 +01:00
Paulus Schoutsen
97a87b2e4e Merge pull request #21982 from home-assistant/rc
0.89.2
2019-03-12 13:38:43 -07:00
Paulus Schoutsen
737c7e871d Bumped version to 0.89.2 2019-03-12 11:51:09 -07:00
Klaudiusz Staniek
1f3e4c5776 Fixes issues #21821 and #21819 (#21911)
* Fix #21821

* datetime fix

* local time to utc conversion fix

* Test cases update

* date import removed

* Update tod.py
2019-03-12 11:51:02 -07:00
Daniel Shokouhi
00d01865cf Fix botvac when no map exists (#21877) 2019-03-12 11:51:02 -07:00
Jason Hu
1b4905ae5a Override http.trusted_networks by auth_provider.trusted_networks (#21844) 2019-03-12 11:51:00 -07:00
Andrew Sayre
39749952ee Update dependencies to receive data on webhook callbacks (#21838) 2019-03-12 11:51:00 -07:00
Paulus Schoutsen
d3960bf745 Fix some cloud things (#21977) 2019-03-12 11:49:46 -07:00
Paulus Schoutsen
9416af5b56 Allow changing password without being admin (#21978) 2019-03-12 11:49:28 -07:00
Paulus Schoutsen
4a4bb43422 Stream: Only add base url when needed (#21979) 2019-03-12 11:46:20 -07:00
Paulus Schoutsen
d635111e4f Update translations 2019-03-12 11:31:17 -07:00
Paulus Schoutsen
9178ac17ad Updated frontend to 20190312.0 2019-03-12 11:30:50 -07:00
Sidney
1444a684e0 Fix MagicHome LEDs with flux_led component (#20733)
* bug fixing for MagicHome LEDs with flux_led component.

* corrections of the fixes for flux_led

* now asyncio sleep and turn on with brigthness possible

* indention fix with flux_led

* async now works

* houndci fixes

* little fixes for flux_led

* self._color fix for flux_led

* Add docstring
2019-03-12 16:51:51 +01:00
Paulus Schoutsen
d3bab30dbe Add cloud status (#21960)
* Add cloud status

* Expose certificate details

* store & reset last state

* Fix tests

* update tests

* update req

* fix lint
2019-03-12 15:54:04 +01:00
Markus Jankowski
ac97cebe11 Add Weather Sensors to Homematic IP (#21887)
* Add HmIP Weather Sensor Devices

* Fix test and icons

* fix test

* Fix comments
2019-03-12 14:52:13 +01:00
Thom Troy
cc34ee5559 fix ephember doing http call from property (#21855) 2019-03-12 14:49:36 +01:00
kbickar
62df6cbd09 Update to sense component to fully be async (#21698)
* Update to sense component to fully be async

* Shortened lines

* Whitespace
2019-03-12 14:44:53 +01:00
Anders Melchiorsen
dd11f8d3fe Avoid playing queue pollution when restoring Sonos snapshots (#21963)
Assume a snapshot state with three speakers in two groups, AB and C. They will
be playing the A and C queues, respectively. The B queue exists but is hidden
in this topology.

Unjoin B and form a new group BC, playing the B queue (now with the C queue
hidden).

To restore the snapshot we would join B back to A. The BC group would now only
contain the C speaker, still playing the B queue. The C queue has been lost :-(

The problem is that unjoining a coordinator will elect a new coordinator that
inherits the group queue and thus has its hidden queue overwritten.

This commit avoids the situation by having restore unjoin all slaves. Above, C
would be unjoined before joining B to A. This restores the C queue and since B
is then alone, it can be joined to A without having to transfer its playing
queue to remaining speakers.
2019-03-12 14:39:55 +01:00
Robbie Trencheny
2225425ed2 Update lametric icon to be HA logo (#21957) 2019-03-11 20:42:13 -07:00
Jason Hunter
7ccd0bba9a Live Streams Component (#21473)
* initial commit of streams

* refactor stream component

* refactor so stream formats are not considered a platform

* initial test and minor refactor

* fix linting

* update requirements

* need av in tests as well

* fix import in class def vs method

* fix travis and docker builds

* address code review comments

* fix logger, add stream start/stop logs, listen to HASS stop

* address additional code review comments

* beef up tests

* fix tests

* fix lint

* add stream_source to onvif camera

* address pr comments

* add keepalive to camera play_stream service

* remove keepalive and move import

* implement registry and have output provider remove itself from stream after idle, set libav log level to error
2019-03-11 19:57:10 -07:00
Klaudiusz Staniek
0a6ba14444 Fixes issues #21821 and #21819 (#21911)
* Fix #21821

* datetime fix

* local time to utc conversion fix

* Test cases update

* date import removed

* Update tod.py
2019-03-11 21:27:41 +01:00
Fabian Affolter
650658ea01 Upgrade schiene to 0.23 (#21940) 2019-03-11 21:25:29 +01:00
Pascal Vizeli
92ff49212b Offload Cloud component (#21937)
* Offload Cloud component & Remote support

* Make hound happy

* Address comments
2019-03-11 12:21:20 -07:00
Paulus Schoutsen
8bfbe3e085 Add update user command (#21922)
* Add update user command

* Add is_admin to current user
2019-03-11 12:08:02 -07:00
Jc2k
5e2302e469 Add an asyncio Lock around pairing, which cant be used concurrently (#21933) 2019-03-11 11:59:41 -07:00
Paulus Schoutsen
4f5446ff02 Add area permission check (#21835) 2019-03-11 11:02:37 -07:00
David McNett
4f49bdf262 Minor version bump for anthemav package (#21932)
Additional Python 3.7 fixes in the anthemav package.
See also: https://pypi.org/project/anthemav/
2019-03-11 20:47:57 +05:30
Marco Orovecchia
e7c85d350e Changed from nanoleaf_aurora to nanoleaf (#21913)
Nanoleaf component now supports both nanoleaf lights, Aurora and Canvas
Changed the dependency to pynanoleaf, nanoleaf does not seem to be
maintained anymore
2019-03-11 20:46:32 +05:30
Michaël Arnauts
bc76055c17 Allow inverting netdata sensor values (#21711)
* Allow inverting netdata sensor values

* Fix lint issue

* Use parentheses
2019-03-11 20:43:53 +05:30
Robbie Trencheny
785fd273e3 If registration supports encryption then return encrypted payloads (#21853) 2019-03-11 08:34:58 -04:00
Andrew Sayre
c401f35a43 Add cloudhook support to SmartThings component (#21905)
* Add support for Nabu Casa cloudhooks

* Added tests to cover cloudhook creation and removal

* Remove cloud dependency
2019-03-11 08:33:25 -04:00
gertdb
3fd6aa0ba9 Fixes Modbus service.yaml validity (#21923)
* Update __init__.py

* Update services.yaml

* Update services.yaml
2019-03-11 08:17:31 -04:00
Anders Melchiorsen
49014ac13f Remove confusing warning for TTS without entity_id (#21927) 2019-03-11 12:31:36 +01:00
Finbarr Brady
85dc5fe4d5 Update enigma2 based on review comments (#21890)
* Updates based on review comments

* bump netdisco and remove enigma2 init code

* revert netdisco bump
2019-03-11 11:42:56 +01:00
Jc2k
b0d55d1946 HomeKit controller config flow fixes (#21898)
* HomeKit controller config flow fixes

* This does work if you have latest vol-serialize
2019-03-11 10:07:12 +01:00
Brad Dixon
9ab543ab3d Add as_timestamp() to Jinja filters. (#21910)
Add as_timestamp() to Jinja filters
2019-03-11 13:21:22 +05:30
Colby Rome
29f01fb14e Add 'ssl' parameter for FiOS Quantum Gateway and upgrade Pypi (#21669)
* bump pypi version and take 'use_https' parameter

* changed to use CONF_SSL
2019-03-11 12:26:19 +08:00
Paulus Schoutsen
429bbc05dc Add WS subscription command for MQTT (#21696)
* Add WS subscription command for MQTT

* Add test

* Add check for connected

* Rename event_listeners to subscriptions
2019-03-10 20:07:09 -07:00
emontnemery
fc85b3fc5f Don't hang forever if manually added cast is down (#21565)
* Don't hang forever if manually added cast is down

* Adapt to pychromecast

* Do not set available until connected

* Update __init__.py

* Update requirements

* Lint, tests

* Fix tests
2019-03-10 19:57:30 -07:00
Jason Hu
fe1840f901 Deprecate http.api_password (#21884)
* Deprecated http.api_password

* Deprecated ApiConfig.api_password

GitHub Drafted PR would trigger CI after changed it to normal PR.
I have to commit a comment change to trigger it

* Trigger CI

* Adjust if- elif chain in auth middleware
2019-03-10 19:55:36 -07:00
Finbarr Brady
7ec7e51f70 bump netdisco to 2.4.0 (#21914) 2019-03-11 09:49:40 +08:00
Thiago Oliveira
77dc7595ee Allow emulated hue to set climate component temperature (#19034) 2019-03-11 00:04:21 +01:00
Niall Donegan
5debc8828a Return time based attributes as datetime in Unifi module (#21146)
* Return time based data as datetime in Unifi module

* Fix missing space and pylint complaints about import order.
2019-03-10 19:22:28 +01:00
Peter Epley
c888e65f11 Add custom holidays to workday sensor (#21718)
* Add custom holidays to workday sensor

* correcting copy/paste errors

* resolve block comment and add default

* resolve line too long

* fixed handling of no custom holidays

* hound fixes

* rerun Travis

* @fabaff requested changes

* spaces v tabs

* Fix validation
2019-03-10 22:44:45 +05:30
gertdb
bab53a1c94 Modbus write_register accept single value and array (#21621)
* Update __init__.py

* Update services.yaml
2019-03-10 20:38:29 +05:30
Thibault Maekelbergh
65ff8b727a Add myself to CODEOWNERS for NMBS code (#21892)
* Add myself to CODEOWNERS for NMBS code

* Fix
2019-03-10 20:17:17 +05:30
Thibault Maekelbergh
6456f71a46 Fix icon for sensor.discogs_random_record (#21891)
* Fix icon for sensor.discogs_random_record

* Add myself to CODEOWNERS for Discogs code
2019-03-10 19:19:31 +05:30
Marco M
05333f60d7 Fix missing code_required check in async_alarm_arm_night (#21858)
* Fix missing code_required check in async_alarm_arm_night

* Remove double code validation
Test added
2019-03-10 14:25:01 +01:00
Julius Mittenzwei
6f77d9bc34 Don't wait until final position of Velux cover is reached (#21558)
## Description:

* Bump version to latest version of pyvlx: 0.2.10. Library more failure tolerant, when detecting an unsupported device.
* When calling API (e.g. run scene, change position) don't wait until device has reached target position (This caused  HASS to be flaky while the device was moving)
* Support for vertical and horizontal awnings.
2019-03-10 03:47:22 -07:00
Joakim Sørensen
7102e82113 Change lib for whois sensor (#21878)
* Change lib for whois sensor

* Change requirements.txt
2019-03-10 14:38:13 +05:30
Paulus Schoutsen
ad73b6eee9 Updated frontend to 20190309.0 2019-03-09 21:26:35 -08:00
Paulus Schoutsen
5fbe2d5477 Update translations 2019-03-09 21:26:26 -08:00
David F. Mulcahey
5ffb471198 Update ZHA state handling (#21866)
* make device available if it was seen within 2 hours

* more state restore

* cleanup init

* clean up storage stuff

* fix tests

* update state handling
2019-03-09 20:09:09 -08:00
Paulus Schoutsen
5b2c6648fb Add user group (#21832)
* Add user group

* Rename system group to plural
2019-03-09 20:07:29 -08:00
Paulus Schoutsen
14b05b0a91 Fix incorrect 2nd param 2019-03-09 19:52:50 -08:00
Andrew Sayre
5ace55ea8d Add SmartThings sensor support for Three Axis (#21841)
* Add support for Three Axis to sensor platform

* Changes per review feedback.

* Remove unnecessary KeyError except

* Fix lint issue in line wrapping
2019-03-09 18:45:15 -06:00
Andrew Sayre
c927cd9c14 Add SmartThings climate support for Air Conditioners (#21840)
* Add support for Samsung Air Conditioners to Climate

* Changes per review feedback.

* Fix py3.5 compat list sorting in test
2019-03-09 18:43:16 -06:00
Daniel Shokouhi
2d2abc7831 Fix botvac when no map exists (#21877) 2019-03-09 23:06:35 +01:00
Zak
896075fa1c Add ClearPass Policy Manger device tracker (#21673)
* Adding ClearPass Policy Manger device tracker. Amending author

* Cleaned redundant code

* Updated .coveragerc

* Updated requirements_all.txt

* Implemented suggested changes partially.

* Implemented more suggested changes.

* Hound was unhappy

* Implement further suggested changes.

* Make Hound happy.

* Satisfy Travic CI

* Satisfy Travis CI #2

* Hound barking

* pylint else: return

* Implemented suggested changes minus AccessToken

* Removed access token logging

* Removed throttle import

* Removed period from debug string

* Make travis happy :(

* Moved source to new component structure.

* Forgot to rename source.
2019-03-09 22:12:29 +01:00
Paulus Schoutsen
f4f0d363ca Better cloud check (#21875) 2019-03-09 12:15:16 -08:00
David F. Mulcahey
ac5ccd651c Bump quirks for ZHA and handle resulting battery % change (#21869)
* bump quirks and handle battery change

* move inside guard

* round battery
2019-03-09 12:14:58 -08:00
Jason Hu
226be65910 Only commit if need. (#21848) 2019-03-09 12:04:13 -08:00
Paul Bottein
4d9cf15c45 Fix authorization header in cors (#21662)
* Fix authorization headers in cors

* Use aiohttp authorization header instead of custom const
2019-03-09 10:00:10 -08:00
emontnemery
fc81826763 Introduce Entity.async_write_ha_state() to not miss state transition (#21590)
* Copy state in schedule_update_ha_state

* Lint

* Fix broken test

* Review comment, improve docstring

* Preserve order of state updates

* Rewrite

* Break up async_update_ha_state

* Update binary_sensor.py

* Review comments

* Update docstring

* hass -> ha

* Update entity.py

* Update entity.py
2019-03-09 09:52:22 -08:00
Willem Burgers
458548daec Fix TypeError (#21734)
* timediff is of type timedelta. Divide by timedelta does not work.

- convert a timedelta to int
- make sure the test inputs real timestamps

* Convert the total_seconds to decimal and round the result

readings are of type Decimal, so fix test to reflect that

* split line into multiple statements

Line too long

* use total_seconds instead of timediff

* Make both values float instead of Decimal
2019-03-09 17:51:15 +01:00
Hackashaq666
be989ebb7e Update honeywell.py to read current humidity for US Thermostats (#21728)
* Update honeywell.py

Add thermostat humidity reading available in somecomfort for US thermostats.

* Update honeywell.py

* Update honeywell.py
2019-03-09 21:47:28 +05:30
Jason Hu
bbd01968ba Override http.trusted_networks by auth_provider.trusted_networks (#21844) 2019-03-08 23:56:37 -08:00
Robbie Trencheny
9ab0753cf7 mobile_app improvements (#21607)
* First webhook commands for getting and deleting single registrations

* Keep a list of deleted webhook IDs so we can 410 if the webhook receives traffic in the future

* Return a empty JSON object instead of None

* Split up mobile_app bits into individual files

* Add typing

* Sort keys

* Remove unused async_setup_entry

* New decorator method of registering webhooks

* Add tests for cloud hook forwarding and improve error handling for cloud hooks

* Initial implementation of platform specific logic

* Add get registrations by user ID websocket call, minor style fixes

* Stop using resp dictionary during registration

* Move mobile_app/ios.py to ios/mobile_app.py

* Log any errors encountered during webhook

* Improve update registration call

* Split up mobile_app tests to match split up component

* Fix tests

* Remove integration_map in favor of component name in registration

* Add a few helper functions for custom logic components to use

* Load the app_component platform at device registration or component setup time

* Remove extraneous function

* Use guard function for checking if component is in device

* Inline websocket schemas

* Rename ATTR_s used in storage to DATA_ prefix

* squash flake8 and pylint issues

* Remove ios.mobile_app platform

* Dont mark websocket_api as a dependency

* Return standard empty_okay_response with 400 if no JSON sent

* Ensure deleted webhook IDs are registered at launch

* Remove the creation of cloudhooks during handle_webhook

* Rename device to registration everywhere applicable

* Dont check if cloud is logged in, just check if cloud is in components

* Dont ever use cloudhook_id

* Remove component loading logic for a later PR

* Cast exception to string

* Remove unused functions
2019-03-08 23:44:56 -08:00
Aaron Bach
49eaa34e03 Fixed a misspelling in a docstring (#21846) 2019-03-08 22:36:41 -07:00
Andrew Sayre
c5734eecc7 Update dependencies to receive data on webhook callbacks (#21838) 2019-03-08 21:20:07 -08:00
Aaron Bach
113db9afd4 Fix config entry exception in Ambient PWS (#21836) 2019-03-08 21:25:35 -06:00
William Scanlon
012c657a9c Updated to pyeconet 0.0.10 (#21837) 2019-03-08 21:24:17 -06:00
engrbm87
76d11e4b74 fix empty TOPIC_BASE issue (#21740)
* fix empty TOPIC_BASE issue

if the value of the TOPIC_BASE is empty then we need to remove "~" from the topic value if it exists. 
by doing `if base:` on line 239 the condition will be false if the value is empty so the '~' will not be stripped from the topic value.
I simply removed the `if base:` line and added `if TOPIC_BASE in payload:`

* Update homeassistant/components/mqtt/discovery.py

Co-Authored-By: engrbm87 <engrbm87@gmail.com>
2019-03-08 16:48:54 -08:00
Mike Megally
d8ac761bb6 Synology sensor quick return if attr is null (#21709)
* Quick return if attr is null

There are some case where attr is null. Returning null doesn't change anything (in my case this is mapped to a volume that doesn't exist, not sure what others are seeing). 

If you have confirmed you hass instance for C instead of F you do not see this error.

* update == to is

* whitespace
2019-03-08 16:35:38 -08:00
Finbarr Brady
0f189809a9 Add support for Cisco Mobility Express (#21531)
* Move cisco me to new layout

* Add docstring

* Move items out of init method and pass the controller instance to the scanner in get_scanner

* Update homeassistant/components/cisco_mobility_express/device_tracker.py

Co-Authored-By: fbradyirl <fbradyirl@users.noreply.github.com>

* Update homeassistant/components/cisco_mobility_express/device_tracker.py

Co-Authored-By: fbradyirl <fbradyirl@users.noreply.github.com>

* Update homeassistant/components/cisco_mobility_express/device_tracker.py

Co-Authored-By: fbradyirl <fbradyirl@users.noreply.github.com>

* Update homeassistant/components/cisco_mobility_express/device_tracker.py

Co-Authored-By: fbradyirl <fbradyirl@users.noreply.github.com>

* Fix build error

* Cleanup based on comments.
2019-03-09 00:47:06 +01:00
Robbie Trencheny
31a4187cc0 Log if aiohttp hits error during IndieAuth (#21780)
* Log if aiohttp hits error during IndieAuth

* Add content of redirect_url into error log

Co-Authored-By: awarecan <awarecan@users.noreply.github.com>
2019-03-08 14:51:13 -08:00
Jason Hu
3d8673dbf8 Resolve auth_store loading race condition (#21794)
* Add lock in auth_store._async_load()

* Python 3.5 does not like assert_called_once()
2019-03-08 14:50:24 -08:00
Jason Hu
3ff2d99cd6 Load logger and system_log components as soon as possible (#21799) 2019-03-08 14:47:10 -08:00
Paulus Schoutsen
22ab5a498f Change how we import config modules (#21824) 2019-03-08 14:09:18 -08:00
uchagani
ed6082eb2b change paths to be relative (#21827) 2019-03-08 14:08:19 -08:00
Paulus Schoutsen
4c9e5eef9c Remove stub from config component (#21822) 2019-03-08 14:07:49 -08:00
Paulus Schoutsen
3da0ed9cc7 Onboarding to generate auth code (#21777) 2019-03-08 13:51:42 -08:00
Toon Willems
a0e8543aed remove occupancy, as it is not available at this level in the iRail api (#21810) 2019-03-09 02:49:48 +05:30
Greg Dowling
7226e917ed Bump loopenergy to 0.1.0. Loop updated their socket.io server from 0.9 to 2.0 - which required a library update. (#21809) 2019-03-09 02:13:59 +05:30
Finbarr Brady
4571f1bf0d Adding enigma2 media player (#21271)
* Updated based on review comments

* fix hound

* Update homeassistant/components/media_player/enigma2.py

* Update homeassistant/components/media_player/enigma2.py

* Update homeassistant/components/media_player/enigma2.py

* Update enigma2.py

* Update enigma2.py

* Move file and update docsstring

* Fix path in coverage rc file

* requirements

* Update media_player.py

* Setup discovery for e2

* Handle discovered devices

* Add reqs

* Update for auth for openwebif

* Forget to set DEFAULT_PASSWORD

* Add source selection

* Fix get current source name

* Update pip version

* - adding some extra attributes
- support better recording playback integration

* bump pip version

* Bump pip

* Adding prefer_picon config option

* Updates to move logic into pypi module

* bump pip

* bump pip

* - remove http dependancy.

- rename prefer_picon to use_channel_icon

* Bump pypi to fix toggle bug.

also fix travis

also move setup out of init
2019-03-08 14:56:10 +01:00
Ville Skyttä
dfd9f7ccf3 Upgrade huawei-lte-api to 1.1.5 (#21791) 2019-03-08 09:28:53 +01:00
Jose Motta Lopes
f705ac6b43 Add Time of Flight Sensor using VL53L1X (#21230)
* Add Time of Flight Sensor using VL53L1X

* Fix issues found by bot

* Fix issues from bot

* Remove extra logs

* Keep removing logs dependencies not used

* Remove log from update

* Add logger info to async_update

* Fix over-indented line

* Fix pylint error

* Remove logger reporting successful operation

* Update requirements

* Update requirements_all.txt

* Update requirements_test_all.txt

* Used isort to keep imports and added STMicroelectronics to docstring

* Replace time.sleep by asyncio.sleep

* Add requirements to COMMENT_REQUIREMENTS and fix typo

* Using async_add_executor_job to schedule the call in the pool

* Fix typo

* Optimize async_update

* Updated requirements files

* Group and schedule calls that should be run sequentially

* Fix lint errors

* Revision showing development history

* Cleaning and typos

* Cleaning and typos

* Fix wrong-import-order

* Fix gen_requirements_all

* Schedule rpi_gpio I/O on the executor thread pool

* Fix partial parameters

* Fix bot error - add blank line

* Fix lint error

* Remove dependencies from requirements

* Review initial commits

* Move all device I/O to async_update

* Update requirements_all.txt

* Revised header with no url to the docs

* Use async_added_to_hass to add and initialize the sensor

* Add docstring to init()

* Move sensor.open() to async_setup_platform

* Remove logging and async

* Fix typo

* Move sensor.open to safe initialization

* Fix typo

* Fix typo

* Add the new tof module to .coveragerc

* Move the sensor platform under a tof package

* Update .coveragerc and requirements_all for tof package
2019-03-08 08:21:22 +01:00
Paulus Schoutsen
ac4d5d7c30 Merge pull request #21778 from home-assistant/rc
0.89.1
2019-03-07 23:16:17 -08:00
Ville Skyttä
2812483193 Upgrade pylint to 2.3.1 (#21789) 2019-03-08 09:13:35 +02:00
Paulus Schoutsen
f3e8e34089 Add workflow for tests 2019-03-07 17:03:23 -08:00
Paulus Schoutsen
eae6d1c7a6 Bumped version to 0.89.1 2019-03-07 16:48:53 -08:00
William Scanlon
a121c92f52 Updated to newest pyeconet (#21772) 2019-03-07 16:48:47 -08:00
David Thulke
4d6f21ecb2 adds missing SUPPORT_VOLUME_SET flag to webos media_player (#21766) 2019-03-07 16:48:46 -08:00
Sebastian Muszynski
1638d0a92f Bump PyXiaomiGateway version to 0.12.2 (Closes: #21731) (#21764) 2019-03-07 16:48:46 -08:00
Jason Hu
c031fd4164 Fix script load module issue (#21763)
* Fix script load depedency

* Revert #21754
2019-03-07 16:48:45 -08:00
Jason Hu
78a806bc5c Fix script load module issue (#21763)
* Fix script load depedency

* Revert #21754
2019-03-07 16:48:14 -08:00
David Thulke
2fb978393b adds missing SUPPORT_VOLUME_SET flag to webos media_player (#21766) 2019-03-07 16:46:50 -08:00
William Scanlon
a843da1bfc Updated to newest pyeconet (#21772) 2019-03-07 16:46:01 -08:00
Sebastian Muszynski
cfd94ecbbc Bump PyXiaomiGateway version to 0.12.2 (Closes: #21731) (#21764) 2019-03-07 22:55:11 +01:00
Marvin Wichmann
5112f8f6b5 Introduce target_temperature_state_address for climate device (#21541) 2019-03-07 21:53:42 +00:00
Jason Hu
5f0c37ccfc Fix colorlog import error (#21754)
* Fix colorlog import error

* Lint
2019-03-07 11:07:24 -08:00
Jason Hu
c91fb82807 Fix colorlog import error (#21754)
* Fix colorlog import error

* Lint
2019-03-07 11:07:07 -08:00
Daniel Shokouhi
e412317194 Fix botvac connected maps call as it is not a supported model (#21752) 2019-03-07 11:06:42 -08:00
Leonardo Merza
44341a958a automated commit 07/03/2019 10:47:38 (#21749) 2019-03-07 11:06:41 -08:00
Markus Jankowski
5a555102b9 Fix group-switch availability for Homematic IP (#21640)
* Add available=True to groups

* Added unreach to stateattributes

* Fixed comments

* added missing sabotage check

* added missing lowBat check

* fix typo

* apply suggestion

Co-Authored-By: SukramJ <markus@mm-jankowski.de>

* apply suggestion

Co-Authored-By: SukramJ <markus@mm-jankowski.de>

* applied suggiestions

* readded lost str()

* fix comment
2019-03-07 11:06:40 -08:00
Markus Jankowski
aebe6ab70c Fix Name of Homematic IP accesspoint in devices, if name is configured (#21617)
* Fix Name of Accesspoint if name is configured

* fix lint

* Simplyfied naming

* applied suggestion

Co-Authored-By: SukramJ <markus@mm-jankowski.de>

* update comment
2019-03-07 11:06:39 -08:00
Kevin Fronczak
48c9758cf5 Upgrade blinkpy==0.13.1 (Fixes #21559) (#21578)
* Upgrade blinkpy with new api endpoint

* Change wifi units to dBm
2019-03-07 11:06:39 -08:00
Leonardo Merza
e356b48fca automated commit 07/03/2019 10:47:38 (#21749) 2019-03-07 11:03:32 -08:00
Daniel Shokouhi
fc943dc4b6 Fix botvac connected maps call as it is not a supported model (#21752) 2019-03-07 11:03:02 -08:00
Paulus Schoutsen
279470613c Updated frontend to 20190305.1 2019-03-07 10:54:56 -08:00
zewelor
f2abc91c1e Allow light toggle service to accept all turn on params (#20912) 2019-03-07 22:33:30 +05:30
Pascal Vizeli
61786b79f7 Revert pull request to push 2019-03-07 15:33:13 +01:00
Pascal Vizeli
720b0c5334 Revert Travis until github actions work better for PR (#21746) 2019-03-07 15:30:48 +01:00
Pascal Vizeli
5c2d174d5f Change github trigger type 2019-03-07 15:25:27 +01:00
Pascal Vizeli
02bcf46053 Update .travis.yml (#21736)
* Update .travis.yml

* Update tox.ini

* Update main.workflow

* Update tox.ini
2019-03-07 14:40:18 +01:00
Jason Hu
ba70459e1e Remove pytest warning message (#21713) 2019-03-07 16:59:15 +05:30
Markus Jankowski
1891d5bf22 Fix group-switch availability for Homematic IP (#21640)
* Add available=True to groups

* Added unreach to stateattributes

* Fixed comments

* added missing sabotage check

* added missing lowBat check

* fix typo

* apply suggestion

Co-Authored-By: SukramJ <markus@mm-jankowski.de>

* apply suggestion

Co-Authored-By: SukramJ <markus@mm-jankowski.de>

* applied suggiestions

* readded lost str()

* fix comment
2019-03-07 11:12:03 +01:00
Markus Jankowski
a46458d04f Fix Name of Homematic IP accesspoint in devices, if name is configured (#21617)
* Fix Name of Accesspoint if name is configured

* fix lint

* Simplyfied naming

* applied suggestion

Co-Authored-By: SukramJ <markus@mm-jankowski.de>

* update comment
2019-03-07 11:07:32 +01:00
Leonardo Merza
9c70b00403 tplink - catch SmartDeviceException on is_dimmable call (#21726)
* automated commit 06/03/2019 20:49:50

* automated commit 06/03/2019 20:53:13

* automated commit 06/03/2019 20:53:48
2019-03-07 10:54:09 +01:00
Jason Hu
38a93afa66 Make pytest in tox quite (#21727) 2019-03-06 22:27:46 -08:00
Jason Hu
a85119ac09 Fix pylint warning on python 3.7 (#21714) 2019-03-07 06:47:56 +01:00
c-soft
f4a9ad0b2e Fix initialization and add "pending" status of Satel integra (#21194)
* Added updating alarm state after start of the HA. Still rough and dirty.

* Fixed initialization of the panel and binary sensor.  Before cleanup.

* Added alarm clearing, linting fixes.

* Removed dead code, added style changes.

* Updated requirements

* Fixed linting errors.

* Fixed linting errors

* Fixed linter errors.

* Fixed hopefully last linter errors.

* Fixes after code review, imports sorted.

* Removed init debugging
2019-03-06 19:47:47 -08:00
Sergio Oller
9f06be750f Support multiple keys in ifttt triggers (#21454)
* Support multiple keys in ifttt triggers

* Rename `to` to `target` in ifttt.

Follow PR code review suggestions
2019-03-06 19:47:13 -08:00
Jc2k
dbf129dfdd Start preparing for homekit_controller config entries (#21564)
* Start preparing for homekit_controller config entries

* Review feedback

* Review feedback

* Only use the vol.strip validator for pairing_code

* CV not required now

* Changes from review

* Changes after review
2019-03-06 19:44:52 -08:00
Phil Bruckner
5616505032 Change amcrest camera_image to async (#21720)
Change AmcrestCam method camera_image to async so asyncio lock can be used instead of a threading lock. Bump amcrest package to 1.2.5.
2019-03-06 19:42:59 -08:00
Paulus Schoutsen
88bc3033d3 Merge pull request #21712 from home-assistant/rc
0.89.0
2019-03-06 15:15:37 -08:00
Paulus Schoutsen
21de636e5b Bumped version to 0.89.0 2019-03-06 10:07:31 -08:00
Franck Nijhof
87b5faa244 Upgrade toonapilib to 3.2.1 (#21706) 2019-03-06 10:05:32 -08:00
Fredrik Erlandsson
c2f4293c6a resync hass that changes have occured (#21705) 2019-03-06 10:05:31 -08:00
Franck Nijhof
0e36b26770 Upgrade toonapilib to 3.2.1 (#21706) 2019-03-06 07:40:29 -08:00
Diogo Gomes
8e9a496002 Utility Meter offset defined by a time_period (#20926)
* change offset from int to Time period dictionary

* track according to offset

* left overs... tks @fabaff

* typo
2019-03-06 07:55:24 -05:00
Fredrik Erlandsson
54895fcb1e resync hass that changes have occured (#21705) 2019-03-06 07:52:25 -05:00
Alan Tse
b7b034c532 Update to teslajsonpy v0.0.25 (#21702) 2019-03-05 21:44:37 -08:00
Penny Wood
d1038ea79f Google Assistant: Create and pass context to service calls (#21551)
* Google Assistant: Create and pass context to service calls

* Refactor request data into separate object and pass to execute.
2019-03-05 20:00:53 -08:00
Paulus Schoutsen
fc1ee9be43 Use new style for built-in ws commmands (#21694)
* Use new style for built-in ws commmands

* Lint
2019-03-05 19:31:26 -08:00
Paulus Schoutsen
c9b173405b Fix Z-Wave relative imports (#21693) 2019-03-05 17:17:58 -08:00
Paulus Schoutsen
4c72f3c48b Bumped version to 0.89.0b3 2019-03-05 11:46:30 -08:00
carstenschroeder
cb613984df Fix ADS race condition (#21677) 2019-03-05 11:46:19 -08:00
Diogo Gomes
4978a1681e check we have a tb (#21670) 2019-03-05 11:46:18 -08:00
Paulus Schoutsen
2303e1684e Updated frontend to 20190305.0 2019-03-05 11:45:46 -08:00
Paulus Schoutsen
467d8d616e Updated frontend to 20190305.0 2019-03-05 11:45:31 -08:00
Alan Tse
dbb92048aa Bump teslajsonpy to 0.0.24 (#21675)
* Bump teslajsonpy to 0.0.24

* Update requirements_all.txt
2019-03-05 09:23:00 -08:00
Jonathan McDowell
401720085d Allow 202 status code as a successful REST notify response (#21678)
The REST notification component only allows 200 + 201 as a successful
response code to the submission. notify.me returns a 202 (Accepted)
response, which works fine but gets logged as a warning in the log.
Update the allowed statuses to treat the 202 as ok.
2019-03-05 09:22:21 -08:00
Nick Whyte
7d9c14541b Bump nessclient version to 0.9.14 (#21679) 2019-03-05 09:21:13 -08:00
Phil Bruckner
16d79b52c3 Serialize amcrest snapshot commands and bump PyPI package to 1.2.4 (#21664)
* Serialize snapshot commands and bump amcrest package to 1.2.4

Attempting to send a snapshot command when a previous one hasn't finished will result in warnings and/or errors. This can happen when the camera picture is clicked on in the frontend, resulting in the thread that updates the thumbnail in the background every 10 seconds to sometimes collide with the thread that updates the large picture in the foreground quickly. An automation that calls the camera.snapshot service in yet another thread can make the situation worse. Fix by adding a thread lock to serialize snapshot commands. Also bump the amcrest package to 1.2.4 which fixes error handling in the command method and improves performance by reusing requests sessions.

* Update amcrest package to 1.2.4
2019-03-05 17:03:19 +01:00
Steven Looman
3ffff887d8 Adds option in UPnP component to override callback url (#21583)
* Add option to override callback url

* Upgrade to async_upnp_client==0.14.5

* Fix requirements_all.txt
2019-03-05 15:48:44 +00:00
carstenschroeder
17c3c14833 Fix ADS race condition (#21677) 2019-03-05 11:07:40 +01:00
Colby Rome
0e78054195 Xfinity Gateway device_tracker platform (#21026)
* initial commit

* updated .coveragerc, CODEOWNERS, generated requirements_all.txt

* fixed lines exceeding 79 characters

* pylint fixes

* shorten docstring and simplify get_scanner

* extract initialization into get_scanner

* bump pypi version

* name change
2019-03-04 22:57:45 -08:00
Diogo Gomes
efe4ce9a05 check we have a tb (#21670) 2019-03-05 06:18:25 +01:00
ktnrg45
efa5d5dfe3 Add support for multiple devices for PS4 component (#21302)
* Support multiple devices.

* Revert "Support multiple devices."

This reverts commit 3f5d4462a98da13ebb1ab1c07d341dbd7020e6cc.

* Support multiple devices

* Bump to 0.3.3

* bump 0.3.4

* Add tests for multiple devices.

* Update Requirements

* Update config_flow.py

* Update config_flow.py

* fixed typo

* Reordered functions

* Added multiple flow implementation test.

* fix

* typo

* fix tests

* bump 0.4.0

* Bump 0.4.0

* 0.4.0

* bump version

* bump version

* bump version

* Add keep alive feature with multiple devices

* bump version

* bump version

* bump version

* bump 0.4.7

* bump 0.4.7

* bump 0.4.7

* Edited tests.

* bump/pylint

* pylint

* bump/pylint

* bump/pylint

* Change to add additional entry

* Changed to multiple entries

* pylint

* Corrections to manage multiple devices.

* lint

* comments

* Removed redundant for loop

* Shorthand correction

* Remove reference to private object

* Test fix

* Revert changes. Test failure.

* Test fix

* test fix

* unindent assertions

* pylint
2019-03-05 01:48:25 +01:00
Paulus Schoutsen
3135257c0d Bumped version to 0.89.0b2 2019-03-04 16:02:05 -08:00
Paulus Schoutsen
b20b811cb9 Avoid recorder thread crashing (#21668) 2019-03-04 16:01:59 -08:00
Paulus Schoutsen
df25128923 Avoid recorder thread crashing (#21668) 2019-03-04 16:01:31 -08:00
Franck Nijhof
a778cd117f Upgrade toonapilib to 3.1.0 (#21661) 2019-03-04 16:01:15 -08:00
Franck Nijhof
31b88197eb 🚑 Fixes Toon doing I/O in coroutines (#21657) 2019-03-04 16:01:14 -08:00
Paulus Schoutsen
81c252f917 Rename Google Assistant evenets (#21655) 2019-03-04 16:01:13 -08:00
Franck Nijhof
f5a0b5ab98 👕 Corrects unit of measurement symbol for Watt (#21654) 2019-03-04 16:01:12 -08:00
Gijs Reichert
a382ba731d Cast displaytime to int for JSON RPC (#21649) 2019-03-04 15:59:19 -08:00
Paulus Schoutsen
cca8d4c951 Fix calc next (#21630) 2019-03-04 15:59:18 -08:00
Anders Melchiorsen
932080656d Upgrade pysonos to 0.0.8 (#21624) 2019-03-04 15:59:18 -08:00
Jason Hu
d5bdfdb0b3 Resolve race condition when HA auth provider is loading (#21619)
* Resolve race condition when HA auth provider is loading

* Fix

* Add more tests

* Lint
2019-03-04 15:59:17 -08:00
Andrew Sayre
d9806f759b Handle when installed app has already been removed (#21595) 2019-03-04 15:59:16 -08:00
Anders Melchiorsen
e6debe09e8 Word the tplink deprecation warning more strongly (#21586) 2019-03-04 15:59:16 -08:00
Jason Hu
c5dad82211 Log exception occurred in WS service call command (#21584) 2019-03-04 15:59:15 -08:00
Daniel Høyer Iversen
ec9ccf6402 Upgrade PyXiaomiGateway library (#21582) 2019-03-04 15:59:15 -08:00
Jason Hu
a268aab2ec Re-thrown exception occurred in the blocking service call (#21573)
* Rethrown exception occurred in the actual service call

* Fix lint and test
2019-03-04 15:59:14 -08:00
damarco
996e0a6389 Bump zigpy-deconz (#21566) 2019-03-04 15:59:14 -08:00
emontnemery
e877983533 Make time trigger data trigger.now local (#21544)
* Make time trigger data trigger.now local

* Make time pattern trigger data trigger.now local

* Lint

* Rework according to review comment

* Lint
2019-03-04 15:59:13 -08:00
Robbie Trencheny
73675d5a48 mobile_app component (#21475)
* Initial pass of a mobile_app component

* Fully support encryption, validation for the webhook payloads, and other general improvements

* Return same format as original API calls

* Minor encryption fixes, logging improvements

* Migrate Owntracks to use the superior PyNaCl instead of libnacl, mark it as a requirement in mobile_app

* Add mobile_app to .coveragerc

* Dont manually b64decode on OT

* Initial requested changes

* Round two of fixes

* Initial mobile_app tests

* Dont allow making registration requests for same/existing device

* Test formatting fixes

* Add mobile_app to default_config

* Add some more keys allowed in registration payloads

* Add support for getting a single device, updating a device, getting all devices. Also change from /api/mobile_app/register to /api/mobile_app/devices

* Change device_id to fingerprint

* Next round of changes

* Add keyword args and pass context on all relevant calls

* Remove SingleDeviceView in favor of webhook type to update registration

* Only allow some properties to be updated on registrations, rename integration_data to app_data

* Add call service test, ensure events actually fire, only run the encryption tests if sodium is installed

* pylint

* Fix OwnTracks test

* Fix iteration of devices and remove device_for_webhook_id
2019-03-04 15:59:12 -08:00
roblandry
e10e27d809 Add SmartThingsAccelCluster to ZHA binary_sensor (#21609)
* Add SmartThingsAccelCluster to binary_sensor

* Make corrections per discussion with @dmulcahey

* Add missing const to gateway.py

* Remove Acceleration from no sensor
2019-03-04 15:56:05 -08:00
Jason Hu
4a3b4cf346 Resolve race condition when HA auth provider is loading (#21619)
* Resolve race condition when HA auth provider is loading

* Fix

* Add more tests

* Lint
2019-03-04 15:55:26 -08:00
Daniel Høyer Iversen
7a7080055e Netatmo, handle missing thermostat devices (#21651) 2019-03-04 15:54:21 -08:00
Franck Nijhof
955b71c44b 👕 Corrects unit of measurement symbol for Watt (#21654) 2019-03-04 15:53:16 -08:00
Franck Nijhof
73b100d3af 🚑 Fixes Toon doing I/O in coroutines (#21657) 2019-03-04 15:52:00 -08:00
Franck Nijhof
641138a986 Upgrade toonapilib to 3.1.0 (#21661) 2019-03-04 15:51:15 -08:00
Paulus Schoutsen
27e8a6ee80 Rename Google Assistant evenets (#21655) 2019-03-04 13:18:16 -08:00
Alok Saboo
5375510535 Add camera name to logs (#21653) 2019-03-04 12:06:28 -08:00
Paulus Schoutsen
8213016eaf Allow targeting areas in service calls (#21472)
* Allow targeting areas in service calls

* Lint + Type

* Address comments
2019-03-04 09:51:12 -08:00
Nate Clark
f62eb22ef8 Add support for DHT and DS18B20 sensors via Konnected firmware (#21189)
* mvp basic temperature sensor support

* support for DHT temperature & humidity

* add support for ds18b20 sensors

* improve resolution of device settings

* update requirements_all.txt

* re-organize new file

* don't use filter(lambda: syntax

* set unique_id on entities to allow renaming in the UI

* leverage base Entity module to do C to F conversion

* add option for setting poll_interval

* use handler pattern to handle updates from Konnected device

* cleanups from code review
2019-03-04 16:56:41 +01:00
Gijs Reichert
158e25562b Cast displaytime to int for JSON RPC (#21649) 2019-03-04 15:25:28 +01:00
Pascal Vizeli
72b6e80d02 Better output of workflow 2019-03-04 14:06:05 +01:00
Fabian Affolter
eb1d7be67c Upgrade youtube_dl to 2019.03.01 (#21647) 2019-03-04 14:00:10 +01:00
Pascal Vizeli
c60627c699 GitHub Workflow (#21643)
* Fix tox.ini

* Update main.workflow

* Update tox.ini

* Update main.workflow

* Update main.workflow

* Update tox.ini

* Try only with one

* Update main.workflow

* Update main.workflow

* Update main.workflow

* Update main.workflow

* Update main.workflow
2019-03-04 12:36:50 +01:00
Pascal Vizeli
5c9f266672 Fix actions with tox (#21642)
* Fix actions with tox

* Update main.workflow
2019-03-04 10:23:19 +01:00
Pascal Vizeli
5efcbc5043 Replace travis (#21641) 2019-03-04 09:59:35 +01:00
Nick Whyte
10e334cbf0 Allow configuration of update interval for ness_alarm (#21415)
* ness_alarm: Allow configuration of update_interval

* requirements

* update_interval -> scan_interval

* Consistent config validation

* requirements

* don't touch dependency version
2019-03-04 00:05:44 -08:00
Paulus Schoutsen
43f85f7053 Updated frontend to 20190303.0 2019-03-03 22:41:38 -08:00
Paulus Schoutsen
c03116291e Updated frontend to 20190303.0 2019-03-03 21:55:51 -08:00
Paulus Schoutsen
de9e6e8d1a Update translations 2019-03-03 21:53:45 -08:00
David F. Mulcahey
fc07d3a159 Add storage helper to ZHA and use it for the device node descriptor (#21500)
* node descriptor implementation

add info to device info

disable pylint rule

check for success

* review comments

* send manufacturer code for get attr value for mfg clusters

* ST report configs

* do zdo task first

* add guard

* use faster reporting config

* disable false positive pylint
2019-03-03 21:22:42 -08:00
Jason Hu
ee6f09dd29 Log exception occurred in WS service call command (#21584) 2019-03-03 21:22:22 -08:00
Paulus Schoutsen
48a2e50f84 Fix calc next (#21630) 2019-03-03 21:36:13 -07:00
Paulus Schoutsen
f5ed6432eb Expose create/delete cloudhook (#21606)
* Expose create/delete cloudhook

* Make sure we dont publish cloudhooks when not connected
2019-03-03 19:03:49 -08:00
shanbs
c25cbccca9 Return Netatmo climate operation_mode instead of boiler status (#21633)
* Merge the devices into one list and add into entries at once; Return operation_mode instead of boiler status.

* Removing property operation_mode
2019-03-04 02:42:29 +01:00
Aaron Bach
31bcf6c35f Bump pyflunearyou to 1.0.3 (#21634) 2019-03-03 18:39:13 -07:00
Willem Burgers
2017e45d78 fix derived rate, fixes #20097 (#21620)
* fix derived rate, fixes #20097

* fix derived rate, fixes #20097

* Fix typo

thnx @amelchio

* Make the test more realistic

Took values from my own smart meter for the test

* Update test to ignore rounding issues
2019-03-03 23:42:52 +01:00
srirams
818776d2b4 Add optional sender name for SendGrid (#21610)
* Set "Home Assistant" as email sender name for SendGrid

* make sender name configurable

* sendgrid tweaks

* fix config
2019-03-03 13:44:40 -08:00
Jeff Irion
fa938f5628 Add 'app_name' property and 'apps' config entry to Fire TV (#21601)
* Add 'app_name' property and 'apps' config entry to Fire TV

* Define 'CONF_APPS', don't import it

* Address reviewer comments
2019-03-03 12:39:39 -08:00
Markus Jankowski
3032283b99 Add device HMIP-eTRV-C to HomematicIP (#21612)
* Update dependencies

* Add additional device HMIP-eTRV-C

add valveActualTemperature to HeatingThermostats (HMIP-eTRV-C, HMIP-eTRV, HMIP-eTRV-2)

* Removed HomematicipThermostatTemperatureSensor

already in climate
2019-03-03 12:33:48 -08:00
kennedyshead
1308ead8d6 Bumping aioasuswrt (#21627) 2019-03-03 12:31:09 -08:00
Andrew Sayre
3e0459cef9 SmartThings remove SmartApp/Automation on integration removal (#21594)
* Add clean-up logic upon entry removal

* Removed unecessary app removal from migration

* Change log level and clarified code
2019-03-03 13:47:25 -06:00
Anders Melchiorsen
0f6e0aa355 Upgrade pysonos to 0.0.8 (#21624) 2019-03-03 18:49:29 +01:00
Maikel Punie
b985223603 Add the velbus sync clock service (#21308)
* Add the velbus sync clock service

* Fixed houndci-bot commants

* Fix lint and pylint

* fixed all comments

* Hound bot comments

* Fix for flake8
2019-03-03 06:37:36 -06:00
Andrew Sayre
1e60993aa7 Handle when installed app has already been removed (#21595) 2019-03-02 21:57:57 -06:00
shanbs
18372ad81b Added support for multiple Netatmo thermostats/valves (#19407)
* climate/netatmo: Added support for muletiple thermostats/valves

* Adjusted the update interval throttle to 10 seconds

* Avoid returning 'homes' without 'therm_schedules'

* Requires home to have 'modules' as well as 'therm_schedules'; Using pyatmo 1.7

* Support multiple homes

* Fix nest level too deep issue

* Fix crashing bug when discovery is true

* Fix crashing bug when discovery is true

* Modifications according to review comments

* Resolve format issue

* Fix mode name issue

* Revisions according to review's suggestions

* Revisions according to review's comments

* Revisions according to review's comments
2019-03-02 19:51:42 -08:00
Matt White
18491c515f Further Yale ZWave lock device mapping cleanup (#21128)
* Update device mapping for workarounds from zwave device db

* Update comment on old Yale vendor ID
2019-03-02 20:29:16 -06:00
Rohan Kapoor
9af8c95e83 Upgrade motorparts to 1.1.0 (#21602) 2019-03-02 20:23:17 -06:00
ehendrix23
833f17de04 Add parameter hold_secs for Harmony remote send command (#19650)
* Update requirements

Updated requirements

* Small bump for aioharmony

Small version bump increase for aioharmony

* Add attributes

Add firmware and config version attributes

* Add hold for button press on send_command

* Fix requirements file

For some reason aioharmony ended up in there as a duplicate. Fixed it.

* Revert rebase changes

Revert some changes that should have been reverted back as part of rebase.

* Updated based on review

Removed HOLD_SECS from platform schema (configuration)
Updated getting kwargs in async_send_command
Updated debug log to include delay_secs
2019-03-03 00:54:03 +01:00
Daniel Perna
b8eebda541 Update pyhomematic (#21600) 2019-03-02 17:42:51 -05:00
David F. Mulcahey
45316f6ed6 ZHA fixes (#21592)
* do not report on 0x1000 LightLink cluster
* don't flood Zigbee network during configuration or initialization
* add lifeline of 60 minutes to lights
* use ootb polling
2019-03-02 14:09:01 -05:00
Anders Melchiorsen
5eab86986e Word the tplink deprecation warning more strongly (#21586) 2019-03-02 12:32:18 +01:00
Joe Trabulsy
61e4a6be18 Update for new pyvesyncv_v2 library and vesync switch support (#21449)
* Change dependency to pyvesync-v2 for vesync switch

* Update requirements_all.txt

* Update Version - Wall Switch Support

Update required version for vesync outlets and switches.  Eliminate API call for energy usage for wall switches that do not have that feature

* fix name convention
2019-03-02 11:57:10 +01:00
Diogo Gomes
1ad4779443 Add network throughput statistics to systemmonitor sensor (#21575)
* add network throughput

* lint
2019-03-02 16:08:15 +05:30
Diogo Gomes
ed2b9e5483 Centrally define Watt (#21570)
* centralize Watt definition

* lint
2019-03-02 11:29:59 +01:00
Kevin Fronczak
e55ce61100 Upgrade blinkpy==0.13.1 (Fixes #21559) (#21578)
* Upgrade blinkpy with new api endpoint

* Change wifi units to dBm
2019-03-02 11:28:44 +01:00
Daniel Høyer Iversen
8e75bfb11e Upgrade PyXiaomiGateway library (#21582) 2019-03-02 11:27:36 +01:00
Penny Wood
f61f650495 Get room hints from areas (#21519)
* Get google room hint from area.

* Test case for area code.

* Updates as per code review.
2019-03-01 23:31:57 -08:00
Anders Melchiorsen
0c8a31b8ec Memory optimization for logbook (#21549) 2019-03-01 23:23:45 -08:00
Jason Hu
f1b867dccb Re-thrown exception occurred in the blocking service call (#21573)
* Rethrown exception occurred in the actual service call

* Fix lint and test
2019-03-01 23:09:31 -08:00
emontnemery
cd89809be5 Make time trigger data trigger.now local (#21544)
* Make time trigger data trigger.now local

* Make time pattern trigger data trigger.now local

* Lint

* Rework according to review comment

* Lint
2019-03-01 23:09:12 -08:00
Robbie Trencheny
655ada1374 mobile_app component (#21475)
* Initial pass of a mobile_app component

* Fully support encryption, validation for the webhook payloads, and other general improvements

* Return same format as original API calls

* Minor encryption fixes, logging improvements

* Migrate Owntracks to use the superior PyNaCl instead of libnacl, mark it as a requirement in mobile_app

* Add mobile_app to .coveragerc

* Dont manually b64decode on OT

* Initial requested changes

* Round two of fixes

* Initial mobile_app tests

* Dont allow making registration requests for same/existing device

* Test formatting fixes

* Add mobile_app to default_config

* Add some more keys allowed in registration payloads

* Add support for getting a single device, updating a device, getting all devices. Also change from /api/mobile_app/register to /api/mobile_app/devices

* Change device_id to fingerprint

* Next round of changes

* Add keyword args and pass context on all relevant calls

* Remove SingleDeviceView in favor of webhook type to update registration

* Only allow some properties to be updated on registrations, rename integration_data to app_data

* Add call service test, ensure events actually fire, only run the encryption tests if sodium is installed

* pylint

* Fix OwnTracks test

* Fix iteration of devices and remove device_for_webhook_id
2019-03-01 23:08:20 -08:00
Andrew Sayre
0903bd92f0 Add config entry remove callback (#21576) 2019-03-01 21:13:55 -08:00
David F. Mulcahey
cd6c923123 fix exception (#21571) 2019-03-01 20:15:36 -05:00
Wagner Sartori Junior
b8ec74cc15 bump pyxeoma to 1.4.1 to fix and close #19306 (#21568) 2019-03-01 20:11:32 -05:00
damarco
1a9dcaefd2 Bump zigpy-deconz (#21566) 2019-03-01 13:47:20 -05:00
Paulus Schoutsen
52f337ef00 Allow chaining contexts (#21028)
* Allow chaining contexts

* Add stubbed out migration
2019-03-01 10:08:38 -08:00
David F. Mulcahey
b39846fb6b add friendly name to devices in the device registry (#21499)
switch to name_by_user

review comments

add device reg info to zha device api
2019-03-01 08:11:24 -05:00
msvinth
0aba49adce Add separate on/off ids on manual configured IHC lights (#20253)
* Add support for separate on/off ids on manual configured IHC lights.
This makes it easier to support IHC code units thats relies on being
turned on and off through specific inputs.
Also adds a pulse service (ihc.pulse) that supports sending a short on/off pulse to an IHC input.

* Fix

* Lint fix

* Add on/off id support in switch

* Make pulse async

* Code review fixes
2019-03-01 08:17:59 +01:00
Paulus Schoutsen
ee4be13bda Allow config entry reloading (#21502)
* Allow config entry reloading

* Fix duplicate test name

* Add comment

* fix typing
2019-02-28 22:27:20 -06:00
David F. Mulcahey
aa30ac52ea prevent duplicate event channel registration (#21534) 2019-02-28 22:53:59 -05:00
Aaron Bach
326513af90 Add pause/unpause services to RainMachine (#21548)
* Add pause/unpause services to RainMachine

* Update requirements
2019-02-28 17:58:39 -08:00
Paulus Schoutsen
ed28482311 Bumped version to 0.89.0b1 2019-02-28 17:58:23 -08:00
Aaron Bach
0f09c02875 Fix incorrect pyairvisual call (#21542) 2019-02-28 17:46:32 -08:00
Jason Hu
97b93bcf7b Fix warning (#21538) 2019-02-28 17:46:31 -08:00
emontnemery
b05062e9d9 Add missing retain option to mqtt.climate configuration schema (#21536) 2019-02-28 17:46:31 -08:00
Victor Vostrikov
6f2dd21516 Updated variable name for readability (#21528) 2019-02-28 17:46:30 -08:00
Jason Hu
eda2290d47 Allow skip-pip applied to HA core (#21527) 2019-02-28 17:46:30 -08:00
Paulus Schoutsen
238c4247d9 Only use a single store instance (#21521) 2019-02-28 17:46:30 -08:00
Paulus Schoutsen
4fe9f966ad Fix lint (#21520) 2019-02-28 17:46:29 -08:00
Anders Melchiorsen
26a534a67c Improve new Sonos snapshot/restore (#21509)
* Fine-tune new Sonos snapshot/restore

* Move into class
2019-02-28 17:46:29 -08:00
Aaron Bach
aa546b5a1f Add watchdog to Ambient PWS (#21507)
* Add watchdog to Ambient PWS

* Better labeling

* Owner comments
2019-02-28 17:46:28 -08:00
Robert Svensson
9e140d27bf Fix deCONZ retry mechanism for setup 2019-02-28 17:45:41 -08:00
Ben Randall
e6cbdf0645 Add PLATFORM_SCHEMA_BASE to telegram_bot component (#21155) 2019-02-28 17:44:04 -08:00
Paulus Schoutsen
1c889cfcc3 Updated frontend to 20190228.0 2019-02-28 17:43:48 -08:00
Paulus Schoutsen
5e67054ee1 Updated frontend to 20190228.0 2019-02-28 17:43:36 -08:00
David F. Mulcahey
901b2b4ba3 new websocket api way (#21533) 2019-02-28 19:32:41 -05:00
Aaron Bach
b8a94c30e8 Add watchdog to Ambient PWS (#21507)
* Add watchdog to Ambient PWS

* Better labeling

* Owner comments
2019-02-28 14:28:20 -08:00
Martin Hjelmare
40d7fbcda4 Clean up gpslogger tests (#21543) 2019-02-28 14:17:53 -08:00
Aaron Bach
8ebe5c61e8 Fix incorrect pyairvisual call (#21542) 2019-02-28 14:17:10 -08:00
Diogo Gomes
81dd2acf3b Update CODEOWNERS (#21545)
add myself to camera.push
2019-02-28 14:16:51 -08:00
Anders Melchiorsen
193cab4f62 Improve new Sonos snapshot/restore (#21509)
* Fine-tune new Sonos snapshot/restore

* Move into class
2019-02-28 10:25:31 -08:00
Jason Hu
b18b1cffff Fix warning (#21538) 2019-02-28 10:10:21 -08:00
cpopp
84b84559a4 Add support for homekit controller sensors (#21535)
Adds support for homekit devices with temperature, humidity, and
light level characteristics (such as the iHome iSS50)
2019-02-28 10:09:04 -08:00
David F. Mulcahey
82bdd9568d Add direct binding for remotes and lights for ZHA (#21498)
* cluster matching and binding apis

implement binding

callback

fix loop

fix loops

* review comments

* use any because it is clearer
2019-02-28 10:04:35 -08:00
Jason Hu
5ce4fe65b2 Allow skip-pip applied to HA core (#21527) 2019-02-28 10:01:10 -08:00
Paulus Schoutsen
4f4a8a61d2 Only use a single store instance (#21521) 2019-02-28 10:00:17 -08:00
Ben Randall
e14c8c788e Add PLATFORM_SCHEMA_BASE to telegram_bot component (#21155) 2019-02-28 18:27:40 +01:00
emontnemery
c340083ba5 Add missing retain option to mqtt.climate configuration schema (#21536) 2019-02-28 18:26:54 +01:00
Marco M
c3d4738649 Mqtt alarm added value_template and code_arm_required (#19558)
* Added value_template config for parsing json value from state topic

Added arm_code_required to avoid code enter when arming

* Renamed config parameter to code_arm_required

* Fix for discovery update compatibility

* Fixed lint error

* Added test
2019-02-28 17:44:23 +01:00
Fabian Affolter
b0dd6e4093 Upgrade python-mystrom to 0.5.0 (#21523) 2019-02-28 17:46:38 +05:30
Fabian Affolter
3e8e998078 Upgrade numpy to 1.16.2 (#21525) 2019-02-28 17:46:21 +05:30
Victor Vostrikov
342ddbfe8c Updated variable name for readability (#21528) 2019-02-28 17:35:39 +05:30
koolsb
bfc6f51b25 Add arm night for alarm decoder (#21488) 2019-02-28 17:15:17 +05:30
Jeff Irion
27a780dcc9 Register 'firetv.adb_command' service (#21419)
* Register 'media_player.firetv_adb_cmd' service

* Wrap the 'firetv_adb_cmd' service with 'adb_decorator'

* Address reviewer comments

* Move firetv to its own platform

* Move 'adb_command' service description

* Rename DOMAIN to FIRETV_DOMAIN

* Import KEYS in __init__ method

* Change 'self.KEYS' to 'self.keys'

* Update firetv in .coveragerc

* 'homeassistant.components.media_player.firetv' -> 'homeassistant.components.firetv'

* 'homeassistant.components.firetv' -> 'homeassistant.components.firetv.media_player'
2019-02-28 12:29:56 +01:00
Fabian Affolter
6f2def06be Upgrade opensensemap-api to 0.1.5 (#21524) 2019-02-28 11:59:14 +01:00
Paulus Schoutsen
229d19bb20 Fix lint (#21520) 2019-02-27 21:35:14 -08:00
Adam Dullage
548d7bbeda Bump starlingbank version to 3.1 (#21501)
* Bump starlingbank version to 3.1

Resolves Python 3.5 compatibility issue.

* Remove syntax error.
2019-02-28 09:53:21 +05:30
Aaron Bach
aad15776c0 Upgrade pyflunearyou to 1.0.2 (#21514) 2019-02-27 17:52:50 -07:00
Aaron Bach
c1365de861 Upgraded py17track to 2.2.2 (#21515) 2019-02-27 17:52:31 -07:00
Aaron Bach
fd32910185 Upgrade pytile to 2.0.6 (#21516) 2019-02-27 17:52:05 -07:00
Aaron Bach
1369b0b583 Upgrade pypollencom to 2.2.3 (#21517) 2019-02-27 17:51:36 -07:00
Aaron Bach
4ca7273c58 Upgrade pyopenuv to 1.0.9 (#21513) 2019-02-27 17:51:09 -07:00
Paulus Schoutsen
45bbe75d29 Bumped version to 0.89.0b0 2019-02-27 16:45:14 -08:00
Victor Vostrikov
4a45510c88 Changed source priority for Person (#21479)
* Added gps accuracy to Person

* Corrected GPS accuracy for Person

* Added priority of sources to Person

* Fixed formatting

* Removed rounding of coordinates.

* Added test for source priority.
Changed test for rounding of coordinates.

* Improved code style

* Code style cleanup

* Code style cleanup

* Code style cleanup

* Code style cleanup

* Code style cleanup

* Lint

* Lint
2019-02-27 16:40:23 -08:00
msvinth
070320a24a Bump ihc to 2.3.0 (#21494) 2019-02-27 16:39:11 -08:00
Nick Whyte
1ef3e32d4a ness_alarm: Bump nessclient version to 0.9.13 (#21466) 2019-02-27 16:38:53 -08:00
Paulus Schoutsen
c9ade6ee85 Merge remote-tracking branch 'origin/master' into dev 2019-02-27 16:34:47 -08:00
Paulus Schoutsen
78217fa9b0 Update translations 2019-02-27 16:34:13 -08:00
Paulus Schoutsen
f3bb9e870e Updated frontend to 20190227.0 2019-02-27 16:33:56 -08:00
Daniel Høyer Iversen
732110b4c3 Upgrade tibber lib (#21486) 2019-02-27 16:33:26 -08:00
Aaron Bach
ab2be6df48 Upgrade aioambient to 0.1.3 (#21510) 2019-02-27 16:27:26 -08:00
Aaron Bach
e4b2aab1e9 Bump simplisafe-python to 3.4.1 (#21511) 2019-02-27 16:27:13 -08:00
Aaron Bach
3749321fa5 Upgrade pyairvisual to 3.0.1 (#21512) 2019-02-27 16:26:59 -08:00
Paulus Schoutsen
63fda29eaf Merge pull request #21508 from home-assistant/rc
0.88.2
2019-02-27 16:19:26 -08:00
Jeff Irion
0ebd12fa6c Avoid unnecessary commands in Vizio update function (#20867) 2019-02-27 16:08:02 -08:00
Paulus Schoutsen
14f912500e Pin isort (#21463) 2019-02-27 15:28:22 -08:00
Paulus Schoutsen
651b0d3506 Fix cherry-pick fail ST 2019-02-27 15:27:55 -08:00
Paulus Schoutsen
626f8a8b09 Bumped version to 0.88.2 2019-02-27 15:25:21 -08:00
Sebastian Muszynski
51eb6c7b4e Bump PyXiaomiGateway version to 0.11.2 (#21453) 2019-02-27 15:25:14 -08:00
Andrew Sayre
2c10327945 Improve tolerance of SmartThings Climate platform (#21383)
* Improve resilience of platform with buggy handlers

* Eliminate possibility of None in operation list

* Refactor variable name
2019-02-27 15:24:50 -08:00
yosilevy
d1349d4919 Scene validator fix (#21362) 2019-02-27 15:24:00 -08:00
Martin Hjelmare
0f4c2ccd1e Fix person update on create (#21355)
* Update tests to set correct hass running state

* Update person on adding person if hass is running

* Test creating person when hass is running
2019-02-27 15:23:59 -08:00
David Conley
f6811a85b6 Allow custom_effect to be absent from Flux configuration (#21317)
* Allow custom_effect to be absent from Flux configuration

* set custom effect to none during setup
2019-02-27 15:23:59 -08:00
Paulus Schoutsen
fbfa3d1a18 Make sure that device trackers is always a list during creation (#21193) 2019-02-27 15:23:58 -08:00
CV
8a026bf214 HomeMatic: Add error-attribute (#21009)
Error attribute has different meanings depending on device
2019-02-27 23:09:49 +01:00
Daniel Høyer Iversen
519315f9c8 pylint 2.3.0 (#21485)
* pylint 2.3.0

* remove const

*  disable=syntax-error
2019-02-27 16:10:40 -05:00
Robert Svensson
2482816a11 Fix deCONZ retry mechanism for setup 2019-02-27 21:04:55 +01:00
Penny Wood
b87eb9d79e Fire events when Google Assistant commands come in #15139 (#20204) 2019-02-27 11:33:34 -08:00
Markus Jankowski
9b3a3fc1ac Add device_info to enable HA-devices for Homematic IP (#21241)
* add device_info to device

* added checks

* Fixes based on feedback

* Fix spelling

* Simplified implementation

On homematicip devices and the ap are created

* small fix with device.id

* hub/ap device creation moved to __init__.py

* Fixed result handling

* fixes after review.

* Fix test
2019-02-27 11:25:11 -08:00
Alexei Chetroi
9066609d23 Refactor async_turn_on() for ZHA Light. (#21156)
* Refactor async_turn_on() for ZHA Light.

Use "move_to_level_with_on_off" if brightness or transition attributes
are present in the service call data, otherwise issue "On" Zigbee
command.
Allow brightness of 0 for service call -- effectively turning the light
off.
Send color commands only after the light was turned on.

* Fix zha.light tests.
2019-02-27 08:34:38 -05:00
Fabian Affolter
27e6c6665f Upgrade astral to 1.10.1 (#21474) 2019-02-27 14:07:51 +01:00
Fabian Affolter
0b68da2f88 Upgrade shodan to 1.11.1 (#21478) 2019-02-27 14:07:26 +01:00
Fabian Affolter
01ee92177f Upgrade bcrypt to 3.1.6 (#21476) 2019-02-27 14:07:02 +01:00
Tomas Hellström
33c9afd6e0 Added a digit for precipitation (#21439) 2019-02-27 11:07:35 +05:30
Kevin Tuhumury
28f9c7c2cd Add cpu_use_percent as a new resource to the Glances sensor. (#21455) 2019-02-27 10:54:09 +05:30
Petro31
51773f338e Add person support for Waze Travel Time (#21471)
Adds person to the list of TRACKABLE_DOMAINS domains.  _get_location_from_entity will handle the person domain without any changes.
2019-02-26 20:02:49 -08:00
dfournie
822b6328e1 Add Somfy IO Garage door (#21320)
* Add Somfy IO Garage door

* Fix code style
2019-02-26 22:22:29 -05:00
Paulus Schoutsen
e9f79c3d06 Lint 2019-02-26 18:50:34 -08:00
blackray12
be78265631 Add mitemp bt sensor device class (#20293)
* Fix HomeKit missing humidity issue

When using HomeKit components, MiTemp BT's humidity state will not display in Home.app.
After Added home-assistant device class into property, this problem is solved.

* Add Device_Class_Battery to property

* Break long lines.

* Lint
2019-02-26 15:10:25 -08:00
Thibault Maekelbergh
4d4cd2d752 Update sensor.nmbs to support vias better + show on map (#20063)
* Add the destination stations to the attributes

* Add support for showing station on map

* Add option to exclude via connections

* Cleanup the live sensor

* Perform better checking against false i/o None values

* Add support for excluding vias

* Add more details for via trains

* Lint file

* Update logger level
2019-02-26 15:08:25 -08:00
Daniel Høyer Iversen
efa48848a5 Comment out bluepy libraries from requirements_all.txt (#20856)
* Comment bluepy libraries from requirements_all.txt, fixes #20778

* Comment bluepy libraries from requirements_all.txt, fixes #20778

* Comment bluepy libraries from requirements_all.txt, fixes #20778
2019-02-26 14:50:48 -08:00
William Scanlon
9cff1dd4ba Added new econet states (#21420) 2019-02-26 14:49:15 -08:00
Mattias Welponer
42e691c194 Add HomematicIP HmIP-OC8 module (#21401)
* Add support for HmIP-OC8 module

* Fix line lenght
2019-02-26 14:48:19 -08:00
Jason Hu
7bae76843c Add config for trusted networks auth provider (#21111)
* Add config for trusted networks auth provider

* Lint

* Fix typing

* Fix pylint

* Fix lint

* Add some log information

* Add http.trusted_networks deprecated warning

* Remove log info

* Lint
2019-02-26 14:42:48 -08:00
Paulus Schoutsen
5c2f997394 Lint 2019-02-26 14:42:09 -08:00
Leonardo Merza
e739fd8a31 Reddit Sensor (#21344)
* init

automated commit 22/02/2019 22:55:49

cr comments

cr comments

automated commit 24/02/2019 14:41:08

automated commit 24/02/2019 14:41:59

automated commit 24/02/2019 14:54:16

automated commit 24/02/2019 14:54:49

automated commit 24/02/2019 19:46:15

automated commit 25/02/2019 10:10:46

automated commit 25/02/2019 10:10:52

automated commit 25/02/2019 10:12:16

automated commit 25/02/2019 10:15:59

* automated commit 25/02/2019 12:26:38

* automated commit 25/02/2019 13:55:52
2019-02-26 13:55:11 -08:00
René-Marc Simard
aa472d4f10 Adjust GTFS dates when crossing midnight (#20916) 2019-02-26 13:17:20 -08:00
Andrew Sayre
3b9db88065 Add SmartThings Scene platform (#21405)
* Add SmartThings Scene platform

* Fixed failing tests after rebase

* Update cover tests.
2019-02-26 13:12:24 -08:00
Paulus Schoutsen
344e839bec Remove launching a server in a test (#21445) 2019-02-26 13:06:27 -08:00
Sebastian Muszynski
e119deafe5 Bump PyXiaomiGateway version to 0.11.2 (#21453) 2019-02-26 12:37:21 -08:00
Patrick T.C
dc6fd780a9 Fix for Snips platform update that breaks hermes api. (#21443) 2019-02-26 12:37:01 -08:00
Otto Winter
29187795a8 Fix ESPHome nodes being auto-added without user confirmation (#21444) 2019-02-26 12:35:25 -08:00
Paulus Schoutsen
ab73b725e1 Pin isort (#21463) 2019-02-26 12:33:40 -08:00
David F. Mulcahey
c4400be62a Add friendly name to devices in the device registry (#21318)
* add friendly name to devices in the device registry

* switch to name_by_user

* review comments
2019-02-26 12:20:16 -08:00
David F. Mulcahey
a34524febe Clean up ZHA post rewrite (#21448)
* update async handling to reduce unnecessary coroutine creation

* lint

* cleanup
2019-02-26 10:48:10 -08:00
Ville Skyttä
beb86426e4 Upgrade flake8 to 3.7.7 (#21452) 2019-02-26 10:47:57 -08:00
Anders Melchiorsen
03fc81a434 Clean up codeowners file (#21442) 2019-02-26 10:47:08 -08:00
Giorgos Logiotatidis
5a5c97acb3 Add timeout option to sensor.rest and binary_sensor.rest. (#20065) 2019-02-26 10:23:46 -08:00
Johann Kellerman
90d3f517d8 Check if a script requirement is available before install (#20517)
* Check if a script requirement is available before install

* PackageLoadable

* hound

* req
2019-02-26 10:20:54 -08:00
Franck Nijhof
f3c9327ccf Rewrite of Toon component (#21186)
* 🚜 Rewrite of Toon component

* 🔥 Removed manual state from list

* 👕 Addresses code review comments

* 🔥 Removes a log line that should not have been left behind

* 👕 Addresses linting warnings

* 👕 Addresses Hound CI warning

* 👕 Fixes small code styling issues

*  Sets an appropriate SCAN_INTERVAL

*  Sets min/max temperature for climate platform

* 👕 Makes imports more consistent with codebase

* 🚑 Fixes incorrect SCAN_INTERVAL value in climate platform

* 🚑 Uses OrderedDict for config_flow schema

* 👕 Adds return types for min/max temp

* 🚜 Refactors entities into their actual devices

* ⬆️ Updates toonapilib to 3.0.7

* 🚜 Refactors binary sensor state inversion

* 🚑 Fixes states of OpenTherm connection and Hot Tap Water

*  Adds Boiler Preheat binary sensor

*  Adds Toon Thermostat Program binary sensor

*  Adds Boiler Modulation Level sensor

*  Adds Daily Power Cost sensor

* 🔥 Cleanup of Toon Thermostat climate attributes

* 🚜 Adjusts config_flow with Tenant selection

* 🙋 Adds myself to codeowners file as maintainer

* ⬆️ Gen requirements

* ⬆️ Updates toonapilib to 3.0.9

*  Adds config_flow tests
2019-02-26 10:18:09 -08:00
Andrew Sayre
f0268688be Increase travis timeout (#21447) 2019-02-25 18:59:02 -08:00
Anders Melchiorsen
095a0d19d1 Fix Sonos snapshot/restore (#21411) 2019-02-25 13:03:15 -08:00
koreth
4e9d0ebc63 Fix double events on Lutron Pico keypads (#21408)
* Fix double events on Lutron Pico keypads (#21235)

* Replace "else" with default value; remove explanatory comments
2019-02-25 12:09:58 -08:00
Paulus Schoutsen
6626e5c4a4 Handle GA Disconnect intent (#21387)
* Handle GA Disconnect intent

* Fixed lint error
2019-02-25 10:35:03 -08:00
Otto Winter
db4c06c8fe Add ESPHome User-Defined Services (#21409)
* Add ESPHome User-Defined Services

* Update requirements_all.txt
2019-02-25 10:34:06 -08:00
Andrew Sayre
d3f1ee4a89 Add SmartThings Cover platform and add cover device classes (#21192)
* Add additional device classes to Cover component; Add SmartThings cover platform; Improve lock test coverage

* Enhance cover platform to support position and battery level reporting.

* Add additional classes

* Removed device class descriptions

* Updates based on review feedback

* Add test case for closed
2019-02-25 10:13:34 -08:00
Andrew Sayre
0ccbf61aea Add power and energy attributes to SmartThings switch (#21375) 2019-02-25 15:50:16 +01:00
Joakim Plate
a50bcdff1a Mark water_heater as significant domain (#21390) 2019-02-25 07:45:40 +01:00
Baptiste Lecocq
f190b698c6 Update pylinky (#21416) 2019-02-25 07:44:33 +01:00
Ville Skyttä
619ea3ff98 Upgrade mypy to 0.670 (#20934) 2019-02-25 07:54:54 +02:00
Ville Skyttä
dd5fc0a1da Upgrade pytest to 4.3.0 (#21412) 2019-02-25 07:36:57 +02:00
Jeff Irion
ff93cdb0bc Add ADB server functionality to Fire TV (#21221)
* Bump firetv to 1.0.8

* Update the 'update' function for Fire TV

* Return None for properties when unavailable

* Remove 'self.adb_lock' attribute

* Remove threading import

* Update configuration for Fire TV component

* Clarify 'python-adb' vs. 'pure-python-adb'

* Rename '__adb_decorator' to '_adb_exception_catcher'

* Don't check 'self._available' in properties

* Bump firetv to 1.0.9
2019-02-25 00:16:49 +01:00
Joakim Plate
814e610b1d Philips js state (#21407)
* Switch to SCAN_INTERVAL instead of throttle

This allows forced update of state

* Don't change tv on/off state in services

* Drop unused variables

* Only send mute if different from current state

* No need to update variables, will behandled on update

* Drop unused import
2019-02-24 14:33:07 -06:00
Anders Melchiorsen
a4bb35142c Add Sonos discovery of multiple households (#21337)
* Remove confusing device naming

* Add discovery of multiple households

* Rename SonosDevice to SonosEntity
2019-02-24 18:45:08 +01:00
Martin Hjelmare
47220d71a1 Clean up locative tests (#21400) 2019-02-24 10:49:50 -06:00
Andrew Sayre
04fc951048 Improve tolerance of SmartThings Climate platform (#21383)
* Improve resilience of platform with buggy handlers

* Eliminate possibility of None in operation list

* Refactor variable name
2019-02-24 10:45:11 -06:00
Martin Hjelmare
7255fbdf3a Clean up geofency test (#21397) 2019-02-24 15:56:19 +01:00
Hmmbob
65bc7a6fbd Update WazeTravelSensor to 0.9 (#21130)
* Update WazeRouteCalculator to 0.8 and suppress logging

Fixes #20071 and #21051

* Update requirements_all.txt

* Update requirements_all.txt

* Update waze_travel_time.py

* Update waze_travel_time.py

* Update waze_travel_time.py

* Update waze_travel_time.py
2019-02-24 07:21:56 -06:00
koreth
3e9376c418 Handle capitalized HomeKit property names (#21382)
The Velux ACTIVE gateway uses `C#` rather than `c#` as the name of
the property that holds the count of accessories. Apple's HomeKit docs
suggest that properties should be case-insensitive, so update the
code to not assume the property names are lower case.
2019-02-24 13:56:52 +01:00
Nick Whyte
6e0186fd56 Bump nessclient version to 0.9.10 (#21388)
* ness_alarm: Bump nessclient version

* update requirements_all.txt
2019-02-24 10:26:02 +01:00
Fabian Affolter
3732d75633 Update ordering (#21377) 2019-02-24 10:22:17 +01:00
Fabian Affolter
2ada0ecfd9 Upgrade shodan to 1.11.0 (#21384) 2019-02-23 22:14:26 -06:00
Andrew Sayre
3d9f4bf2aa SmartThings Lock platform state attributes enhancement (#21379)
* Add additional lock metadata

* Fixed attribute name in test
2019-02-24 02:52:37 +01:00
Rohan Kapoor
ce86fe47e3 Remove the google travel time update service (#21153) 2019-02-23 19:24:38 -06:00
Martin Hjelmare
d44269981b Clean up owntracks tests (#21378) 2019-02-23 19:17:49 -06:00
Andre Lengwenus
fc13e37d8d Refactoring. Moved LCN constants to const.py (#21376) 2019-02-24 01:30:19 +01:00
Daniel Høyer Iversen
b588c1fe1c Handle connection issue for netatmo (#21346)
* Handle connection issue for netatmo

* reduce logging
2019-02-24 00:41:38 +01:00
Tony763
6743ef10ab Update panasonic_viera.py (#21365) 2019-02-23 23:39:51 +01:00
Thibault Maekelbergh
a1c3a38428 Generate new Discogs sensors + fix scan interval (#19443)
* Generate new sensors for discogs:
- Generate collection sensor
- Generate wantlist sensor
- Generate random record sensor
- Removes the option to set a name

* Make it so name can still be configured

* Fix invalid syntax

* Use shared data object + 1 sensor

* Linting

* Remove straying comment

* Dont use async for non-async stuff

* Don't use separate list for conf already in dict

* Use consts for keys

* Copy dict to list for sensors

* Fix syntax for computed keys in SENSORS dict
2019-02-23 15:58:30 -06:00
Teemu R
492c3b24de Check for attribute existence for HS220 support (#21309)
* Check for attribute existence as smartplug does not have them (for HS220 support)

* use getattr over hasattr and a separate check
2019-02-23 22:57:54 +01:00
Alistair Galbraith
1eba90d2a1 Add initial support for Sony SDCP projector control (#20269)
* Add initial support for Sony SDCP projector control

* Changes to reflect code review

* Added code per change requests

- Validation of connection during setup_platform
- Docs pending

* Removed blank lines per CI build

* Lint fix

* Update homeassistant/components/switch/sony_projector.py

Co-Authored-By: alistairg <alistair@alistairs.net>

* Updated .coveragerc, made requested logger changes

* Update docstring
2019-02-23 15:57:10 -06:00
Jérôme W
a8a2daeac5 Add custom and zone cleaning to Neato Vacuums (#20779)
* Adding custom and zone cleaning to Neato Vacuums

* Fixing line length and missing imports

* Line too long

* Adding details to the custom service

* Fix linting issues

* Reverting ACTION

* Code cleanup

* Typo

* Requested modifications

* Changing the custom service domain

* No service schema depency anymore

* Removing useless code

* Linting

* Requested changes

* Requested changes for domain

* Revert the service domain back to vacuum
2019-02-23 15:55:55 -06:00
Rohan Kapoor
dc5b8fd8c4 Split out iperf3 into a component with a sensor platform (#21138)
* Move iperf3 sensor to a standalone component

* Split out iperf3 into a component with a sensor platform

* Update coverage and requirements

* Add services.yaml

* Clean up a little bit

* Lint

* Lint
2019-02-23 15:55:08 -06:00
Martin Hjelmare
7143f4e621 Fix person update on create (#21355)
* Update tests to set correct hass running state

* Update person on adding person if hass is running

* Test creating person when hass is running
2019-02-23 15:38:21 -06:00
Adam Dullage
bfda923999 Update Starling Bank Integration to v2 API (#21358)
* Bump starlingbank to v2 API

* Fixed incorrect call
2019-02-23 20:54:42 +01:00
yosilevy
e8b67fc19f Scene validator fix (#21362) 2019-02-23 18:26:27 +01:00
Richard Mitchell
c595cf016f Support the person component in Prometheus (#21363) 2019-02-23 18:13:27 +01:00
Finbarr Brady
d027965304 Update luci device tracker (#21321)
* * bump pip module version.
* moved named tuple into the module.
* pass SSL bool into the object init.
* support get_extra_attributes

* Update homeassistant/components/device_tracker/luci.py
2019-02-23 16:28:41 +01:00
Andre Lengwenus
f20195ba75 Add conf_key check for LCN platform load (#21354) 2019-02-23 15:58:18 +01:00
Benny de Leeuw
197303b63e Add voltage per phase (#21319) 2019-02-23 15:57:54 +01:00
tmechen
2f7b4ed7f0 implementing freedaily mode (#21314)
adressing #15105 and add a freedaily mode for a 5 day forecast with free API key
2019-02-23 15:52:08 +01:00
Justin Bassett
02745be44d Allows the utility_meter to net meter rather than only allow increases. (#21204)
* Allow the utility_meter to net meter rather than only allow increases.

* Fix PR issues around CI.

* Fix line length fallout.

* Change rollover to net_consumption.  Add unit tests.

* Fix test style issues.

* Fix style in tests.
2019-02-23 14:02:39 +00:00
siberx
616c7628d7 Fixes the sensor.filter outlier filter (handle step-changes correctly) (#21332)
* Fix outlier filter median return, Add/update filter outlier tests

* Switch outlier filter to store raw vals (handles step-changes correctly)

* Filter store_raw as attribute instead of filter_state parameter

* Fix linting issues
2019-02-23 13:51:33 +00:00
Hmmbob
954bd4e13b Update buienradar.py (#21351)
Fixing warning about unsupported config key in Buienradar sensor, whilst it was actually supported (but not validated)
2019-02-23 14:43:37 +01:00
Julius Mittenzwei
48e44f4b5b Updated pyvlx from 0.2.8 to 0.2.9. This version has slightly improved logging (#21349) 2019-02-23 08:04:32 -05:00
Daniel Høyer Iversen
b7b4a6dcc8 Add location to Norway airquality (#21347) 2019-02-23 10:35:18 +01:00
Andre Lengwenus
8f70c16863 Add LCN cover platform (#20288)
* Add LCN cover platform

* Removed unused default value

* Moved cover component to lcn platform directory. Small changes due to change request

* Closed state is set before updating
2019-02-23 10:13:15 +01:00
Daniel Shokouhi
2aa7bdb1d5 Allow google home component device tracker to be optional (#21335) 2019-02-23 01:01:09 -08:00
Robbie Trencheny
111f882d78 Add note to issue template regarding iOS issues (#21342)
## Description:

Add an additional line to the issue template mentioning that iOS issues should be reported to the home-assistant-iOS repo.
2019-02-22 17:39:19 -08:00
David Conley
b437b87655 Allow custom_effect to be absent from Flux configuration (#21317)
* Allow custom_effect to be absent from Flux configuration

* set custom effect to none during setup
2019-02-23 00:13:40 +01:00
philipperequile
2b3c31cdb0 Add more ads plc types (#19801)
* Update __init__.py

Support for 2 new 4-byte PLC datatypes DINT and UDINT

* Update __init__.py

* Fix lint issue

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Support for 2 new PLC types

Sensor supports DINT and UDINT PLC types

* Update __init__.py

I removed unused TYPES = [ADSTYPE_INT, ADSTYPE_UINT, ADSTYPE_BYTE, ADSTYPE_DINT, ADSTYPE_UDINT]
2019-02-22 23:52:46 +01:00
Andrew Sayre
8b38b82e73 Enhance SmartThings component subscription (#21124)
* Move to config v2 to store SmartApp oauth keys

* Add migration functionality.

* Regenerate refresh token on periodic basis

* Fix regenerate and misc. optimizations

* Review feedback

* Subscription sync logic now performs a difference operation

* Removed config entry reloading.
2019-02-22 20:35:12 +01:00
Robert Svensson
d9712027e8 Config entry options (#18929)
Add support for options flow for config entries
2019-02-22 17:59:43 +01:00
Phil Cole
caa3b123ae Nissanleaf (#21145)
* Remove unneeded returns from handle_update()

* Start __init__() params with hass.

* Remove excess logging and downgrade remaining logging.

* Remove period from end of comment

* Decorate callback with @callback

* Use more descriptive variables than key and value.

* Inherit from BinarySensorDevice and overwrite is_on rather than state.

* Removed uncheckedreturn values.

* Use super() rather than explicit object.

* Use add_entities instead of add_devices.

* Don't use listener when calling immediately.

* Remove some excess logging.

* Switch to sync since pycarwings2 is sync.

* Remove RuntimeError exception matching.

* Add temporary reviewer comments.

* Add UI help descriptions for update service.

* Fix hound errors.

* Replaced time.sleep() with await asyncio.sleep()

* Removed location_updateon_on attribute since on device_tracker.

* Use async_added_to_hass() and async_dispatcher_connect().

* Use dict[key] because schema key is required.

* Clarify variable names.

* Remove icon for charging switch.

* Convert LeafChargeSwitch into service and sensor.

* Use async_dispatcher_send().

* Add guard checks for discovery_info. Consistent logs.

* Use async_schedul_update_ha_state().

* Device tracker should return true.

* Remove icon for climate control.

* Really remove icon for climate control.

* Use register() instead of async_register().

* Add guard on device tracker if discovery_info is None.
2019-02-22 17:34:23 +01:00
SNoof85
4102e24481 Adding myself as codeowner for Freebox component (#21288) 2019-02-22 09:58:48 -05:00
Fabian Affolter
3f29e91367 Remove index (#21304)
* Remove index

* Remove emnumerate
2019-02-22 14:11:07 +01:00
Paulus Schoutsen
3a3957aeed Merge pull request #21296 from home-assistant/rc
0.88.1
2019-02-21 20:16:44 -08:00
Paulus Schoutsen
e4a21011a3 Bumped version to 0.88.1 2019-02-21 17:06:30 -08:00
Paulus Schoutsen
07e04e5b84 Fix yeelight config validation (#21295) 2019-02-21 17:06:24 -08:00
Aaron Bach
df5b17d139 Fix unhandled exception in Ambient PWS config entry (#21278) 2019-02-21 17:06:24 -08:00
David F. Mulcahey
e3d29ad26a update services.yaml (#21276) 2019-02-21 17:06:23 -08:00
Paulus Schoutsen
e2a57add2c Add SamsungTV Mac validation (#21268) 2019-02-21 17:06:23 -08:00
Joakim Plate
e59776377b Add missing configation option (#21265)
Fixes https://github.com/home-assistant/home-assistant/issues/21254
2019-02-21 17:06:23 -08:00
Joakim Plate
b2482d8205 Add missing configuration option to plex (#21264)
Fixes part of: https://github.com/home-assistant/home-assistant/issues/21254
2019-02-21 17:06:22 -08:00
David F. Mulcahey
dc133fe9f2 Fix ZHA bugs (#21246)
* fix bugs

* add comment

* allow entities to be marked unavailable
2019-02-21 17:06:22 -08:00
Paulus Schoutsen
3fcbc36abe Update translations 2019-02-21 16:40:25 -08:00
Paulus Schoutsen
bd352b9950 Merge remote-tracking branch 'origin/master' into dev 2019-02-21 16:40:07 -08:00
Paulus Schoutsen
bf4fb36bb1 Fix yeelight config validation (#21295) 2019-02-21 16:39:17 -08:00
Paulus Schoutsen
ac502980a2 Do not warn for internally loaded components (#21287) 2019-02-21 14:57:38 -08:00
David McNett
d9a44f2a78 Version bump: python-anthemav to v1.1.9 (#21273) 2019-02-21 23:24:29 +01:00
Aaron Bach
d0e88d9628 Fix unhandled exception in Ambient PWS config entry (#21278) 2019-02-21 13:27:34 -07:00
David F. Mulcahey
a2877c4ea0 update services.yaml (#21276) 2019-02-21 14:39:55 -05:00
Teemu R
94be43e3e1 Add support for automatic discovery of TP-Link switches, bulbs and dimmers (#18091)
* {switch,light}.tplink: use deviceid as unique id, fetch name from the device during initialization

* raise PlatformNotReady when no device is available

* Use mac instead of deviceid

* remove name option as obsolete

* Add support for configuration flow / integration

Allows activating automatic discovery of supported devices from the configuration

* Fix linting, update requirements_all.txt

* start cleaning up tplink component based on feedback

* add device info, improve config handling

* Allow overriding detected devices via configuration file

* Update requirements.txt

* Remove debug logging

* make hound happy

* Avoid I/O during init and simplify the code, remove remains of leds_on

* Fix issues based on feedback, use consistent quotation marks for device info

* add async_setup_platform emiting a deprecation warning

* Avoid blocking the I/O, check for None on features

* handle some Martin's comments, schema-validation is still missing

* use async_create_task instead of async_add_job, let core validate the schema

* simplify configuration handling by storing the configuration data separately from initialized instances

* add default values to schema, make hound happy

* with defaults set by schema, simplify the checks. add async_unload_entry

* Use constant for data structure access

* REWORD add a short note about async_unload_entry

* handle feedback from Martin, config_data is checked against Noneness

* use pop to remove the domain on unload

* First steps to add tests for the new tplink component

* embed platforms under the component directory

* Fix tests by mocking the pyhs100 internals

* Fix linting

* Test against multiple instances of devices, tidy up

* (hopefully) final linting round

* Add pyHS100 to test requirements

* log always the warnings occured during an update to make them easy to see

* revert back the warning behavior (requirement for silver level in IQS)

* Unload only when an entry is being loaded and add tests for that

Thanks @MartinHjelmare for pointing this out!

* Fix linting

* Bump the upstream lib, fixes most prominently the HSV setting on bulbs

* Test unloading for all platforms, clear the data storage instead of popping it out, making it possible to reconfigure after removal without restarting hass first

* Use class variables instead of instance variables for bulb states, required for HS220

* Use new-style format string

* Fix indenting, uppercase the mock constant

* Run black on test_init, hopefully that will finally fix the weird formatting (pycharm, pylint and hound seems to have different opinions...)
2019-02-21 20:29:07 +01:00
Tobias Hoff
c637bad1eb account specific cookies file to enable multiple accounts (#19811) 2019-02-21 10:35:27 -08:00
Miroslav Ždrale
565f513b77 Added device tracker support for Ubee Router (#19586)
* Added Ubee Router Device Tracker.

* Updated code to meet requirements.

* Code clean-up.

* Code clean-up.

* Code clean-up.

* Minor error message update

* Ubee device tracker: Minor code clean-up

* Bump pyubee version

* Code clean-up
2019-02-21 09:24:37 -08:00
Paulus Schoutsen
4c4317fb37 Add SamsungTV Mac validation (#21268) 2019-02-21 08:52:45 -08:00
Joakim Plate
998b5f6d19 Add missing configation option (#21265)
Fixes https://github.com/home-assistant/home-assistant/issues/21254
2019-02-21 08:26:26 -08:00
Joakim Plate
6b7a5cfcad Add missing configuration option to plex (#21264)
Fixes part of: https://github.com/home-assistant/home-assistant/issues/21254
2019-02-21 08:26:09 -08:00
Gido
e764d9461a Update rova component with suffix for house number (#21182)
* Update rova component with release rova release 0.1.0
Add house_number_suffix to configuration

* Set default value for house_number_suffix
2019-02-21 09:51:36 -05:00
OleksandrBerchenko
09692143d0 Correctly detect devices, which went offline during HA restart (#20933)
* Correctly detect devices, which went offline during HA restart

* Update __init__.py
2019-02-21 14:48:17 +01:00
David F. Mulcahey
0f8575f939 Fix ZHA bugs (#21246)
* fix bugs

* add comment

* allow entities to be marked unavailable
2019-02-21 14:20:58 +01:00
Paulus Schoutsen
2435456248 Prevent partial custom component overlays (#21070)
* Prevent partial custom component overlays

* Fix tests
2019-02-21 09:41:36 +01:00
Fredrik Erlandsson
73099caede Alarm trigger support for Point (#21207) 2019-02-21 06:50:02 +01:00
Fabian Affolter
966fd1034d Upgrade opensensemap-api to 0.1.4 (#21240) 2019-02-20 17:46:37 -07:00
Paulus Schoutsen
ddd63c615f Remove constraint from regex (#21239) 2019-02-20 21:31:41 +01:00
Paulus Schoutsen
7bd5e60767 Merge pull request #21238 from home-assistant/rc
0.88.0
2019-02-20 11:13:27 -08:00
David F. Mulcahey
67008e0947 Fix bug in ZHA and tweak non sensor channel logic (#21234)
* fix race condition and prevent profiles from stealing channels

* fix battery voltage
2019-02-20 09:35:32 -08:00
David F. Mulcahey
9f99e173de Don't dispatch to components when there are no channels for ZHA sensors (#21223)
* don't dispatch when channels don't exist

* review comment
2019-02-20 09:35:31 -08:00
Paulus Schoutsen
7dd3fc7ca7 Bumped version to 0.88.0 2019-02-20 08:58:37 -08:00
Paulus Schoutsen
fd3bea177b Prevent invalid context from crashing (#21231)
* Prevent invalid context from crashing

* Lint
2019-02-20 08:57:51 -08:00
Aaron Bach
be26fc896d Fix an Ambient PWS exception when location info is missing (#21220) 2019-02-20 08:57:50 -08:00
David F. Mulcahey
9057da01bd Refactor ZHA listeners into channels (#21196)
* refactor listeners to channels

* update coveragerc
2019-02-20 08:57:50 -08:00
Paulus Schoutsen
d09cf8dd17 Updated frontend to 20190220.0 2019-02-20 08:55:56 -08:00
Paulus Schoutsen
03573781c7 Updated frontend to 20190220.0 2019-02-20 08:55:42 -08:00
Finbarr Brady
54949cff5a Support OpenWRT 18.06 in luci device tracker (#21236)
* Got it right this time i hope

* updates on comments
2019-02-20 16:55:00 +01:00
damarco
1518a80069 Bump zigpy (#21203)
* Bump zigpy

* Update requirements

* Update test requirements

* Bump zigpy-deconz
2019-02-20 16:34:59 +01:00
David F. Mulcahey
cece6454e4 Fix bug in ZHA and tweak non sensor channel logic (#21234)
* fix race condition and prevent profiles from stealing channels

* fix battery voltage
2019-02-20 16:33:29 +01:00
David F. Mulcahey
5b24b271cc Don't dispatch to components when there are no channels for ZHA sensors (#21223)
* don't dispatch when channels don't exist

* review comment
2019-02-20 16:27:03 +01:00
Marco Gazzola
5115dfada2 Add zone and reps for Xiaomi vacuum (#19777)
* xiaomi vacuum with zone and reps

* tail whitespace

* tail whitespaces

* new version

* fix params typs

* fix param type

* line length

* rytilahti tips

* houndci-bot

* fix trevis

* rytilahti tips

* service description

* syssi fix

* MartinHjelmare tips

* MartinHjelmare

* data_template schema

* line lenght

* line lenght

* line lenght

* data_template schema

* fix

* Update homeassistant/components/vacuum/xiaomi_miio.py

Co-Authored-By: marcogazzola <dev@marcogazzola.com>

* Update homeassistant/components/vacuum/xiaomi_miio.py

Co-Authored-By: marcogazzola <dev@marcogazzola.com>

* xiaomi vacuum with zone and reps

* tail whitespace

* new version

* fix param type

* rytilahti tips

* rytilahti tips

* MartinHjelmare

* data_template schema

* line lenght

* line lenght

* data_template schema

* fix

* Merge branch 'dev' of https://github.com/marcogazzola/home-assistant into dev

* Revert "Merge branch 'dev' of https://github.com/marcogazzola/home-assistant into dev"

This reverts commit e1f370b3b45d2541c8117146b0940d7c2b5bc8b0.

* log fixed

* Revert "log fixed"

This reverts commit 1f0e7b35e8.

* Revert "Revert "Merge branch 'dev' of https://github.com/marcogazzola/home-assistant into dev""

This reverts commit 1cf9e5ae1f.

* Revert "Merge branch 'dev' of https://github.com/marcogazzola/home-assistant into dev"

This reverts commit 0e8d53449a.

* log fixed
2019-02-20 15:44:04 +01:00
Aaron Bach
7e06d03b45 Fix an Ambient PWS exception when location info is missing (#21220) 2019-02-20 12:10:42 +01:00
Diogo Gomes
1ff299875b Add self to integration sensor and utility_meter (#21226) 2019-02-20 08:34:10 +01:00
Paulus Schoutsen
cf3a8b60ff Prevent invalid context from crashing (#21231)
* Prevent invalid context from crashing

* Lint
2019-02-20 08:02:56 +01:00
Daniel Perna
27d598fff8 Update pyhomematic to 0.1.56 (#21227) 2019-02-20 00:31:46 +01:00
Paulus Schoutsen
49995c2120 Fix the build (#21229) 2019-02-19 13:52:14 -08:00
Paulus Schoutsen
4cc90c437f Bumped version to 0.88.0b4 2019-02-19 10:31:47 -08:00
carstenschroeder
c0f83b4164 Push pyads to 3.0.7 (#21216)
* Push to pyads 3.0.7

* Correct too long line
2019-02-19 10:31:34 -08:00
ehendrix23
4500760b52 Set aioharmony version to 0.1.8 (#21213)
Update aioharmony version to support latest HUB firmware (4.15.250).
2019-02-19 10:31:34 -08:00
Diogo Gomes
620f23d433 ordered by last occurence (#21200) 2019-02-19 10:31:33 -08:00
Anders Melchiorsen
4562bdc69f Upgrade aioimaplib for Python 3.7 compatibility (#21197) 2019-02-19 10:31:33 -08:00
Paulus Schoutsen
dfb45c03e4 Updated frontend to 20190219.0 2019-02-19 10:31:03 -08:00
Paulus Schoutsen
f452409cfa Updated frontend to 20190219.0 2019-02-19 10:14:33 -08:00
zewelor
fb820975b5 Add yeelight flow action support (#21195) 2019-02-19 19:06:40 +01:00
David F. Mulcahey
3be8178035 Refactor ZHA listeners into channels (#21196)
* refactor listeners to channels

* update coveragerc
2019-02-19 09:58:22 -08:00
Johann Bauer
fe4a2b5b31 Fix Homematic IP Cloud configuration (#21202)
`homematicip.aio.auth.isRequestAcknowledged` returns false if the
request failed in stead of raising an error.

See coreGreenberet/homematicip-rest-api@0b61954f6a

Closes: #20428
2019-02-19 09:53:20 -08:00
carstenschroeder
df8589c36a Push pyads to 3.0.7 (#21216)
* Push to pyads 3.0.7

* Correct too long line
2019-02-19 18:42:00 +01:00
Diogo Gomes
b0f317743b ordered by last occurence (#21200) 2019-02-19 08:45:21 -08:00
ehendrix23
99eda385d1 Set aioharmony version to 0.1.8 (#21213)
Update aioharmony version to support latest HUB firmware (4.15.250).
2019-02-19 08:44:42 -08:00
Fabian Affolter
e3cfcbad69 Upgrade numpy to 1.16.1 (#21190) 2019-02-19 16:04:56 +01:00
Julien Brochet
98c3c02daa Bump Synology SRM dependency to version 0.0.6 (#21212)
* Bump Synology SRM dependency to version 0.0.6

* Add @aerialls to the Synology SRM code owners
2019-02-19 10:01:47 -05:00
Fabian Affolter
2d2c6cf4a1 Use constants from const.py (#21068)
* Use constants from const.py

* Fix lint issues
2019-02-19 14:09:06 +01:00
Daniel Perna
9d3eaada27 Netatmo, address comments from #20755 (#21157)
Netatmo component cleanup
2019-02-19 10:53:45 +01:00
Fabian Affolter
baaeaab61d Upgrade crimereports to 1.0.1 (#21187) 2019-02-19 10:04:14 +01:00
starkillerOG
921efbdfef Philips Hue: Add bridge update prompt (#21119)
* Add a prompt if bridge update is available.

* Change logger warning for light update

The self.light.swupdatestate only checks for updates of that specific light, it does not check for updates of the bridge.
Theirfore the warning message schould be updated.

* add space

* fix tests

* rename to swupdate2_bridge_state

* update aiohue to v1.9.1

* update aiohue to v1.9.1

* update aiohue to v1.9.1
2019-02-18 21:31:42 -08:00
Anders Melchiorsen
bc46e48d23 Upgrade aioimaplib for Python 3.7 compatibility (#21197) 2019-02-19 06:11:56 +01:00
OleksandrBerchenko
bdea222196 Expose effect_list attribute for turned off lights (#20750) 2019-02-18 21:01:26 -08:00
Paulus Schoutsen
5ad252bd3b Bumped version to 0.88.0b3 2019-02-18 13:31:21 -08:00
sjabby
1768c2b447 Fix for #19072 (#21175)
* Fix for #19072

PR #19072 introduced the custom_effect feature but it didnt make it optional as the documentation states.
This causes error on startup and the component does not work.
```
Error while setting up platform flux_led
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity_platform.py", line 128, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=hass.loop)
  File "/usr/lib/python3.5/asyncio/tasks.py", line 400, in wait_for
    return fut.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/flux_led.py", line 135, in setup_platform
    device[CONF_CUSTOM_EFFECT] = device_config[CONF_CUSTOM_EFFECT]
KeyError: 'custom_effect'
```

Changing this line to make the custom_effect optional as the original intention.

* Update flux_led.py
2019-02-18 13:30:59 -08:00
David F. Mulcahey
d1fa341a78 Add power source to device and clean up zha listeners (#21174)
check available and add comments

ensure order on API test
2019-02-18 13:30:59 -08:00
John Mihalic
8b5aff63ae Update pyEight for Python 3.7 Compatability (#21161) 2019-02-18 13:30:58 -08:00
Diogo Gomes
c544845e29 Fix track_change error in utility_meter (#21134)
* split validation

* remove any()
2019-02-18 13:30:58 -08:00
Andrew Sayre
d55693762e Fix SmartThings Translation Error (#21103) 2019-02-18 13:30:57 -08:00
Andrew Sayre
7ce18146d4 SmartThings Component Enhancements/Fixes (#21085)
* Improve component setup error logging/notification

* Prevent capabilities from being represented my multiple platforms

* Improved logging of received updates

* Updates based on review feedback
2019-02-18 13:29:03 -08:00
René-Marc Simard
834d8940a8 Return None if no GTFS departures found (#20919) 2019-02-18 13:26:26 -08:00
Paulus Schoutsen
933076560b Updated frontend to 20190218.0 2019-02-18 13:25:55 -08:00
Paulus Schoutsen
d1ebe2cbac Updated frontend to 20190218.0 2019-02-18 13:25:43 -08:00
Paulus Schoutsen
d2fea76fd7 Add context to service call event (#21181) 2019-02-18 13:07:44 -08:00
sjabby
463c4ae5c9 Fix for #19072 (#21175)
* Fix for #19072

PR #19072 introduced the custom_effect feature but it didnt make it optional as the documentation states.
This causes error on startup and the component does not work.
```
Error while setting up platform flux_led
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity_platform.py", line 128, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=hass.loop)
  File "/usr/lib/python3.5/asyncio/tasks.py", line 400, in wait_for
    return fut.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/light/flux_led.py", line 135, in setup_platform
    device[CONF_CUSTOM_EFFECT] = device_config[CONF_CUSTOM_EFFECT]
KeyError: 'custom_effect'
```

Changing this line to make the custom_effect optional as the original intention.

* Update flux_led.py
2019-02-18 13:05:46 -08:00
Paulus Schoutsen
600070af3a Make sure that device trackers is always a list during creation (#21193) 2019-02-18 13:04:04 -08:00
Robert Svensson
9ce8f4737d deCONZ thermostat support (#20586)
* Add support for thermostats in deCONZ by adding Climate platform
2019-02-18 17:43:22 +01:00
David F. Mulcahey
3f9e6a7064 Add power source to device and clean up zha listeners (#21174)
check available and add comments

ensure order on API test
2019-02-18 16:55:41 +01:00
Martin Hjelmare
0ab9b006f0 Clean up upc_connect tests (#21150) 2019-02-18 08:58:25 -06:00
Mattias Welponer
0b77a89a2f Fix HomematicIP Cloud fix cover position property (#21154) 2019-02-18 08:54:23 -06:00
Fabian Affolter
4d410bf5b9 Upgrade psutil to 5.5.1 (#21171) 2019-02-18 15:51:21 +01:00
John Mihalic
1afbc22ad5 Update pyEight for Python 3.7 Compatability (#21161) 2019-02-18 11:20:31 +01:00
Fabian Affolter
6cdc5a5c2d Upgrade sqlalchemy to 1.2.18 (#21162) 2019-02-18 11:19:40 +01:00
Fabian Affolter
7e855d5b48 Upgrade youtube_dl to 2019.02.18 (#21164) 2019-02-18 11:19:21 +01:00
Fabian Affolter
2b86fc3841 Upgrade voluptuous-serialize to 2.1.0 (#21166) 2019-02-18 11:18:40 +01:00
Diogo Gomes
3b5ed7a20f Fix track_change error in utility_meter (#21134)
* split validation

* remove any()
2019-02-17 20:40:51 -08:00
CV
ce7f678b9b RSSI_PEER and RSSI_DEVICE are different things (fixes #20900) (#20902)
* Fix #20900: RSSI_PEER and RSSI_DEVICE are different things

This change is fixing issue #20900.

Wireless actors are having two RSSI values. The way the component was programmed one of them was overwritten.

* Added deprecation comment

* Fixed long line

* Fix: pylint comment

* Lint

* flake8

* flake8 again

* Update __init__.py
2019-02-17 20:53:57 -06:00
lapy
425b9851fc Add traccar monitored_conditions option (#21149)
* Add traccar monitored_conditions option

User defined additional parameters to track from the traccar platform

* Version bump for pytraccar client

* Update traccar.py

* Remove default value

* Update homeassistant/components/device_tracker/traccar.py

Co-Authored-By: lapy <lapy@users.noreply.github.com>

* Update traccar.py
2019-02-17 23:38:04 +01:00
ktnrg45
72ef9670e6 Add component media player.ps4 (#21074)
* Added PS4/ __init__.py

* Create en.json

* Create config_flow.py

* Create const.py

* Create media_player.py

* Create services.yaml

* Create strings.json

* Create __init__.py

* Add test_config_flow.py/ Finished adding PS4 files

* Rewrote for loop into short-hand

* bumped pyps4 to 0.2.8

* Pass in helper()

* Rewrite func

* Fixed test

* Added import in init

* bump to 0.2.9

* bump to 0.3.0

* Removed line

* lint

* Add ps4 to flows list

* Added pyps4-homeassistant with script

* Added pyps4

* Added pypys4 to test

* removed list def

* reformatted service call dicts

* removed config from device class

* typo

* removed line

* reformatted .. format

* redefined property

* reformat load games func

* Add __init__ and media_player.py to coveragerc

* Fix for test

* remove init

* remove blank line

* remove mock_coro

* Revert "remove init"

This reverts commit b68996aa34699bf38781e153acdd597579e8131f.

* Correct permissions

* fixes

* fixes
2019-02-17 15:41:55 -05:00
lapy
4e7cfc923d Add traccar scan_interval configuration option (#21079)
* Added scan_interval configuration option

* Fixed trailing whitespace and indentation

* Update traccar.py

* Update homeassistant/components/device_tracker/traccar.py

Co-Authored-By: lapy <lapy@users.noreply.github.com>
2019-02-17 17:55:06 +01:00
Robert Svensson
9251860201 Logging to find what deCONZ events get created (#20551)
* Helpful logging to easily find what events get created
2019-02-17 16:58:46 +01:00
Daniel Perna
847711ddc9 Add webhook support for Netatmo Cameras (#20755)
Add webhook support for Netatmo Cameras
2019-02-17 12:31:47 +01:00
René-Marc Simard
33b8dbe73a Return None if no GTFS departures found (#20919) 2019-02-17 11:46:08 +01:00
msvinth
df598544d6 Make Netatmo able to discover both Weather station and Health Coach (#20274)
* Resolve conflicts and review comments

* Corretly handle HomeCoach in manual setup

* Fix code reivew comments

* Move import back int methods

* Formatting fix

* Lint fix
2019-02-17 11:45:58 +01:00
Ville Skyttä
816364bfd9 Upgrade pytest to 4.2.1 (#21112)
* Upgrade pytest to 4.2.0

* Upgrade pytest to 4.2.1

* Make litejet switch test work with pytest 4.2
2019-02-17 09:55:33 +01:00
Paulus Schoutsen
7d111c2b4e Bump pychromecast to 2.5.2 (#21127) 2019-02-16 23:52:26 -08:00
Paulus Schoutsen
30c8c689d8 Handle ValueError (#21126) 2019-02-16 23:52:25 -08:00
cdce8p
017f34770b Fix battery_level error - HomeKit (#21120) 2019-02-16 23:52:25 -08:00
Paulus Schoutsen
f881a3af82 Bumped version to 0.88.0b2 2019-02-16 23:52:04 -08:00
Otto Winter
6f0b853547 Update bootstrap.py 2019-02-16 23:51:59 -08:00
Otto Winter
9696a8b8a9 Add persistent notification 2019-02-16 23:51:59 -08:00
Otto Winter
219ca336a9 Lint 2019-02-16 23:51:59 -08:00
Otto Winter
26a79dff99 Fix tests 2019-02-16 23:51:59 -08:00
Otto Winter
0023da778a Add legacy PLATFORM_SCHEMA config validation 2019-02-16 23:51:59 -08:00
Rohan Kapoor
84053103f0 Deprecate conf_update_interval (#20924)
* Deprecate update_interval and replace with scan_interval

* Update tests

* Fix Darksky tests

* Fix Darksky tests correctly

This reverts commit a73384a223ba8a93c682042d9351cd5a7a399183.

* Provide the default for the non deprecated option

* Don't override default schema for sensors
2019-02-16 23:48:37 -08:00
Diogo Gomes
bc17adda8d Don't expose services in Utility_Meter unless tariffs are available (#20878)
* only expose services when tariffs configured

* don't register services multiple times
2019-02-16 23:48:37 -08:00
Jason Hu
2155a861cd Remove outdated url pattern match support for static file hosting (#21109) 2019-02-16 23:06:42 -08:00
Paulus Schoutsen
f1b84962ed Add legacy PLATFORM_SCHEMA config validation (#21072)
* Add legacy PLATFORM_SCHEMA config validation

* Fix tests

* Lint

* Add persistent notification

* Update bootstrap.py
2019-02-16 23:05:06 -08:00
cdce8p
9125e49628 Fix battery_level error - HomeKit (#21120) 2019-02-16 23:04:29 -08:00
Markus Jankowski
8c5763624c Add Groups to Homematic IP (#21076)
* Added HmIP-Groups

* Fix imports

* Removed config options from conflig_flow

* fix tests

* Removed config options

* reverted smaller code changes

* changes after review

* minor fix

* Fixed comments
2019-02-17 06:24:13 +01:00
Rohan Kapoor
481439d387 Deprecate conf_update_interval (#20924)
* Deprecate update_interval and replace with scan_interval

* Update tests

* Fix Darksky tests

* Fix Darksky tests correctly

This reverts commit a73384a223ba8a93c682042d9351cd5a7a399183.

* Provide the default for the non deprecated option

* Don't override default schema for sensors
2019-02-17 06:23:09 +01:00
Matthew Garrett
ad9ec2190c Merge pull request #21133 from mjg59/eufy
Update Lakeside dependency in Eufy component
2019-02-16 20:59:20 -08:00
Diogo Gomes
9cab597bc4 Don't expose services in Utility_Meter unless tariffs are available (#20878)
* only expose services when tariffs configured

* don't register services multiple times
2019-02-16 20:04:56 -08:00
Paulus Schoutsen
9c92880b5a Handle ValueError (#21126) 2019-02-16 19:38:52 -08:00
Paulus Schoutsen
ea592a003b Bump pychromecast to 2.5.2 (#21127) 2019-02-16 20:48:43 -05:00
Matthew Garrett
451241b481 Update Lakeside dependency in Eufy component
This should fix #16834
2019-02-16 15:43:30 -08:00
Nick Horvath
c91512d55d Bump thermoworks_smoke version to get new pyrebase version (#21100) 2019-02-16 12:15:15 -08:00
Paulus Schoutsen
d34fe106e4 Updated frontend to 20190216.0 2019-02-16 12:15:04 -08:00
Paulus Schoutsen
66267474dc Updated frontend to 20190216.0 2019-02-16 12:00:04 -08:00
Fabian Affolter
1a6c79d5e2 Order imports (#21117) 2019-02-16 17:03:08 +01:00
Otto Winter
a49686879d Update bootstrap.py 2019-02-16 14:51:30 +01:00
Nick Horvath
f7d9031486 Bump thermoworks_smoke version to get new pyrebase version (#21100) 2019-02-16 11:18:13 +01:00
Andrew Sayre
b39b66ef65 Fix SmartThings Translation Error (#21103) 2019-02-16 10:49:24 +01:00
Matt Snyder
4c23ccad98 Owlet baby monitor component (#21108) 2019-02-16 10:12:16 +01:00
David Barrera
4509caefde Add index parameter to scrape sensor (#21084)
* Add index parameter to scrape sensor

The scrape sensor selects the first element of the list returned by
BeautifulSoup. This commit adds an optional index parameter to allow the
selection of a different element from the list of results. To make this
a non-breaking change, if no index value is configured, the sensor
defaults to the previous behaviour of returning the first element.

* Set default value for index to avoid later checks
2019-02-16 09:29:24 +01:00
Paulus Schoutsen
5cf936c777 Bumped version to 0.88.0b1 2019-02-15 10:32:28 -08:00
Aaron Bach
91a2c73a2c Bump aioambient to 0.1.2 (#21098) 2019-02-15 10:32:23 -08:00
Paulus Schoutsen
90da9120e8 Update pychromecast (#21097) 2019-02-15 10:32:23 -08:00
Paulus Schoutsen
da672c6593 Fix hue retry crash (#21083)
* Fix Hue retry crash

* Fix hue retry crash

* Fix tests
2019-02-15 10:32:22 -08:00
Paulus Schoutsen
2de65af3fa Check against unlinked user (#21081) 2019-02-15 10:32:22 -08:00
Phil Hawthorne
dc606b40ac Set uvloop version consistent with hass.io (#21080)
This sets the uvloop version in Docker containers to 0.11.3, which is the
same version that hass.io uses.

uvloop might be causing issues with some Docker containers on some host
systems, as reported in #20829
2019-02-15 10:32:21 -08:00
Paulus Schoutsen
8973852a2e Fix pushover schema 2019-02-15 10:32:05 -08:00
David F. Mulcahey
2b6b922e3f Set ZHA device availability on new join (#21066)
* set availability on device join

* fix new join test
2019-02-15 10:30:43 -08:00
Aaron Bach
539d24dd60 Bump aioambient to 0.1.2 (#21098) 2019-02-15 10:28:23 -08:00
Phil Hawthorne
9203ae201f Set uvloop version consistent with hass.io (#21080)
This sets the uvloop version in Docker containers to 0.11.3, which is the
same version that hass.io uses.

uvloop might be causing issues with some Docker containers on some host
systems, as reported in #20829
2019-02-15 10:25:03 -08:00
David F. Mulcahey
3a6a246746 Set ZHA device availability on new join (#21066)
* set availability on device join

* fix new join test
2019-02-15 13:14:58 -05:00
Paulus Schoutsen
6c574a4eb4 Updated frontend to 20190215.0 2019-02-15 10:09:24 -08:00
Paulus Schoutsen
f7a6027466 Updated frontend to 20190215.0 2019-02-15 10:09:09 -08:00
Paulus Schoutsen
05808afe75 Update pychromecast (#21097) 2019-02-15 09:46:03 -08:00
Otto Winter
06f2aa93a4 Add persistent notification 2019-02-15 18:40:46 +01:00
Jason Hu
46efc0eafb Refactor http CachingStaticResource (#21062)
* Simplify http.CachingStaticResource implementation

* Sync up CachingStaticResource._handle() implementation from aiohttp

* Ignore pylint duplicate-base warning

* Try to disable pylint for http/static.py

Caused by https://github.com/PyCQA/astroid/issues/633#issuecomment-463879288

* Remove pylint ignore

* Ignore pylint duplicate-base warning
2019-02-15 09:31:54 -08:00
Andrew Sayre
383813bfe6 Config Entry migrations (#20888)
* Updated per review feedback.

* Fixed line length

* Review comments and lint error

* Fixed mypy typeing error

* Moved migration logic to setup

* Use new migration error state

* Fix bug and ignore mypy type error

* Removed SmartThings example and added unit tests.

* Fixed test comments.
2019-02-15 09:30:47 -08:00
Paulus Schoutsen
1130ccb325 Fix hue retry crash (#21083)
* Fix Hue retry crash

* Fix hue retry crash

* Fix tests
2019-02-15 08:43:30 -08:00
Andrew Sayre
93f84a5cd1 SmartThings Component Enhancements/Fixes (#21085)
* Improve component setup error logging/notification

* Prevent capabilities from being represented my multiple platforms

* Improved logging of received updates

* Updates based on review feedback
2019-02-15 17:40:54 +01:00
Jonas Pedersen
7d0f847f83 Add switch platform for Danfoss Air and additional sensors. (#21046)
* Add switch platform for Danfoss Air and additional sensors.

* Solve lint issues.

* Correct style.

* Minor changes

* Minor changes

* Minor changes

* Update file header

* Remove space

* Remove space
2019-02-15 14:54:25 +01:00
Phil Cole
656d39e3ec Nissan Leaf Integration (Carwings / NissanConnect EV) (#19786)
* Added work so far.

* Change interval so nobody drains their battery when I put this online

* Added the warning notice.

* Async setup

* Still broken, but we're getting there.

* Back to synchronous, moved refresh stuff into DataStore

* Functional sensors!

* Added working switches, tweaked intervals a bit

* Fixed turn off result

* Moved plug status to binary_sensor, added smart intervals

* Documentation and car nickname stuff

* Syntax fixes and coveragerc additions

* Style fixes

* Fixing the final line length

* Fixed an issue with newer models and bad climate data

* Forgot to check my line endings.

* New icons for most of the components

* Hotfix for handling Nissan's awful servers

* Merge in fixes made by Phil Cole

Remove invalid FIXMEs and update TODOs
Fixes for pylint and test for CarwingsError exception rather than Exception
Flake8 fixes
Add pycarwings2 to requirements_all.txt
Add extra configuration documentation.
Use pycarwings2 from pip. Check server dates between requests.
Add sensor device class for battery.
Async conversion fixes
flake8 fixes and docstrings
Non-async charging is OK
Handle multiple cars in the configuration
Convert to async. Better imports for platforms
Fix scanning interval & prevent extra refreshes.  async switchover
Check discovery_info to prevent load of platforms
Ensure update frequency is always above a minimum interval (1 min).
Platforms don't have return values
Use values() instead of items() when not using key
Use snake_case (LeafCore becomes leaf_core)

commit 418b6bbcc49cf2909aac85869440435410abf3fd

* Add pycarwings2 to requirements_all.txt

* Make stopping charge error an 'info'. Remove TODO.

* Request update from car after sending start charging command.

* Delay initial (slow) update for 15 seconds and make async

* Flake8 line length fixes

* Try to fix D401 'imperative mood' git diff tox errors

* Try to fix more D401 'imperative mood' tox errors

* Default interval of an hour in code, to match comments.

* Update to pycarwings2 2.3

* Update to pycarwings2 2.3 in requirements_all.txt

* Remove documentation, instead refering to home-assistant.io

* Remove unneeded dispatcher_send()

* Remove unneeded requirements comments

* Combine excess debugging.

* Remove single line method signal_components()

* Bump to version 2.4 of pycarwings2

* Remove unused dispatcher_send

* Simplify logging of LeafEntity registration

* Update requirements_all.txt

* Multiple changes

Increase timeout to 30 seconds
Only consider battery_status
Fix plugged in status
Better attempts at try/exception handling

* Fix line length

* Use pycarwings 2.5

* Remove pointless 'is True'

* Remove unnecessary 'is True/False'

* Remove unnecessary 'is True/False'

* Use LENGTH_MILES and LENGTH_KILOMETERS

* Remove excess logging in setup_platform()

* Remove unnecessary 'is True'

* Use pycarwings2 version 2.6

* Require pycarwings2 version 2.7.

* Increase sleep delay for climate and location reponses.

* Remove unnecessary 'is True'

* Increase frequent polling warning to _LOGGER.warning()

* Use DEVICE_CLASS_BATTERY

* Remove extraneous 'is True'.

* Move icon strings to constants.

* Remove unneeded key.

* LeafRangeSensor ac_on property is internal.

* Flake8 missing line

* Remove homebridge attributes.

* Remove round battery % and range to whole numbers

* Use pycarwings2 2.8

* Move to embedded component model

* Reduce maximum attempts to 10 (5 mins)

* Include attempt count in 'waiting' log message

* Use await instead of yield. Remove @asyncio.coroutine decorators.

* Add @filcole as nissan_leaf codeowner

* Fix checking for if not data returned from vehicle. Don't double send signal on location update.

* Exposed updated_on, update_in_progress and next_update attributes.

* Add nissan_leaf.update service that triggers an update.

* Flake8 line fixes

* Remove excess and double logging.

* Add updated_on attribute for device tracker.

* Fix crash if pycarwings2 doesn't provide cruising ranges.

* Minor changes

* Minor changes

* Minor changes

* Minor changes

* Minor changes
2019-02-15 14:35:25 +01:00
Klaudiusz Staniek
7b19428279 Times of The Day Binary Sensor (#20068)
* First commit

* Times of the Day binary sensor added

* Python 3.5 fixes and logging removed

* Code refactored according to reviewer's suggestions

* Fixed config template with friendly name support

* Finall pep8 fixes

* Removed async_generate_entity_id and moved initial calculation to async_added_to_hass

* Change the configuration schema to follow the current requirements

* Update according latest suggestsion

* Fix typos and minor changes

* Fix lint issue
2019-02-15 14:13:44 +01:00
Fredrik Erlandsson
f3786e2f2b Point alarm control (#20972)
* initial working example of alarm_control

* fixes for alarm_control

* arm home is the same as arm away

* updated documentation

* final fixes

* pypoint version up

* fixes for Martin
2019-02-15 12:19:42 +01:00
Eliran Turgeman
b44ff38f5a Fix "Unable to find entity" at Waze component (#21087)
Should fix https://github.com/home-assistant/home-assistant/issues/20953 
(Unable to create this issue on my HA platform)
2019-02-15 11:48:27 +01:00
Fabian Affolter
eb573c2701 Meteo france (#21065)
* Move files

* Move file

* Update .coveragerc

* Sort import and update file header

* Minor changes
2019-02-15 10:57:47 +01:00
Otto Winter
f6ae054e9f Lint 2019-02-15 10:57:02 +01:00
Otto Winter
b7607ff472 Fix tests 2019-02-15 10:51:52 +01:00
John Mihalic
c115c89afd Bump pyHik library to 0.2.2, improve connections, add sensors (#21086) 2019-02-15 07:18:12 +01:00
Paulus Schoutsen
12c18d63fd Fix pushover schema (#21073) 2019-02-14 15:54:48 -08:00
Paulus Schoutsen
ab7fda4286 Check against unlinked user (#21081) 2019-02-14 15:54:38 -08:00
Fabian Affolter
cdc4dc3f11 Rename CONF_ATTRIBUTION to ATTRIBUTION (#21069)
* Rename CONF_ATTRIBUTION to ATTRIBUTION

* Update homeassistant/components/sensor/irish_rail_transport.py

Co-Authored-By: fabaff <mail@fabian-affolter.ch>
2019-02-14 22:09:22 +01:00
Paulus Schoutsen
d60934c028 Fix pushover schema 2019-02-14 12:06:25 -08:00
Otto Winter
9c09a98c9e Add legacy PLATFORM_SCHEMA config validation 2019-02-14 20:55:51 +01:00
Fabian Affolter
03ec3ac16e Update file header (#21067) 2019-02-14 20:35:47 +01:00
Joakim Plate
c5de32e7b1 Climate const.py move (#20945)
* Move constants to const.py

* Import from const instead of climate
2019-02-14 20:34:43 +01:00
Fabian Affolter
dc62cb6a88 Update file header 2019-02-14 16:42:03 +01:00
Fabian Affolter
3736120c6a Update file header (#21061)
* Update file header

* Fix lint issue

* Fix lint issue
2019-02-14 16:01:46 +01:00
Victor Cerutti
f4b2573c4b Météo-France platform for the weather component (#18404)
* new weather component for meteofrance

* linting

* upgrade meteofrance package version

* Update .coveragerc

* Remove updates to the weather component architecture

* Rewrite Météo-France as a component

* Update .coveragerc

* Update requirements_all.txt

* remove Weather Card option

* Update conf name

Changing conf name to something more universal for worldwide weather forecast (postal code was only relevent for France)

* Update meteofrance pypi package

* fix line too long

* Update requirements_all.txt

* prevent from calling an API endpoint if not in monitored conditions

* fix stale url and remove blank line

* Insure that all cities are unique

* rename CONF_ATTRIBUTION

* Updating data from component setup

* fix missing extra lines
2019-02-14 14:40:27 +01:00
Paulus Schoutsen
801401e9cb Bumped version to 0.89.0.dev0 2019-02-13 20:47:04 -08:00
Paulus Schoutsen
e404afc0d0 Bumped version to 0.88.0b0 2019-02-13 20:37:46 -08:00
Paulus Schoutsen
3c8c6688be Merge remote-tracking branch 'origin/master' into dev 2019-02-13 20:37:22 -08:00
Paulus Schoutsen
882f5ed079 Don't directly update config entries (#20877)
* Don't directly update config entries

* Use ConfigEntryNotReady

* Fix tests

* Remove old test

* Lint
2019-02-13 20:36:06 -08:00
Fabian Affolter
161c368c9d Update file header (#21054)
* Update file header

* Update __init__.py
2019-02-13 20:35:12 -08:00
Fabian Affolter
3a386e627e Upgrade ruamel.yaml to 0.15.88 (#21055) 2019-02-13 20:29:11 -08:00
Fredrik Erlandsson
1faf2f49d0 fix webhook update (#21048) 2019-02-13 20:27:17 -08:00
Diogo Gomes
f1f3074612 Add integration method to sensor.integration (#21050)
* add integration method and respective new methods

* ack @ottowinter tip

* align const name with value
2019-02-13 20:26:27 -08:00
Paulus Schoutsen
81d2ec9618 Person: Ignore unavailable states (#21058)
* Ignore unavailable states

* Revert validation
2019-02-13 20:10:31 -08:00
Paulus Schoutsen
4d3790e2d4 Person checks (#21056)
* Do not allow creating/updating persons with invalid user IDs

* Unset user_id from person when user deleted

* Lint

* Lint

* Lint
2019-02-13 20:04:08 -08:00
Paulus Schoutsen
50ba3d0427 Create a person during onboarding (#21057) 2019-02-13 20:00:08 -08:00
Alok Saboo
bf0a50cdb2 Add template support to Bayesian sensor (#20757)
* Add template support to Bayesian sensor

* Removed unused import
2019-02-13 17:39:53 -07:00
Ben Dews
c20e0b985a Add Lock capability to SmartThings platform (#20977)
* Bumped pysmartthings version to 0.6.1

* Added Lock to supported platforms

* Added SmartThings Lock component

* Updated lock to eagerly set state

* Updated requirements_all.txt & requirements_test_all.txt with pysmartthings==0.6.1

* Added SmartThings Lock tests

* Removed inapplicable comment

* Removed unused import (STATE_UNLOCKED)

* Populated device_state_attributes with values provided by SmartThings

* Condensed if_lock assertion function

* Updated gathered attributes

* Fixed typo

* Updated tests to use new setup_platform

* Updated assignment of device state attributes

* Updated tests to utilise the LOCK_DOMAIN constant where suitable

* Fixed false positive for Switch test: (test_unload_config_entry)

* Implemented constant to contain expected SmartThings state for is_locked check

* Improved allocation of State Attributes

* Improved allocation of state attributes

* Fixed lint error (was running lint checks against the wrong file, whoops)

* Added test for unloading lock config

* Use isinstance instead of type()

* Updated device state to explicitly check for is not None instead of a truthy value
2019-02-13 18:36:49 -06:00
Paulus Schoutsen
02f207ea8e Update translations 2019-02-13 15:44:18 -08:00
Paulus Schoutsen
c2579d1d8a Updated frontend to 20190213.0 2019-02-13 15:43:55 -08:00
Otto Winter
faeb6295b6 Fix updated file header (#21049) 2019-02-13 22:52:48 +01:00
Ryan Wagoner
62b2b23d0b Add night arm mode to MQTT alarm control panel (#20961)
* Add night arm mode to MQTT alarm control panel

* Add unit test for MQTT alarm night mode
2019-02-13 22:52:32 +01:00
Fabian Affolter
127c55e0c1 Update file header (#21023)
* Update file header

* Update file header

* Update file header

* Update file header

* Update file header

* Fix lint issues
2019-02-13 21:21:14 +01:00
emontnemery
22af9707ad Add support for device_class to MQTT cover (#21044) 2019-02-13 19:58:46 +00:00
Kevin Fronczak
67780dfb4e Update scan interval to 5 minutes. (#21041) 2019-02-13 17:47:38 +01:00
Colby Rome
136b1e1f6c Fix broken links to code examples (#21039) 2019-02-13 17:14:59 +01:00
David F. Mulcahey
d692251e62 Run tasks when ZHA devices become available (#20998)
* use tasks for message interception

* update available handling

* review comments and cleaned up check

* review comments
2019-02-13 08:52:29 -05:00
Fabian Affolter
8db8a58763 Upgrade sqlalchemy to 1.2.17 (#21020)
* Upgrade sqlalchemy to 1.2.17

* Update requirements_all.txt

* Update requirements_test_all.txt

* Run script again
2019-02-13 12:30:37 +01:00
Aaron Bach
8a6235fdac Bump aioambient to 0.1.1 (#21024)
* Bump aioambient to 0.1.1

* Requirements
2019-02-12 22:57:53 -07:00
Andrew Sayre
d037359bda Add lock config entry unload support. (#21025) 2019-02-12 22:35:20 -06:00
Fabian Affolter
6bbc663d0b Add missing helpers (#21021) 2019-02-12 20:52:02 -06:00
Jef D
d1950cd75c Update co2signal==0.4.2 to fix #20805 (#21022)
Update co2signal==0.4.2 to fix #20805
2019-02-12 20:51:10 -06:00
David F. Mulcahey
561ff33641 Update entity state when ZHA device becomes available (#20993)
* correctly update device entity state

* update state when device becomes available

* constants

* review comments
2019-02-12 20:37:39 -05:00
emontnemery
888345e4ff Fix discovery of audio groups (#20947)
* Fix discovery of audio groups

* Fix tests

* Re-discover

* Review comments

* Remove failing tests

* Update dependencies

* Fix test
2019-02-12 15:00:54 -08:00
Paulus Schoutsen
6fad9e1a0a RFC: Embed platforms without component for remote component. (#20809)
* Embed platforms for remote component.

* Update reqs
2019-02-12 14:57:13 -08:00
rbflurry
f1a00cc0f9 Allow target all timer services using 'entity_id: all' (#21008) 2019-02-12 23:18:45 +01:00
Paulus Schoutsen
4d1d22070c Bump frontend to 20190212.0 2019-02-12 13:48:11 -08:00
Daniel Høyer Iversen
7b7720d0ea Norway air, minor fix (#21016) 2019-02-12 13:45:12 -08:00
Fabian Affolter
b6854a82cf Upgrade restrictedpython to 4.0b8 (#21015) 2019-02-12 13:44:32 -08:00
Otto Winter
fe9800e784 Prevent OverflowError in ESPHome integration (#21014) 2019-02-12 22:34:06 +01:00
Fabian Affolter
d795410b27 Update ordering (#21013) 2019-02-12 21:44:30 +01:00
David F. Mulcahey
80442e655d Update ZHA API to be device oriented (#20990)
* update cluster API

* swap to device focused API

* update test
2019-02-12 15:05:02 -05:00
Jason Hu
6b46ed850b Upgrade cryptography to 2.5 (#21011) 2019-02-12 19:52:24 +01:00
carstenschroeder
d1c8d39107 Add unique id to ADS platforms (#20511)
* Add friendly_name option

* Correct hound findings

* correct hound findings 2

* add unique id

* add unique id to all ads platforms
2019-02-12 18:42:09 +01:00
Fredrik Erlandsson
d89c56829c Fix Point does I/O in event loop (#20939)
* call I/O operations via hass.async_add_executor_job

* asyncio fixes

* Fixes from @amelchio

* async _update_callback
2019-02-12 17:15:02 +01:00
Daniel Høyer Iversen
2702c75fb0 Norway air quality (#20683)
* Add norway air quality sensor

* style

* library

* Refacotr to air_quality

* fix norway air comments
2019-02-12 16:40:22 +01:00
Paulus Schoutsen
00b8d57cd0 Add frontend storage (#20880)
* Add frontend storage

* Update storage.py
2019-02-12 16:38:19 +01:00
carstenschroeder
1e69848af4 Updates pyatmo to 1.8 and adds exception handling (#20938)
* switch to pyatmo 1.7 & add exception handling

* STATE_UNKNOWN => None

* correct too long line

* delete whitespace

* remove fancy update logic
2019-02-12 11:12:44 +00:00
Paulus Schoutsen
5dfaec5967 Update to Python 3.7 (#20988) 2019-02-12 10:33:03 +01:00
Paulus Schoutsen
9cbb26bee2 Bump feedparser version to py3.7 compat (#20987)
* Bump feedparser version to py3.7 compat

* Update requirements_test_all.txt

* Update gen_requirements_all.py
2019-02-12 10:30:09 +01:00
Thomas Passer Jensen
69df620ad6 Add Rejseplanen danish public transport sensor component (#19885)
* Add Rejseplanen danish public transport sensor component

* Removed commented out code and fixed style errors

* Use rjpl pypi package for API calls.

* Fix platform schema config and code cleanup.

* Use updated rjpl library with specific exceptions

* API error message is now logged, unknown state attributes excluded
2019-02-12 09:26:46 +01:00
Andrew Sayre
e8ed56ca52 Add SmartThings Climate platform (#20963)
* Add SmartThings Climate platform

* Add SmartThings Climate platform
2019-02-12 08:11:36 +01:00
arigilder
0d98f9783f Add lagging hdate for sensors that should lag to update (#20655)
* Add lagging hdate for sensors that should lag to update

* Fix indentation

* Lint fix
2019-02-11 23:34:48 +01:00
Aaron Bach
b5b03f5b7f Fix bug with monitored_conditions in Ambient PWS (#20837)
* Make monitored_conditions more specific in Ambient PWS

* Revert messing around with storing monitored_conditions elsewhere

* Come on, Aaron

* Fix bug with monitored_conditions in Ambient PWS
2019-02-11 23:31:49 +01:00
Otto Winter
55f9db6992 Bump aioesphomeapi to 1.5.0 (#20986)
* Bump aioesphomeapi to 1.5.0

* Update requirements_all.txt

* Fix editor line length setting
2019-02-11 21:57:17 +01:00
Fabian Affolter
277f37423e Sort imports (#20985) 2019-02-11 15:22:12 -05:00
Brian Towles
c3c92232da Unique Ids for August entities to allow renames (#20887)
* working unique ids for august

* cleanup blank lines

* cleanup blank lines

* cleanup blank lines

* rebase

* get the oneline back in

* blank line stuff

* whitespace cleanup

* Blank Line .

* blank line again
2019-02-11 14:48:02 -05:00
Fabian Affolter
4cb408f8f9 Sort imports (#20984) 2019-02-11 14:46:21 -05:00
David F. Mulcahey
868820c424 add device info API (#20950) 2019-02-11 14:38:04 -05:00
Ben Van Mechelen
861d58f58f Support for Multiple modbus hubs (#19726)
* modbus: support multiple modbus hub

* update data after entities added

* pass hub object to each entity. and save hub to hass.data but not in module level

* add hub_client setup log

* don't update when adding device, because hub_client is not ready right now

* support restore last state

* remove useless func

* compatible with python35

* removed unrelated style changes

* Update flexit for multi-device modbus

* change how hubs are referenced in the configuration

* Also update climate/modbus.py

* Remove unwanted whitescapce

* Defined common constants centrally

* Update DOMAIN in climate and switch components

* Removed unnecessary vol.schema

* Make hub name optional

* Add name property to ModbusHub
2019-02-11 14:00:37 -05:00
Patrick T.C
49ecca9cb9 Set cover level using emulated_hue (#19594)
* set cover level using emulated_hue

* changed mapping for service turn_on/off for cover.

* removed whitespace for the sake of hound

* using const for domains instead of hardcoded strings.

* change length of lines for the sake of hound

* fixed under-intended line

* changed intent for the sake of hound
2019-02-11 13:59:34 -05:00
Fabian Affolter
788f7988e7 Upgrade ruamel.yaml to 0.15.87 (#20955) 2019-02-11 17:18:25 +01:00
Fabian Affolter
0425c8195f Upgrade slixmpp to 1.4.2 (#20971) 2019-02-11 08:33:57 -05:00
Stefan Burke
de2892caa8 Update pyHS100 to 0.3.4 (#20979) 2019-02-11 08:32:43 -05:00
Mattias Welponer
e538320901 HomematicIP fix cover direction (#20901)
* Fix cover direction

* Update for better readability

* Fix lint
2019-02-11 10:20:00 +01:00
Aaron Bach
a55c2514d1 Add missing data fields to Ambient PWS (#20808)
* Fix binary sensor in Ambient PWS

* Add missing data points for Ambient PWS

* Member comments

* Binary sensor doesn't need state property
2019-02-11 09:54:29 +01:00
Oliver
88d0aa14ee Update denonavr to 0.7.8 (add various sound modes) (#20951) 2019-02-10 19:13:03 -06:00
CrazYoshi
fd991bd1a4 Ebusd integration (#19607)
* ebusd component and sensor splitted

ebusd component and sensor splitted and tested

* houndci-bot fixes

* pep8 validated

* Update requirements_all.txt

* travis fixes

* Fix __init__.py for travis

* translation updated

* proposed changed

* move logic from component to ebusdpy lib

* hound fixes

* Update requirements_all.txt

* update pypi library to V0.0.11

* error management in command_result

Avoid sensor status change in case an error in reading occurs

* add opMode translations

add opMode translations

* send type to read ebusdpy API

* timeframe as attribute for time schedule type sensors

* hound fix

* bugfix on library

* ebusd sensor moved to ebusd component directory

* update ebusdpy dependency

* improvement proposed

* travis fix

* update error managing

* insert log debug start setup

* changes requested

* exception tuple on init

* cla-bot stucked pull

* added bai circuit support

* merged coveragerc from dev

* configuration get change
2019-02-10 13:04:18 -08:00
Rohan Kapoor
8f249f9149 Use CONF_RECIPIENT for default recipient in config (#20925)
* Use CONF_RECIPIENT for default recipient in config

* Fix typo
2019-02-10 21:52:35 +01:00
Rudolf Offereins
203a6fd349 Fixed Thethingsnetwork sensor issue so that it takes the most recent (last) item from the TTN data storage query result instead of the first. (#20790)
* Fixed Thethingsnetwork sensor issue so that it takes the most recent (last) item from the TTN data storage query result instead of the first.

* Update sensor.py

More pythonic way to get the last item of the sensor value list.
2019-02-10 21:49:45 +01:00
Fredrik Erlandsson
5df02f3a78 fix missing sensor values for Point (#20937) 2019-02-10 21:48:33 +01:00
Tim van Cann
d049b521b2 Add Google pubsub component (#20049)
* Add google pubsub component

* Add tests and requirements

* Make python3.5 compatible

* Fix linting

* Fix pubsub test

* Code review comments

* Add missing docstrings

* Update requirements_all

* Code review comment

- Remove pylint ignores
- Don't modify global environment
2019-02-10 21:45:46 +01:00
Markus Jankowski
1ebdc2e2c2 Add device HmIP-BSL to Homematic IP (#20865)
* Added support from HmIP-BSL

* Fixed setup of initial on

* Minor changes

Removed Black from Dictionary
added extra case to turn_on
added comments

* moved 3rd party libraries inside methods

* Fixed comment

* Removed code block to keep component behavior consisten to other dimmers

Minimum brightness is 10, otherwise the led is not visible anymore

* moved 3rd party libraries inside methods 2nd

* corrected spelling and variable assignment

* implemented feedback

* removed own state implementation

it is  the same as in parent class

* reduced device_state_attributes

brightness is alread in parent class

* On/Off is only determined by brightness now

turn_off sets brightness to 0.
turn_on now uses the previous used color an sets the brightness to 255

* Fixed string sorting of unique_id

* improved usage of base class

* Update code after review by MartinHjelmare

* Fix for the hound
2019-02-10 19:49:16 +01:00
On Freund
d8993af548 CoolMasterNet Climate platform (#20787)
* CoolMasterNet Climate platform

* Address Coolmaster PR comments

* Fix docstrings on climate demo platform

* Additional CoolMaster PR review fixes
2019-02-10 19:34:39 +01:00
Paulus Schoutsen
4a559cd4df Merge pull request #20930 from home-assistant/rc
0.87.1
2019-02-10 10:06:50 -08:00
David F. Mulcahey
16154ab445 Update ZHA helpers (#20898)
* update helpers

* review comments

* remove ternary

* use correct timeout
2019-02-10 19:01:07 +01:00
Aaron Godfrey
9f7443ba97 Reverts 2105724. (#20915)
This change broke functionality for existing users using hdmi grabbers.
2019-02-10 09:41:29 -06:00
Martin Gross
852d67b95c Fix #19990: Alexa-support for climate in manual-mode (#20910) 2019-02-10 09:02:53 -06:00
Matt White
44d7c3584d Added IDs and enabled workarounds for Yale YRD220, YRL220, YRD120 (#20929) 2019-02-10 09:00:03 -06:00
David F. Mulcahey
898b699311 Add quirks info to ZHA device (#20923)
* add quirks info to zha device

* move import

* remove device entity part
2019-02-10 08:56:27 -06:00
Peter Nijssen
ace1ae85dd add fan support for spider thermostats (#20897)
* add fan support for spider thermostats

* resolved feedback on pull request
2019-02-10 07:54:30 -06:00
javicalle
13421b326b Fix RFLink restore state (#20588)
* some minor tests refactor

* unused import

* async/await refactor

* Correct tests failures

* Restore state bug
added call to super().async_added_to_hass()

* Show brightness attribute if device supports it

* Fix light/test_rflink 

Dimmable devices defaults to 255 brightness

* delete super().device_state_attributes call
2019-02-10 12:50:40 +01:00
emontnemery
5f7f7777a0 Fix encoding for MQTT camera (#20932) 2019-02-10 12:35:54 +01:00
CV
5def64156f Missing Binary Sensor (#20921)
TiltIP Binary Sensor is missing in the discover list.
2019-02-10 12:34:54 +01:00
David F. Mulcahey
326010629c Add some api tests for ZHA (#20909)
* start API tests

* blank lines
2019-02-10 06:29:36 -05:00
Paulus Schoutsen
3a4b3a2f81 Bumped version to 0.87.1 2019-02-09 22:48:17 -08:00
Matt N
f601e9f774 Upgrade zm-py to 0.3.3 (#20886)
Fixes #20833
2019-02-09 22:48:11 -08:00
Paulus Schoutsen
c66ec87b69 Use text= instead of body= for creating web responses (#20879) 2019-02-09 22:48:09 -08:00
Daniel Høyer Iversen
81cad8cd52 Fix STATE_UNLOCKED for verisure (#20858) 2019-02-09 22:48:08 -08:00
Jc2k
5a762c74f4 Fix homekit_controller non-standard hk characteristics (#20824) 2019-02-09 22:48:07 -08:00
jonudewux
21583d25e2 Add Transmission component 'scan_interval' option (#20575)
* Transmission component fix 'scan_interval' option

* Fix dict[key] comments

* Fix latest mess
2019-02-09 22:48:06 -08:00
Eliran Turgeman
b5e40669c9 Fix waze_travel_time component ERROR on startup (#20316)
* Fix waze_travel_time component ERROR on startup

Fix the unhandled exception with Waze Travel Time sensor upon startup,
by adding Throttle before update_interval are starting.

* add missing whitespace after ','

* fix line too long (80 > 79 characters)

* lint

* fix interval to use const

* Change to Throttle as a decorator to update

Change to Throttle as a decorator to update instead of self.update = Throttle(interval)(self.update)
remove unnecessary code.

* fix  indentations

* Update waze_travel_time.py

* Update waze_travel_time.py

* Update waze_travel_time.py
2019-02-09 22:48:05 -08:00
Jason Hu
8137b0bb9e Fix coroutine never awaited warning in test (#20892) 2019-02-09 15:13:12 -06:00
Paulus Schoutsen
987b5cd905 Person component: add storage and WS commands (#20852)
* Forbid duplicate IDs

* Allow loading persons from storage

* Convert to PersonManager

* Add storage support and WS commands to Person component

* Convert list command to differentiate types

* Allow loading person component without defining persons

* Fix cleanups after update/delete

* Address comments

* Start tracking when HA started
2019-02-09 10:41:40 -08:00
Eliran Turgeman
cfd1563bc8 Added more language options (#20890)
This is a Small PR, Just Added 3 more language : 
* he: Hebrew
* ko: Korean
* lv: Latvian
2019-02-09 09:47:35 -06:00
Brian Towles
24914aade5 Set August doorbell availability state from online state (#20883)
The available state for the August Doorbell is currently set based on the state of the binary ding sensor.  This means that if there is no door bell rings in a while on startup the doorbell is shown as Unavailable (#20421) . This ties the availability of the doorbell to the  actual online state thats in the device information retrieved from august so that even if there has not been a doorbell ring activity on a while the device shows as online when it is.
2019-02-09 09:01:02 -06:00
Paulus Schoutsen
33dcb071da Use text= instead of body= for creating web responses (#20879) 2019-02-08 23:10:04 -08:00
Ville Skyttä
876e2a0a11 Upgrade mypy to 0.660 (#20873) 2019-02-09 08:32:14 +02:00
Matt N
33d607bb22 Upgrade zm-py to 0.3.3 (#20886)
Fixes #20833
2019-02-09 06:44:33 +01:00
René-Marc Simard
a014c2be59 Cleanup GTFS query (#20874) 2019-02-08 21:47:02 -06:00
René-Marc Simard
9db9a81793 Set GTFS icon by route type (#20876) 2019-02-08 21:38:39 -06:00
Joakim Plate
d16d14b648 Media player const.py move (#20822)
* Move more constants to const.py

* Import constants directly from const

* ATTR_ENTITY_ID is not defined in media_player

* MEDIA_PLAYER_PLAY_MEDIA_SCHEMA is still in __init__.py

* Correct imports in tts

* PLATFORM_SCHEMA, SCHEMA is still defined in __init__.py

* Pandora imports several services

* Some additional fixes for move of const in media_player

* Fix hound lengths
2019-02-08 14:18:18 -08:00
MatteGary
faf7ae29b1 Fix init of TransmissionData (#20817)
* Fix init of TransmissionData

 Fix in order to avoid null object on first update of Turtle Mode Switch

* Using async functionality

* Various fix

* HoundBot fix

* Removed some async calls

* Fix compilation Error

* Fix

* PEP fix
2019-02-08 18:15:14 +01:00
Daniel Høyer Iversen
6a78ad8ab6 Fix STATE_UNLOCKED for verisure (#20858) 2019-02-08 14:35:38 +01:00
Fabian Affolter
c99d140651 Upgrade youtube_dl to 2019.02.08 (#20859) 2019-02-08 07:44:08 -05:00
Markus Jankowski
ca0e5a75ec Add additional devices and features to Homematic IP (#20747)
* Homematic IP: updated dependency homematicip to 0.10.5

* Homematic IP: Added LightSensor

* Homematic IP: Added power measure for XXXSwitchMeasuring

* reverted unnessessary change

* reverted unnessessary change

* removed device_class from core

* Removed optional property device_class

* Added description for property

* Changed comment to fix travis build

* Changed comment to fix travis build
2019-02-08 12:43:48 +01:00
Rohan Kapoor
d5fad33599 Add better handling of deprecated configs (#20565)
* Add better handling of deprecated configs

* Embed the call to has_at_most_one_key in deprecated

* Add tests for checking the deprecated logs

* Add thoroughly documented tests

* Always check has_at_most_one_key

* Fix typing

* Move logging helpers to homea new logging helper

* Lint

* Rename to KeywordMessage instead of BraceMessage

* Remove unneeded KeywordStyleAdapter

* Lint

* Use dict directly rather than dict.keys() when creating set

* Patch the version in unit tests, update logging and use parse_version

* Re-add KeywordStyleAdapter and fix tests

* Lint

* Lint
2019-02-08 11:14:50 +01:00
Jc2k
ee3631e93e Fix homekit_controller non-standard hk characteristics (#20824) 2019-02-08 11:00:51 +01:00
Diogo Gomes
55d1d3d8ae Move weather.ipma into a component (#20706)
* initial version

* works

* lint

* move

* hound

* fix formatting

* update

* add extra features

* houmd

* docstring

* fix tests

* lint

* update requirements_all.txt

* new tests

* lint

* update CODEOWNERS

* MockDependency pyipma

* hound

* bump pyipma version

* add config_flow tests

* lint

* improve test coverage

* fix test

* address comments by @MartinHjelmare

* remove device_info

* hound

* stale comment

* Add deprecation warning

* address comments

* lint
2019-02-08 10:55:58 +01:00
Marvin Wichmann
1e95719436 Support knx tunable white and color temperature lights (#19699)
* KNX: Bumped version to 0.9.4 and added support for tunable white and color temperature for lights.

* Updated to the latest changes

* return None when ct value is unknown

- return None instead of default value when ct is unknown
- remove DEFAULT_COLOR_TEMPERATURE

* use Kelvin as base for relative color temperature

use Kelvin as base for relative color temperature instead of Mireds

* moved fallback value tests for clarity

* Update request from oliverblaha

Co-Authored-By: marvin-w <marvin@fam-wichmann.de>

* Address suggested changes

* Update homeassistant/components/knx/light.py

Co-Authored-By: marvin-w <marvin@fam-wichmann.de>

* Update homeassistant/components/knx/light.py

Co-Authored-By: marvin-w <marvin@fam-wichmann.de>
2019-02-08 08:28:52 +01:00
Andrew Sayre
706810bbce Add SmartThings Sensor platform (#20848)
* Add Sensor platform and update pysmartthings 0.6.0

* Add tests for Sensor platform

* Redesigned capability subscription process

* Removed redundant Entity inheritance

* Updated per review feedback.
2019-02-07 21:51:17 -07:00
Aaron Bach
c7df4cf092 Make monitored_conditions more specific in Ambient PWS (#20803)
* Make monitored_conditions more specific in Ambient PWS

* Revert messing around with storing monitored_conditions elsewhere

* Come on, Aaron
2019-02-07 21:39:30 -07:00
Paulus Schoutsen
e59240fa00 Add default_config component (#20799)
* Add default config component

* Add default_config to default config

* Fix comments
2019-02-07 20:07:15 -08:00
Aaron Bach
222c4ea6f3 Added Ambient PWS to device registry (#20841) 2019-02-07 21:12:58 -06:00
Paulus Schoutsen
49bab574b9 Clean up Z-Wave pt2 (#20842) 2019-02-07 17:27:31 -08:00
Martin Hjelmare
5f76628665 Add MVP person component (#20290)
* Add person component

* Required first name.
* Optional last name and user id.
* Optionally track device trackers. Last device tracker state change will
  set state.
* Set device tracker state entity_id as source attribute.
* Set coordinates of device tracker state as state attributes.
* Restore state.

* Parse restored state too

* Clean up

* Add missing property decorator

* Validate source entities as device trackers

* Only use name instead of first and last name

* Add user_id validation

* Add unique_id

* Remove not needed properties

* Uniform docstrings

* Fail component setup if no valid entities

* Add tests

* Add id and use that for unique_id

* Clean up
2019-02-07 15:25:30 -08:00
David F. Mulcahey
32f2221b22 Fix zha light bugs (#20825) 2019-02-08 00:09:47 +01:00
Markus Ressel
542f024356 XS1 component (#19115)
* added xs1 main component
added implementations for switch, sensor, climate and binary_sensor

* updated code
fixed styling
added comments
removed binary_sensor (wasn't working)

* ran "gen_requirements_all.py" script

* fixed linting issues

* added config options for port and ssl
small fixes

* use already defined config constants instead of defining new ones

* avoid passing in hass to the entity

* use async keyword and proper asyncio calls
limit updates with a global lock to prevent overwhelming the gateway with concurrent requests
change info logger calls to debug

* update dependency

* removed unneeded constant

* fix lint issues

* updated requirements

* removed unused imports

* fixed some flake8 errors

* fixed some flake8 errors

* changed imports to absolute paths

* fixed some lint errors

* fixed some lint errors

* fix update of attached sensor

* reordered imports
added config defaults
check if platform is available
changed docstring

* lint fix

* review fixes

* isort

* import fix

* review fix

* review fix

* review fix

* removed unused imports

* lint fix

* lint fix

* climate fix
exclude sensors that will be used in climate component from default sensor category

* .coveragerc fix

* lint fix

* moved platform to it's own package
2019-02-07 23:21:41 +01:00
Paulus Schoutsen
a9672b0d52 Load as many components in parallel as possible (#20806)
* Load as many components in parallel as possible

* Lint
2019-02-07 22:56:40 +01:00
Paulus Schoutsen
f3b20d138e Embed Z-Wave platforms (#20810) 2019-02-07 22:50:59 +01:00
Aaron Bach
d24ccbd1e6 Fix binary sensor in Ambient PWS (#20801)
* Fix binary sensor in Ambient PWS

* Correctly load entities

* Corrected what on and off means for existing sensor

* Make sure to return a boolean

* Member comments

* Binary sensor doesn't need state property
2019-02-07 14:35:23 -07:00
Ville Skyttä
d45f25ce2c Add more type hints to helpers (#20811)
* Add type hints to helpers.aiohttp_client

* Add type hints to helpers.area_registry
2019-02-07 13:34:14 -08:00
Paulus Schoutsen
16159cc3d0 Update platform loading path (#20807)
* Warn when platform loaded from an entity component folder

* Fix tests
2019-02-07 13:33:12 -08:00
Diogo Gomes
e0f63132e8 Deduplication of log entries in system_log (#20493)
* Deduplication of log entries

* fix
2019-02-07 13:32:37 -08:00
Timmo
968f98706e GitHub Sensor (#19561)
*  Add GitHub sensor

* 👕 fix tox lint warning

* 🔨 Add GitHub to .coveragerc

* 👕 Fix pylint warning

* 🔨 Use config.get

* 🔥 Tighten validation

* 👕 fix linter error

* 🔨 Add path for context in errors

*  Add releases

*  Add GitHub Enterprise server support

* 🔨 remove unused constant

* 🔨 Requested changes

* 🔨 Reorder imports

* 🔨 Change to CONF_URL

* 🔨 Add docstring

* 🔨 Add validation for repo list

* ⬆️ Update PyGithub to 1.43.5

* 🔨 Sort attributes

* 🔥 Fix validation

* 👕 Fix linting issue

* 🔨 Fail platform setup when data init fails with bad credentials etc

* 👕 Fix whitespace lint error

* 🔨 Fix requirements_all version

* 👕 Linter fix attempt

* 🔥 Missing bracket

* 🔥 Another attempt to at a linter fix

* 🔥 Fix indentation

* 🔨 Reduce exception down to main one

* 🔥 Remove update throttle logic

* 🔨 Reduce calls

* 👕 Remove unused imports

* 🔥 🔨 Reduce attribute data

* 👕 Remove unused json import

* 🔨 Remove username and password

* 🔥 Fix counts

* 🔨 Update attrs and add any missing

* 🔨 Add unique_id

* 🔥 Convert uuid to string

* 🔥 Replace UUID with repository path

* 🔨 Cleanup

* 🔨 Cleanup

* 🔥 Remove unused variable

* 🔨 Change to update instead of _update

* 🔨 Improved consistency

* 🔨 Improve consistency

* 👕 Fix line lengths

* 🔨 Fix length

* 🔨 Fix syntax
2019-02-07 18:34:27 +01:00
David F. Mulcahey
d177e1324c Add device ieee to zha events (#20791) 2019-02-07 16:31:24 +01:00
David F. Mulcahey
d4c34c6b02 Cleanup zha listener lifecycle (#20789) 2019-02-07 09:23:01 +01:00
David F. Mulcahey
03ab152c82 Enable the available property for zha entities (#20788) 2019-02-07 09:14:19 +01:00
Fabian Affolter
1715a2070b Upgrade astral to 1.9.2 (#20796) 2019-02-06 22:00:39 -08:00
William Scanlon
ff84c01d41 Remove wink sensor log calls (#20798)
* Removed log calls

* pass during exception
2019-02-07 06:22:44 +01:00
Daniel Høyer Iversen
850556d6c3 upgrade switchmate lib (#20792) 2019-02-06 21:41:38 -05:00
Fabian Affolter
a611fb1664 Upgrade distro to 1.4.0 (#20797) 2019-02-06 21:40:38 -05:00
Robert Schindler
06f3e8137a Added command_line auth provider that validates credentials by calling a command (#19985)
* Added external auth provider that calls a configurable program

Closes #19975

* Raise proper InvalidAuth exception on OSError during program execution

* Changed name of external auth provider to command_line

* Renamed program config option to command in command_line auth provider

* Made meta variable parsing in command_line auth provider optional

* Added tests for command_line auth provider

* Fixed indentation

* Suppressed wrong pylint warning

* Fixed linting

* Added test for command line auth provider login flow

* Log error when user fails authentication

* Use %r formatter instead of explicit repr()

* Mix all used names of typing module into module namespace

I consider this nasty and bad coding style, but was requested by
@awarecan for consistency with the remaining codebase.

* Small code style change

* Strip usernames with command_line auth provider
2019-02-06 16:36:41 -08:00
Paulus Schoutsen
c366fa00d8 Merge pull request #20794 from home-assistant/rc
0.87.0
2019-02-06 14:57:53 -08:00
Paulus Schoutsen
180689fb04 Bumped version to 0.87.0 2019-02-06 11:49:56 -08:00
Paulus Schoutsen
9912e0fc48 Make sure Locative doesn't submit invalid device IDs (#20784) 2019-02-06 11:49:08 -08:00
Erik Hendrix
58b7905276 Update version for pymyq to 1.1.0
Update version of pymyq to 1.1.0; this version brings improved functionality, reducing errors for retrieving current state for the MyQ covers.
2019-02-06 11:48:20 -08:00
Fredrik Erlandsson
a6bcb515f9 Fix tellduslive responsiveness (#20603)
* use async_call_later for update

* no need to timeout

* fixes

* move init tasks to hass.loop

* version bump of tellduslive

* fixes for @MartinHjelmare

* fixes task cancel

* don't return from new client
2019-02-06 11:47:32 -08:00
Greg Johnson
fb1da53568 Allow both VOLUME_STEP and VOLUME_SET (#20732)
* Allow both VOLUME_STEP and VOLUME_SET

Seems like it should be possible to support both at the same time.

* Update test to allow VOLUME_SET and VOLUME_STEP
2019-02-06 11:16:21 -08:00
Paulus Schoutsen
59393ab085 Prevent template changing options (#20775)
* Prevent complex template validation changing input value

* Remove deprecation warnings
2019-02-06 11:15:27 -08:00
David F. Mulcahey
e6cd04d711 ZHA component rewrite (#20434)
* rebase reorg

* update coveragerc for now

* sensor cleanup

* remove availability tracking for entities

* finish removing changes from tests

* review comments pass 1

* use asyncio.gather - review comments

* review comments

* cleanup - review comments

* review comments

* review comments

* cleanup

* cleanup - review comments

* review comments

* review comments

* use signal for removal

* correct comment

* remove entities from gateway

* remove dead module

* remove accidently committed file

* use named tuple - review comments

* squash bugs

* squash bugs

* add light and sensor back to coveragerc until % is higher
2019-02-06 13:33:21 -05:00
Paulus Schoutsen
65a225da75 Make sure Locative doesn't submit invalid device IDs (#20784) 2019-02-06 09:50:48 -08:00
Pawel
208f1a4a47 Allow pausing xiaomi vacuum in all states (#20620)
* fix state update when no cleaning is yet performed
allow pause vacuum when returning to base

* revert checking of atttribute updates. Will be fixed in upstream lib.

* remove unnecesarry if on pause_commadn
2019-02-06 13:04:01 +01:00
Eliran Turgeman
3de21d3fda Fix waze_travel_time component ERROR on startup (#20316)
* Fix waze_travel_time component ERROR on startup

Fix the unhandled exception with Waze Travel Time sensor upon startup,
by adding Throttle before update_interval are starting.

* add missing whitespace after ','

* fix line too long (80 > 79 characters)

* lint

* fix interval to use const

* Change to Throttle as a decorator to update

Change to Throttle as a decorator to update instead of self.update = Throttle(interval)(self.update)
remove unnecessary code.

* fix  indentations

* Update waze_travel_time.py

* Update waze_travel_time.py

* Update waze_travel_time.py
2019-02-06 11:42:11 +01:00
Oleksii Serdiuk
574823fcbb Flux Led: Add support for defining custom effect (#19072)
Flux Led controllers support defining a custom effect. User may define
up to 16 colors, speed of switching between them, and transition type.

Additional changes:

 - add support for reporting currently running effect on the controller.

 - make effects list sorted, so it's easier to find specific effect in
   the list.
2019-02-06 11:40:57 +01:00
OleksandrBerchenko
a1477fa156 Fix error handling in switch.broadlink module (#20772)
* Fix error handling in switch.broadlink module

* Improve error messages
2019-02-06 11:39:56 +01:00
Paulus Schoutsen
b8cc547fa3 Move components to folders (#20774)
* Move all components into folders

* Move component tests into folders

* Fix init moving

* Move tests

* Lint

* Update coverage

* Fix service descriptions

* Update CODEOWNERS
2019-02-05 19:31:15 -08:00
William Scanlon
d13b2ca6ef Added egg age to the eggminder sensor (#20758)
* Added egg age to the eggminder sensor
2019-02-05 21:26:54 -05:00
Joakim Plate
3bb5caabe2 Reproduce states by letting each component opt in on handling state recovery itself (#18700)
* Move group to it's own setup

* Let each component to handle restore of state

* Move constants for climate into const.py

For now import all into __init__.py to keep backword compat

* Move media plyaer constants to const.py file

For now import all constants into __init__.py to keep
backword compatibility

* Move media player to it's own file

* Move climate to it's own file

* Remove ecobee service from common components

BREAKING CHANGE

* Add tests for climate

* Add test for media_player

* Make sure we clone timestamps of state

* Add tests for groups

* Remove old tests for media player, it's handled by other tests

* Add tests for calls to component functions

* Add docstring for climate const

* Add docstring for media_player const

* Explicitly import constants in climate

* Explicitly import constants in media_player

* Add period to climate const

* Add period to media_player const

* Fix some lint errors in climate

* Fix some lint errors in media_player

* Fix lint warnings on climate tests

* Fix lint warnings on group tests

* Fix lint warnings on media_player tests

* Fix lint warnings on state tests

* Adjust indent for state tests
2019-02-05 17:25:27 -08:00
Fredrik Erlandsson
c76a61ad16 Fix tellduslive responsiveness (#20603)
* use async_call_later for update

* no need to timeout

* fixes

* move init tasks to hass.loop

* version bump of tellduslive

* fixes for @MartinHjelmare

* fixes task cancel

* don't return from new client
2019-02-05 15:20:23 -08:00
Daniel Høyer Iversen
ca17d4395a Merge pull request #20766 from home-assistant/Danielhiversen-patch-1
Fix opensensemap doc url
2019-02-05 19:57:31 +01:00
Paulus Schoutsen
e8dfc326d3 Bumped version to 0.87.0b6 2019-02-05 08:04:49 -08:00
Paulus Schoutsen
3d75e1c299 Keep cloud tokens always valid (#20762)
* Keep auth token always valid

* Remove unused refresh_auth message

* Capture EndpointConnectionError

* Lint
2019-02-05 08:04:41 -08:00
Daniel Høyer Iversen
5b4cc20ce4 opensensemap doc url 2019-02-05 16:15:41 +01:00
Andreas Hartl
a94a24f6f8 Added HomeKit fan speed based on speed_list (#19767)
Speed_list needs to be in ascending order.
2019-02-05 16:11:19 +01:00
Tomas Hellström
208ea6eae4 SMHI component: Bugfix - calc precipitation (#20745)
* Bugfix - calc precipitation

* Feedback: better way to skip first forecast

* Even less messy way

* lint error
2019-02-05 07:43:04 -05:00
Eliseo Martelli
e581d41ded Fix googlehome alarm sensor platform (#20742)
* fixed googlehome alarm sensor platform

* removed info and moved info discovery out of loop

* moved device info up
2019-02-05 07:42:14 -05:00
Jean Gauthier
aa4a3d8b96 Modifying MTUs acquisition (#20654)
**Description:**

I modified the file because it should not disable a MTU based on voltage or power. If one has programmed a certain amount of MTUs in his Gateway, they should be all visible and show 0W or 0V. 
The problem arises when you have a device that shuts off at night (e.g.: pool pump). It pulls 0W for a while, I don't want my interface to show a big yellow error during that time because the sensor no longer exists. Even the 0V is not a good idea because we can use it to indicate the breaker has tripped.

Hopefully it would be accepted :-)
2019-02-05 11:26:28 +01:00
Daniel Høyer Iversen
ef6b0b8e0b Update flake8 to 3.7.5 (#20761)
* Upgrade flake8

* Upgrade flake8

* Add noqa for hound
2019-02-05 11:12:09 +01:00
Paulus Schoutsen
2733919cd8 Keep cloud tokens always valid (#20762)
* Keep auth token always valid

* Remove unused refresh_auth message

* Capture EndpointConnectionError

* Lint
2019-02-05 10:45:03 +01:00
Steven Looman
7f76210549 Upgrade to async_upnp_client==0.14.4 (#20751) 2019-02-04 22:01:51 -08:00
Jason Hu
a8b4467763 Fix the line reference in config error message (#20743)
* Fix the line reference in config error message

* Fix platform config validation

* Fix test

* Handle error in error handling routine
2019-02-04 22:01:50 -08:00
Pascal Vizeli
cfa03a408e Fix cloud webhook body (#20739)
* Bugfix cloud webhooks text response

* address comments

* Fix lint
2019-02-04 22:01:49 -08:00
Paulus Schoutsen
94ab5dca7f Improve cloud error handling (#20729)
* Improve cloud error handling

* Lint
2019-02-04 22:01:48 -08:00
Jason Hu
207a050dba Fix ffmpeg v4 stream issue (#20314)
* Add ffmpeg version

* Add ffmpeg stream content type

* Change ffmpeg camera stream content type

* Change ffmpeg stream content type

* Lint

* Add a none guard

* Fix

* Fix

* Update onvif.py

* Fix version match regrex

* Fix regrex

* Upgrade ha-ffmpeg to 1.11

* Lint

* Get ffmpeg version in ffmpeg component setup
2019-02-04 22:01:47 -08:00
emontnemery
b1faad0a50 Use PLATFORM_SCHEMA_BASE as base schema for additional components. (#20578)
* Disable extra=vol.ALLOW_EXTRA for additional platforms.

* Remove PLATFORM_SCHEMA_2

* Add entity_namespace to base platform schema
2019-02-04 21:52:19 -08:00
Daniel Høyer Iversen
154b401d0a Update version for pymyq to 1.1.0 (#20756)
Update version of pymyq to 1.1.0; this version brings improved functionality, reducing errors for retrieving current state for the MyQ covers.
2019-02-05 06:42:39 +01:00
Andrew Sayre
f84317e325 Update pysmartthings to 0.5.0 (#20759) 2019-02-05 06:42:30 +01:00
Steven Looman
e0d534c3fb Upgrade to async_upnp_client==0.14.4 (#20751) 2019-02-05 00:36:25 +00:00
Erik Hendrix
3880a70965 Update version for pymyq to 1.1.0
Update version of pymyq to 1.1.0; this version brings improved functionality, reducing errors for retrieving current state for the MyQ covers.
2019-02-04 16:48:35 -07:00
jonudewux
cd04661101 Add Transmission component 'scan_interval' option (#20575)
* Transmission component fix 'scan_interval' option

* Fix dict[key] comments

* Fix latest mess
2019-02-04 20:08:38 +00:00
Pascal Vizeli
29b64d56be Fix cloud webhook body (#20739)
* Bugfix cloud webhooks text response

* address comments

* Fix lint
2019-02-04 10:58:38 -08:00
Jason Hu
c812176e94 Fix the line reference in config error message (#20743)
* Fix the line reference in config error message

* Fix platform config validation

* Fix test

* Handle error in error handling routine
2019-02-04 10:58:06 -08:00
emontnemery
79d3f533a9 Add missing abbreviations (#20741) 2019-02-04 10:54:40 -08:00
Jason Hu
7455d950b1 Fix ffmpeg v4 stream issue (#20314)
* Add ffmpeg version

* Add ffmpeg stream content type

* Change ffmpeg camera stream content type

* Change ffmpeg stream content type

* Lint

* Add a none guard

* Fix

* Fix

* Update onvif.py

* Fix version match regrex

* Fix regrex

* Upgrade ha-ffmpeg to 1.11

* Lint

* Get ffmpeg version in ffmpeg component setup
2019-02-04 09:57:22 -08:00
Eliseo Martelli
a40c5bf70e Add google home alarm sensor (#20709)
* added googlehome alarm sensor

* splitted update method

* fix linting

* remove whitespace

* removed whitespace in line

* changed accordingly to the review

* removed redundant method

* Update homeassistant/components/googlehome/__init__.py

Co-Authored-By: eliseomartelli <martely98@gmail.com>
2019-02-04 07:44:23 -08:00
David F. Mulcahey
0cf71d5bcb Add ZHA light tests (#20713)
* add sensor tests

* add light test

* update comments

* fix coveragerc after rebase
2019-02-04 06:51:47 -05:00
David F. Mulcahey
ff9a33ba36 Add ZHA fan tests (#20712)
* add sensor tests

* add fan tests

* hound

* fix coveragerc

* update comments
2019-02-04 06:51:32 -05:00
David F. Mulcahey
b9d108284b Add ZHA binary sensor tests (#20711)
* add sensor tests

* add binary sensor tests

* add comments

* fix coveragerc after rebase
2019-02-04 06:51:13 -05:00
Paulus Schoutsen
07b5b68a51 Improve cloud error handling (#20729)
* Improve cloud error handling

* Lint
2019-02-04 10:14:30 +01:00
Rohan Kapoor
a3c8439ce2 Split out speedtest into a component and a sensor platform (#20527)
* Move sensor.speedtest to the new speedtestdotnet component.

* Split out speedtest.net into a component and sensor platform

* Remove the throttle and add async_track_time_interval

* Add should_poll and cleanup

* Update requirements_all.txt

* Move time interval tracking out of the data class and into the setup method

* Add now=None argument to update
2019-02-04 00:47:04 -08:00
Rohan Kapoor
ec625f02fc Clean up fastdotcom by doing time tracking outside of the data object (#20725) 2019-02-03 22:43:59 -08:00
Paulus Schoutsen
7d334783de Bumped version to 0.87.0b5 2019-02-03 15:27:14 -08:00
David Lie
027fcf269b Revert pyfoscam back to libpyfoscam (#20727)
* Change foscam python library to pyfoscam, which is more up to date and has several critical bug fixes.

* Update requirements_all.txt to match.

* Inserting automatically generated requirements.txt

* Revert changes until pyfoscam captures recent bug fixes. The pyfoscam version pulled by pip is currently broken.

* Updated requirements_all.txt based on changing pyfoscam back to libpyfoscam.
2019-02-03 15:26:19 -08:00
Aaron Bach
e1509bcc0c Fix temperature unit conversion in Ambient PWS (#20723) 2019-02-03 15:26:18 -08:00
Andrew Sayre
9a13aafeea Add SmartThings button support via events (#20707)
* Add event support for buttons

* binary_sensor test clean-up
2019-02-03 15:26:17 -08:00
Paulus Schoutsen
1fe67fb1b0 Updated frontend to 20190203.0 2019-02-03 15:24:46 -08:00
Aaron Bach
a05031c22e Fix temperature unit conversion in Ambient PWS (#20723) 2019-02-03 15:23:30 -08:00
David Lie
ce05af2720 Revert pyfoscam back to libpyfoscam (#20727)
* Change foscam python library to pyfoscam, which is more up to date and has several critical bug fixes.

* Update requirements_all.txt to match.

* Inserting automatically generated requirements.txt

* Revert changes until pyfoscam captures recent bug fixes. The pyfoscam version pulled by pip is currently broken.

* Updated requirements_all.txt based on changing pyfoscam back to libpyfoscam.
2019-02-03 14:47:38 -08:00
Aaron Bach
e90011fd88 Remove SUPPORT_VOLUME_SET from Fire TV component (#20718)
Volume control isn't actually implemented, so it shouldn't show as being supported.
2019-02-03 14:58:00 -07:00
Jeff Irion
5c4dc3a54f Add app_id property to Fire TV component (#20719) 2019-02-03 14:57:17 -07:00
Dane
5506569c3a Change log level for 'loading devices' message (#20721)
The 'Loading [wireless] devices from Mikrotik ([ip address])' message
is incredibly spammy at the info log level, such that in the last 24
hours on my installation, that log message has appeared 6732 times,
versus 70 for every other log message. I've moved this message to the
debug log level as I don't believe it adds anything at the info level,
and makes it harder to diagnose other problems.
2019-02-03 13:06:39 -08:00
David F. Mulcahey
9c11602674 Add ZHA sensor tests (#20710)
* add sensor tests

* update switch test

* add sensor back to coveragerc

* review comments

* added comments
2019-02-03 22:03:35 +01:00
Paulus Schoutsen
5f2d209dec Updated frontend to 20190203.0 2019-02-03 11:32:26 -08:00
Jeff Irion
0e5aa5801a Remove SUPPORT_VOLUME_SET from Fire TV component
Volume control isn't actually implemented, so it shouldn't show as being supported.
2019-02-03 09:27:49 -08:00
David F. Mulcahey
74cdf7c347 Add tests for ZHA switch (#20691)
* start test setup

test cleanup

test deps

update switch test

actually update test deps

cleanup and remove switch from coveragerc

comment

refactor to use fixtures and shared components

lint

* remove availability part that isn't in zha yet

* review comments and cleanup

* review comments

* add switch back unil post reorg merge
2019-02-03 07:03:31 -05:00
Andrew Sayre
38ea43b678 Add SmartThings button support via events (#20707)
* Add event support for buttons

* binary_sensor test clean-up
2019-02-02 22:08:37 -08:00
Paulus Schoutsen
b0200cdbfe Bumped version to 0.87.0b4 2019-02-02 20:28:03 -08:00
Diogo Gomes
c9f64af85a fix test commented in #20678 (#20680) 2019-02-02 17:05:40 -08:00
Paulus Schoutsen
e4d45bf53a Test is broken 2019-02-02 17:04:48 -08:00
Paulus Schoutsen
e984868762 Bumped version to 0.87.0b3 2019-02-02 16:32:26 -08:00
Paulus Schoutsen
e5835eb7c8 Remove fingerprint middleware (#20682)
* Remove fingerprint middleware

* Lint
2019-02-02 16:32:20 -08:00
Paulus Schoutsen
3553d26f6b Updated frontend to 20190202.0 2019-02-02 14:12:23 -08:00
Paulus Schoutsen
c2eec16721 Update translations 2019-02-02 14:12:23 -08:00
Paulus Schoutsen
f73cb0eba5 Bumped version to 0.87.0b2 2019-02-02 14:09:55 -08:00
Andrew Sayre
d3e011ff50 Add SmartThings Binary Sensor platform (#20699)
* Add SmartThings binary_sensor platform

* Fixed comment typo.
2019-02-02 14:09:44 -08:00
emontnemery
4255f2c62f Add entity_namespace to PLATFORM_SCHEMA (#20693)
* Add entity_namespace to base platform schema

* Add test

* Fix
2019-02-02 14:09:43 -08:00
Andrew Sayre
b669e1498a Add SmartThings Fan platform (#20681)
* Add SmartThings fan

* Removed unnecessary update method

* Corrected usage of async_schedule_update_ha_state

* Clean-up/optimization
2019-02-02 14:09:42 -08:00
Rohan Kapoor
c0fd22c285 Fix allow extra in locative webhook schema validation (#20657)
* Allow extra in locative webhook schema validation (fixes #20566)

* Remove extra attribute
2019-02-02 14:09:41 -08:00
Andrew Sayre
785b42ecde Add SmartThings Light platform (#20652)
* Add SmartThings Light platform and tests

* Cleaned a few awk comments

* Updates per review feedback

* Switched to super

* Changes per review feedback
2019-02-02 14:09:40 -08:00
Andrew Sayre
6458abca2e Add SmartThings Binary Sensor platform (#20699)
* Add SmartThings binary_sensor platform

* Fixed comment typo.
2019-02-02 14:06:30 -08:00
Andrew Sayre
acf5b04231 Add SmartThings Fan platform (#20681)
* Add SmartThings fan

* Removed unnecessary update method

* Corrected usage of async_schedule_update_ha_state

* Clean-up/optimization
2019-02-02 14:04:29 -08:00
Paulus Schoutsen
8988ee5b34 Updated frontend to 20190202.0 2019-02-02 14:03:37 -08:00
Paulus Schoutsen
61b2f1bff0 Update translations 2019-02-02 14:03:37 -08:00
emontnemery
bada9b5e0b Add entity_namespace to PLATFORM_SCHEMA (#20693)
* Add entity_namespace to base platform schema

* Add test

* Fix
2019-02-02 18:31:28 +01:00
Peter Nijssen
fee3468b7a add peternijssen as codeowner of spider component (#20695) 2019-02-02 09:23:20 -08:00
Paulus Schoutsen
e2d3c27e85 Embed all platforms into components (#20677)
* Consolidate all components with platforms

* Organize tests

* Fix more tests

* Fix Verisure tests

* one final test fix

* Add change

* Fix coverage
2019-02-02 07:13:16 -08:00
Andrew Sayre
a24da611c5 Add SmartThings Light platform (#20652)
* Add SmartThings Light platform and tests

* Cleaned a few awk comments

* Updates per review feedback

* Switched to super

* Changes per review feedback
2019-02-02 07:12:24 -08:00
Diogo Gomes
ca143f8a35 print() left behind (#20689) 2019-02-02 14:54:46 +01:00
Paulus Schoutsen
47f60e6cf2 Remove fingerprint middleware (#20682)
* Remove fingerprint middleware

* Lint
2019-02-02 11:52:34 +01:00
Diogo Gomes
384a9625c9 fix test commented in #20678 (#20680) 2019-02-01 22:11:50 -08:00
Rohan Kapoor
fcccf133ba Split out fastdotcom into a component and a sensor platform (#20341)
* Split out fastdotcom into a component and a sensor platform

* Update .coveragerc

* Switching to async and using a Throttle

* Add the async_track_time_interval call

* Remove the throttle

* Reorder sensor methods and add should_poll property
2019-02-01 21:50:22 -08:00
Paulus Schoutsen
9e765fb05d Merge pull request #20678 from home-assistant/skip-broken-test
Test is broken
2019-02-01 16:33:02 -08:00
Paulus Schoutsen
c9671f8205 Test is broken 2019-02-01 16:31:53 -08:00
Paulus Schoutsen
ec57db78b5 Consolidate config flow components (#20635)
* Consolidate config flow components

* Fix tests

* Fix tests

* Put unifi back

* Fix reqs

* Update coveragerc
2019-02-01 15:45:44 -08:00
Paulus Schoutsen
224c258876 Bumped version to 0.87.0b1 2019-02-01 14:35:23 -08:00
Oliver Völker
e4d76d5c44 InfluxDB - change connection test method (#20666) 2019-02-01 14:10:39 -08:00
emontnemery
c702e1e3c6 Add PLATFORM_SCHEMA_BASE support to check_config.py (#20663) 2019-02-01 14:10:39 -08:00
zewelor
47660f9312 Fix parsing yeelight custom effects, when not present in config (#20658) 2019-02-01 14:10:38 -08:00
Kevin Fronczak
1a5028f56f Upgrade blinkpy to re-enable motion detection (#20651) 2019-02-01 14:10:38 -08:00
Paulus Schoutsen
ca729b178b Fix geofency requiring a configuration.yaml entry (#20631) 2019-02-01 14:10:37 -08:00
emkay82
557b745053 Fix pjlink issue (#20510)
* Fix issue #16606

Some projectors do not respond to pjlink requests during a short period after the status changes or when its in standby, resulting in pypjlink2 throwing an error. This fix catches these errors. Furthermore, only the status 'on' and 'warm-up' is interpreted as switched on, because 'cooling' is actually a switched off status.

* Update pjlink.py

Improved error handling

* Update pjlink.py

Improved error handling

* Update pjlink.py

Clean up
2019-02-01 14:10:37 -08:00
Paulus Schoutsen
57ef8c271e Fix geofency requiring a configuration.yaml entry (#20631) 2019-02-01 14:09:23 -08:00
Till
495524ecc0 Update miflora.py to have relevant sensor icons (#20650)
* Update miflora.py to have relevant sensor icons

Adds relevant default icons for the sensors of the Mi Flora plant sensor component.

* Clean up code
2019-02-01 14:08:03 -08:00
Paulus Schoutsen
0400e29f7a Updated frontend to 20190201.0 2019-02-01 12:51:17 -08:00
Paulus Schoutsen
da807b20a0 Updated frontend to 20190201.0 2019-02-01 12:50:58 -08:00
Fabian Affolter
198dc2b7a9 Upgrade rxv to 0.6.0 (#20669) 2019-02-01 21:37:00 +01:00
Ville Skyttä
3f997aefc1 Add huawei_lte notify component (#19544)
* Add huawei_lte notify component

* Use CONF_RECIPIENT instead of ATTR_TARGET in config
2019-02-01 18:42:45 +01:00
Oliver Völker
aec8ad2188 InfluxDB - change connection test method (#20666) 2019-02-01 18:35:49 +01:00
Akın Ömeroğlu
f19bbaec08 Update deconz integration text for PWA (#20634)
Text should reflect the GUI it describes
2019-02-01 18:28:30 +01:00
emontnemery
44c2a83105 Add PLATFORM_SCHEMA_BASE support to check_config.py (#20663) 2019-02-01 08:14:02 -08:00
emkay82
47d24759f2 Fix pjlink issue (#20510)
* Fix issue #16606

Some projectors do not respond to pjlink requests during a short period after the status changes or when its in standby, resulting in pypjlink2 throwing an error. This fix catches these errors. Furthermore, only the status 'on' and 'warm-up' is interpreted as switched on, because 'cooling' is actually a switched off status.

* Update pjlink.py

Improved error handling

* Update pjlink.py

Improved error handling

* Update pjlink.py

Clean up
2019-02-01 14:53:40 +01:00
zewelor
7429b9d87e Fix parsing yeelight custom effects, when not present in config (#20658) 2019-02-01 10:59:05 +01:00
Kevin Fronczak
25e1639050 Upgrade blinkpy to re-enable motion detection (#20651) 2019-02-01 00:52:30 -08:00
Rohan Kapoor
3e2dae62c0 Fix allow extra in locative webhook schema validation (#20657)
* Allow extra in locative webhook schema validation (fixes #20566)

* Remove extra attribute
2019-02-01 00:40:27 -08:00
Rohan Kapoor
9e7d7354ed Fix sensor.cpuspeed inside docker container (#20614) (#20656) 2019-02-01 08:58:29 +01:00
Thomas Hervé
5f930debd4 Fix xiaomi default gateway in services (#20623)
When xiaomi_aqara services with one gateway, the default should be set
to the sid of the gateway, not the python object itself, otherwise the
call fails.
2019-02-01 06:59:31 +01:00
Julius Mittenzwei
74794102c8 Support for new velux api, added cover.velux (#18738)
* Support for new velux api, added cover.velux

* More steps on new velux covers.

* correct position handling of velux windows

* Following suggestion from hound.

* bumped version

* added cover stop

* bumped version of pyvlx

* Bumped version to 0.2.8

* removed log_frames parameter
2019-02-01 02:13:47 +01:00
Alok Saboo
c63a37d0ad Revert #20611: code in Abode alarm panel (#20629) 2019-01-31 21:24:52 +01:00
Jason Hu
d7b61f7ff6 Move mqtt_mock to tests/components/mqtt/conftest.py (#20621)
* Move mqtt_mock to tests/components/mqtt/conftest.py

* Move mqtt room presence sensor test to tests/components/mqtt

* Revert "Move mqtt room presence sensor test to tests/components/mqtt"

This reverts commit e08bc143

* Decouple mqtt room presence sensor test and mqtt_mock
2019-01-31 21:22:29 +01:00
Joakim Sørensen
632b2042e4 Split googlehome to a component with device tracker platform (#19971)
* Add component for googlehome

* Add missing name in CODEOWNERS

* Linting issues

* googledevices version bump

* Use NAME from component instead of DOMAIN

* Cleaner handling of accepted devices in for loop

* Fixes one linting issue

* Validate device_types

* Fixes one linting issue

* Fixes linting issue

* Revert 0abb642 and import DOMAIN as GOOGLEHOME_DOMAIN

* Return false if discovery_info is None

* Combine if's in for loop

* Use async_load_platfrom

* Fix line length

* Add error message to user

* Shorter log message

* error -> warning, remove period

* Update .coveragerc

* Move to correct place
2019-01-31 21:16:31 +01:00
Sander Zumbrink
e20c2aa113 Add precision parameter to dsmr sensor (#19873)
* Added precision parameter to dsmr sensor

* Added precision parameter to dsmr sensor, added whitespace after comma

* Added precision parameter to dsmr sensor

* Added precision parameter to dsmr sensor, fixed test

* Changed try except as requested
2019-01-31 16:46:54 +01:00
Julien Brochet
c9971673da Update synology-srm dependency to 0.0.4 (#20625) 2019-01-31 15:26:42 +01:00
Thomas Hervé
511e35e8fd Fix typo in config entries doc (#20619)
This fixes a typo in the docstring of config_entries which was
propagated in the point component.
2019-01-31 10:52:42 +01:00
Paulus Schoutsen
7151c4bcd7 Bumped version to 0.88.0.dev0 2019-01-30 17:38:17 -08:00
Paulus Schoutsen
8db2152230 Bumped version to 0.87.0b0 2019-01-30 17:37:56 -08:00
Paulus Schoutsen
47848e26f9 Merge remote-tracking branch 'origin/master' into dev 2019-01-30 17:37:38 -08:00
Diogo Gomes
c7ff8d4996 fix #20571 (#20589) 2019-01-30 17:33:52 -08:00
Andrew Sayre
69ec7980ad Add SmartThings component and switch platform (#20148)
* Added SmartThings component and switch platform

* Corrected comment typos.

* Embedded switch platform.

* Replaced custom view usage with webhook component.

* Replaced urls with tokens in strings.

* Fixed line length.

* Use generated webhook id instead of static one.

* Reuse core constant instead of defining again.

* Optimizations in anticipation of future platforms.

* Use async_generate_path instead of hard-coded path.

* Fixed line length.

* Updates per review feedback.

* Updates per latest review feedback.
2019-01-30 17:31:59 -08:00
Jasper van der Neut - Stulen
5a0c707a37 Fix duplicate luftdaten entities (#20226)
* Use same data schema for configflow, make sensor_id a positive integer.

* Change sensor_id to int and remove duplicate Luftdaten config entries.

This fixes #18838, and also fixes the root cause
of #19981 and #19622.

* Use pure type for boolean.
2019-01-30 17:12:59 -08:00
Paulus Schoutsen
473bf93973 Updated frontend to 20190130.1 2019-01-30 17:00:36 -08:00
David F. Mulcahey
ed75549123 ZHA component rewrite part 4 - add device module (#20469)
* add device module

* spelling

* review comments

* filter out endpoint id 0 (ZDO)

* review comments

* change name

* remove return
2019-01-30 16:44:22 -05:00
Alok Saboo
3e98aad8a2 Added code to Abode Alarm control panel (#20611) 2019-01-30 13:02:23 -08:00
Gido
542160fc56 Add sensor platform for Rova Garbage Collection (#18868)
* Adding sensor for SolarEdge Monitoring API support

* Adding support for Rova garbage calendar

* Added Rova platform to retrieve garbage pickup times

* Update async to new syntax
Added async_update to sensor class
Added Throttle to Rova update function
Minor code style changes

* Small style fixes

* Removed domain

* Update debug to error messages
Change CONF_MONITORED_VARIABLES to CONF_MONITORED_CONDITIONS
Update async update call to normal update

* Update requirements to rova v0.0.2
Add address check to see if ROVA collects in the given area

* Rename entity names to English
Add json_key to Sensor entities

* Add device_class to the RovaSensor

* Fix pylint and flake8 messages

* Add check for None in case collection date is unknown

* Return device class constant
2019-01-30 21:58:41 +01:00
Paulus Schoutsen
e2cc1564a0 Add lovelace systeam health (#20592) 2019-01-30 12:57:56 -08:00
William Scanlon
2836ff86fe Update to the newest python-wink and fix push updates! (#20594)
* Update to the newest python-wink and make post session call to Wink to keep pubnub working.

* Update __init__.py
2019-01-30 11:35:47 -08:00
Paulus Schoutsen
cb07ea0d60 RFC: Add system health component (#20436)
* Add system health component

* Remove stale comment

* Fix confusing syntax

* Update test_init.py

* Address comments

* Lint

* Move distro check to updater

* Convert to websocket

* Lint

* Make info callback async

* Fix tests

* Fix tests

* Lint

* Catch exceptions
2019-01-30 10:57:53 -08:00
Anders Melchiorsen
91aa874c0c Fix LIFX for single-zone strip extensions (#20604) 2019-01-30 10:47:28 -08:00
Paulus Schoutsen
ca0ee509e7 Fix map icons (#20602) 2019-01-30 09:50:58 -08:00
Paulus Schoutsen
8062f48973 Add remove commmand to entity registry (#20597) 2019-01-30 09:50:32 -08:00
choss
ed299a9137 Add support for FRITZ DECT 100 (temp sensor) (#20308) 2019-01-30 18:44:36 +01:00
starkillerOG
349de19316 Philips Hue: add prompt to update bridge/bulb (#20590)
* Philips Hue: add prompt to update bridge/bulb

* bump aiohue to v1.9.0

* bump aiohue to v1.9.0

* bump aiohue to v1.9.0
2019-01-30 09:42:18 -08:00
Paulus Schoutsen
7c9597f824 Fix area registry config being loaded (#20598)
* Fi area registry config being loaded

* Mark area_id optional
2019-01-30 09:41:55 -08:00
Alok Saboo
a011048a4e Change Unifi timeout (#20606) 2019-01-30 18:40:40 +01:00
Bram Kragten
0ef9882e2e Fix map icons 2019-01-30 17:09:56 +01:00
mindakas
ec4495bd0c Bump pymodbus to 1.5.2 (#20582) 2019-01-30 11:57:14 +00:00
Tommy Jonsson
c5c64e738e html5 notifications add VAPID support (#20415)
* html5 notifications add VAPID support

* fix lint errors

* replace httpapi with websocketapi

* Address my own comment
2019-01-29 14:49:33 -08:00
emontnemery
89fc3b2a1b Disable extra=vol.ALLOW_EXTRA for MQTT platforms. (#20562) 2019-01-29 09:29:02 -08:00
merc1031
48f0e8311b add empy all groups view. Makes Brilliant Lightpad work (#20564) 2019-01-29 09:26:07 -08:00
Jc2k
e0e5b860e4 Homekit Motion Sensor Review feedback (#20568) 2019-01-29 11:25:18 -05:00
kennedyshead
988bcf9399 Fixing the openssl issue (#20570) 2019-01-29 07:42:38 -08:00
MatteGary
e95c50c742 New Transmission component (#19230)
* New Transmission component and interaction

First commit for New Transmission component and interaction

* Fix commit

* Fix commit

* Fix + Switch checkin

Fix according to failed build and request, first checkin for Turtle Mode Switch in Transmission, still have to figure it out why it's not working.

* Bugfixing

* Fix commit

Multiple fix

* Fix

* fix for missing config

* Update on requirements_all.txt

* Fix in requirements_all.txt

* Fix

* Fix for build

* fix

* Fix

* Fix (again)

* Fix

* Fix indentation

* Fix indentation

* Fix Throttle

* Update .coveragerc

* Fix import and coveragerc
2019-01-29 10:27:26 +01:00
Stealth Hacker
6ff4ea1126 Add Recollect Waste (#20121)
* Added Recollect Waste Curbside Collection sensor for tracking next collection date and for which types of waste.

* Added missing schema attributes.

* Adding requirements and coverage entries for Recollect Waste platform.

* Added exception handling, some other fixes and suggestions from code review.

* Fixed reference to incorrect exception type.

* Updated requirements_all.txt with new version of recollect-waste.

* Added true to add_entities. Created constant for default time interval. Used different pylint exclusion comment.

* Using HA's CONF_SCAN_INTERVAL now. Unique_id is now set in @property.

* Changed parameter of timedelta from seconds to days.

* Added test run of recollect client during setup_platform. Using built in SCAN_INTERVAL now.

* Return nothing in setup_platform if there is an exception.
2019-01-29 09:38:01 +01:00
Richard Mitchell
a7c74151bc Treat each player as a 'device' for non-client devices. (#20074) 2019-01-29 09:15:42 +01:00
Julien Brochet
6859d5216e Add Synology SRM device tracker (#20320) 2019-01-29 09:12:10 +01:00
Paulus Schoutsen
73a0c664b8 Allow usernames to be case-insensitive (#20558)
* Allow usernames to be case-insensitive

* Fix typing

* FLAKE*
2019-01-29 08:28:52 +01:00
Diogo Gomes
b0ff51b0ef Add an Integration sensor (#19703)
* initial version

* Tested

* set state added

* lint

* lint

* remove artifacts

* Use Decimal instead of float

* simplify

* travis lint fix

* addres comments by @ottowinter

* remove job

* better sanity check

* lower error -> warning

* hound

* fix state validation

* refactor energy -> integration

* address @MartinHjelmare comments

* new style string format

* remove async_set_state

* patching the source function
2019-01-29 08:25:36 +01:00
Jc2k
e22802a4d4 Add support for HomeKit motion sensor devices (#20555) 2019-01-28 20:30:56 -08:00
Paulus Schoutsen
aa29eeba04 Merge pull request #20559 from home-assistant/rc
0.86.4
2019-01-28 20:28:08 -08:00
Rohan Kapoor
cc74035c3b Move CONF_UPDATE_INTERVAL to homeassistant.const (#20526) 2019-01-28 20:26:31 -08:00
Rohan Kapoor
fe47253f68 Fix linting error (#20488) 2019-01-28 20:26:02 -08:00
emontnemery
3ee3acd550 Update device registry of MQTT light (#20441)
* Update device registry of MQTT light

* Move config_entry to constructor
2019-01-28 19:45:34 -08:00
Paulus Schoutsen
234c759b45 Bumped version to 0.86.4 2019-01-28 17:52:42 -08:00
Fredrik Erlandsson
ba4d4bcd29 fix #20387 devices without model/protocol (#20530) 2019-01-28 17:52:36 -08:00
starkillerOG
d7bbdb033d Add check to validate gamut (#20518)
* color.util - Add check to validate gamut

* fix indents

* fix typo

* Add check to validate gamut

* Add tests for gamut checker

* fix test

* fix pylint issues

* fix hue light gamut tests

* add check to validate gamut

* move None check

* Move None check

* Include prompt to update bridge/bulb on error

* fix wrong commit

* fix error message

* Update light.py
2019-01-28 17:52:35 -08:00
kennedyshead
63fd5f2d31 Bumps aioasuswrt (#20432) 2019-01-28 17:52:35 -08:00
starkillerOG
f353d51ab1 Add check to validate gamut (#20518)
* color.util - Add check to validate gamut

* fix indents

* fix typo

* Add check to validate gamut

* Add tests for gamut checker

* fix test

* fix pylint issues

* fix hue light gamut tests

* add check to validate gamut

* move None check

* Move None check

* Include prompt to update bridge/bulb on error

* fix wrong commit

* fix error message

* Update light.py
2019-01-28 17:52:00 -08:00
Per Osbäck
3f484228cb Add missing switch for motion_detect (#20540) 2019-01-28 16:48:55 -08:00
Fredrik Erlandsson
717a0c2b2d fix #20387 devices without model/protocol (#20530) 2019-01-28 16:46:37 -08:00
David F. Mulcahey
34090bd021 ZHA component rewrite part 3 - update helpers (#20463)
* update helpers

* address comments

* remove ieee

* cluster id as hex too
2019-01-28 16:40:00 -08:00
emontnemery
bb1583c453 Add discovery update support to MQTT camera (#20529) 2019-01-28 16:21:38 -08:00
emontnemery
d7ba2aad1d Add COMPONENT_SCHEMA and use it in alarm_control_panel (#20224)
* Add COMPONENT_SCHEMA and use in alarm and mqtt

* Revert MQTT changes

* Lint

* Small tweak

* Add tests

* Rename COMPONENT_SCHEMA to PLATFORM_SCHEMA_BASE

* Fix tests

* Improve tests
2019-01-28 16:14:55 -08:00
emontnemery
bb4ca1f525 Cleanup if discovered mqtt vacuum can't be added (#20549) 2019-01-28 15:56:47 -08:00
Robert Svensson
bd335e1ac1 Area registry (#20435)
* First draft of area registry

* Refactor based on input

* Add tests for areas
Add tests for updating device

* Updating a device shouldn't require area

* Fix Martins comment

* Require admin

* Save after deleting

* Rename read to list_areas
Fix device entry_dict
Remove area id from device when deleting area

* Fix tests
2019-01-28 15:52:42 -08:00
Aaron Bach
2c7060896b Make Ambient PWS async and cloud-push (#20332)
* Moving existing sensor file

* Initial functionality in place

* Added test for config flow

* Updated coverage and CODEOWNERS

* Linting

* Linting

* Member comments

* Hound

* Moving socket disconnect on HASS stop

* Member comments

* Removed unnecessary dispatcher call

* Config entry fix

* Added support in config flow for good accounts with no devices

* Hound

* Updated comment

* Member comments

* Stale docstrings

* Stale docstring
2019-01-28 15:35:39 -08:00
Jc2k
abeb875c61 Homekit controller BLE groundwork (part 2) (#20548)
* Only fetch values of characteristics we are tracking.

* Use callbacks on subclasses to update individual values

* Update alarm_control_panel to use update callbacks

* Update climate to use update callbacks

* Update cover to use update callbacks

* Update light to use update callbacks

* Update lock to use update callbacks

* Update switch to use update callbacks

* Remove compatibility code as all entities migrated

* pylint by name rather than code
2019-01-28 21:27:26 +01:00
Jc2k
41c1997b88 Homekit controller BLE groundwork (#20538)
* Define the characteristics to poll (or subscribe to) up front

* Configure characteristics immediately instead of during first poll

* Do as much cover configuration upfront as possible

* Remove test workaround as no longer needed

* Remove switch code that is already handled by HomeKitEntity

* Remove lock code already handled by HomeKitEntity

* Remove light code already handled by HomeKitEntity

* Remove alarm code already handled by HomeKitEntity

* Remove climate code already handled by HomeKitEntity
2019-01-28 17:21:20 +01:00
Jc2k
995758b8ac Add more HomeKit controller tests (#20515)
* homekit_controller tests: automatically find entity ids in tests

Some entities use dynamic ids because of the nature of the test fakes it is
hard to predict the name of the entity that will be created. This inspects the
EntityComponent of the domain to find the freshly created entity.

* homekit_controller: Tests can now define their own Service models.

All existing tests use models as defined upstream. But upstream only defines a
few service models. This adds a generic model helper for creating test
service/characteristic models.

* homekit_controller: Add cover tests

* homekit_controller: Add lock tests

* homekit_controller: Add alarm_control_panel tests

* homekit_controller: Update light tests for color_temp.

* Revert "homekit_controller tests: automatically find entity ids in tests"

This reverts commit 506caa4c3e.

* homekit_controller: Mock entity name so entity_id is consistent.

Also remove spurious subclass overrides that are identical to parent class.

* homekit_controler: Make tests less awkward as allowed top level imports
2019-01-28 13:20:32 +01:00
Christian Biamont
f33e432cab Reset Brottsplatskartan incident types every day (#20117)
* Reset the incident types count every day

* Remove functionality that was never implemented

We don't need to keep track of previous incidents because it's not used
anywhere.

* Create empty dictionary with a pair of braces: {}
2019-01-28 12:30:15 +01:00
David Lie
29984efd8c Use more up-to-date version of pyfoscam library (#20419)
* Change foscam python library to pyfoscam, which is more up to date and has several critical bug fixes.

* Update requirements_all.txt to match.

* Inserting automatically generated requirements.txt
2019-01-28 08:07:39 +01:00
Rohan Kapoor
d179686edf Load/unload gpslogger entities correctly between component and platform (#20448)
* Embed device_tracker in gpslogger

* Load/unload gpslogger entities correctly between component and platform

* Await the coroutine directly
2019-01-27 15:37:19 -08:00
Rohan Kapoor
0c87fb421e Load/unload locative entities correctly between component and platform (#20498)
* Embed device_tracker in locative

* Load/unload locative entities correctly between component and platform

* Await the coroutine directly

* Await the correct coroutine
2019-01-27 23:43:16 +01:00
Rohan Kapoor
f575d1d3a6 Load/unload geofency entities correctly between component and platform (#20497)
* Load/unload geofency entities correctly between component and platform

* Lint

* Await the coroutine directly
2019-01-27 13:18:20 -08:00
Eliseo Martelli
3d4f2926e9 Add Iliad Italy (Mobile Telephony Provider) Sensor (#19645)
* working state

* Attrs

* > requirements generated

* linting

* fixes

* coveragerc

* ordered imports and fixed auth

* Added Throttle

* moved throttle to decorator

* remove scan interval

* lower throttle

* moved to scan interval

* Add attribution
2019-01-27 21:44:19 +01:00
Heine Furubotten
7412d0f97c Add nilu air_quality platform (#19674)
* Add nilu air_pollutants platform

* Code Review - validation, DRYs, rm state override, new attr
- Repeated code moved to own method.
- Removed override of state property.
- New attr for showing nilu pollution recommendations.
- More validation of stations input.
- Minor fixes and typos.

* Removed unused prop

* Check for none result from client before entity add

* Moved platform to air_quality component

* Updated outdated docstrings

* Minor changes
2019-01-27 21:32:23 +01:00
Daniel Høyer Iversen
f91ff76b95 Upgrade mill library (#20514) 2019-01-27 19:20:43 +01:00
emontnemery
648adcc708 Small cleanup of MQTT platforms (#20503)
* Move CONF_UNIQUE_ID to init

* Sort imports

* Update ordering
2019-01-27 18:54:52 +01:00
emontnemery
8804f55fcc Update device registry of MQTT Vacuum (#20500) 2019-01-27 17:43:16 +01:00
emontnemery
1f93984fd5 Update device registry of MQTT Lock (#20501) 2019-01-27 17:42:45 +01:00
Daniel Høyer Iversen
ae84a91ea8 Upgrade tibber library (#20504)
* Upgrade tibber library

* Upgrade tibber library
2019-01-27 17:39:56 +01:00
Steven Looman
2aab646be2 Upgrade to async-upnp-client==0.14.3 (#20502) 2019-01-27 13:52:51 +01:00
Jc2k
10e3698fd7 Add homekit_controller tests (#20457)
* Add a test for a homekit_controller switch

* Add a test for a homekit_controller lightbulb

* Add a test for homekit_controller thermostat

* Changes from review

* Patch utcnow to known time in HK tests

* Neater fixture use per review
2019-01-27 12:34:49 +01:00
Rohan Kapoor
7368c623d4 Split out dovado to a component and sensor platform (#20339)
* Split out dovado to a component and sensor platform

* Lint

* Address code review comments (#20339)

* Switch to using a notify platform for dovado SMS (#20339)

* Optimizing imports

* Remove return on `setup_platform`.

* Clean up unneeded constants
2019-01-27 10:36:10 +01:00
Rohan Kapoor
d82e5ecbb0 Upgrade zm-py to 0.3.1 (#20489) 2019-01-27 10:28:20 +01:00
Aaron Bach
239c60c09f Use HASS latitude/longitude as defaults for Lyft (#20491) 2019-01-26 23:21:51 -07:00
Rohan Kapoor
38c33bd01e Fix linting error (#20488) 2019-01-26 17:11:09 -08:00
Paulus Schoutsen
86f5f0226c Bumped version to 0.87.0.dev0 2019-01-26 14:15:36 -08:00
Paulus Schoutsen
c78d3b6154 Merge pull request #20485 from home-assistant/rc
0.86.3
2019-01-26 14:14:06 -08:00
Paulus Schoutsen
dcfe7b2280 Bumped version to 0.86.3 2019-01-26 14:11:44 -08:00
Shantanu Tushar
a368db9ad4 Include exception details in the error log (#20461)
* Include exception details in the error log

I see this error quite often in my HA logs and this will be helpful for anyone who is attempting to debug this.

* Minor change

* Remove line break
2019-01-26 14:11:16 -08:00
Paulus Schoutsen
6330bb1004 Warn for old slugs/entity ids (#20478)
* Warn for old slugs/entity ids

* add comments

* Lint

* LInt

* Lint

* Lint
2019-01-26 14:10:05 -08:00
starkillerOG
672a896124 Philips Hue, include debug message for color gamut (#20455) 2019-01-26 14:10:04 -08:00
Paulus Schoutsen
87316c4e83 Warn for old slugs/entity ids (#20478)
* Warn for old slugs/entity ids

* add comments

* Lint

* LInt

* Lint

* Lint
2019-01-26 14:09:41 -08:00
Fabian Affolter
38b1ce3fe0 Upgrade psutil to 5.5.0 (#20462) 2019-01-26 22:11:36 +01:00
Fabian Affolter
9920699bb8 Upgrade sqlalchemy to 1.2.16 (#20474) 2019-01-26 22:11:00 +01:00
starkillerOG
b9bf6963fd Philips Hue, include debug message for color gamut (#20455) 2019-01-26 12:50:34 -08:00
emontnemery
60dc337f3f Update device registry of MQTT cover (#20443)
* Update device registry of MQTT cover

* Move config_entry to constructor
2019-01-26 10:52:41 -08:00
emontnemery
85c72fbca6 Update device registry of MQTT alarm (#20439) 2019-01-26 10:48:35 -08:00
emontnemery
85ccd71d39 Update device registry of MQTT sensor (#20440) 2019-01-26 10:48:18 -08:00
Paulus Schoutsen
09cbcb74bc Merge pull request #20442 from emontnemery/mqtt_binary_sensor_update_device_info
Update device registry of MQTT binary_sensor
2019-01-26 10:47:57 -08:00
Paulus Schoutsen
0e453fe492 Update device registry of MQTT climate (#20444) 2019-01-26 10:47:29 -08:00
emontnemery
1d16bb2cd4 Update device registry of MQTT fan (#20445) 2019-01-26 10:46:41 -08:00
David F. Mulcahey
05d41bc0ee introduce gateway (#20460) 2019-01-26 13:28:13 -05:00
Jef D
f3285f96bb Add Co2signal sensor (#19204)
* Initial commit for the co2signal sensor

* Clean code

* Run script gen_requirements_all.py

* remove unintended character

* Remove redundancy

* Remove unused imports

* Code style

* Code style fixes

* Code style

* Fix comments PR

Comments by @fabaff
* Remove redundant comments and variables
* Follow the latest home-assistant guidelines

* Bump CO2Signal version

* Round API result

* Improve default latitude/longitude handling

* Improve friendly name

* Improve config handling

* Make lines shorter

* Style

* Convert default to variable

None does not pass cv.string

* Message if not inclusive

* Shorten line

* Update requirements

* Update co2signal.py

Group imports;  remove empty lines; refactor use of location_type; remove logging messages; remove unused functions; add global variables

* Update co2signal.py

Import platform schema from sensor

* Small fix

* Update co2signal.py

Remove last mentions of location_type

* Review changes

Add attribution
Formatting

* Missing whitespace

* Update co2signal.py

Fix pylint

* Update co2signal.py

Change blank lines

* Update co2signal.py

Initialise _data
2019-01-26 19:02:46 +01:00
Diogo Gomes
1d5ffe9ad5 Utility meter (#19718)
* initial commit

* test service calls

* lint

* float -> Decimal

* extra tests

* lint

* lint

* lint

* lint

* fix self reset

* clean

* add services

* improve service example description

* add optional paused initialization

* fix

* travis fix

* fix YEARLY

* add tests for previous bug

* address comments and suggestions from @ottowinter

* lint

* remove debug

* add discoverability capabilities

* no need for _hass

* Update homeassistant/components/sensor/utility_meter.py

Co-Authored-By: dgomes <diogogomes@gmail.com>

* Update homeassistant/components/sensor/utility_meter.py

Co-Authored-By: dgomes <diogogomes@gmail.com>

* correct comment

* improve error handling

* address @MartinHjelmare comments

* address @MartinHjelmare comments

* one patch is enought

* follow @ballob suggestion in https://github.com/home-assistant/architecture/issues/131

* fix tests

* review fixes

* major refactor

* lint

* lint

* address comments by @MartinHjelmare

* rename variable
2019-01-26 16:33:11 +01:00
Jonas Pedersen
ed6e349515 Correct minor comments from PR#20138. (#20454) 2019-01-26 15:55:25 +01:00
Fabian Affolter
a85e018bc4 Upgrade astral to 1.8 (#20459) 2019-01-26 15:54:35 +01:00
David F. Mulcahey
a0b93c2add ZHA component rewrite part 1 (#20456)
* rearrange files

* add init to module

* update imports

* update coveragerc

* put blank line back... git raw view be damned
2019-01-26 08:54:49 -05:00
Anders Melchiorsen
e593383b4d Error handling for recorder purge (#20424) 2019-01-26 11:02:16 +01:00
Austin Drummond
b3c3721a79 Add alarm type workaround zwave lock Yale YRD240 (#20438) 2019-01-26 11:01:04 +01:00
Adam Belebczuk
310c073c64 WeMo - Fix device discovery issues (#20446) 2019-01-26 11:00:06 +01:00
Louis Matthijssen
d39784906b Fix HTTP login attempts check triggering too late (#20431) 2019-01-26 03:13:44 +01:00
emontnemery
6d2e7db123 Update device registry of MQTT climate 2019-01-26 09:04:02 +08:00
emontnemery
d8e43978b7 Update device registry of MQTT binary_sensor 2019-01-26 08:58:08 +08:00
kennedyshead
76c0295403 Bumps aioasuswrt (#20432) 2019-01-25 23:27:44 +01:00
coreGreenberet
2bc7444427 Fix homematicip cloud alarm_arm_home (#20321) 2019-01-25 19:45:42 +01:00
coreGreenberet
4518e6bdf7 Fix minor homematicip cloud binary sensor issues (#20398)
* fix for smoke detection

* a tilted window is now considered as "open"/on

* changed comparison to enum

* line length

* insert brackets for line length and comparison

* indentation should now be ok for hound
changed api version to 0.10.4

* indentation should now be ok for hound
changed api version to 0.10.4

* updating requirement files

* satisfy lint
2019-01-25 19:00:37 +01:00
zewelor
d6c12e47f4 Fix cast platform album name property (#20411) 2019-01-25 18:49:50 +01:00
Jc2k
cea2bf94bd Move homekit_controller entity types under homekit_controller platform (#20376)
* Move homekit_controller entity types under homekit_controller platform

* Update coveragerc as homekit_controller moved
2019-01-25 07:43:01 -08:00
jonudewux
1fcaaf93ad Upgrade youtube_dl to 2019.01.24 (#20408) 2019-01-25 11:57:13 +01:00
Andrey Kupreychik
d4c7515681 Add time_throttle filter to sensor.filter (#20334)
* Added time_throttle filter

* Added time_throttle filter test

* Updated comments for time_throttle filter
2019-01-25 10:07:45 +00:00
Anders Melchiorsen
c94834d8f6 Add LIFX listen port advanced configuration (#20299) 2019-01-24 22:50:26 -08:00
emontnemery
ec5da05804 Add character encoding to MQTT automation. (#20292) 2019-01-24 22:43:56 -08:00
emontnemery
d84cd01cbf Cleanup if discovered mqtt light can't be added (#19740)
* Cleanup if discovered mqtt light can't be added

* No bare except

* Clear ALREADY_DISCOVERED list with helper

* Use constant instead of string literal
2019-01-24 22:40:52 -08:00
emontnemery
a1da6a677a Update device registry of MQTT Switch (#19540)
* MQTT Switch: Update device registry

* Move config_entry to constructor

* Remove duplicated code

* Fix merge error
2019-01-24 22:39:16 -08:00
Jasper van der Neut - Stulen
55943cfac0 Return windspeed and windgust in km/h instead of m/s. (#20340)
Darksky dev docs state (https://darksky/dev/docs):
`ca: same as si, except that windSpeed and windGust are in kilometers per
hour`
2019-01-24 22:36:25 -08:00
Paulus Schoutsen
567e3e6e50 Merge pull request #20402 from home-assistant/rc
0.86.2
2019-01-24 21:01:22 -08:00
Paulus Schoutsen
259915eee9 Bumped version to 0.86.2 2019-01-24 19:34:10 -08:00
Paulus Schoutsen
d7859b5900 history allowed to load states with invalid entity IDs (#20399) 2019-01-24 19:34:02 -08:00
starkillerOG
ebcae2503c Philips Hue - Remove unnessesary warning (#20394)
for white hue bulbs and bulbs from other brands like Ikea and Innr, this warning will be issued while this is not really a problem.
So just remove the warning.
2019-01-24 19:34:01 -08:00
Daniel Perna
400aaf8a3a Update pyhomematic to 0.1.55 (#20397) 2019-01-24 17:53:31 -08:00
Fabian Affolter
046683ee3f Upgrade numpy to 1.16.0 (#20396) 2019-01-24 17:53:17 -08:00
Paulus Schoutsen
c7f5beb794 history allowed to load states with invalid entity IDs (#20399) 2019-01-24 17:53:01 -08:00
starkillerOG
c508ba166c Philips Hue - Remove unnessesary warning (#20394)
for white hue bulbs and bulbs from other brands like Ikea and Innr, this warning will be issued while this is not really a problem.
So just remove the warning.
2019-01-24 23:46:55 +01:00
mindigmarton
68bd5f5df8 Upgrade emulated_roku to 0.1.8 to fix invalid encodings, fixes #20388 (#20390) 2019-01-24 22:51:15 +01:00
Anders Melchiorsen
70c5807976 Improve deprecation warnings (#20391) 2019-01-24 13:37:30 -08:00
Daniel Høyer Iversen
3b1534c126 Remove logging from tibber (#20382)
* Remove logging from tibber

* keep guard
2019-01-24 21:56:44 +01:00
zewelor
2559bc4226 Add yeelight start_flow service and ability to declare custom effects (#20107) 2019-01-24 17:41:07 +01:00
Fréderic Kinnaer
0be922dc9c SongPal: do not crash if active_source is not (yet) available - fixes #20343 (#20344)
* SongPal: error handling if active_source can't be detected

* sonpal: Add comment to the use of getattr() for property source

* songpal: make comment single-line
2019-01-24 12:55:39 +01:00
Fabian Affolter
7038dd484a Upgrade TwitterAPI to 2.5.9 (#20372) 2019-01-24 09:37:25 +01:00
Daniel Høyer Iversen
1bd31e3459 Change STATE_UNKOWN to None (#20337)
* Change STATE_UNKOWN to None

* Change STATE_UNKOWN to None

* tests

* tests

* tests

* tests

* tests

* style

* fix comments

* fix comments

* update fan test
2019-01-24 08:20:20 +01:00
Paulus Schoutsen
77ee2f1f3e Merge pull request #20369 from home-assistant/rc
0.86.1
2019-01-23 21:16:46 -08:00
Paulus Schoutsen
761385dea1 Bumped version to 0.86.1 2019-01-23 21:14:52 -08:00
Paulus Schoutsen
2b2809a4c6 Calling save before load would crash Lovelace storage (#20368) 2019-01-23 21:14:47 -08:00
Paulus Schoutsen
3c32bfda95 Fix restore state crashing invalid entity ID (#20367) 2019-01-23 21:14:47 -08:00
Diogo Gomes
65d9460e09 Fix error when API doesn't return a forecast. (#20365)
* add guard

* wrong logic
2019-01-23 21:14:46 -08:00
Eliseo Martelli
2b542b7789 [FIX] Time reporting incorrect in sensor.gtt (#20362)
* quick fix

* remove print statement

* fixes

* remove lambda

* added pylint disable

* should be fine now
2019-01-23 21:14:46 -08:00
Kevin Fronczak
bbdb7a6f4c Hotfix for blink initialization failure. Fixes #20335 (#20351) 2019-01-23 21:14:45 -08:00
Diogo Gomes
074fcd96ed Fix error when API doesn't return a forecast. (#20365)
* add guard

* wrong logic
2019-01-23 21:14:21 -08:00
Paulus Schoutsen
5580bec1d3 Calling save before load would crash Lovelace storage (#20368) 2019-01-23 21:13:55 -08:00
Paulus Schoutsen
af3afb673a Fix restore state crashing invalid entity ID (#20367) 2019-01-23 21:12:38 -08:00
Daniel Høyer Iversen
697c331903 Clean up concord232 (#20353)
* Clean up concord232

* concord cleanup

* clean up

* fix import
2019-01-23 17:05:56 -08:00
Eliseo Martelli
971d933140 [FIX] Time reporting incorrect in sensor.gtt (#20362)
* quick fix

* remove print statement

* fixes

* remove lambda

* added pylint disable

* should be fine now
2019-01-23 17:05:16 -08:00
Paulus Schoutsen
0300ef2040 Fix entity registry comments (#20357) 2019-01-23 16:33:21 -08:00
Paulus Schoutsen
e049b35413 Merge pull request #20354 from home-assistant/rc
0.86.0
2019-01-23 12:49:23 -08:00
Jc2k
a396ee2cb5 Bump homekit==0.12.2 + improve controller reliability (#20325)
Sessions were timing out and requiring a HA restart in order to restore
functionality. Network disconnects are now handled and sessions will be
automatically recovered after they fail.
2019-01-23 20:44:21 +01:00
Kevin Fronczak
7ca7951526 Hotfix for blink initialization failure. Fixes #20335 (#20351) 2019-01-23 20:37:21 +01:00
Daniel Høyer Iversen
5bf3b2dd9f clean up of islamic_prayer_times (#20352)
update_sensors was not awaited in async_track_point_in_time()
2019-01-23 20:17:45 +01:00
Paulus Schoutsen
cdcc535ae1 Version bump to 0.86.0 2019-01-23 10:48:55 -08:00
Paulus Schoutsen
4662ab215c Fix invalid entity ID in entity registry (#20328) 2019-01-23 10:48:15 -08:00
rolfberkenbosch
80aa2075c6 Update locationsharinglib to version 3.0.11 (#20322)
* Update google_maps.py

There are known bug in locationsharinglib version 3.0.9, the developer has fixed this in 3.0.11. (https://github.com/costastf/locationsharinglib/issues/42)

* Update requirements_all.txt
2019-01-23 10:48:14 -08:00
Sebastian Muszynski
4b7d944a74 Fix xiaomi speed attribute name clash (#20312) 2019-01-23 10:48:14 -08:00
Richard Mitchell
b7218e6a1d Should require the 'GATTOOL' setup extras which includes pexpect. (#20263)
* Should require the 'GATTOOL' setup extras which includes pexpect.

* Also fix skybeacon's requirement and requirements_all.
2019-01-23 10:48:13 -08:00
Jonas Pedersen
c6cee1ccd3 Add Danfoss Air HRV support (#20138)
* Add support for Danfoss Air HRV systems.

* Correct lint errors after initial commit of Danfoss Air HRV support.

* A couple of lint fixes for danfoss_air.

* Refactor to comply with HA standards.

* Style fix.

* Use wildcard for danfoss_air in .coveragerc.

* Remove config example from header documentation.
Correct import name for platforms.
2019-01-23 11:58:45 -05:00
Corey Edwards
16a4180fab Fix mpd logging format string field (#20333)
* Fix format string field

* Remove str.format and let _LOGGER handle formatting

* Remove trailing period from log message
2019-01-23 11:50:04 -05:00
shbatm
e8f0e534f9 Update Requirement for PyISY Package in isy994 Component to v1.1.1 (#20349) 2019-01-23 11:48:35 -05:00
Fabien Piuzzi
07f1e2ce75 Add Octoprint custom path (#20302)
* Added custom path config option to octoprint component

* Added some debug logging

* removed debug logging for base url

* Fixed single/double quotes style
2019-01-23 12:50:17 +01:00
Malte Franken
eaa9c4d437 Remove creation of geolocation default group (#20338) 2019-01-23 10:04:41 +01:00
Frank
db277ad023 Add data/data_template/title to alert component (#17616)
* Add data/data_template/title to alert component

* Fix line length

* Fix tests

* Fix lint

* fix line length

* Fix tests, make title templatable

* Fix test

* Fix test

* Optimize data, make title templated

* Fix line length

* Add title template

* typo

* Fix tests
2019-01-23 08:47:37 +01:00
Sebastian Muszynski
3484e506e8 Fix xiaomi speed attribute name clash (#20312) 2019-01-23 05:04:13 +01:00
Paulus Schoutsen
e964750ac1 Fix invalid entity ID in entity registry (#20328) 2019-01-22 14:07:17 -08:00
Paulus Schoutsen
c87c5797db Updated frontend to 20190121.1 2019-01-22 12:58:53 -08:00
Richard Mitchell
5b25188474 Should require the 'GATTOOL' setup extras which includes pexpect. (#20263)
* Should require the 'GATTOOL' setup extras which includes pexpect.

* Also fix skybeacon's requirement and requirements_all.
2019-01-22 18:50:21 +01:00
Fabian Affolter
91ef78adc5 Upgrade youtube_dl to 2019.01.17 (#20318) 2019-01-22 18:45:16 +01:00
rolfberkenbosch
e2a4fdeadf Update locationsharinglib to version 3.0.11 (#20322)
* Update google_maps.py

There are known bug in locationsharinglib version 3.0.9, the developer has fixed this in 3.0.11. (https://github.com/costastf/locationsharinglib/issues/42)

* Update requirements_all.txt
2019-01-22 08:24:40 -08:00
Mateusz Korniak
9b7780edf0 Ecoal (esterownik.pl) static fuel boiler and pump controller (#18480) - matkor
* Starting work on ecoal boiler controller iface.

* Sending some values/states to controller.

* Basic status parsing, and simple settings.

* Platform configuration.

* Temp sensors seems be working.

* Switch from separate h/m/s to datetime.

* Vocabulary updates.

* secondary_central_heating_pump -> central_heating_pump2

* Pumps as switches.

* Optional enabling pumps via config.

* requests==2.20.1 added to REQUIREMENTS.

* Optional enabling temp sensors from configuration yaml.

* autopep8, black, pylint.

* flake8.

* pydocstyle

* All style checkers again.

* requests==2.20.1 required by  homeassistant.components.sensor.ecoal_boiler.

* Verify / set switches in update().
Code cleanup.

* script/lint + travis issues.

* Cleanup, imperative mood.

* pylint, travis.

* Updated .coveragerc.

* Using configuration consts from homeassistant.const

* typo.

* Replace global ECOAL_CONTR with hass.data[DATA_ECOAL_BOILER].
Remove requests from REQUIREMENTS.

* Killed .update()/reread_update() in Entities __init__()s.
Removed debug/comments.

* Removed debug/comments.

* script/lint fixes.

* script/gen_requirements_all.py run.

* Travis fixes.

* Configuration now validated.

* Split controller code to separate package.

* Replace in module docs with link to https://home-assistant.io .

* Correct component module path in .coveragerc.
More vals from  const.py.
Use dict[key] for required config keys.
Check if credentials are correct during component setup.
Renamed add_devices to add_entities.

* Sensor/switch depends on ecoal_boiler component.
EcoalSwitch inherits from SwitchDevice.
Killed same as default should_poll().
Remove not neede schedule_update_ha_state() calls from turn_on/off.

* lint fixes.

* Move sensors/switches configuration to component setup.

* Lint fixes.

* Invalidating ecoal iface cache instead of force read in turn_on/off().

* Fail component setup before adding any platform entities.
Kill NOTE.

* Disallow setting entity names from config file, use code defined default names.

* Rework configuration file to use monitored_conditions like in rainmachine component.

* Killed pylint exception.
Log error when connection to controller fails.

* A few fixes.

* Linted.
2019-01-22 08:14:27 -05:00
Jason Hu
f84c0ee473 Upgrade python-nest to 4.1.0 (#20313) 2019-01-22 13:23:33 +01:00
Mattias Welponer
89ba374d51 HomematicIP add cover FROLL and BROLL devices (#19794)
* Add cover FROLL and BROLL devices

* Fix import

* Fix async calls

* Update cover functions and async fixes

* Update test

* Cleanup code

* Update header

* Merge imports

* Update

* Remove init

* Update coveragerc file

* Update coveragerc
2019-01-22 09:22:45 +01:00
krygal
a8ef7a2774 Add device tracker support for EE Brightbox 2 router (#19611)
* Added device tracker support for EE Brightbox 2

* removed timeago dependency

* get scanner checks and improved tests

* fixed lint issues

* removed redundant timeago from test requirements

* fixed variable naming in test

* removed unecessary blank line
2019-01-22 09:16:35 +01:00
Johann Kellerman
5a30b0507d Add git to the development Dockerfile (#20276)
* git_on_dev

* feedback
2019-01-22 08:21:43 +01:00
Paulus Schoutsen
6d0ac30687 Bumped version to 0.86.0b3 2019-01-21 21:23:00 -08:00
Fabien Piuzzi
d419471372 Fix typo C02 to CO2 (#20306)
* Fix type C02 to CO2 and added VOC to air quality platform

* singularized volatile_organic_compound

* Remove VOC prop

* Update __init__.py

* Update __init__.py
2019-01-21 21:22:38 -08:00
Fabien Piuzzi
0ceace96e7 Bugfix: prevent error notification when octoprint server auto detected but no configuration present. (#20303) 2019-01-21 21:22:20 -08:00
Fabien Piuzzi
3e056a24dd Bugfix: prevent error notification when octoprint server auto detected but no configuration present. (#20303) 2019-01-21 21:21:59 -08:00
Johann Kellerman
ec7f2657cd Config Validator: schema_with_slug_keys (#20298)
* schema_with_slug_keys

* Update config_validation.py

* Update config_validation.py
2019-01-21 21:21:00 -08:00
Paulus Schoutsen
5945929e7e Updated frontend to 20190121.1 2019-01-21 21:20:23 -08:00
Johann Kellerman
6511e11ec9 Config Validator: schema_with_slug_keys (#20298)
* schema_with_slug_keys

* Update config_validation.py

* Update config_validation.py
2019-01-21 16:36:04 -08:00
Ted Drain
4b3cdb9f4e Add radiotherm is_on method to return on/off (#20283)
* Added state method to return current operating state to fix #18244 for radiotherm component.

* Changed to set the is_on property when actively heating or cooling.
2019-01-21 12:05:42 -08:00
Andrew Sayre
bb21cb6c89 Remove trailing slash from base_url and added ability to generate webhook path. (#20295) 2019-01-21 20:50:41 +01:00
Paulus Schoutsen
9667c8057f Bumped version to 0.86.0b2 2019-01-21 09:45:42 -08:00
Johann Kellerman
028cc8d24f Align valid_entity_id with new slugify (#20231)
* slug

* ensure a dot

* fix

* schema_with_slug_keys

* lint

* test
2019-01-21 09:45:37 -08:00
Johann Kellerman
c36c708068 Align valid_entity_id with new slugify (#20231)
* slug

* ensure a dot

* fix

* schema_with_slug_keys

* lint

* test
2019-01-21 09:45:11 -08:00
Paulus Schoutsen
df47a8c58c Updated frontend to 20190121.0 2019-01-21 09:38:16 -08:00
Paulus Schoutsen
6ca0da5c52 Updated frontend to 20190121.0 2019-01-21 09:21:11 -08:00
Daniel Høyer Iversen
e4f42d1282 Update Tibber lib (#20289) 2019-01-21 16:12:03 +01:00
Andrey Kupreychik
ec9575a86f Added Xiaomi AirPurifier 2S profile (#20285) 2019-01-21 09:22:44 +01:00
Andrew Sayre
5c208da82e Added recursive detection of functools.partial. (#20284) 2019-01-20 22:27:32 -08:00
Jon Caruana
9482a6303d Add EverLights light component (#19817)
* EverLights light integration. Supports single color (with color and brightness parameters) or saved pattern (with effect parameter).

* Fix pylint parameter name warning.

* Code review feedback.

* Add tests for the two helper functions of EverLights component.

* Fixes for review feedback.

* Change test style.

* Style fixes for hound.
2019-01-21 04:23:36 +01:00
Paulus Schoutsen
657544a381 Clean up build artifacts correctly 2019-01-20 17:31:22 -08:00
Paulus Schoutsen
5999df1953 Clean up build artifacts correctly 2019-01-20 17:31:09 -08:00
Paulus Schoutsen
143eb4e8f4 Bumped version to 0.86.0b1 2019-01-20 17:02:44 -08:00
Anders Melchiorsen
41d2321756 Fix 'all' entity_id in service call extraction (#20281) 2019-01-20 17:02:36 -08:00
Anders Melchiorsen
f02e887fcc Allow 'all' entity_id in service schema (#20278) 2019-01-20 17:02:36 -08:00
Anders Melchiorsen
97e8e20bcc Remove double logging of automation action (#20264) 2019-01-20 17:02:36 -08:00
Otto Winter
33ed113211 Bump aioesphomeapi to 1.4.2 (#20247)
* Bump aioesphomeapi to 1.4.2

* Update requirements_all.txt
2019-01-20 17:02:35 -08:00
Phil Bruckner
ba2b28cd4d Handle non-string values in JSON renderer (#20233)
Handle the case of async_render_with_possible_json_value's value argument
being something other than a string. This can happen, e.g., when using the
SQL sensor to extract a datetime column such as last_changed and also using
its value_template to convert that datetime to another format. This was
causing a TypeError from json.loads, but async_render_with_possible_json_value
was only catching ValueError's.
2019-01-20 17:02:35 -08:00
Anders Melchiorsen
d843bf9c58 Improve Sonos discovery (#20196) 2019-01-20 17:02:34 -08:00
Paulus Schoutsen
84d6453a97 Add command to refresh auth (#20183) 2019-01-20 17:02:34 -08:00
Paulus Schoutsen
1f54edfbc4 Distribute reconnect (#20181) 2019-01-20 17:02:33 -08:00
Paulus Schoutsen
27be95e597 Sensibo to use HA operation modes (#20180) 2019-01-20 17:02:33 -08:00
Phil Bruckner
935e5c67a3 Handle non-string values in JSON renderer (#20233)
Handle the case of async_render_with_possible_json_value's value argument
being something other than a string. This can happen, e.g., when using the
SQL sensor to extract a datetime column such as last_changed and also using
its value_template to convert that datetime to another format. This was
causing a TypeError from json.loads, but async_render_with_possible_json_value
was only catching ValueError's.
2019-01-20 16:46:14 -08:00
emontnemery
3fcbcd5a38 Add JSON attribute topic to MQTT alarm (#20238) 2019-01-20 16:42:56 -08:00
emontnemery
dbba3eb0d4 Add JSON attribute topic to MQTT climate (#20239) 2019-01-20 16:42:35 -08:00
emontnemery
89e9d827a2 Add JSON attribute topic to MQTT fan (#20240) 2019-01-20 16:42:17 -08:00
emontnemery
ab4e4787e3 Add JSON attribute topic to MQTT lock (#20241) 2019-01-20 16:41:50 -08:00
Paulus Schoutsen
b6e1675c46 Add JSON attribute topic to MQTT vacuum (#20242) 2019-01-20 16:36:24 -08:00
Teemu R
e69ca810e4 Print a message when reconnected after a connection failure, requirement for IQS silver (#20261) 2019-01-20 16:36:01 -08:00
Anders Melchiorsen
62844e237c Allow 'all' entity_id in service schema (#20278) 2019-01-20 16:33:39 -08:00
Anders Melchiorsen
1218127d83 Fix 'all' entity_id in service call extraction (#20281) 2019-01-20 16:33:11 -08:00
koreth
08a57959b9 Reduce log noise from Envisalink component (#20282) 2019-01-20 16:32:01 -08:00
Paulus Schoutsen
d2dec44b18 Updated frontend to 20190120.0 2019-01-20 16:22:57 -08:00
Paulus Schoutsen
f771667c14 Updated frontend to 20190120.0 2019-01-20 16:22:42 -08:00
Andre Lengwenus
d5dcb8f140 Add discovery_info check to LCN light platform (#20280)
* Added discovery_info check to LCN light platform

* Removed whitespaces
2019-01-20 15:49:28 -08:00
Anders Melchiorsen
362ac725bf Remove double logging of automation action (#20264) 2019-01-21 00:10:12 +01:00
Ville Skyttä
58bb6f2e99 Add type hints to helpers.condition (#20266) 2019-01-21 00:03:12 +01:00
NotoriousBDG
5b8cb10ad7 Make Netatmo battery_percent icon dynamic (#20275) 2019-01-20 22:30:17 +01:00
Daniel Høyer Iversen
2eb5ce9dfe Update Tibber library (#20273) 2019-01-20 21:37:02 +01:00
koreth
fd2cff6b1c Fire events for Lutron RadioRA2 keypad buttons (#20090)
* Add binary sensor for Lutron RadioRA2 keypad buttons

Allow automations to be triggered from RadioRA2 keypads by exposing
each button as a binary sensor.

* Remove binary sensor component; fire events directly instead.

* Address comments from code review
2019-01-20 21:16:48 +01:00
kbickar
0e5fa010a7 Updated sense library to 0.6.0 (#20271) 2019-01-20 21:02:36 +01:00
Andre Lengwenus
7c25389f0d Add LCN switch platform (#20267)
* Add LCN switch platform

* Added guard clause for discovery_info check and removed unnecessary parathesis
2019-01-20 20:49:30 +01:00
Andre Lengwenus
a8d3a904e7 Support for relay ports for LCN light platform (#19632)
* Added relay ports to LCN lights platform

* Exchanged validation for ports with uppercase validator. Makes interfacing with pypck enums much more simple.

* Removed supported_features property as it is correctly inherited from parent

* Removed type annotations.
2019-01-20 14:50:29 +01:00
Matthew Wegner
6bf42ad43d Added Search Configuration to IMAP Sensor (#19749)
* Added Search Configuration to IMAP Sensor

The IMAP sensor currently only counts unread emails in a folder.  By exposing the IMAP search parameter, the sensor can be used to count other results:

- All emails in an inbox
- Emails sent from an address
- Emails matching a subject
- Other advanced searches, especially with vendor-specific extensions.  Gmail in particular supports X-GM-RAW, which lets you use any Gmail search directly ("emails with X label older than 14 days with", etc)

For my use case, I just wanted total emails in a folder, to show an "X/Y" counter for total/unread.  I started work on a one-off script to throw the data in, but figured I'd try to extend Home Assistant more directly, especially since this IMAP sensor correctly handles servers that push data.  This is my first Home Assistant contribution, so apologies in advance if something is out of place!  It's a pretty minimal modification.

* Added Server Response Checking

Looks like no library exception is thrown, so check for response text before parsing out results (previous code just counts spaces, so an error actually returns a state value of 4).

* IMAP Warning -> Error, Count Initializes to None

IMAP search response parsing throws an error instead of a warning.

Email count initializes as None instead 0.

Email count is untouched in case of failure to parse response (i.e. if server is temporarily down or throwing errors, or maybe due to user updating their authentication/login/etc).

Fixed line length on error so it fits under 80 characters.

* Fixed Indent on Logger Error

Sorry about the churn!  Python is pretty far from my daily-use language.  (I did run this one through pep8, at least)
2019-01-19 21:37:02 +01:00
Daniel Høyer Iversen
0987219b28 Tibber Pulse for homes without subscriptions (#20246) 2019-01-19 10:23:22 -08:00
Victor Vostrikov
fb52f66da0 Use local IP to discover IGD device (#20035)
* Use local_ip from config to discover IGD device

In case of multi-homed server UPNP discovery finds IGD device on some "default" interface. WIth this modification discovery will be performed from 'local_ip'.

* Update device.py

* Changed version of async_upnp_client in requirements

* Used aysnc_upnp_client==0.14.0

* Changed requirement to async_upnp_client==0.14.0.dev0

* Changed requirement to async_upnp_client==0.14.0.dev0

* Changed requirement to async_upnp_client==0.14.0.dev0

* Fixed code style

* Fixed code style

* Changed version of async_upnp_client in requerements

* Changed version of async_upnp_client in requirements

* Regenerated requirements (new async_upnp_client)

* Regenerated requirements (new async_upnp_client)

* Changed requirement to async_upnp_client=0.14.1

* Changed requirement to async_upnp_client=0.14.1

* Updated requirements

* Updated requirements.txt

* Corrected requirements

* Corrected import of DeviceState

* Constants changed according new async_upnp_client

* Upgraded for async_upnp_client==0.14.2
2019-01-19 17:08:53 +00:00
Otto Winter
8000b97180 Bump aioesphomeapi to 1.4.2 (#20247)
* Bump aioesphomeapi to 1.4.2

* Update requirements_all.txt
2019-01-19 17:13:32 +01:00
Erik
5b8f64093b Add JSON attribute topic to MQTT vacuum 2019-01-19 11:58:21 +01:00
Joakim Lindbom
440d479be8 Fix for issue #19086 (#20225) 2019-01-18 22:12:56 -08:00
Louis Matthijssen
e80702a45c Fix unused friendly name for SolarEdge sensor (#20109) 2019-01-18 15:02:27 +01:00
Anders Melchiorsen
63b19094c1 Improve Sonos discovery (#20196) 2019-01-18 13:43:48 +01:00
Rohan Kapoor
84b1fcbc36 Add verify_ssl to restful_command and switch.rest (#20199) (#20207) 2019-01-18 13:42:52 +01:00
zhujisheng
81a5208762 Add platform image_processing.qrcode (#20215)
* Add platform image_processing.qrcode

* Update qrcode.py
2019-01-18 13:40:49 +01:00
ehendrix23
afa019ae47 Set ehendrix23 as owner for harmony platform (#20203)
Put myself (ehendrix23) as code owner for remote.harmony platform
2019-01-17 19:35:45 -07:00
emontnemery
6800871c13 Log exceptions thrown by signal callbacks (#20015)
* Log exceptions thrown by signal callbacks

* Fix unsub

* Simplify traceback print

* Typing

* Add test

* lint

* Review comments

* Rework MQTT test case

* Fix bad merge

* Fix bad merge
2019-01-17 14:44:57 -08:00
emontnemery
f094a7369d Add JSON attribute topic to MQTT switch (#20192) 2019-01-17 10:55:22 -08:00
emontnemery
234f348ba1 Add JSON attribute topic to MQTT light (#20191) 2019-01-17 10:54:22 -08:00
emontnemery
d1c6eb4f3e Add JSON attribute topic to MQTT cover (#20190)
* Add JSON attribute topic to MQTT cover

* Lint
2019-01-17 10:53:52 -08:00
Rohan Kapoor
5232df34cb Add a Zoneminder availability sensor (#20184)
* Embed zoneminder platforms into component

* Add a binary sensor for ZoneMinder availability

* Lint

* Add missing docstrings
2019-01-17 10:52:53 -08:00
Paulus Schoutsen
0fe5d567a2 Add command to refresh auth (#20183) 2019-01-17 19:33:01 +01:00
Paulus Schoutsen
136364f5db Distribute reconnect (#20181) 2019-01-17 19:30:47 +01:00
Rohan Kapoor
2de6a94506 Embed zoneminder platforms into component (#20182) 2019-01-17 11:13:15 +01:00
Paulus Schoutsen
e1b63d9706 Sensibo to use HA operation modes (#20180) 2019-01-16 23:12:18 -08:00
Aaron Godfrey
27a8171a8b Remove color call to set lights to black. (#20176)
Calling clear all is enough to turn off the light.  Calling the color
command makes the light no longer function until clear all is called
again.  The component calls clear all beforing turning it on which is
why it works through home assistant.  However if you try to control the
light via the hyperion app or through kodi after it has been turned off
via home assistant it will not function until you call clear all again.
2019-01-16 21:19:52 -08:00
Paulus Schoutsen
722d285904 Bumped version to 0.86.0b0 2019-01-16 16:27:15 -08:00
Paulus Schoutsen
bc8aa73448 Updated frontend to 20190116.0 2019-01-16 16:14:55 -08:00
damarco
b557157ea1 Add support for deconz radios to zha component (#20167)
* Add support for deconz radios

* Update check_zigpy_connection()
2019-01-16 16:09:09 -08:00
Sebastian Muszynski
85404783d6 Add Xiaomi Airpurifier Pro V7 support (#20093)
* Add Xiaomi Air Purifier Pro V7 support

* Reorder the model list

* Improve the list of supported attributes/properties

* Fix lint
2019-01-16 16:08:41 -08:00
damarco
06440bf076 Bump pynuki to 1.3.2 (#20173) 2019-01-16 16:07:40 -08:00
Paulus Schoutsen
84a2e5d8fb Strip login username in backend (#20150)
* Add modern mode to HA auth provider that strips usernames

* Add tests for async_get_or_create_credentials

* Fix test
2019-01-16 15:03:05 -08:00
Fabian Affolter
9bb7e40ee3 Upgrade aiohttp to 3.5.3 (#19957)
* Upgrade aiohttp to 3.5.3

* Upgrade aiohttp to 3.5.4

* Remove test for webhook component from camera.push

* Lint
2019-01-16 14:23:46 -08:00
emontnemery
368682647d Log exceptions thrown by MQTT message callbacks (#19977)
* Log exceptions thrown by MQTT message callbacks

* Fix tests

* Correct method for skipping wrapper in traceback

* Lint

* Simplify traceback print

* Add test

* Move wrapper to common helper function

* Typing

* Lint
2019-01-16 13:50:21 -08:00
Paulus Schoutsen
1d86905d5b Switch locative to use the webhook component (#20043)
* Switch locative to use the webhook component

* Lint

* Remove dead test code

* Use voluptuous to validate the webhook schema

* Validate test mode schema as well

* Lint

* Remove allow_extra

* Return web.Response correctly

* #20043: Remove superfluous dict in WEBHOOK_SCHEMA validation
2019-01-16 11:08:42 -08:00
David F. Mulcahey
8748ace244 Make imports relative in ZHA component (#20020)
* make imports relative

* remove cyclic import
2019-01-16 11:06:22 -08:00
cvwillegen
5e73846bcc imap_email_content: allow configuring folder to read. (#20160)
* Update imap_email_content.py

Add configuration for selection of IMAP folder to track

* Update imap_email_content.py
2019-01-16 10:59:54 -08:00
Rohan Kapoor
b5bfc759ec Migrate gpslogger to the automatically generated webhook (#20079)
* Migrate gpslogger to the automatically generated webhook

* Lint

* Lint and return error code
2019-01-16 10:56:25 -08:00
Nikolay Vasilchuk
075b575bde Support device_class for rest sensor (#20132)
* Ready

* Tests fixed
2019-01-16 10:03:53 -08:00
Paulus Schoutsen
29c6584fe2 Enable setting alarm mode night for arlo platform (#20143)
* Enable setting alarm mode night for arlo platform

* Missed one small comment
2019-01-16 10:02:30 -08:00
Rohan Kapoor
48127cade0 Embed mailgun platform into component (#20147)
* Embed mailgun platform into component

* #20147: Update .coveragerc

* #20147 update requirements.txt
2019-01-16 10:01:08 -08:00
cvwillegen
c8efbb2cdc Fix link to documentation link, select read-only (#20155)
- Fixed link to documentation page at the top of the sensor
- Select the IMAP4 Inbox read-only so that reading e-mail does not mark messages as Read
2019-01-16 09:56:53 -08:00
Pascal Vizeli
9d112dc3f0 Remove .isort because we use the config from setup.cfg (#20158) 2019-01-16 09:54:11 -08:00
Rohan Kapoor
11c78d5de8 Embed geofency platform into component (#20083)
* Embded geofency platform into component

* #20083: Change docstring for geofency device tracker platform
2019-01-16 10:33:25 +01:00
Rohan Kapoor
bc30491dc0 Add support for connecting to multiple zoneminder instances (#19955)
* Add support for connecting to multiple zoneminder instances

* Lint

* Lint

* Clean up and better error handling

* Fix config validation

* Lint
2019-01-16 10:15:13 +01:00
Tim Gerla
fe93ea9bdf Use the correct Unicode degree symbol (#20058)
The previous symbol used for degrees was U+00BA, the "Masculine Ordinal Indicator". This patch changes the symbol to U+00B0, "Degree Sign", to match the rest of the Home Assistant system.
2019-01-16 09:08:23 +01:00
Paulus Schoutsen
75fa9b2fba Fix TTS say config validation (#20145) 2019-01-16 09:07:32 +01:00
ehendrix23
78da6828f0 Reconnect and device name fix for harmony platform (#20108)
* Update requirements

Updated requirements

* Add attributes

Add firmware and config version attributes

* Small bump for aioharmony

Small version bump increase for aioharmony

* Fix requirements file

For some reason aioharmony ended up in there as a duplicate. Fixed it.

* Fix for send command with named device

* Update requirements to get reconnect fix

* Set aioharmony version to 0.1.4

Version 0.1.4 has additional small fixes.

* Keep trying to connect on startup

Keep trying to connect to the HUB on startup

* Revert rebase changes

Revert some changes that should have been reverted back as part of rebase.

* PlatformNotReady if unable to connect on startup

Will call PlatformNotReady if unable to connect to Hub on startup

* Increase aioharmony requirement to 0.1.5

Increase aioharmony requirement to 0.1.5

* Register callbacks when entity added to HASS

Register the callbacks only once the entity has been added to HASS instead of during setup of platform.

* Removed debug log in __init__

Removed debug log in __init__
2019-01-16 08:35:29 +01:00
Robert Svensson
19e19009cc Make all deCONZ platforms use a common base (#20137)
* Make all deconz platforms use a common base

* Fix one cover to device replacement too much...
2019-01-16 08:33:04 +01:00
Rohan Kapoor
1e784b4d7a #20043: Remove superfluous dict in WEBHOOK_SCHEMA validation 2019-01-15 22:26:42 -08:00
Anders Melchiorsen
c218757336 Accept both domains and entities in influxdb include (#19927)
* Accept both domains and entities in influxdb include

* Explicit test

* Remove lint
2019-01-15 16:20:51 -08:00
Fabian Affolter
25f6302813 Switch to ipapi.co (fixes #19846) (#19886)
* Switch to ipapi.co (fixes #19846)

* Fix name

* Update name
2019-01-15 16:18:57 -08:00
Alexei Chetroi
4b3d4b275e Zha light.turn_on service fixes. (#20085)
Set color only if light supports color mode.
Set color temp only light supports color temp.
Update entity's brightness only if Zigbee command to set the brightness
was sent successfuly.
2019-01-15 16:12:22 -08:00
Rohan Kapoor
f36755e447 Switch geofency tests to using an unauthenticated HTTP client (#20080) 2019-01-15 16:11:30 -08:00
Paulus Schoutsen
9fd21d20ae Fix loading translations for embedded platforms (#20122)
* Fix loading translations for embedded platforms

* Update doc string

* Lint
2019-01-15 16:06:04 -08:00
Paulus Schoutsen
cd6679eb5b Updated frontend to 20190115.0 2019-01-15 15:35:18 -08:00
Tommy Jonsson
1b79872dd6 Add notify.html5_dismiss service (#19912)
* Add notify.html5_dismiss service

* fix test

* add can_dismiss

* fix service data payload

* fix hasattr -> getattr

* fixes

* move dismiss service to html5

* fix services.yaml

* fix line to long
2019-01-15 15:31:57 -08:00
Morgan Kesler
732743aeb5 Missed one small comment 2019-01-15 17:27:56 -05:00
emontnemery
0ec1401be7 Minor refactoring of MQTT availability (#20136)
* Small refactor of MQTT availability

* Use dict[key] for required config keys and keys with default values.
2019-01-15 14:26:37 -08:00
Morgan Kesler
cc166bf6a7 Enable setting alarm mode night for arlo platform 2019-01-15 17:19:04 -05:00
starkillerOG
11602c1da0 Improve Philips Hue color conversion 2 (#20118)
* Add gamut capability to color util

* Include gamut in hue_test

* Improve Philips Hue color conversion

* correct import for new location hue.light

* include file changes between PR's

* update aiohue version

* update aiohue version

* update aiohue version

* fix hue_test

Now Idea why it failed compared to the previous time

* Include gamut in hue_test

* fix hue_test

* Try to test hue gamut conversion

supply a color that is well outside the color gamut of the light, and see if the response is correctly converted to within the reach of the light.

* switch from gamut A to gamut B for the tests.

* remove white space in blanck line

* Fix gamut hue test

* Add Gamut tests for the util.color

* fix hue gamut test

* fix hue gamut test

* Improve Philips Hue color conversion
2019-01-15 11:30:50 -08:00
Robert Svensson
a3f0d55737 Change deCONZ to embedded platforms (#20113)
Move all platforms into components/deconz
2019-01-15 19:29:56 +01:00
Adam Mills
336b6adc88 Split time_pattern triggers from time trigger (#19825)
* Split interval triggers from time trigger

* Default smaller interval units to zero

* Rename interval to schedule

* Rename schedule to time_pattern
2019-01-15 09:33:34 -08:00
emontnemery
5b53bd6aa0 Move MQTT platforms under the component (#20050)
* Move MQTT platforms under the component
2019-01-15 17:31:06 +01:00
Eliseo Martelli
5fd1053a38 fixed gtt to report isotime (#20128) 2019-01-15 13:39:43 +01:00
Rohan Kapoor
80bc42af4f Use voluptuous to perform validation for the geofency webhook (#20067)
* Use voluptuous to perform validation for the geofency webhook

* Add missing attribute to schema

* Lint
2019-01-15 12:50:09 +01:00
Fredrik Erlandsson
c8d885fb78 Fix tellduslive discovery and auth issues (#20023)
* fix for #19954, discovered tellsticks shows up to be configured

* fix for #19954, authentication issues

* updated tests

* move I/O to executer thread pool

* Apply suggestions from code review

Co-Authored-By: fredrike <fredrik.e@gmail.com>
2019-01-15 06:36:17 +01:00
Andrew Sayre
e73569c203 Added partial detection to async_add_job (#20119) 2019-01-14 15:08:44 -08:00
emontnemery
0f3b6f1739 Reconfigure MQTT lock component if discovery info is changed (#19468)
* Reconfigure MQTT lock component if discovery info is changed

* Use dict[key] for required config keys and keys with default config schema values.
2019-01-14 21:01:42 +01:00
Aaron Bach
af2949f85f Embed OpenUV platforms into the component (#20072)
* Embed OpenUV platforms into the component

* Updated CODEOWNERS

* Updated .coveragerc
2019-01-14 11:44:00 -07:00
Aaron Bach
b3886820b4 Embed SimpliSafe platforms into the component (#20069)
* Embed SimpliSafe platforms into the component

* Updated CODEOWNERS

* Updated .coveragerc
2019-01-14 11:42:48 -07:00
Aaron Bach
d717d9f6be Embed RainMachine platforms into the component (#20066)
* Embed RainMachine platforms into the component

* Updated CODEOWNERS

* Updated .coveragerc
2019-01-14 11:42:21 -07:00
Otto Winter
f225570980 Move ESPHome Source Files (#20092)
* Move ESPHome source files

* Update .coveragerc

* Update CODEOWNERS
2019-01-14 09:00:48 -07:00
Morten Lüneborg
e505a9b7b4 Fix ihc issues caused by update to defusedxml (#20091)
* Update __init__.py

* Update __init__.py
2019-01-14 13:12:57 +01:00
Aaron Bach
ef79566864 Adjust OpenUV integration for upcoming API limit changes (#19949)
* Adjust OpenUV integration for upcoming API limit changes

* Added fix for "Invalid API Key"

* Bugfix

* Add initial nighttime check

* Move from polling to a service-based model

* Fixed test

* Removed unnecessary scan interval

* Fixed test

* Moving test imports

* Member comments

* Hound

* Removed unused import
2019-01-14 13:12:06 +01:00
Alok Saboo
fff3cb0b46 Change return text code for alarm control panels (#20055)
* Change return text code for alarmdotcom

* Change return text code for ialarm

* Change return text code for IFTTT

* Change return text code for manual alarm panel

* Change return text code for manual MQTT alarm

* Change return text code for MQTT

* Change return text code for Simplisafe
2019-01-14 13:02:30 +01:00
shred86
5652a4a58b Bump abode to 0.15.0 (#20064)
Fix for motion sensor states
2019-01-14 13:01:59 +01:00
Thom Troy
cb9e0c03d5 fix logic error in dubln bus (#20075) 2019-01-14 10:51:37 +01:00
Paulus Schoutsen
d6d28dd3e9 Lowercase code format (#20077) 2019-01-14 10:49:38 +01:00
Ville Skyttä
eb610e6093 Upgrade pytest to 4.1.1 (#20088) 2019-01-14 10:05:24 +02:00
Spencer Oberstadt
7db28d3d91 Add Roku hub and remote (#17548)
* add roku remote component

* remove name config (for now)

* update coveragerc and requirements_all

* fix linting errors

* remove extra requirements entry

* fix flake8 errors

* remove some references to apple tv

* remove redundant REQUIREMENTS

* Update requirements_all.txt

* Pass hass_config to load_platform

* don't expose registry constant

* remove unnecessary registry list

* use await instead of add_job

* use ensure_list

* fix code style

* some review fixes

* code style fixes

* stop using async

* use add with update

* fix whitespace

* remove I/O from init loop

* move import
2019-01-14 08:44:30 +01:00
Rohan Kapoor
452d7cfd61 Return web.Response correctly 2019-01-13 17:07:45 -08:00
Rohan Kapoor
7f3871028d Split out gpslogger into a separate component and platform (#20044)
* Split out gpslogger into a separate component and platform

* Lint

* Lint

* Increase test coverage
2019-01-14 01:09:47 +01:00
Rohan Kapoor
e476949c3e Remove allow_extra 2019-01-13 13:35:13 -08:00
Rohan Kapoor
9036aafc81 Lint 2019-01-13 13:26:51 -08:00
Teemu R
2a2318b7f6 warning -> debug, this should not have been visible to users (#20061) 2019-01-13 21:31:08 +01:00
Rohan Kapoor
b75356d532 Validate test mode schema as well 2019-01-13 12:12:04 -08:00
Rohan Kapoor
0f92d061c4 Use voluptuous to validate the webhook schema 2019-01-13 11:49:20 -08:00
Austin Drummond
3b83a64f7c Add support for HomeKit Controller covers (#19866)
* Added support for HomeKit Controller covers

* removed copied code

* more linting fixes

* added device type to service info

* added checks for value in characteristics

* added state stopped parsing

* removed logger

* removed unused args

* fixed inits

* removed unused imports

* fixed lint issues

* fixed lint issues

* remove state_unknown

* remove validation of kwargs in homekit controller covers

* guarantee tilt position is not none before setting
2019-01-13 19:09:47 +01:00
Matt Snyder
db87842335 Show persistent notification on Doorbird schedule failure (#20033)
* Remove unnecessary return.
Add persistent notification on failure to configure doorbird schedule.

* Update doorbirdpy to 2.0.5

* Fix bare except

* Bump version again

* Lint

* Return false
2019-01-13 18:47:50 +01:00
Paulus Schoutsen
798f630029 Updated frontend to 20190113.0 2019-01-13 09:38:35 -08:00
Paulus Schoutsen
96b8c517f0 Update translations 2019-01-13 09:38:22 -08:00
Anders Melchiorsen
4af4b2d10e Fix remote.harmony_change_channel services.yaml indentation (#20051) 2019-01-13 16:39:50 +01:00
Otto Winter
2339cb05ad Fix errors in ESPHome integration (#20048)
* Fix Home Assistant State Import

* Fix cover state

* Fix fan supported features

* Fix typo
2019-01-13 15:52:23 +01:00
carstenschroeder
aae6ff830a ADS service: Enable use of templates for value (#20024) 2019-01-13 14:23:22 +01:00
Alok Saboo
1c11394f5f Change alarm panel code format (#20037)
* Change code format

* Update elkm1 code format

* Update alarmdecodes code_format

* Update alarmdotcom code_format

* Update concord232 code_format

* Update envisalink code_format

* Update ialarm code_format

* Update ifttt code_format

* Update manual alarm code_format

* Update manual mqtt code_format

* Update mqtt code_format

* Update ness code_format

* Update nx584 code_format

* Update satel_integra code_format

* Update simplisafe code_format

* Update verisure code_format

* Change text to be consistent with the Polymer PR
2019-01-13 11:59:12 +01:00
Ville Skyttä
162e2b8385 Upgrade pytest to 4.1.0 (#20013) 2019-01-13 08:56:26 +01:00
Caleb Dunn
e295ca7b8e update to pyunifi 2.16 (#20042)
* update to pyunifi 2.16

* update requirements to version 2.16
2019-01-13 08:56:05 +01:00
Rohan Kapoor
3e325a4ef9 Remove dead test code 2019-01-12 20:24:55 -08:00
Rohan Kapoor
0007f35f96 Lint 2019-01-12 19:23:19 -08:00
Rohan Kapoor
4e020b90e1 Switch locative to use the webhook component 2019-01-12 19:18:33 -08:00
ehendrix23
04636e9ba7 Add harmony service to remote services.yaml (#20031)
Added the harmony_change_channel service to services.yaml for remote component.
2019-01-12 20:15:27 +01:00
Sean Dague
218c82eaf3 mychevy: Fix wrong attribute on battery level selector (#20016)
The battery level sensor is broken because the logic for determining
if the battery is charged accessed the wrong variable. This one
character fix makes it work again.
2019-01-12 13:51:01 -05:00
ehendrix23
22c0733d8e Add service change_channel to Harmony component (#19649)
* Update requirements

Updated requirements

* Add attributes

Add firmware and config version attributes

* Small bump for aioharmony

Small version bump increase for aioharmony

* Order ATTR constants

* Add the service

Add service change_channel

* Fix requirements file

For some reason aioharmony ended up in there as a duplicate. Fixed it.

* Updates based on review
2019-01-12 19:02:00 +01:00
Robert Svensson
d3f2854c89 UniFi - Fix issue with POE switch reset switch config (#20021)
* Fix issue when controlling POE would reset configuration for all other ports on same device
2019-01-12 17:59:44 +01:00
carstenschroeder
eabc7b22cd Enable bool type for ADS service (#20011) 2019-01-12 16:36:50 +01:00
David F. Mulcahey
012e91f9b1 version bump for zha-quirks (#20019) 2019-01-12 15:21:30 +01:00
Jonathan Keljo
6395087a40 Upgrade greeneye_monitor to 1.0 (#19631)
* Upgrade greeneye_monitor to 1.0

This is a breaking change; it causes the `serial_number` field in
configuration to be treated as the full 8-digit serial number rather
than the last 5 digits as was previously done, which results in the unique
identifiers for the sensors being different. (Fixing them up in
`config/.storage/core.entity_registry` before rebooting into the updated
version seems to prevent any weirdness.)

The last-5-digits behavior was a result of me misunderstanding the packet
format docs and not realizing that the true serial number was split across
two fields. In addition to being confusing (see
https://community.home-assistant.io/t/brultech-greeneye-issues/86852), it
was technically incorrect. The `greeneye_monitor` platform was just introduced
in 0.82, so it seems like the kind of thing that's best to fix now while
adoption is relatively low rather than later when somebody runs into it
as more than just a point of confusion.

* Switch to 8-character string

* Coerce to int

* Remove now-unnecessary cast
2019-01-11 20:54:22 -08:00
Matt Snyder
b3580f46b9 Update doorbird events to include URLs on event_data (#19262)
* Update doorbird events to include URLs on event_data as shown in documentation.

(cherry picked from commit 2405bc96fe)

* Format timestamp

* Update timestamp

* Lint
2019-01-11 20:45:03 -08:00
Tommy Jonsson
3bdee57066 Support for html5 notifications to suggest their names (#19965)
* support for devices to suggest their names

* houndci fixes

* Lint
2019-01-11 20:44:29 -08:00
Thomas Delaet
2208563de4 catch TypeError's in addition to ValueError's for unifi direct device tracker (#19994)
* catch TypeError's in addition to ValueError's in response from unifi access point

sometimes unifi's access point returns incomplete json which results in a TypeError because ssid_table is None

* fix syntax error
2019-01-11 20:44:16 -08:00
Sriram Vaidyanathan
418fa226e6 'latest_dir' referenced before assignment (#19952)
* 'latest_dir' referenced before assignment

local variable 'latest_dir' referenced before assignment

* Better fix
2019-01-11 20:44:01 -08:00
David F. Mulcahey
ba21608042 Repackage ZHA component (#19989)
* move files

* rename files

* rename files

* move files

* relative import

* update coveragerc
2019-01-11 20:34:48 -08:00
Austin Drummond
7676b3fbe8 Add support for HomeKit Controller Locks (#19867)
* Added HomeKit Controller Lock

* cleaned up code according to standards

* fixed lint issues

* added private constant for jammed state

* removed state_unknown
2019-01-12 03:48:28 +01:00
Alexei Chetroi
5ab3c7b765 Don't set friendly_name in Zha entity. (#19991)
Use @property name instead of setting friendly_name device state attr.
2019-01-11 21:41:27 -05:00
Paulus Schoutsen
6cba51fd0e Lint 2019-01-11 16:31:16 -08:00
Louis-Etienne
fe148606b8 Wink: Update pubnubsub-handler version to make it compatible with python 3.7 (#19625) 2019-01-11 16:30:31 -08:00
Ville Skyttä
574669bd20 Upgrade pytest-cov to 2.6.1 (#19988) 2019-01-11 16:24:59 -08:00
Ville Skyttä
83c5dc67f7 Upgrade huawei-lte-api to 1.1.3 (#19987) 2019-01-11 16:24:31 -08:00
Paulus Schoutsen
2ffadde0a3 Add Hass.io user headers to supervisor proxy (#19395)
* Add Hass.io user headers to supervisor proxy

* Update test_http.py

* Fix tests

* Update test_auth.py
2019-01-11 15:30:40 -08:00
pbalogh77
7dac7b9e5e Support for multiple Fibaro gateways (#19705)
* Preparing for transition to config flow

Added multiple gateway support
Reworked parameter flow to platforms to enable multiple controllers
Breaking change to config, now a list of gateways is expected instead of a single config

* Updated coveragerc

Added new location of fibaro component

* Fixes based on code review and extended logging

Addressed issues raised by code review
Added extended debug logging to get better reports from users if the device type mapping is not perfect

* Changhes based on code review

Changes to how configuration is read and schemas
Fix to device type mapping logic

* simplified reading config

* oops

oops

* grr

grr

* change based on code review

* changes based on code review

changes based on code review
2019-01-11 15:29:54 -08:00
Rohan Kapoor
d820efc4e3 Split locative to a separate component (#19964)
* Split locative to a separate component

* Switch tests to use constants for http codes

* Fix tests
2019-01-11 15:14:11 -08:00
Paulus Schoutsen
8755389c49 Bumped version to 0.86.0.dev0 2019-01-11 15:10:01 -08:00
Paulus Schoutsen
11647f9fab Merge remote-tracking branch 'origin/master' into dev 2019-01-11 15:09:48 -08:00
Paulus Schoutsen
578bfe9798 Fix fail2ban tests 2019-01-11 15:01:24 -08:00
Bas
8c27bf8c7c Expose more information about shipments by PostNL (#18334)
* Expose more information about shipments by PostNL

* Update postnl.py
2019-01-11 14:59:31 -08:00
Andrew Chatham
ab4e1fddd5 Fix the anthemav component by removing a debugging line. (#19979)
This lane ended up calling vars(transport) on an asyncio Transport
object. In a standard setup, that's a python object provided by syncio,
and it works. Home Assistant injects uvloop into asyncio, which makes this
a Python C object, and those don't support vars().
2019-01-11 23:34:32 +01:00
Fredrik Erlandsson
b9a488912a Add support for 'via_hub' for device_info (#19454)
* Add support for 'via_hub'

* Update config schema

* add domain to via_hub

* add tests for via_hub
2019-01-11 13:11:13 -08:00
Matt Snyder
199db7219e Add ability to monitor relay events (#18730)
* Add ability to monitor relay events

* Account for empty events array instead of none.
2019-01-11 13:07:12 -08:00
Martin Hjelmare
937688f7a6 Add mysensors state update delay (#18891)
* Add mysensors state update delay

* Schedule state update after delay to avoid updating state multiple
  times during the same short timespan.

* Code review
2019-01-11 13:06:06 -08:00
Oliver
25408bd483 Include Scripts/ directory to .gitignore - this is created by virtualenv on Windows (#18918) 2019-01-11 13:04:56 -08:00
Mike Miller
a65d14c0cd Always use datetime and timedelta in camera.proxy instead of int/float (#19571) 2019-01-11 12:58:14 -08:00
Paulus Schoutsen
12d16d9bdc Update test_auth.py 2019-01-11 12:55:23 -08:00
Antoine GRÉA
14dd8791ec Adding IPv6 to fail2ban sensor (#19457)
* Fixing fail2ban regex for ipv6

* Adding IPv6 tests for fail2ban

* Formating code for hound

* Formating again

* Formating again 2
2019-01-11 12:54:47 -08:00
Paulus Schoutsen
088584b66d Merge pull request #19986 from home-assistant/rc
0.85.1
2019-01-11 12:41:00 -08:00
Paulus Schoutsen
963ffa1ccc Bumped version to 0.85.1 2019-01-11 12:06:12 -08:00
Paulus Schoutsen
990e7c57f2 Fix warning (#19946)
* Fix warning

* Update service.py
2019-01-11 12:05:56 -08:00
Daniel Shokouhi
0979ce476a Fix botvac connected alert retrieval 2019-01-11 12:05:07 -08:00
Alexei Chetroi
ded37d971d Don't map LevelControl to light for single cluster devices. (#19929) 2019-01-11 11:58:41 -08:00
David F. Mulcahey
7a83b86ebd check config instead of config_entry for quirks flag (#19730) 2019-01-11 11:58:40 -08:00
Paulus Schoutsen
8ef2f1f67b Fix warning (#19946)
* Fix warning

* Update service.py
2019-01-11 11:58:14 -08:00
Paulus Schoutsen
99c2e4ac44 Fix warning (#19946)
* Fix warning

* Update service.py
2019-01-11 11:52:07 -08:00
Paulus Schoutsen
fe92cf1e72 Updated frontend to 20190109.1 2019-01-11 11:48:49 -08:00
Paulus Schoutsen
7dbbea2238 Updated frontend to 20190109.1 2019-01-11 11:48:32 -08:00
David F. Mulcahey
7be015fcc6 Add services and helper functions to support a config panel for ZHA (#19664)
* reconfigure zha device service

add log line to reconfigure service for consistency

* add entity functions to support new services

* added new services and web socket api and split them into their own module

* support manufacturer code

logging to debug

get safe value for manufacturer

* update services.yaml

* add comma back

* update coveragerc

* remove blank line

* fix type

* api cleanup - review comments

* move static method to helpers - review comment

* convert reconfigure service to websocket command - review comment

* change path

* fix attribute
2019-01-11 11:34:29 -08:00
Paulus Schoutsen
a8f22287ca Allow embedded platforms (#19948)
* Allow embedded platforms

* Fix test
2019-01-11 11:30:22 -08:00
Jarle B. Hjortand
b3a08d5876 When tradfri experience communication errors make the lights/devices unavailable. (#19288) 2019-01-11 10:55:55 -08:00
Sebastian Muszynski
e2f55a959f Support next generation of the Xiaomi Mi Smart Plug (chuangmi.plug.m3) (#19972)
* Support next generation of the Xiaomi Mi Smart Plug (chuangmi.plug.m3)

* Fix indent
2019-01-11 19:44:55 +01:00
Paulus Schoutsen
b81260e912 Fix tests 2019-01-11 10:10:36 -08:00
Paulus Schoutsen
7be197b845 Update test_http.py 2019-01-11 10:00:38 -08:00
Paulus Schoutsen
fd21d6cc9d Add Hass.io user headers to supervisor proxy 2019-01-11 10:00:38 -08:00
Paulus Schoutsen
3f65a03024 Merge pull request #19959 from home-assistant/awarecan-trusted-network-auth-must-have-user
Trusted Network Auth: only authenticate request when owner can be found
2019-01-11 09:53:35 -08:00
Paulus Schoutsen
82c6d3d8c2 Add support for spot cleaning that was introduced in pybotvac 0.12 (#19857)
* Added support for spot cleaning that was introduced in pybotvac 0.12.

* Corrected formating.

* Added missing operator.
2019-01-11 09:52:06 -08:00
Eliseo Martelli
71eaef8da4 add service type in name (#19980) 2019-01-11 09:51:41 -08:00
Paulus Schoutsen
d812f23f6b min_max sensor support for STATE_UNAVAILABLE (#19914) 2019-01-11 09:27:48 -08:00
Sören Oldag
17dce6697f Add support for restoring state to rpi_gpio_pwm (#19944) 2019-01-11 09:25:14 -08:00
Fabian Affolter
49cfebd903 Upgrade keyring to 17.1.1 (#19962) 2019-01-11 10:48:07 -05:00
Fabian Affolter
2228f2ef66 Upgrade pysnmp to 4.4.8 (#19961) 2019-01-11 10:47:53 -05:00
Fabian Affolter
734d8c52e9 Upgrade ruamel.yaml to 0.15.85 (#19960) 2019-01-11 07:44:11 -08:00
Fabian Affolter
caf0751be8 Upgrade pillow to 5.4.1 (#19958) 2019-01-11 12:37:15 +01:00
Fabian Affolter
7b81727c69 Upgrade mutagen to 1.42.0 (#19956) 2019-01-11 10:38:39 +01:00
Jason Hu
97394df0b9 Only authenticate request when owner can be found 2019-01-11 00:26:25 -08:00
Tyler Page
c3e9bd1444 Change state() to try/except to catch KeyError (#19935)
* Change state() to try/except to catch KeyError

When Tautulli is up but Plex is down, the API doesn't return a 'stream_count' key. This causes calls to state() to raise KeyError exceptions. The new code includes a try/except to catch the KeyError and return -1 signifying that the Tautulli API cannot talk to Plex

* Update tautulli.py
2019-01-11 08:48:36 +01:00
mindigmarton
31d92683f7 Add emulated_roku component (#17596)
* Add emulated_roku component

* Add emulated_roku config tests

* Fix emulated_roku test dependencies

* Remove emulated_roku yaml support, add tests

* Add yaml support, simplify config flow

* Improve emulated_roku code quality

* Fix emulated_roku translation, improve code quality

* Fix emulated_roku translation

* Bump emulated_roku to 0.1.6 to fix SSDP discovery

* Bump emulated roku to 0.1.7, refactor component start/stop methods
2019-01-11 03:20:35 +01:00
Thomas Hervé
cee51ecb2b Remove spurious libzwave error (#19928)
If a network_key is not configuired, the following error is logged:
TypeError: expected bytes, NoneType found
Exception ignored in: 'libopenzwave.str_to_cppstr'
TypeError: expected bytes, NoneType found

We don't need to set the key if it's None, let's skip in that case.
2019-01-10 17:45:50 -08:00
Paulus Schoutsen
646aaab936 Fix botvac connected alert retrieval (#19937) 2019-01-10 17:43:50 -08:00
Fabian Affolter
4c1eeb9e96 Upgrade pylast to 3.0.0 (#19938) 2019-01-10 17:43:31 -08:00
Abílio Costa
ca460ace5d Small refactoring for the alexa component (#19782)
* small refactoring

* fix tests
2019-01-10 17:39:49 -08:00
Kevin Fronczak
2be0d1b096 Upgrade blinkpy and use calibrated temperature for sensor (#19723) 2019-01-10 17:24:35 -08:00
Sergey Rymsha
47f64b472d Add nad telnet (#19704)
* fix cla-bot

* fix bug introduced after linter complaint

* merge two components into one
support telnet port configuration

* remove obsolete nadtcp component. nad component must be used instead.

* back to correct nad_receiver version
2019-01-10 17:21:57 -08:00
SNoof85
96d20a64d5 add_entities -> async_add_entities (#19943)
Better state handling at HA startup
2019-01-10 17:13:29 -08:00
arigilder
4d187e08d4 Add sensors to jewish_calendar for upcoming Shabbat times (#19278)
* Initial pass of cleanup for shabbat_times

* Switch to async defs

* First pass of unit tests + fixture data

* Completion of first round of unit tests, 100% passing

* Unit tests for state restoring

* Style fixes

* More style fixes

* Lint fix

* Add upcoming candelighting and havdalah sensors

* Add unit tests, remove havdalah offset

* More unit tests + small bugfix for weekly_portion

* Add issur melacha sensor

* Remove old shabbat_times work-in-progress files

* Bump required version of hdate

* Add havdalah offset config parameter

* Bump hdate version required

* Pin hdate requirement

* Lint fixes

* Changes based on review + API changes for hdate 0.8.7

* Add three-day holiday unit tests

* Remove debugging line

* Add missing docstring

* Fix doc lint comment
2019-01-10 16:27:34 -08:00
so3n
4d52adb008 Remove Discovery dependency from konnected.py (#19910) 2019-01-10 15:53:12 -08:00
Abílio Costa
6c29315088 Add Alexa's EndpointHealth reporting (#19784)
* add Health reports

* add health report for all devices

* update tests

* Update homeassistant/components/alexa/smart_home.py

Co-Authored-By: abmantis <abmantis@users.noreply.github.com>

* lint

* add tests
2019-01-10 15:52:21 -08:00
Daniel Shokouhi
6403a13ea3 Fix botvac connected alert retrieval 2019-01-10 13:56:10 -08:00
Fabian Affolter
de76b59d0b Upgrade youtube_dl to 2019.01.10 2019-01-10 22:50:39 +01:00
Clifford W. Hansen
616f23ae1d Add btle_name attribute to devices (#19915)
* Update googlehome.py

Added name from bluetooth device to attributes

* Update homeassistant/components/device_tracker/googlehome.py

Check if key exists before assigning name

Co-Authored-By: cliffordwhansen <clifford@nighthawk.co.za>
2019-01-10 21:55:17 +01:00
Alexei Chetroi
d859c3fa86 Don't map LevelControl to light for single cluster devices. (#19929) 2019-01-10 14:43:24 -05:00
Richard Mitchell
e753ffca94 Correctly map Nest hvac_state to Home Assistant states. (#19895) 2019-01-10 09:28:01 -08:00
Roy Duineveld
c44f5d31ef Plant monitor defaults (#19891)
* Plant monitor defaults

* houndci-bot fixes
2019-01-10 15:49:13 +01:00
Jérôme Wiedemann
e6a2c18430 min_max sensor support for STATE_UNAVAILABLE 2019-01-10 13:48:24 +01:00
Artem Tokarev
8b49ecbe7d Removed mkdir, If the WORKDIR doesn’t exist, it will be created. (#19892) 2019-01-10 07:18:59 +01:00
Aaron Bach
01eee52990 Bump pyflunearyou to 1.0.1 (#19899) 2019-01-09 19:38:19 -07:00
Paulus Schoutsen
70a8cac19d Merge pull request #19897 from home-assistant/rc
0.85.0
2019-01-09 16:51:11 -08:00
Paulus Schoutsen
9aed40a88d Update translations 2019-01-09 15:29:31 -08:00
Paulus Schoutsen
7641658e38 Bumped version to 0.85.0 2019-01-09 15:13:29 -08:00
Florian Ludwig
8cf595dd3e assign user to websocket connection when using legacy_api_password (#19797) 2019-01-09 15:13:13 -08:00
Paulus Schoutsen
f17d6c0593 Updated frontend to 20190109.0 2019-01-09 15:12:52 -08:00
Paulus Schoutsen
5cab319798 Updated frontend to 20190109.0 2019-01-09 15:12:29 -08:00
Rendili
4394e37df9 Bug fix with getting a device battery level when API unavailable for Hive (#19841)
* hive updates - bug fix and add entity registration

* remove hive entity registration code
2019-01-09 11:21:03 +01:00
Paulus Schoutsen
64b4c8f43a Fix deprecation warning (#19882) 2019-01-08 21:09:47 -08:00
Paulus Schoutsen
a3d05328ec Refactor motion sensor of the xiaomi_aqara platform (#19805)
* Refactor motion sensor

* Improve debug output
2019-01-08 20:48:09 -08:00
Rohan Kapoor
2bdbf6955d Migrate geofency over to the Webhook component (#18951)
* Migrate geofency over to the Webhook component

* Return web.Response correctly

* Fix test

* Lint

* Fix error that tests caught
2019-01-08 20:47:05 -08:00
Florian Ludwig
23382ab199 assign user to websocket connection when using legacy_api_password (#19797) 2019-01-08 20:45:24 -08:00
Paulus Schoutsen
8a3d43745d Bumped version to 0.85.0b1 2019-01-08 20:23:59 -08:00
Pascal Vizeli
6b56985e01 Update OZW to 0.1.2 (#19878)
* Update ozw 0.1.2

* Update requirements_all.txt
2019-01-08 20:23:49 -08:00
Steven Looman
ed41421a3d Fix error when trying to log used UPnP device, if multiple found (#19875) 2019-01-08 20:23:49 -08:00
Alistair Galbraith
f019131352 Resolves #17196, Resolves #18739 - Hue Beyond light fixture errors (#19874)
* Resolves #17196, Resolves #18739 - Hue Beyond light fixtures being incorrectly recognized

* Removed long code lines that were failing code review

* Removed trailing whitespace
2019-01-08 20:23:48 -08:00
Otto Winter
4ec313cb3b Bump aioesphomeapi (#19838) 2019-01-08 20:23:47 -08:00
Fredrik Erlandsson
68e33fdbf5 fixes #19814, Daikin config setting (#19823) 2019-01-08 20:23:47 -08:00
cdheiser
312ad7057d Fix a bug in Lutron RadioRA2 Scene support (#19819) 2019-01-08 20:23:46 -08:00
cdce8p
0d49b19624 Update HAP-python to 2.4.2 (#19776)
* Bugfixes for connection issues
2019-01-08 20:23:46 -08:00
Otto Winter
6d9c37d636 Fix some ESPHome race conditions (#19772)
* Fix some ESPHome race conditions

* Remove debug

* Update requirements_all.txt

* 🚑 Fix IDE line length settings
2019-01-08 20:23:45 -08:00
Sebastian Muszynski
ed881f399f Don't slugify unique id (#19770) 2019-01-08 20:23:45 -08:00
Sebastian Muszynski
3a466195b9 Simplify data_key for a stable unique_id because the order of the dict will not be preserved (Closes: #13522) (#19766) 2019-01-08 20:23:44 -08:00
Alexei Chetroi
3453d31f01 Use manufacturer id only for configure_reporting only when specified. (#19729) 2019-01-08 20:23:44 -08:00
Eliseo Martelli
afa0d37ff0 Rename air pollutants to air quality (#19448)
* mv component folder

* moved in airquality

* changed names in files

* renamed test init

* renamed test air quality

* renamed in tests

* renamed coverage

* fixed naming

* corrected attr names

* changed attr names
2019-01-08 20:23:43 -08:00
Otto Winter
57c96a5489 Add ESPHome native API discovery (#19399)
* ESPHome discovery

* Add note about netdisco

* 🔡

* Address comments

* Bump netdisco to 2.3.0

* Update requirements_all.txt
2019-01-08 20:21:31 -08:00
Rendili
6d9fda04ac add entity support to hive (#19879) 2019-01-08 20:15:12 -08:00
Pascal Vizeli
b4c657a39c Update OZW to 0.1.2 (#19878)
* Update ozw 0.1.2

* Update requirements_all.txt
2019-01-08 20:14:27 -08:00
Alistair Galbraith
35cb0458fa Resolves #17196, Resolves #18739 - Hue Beyond light fixture errors (#19874)
* Resolves #17196, Resolves #18739 - Hue Beyond light fixtures being incorrectly recognized

* Removed long code lines that were failing code review

* Removed trailing whitespace
2019-01-08 20:13:47 -08:00
Malte Franken
6d3343e4d1 Geo Location -> Geolocation (class names and unit test comments) (#19877)
* fixed geolocation naming in class names

* fixed geolocation naming in comments in unit test
2019-01-08 20:11:51 -08:00
Thomas Lovén
f73bda1218 Allow other icon prefixes than mdi: (#19872) 2019-01-08 20:08:20 -08:00
Pierre
c29bffc8d8 Replace influxdb query by another query that is more lightweight (#19880)
same as #6289
2019-01-08 23:31:39 +00:00
Steven Looman
cc6e70a270 Fix error when trying to log used UPnP device, if multiple found (#19875) 2019-01-08 21:05:36 +00:00
Lars Lydersen
42821b5f64 Added missing operator. 2019-01-08 21:12:35 +01:00
Lars Lydersen
c164533404 Corrected formating. 2019-01-08 20:36:57 +01:00
David F. Mulcahey
acdf9c7ce2 Relay events for onoff and levelcontrol output clusters in ZHA (#19863)
* auto relay events for onoff and levelcontrol output clusters

* fix docstring

* correct copy/paste failure - review comment

* add space - review comment
2019-01-08 17:20:50 +01:00
emontnemery
0cea54cea1 Cleanup if discovered mqtt climate can't be added (#19739)
* Cleanup if discovered mqtt climate can't be added
2019-01-08 16:53:02 +01:00
emontnemery
203701bc7c Cleanup if discovered mqtt fan can't be added (#19741)
* Cleanup if discovered mqtt fan can't be added
2019-01-08 16:51:03 +01:00
emontnemery
44f6151548 Cleanup if discovered mqtt alarm can't be added (#19742)
* Cleanup if discovered mqtt alarm can't be added
2019-01-08 16:49:47 +01:00
emontnemery
1a5fe3d880 Cleanup if discovered mqtt cover can't be added (#19743)
* Cleanup if discovered mqtt cover can't be added
2019-01-08 16:48:42 +01:00
emontnemery
a62e514d8f Merge pull request #19744 from emontnemery/mqtt_discovery_cleanup_binary_sensor
Cleanup if discovered mqtt binary_sensor can't be added
2019-01-08 16:47:36 +01:00
emontnemery
f0f386e314 Cleanup if discovered mqtt sensor can't be added (#19745)
* Cleanup if discovered mqtt sensor can't be added

* No bare except

* Clear ALREADY_DISCOVERED list with helper
2019-01-08 16:46:26 +01:00
emontnemery
bb37cf906c Cleanup if discovered mqtt lock can't be added (#19746)
* Cleanup if discovered mqtt lock can't be added
2019-01-08 16:45:38 +01:00
Fabian Affolter
406b45c6e7 Upgrade bcrypt to 3.1.5 (#19854) 2019-01-08 09:22:45 -05:00
kennedyshead
377b129c9c Make asuswrt sensor optional (#19736) @kennedyshead
* Dont load if not in config

* Adding config options for sensors

* Fixed mistake with iterating over wrong things

* lint

* lint

* Setting None state

* Using .get when fetching optional config
2019-01-08 09:14:16 -05:00
Rene Nulsch
410f19c777 Replace MyChevy persistant_notification with error log entry (#19804)
The mychevy service is notoriously unreliable, often only having 50% uptime. 
Previously a persistent notification was emitted when the platform errored out. 
Users have found that is happening too often, so instead log an error when
this happens instead.
2019-01-08 08:06:08 -05:00
Malte Franken
4bbfc04f5e Geo Location -> Geolocation (comments and default group name) (#19865)
* fixed geolocation naming in comments

* fixed geolocation naming in default group name

* fixed link to documentation (after https://github.com/home-assistant/home-assistant.io/pull/8086)
2019-01-08 11:24:57 +01:00
kennedyshead
c7a32e59b7 Fix state and attribute fetching in vasttrafik (#19856)
* Fixing state and attribute fetching

* Fixing state and attribute fetching

* Setting None state

* Need to brreak loop
2019-01-08 09:54:22 +01:00
emontnemery
fb9aad8791 Small cleanup of MQTT light (#19816)
* Small refactor of MQTT light removing unused variable
2019-01-08 07:21:26 +01:00
Fabian Affolter
493d2743ba Merge pull request #19853 from home-assistant/upgrade-beautifulsoup4
Upgrade beautifulsoup4 to 4.7.1
2019-01-08 00:13:50 +01:00
Fabian Affolter
f259c5724b Upgrade holidays to 0.9.9 (#19851) 2019-01-08 00:13:33 +01:00
Vincent KHERBACHE
ea8bb28d21 Fix french Amazon Polly voice 'Léa'. (#19852)
The accent must be removed (Léa -> Lea) just like the other voices (eg. Celine, Peneloppe) to match with Amazon voices ID. 
Fun fact: there is no alternative name for "Léa" on Amazon Polly documentation: https://docs.aws.amazon.com/en_us/polly/latest/dg/voicelist.html, probably just omitted.
Mitigation: alternative voices (with and without accents) can be put into `SUPPORTED_VOICES`, both `voice.get('Id')` and `voice.get('Name')` must be then checked for a match.
This fixes #19802.
2019-01-08 00:13:09 +01:00
Lars Lydersen
8aa136f7ed Added support for spot cleaning that was introduced in pybotvac 0.12. 2019-01-07 20:03:22 +01:00
Fabian Affolter
4905f4dd97 Upgrade beautifulsoup4 to 4.7.1 2019-01-07 19:16:04 +01:00
koomik
45fae5a50e Upgrade tahoma-api to 0.0.14 (#19840)
* Update requirements_all.txt

Change to tahoma-api 0.0.14 to solve #19542 
https://github.com/home-assistant/home-assistant/issues/19542

* Update tahoma.py
2019-01-07 19:02:42 +01:00
Fabian Affolter
2eec2cc656 Upgrade holidays to 0.9.9 2019-01-07 19:00:03 +01:00
Mickaël Schoentgen
a57aae9891 Fix 2 ResourceWarning: unclosed file in test_ruamel_yaml.py (#19780)
Signed-off-by: Mickaël Schoentgen <contact@tiger-222.fr>
2019-01-07 11:53:31 -05:00
Sean Dague
9cdfa77a21 bump watefurnace version to 1.1.0 (#19847)
There is better retry logic in the new library to handle login faults.
2019-01-07 11:36:02 -05:00
sander76
0af635e8d7 adding more dimmer components (#19843)
* adding more dimmer components

* updated library version

* updated requirements_test_all
2019-01-07 11:32:28 -05:00
emontnemery
08ac6da8a6 Clear ALREADY_DISCOVERED list with helper 2019-01-07 17:03:10 +01:00
emontnemery
8701be095b No bare except 2019-01-07 17:03:10 +01:00
emontnemery
0b57cfb004 Cleanup if discovered mqtt sensor can't be added 2019-01-07 17:03:10 +01:00
emontnemery
ddeb7f3bea Clear ALREADY_DISCOVERED list with helper 2019-01-07 17:00:03 +01:00
emontnemery
44c619a853 No bare except 2019-01-07 17:00:03 +01:00
emontnemery
d8370f44cb Cleanup if discovered mqtt binary_sensor can't be added 2019-01-07 17:00:03 +01:00
emontnemery
dd75c49796 Cleanup if discovered mqtt switch can't be added (#19721)
* Cleanup if discovered mqtt switch can't be added
2019-01-07 16:57:51 +01:00
Sebastian Muszynski
8b232e7ce6 Simplify data_key for a stable unique_id because the order of the dict will not be preserved (Closes: #13522) (#19766) 2019-01-07 13:36:16 +01:00
Fredrik Erlandsson
3c465434cd fixes #19814, Daikin config setting (#19823) 2019-01-07 13:04:53 +01:00
Otto Winter
e30c324b32 Bump aioesphomeapi (#19838) 2019-01-07 11:58:10 +01:00
Daniel Shokouhi
903c86a116 Bump pybotvac (#19831)
* Bump pybotvac to support No Go lines

* Update requirements
2019-01-06 23:58:36 +01:00
kennedyshead
c96778c82a This makes the vasttrafik platform stop spamming the logs with warnings (#19792)
* This makes the vasttrafik platform stop spamming the logs with warrnings

* Forcing build
2019-01-06 21:06:20 +01:00
Rene Nulsch
1e18a2c679 Remove temperature from the list of available forecast sensors (#19818) 2019-01-06 20:52:55 +01:00
Tommy Jonsson
5b35317e1e [3/3] mqtt-vacuum device-registry (#19479)
* add device registry to mqtt-vacuum
2019-01-06 19:23:33 +01:00
cdheiser
bf4830bc07 Fix a bug in Lutron RadioRA2 Scene support (#19819) 2019-01-06 19:25:09 +02:00
Johann Kellerman
3ffa0176cc SMA sensor - updated library (#19753) 2019-01-06 19:20:19 +02:00
Tommy Jonsson
ccbc231d3a [2/3] vacuum mqtt-discovery (#19478)
* add discoverability to mqtt-vacuum
2019-01-06 17:05:04 +01:00
Tommy Jonsson
dee229152f [1/3] Refactor mqtt-vacuum in preparation for discovery and device registry (#19462)
* Refactor mqtt-vacuum in preparation for discovery and device registry
2019-01-06 14:16:46 +01:00
emontnemery
76c30aca38 Remove duplicated MQTT switch test case (#19799) 2019-01-06 06:27:57 +01:00
Mattias Welponer
3d0c3ab746 HomematicIP update version to 0.10.1 (#19788)
* Update version to 0.10.1

* Update of requirements files
2019-01-05 16:25:36 -07:00
Sebastian Muszynski
32faf5b709 Improve debug output 2019-01-05 22:39:02 +01:00
Sebastian Muszynski
09ff272290 Refactor motion sensor 2019-01-05 22:31:41 +01:00
Eliseo Martelli
3a5ba77e04 Rename air pollutants to air quality (#19448)
* mv component folder

* moved in airquality

* changed names in files

* renamed test init

* renamed test air quality

* renamed in tests

* renamed coverage

* fixed naming

* corrected attr names

* changed attr names
2019-01-05 11:42:36 -05:00
Otto Winter
68723730a7 Add ESPHome native API discovery (#19399)
* ESPHome discovery

* Add note about netdisco

* 🔡

* Address comments

* Bump netdisco to 2.3.0

* Update requirements_all.txt
2019-01-05 16:00:07 +01:00
Sören Oldag
0125b3fd80 Upgrade pwmled to 1.4.0 (#19783) 2019-01-05 08:05:37 -05:00
Austin Drummond
fb5b5223fb Added zwave lock state from alarm type workaround (#18996)
Thank you 👍 

* added zwave lock state from alarm type workaround

* fixed test indents

* more linting fixes

* one more linting fix

* simplified logic

* fixed lint new lines

* fixed merge conflict issue

* fixed definition of _alarm_type_workaround in zwave lock
2019-01-05 09:59:43 +01:00
keesak
aacf7ba9aa Add support for Kwikset 914 Convert - lock.zwave id0446 (#19710) (#19722)
Thank you 👍
2019-01-05 09:48:40 +01:00
cdce8p
bf29824dac Update HAP-python to 2.4.2 (#19776)
* Bugfixes for connection issues
2019-01-04 22:37:42 +01:00
sander76
a1cb4018a1 update powerview scene component to latest api. (#19717) 2019-01-04 22:19:06 +01:00
Otto Winter
c7700ad11c Fix some ESPHome race conditions (#19772)
* Fix some ESPHome race conditions

* Remove debug

* Update requirements_all.txt

* 🚑 Fix IDE line length settings
2019-01-04 22:10:52 +01:00
Alexei Chetroi
ed8f89df74 Use manufacturer id only for configure_reporting only when specified. (#19729) 2019-01-04 16:05:37 -05:00
Sebastian Muszynski
65c7bdc1ad Don't slugify unique id (#19770) 2019-01-04 16:02:42 -05:00
Austin Drummond
bf40bea965 Support for Homekit controller/alarm control panel (#19612)
* added support for homekit security systems

* fixed linting issues

* fixed indentation issues

* simplifired logic on homekit_controller alarm controller panel

* cleaned up battery level const on homekit controller alarm control panel
2019-01-04 12:54:37 -07:00
David F. Mulcahey
ef180c489a check config instead of config_entry for quirks flag (#19730) 2019-01-04 14:00:26 -05:00
Paulus Schoutsen
6fb8378b45 Bumped version to 0.85.0b0 2019-01-04 13:47:02 -05:00
Maciej Bieniek
27a9f5a05c Round illumination and lux value to one (#19747) 2019-01-04 18:25:37 +01:00
Daniel Høyer Iversen
16ab799798 Upgrade tibber library (#19768) 2019-01-04 17:59:46 +01:00
Sean Dague
03488af3fb Add mychevy optional country parameter (#19727)
* Add optional country parameter

mychevy 1.2.0 provides the ability to work in canada as well as the us
(there are different service urls for each region). This creates a new
config option to enable it.

* Update mychevy.py
2019-01-04 10:01:47 -05:00
Dan Cinnamon
dbb3802b4e Move envisalink component to package and add services.yaml (#19731)
* Moved component to a package and added a services.yaml file.

* Fixing coverage issue and grammar issue on the services.yaml file.

* Fixed typo in the services.yaml file.
2019-01-04 09:57:32 -05:00
Abílio Costa
ead38f6005 Proactive Alexa ChangeReport messages (#18114)
* Alexa: implement auth and proactive ChangeReport messages

* refactor after rebase from dev to use the new AlexaDirective and Response classes

* move to aiohttp; cleanup

* better function name

* move endpoint to config

* allow passing token function

* remove uneeded state get

* use iterable directly

Co-Authored-By: abmantis <abmantis@users.noreply.github.com>

* missing delete from previous commit

* checks for when user has no auth config

* update cloud component

* PR suggestions

* string lint

* Revert "string lint"

This reverts commit a05a1f134c9ebc7a6e67c093009744f142256365.

* linters are now happier

* more happy linters

* use internal date parser; improve json response handling

* remove unused import

* use await instead of async_add_job

* protect access token update method

* add test_report_state

* line too long

* add docstring

* Update test_smart_home.py

* test accept grant api

* init prefs if None

* add tests for auth and token requests

* replace global with hass.data

* doc lint
2019-01-03 22:28:43 +01:00
Rohan Kapoor
c2525bede2 Filter urllib3.connectionpool warnings in camera.axis and camera.zoneminder (#19641)
* Filter urllib3.connectionpool warnings in camera.axis and camera.zoneminder

* Lint
2019-01-03 11:56:36 -07:00
carstenschroeder
b79057348d Add exception handling to ADS shutdown (#19682)
* Added exception handling to ADS shutdown

* corrected whitespaces

* deleted blank line
2019-01-03 11:47:16 -07:00
ctborg
6b18b92bdd Drop bme680 os_lookup for temp_offset (#19733)
Drops os_lookup, as it isn't needed to set the temperature offset.
2019-01-03 11:35:13 -07:00
Adam Belebczuk
ada0f7cf65 Fix WeMo incorrect mapping of device type during discovery (#19691) 2019-01-03 11:28:40 -07:00
Andrew Hayworth
87a0118082 Do not choke on no awair data (#19708)
* awair: do not choke on no data

The awair API returns an empty response for various air data queries
when a device is offline. The underlying library (python_awair) does
not directly inform us that a device is offline, since we really can
only infer it from an empty response - there is no online/offline
indicator in the graphql API.

So - we should just ensure that we do not attempt to update device state
from an empty response. This ensures that the platform does not crash
when starting up with offline devices, and also ensures that the
platform is marked unavailable once devices go offline.

* Fix typo

Further proof that coding after 10pm is rolling the dice.
2019-01-03 14:41:18 +01:00
ctborg
688bdc6532 Adds ability to calibrate temperature for BME680 (#19684)
* Adds temperature calibration

* Add deps.  Lint fix
2019-01-02 13:02:29 -05:00
kennedyshead
bba9ef7d7d Bumping aioasuswrt version to 1.1.17 (#19714) 2019-01-02 07:55:09 -05:00
mvn23
635252ec8e Bump pyotgw to 0.4b1 (#19715) 2019-01-02 07:54:23 -05:00
Dan Cinnamon
a10ca95c01 Envisalink pgm (#19499)
* Added a new service for calling custom PGM functions.

* Fixed lint issues

* Fixed lint issues reported by travis-CI

* Fixed style issue.

* Complete rename of attribute.
2019-01-02 05:46:33 -07:00
Daniel Perna
4244ea78d0 Update pyhomematic 0.1.54 + small fixes (#19667)
* Update pyhomematic + small fix

* Add casting for ILLUMINATION

* Revert suggested fix
2019-01-01 16:25:57 +01:00
Nick Whyte
5aa2bd81cf Add ness alarm control panel using nessclient (#18463)
* Add ness alarm control panel using nessclient

* indenting

* .

* Remove availability functionality, will improve and add back in another PR

* Use call_count

* lint

* lint

* Review changes

* Lint

* Bump nessclient to 0.9.8

* Bump nessclient to 0.9.9

* Remove from .coveragerc
2019-01-01 08:08:13 -07:00
Daniel Chesterton
61d5b3028d Add support for color_temp_command_template in MQTT light component (#19675)
* Add support for color_temp_command_template in MQTT light component
2019-01-01 15:42:41 +01:00
javicalle
b9f4a7220e Improve rflink coverage (#19596)
* some minor tests refactor
* async/await refactor
* toggle have not brightness
* test for race condition in unknown device
* test for 'no_command' and 'not_connected'
* test for race condition in unknown device
* sensor events are handled in sensor devices, RflinkDevice handle
command events
* test race conditions & bogus entity remove
* two more tests
* Test race condition for unknown components
* Test cleanup for `commands events` and `sensor events`
2019-01-01 15:35:31 +01:00
Fabian Affolter
2ea53e0787 Suppress traceback if network is not available (#19651) 2019-01-01 14:21:46 +01:00
Fabian Affolter
7c302bfd7e Luftdaten traceback (#19666)
* Suppress traceback if there is not connection available

* Remove line break
2019-01-01 14:21:02 +01:00
Robin
ff80fc347b Fix london_underground issue (#19642)
* Update london_underground.py

* Update test

* Update london_underground.py

* Update london_underground.py

* Update london_underground.py

* Fix lint

* Use london-tube-status==0.2
2018-12-31 06:24:52 -08:00
Michael Dubno
4b541f4058 Add IDTECK proximity card component (#18309)
* Added IDTECK proximity card sensor component.

* Moved from sensor to platform

* Made requested standards changes
2018-12-30 20:15:45 -08:00
Jc2k
855274e354 Fix homekit_controller pairing regression (#19654)
* Fix homekit_controller pairing regression

* Use constant for pairing file name
2018-12-30 14:44:26 -05:00
ehendrix23
43eaa960e8 Fix error in got_connected for remote.harmony (#19662)
* Fix config call in connected

* Change aioharmony version for fixes
2018-12-30 13:35:08 -05:00
Thom Troy
81a0ce621e Fix exception checking for next dublin bus (#19663) 2018-12-30 18:35:12 +01:00
Pär Svanström
18d36e011a Added regexp validation allowing Twilio notifications to use Sender ID instead of phone number (#19644)
* Added regexp validation allowing Twilio notifications to use Sender ID instead of phone number

* Fix line length
2018-12-30 18:34:29 +01:00
Joakim Sørensen
6d44245456 pytraccar version bump (#19659) 2018-12-30 14:59:43 +01:00
carstenschroeder
4b90ed6b22 Fix ADS light when parameter adsvar_brightness is not set (#19636)
* ADS light breaks if optional parameter adsvar_brightness is not set

Just a small change to prevent exception if optional parameter adsvar_brightness is not set

* corrected blank lines
2018-12-30 02:39:00 -08:00
John Mihalic
cc8b811572 Bump pyHik library to 0.1.9 to improve device support. (#19656) 2018-12-30 10:13:49 +01:00
ehendrix23
faeee4f7ad Use aioharmony for remote.harmony platform (#19595)
* Use aioharmony for async

Use aioharmony to interact with Harmony hub. Due to this following improvements:
-) Setting of available state for entity
-) Automatic config update if configuration changes (including updating file containing config)
-) Allow using of device name instead of number
-) When sending command with repeat, nothing else will be able to put a IR command in between

* Requirements updated

* Version update for fix

* Mainly cleanup

* Update requirements

Updated requirements

* Fixed lint issue

* Small bump for aioharmony

Small version bump increase for aioharmony

* Updated based on review
2018-12-29 17:22:27 -08:00
Markus Ressel
9aa6037219 Add RaspyRFM switch platform (#19130)
* added components and requirement

* change config to allow the definition of multiple switches without redefining the gateway

* dont assume false state
fix default value

* added exclude to coveragerc

* sorted imports

* review fixes

* review fixes

* bugfix
review fixes

* review fix
2018-12-29 16:40:03 -08:00
David F. Mulcahey
d0742cb332 Only bind clusters in ZHA remote entity (#19577)
* split bind and configure reporting helpers

* only bind remote clusters

* update comments - review comment
2018-12-29 16:17:17 -08:00
Alexei Chetroi
e096532cf1 Use async_configure for ZHA IAS binary sensor (#19629)
* Update Zha IAS binary sensor to use async_configure().

* Make less debug logging noise.
2018-12-29 16:13:52 -08:00
Adam Belebczuk
25e5864a22 Improve Wemo setup speed (#19563)
* Wemo - Improve setup speed

Move WeMo device discovery to an async context so it won't block initial component setup from completing quickly.

* WeMo - Fix too long lines

* WeMo - Update subscription shutdown log message

* WeMo - Fix flake8 issues

* WeMo - Code review fixes

* WeMo - Fix long lines

* WeMo - More code review fixes

* WeMo - Code review fixes
2018-12-29 16:05:21 -08:00
Marvin Wichmann
338077f557 Support knx operation types (#19546)
* Updated version to 0.9.3

Adjusted climate component due to changes in the underlying library.

* Climate.KNX: fix updating view when operation mode is changed due to refactoring

* Addressed review comments

* Added validation for config.
2018-12-29 15:18:55 -08:00
Ville Skyttä
f925d9ca6b Use xml.etree through defusedxml (#19640) 2018-12-30 00:07:48 +01:00
Fabian Affolter
b1c9f8d55d Suppress traceback if network is not available 2018-12-29 23:55:43 +01:00
Marius Retegan
32eb4e518b Fix cpu_temp issue on Vero 4K (#19638) 2018-12-29 21:01:47 +01:00
Robbert Müller
9928b977fd Added events STARTED, RESTARTED AND PAUSED (#19516)
Rewrote the tests a bit
the 'wait for the timer to finish' part of the test is now it's own test.
The rest is a sequence of fire/assert. Which i rewrote to a loop to
reduce the amount of duplicate code
2018-12-29 16:40:17 +01:00
mvn23
dc9da79a1c Revert "Bump pyotgw to 0.4b0 (#19618)" (#19635)
This reverts commit dae4543e54.
There's a bug in the new version of the library that may cause 100% CPU usage, rendering Home Assistant unresponsive.
2018-12-29 16:38:55 +01:00
Steven Looman
2ba86310f0 Upgrade to async_upnp_client==0.13.8 (#19634) 2018-12-29 14:09:29 +00:00
Marcelo Moreira de Mello
457708cbda Upgraded pyarlo to 0.2.3 (#19626) 2018-12-28 16:51:59 -05:00
Andrei
82d6fe5bd5 Fix cpu_temp issue on Odroid (#19620) 2018-12-28 21:36:00 +01:00
mvn23
dae4543e54 Bump pyotgw to 0.4b0 (#19618) 2018-12-28 10:12:10 -05:00
Daniel Shokouhi
33c5e09ac2 Add additional neato alerts and errors (#19608) 2018-12-28 09:53:54 -05:00
Andre Lengwenus
f09cea1499 LCN component and light platform (#18621)
* Initial commit of LCN component and light platform

* Corrected pre-review comments

* Fixed dimming behaviour in combination with transitions for lcn lights

* Removed unused logger

* Combined __init__.py and core.py into lcn.py component. Bumped to pypck==0.5.6

* Fixed .coveragerc

* Bumped to pypck==0.5.7

* Bump to pypck==0.5.8

* Fixed requirements_all.txt

* Moved unique generation of connection names to config schema's validator

* Minor changes due to review comments.
Bump to pypck==0.5.9.

* Address_connection is passed into LcnDevice

* Set should_poll property on LcnDevice to return False

* Moved platform config validation to component. Load platform using discovery helper

* Furtehr changes due to the review

* Light configuration is set required as there are no other platforms up to now
2018-12-28 03:39:06 -08:00
Rene Nulsch
14c39f7c24 Systemmonitor - add device_class property (#19614) 2018-12-28 10:28:40 +01:00
Ville Skyttä
b83a405b14 Upgrade huawei-lte-api to 1.1.1 (#19615) 2018-12-28 11:10:34 +02:00
SNoof85
699a38de52 Add Freebox component with sensors and device tracker (#18472)
* Add freebox component with sensor and device tracker

* script/gen_requirements_all passed and pylint fixes

* Fix docstring in wrong place

* Fix indentation

* Lint fixes

* More lint fixes

* Lint fixes again

* Pylint fixes

* Bump aiopyfreebox version

* Close freebox connection on HA Stop

* Fixed docstring

* Fixed ident

* Lint fixes

* Fix cloing session when HA stop

* Fix URL

* Fix URL

* Fix double look up in discovery datas

* Fix logging level

* Fix get_device_name

Thx for the hint Martin

* Fix async_update_info

* Update requirements_all.txt
2018-12-27 15:26:09 -08:00
Fabian Affolter
fe14be53e3 Upgrade aiohttp to 3.5.1 (#19584) 2018-12-27 21:56:08 +01:00
Max Rydahl Andersen
b32e6fe0d5 Add AfterShip sensor for packages (#18034)
* Add AfterShip sensor for packages

Why:

 * I receive a lot of packages from many different shipping companies.
 * I would like to see in haas how many packages are being delivered.

This change addreses the need by:

 * Adding a sensor for AfterShip (aftership.com)
 * AfterShip supports ~490 couriers world wide thus should cover
   almost any sensible tracking.

Notes:
  - For now this sensor assumes you somehow have added trackings to
    aftership manually.
  - Future idea is to expose service that allows adding a tracking
    based on incoming mails.
  - Other improvments would be to add map markers for package locations.

Related:
- https://community.home-assistant.io/t/package-tracking/858
- https://community.home-assistant.io/t/aftership-package-tracking/24068
- https://community.home-assistant.io/t/aftership-shipment-tracking-platform/14074
- https://community.home-assistant.io/t/aftership-state-card/57912

* Fix typo and update ordering
2018-12-27 10:01:57 -08:00
Daniel Shokouhi
d05450487c Improve how neato displays alerts and add alerts for persistent maps (#19593)
* Improve how neato displays alerts and add alerts for persistent maps

* Review comments
2018-12-27 09:57:38 -08:00
emontnemery
f9aa364b6d Don't truncate brightness and white_value of MQTT light (#19502)
* MQTT light: Don't truncate brightness

* Clamp after rounding
2018-12-27 18:18:12 +01:00
Ioan Loosley
5eab4f1dcc Version Bump for aioftp (#19510)
* Version Bump for aioftp

* Version Bump
2018-12-27 18:17:12 +01:00
Andrei
4c59a6522a Updated set of available voices for Yandex TTS (#19603) 2018-12-27 17:54:12 +01:00
Simon Nørager Sørensen
40bb4266c9 Update pymitv dependency (#19601)
* Security update, fixed fatal error when TV could become unresponsive

* Dependency update
2018-12-27 17:38:07 +01:00
FieldofClay
bf8b201bb3 Add verify_ssl option to Splunk component (#19112)
* added verify_ssl option to Splunk component

* update Splunk tests

* fix typo in Splunk tests

* Update test
2018-12-27 14:23:04 +01:00
apetrycki
cd0da4ed0e Fix mpd shuffle/random status (#19308)
* Fix shuffle/random status

MPD always shows true for shuffle.  For some reason casting the 0 or 1 as a boolean does not work.  Now returns 'true' or 'false' based on the value of 'random'.

* Update homeassistant/components/media_player/mpd.py

Change to correct way of returning shuffle boolean. 'random' needs to be cast as an integer before being cast as a boolean.

Co-Authored-By: apetrycki <34962392+apetrycki@users.noreply.github.com>

* Remove incorrect string code

Original fix method returns a string instead of a boolean.  Removed in favor of MartinHjelmare's method.
2018-12-27 00:04:40 -08:00
Fabian Affolter
22acc03fb8 Upgrade Sphinx to 1.8.3 (#19580) 2018-12-27 08:26:37 +01:00
Fabian Affolter
10831a0889 Upgrade rpi-rf to 0.9.7 (#19394) 2018-12-26 14:50:45 -05:00
Fabian Affolter
5de4f546f9 Upgrade keyring to 17.1.0 (#19583) 2018-12-26 14:47:38 -05:00
Fabian Affolter
2efa297df1 Upgrade pyowm to 2.10.0 (#19582) 2018-12-26 14:46:59 -05:00
Fabian Affolter
98229899dc Upgrade TwitterAPI to 2.5.8 (#19581) 2018-12-26 14:46:18 -05:00
Fabian Affolter
0a792620f8 Upgrade sphinx-autodoc-typehints to 1.6.0 (#19579) 2018-12-26 14:44:44 -05:00
Ted Sluis
54f6cfd569 Add a new click_type double_both to improve the support of the new Xiaomi aqara remote.b286acn01 dual switch. (#19578) 2018-12-26 17:48:58 +01:00
javicalle
70fff26383 Clean up remaining rflink tests (#19551)
* some minor tests refactor

* unused import

* async/await refactor

* Correct tests failures
2018-12-26 15:25:16 +01:00
Sebastian Muszynski
dc11e41cf0 Add a new click_type "long_both" to improve the support of the new Xiaomi Wireless Wall Switch (remote.b286acn01) (#19573) 2018-12-26 14:16:53 +01:00
Ville Skyttä
a6e091f60f Link to dicttoxml excessive INFO logging issue (#19575) 2018-12-26 14:16:08 +01:00
Daniel Høyer Iversen
1428919f98 Tibber, improve server reconnection (#19574) 2018-12-26 13:03:06 +01:00
Michael Dubno
6f9943787a Pencom (#19369)
* Added Pencom relay switch.

* Added Pencom relay switch.

* Cleaned up for submission.

* Fixed attribute keys. Switched to add_entities.
2018-12-26 08:49:34 +01:00
DoloresHA
796b195c73 Update pylaunches dependency to 0.2.0 (#19570)
* Update pylaunches dependency to 0.2.0

Update launch library to use pylaunches 0.2.0 as a dependency. launch_time sensor attribute will now be passed in ISO format, allowing for templating/easier automating with this attribute.

* Update pylaunches to 0.2.0
2018-12-25 23:47:19 +01:00
Heine Furubotten
47f8d248f7 Whitelisting of lines on entur sensor (#19539) 2018-12-25 23:43:46 +01:00
Igor Motov
b9a0f40827 Add device_id configuration option to Bluetooth tracker (#18539)
* Bluetooth tracker: add device_id configuration option

Makes the device id that bluetooth tracker is using configurable instead 
of using the first available device.

* Remove unncessary default in config.get

It is already handled in the configuration validation.
2018-12-25 18:29:44 +01:00
sander76
6b204941cf Add homematicip cloud full flush measuring switch (#19247) 2018-12-25 16:43:28 +01:00
mreiling
4d62e77049 Added support for triggered state on NX584 alarm. (#19524)
* Added support for triggered state on NX584 alarm.

* Minor update
2018-12-25 16:29:53 +01:00
Mattias Welponer
b80bed64f5 Add HomematicIP SMI55 device (#19400) 2018-12-25 10:40:21 +01:00
sander76
18b7f74ad7 Clean up homematicip cloud (#19481)
* Better logging, remove unused method, re-try handling fix. Other minor fixes.

* fix test

* typo fix
2018-12-25 09:40:36 +01:00
cdheiser
b2081c579b Improve Lutron RadioRA2 support, adding switches and scenes (#18330)
* Improve Lutron RadioRA2 support, adding switch and scene support.

- Update the version of pylutron to 0.2 which has various bug fixes.
- Switch to pylutron's per-device subscribe
- Add switch support, and configure any non-dimmable output as a switch.
- Add scene support, using any configured keypad button with a corresponding LED as a scene.

* Fixes for comments in pull request home-assistant/home-assistant#18330

* More fixes for comments in pull request #18330

* Remove unused imports

* Cleanup in docstrings for Lutron scene support.
2018-12-25 09:33:03 +01:00
David F. Mulcahey
bef85ecd2e Remove global from ZHA application controller (#19557)
* remove global from application controller per request

* remove unneeded line

* don't store controller application in hass.data - review comment
2018-12-25 09:20:09 +01:00
Jc2k
e0f50a9e54 Update homekit controller to homekit==0.12.0 (#19549) 2018-12-24 22:13:17 +01:00
emontnemery
a8797a08c6 Improve handling of MQTT light discovery (#19436) 2018-12-24 14:28:26 +01:00
emontnemery
edb7ec78f9 Fix support for base topic for empty values in MQTT discovery msg (#19501)
* Fix topic expansion for short strings

* Lint
2018-12-24 14:21:58 +01:00
Alexei Chetroi
4a1da0b041 Configure ZHA entity on new ZHA device join (#19470)
* Address PR#19177 comments.

* Make 'new_join' part of ZhaEntity.

Call async_configure() automatically when new device ZHA device joins.
2018-12-23 20:47:06 +01:00
Fredrik Erlandsson
0b84eefa2e Add hub- and device-info for tellduslive (#19180)
* add hub- and device-info

* attempt to make I/O outside event loop

* add_executer_job

* coroutines

* async_get_hubs

Co-Authored-By: fredrike <fredrik.e@gmail.com>

* asyncio fixes

* do device_info IO when device is discovered

* it's called async_add_executor_job

* nicer unique_id

* add comment

* it's called `async_add_executor_job`

* hub always contains 'name'

* await each new device

* add comment to why gather is bad
2018-12-23 13:13:49 -05:00
David F. Mulcahey
50888ae339 Fix issues in ZHA light (#19368)
* make light report on/off and level

* refactoring and review comments

* refactor

* use boolean for set_state - review comment

* async_schedule_update_ha_state() on level change - review comment

* fix docstring - review comment
2018-12-23 16:16:21 +01:00
kdvlr
a9f796a97c Updated to support per device find iphone sound. (#19535)
Added additional log statements to help debug
2018-12-23 13:35:39 +01:00
Steve9F
10ff169c76 Change ISY binary_sensor subnode to hex (#19471)
The subnode id for the motion enable node of Insteon 2844-222 motion sensor II on the ISY is 'D'. The binary_sensory/isy994.py assumed this value will be an integer rather than hex and fails. Changing line 55 to subnode_id = int(node.nid[-1], 16) fixes the issue.
2018-12-23 13:31:16 +01:00
Diogo Gomes
0b22880f22 increase robustness, when something upstream fails (#19493) 2018-12-23 13:29:02 +01:00
Alexei Chetroi
5a4e6bbb07 Support ZHA light turn_off transition (#19531) 2018-12-23 12:15:54 +01:00
Adam Belebczuk
0776456b59 Pywemo version bump (#19538)
* Bump pywemo version

* Bump pywemo version
2018-12-23 11:40:34 +01:00
Alexei Chetroi
01fc322488 Make ZHA entities non-polled by default (#19536) 2018-12-23 11:11:24 +01:00
David F. Mulcahey
2a2af80309 Add ZHA occupancy sensor (#19365)
* occupancy sensor

* lint

* map occupancy cluster to binary_sensor

* update to use reporting configuration and async_configure

* refactor

* fix typo - review comment

* handle restore entity functionality
2018-12-22 20:53:15 +01:00
William Comartin
2765440aa5 Implement path in the config to fix issues for some users (#19491)
* Update Tautulli sensor dependency pytautulli

Implement path in the config to fix issues for some users

* Add requirement
2018-12-22 14:36:06 -05:00
Andrew Loe
43e174899d Add additional Z-Wave Bulbs to ZW098 Workaround (#19480) 2018-12-22 14:33:28 -05:00
Panagiotis Panagiotopoulos
07b6aaec63 Add long click at new Aqara Wireless Remote Switch (#19518)
New Aqara Wireless Remote Switch Single supports long click.
2018-12-22 19:35:25 +01:00
Daniel Høyer Iversen
ef53a2d118 Fix Mill connection problem (#19519)
* Update mill library, improve connection

* Mill connection

* revert print

* Mill connection
2018-12-22 19:01:52 +01:00
Antoine GRÉA
1099018a5e Fix fail2ban by removal of internal timer logic (#19456)
* Remove timer logic from sensor class

Proposed fix for issue #10500

* Updating the tests to remove timer logic

* Removing unecessary dependancy

* Fixing requested changes

* Commit to try to fix the CLA ?
2018-12-22 18:25:02 +01:00
David F. Mulcahey
4bdb21a871 Update ZHA entity state on ZigBee zdo device announce (#19208)
* call async_update if defined on device_announce

* lint

* change update method

* remove unneeded listener
2018-12-22 18:18:48 +01:00
Fabian Affolter
6880be5aeb Add sunrise and sunset to Darksky weather sensor (#19492)
* Add sunrise and sunset to Darksky weather sensor

* Fix lint issue
2018-12-22 08:52:36 -05:00
Dom
f0e187e306 Update yale smart alarm client to v0.1.6 (#19495) 2018-12-22 08:50:03 -05:00
Joakim Sørensen
7c5ac88aae Add deprecation warning (#19515)
* Update ruter.py

* formating
2018-12-22 14:01:31 +01:00
Alexei Chetroi
54c57fe5db Restore state for zha binary_sensors on restart. (#19314)
Poll zha devices for current status, if not available restore state.
2018-12-22 09:34:47 +01:00
David F. Mulcahey
b444dfe8a6 Add ZHA battery sensor (#19363)
* add batery sensor

* add additional battery sizes

* remove blank line

* lint

* fix attribute report configuration

* return None - review comments
2018-12-22 09:11:33 +01:00
javicalle
fb226e3e3b Clean up RFLink tests and add two tests (#19511)
* some minor tests refactor

* unused import
2018-12-22 08:53:02 +01:00
uchagani
3a3d488de3 Allow scrape sensor to retry setting up platform if initial setup fails (#19498) 2018-12-22 08:40:30 +01:00
Michael Dubno
30841ef4da Add Lutron Homeworks component (#18311)
* Added Lutron Homeworks components.

* Made all requested changes other than config.

* Removed commented out code.

* Removed binary_sensor.
Implemented new signal/events for button presses.
Cleaned up some data passing.

* Fixed minor formatting.

* Got rid of unused config stuff.
Reordered imports.

* Missed removing vol, and forgot an extra line.

* More requested changes
Removed HomeworksController, it wasn't needed.

* Removed stale code.

* Imperative doc change.
2018-12-21 18:11:00 -05:00
Steven Looman
501b3f9927 Disable creating port mappings from UI, add discovery from component (#18565)
* Disable creating port mappings from UI, add discovery from component

* Remove unused constant

* Upgrade to async_upnp_client==0.13.6 and use manufacturer from device

* Upgrade to async_upnp_client==0.13.7
2018-12-21 17:25:23 +00:00
Paulus Schoutsen
5efc61feaf Merge branch 'master' into dev 2018-12-21 15:34:40 +01:00
Paulus Schoutsen
28abc30b4d Merge pull request #19505 from home-assistant/rc
0.84.6
2018-12-21 15:33:17 +01:00
Paulus Schoutsen
0471e15c28 Bumped version to 0.84.6 2018-12-21 14:04:54 +01:00
Paulus Schoutsen
ec28ee3c42 Remove check if base url is local (#19494) 2018-12-21 14:04:46 +01:00
Paulus Schoutsen
1281da024c Remove check if base url is local (#19494) 2018-12-21 11:23:05 +01:00
Diogo Gomes
c789f11ef8 Fixed the range filter unknown argument precision (#19428)
In HomeAssistant 0.84.3, the range filter would not work due to the unexpected precision filter parameter. 
The default range scheme has been edited to remove the unexpected precision parameter.

Verified and tested.
2018-12-20 22:30:06 +00:00
Otto Winter
dbd5396dc7 Add native ESPHome Home Assistant state feature (#19429)
* Add native ESPHome Home Assistant state feature

* Update aioesphomeapi
2018-12-20 23:29:57 +01:00
uchagani
71900ca719 Add new sensor platform to expose Islamic prayer times (#19444)
* added new sensor platform to expose Islamic prayer times

* added new sensor platform to expose Islamic prayer times

* updated tests according to feedback

* make prayer_times_info a public attribute

* remove stale comments
2018-12-20 22:52:43 +01:00
Aaron Bach
c15445159d Add timeout to RainMachine login (#19476)
* Add timeout to RainMachine login

* Moved timeout logic to regenmaschine

* Moving logic back into try/except

* Bumped requirements
2018-12-20 22:51:10 +01:00
Tom French
dd885a456e Reorder FLOW entries in config_entries.py (#19475) 2018-12-20 21:54:42 +01:00
Mathieu Velten
b5c9eca654 Update pynetgear to 0.5.2 (#19490) 2018-12-20 21:16:50 +01:00
jumpkick
dcf925a67f Rename ocr.png to ssocr-(entity_name).png to allow multiple instances (#18634)
* * Rename ocr.png to ssocr-(entity_name).png to allow multiple seven_segments instances to run without overwrting each other's data.

* Update seven_segments.py

* Update seven_segments.py

* Use string formatting
2018-12-20 11:31:58 -05:00
Bob Clough
d42d8543c8 Add Mythic Beasts DNSAPI Component (#18333)
* Add Mythic Beasts DNSAPI Component

* Added timeout, and tests for exceptions while updating

* Move API to external module

* Move mbddns import into function

* Updated tests to mock out mbddns library
2018-12-20 11:33:47 +01:00
Jens
fa0185a481 Adds battery_percent which had been introduced with pyatmo 1.4 and resolves unknown var warning. (#19309) 2018-12-19 23:42:16 +01:00
Daniel Shokouhi
28d2f9bd87 Bump Pybotvac To Support D7 On Latest Firmware (#19463)
* Bump pybotvac to support D7 on latest firmware

* Update requirements
2018-12-19 22:37:20 +01:00
emontnemery
27ea59f6c3 Add device registry to MQTT climate (#19332)
* Add device registry to MQTT climate

* Add testcase test_entity_id_update
2018-12-19 19:27:44 +01:00
emontnemery
ae776e2d28 Add device registry to MQTT alarm control panel (#19331)
* Add device registry to MQTT alarm control panel

* Add testcase test_entity_id_update
2018-12-19 19:27:23 +01:00
emontnemery
fed5d0f5be Add device registry to MQTT lock (#19333) 2018-12-19 19:26:07 +01:00
Paulus Schoutsen
4f134f339c Merge pull request #19461 from home-assistant/rc
0.84.5
2018-12-19 16:49:21 +01:00
Paulus Schoutsen
264d18bc83 Bumped version to 0.84.5 2018-12-19 15:42:02 +01:00
Paulus Schoutsen
4c1d978aa4 Bump pyharmony (#19460) 2018-12-19 15:41:25 +01:00
Paulus Schoutsen
196fe4b927 Bump pyharmony (#19460) 2018-12-19 15:41:14 +01:00
Erik
a9de9aa58d Add testcase test_entity_id_update 2018-12-19 15:28:25 +01:00
Erik
e874093818 Add device registry to MQTT climate 2018-12-19 15:28:25 +01:00
Paulus Schoutsen
b10149c2a0 Merge pull request #19459 from home-assistant/rc
0.84.4
2018-12-19 15:13:42 +01:00
Paulus Schoutsen
c71a6ee562 Updated frontend to 20181219.0 2018-12-19 15:01:02 +01:00
Paulus Schoutsen
57ee514d70 Update translations 2018-12-19 15:01:02 +01:00
Alexei Chetroi
4692605974 ZHA entity ZCL reporting configuration (#19177)
* Implement async_configure() method for ZHA entities.

Allow attribute reporting configuration to be stored as dict of zha
entity.

* Update ZHA platform to use new attribute reporting configuration.

* Use const declaration instead of magic numbers.

* Add support for manufacturer_id in ZCL attribute reporting configuration.

* Refactor async_configure() method.

Rename attribute reporting dict to zcl_reporting_config.
2018-12-19 14:52:20 +01:00
Paulus Schoutsen
2b82830eb1 Bumped version to 0.84.4 2018-12-19 14:23:07 +01:00
ehendrix23
ff1dba3529 Use web sockets for Harmony HUB (#19440)
* Updates to Harmony for web sockets

Updates to harmony to use web sockets with async

* Lint

* Small fixes

* Fix send_command

Continued improvements:
-) Fixed send_command
-) Get HUB configuration during update in case it was not retrieved earlier (i.e. HUB unavailable)

* Further improvements

Completely removed dependency on __main__ for pyharmony, instead everything is now done from the HarmonyClient class.
Writing out Harmony configuration file as a JSON file.
Using same functionality to determine if activity provided is an ID or name for device, allowing send_command to receive a device ID or device name.

* Point requirements to updated pyharmony repo

Updated REQUIREMENTS to point to repository containing the updates for pyharmony.

* lint

lint

* Small fix for device and activity ID

Small fix in checking if provided device or activity ID is valid.

* Pin package version

* No I/O in event loop

* Point at HA fork with correct version bump

* Fix req
2018-12-19 14:23:00 +01:00
Morten Lüneborg
257a91d929 Fix IHC config schema (#19415)
* Update __init__.py

Update "unit" -> "unit_of_measurement" and configuration (from plural to singular)

* Update __init__.py

* Removing vol.ALLOW_EXTRA arguments

* Update __init__.py
2018-12-19 14:22:59 +01:00
ehendrix23
23a579421d Use web sockets for Harmony HUB (#19440)
* Updates to Harmony for web sockets

Updates to harmony to use web sockets with async

* Lint

* Small fixes

* Fix send_command

Continued improvements:
-) Fixed send_command
-) Get HUB configuration during update in case it was not retrieved earlier (i.e. HUB unavailable)

* Further improvements

Completely removed dependency on __main__ for pyharmony, instead everything is now done from the HarmonyClient class.
Writing out Harmony configuration file as a JSON file.
Using same functionality to determine if activity provided is an ID or name for device, allowing send_command to receive a device ID or device name.

* Point requirements to updated pyharmony repo

Updated REQUIREMENTS to point to repository containing the updates for pyharmony.

* lint

lint

* Small fix for device and activity ID

Small fix in checking if provided device or activity ID is valid.

* Pin package version

* No I/O in event loop

* Point at HA fork with correct version bump

* Fix req
2018-12-19 14:21:40 +01:00
emontnemery
1568de62df Correct calls to subscription.async_unsubscribe_topics (#19414)
* Correct calls to subscription.async_unsubscribe_topics

* Review comments

* Add testcases
2018-12-19 14:05:24 +01:00
Paulus Schoutsen
a7e98f12f4 Updated frontend to 20181211.2 2018-12-19 14:04:08 +01:00
Fabian Affolter
8cec559103 Various updates (#19449)
* Various updates

* Fix lint issues
2018-12-19 12:39:16 +01:00
Gido
258fe1f09b Add sensor platform for SolarEdge Monitoring API (#18846)
* Adding sensor for SolarEdge Monitoring API support

* Adding support for Rova garbage calendar

* Update solaredge to pass lint and flake8

* Added solaredge.py to .coveragerc

* Added extend for Voluptuous schema

* Fixed styling issues

* Removed rova.py for later feature

* Replaced API requests with python pip package

* Fixed styling issues

* Updated to new async syntax
Added async_update to sensor class
Added Throttle to SolarEdge data update
Added CONF_NAME to platform settings
Added credentials check for api
Minor code style changes

* Remove unnecessary debug logging

* Updated dict keys

* Added SCAN_INTERVAL
Updated platform setup

* Remove DOMAIN variable
Correct import for PLATFORM_SCHEMA

* Change some debug to error messages
Correct return statements
Remove initial update call

* Fix pylint and flake8 errors
2018-12-19 09:56:45 +01:00
Fredrik Erlandsson
e5487722a8 Add device_info to Daikin (#19372)
* add device_info to Daikin

* Use the constant CONNECTION_NETWORK_MAC from the device registry helper.
2018-12-19 08:18:40 +01:00
Adam Belebczuk
7f0dd442fd Various enhancements for WeMo component/platforms (#19419)
* WeMo - Various fixes and improvements

Various fixes & improvements to the WeMo components, including:
-- Fixes to rediscovery
-- New reset filter service for the WeMo Humidifier
-- Switched the remainder of the WeMo components to async IO
-- Removed any remaining IO in entity properties and moved them to the polling/subscription update process

* WeMo - Fix pywemo version and remove test code from WeMo fan component

* WeMo Humidifier - Add services.yaml entry for reset filter life service

* WeMo - Update binary_sensor component to use asyncio

* WeMo - Add available property to binary_sensor component

* WeMo - Fixed line length issue

* WeMo - Fix issue with discovering the same device multiple times

* WeMo - Fix for the fix for discovering devices multiple times

* WeMo - Fix long lines

* WeMo - Fixes from code review

* WeMo - Breaking Change - entity_ids is now required on wemo_set_humidity

* WeMo - Code review fixes

* WeMo - Code review fixes

* WeMo - Code review fixes
2018-12-19 08:12:32 +01:00
Fabian Affolter
ef6c39f911 Fix typo (#19433) 2018-12-18 19:32:42 +01:00
Otto Winter
7317b1bb8b Miscellaneous ESPHome cleanups (#19425) 2018-12-18 19:04:50 +01:00
Fabian Affolter
c0ae7b1a49 Upgrade requests to 2.21.0 (#19385) 2018-12-18 17:29:38 +01:00
Fabian Affolter
686a856a17 Upgrade sqlalchemy to 1.2.15 (#19383) 2018-12-18 15:48:06 +01:00
Eliseo Martelli
51e6371991 Add Prezzibenzina (Italian Fuel Price) Sensor (#19297)
* complete(?)

* fixed linting

* update requirements

* added to coveragerc

* fixed linting

* added ability to set custom name

* fixed linting

* added filter

* spacing

* Added list of possible fuels

* Minor updates
2018-12-18 15:47:38 +01:00
Fabian Affolter
96c233d4b9 Use string foratting (#19427) 2018-12-18 15:23:53 +01:00
timkoers
17fbeb6245 Fixed the range filter unknown argument precision
In HomeAssistant 0.84.3, the range filter would not work due to the unexpected precision filter parameter. 
The default range scheme has been edited to remove the unexpected precision parameter.

Verified and tested.
2018-12-18 13:21:08 +01:00
Morten Lüneborg
c59e049050 Fix IHC config schema (#19415)
* Update __init__.py

Update "unit" -> "unit_of_measurement" and configuration (from plural to singular)

* Update __init__.py

* Removing vol.ALLOW_EXTRA arguments

* Update __init__.py
2018-12-18 12:40:03 +01:00
Rohan Kapoor
6c64b315db Optionally disable ssl verification for mjpeg (#19277) 2018-12-18 11:22:47 +01:00
Paulus Schoutsen
2f6ef08959 Remove reviewed by hound. That's not worth a badge. 2018-12-18 11:06:30 +01:00
Fabian Affolter
9c8e10936b Add openSenseMap air pollutants platform (#19357)
* Add openSenseMap air pollutants platform

* Fix issues (Docstring, log entries and check)

* Use SCAN_INTERVAL and name handling
2018-12-18 09:15:07 +01:00
John Mihalic
f2c7e3fed4 Bump pyEmby to 1.6, add channel media type mapping (#19318) 2018-12-17 19:16:32 -05:00
Nick Horvath
6adbf3ba84 Add camera selection config to skybell camera (#19310)
* add camera selection config to skybell camera

* code review changes.
2018-12-17 18:31:10 -05:00
Marius Retegan
da10598fa1 Fix cpu_temp issue on Raspberry Pi (#19404) 2018-12-17 18:30:17 -05:00
c-soft
6c8ed86f3e Satel integra monitor outputs (#19149)
* Adjusted api for new library version.

* Added support for output monitoring. Added initial status check for the alarm.

* Added default values to the configuration as per review notes.
2018-12-17 18:28:41 -05:00
jumpkick
f1005d37a7 Cast lametric cycles parameter to int (#19370) 2018-12-18 00:14:55 +01:00
Erik Eriksson
d270d52cb5 Upgrade volvooncall to 0.8.7 (#19398) 2018-12-18 00:08:57 +01:00
Eliseo Martelli
6e26713184 Add GTT Sensor (#18449)
* added gtt sensor

* removed trailing space

* updated requirements_all

* fixed two errors in the code style

* fixed imperative in docstring

* disabled pylint false positive

* fixed description on top of the file

* added files to .coveragerc

* fixes

* linting

* fixed linting 👍

* left a trailing space, now it's gone.

* fix
2018-12-17 18:03:34 -05:00
Sean Dague
e9c19462d6 Provide charging indicator for mychevy (#19348)
* Provide charging indicator for mychevy

This expands the mychevy sensor for the battery level to also know if
the system is currently charging to get the correct icon.

* address review feedback
2018-12-17 17:56:49 -05:00
Fabian Affolter
57ccd8283d Upgade colorlog to 4.0.2 (#19390) 2018-12-17 17:54:07 -05:00
Otto Winter
4ffacec4be Add native ESPHome API service call feature (#19401)
* Add native ESPHome API service call feature

* 🚑 Fix
2018-12-17 21:18:54 +01:00
Otto Winter
44bf5ba001 Add native ESPHome API device registry feature (#19381)
* Add native ESPHome API device registry feature

* 😅 Actually call method

* Run script/gen_requirements_all

* Don't prefix sw_version
2018-12-17 20:54:39 +01:00
Otto Winter
77e4f69af0 ESPHome Native API Restore Entities on startup (#19379)
* Update __init__.py

* Use attr.fields_dict
2018-12-17 20:53:51 +01:00
Otto Winter
8861909ea4 Add native ESPHome API text sensor (#19377)
* Update

* 🚑 Lint
2018-12-17 20:51:59 +01:00
Otto Winter
4b124e4c25 Add native ESPHome API switch (#19376)
* Add esphomelib native API switch

* Update

* 🚑 Lint
2018-12-17 20:50:56 +01:00
Otto Winter
c45beeef6d Add native ESPHome API light (#19375)
* Add esphomelib native API light

* Update

* 🚑 Lint
2018-12-17 20:49:03 +01:00
Otto Winter
a158397b6d Add native ESPHome API fan (#19374)
* Add esphomelib native API fan

* Update

* 🚑 Lint
2018-12-17 20:46:57 +01:00
Otto Winter
a1fb6ae38f Add native ESPHome API cover (#19373)
* Add esphomelib native API cover

* Update

* 🚑 Lint
2018-12-17 20:44:47 +01:00
Otto Winter
8c67ebc143 Add native ESPHome API binary sensor (#19371)
* Add esphomelib native API binary sensor

* Fixes

* 🚑 Lint
2018-12-17 20:40:57 +01:00
Fredrik Erlandsson
40d8bd43a1 fix unique_id for Tellduslive sensors (#19389) 2018-12-17 20:33:01 +01:00
Fabian Affolter
c7ea1d07be Add air pollutants PROP_TO_ATTR (#19336)
* Add PROP_TO_ATTR

* Change condition
2018-12-17 19:38:36 +01:00
Fabian Affolter
e60de53404 Upgrade RPi.GPIO to 0.6.5 (#19392) 2018-12-17 12:31:03 -05:00
Fabian Affolter
3a1dc16c0d Set pytz to >=2018.07 (#19387) 2018-12-17 11:35:13 -05:00
Fabian Affolter
a6568fba7a Upgrade keyrings.alt==3.1.1 (#19386) 2018-12-17 11:34:19 -05:00
Fredrik Erlandsson
0ab9e33110 Version bump pydaikin (#19388)
* version bump pydaikin

* remove requirements from platform
2018-12-17 11:32:10 -05:00
Fabian Affolter
8483850729 Upgrade ruamel.yaml to 0.15.81 (#19384) 2018-12-17 08:28:35 -05:00
Fabian Affolter
90608da5c2 Upgrade TwitterAPI to 2.5.7 (#19382) 2018-12-17 13:52:09 +01:00
Fabian Affolter
6b8835b196 Upgrade youtube_dl to 2018.12.17 (#19378) 2018-12-17 13:28:20 +01:00
Pascal Vizeli
2bf36bb1db Use unicode slugify (#19192)
* Update __init__.py

* Update setup.py

* Update requirements_all.txt

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* remove `-`

* fix packages

* Update package_constraints.txt

* Update __init__.py

* Update package_constraints.txt

* Update requirements_all.txt

* Update setup.py

* Fix tests

* Fix line issue

* fix all test

* fix type

* Fix lint
2018-12-17 07:51:13 +01:00
Aaron Bach
cc90cba78a Add support for statewide data for Flu Near You (#19341)
* Initial changes

* Add support for state-wide data for Flu Near You

* Bumped requirements

* Member comments
2018-12-16 18:51:56 -07:00
Otto Winter
a08bab7b18 Add native ESPHome API component (#19334)
* Create esphomelib component

* Update requirements

* Remove python 2 string literals

* MVP

* Remove config flow

* Remove config flow translations

* Use dispatcher more

* Use data classes

* Type Hints

* Cleanup on remove

* Use helper and cleanup

* Fix HA stop listener cleanup

* Add config flow

* Fix SyntaxError for Py3.5

* Update

* Lint

* Re-do tests

*  Rename to ESPHome

* Better error message for resolve errors

* Fix tests when aioesphomeapi not installed

* Refactor mock

* Update requirements

* Add strings.json

* 🍵 100% config flow  test coverage
2018-12-17 01:29:32 +01:00
Anders Melchiorsen
f9c02889b2 Remove recorder purge protection (#19358) 2018-12-16 23:31:50 +01:00
PeteBa
9d4de2a722 Initialise plant attributes at startup (#19315)
* Initialise plant attributes at startup

* Pvizeli review comments

* Martin review change
2018-12-16 21:54:33 +01:00
Joakim Sørensen
92c5249746 Add traccar motion, speed and battery_level attributes (#19090)
* Added motion, speed and battery attributes.

* Use dict[key] when we know there is a value there.

Co-Authored-By: ludeeus <joasoe@gmail.com>

* Use dict[key] when we know there is a value there.

Co-Authored-By: ludeeus <joasoe@gmail.com>

* Use dict[key] when we know there is a value there.

Co-Authored-By: ludeeus <joasoe@gmail.com>

* Use dict[key] when we know there is a value there.

Co-Authored-By: ludeeus <joasoe@gmail.com>

* Use dict[key] when we know there is a value there.

Co-Authored-By: ludeeus <joasoe@gmail.com>

* Use dict[key] when we know there is a value there.

Co-Authored-By: ludeeus <joasoe@gmail.com>
2018-12-16 20:09:45 +01:00
Glen Takahashi
b031ded671 Fix not being able to update entities (#19344)
When editing an entity in the frontend dialog, pressing save causes a "save failed: Entity is already registered" error. This is because the frontend always sets `name` and `new_entity_id` in the websocket command even if they haven't been changed. This adds a check that the `new_entity_id` is actually different from `entity_id` before erroring that the `new_entity_id` is already registered.
2018-12-16 13:06:27 -05:00
Fredrik Erlandsson
5a295ad42b Add config flow for Daikin (#19182)
* config flow for daikin

* tox test

* return fixes

* tox test fixes

* tox formatting
2018-12-16 16:19:18 +01:00
Jens
266477a4f5 Adds io:OnOffIOComponent as switch to tahoma.py (#19338) 2018-12-16 16:05:21 +01:00
emontnemery
07e3843918 Fix broken sensor.mqtt json_attributes deprecation message (#19349) 2018-12-16 15:44:25 +01:00
Christian Biamont
c26c8affc7 Add Brottsplatskartan sensor (#19018)
* Added brottsplatskartan sensor

* Update brottsplatskartan sensor

* Remove redundant configuration checks.
* Set attributes during initialization.
* Setup brottsplatskartan module in setup_platform().
* Just do a simple return, no need for returning false.

* Remove file that was used during testing

* Better variable name and remove excessive newline.

* More updates to brottsplatskartan

* Import uuid at the top of the module.
* Use sensor as domain.
* Don't fire custom events.
* Remove period from logging message.

* Adding validation for area parameter

* Validate empty area configuration

* Fixing indentation.

* Fixing the config schema
2018-12-16 12:21:07 +01:00
Malte Franken
629dd24ff3 bump georss_client to 0.5 (#19337) 2018-12-16 11:14:36 +01:00
Ville Skyttä
c545d2e22e Upgrade pydocstyle to 3.0.0 (#19328) 2018-12-15 21:11:28 +02:00
Ville Skyttä
06383a4383 Upgrade pytest to 4.0.2 (#19327) 2018-12-15 21:10:55 +02:00
emontnemery
3a7083900c Merge pull request #19223 from emontnemery/mqtt_sensor_json_attributes_topic
Add JSON attribute topic to MQTT sensor
2018-12-15 16:28:34 +01:00
John Mihalic
e2d3beca22 Bump pyEight to fix Single Sleeper (#19316) 2018-12-14 23:25:12 -05:00
Charles Garwood
70dbbbd974 Add note to issue template regarding frontend issues (#19295) 2018-12-14 19:06:20 -05:00
tmd224
d60b7d46b7 Add Ambient Weather PWS Sensor component (#18551)
* Adding ambient_station.py sensor and updating requirements file

* Cleaning up code and fixing flake8 warnings

* Fixing flake8 and pylint warnings

* Adding ambient_station.py sensor and updating requirements file

* Cleaning up code and fixing flake8 warnings

* Fixing flake8 and pylint warnings

* Fixing bug, things are working well now

* removing nosetests file

* Adding changes as requested in pull request #18551

* Updating with more change requests from PR code review

* Removing SCAN_INTERVAL from PLATFORM_SCHEMA

* Removing unused import

* Adding platform schema validation for monitored_conditions and conf_units

* Updating link to documentation in doc-string.  File already named in doc repo

* Only setup platform if component can successfully communicate with API

* Inverting check for platform setup success
2018-12-14 23:53:49 +01:00
Paulus Schoutsen
d83f20f743 Fix tests 2018-12-14 17:58:45 +01:00
Ville Skyttä
1c147b5c5f huawei_lte: Fetch only required data (#17618)
When debug logging is enabled, still fetch everything in order to
provide indication of available/supported data to users, as instructed
in docs.
2018-12-14 14:51:13 +01:00
Colin Harrington
9c62149b00 Adding support for Plum Lightpad (#16576)
* Adding basic Plum Lightpad support - https://plumlife.com/

* Used Const values
is_on is a bool

* Added LightpadPowerMeter Sensor to the plum_lightpad platform

* Moved to async setup, Introduced a PlumManager, events, subscription, Light and Power meter working

* Added PlumMotionSensor

* Added Glow Ring support

* Updated plum library and re-normalized

* set the glow-ring's icon

* Naming the glow ring

* Formatting and linting

* Cleaned up a number of linting issues.  Left a number of documentation warnings

* setup_platform migrated to async_setup_platform Plum discovery run as a job

* bumped plumlightpad version

* On shutdown disconnect the telnet session from each plum lightpad

* Cleanup & formatting. Worked on parallell cloud update

* Moved setup from async to non-async

* Utilize async_call_later from the helpers

* Cleanedup and linted, down to documentation & one #TODO

* Remove commented out debug lines

* Fixed Linting issues

* Remove TODO

* Updated comments & fixed Linting issues

* Added plumlightpad to requirements_all.txt

* Fixing imports with isort

* Added components to .coveragerc

* Added PLUM_DATA constant for accessing hass.data[PLUM_DATA]

* used dictionary syntax vs get(...) for config

* Linting needed an additonal line

* Fully async_setup now. removed @callback utilize bus events for detecting new devices found.

* Upgraded to plumlightpad 0.0.10

* Removed extra unused PLATFORM_SCHEMA declarations

* Moved listener attachment to `async_added_to_hass` and removed unused properties & device_state_attributes

* Utilized Discovery when devices were located

* Linting and cleanup

* used `hass.async_create_task` instead of `hass.async_add_job` per Martin

* Removed redundant criteria in if block

* Without discovery info, there is no need to setup

* Better state management and async on/off for Glow Ring

* renamed async_set_config back to set_config, fixed cleanup callback and Plum Initialization

* Fixed flake8 linting issues

* plumlightpad package update

* Add 'motion' device_class to Motion Sensor

* Fixed last known Linting issue

* let homeassistant handle setting the brightness state

* String formatting vs concatenation

* use shared aiohttp session from homeassistant

* Updating to use new formatting style

* looks like @cleanup isn't neccesary

* ditch the serial awaits

* Ensure async_add_entities is only called once per async_setup_platform

* Creating tasks to wait for vs coroutines

* Remove unused white component in the GlowRing

* Used local variables for GlowRing colors & added a setter for the hs_color property to keep the values in sync

* Linted and added docstring

* Update the documentation path to point to the component page

* Removed the extra sensor and binary_sensor platforms as requested. (To be added in later PRs)

* Update plum_lightpad.py

* Update plum_lightpad.py
2018-12-14 14:42:04 +01:00
liaanvdm
027920ff52 Fix restore state for manual alarm control panel (#19284)
* Fixed manual alarm control panel restore state

* Revert "Fixed manual alarm control panel restore state"

This reverts commit 61c9faf434.

* Fixed manual alarm control panel's state restore
2018-12-14 14:04:04 +01:00
Brian Towles
a30921e67d Set InsteonEntity name to be combo of description and address. (#17262)
* Set InsteonEntity name to be combo of description and address.

ie "LampLinc Dimmer 26453a" or "Keypad Dimmer 291abb_2"

Using a centralized network name

* Updated the name to have a more contextual references for device
functions then just the group id.

* Cleanup for hound

* Removed the _generate_network_address function.  Not used anymore

* Cleanup for lint

* clean for hound

* Moved descriptor mapper to be a class variable of the InsteonEntity in order to fix lib loading issue for lint

* Well, moved DescriptorMapper instance to a function variable now...

* fix hound

* Lint Cleanup

* Clean up docstrings

* Simplify Label lookup based on state name
2018-12-14 14:02:06 +01:00
pbalogh77
7f9cc10447 Device config for Fibaro hub integration (#19171) 2018-12-14 13:35:12 +01:00
Fabian Affolter
b88cf64850 Add air pollutants component (#18707)
* Add air pollutants component

* Fix lint issue

* Update docstrings

* Revert change

* Remove entries

* Remove imports

* Fix variable and other fixes

* Change tests

* Set SCAN_INTERVAL
2018-12-14 13:32:58 +01:00
Erik Eriksson
004179775c Updated ELIQ Online sensor to async API (#19248)
* Updated ELIQ Online sensor to async API

* Remove use of STATE_UNKNOWN
2018-12-14 13:25:28 +01:00
MaxG88
f95bd9c78f Set unavailable when unreachable (#19012)
* Turn GPMDP Off When Unavailable

* Update requirements_all.txt

* Specified Exception Type

* Update gpmdp.py
2018-12-14 13:14:32 +01:00
emontnemery
b97f0c0261 Make variable entity_id available to value_template for MQTT binary sensor (#19195)
* MQTT binary_sensor: Make variable `entity_id` available to value_template

* Review comments

* Add testcase
2018-12-14 13:00:37 +01:00
Eric Nagley
e886576a64 home-assistant/home-assistant#17333: update to use DOMAIN constants and standards. (#19242) 2018-12-14 12:41:09 +01:00
Paulus Schoutsen
bb11b0f067 Merge branch 'master' into dev 2018-12-14 11:22:05 +01:00
emontnemery
7a7c2ad416 Fix race in entity_platform.async_add_entities (#19222) 2018-12-14 10:33:37 +01:00
Luca Angemi
fb680bc1e4 Add automation and script events to logbook filter events (#19253)
* Add automation and script events to logbook filter events

* Update logbook.py

* Update logbook.py

* Update logbook tests

* Update test_logbook.py

* Update test_logbook.py

* Update test_logbook.py

* Update test_logbook.py
2018-12-14 10:25:02 +01:00
Paulus Schoutsen
4f98818258 Rename is_owner decorator to is_admin (#19266)
* Rename is_owner decorator to is_admin

* Update test_auth.py
2018-12-14 10:19:27 +01:00
Paulus Schoutsen
a5a896b519 Check admin permission before able to manage config entries (#19265)
* Check admin permission before able to manage config entries

* Lint
2018-12-14 10:19:04 +01:00
Paulus Schoutsen
0eb0faff03 Add permission check to light service (#19259) 2018-12-14 10:18:36 +01:00
Thibault Maekelbergh
4a23d4c7d3 Add NMBS (Belgian railway) sensor platform (#18610)
* Add custom component to core

* Add pyrail to reqs

* Format & lint

* Sort nmbs.py into place on coveragerc

* Only set up station live if provided

* Only set up sensor if config is provided

* Fix line too long linting error

* PR Remarks

* Add docstrings

* Fix hound line to long error

* Fix quotes

* Rebase coveragerc

* PR Review

* Init empty attrs

* Dont include delay if there is none

* PR review

* Safer check

* Rebase reqs

* Generate req

* Update homeassistant/components/sensor/nmbs.py

Co-Authored-By: thibmaek <thibault.maekelbergh@iCloud.com>

* PR remarks
2018-12-14 09:52:34 +01:00
Eric Nagley
377c61203d Fix call to super() (#19279)
* home-assistant/home-assistant#19273: fix call to super()

* home-assistant/home-assistant#19273: adjust to python3 standards.

* home-assistant/home-assistant#19273: remove bad test.
2018-12-14 08:52:29 +01:00
bremor
74a93fe764 Synology chat add verify ssl (#19276)
* Update synology_chat.py

* Added verify_ssl option to notify.synology_chat

Python requests will verify ssl by default, this configuration options allows the user to specify if they want to verify ssl or not. Non breaking change, default is True - do verify ssl.
2018-12-14 08:42:01 +01:00
Heine Furubotten
ddbfdf14e9 Upgraded enturclient to 0.1.2 (#19267) 2018-12-14 08:33:46 +01:00
Rohan Kapoor
e8ec74b944 Expose ZoneMinder availability to Home Assistant (#18946)
* Expose ZoneMinder availability to Home Assistant

* Bump zm-py to 0.2.0 with the availability changes published
2018-12-14 08:10:54 +01:00
damarco
f60f9bae00 Always add friendly name attribute to ZHA entities (#19141)
* Always add friendly name attribute

* Only change device_info name
2018-12-13 23:08:35 +01:00
Paulus Schoutsen
eada1a184c Improve check for duplicated entity_id (#19194)
* Fail if new entity_id is in hass.states

* Move check to websocket

* Review comments
2018-12-13 20:57:33 +01:00
Paulus Schoutsen
34cfdb4e35 Fix OwnTracks deadlocking (#19260)
* Fix OwnTracks deadlocking

* Fix deadlock
2018-12-13 20:56:48 +01:00
Paulus Schoutsen
85e6f92c5a Lint 2018-12-13 20:08:31 +01:00
Tom Harris
9efb90d23c Resolve IOLinc sensor name (#19050) 2018-12-13 16:52:12 +01:00
Fabian Affolter
66aa7d0e68 Fix list (fixes #19235) (#19258) 2018-12-13 16:43:59 +01:00
Fredrik Erlandsson
9f790325bb Fix point sensor discovery (#19245) 2018-12-13 16:40:56 +01:00
Sander Geerts
0fa7186296 Support for the Harman Kardon AVR (#18471)
* Feature: support for the HK AVR

* Remove testcode

* Feature: support for the HK AVR

* Remove testcode

* Added checklist

* Review fixes whitespaces

* Lint fixes

* Review fixes, add current source

* Remove unused imports

* Review fixes; State constants, dict[key]

* More review fixes, Unknown state and Sources

* Review fix; rename devices to entities
2018-12-13 16:31:14 +01:00
Paulus Schoutsen
90df932fe1 Check admin permission before able to manage config entries 2018-12-13 16:13:43 +01:00
emontnemery
7436c0fe42 Add device registry to MQTT light (#19013) 2018-12-13 15:51:50 +01:00
Erik Eriksson
6766d25e62 Re-use connection-pool (#19249)
Re-use connection-pool of VOC
2018-12-13 12:25:39 +01:00
Paulus Schoutsen
9d9e11372b Make automations log errors (#18965) 2018-12-13 12:21:16 +01:00
Paulus Schoutsen
8ea0a8d40b RFC: Deprecate auto target all for services and introduce entity_id: * (#19006)
* Deprecate auto target all

* Match on word 'all'
2018-12-13 10:07:59 +01:00
Andrey Kupreychik
56c7e78cf2 Bumped NDMS2 client to 0.0.6 (#19244) 2018-12-13 10:01:41 +01:00
Teemu R
2fc0dfecb1 Convert songpal to use asynchronous websocket for state updates (#19129)
* Add websocket-based non-polling variant for songpal

* linting fixes

* changes based on Martin's feedback

* Fix linting

* add backoff timer for reconnects, fix variable naming (I thought that this wouldn't matter for internals..)

* Remove poll configuration variable

* bump the version just to be sure, the previous release lacked a version file (required for setup.py)
2018-12-12 23:05:55 +01:00
kennedyshead
8c6b9b57cd Bump aioasuswrt (#19229)
* bump aioasuswrt version

* run gen_requirements
2018-12-12 20:24:44 +01:00
Aaron Bach
f8438e96d1 Add package data attribute to 17track.net summary sensors (#19213)
* 17track.net: Add package data attribute to summary sensors

* Member comments
2018-12-12 19:07:06 +01:00
Paulus Schoutsen
2926989ec3 Merge remote-tracking branch 'origin/master' into dev 2018-12-12 18:47:41 +01:00
Paulus Schoutsen
7d9e257713 Fix owntracks topic in encrypted ios (#19220)
* Fix owntracks topic

* Warn if per-topic secret and using HTTP
2018-12-12 17:17:27 +01:00
David F. Mulcahey
031ee71adf Add ZHA device handler library (#19099)
* event foundation

* implement quirks

* lock zha-quirks version

* allow quirks handling to be toggled on and off

* revert event commit

* disable warning

* update requirements_all

* Remove fix in favor of #19141

#19141 should be what ultimately corrects this issue.

* review comment
2018-12-12 17:06:22 +01:00
Erik
d03dfd985b Review comments 2018-12-12 16:30:42 +01:00
Erik
0e868deedd Add JSON attribute topic to MQTT sensor 2018-12-12 16:26:44 +01:00
Lukas Barth
4984030871 Fix geizhals crash if no price found (#19197)
* Fix geizhals crash if no price found

* Return None on unknown price.

* Linting

* Linting the linting
2018-12-12 16:11:18 +01:00
Jason Hunter
7de509dc76 Add automation and script events to logbook event types (#19219) 2018-12-12 15:54:25 +01:00
Paulus Schoutsen
6f4657fe02 Revert PR #18602 (#19188) 2018-12-12 11:44:50 +01:00
Fredrik Erlandsson
c0cd2d48ec add unique_id to SMHI (#19183) 2018-12-12 09:29:45 +01:00
Daniel Høyer Iversen
d1eb5da5f4 Update switchbot library (#19202) 2018-12-12 09:16:20 +01:00
Erik
c7492b0feb Move check to websocket 2018-12-11 20:20:57 +01:00
Fredrik Erlandsson
c20322232a Move daikin to package (#19187) 2018-12-11 18:17:45 +01:00
javicalle
61ca9bb8e4 Restore states for RFLink devices (#18816)
* Merge branch 'master' of https://github.com/home-assistant/home-assistant into dev

# Conflicts:
#	homeassistant/components/binary_sensor/point.py
#	homeassistant/components/cloud/__init__.py
#	homeassistant/components/cloud/prefs.py
#	homeassistant/components/frontend/__init__.py
#	homeassistant/components/light/fibaro.py
#	homeassistant/components/logbook.py
#	homeassistant/components/point/__init__.py
#	homeassistant/config_entries.py
#	homeassistant/const.py
#	homeassistant/helpers/service.py
#	requirements_all.txt
#	requirements_test_all.txt

* one 'async_get_last_state' refactor left behind

* Remove RestoreEntity inheritance (already in parent class)

* # pylint: disable=too-many-ancestors

* code predictor can be a bitch

* lint corrections

* # pylint: disable=too-many-ancestors

* recover from dict[key]

* Remove all 'coroutine' decorator, replace for 'async def'
Replace all 'yield from' for 'await'
Replace 'hass.async_add_job' for 'hass.async_create_task'
2018-12-11 17:20:30 +01:00
Erik
1f8156e26c Fail if new entity_id is in hass.states 2018-12-11 17:17:42 +01:00
Fabian Affolter
3e7b908a61 Add SCAN_INTERVAL (#19186)
* Add SCAN_INTERVAL

* More clean-up
2018-12-11 14:12:27 +01:00
Jonathan Keljo
eb4a44535c Enable alarmdecoder to see open/close state of bypassed RF zones when armed (#18477)
* Enable alarmdecoder to see open/close state of bypassed zones when armed

The alarmdecoder component already reported RF state bits as attributes. If the user knows which loop is set up for the zone in the alarm panel, they can use that information to tell whether the zone is open or closed even when the system is armed by monitoring the appropriate attribute. That’s awkward, so this commit enables the user to simply configure which loop is used and the component will update the state itself.

* Simplify, also it's more correct to treat it as a state change rather than a
permanent state, since it's possible the decoder might miss some events.

* Remove relative import
2018-12-11 11:34:03 +01:00
Paulus Schoutsen
ab8cf4f1e4 Updated frontend to 20181211.0 2018-12-11 10:30:24 +01:00
Paulus Schoutsen
557720b094 Fix cloud defaults (#19172) 2018-12-11 06:50:54 +01:00
Fredrik Erlandsson
92e19f6001 TelldusLive config flow (#18758)
* update TelldusLive to use config flow

* fixes from Martin

* Update homeassistant/components/tellduslive/config_flow.py

Co-Authored-By: fredrike <fredrik.e@gmail.com>

* revert changes in entry.py

* tox tests

* tox fixes

* woof woof (fix for hound)

* lint ignore

* unload entry

* coverall toxtests

* fix some toxtests
2018-12-10 18:44:45 +01:00
David F. Mulcahey
f4f42176bd ZHA - Event foundation (#19095)
* event foundation

* add missing periods to comments

* reworked so that entities don't fire events

* lint

* review comments
2018-12-10 10:59:50 -05:00
Paulus Schoutsen
59581786d3 Add raw service data to event (#19163) 2018-12-10 12:58:51 +01:00
Paulus Schoutsen
3cf8610cb3 Updated frontend to 20181210.1 2018-12-10 12:50:30 +01:00
Paulus Schoutsen
802497b05c Google_assistant: fix climate modes (#19084)
* home-assistant/home-assistant#18645: Fix climate mode mapping.

* home-assistant/home-assistant#18645: Remove un-used constants.

* home-assistant/home-assistant#18645: revert heat-cool -> auto change
2018-12-10 12:32:24 +01:00
Eric Nagley
df2f476c67 Google assistant fix target temp for *F values. (#19083)
* home-assistant/home-assistant#18524 : Add rounding to *F temps

* home-assistant/home-assistant#18524 : Linting

* simplify round behavior

* fix trailing whitespace

(thanks github editor)
2018-12-10 12:31:52 +01:00
Paulus Schoutsen
da338f2c1a Fix lovelace save (#19162) 2018-12-10 12:25:08 +01:00
Paulus Schoutsen
fdea9cb426 Drop OwnTracks bad packets (#19161) 2018-12-10 12:24:56 +01:00
Paulus Schoutsen
fe2d24c240 Update translations 2018-12-10 09:54:12 +01:00
Paulus Schoutsen
faab0aa9df Updated frontend to 20181210.0 2018-12-10 09:53:53 +01:00
Paulus Schoutsen
a521b885bf Lovelace using storage (#19101)
* Add MVP

* Remove unused code

* Fix

* Add force back

* Fix tests

* Storage keyed

* Error out when storage doesnt find config

* Use old load_yaml

* Set config for panel correct

* Use instance cache var

* Make config option
2018-12-10 08:57:17 +01:00
Yaron de Leeuw
a744dc270b Update pygtfs to upstream's 0.1.5 (#19151)
This works by adding `?check_same_thread=False` to the sqlite
connection string, as suggested by robbiet480@.
It upgrades pygtfs from homeassitant's forked 0.1.3 version to 0.1.5.

Fixes #15725
2018-12-09 23:32:48 +01:00
clayton craft
866c2ca994 Update radiotherm to 2.0.0 and handle change in tstat error detection (#19107)
* radiotherm: bump version to 2.0.0

* radiotherm: change handling of transient errors from tstat

Radiotherm 2.0.0 now throws an exception when a transient error is
detected, instead of returning -1 for the field where the error was
detected. This change supports handling the exception.
2018-12-09 23:27:31 +01:00
Fabian Affolter
bc8414a6f8 Merge pull request #19148 from scop/upgrade-upcloud
Upgrade upcloud-api to 0.4.3
2018-12-09 23:23:50 +01:00
Fabian Affolter
527f9cdfb2 Upgrade slacker to 0.12.0 (#19142) 2018-12-09 23:23:07 +01:00
Fabian Affolter
4c04fe652c Upgrade sphinx-autodoc-typehints to 1.5.2 (#19140) 2018-12-09 23:22:56 +01:00
Lukas Barth
5e65e27bda Update geizhals dependency (#19152) 2018-12-09 23:22:33 +01:00
Ville Skyttä
7d3a962f73 Upgrade mypy to 0.650 (#19150)
* Upgrade to 0.650

* Remove no longer needed type: ignore
2018-12-09 21:22:08 +02:00
Ville Skyttä
ce998cdc87 Upgrade upcloud-api to 0.4.3 2018-12-09 19:19:13 +02:00
Fabian Affolter
dbbbfaa869 Upgrade youtube_dl to 2018.12.03 (#19139) 2018-12-09 12:38:42 +01:00
Fabian Affolter
863edfd660 Upgrade slacker to 0.12.0 2018-12-09 11:34:53 +01:00
Ludovico de Nittis
4d4967d0dd Add code support for iAlarm (#19124) 2018-12-09 11:08:39 +01:00
Bas Schipper
4b4f51fb6f Fixed doorbird config without events (empty list) (#19121) 2018-12-09 10:33:39 +01:00
arigilder
30064655c2 Remove marking device tracker stale if state is stale (#19133) 2018-12-08 21:27:01 -07:00
edif30
fd5b92b2fb Update Google Assistant services description and request sync timeout (#19113)
* Fix google assistant request sync service call

* More descriptive services.yaml

* Update services.yaml

* Update __init__.py

* Update request sync service call timeout

Change from 5s to 15s to allow Google to respond.  5s was too short.  The service would sync but the service call would time out and throw the error.
2018-12-08 20:39:51 -05:00
Abílio Costa
6e55c2a345 update edp_redy version (#19078)
* update edp_redy version

* update requirements_all.txt
2018-12-08 21:16:16 +01:00
Sebastian Muszynski
2134331e2b Add Philips Moonlight Bedside Lamp support (#18496)
* Add Philips Moonlight Bedside Lamp support

* Update comment

* Make hound happy

* Wrap the call that could raise the exception only

* Remote blank line

* Use updated python-miio API
2018-12-08 14:49:14 +01:00
Daniel Høyer Iversen
ffe83d9ab1 Upgrade Mill library (#19117) 2018-12-08 11:38:42 +01:00
Sebastian Muszynski
f2f649680f Don't avoid async_schedule_update_ha_state by returning false (#19102) 2018-12-08 08:45:03 +01:00
Sebastian Muszynski
ece7b498ed Fix the Xiaomi Aqara Cube rotate event of the LAN protocol 2.0 (Closes: #18199) (#19104) 2018-12-08 08:28:39 +01:00
Sebastian Muszynski
65c2a25736 Support next generation of the Xiaomi Mi Smart Plug (chuangmi.plug.hmi205) (#19071)
* Add next generation of the Xiaomi Mi Smart Plug (chuangmi.plug.hmi205)

* Fix linting
2018-12-07 23:40:48 +01:00
Andrew Hayworth
05586de51f Set lock status correctly for Schlage BE469 Z-Wave locks (#18737)
* Set lock status correctly for Schlage BE469 Z-Wave locks

PR #17386 attempted to improve the state of z-wave lock tracking for
some problematic models. However, it operated under a flawed
assumptions. Namely, that we can always trust `self.values` to have
fresh data, and that the Schlage BE469 sends alarm reports after every
lock event. We can't trust `self.values`, and the Schlage is very
broken. :)

When we receive a notification from the driver about a state change,
we call `update_properties` - but we can (and do!) have _stale_
properties left over from previous updates. #17386 really works best
if you start from a clean slate each time. However, `update_properties`
is called on every value update, and we don't get a reason why.
Moreover, values that weren't just refreshed are not removed. So blindly
looking at something like `self.values.access_control` when deciding to
apply a workaround is not going to always be correct - it may or may not
be, depending on what happened in the past.

For the sad case of the BE469, here are the Z-Wave events that happen
under various circumstances:

RF Lock / Unlock:
- Send: door lock command set
- Receive: door lock report
- Send: door lock command get
- Receive: door lock report

Manual lock / Unlock:
- Receive: alarm
- Send: door lock command get
- Receive: door lock report

Keypad lock / Unlock:
- Receive: alarm
- Send: door lock command get
- Receive: door lock report

Thus, this PR introduces yet another work around - we track the current
and last z-wave command that the driver saw, and make assumptions based
on the sequence of events. This seems to be the most reliable way to go
- simply asking the driver to refresh various states doesn't clear out
alarms the way you would expect; this model doesn't support the access
control logging commands; and trying to manually clear out alarm state
when calling RF lock/unlock was tricky.

The lock state, when the z-wave network restarts, may look out of sync
for a few minutes. However, after the full network restart is complete,
everything looks good in my testing.

* Fix linter
2018-12-07 21:17:34 +01:00
Daniel Høyer Iversen
a58b3aad59 Upgrade Tibber lib (#19098) 2018-12-07 19:33:06 +01:00
Nick Horvath
e567e3d4e7 Bump skybellpy version to fix api issue (#19100) 2018-12-07 19:20:05 +01:00
phnx
385f0298bd home-assistant/home-assistant#18645: revert heat-cool -> auto change 2018-12-07 10:00:56 -05:00
speedmann
7edd241059 Automatically detect if ipv4/ipv6 is used for cert_expiry (#18916)
* Automatically detect if ipv4/ipv6 is used for cert_expiry

Fixes #18818
Python sockets use ipv4 per default. If the domain which should be checked
only has an ipv6 record, socket creation errors out with
`[Errno -2] Name or service not known`
This fix tries to guess the protocol family and creates the socket
with the correct family type

* Fix line length violation
2018-12-07 11:08:41 +01:00
Pierre Ståhl
5bf6951311 Upgrade pyatv to 0.3.12 (#19085) 2018-12-07 11:06:38 +01:00
phnx
24d0aa3f55 home-assistant/home-assistant#18645: Remove un-used constants. 2018-12-07 01:50:48 -05:00
emontnemery
5ff7563070 Merge pull request #18923 from emontnemery/mqtt_binary_sensor_json_attributes_topic
Add JSON attribute topic to MQTT binary sensor
2018-12-07 07:48:55 +01:00
Matthew Garrett
def4e89372 Bump lakeside requirement to support more Eufy devices (#19080)
The T1203 works fine with the existing protocol.
2018-12-07 07:32:21 +01:00
ehendrix23
8a62bc9237 Set directv unavailable state when errors returned for longer then a minute (#19014)
* Fix unavailable

Change setting to unavailable when getting request exceptions only after 1 minute has past since 1st occurrence.

* Put common code in _check_state_available

Put common code to determine if available should be set to False in method _check_state_available
2018-12-07 07:26:49 +01:00
phnx
471d94b6cd home-assistant/home-assistant#18645: Fix climate mode mapping. 2018-12-07 01:15:04 -05:00
Paulus Schoutsen
ce736e7ba1 Updated frontend to 20181207.0 2018-12-07 07:12:59 +01:00
Bram Kragten
455508deac Force refresh Lovelace (#19073)
* Force refresh Lovelace

* Check config on load

* Update __init__.py

* Update __init__.py
2018-12-07 07:09:05 +01:00
Anders Melchiorsen
0a3af545fe Upgrade aiolifx to 0.6.7 (#19077) 2018-12-07 07:06:35 +01:00
Mike Miller
dd92318762 Fix missing colorTemperatureInKelvin from Alexa responses (#19069)
* Fix missing colorTemperatureInKelvin from Alexa responses

* Update smart_home.py

* Add test
2018-12-06 17:05:14 +01:00
Sean Wilson
c931619269 Add CM17A support (#19041)
* Add CM17A support.

* Update log entry
2018-12-06 16:25:58 +01:00
Ville Skyttä
1be440a72b Upgrade pylint to 2.2.2 (#18750)
* Upgrade to 2.2.0

* simplifiable-if-expression fixes

* duplicate-string-formatting-argument fixes

* unused-import fixes

* Upgrade to 2.2.1

* Remove no longer needed disable

* Upgrade to 2.2.2
2018-12-06 11:54:44 +01:00
Paulus Schoutsen
04c7d5c128 Revert #17745 (#19064) 2018-12-06 10:38:26 +01:00
Paulus Schoutsen
30c77b9e64 Bumped version to 0.85.0.dev0 2018-12-06 09:36:44 +01:00
Erik
21197fb968 Review comments 2018-12-04 19:56:34 +01:00
Erik
b9ad19acbf Add JSON attribute topic to MQTT binary sensor
Add MqttAttributes mixin
2018-12-02 17:00:31 +01:00
3270 changed files with 177095 additions and 119427 deletions

View File

@@ -10,429 +10,34 @@ omit =
homeassistant/helpers/signal.py
# omit pieces of code that rely on external devices being present
homeassistant/components/abode.py
homeassistant/components/*/abode.py
homeassistant/components/ads/__init__.py
homeassistant/components/*/ads.py
homeassistant/components/alarmdecoder.py
homeassistant/components/*/alarmdecoder.py
homeassistant/components/amcrest.py
homeassistant/components/*/amcrest.py
homeassistant/components/apcupsd.py
homeassistant/components/*/apcupsd.py
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/android_ip_webcam.py
homeassistant/components/*/android_ip_webcam.py
homeassistant/components/arlo.py
homeassistant/components/*/arlo.py
homeassistant/components/asterisk_mbox.py
homeassistant/components/*/asterisk_mbox.py
homeassistant/components/*/asterisk_cdr.py
homeassistant/components/august.py
homeassistant/components/*/august.py
homeassistant/components/axis.py
homeassistant/components/*/axis.py
homeassistant/components/bbb_gpio.py
homeassistant/components/*/bbb_gpio.py
homeassistant/components/blink/*
homeassistant/components/*/blink.py
homeassistant/components/bloomsky.py
homeassistant/components/*/bloomsky.py
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
homeassistant/components/daikin.py
homeassistant/components/*/daikin.py
homeassistant/components/digital_ocean.py
homeassistant/components/*/digital_ocean.py
homeassistant/components/dominos.py
homeassistant/components/doorbird.py
homeassistant/components/*/doorbird.py
homeassistant/components/dweet.py
homeassistant/components/*/dweet.py
homeassistant/components/eight_sleep.py
homeassistant/components/*/eight_sleep.py
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
homeassistant/components/elkm1/*
homeassistant/components/*/elkm1.py
homeassistant/components/enocean.py
homeassistant/components/*/enocean.py
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/fibaro.py
homeassistant/components/*/fibaro.py
homeassistant/components/gc100.py
homeassistant/components/*/gc100.py
homeassistant/components/google.py
homeassistant/components/*/google.py
homeassistant/components/greeneye_monitor.py
homeassistant/components/sensor/greeneye_monitor.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/hlk_sw16.py
homeassistant/components/*/hlk_sw16.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_plm.py
homeassistant/components/ios.py
homeassistant/components/*/ios.py
homeassistant/components/iota.py
homeassistant/components/*/iota.py
homeassistant/components/isy994.py
homeassistant/components/*/isy994.py
homeassistant/components/joaoapps_join.py
homeassistant/components/*/joaoapps_join.py
homeassistant/components/juicenet.py
homeassistant/components/*/juicenet.py
homeassistant/components/kira.py
homeassistant/components/*/kira.py
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/lightwave.py
homeassistant/components/*/lightwave.py
homeassistant/components/logi_circle.py
homeassistant/components/*/logi_circle.py
homeassistant/components/lupusec.py
homeassistant/components/*/lupusec.py
homeassistant/components/lutron.py
homeassistant/components/*/lutron.py
homeassistant/components/lutron_caseta.py
homeassistant/components/*/lutron_caseta.py
homeassistant/components/*/mailgun.py
homeassistant/components/matrix.py
homeassistant/components/*/matrix.py
homeassistant/components/maxcube.py
homeassistant/components/*/maxcube.py
homeassistant/components/mochad.py
homeassistant/components/*/mochad.py
homeassistant/components/modbus.py
homeassistant/components/*/modbus.py
homeassistant/components/mychevy.py
homeassistant/components/*/mychevy.py
homeassistant/components/mysensors/*
homeassistant/components/*/mysensors.py
homeassistant/components/neato.py
homeassistant/components/*/neato.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/opentherm_gw/*
homeassistant/components/*/opentherm_gw.py
homeassistant/components/openuv/__init__.py
homeassistant/components/*/openuv.py
homeassistant/components/pilight.py
homeassistant/components/*/pilight.py
homeassistant/components/point/__init__.py
homeassistant/components/point/const.py
homeassistant/components/*/point.py
homeassistant/components/switch/qwikswitch.py
homeassistant/components/light/qwikswitch.py
homeassistant/components/rachio.py
homeassistant/components/*/rachio.py
homeassistant/components/raincloud.py
homeassistant/components/*/raincloud.py
homeassistant/components/rainmachine/__init__.py
homeassistant/components/*/rainmachine.py
homeassistant/components/raspihats.py
homeassistant/components/*/raspihats.py
homeassistant/components/rfxtrx.py
homeassistant/components/*/rfxtrx.py
homeassistant/components/rpi_gpio.py
homeassistant/components/*/rpi_gpio.py
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/sense.py
homeassistant/components/*/sense.py
homeassistant/components/simplisafe/__init__.py
homeassistant/components/*/simplisafe.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
homeassistant/components/tahoma.py
homeassistant/components/*/tahoma.py
homeassistant/components/tellduslive/__init__.py
homeassistant/components/tellduslive/entry.py
homeassistant/components/*/tellduslive.py
homeassistant/components/tellstick.py
homeassistant/components/*/tellstick.py
homeassistant/components/tesla.py
homeassistant/components/*/tesla.py
homeassistant/components/thethingsnetwork.py
homeassistant/components/*/thethingsnetwork.py
homeassistant/components/*/thinkingcleaner.py
homeassistant/components/tibber/*
homeassistant/components/*/tibber.py
homeassistant/components/toon.py
homeassistant/components/*/toon.py
homeassistant/components/tplink_lte.py
homeassistant/components/*/tplink_lte.py
homeassistant/components/tradfri.py
homeassistant/components/*/tradfri.py
homeassistant/components/notify/twilio_sms.py
homeassistant/components/notify/twilio_call.py
homeassistant/components/upcloud.py
homeassistant/components/*/upcloud.py
homeassistant/components/usps.py
homeassistant/components/*/usps.py
homeassistant/components/velbus.py
homeassistant/components/*/velbus.py
homeassistant/components/velux.py
homeassistant/components/*/velux.py
homeassistant/components/vera.py
homeassistant/components/*/vera.py
homeassistant/components/verisure.py
homeassistant/components/*/verisure.py
homeassistant/components/volvooncall.py
homeassistant/components/*/volvooncall.py
homeassistant/components/waterfurnace.py
homeassistant/components/*/waterfurnace.py
homeassistant/components/*/webostv.py
homeassistant/components/w800rf32.py
homeassistant/components/*/w800rf32.py
homeassistant/components/wemo.py
homeassistant/components/*/wemo.py
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
homeassistant/components/*/xiaomi_miio.py
homeassistant/components/zabbix.py
homeassistant/components/*/zabbix.py
homeassistant/components/zha/__init__.py
homeassistant/components/zha/const.py
homeassistant/components/zha/entities/*
homeassistant/components/zha/helpers.py
homeassistant/components/*/zha.py
homeassistant/components/zigbee.py
homeassistant/components/*/zigbee.py
homeassistant/components/zoneminder/*
homeassistant/components/*/zoneminder.py
homeassistant/components/tuya.py
homeassistant/components/*/tuya.py
homeassistant/components/spider.py
homeassistant/components/*/spider.py
homeassistant/components/abode/*
homeassistant/components/ads/*
homeassistant/components/air_quality/nilu.py
homeassistant/components/air_quality/norway_air.py
homeassistant/components/air_quality/opensensemap.py
homeassistant/components/alarm_control_panel/alarmdotcom.py
homeassistant/components/alarm_control_panel/canary.py
homeassistant/components/alarm_control_panel/concord232.py
homeassistant/components/alarm_control_panel/ialarm.py
homeassistant/components/alarm_control_panel/ifttt.py
homeassistant/components/alarm_control_panel/manual_mqtt.py
homeassistant/components/alarm_control_panel/nx584.py
homeassistant/components/alarm_control_panel/totalconnect.py
homeassistant/components/alarm_control_panel/yale_smart_alarm.py
homeassistant/components/apiai.py
homeassistant/components/alarmdecoder/*
homeassistant/components/ambient_station/*
homeassistant/components/amcrest/*
homeassistant/components/android_ip_webcam/*
homeassistant/components/androidtv/*
homeassistant/components/apcupsd/*
homeassistant/components/apiai/*
homeassistant/components/apple_tv/*
homeassistant/components/aqualogic/*
homeassistant/components/arduino/*
homeassistant/components/arlo/*
homeassistant/components/asterisk_mbox/*
homeassistant/components/august/*
homeassistant/components/axis/*
homeassistant/components/bbb_gpio/*
homeassistant/components/binary_sensor/arest.py
homeassistant/components/binary_sensor/concord232.py
homeassistant/components/binary_sensor/flic.py
@@ -443,7 +48,10 @@ omit =
homeassistant/components/binary_sensor/rest.py
homeassistant/components/binary_sensor/tapsaff.py
homeassistant/components/binary_sensor/uptimerobot.py
homeassistant/components/browser.py
homeassistant/components/blink/*
homeassistant/components/bloomsky/*
homeassistant/components/bmw_connected_drive/*
homeassistant/components/browser/*
homeassistant/components/calendar/caldav.py
homeassistant/components/calendar/todoist.py
homeassistant/components/camera/bloomsky.py
@@ -460,6 +68,9 @@ omit =
homeassistant/components/camera/xeoma.py
homeassistant/components/camera/xiaomi.py
homeassistant/components/camera/yi.py
homeassistant/components/cast/*
homeassistant/components/cisco_mobility_express/device_tracker.py
homeassistant/components/climate/coolmaster.py
homeassistant/components/climate/ephember.py
homeassistant/components/climate/eq3btsmart.py
homeassistant/components/climate/flexit.py
@@ -475,6 +86,9 @@ omit =
homeassistant/components/climate/touchline.py
homeassistant/components/climate/venstar.py
homeassistant/components/climate/zhong_hong.py
homeassistant/components/cloudflare/*
homeassistant/components/coinbase/*
homeassistant/components/comfoconnect/*
homeassistant/components/cover/aladdin_connect.py
homeassistant/components/cover/brunt.py
homeassistant/components/cover/garadget.py
@@ -485,6 +99,8 @@ omit =
homeassistant/components/cover/opengarage.py
homeassistant/components/cover/rpi_gpio.py
homeassistant/components/cover/scsgate.py
homeassistant/components/daikin/*
homeassistant/components/danfoss_air/*
homeassistant/components/device_tracker/actiontec.py
homeassistant/components/device_tracker/aruba.py
homeassistant/components/device_tracker/asuswrt.py
@@ -495,12 +111,10 @@ omit =
homeassistant/components/device_tracker/bt_home_hub_5.py
homeassistant/components/device_tracker/bt_smarthub.py
homeassistant/components/device_tracker/cisco_ios.py
homeassistant/components/cppm_tracker/device_tracker.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/googlehome.py
homeassistant/components/device_tracker/gpslogger.py
homeassistant/components/device_tracker/hitron_coda.py
homeassistant/components/device_tracker/huawei_router.py
homeassistant/components/device_tracker/icloud.py
@@ -517,6 +131,7 @@ omit =
homeassistant/components/device_tracker/sky_hub.py
homeassistant/components/device_tracker/snmp.py
homeassistant/components/device_tracker/swisscom.py
homeassistant/components/device_tracker/synology_srm.py
homeassistant/components/device_tracker/tado.py
homeassistant/components/device_tracker/thomson.py
homeassistant/components/device_tracker/tile.py
@@ -524,27 +139,95 @@ omit =
homeassistant/components/device_tracker/tplink.py
homeassistant/components/device_tracker/traccar.py
homeassistant/components/device_tracker/trackr.py
homeassistant/components/device_tracker/ubee.py
homeassistant/components/device_tracker/ubus.py
homeassistant/components/downloader.py
homeassistant/components/emoncms_history.py
homeassistant/components/device_tracker/xfinity.py
homeassistant/components/digital_ocean/*
homeassistant/components/dominos/*
homeassistant/components/doorbird/*
homeassistant/components/dovado/*
homeassistant/components/downloader/*
homeassistant/components/dweet/*
homeassistant/components/ebusd/*
homeassistant/components/ecoal_boiler/*
homeassistant/components/ecobee/*
homeassistant/components/ecovacs/*
homeassistant/components/edp_redy/*
homeassistant/components/egardia/*
homeassistant/components/eight_sleep/*
homeassistant/components/elkm1/*
homeassistant/components/emoncms_history/*
homeassistant/components/emulated_hue/upnp.py
homeassistant/components/fan/mqtt.py
homeassistant/components/enigma2/media_player.py
homeassistant/components/enocean/*
homeassistant/components/envisalink/*
homeassistant/components/esphome/__init__.py
homeassistant/components/esphome/binary_sensor.py
homeassistant/components/esphome/cover.py
homeassistant/components/esphome/fan.py
homeassistant/components/esphome/light.py
homeassistant/components/esphome/sensor.py
homeassistant/components/esphome/switch.py
homeassistant/components/eufy/*
homeassistant/components/evohome/*
homeassistant/components/fan/wemo.py
homeassistant/components/folder_watcher.py
homeassistant/components/foursquare.py
homeassistant/components/goalfeed.py
homeassistant/components/ifttt.py
homeassistant/components/fastdotcom/*
homeassistant/components/fibaro/*
homeassistant/components/folder_watcher/*
homeassistant/components/foursquare/*
homeassistant/components/freebox/*
homeassistant/components/fritzbox/*
homeassistant/components/gc100/*
homeassistant/components/goalfeed/*
homeassistant/components/google/*
homeassistant/components/googlehome/*
homeassistant/components/greeneye_monitor/*
homeassistant/components/habitica/*
homeassistant/components/hangouts/__init__.py
homeassistant/components/hangouts/*
homeassistant/components/hangouts/const.py
homeassistant/components/hangouts/hangouts_bot.py
homeassistant/components/hangouts/hangups_utils.py
homeassistant/components/hdmi_cec/*
homeassistant/components/hive/*
homeassistant/components/hlk_sw16/*
homeassistant/components/homekit_controller/*
homeassistant/components/homematic/*
homeassistant/components/homematicip_cloud/*
homeassistant/components/homeworks/*
homeassistant/components/huawei_lte/*
homeassistant/components/hydrawise/*
homeassistant/components/idteck_prox/*
homeassistant/components/ifttt/*
homeassistant/components/ihc/*
homeassistant/components/image_processing/dlib_face_detect.py
homeassistant/components/image_processing/dlib_face_identify.py
homeassistant/components/image_processing/qrcode.py
homeassistant/components/image_processing/seven_segments.py
homeassistant/components/image_processing/tensorflow.py
homeassistant/components/keyboard_remote.py
homeassistant/components/keyboard.py
homeassistant/components/insteon_local/*
homeassistant/components/insteon_plm/*
homeassistant/components/insteon/*
homeassistant/components/ios/*
homeassistant/components/iota/*
homeassistant/components/iperf3/*
homeassistant/components/isy994/*
homeassistant/components/joaoapps_join/*
homeassistant/components/juicenet/*
homeassistant/components/keyboard_remote/*
homeassistant/components/keyboard/*
homeassistant/components/kira/*
homeassistant/components/knx/*
homeassistant/components/konnected/*
homeassistant/components/lametric/*
homeassistant/components/lcn/*
homeassistant/components/lifx/*
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/everlights.py
homeassistant/components/light/flux_led.py
homeassistant/components/light/futurenow.py
homeassistant/components/light/greenwave.py
@@ -552,11 +235,10 @@ omit =
homeassistant/components/light/hyperion.py
homeassistant/components/light/iglo.py
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/nanoleaf.py
homeassistant/components/light/niko_home_control.py
homeassistant/components/light/opple.py
homeassistant/components/light/osramlightify.py
@@ -570,14 +252,25 @@ omit =
homeassistant/components/light/yeelight.py
homeassistant/components/light/yeelightsunflower.py
homeassistant/components/light/zengge.py
homeassistant/components/lirc.py
homeassistant/components/lightwave/*
homeassistant/components/linode/*
homeassistant/components/lirc/*
homeassistant/components/lock/kiwi.py
homeassistant/components/lock/lockitron.py
homeassistant/components/lock/nello.py
homeassistant/components/lock/nuki.py
homeassistant/components/lock/sesame.py
homeassistant/components/map.py
homeassistant/components/media_extractor.py
homeassistant/components/logi_circle/*
homeassistant/components/luftdaten/*
homeassistant/components/lupusec/*
homeassistant/components/lutron_caseta/*
homeassistant/components/lutron/*
homeassistant/components/mailbox/asterisk_cdr.py
homeassistant/components/mailgun/notify.py
homeassistant/components/map/*
homeassistant/components/matrix/*
homeassistant/components/maxcube/*
homeassistant/components/media_extractor/*
homeassistant/components/media_player/anthemav.py
homeassistant/components/media_player/aquostv.py
homeassistant/components/media_player/bluesound.py
@@ -592,10 +285,10 @@ omit =
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/harman_kardon_avr.py
homeassistant/components/media_player/horizon.py
homeassistant/components/media_player/itunes.py
homeassistant/components/media_player/kodi.py
@@ -616,7 +309,6 @@ omit =
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
@@ -631,14 +323,25 @@ omit =
homeassistant/components/media_player/yamaha_musiccast.py
homeassistant/components/media_player/yamaha.py
homeassistant/components/media_player/ziggo_mediabox_xl.py
homeassistant/components/mycroft.py
homeassistant/components/meteo_france/*
homeassistant/components/mobile_app/*
homeassistant/components/mochad/*
homeassistant/components/modbus/*
homeassistant/components/mychevy/*
homeassistant/components/mycroft/*
homeassistant/components/mysensors/*
homeassistant/components/neato/*
homeassistant/components/nest/*
homeassistant/components/netatmo/*
homeassistant/components/netgear_lte/*
homeassistant/components/nissan_leaf/*
homeassistant/components/notify/aws_lambda.py
homeassistant/components/notify/aws_sns.py
homeassistant/components/notify/aws_sqs.py
homeassistant/components/notify/ciscospark.py
homeassistant/components/notify/clickatell.py
homeassistant/components/notify/clicksend.py
homeassistant/components/notify/clicksend_tts.py
homeassistant/components/notify/clicksend.py
homeassistant/components/notify/discord.py
homeassistant/components/notify/flock.py
homeassistant/components/notify/free_mobile.py
@@ -669,17 +372,50 @@ omit =
homeassistant/components/notify/syslog.py
homeassistant/components/notify/telegram.py
homeassistant/components/notify/telstra.py
homeassistant/components/notify/twilio_call.py
homeassistant/components/notify/twilio_sms.py
homeassistant/components/notify/twitter.py
homeassistant/components/notify/xmpp.py
homeassistant/components/nuimo_controller.py
homeassistant/components/prometheus.py
homeassistant/components/rainbird.py
homeassistant/components/nuimo_controller/*
homeassistant/components/octoprint/*
homeassistant/components/opencv/*
homeassistant/components/opentherm_gw/*
homeassistant/components/openuv/__init__.py
homeassistant/components/openuv/binary_sensor.py
homeassistant/components/openuv/sensor.py
homeassistant/components/owlet/*
homeassistant/components/pilight/*
homeassistant/components/plum_lightpad/*
homeassistant/components/point/*
homeassistant/components/prometheus/*
homeassistant/components/ps4/__init__.py
homeassistant/components/ps4/media_player.py
homeassistant/components/qwikswitch/*
homeassistant/components/rachio/*
homeassistant/components/rainbird/*
homeassistant/components/raincloud/*
homeassistant/components/rainmachine/__init__.py
homeassistant/components/rainmachine/binary_sensor.py
homeassistant/components/rainmachine/sensor.py
homeassistant/components/rainmachine/switch.py
homeassistant/components/raspihats/*
homeassistant/components/raspyrfm/*
homeassistant/components/reddit/*
homeassistant/components/remember_the_milk/__init__.py
homeassistant/components/remote/harmony.py
homeassistant/components/remote/itach.py
homeassistant/components/route53.py
homeassistant/components/rfxtrx/*
homeassistant/components/roku/*
homeassistant/components/route53/*
homeassistant/components/rpi_gpio/*
homeassistant/components/rpi_pfio/*
homeassistant/components/sabnzbd/*
homeassistant/components/satel_integra/*
homeassistant/components/scene/hunterdouglas_powerview.py
homeassistant/components/scene/lifx_cloud.py
homeassistant/components/scsgate/*
homeassistant/components/sense/*
homeassistant/components/sensor/aftership.py
homeassistant/components/sensor/airvisual.py
homeassistant/components/sensor/alpha_vantage.py
homeassistant/components/sensor/arest.py
@@ -692,9 +428,11 @@ omit =
homeassistant/components/sensor/bme680.py
homeassistant/components/sensor/bom.py
homeassistant/components/sensor/broadlink.py
homeassistant/components/sensor/brottsplatskartan.py
homeassistant/components/sensor/buienradar.py
homeassistant/components/sensor/cert_expiry.py
homeassistant/components/sensor/citybikes.py
homeassistant/components/sensor/coinbase.py
homeassistant/components/sensor/comed_hourly_pricing.py
homeassistant/components/sensor/cpuspeed.py
homeassistant/components/sensor/crimereports.py
@@ -705,7 +443,6 @@ omit =
homeassistant/components/sensor/dht.py
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
@@ -718,7 +455,6 @@ omit =
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
@@ -731,20 +467,22 @@ omit =
homeassistant/components/sensor/fritzbox_netmonitor.py
homeassistant/components/sensor/gearbest.py
homeassistant/components/sensor/geizhals.py
homeassistant/components/sensor/github.py
homeassistant/components/sensor/gitlab_ci.py
homeassistant/components/sensor/gitter.py
homeassistant/components/sensor/glances.py
homeassistant/components/sensor/google_travel_time.py
homeassistant/components/sensor/gpsd.py
homeassistant/components/sensor/greeneye_monitor.py
homeassistant/components/sensor/gtfs.py
homeassistant/components/sensor/gtt.py
homeassistant/components/sensor/haveibeenpwned.py
homeassistant/components/sensor/hp_ilo.py
homeassistant/components/sensor/htu21d.py
homeassistant/components/sensor/upnp.py
homeassistant/components/sensor/iliad_italy.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
@@ -752,11 +490,10 @@ omit =
homeassistant/components/sensor/launch_library.py
homeassistant/components/sensor/linky.py
homeassistant/components/sensor/linux_battery.py
homeassistant/components/sensor/london_underground.py
homeassistant/components/sensor/loopenergy.py
homeassistant/components/sensor/luftdaten.py
homeassistant/components/sensor/lyft.py
homeassistant/components/sensor/magicseaweed.py
homeassistant/components/sensor/meteo_france.py
homeassistant/components/sensor/metoffice.py
homeassistant/components/sensor/miflora.py
homeassistant/components/sensor/mitemp_bt.py
@@ -766,9 +503,10 @@ omit =
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/netdata.py
homeassistant/components/sensor/neurio_energy.py
homeassistant/components/sensor/nmbs.py
homeassistant/components/sensor/noaa_tides.py
homeassistant/components/sensor/nsw_fuel_station.py
homeassistant/components/sensor/nut.py
@@ -785,6 +523,7 @@ omit =
homeassistant/components/sensor/pocketcasts.py
homeassistant/components/sensor/pollen.py
homeassistant/components/sensor/postnl.py
homeassistant/components/sensor/prezzibenzina.py
homeassistant/components/sensor/pushbullet.py
homeassistant/components/sensor/pvoutput.py
homeassistant/components/sensor/pyload.py
@@ -792,7 +531,10 @@ omit =
homeassistant/components/sensor/qnap.py
homeassistant/components/sensor/radarr.py
homeassistant/components/sensor/rainbird.py
homeassistant/components/sensor/recollect_waste.py
homeassistant/components/sensor/rejseplanen.py
homeassistant/components/sensor/ripple.py
homeassistant/components/sensor/rova.py
homeassistant/components/sensor/rtorrent.py
homeassistant/components/sensor/ruter.py
homeassistant/components/sensor/scrape.py
@@ -800,8 +542,8 @@ omit =
homeassistant/components/sensor/serial_pm.py
homeassistant/components/sensor/serial.py
homeassistant/components/sensor/seventeentrack.py
homeassistant/components/sensor/sht31.py
homeassistant/components/sensor/shodan.py
homeassistant/components/sensor/sht31.py
homeassistant/components/sensor/sigfox.py
homeassistant/components/sensor/simulated.py
homeassistant/components/sensor/skybeacon.py
@@ -809,9 +551,10 @@ omit =
homeassistant/components/sensor/snmp.py
homeassistant/components/sensor/sochain.py
homeassistant/components/sensor/socialblade.py
homeassistant/components/sensor/solaredge.py
homeassistant/components/sensor/sonarr.py
homeassistant/components/sensor/speedtest.py
homeassistant/components/sensor/spotcrime.py
homeassistant/components/sensor/srp_energy.py
homeassistant/components/sensor/starlingbank.py
homeassistant/components/sensor/steam_online.py
homeassistant/components/sensor/supervisord.py
@@ -819,7 +562,6 @@ omit =
homeassistant/components/sensor/swiss_public_transport.py
homeassistant/components/sensor/syncthru.py
homeassistant/components/sensor/synologydsm.py
homeassistant/components/sensor/srp_energy.py
homeassistant/components/sensor/systemmonitor.py
homeassistant/components/sensor/sytadin.py
homeassistant/components/sensor/tank_utility.py
@@ -830,7 +572,6 @@ omit =
homeassistant/components/sensor/time_date.py
homeassistant/components/sensor/torque.py
homeassistant/components/sensor/trafikverket_weatherstation.py
homeassistant/components/sensor/transmission.py
homeassistant/components/sensor/travisci.py
homeassistant/components/sensor/twitch.py
homeassistant/components/sensor/uber.py
@@ -847,8 +588,16 @@ omit =
homeassistant/components/sensor/xbox_live.py
homeassistant/components/sensor/zamg.py
homeassistant/components/sensor/zestimate.py
homeassistant/components/shiftr.py
homeassistant/components/spc.py
homeassistant/components/shiftr/*
homeassistant/components/simplisafe/__init__.py
homeassistant/components/simplisafe/alarm_control_panel.py
homeassistant/components/sisyphus/*
homeassistant/components/skybell/*
homeassistant/components/smappee/*
homeassistant/components/sonos/*
homeassistant/components/spc/*
homeassistant/components/speedtestdotnet/*
homeassistant/components/spider/*
homeassistant/components/switch/acer_projector.py
homeassistant/components/switch/anel_pwrctrl.py
homeassistant/components/switch/arest.py
@@ -864,28 +613,52 @@ omit =
homeassistant/components/switch/mystrom.py
homeassistant/components/switch/netio.py
homeassistant/components/switch/orvibo.py
homeassistant/components/switch/pencom.py
homeassistant/components/switch/pulseaudio_loopback.py
homeassistant/components/switch/rainbird.py
homeassistant/components/switch/rest.py
homeassistant/components/switch/recswitch.py
homeassistant/components/switch/rest.py
homeassistant/components/switch/rpi_rf.py
homeassistant/components/switch/snmp.py
homeassistant/components/switch/sony_projector.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
homeassistant/components/switch/vesync.py
homeassistant/components/tado/*
homeassistant/components/tahoma/*
homeassistant/components/telegram_bot/*
homeassistant/components/thingspeak.py
homeassistant/components/tellduslive/*
homeassistant/components/tellstick/*
homeassistant/components/tesla/*
homeassistant/components/thethingsnetwork/*
homeassistant/components/thingspeak/*
homeassistant/components/thinkingcleaner/*
homeassistant/components/tibber/*
homeassistant/components/tof/sensor.py
homeassistant/components/toon/*
homeassistant/components/tplink_lte/*
homeassistant/components/tradfri/*
homeassistant/components/transmission/*
homeassistant/components/tts/amazon_polly.py
homeassistant/components/tts/baidu.py
homeassistant/components/tts/microsoft.py
homeassistant/components/tts/picotts.py
homeassistant/components/vacuum/mqtt.py
homeassistant/components/tuya/*
homeassistant/components/upcloud/*
homeassistant/components/upnp/*
homeassistant/components/usps/*
homeassistant/components/vacuum/roomba.py
homeassistant/components/velbus/*
homeassistant/components/velux/*
homeassistant/components/vera/*
homeassistant/components/verisure/*
homeassistant/components/volvooncall/*
homeassistant/components/w800rf32/*
homeassistant/components/water_heater/econet.py
homeassistant/components/watson_iot.py
homeassistant/components/waterfurnace/*
homeassistant/components/watson_iot/*
homeassistant/components/weather/bom.py
homeassistant/components/weather/buienradar.py
homeassistant/components/weather/darksky.py
@@ -893,7 +666,29 @@ omit =
homeassistant/components/weather/metoffice.py
homeassistant/components/weather/openweathermap.py
homeassistant/components/weather/zamg.py
homeassistant/components/zeroconf.py
homeassistant/components/webostv/*
homeassistant/components/wemo/*
homeassistant/components/wink/*
homeassistant/components/wirelesstag/*
homeassistant/components/xiaomi_aqara/*
homeassistant/components/xiaomi_miio/*
homeassistant/components/xs1/*
homeassistant/components/zabbix/*
homeassistant/components/zeroconf/*
homeassistant/components/zha/__init__.py
homeassistant/components/zha/api.py
homeassistant/components/zha/const.py
homeassistant/components/zha/core/channels/*
homeassistant/components/zha/core/const.py
homeassistant/components/zha/core/device.py
homeassistant/components/zha/core/gateway.py
homeassistant/components/zha/core/helpers.py
homeassistant/components/zha/device_entity.py
homeassistant/components/zha/entity.py
homeassistant/components/zha/light.py
homeassistant/components/zha/sensor.py
homeassistant/components/zigbee/*
homeassistant/components/zoneminder/*
homeassistant/components/zwave/util.py
[report]

View File

@@ -1,6 +1,8 @@
<!-- 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
- Frontend issues should be submitted to the home-assistant-polymer repository: https://github.com/home-assistant/home-assistant-polymer/issues
- iOS issues should be submitted to the home-assistant-iOS repository: https://github.com/home-assistant/home-assistant-iOS/issues
- 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!

View File

@@ -7,6 +7,8 @@ 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
- Frontend issues should be submitted to the home-assistant-polymer repository: https://github.com/home-assistant/home-assistant-polymer/issues
- iOS issues should be submitted to the home-assistant-iOS repository: https://github.com/home-assistant/home-assistant-iOS/issues
- 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!

View File

@@ -1,3 +1,7 @@
## Breaking Change:
<!-- What is breaking and why we have to break it. Remove this section only if it was NOT a breaking change. -->
## Description:
@@ -27,5 +31,5 @@ If the code communicates with devices, web services, or third-party tools:
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
[ex-requir]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard/__init__.py#L14
[ex-import]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard/__init__.py#L23

41
.github/main.workflow vendored Normal file
View File

@@ -0,0 +1,41 @@
workflow "Python 3.7 - tox" {
resolves = ["Python 3.7 - tests"]
on = "push"
}
action "Python 3.7 - tests" {
uses = "home-assistant/actions/py37-tox@master"
args = "-e py37"
}
workflow "Python 3.6 - tox" {
resolves = ["Python 3.6 - tests"]
on = "push"
}
action "Python 3.6 - tests" {
uses = "home-assistant/actions/py36-tox@master"
args = "-e py36"
}
workflow "Python 3.5 - tox" {
resolves = ["Pyton 3.5 - typing"]
on = "push"
}
action "Python 3.5 - tests" {
uses = "home-assistant/actions/py35-tox@master"
args = "-e py35"
}
action "Python 3.5 - lints" {
uses = "home-assistant/actions/py35-tox@master"
needs = ["Python 3.5 - tests"]
args = "-e lint"
}
action "Pyton 3.5 - typing" {
uses = "home-assistant/actions/py35-tox@master"
args = "-e typing"
needs = ["Python 3.5 - lints"]
}

1
.gitignore vendored
View File

@@ -78,6 +78,7 @@ venv
.venv
Pipfile*
share/*
Scripts/
# vimmy stuff
*.swp

View File

@@ -1,2 +0,0 @@
[settings]
multi_line_output=4

View File

@@ -1,8 +1,18 @@
sudo: false
dist: xenial
addons:
apt:
sources:
- sourceline: "ppa:jonathonf/ffmpeg-4"
packages:
- libudev-dev
- libavformat-dev
- libavcodec-dev
- libavdevice-dev
- libavutil-dev
- libswscale-dev
- libswresample-dev
- libavfilter-dev
matrix:
fast_finish: true
include:
@@ -19,22 +29,19 @@ matrix:
env: TOXENV=py36
- 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:
- $HOME/.cache/pip
install: pip install -U tox coveralls
language: python
script: travis_wait 30 tox --develop
script: travis_wait 40 tox --develop
services:
- docker
before_deploy:

View File

@@ -7,34 +7,34 @@ setup.py @home-assistant/core
homeassistant/*.py @home-assistant/core
homeassistant/helpers/* @home-assistant/core
homeassistant/util/* @home-assistant/core
homeassistant/components/api.py @home-assistant/core
homeassistant/components/api/* @home-assistant/core
homeassistant/components/auth/* @home-assistant/core
homeassistant/components/automation/* @home-assistant/core
homeassistant/components/cloud/* @home-assistant/core
homeassistant/components/config/* @home-assistant/core
homeassistant/components/configurator.py @home-assistant/core
homeassistant/components/configurator/* @home-assistant/core
homeassistant/components/conversation/* @home-assistant/core
homeassistant/components/frontend/* @home-assistant/core
homeassistant/components/group/* @home-assistant/core
homeassistant/components/history.py @home-assistant/core
homeassistant/components/history/* @home-assistant/core
homeassistant/components/http/* @home-assistant/core
homeassistant/components/input_*.py @home-assistant/core
homeassistant/components/introduction.py @home-assistant/core
homeassistant/components/logger.py @home-assistant/core
homeassistant/components/introduction/* @home-assistant/core
homeassistant/components/logger/* @home-assistant/core
homeassistant/components/lovelace/* @home-assistant/core
homeassistant/components/mqtt/* @home-assistant/core
homeassistant/components/panel_custom.py @home-assistant/core
homeassistant/components/panel_iframe.py @home-assistant/core
homeassistant/components/panel_custom/* @home-assistant/core
homeassistant/components/panel_iframe/* @home-assistant/core
homeassistant/components/onboarding/* @home-assistant/core
homeassistant/components/persistent_notification/* @home-assistant/core
homeassistant/components/scene/__init__.py @home-assistant/core
homeassistant/components/scene/hass.py @home-assistant/core
homeassistant/components/script.py @home-assistant/core
homeassistant/components/shell_command.py @home-assistant/core
homeassistant/components/sun.py @home-assistant/core
homeassistant/components/updater.py @home-assistant/core
homeassistant/components/scene/homeassistant.py @home-assistant/core
homeassistant/components/script/* @home-assistant/core
homeassistant/components/shell_command/* @home-assistant/core
homeassistant/components/sun/* @home-assistant/core
homeassistant/components/updater/* @home-assistant/core
homeassistant/components/weblink/* @home-assistant/core
homeassistant/components/websocket_api.py @home-assistant/core
homeassistant/components/websocket_api/* @home-assistant/core
homeassistant/components/zone/* @home-assistant/core
# Home Assistant Developer Teams
@@ -47,12 +47,13 @@ homeassistant/components/*/zwave.py @home-assistant/z-wave
homeassistant/components/hassio/* @home-assistant/hassio
# Individual platforms
homeassistant/components/alarm_control_panel/egardia.py @jeroenterheerdt
homeassistant/components/alarm_control_panel/manual_mqtt.py @colinodell
homeassistant/components/binary_sensor/hikvision.py @mezz64
homeassistant/components/binary_sensor/threshold.py @fabaff
homeassistant/components/binary_sensor/uptimerobot.py @ludeeus
homeassistant/components/camera/push.py @dgomes
homeassistant/components/camera/yi.py @bachya
homeassistant/components/climate/coolmaster.py @OnFreund
homeassistant/components/climate/ephember.py @ttroy50
homeassistant/components/climate/eq3btsmart.py @rytilahti
homeassistant/components/climate/mill.py @danielhiversen
@@ -62,16 +63,14 @@ homeassistant/components/cover/group.py @cdce8p
homeassistant/components/cover/template.py @PhracturedBlue
homeassistant/components/device_tracker/asuswrt.py @kennedyshead
homeassistant/components/device_tracker/automatic.py @armills
homeassistant/components/device_tracker/googlehome.py @ludeeus
homeassistant/components/device_tracker/bt_smarthub.py @jxwolstenholme
homeassistant/components/device_tracker/huawei_router.py @abmantis
homeassistant/components/device_tracker/quantum_gateway.py @cisasteelersfan
homeassistant/components/device_tracker/tile.py @bachya
homeassistant/components/device_tracker/traccar.py @ludeeus
homeassistant/components/device_tracker/bt_smarthub.py @jxwolstenholme
homeassistant/components/history_graph.py @andrey-git
homeassistant/components/influx.py @fabaff
homeassistant/components/device_tracker/synology_srm.py @aerialls
homeassistant/components/device_tracker/xfinity.py @cisasteelersfan
homeassistant/components/light/lifx_legacy.py @amelchio
homeassistant/components/light/tplink.py @rytilahti
homeassistant/components/light/yeelight.py @rytilahti
homeassistant/components/light/yeelightsunflower.py @lindsaymarkward
homeassistant/components/lock/nello.py @pschmitt
@@ -82,19 +81,15 @@ 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/mpd.py @fabaff
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/no_ip.py @fabaff
homeassistant/components/notify/file.py @fabaff
homeassistant/components/notify/flock.py @fabaff
homeassistant/components/notify/instapush.py @fabaff
homeassistant/components/notify/mastodon.py @fabaff
homeassistant/components/notify/smtp.py @fabaff
homeassistant/components/notify/syslog.py @fabaff
homeassistant/components/notify/xmpp.py @fabaff
homeassistant/components/notify/yessssms.py @flowolf
homeassistant/components/plant.py @ChristianKuehnel
homeassistant/components/scene/lifx_cloud.py @amelchio
homeassistant/components/sensor/airvisual.py @bachya
homeassistant/components/sensor/alpha_vantage.py @fabaff
@@ -102,14 +97,16 @@ homeassistant/components/sensor/bitcoin.py @fabaff
homeassistant/components/sensor/cpuspeed.py @fabaff
homeassistant/components/sensor/cups.py @fabaff
homeassistant/components/sensor/darksky.py @fabaff
homeassistant/components/sensor/discogs.py @thibmaek
homeassistant/components/sensor/file.py @fabaff
homeassistant/components/sensor/filter.py @dgomes
homeassistant/components/sensor/fixer.py @fabaff
homeassistant/components/sensor/flunearyou.py.py @bachya
homeassistant/components/sensor/flunearyou.py @bachya
homeassistant/components/sensor/gearbest.py @HerrHofrat
homeassistant/components/sensor/gitter.py @fabaff
homeassistant/components/sensor/glances.py @fabaff
homeassistant/components/sensor/gpsd.py @fabaff
homeassistant/components/sensor/integration.py @dgomes
homeassistant/components/sensor/irish_rail_transport.py @ttroy50
homeassistant/components/sensor/jewish_calendar.py @tsvi
homeassistant/components/sensor/launch_library.py @ludeeus
@@ -118,6 +115,7 @@ homeassistant/components/sensor/miflora.py @danielhiversen @ChristianKuehnel
homeassistant/components/sensor/min_max.py @fabaff
homeassistant/components/sensor/moon.py @fabaff
homeassistant/components/sensor/netdata.py @fabaff
homeassistant/components/sensor/nmbs.py @thibmaek
homeassistant/components/sensor/nsw_fuel_station.py @nickw444
homeassistant/components/sensor/pi_hole.py @fabaff
homeassistant/components/sensor/pollen.py @bachya
@@ -134,140 +132,134 @@ homeassistant/components/sensor/statistics.py @fabaff
homeassistant/components/sensor/swiss*.py @fabaff
homeassistant/components/sensor/sytadin.py @gautric
homeassistant/components/sensor/tautulli.py @ludeeus
homeassistant/components/sensor/time_data.py @fabaff
homeassistant/components/sensor/time_date.py @fabaff
homeassistant/components/sensor/version.py @fabaff
homeassistant/components/sensor/waqi.py @andrey-git
homeassistant/components/sensor/worldclock.py @fabaff
homeassistant/components/shiftr.py @fabaff
homeassistant/components/spaceapi.py @fabaff
homeassistant/components/switch/switchbot.py @danielhiversen
homeassistant/components/switch/switchmate.py @danielhiversen
homeassistant/components/switch/tplink.py @rytilahti
homeassistant/components/vacuum/roomba.py @pschmitt
homeassistant/components/weather/__init__.py @fabaff
homeassistant/components/weather/darksky.py @fabaff
homeassistant/components/weather/demo.py @fabaff
homeassistant/components/weather/met.py @danielhiversen
homeassistant/components/weather/openweathermap.py @fabaff
homeassistant/components/xiaomi_aqara.py @danielhiversen @syssi
# A
homeassistant/components/arduino.py @fabaff
homeassistant/components/*/arduino.py @fabaff
homeassistant/components/ambient_station/* @bachya
homeassistant/components/arduino/* @fabaff
homeassistant/components/axis/* @kane610
homeassistant/components/*/arest.py @fabaff
homeassistant/components/*/axis.py @kane610
# B
homeassistant/components/blink/* @fronzbot
homeassistant/components/*/blink.py @fronzbot
homeassistant/components/bmw_connected_drive.py @ChristianKuehnel
homeassistant/components/*/bmw_connected_drive.py @ChristianKuehnel
homeassistant/components/bmw_connected_drive/* @ChristianKuehnel
homeassistant/components/*/broadlink.py @danielhiversen
# C
homeassistant/components/cloudflare.py @ludeeus
homeassistant/components/cloudflare/* @ludeeus
homeassistant/components/counter/* @fabaff
# D
homeassistant/components/daikin.py @fredrike @rofrantz
homeassistant/components/*/daikin.py @fredrike @rofrantz
homeassistant/components/*/deconz.py @kane610
homeassistant/components/digital_ocean.py @fabaff
homeassistant/components/*/digital_ocean.py @fabaff
homeassistant/components/dweet.py @fabaff
homeassistant/components/*/dweet.py @fabaff
homeassistant/components/daikin/* @fredrike @rofrantz
homeassistant/components/deconz/* @kane610
homeassistant/components/digital_ocean/* @fabaff
homeassistant/components/dweet/* @fabaff
# E
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/ecovacs/* @OverloadUT
homeassistant/components/edp_redy/* @abmantis
homeassistant/components/eight_sleep/* @mezz64
homeassistant/components/egardia/* @jeroenterheerdt
homeassistant/components/esphome/*.py @OttoWinter
# F
homeassistant/components/freebox/*.py @snoof85
# G
homeassistant/components/googlehome/* @ludeeus
# H
homeassistant/components/hive.py @Rendili @KJonline
homeassistant/components/*/hive.py @Rendili @KJonline
homeassistant/components/harmony/* @ehendrix23
homeassistant/components/history_graph/* @andrey-git
homeassistant/components/hive/* @Rendili @KJonline
homeassistant/components/homekit/* @cdce8p
homeassistant/components/huawei_lte.py @scop
homeassistant/components/*/huawei_lte.py @scop
homeassistant/components/huawei_lte/* @scop
# I
homeassistant/components/influx/* @fabaff
homeassistant/components/ipma/* @dgomes
# K
homeassistant/components/knx.py @Julius2342
homeassistant/components/*/knx.py @Julius2342
homeassistant/components/konnected.py @heythisisnate
homeassistant/components/*/konnected.py @heythisisnate
homeassistant/components/knx/* @Julius2342
homeassistant/components/konnected/* @heythisisnate
# L
homeassistant/components/lifx.py @amelchio
homeassistant/components/*/lifx.py @amelchio
homeassistant/components/lifx/* @amelchio
homeassistant/components/luftdaten/* @fabaff
homeassistant/components/*/luftdaten.py @fabaff
# M
homeassistant/components/matrix.py @tinloaf
homeassistant/components/*/matrix.py @tinloaf
homeassistant/components/melissa.py @kennedyshead
homeassistant/components/matrix/* @tinloaf
homeassistant/components/melissa/* @kennedyshead
homeassistant/components/*/melissa.py @kennedyshead
homeassistant/components/*/mystrom.py @fabaff
# N
homeassistant/components/ness_alarm/* @nickw444
homeassistant/components/*/ness_alarm.py @nickw444
homeassistant/components/nissan_leaf/* @filcole
homeassistant/components/no_ip/* @fabaff
# O
homeassistant/components/openuv/* @bachya
homeassistant/components/*/openuv.py @bachya
# P
homeassistant/components/plant/* @ChristianKuehnel
homeassistant/components/point/* @fredrike
homeassistant/components/*/point.py @fredrike
# Q
homeassistant/components/qwikswitch.py @kellerza
homeassistant/components/*/qwikswitch.py @kellerza
homeassistant/components/qwikswitch/* @kellerza
# R
homeassistant/components/rainmachine/* @bachya
homeassistant/components/*/rainmachine.py @bachya
homeassistant/components/rfxtrx/* @danielhiversen
homeassistant/components/*/random.py @fabaff
homeassistant/components/*/rfxtrx.py @danielhiversen
# S
homeassistant/components/shiftr/* @fabaff
homeassistant/components/simplisafe/* @bachya
homeassistant/components/*/simplisafe.py @bachya
homeassistant/components/smartthings/* @andrewsayre
homeassistant/components/sonos/* @amelchio
homeassistant/components/spaceapi/* @fabaff
homeassistant/components/spider/* @peternijssen
# T
homeassistant/components/tahoma.py @philklei
homeassistant/components/*/tahoma.py @philklei
homeassistant/components/tahoma/* @philklei
homeassistant/components/tellduslive/*.py @fredrike
homeassistant/components/*/tellduslive.py @fredrike
homeassistant/components/tesla.py @zabuldon
homeassistant/components/*/tesla.py @zabuldon
homeassistant/components/thethingsnetwork.py @fabaff
homeassistant/components/*/thethingsnetwork.py @fabaff
homeassistant/components/tesla/* @zabuldon
homeassistant/components/thethingsnetwork/* @fabaff
homeassistant/components/tibber/* @danielhiversen
homeassistant/components/*/tibber.py @danielhiversen
homeassistant/components/tplink/* @rytilahti
homeassistant/components/tradfri/* @ggravlingen
homeassistant/components/*/tradfri.py @ggravlingen
homeassistant/components/toon/* @frenck
# U
homeassistant/components/unifi.py @kane610
homeassistant/components/switch/unifi.py @kane610
homeassistant/components/upcloud.py @scop
homeassistant/components/*/upcloud.py @scop
homeassistant/components/unifi/* @kane610
homeassistant/components/upcloud/* @scop
homeassistant/components/utility_meter/* @dgomes
# V
homeassistant/components/velux.py @Julius2342
homeassistant/components/*/velux.py @Julius2342
homeassistant/components/velux/* @Julius2342
# W
homeassistant/components/wemo.py @sqldiablo
homeassistant/components/*/wemo.py @sqldiablo
homeassistant/components/wemo/* @sqldiablo
# X
homeassistant/components/*/xiaomi_aqara.py @danielhiversen @syssi
homeassistant/components/*/xiaomi_miio.py @rytilahti @syssi
homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi
homeassistant/components/xiaomi_miio/* @rytilahti @syssi
# Z
homeassistant/components/zoneminder/ @rohankapoorcom
homeassistant/components/*/zoneminder.py @rohankapoorcom
homeassistant/components/zoneminder/* @rohankapoorcom
# Other code
homeassistant/scripts/check_config.py @kellerza

View File

@@ -2,7 +2,7 @@
# When updating this file, please also update virtualization/Docker/Dockerfile.dev
# This way, the development image and the production image are kept in sync.
FROM python:3.6
FROM python:3.7
LABEL maintainer="Paulus Schoutsen <Paulus@PaulusSchoutsen.nl>"
# Uncomment any of the following lines to disable the installation.
@@ -16,7 +16,6 @@ LABEL maintainer="Paulus Schoutsen <Paulus@PaulusSchoutsen.nl>"
VOLUME /config
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Copy build scripts
@@ -28,7 +27,7 @@ COPY requirements_all.txt requirements_all.txt
# Uninstall enum34 because some dependencies install it but breaks Python 3.4+.
# See PR #8103 for more info.
RUN pip3 install --no-cache-dir -r requirements_all.txt && \
pip3 install --no-cache-dir mysqlclient psycopg2 uvloop cchardet cython tensorflow
pip3 install --no-cache-dir mysqlclient psycopg2 uvloop==0.11.3 cchardet cython tensorflow
# Copy source
COPY . .

View File

@@ -1,4 +1,4 @@
Home Assistant |Build Status| |Coverage Status| |Chat Status| |Reviewed by Hound|
Home Assistant |Build Status| |Coverage Status| |Chat Status|
=================================================================================
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.
@@ -33,8 +33,6 @@ 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

@@ -4,6 +4,23 @@ homeassistant.helpers package
Submodules
----------
homeassistant.helpers.aiohttp_client module
-------------------------------------------
.. automodule:: homeassistant.helpers.aiohttp_client
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.area_registry module
------------------------------------------
.. automodule:: homeassistant.helpers.area_registry
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.condition module
--------------------------------------
@@ -12,6 +29,14 @@ homeassistant.helpers.condition module
:undoc-members:
:show-inheritance:
homeassistant.helpers.config_entry_flow module
----------------------------------------------
.. automodule:: homeassistant.helpers.config_entry_flow
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.config_validation module
----------------------------------------------
@@ -20,6 +45,30 @@ homeassistant.helpers.config_validation module
:undoc-members:
:show-inheritance:
homeassistant.helpers.data_entry_flow module
--------------------------------------------
.. automodule:: homeassistant.helpers.data_entry_flow
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.deprecation module
----------------------------------------
.. automodule:: homeassistant.helpers.depracation
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.device_registry module
--------------------------------------------
.. automodule:: homeassistant.helpers.device_registry
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.discovery module
--------------------------------------
@@ -28,6 +77,14 @@ homeassistant.helpers.discovery module
:undoc-members:
:show-inheritance:
homeassistant.helpers.dispatcher module
---------------------------------------
.. automodule:: homeassistant.helpers.dispatcher
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.entity module
-----------------------------------
@@ -44,6 +101,38 @@ homeassistant.helpers.entity_component module
:undoc-members:
:show-inheritance:
homeassistant.helpers.entity_platform module
--------------------------------------------
.. automodule:: homeassistant.helpers.entity_platform
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.entity_registry module
--------------------------------------------
.. automodule:: homeassistant.helpers.entity_registry
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.entity_values module
------------------------------------------
.. automodule:: homeassistant.helpers.entity_values
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.entityfilter module
-----------------------------------------
.. automodule:: homeassistant.helpers.entityfilter
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.event module
----------------------------------
@@ -52,10 +141,26 @@ homeassistant.helpers.event module
:undoc-members:
:show-inheritance:
homeassistant.helpers.event_decorators module
---------------------------------------------
homeassistant.helpers.icon module
---------------------------------
.. automodule:: homeassistant.helpers.event_decorators
.. automodule:: homeassistant.helpers.icon
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.intent module
-----------------------------------
.. automodule:: homeassistant.helpers.intent
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.json module
---------------------------------
.. automodule:: homeassistant.helpers.json
:members:
:undoc-members:
:show-inheritance:
@@ -68,6 +173,22 @@ homeassistant.helpers.location module
:undoc-members:
:show-inheritance:
homeassistant.helpers.logging module
------------------------------------
.. automodule:: homeassistant.helpers.logging
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.restore_state module
------------------------------------------
.. automodule:: homeassistant.helpers.restore_state
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.script module
-----------------------------------
@@ -84,6 +205,14 @@ homeassistant.helpers.service module
:undoc-members:
:show-inheritance:
homeassistant.helpers.signal module
-----------------------------------
.. automodule:: homeassistant.helpers.signal
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.state module
----------------------------------
@@ -92,6 +221,38 @@ homeassistant.helpers.state module
:undoc-members:
:show-inheritance:
homeassistant.helpers.storage module
------------------------------------
.. automodule:: homeassistant.helpers.storage
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.sun module
--------------------------------
.. automodule:: homeassistant.helpers.sun
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.system_info module
----------------------------------------
.. automodule:: homeassistant.helpers.system_info
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.temperature module
----------------------------------------
.. automodule:: homeassistant.helpers.temperature
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.template module
-------------------------------------
@@ -100,6 +261,14 @@ homeassistant.helpers.template module
:undoc-members:
:show-inheritance:
homeassistant.helpers.translation module
-----------------------------------------
.. automodule:: homeassistant.helpers.translation
:members:
:undoc-members:
:show-inheritance:
homeassistant.helpers.typing module
-----------------------------------

View File

@@ -100,9 +100,21 @@ class AuthManager:
"""Return a list of available auth modules."""
return list(self._mfa_modules.values())
def get_auth_provider(self, provider_type: str, provider_id: str) \
-> Optional[AuthProvider]:
"""Return an auth provider, None if not found."""
return self._providers.get((provider_type, provider_id))
def get_auth_providers(self, provider_type: str) \
-> List[AuthProvider]:
"""Return a List of auth provider of one type, Empty if not found."""
return [provider
for (p_type, _), provider in self._providers.items()
if p_type == provider_type]
def get_auth_mfa_module(self, module_id: str) \
-> Optional[MultiFactorAuthModule]:
"""Return an multi-factor auth module, None if not found."""
"""Return a multi-factor auth module, None if not found."""
return self._mfa_modules.get(module_id)
async def async_get_users(self) -> List[models.User]:
@@ -113,6 +125,11 @@ class AuthManager:
"""Retrieve a user."""
return await self._store.async_get_user(user_id)
async def async_get_owner(self) -> Optional[models.User]:
"""Retrieve the owner."""
users = await self.async_get_users()
return next((user for user in users if user.is_owner), None)
async def async_get_group(self, group_id: str) -> Optional[models.Group]:
"""Retrieve all groups."""
return await self._store.async_get_group(group_id)
@@ -170,8 +187,7 @@ class AuthManager:
user = await self.async_get_user_by_credentials(credentials)
if user is None:
raise ValueError('Unable to find the user.')
else:
return user
return user
auth_provider = self._async_get_auth_provider(credentials)

View File

@@ -11,13 +11,14 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.util import dt as dt_util
from . import models
from .const import GROUP_ID_ADMIN, GROUP_ID_READ_ONLY
from .const import GROUP_ID_ADMIN, GROUP_ID_USER, GROUP_ID_READ_ONLY
from .permissions import PermissionLookup, system_policies
from .permissions.types import PolicyType # noqa: F401
STORAGE_VERSION = 1
STORAGE_KEY = 'auth'
GROUP_NAME_ADMIN = 'Administrators'
GROUP_NAME_USER = "Users"
GROUP_NAME_READ_ONLY = 'Read Only'
@@ -38,6 +39,7 @@ class AuthStore:
self._perm_lookup = None # type: Optional[PermissionLookup]
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY,
private=True)
self._lock = asyncio.Lock()
async def async_get_groups(self) -> List[models.Group]:
"""Retrieve all users."""
@@ -272,8 +274,16 @@ class AuthStore:
async def _async_load(self) -> None:
"""Load the users."""
[ent_reg, data] = await asyncio.gather(
async with self._lock:
if self._users is not None:
return
await self._async_load_task()
async def _async_load_task(self) -> None:
"""Load the users."""
[ent_reg, dev_reg, data] = await asyncio.gather(
self.hass.helpers.entity_registry.async_get_registry(),
self.hass.helpers.device_registry.async_get_registry(),
self._store.async_load(),
)
@@ -282,7 +292,9 @@ class AuthStore:
if self._users is not None:
return
self._perm_lookup = perm_lookup = PermissionLookup(ent_reg)
self._perm_lookup = perm_lookup = PermissionLookup(
ent_reg, dev_reg
)
if data is None:
self._set_defaults()
@@ -297,6 +309,7 @@ class AuthStore:
# 1. Data from a recent version which has a single group without policy
# 2. Data from old version which has no groups
has_admin_group = False
has_user_group = False
has_read_only_group = False
group_without_policy = None
@@ -314,6 +327,13 @@ class AuthStore:
policy = system_policies.ADMIN_POLICY
system_generated = True
elif group_dict['id'] == GROUP_ID_USER:
has_user_group = True
name = GROUP_NAME_USER
policy = system_policies.USER_POLICY
system_generated = True
elif group_dict['id'] == GROUP_ID_READ_ONLY:
has_read_only_group = True
@@ -361,6 +381,10 @@ class AuthStore:
read_only_group = _system_read_only_group()
groups[read_only_group.id] = read_only_group
if not has_user_group:
user_group = _system_user_group()
groups[user_group.id] = user_group
for user_dict in data['users']:
# Collect the users group.
user_groups = []
@@ -475,7 +499,7 @@ class AuthStore:
'name': group.name
} # type: Dict[str, Any]
if group.id not in (GROUP_ID_READ_ONLY, GROUP_ID_ADMIN):
if not group.system_generated:
g_dict['policy'] = group.policy
groups.append(g_dict)
@@ -528,6 +552,8 @@ class AuthStore:
groups = OrderedDict() # type: Dict[str, models.Group]
admin_group = _system_admin_group()
groups[admin_group.id] = admin_group
user_group = _system_user_group()
groups[user_group.id] = user_group
read_only_group = _system_read_only_group()
groups[read_only_group.id] = read_only_group
self._groups = groups
@@ -543,6 +569,16 @@ def _system_admin_group() -> models.Group:
)
def _system_user_group() -> models.Group:
"""Create system user group."""
return models.Group(
name=GROUP_NAME_USER,
id=GROUP_ID_USER,
policy=system_policies.USER_POLICY,
system_generated=True,
)
def _system_read_only_group() -> models.Group:
"""Create read only group."""
return models.Group(

View File

@@ -5,4 +5,5 @@ ACCESS_TOKEN_EXPIRATION = timedelta(minutes=30)
MFA_SESSION_EXPIRATION = timedelta(minutes=5)
GROUP_ID_ADMIN = 'system-admin'
GROUP_ID_USER = 'system-users'
GROUP_ID_READ_ONLY = 'system-read-only'

View File

@@ -2,6 +2,7 @@
Sending HOTP through notify service
"""
import asyncio
import logging
from collections import OrderedDict
from typing import Any, Dict, Optional, List
@@ -90,6 +91,7 @@ class NotifyAuthModule(MultiFactorAuthModule):
self._include = config.get(CONF_INCLUDE, [])
self._exclude = config.get(CONF_EXCLUDE, [])
self._message_template = config[CONF_MESSAGE]
self._init_lock = asyncio.Lock()
@property
def input_schema(self) -> vol.Schema:
@@ -98,15 +100,19 @@ class NotifyAuthModule(MultiFactorAuthModule):
async def _async_load(self) -> None:
"""Load stored data."""
data = await self._user_store.async_load()
async with self._init_lock:
if self._user_settings is not None:
return
if data is None:
data = {STORAGE_USERS: {}}
data = await self._user_store.async_load()
self._user_settings = {
user_id: NotifySetting(**setting)
for user_id, setting in data.get(STORAGE_USERS, {}).items()
}
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."""

View File

@@ -1,4 +1,5 @@
"""Time-based One Time Password auth module."""
import asyncio
import logging
from io import BytesIO
from typing import Any, Dict, Optional, Tuple # noqa: F401
@@ -68,6 +69,7 @@ class TotpAuthModule(MultiFactorAuthModule):
self._users = None # type: Optional[Dict[str, str]]
self._user_store = hass.helpers.storage.Store(
STORAGE_VERSION, STORAGE_KEY, private=True)
self._init_lock = asyncio.Lock()
@property
def input_schema(self) -> vol.Schema:
@@ -76,12 +78,16 @@ class TotpAuthModule(MultiFactorAuthModule):
async def _async_load(self) -> None:
"""Load stored data."""
data = await self._user_store.async_load()
async with self._init_lock:
if self._users is not None:
return
if data is None:
data = {STORAGE_USERS: {}}
data = await self._user_store.async_load()
self._users = data.get(STORAGE_USERS, {})
if data is None:
data = {STORAGE_USERS: {}}
self._users = data.get(STORAGE_USERS, {})
async def _async_save(self) -> None:
"""Save data."""

View File

@@ -1,5 +1,6 @@
"""Permission constants."""
CAT_ENTITIES = 'entities'
CAT_CONFIG_ENTRIES = 'config_entries'
SUBCAT_ALL = 'all'
POLICY_READ = 'read'

View File

@@ -1,12 +1,14 @@
"""Entity permissions."""
from functools import wraps
from typing import Callable, List, Union # noqa: F401
from collections import OrderedDict
from typing import Callable, Optional # noqa: F401
import voluptuous as vol
from .const import SUBCAT_ALL, POLICY_READ, POLICY_CONTROL, POLICY_EDIT
from .models import PermissionLookup
from .types import CategoryType, ValueType
from .types import CategoryType, SubCategoryDict, ValueType
# pylint: disable=unused-import
from .util import SubCatLookupType, lookup_all, compile_policy # noqa
SINGLE_ENTITY_SCHEMA = vol.Any(True, vol.Schema({
vol.Optional(POLICY_READ): True,
@@ -15,6 +17,7 @@ SINGLE_ENTITY_SCHEMA = vol.Any(True, vol.Schema({
}))
ENTITY_DOMAINS = 'domains'
ENTITY_AREAS = 'area_ids'
ENTITY_DEVICE_IDS = 'device_ids'
ENTITY_ENTITY_IDS = 'entity_ids'
@@ -24,148 +27,65 @@ ENTITY_VALUES_SCHEMA = vol.Any(True, vol.Schema({
ENTITY_POLICY_SCHEMA = vol.Any(True, vol.Schema({
vol.Optional(SUBCAT_ALL): SINGLE_ENTITY_SCHEMA,
vol.Optional(ENTITY_AREAS): ENTITY_VALUES_SCHEMA,
vol.Optional(ENTITY_DEVICE_IDS): ENTITY_VALUES_SCHEMA,
vol.Optional(ENTITY_DOMAINS): ENTITY_VALUES_SCHEMA,
vol.Optional(ENTITY_ENTITY_IDS): ENTITY_VALUES_SCHEMA,
}))
def _entity_allowed(schema: ValueType, key: str) \
-> Union[bool, None]:
"""Test if an entity is allowed based on the keys."""
if schema is None or isinstance(schema, bool):
return schema
assert isinstance(schema, dict)
return schema.get(key)
def _lookup_domain(perm_lookup: PermissionLookup,
domains_dict: SubCategoryDict,
entity_id: str) -> Optional[ValueType]:
"""Look up entity permissions by domain."""
return domains_dict.get(entity_id.split(".", 1)[0])
def _lookup_area(perm_lookup: PermissionLookup, area_dict: SubCategoryDict,
entity_id: str) -> Optional[ValueType]:
"""Look up entity permissions by area."""
entity_entry = perm_lookup.entity_registry.async_get(entity_id)
if entity_entry is None or entity_entry.device_id is None:
return None
device_entry = perm_lookup.device_registry.async_get(
entity_entry.device_id
)
if device_entry is None or device_entry.area_id is None:
return None
return area_dict.get(device_entry.area_id)
def _lookup_device(perm_lookup: PermissionLookup,
devices_dict: SubCategoryDict,
entity_id: str) -> Optional[ValueType]:
"""Look up entity permissions by device."""
entity_entry = perm_lookup.entity_registry.async_get(entity_id)
if entity_entry is None or entity_entry.device_id is None:
return None
return devices_dict.get(entity_entry.device_id)
def _lookup_entity_id(perm_lookup: PermissionLookup,
entities_dict: SubCategoryDict,
entity_id: str) -> Optional[ValueType]:
"""Look up entity permission by entity id."""
return entities_dict.get(entity_id)
def compile_entities(policy: CategoryType, perm_lookup: PermissionLookup) \
-> Callable[[str, str], bool]:
"""Compile policy into a function that tests policy."""
# None, Empty Dict, False
if not policy:
def apply_policy_deny_all(entity_id: str, key: str) -> bool:
"""Decline all."""
return False
subcategories = OrderedDict() # type: SubCatLookupType
subcategories[ENTITY_ENTITY_IDS] = _lookup_entity_id
subcategories[ENTITY_DEVICE_IDS] = _lookup_device
subcategories[ENTITY_AREAS] = _lookup_area
subcategories[ENTITY_DOMAINS] = _lookup_domain
subcategories[SUBCAT_ALL] = lookup_all
return apply_policy_deny_all
if policy is True:
def apply_policy_allow_all(entity_id: str, key: str) -> bool:
"""Approve all."""
return True
return apply_policy_allow_all
assert isinstance(policy, dict)
domains = policy.get(ENTITY_DOMAINS)
device_ids = policy.get(ENTITY_DEVICE_IDS)
entity_ids = policy.get(ENTITY_ENTITY_IDS)
all_entities = policy.get(SUBCAT_ALL)
funcs = [] # type: List[Callable[[str, str], Union[None, bool]]]
# The order of these functions matter. The more precise are at the top.
# If a function returns None, they cannot handle it.
# If a function returns a boolean, that's the result to return.
# Setting entity_ids to a boolean is final decision for permissions
# So return right away.
if isinstance(entity_ids, bool):
def allowed_entity_id_bool(entity_id: str, key: str) -> bool:
"""Test if allowed entity_id."""
return entity_ids # type: ignore
return allowed_entity_id_bool
if entity_ids is not None:
def allowed_entity_id_dict(entity_id: str, key: str) \
-> Union[None, bool]:
"""Test if allowed entity_id."""
return _entity_allowed(
entity_ids.get(entity_id), key) # type: ignore
funcs.append(allowed_entity_id_dict)
if isinstance(device_ids, bool):
def allowed_device_id_bool(entity_id: str, key: str) \
-> Union[None, bool]:
"""Test if allowed device_id."""
return device_ids
funcs.append(allowed_device_id_bool)
elif device_ids is not None:
def allowed_device_id_dict(entity_id: str, key: str) \
-> Union[None, bool]:
"""Test if allowed device_id."""
entity_entry = perm_lookup.entity_registry.async_get(entity_id)
if entity_entry is None or entity_entry.device_id is None:
return None
return _entity_allowed(
device_ids.get(entity_entry.device_id), key # type: ignore
)
funcs.append(allowed_device_id_dict)
if isinstance(domains, bool):
def allowed_domain_bool(entity_id: str, key: str) \
-> Union[None, bool]:
"""Test if allowed domain."""
return domains
funcs.append(allowed_domain_bool)
elif domains is not None:
def allowed_domain_dict(entity_id: str, key: str) \
-> Union[None, bool]:
"""Test if allowed domain."""
domain = entity_id.split(".", 1)[0]
return _entity_allowed(domains.get(domain), key) # type: ignore
funcs.append(allowed_domain_dict)
if isinstance(all_entities, bool):
def allowed_all_entities_bool(entity_id: str, key: str) \
-> Union[None, bool]:
"""Test if allowed domain."""
return all_entities
funcs.append(allowed_all_entities_bool)
elif all_entities is not None:
def allowed_all_entities_dict(entity_id: str, key: str) \
-> Union[None, bool]:
"""Test if allowed domain."""
return _entity_allowed(all_entities, key)
funcs.append(allowed_all_entities_dict)
# Can happen if no valid subcategories specified
if not funcs:
def apply_policy_deny_all_2(entity_id: str, key: str) -> bool:
"""Decline all."""
return False
return apply_policy_deny_all_2
if len(funcs) == 1:
func = funcs[0]
@wraps(func)
def apply_policy_func(entity_id: str, key: str) -> bool:
"""Apply a single policy function."""
return func(entity_id, key) is True
return apply_policy_func
def apply_policy_funcs(entity_id: str, key: str) -> bool:
"""Apply several policy functions."""
for func in funcs:
result = func(entity_id, key)
if result is not None:
return result
return False
return apply_policy_funcs
return compile_policy(policy, subcategories, perm_lookup)

View File

@@ -8,6 +8,9 @@ if TYPE_CHECKING:
from homeassistant.helpers import ( # noqa
entity_registry as ent_reg,
)
from homeassistant.helpers import ( # noqa
device_registry as dev_reg,
)
@attr.s(slots=True)
@@ -15,3 +18,4 @@ class PermissionLookup:
"""Class to hold data for permission lookups."""
entity_registry = attr.ib(type='ent_reg.EntityRegistry')
device_registry = attr.ib(type='dev_reg.DeviceRegistry')

View File

@@ -5,6 +5,10 @@ ADMIN_POLICY = {
CAT_ENTITIES: True,
}
USER_POLICY = {
CAT_ENTITIES: True,
}
READ_ONLY_POLICY = {
CAT_ENTITIES: {
SUBCAT_ALL: {

View File

@@ -10,9 +10,11 @@ ValueType = Union[
None
]
# Example: entities.domains = { light: … }
SubCategoryDict = Mapping[str, ValueType]
SubCategoryType = Union[
# Example: entities.domains = { light: … }
Mapping[str, ValueType],
SubCategoryDict,
bool,
None
]

View File

@@ -0,0 +1,98 @@
"""Helpers to deal with permissions."""
from functools import wraps
from typing import Callable, Dict, List, Optional, Union, cast # noqa: F401
from .models import PermissionLookup
from .types import CategoryType, SubCategoryDict, ValueType
LookupFunc = Callable[[PermissionLookup, SubCategoryDict, str],
Optional[ValueType]]
SubCatLookupType = Dict[str, LookupFunc]
def lookup_all(perm_lookup: PermissionLookup, lookup_dict: SubCategoryDict,
object_id: str) -> ValueType:
"""Look up permission for all."""
# In case of ALL category, lookup_dict IS the schema.
return cast(ValueType, lookup_dict)
def compile_policy(
policy: CategoryType, subcategories: SubCatLookupType,
perm_lookup: PermissionLookup
) -> Callable[[str, str], bool]: # noqa
"""Compile policy into a function that tests policy.
Subcategories are mapping key -> lookup function, ordered by highest
priority first.
"""
# None, False, empty dict
if not policy:
def apply_policy_deny_all(entity_id: str, key: str) -> bool:
"""Decline all."""
return False
return apply_policy_deny_all
if policy is True:
def apply_policy_allow_all(entity_id: str, key: str) -> bool:
"""Approve all."""
return True
return apply_policy_allow_all
assert isinstance(policy, dict)
funcs = [] # type: List[Callable[[str, str], Union[None, bool]]]
for key, lookup_func in subcategories.items():
lookup_value = policy.get(key)
# If any lookup value is `True`, it will always be positive
if isinstance(lookup_value, bool):
return lambda object_id, key: True
if lookup_value is not None:
funcs.append(_gen_dict_test_func(
perm_lookup, lookup_func, lookup_value))
if len(funcs) == 1:
func = funcs[0]
@wraps(func)
def apply_policy_func(object_id: str, key: str) -> bool:
"""Apply a single policy function."""
return func(object_id, key) is True
return apply_policy_func
def apply_policy_funcs(object_id: str, key: str) -> bool:
"""Apply several policy functions."""
for func in funcs:
result = func(object_id, key)
if result is not None:
return result
return False
return apply_policy_funcs
def _gen_dict_test_func(
perm_lookup: PermissionLookup,
lookup_func: LookupFunc,
lookup_dict: SubCategoryDict
) -> Callable[[str, str], Optional[bool]]: # noqa
"""Generate a lookup function."""
def test_value(object_id: str, key: str) -> Optional[bool]:
"""Test if permission is allowed based on the keys."""
schema = lookup_func(
perm_lookup, lookup_dict, object_id) # type: ValueType
if schema is None or isinstance(schema, bool):
return schema
assert isinstance(schema, dict)
return schema.get(key)
return test_value

View File

@@ -0,0 +1,164 @@
"""Auth provider that validates credentials via an external command."""
from typing import Any, Dict, Optional, cast
import asyncio.subprocess
import collections
import logging
import os
import voluptuous as vol
from homeassistant.exceptions import HomeAssistantError
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
from ..models import Credentials, UserMeta
CONF_COMMAND = "command"
CONF_ARGS = "args"
CONF_META = "meta"
CONFIG_SCHEMA = AUTH_PROVIDER_SCHEMA.extend({
vol.Required(CONF_COMMAND): vol.All(
str,
os.path.normpath,
msg="must be an absolute path"
),
vol.Optional(CONF_ARGS, default=None): vol.Any(vol.DefaultTo(list), [str]),
vol.Optional(CONF_META, default=False): bool,
}, extra=vol.PREVENT_EXTRA)
_LOGGER = logging.getLogger(__name__)
class InvalidAuthError(HomeAssistantError):
"""Raised when authentication with given credentials fails."""
@AUTH_PROVIDERS.register("command_line")
class CommandLineAuthProvider(AuthProvider):
"""Auth provider validating credentials by calling a command."""
DEFAULT_TITLE = "Command Line Authentication"
# which keys to accept from a program's stdout
ALLOWED_META_KEYS = ("name",)
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Extend parent's __init__.
Adds self._user_meta dictionary to hold the user-specific
attributes provided by external programs.
"""
super().__init__(*args, **kwargs)
self._user_meta = {} # type: Dict[str, Dict[str, Any]]
async def async_login_flow(self, context: Optional[dict]) -> LoginFlow:
"""Return a flow to login."""
return CommandLineLoginFlow(self)
async def async_validate_login(self, username: str, password: str) -> None:
"""Validate a username and password."""
env = {
"username": username,
"password": password,
}
try:
# pylint: disable=no-member
process = await asyncio.subprocess.create_subprocess_exec(
self.config[CONF_COMMAND], *self.config[CONF_ARGS],
env=env,
stdout=asyncio.subprocess.PIPE
if self.config[CONF_META] else None,
)
stdout, _ = (await process.communicate())
except OSError as err:
# happens when command doesn't exist or permission is denied
_LOGGER.error("Error while authenticating %r: %s",
username, err)
raise InvalidAuthError
if process.returncode != 0:
_LOGGER.error("User %r failed to authenticate, command exited "
"with code %d.",
username, process.returncode)
raise InvalidAuthError
if self.config[CONF_META]:
meta = {} # type: Dict[str, str]
for _line in stdout.splitlines():
try:
line = _line.decode().lstrip()
if line.startswith("#"):
continue
key, value = line.split("=", 1)
except ValueError:
# malformed line
continue
key = key.strip()
value = value.strip()
if key in self.ALLOWED_META_KEYS:
meta[key] = value
self._user_meta[username] = meta
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.
Currently, only name is supported.
"""
meta = self._user_meta.get(credentials.data["username"], {})
return UserMeta(
name=meta.get("name"),
is_active=True,
)
class CommandLineLoginFlow(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:
user_input["username"] = user_input["username"].strip()
try:
await cast(CommandLineAuthProvider, 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 = collections.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

@@ -1,7 +1,10 @@
"""Home Assistant auth provider."""
import asyncio
import base64
from collections import OrderedDict
from typing import Any, Dict, List, Optional, cast
import logging
from typing import Any, Dict, List, Optional, Set, cast # noqa: F401
import bcrypt
import voluptuous as vol
@@ -51,6 +54,18 @@ class Data:
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY,
private=True)
self._data = None # type: Optional[Dict[str, Any]]
# Legacy mode will allow usernames to start/end with whitespace
# and will compare usernames case-insensitive.
# Remove in 2020 or when we launch 1.0.
self.is_legacy = False
@callback
def normalize_username(self, username: str) -> str:
"""Normalize a username based on the mode."""
if self.is_legacy:
return username
return username.strip().casefold()
async def async_load(self) -> None:
"""Load stored data."""
@@ -61,6 +76,37 @@ class Data:
'users': []
}
seen = set() # type: Set[str]
for user in data['users']:
username = user['username']
# check if we have duplicates
folded = username.casefold()
if folded in seen:
self.is_legacy = True
logging.getLogger(__name__).warning(
"Home Assistant auth provider is running in legacy mode "
"because we detected usernames that are case-insensitive"
"equivalent. Please change the username: '%s'.", username)
break
seen.add(folded)
# check if we have unstripped usernames
if username != username.strip():
self.is_legacy = True
logging.getLogger(__name__).warning(
"Home Assistant auth provider is running in legacy mode "
"because we detected usernames that start or end in a "
"space. Please change the username: '%s'.", username)
break
self._data = data
@property
@@ -73,12 +119,13 @@ class Data:
Raises InvalidAuth if auth invalid.
"""
username = self.normalize_username(username)
dummy = b'$2b$12$CiuFGszHx9eNHxPuQcwBWez4CwDTOcLTX5CbOpV6gef2nYuXkY7BO'
found = None
# Compare all users to avoid timing attacks.
for user in self.users:
if username == user['username']:
if self.normalize_username(user['username']) == username:
found = user
if found is None:
@@ -105,7 +152,10 @@ class Data:
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):
username = self.normalize_username(username)
if any(self.normalize_username(user['username']) == username
for user in self.users):
raise InvalidUser
self.users.append({
@@ -116,9 +166,11 @@ class Data:
@callback
def async_remove_auth(self, username: str) -> None:
"""Remove authentication."""
username = self.normalize_username(username)
index = None
for i, user in enumerate(self.users):
if user['username'] == username:
if self.normalize_username(user['username']) == username:
index = i
break
@@ -132,8 +184,10 @@ class Data:
Raises InvalidUser if user cannot be found.
"""
username = self.normalize_username(username)
for user in self.users:
if user['username'] == username:
if self.normalize_username(user['username']) == username:
user['password'] = self.hash_password(
new_password, True).decode()
break
@@ -151,15 +205,21 @@ class HassAuthProvider(AuthProvider):
DEFAULT_TITLE = 'Home Assistant Local'
data = None
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Initialize an Home Assistant auth provider."""
super().__init__(*args, **kwargs)
self.data = None # type: Optional[Data]
self._init_lock = asyncio.Lock()
async def async_initialize(self) -> None:
"""Initialize the auth provider."""
if self.data is not None:
return
async with self._init_lock:
if self.data is not None:
return
self.data = Data(self.hass)
await self.data.async_load()
data = Data(self.hass)
await data.async_load()
self.data = data
async def async_login_flow(
self, context: Optional[Dict]) -> LoginFlow:
@@ -178,10 +238,15 @@ class HassAuthProvider(AuthProvider):
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']
if self.data is None:
await self.async_initialize()
assert self.data is not None
norm_username = self.data.normalize_username
username = norm_username(flow_result['username'])
for credential in await self.async_credentials():
if credential.data['username'] == username:
if norm_username(credential.data['username']) == username:
return credential
# Create new credentials.

View File

@@ -4,27 +4,23 @@ Support Legacy API password auth provider.
It will be removed when auth system production ready
"""
import hmac
from typing import Any, Dict, Optional, cast, TYPE_CHECKING
from typing import Any, Dict, Optional, cast
import voluptuous as vol
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.config_validation as cv
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
from .. import AuthManager
from ..models import Credentials, UserMeta, User
if TYPE_CHECKING:
from homeassistant.components.http import HomeAssistantHTTP # noqa: F401
USER_SCHEMA = vol.Schema({
vol.Required('username'): str,
})
AUTH_PROVIDER_TYPE = 'legacy_api_password'
CONF_API_PASSWORD = 'api_password'
CONFIG_SCHEMA = AUTH_PROVIDER_SCHEMA.extend({
vol.Required(CONF_API_PASSWORD): cv.string,
}, extra=vol.PREVENT_EXTRA)
LEGACY_USER_NAME = 'Legacy API password user'
@@ -34,40 +30,45 @@ class InvalidAuthError(HomeAssistantError):
"""Raised when submitting invalid authentication."""
async def async_get_user(hass: HomeAssistant) -> User:
"""Return the legacy API password user."""
async def async_validate_password(hass: HomeAssistant, password: str)\
-> Optional[User]:
"""Return a user if password is valid. None if not."""
auth = cast(AuthManager, hass.auth) # type: ignore
found = None
for prv in auth.auth_providers:
if prv.type == 'legacy_api_password':
found = prv
break
if found is None:
providers = auth.get_auth_providers(AUTH_PROVIDER_TYPE)
if not providers:
raise ValueError('Legacy API password provider not found')
return await auth.async_get_or_create_user(
await found.async_get_or_create_credentials({})
)
try:
provider = cast(LegacyApiPasswordAuthProvider, providers[0])
provider.async_validate_login(password)
return await auth.async_get_or_create_user(
await provider.async_get_or_create_credentials({})
)
except InvalidAuthError:
return None
@AUTH_PROVIDERS.register('legacy_api_password')
@AUTH_PROVIDERS.register(AUTH_PROVIDER_TYPE)
class LegacyApiPasswordAuthProvider(AuthProvider):
"""Example auth provider based on hardcoded usernames and passwords."""
"""An auth provider support legacy api_password."""
DEFAULT_TITLE = 'Legacy API Password'
@property
def api_password(self) -> str:
"""Return api_password."""
return str(self.config[CONF_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
"""Validate password."""
api_password = str(self.config[CONF_API_PASSWORD])
if not hmac.compare_digest(hass_http.api_password.encode('utf-8'),
if not hmac.compare_digest(api_password.encode('utf-8'),
password.encode('utf-8')):
raise InvalidAuthError
@@ -99,12 +100,6 @@ class LegacyLoginFlow(LoginFlow):
"""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)\

View File

@@ -3,18 +3,23 @@
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
from ipaddress import ip_network, IPv4Address, IPv6Address, IPv4Network,\
IPv6Network
from typing import Any, Dict, List, Optional, Union, cast
import voluptuous as vol
from homeassistant.components.http import HomeAssistantHTTP # noqa: F401
import homeassistant.helpers.config_validation as cv
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
from ..models import Credentials, UserMeta
IPAddress = Union[IPv4Address, IPv6Address]
IPNetwork = Union[IPv4Network, IPv6Network]
CONFIG_SCHEMA = AUTH_PROVIDER_SCHEMA.extend({
vol.Required('trusted_networks'): vol.All(cv.ensure_list, [ip_network])
}, extra=vol.PREVENT_EXTRA)
@@ -35,6 +40,11 @@ class TrustedNetworksAuthProvider(AuthProvider):
DEFAULT_TITLE = 'Trusted Networks'
@property
def trusted_networks(self) -> List[IPNetwork]:
"""Return trusted networks."""
return cast(List[IPNetwork], self.config['trusted_networks'])
@property
def support_mfa(self) -> bool:
"""Trusted Networks auth provider does not support MFA."""
@@ -49,7 +59,7 @@ class TrustedNetworksAuthProvider(AuthProvider):
if not user.system_generated and user.is_active}
return TrustedNetworksLoginFlow(
self, cast(str, context.get('ip_address')), available_users)
self, cast(IPAddress, context.get('ip_address')), available_users)
async def async_get_or_create_credentials(
self, flow_result: Dict[str, str]) -> Credentials:
@@ -80,19 +90,17 @@ class TrustedNetworksAuthProvider(AuthProvider):
raise NotImplementedError
@callback
def async_validate_access(self, ip_address: str) -> None:
def async_validate_access(self, ip_addr: IPAddress) -> 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:
if not self.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):
if not any(ip_addr in trusted_network for trusted_network
in self.trusted_networks):
raise InvalidAuthError('Not in trusted_networks')
@@ -100,12 +108,12 @@ class TrustedNetworksLoginFlow(LoginFlow):
"""Handler for the login flow."""
def __init__(self, auth_provider: TrustedNetworksAuthProvider,
ip_address: str, available_users: Dict[str, Optional[str]]) \
-> None:
ip_addr: IPAddress,
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
self._ip_address = ip_addr
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \

View File

@@ -5,12 +5,13 @@ import os
import sys
from time import time
from collections import OrderedDict
from typing import Any, Optional, Dict
from typing import Any, Optional, Dict, Set
import voluptuous as vol
from homeassistant import (
core, config as conf_util, config_entries, components as core_components)
core, config as conf_util, config_entries, components as core_components,
loader)
from homeassistant.components import persistent_notification
from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE
from homeassistant.setup import async_setup_component
@@ -18,6 +19,7 @@ from homeassistant.util.logging import AsyncHandler
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 import config_validation as cv
_LOGGER = logging.getLogger(__name__)
@@ -26,8 +28,16 @@ ERROR_LOG_FILENAME = 'home-assistant.log'
# hass.data key for logging information.
DATA_LOGGING = 'logging'
FIRST_INIT_COMPONENT = {'system_log', 'recorder', 'mqtt', 'mqtt_eventstream',
'logger', 'introduction', 'frontend', 'history'}
LOGGING_COMPONENT = {'logger', 'system_log'}
FIRST_INIT_COMPONENT = {
'recorder',
'mqtt',
'mqtt_eventstream',
'introduction',
'frontend',
'history',
}
def from_config_dict(config: Dict[str, Any],
@@ -83,14 +93,18 @@ async def async_from_config_dict(config: Dict[str, Any],
async_enable_logging(hass, verbose, log_rotate_days, log_file,
log_no_color)
hass.config.skip_pip = skip_pip
if skip_pip:
_LOGGER.warning("Skipping pip installation of required modules. "
"This may cause issues")
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'))
api_password = config.get('http', {}).get('api_password')
trusted_networks = config.get('http', {}).get('trusted_networks')
try:
await conf_util.async_process_ha_core_config(
hass, core_config, has_api_password, has_trusted_networks)
hass, core_config, api_password, trusted_networks)
except vol.Invalid as config_err:
conf_util.async_log_exception(
config_err, 'homeassistant', core_config, hass)
@@ -103,11 +117,6 @@ async def async_from_config_dict(config: Dict[str, Any],
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")
# Make a copy because we are mutating it.
config = OrderedDict(config)
@@ -116,12 +125,18 @@ async def async_from_config_dict(config: Dict[str, Any],
hass, config, core_config.get(conf_util.CONF_PACKAGES, {}))
hass.config_entries = config_entries.ConfigEntries(hass, config)
await hass.config_entries.async_load()
await hass.config_entries.async_initialize()
# Filter out the repeating and common config section [homeassistant]
components = set(key.split(' ')[0] for key in config.keys()
if key != core.DOMAIN)
components.update(hass.config_entries.async_domains())
components = _get_components(hass, config)
# Resolve all dependencies of all components.
for component in list(components):
try:
components.update(loader.component_dependencies(hass, component))
except loader.LoaderError:
# Ignore it, or we'll break startup
# It will be properly handled during setup.
pass
# setup components
res = await core_components.async_setup(hass, config)
@@ -134,17 +149,25 @@ async def async_from_config_dict(config: Dict[str, Any],
_LOGGER.info("Home Assistant core initialized")
# stage 0, load logging components
for component in components:
if component in LOGGING_COMPONENT:
hass.async_create_task(
async_setup_component(hass, component, config))
await hass.async_block_till_done()
# stage 1
for component in components:
if component not in FIRST_INIT_COMPONENT:
continue
hass.async_create_task(async_setup_component(hass, component, config))
if component in FIRST_INIT_COMPONENT:
hass.async_create_task(
async_setup_component(hass, component, config))
await hass.async_block_till_done()
# stage 2
for component in components:
if component in FIRST_INIT_COMPONENT:
if component in FIRST_INIT_COMPONENT or component in LOGGING_COMPONENT:
continue
hass.async_create_task(async_setup_component(hass, component, config))
@@ -153,6 +176,51 @@ async def async_from_config_dict(config: Dict[str, Any],
stop = time()
_LOGGER.info("Home Assistant initialized in %.2fs", stop-start)
# TEMP: warn users for invalid slugs
# Remove after 0.94 or 1.0
if cv.INVALID_SLUGS_FOUND or cv.INVALID_ENTITY_IDS_FOUND:
msg = []
if cv.INVALID_ENTITY_IDS_FOUND:
msg.append(
"Your configuration contains invalid entity ID references. "
"Please find and update the following. "
"This will become a breaking change."
)
msg.append('\n'.join('- {} -> {}'.format(*item)
for item
in cv.INVALID_ENTITY_IDS_FOUND.items()))
if cv.INVALID_SLUGS_FOUND:
msg.append(
"Your configuration contains invalid slugs. "
"Please find and update the following. "
"This will become a breaking change."
)
msg.append('\n'.join('- {} -> {}'.format(*item)
for item in cv.INVALID_SLUGS_FOUND.items()))
hass.components.persistent_notification.async_create(
'\n\n'.join(msg), "Config Warning", "config_warning"
)
# TEMP: warn users of invalid extra keys
# Remove after 0.92
if cv.INVALID_EXTRA_KEYS_FOUND:
msg = []
msg.append(
"Your configuration contains extra keys "
"that the platform does not support (but were silently "
"accepted before 0.88). Please find and remove the following."
"This will become a breaking change."
)
msg.append('\n'.join('- {}'.format(it)
for it in cv.INVALID_EXTRA_KEYS_FOUND))
hass.components.persistent_notification.async_create(
'\n\n'.join(msg), "Config Warning", "config_warning"
)
return hass
@@ -320,3 +388,21 @@ async def async_mount_local_lib_path(config_dir: str) -> str:
if lib_dir not in sys.path:
sys.path.insert(0, lib_dir)
return deps_dir
@core.callback
def _get_components(hass: core.HomeAssistant,
config: Dict[str, Any]) -> Set[str]:
"""Get components to set up."""
# Filter out the repeating and common config section [homeassistant]
components = set(key.split(' ')[0] for key in config.keys()
if key != core.DOMAIN)
# Add config entry domains
components.update(hass.config_entries.async_domains()) # type: ignore
# Make sure the Hass.io component is loaded
if 'HASSIO' in os.environ:
components.add('hassio')
return components

View File

@@ -17,7 +17,7 @@ import voluptuous as vol
import homeassistant.core as ha
import homeassistant.config as conf_util
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.service import extract_entity_ids
from homeassistant.helpers.service import async_extract_entity_ids
from homeassistant.helpers import intent
from homeassistant.const import (
ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE,
@@ -70,7 +70,7 @@ async def async_setup(hass: ha.HomeAssistant, config: dict) -> Awaitable[bool]:
"""Set up general services related to Home Assistant."""
async def async_handle_turn_service(service):
"""Handle calls to homeassistant.turn_on/off."""
entity_ids = extract_entity_ids(hass, service)
entity_ids = await async_extract_entity_ids(hass, service)
# Generic turn on/off method requires entity id
if not entity_ids:
@@ -166,6 +166,7 @@ async def async_setup(hass: ha.HomeAssistant, config: dict) -> Awaitable[bool]:
_LOGGER.error(err)
return
# auth only processed during startup
await conf_util.async_process_ha_core_config(
hass, conf.get(ha.DOMAIN) or {})

View File

@@ -1,344 +0,0 @@
"""
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 logging
from functools import partial
from requests.exceptions import HTTPError, ConnectTimeout
import voluptuous as vol
from homeassistant.const import (
ATTR_ATTRIBUTION, ATTR_DATE, ATTR_TIME, ATTR_ENTITY_ID, CONF_USERNAME,
CONF_PASSWORD, CONF_EXCLUDE, CONF_NAME, CONF_LIGHTS,
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import discovery
from homeassistant.helpers.entity import Entity
REQUIREMENTS = ['abodepy==0.14.0']
_LOGGER = logging.getLogger(__name__)
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'
EVENT_ABODE_ALARM = 'abode_alarm'
EVENT_ABODE_ALARM_END = 'abode_alarm_end'
EVENT_ABODE_AUTOMATION = 'abode_automation'
EVENT_ABODE_FAULT = 'abode_panel_fault'
EVENT_ABODE_RESTORE = 'abode_panel_restore'
SERVICE_SETTINGS = 'change_setting'
SERVICE_CAPTURE_IMAGE = 'capture_image'
SERVICE_TRIGGER = 'trigger_quick_action'
ATTR_DEVICE_ID = 'device_id'
ATTR_DEVICE_NAME = 'device_name'
ATTR_DEVICE_TYPE = 'device_type'
ATTR_EVENT_CODE = 'event_code'
ATTR_EVENT_NAME = 'event_name'
ATTR_EVENT_TYPE = 'event_type'
ATTR_EVENT_UTC = 'event_utc'
ATTR_SETTING = 'setting'
ATTR_USER_NAME = 'user_name'
ATTR_VALUE = 'value'
ABODE_DEVICE_ID_LIST_SCHEMA = vol.Schema([str])
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_POLLING, default=False): cv.boolean,
vol.Optional(CONF_EXCLUDE, default=[]): ABODE_DEVICE_ID_LIST_SCHEMA,
vol.Optional(CONF_LIGHTS, default=[]): ABODE_DEVICE_ID_LIST_SCHEMA
}),
}, extra=vol.ALLOW_EXTRA)
CHANGE_SETTING_SCHEMA = vol.Schema({
vol.Required(ATTR_SETTING): cv.string,
vol.Required(ATTR_VALUE): cv.string
})
CAPTURE_IMAGE_SCHEMA = vol.Schema({
ATTR_ENTITY_ID: cv.entity_ids,
})
TRIGGER_SCHEMA = vol.Schema({
ATTR_ENTITY_ID: cv.entity_ids,
})
ABODE_PLATFORMS = [
'alarm_control_panel', 'binary_sensor', 'lock', 'switch', 'cover',
'camera', 'light', 'sensor'
]
class AbodeSystem:
"""Abode System class."""
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, cache_path=cache)
self.name = name
self.polling = polling
self.exclude = exclude
self.lights = lights
self.devices = []
def is_excluded(self, device):
"""Check if a device is configured to be excluded."""
return device.device_id in self.exclude
def is_automation_excluded(self, automation):
"""Check if an automation is configured to be excluded."""
return automation.automation_id in self.exclude
def is_light(self, device):
"""Check if a switch device is configured as a light."""
import abodepy.helpers.constants as CONST
return (device.generic_type == CONST.TYPE_LIGHT or
(device.generic_type == CONST.TYPE_SWITCH and
device.device_id in self.lights))
def setup(hass, config):
"""Set up Abode component."""
from abodepy.exceptions import AbodeException
conf = config[DOMAIN]
username = conf.get(CONF_USERNAME)
password = conf.get(CONF_PASSWORD)
name = conf.get(CONF_NAME)
polling = conf.get(CONF_POLLING)
exclude = conf.get(CONF_EXCLUDE)
lights = conf.get(CONF_LIGHTS)
try:
cache = hass.config.path(DEFAULT_CACHEDB)
hass.data[DOMAIN] = AbodeSystem(
username, password, cache, name, polling, exclude, lights)
except (AbodeException, ConnectTimeout, HTTPError) as ex:
_LOGGER.error("Unable to connect to Abode: %s", str(ex))
hass.components.persistent_notification.create(
'Error: {}<br />'
'You will need to restart hass after fixing.'
''.format(ex),
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
setup_hass_services(hass)
setup_hass_events(hass)
setup_abode_events(hass)
for platform in ABODE_PLATFORMS:
discovery.load_platform(hass, platform, DOMAIN, {}, config)
return True
def setup_hass_services(hass):
"""Home assistant services."""
from abodepy.exceptions import AbodeException
def change_setting(call):
"""Change an Abode system setting."""
setting = call.data.get(ATTR_SETTING)
value = call.data.get(ATTR_VALUE)
try:
hass.data[DOMAIN].abode.set_setting(setting, value)
except AbodeException as ex:
_LOGGER.warning(ex)
def capture_image(call):
"""Capture a new image."""
entity_ids = call.data.get(ATTR_ENTITY_ID)
target_devices = [device for device in hass.data[DOMAIN].devices
if device.entity_id in entity_ids]
for device in target_devices:
device.capture()
def trigger_quick_action(call):
"""Trigger a quick action."""
entity_ids = call.data.get(ATTR_ENTITY_ID, None)
target_devices = [device for device in hass.data[DOMAIN].devices
if device.entity_id in entity_ids]
for device in target_devices:
device.trigger()
hass.services.register(
DOMAIN, SERVICE_SETTINGS, change_setting,
schema=CHANGE_SETTING_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_CAPTURE_IMAGE, capture_image,
schema=CAPTURE_IMAGE_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_TRIGGER, trigger_quick_action,
schema=TRIGGER_SCHEMA)
def setup_hass_events(hass):
"""Home Assistant start and stop callbacks."""
def startup(event):
"""Listen for push events."""
hass.data[DOMAIN].abode.events.start()
def logout(event):
"""Logout of Abode."""
if not hass.data[DOMAIN].polling:
hass.data[DOMAIN].abode.events.stop()
hass.data[DOMAIN].abode.logout()
_LOGGER.info("Logged out of Abode")
if not hass.data[DOMAIN].polling:
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, startup)
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, logout)
def setup_abode_events(hass):
"""Event callbacks."""
import abodepy.helpers.timeline as TIMELINE
def event_callback(event, event_json):
"""Handle an event callback from Abode."""
data = {
ATTR_DEVICE_ID: event_json.get(ATTR_DEVICE_ID, ''),
ATTR_DEVICE_NAME: event_json.get(ATTR_DEVICE_NAME, ''),
ATTR_DEVICE_TYPE: event_json.get(ATTR_DEVICE_TYPE, ''),
ATTR_EVENT_CODE: event_json.get(ATTR_EVENT_CODE, ''),
ATTR_EVENT_NAME: event_json.get(ATTR_EVENT_NAME, ''),
ATTR_EVENT_TYPE: event_json.get(ATTR_EVENT_TYPE, ''),
ATTR_EVENT_UTC: event_json.get(ATTR_EVENT_UTC, ''),
ATTR_USER_NAME: event_json.get(ATTR_USER_NAME, ''),
ATTR_DATE: event_json.get(ATTR_DATE, ''),
ATTR_TIME: event_json.get(ATTR_TIME, ''),
}
hass.bus.fire(event, data)
events = [TIMELINE.ALARM_GROUP, TIMELINE.ALARM_END_GROUP,
TIMELINE.PANEL_FAULT_GROUP, TIMELINE.PANEL_RESTORE_GROUP,
TIMELINE.AUTOMATION_GROUP]
for event in events:
hass.data[DOMAIN].abode.events.add_event_callback(
event,
partial(event_callback, event))
class AbodeDevice(Entity):
"""Representation of an Abode device."""
def __init__(self, data, device):
"""Initialize a sensor for Abode device."""
self._data = data
self._device = device
async def async_added_to_hass(self):
"""Subscribe Abode events."""
self.hass.async_add_job(
self._data.abode.events.add_device_callback,
self._device.device_id, self._update_callback
)
@property
def should_poll(self):
"""Return the polling state."""
return self._data.polling
def update(self):
"""Update automation state."""
self._device.refresh()
@property
def name(self):
"""Return the name of the sensor."""
return self._device.name
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
'device_id': self._device.device_id,
'battery_low': self._device.battery_low,
'no_response': self._device.no_response,
'device_type': self._device.type
}
def _update_callback(self, device):
"""Update the device state."""
self.schedule_update_ha_state()
class AbodeAutomation(Entity):
"""Representation of an Abode automation."""
def __init__(self, data, automation, event=None):
"""Initialize for Abode automation."""
self._data = data
self._automation = automation
self._event = event
async def async_added_to_hass(self):
"""Subscribe Abode events."""
if self._event:
self.hass.async_add_job(
self._data.abode.events.add_event_callback,
self._event, self._update_callback
)
@property
def should_poll(self):
"""Return the polling state."""
return self._data.polling
def update(self):
"""Update automation state."""
self._automation.refresh()
@property
def name(self):
"""Return the name of the sensor."""
return self._automation.name
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
'automation_id': self._automation.automation_id,
'type': self._automation.type,
'sub_type': self._automation.sub_type
}
def _update_callback(self, device):
"""Update the device state."""
self._automation.refresh()
self.schedule_update_ha_state()

View File

@@ -0,0 +1,340 @@
"""Support for Abode Home Security system."""
import logging
from functools import partial
from requests.exceptions import HTTPError, ConnectTimeout
import voluptuous as vol
from homeassistant.const import (
ATTR_ATTRIBUTION, ATTR_DATE, ATTR_TIME, ATTR_ENTITY_ID, CONF_USERNAME,
CONF_PASSWORD, CONF_EXCLUDE, CONF_NAME, CONF_LIGHTS,
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import discovery
from homeassistant.helpers.entity import Entity
REQUIREMENTS = ['abodepy==0.15.0']
_LOGGER = logging.getLogger(__name__)
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'
EVENT_ABODE_ALARM = 'abode_alarm'
EVENT_ABODE_ALARM_END = 'abode_alarm_end'
EVENT_ABODE_AUTOMATION = 'abode_automation'
EVENT_ABODE_FAULT = 'abode_panel_fault'
EVENT_ABODE_RESTORE = 'abode_panel_restore'
SERVICE_SETTINGS = 'change_setting'
SERVICE_CAPTURE_IMAGE = 'capture_image'
SERVICE_TRIGGER = 'trigger_quick_action'
ATTR_DEVICE_ID = 'device_id'
ATTR_DEVICE_NAME = 'device_name'
ATTR_DEVICE_TYPE = 'device_type'
ATTR_EVENT_CODE = 'event_code'
ATTR_EVENT_NAME = 'event_name'
ATTR_EVENT_TYPE = 'event_type'
ATTR_EVENT_UTC = 'event_utc'
ATTR_SETTING = 'setting'
ATTR_USER_NAME = 'user_name'
ATTR_VALUE = 'value'
ABODE_DEVICE_ID_LIST_SCHEMA = vol.Schema([str])
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_POLLING, default=False): cv.boolean,
vol.Optional(CONF_EXCLUDE, default=[]): ABODE_DEVICE_ID_LIST_SCHEMA,
vol.Optional(CONF_LIGHTS, default=[]): ABODE_DEVICE_ID_LIST_SCHEMA
}),
}, extra=vol.ALLOW_EXTRA)
CHANGE_SETTING_SCHEMA = vol.Schema({
vol.Required(ATTR_SETTING): cv.string,
vol.Required(ATTR_VALUE): cv.string
})
CAPTURE_IMAGE_SCHEMA = vol.Schema({
ATTR_ENTITY_ID: cv.entity_ids,
})
TRIGGER_SCHEMA = vol.Schema({
ATTR_ENTITY_ID: cv.entity_ids,
})
ABODE_PLATFORMS = [
'alarm_control_panel', 'binary_sensor', 'lock', 'switch', 'cover',
'camera', 'light', 'sensor'
]
class AbodeSystem:
"""Abode System class."""
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, cache_path=cache)
self.name = name
self.polling = polling
self.exclude = exclude
self.lights = lights
self.devices = []
def is_excluded(self, device):
"""Check if a device is configured to be excluded."""
return device.device_id in self.exclude
def is_automation_excluded(self, automation):
"""Check if an automation is configured to be excluded."""
return automation.automation_id in self.exclude
def is_light(self, device):
"""Check if a switch device is configured as a light."""
import abodepy.helpers.constants as CONST
return (device.generic_type == CONST.TYPE_LIGHT or
(device.generic_type == CONST.TYPE_SWITCH and
device.device_id in self.lights))
def setup(hass, config):
"""Set up Abode component."""
from abodepy.exceptions import AbodeException
conf = config[DOMAIN]
username = conf.get(CONF_USERNAME)
password = conf.get(CONF_PASSWORD)
name = conf.get(CONF_NAME)
polling = conf.get(CONF_POLLING)
exclude = conf.get(CONF_EXCLUDE)
lights = conf.get(CONF_LIGHTS)
try:
cache = hass.config.path(DEFAULT_CACHEDB)
hass.data[DOMAIN] = AbodeSystem(
username, password, cache, name, polling, exclude, lights)
except (AbodeException, ConnectTimeout, HTTPError) as ex:
_LOGGER.error("Unable to connect to Abode: %s", str(ex))
hass.components.persistent_notification.create(
'Error: {}<br />'
'You will need to restart hass after fixing.'
''.format(ex),
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
setup_hass_services(hass)
setup_hass_events(hass)
setup_abode_events(hass)
for platform in ABODE_PLATFORMS:
discovery.load_platform(hass, platform, DOMAIN, {}, config)
return True
def setup_hass_services(hass):
"""Home assistant services."""
from abodepy.exceptions import AbodeException
def change_setting(call):
"""Change an Abode system setting."""
setting = call.data.get(ATTR_SETTING)
value = call.data.get(ATTR_VALUE)
try:
hass.data[DOMAIN].abode.set_setting(setting, value)
except AbodeException as ex:
_LOGGER.warning(ex)
def capture_image(call):
"""Capture a new image."""
entity_ids = call.data.get(ATTR_ENTITY_ID)
target_devices = [device for device in hass.data[DOMAIN].devices
if device.entity_id in entity_ids]
for device in target_devices:
device.capture()
def trigger_quick_action(call):
"""Trigger a quick action."""
entity_ids = call.data.get(ATTR_ENTITY_ID, None)
target_devices = [device for device in hass.data[DOMAIN].devices
if device.entity_id in entity_ids]
for device in target_devices:
device.trigger()
hass.services.register(
DOMAIN, SERVICE_SETTINGS, change_setting,
schema=CHANGE_SETTING_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_CAPTURE_IMAGE, capture_image,
schema=CAPTURE_IMAGE_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_TRIGGER, trigger_quick_action,
schema=TRIGGER_SCHEMA)
def setup_hass_events(hass):
"""Home Assistant start and stop callbacks."""
def startup(event):
"""Listen for push events."""
hass.data[DOMAIN].abode.events.start()
def logout(event):
"""Logout of Abode."""
if not hass.data[DOMAIN].polling:
hass.data[DOMAIN].abode.events.stop()
hass.data[DOMAIN].abode.logout()
_LOGGER.info("Logged out of Abode")
if not hass.data[DOMAIN].polling:
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, startup)
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, logout)
def setup_abode_events(hass):
"""Event callbacks."""
import abodepy.helpers.timeline as TIMELINE
def event_callback(event, event_json):
"""Handle an event callback from Abode."""
data = {
ATTR_DEVICE_ID: event_json.get(ATTR_DEVICE_ID, ''),
ATTR_DEVICE_NAME: event_json.get(ATTR_DEVICE_NAME, ''),
ATTR_DEVICE_TYPE: event_json.get(ATTR_DEVICE_TYPE, ''),
ATTR_EVENT_CODE: event_json.get(ATTR_EVENT_CODE, ''),
ATTR_EVENT_NAME: event_json.get(ATTR_EVENT_NAME, ''),
ATTR_EVENT_TYPE: event_json.get(ATTR_EVENT_TYPE, ''),
ATTR_EVENT_UTC: event_json.get(ATTR_EVENT_UTC, ''),
ATTR_USER_NAME: event_json.get(ATTR_USER_NAME, ''),
ATTR_DATE: event_json.get(ATTR_DATE, ''),
ATTR_TIME: event_json.get(ATTR_TIME, ''),
}
hass.bus.fire(event, data)
events = [TIMELINE.ALARM_GROUP, TIMELINE.ALARM_END_GROUP,
TIMELINE.PANEL_FAULT_GROUP, TIMELINE.PANEL_RESTORE_GROUP,
TIMELINE.AUTOMATION_GROUP]
for event in events:
hass.data[DOMAIN].abode.events.add_event_callback(
event,
partial(event_callback, event))
class AbodeDevice(Entity):
"""Representation of an Abode device."""
def __init__(self, data, device):
"""Initialize a sensor for Abode device."""
self._data = data
self._device = device
async def async_added_to_hass(self):
"""Subscribe Abode events."""
self.hass.async_add_job(
self._data.abode.events.add_device_callback,
self._device.device_id, self._update_callback
)
@property
def should_poll(self):
"""Return the polling state."""
return self._data.polling
def update(self):
"""Update automation state."""
self._device.refresh()
@property
def name(self):
"""Return the name of the sensor."""
return self._device.name
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: ATTRIBUTION,
'device_id': self._device.device_id,
'battery_low': self._device.battery_low,
'no_response': self._device.no_response,
'device_type': self._device.type
}
def _update_callback(self, device):
"""Update the device state."""
self.schedule_update_ha_state()
class AbodeAutomation(Entity):
"""Representation of an Abode automation."""
def __init__(self, data, automation, event=None):
"""Initialize for Abode automation."""
self._data = data
self._automation = automation
self._event = event
async def async_added_to_hass(self):
"""Subscribe Abode events."""
if self._event:
self.hass.async_add_job(
self._data.abode.events.add_event_callback,
self._event, self._update_callback
)
@property
def should_poll(self):
"""Return the polling state."""
return self._data.polling
def update(self):
"""Update automation state."""
self._automation.refresh()
@property
def name(self):
"""Return the name of the sensor."""
return self._automation.name
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: ATTRIBUTION,
'automation_id': self._automation.automation_id,
'type': self._automation.type,
'sub_type': self._automation.sub_type
}
def _update_callback(self, device):
"""Update the device state."""
self._automation.refresh()
self.schedule_update_ha_state()

View File

@@ -0,0 +1,80 @@
"""Support for Abode Security System alarm control panels."""
import logging
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.abode import ATTRIBUTION, AbodeDevice
from homeassistant.components.abode import DOMAIN as ABODE_DOMAIN
from homeassistant.const import (
ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED)
DEPENDENCIES = ['abode']
_LOGGER = logging.getLogger(__name__)
ICON = 'mdi:security'
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]
alarm_devices = [AbodeAlarm(data, data.abode.get_alarm(), data.name)]
data.devices.extend(alarm_devices)
add_entities(alarm_devices)
class AbodeAlarm(AbodeDevice, alarm.AlarmControlPanel):
"""An alarm_control_panel implementation for Abode."""
def __init__(self, data, device, name):
"""Initialize the alarm control panel."""
super().__init__(data, device)
self._name = name
@property
def icon(self):
"""Return the icon."""
return ICON
@property
def state(self):
"""Return the state of the device."""
if self._device.is_standby:
state = STATE_ALARM_DISARMED
elif self._device.is_away:
state = STATE_ALARM_ARMED_AWAY
elif self._device.is_home:
state = STATE_ALARM_ARMED_HOME
else:
state = None
return state
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._device.set_standby()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self._device.set_home()
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self._device.set_away()
@property
def name(self):
"""Return the name of the alarm."""
return self._name or super().name
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: ATTRIBUTION,
'device_id': self._device.device_id,
'battery_backup': self._device.battery,
'cellular_backup': self._device.is_cellular,
}

View File

@@ -0,0 +1,68 @@
"""Support for Abode Security System binary sensors."""
import logging
from homeassistant.components.abode import (AbodeDevice, AbodeAutomation,
DOMAIN as ABODE_DOMAIN)
from homeassistant.components.binary_sensor import BinarySensorDevice
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['abode']
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up a sensor for an Abode device."""
import abodepy.helpers.constants as CONST
import abodepy.helpers.timeline as TIMELINE
data = hass.data[ABODE_DOMAIN]
device_types = [CONST.TYPE_CONNECTIVITY, CONST.TYPE_MOISTURE,
CONST.TYPE_MOTION, CONST.TYPE_OCCUPANCY,
CONST.TYPE_OPENING]
devices = []
for device in data.abode.get_devices(generic_type=device_types):
if data.is_excluded(device):
continue
devices.append(AbodeBinarySensor(data, device))
for automation in data.abode.get_automations(
generic_type=CONST.TYPE_QUICK_ACTION):
if data.is_automation_excluded(automation):
continue
devices.append(AbodeQuickActionBinarySensor(
data, automation, TIMELINE.AUTOMATION_EDIT_GROUP))
data.devices.extend(devices)
add_entities(devices)
class AbodeBinarySensor(AbodeDevice, BinarySensorDevice):
"""A binary sensor implementation for Abode device."""
@property
def is_on(self):
"""Return True if the binary sensor is on."""
return self._device.is_on
@property
def device_class(self):
"""Return the class of the binary sensor."""
return self._device.generic_type
class AbodeQuickActionBinarySensor(AbodeAutomation, BinarySensorDevice):
"""A binary sensor implementation for Abode quick action automations."""
def trigger(self):
"""Trigger a quick automation."""
self._automation.trigger()
@property
def is_on(self):
"""Return True if the binary sensor is on."""
return self._automation.is_active

View File

@@ -0,0 +1,93 @@
"""Support for Abode Security System cameras."""
import logging
from datetime import timedelta
import requests
from homeassistant.components.abode import AbodeDevice, DOMAIN as ABODE_DOMAIN
from homeassistant.components.camera import Camera
from homeassistant.util import Throttle
DEPENDENCIES = ['abode']
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90)
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up Abode camera devices."""
import abodepy.helpers.constants as CONST
import abodepy.helpers.timeline as TIMELINE
data = hass.data[ABODE_DOMAIN]
devices = []
for device in data.abode.get_devices(generic_type=CONST.TYPE_CAMERA):
if data.is_excluded(device):
continue
devices.append(AbodeCamera(data, device, TIMELINE.CAPTURE_IMAGE))
data.devices.extend(devices)
add_entities(devices)
class AbodeCamera(AbodeDevice, Camera):
"""Representation of an Abode camera."""
def __init__(self, data, device, event):
"""Initialize the Abode device."""
AbodeDevice.__init__(self, data, device)
Camera.__init__(self)
self._event = event
self._response = None
async def async_added_to_hass(self):
"""Subscribe Abode events."""
await super().async_added_to_hass()
self.hass.async_add_job(
self._data.abode.events.add_timeline_callback,
self._event, self._capture_callback
)
def capture(self):
"""Request a new image capture."""
return self._device.capture()
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def refresh_image(self):
"""Find a new image on the timeline."""
if self._device.refresh_image():
self.get_image()
def get_image(self):
"""Attempt to download the most recent capture."""
if self._device.image_url:
try:
self._response = requests.get(
self._device.image_url, stream=True)
self._response.raise_for_status()
except requests.HTTPError as err:
_LOGGER.warning("Failed to get camera image: %s", err)
self._response = None
else:
self._response = None
def camera_image(self):
"""Get a camera image."""
self.refresh_image()
if self._response:
return self._response.content
return None
def _capture_callback(self, capture):
"""Update the image with the device then refresh device."""
self._device.update_image_location(capture)
self.get_image()
self.schedule_update_ha_state()

View File

@@ -0,0 +1,44 @@
"""Support for Abode Security System covers."""
import logging
from homeassistant.components.abode import AbodeDevice, DOMAIN as ABODE_DOMAIN
from homeassistant.components.cover import CoverDevice
DEPENDENCIES = ['abode']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up Abode cover devices."""
import abodepy.helpers.constants as CONST
data = hass.data[ABODE_DOMAIN]
devices = []
for device in data.abode.get_devices(generic_type=CONST.TYPE_COVER):
if data.is_excluded(device):
continue
devices.append(AbodeCover(data, device))
data.devices.extend(devices)
add_entities(devices)
class AbodeCover(AbodeDevice, CoverDevice):
"""Representation of an Abode cover."""
@property
def is_closed(self):
"""Return true if cover is closed, else False."""
return not self._device.is_open
def close_cover(self, **kwargs):
"""Issue close command to cover."""
self._device.close_cover()
def open_cover(self, **kwargs):
"""Issue open command to cover."""
self._device.open_cover()

View File

@@ -0,0 +1,98 @@
"""Support for Abode Security System lights."""
import logging
from math import ceil
from homeassistant.components.abode import AbodeDevice, DOMAIN as ABODE_DOMAIN
from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_HS_COLOR, ATTR_COLOR_TEMP,
SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_COLOR_TEMP, Light)
from homeassistant.util.color import (
color_temperature_kelvin_to_mired, color_temperature_mired_to_kelvin)
DEPENDENCIES = ['abode']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up Abode light devices."""
import abodepy.helpers.constants as CONST
data = hass.data[ABODE_DOMAIN]
device_types = [CONST.TYPE_LIGHT, CONST.TYPE_SWITCH]
devices = []
# Get all regular lights that are not excluded or switches marked as lights
for device in data.abode.get_devices(generic_type=device_types):
if data.is_excluded(device) or not data.is_light(device):
continue
devices.append(AbodeLight(data, device))
data.devices.extend(devices)
add_entities(devices)
class AbodeLight(AbodeDevice, Light):
"""Representation of an Abode light."""
def turn_on(self, **kwargs):
"""Turn on the light."""
if ATTR_COLOR_TEMP in kwargs and self._device.is_color_capable:
self._device.set_color_temp(
int(color_temperature_mired_to_kelvin(
kwargs[ATTR_COLOR_TEMP])))
if ATTR_HS_COLOR in kwargs and self._device.is_color_capable:
self._device.set_color(kwargs[ATTR_HS_COLOR])
if ATTR_BRIGHTNESS in kwargs and self._device.is_dimmable:
# Convert HASS brightness (0-255) to Abode brightness (0-99)
# If 100 is sent to Abode, response is 99 causing an error
self._device.set_level(ceil(kwargs[ATTR_BRIGHTNESS] * 99 / 255.0))
else:
self._device.switch_on()
def turn_off(self, **kwargs):
"""Turn off the light."""
self._device.switch_off()
@property
def is_on(self):
"""Return true if device is on."""
return self._device.is_on
@property
def brightness(self):
"""Return the brightness of the light."""
if self._device.is_dimmable and self._device.has_brightness:
brightness = int(self._device.brightness)
# Abode returns 100 during device initialization and device refresh
if brightness == 100:
return 255
# Convert Abode brightness (0-99) to HASS brightness (0-255)
return ceil(brightness * 255 / 99.0)
@property
def color_temp(self):
"""Return the color temp of the light."""
if self._device.has_color:
return color_temperature_kelvin_to_mired(self._device.color_temp)
@property
def hs_color(self):
"""Return the color of the light."""
if self._device.has_color:
return self._device.color
@property
def supported_features(self):
"""Flag supported features."""
if self._device.is_dimmable and self._device.is_color_capable:
return SUPPORT_BRIGHTNESS | SUPPORT_COLOR | SUPPORT_COLOR_TEMP
if self._device.is_dimmable:
return SUPPORT_BRIGHTNESS
return 0

View File

@@ -0,0 +1,44 @@
"""Support for Abode Security System locks."""
import logging
from homeassistant.components.abode import AbodeDevice, DOMAIN as ABODE_DOMAIN
from homeassistant.components.lock import LockDevice
DEPENDENCIES = ['abode']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up Abode lock devices."""
import abodepy.helpers.constants as CONST
data = hass.data[ABODE_DOMAIN]
devices = []
for device in data.abode.get_devices(generic_type=CONST.TYPE_LOCK):
if data.is_excluded(device):
continue
devices.append(AbodeLock(data, device))
data.devices.extend(devices)
add_entities(devices)
class AbodeLock(AbodeDevice, LockDevice):
"""Representation of an Abode lock."""
def lock(self, **kwargs):
"""Lock the device."""
self._device.lock()
def unlock(self, **kwargs):
"""Unlock the device."""
self._device.unlock()
@property
def is_locked(self):
"""Return true if device is on."""
return self._device.is_locked

View File

@@ -0,0 +1,78 @@
"""Support for Abode Security System sensors."""
import logging
from homeassistant.components.abode import AbodeDevice, DOMAIN as ABODE_DOMAIN
from homeassistant.const import (
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_TEMPERATURE)
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['abode']
# Sensor types: Name, icon
SENSOR_TYPES = {
'temp': ['Temperature', DEVICE_CLASS_TEMPERATURE],
'humidity': ['Humidity', DEVICE_CLASS_HUMIDITY],
'lux': ['Lux', DEVICE_CLASS_ILLUMINANCE],
}
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up a sensor for an Abode device."""
import abodepy.helpers.constants as CONST
data = hass.data[ABODE_DOMAIN]
devices = []
for device in data.abode.get_devices(generic_type=CONST.TYPE_SENSOR):
if data.is_excluded(device):
continue
for sensor_type in SENSOR_TYPES:
devices.append(AbodeSensor(data, device, sensor_type))
data.devices.extend(devices)
add_entities(devices)
class AbodeSensor(AbodeDevice):
"""A sensor implementation for Abode devices."""
def __init__(self, data, device, sensor_type):
"""Initialize a sensor for an Abode device."""
super().__init__(data, device)
self._sensor_type = sensor_type
self._name = '{0} {1}'.format(
self._device.name, SENSOR_TYPES[self._sensor_type][0])
self._device_class = SENSOR_TYPES[self._sensor_type][1]
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def device_class(self):
"""Return the device class."""
return self._device_class
@property
def state(self):
"""Return the state of the sensor."""
if self._sensor_type == 'temp':
return self._device.temp
if self._sensor_type == 'humidity':
return self._device.humidity
if self._sensor_type == 'lux':
return self._device.lux
@property
def unit_of_measurement(self):
"""Return the units of measurement."""
if self._sensor_type == 'temp':
return self._device.temp_unit
if self._sensor_type == 'humidity':
return self._device.humidity_unit
if self._sensor_type == 'lux':
return self._device.lux_unit

View File

@@ -0,0 +1,13 @@
capture_image:
description: Request a new image capture from a camera device.
fields:
entity_id: {description: Entity id of the camera to request an image., example: camera.downstairs_motion_camera}
change_setting:
description: Change an Abode system setting.
fields:
setting: {description: Setting to change., example: beeper_mute}
value: {description: Value of the setting., example: '1'}
trigger_quick_action:
description: Trigger an Abode quick action.
fields:
entity_id: {description: Entity id of the quick action to trigger., example: binary_sensor.home_quick_action}

View File

@@ -0,0 +1,74 @@
"""Support for Abode Security System switches."""
import logging
from homeassistant.components.abode import (AbodeDevice, AbodeAutomation,
DOMAIN as ABODE_DOMAIN)
from homeassistant.components.switch import SwitchDevice
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['abode']
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up Abode switch devices."""
import abodepy.helpers.constants as CONST
import abodepy.helpers.timeline as TIMELINE
data = hass.data[ABODE_DOMAIN]
devices = []
# Get all regular switches that are not excluded or marked as lights
for device in data.abode.get_devices(generic_type=CONST.TYPE_SWITCH):
if data.is_excluded(device) or data.is_light(device):
continue
devices.append(AbodeSwitch(data, device))
# Get all Abode automations that can be enabled/disabled
for automation in data.abode.get_automations(
generic_type=CONST.TYPE_AUTOMATION):
if data.is_automation_excluded(automation):
continue
devices.append(AbodeAutomationSwitch(
data, automation, TIMELINE.AUTOMATION_EDIT_GROUP))
data.devices.extend(devices)
add_entities(devices)
class AbodeSwitch(AbodeDevice, SwitchDevice):
"""Representation of an Abode switch."""
def turn_on(self, **kwargs):
"""Turn on the device."""
self._device.switch_on()
def turn_off(self, **kwargs):
"""Turn off the device."""
self._device.switch_off()
@property
def is_on(self):
"""Return true if device is on."""
return self._device.is_on
class AbodeAutomationSwitch(AbodeAutomation, SwitchDevice):
"""A switch implementation for Abode automations."""
def turn_on(self, **kwargs):
"""Turn on the device."""
self._automation.set_active(True)
def turn_off(self, **kwargs):
"""Turn off the device."""
self._automation.set_active(False)
@property
def is_on(self):
"""Return True if the binary sensor is on."""
return self._automation.is_active

View File

@@ -1,38 +1,37 @@
"""
Support for Automation Device Specification (ADS).
For more details about this component, please refer to the documentation.
https://home-assistant.io/components/ads/
"""
"""Support for Automation Device Specification (ADS)."""
import threading
import struct
import logging
import ctypes
from collections import namedtuple
import voluptuous as vol
from homeassistant.const import CONF_DEVICE, CONF_PORT, CONF_IP_ADDRESS, \
EVENT_HOMEASSISTANT_STOP
from homeassistant.const import (
CONF_DEVICE, CONF_IP_ADDRESS, CONF_PORT, EVENT_HOMEASSISTANT_STOP)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyads==2.2.6']
REQUIREMENTS = ['pyads==3.0.7']
_LOGGER = logging.getLogger(__name__)
DATA_ADS = 'data_ads'
# Supported Types
ADSTYPE_INT = 'int'
ADSTYPE_UINT = 'uint'
ADSTYPE_BYTE = 'byte'
ADSTYPE_BOOL = 'bool'
ADSTYPE_BYTE = 'byte'
ADSTYPE_DINT = 'dint'
ADSTYPE_INT = 'int'
ADSTYPE_UDINT = 'udint'
ADSTYPE_UINT = 'uint'
DOMAIN = 'ads'
CONF_ADS_FACTOR = 'factor'
CONF_ADS_TYPE = 'adstype'
CONF_ADS_VALUE = 'value'
CONF_ADS_VAR = 'adsvar'
CONF_ADS_VAR_BRIGHTNESS = 'adsvar_brightness'
CONF_ADS_TYPE = 'adstype'
CONF_ADS_FACTOR = 'factor'
CONF_ADS_VALUE = 'value'
DOMAIN = 'ads'
SERVICE_WRITE_DATA_BY_NAME = 'write_data_by_name'
@@ -46,8 +45,9 @@ CONFIG_SCHEMA = vol.Schema({
SCHEMA_SERVICE_WRITE_DATA_BY_NAME = vol.Schema({
vol.Required(CONF_ADS_TYPE):
vol.In([ADSTYPE_INT, ADSTYPE_UINT, ADSTYPE_BYTE]),
vol.Required(CONF_ADS_VALUE): cv.match_all,
vol.In([ADSTYPE_INT, ADSTYPE_UINT, ADSTYPE_BYTE, ADSTYPE_BOOL,
ADSTYPE_DINT, ADSTYPE_UDINT]),
vol.Required(CONF_ADS_VALUE): vol.Coerce(int),
vol.Required(CONF_ADS_VAR): cv.string,
})
@@ -66,21 +66,26 @@ def setup(hass, config):
AdsHub.ADS_TYPEMAP = {
ADSTYPE_BOOL: pyads.PLCTYPE_BOOL,
ADSTYPE_BYTE: pyads.PLCTYPE_BYTE,
ADSTYPE_DINT: pyads.PLCTYPE_DINT,
ADSTYPE_INT: pyads.PLCTYPE_INT,
ADSTYPE_UDINT: pyads.PLCTYPE_UDINT,
ADSTYPE_UINT: pyads.PLCTYPE_UINT,
}
AdsHub.ADSError = pyads.ADSError
AdsHub.PLCTYPE_BOOL = pyads.PLCTYPE_BOOL
AdsHub.PLCTYPE_BYTE = pyads.PLCTYPE_BYTE
AdsHub.PLCTYPE_DINT = pyads.PLCTYPE_DINT
AdsHub.PLCTYPE_INT = pyads.PLCTYPE_INT
AdsHub.PLCTYPE_UDINT = pyads.PLCTYPE_UDINT
AdsHub.PLCTYPE_UINT = pyads.PLCTYPE_UINT
AdsHub.ADSError = pyads.ADSError
try:
ads = AdsHub(client)
except pyads.pyads.ADSError:
except pyads.ADSError:
_LOGGER.error(
"Could not connect to ADS host (netid=%s, port=%s)", net_id, port)
"Could not connect to ADS host (netid=%s, ip=%s, port=%s)",
net_id, ip_address, port)
return False
hass.data[DATA_ADS] = ads
@@ -125,16 +130,23 @@ class AdsHub:
def shutdown(self, *args, **kwargs):
"""Shutdown ADS connection."""
import pyads
_LOGGER.debug("Shutting down ADS")
for notification_item in self._notification_items.values():
self._client.del_device_notification(
notification_item.hnotify,
notification_item.huser
)
_LOGGER.debug(
"Deleting device notification %d, %d",
notification_item.hnotify, notification_item.huser)
self._client.close()
try:
self._client.del_device_notification(
notification_item.hnotify,
notification_item.huser
)
except pyads.ADSError as err:
_LOGGER.error(err)
try:
self._client.close()
except pyads.ADSError as err:
_LOGGER.error(err)
def register_device(self, device):
"""Register a new device."""
@@ -159,14 +171,13 @@ class AdsHub:
hnotify, huser = self._client.add_device_notification(
name, attr, self._device_notification_callback)
hnotify = int(hnotify)
self._notification_items[hnotify] = NotificationItem(
hnotify, huser, name, plc_datatype, callback)
_LOGGER.debug(
"Added device notification %d for variable %s", hnotify, name)
self._notification_items[hnotify] = NotificationItem(
hnotify, huser, name, plc_datatype, callback)
def _device_notification_callback(self, addr, notification, huser):
def _device_notification_callback(self, notification, name):
"""Handle device notifications."""
contents = notification.contents
@@ -175,9 +186,10 @@ class AdsHub:
data = contents.data
try:
notification_item = self._notification_items[hnotify]
with self._lock:
notification_item = self._notification_items[hnotify]
except KeyError:
_LOGGER.debug("Unknown device notification handle: %d", hnotify)
_LOGGER.error("Unknown device notification handle: %d", hnotify)
return
# Parse data to desired datatype
@@ -189,6 +201,10 @@ class AdsHub:
value = struct.unpack('<B', bytearray(data)[:1])[0]
elif notification_item.plc_datatype == self.PLCTYPE_UINT:
value = struct.unpack('<H', bytearray(data)[:2])[0]
elif notification_item.plc_datatype == self.PLCTYPE_DINT:
value = struct.unpack('<i', bytearray(data)[:4])[0]
elif notification_item.plc_datatype == self.PLCTYPE_UDINT:
value = struct.unpack('<I', bytearray(data)[:4])[0]
else:
value = bytearray(data)
_LOGGER.warning("No callback available for this datatype")

View File

@@ -0,0 +1,83 @@
"""Support for ADS binary sensors."""
import logging
import voluptuous as vol
from homeassistant.components.ads import CONF_ADS_VAR, DATA_ADS
from homeassistant.components.binary_sensor import (
DEVICE_CLASSES_SCHEMA, PLATFORM_SCHEMA, BinarySensorDevice)
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'ADS binary sensor'
DEPENDENCIES = ['ads']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Binary Sensor platform for ADS."""
ads_hub = hass.data.get(DATA_ADS)
ads_var = config.get(CONF_ADS_VAR)
name = config.get(CONF_NAME)
device_class = config.get(CONF_DEVICE_CLASS)
ads_sensor = AdsBinarySensor(ads_hub, name, ads_var, device_class)
add_entities([ads_sensor])
class AdsBinarySensor(BinarySensorDevice):
"""Representation of ADS binary sensors."""
def __init__(self, ads_hub, name, ads_var, device_class):
"""Initialize ADS binary sensor."""
self._name = name
self._unique_id = ads_var
self._state = False
self._device_class = device_class or 'moving'
self._ads_hub = ads_hub
self.ads_var = ads_var
async def async_added_to_hass(self):
"""Register device notification."""
def update(name, value):
"""Handle device notifications."""
_LOGGER.debug('Variable %s changed its value to %d', name, value)
self._state = value
self.schedule_update_ha_state()
self.hass.async_add_job(
self._ads_hub.add_device_notification,
self.ads_var, self._ads_hub.PLCTYPE_BOOL, update)
@property
def name(self):
"""Return the default name of the binary sensor."""
return self._name
@property
def unique_id(self):
"""Return an unique identifier for this entity."""
return self._unique_id
@property
def device_class(self):
"""Return the device class."""
return self._device_class
@property
def is_on(self):
"""Return if the binary sensor is on."""
return self._state
@property
def should_poll(self):
"""Return False because entity pushes its state to HA."""
return False

View File

@@ -0,0 +1,118 @@
"""Support for ADS light sources."""
import logging
import voluptuous as vol
from homeassistant.components.light import Light, ATTR_BRIGHTNESS, \
SUPPORT_BRIGHTNESS, PLATFORM_SCHEMA
from homeassistant.const import CONF_NAME
from homeassistant.components.ads import DATA_ADS, CONF_ADS_VAR, \
CONF_ADS_VAR_BRIGHTNESS
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['ads']
DEFAULT_NAME = 'ADS Light'
CONF_ADSVAR_BRIGHTNESS = 'adsvar_brightness'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_ADS_VAR_BRIGHTNESS): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the light platform for ADS."""
ads_hub = hass.data.get(DATA_ADS)
ads_var_enable = config.get(CONF_ADS_VAR)
ads_var_brightness = config.get(CONF_ADS_VAR_BRIGHTNESS)
name = config.get(CONF_NAME)
add_entities([AdsLight(ads_hub, ads_var_enable, ads_var_brightness,
name)], True)
class AdsLight(Light):
"""Representation of ADS light."""
def __init__(self, ads_hub, ads_var_enable, ads_var_brightness, name):
"""Initialize AdsLight entity."""
self._ads_hub = ads_hub
self._on_state = False
self._brightness = None
self._name = name
self._unique_id = ads_var_enable
self.ads_var_enable = ads_var_enable
self.ads_var_brightness = ads_var_brightness
async def async_added_to_hass(self):
"""Register device notification."""
def update_on_state(name, value):
"""Handle device notifications for state."""
_LOGGER.debug('Variable %s changed its value to %d', name, value)
self._on_state = value
self.schedule_update_ha_state()
def update_brightness(name, value):
"""Handle device notification for brightness."""
_LOGGER.debug('Variable %s changed its value to %d', name, value)
self._brightness = value
self.schedule_update_ha_state()
self.hass.async_add_executor_job(
self._ads_hub.add_device_notification,
self.ads_var_enable, self._ads_hub.PLCTYPE_BOOL, update_on_state
)
if self.ads_var_brightness is not None:
self.hass.async_add_executor_job(
self._ads_hub.add_device_notification,
self.ads_var_brightness, self._ads_hub.PLCTYPE_INT,
update_brightness
)
@property
def name(self):
"""Return the name of the device if any."""
return self._name
@property
def unique_id(self):
"""Return an unique identifier for this entity."""
return self._unique_id
@property
def brightness(self):
"""Return the brightness of the light (0..255)."""
return self._brightness
@property
def is_on(self):
"""Return if light is on."""
return self._on_state
@property
def should_poll(self):
"""Return False because entity pushes its state to HA."""
return False
@property
def supported_features(self):
"""Flag supported features."""
support = 0
if self.ads_var_brightness is not None:
support = SUPPORT_BRIGHTNESS
return support
def turn_on(self, **kwargs):
"""Turn the light on or set a specific dimmer value."""
brightness = kwargs.get(ATTR_BRIGHTNESS)
self._ads_hub.write_by_name(self.ads_var_enable, True,
self._ads_hub.PLCTYPE_BOOL)
if self.ads_var_brightness is not None and brightness is not None:
self._ads_hub.write_by_name(self.ads_var_brightness, brightness,
self._ads_hub.PLCTYPE_UINT)
def turn_off(self, **kwargs):
"""Turn the light off."""
self._ads_hub.write_by_name(self.ads_var_enable, False,
self._ads_hub.PLCTYPE_BOOL)

View File

@@ -0,0 +1,102 @@
"""Support for ADS sensors."""
import logging
import voluptuous as vol
from homeassistant.components import ads
from homeassistant.components.ads import (
CONF_ADS_FACTOR, CONF_ADS_TYPE, CONF_ADS_VAR)
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import CONF_NAME, CONF_UNIT_OF_MEASUREMENT
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "ADS sensor"
DEPENDENCIES = ['ads']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_ADS_FACTOR): cv.positive_int,
vol.Optional(CONF_ADS_TYPE, default=ads.ADSTYPE_INT):
vol.In([ads.ADSTYPE_INT, ads.ADSTYPE_UINT, ads.ADSTYPE_BYTE,
ads.ADSTYPE_DINT, ads.ADSTYPE_UDINT]),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_UNIT_OF_MEASUREMENT, default=''): cv.string,
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up an ADS sensor device."""
ads_hub = hass.data.get(ads.DATA_ADS)
ads_var = config.get(CONF_ADS_VAR)
ads_type = config.get(CONF_ADS_TYPE)
name = config.get(CONF_NAME)
unit_of_measurement = config.get(CONF_UNIT_OF_MEASUREMENT)
factor = config.get(CONF_ADS_FACTOR)
entity = AdsSensor(
ads_hub, ads_var, ads_type, name, unit_of_measurement, factor)
add_entities([entity])
class AdsSensor(Entity):
"""Representation of an ADS sensor entity."""
def __init__(self, ads_hub, ads_var, ads_type, name, unit_of_measurement,
factor):
"""Initialize AdsSensor entity."""
self._ads_hub = ads_hub
self._name = name
self._unique_id = ads_var
self._value = None
self._unit_of_measurement = unit_of_measurement
self.ads_var = ads_var
self.ads_type = ads_type
self.factor = factor
async def async_added_to_hass(self):
"""Register device notification."""
def update(name, value):
"""Handle device notifications."""
_LOGGER.debug("Variable %s changed its value to %d", name, value)
# If factor is set use it otherwise not
if self.factor is None:
self._value = value
else:
self._value = value / self.factor
self.schedule_update_ha_state()
self.hass.async_add_job(
self._ads_hub.add_device_notification,
self.ads_var, self._ads_hub.ADS_TYPEMAP[self.ads_type], update
)
@property
def name(self):
"""Return the name of the entity."""
return self._name
@property
def unique_id(self):
"""Return an unique identifier for this entity."""
return self._unique_id
@property
def state(self):
"""Return the state of the device."""
return self._value
@property
def unit_of_measurement(self):
"""Return the unit of measurement."""
return self._unit_of_measurement
@property
def should_poll(self):
"""Return False because entity pushes its state."""
return False

View File

@@ -0,0 +1,85 @@
"""Support for ADS switch platform."""
import logging
import voluptuous as vol
from homeassistant.components.ads import CONF_ADS_VAR, DATA_ADS
from homeassistant.components.switch import PLATFORM_SCHEMA
from homeassistant.const import CONF_NAME
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import ToggleEntity
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['ads']
DEFAULT_NAME = 'ADS Switch'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_NAME): cv.string,
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up switch platform for ADS."""
ads_hub = hass.data.get(DATA_ADS)
name = config.get(CONF_NAME)
ads_var = config.get(CONF_ADS_VAR)
add_entities([AdsSwitch(ads_hub, name, ads_var)], True)
class AdsSwitch(ToggleEntity):
"""Representation of an ADS switch device."""
def __init__(self, ads_hub, name, ads_var):
"""Initialize the AdsSwitch entity."""
self._ads_hub = ads_hub
self._on_state = False
self._name = name
self._unique_id = ads_var
self.ads_var = ads_var
async def async_added_to_hass(self):
"""Register device notification."""
def update(name, value):
"""Handle device notification."""
_LOGGER.debug("Variable %s changed its value to %d", name, value)
self._on_state = value
self.schedule_update_ha_state()
self.hass.async_add_job(
self._ads_hub.add_device_notification,
self.ads_var, self._ads_hub.PLCTYPE_BOOL, update)
@property
def is_on(self):
"""Return if the switch is turned on."""
return self._on_state
@property
def name(self):
"""Return the name of the entity."""
return self._name
@property
def unique_id(self):
"""Return an unique identifier for this entity."""
return self._unique_id
@property
def should_poll(self):
"""Return False because entity pushes its state to HA."""
return False
def turn_on(self, **kwargs):
"""Turn the switch on."""
self._ads_hub.write_by_name(
self.ads_var, True, self._ads_hub.PLCTYPE_BOOL)
def turn_off(self, **kwargs):
"""Turn the switch off."""
self._ads_hub.write_by_name(
self.ads_var, False, self._ads_hub.PLCTYPE_BOOL)

View File

@@ -0,0 +1,148 @@
"""
Component for handling Air Quality data for your location.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/air_quality/
"""
from datetime import timedelta
import logging
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.config_validation import ( # noqa
PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE)
from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
ATTR_AQI = 'air_quality_index'
ATTR_ATTRIBUTION = 'attribution'
ATTR_CO2 = 'carbon_dioxide'
ATTR_CO = 'carbon_monoxide'
ATTR_N2O = 'nitrogen_oxide'
ATTR_NO = 'nitrogen_monoxide'
ATTR_NO2 = 'nitrogen_dioxide'
ATTR_OZONE = 'ozone'
ATTR_PM_0_1 = 'particulate_matter_0_1'
ATTR_PM_10 = 'particulate_matter_10'
ATTR_PM_2_5 = 'particulate_matter_2_5'
ATTR_SO2 = 'sulphur_dioxide'
DOMAIN = 'air_quality'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
SCAN_INTERVAL = timedelta(seconds=30)
PROP_TO_ATTR = {
'air_quality_index': ATTR_AQI,
'attribution': ATTR_ATTRIBUTION,
'carbon_dioxide': ATTR_CO2,
'carbon_monoxide': ATTR_CO,
'nitrogen_oxide': ATTR_N2O,
'nitrogen_monoxide': ATTR_NO,
'nitrogen_dioxide': ATTR_NO2,
'ozone': ATTR_OZONE,
'particulate_matter_0_1': ATTR_PM_0_1,
'particulate_matter_10': ATTR_PM_10,
'particulate_matter_2_5': ATTR_PM_2_5,
'sulphur_dioxide': ATTR_SO2,
}
async def async_setup(hass, config):
"""Set up the air quality component."""
component = hass.data[DOMAIN] = EntityComponent(
_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
await component.async_setup(config)
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)
class AirQualityEntity(Entity):
"""ABC for air quality data."""
@property
def particulate_matter_2_5(self):
"""Return the particulate matter 2.5 level."""
raise NotImplementedError()
@property
def particulate_matter_10(self):
"""Return the particulate matter 10 level."""
return None
@property
def particulate_matter_0_1(self):
"""Return the particulate matter 0.1 level."""
return None
@property
def air_quality_index(self):
"""Return the Air Quality Index (AQI)."""
return None
@property
def ozone(self):
"""Return the O3 (ozone) level."""
return None
@property
def carbon_monoxide(self):
"""Return the CO (carbon monoxide) level."""
return None
@property
def carbon_dioxide(self):
"""Return the CO2 (carbon dioxide) level."""
return None
@property
def attribution(self):
"""Return the attribution."""
return None
@property
def sulphur_dioxide(self):
"""Return the SO2 (sulphur dioxide) level."""
return None
@property
def nitrogen_oxide(self):
"""Return the N2O (nitrogen oxide) level."""
return None
@property
def nitrogen_monoxide(self):
"""Return the NO (nitrogen monoxide) level."""
return None
@property
def nitrogen_dioxide(self):
"""Return the NO2 (nitrogen dioxide) level."""
return None
@property
def state_attributes(self):
"""Return the state attributes."""
data = {}
for prop, attr in PROP_TO_ATTR.items():
value = getattr(self, prop)
if value is not None:
data[attr] = value
return data
@property
def state(self):
"""Return the current state."""
return self.particulate_matter_2_5

View File

@@ -0,0 +1,56 @@
"""
Demo platform that offers fake air quality data.
For more details about this platform, please refer to the documentation
https://home-assistant.io/components/demo/
"""
from homeassistant.components.air_quality import AirQualityEntity
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Air Quality."""
add_entities([
DemoAirQuality('Home', 14, 23, 100),
DemoAirQuality('Office', 4, 16, None)
])
class DemoAirQuality(AirQualityEntity):
"""Representation of Air Quality data."""
def __init__(self, name, pm_2_5, pm_10, n2o):
"""Initialize the Demo Air Quality."""
self._name = name
self._pm_2_5 = pm_2_5
self._pm_10 = pm_10
self._n2o = n2o
@property
def name(self):
"""Return the name of the sensor."""
return '{} {}'.format('Demo Air Quality', self._name)
@property
def should_poll(self):
"""No polling needed for Demo Air Quality."""
return False
@property
def particulate_matter_2_5(self):
"""Return the particulate matter 2.5 level."""
return self._pm_2_5
@property
def particulate_matter_10(self):
"""Return the particulate matter 10 level."""
return self._pm_10
@property
def nitrogen_oxide(self):
"""Return the nitrogen oxide (N2O) level."""
return self._n2o
@property
def attribution(self):
"""Return the attribution."""
return 'Powered by Home Assistant'

View File

@@ -0,0 +1,252 @@
"""
Sensor for checking the air quality around Norway.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/air_quality.nilu/
"""
from datetime import timedelta
import logging
import voluptuous as vol
from homeassistant.components.air_quality import (
PLATFORM_SCHEMA, AirQualityEntity)
from homeassistant.const import (
CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, CONF_SHOW_ON_MAP)
import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle
REQUIREMENTS = ['niluclient==0.1.2']
_LOGGER = logging.getLogger(__name__)
ATTR_AREA = 'area'
ATTR_POLLUTION_INDEX = 'nilu_pollution_index'
ATTRIBUTION = "Data provided by luftkvalitet.info and nilu.no"
CONF_AREA = 'area'
CONF_STATION = 'stations'
DEFAULT_NAME = 'NILU'
SCAN_INTERVAL = timedelta(minutes=30)
CONF_ALLOWED_AREAS = [
'Bergen',
'Birkenes',
'Bodø',
'Brumunddal',
'Bærum',
'Drammen',
'Elverum',
'Fredrikstad',
'Gjøvik',
'Grenland',
'Halden',
'Hamar',
'Harstad',
'Hurdal',
'Karasjok',
'Kristiansand',
'Kårvatn',
'Lillehammer',
'Lillesand',
'Lillestrøm',
'Lørenskog',
'Mo i Rana',
'Moss',
'Narvik',
'Oslo',
'Prestebakke',
'Sandve',
'Sarpsborg',
'Stavanger',
'Sør-Varanger',
'Tromsø',
'Trondheim',
'Tustervatn',
'Zeppelinfjellet',
'Ålesund',
]
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Inclusive(CONF_LATITUDE, 'coordinates',
'Latitude and longitude must exist together'): cv.latitude,
vol.Inclusive(CONF_LONGITUDE, 'coordinates',
'Latitude and longitude must exist together'): cv.longitude,
vol.Exclusive(CONF_AREA, 'station_collection',
'Can only configure one specific station or '
'stations in a specific area pr sensor. '
'Please only configure station or area.'
): vol.All(cv.string, vol.In(CONF_ALLOWED_AREAS)),
vol.Exclusive(CONF_STATION, 'station_collection',
'Can only configure one specific station or '
'stations in a specific area pr sensor. '
'Please only configure station or area.'
): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_SHOW_ON_MAP, default=False): cv.boolean,
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the NILU air quality sensor."""
import niluclient as nilu
name = config.get(CONF_NAME)
area = config.get(CONF_AREA)
stations = config.get(CONF_STATION)
show_on_map = config.get(CONF_SHOW_ON_MAP)
sensors = []
if area:
stations = nilu.lookup_stations_in_area(area)
elif not area and not stations:
latitude = config.get(CONF_LATITUDE, hass.config.latitude)
longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
location_client = nilu.create_location_client(latitude, longitude)
stations = location_client.station_names
for station in stations:
client = NiluData(nilu.create_station_client(station))
client.update()
if client.data.sensors:
sensors.append(NiluSensor(client, name, show_on_map))
else:
_LOGGER.warning("%s didn't give any sensors results", station)
add_entities(sensors, True)
class NiluData:
"""Class for handling the data retrieval."""
def __init__(self, api):
"""Initialize the data object."""
self.api = api
@property
def data(self):
"""Get data cached in client."""
return self.api.data
@Throttle(SCAN_INTERVAL)
def update(self):
"""Get the latest data from nilu API."""
self.api.update()
class NiluSensor(AirQualityEntity):
"""Single nilu station air sensor."""
def __init__(self, api_data: NiluData, name: str, show_on_map: bool):
"""Initialize the sensor."""
self._api = api_data
self._name = "{} {}".format(name, api_data.data.name)
self._max_aqi = None
self._attrs = {}
if show_on_map:
self._attrs[CONF_LATITUDE] = api_data.data.latitude
self._attrs[CONF_LONGITUDE] = api_data.data.longitude
@property
def attribution(self) -> str:
"""Return the attribution."""
return ATTRIBUTION
@property
def device_state_attributes(self) -> dict:
"""Return other details about the sensor state."""
return self._attrs
@property
def name(self) -> str:
"""Return the name of the sensor."""
return self._name
@property
def air_quality_index(self) -> str:
"""Return the Air Quality Index (AQI)."""
return self._max_aqi
@property
def carbon_monoxide(self) -> str:
"""Return the CO (carbon monoxide) level."""
from niluclient import CO
return self.get_component_state(CO)
@property
def carbon_dioxide(self) -> str:
"""Return the CO2 (carbon dioxide) level."""
from niluclient import CO2
return self.get_component_state(CO2)
@property
def nitrogen_oxide(self) -> str:
"""Return the N2O (nitrogen oxide) level."""
from niluclient import NOX
return self.get_component_state(NOX)
@property
def nitrogen_monoxide(self) -> str:
"""Return the NO (nitrogen monoxide) level."""
from niluclient import NO
return self.get_component_state(NO)
@property
def nitrogen_dioxide(self) -> str:
"""Return the NO2 (nitrogen dioxide) level."""
from niluclient import NO2
return self.get_component_state(NO2)
@property
def ozone(self) -> str:
"""Return the O3 (ozone) level."""
from niluclient import OZONE
return self.get_component_state(OZONE)
@property
def particulate_matter_2_5(self) -> str:
"""Return the particulate matter 2.5 level."""
from niluclient import PM25
return self.get_component_state(PM25)
@property
def particulate_matter_10(self) -> str:
"""Return the particulate matter 10 level."""
from niluclient import PM10
return self.get_component_state(PM10)
@property
def particulate_matter_0_1(self) -> str:
"""Return the particulate matter 0.1 level."""
from niluclient import PM1
return self.get_component_state(PM1)
@property
def sulphur_dioxide(self) -> str:
"""Return the SO2 (sulphur dioxide) level."""
from niluclient import SO2
return self.get_component_state(SO2)
def get_component_state(self, component_name: str) -> str:
"""Return formatted value of specified component."""
if component_name in self._api.data.sensors:
sensor = self._api.data.sensors[component_name]
return sensor.value
return None
def update(self) -> None:
"""Update the sensor."""
import niluclient as nilu
self._api.update()
sensors = self._api.data.sensors.values()
if sensors:
max_index = max([s.pollution_index for s in sensors])
self._max_aqi = max_index
self._attrs[ATTR_POLLUTION_INDEX] = \
nilu.POLLUTION_INDEX[self._max_aqi]
self._attrs[ATTR_AREA] = self._api.data.area

View File

@@ -0,0 +1,140 @@
"""
Sensor for checking the air quality forecast around Norway.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/air_quality.norway_air/
"""
import logging
from datetime import timedelta
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.air_quality import (
PLATFORM_SCHEMA, AirQualityEntity)
from homeassistant.const import (CONF_LATITUDE, CONF_LONGITUDE,
CONF_NAME)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
REQUIREMENTS = ['pyMetno==0.4.6']
_LOGGER = logging.getLogger(__name__)
ATTRIBUTION = "Air quality from " \
"https://luftkvalitet.miljostatus.no/, " \
"delivered by the Norwegian Meteorological Institute."
# https://api.met.no/license_data.html
CONF_FORECAST = 'forecast'
DEFAULT_FORECAST = 0
DEFAULT_NAME = 'Air quality Norway'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_FORECAST, default=DEFAULT_FORECAST): vol.Coerce(int),
vol.Optional(CONF_LATITUDE): cv.latitude,
vol.Optional(CONF_LONGITUDE): cv.longitude,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
})
SCAN_INTERVAL = timedelta(minutes=5)
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the air_quality norway sensor."""
forecast = config.get(CONF_FORECAST)
latitude = config.get(CONF_LATITUDE, hass.config.latitude)
longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
name = config.get(CONF_NAME)
if None in (latitude, longitude):
_LOGGER.error("Latitude or longitude not set in Home Assistant config")
return
coordinates = {
'lat': str(latitude),
'lon': str(longitude),
}
async_add_entities([AirSensor(name, coordinates,
forecast, async_get_clientsession(hass),
)],
True)
def round_state(func):
"""Round state."""
def _decorator(self):
res = func(self)
if isinstance(res, float):
return round(res, 2)
return res
return _decorator
class AirSensor(AirQualityEntity):
"""Representation of an Yr.no sensor."""
def __init__(self, name, coordinates, forecast, session):
"""Initialize the sensor."""
import metno
self._name = name
self._api = metno.AirQualityData(coordinates, forecast, session)
@property
def attribution(self) -> str:
"""Return the attribution."""
return ATTRIBUTION
@property
def device_state_attributes(self) -> dict:
"""Return other details about the sensor state."""
return {'level': self._api.data.get('level'),
'location': self._api.data.get('location'),
}
@property
def name(self) -> str:
"""Return the name of the sensor."""
return self._name
@property
@round_state
def air_quality_index(self):
"""Return the Air Quality Index (AQI)."""
return self._api.data.get('aqi')
@property
@round_state
def nitrogen_dioxide(self):
"""Return the NO2 (nitrogen dioxide) level."""
return self._api.data.get('no2_concentration')
@property
@round_state
def ozone(self):
"""Return the O3 (ozone) level."""
return self._api.data.get('o3_concentration')
@property
@round_state
def particulate_matter_2_5(self):
"""Return the particulate matter 2.5 level."""
return self._api.data.get('pm25_concentration')
@property
@round_state
def particulate_matter_10(self):
"""Return the particulate matter 10 level."""
return self._api.data.get('pm10_concentration')
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self._api.units.get('pm25_concentration')
async def async_update(self) -> None:
"""Update the sensor."""
await self._api.update()

View File

@@ -0,0 +1,100 @@
"""Support for openSenseMap Air Quality data."""
from datetime import timedelta
import logging
import voluptuous as vol
from homeassistant.components.air_quality import (
PLATFORM_SCHEMA, AirQualityEntity)
from homeassistant.const import CONF_NAME
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle
REQUIREMENTS = ['opensensemap-api==0.1.5']
_LOGGER = logging.getLogger(__name__)
ATTRIBUTION = 'Data provided by openSenseMap'
CONF_STATION_ID = 'station_id'
SCAN_INTERVAL = timedelta(minutes=10)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_STATION_ID): cv.string,
vol.Optional(CONF_NAME): cv.string,
})
async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None):
"""Set up the openSenseMap air quality platform."""
from opensensemap_api import OpenSenseMap
name = config.get(CONF_NAME)
station_id = config[CONF_STATION_ID]
session = async_get_clientsession(hass)
osm_api = OpenSenseMapData(OpenSenseMap(station_id, hass.loop, session))
await osm_api.async_update()
if 'name' not in osm_api.api.data:
_LOGGER.error("Station %s is not available", station_id)
return
station_name = osm_api.api.data['name'] if name is None else name
async_add_entities([OpenSenseMapQuality(station_name, osm_api)], True)
class OpenSenseMapQuality(AirQualityEntity):
"""Implementation of an openSenseMap air quality entity."""
def __init__(self, name, osm):
"""Initialize the air quality entity."""
self._name = name
self._osm = osm
@property
def name(self):
"""Return the name of the air quality entity."""
return self._name
@property
def particulate_matter_2_5(self):
"""Return the particulate matter 2.5 level."""
return self._osm.api.pm2_5
@property
def particulate_matter_10(self):
"""Return the particulate matter 10 level."""
return self._osm.api.pm10
@property
def attribution(self):
"""Return the attribution."""
return ATTRIBUTION
async def async_update(self):
"""Get the latest data from the openSenseMap API."""
await self._osm.async_update()
class OpenSenseMapData:
"""Get the latest data and update the states."""
def __init__(self, api):
"""Initialize the data object."""
self.api = api
@Throttle(SCAN_INTERVAL)
async def async_update(self):
"""Get the latest data from the Pi-hole."""
from opensensemap_api.exceptions import OpenSenseMapError
try:
await self.api.get_data()
except OpenSenseMapError as err:
_LOGGER.error("Unable to fetch data: %s", err)

View File

@@ -13,7 +13,8 @@ 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.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.helpers.config_validation import ( # noqa
PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
@@ -21,11 +22,13 @@ from homeassistant.helpers.entity_component import EntityComponent
DOMAIN = 'alarm_control_panel'
SCAN_INTERVAL = timedelta(seconds=30)
ATTR_CHANGED_BY = 'changed_by'
FORMAT_TEXT = 'text'
FORMAT_NUMBER = 'number'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
ALARM_SERVICE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
vol.Optional(ATTR_ENTITY_ID): cv.comp_entity_ids,
vol.Optional(ATTR_CODE): cv.string,
})

View File

@@ -1,85 +0,0 @@
"""
This component provides HA alarm_control_panel support for Abode System.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.abode/
"""
import logging
from homeassistant.components.abode import CONF_ATTRIBUTION, AbodeDevice
from homeassistant.components.abode import DOMAIN as ABODE_DOMAIN
from homeassistant.components.alarm_control_panel import AlarmControlPanel
from homeassistant.const import (
ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED)
DEPENDENCIES = ['abode']
_LOGGER = logging.getLogger(__name__)
ICON = 'mdi:security'
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]
alarm_devices = [AbodeAlarm(data, data.abode.get_alarm(), data.name)]
data.devices.extend(alarm_devices)
add_entities(alarm_devices)
class AbodeAlarm(AbodeDevice, AlarmControlPanel):
"""An alarm_control_panel implementation for Abode."""
def __init__(self, data, device, name):
"""Initialize the alarm control panel."""
super().__init__(data, device)
self._name = name
@property
def icon(self):
"""Return the icon."""
return ICON
@property
def state(self):
"""Return the state of the device."""
if self._device.is_standby:
state = STATE_ALARM_DISARMED
elif self._device.is_away:
state = STATE_ALARM_ARMED_AWAY
elif self._device.is_home:
state = STATE_ALARM_ARMED_HOME
else:
state = None
return state
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._device.set_standby()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self._device.set_home()
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self._device.set_away()
@property
def name(self):
"""Return the name of the alarm."""
return self._name or super().name
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
'device_id': self._device.device_id,
'battery_backup': self._device.battery,
'cellular_backup': self._device.is_cellular,
}

View File

@@ -1,142 +0,0 @@
"""
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 logging
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarmdecoder import DATA_AD, SIGNAL_PANEL_MESSAGE
from homeassistant.const import (
ATTR_CODE, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED)
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['alarmdecoder']
SERVICE_ALARM_TOGGLE_CHIME = 'alarmdecoder_alarm_toggle_chime'
ALARM_TOGGLE_CHIME_SCHEMA = vol.Schema({
vol.Required(ATTR_CODE): cv.string,
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up for AlarmDecoder alarm panels."""
device = AlarmDecoderAlarmPanel()
add_entities([device])
def alarm_toggle_chime_handler(service):
"""Register toggle chime handler."""
code = service.data.get(ATTR_CODE)
device.alarm_toggle_chime(code)
hass.services.register(
alarm.DOMAIN, SERVICE_ALARM_TOGGLE_CHIME, alarm_toggle_chime_handler,
schema=ALARM_TOGGLE_CHIME_SCHEMA)
class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
"""Representation of an AlarmDecoder-based alarm panel."""
def __init__(self):
"""Initialize the alarm panel."""
self._display = ""
self._name = "Alarm Panel"
self._state = None
self._ac_power = None
self._backlight_on = None
self._battery_low = None
self._check_zone = None
self._chime = None
self._entry_delay_off = None
self._programming_mode = None
self._ready = None
self._zone_bypassed = None
async def async_added_to_hass(self):
"""Register callbacks."""
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_PANEL_MESSAGE, self._message_callback)
def _message_callback(self, message):
"""Handle received messages."""
if message.alarm_sounding or message.fire_alarm:
self._state = STATE_ALARM_TRIGGERED
elif message.armed_away:
self._state = STATE_ALARM_ARMED_AWAY
elif message.armed_home:
self._state = STATE_ALARM_ARMED_HOME
else:
self._state = STATE_ALARM_DISARMED
self._ac_power = message.ac_power
self._backlight_on = message.backlight_on
self._battery_low = message.battery_low
self._check_zone = message.check_zone
self._chime = message.chime_on
self._entry_delay_off = message.entry_delay_off
self._programming_mode = message.programming_mode
self._ready = message.ready
self._zone_bypassed = message.zone_bypassed
self.schedule_update_ha_state()
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def should_poll(self):
"""Return the polling state."""
return False
@property
def code_format(self):
"""Return one or more digits/characters."""
return 'Number'
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'ac_power': self._ac_power,
'backlight_on': self._backlight_on,
'battery_low': self._battery_low,
'check_zone': self._check_zone,
'chime': self._chime,
'entry_delay_off': self._entry_delay_off,
'programming_mode': self._programming_mode,
'ready': self._ready,
'zone_bypassed': self._zone_bypassed,
}
def alarm_disarm(self, code=None):
"""Send disarm command."""
if code:
self.hass.data[DATA_AD].send("{!s}1".format(code))
def alarm_arm_away(self, code=None):
"""Send arm away command."""
if code:
self.hass.data[DATA_AD].send("{!s}2".format(code))
def alarm_arm_home(self, code=None):
"""Send arm home command."""
if code:
self.hass.data[DATA_AD].send("{!s}3".format(code))
def alarm_toggle_chime(self, code=None):
"""Send toggle chime command."""
if code:
self.hass.data[DATA_AD].send("{!s}9".format(code))

View File

@@ -13,7 +13,7 @@ import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_CODE, CONF_NAME, CONF_PASSWORD, CONF_USERNAME, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN)
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
@@ -57,7 +57,7 @@ class AlarmDotCom(alarm.AlarmControlPanel):
self._username = username
self._password = password
self._websession = async_get_clientsession(self._hass)
self._state = STATE_UNKNOWN
self._state = None
self._alarm = Alarmdotcom(
username, password, self._websession, hass.loop)
@@ -81,8 +81,8 @@ class AlarmDotCom(alarm.AlarmControlPanel):
if self._code is None:
return None
if isinstance(self._code, str) and re.search('^\\d+$', self._code):
return 'Number'
return 'Any'
return alarm.FORMAT_NUMBER
return alarm.FORMAT_TEXT
@property
def state(self):
@@ -93,7 +93,7 @@ class AlarmDotCom(alarm.AlarmControlPanel):
return STATE_ALARM_ARMED_HOME
if self._alarm.state.lower() == 'armed away':
return STATE_ALARM_ARMED_AWAY
return STATE_UNKNOWN
return None
@property
def device_state_attributes(self):

View File

@@ -1,131 +0,0 @@
"""
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 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, SIGNAL_UPDATE_ARLO)
from homeassistant.const import (
ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED)
_LOGGER = logging.getLogger(__name__)
ARMED = 'armed'
CONF_HOME_MODE_NAME = 'home_mode_name'
CONF_AWAY_MODE_NAME = 'away_mode_name'
DEPENDENCIES = ['arlo']
DISARMED = 'disarmed'
ICON = 'mdi:security'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_HOME_MODE_NAME, default=ARMED): cv.string,
vol.Optional(CONF_AWAY_MODE_NAME, default=ARMED): cv.string,
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Arlo Alarm Control Panels."""
arlo = hass.data[DATA_ARLO]
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 arlo.base_stations:
base_stations.append(ArloBaseStation(base_station, home_mode_name,
away_mode_name))
add_entities(base_stations, True)
class ArloBaseStation(AlarmControlPanel):
"""Representation of an Arlo Alarm Control Panel."""
def __init__(self, data, home_mode_name, away_mode_name):
"""Initialize the alarm control panel."""
self._base_station = data
self._home_mode_name = home_mode_name
self._away_mode_name = away_mode_name
self._state = None
@property
def icon(self):
"""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."""
return self._state
def update(self):
"""Update the state of the device."""
_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
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
self._base_station.mode = DISARMED
async def async_alarm_arm_away(self, code=None):
"""Send arm away command. Uses custom mode."""
self._base_station.mode = self._away_mode_name
async def async_alarm_arm_home(self, code=None):
"""Send arm home command. Uses custom mode."""
self._base_station.mode = self._home_mode_name
@property
def name(self):
"""Return the name of the base station."""
return self._base_station.name
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
'device_id': self._base_station.device_id
}
def _get_state_from_mode(self, mode):
"""Convert Arlo mode to Home Assistant state."""
if mode == ARMED:
return STATE_ALARM_ARMED_AWAY
if mode == DISARMED:
return STATE_ALARM_DISARMED
if mode == self._home_mode_name:
return STATE_ALARM_ARMED_HOME
if mode == self._away_mode_name:
return STATE_ALARM_ARMED_AWAY
return mode

View File

@@ -1,91 +0,0 @@
"""
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]
sync_modules = []
for sync_name, sync_module in data.sync.items():
sync_modules.append(BlinkSyncModule(data, sync_name, sync_module))
add_entities(sync_modules, True)
class BlinkSyncModule(AlarmControlPanel):
"""Representation of a Blink Alarm Control Panel."""
def __init__(self, data, name, sync):
"""Initialize the alarm control panel."""
self.data = data
self.sync = 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['associated_cameras'] = list(self.sync.cameras.keys())
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

@@ -5,18 +5,17 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.concord232/
"""
import datetime
from datetime import timedelta
import logging
import requests
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
import homeassistant.helpers.config_validation as cv
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_PORT, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN)
import homeassistant.helpers.config_validation as cv
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED)
REQUIREMENTS = ['concord232==0.15']
@@ -26,7 +25,7 @@ DEFAULT_HOST = 'localhost'
DEFAULT_NAME = 'CONCORD232'
DEFAULT_PORT = 5007
SCAN_INTERVAL = timedelta(seconds=10)
SCAN_INTERVAL = datetime.timedelta(seconds=10)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
@@ -44,33 +43,24 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
url = 'http://{}:{}'.format(host, port)
try:
add_entities([Concord232Alarm(hass, url, name)])
add_entities([Concord232Alarm(url, name)], True)
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to Concord232: %s", str(ex))
return
class Concord232Alarm(alarm.AlarmControlPanel):
"""Representation of the Concord232-based alarm panel."""
def __init__(self, hass, url, name):
def __init__(self, url, name):
"""Initialize the Concord232 alarm panel."""
from concord232 import client as concord232_client
self._state = STATE_UNKNOWN
self._hass = hass
self._state = None
self._name = name
self._url = url
try:
client = concord232_client.Client(self._url)
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to Concord232: %s", str(ex))
self._alarm = client
self._alarm = concord232_client.Client(self._url)
self._alarm.partitions = self._alarm.list_partitions()
self._alarm.last_partition_update = datetime.datetime.now()
self.update()
@property
def name(self):
@@ -80,7 +70,7 @@ class Concord232Alarm(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return the characters if code is defined."""
return 'Number'
return alarm.FORMAT_NUMBER
@property
def state(self):
@@ -94,22 +84,17 @@ class Concord232Alarm(alarm.AlarmControlPanel):
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to %(host)s: %(reason)s",
dict(host=self._url, reason=ex))
newstate = STATE_UNKNOWN
return
except IndexError:
_LOGGER.error("Concord232 reports no partitions")
newstate = STATE_UNKNOWN
return
if part['arming_level'] == 'Off':
newstate = STATE_ALARM_DISARMED
self._state = STATE_ALARM_DISARMED
elif 'Home' in part['arming_level']:
newstate = STATE_ALARM_ARMED_HOME
self._state = STATE_ALARM_ARMED_HOME
else:
newstate = STATE_ALARM_ARMED_AWAY
if not newstate == self._state:
_LOGGER.info("State change from %s to %s", self._state, newstate)
self._state = newstate
return self._state
self._state = STATE_ALARM_ARMED_AWAY
def alarm_disarm(self, code=None):
"""Send disarm command."""

View File

@@ -1,142 +0,0 @@
"""
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 logging
import requests
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.const import (
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_TRIGGERED,
STATE_ALARM_ARMED_NIGHT)
from homeassistant.components.egardia import (
EGARDIA_DEVICE, EGARDIA_SERVER,
REPORT_SERVER_CODES_IGNORE, CONF_REPORT_SERVER_CODES,
CONF_REPORT_SERVER_ENABLED, CONF_REPORT_SERVER_PORT
)
DEPENDENCIES = ['egardia']
_LOGGER = logging.getLogger(__name__)
STATES = {
'ARM': STATE_ALARM_ARMED_AWAY,
'DAY HOME': STATE_ALARM_ARMED_HOME,
'DISARM': STATE_ALARM_DISARMED,
'ARMHOME': STATE_ALARM_ARMED_HOME,
'HOME': STATE_ALARM_ARMED_HOME,
'NIGHT HOME': STATE_ALARM_ARMED_NIGHT,
'TRIGGERED': STATE_ALARM_TRIGGERED
}
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Egardia platform."""
if discovery_info is None:
return
device = EgardiaAlarm(
discovery_info['name'],
hass.data[EGARDIA_DEVICE],
discovery_info[CONF_REPORT_SERVER_ENABLED],
discovery_info.get(CONF_REPORT_SERVER_CODES),
discovery_info[CONF_REPORT_SERVER_PORT])
# add egardia alarm device
add_entities([device], True)
class EgardiaAlarm(alarm.AlarmControlPanel):
"""Representation of a Egardia alarm."""
def __init__(self, name, egardiasystem,
rs_enabled=False, rs_codes=None, rs_port=52010):
"""Initialize the Egardia alarm."""
self._name = name
self._egardiasystem = egardiasystem
self._status = None
self._rs_enabled = rs_enabled
self._rs_codes = rs_codes
self._rs_port = rs_port
async def async_added_to_hass(self):
"""Add Egardiaserver callback if enabled."""
if self._rs_enabled:
_LOGGER.debug("Registering callback to Egardiaserver")
self.hass.data[EGARDIA_SERVER].register_callback(
self.handle_status_event)
@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._status
@property
def should_poll(self):
"""Poll if no report server is enabled."""
if not self._rs_enabled:
return True
return False
def handle_status_event(self, event):
"""Handle the Egardia system status event."""
statuscode = event.get('status')
if statuscode is not None:
status = self.lookupstatusfromcode(statuscode)
self.parsestatus(status)
self.schedule_update_ha_state()
def lookupstatusfromcode(self, statuscode):
"""Look at the rs_codes and returns the status from the code."""
status = next((
status_group.upper() for status_group, codes
in self._rs_codes.items() for code in codes
if statuscode == code), 'UNKNOWN')
return status
def parsestatus(self, status):
"""Parse the status."""
_LOGGER.debug("Parsing status %s", status)
# Ignore the statuscode if it is IGNORE
if status.lower().strip() != REPORT_SERVER_CODES_IGNORE:
_LOGGER.debug("Not ignoring status %s", status)
newstatus = STATES.get(status.upper())
_LOGGER.debug("newstatus %s", newstatus)
self._status = newstatus
else:
_LOGGER.error("Ignoring status")
def update(self):
"""Update the alarm status."""
status = self._egardiasystem.getstate()
self.parsestatus(status)
def alarm_disarm(self, code=None):
"""Send disarm command."""
try:
self._egardiasystem.alarm_disarm()
except requests.exceptions.RequestException as err:
_LOGGER.error("Egardia device exception occurred when "
"sending disarm command: %s", err)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
try:
self._egardiasystem.alarm_arm_home()
except requests.exceptions.RequestException as err:
_LOGGER.error("Egardia device exception occurred when "
"sending arm home command: %s", err)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
try:
self._egardiasystem.alarm_arm_away()
except requests.exceptions.RequestException as err:
_LOGGER.error("Egardia device exception occurred when "
"sending arm away command: %s", err)

View File

@@ -1,204 +0,0 @@
"""
Each ElkM1 area will be created as a separate alarm_control_panel in HASS.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.elkm1/
"""
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.const import (
ATTR_CODE, ATTR_ENTITY_ID, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT, STATE_ALARM_ARMING, STATE_ALARM_DISARMED,
STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED)
from homeassistant.components.elkm1 import (
DOMAIN as ELK_DOMAIN, create_elk_entities, ElkEntity)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, async_dispatcher_send)
DEPENDENCIES = [ELK_DOMAIN]
SIGNAL_ARM_ENTITY = 'elkm1_arm'
SIGNAL_DISPLAY_MESSAGE = 'elkm1_display_message'
ELK_ALARM_SERVICE_SCHEMA = vol.Schema({
vol.Required(ATTR_ENTITY_ID, default=[]): cv.entity_ids,
vol.Required(ATTR_CODE): vol.All(vol.Coerce(int), vol.Range(0, 999999)),
})
DISPLAY_MESSAGE_SERVICE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID, default=[]): cv.entity_ids,
vol.Optional('clear', default=2): vol.In([0, 1, 2]),
vol.Optional('beep', default=False): cv.boolean,
vol.Optional('timeout', default=0): vol.Range(min=0, max=65535),
vol.Optional('line1', default=''): cv.string,
vol.Optional('line2', default=''): cv.string,
})
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the ElkM1 alarm platform."""
if discovery_info is None:
return
elk = hass.data[ELK_DOMAIN]['elk']
entities = create_elk_entities(hass, elk.areas, 'area', ElkArea, [])
async_add_entities(entities, True)
def _dispatch(signal, entity_ids, *args):
for entity_id in entity_ids:
async_dispatcher_send(
hass, '{}_{}'.format(signal, entity_id), *args)
def _arm_service(service):
entity_ids = service.data.get(ATTR_ENTITY_ID, [])
arm_level = _arm_services().get(service.service)
args = (arm_level, service.data.get(ATTR_CODE))
_dispatch(SIGNAL_ARM_ENTITY, entity_ids, *args)
for service in _arm_services():
hass.services.async_register(
alarm.DOMAIN, service, _arm_service, ELK_ALARM_SERVICE_SCHEMA)
def _display_message_service(service):
entity_ids = service.data.get(ATTR_ENTITY_ID, [])
data = service.data
args = (data['clear'], data['beep'], data['timeout'],
data['line1'], data['line2'])
_dispatch(SIGNAL_DISPLAY_MESSAGE, entity_ids, *args)
hass.services.async_register(
alarm.DOMAIN, 'elkm1_alarm_display_message',
_display_message_service, DISPLAY_MESSAGE_SERVICE_SCHEMA)
def _arm_services():
from elkm1_lib.const import ArmLevel
return {
'elkm1_alarm_arm_vacation': ArmLevel.ARMED_VACATION.value,
'elkm1_alarm_arm_home_instant': ArmLevel.ARMED_STAY_INSTANT.value,
'elkm1_alarm_arm_night_instant': ArmLevel.ARMED_NIGHT_INSTANT.value,
}
class ElkArea(ElkEntity, alarm.AlarmControlPanel):
"""Representation of an Area / Partition within the ElkM1 alarm panel."""
def __init__(self, element, elk, elk_data):
"""Initialize Area as Alarm Control Panel."""
super().__init__(element, elk, elk_data)
self._changed_by_entity_id = ''
self._state = None
async def async_added_to_hass(self):
"""Register callback for ElkM1 changes."""
await super().async_added_to_hass()
for keypad in self._elk.keypads:
keypad.add_callback(self._watch_keypad)
async_dispatcher_connect(
self.hass, '{}_{}'.format(SIGNAL_ARM_ENTITY, self.entity_id),
self._arm_service)
async_dispatcher_connect(
self.hass, '{}_{}'.format(SIGNAL_DISPLAY_MESSAGE, self.entity_id),
self._display_message)
def _watch_keypad(self, keypad, changeset):
if keypad.area != self._element.index:
return
if changeset.get('last_user') is not None:
self._changed_by_entity_id = self.hass.data[
ELK_DOMAIN]['keypads'].get(keypad.index, '')
self.async_schedule_update_ha_state(True)
@property
def code_format(self):
"""Return the alarm code format."""
return '^[0-9]{4}([0-9]{2})?$'
@property
def state(self):
"""Return the state of the element."""
return self._state
@property
def device_state_attributes(self):
"""Attributes of the area."""
from elkm1_lib.const import AlarmState, ArmedStatus, ArmUpState
attrs = self.initial_attrs()
elmt = self._element
attrs['is_exit'] = elmt.is_exit
attrs['timer1'] = elmt.timer1
attrs['timer2'] = elmt.timer2
if elmt.armed_status is not None:
attrs['armed_status'] = \
ArmedStatus(elmt.armed_status).name.lower()
if elmt.arm_up_state is not None:
attrs['arm_up_state'] = ArmUpState(elmt.arm_up_state).name.lower()
if elmt.alarm_state is not None:
attrs['alarm_state'] = AlarmState(elmt.alarm_state).name.lower()
attrs['changed_by_entity_id'] = self._changed_by_entity_id
return attrs
def _element_changed(self, element, changeset):
from elkm1_lib.const import ArmedStatus
elk_state_to_hass_state = {
ArmedStatus.DISARMED.value: STATE_ALARM_DISARMED,
ArmedStatus.ARMED_AWAY.value: STATE_ALARM_ARMED_AWAY,
ArmedStatus.ARMED_STAY.value: STATE_ALARM_ARMED_HOME,
ArmedStatus.ARMED_STAY_INSTANT.value: STATE_ALARM_ARMED_HOME,
ArmedStatus.ARMED_TO_NIGHT.value: STATE_ALARM_ARMED_NIGHT,
ArmedStatus.ARMED_TO_NIGHT_INSTANT.value: STATE_ALARM_ARMED_NIGHT,
ArmedStatus.ARMED_TO_VACATION.value: STATE_ALARM_ARMED_AWAY,
}
if self._element.alarm_state is None:
self._state = None
elif self._area_is_in_alarm_state():
self._state = STATE_ALARM_TRIGGERED
elif self._entry_exit_timer_is_running():
self._state = STATE_ALARM_ARMING \
if self._element.is_exit else STATE_ALARM_PENDING
else:
self._state = elk_state_to_hass_state[self._element.armed_status]
def _entry_exit_timer_is_running(self):
return self._element.timer1 > 0 or self._element.timer2 > 0
def _area_is_in_alarm_state(self):
from elkm1_lib.const import AlarmState
return self._element.alarm_state >= AlarmState.FIRE_ALARM.value
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
self._element.disarm(int(code))
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
from elkm1_lib.const import ArmLevel
self._element.arm(ArmLevel.ARMED_STAY.value, int(code))
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
from elkm1_lib.const import ArmLevel
self._element.arm(ArmLevel.ARMED_AWAY.value, int(code))
async def async_alarm_arm_night(self, code=None):
"""Send arm night command."""
from elkm1_lib.const import ArmLevel
self._element.arm(ArmLevel.ARMED_NIGHT.value, int(code))
async def _arm_service(self, arm_level, code):
self._element.arm(arm_level, code)
async def _display_message(self, clear, beep, timeout, line1, line2):
"""Display a message on all keypads for the area."""
self._element.display_message(clear, beep, timeout, line1, line2)

View File

@@ -1,164 +0,0 @@
"""
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 logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
import homeassistant.components.alarm_control_panel as alarm
import homeassistant.helpers.config_validation as cv
from homeassistant.components.envisalink import (
DATA_EVL, EnvisalinkDevice, PARTITION_SCHEMA, CONF_CODE, CONF_PANIC,
CONF_PARTITIONNAME, SIGNAL_KEYPAD_UPDATE, SIGNAL_PARTITION_UPDATE)
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_UNKNOWN, STATE_ALARM_TRIGGERED, STATE_ALARM_PENDING, ATTR_ENTITY_ID)
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['envisalink']
SERVICE_ALARM_KEYPRESS = 'envisalink_alarm_keypress'
ATTR_KEYPRESS = 'keypress'
ALARM_KEYPRESS_SCHEMA = vol.Schema({
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
vol.Required(ATTR_KEYPRESS): cv.string
})
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]
panic_type = discovery_info[CONF_PANIC]
devices = []
for part_num in configured_partitions:
device_config_data = PARTITION_SCHEMA(configured_partitions[part_num])
device = EnvisalinkAlarm(
hass,
part_num,
device_config_data[CONF_PARTITIONNAME],
code,
panic_type,
hass.data[DATA_EVL].alarm_state['partition'][part_num],
hass.data[DATA_EVL]
)
devices.append(device)
async_add_entities(devices)
@callback
def alarm_keypress_handler(service):
"""Map services to methods on Alarm."""
entity_ids = service.data.get(ATTR_ENTITY_ID)
keypress = service.data.get(ATTR_KEYPRESS)
target_devices = [device for device in devices
if device.entity_id in entity_ids]
for device in target_devices:
device.async_alarm_keypress(keypress)
hass.services.async_register(
alarm.DOMAIN, SERVICE_ALARM_KEYPRESS, alarm_keypress_handler,
schema=ALARM_KEYPRESS_SCHEMA)
return True
class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
"""Representation of an Envisalink-based alarm panel."""
def __init__(self, hass, partition_number, alarm_name, code, panic_type,
info, controller):
"""Initialize the alarm panel."""
self._partition_number = partition_number
self._code = code
self._panic_type = panic_type
_LOGGER.debug("Setting up alarm: %s", alarm_name)
super().__init__(alarm_name, info, controller)
async def async_added_to_hass(self):
"""Register callbacks."""
async_dispatcher_connect(
self.hass, SIGNAL_KEYPAD_UPDATE, self._update_callback)
async_dispatcher_connect(
self.hass, SIGNAL_PARTITION_UPDATE, self._update_callback)
@callback
def _update_callback(self, partition):
"""Update Home Assistant state, if needed."""
if partition is None or int(partition) == self._partition_number:
self.async_schedule_update_ha_state()
@property
def code_format(self):
"""Regex for code format or None if no code is required."""
if self._code:
return None
return 'Number'
@property
def state(self):
"""Return the state of the device."""
state = STATE_UNKNOWN
if self._info['status']['alarm']:
state = STATE_ALARM_TRIGGERED
elif self._info['status']['armed_away']:
state = STATE_ALARM_ARMED_AWAY
elif self._info['status']['armed_stay']:
state = STATE_ALARM_ARMED_HOME
elif self._info['status']['exit_delay']:
state = STATE_ALARM_PENDING
elif self._info['status']['entry_delay']:
state = STATE_ALARM_PENDING
elif self._info['status']['alpha']:
state = STATE_ALARM_DISARMED
return state
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
if code:
self.hass.data[DATA_EVL].disarm_partition(
str(code), self._partition_number)
else:
self.hass.data[DATA_EVL].disarm_partition(
str(self._code), self._partition_number)
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
if code:
self.hass.data[DATA_EVL].arm_stay_partition(
str(code), self._partition_number)
else:
self.hass.data[DATA_EVL].arm_stay_partition(
str(self._code), self._partition_number)
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
if code:
self.hass.data[DATA_EVL].arm_away_partition(
str(code), self._partition_number)
else:
self.hass.data[DATA_EVL].arm_away_partition(
str(self._code), self._partition_number)
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)
@callback
def async_alarm_keypress(self, keypress=None):
"""Send custom keypress."""
if keypress:
self.hass.data[DATA_EVL].keypresses_to_partition(
self._partition_number, keypress)

View File

@@ -1,83 +0,0 @@
"""
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

@@ -5,14 +5,16 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.ialarm/
"""
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.const import (
CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_USERNAME, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED)
CONF_CODE, CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_USERNAME,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyialarm==0.3']
@@ -36,6 +38,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): vol.All(cv.string, no_application_protocol),
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Optional(CONF_CODE): cv.positive_int,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
})
@@ -43,23 +46,25 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up an iAlarm control panel."""
name = config.get(CONF_NAME)
code = config.get(CONF_CODE)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
host = config.get(CONF_HOST)
url = 'http://{}'.format(host)
ialarm = IAlarmPanel(name, username, password, url)
ialarm = IAlarmPanel(name, code, username, password, url)
add_entities([ialarm], True)
class IAlarmPanel(alarm.AlarmControlPanel):
"""Representation of an iAlarm status."""
def __init__(self, name, username, password, url):
def __init__(self, name, code, username, password, url):
"""Initialize the iAlarm status."""
from pyialarm import IAlarm
self._name = name
self._code = str(code) if code else None
self._username = username
self._password = password
self._url = url
@@ -71,6 +76,15 @@ class IAlarmPanel(alarm.AlarmControlPanel):
"""Return the name of the device."""
return self._name
@property
def code_format(self):
"""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 alarm.FORMAT_NUMBER
return alarm.FORMAT_TEXT
@property
def state(self):
"""Return the state of the device."""
@@ -98,12 +112,22 @@ class IAlarmPanel(alarm.AlarmControlPanel):
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._client.disarm()
if self._validate_code(code):
self._client.disarm()
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self._client.arm_away()
if self._validate_code(code):
self._client.arm_away()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self._client.arm_stay()
if self._validate_code(code):
self._client.arm_stay()
def _validate_code(self, code):
"""Validate given code."""
check = self._code is None or code == self._code
if not check:
_LOGGER.warning("Wrong code entered")
return check

View File

@@ -1,175 +0,0 @@
"""
Interfaces with alarm control panels that have to be controlled through IFTTT.
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
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import (
DOMAIN, PLATFORM_SCHEMA)
from homeassistant.components.ifttt import (
ATTR_EVENT, DOMAIN as IFTTT_DOMAIN, SERVICE_TRIGGER)
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_STATE, CONF_NAME, CONF_CODE,
CONF_OPTIMISTIC, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY)
import homeassistant.helpers.config_validation as cv
DEPENDENCIES = ['ifttt']
_LOGGER = logging.getLogger(__name__)
ALLOWED_STATES = [
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME]
DATA_IFTTT_ALARM = 'ifttt_alarm'
DEFAULT_NAME = "Home"
CONF_EVENT_AWAY = "event_arm_away"
CONF_EVENT_HOME = "event_arm_home"
CONF_EVENT_NIGHT = "event_arm_night"
CONF_EVENT_DISARM = "event_disarm"
DEFAULT_EVENT_AWAY = "alarm_arm_away"
DEFAULT_EVENT_HOME = "alarm_arm_home"
DEFAULT_EVENT_NIGHT = "alarm_arm_night"
DEFAULT_EVENT_DISARM = "alarm_disarm"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_CODE): cv.string,
vol.Optional(CONF_EVENT_AWAY, default=DEFAULT_EVENT_AWAY): cv.string,
vol.Optional(CONF_EVENT_HOME, default=DEFAULT_EVENT_HOME): cv.string,
vol.Optional(CONF_EVENT_NIGHT, default=DEFAULT_EVENT_NIGHT): cv.string,
vol.Optional(CONF_EVENT_DISARM, default=DEFAULT_EVENT_DISARM): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
})
SERVICE_PUSH_ALARM_STATE = "ifttt_push_alarm_state"
PUSH_ALARM_STATE_SERVICE_SCHEMA = vol.Schema({
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
vol.Required(ATTR_STATE): cv.string,
})
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] = []
name = config.get(CONF_NAME)
code = config.get(CONF_CODE)
event_away = config.get(CONF_EVENT_AWAY)
event_home = config.get(CONF_EVENT_HOME)
event_night = config.get(CONF_EVENT_NIGHT)
event_disarm = config.get(CONF_EVENT_DISARM)
optimistic = config.get(CONF_OPTIMISTIC)
alarmpanel = IFTTTAlarmPanel(name, code, event_away, event_home,
event_night, event_disarm, optimistic)
hass.data[DATA_IFTTT_ALARM].append(alarmpanel)
add_entities([alarmpanel])
async def push_state_update(service):
"""Set the service state as device state attribute."""
entity_ids = service.data.get(ATTR_ENTITY_ID)
state = service.data.get(ATTR_STATE)
devices = hass.data[DATA_IFTTT_ALARM]
if entity_ids:
devices = [d for d in devices if d.entity_id in entity_ids]
for device in devices:
device.push_alarm_state(state)
device.async_schedule_update_ha_state()
hass.services.register(DOMAIN, SERVICE_PUSH_ALARM_STATE, push_state_update,
schema=PUSH_ALARM_STATE_SERVICE_SCHEMA)
class IFTTTAlarmPanel(alarm.AlarmControlPanel):
"""Representation of an alarm control panel controlled through IFTTT."""
def __init__(self, name, code, event_away, event_home, event_night,
event_disarm, optimistic):
"""Initialize the alarm control panel."""
self._name = name
self._code = code
self._event_away = event_away
self._event_home = event_home
self._event_night = event_night
self._event_disarm = event_disarm
self._optimistic = optimistic
self._state = None
@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
@property
def assumed_state(self):
"""Notify that this platform return an assumed state."""
return True
@property
def code_format(self):
"""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."""
if not self._check_code(code):
return
self.set_alarm_state(self._event_disarm, STATE_ALARM_DISARMED)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
if not self._check_code(code):
return
self.set_alarm_state(self._event_away, STATE_ALARM_ARMED_AWAY)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
if not self._check_code(code):
return
self.set_alarm_state(self._event_home, STATE_ALARM_ARMED_HOME)
def alarm_arm_night(self, code=None):
"""Send arm night command."""
if not self._check_code(code):
return
self.set_alarm_state(self._event_night, STATE_ALARM_ARMED_NIGHT)
def set_alarm_state(self, event, state):
"""Call the IFTTT trigger service to change the alarm state."""
data = {ATTR_EVENT: event}
self.hass.services.call(IFTTT_DOMAIN, SERVICE_TRIGGER, data)
_LOGGER.debug("Called IFTTT component to trigger event %s", event)
if self._optimistic:
self._state = state
def push_alarm_state(self, value):
"""Push the alarm state to the given value."""
if value in ALLOWED_STATES:
_LOGGER.debug("Pushed the alarm state to %s", value)
self._state = value
def _check_code(self, code):
return self._code is None or self._code == code

View File

@@ -1,70 +0,0 @@
"""
This component provides HA alarm_control_panel support for Lupusec System.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.lupusec/
"""
from datetime import timedelta
from homeassistant.components.alarm_control_panel import AlarmControlPanel
from homeassistant.components.lupusec import DOMAIN as LUPUSEC_DOMAIN
from homeassistant.components.lupusec import LupusecDevice
from homeassistant.const import (STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED)
DEPENDENCIES = ['lupusec']
ICON = 'mdi:security'
SCAN_INTERVAL = timedelta(seconds=2)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up an alarm control panel for a Lupusec device."""
if discovery_info is None:
return
data = hass.data[LUPUSEC_DOMAIN]
alarm_devices = [LupusecAlarm(data, data.lupusec.get_alarm())]
add_entities(alarm_devices)
class LupusecAlarm(LupusecDevice, AlarmControlPanel):
"""An alarm_control_panel implementation for Lupusec."""
@property
def icon(self):
"""Return the icon."""
return ICON
@property
def state(self):
"""Return the state of the device."""
if self._device.is_standby:
state = STATE_ALARM_DISARMED
elif self._device.is_away:
state = STATE_ALARM_ARMED_AWAY
elif self._device.is_home:
state = STATE_ALARM_ARMED_HOME
elif self._device.is_alarm_triggered:
state = STATE_ALARM_TRIGGERED
else:
state = None
return state
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self._device.set_away()
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._device.set_standby()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self._device.set_home()

View File

@@ -207,8 +207,8 @@ class ManualAlarm(alarm.AlarmControlPanel, RestoreEntity):
if self._code is None:
return None
if isinstance(self._code, str) and re.search('^\\d+$', self._code):
return 'Number'
return 'Any'
return alarm.FORMAT_NUMBER
return alarm.FORMAT_TEXT
def alarm_disarm(self, code=None):
"""Send disarm command."""

View File

@@ -241,8 +241,8 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
if self._code is None:
return None
if isinstance(self._code, str) and re.search('^\\d+$', self._code):
return 'Number'
return 'Any'
return alarm.FORMAT_NUMBER
return alarm.FORMAT_TEXT
def alarm_disarm(self, code=None):
"""Send disarm command."""
@@ -342,18 +342,18 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
)
@callback
def message_received(topic, payload, qos):
def message_received(msg):
"""Run when new MQTT message has been received."""
if payload == self._payload_disarm:
if msg.payload == self._payload_disarm:
self.async_alarm_disarm(self._code)
elif payload == self._payload_arm_home:
elif msg.payload == self._payload_arm_home:
self.async_alarm_arm_home(self._code)
elif payload == self._payload_arm_away:
elif msg.payload == self._payload_arm_away:
self.async_alarm_arm_away(self._code)
elif payload == self._payload_arm_night:
elif msg.payload == self._payload_arm_night:
self.async_alarm_arm_night(self._code)
else:
_LOGGER.warning("Received unexpected payload: %s", payload)
_LOGGER.warning("Received unexpected payload: %s", msg.payload)
return
await mqtt.async_subscribe(

View File

@@ -1,203 +0,0 @@
"""
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 logging
import re
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.components.alarm_control_panel as alarm
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 (
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, subscription)
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__)
CONF_PAYLOAD_DISARM = 'payload_disarm'
CONF_PAYLOAD_ARM_HOME = 'payload_arm_home'
CONF_PAYLOAD_ARM_AWAY = 'payload_arm_away'
DEFAULT_ARM_AWAY = 'ARM_AWAY'
DEFAULT_ARM_HOME = 'ARM_HOME'
DEFAULT_DISARM = 'DISARM'
DEFAULT_NAME = 'MQTT Alarm'
DEPENDENCIES = ['mqtt']
PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Required(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_CODE): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PAYLOAD_ARM_AWAY, default=DEFAULT_ARM_AWAY): cv.string,
vol.Optional(CONF_PAYLOAD_ARM_HOME, default=DEFAULT_ARM_HOME): cv.string,
vol.Optional(CONF_PAYLOAD_DISARM, default=DEFAULT_DISARM): cv.string,
}).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema)
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(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(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(config, async_add_entities,
discovery_hash=None):
"""Set up the MQTT Alarm Control Panel platform."""
async_add_entities([MqttAlarm(config, discovery_hash)])
class MqttAlarm(MqttAvailability, MqttDiscoveryUpdate,
alarm.AlarmControlPanel):
"""Representation of a MQTT alarm status."""
def __init__(self, config, discovery_hash):
"""Init the MQTT Alarm Control Panel."""
self._state = STATE_UNKNOWN
self._config = config
self._sub_state = None
availability_topic = config.get(CONF_AVAILABILITY_TOPIC)
payload_available = config.get(CONF_PAYLOAD_AVAILABLE)
payload_not_available = config.get(CONF_PAYLOAD_NOT_AVAILABLE)
qos = config.get(CONF_QOS)
MqttAvailability.__init__(self, availability_topic, qos,
payload_available, payload_not_available)
MqttDiscoveryUpdate.__init__(self, discovery_hash,
self.discovery_update)
async def async_added_to_hass(self):
"""Subscribe mqtt events."""
await super().async_added_to_hass()
await self._subscribe_topics()
async def discovery_update(self, discovery_payload):
"""Handle updated discovery message."""
config = PLATFORM_SCHEMA(discovery_payload)
self._config = config
await self.availability_discovery_update(config)
await self._subscribe_topics()
self.async_schedule_update_ha_state()
async def _subscribe_topics(self):
"""(Re)Subscribe to topics."""
@callback
def message_received(topic, payload, qos):
"""Run when new MQTT message has been received."""
if payload not in (STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_PENDING,
STATE_ALARM_TRIGGERED):
_LOGGER.warning("Received unexpected payload: %s", payload)
return
self._state = payload
self.async_schedule_update_ha_state()
self._sub_state = await subscription.async_subscribe_topics(
self.hass, self._sub_state,
{'state_topic': {'topic': self._config.get(CONF_STATE_TOPIC),
'msg_callback': message_received,
'qos': self._config.get(CONF_QOS)}})
async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
await MqttAvailability.async_will_remove_from_hass(self)
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def name(self):
"""Return the name of the device."""
return self._config.get(CONF_NAME)
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def code_format(self):
"""Return one or more digits/characters."""
code = self._config.get(CONF_CODE)
if code is None:
return None
if isinstance(code, str) and re.search('^\\d+$', code):
return 'Number'
return 'Any'
async def async_alarm_disarm(self, code=None):
"""Send disarm command.
This method is a coroutine.
"""
if not self._validate_code(code, 'disarming'):
return
mqtt.async_publish(
self.hass, self._config.get(CONF_COMMAND_TOPIC),
self._config.get(CONF_PAYLOAD_DISARM),
self._config.get(CONF_QOS),
self._config.get(CONF_RETAIN))
async def async_alarm_arm_home(self, code=None):
"""Send arm home command.
This method is a coroutine.
"""
if not self._validate_code(code, 'arming home'):
return
mqtt.async_publish(
self.hass, self._config.get(CONF_COMMAND_TOPIC),
self._config.get(CONF_PAYLOAD_ARM_HOME),
self._config.get(CONF_QOS),
self._config.get(CONF_RETAIN))
async def async_alarm_arm_away(self, code=None):
"""Send arm away command.
This method is a coroutine.
"""
if not self._validate_code(code, 'arming away'):
return
mqtt.async_publish(
self.hass, self._config.get(CONF_COMMAND_TOPIC),
self._config.get(CONF_PAYLOAD_ARM_AWAY),
self._config.get(CONF_QOS),
self._config.get(CONF_RETAIN))
def _validate_code(self, code, state):
"""Validate given code."""
conf_code = self._config.get(CONF_CODE)
check = conf_code is None or code == conf_code
if not check:
_LOGGER.warning('Wrong code entered for %s', state)
return check

View File

@@ -0,0 +1,107 @@
"""
Support for Ness D8X/D16X alarm panel.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.ness_alarm/
"""
import logging
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.ness_alarm import (
DATA_NESS, SIGNAL_ARMING_STATE_CHANGED)
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMING,
STATE_ALARM_TRIGGERED, STATE_ALARM_PENDING, STATE_ALARM_DISARMED)
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['ness_alarm']
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the Ness Alarm alarm control panel devices."""
if discovery_info is None:
return
device = NessAlarmPanel(hass.data[DATA_NESS], 'Alarm Panel')
async_add_entities([device])
class NessAlarmPanel(alarm.AlarmControlPanel):
"""Representation of a Ness alarm panel."""
def __init__(self, client, name):
"""Initialize the alarm panel."""
self._client = client
self._name = name
self._state = None
async def async_added_to_hass(self):
"""Register callbacks."""
async_dispatcher_connect(
self.hass, SIGNAL_ARMING_STATE_CHANGED,
self._handle_arming_state_change)
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def should_poll(self):
"""Return the polling state."""
return False
@property
def code_format(self):
"""Return the regex for code format or None if no code is required."""
return alarm.FORMAT_NUMBER
@property
def state(self):
"""Return the state of the device."""
return self._state
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
await self._client.disarm(code)
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
await self._client.arm_away(code)
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
await self._client.arm_home(code)
async def async_alarm_trigger(self, code=None):
"""Send trigger/panic command."""
await self._client.panic(code)
@callback
def _handle_arming_state_change(self, arming_state):
"""Handle arming state update."""
from nessclient import ArmingState
if arming_state == ArmingState.UNKNOWN:
self._state = None
elif arming_state == ArmingState.DISARMED:
self._state = STATE_ALARM_DISARMED
elif arming_state == ArmingState.ARMING:
self._state = STATE_ALARM_ARMING
elif arming_state == ArmingState.EXIT_DELAY:
self._state = STATE_ALARM_ARMING
elif arming_state == ArmingState.ARMED:
self._state = STATE_ALARM_ARMED_AWAY
elif arming_state == ArmingState.ENTRY_DELAY:
self._state = STATE_ALARM_PENDING
elif arming_state == ArmingState.TRIGGERED:
self._state = STATE_ALARM_TRIGGERED
else:
_LOGGER.warning("Unhandled arming state: %s", arming_state)
self.async_schedule_update_ha_state()

View File

@@ -13,7 +13,7 @@ import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_PORT, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN)
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pynx584==0.4']
@@ -43,7 +43,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
add_entities([NX584Alarm(hass, url, name)])
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to NX584: %s", str(ex))
return False
return
class NX584Alarm(alarm.AlarmControlPanel):
@@ -60,7 +60,7 @@ class NX584Alarm(alarm.AlarmControlPanel):
# talk to the API and trigger a requests exception for setup_platform()
# to catch
self._alarm.list_zones()
self._state = STATE_UNKNOWN
self._state = None
@property
def name(self):
@@ -70,7 +70,7 @@ class NX584Alarm(alarm.AlarmControlPanel):
@property
def code_format(self):
"""Return one or more digits/characters."""
return 'Number'
return alarm.FORMAT_NUMBER
@property
def state(self):
@@ -85,11 +85,11 @@ class NX584Alarm(alarm.AlarmControlPanel):
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to %(host)s: %(reason)s",
dict(host=self._url, reason=ex))
self._state = STATE_UNKNOWN
self._state = None
zones = []
except IndexError:
_LOGGER.error("NX584 reports no partitions")
self._state = STATE_UNKNOWN
self._state = None
zones = []
bypassed = False
@@ -107,6 +107,10 @@ class NX584Alarm(alarm.AlarmControlPanel):
else:
self._state = STATE_ALARM_ARMED_AWAY
for flag in part['condition_flags']:
if flag == "Siren on":
self._state = STATE_ALARM_TRIGGERED
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._alarm.disarm(code)

View File

@@ -1,88 +0,0 @@
"""
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 logging
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.satel_integra import (
CONF_ARM_HOME_MODE, DATA_SATEL, SIGNAL_PANEL_MESSAGE)
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['satel_integra']
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_entities([device])
class SatelIntegraAlarmPanel(alarm.AlarmControlPanel):
"""Representation of an AlarmDecoder-based alarm panel."""
def __init__(self, name, arm_home_mode):
"""Initialize the alarm panel."""
self._name = name
self._state = None
self._arm_home_mode = arm_home_mode
async def async_added_to_hass(self):
"""Register callbacks."""
async_dispatcher_connect(
self.hass, SIGNAL_PANEL_MESSAGE, self._message_callback)
@callback
def _message_callback(self, message):
"""Handle received messages."""
if message != self._state:
self._state = message
self.async_schedule_update_ha_state()
else:
_LOGGER.warning("Ignoring alarm status message, same state")
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def should_poll(self):
"""Return the polling state."""
return False
@property
def code_format(self):
"""Return the regex for code format or None if no code is required."""
return 'Number'
@property
def state(self):
"""Return the state of the device."""
return self._state
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
if code:
await self.hass.data[DATA_SATEL].disarm(code)
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
if code:
await self.hass.data[DATA_SATEL].arm(code)
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
if code:
await self.hass.data[DATA_SATEL].arm(
code, self._arm_home_mode)

View File

@@ -1,145 +0,0 @@
"""
This platform provides alarm control functionality for SimpliSafe.
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
from homeassistant.components.alarm_control_panel import AlarmControlPanel
from homeassistant.components.simplisafe.const import (
DATA_CLIENT, DOMAIN, TOPIC_UPDATE)
from homeassistant.const import (
CONF_CODE, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED)
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
_LOGGER = logging.getLogger(__name__)
ATTR_ALARM_ACTIVE = 'alarm_active'
ATTR_TEMPERATURE = 'temperature'
async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None):
"""Set up a SimpliSafe alarm control panel based on existing config."""
pass
async def async_setup_entry(hass, entry, async_add_entities):
"""Set up a SimpliSafe alarm control panel based on a config entry."""
systems = hass.data[DOMAIN][DATA_CLIENT][entry.entry_id]
async_add_entities([
SimpliSafeAlarm(system, entry.data.get(CONF_CODE))
for system in systems
], True)
class SimpliSafeAlarm(AlarmControlPanel):
"""Representation of a SimpliSafe alarm."""
def __init__(self, system, code):
"""Initialize the SimpliSafe alarm."""
self._async_unsub_dispatcher_connect = None
self._attrs = {}
self._code = code
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."""
return self._system.address
@property
def code_format(self):
"""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."""
return self._state
@property
def device_state_attributes(self):
"""Return the state attributes."""
return self._attrs
def _validate_code(self, code, state):
"""Validate given code."""
check = self._code is None or code == self._code
if not check:
_LOGGER.warning("Wrong code entered for %s", state)
return check
async def async_added_to_hass(self):
"""Register callbacks."""
@callback
def update():
"""Update the state."""
self.async_schedule_update_ha_state(True)
self._async_unsub_dispatcher_connect = async_dispatcher_connect(
self.hass, TOPIC_UPDATE, update)
async def async_will_remove_from_hass(self) -> None:
"""Disconnect dispatcher listener when removed."""
if self._async_unsub_dispatcher_connect:
self._async_unsub_dispatcher_connect()
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."""
from simplipy.system import SystemStates
await self._system.update()
self._attrs[ATTR_ALARM_ACTIVE] = self._system.alarm_going_off
if self._system.temperature:
self._attrs[ATTR_TEMPERATURE] = self._system.temperature
if self._system.state == SystemStates.error:
return
if self._system.state == SystemStates.off:
self._state = STATE_ALARM_DISARMED
elif self._system.state in (SystemStates.home,
SystemStates.home_count):
self._state = STATE_ALARM_ARMED_HOME
elif self._system.state in (SystemStates.away, SystemStates.away_count,
SystemStates.exit_delay):
self._state = STATE_ALARM_ARMED_AWAY
else:
self._state = None

View File

@@ -14,11 +14,11 @@ from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_PASSWORD, CONF_USERNAME, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED,
STATE_ALARM_ARMING, STATE_ALARM_DISARMING, STATE_UNKNOWN, CONF_NAME,
STATE_ALARM_ARMING, STATE_ALARM_DISARMING, CONF_NAME,
STATE_ALARM_ARMED_CUSTOM_BYPASS)
REQUIREMENTS = ['total_connect_client==0.22']
REQUIREMENTS = ['total_connect_client==0.25']
_LOGGER = logging.getLogger(__name__)
@@ -52,7 +52,7 @@ class TotalConnect(alarm.AlarmControlPanel):
self._name = name
self._username = username
self._password = password
self._state = STATE_UNKNOWN
self._state = None
self._client = TotalConnectClient.TotalConnectClient(
username, password)
@@ -85,7 +85,7 @@ class TotalConnect(alarm.AlarmControlPanel):
elif status == self._client.DISARMING:
state = STATE_ALARM_DISARMING
else:
state = STATE_UNKNOWN
state = None
self._state = state

View File

@@ -1,95 +0,0 @@
"""
Interfaces with Verisure alarm control panel.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.verisure/
"""
import logging
from time import sleep
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.verisure import CONF_ALARM, CONF_CODE_DIGITS
from homeassistant.components.verisure import HUB as hub
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_UNKNOWN)
_LOGGER = logging.getLogger(__name__)
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_entities(alarms)
def set_arm_state(state, code=None):
"""Send set arm state command."""
transaction_id = hub.session.set_arm_state(code, state)[
'armStateChangeTransactionId']
_LOGGER.info('verisure set arm state %s', state)
transaction = {}
while 'result' not in transaction:
sleep(0.5)
transaction = hub.session.get_arm_state_transaction(transaction_id)
# pylint: disable=unexpected-keyword-arg
hub.update_overview(no_throttle=True)
class VerisureAlarm(alarm.AlarmControlPanel):
"""Representation of a Verisure alarm status."""
def __init__(self):
"""Initialize the Verisure alarm panel."""
self._state = STATE_UNKNOWN
self._digits = hub.config.get(CONF_CODE_DIGITS)
self._changed_by = None
@property
def name(self):
"""Return the name of the device."""
return '{} alarm'.format(hub.session.installations[0]['alias'])
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def code_format(self):
"""Return one or more digits/characters."""
return 'Number'
@property
def changed_by(self):
"""Return the last change triggered by."""
return self._changed_by
def update(self):
"""Update alarm status."""
hub.update_overview()
status = hub.get_first("$.armState.statusType")
if status == 'DISARMED':
self._state = STATE_ALARM_DISARMED
elif status == 'ARMED_HOME':
self._state = STATE_ALARM_ARMED_HOME
elif status == 'ARMED_AWAY':
self._state = STATE_ALARM_ARMED_AWAY
elif status != 'PENDING':
_LOGGER.error('Unknown alarm state %s', status)
self._changed_by = hub.get_first("$.armState.name")
def alarm_disarm(self, code=None):
"""Send disarm command."""
set_arm_state('DISARMED', code)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
set_arm_state('ARMED_HOME', code)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
set_arm_state('ARMED_AWAY', code)

View File

@@ -1,75 +0,0 @@
"""
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 logging
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.wink import DOMAIN, WinkDevice
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_UNKNOWN)
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['wink']
STATE_ALARM_PRIVACY = 'Private'
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Wink platform."""
import pywink
for camera in pywink.get_cameras():
# get_cameras returns multiple device types.
# Only add those that aren't sensors.
try:
camera.capability()
except AttributeError:
_id = camera.object_id() + camera.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_entities([WinkCameraDevice(camera, hass)])
class WinkCameraDevice(WinkDevice, alarm.AlarmControlPanel):
"""Representation a Wink camera alarm."""
async def async_added_to_hass(self):
"""Call when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['alarm_control_panel'].append(self)
@property
def state(self):
"""Return the state of the device."""
wink_state = self.wink.state()
if wink_state == "away":
state = STATE_ALARM_ARMED_AWAY
elif wink_state == "home":
state = STATE_ALARM_DISARMED
elif wink_state == "night":
state = STATE_ALARM_ARMED_HOME
else:
state = STATE_UNKNOWN
return state
def alarm_disarm(self, code=None):
"""Send disarm command."""
self.wink.set_mode("home")
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self.wink.set_mode("night")
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self.wink.set_mode("away")
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'private': self.wink.private()
}

View File

@@ -15,7 +15,7 @@ from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['yalesmartalarmclient==0.1.5']
REQUIREMENTS = ['yalesmartalarmclient==0.1.6']
CONF_AREA_ID = 'area_id'

View File

@@ -1,203 +0,0 @@
"""
Support for AlarmDecoder devices.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alarmdecoder/
"""
import logging
from datetime import timedelta
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.helpers.discovery import load_platform
from homeassistant.util import dt as dt_util
from homeassistant.components.binary_sensor import DEVICE_CLASSES_SCHEMA
REQUIREMENTS = ['alarmdecoder==1.13.2']
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'alarmdecoder'
DATA_AD = 'alarmdecoder'
CONF_DEVICE = 'device'
CONF_DEVICE_BAUD = 'baudrate'
CONF_DEVICE_HOST = 'host'
CONF_DEVICE_PATH = 'path'
CONF_DEVICE_PORT = 'port'
CONF_DEVICE_TYPE = 'type'
CONF_PANEL_DISPLAY = 'panel_display'
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'
DEFAULT_DEVICE_PORT = 10000
DEFAULT_DEVICE_PATH = '/dev/ttyUSB0'
DEFAULT_DEVICE_BAUD = 115200
DEFAULT_PANEL_DISPLAY = False
DEFAULT_ZONE_TYPE = 'opening'
SIGNAL_PANEL_MESSAGE = 'alarmdecoder.panel_message'
SIGNAL_PANEL_ARM_AWAY = 'alarmdecoder.panel_arm_away'
SIGNAL_PANEL_ARM_HOME = 'alarmdecoder.panel_arm_home'
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',
vol.Optional(CONF_DEVICE_HOST, default=DEFAULT_DEVICE_HOST): cv.string,
vol.Optional(CONF_DEVICE_PORT, default=DEFAULT_DEVICE_PORT): cv.port})
DEVICE_SERIAL_SCHEMA = vol.Schema({
vol.Required(CONF_DEVICE_TYPE): 'serial',
vol.Optional(CONF_DEVICE_PATH, default=DEFAULT_DEVICE_PATH): cv.string,
vol.Optional(CONF_DEVICE_BAUD, default=DEFAULT_DEVICE_BAUD): cv.string})
DEVICE_USB_SCHEMA = vol.Schema({
vol.Required(CONF_DEVICE_TYPE): 'usb'})
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.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({
vol.Required(CONF_DEVICE): vol.Any(
DEVICE_SOCKET_SCHEMA, DEVICE_SERIAL_SCHEMA,
DEVICE_USB_SCHEMA),
vol.Optional(CONF_PANEL_DISPLAY,
default=DEFAULT_PANEL_DISPLAY): cv.boolean,
vol.Optional(CONF_ZONES): {vol.Coerce(int): ZONE_SCHEMA},
}),
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Set up for the AlarmDecoder devices."""
from alarmdecoder import AlarmDecoder
from alarmdecoder.devices import (SocketDevice, SerialDevice, USBDevice)
conf = config.get(DOMAIN)
restart = False
device = conf.get(CONF_DEVICE)
display = conf.get(CONF_PANEL_DISPLAY)
zones = conf.get(CONF_ZONES)
device_type = device.get(CONF_DEVICE_TYPE)
host = DEFAULT_DEVICE_HOST
port = DEFAULT_DEVICE_PORT
path = DEFAULT_DEVICE_PATH
baud = DEFAULT_DEVICE_BAUD
def stop_alarmdecoder(event):
"""Handle the shutdown of AlarmDecoder."""
_LOGGER.debug("Shutting down alarmdecoder")
nonlocal restart
restart = False
controller.close()
def open_connection(now=None):
"""Open a connection to AlarmDecoder."""
from alarmdecoder.util import NoDeviceError
nonlocal restart
try:
controller.open(baud)
except NoDeviceError:
_LOGGER.debug("Failed to connect. Retrying in 5 seconds")
hass.helpers.event.track_point_in_time(
open_connection, dt_util.utcnow() + timedelta(seconds=5))
return
_LOGGER.debug("Established a connection with the alarmdecoder")
restart = True
def handle_closed_connection(event):
"""Restart after unexpected loss of connection."""
nonlocal restart
if not restart:
return
restart = False
_LOGGER.warning("AlarmDecoder unexpectedly lost connection.")
hass.add_job(open_connection)
def handle_message(sender, message):
"""Handle message from AlarmDecoder."""
hass.helpers.dispatcher.dispatcher_send(
SIGNAL_PANEL_MESSAGE, message)
def handle_rfx_message(sender, message):
"""Handle RFX message from AlarmDecoder."""
hass.helpers.dispatcher.dispatcher_send(
SIGNAL_RFX_MESSAGE, message)
def zone_fault_callback(sender, zone):
"""Handle zone fault from AlarmDecoder."""
hass.helpers.dispatcher.dispatcher_send(
SIGNAL_ZONE_FAULT, zone)
def zone_restore_callback(sender, zone):
"""Handle zone restore from AlarmDecoder."""
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)
port = device.get(CONF_DEVICE_PORT)
controller = AlarmDecoder(SocketDevice(interface=(host, port)))
elif device_type == 'serial':
path = device.get(CONF_DEVICE_PATH)
baud = device.get(CONF_DEVICE_BAUD)
controller = AlarmDecoder(SerialDevice(interface=path))
elif device_type == 'usb':
AlarmDecoder(USBDevice.find())
return False
controller.on_message += handle_message
controller.on_rfx_message += handle_rfx_message
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
open_connection()
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder)
load_platform(hass, 'alarm_control_panel', DOMAIN, conf, config)
if zones:
load_platform(
hass, 'binary_sensor', DOMAIN, {CONF_ZONES: zones}, config)
if display:
load_platform(hass, 'sensor', DOMAIN, conf, config)
return True

View File

@@ -0,0 +1,201 @@
"""Support for AlarmDecoder devices."""
import logging
from datetime import timedelta
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.helpers.discovery import load_platform
from homeassistant.util import dt as dt_util
from homeassistant.components.binary_sensor import DEVICE_CLASSES_SCHEMA
REQUIREMENTS = ['alarmdecoder==1.13.2']
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'alarmdecoder'
DATA_AD = 'alarmdecoder'
CONF_DEVICE = 'device'
CONF_DEVICE_BAUD = 'baudrate'
CONF_DEVICE_HOST = 'host'
CONF_DEVICE_PATH = 'path'
CONF_DEVICE_PORT = 'port'
CONF_DEVICE_TYPE = 'type'
CONF_PANEL_DISPLAY = 'panel_display'
CONF_ZONE_NAME = 'name'
CONF_ZONE_TYPE = 'type'
CONF_ZONE_LOOP = 'loop'
CONF_ZONE_RFID = 'rfid'
CONF_ZONES = 'zones'
CONF_RELAY_ADDR = 'relayaddr'
CONF_RELAY_CHAN = 'relaychan'
DEFAULT_DEVICE_TYPE = 'socket'
DEFAULT_DEVICE_HOST = 'localhost'
DEFAULT_DEVICE_PORT = 10000
DEFAULT_DEVICE_PATH = '/dev/ttyUSB0'
DEFAULT_DEVICE_BAUD = 115200
DEFAULT_PANEL_DISPLAY = False
DEFAULT_ZONE_TYPE = 'opening'
SIGNAL_PANEL_MESSAGE = 'alarmdecoder.panel_message'
SIGNAL_PANEL_ARM_AWAY = 'alarmdecoder.panel_arm_away'
SIGNAL_PANEL_ARM_HOME = 'alarmdecoder.panel_arm_home'
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',
vol.Optional(CONF_DEVICE_HOST, default=DEFAULT_DEVICE_HOST): cv.string,
vol.Optional(CONF_DEVICE_PORT, default=DEFAULT_DEVICE_PORT): cv.port})
DEVICE_SERIAL_SCHEMA = vol.Schema({
vol.Required(CONF_DEVICE_TYPE): 'serial',
vol.Optional(CONF_DEVICE_PATH, default=DEFAULT_DEVICE_PATH): cv.string,
vol.Optional(CONF_DEVICE_BAUD, default=DEFAULT_DEVICE_BAUD): cv.string})
DEVICE_USB_SCHEMA = vol.Schema({
vol.Required(CONF_DEVICE_TYPE): 'usb'})
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_LOOP):
vol.All(vol.Coerce(int), vol.Range(min=1, max=4)),
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({
vol.Required(CONF_DEVICE): vol.Any(
DEVICE_SOCKET_SCHEMA, DEVICE_SERIAL_SCHEMA,
DEVICE_USB_SCHEMA),
vol.Optional(CONF_PANEL_DISPLAY,
default=DEFAULT_PANEL_DISPLAY): cv.boolean,
vol.Optional(CONF_ZONES): {vol.Coerce(int): ZONE_SCHEMA},
}),
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Set up for the AlarmDecoder devices."""
from alarmdecoder import AlarmDecoder
from alarmdecoder.devices import (SocketDevice, SerialDevice, USBDevice)
conf = config.get(DOMAIN)
restart = False
device = conf.get(CONF_DEVICE)
display = conf.get(CONF_PANEL_DISPLAY)
zones = conf.get(CONF_ZONES)
device_type = device.get(CONF_DEVICE_TYPE)
host = DEFAULT_DEVICE_HOST
port = DEFAULT_DEVICE_PORT
path = DEFAULT_DEVICE_PATH
baud = DEFAULT_DEVICE_BAUD
def stop_alarmdecoder(event):
"""Handle the shutdown of AlarmDecoder."""
_LOGGER.debug("Shutting down alarmdecoder")
nonlocal restart
restart = False
controller.close()
def open_connection(now=None):
"""Open a connection to AlarmDecoder."""
from alarmdecoder.util import NoDeviceError
nonlocal restart
try:
controller.open(baud)
except NoDeviceError:
_LOGGER.debug("Failed to connect. Retrying in 5 seconds")
hass.helpers.event.track_point_in_time(
open_connection, dt_util.utcnow() + timedelta(seconds=5))
return
_LOGGER.debug("Established a connection with the alarmdecoder")
restart = True
def handle_closed_connection(event):
"""Restart after unexpected loss of connection."""
nonlocal restart
if not restart:
return
restart = False
_LOGGER.warning("AlarmDecoder unexpectedly lost connection.")
hass.add_job(open_connection)
def handle_message(sender, message):
"""Handle message from AlarmDecoder."""
hass.helpers.dispatcher.dispatcher_send(
SIGNAL_PANEL_MESSAGE, message)
def handle_rfx_message(sender, message):
"""Handle RFX message from AlarmDecoder."""
hass.helpers.dispatcher.dispatcher_send(
SIGNAL_RFX_MESSAGE, message)
def zone_fault_callback(sender, zone):
"""Handle zone fault from AlarmDecoder."""
hass.helpers.dispatcher.dispatcher_send(
SIGNAL_ZONE_FAULT, zone)
def zone_restore_callback(sender, zone):
"""Handle zone restore from AlarmDecoder."""
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)
port = device.get(CONF_DEVICE_PORT)
controller = AlarmDecoder(SocketDevice(interface=(host, port)))
elif device_type == 'serial':
path = device.get(CONF_DEVICE_PATH)
baud = device.get(CONF_DEVICE_BAUD)
controller = AlarmDecoder(SerialDevice(interface=path))
elif device_type == 'usb':
AlarmDecoder(USBDevice.find())
return False
controller.on_message += handle_message
controller.on_rfx_message += handle_rfx_message
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
open_connection()
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder)
load_platform(hass, 'alarm_control_panel', DOMAIN, conf, config)
if zones:
load_platform(
hass, 'binary_sensor', DOMAIN, {CONF_ZONES: zones}, config)
if display:
load_platform(hass, 'sensor', DOMAIN, conf, config)
return True

View File

@@ -0,0 +1,142 @@
"""Support for AlarmDecoder-based alarm control panels (Honeywell/DSC)."""
import logging
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarmdecoder import DATA_AD, SIGNAL_PANEL_MESSAGE
from homeassistant.const import (
ATTR_CODE, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED)
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['alarmdecoder']
SERVICE_ALARM_TOGGLE_CHIME = 'alarmdecoder_alarm_toggle_chime'
ALARM_TOGGLE_CHIME_SCHEMA = vol.Schema({
vol.Required(ATTR_CODE): cv.string,
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up for AlarmDecoder alarm panels."""
device = AlarmDecoderAlarmPanel()
add_entities([device])
def alarm_toggle_chime_handler(service):
"""Register toggle chime handler."""
code = service.data.get(ATTR_CODE)
device.alarm_toggle_chime(code)
hass.services.register(
alarm.DOMAIN, SERVICE_ALARM_TOGGLE_CHIME, alarm_toggle_chime_handler,
schema=ALARM_TOGGLE_CHIME_SCHEMA)
class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
"""Representation of an AlarmDecoder-based alarm panel."""
def __init__(self):
"""Initialize the alarm panel."""
self._display = ""
self._name = "Alarm Panel"
self._state = None
self._ac_power = None
self._backlight_on = None
self._battery_low = None
self._check_zone = None
self._chime = None
self._entry_delay_off = None
self._programming_mode = None
self._ready = None
self._zone_bypassed = None
async def async_added_to_hass(self):
"""Register callbacks."""
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_PANEL_MESSAGE, self._message_callback)
def _message_callback(self, message):
"""Handle received messages."""
if message.alarm_sounding or message.fire_alarm:
self._state = STATE_ALARM_TRIGGERED
elif message.armed_away:
self._state = STATE_ALARM_ARMED_AWAY
elif message.armed_home:
self._state = STATE_ALARM_ARMED_HOME
else:
self._state = STATE_ALARM_DISARMED
self._ac_power = message.ac_power
self._backlight_on = message.backlight_on
self._battery_low = message.battery_low
self._check_zone = message.check_zone
self._chime = message.chime_on
self._entry_delay_off = message.entry_delay_off
self._programming_mode = message.programming_mode
self._ready = message.ready
self._zone_bypassed = message.zone_bypassed
self.schedule_update_ha_state()
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def should_poll(self):
"""Return the polling state."""
return False
@property
def code_format(self):
"""Return one or more digits/characters."""
return alarm.FORMAT_NUMBER
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'ac_power': self._ac_power,
'backlight_on': self._backlight_on,
'battery_low': self._battery_low,
'check_zone': self._check_zone,
'chime': self._chime,
'entry_delay_off': self._entry_delay_off,
'programming_mode': self._programming_mode,
'ready': self._ready,
'zone_bypassed': self._zone_bypassed,
}
def alarm_disarm(self, code=None):
"""Send disarm command."""
if code:
self.hass.data[DATA_AD].send("{!s}1".format(code))
def alarm_arm_away(self, code=None):
"""Send arm away command."""
if code:
self.hass.data[DATA_AD].send("{!s}2".format(code))
def alarm_arm_home(self, code=None):
"""Send arm home command."""
if code:
self.hass.data[DATA_AD].send("{!s}3".format(code))
def alarm_arm_night(self, code=None):
"""Send arm night command."""
if code:
self.hass.data[DATA_AD].send("{!s}33".format(code))
def alarm_toggle_chime(self, code=None):
"""Send toggle chime command."""
if code:
self.hass.data[DATA_AD].send("{!s}9".format(code))

View File

@@ -0,0 +1,140 @@
"""Support for AlarmDecoder zone states- represented as binary sensors."""
import logging
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.alarmdecoder import (
ZONE_SCHEMA, CONF_ZONES, CONF_ZONE_NAME, CONF_ZONE_TYPE,
CONF_ZONE_RFID, CONF_ZONE_LOOP, SIGNAL_ZONE_FAULT, SIGNAL_ZONE_RESTORE,
SIGNAL_RFX_MESSAGE, SIGNAL_REL_MESSAGE, CONF_RELAY_ADDR,
CONF_RELAY_CHAN)
DEPENDENCIES = ['alarmdecoder']
_LOGGER = logging.getLogger(__name__)
ATTR_RF_BIT0 = 'rf_bit0'
ATTR_RF_LOW_BAT = 'rf_low_battery'
ATTR_RF_SUPERVISED = 'rf_supervised'
ATTR_RF_BIT3 = 'rf_bit3'
ATTR_RF_LOOP3 = 'rf_loop3'
ATTR_RF_LOOP2 = 'rf_loop2'
ATTR_RF_LOOP4 = 'rf_loop4'
ATTR_RF_LOOP1 = 'rf_loop1'
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the AlarmDecoder binary sensor devices."""
configured_zones = discovery_info[CONF_ZONES]
devices = []
for zone_num in configured_zones:
device_config_data = ZONE_SCHEMA(configured_zones[zone_num])
zone_type = device_config_data[CONF_ZONE_TYPE]
zone_name = device_config_data[CONF_ZONE_NAME]
zone_rfid = device_config_data.get(CONF_ZONE_RFID)
zone_loop = device_config_data.get(CONF_ZONE_LOOP)
relay_addr = device_config_data.get(CONF_RELAY_ADDR)
relay_chan = device_config_data.get(CONF_RELAY_CHAN)
device = AlarmDecoderBinarySensor(
zone_num, zone_name, zone_type, zone_rfid, zone_loop, relay_addr,
relay_chan)
devices.append(device)
add_entities(devices)
return True
class AlarmDecoderBinarySensor(BinarySensorDevice):
"""Representation of an AlarmDecoder binary sensor."""
def __init__(self, zone_number, zone_name, zone_type, zone_rfid, zone_loop,
relay_addr, relay_chan):
"""Initialize the binary_sensor."""
self._zone_number = zone_number
self._zone_type = zone_type
self._state = None
self._name = zone_name
self._rfid = zone_rfid
self._loop = zone_loop
self._rfstate = None
self._relay_addr = relay_addr
self._relay_chan = relay_chan
async def async_added_to_hass(self):
"""Register callbacks."""
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_ZONE_FAULT, self._fault_callback)
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_ZONE_RESTORE, self._restore_callback)
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_RFX_MESSAGE, self._rfx_message_callback)
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_REL_MESSAGE, self._rel_message_callback)
@property
def name(self):
"""Return the name of the entity."""
return self._name
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def device_state_attributes(self):
"""Return the state attributes."""
attr = {}
if self._rfid and self._rfstate is not None:
attr[ATTR_RF_BIT0] = bool(self._rfstate & 0x01)
attr[ATTR_RF_LOW_BAT] = bool(self._rfstate & 0x02)
attr[ATTR_RF_SUPERVISED] = bool(self._rfstate & 0x04)
attr[ATTR_RF_BIT3] = bool(self._rfstate & 0x08)
attr[ATTR_RF_LOOP3] = bool(self._rfstate & 0x10)
attr[ATTR_RF_LOOP2] = bool(self._rfstate & 0x20)
attr[ATTR_RF_LOOP4] = bool(self._rfstate & 0x40)
attr[ATTR_RF_LOOP1] = bool(self._rfstate & 0x80)
return attr
@property
def is_on(self):
"""Return true if sensor is on."""
return self._state == 1
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return self._zone_type
def _fault_callback(self, zone):
"""Update the zone's state, if needed."""
if zone is None or int(zone) == self._zone_number:
self._state = 1
self.schedule_update_ha_state()
def _restore_callback(self, zone):
"""Update the zone's state, if needed."""
if zone is None or int(zone) == self._zone_number:
self._state = 0
self.schedule_update_ha_state()
def _rfx_message_callback(self, message):
"""Update RF state."""
if self._rfid and message and message.serial_number == self._rfid:
self._rfstate = message.value
if self._loop:
self._state = 1 if message.loop[self._loop - 1] else 0
self.schedule_update_ha_state()
def _rel_message_callback(self, message):
"""Update relay state."""
if (self._relay_addr == message.address and
self._relay_chan == message.channel):
_LOGGER.debug("Relay %d:%d value:%d", message.address,
message.channel, message.value)
self._state = message.value
self.schedule_update_ha_state()

View File

@@ -0,0 +1,59 @@
"""Support for AlarmDecoder sensors (Shows Panel Display)."""
import logging
from homeassistant.helpers.entity import Entity
from homeassistant.components.alarmdecoder import (SIGNAL_PANEL_MESSAGE)
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['alarmdecoder']
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up for AlarmDecoder sensor devices."""
_LOGGER.debug("AlarmDecoderSensor: setup_platform")
device = AlarmDecoderSensor(hass)
add_entities([device])
class AlarmDecoderSensor(Entity):
"""Representation of an AlarmDecoder keypad."""
def __init__(self, hass):
"""Initialize the alarm panel."""
self._display = ""
self._state = None
self._icon = 'mdi:alarm-check'
self._name = 'Alarm Panel Display'
async def async_added_to_hass(self):
"""Register callbacks."""
self.hass.helpers.dispatcher.async_dispatcher_connect(
SIGNAL_PANEL_MESSAGE, self._message_callback)
def _message_callback(self, message):
if self._display != message.text:
self._display = message.text
self.schedule_update_ha_state()
@property
def icon(self):
"""Return the icon if any."""
return self._icon
@property
def state(self):
"""Return the overall state."""
return self._display
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def should_poll(self):
"""No polling needed."""
return False

View File

@@ -1,276 +0,0 @@
"""
Support for repeating alerts when conditions are met.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alert/
"""
import asyncio
from datetime import datetime, timedelta
import logging
import voluptuous as vol
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)
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers import service, event
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'alert'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
CONF_CAN_ACK = 'can_acknowledge'
CONF_NOTIFIERS = 'notifiers'
CONF_REPEAT = 'repeat'
CONF_SKIP_FIRST = 'skip_first'
CONF_ALERT_MESSAGE = 'message'
CONF_DONE_MESSAGE = 'done_message'
DEFAULT_CAN_ACK = True
DEFAULT_SKIP_FIRST = False
ALERT_SCHEMA = vol.Schema({
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_ENTITY_ID): cv.entity_id,
vol.Required(CONF_STATE, default=STATE_ON): cv.string,
vol.Required(CONF_REPEAT): vol.All(cv.ensure_list, [vol.Coerce(float)]),
vol.Required(CONF_CAN_ACK, default=DEFAULT_CAN_ACK): cv.boolean,
vol.Required(CONF_SKIP_FIRST, default=DEFAULT_SKIP_FIRST): cv.boolean,
vol.Optional(CONF_ALERT_MESSAGE): cv.template,
vol.Optional(CONF_DONE_MESSAGE): cv.template,
vol.Required(CONF_NOTIFIERS): cv.ensure_list})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: ALERT_SCHEMA,
}),
}, extra=vol.ALLOW_EXTRA)
ALERT_SERVICE_SCHEMA = vol.Schema({
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
})
def is_on(hass, entity_id):
"""Return if the alert is firing and not acknowledged."""
return hass.states.is_state(entity_id, STATE_ON)
async def async_setup(hass, config):
"""Set up the Alert component."""
entities = []
for object_id, cfg in config[DOMAIN].items():
if not cfg:
cfg = {}
name = cfg.get(CONF_NAME)
watched_entity_id = cfg.get(CONF_ENTITY_ID)
alert_state = cfg.get(CONF_STATE)
repeat = cfg.get(CONF_REPEAT)
skip_first = cfg.get(CONF_SKIP_FIRST)
message_template = cfg.get(CONF_ALERT_MESSAGE)
done_message_template = cfg.get(CONF_DONE_MESSAGE)
notifiers = cfg.get(CONF_NOTIFIERS)
can_ack = cfg.get(CONF_CAN_ACK)
entities.append(Alert(hass, object_id, name,
watched_entity_id, alert_state, repeat,
skip_first, message_template,
done_message_template, notifiers,
can_ack))
if not entities:
return False
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:
for alert in entities:
if alert.entity_id != alert_id:
continue
alert.async_set_context(service_call.context)
if service_call.service == SERVICE_TURN_ON:
await alert.async_turn_on()
elif service_call.service == SERVICE_TOGGLE:
await alert.async_toggle()
else:
await alert.async_turn_off()
# Setup service calls
hass.services.async_register(
DOMAIN, SERVICE_TURN_OFF, async_handle_alert_service,
schema=ALERT_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TURN_ON, async_handle_alert_service,
schema=ALERT_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, async_handle_alert_service,
schema=ALERT_SERVICE_SCHEMA)
tasks = [alert.async_update_ha_state() for alert in entities]
if tasks:
await asyncio.wait(tasks, loop=hass.loop)
return True
class Alert(ToggleEntity):
"""Representation of an alert."""
def __init__(self, hass, entity_id, name, watched_entity_id,
state, repeat, skip_first, message_template,
done_message_template, notifiers, can_ack):
"""Initialize the alert."""
self.hass = hass
self._name = name
self._alert_state = state
self._skip_first = skip_first
self._message_template = message_template
if self._message_template is not None:
self._message_template.hass = hass
self._done_message_template = done_message_template
if self._done_message_template is not None:
self._done_message_template.hass = hass
self._notifiers = notifiers
self._can_ack = can_ack
self._delay = [timedelta(minutes=val) for val in repeat]
self._next_delay = 0
self._firing = False
self._ack = False
self._cancel = None
self._send_done_message = False
self.entity_id = ENTITY_ID_FORMAT.format(entity_id)
event.async_track_state_change(
hass, watched_entity_id, self.watched_entity_change)
@property
def name(self):
"""Return the name of the alert."""
return self._name
@property
def should_poll(self):
"""HASS need not poll these entities."""
return False
@property
def state(self):
"""Return the alert status."""
if self._firing:
if self._ack:
return STATE_OFF
return STATE_ON
return STATE_IDLE
@property
def hidden(self):
"""Hide the alert when it is not firing."""
return not self._can_ack or not self._firing
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:
await self.begin_alerting()
if to_state.state != self._alert_state and self._firing:
await self.end_alerting()
async def begin_alerting(self):
"""Begin the alert procedures."""
_LOGGER.debug("Beginning Alert: %s", self._name)
self._ack = False
self._firing = True
self._next_delay = 0
if not self._skip_first:
await self._notify()
else:
await self._schedule_notify()
self.async_schedule_update_ha_state()
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._send_done_message:
await self._notify_done_message()
self.async_schedule_update_ha_state()
async def _schedule_notify(self):
"""Schedule a notification."""
delay = self._delay[self._next_delay]
next_msg = datetime.now() + delay
self._cancel = \
event.async_track_point_in_time(self.hass, self._notify, next_msg)
self._next_delay = min(self._next_delay + 1, len(self._delay) - 1)
async def _notify(self, *args):
"""Send the alert notification."""
if not self._firing:
return
if not self._ack:
_LOGGER.info("Alerting: %s", self._name)
self._send_done_message = True
if self._message_template is not None:
message = self._message_template.async_render()
else:
message = self._name
await self._send_notification_message(message)
await self._schedule_notify()
async def _notify_done_message(self, *args):
"""Send notification of complete alert."""
_LOGGER.info("Alerting: %s", self._done_message_template)
self._send_done_message = False
if self._done_message_template is None:
return
message = self._done_message_template.async_render()
await self._send_notification_message(message)
async def _send_notification_message(self, message):
for target in self._notifiers:
await self.hass.services.async_call(
DOMAIN_NOTIFY, target, {ATTR_MESSAGE: message})
async def async_turn_on(self, **kwargs):
"""Async Unacknowledge alert."""
_LOGGER.debug("Reset Alert: %s", self._name)
self._ack = False
await self.async_update_ha_state()
async def async_turn_off(self, **kwargs):
"""Async Acknowledge alert."""
_LOGGER.debug("Acknowledged Alert: %s", self._name)
self._ack = True
await self.async_update_ha_state()
async def async_toggle(self, **kwargs):
"""Async toggle alert."""
if self._ack:
return await self.async_turn_on()
return await self.async_turn_off()

View File

@@ -0,0 +1,291 @@
"""Support for repeating alerts when conditions are met."""
import asyncio
import logging
from datetime import datetime, timedelta
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.notify import (
ATTR_MESSAGE, ATTR_TITLE, ATTR_DATA, 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)
from homeassistant.helpers import service, event
from homeassistant.helpers.entity import ToggleEntity
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'alert'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
CONF_CAN_ACK = 'can_acknowledge'
CONF_NOTIFIERS = 'notifiers'
CONF_REPEAT = 'repeat'
CONF_SKIP_FIRST = 'skip_first'
CONF_ALERT_MESSAGE = 'message'
CONF_DONE_MESSAGE = 'done_message'
CONF_TITLE = 'title'
CONF_DATA = 'data'
DEFAULT_CAN_ACK = True
DEFAULT_SKIP_FIRST = False
ALERT_SCHEMA = vol.Schema({
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_ENTITY_ID): cv.entity_id,
vol.Required(CONF_STATE, default=STATE_ON): cv.string,
vol.Required(CONF_REPEAT): vol.All(cv.ensure_list, [vol.Coerce(float)]),
vol.Required(CONF_CAN_ACK, default=DEFAULT_CAN_ACK): cv.boolean,
vol.Required(CONF_SKIP_FIRST, default=DEFAULT_SKIP_FIRST): cv.boolean,
vol.Optional(CONF_ALERT_MESSAGE): cv.template,
vol.Optional(CONF_DONE_MESSAGE): cv.template,
vol.Optional(CONF_TITLE): cv.template,
vol.Optional(CONF_DATA): dict,
vol.Required(CONF_NOTIFIERS): cv.ensure_list})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: cv.schema_with_slug_keys(ALERT_SCHEMA),
}, extra=vol.ALLOW_EXTRA)
ALERT_SERVICE_SCHEMA = vol.Schema({
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
})
def is_on(hass, entity_id):
"""Return if the alert is firing and not acknowledged."""
return hass.states.is_state(entity_id, STATE_ON)
async def async_setup(hass, config):
"""Set up the Alert component."""
entities = []
for object_id, cfg in config[DOMAIN].items():
if not cfg:
cfg = {}
name = cfg.get(CONF_NAME)
watched_entity_id = cfg.get(CONF_ENTITY_ID)
alert_state = cfg.get(CONF_STATE)
repeat = cfg.get(CONF_REPEAT)
skip_first = cfg.get(CONF_SKIP_FIRST)
message_template = cfg.get(CONF_ALERT_MESSAGE)
done_message_template = cfg.get(CONF_DONE_MESSAGE)
notifiers = cfg.get(CONF_NOTIFIERS)
can_ack = cfg.get(CONF_CAN_ACK)
title_template = cfg.get(CONF_TITLE)
data = cfg.get(CONF_DATA)
entities.append(Alert(hass, object_id, name,
watched_entity_id, alert_state, repeat,
skip_first, message_template,
done_message_template, notifiers,
can_ack, title_template, data))
if not entities:
return False
async def async_handle_alert_service(service_call):
"""Handle calls to alert services."""
alert_ids = await service.async_extract_entity_ids(hass, service_call)
for alert_id in alert_ids:
for alert in entities:
if alert.entity_id != alert_id:
continue
alert.async_set_context(service_call.context)
if service_call.service == SERVICE_TURN_ON:
await alert.async_turn_on()
elif service_call.service == SERVICE_TOGGLE:
await alert.async_toggle()
else:
await alert.async_turn_off()
# Setup service calls
hass.services.async_register(
DOMAIN, SERVICE_TURN_OFF, async_handle_alert_service,
schema=ALERT_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TURN_ON, async_handle_alert_service,
schema=ALERT_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, async_handle_alert_service,
schema=ALERT_SERVICE_SCHEMA)
tasks = [alert.async_update_ha_state() for alert in entities]
if tasks:
await asyncio.wait(tasks, loop=hass.loop)
return True
class Alert(ToggleEntity):
"""Representation of an alert."""
def __init__(self, hass, entity_id, name, watched_entity_id,
state, repeat, skip_first, message_template,
done_message_template, notifiers, can_ack, title_template,
data):
"""Initialize the alert."""
self.hass = hass
self._name = name
self._alert_state = state
self._skip_first = skip_first
self._data = data
self._message_template = message_template
if self._message_template is not None:
self._message_template.hass = hass
self._done_message_template = done_message_template
if self._done_message_template is not None:
self._done_message_template.hass = hass
self._title_template = title_template
if self._title_template is not None:
self._title_template.hass = hass
self._notifiers = notifiers
self._can_ack = can_ack
self._delay = [timedelta(minutes=val) for val in repeat]
self._next_delay = 0
self._firing = False
self._ack = False
self._cancel = None
self._send_done_message = False
self.entity_id = ENTITY_ID_FORMAT.format(entity_id)
event.async_track_state_change(
hass, watched_entity_id, self.watched_entity_change)
@property
def name(self):
"""Return the name of the alert."""
return self._name
@property
def should_poll(self):
"""HASS need not poll these entities."""
return False
@property
def state(self):
"""Return the alert status."""
if self._firing:
if self._ack:
return STATE_OFF
return STATE_ON
return STATE_IDLE
@property
def hidden(self):
"""Hide the alert when it is not firing."""
return not self._can_ack or not self._firing
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:
await self.begin_alerting()
if to_state.state != self._alert_state and self._firing:
await self.end_alerting()
async def begin_alerting(self):
"""Begin the alert procedures."""
_LOGGER.debug("Beginning Alert: %s", self._name)
self._ack = False
self._firing = True
self._next_delay = 0
if not self._skip_first:
await self._notify()
else:
await self._schedule_notify()
self.async_schedule_update_ha_state()
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._send_done_message:
await self._notify_done_message()
self.async_schedule_update_ha_state()
async def _schedule_notify(self):
"""Schedule a notification."""
delay = self._delay[self._next_delay]
next_msg = datetime.now() + delay
self._cancel = \
event.async_track_point_in_time(self.hass, self._notify, next_msg)
self._next_delay = min(self._next_delay + 1, len(self._delay) - 1)
async def _notify(self, *args):
"""Send the alert notification."""
if not self._firing:
return
if not self._ack:
_LOGGER.info("Alerting: %s", self._name)
self._send_done_message = True
if self._message_template is not None:
message = self._message_template.async_render()
else:
message = self._name
await self._send_notification_message(message)
await self._schedule_notify()
async def _notify_done_message(self, *args):
"""Send notification of complete alert."""
_LOGGER.info("Alerting: %s", self._done_message_template)
self._send_done_message = False
if self._done_message_template is None:
return
message = self._done_message_template.async_render()
await self._send_notification_message(message)
async def _send_notification_message(self, message):
msg_payload = {ATTR_MESSAGE: message}
if self._title_template is not None:
title = self._title_template.async_render()
msg_payload.update({ATTR_TITLE: title})
if self._data:
msg_payload.update({ATTR_DATA: self._data})
_LOGGER.debug(msg_payload)
for target in self._notifiers:
await self.hass.services.async_call(
DOMAIN_NOTIFY, target, msg_payload)
async def async_turn_on(self, **kwargs):
"""Async Unacknowledge alert."""
_LOGGER.debug("Reset Alert: %s", self._name)
self._ack = False
await self.async_update_ha_state()
async def async_turn_off(self, **kwargs):
"""Async Acknowledge alert."""
_LOGGER.debug("Acknowledged Alert: %s", self._name)
self._ack = True
await self.async_update_ha_state()
async def async_toggle(self, **kwargs):
"""Async toggle alert."""
if self._ack:
return await self.async_turn_on()
return await self.async_turn_off()

View File

@@ -0,0 +1,12 @@
toggle:
description: Toggle alert's notifications.
fields:
entity_id: {description: Name of the alert to toggle., example: alert.garage_door_open}
turn_off:
description: Silence alert's notifications.
fields:
entity_id: {description: Name of the alert to silence., example: alert.garage_door_open}
turn_on:
description: Reset alert's notifications.
fields:
entity_id: {description: Name of the alert to reset., example: alert.garage_door_open}

View File

@@ -1,9 +1,4 @@
"""
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/
"""
"""Support for Alexa skill service end point."""
import logging
import voluptuous as vol
@@ -13,8 +8,9 @@ from homeassistant.helpers import entityfilter
from . import flash_briefings, intent, smart_home
from .const import (
CONF_AUDIO, CONF_DISPLAY_URL, CONF_TEXT, CONF_TITLE, CONF_UID, DOMAIN,
CONF_FILTER, CONF_ENTITY_CONFIG)
CONF_AUDIO, CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_DISPLAY_URL,
CONF_ENDPOINT, CONF_TEXT, CONF_TITLE, CONF_UID, DOMAIN, CONF_FILTER,
CONF_ENTITY_CONFIG)
_LOGGER = logging.getLogger(__name__)
@@ -30,6 +26,9 @@ ALEXA_ENTITY_SCHEMA = vol.Schema({
})
SMART_HOME_SCHEMA = vol.Schema({
vol.Optional(CONF_ENDPOINT): cv.string,
vol.Optional(CONF_CLIENT_ID): cv.string,
vol.Optional(CONF_CLIENT_SECRET): cv.string,
vol.Optional(CONF_FILTER, default={}): entityfilter.FILTER_SCHEMA,
vol.Optional(CONF_ENTITY_CONFIG): {cv.entity_id: ALEXA_ENTITY_SCHEMA}
})
@@ -53,7 +52,7 @@ CONFIG_SCHEMA = vol.Schema({
async def async_setup(hass, config):
"""Activate Alexa component."""
"""Activate the Alexa component."""
config = config.get(DOMAIN, {})
flash_briefings_config = config.get(CONF_FLASH_BRIEFINGS)
@@ -68,6 +67,6 @@ async def async_setup(hass, config):
pass
else:
smart_home_config = smart_home_config or SMART_HOME_SCHEMA({})
smart_home.async_setup(hass, smart_home_config)
await smart_home.async_setup(hass, smart_home_config)
return True

View File

@@ -0,0 +1,153 @@
"""Support for Alexa skill auth."""
import asyncio
import json
import logging
from datetime import timedelta
import aiohttp
import async_timeout
from homeassistant.core import callback
from homeassistant.helpers import aiohttp_client
from homeassistant.util import dt
from .const import DEFAULT_TIMEOUT
_LOGGER = logging.getLogger(__name__)
LWA_TOKEN_URI = "https://api.amazon.com/auth/o2/token"
LWA_HEADERS = {
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
}
PREEMPTIVE_REFRESH_TTL_IN_SECONDS = 300
STORAGE_KEY = 'alexa_auth'
STORAGE_VERSION = 1
STORAGE_EXPIRE_TIME = "expire_time"
STORAGE_ACCESS_TOKEN = "access_token"
STORAGE_REFRESH_TOKEN = "refresh_token"
class Auth:
"""Handle authentication to send events to Alexa."""
def __init__(self, hass, client_id, client_secret):
"""Initialize the Auth class."""
self.hass = hass
self.client_id = client_id
self.client_secret = client_secret
self._prefs = None
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY)
self._get_token_lock = asyncio.Lock(loop=hass.loop)
async def async_do_auth(self, accept_grant_code):
"""Do authentication with an AcceptGrant code."""
# access token not retrieved yet for the first time, so this should
# be an access token request
lwa_params = {
"grant_type": "authorization_code",
"code": accept_grant_code,
"client_id": self.client_id,
"client_secret": self.client_secret
}
_LOGGER.debug("Calling LWA to get the access token (first time), "
"with: %s", json.dumps(lwa_params))
return await self._async_request_new_token(lwa_params)
async def async_get_access_token(self):
"""Perform access token or token refresh request."""
async with self._get_token_lock:
if self._prefs is None:
await self.async_load_preferences()
if self.is_token_valid():
_LOGGER.debug("Token still valid, using it.")
return self._prefs[STORAGE_ACCESS_TOKEN]
if self._prefs[STORAGE_REFRESH_TOKEN] is None:
_LOGGER.debug("Token invalid and no refresh token available.")
return None
lwa_params = {
"grant_type": "refresh_token",
"refresh_token": self._prefs[STORAGE_REFRESH_TOKEN],
"client_id": self.client_id,
"client_secret": self.client_secret
}
_LOGGER.debug("Calling LWA to refresh the access token.")
return await self._async_request_new_token(lwa_params)
@callback
def is_token_valid(self):
"""Check if a token is already loaded and if it is still valid."""
if not self._prefs[STORAGE_ACCESS_TOKEN]:
return False
expire_time = dt.parse_datetime(self._prefs[STORAGE_EXPIRE_TIME])
preemptive_expire_time = expire_time - timedelta(
seconds=PREEMPTIVE_REFRESH_TTL_IN_SECONDS)
return dt.utcnow() < preemptive_expire_time
async def _async_request_new_token(self, lwa_params):
try:
session = aiohttp_client.async_get_clientsession(self.hass)
with async_timeout.timeout(DEFAULT_TIMEOUT, loop=self.hass.loop):
response = await session.post(LWA_TOKEN_URI,
headers=LWA_HEADERS,
data=lwa_params,
allow_redirects=True)
except (asyncio.TimeoutError, aiohttp.ClientError):
_LOGGER.error("Timeout calling LWA to get auth token.")
return None
_LOGGER.debug("LWA response header: %s", response.headers)
_LOGGER.debug("LWA response status: %s", response.status)
if response.status != 200:
_LOGGER.error("Error calling LWA to get auth token.")
return None
response_json = await response.json()
_LOGGER.debug("LWA response body : %s", response_json)
access_token = response_json["access_token"]
refresh_token = response_json["refresh_token"]
expires_in = response_json["expires_in"]
expire_time = dt.utcnow() + timedelta(seconds=expires_in)
await self._async_update_preferences(access_token, refresh_token,
expire_time.isoformat())
return access_token
async def async_load_preferences(self):
"""Load preferences with stored tokens."""
self._prefs = await self._store.async_load()
if self._prefs is None:
self._prefs = {
STORAGE_ACCESS_TOKEN: None,
STORAGE_REFRESH_TOKEN: None,
STORAGE_EXPIRE_TIME: None
}
async def _async_update_preferences(self, access_token, refresh_token,
expire_time):
"""Update user preferences."""
if self._prefs is None:
await self.async_load_preferences()
if access_token is not None:
self._prefs[STORAGE_ACCESS_TOKEN] = access_token
if refresh_token is not None:
self._prefs[STORAGE_REFRESH_TOKEN] = refresh_token
if expire_time is not None:
self._prefs[STORAGE_EXPIRE_TIME] = expire_time
await self._store.async_save(self._prefs)

View File

@@ -10,6 +10,9 @@ CONF_DISPLAY_URL = 'display_url'
CONF_FILTER = 'filter'
CONF_ENTITY_CONFIG = 'entity_config'
CONF_ENDPOINT = 'endpoint'
CONF_CLIENT_ID = 'client_id'
CONF_CLIENT_SECRET = 'client_secret'
ATTR_UID = 'uid'
ATTR_UPDATE_DATE = 'updateDate'
@@ -21,3 +24,5 @@ ATTR_REDIRECTION_URL = 'redirectionURL'
SYN_RESOLUTION_MATCH = 'ER_SUCCESS_MATCH'
DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.0Z'
DEFAULT_TIMEOUT = 30

View File

@@ -1,9 +1,4 @@
"""
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/
"""
"""Support for Alexa skill service end point."""
import copy
from datetime import datetime
import logging

View File

@@ -1,9 +1,4 @@
"""
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/
"""
"""Support for Alexa skill service end point."""
import enum
import logging

View File

@@ -1,33 +1,38 @@
"""Support for alexa Smart Home Skill API.
API documentation:
https://developer.amazon.com/docs/smarthome/understand-the-smart-home-skill-api.html
https://developer.amazon.com/docs/device-apis/message-guide.html
"""
from collections import OrderedDict
from datetime import datetime
"""Support for alexa Smart Home Skill API."""
import asyncio
import json
import logging
import math
from collections import OrderedDict
from datetime import datetime
from uuid import uuid4
import aiohttp
import async_timeout
import homeassistant.core as ha
import homeassistant.util.color as color_util
from homeassistant.components import (
alert, automation, binary_sensor, climate, cover, fan, group, http,
alert, automation, binary_sensor, cover, fan, group, http,
input_boolean, light, lock, media_player, scene, script, sensor, switch)
from homeassistant.components.climate import const as climate
from homeassistant.const import (
ATTR_DEVICE_CLASS, ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES,
ATTR_TEMPERATURE, ATTR_UNIT_OF_MEASUREMENT, CLOUD_NEVER_EXPOSED_ENTITIES,
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, STATE_LOCKED, STATE_ON, STATE_UNLOCKED,
TEMP_CELSIUS, TEMP_FAHRENHEIT)
import homeassistant.core as ha
import homeassistant.util.color as color_util
SERVICE_UNLOCK, SERVICE_VOLUME_DOWN, SERVICE_VOLUME_UP, SERVICE_VOLUME_SET,
SERVICE_VOLUME_MUTE, STATE_LOCKED, STATE_ON, STATE_OFF, STATE_UNAVAILABLE,
STATE_UNLOCKED, TEMP_CELSIUS, TEMP_FAHRENHEIT, MATCH_ALL)
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.event import async_track_state_change
from homeassistant.util.decorator import Registry
from homeassistant.util.temperature import convert as convert_temperature
from .const import CONF_ENTITY_CONFIG, CONF_FILTER
from .auth import Auth
from .const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_ENDPOINT, \
CONF_ENTITY_CONFIG, CONF_FILTER, DATE_FORMAT, DEFAULT_TIMEOUT
_LOGGER = logging.getLogger(__name__)
@@ -37,6 +42,8 @@ API_EVENT = 'event'
API_CONTEXT = 'context'
API_HEADER = 'header'
API_PAYLOAD = 'payload'
API_SCOPE = 'scope'
API_CHANGE = 'change'
API_TEMP_UNITS = {
TEMP_FAHRENHEIT: 'FAHRENHEIT',
@@ -51,10 +58,11 @@ API_THERMOSTAT_MODES = OrderedDict([
(climate.STATE_COOL, 'COOL'),
(climate.STATE_AUTO, 'AUTO'),
(climate.STATE_ECO, 'ECO'),
(climate.STATE_OFF, 'OFF'),
(climate.STATE_MANUAL, 'AUTO'),
(STATE_OFF, 'OFF'),
(climate.STATE_IDLE, 'OFF'),
(climate.STATE_FAN_ONLY, 'OFF'),
(climate.STATE_DRY, 'OFF')
(climate.STATE_DRY, 'OFF'),
])
SMART_HOME_HTTP_ENDPOINT = '/api/alexa/smart_home'
@@ -66,6 +74,8 @@ HANDLERS = Registry()
ENTITY_ADAPTERS = Registry()
EVENT_ALEXA_SMART_HOME = 'alexa_smart_home'
AUTH_KEY = "alexa.smart_home.auth"
class _DisplayCategory:
"""Possible display categories for Discovery response.
@@ -375,9 +385,42 @@ class _AlexaInterface:
'name': prop_name,
'namespace': self.name(),
'value': prop_value,
'timeOfSample': datetime.now().strftime(DATE_FORMAT),
'uncertaintyInMilliseconds': 0
}
class _AlexaEndpointHealth(_AlexaInterface):
"""Implements Alexa.EndpointHealth.
https://developer.amazon.com/docs/smarthome/state-reporting-for-a-smart-home-skill.html#report-state-when-alexa-requests-it
"""
def __init__(self, hass, entity):
super().__init__(entity)
self.hass = hass
def name(self):
return 'Alexa.EndpointHealth'
def properties_supported(self):
return [{'name': 'connectivity'}]
def properties_proactively_reported(self):
return False
def properties_retrievable(self):
return True
def get_property(self, name):
if name != 'connectivity':
raise _UnsupportedProperty(name)
if self.entity.state == STATE_UNAVAILABLE:
return {'value': 'UNREACHABLE'}
return {'value': 'OK'}
class _AlexaPowerController(_AlexaInterface):
"""Implements Alexa.PowerController.
@@ -390,6 +433,9 @@ class _AlexaPowerController(_AlexaInterface):
def properties_supported(self):
return [{'name': 'powerState'}]
def properties_proactively_reported(self):
return True
def properties_retrievable(self):
return True
@@ -417,6 +463,9 @@ class _AlexaLockController(_AlexaInterface):
def properties_retrievable(self):
return True
def properties_proactively_reported(self):
return True
def get_property(self, name):
if name != 'lockState':
raise _UnsupportedProperty(name)
@@ -454,6 +503,9 @@ class _AlexaBrightnessController(_AlexaInterface):
def properties_supported(self):
return [{'name': 'brightness'}]
def properties_proactively_reported(self):
return True
def properties_retrievable(self):
return True
@@ -585,6 +637,9 @@ class _AlexaTemperatureSensor(_AlexaInterface):
def properties_supported(self):
return [{'name': 'temperature'}]
def properties_proactively_reported(self):
return True
def properties_retrievable(self):
return True
@@ -625,6 +680,9 @@ class _AlexaContactSensor(_AlexaInterface):
def properties_supported(self):
return [{'name': 'detectionState'}]
def properties_proactively_reported(self):
return True
def properties_retrievable(self):
return True
@@ -648,6 +706,9 @@ class _AlexaMotionSensor(_AlexaInterface):
def properties_supported(self):
return [{'name': 'detectionState'}]
def properties_proactively_reported(self):
return True
def properties_retrievable(self):
return True
@@ -686,6 +747,9 @@ class _AlexaThermostatController(_AlexaInterface):
properties.append({'name': 'thermostatMode'})
return properties
def properties_proactively_reported(self):
return True
def properties_retrievable(self):
return True
@@ -702,7 +766,7 @@ class _AlexaThermostatController(_AlexaInterface):
unit = self.hass.config.units.temperature_unit
if name == 'targetSetpoint':
temp = self.entity.attributes.get(climate.ATTR_TEMPERATURE)
temp = self.entity.attributes.get(ATTR_TEMPERATURE)
elif name == 'lowerSetpoint':
temp = self.entity.attributes.get(climate.ATTR_TARGET_TEMP_LOW)
elif name == 'upperSetpoint':
@@ -733,7 +797,8 @@ class _GenericCapabilities(_AlexaEntity):
return [_DisplayCategory.OTHER]
def interfaces(self):
return [_AlexaPowerController(self.entity)]
return [_AlexaPowerController(self.entity),
_AlexaEndpointHealth(self.hass, self.entity)]
@ENTITY_ADAPTERS.register(switch.DOMAIN)
@@ -742,7 +807,8 @@ class _SwitchCapabilities(_AlexaEntity):
return [_DisplayCategory.SWITCH]
def interfaces(self):
return [_AlexaPowerController(self.entity)]
return [_AlexaPowerController(self.entity),
_AlexaEndpointHealth(self.hass, self.entity)]
@ENTITY_ADAPTERS.register(climate.DOMAIN)
@@ -756,6 +822,7 @@ class _ClimateCapabilities(_AlexaEntity):
yield _AlexaPowerController(self.entity)
yield _AlexaThermostatController(self.hass, self.entity)
yield _AlexaTemperatureSensor(self.hass, self.entity)
yield _AlexaEndpointHealth(self.hass, self.entity)
@ENTITY_ADAPTERS.register(cover.DOMAIN)
@@ -768,6 +835,7 @@ class _CoverCapabilities(_AlexaEntity):
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & cover.SUPPORT_SET_POSITION:
yield _AlexaPercentageController(self.entity)
yield _AlexaEndpointHealth(self.hass, self.entity)
@ENTITY_ADAPTERS.register(light.DOMAIN)
@@ -785,6 +853,7 @@ class _LightCapabilities(_AlexaEntity):
yield _AlexaColorController(self.entity)
if supported & light.SUPPORT_COLOR_TEMP:
yield _AlexaColorTemperatureController(self.entity)
yield _AlexaEndpointHealth(self.hass, self.entity)
@ENTITY_ADAPTERS.register(fan.DOMAIN)
@@ -797,6 +866,7 @@ class _FanCapabilities(_AlexaEntity):
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & fan.SUPPORT_SET_SPEED:
yield _AlexaPercentageController(self.entity)
yield _AlexaEndpointHealth(self.hass, self.entity)
@ENTITY_ADAPTERS.register(lock.DOMAIN)
@@ -805,31 +875,33 @@ class _LockCapabilities(_AlexaEntity):
return [_DisplayCategory.SMARTLOCK]
def interfaces(self):
return [_AlexaLockController(self.entity)]
return [_AlexaLockController(self.entity),
_AlexaEndpointHealth(self.hass, self.entity)]
@ENTITY_ADAPTERS.register(media_player.DOMAIN)
@ENTITY_ADAPTERS.register(media_player.const.DOMAIN)
class _MediaPlayerCapabilities(_AlexaEntity):
def default_display_categories(self):
return [_DisplayCategory.TV]
def interfaces(self):
yield _AlexaPowerController(self.entity)
yield _AlexaEndpointHealth(self.hass, self.entity)
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & media_player.SUPPORT_VOLUME_SET:
if supported & media_player.const.SUPPORT_VOLUME_SET:
yield _AlexaSpeaker(self.entity)
step_volume_features = (media_player.SUPPORT_VOLUME_MUTE |
media_player.SUPPORT_VOLUME_STEP)
step_volume_features = (media_player.const.SUPPORT_VOLUME_MUTE |
media_player.const.SUPPORT_VOLUME_STEP)
if supported & step_volume_features:
yield _AlexaStepSpeaker(self.entity)
playback_features = (media_player.SUPPORT_PLAY |
media_player.SUPPORT_PAUSE |
media_player.SUPPORT_STOP |
media_player.SUPPORT_NEXT_TRACK |
media_player.SUPPORT_PREVIOUS_TRACK)
playback_features = (media_player.const.SUPPORT_PLAY |
media_player.const.SUPPORT_PAUSE |
media_player.const.SUPPORT_STOP |
media_player.const.SUPPORT_NEXT_TRACK |
media_player.const.SUPPORT_PREVIOUS_TRACK)
if supported & playback_features:
yield _AlexaPlaybackController(self.entity)
@@ -877,6 +949,7 @@ class _SensorCapabilities(_AlexaEntity):
TEMP_CELSIUS,
):
yield _AlexaTemperatureSensor(self.hass, self.entity)
yield _AlexaEndpointHealth(self.hass, self.entity)
@ENTITY_ADAPTERS.register(binary_sensor.DOMAIN)
@@ -898,6 +971,8 @@ class _BinarySensorCapabilities(_AlexaEntity):
elif sensor_type is self.TYPE_MOTION:
yield _AlexaMotionSensor(self.hass, self.entity)
yield _AlexaEndpointHealth(self.hass, self.entity)
def get_type(self):
"""Return the type of binary sensor."""
attrs = self.entity.attributes
@@ -948,14 +1023,16 @@ class _Cause:
class Config:
"""Hold the configuration for Alexa."""
def __init__(self, should_expose, entity_config=None):
def __init__(self, endpoint, async_get_access_token, should_expose,
entity_config=None):
"""Initialize the configuration."""
self.endpoint = endpoint
self.async_get_access_token = async_get_access_token
self.should_expose = should_expose
self.entity_config = entity_config or {}
@ha.callback
def async_setup(hass, config):
async def async_setup(hass, config):
"""Activate Smart Home functionality of Alexa component.
This is optional, triggered by having a `smart_home:` sub-section in the
@@ -964,12 +1041,61 @@ def async_setup(hass, config):
Even if that's disabled, the functionality in this module may still be used
by the cloud component which will call async_handle_message directly.
"""
if config.get(CONF_CLIENT_ID) and config.get(CONF_CLIENT_SECRET):
hass.data[AUTH_KEY] = Auth(hass, config[CONF_CLIENT_ID],
config[CONF_CLIENT_SECRET])
async_get_access_token = \
hass.data[AUTH_KEY].async_get_access_token if AUTH_KEY in hass.data \
else None
smart_home_config = Config(
endpoint=config.get(CONF_ENDPOINT),
async_get_access_token=async_get_access_token,
should_expose=config[CONF_FILTER],
entity_config=config.get(CONF_ENTITY_CONFIG),
)
hass.http.register_view(SmartHomeView(smart_home_config))
if AUTH_KEY in hass.data:
await async_enable_proactive_mode(hass, smart_home_config)
async def async_enable_proactive_mode(hass, smart_home_config):
"""Enable the proactive mode.
Proactive mode makes this component report state changes to Alexa.
"""
if smart_home_config.async_get_access_token is None:
# no function to call to get token
return
if await smart_home_config.async_get_access_token() is None:
# not ready yet
return
async def async_entity_state_listener(changed_entity, old_state,
new_state):
if not smart_home_config.should_expose(changed_entity):
_LOGGER.debug("Not exposing %s because filtered by config",
changed_entity)
return
if new_state.domain not in ENTITY_ADAPTERS:
return
alexa_changed_entity = \
ENTITY_ADAPTERS[new_state.domain](hass, smart_home_config,
new_state)
for interface in alexa_changed_entity.interfaces():
if interface.properties_proactively_reported():
await async_send_changereport_message(hass, smart_home_config,
alexa_changed_entity)
return
async_track_state_change(hass, MATCH_ALL, async_entity_state_listener)
class SmartHomeView(http.HomeAssistantView):
"""Expose Smart Home v3 payload interface via HTTP POST."""
@@ -989,12 +1115,15 @@ class SmartHomeView(http.HomeAssistantView):
the response.
"""
hass = request.app['hass']
user = request[http.KEY_HASS_USER]
message = await request.json()
_LOGGER.debug("Received Alexa Smart Home request: %s", message)
response = await async_handle_message(
hass, self.smart_home_config, message)
hass, self.smart_home_config, message,
context=ha.Context(user_id=user.id)
)
_LOGGER.debug("Sending Alexa Smart Home response: %s", response)
return b'' if response is None else self.json(response)
@@ -1112,6 +1241,24 @@ class _AlexaResponse:
"""
self._response[API_EVENT][API_HEADER]['correlationToken'] = token
def set_endpoint_full(self, bearer_token, endpoint_id, cookie=None):
"""Set the endpoint dictionary.
This is used to send proactive messages to Alexa.
"""
self._response[API_EVENT][API_ENDPOINT] = {
API_SCOPE: {
'type': 'BearerToken',
'token': bearer_token
}
}
if endpoint_id is not None:
self._response[API_EVENT][API_ENDPOINT]['endpointId'] = endpoint_id
if cookie is not None:
self._response[API_EVENT][API_ENDPOINT]['cookie'] = cookie
def set_endpoint(self, endpoint):
"""Set the endpoint.
@@ -1222,6 +1369,61 @@ async def async_handle_message(
return response.serialize()
async def async_send_changereport_message(hass, config, alexa_entity):
"""Send a ChangeReport message for an Alexa entity."""
token = await config.async_get_access_token()
if not token:
_LOGGER.error("Invalid access token.")
return
headers = {
"Authorization": "Bearer {}".format(token)
}
endpoint = alexa_entity.entity_id()
# this sends all the properties of the Alexa Entity, whether they have
# changed or not. this should be improved, and properties that have not
# changed should be moved to the 'context' object
properties = list(alexa_entity.serialize_properties())
payload = {
API_CHANGE: {
'cause': {'type': _Cause.APP_INTERACTION},
'properties': properties
}
}
message = _AlexaResponse(name='ChangeReport', namespace='Alexa',
payload=payload)
message.set_endpoint_full(token, endpoint)
message_serialized = message.serialize()
try:
session = aiohttp_client.async_get_clientsession(hass)
with async_timeout.timeout(DEFAULT_TIMEOUT, loop=hass.loop):
response = await session.post(config.endpoint,
headers=headers,
json=message_serialized,
allow_redirects=True)
except (asyncio.TimeoutError, aiohttp.ClientError):
_LOGGER.error("Timeout calling LWA to get auth token.")
return None
response_text = await response.text()
_LOGGER.debug("Sent: %s", json.dumps(message_serialized))
_LOGGER.debug("Received (%s): %s", response.status, response_text)
if response.status != 202:
response_json = json.loads(response_text)
_LOGGER.error("Error when sending ChangeReport to Alexa: %s: %s",
response_json["payload"]["code"],
response_json["payload"]["description"])
@HANDLERS.register(('Alexa.Discovery', 'Discover'))
async def async_api_discovery(hass, config, directive, context):
"""Create a API formatted discovery response.
@@ -1258,8 +1460,9 @@ async def async_api_discovery(hass, config, directive, context):
i.serialize_discovery() for i in alexa_entity.interfaces()]
if not endpoint['capabilities']:
_LOGGER.debug("Not exposing %s because it has no capabilities",
entity.entity_id)
_LOGGER.debug(
"Not exposing %s because it has no capabilities",
entity.entity_id)
continue
discovery_endpoints.append(endpoint)
@@ -1270,6 +1473,25 @@ async def async_api_discovery(hass, config, directive, context):
)
@HANDLERS.register(('Alexa.Authorization', 'AcceptGrant'))
async def async_api_accept_grant(hass, config, directive, context):
"""Create a API formatted AcceptGrant response.
Async friendly.
"""
auth_code = directive.payload['grant']['code']
_LOGGER.debug("AcceptGrant code: %s", auth_code)
if AUTH_KEY in hass.data:
await hass.data[AUTH_KEY].async_do_auth(auth_code)
await async_enable_proactive_mode(hass, config)
return directive.response(
name='AcceptGrant.Response',
namespace='Alexa.Authorization',
payload={})
@HANDLERS.register(('Alexa.PowerController', 'TurnOn'))
async def async_api_turn_on(hass, config, directive, context):
"""Process a turn on request."""
@@ -1569,7 +1791,7 @@ async def async_api_set_volume(hass, config, directive, context):
data = {
ATTR_ENTITY_ID: entity.entity_id,
media_player.ATTR_MEDIA_VOLUME_LEVEL: volume,
media_player.const.ATTR_MEDIA_VOLUME_LEVEL: volume,
}
await hass.services.async_call(
@@ -1586,7 +1808,8 @@ async def async_api_select_input(hass, config, directive, context):
entity = directive.entity
# attempt to map the ALL UPPERCASE payload name to a source
source_list = entity.attributes[media_player.ATTR_INPUT_SOURCE_LIST] or []
source_list = entity.attributes[
media_player.const.ATTR_INPUT_SOURCE_LIST] or []
for source in source_list:
# response will always be space separated, so format the source in the
# most likely way to find a match
@@ -1601,7 +1824,7 @@ async def async_api_select_input(hass, config, directive, context):
data = {
ATTR_ENTITY_ID: entity.entity_id,
media_player.ATTR_INPUT_SOURCE: media_input,
media_player.const.ATTR_INPUT_SOURCE: media_input,
}
await hass.services.async_call(
@@ -1617,7 +1840,8 @@ async def async_api_adjust_volume(hass, config, directive, context):
volume_delta = int(directive.payload['volume'])
entity = directive.entity
current_level = entity.attributes.get(media_player.ATTR_MEDIA_VOLUME_LEVEL)
current_level = entity.attributes.get(
media_player.const.ATTR_MEDIA_VOLUME_LEVEL)
# read current state
try:
@@ -1629,11 +1853,11 @@ async def async_api_adjust_volume(hass, config, directive, context):
data = {
ATTR_ENTITY_ID: entity.entity_id,
media_player.ATTR_MEDIA_VOLUME_LEVEL: volume,
media_player.const.ATTR_MEDIA_VOLUME_LEVEL: volume,
}
await hass.services.async_call(
entity.domain, media_player.SERVICE_VOLUME_SET,
entity.domain, SERVICE_VOLUME_SET,
data, blocking=False, context=context)
return directive.response()
@@ -1655,11 +1879,11 @@ async def async_api_adjust_volume_step(hass, config, directive, context):
if volume_step > 0:
await hass.services.async_call(
entity.domain, media_player.SERVICE_VOLUME_UP,
entity.domain, SERVICE_VOLUME_UP,
data, blocking=False, context=context)
elif volume_step < 0:
await hass.services.async_call(
entity.domain, media_player.SERVICE_VOLUME_DOWN,
entity.domain, SERVICE_VOLUME_DOWN,
data, blocking=False, context=context)
return directive.response()
@@ -1674,11 +1898,11 @@ async def async_api_set_mute(hass, config, directive, context):
data = {
ATTR_ENTITY_ID: entity.entity_id,
media_player.ATTR_MEDIA_VOLUME_MUTED: mute,
media_player.const.ATTR_MEDIA_VOLUME_MUTED: mute,
}
await hass.services.async_call(
entity.domain, media_player.SERVICE_VOLUME_MUTE,
entity.domain, SERVICE_VOLUME_MUTE,
data, blocking=False, context=context)
return directive.response()

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Clau d'aplicaci\u00f3 i/o clau API ja registrada",
"invalid_key": "Clau API i/o clau d'aplicaci\u00f3 inv\u00e0lida/es",
"no_devices": "No s'ha trobat cap dispositiu al compte"
},
"step": {
"user": {
"data": {
"api_key": "Clau API",
"app_key": "Clau d'aplicaci\u00f3"
},
"title": "Introdueix la teva informaci\u00f3"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Applikationsn\u00f8gle og/eller API n\u00f8gle er allerede registreret",
"invalid_key": "Ugyldig API n\u00f8gle og/eller applikationsn\u00f8gle",
"no_devices": "Ingen enheder fundet i konto"
},
"step": {
"user": {
"data": {
"api_key": "API n\u00f8gle",
"app_key": "Applikationsn\u00f8gle"
},
"title": "Udfyld dine oplysninger"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Anwendungsschl\u00fcssel und / oder API-Schl\u00fcssel bereits registriert",
"invalid_key": "Ung\u00fcltiger API Key und / oder Anwendungsschl\u00fcssel",
"no_devices": "Keine Ger\u00e4te im Konto gefunden"
},
"step": {
"user": {
"data": {
"api_key": "API Key",
"app_key": "Anwendungsschl\u00fcssel"
},
"title": "Gib deine Informationen ein"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Application Key and/or API Key already registered",
"invalid_key": "Invalid API Key and/or Application Key",
"no_devices": "No devices found in account"
},
"step": {
"user": {
"data": {
"api_key": "API Key",
"app_key": "Application Key"
},
"title": "Fill in your information"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Clave de aplicaci\u00f3n y/o clave de API ya registrada",
"invalid_key": "Clave de API y/o clave de aplicaci\u00f3n no v\u00e1lida",
"no_devices": "No se han encontrado dispositivos en la cuenta."
},
"step": {
"user": {
"data": {
"api_key": "Clave API",
"app_key": "Clave de aplicaci\u00f3n"
},
"title": "Completa tu informaci\u00f3n"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,9 @@
{
"config": {
"step": {
"user": {
"title": "Completa tu informaci\u00f3n"
}
}
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"error": {
"identifier_exists": "Cl\u00e9 d'application et / ou cl\u00e9 API d\u00e9j\u00e0 enregistr\u00e9e",
"invalid_key": "Cl\u00e9 d'API et / ou cl\u00e9 d'application non valide",
"no_devices": "Aucun appareil trouv\u00e9 dans le compte"
},
"step": {
"user": {
"data": {
"api_key": "Cl\u00e9 d'API",
"app_key": "Cl\u00e9 d'application"
},
"title": "Veuillez saisir vos informations"
}
}
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"error": {
"no_devices": "\u05dc\u05d0 \u05e0\u05de\u05e6\u05d0\u05d5 \u05d4\u05ea\u05e7\u05df \u05d1\u05d7\u05e9\u05d1\u05d5\u05df"
},
"step": {
"user": {
"data": {
"api_key": "\u05de\u05e4\u05ea\u05d7 API"
},
"title": "\u05de\u05dc\u05d0 \u05d0\u05ea \u05d4\u05e4\u05e8\u05d8\u05d9\u05dd \u05e9\u05dc\u05da"
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Alkalmaz\u00e1s kulcsot \u00e9s/vagy az API kulcsot m\u00e1r regisztr\u00e1lt\u00e1k",
"invalid_key": "\u00c9rv\u00e9nytelen API kulcs \u00e9s / vagy alkalmaz\u00e1skulcs",
"no_devices": "Nincs a fi\u00f3kodban tal\u00e1lhat\u00f3 eszk\u00f6z"
},
"step": {
"user": {
"data": {
"api_key": "API kulcs",
"app_key": "Alkalmaz\u00e1skulcs"
},
"title": "T\u00f6ltsd ki az adataid"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"error": {
"identifier_exists": "API Key e/o Application Key gi\u00e0 registrata",
"invalid_key": "API Key e/o Application Key non valida",
"no_devices": "Nessun dispositivo trovato nell'account"
},
"step": {
"user": {
"data": {
"api_key": "API Key",
"app_key": "Application Key"
},
"title": "Inserisci i tuoi dati"
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Application \ud0a4 \ud639\uc740 API \ud0a4\uac00 \uc774\ubbf8 \ub4f1\ub85d\ub418\uc5c8\uc2b5\ub2c8\ub2e4",
"invalid_key": "Application \ud0a4 \ud639\uc740 API \ud0a4\uac00 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4",
"no_devices": "\uacc4\uc815\uc5d0 \uae30\uae30\uac00 \uc874\uc7ac\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {
"api_key": "API \ud0a4",
"app_key": "Application \ud0a4"
},
"title": "\uc0ac\uc6a9\uc790 \uc815\ubcf4\ub97c \uc785\ub825\ud574\uc8fc\uc138\uc694"
}
},
"title": "Ambient PWS"
}
}

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