Compare commits

...

1253 Commits

Author SHA1 Message Date
Paulus Schoutsen
026dbffa77 Bumped version to 0.96.0b4 2019-07-16 14:59:46 -07:00
Fabian Affolter
e74fc9836d Upgrade luftdaten to 0.6.2 (#25177) 2019-07-16 14:59:38 -07:00
Alexei Chetroi
c7dfec702d Fix climate is_aux_heat type hint. (#25170) 2019-07-16 14:59:37 -07:00
Anders Melchiorsen
0f8f9db319 Update pysonos to 0.0.21 (#25168) 2019-07-16 14:59:37 -07:00
Daniel Perna
366ad8202a Fix device types for some HomeMatic IP sensors (#25167)
* Update pyhomematic to 0.1.60

* Devicetype for pyhomematic classes, fixes #24080
2019-07-16 14:59:36 -07:00
Paulus Schoutsen
28bd7b6a4e Bumped version to 0.96.0b3 2019-07-15 13:57:41 -07:00
Paulus Schoutsen
c04049d6f6 Make dev tools titlte translatable (#25166) 2019-07-15 13:57:35 -07:00
Joakim Sørensen
ff79e437d2 Version sensor update (#25162)
* component -> integration

* Bump pyhaversion to 3.0.2

* Update requirements

* Formating
2019-07-15 13:57:34 -07:00
Daniel Perna
c8b495f224 Update pyhomematic to 0.1.60 (#25152) 2019-07-15 13:57:33 -07:00
Josh Anderson
842c1a2274 Remove check and restore temp/mode changes (#25149) 2019-07-15 13:57:33 -07:00
Khole
50b145cf05 [Climate] Hive Add water heater Component post the refresh of the climate component. (#25148)
* climate_water_heater

* updated names

* Update water_heater

* Update requirements

* Updated reqirements

* Version update

* updated Versiojn

* Update device list

* Removed unused Attributes
2019-07-15 13:57:32 -07:00
David Bonnes
78a0d72a5c [climate-1.0] Add RoundThermostat to evohome (#25141)
* initial commit

* improve enumeration of zone(s)

* remove unused self._config

* remove unused self._config 2

* remove unused self._id

* clean up device_state_attributes

* remove some pylint: disable=protected-access

* remove LOGGER.warn(

* refactor for RoundThermostat

* ready for review

* small tweak

* small tweak 2

* fix regression, tweak

* tidy up docstring

* simplify code
2019-07-15 13:57:32 -07:00
Markus Jankowski
97ca0d81e7 remove comfort mode (#25140) 2019-07-15 13:57:31 -07:00
David Bonnes
02e8ee137f [climate-1.0] Bugfix evohome showstopper (#25139)
* initial commit

* small tweak
2019-07-15 13:57:31 -07:00
Anders Melchiorsen
2643bbc228 Handle Sonos connection errors during setup (#25135) 2019-07-15 13:57:30 -07:00
Joakim Plate
c8d7e1346c Load requirements for platforms (#25133)
Fixes #25124 and fixes #25126
2019-07-15 13:57:30 -07:00
Paulus Schoutsen
7dedf173ad Allow area ID in service call schemas (#25121)
* Allow area ID in service call schemas

* Remove ATTR_ENTITY_ID from service light turn off schcema
2019-07-15 13:57:29 -07:00
Paulus Schoutsen
65593e36b1 Verify cloud user exists during boot (#25119) 2019-07-15 13:57:28 -07:00
Paulus Schoutsen
8996e330b8 Simplify Alexa/Google for new climate turn_on/off (#25115) 2019-07-15 13:57:28 -07:00
Markus Jankowski
e85d434f4e Add climate related services to Homematic IP Cloud (#25079)
* add hmip climate services

* Rename accesspoint_id to hapid

to comply with config

* Revert "Rename accesspoint_id to hapid"

This reverts commit 4a3cd14e1482fb508273c728ad8020945b02e426.
2019-07-15 13:57:27 -07:00
Paulus Schoutsen
82d9488ec8 Updated frontend to 20190715.0 2019-07-15 13:55:59 -07:00
Pascal Vizeli
4fc302b67a Update azure-pipelines-release.yml for Azure Pipelines 2019-07-15 22:38:48 +02:00
Pascal Vizeli
d444ba397b Update azure-pipelines-wheels.yml for Azure Pipelines 2019-07-15 15:22:41 +02:00
Paulus Schoutsen
c884f9edbc Bumped version to 0.96.0b2 2019-07-12 15:09:02 -07:00
Aaron Bach
d0af73efe1 Fix missing sensor unit in RainMachine (#25101) 2019-07-12 15:08:56 -07:00
Aaron Bach
5eb7268ae7 Fix window exception in WWLLN (#25100)
* Beta fix: handle window exception in WWLLN

* Fixed test

* Fix bug

* Member comments

* Removed unused import
2019-07-12 15:08:55 -07:00
On Freund
60c2e5e2e2 Add turn on/off to coolmaster (#25097) 2019-07-12 15:08:54 -07:00
cgtobi
4e69b5b45f Fix Netatmo climate issue when device out of reach (#25096)
* Fix valve/thermostat out of reach

* Fix boost for valves

* Set netatmo default max temp to 30

* Remove unnecessary get

* Remove unnecessary default value

* Readd get
2019-07-12 15:08:54 -07:00
David Bonnes
1d784bdc05 [climate] Add water_heater to evohome (#25035)
* initial commit

* refactor for sync

* minor tweak

* refactor convert code

* fix regression

* remove bad await

* de-lint

* de-lint 2

* address edge case - invalid tokens

* address edge case - delint

* handle no schedule

* improve support for RoundThermostat

* tweak logging

* delint

* refactor for greatness

* use time_zone: for state attributes

* small tweak

* small tweak 2

* have datetime state attributes as UTC

* have datetime state attributes as UTC - delint

* have datetime state attributes as UTC - tweak

* missed this - remove

* de-lint type hint

* use parse_datetime instead of datetime.strptime)

* remove debug code

* state atrribute datetimes are UTC now

* revert

* de-lint (again)

* tweak type hints

* de-lint (again, again)

* tweak type hints

* Convert datetime closer to sending it out
2019-07-12 15:08:53 -07:00
Paulus Schoutsen
9181660497 Updated frontend to 20190712.0 2019-07-12 15:05:02 -07:00
Pascal Vizeli
7fc8ff982b Version bump to 0.96.0b1 2019-07-12 07:24:30 +00:00
Paulus Schoutsen
155c75c54a Guard module being None (#25077) 2019-07-12 07:23:30 +00:00
Anders Melchiorsen
afade4e997 Support podcast episodes as Sonos favorites (#25087) 2019-07-12 07:22:02 +00:00
Pascal Vizeli
53111f6426 Fix powercontrol media player alexa (#25080) 2019-07-12 07:21:59 +00:00
Aaron Bach
53a701b12c Change unique_id formula for Notion entities (#25076)
* Change unique_id formula for Notion entities

* Don't use name
2019-07-12 07:21:57 +00:00
Pascal Vizeli
a0e45cce79 Add support for on/off climate (#25026)
* Add support for on/off climate

* address comments

* Add test for sync overwrite

* Add more tests
2019-07-12 07:21:54 +00:00
Paulus Schoutsen
2b62ea1f0e Do not reverse open/close calls (#24879) 2019-07-12 07:19:26 +00:00
Pascal Vizeli
cc7b65a6c8 Support hass-release inside devcontainer (#25090) 2019-07-12 07:18:31 +00:00
Pascal Vizeli
3b6b421152 Update azure-pipelines-release.yml for Azure Pipelines 2019-07-11 09:24:45 +02:00
Pascal Vizeli
fcb1783f56 Update azure-pipelines-release.yml for Azure Pipelines 2019-07-11 09:22:37 +02:00
Pascal Vizeli
8041339052 Update azure-pipelines-release.yml for Azure Pipelines 2019-07-11 09:17:44 +02:00
Paulus Schoutsen
87d3680630 Merge commit 'df920b4eda1d64368ed3bf166bcb0a90aeec6c44' into rc 2019-07-10 20:54:06 -07:00
Paulus Schoutsen
bd7c0e87d5 Version bump to 0.96.0b0 2019-07-10 20:49:56 -07:00
Paulus Schoutsen
df920b4eda Merge remote-tracking branch 'origin/master' into dev 2019-07-10 20:48:54 -07:00
Paulus Schoutsen
cde3f670c2 pylint 2019-07-10 20:47:27 -07:00
Phil Bruckner
c80683bb15 Restore automation last_triggered as datetime & fix test (#24951)
* Restore automation last_triggered as datetime & fix test

* last_triggered is always a string
2019-07-10 20:42:38 -07:00
Paulus Schoutsen
073327831f Correctly store removed entities for restore state (#25073)
* Correctly store removed entities for restore state

* Lint

* Do not assume about set encoding
2019-07-10 20:41:03 -07:00
Charles Garwood
312fceeaf6 Add websocket API command for Z-Wave network status (#25066)
* Add websocket API command for Z-Wave network status

* lint

* Add callback decorator

* Remove state_str, fix lint
2019-07-10 19:50:42 -07:00
monte-monte
42d2f30ab8 Complete OPERATION_MODES (#25069)
XKNX library has complete list of KNX controller modes, but current version of HA KNX climate plugin uses only two of them and one is named incorrectly ("Dehumidification" instead of "Dry"). https://github.com/XKNX/xknx/blob/master/xknx/knx/dpt_hvac_mode.py
I've added missing control modes, which has corresponding operation mode in HA. Tested this patch on my KNX IntesisBox which is used with Mitsubishi split AC, all modes were detected correctly and working as expected.
I've also corrected datapoint number in a comment, because it was pointing to a wrong one: http://www.sti.uniurb.it/romanell/Domotica_e_Edifici_Intelligenti/110504-Lez10a-KNX-Datapoint%20Types%20v1.5.00%20AS.pdf see page 94.
2019-07-10 15:59:43 -07:00
Jeff Irion
4844477d3a Make sure volume level is valid when incrementing/decrementing (#25061)
* Make sure volume level is not None before incrementing/decrementing

* Pass linting checks
2019-07-10 15:58:29 -07:00
Martijn van Zal
ca8118138c Change phrases in the logbook component for persons and binary_sensors (#25053)
Persons are now threated the same as device trackers, so the logbook states
"<name> is at <location>" or "<name> is away" instead of "<name> changed to <location|not_home>"

Binary sensors now show phrases that relate to their device_class attribute.
So "Front door is closed" instead of "Front door turned off" or "Hallway PIR detected movement"
instead of "Hallway PIR turned on"
2019-07-10 15:56:41 -07:00
Johann Kellerman
e51b5e801e SMA catch error (#25045)
* SMA small fix

* lib update

* req
2019-07-10 15:55:40 -07:00
Aaron Bach
9ccb85d959 Add support for World Wide Lightning Location Network (#25001)
* Add support for World Wide Lightning Location Network

* Updated .coveragerc

* Added test

* Updated requirements

* Fixed tests

* Use local time for nearest strike

* Base geo location in place

* Finished geolocation work

* Fixed tests

* Cleanup

* Removed no-longer-needed method

* Updated requirements

* Add support for window and attrs

* Add strike ID to entity name

* Member comments
2019-07-10 16:40:11 -06:00
Alexei Chetroi
cea857e18a Bump up ZHA dependencies. (#25062)
Bump zigpy-homeassistant to 0.7.0
Bump zigpy-deconz to 0.2.1
Bump zigpy-xbee-homeassistant to 0.4.0
2019-07-10 12:20:37 -07:00
Anders Melchiorsen
1afa136fc0 Fix for Sonos debug logging (#25064)
* Fix for Sonos debug logging

* Start logging messages with capital letters
2019-07-10 12:19:28 -07:00
Paulus Schoutsen
7d33b0a259 Fix broken test in Python 3.7 (#25067) 2019-07-10 12:17:10 -07:00
David F. Mulcahey
777e1ca832 bump zha-quirks version (#25059) 2019-07-10 11:59:06 -07:00
Johann Kellerman
2e26f0bd2b Add check_config helper (#24557)
* check_config

* no ignore

* tests

* try tests again
2019-07-10 11:56:50 -07:00
Penny Wood
236debb455 Avoid flooding steam API (#23941) 2019-07-10 11:15:42 -07:00
Paulus Schoutsen
5f5c541f2f Update translations 2019-07-10 10:50:50 -07:00
Paulus Schoutsen
f0f7dc4884 Updated frontend to 20190710.0 2019-07-10 10:49:07 -07:00
Anders Melchiorsen
18d27c997d Add Sonos debug logging (#25063) 2019-07-10 09:30:45 -07:00
David Bonnes
a44686389c [climate] Bugfix honeywell misleading error message (#25048)
* initial commit

* refactor for sync

* minor tweak

* refactor convert code

* fix regression

* remove bad await

* de-lint

* de-lint 2

* improve error message

* rebase

* tweak

* de-lint
2019-07-10 08:38:31 -07:00
cdce8p
98ba015f06 Remove myself as codeowner (#25043) 2019-07-10 08:36:17 -07:00
Matte23
c1c2159dee Added marker sensor to CUPS integration (#25037) 2019-07-10 08:35:30 -07:00
Paul Annekov
a30c37017b Update tuyaha to 0.0.2 to catch API exceptions (#25050)
* Update tuyaha to 0.0.2 to catch API exceptions

* Updated tuyaha version in requirements
2019-07-10 01:54:19 +02:00
Aaron Bach
195b034abc Add config flow support to Geolocation (#25046) 2019-07-10 00:50:16 +02:00
William Sutton
c5239c6176 Add radiotherm CT80 current humidity support (#25024)
* Added CT80 Current Humidity Support

Added a check for if device is a CT80, and if so, queries the humidity object to get the current measured humidity reading.

* Update climate.py

Removed whitespace on line 229

* Update climate.py

Added humidity property. Version on local machine had that from previous tinkering.

* Update climate.py

Removed whitespace

* Update climate.py

Fixed tstat error handling for humidity data.
2019-07-09 21:18:05 +02:00
jlrgraham
5be695c49c Bump pyvera to 0.3.2, null/missing value protection (#25041)
* Bump pyvera to 0.3.2, null/missing value protection.

* Add another place where the pyvera version is set.
2019-07-09 20:06:45 +02:00
cgtobi
8652c84745 Fix Netatmo rain gauge precision (#25036) 2019-07-09 19:57:29 +02:00
Franck Nijhof
36ed725ab4 Improve toon climate (#25040)
* Renames internal climate state variable to preset

* Shorten function comments

* Updates local variables on preset and temp changes

* Adds support for hvac_action
2019-07-09 19:52:38 +02:00
Malte Franken
cf5a35a421 updated geojson_client library to version 0.4 (#25039) 2019-07-09 13:06:10 -04:00
Fabian Affolter
8256d72f6d Upgrade youtube_dl to 2019.07.02 (#24990)
* Upgrade youtube_dl to 2019.07.01

* Update homeassistant/components/media_extractor/manifest.json

Co-Authored-By: Josef Schlehofer <pepe.schlehofer@gmail.com>

* Update requirements_all.txt

Co-Authored-By: Josef Schlehofer <pepe.schlehofer@gmail.com>
2019-07-09 13:03:52 -04:00
Pascal Vizeli
25745e9e27 Update build pipeline 2019-07-09 15:32:09 +02:00
Franck Nijhof
3ce1049d21 Centralizes Toon data, reducing API calls (#23988)
* Centralizes Toon data, reducing API calls

Fixes #21825

Signed-off-by: Franck Nijhof <frenck@addons.community>

* Fixes bad copy past action in services.yaml

Signed-off-by: Franck Nijhof <frenck@addons.community>

* Addresses review comments

Signed-off-by: Franck Nijhof <frenck@addons.community>

* 👕 Fixes too many blank lines

* Unsub dispatcher
2019-07-09 14:18:51 +02:00
arigilder
f3e542542a Add missing support for jewish_calendar.omer_count sensor (#24958)
* Add missing support for omer_count to jewish_calendar

* Add tests for omer sensor

* Add tests for omer after tzeit hakochavim

* Lint fixes
2019-07-09 11:58:57 +02:00
cgtobi
07b635e7aa Fix Netatmo climate presets (#25029)
* Fix netatmo presets

* Remove off mode for valves

* Revert usage of global const

* Flip values

* Remove try...except block
2019-07-09 10:40:02 +02:00
Aaron Bach
c2e843cbc3 Add support for Notion Home Monitoring (#24634)
* Add support for Notion Home Monitoring

* Updated coverage

* Removed auto-generated translations

* Stale docstrings

* Corrected hardware version

* Fixed binary sensor representation

* Cleanup and update protection

* Updated log message

* Cleaned up is_on

* Updated docstring

* Modified which data is updated during async_update

* Added more checks during update

* More cleanup

* Fixed unhandled exception

* Owner-requested changes (round 1)

* Fixed incorrect scan interval retrieval

* Ugh

* Removed unnecessary import

* Simplified everything via dict lookups

* Ensure bridges are properly registered

* Fixed tests

* Added catch for invalid credentials

* Ensure bridge ID is updated as necessary

* Updated method name

* Simplified bridge update

* Add support for updating bridge via_device_id

* Device update guard clause

* Removed excess whitespace

* Whitespace

* Owner comments

* Member comments
2019-07-09 10:29:06 +02:00
Andrew Sayre
7a5fca69af Add hvac fan state (#25030) 2019-07-09 09:59:48 +02:00
Franck Nijhof
3016d3a186 Toon fixes for Climate 1.0 (#25027) 2019-07-09 08:44:30 +02:00
Andrew Sayre
a31e49c857 Improve SmartThings test mocking (#25028)
* Migrate to asynctest

* Simplify mock access

* Use mocks
2019-07-08 22:39:55 -04:00
Joakim Plate
2fbbcafaed Support config flow on custom components (#24946)
* Support populating list of flows from custom components

* Re-allow custom component config flows

* Add tests for custom component retrieval

* Don't crash view if no handler exist

* Use get_custom_components instead fo resolve_from_root

* Switch to using an event instead of lock

* Leave list of integrations as set

* The returned list is not guaranteed to be ordered

Backend uses a set to represent them.
2019-07-09 01:19:37 +02:00
Pascal Vizeli
a2237ce5d4 homematic add off support for climate (#25017)
* homematic add off support for climate

* fix lint
2019-07-09 00:00:25 +02:00
Daniel Høyer Iversen
af7f61fec2 ambiclimate hvac_modes (#25015)
* ambiclimate hvac_modes

* style
2019-07-08 14:12:23 -07:00
Paulus Schoutsen
26a66276cd Fix Nest sensor (#25023) 2019-07-08 14:12:02 -07:00
Phil Bruckner
9944e675a5 Add template support to state trigger's for option (#24912) 2019-07-08 13:59:58 -07:00
Phil Bruckner
f9b9883aba Add template support to numeric_state trigger's for option (#24955) 2019-07-08 13:58:50 -07:00
Phil Bruckner
1431fd6fbd Add datetime option to input_datetime.set_datetime service (#24975) 2019-07-08 13:18:42 -07:00
Paulus Schoutsen
b11171aaeb Fix mimetypes on borked Windows machines (#25018) 2019-07-08 13:16:22 -07:00
Paulus Schoutsen
0b7a901c81 Fix ecobee flaky test (#25019) 2019-07-08 13:10:01 -07:00
Daniel Høyer Iversen
662e0dde80 Sensibo, add HVAC_MODE_OFF (#25016) 2019-07-08 13:17:59 -04:00
Joakim Plate
ab832cda71 Add support for arcam fmj receivers (#24621)
* Add arcam_fmj support

* Just use use state in player avoid direct client access

* Avoid leaking exceptions on invalid data

* Fix return value for volume in case of 0

* Mark component as having no coverage

* Add new requirement

* Add myself as maintainer

* Correct linting errors

* Use async_create_task instead of async_add_job

* Use new style string format instead of concat

* Don't call init of base class without init

* Annotate callbacks with @callback

Otherwise they won't be called in loop

* Reduce log level to debug

* Use async_timeout instead of wait_for

* Bump to version of arcam_fmj supporting 3.5

* Fix extra spaces

* Drop somewhat flaky unique_id

* Un-blackify ident to satisy pylint

* Un-blackify ident to satisy pylint

* Move default name calculation to config validation

* Add test folder

* Drop unused code

* Add tests for config flow import
2019-07-08 17:14:19 +02:00
Jesse Rizzo
f90fe7e628 Enphase envoy individual inverter production (#24445)
* bump envoy_reader version to 0.4

* bump dependency envoy_reader to 0.4

* Enphase envoy get individual inverter production

* Add period in function description

* Fix dumb typo

* Define _attributes in __init__

* Better error messages, make update async

* Fix format error

* Fix pylint errors

* set unknown state to None

* Bump envoy_reader version to 0.8

* Change attributes to separate sensors

* Fix dumb thing

* Improve platform_setup for inverters

* Remove unneeded self._attributes, refactor platform setup

* Refactor platform setup
2019-07-08 10:21:08 -04:00
Chris Johnston
32685f16bf Implement Twilio SMS notify MediaUrl support (#24971)
* Implement Twilio SMS notify MediaUrl support

Adds support for setting the `media_url` parameter of the twilio API
client with an optional attribute under the notify `data`
attribute.

Per the twilio docs (https://www.twilio.com/docs/sms/send-messages#include-medi$
this feature is only available in the US and Canada, for
GIF, PNG, or JPEG content.

* lint: fix 80 char ruler

* use kwargs to set the media_url

after testing locally, seems like the previous way of using
object() was not working. this seems to be working

* re-use the ATTR_MEDIAURL attribute
2019-07-08 14:05:15 +02:00
Pascal Vizeli
84cf76ba36 Climate 1.0 (#23899)
* Climate 1.0 / part 1/2/3

* fix flake

* Lint

* Update Google Assistant

* ambiclimate to climate 1.0 (#24911)

* Fix Alexa

* Lint

* Migrate zhong_hong

* Migrate tuya

* Migrate honeywell to new climate schema (#24257)

* Update one

* Fix model climate v2

* Cleanup p4

* Add comfort hold mode

* Fix old code

* Update homeassistant/components/climate/__init__.py

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>

* Update homeassistant/components/climate/const.py

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>

* First renaming

* Rename operation to hvac for paulus

* Rename hold mode to preset mode

* Cleanup & update comments

* Remove on/off

* Fix supported feature count

* Update services

* Update demo

* Fix tests & use current_hvac

* Update comment

* Fix tests & add typing

* Add more typing

* Update modes

* Fix tests

* Cleanup low/high with range

* Update homematic part 1

* Finish homematic

* Fix lint

* fix hm mapping

* Support simple devices

* convert lcn

* migrate oem

* Fix xs1

* update hive

* update mil

* Update toon

* migrate deconz

* cleanup

* update tesla

* Fix lint

* Fix vera

* Migrate zwave

* Migrate velbus

* Cleanup humity feature

* Cleanup

* Migrate wink

* migrate dyson

* Fix current hvac

* Renaming

* Fix lint

* Migrate tfiac

* migrate tado

* Fix PRESET can be None

* apply PR#23913 from dev

* remove EU component, etc.

* remove EU component, etc.

* ready to test now

* de-linted

* some tweaks

* de-lint

* better handling of edge cases

* delint

* fix set_mode typos

* apply PR#23913 from dev

* remove EU component, etc.

* ready to test now

* de-linted

* some tweaks

* de-lint

* better handling of edge cases

* delint

* fix set_mode typos

* delint, move debug code

* away preset now working

* code tidy-up

* code tidy-up 2

* code tidy-up 3

* address issues #18932, #15063

* address issues #18932, #15063 - 2/2

* refactor MODE_AUTO to MODE_HEAT_COOL and use F not C

* add low/high to set_temp

* add low/high to set_temp 2

* add low/high to set_temp - delint

* run HA scripts

* port changes from PR #24402

* manual rebase

* manual rebase 2

* delint

* minor change

* remove SUPPORT_HVAC_ACTION

* Migrate radiotherm

* Convert touchline

* Migrate flexit

* Migrate nuheat

* Migrate maxcube

* Fix names maxcube const

* Migrate proliphix

* Migrate heatmiser

* Migrate fritzbox

* Migrate opentherm_gw

* Migrate venstar

* Migrate daikin

* Migrate modbus

* Fix elif

* Migrate Homematic IP Cloud to climate-1.0 (#24913)

* hmip climate fix

* Update hvac_mode and preset_mode

* fix lint

* Fix lint

* Migrate generic_thermostat

* Migrate incomfort to new climate schema (#24915)

* initial commit

* Update climate.py

* Migrate eq3btsmart

* Lint

* cleanup PRESET_MANUAL

* Migrate ecobee

* No conditional features

* KNX: Migrate climate component to new climate platform (#24931)

* Migrate climate component

* Remove unused code

* Corrected line length

* Lint

* Lint

* fix tests

* Fix value

* Migrate geniushub to new climate schema (#24191)

* Update one

* Fix model climate v2

* Cleanup p4

* Add comfort hold mode

* Fix old code

* Update homeassistant/components/climate/__init__.py

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>

* Update homeassistant/components/climate/const.py

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>

* First renaming

* Rename operation to hvac for paulus

* Rename hold mode to preset mode

* Cleanup & update comments

* Remove on/off

* Fix supported feature count

* Update services

* Update demo

* Fix tests & use current_hvac

* Update comment

* Fix tests & add typing

* Add more typing

* Update modes

* Fix tests

* Cleanup low/high with range

* Update homematic part 1

* Finish homematic

* Fix lint

* fix hm mapping

* Support simple devices

* convert lcn

* migrate oem

* Fix xs1

* update hive

* update mil

* Update toon

* migrate deconz

* cleanup

* update tesla

* Fix lint

* Fix vera

* Migrate zwave

* Migrate velbus

* Cleanup humity feature

* Cleanup

* Migrate wink

* migrate dyson

* Fix current hvac

* Renaming

* Fix lint

* Migrate tfiac

* migrate tado

* delinted

* delinted

* use latest client

* clean up mappings

* clean up mappings

* add duration to set_temperature

* add duration to set_temperature

* manual rebase

* tweak

* fix regression

* small fix

* fix rebase mixup

* address comments

* finish refactor

* fix regression

* tweak type hints

* delint

* manual rebase

* WIP: Fixes for honeywell migration to climate-1.0 (#24938)

* add type hints

* code tidy-up

* Fixes for incomfort migration to climate-1.0 (#24936)

* delint type hints

* no async unless await

* revert: no async unless await

* revert: no async unless await 2

* delint

* fix typo

* Fix homekit_controller on climate-1.0 (#24948)

* Fix tests on climate-1.0 branch

* As part of climate-1.0, make state return the heating-cooling.current characteristic

* Fixes from review

* lint

* Fix imports

* Migrate stibel_eltron

* Fix lint

* Migrate coolmaster to climate 1.0 (#24967)

* Migrate coolmaster to climate 1.0

* fix lint errors

* More lint fixes

* Fix demo to work with UI

* Migrate spider

* Demo update

* Updated frontend to 20190705.0

* Fix boost mode (#24980)

* Prepare Netatmo for climate 1.0 (#24973)

* Migration Netatmo

* Address comments

* Update climate.py

* Migrate ephember

* Migrate Sensibo

* Implemented review comments (#24942)

* Migrate ESPHome

* Migrate MQTT

* Migrate Nest

* Migrate melissa

* Initial/partial migration of ST

* Migrate ST

* Remove Away mode (#24995)

* Migrate evohome, cache access tokens (#24491)

* add water_heater, add storage - initial commit

* add water_heater, add storage - initial commit

delint

add missing code

desiderata

update honeywell client library & CODEOWNER

add auth_tokens code, refactor & delint

refactor for broker

delint

* Add Broker, Water Heater & Refactor

add missing code

desiderata

* update honeywell client library & CODEOWNER

add auth_tokens code, refactor & delint

refactor for broker

* bugfix - loc_idx may not be 0

more refactor - ensure pure async

more refactoring

appears all r/o attributes are working

tweak precsion, DHW & delint

remove unused code

remove unused code 2

remove unused code, refactor _save_auth_tokens()

* support RoundThermostat

bugfix opmode, switch to util.dt, add until=1h

revert breaking change

* store at_expires as naive UTC

remove debug code

delint

tidy up exception handling

delint

add water_heater, add storage - initial commit

delint

add missing code

desiderata

update honeywell client library & CODEOWNER

add auth_tokens code, refactor & delint

refactor for broker

add water_heater, add storage - initial commit

delint

add missing code

desiderata

update honeywell client library & CODEOWNER

add auth_tokens code, refactor & delint

refactor for broker

delint

bugfix - loc_idx may not be 0

more refactor - ensure pure async

more refactoring

appears all r/o attributes are working

tweak precsion, DHW & delint

remove unused code

remove unused code 2

remove unused code, refactor _save_auth_tokens()

support RoundThermostat

bugfix opmode, switch to util.dt, add until=1h

revert breaking change

store at_expires as naive UTC

remove debug code

delint

tidy up exception handling

delint

* update CODEOWNERS

* fix regression

* fix requirements

* migrate to climate-1.0

* tweaking

* de-lint

* TCS working? & delint

* tweaking

* TCS code finalised

* remove available() logic

* refactor _switchpoints()

* tidy up switchpoint code

* tweak

* teaking device_state_attributes

* some refactoring

* move PRESET_CUSTOM back to evohome

* move CONF_ACCESS_TOKEN_EXPIRES CONF_REFRESH_TOKEN back to evohome

* refactor SP code and dt conversion

* delinted

* delinted

* remove water_heater

* fix regression

* Migrate homekit

* Cleanup away mode

* Fix tests

* add helpers

* fix tests melissa

* Fix nehueat

* fix zwave

* add more tests

* fix deconz

* Fix climate test emulate_hue

* fix tests

* fix dyson tests

* fix demo with new layout

* fix honeywell

* Switch homekit_controller to use HVAC_MODE_HEAT_COOL instead of HVAC_MODE_AUTO (#25009)

* Lint

* PyLint

* Pylint

* fix fritzbox tests

* Fix google

* Fix all tests

* Fix lint

* Fix auto for homekit like controler

* Fix lint

* fix lint
2019-07-08 14:00:24 +02:00
Joakim Plate
c2f1c4b981 Correct socket use in cert_expiry platform (#25011)
* Make sure we use same family for ssl socket and connection

getaddrinfo result could be different from what connection
was made with. It also blocks potential use of
happy eye balls algorithm

This also fixes lingering sockets until python garbage
collection.

* Add availability value if unable to get expiry

* Fix lint issue
2019-07-08 11:33:23 +02:00
Seweryn Zeman
31d7b702a6 Added missing yeelight models mapping (#24963) 2019-07-07 23:50:48 -04:00
Joakim Sørensen
df4caf41d0 Install requirements for integrations in packages before importing them. (#25005)
* Process requirements for integrations in packages before loading

* trigger buld
2019-07-07 12:04:30 -07:00
Tom Harris
0595fc3097 Upgrade insteonplm to 0.16.0 and add INSTEON scene triggering (#24765)
* Upgrade insteonplm to 0.16.0 and add INSTEON scene triggering

* Fix spacing issue

* Dummy commit to trigger CLA

* Remove dummy change

* Code review changes

* Use ENTITY_MATCH_ALL keyword from const and lint cleanup

* Make entity method print_aldb private
2019-07-07 20:31:04 +02:00
Tsvi Mostovicz
b0dc782c98 Upgrade hdate==0.8.8 (#25008)
This should fix incosistencies between issur_melacha_in_effect sensor and candle_lighting time.

Probably fixes #24479 and #23852
2019-07-07 17:32:54 +02:00
Daniel Høyer Iversen
ecd7f86df0 upgrade switchmate to latest lib (#25006) 2019-07-07 13:02:13 +02:00
Ville Skyttä
b834671555 Test dependency updates (#25004)
* Upgrade pytest to 5.0.1

https://docs.pytest.org/en/latest/changelog.html#pytest-5-0-1-2019-07-04

* Upgrade asynctest to 0.13.0

* Upgrade requests_mock to 1.6.0
2019-07-07 12:30:31 +02:00
Dave T
6e24b52a7e Add support for aurora ABB Powerone solar photovoltaic inverter (#24809)
* Add support for aurora ABB Powerone solar photovoltaic inverter

* Add support for aurora ABB Powerone solar photovoltaic inverter

* Update stale docstring

* Fixed whitespace lint errors

* Remove test code

* Delete README.md

Website documentation contains setup instructions.  README not needed here.

* Only close the serial line once.

* Correct newlines between imports

* Change add_devices to add_entites and remove unnecessary logging.

* Use new style string formatting instead of concatenation

* Directly access variables rather than via config.get

* Update sensor.py
2019-07-07 11:22:21 +02:00
David Winn
628e12c944 Sleepiq single sleeper crash (#24941)
* Update sleepyq to 0.7

Fixes crash when working with a single sleeper.

* sleepiq: Handle null side definitions

These happen if no sleeper is defined for a side of the bed. Don't
create sensors for null sides; they'll crash every time we try to use
them.

* sleepiq: Fix urls mocked to match sleepyq 0.7

* sleepi: Fix test_sensor.TestSleepIQSensorSetup

Sleepyq 0.7 throws on empty strings, so we have to specify them.

* sleepiq: Test for ValueError thrown by sleepyq 0.7

* sleepiq: Drop no longer used HTTPError import

* sleepiq: Add tests for single sleeper case

* sleepiq: Shorten comments to not overflow line length

* sleepiq: Use formatted string literals for adding suffixes to test files

* sleepiq: Use str.format() for test suffixing
2019-07-07 08:40:02 +02:00
Penny Wood
adbec5bffc Changes as per code review of #24646 (#24917) 2019-07-07 07:36:57 +02:00
Ville Skyttä
e8a5306c23 Upgrade mypy to 0.711, drop no longer needed workarounds (#24998)
https://mypy-lang.blogspot.com/2019/06/mypy-0711-released.html
2019-07-07 03:58:33 +02:00
Franck Nijhof
b274b10f38 Adds Stale Probot for issues (#24985)
* Adds Stale Probot for issues

* Do not ignore assigned issues

* Small language tweak in mark comment
2019-07-06 20:18:20 +02:00
Franck Nijhof
ac4f2c9f73 Adds Lock Threads Probot (#24984) 2019-07-06 19:48:08 +02:00
Paul Annekov
97ed7fbb3f Switched from tuyapy to tuyaha as 1st one is not maintained (#24821) 2019-07-06 10:39:49 -07:00
Robert Dunmire III
003ca655ee Fix errors if rest source becomes unavailable (#24986)
* Fix errors if rest source becomes unavailable

* Remove exclamation mark
2019-07-06 19:33:37 +02:00
Adriaan Peeters
412910ca65 Add sonos.play_queue service (#24974)
* Add sonos.play_queue service

* Add SERVICE_PLAY_QUEUE import in alphabetical order

* Add queue_position parameter for sonos.play_queue service

* Move queue_position default to schema definition
2019-07-06 17:19:03 +02:00
Franck Nijhof
31f569ada9 Batch of Component(s) -> Integration(s) (#24972) 2019-07-05 15:24:26 -07:00
Niels Mündler
e75c9efb3f Fix monitoring of trays in syncthru component (#24961) 2019-07-05 11:23:17 +02:00
cgtobi
e93919673e Implement ADR0003 for Netatmo sensor (#24944)
* Remove configurable monitored conditions

* Only process existing modules

* Remove unused import

* Fix linter error
2019-07-05 09:41:18 +02:00
John Mihalic
c814b39fdb Update pyHik library to 0.2.3 (#24957) 2019-07-05 09:29:35 +02:00
Aaron Bach
a491f97eb9 Allow updating of via_device in device registry (#24921)
* Allow updating of via_device in device registry

* Added test
2019-07-04 19:10:23 -04:00
David F. Mulcahey
3c487928d4 New scanner device tracker and ZHA device tracker support (#24584)
* initial implementation for zha device trackers

* constant

* review comments

* Revert "review comments"

This reverts commit 2130823566820dfc114dbeda08fcdf76ed47a4e7.

* rename device tracker entity

* update trackers

* raise when not implemented

* Update homeassistant/components/device_tracker/config_entry.py

Review comment

Co-Authored-By: Martin Hjelmare <marhje52@kth.se>

* move source type to base state attrs

* review comments

* review comments

* review comments

* fix super call

* fix battery and use last seen from device

* add test

* cleanup and add more to test

* cleanup post zha entity removal PR

* add tests for base entities

* rework entity tests
2019-07-04 12:44:39 +02:00
Steven Rollason
e824c553ca Fix exclusion of routes with excl_filter (#24928)
Fix exclusion of routes with excl_filter (was including instead of excluding)
2019-07-03 19:48:01 -04:00
Chris Soyars
2634f35b4e Add support for Yale YRL256 lock (#24932) 2019-07-03 19:29:21 -04:00
Anders Melchiorsen
a1aaeab33a Update pysonos to 0.0.19 (#24930) 2019-07-03 19:26:16 -04:00
Jeff Irion
e9816f7e30 Bump androidtv to 0.0.18 (#24927)
* Bump androidtv to 0.0.18

* Bump androidtv to 0.0.18
2019-07-03 20:18:37 +02:00
David F. Mulcahey
a9459c6d92 Remove ZHA device entity (#24909)
* move availability handling to device

* update last_seen format

* add battery sensor

* fix interval

* fix battery reporting now that it is a sensor

* remove zha entities and add battery sensor
2019-07-03 13:36:36 -04:00
Дубовик Максим
eec67d8b1a New languages that looks like supported by Google but not documented: (#24881)
* cs-CZ – Czech, Czech Republic
* el-GR – Modern Greek (1453-), Greece
* en-IN – English, India
* fi-FI – Finnish, Finland
* fil-PH – Filipino, Philippines
* hi-IN – Hindi, India
* id-ID – Indonesian, Indonesia
* vi-VN – Vietnamese, Viet Nam
Fixed regex expression to match language codes like fil-PH
2019-07-03 16:40:14 +02:00
cgtobi
e8d9fe0aa8 Fix home coach discovery (#24902)
* Fix home coach discovery

* Update requirements file
2019-07-02 21:55:01 -04:00
Paulus Schoutsen
aa03550f6b Updated frontend to 20190702.0 2019-07-02 10:34:22 -07:00
kreegahbundolo
61c88db8a1 Add ability to send attachments in pushover notifications (#24806)
* Added ability to send attachments in pushover notifications

* Added full name for exception to satisfy static check

* Fixed hanging indent lint problem

* Added path checking, removed import re, changed url check method to use
startswith.

* Removed argument from logging statement.

* Changed IOError to OSError, fixed logging, added logging statement.
2019-07-02 17:56:12 +02:00
Phil Bruckner
8dca73d08e Add missing trigger.for variable to template trigger (#24893) 2019-07-02 17:46:26 +02:00
Phil Bruckner
3f4ce70414 Fix 'same state' monitoring in state trigger (#24904) 2019-07-02 17:29:38 +02:00
Phil Bruckner
945afbc6d4 Fix 'same state' monitoring in numeric_state trigger (#24910) 2019-07-02 17:28:02 +02:00
Anders Melchiorsen
c0a342d790 Stability improvements for Sonos availability (#24880)
* Stability improvements for Sonos availability

* Handle seen reentrancy
2019-07-02 09:25:02 -04:00
Pascal Vizeli
6de6c10bc3 Update devcontainer.json 2019-07-02 14:31:06 +02:00
Pascal Vizeli
6c25c9760a Update devcontainer.json 2019-07-02 13:34:50 +02:00
Pascal Vizeli
7bf140f921 Update devcontainer.json 2019-07-02 13:32:35 +02:00
Phil Bruckner
e3d281b3c4 Bump life360 package to 4.0.1 (#24905) 2019-07-02 12:14:46 +02:00
Pascal Vizeli
0c43c4b5e1 Add git editor / app port 2019-07-02 10:39:02 +02:00
Penny Wood
23dd644f4a Update IDs for rename node/value (#24646)
* Update IDs for rename node/value

* Rename devices and entities

* Improved coverage
2019-07-01 15:54:19 -07:00
David F. Mulcahey
7f90a1cab2 go back to signals and no hard entity references (#24894) 2019-07-01 16:32:57 -04:00
kevank
b6e0f538c5 Update tts.py (#24892) 2019-07-01 10:49:27 -07:00
Dennis Keitzel
8cd138608c Support mqtt discovery topic prefix with slashes (#24840) 2019-07-01 10:23:01 -07:00
David Bonnes
846575b7fb Tweak geniushub battery icons according to device state (#24798)
* tweak battery icons according to device state/availability

* tweak battery icons according to device state/availability 2

* make dt objects aware

* make dt objects aware 2

* woops - use util.dt in favour of datetime

* woops - use util.dt in favour of datetime 2

* refactor battery icon code, remove parallel_updates
2019-07-01 10:19:14 -07:00
Daniel Høyer Iversen
3d2f843c1d Upgrade pytest to 5.0.0 (#24885)
* Upgrade pytest to 5.0.0

* exception message for pytest 5
2019-07-01 10:47:42 -04:00
Jeff Irion
5ba83d4dfb Bump androidtv to 0.0.17 (#24886)
* Bump androidtv to 0.0.17

* Bump androidtv to 0.0.17
2019-07-01 10:47:21 -04:00
Paulus Schoutsen
0dd19ed49c Updated frontend to 20190630.0 2019-06-30 22:53:35 -07:00
Paulus Schoutsen
77b83b9e4d Update translations 2019-06-30 22:53:27 -07:00
Andrew Sayre
7db4eeaf7f Move SmartThings imports to top (#24878)
* Move imports to top

* use lib constants

* Add missing three_axis mapping
2019-06-30 22:29:21 -04:00
David F. Mulcahey
7d651e2b7a Fix traceback during ZHA device removal (#24882)
* fix device remove lifecycle
* clean up remove signal
* add guard
2019-06-30 21:12:27 -04:00
Fabian Affolter
40c424e793 Upgrade bcrypt to 3.1.7 (#24850) 2019-06-30 20:23:47 -04:00
Fabian Affolter
a6ea5d43b4 Upgrade importlib-metadata to 0.18 (#24848) 2019-06-30 20:23:27 -04:00
Maikel Punie
bf70e91a0d Velbus: autodiscover covers (#24877)
* Added covers to the velbus component with autodicovery, bumped python velbus version

* Fixed some pylint stuff
2019-06-30 13:02:07 -07:00
Fabian Affolter
5cf923ead6 Upgrade youtube_dl to 2019.06.27 (#24875) 2019-06-30 13:52:08 -04:00
realthk
fec2461e0e Hungarian is also supported in Google Cloud TTS (#24861)
* Hungarian is also a supported language

* Hungarian is also a supported language

* Hungarian is also a supported language
2019-06-30 13:50:06 -04:00
Fabian Affolter
c71a5643ff Update praw to 6.3.1 (#23737)
* Upgrade praw to 6.3.1

* Update praw to 6.3.1
2019-06-30 16:49:16 +02:00
zewelor
b0387c4428 Fix mysensors icon name (#24871) 2019-06-30 12:15:29 +02:00
Fabian Affolter
1e149a704b Upgrade cryptography to 2.7 (#24852) 2019-06-30 07:21:35 +02:00
Fabian Affolter
cb71b4a657 Upgrade psutil to 5.6.3 (#24854) 2019-06-29 11:40:57 -04:00
Fabian Affolter
26cc41094d Upgrade jinja2 to >=2.10.1 (#24851) 2019-06-29 15:47:22 +02:00
Fabian Affolter
9946b19735 Upgrade pyyaml to 5.1.1 (#24847) 2019-06-29 14:34:55 +02:00
Fabian Affolter
6ad9a97f0d Upgrade certifi to >= 2019.6.16 (#24846) 2019-06-29 14:34:27 +02:00
Fabian Affolter
a91ad0189e Upgrade numpy to 1.16.4 (#24845) 2019-06-29 07:15:32 -04:00
Fabian Affolter
67b6657bcd Upgrade sqlalchemy to 1.3.5 (#24844) 2019-06-29 07:14:47 -04:00
Fabian Affolter
e1a34c8030 Upgrade luftdaten to 0.6.1 (#24842)
* Upgrade luftdaten to 0.6.0

* Upgrade luftdaten to 0.6.1
2019-06-29 11:03:38 +02:00
zewelor
b70f907d25 Fix yeelight color temp getter (#24830)
* Fix yeelight color temp getter

* Remove wrong types
2019-06-28 22:56:11 -07:00
Jonathan Keljo
cde855f67d Upgrade sisyphus-control to 2.2 (#24837)
PR #22457 added some code that used new methods in `sisyphus-control` 2.2.
Unfortunately, because of the move to manifests it was merged still depending
on 2.1.

Fixes #24834
2019-06-28 22:45:57 -07:00
Paulus Schoutsen
9cf43dd8ff Merge pull request #24839 from home-assistant/rc
0.95.4
2019-06-28 22:42:23 -07:00
Phil Bruckner
03e6a92cf3 Add template support to template trigger's for option (#24810) 2019-06-28 22:30:47 -07:00
Paulus Schoutsen
21c2e8da6e Bumped version to 0.95.4 2019-06-28 22:23:22 -07:00
Paulus Schoutsen
b3963e56ec Guard for None entity config (#24838) 2019-06-28 22:23:17 -07:00
zewelor
c6e8e2398c Improve autodiscovered yeelights model detection (#24671)
* Improve autodiscovered yeelights model detection

* Lint fixes

* Logger warn fix
2019-06-28 22:23:17 -07:00
Paulus Schoutsen
4b5718431d Guard for None entity config (#24838) 2019-06-28 22:23:00 -07:00
Niels Mündler
333e1d6789 Fronius (solar energy and inverter) component (#22316)
* Introduced fronius component that adds ability to track Fronius devices from Home Assistant

* Use device parameter for fetching inverter data

* Fixed handling of default scope

* Handle exceptions from yield

* Fulfill PR requirements

* Fixed houndci violations

* Found the last hound violation

* Fixed docstring (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165776934)

* Fixed import order with isort (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165776957)

* CONF_DEVICE is now CONF_DEVICEID (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165777161)

* Added docstring to class FroniusSensor (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165777792)

* Fixed docstring for state (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165777885)

* Added/fixed docstrings (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165778108 & https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165778125)

* Remove redundant log entry (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165779213)

* Fixed error message if sensor update fails (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165779435)

* Fixed error log messages (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165779751 & https://github.com/home-assistant/home-assistant/pull/11446#discussion_r165779761)

* Satisfy hound

* Handle exceptions explicit (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r168940902)

* Removed unnecessary call of update (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r168940894)

* The point makes the difference.

* Removed unrelated requirements

* Remove config logging (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r168968748)

* Reorder and fix imports (https://github.com/home-assistant/home-assistant/pull/11446#discussion_r168968725, https://github.com/home-assistant/home-assistant/pull/11446#discussion_r168968691)

* Update fronius requirement

* Various small fixes

* Small fixes

* Formatting

* Add fronius to coverage

* New structure and formatting

* Add manifest.json

* Fix data loading

* Make pylint happy

* Fix issues

* Fix parse_attributes

* Fix docstring and platform schema

* Make use of default HA-Const config values

* Change configuration setup, introducing list of monitored conditions

* Change the structure slightly, allowing for a list of sensors

* Remove periods from logging

* Formatting

* Change name generation, use variable instead of string

* small fixes

* Update sensor.py

* Incorporate correction proposals

* Setting default device inside validation

* Move import on top and small format

* Formatting fix

* Rename validation method to _device_id_validator
2019-06-28 20:48:52 -07:00
Paulus Schoutsen
2e9c71f2c0 Merge pull request #24836 from home-assistant/rc
0.95.3
2019-06-28 20:45:21 -07:00
Paulus Schoutsen
072879cc6e Bumped version to 0.95.3 2019-06-28 20:44:23 -07:00
Paulus Schoutsen
cc75adfed6 Alexa sync state report (#24835)
* Do a sync after changing state reporting

* Fix entity config being None
2019-06-28 20:44:19 -07:00
Paulus Schoutsen
3cafc1f2c6 Alexa sync state report (#24835)
* Do a sync after changing state reporting

* Fix entity config being None
2019-06-28 20:43:57 -07:00
Aaron Bach
19a65f8db6 Remove temperature attribute from SimpliSafe alarm control panel (#24833) 2019-06-28 20:38:07 -07:00
Paulus Schoutsen
e8d1d28fdd Make sure alert is set up after notify (#24829) 2019-06-28 16:28:33 -06:00
Pascal Vizeli
9ad063ce03 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-28 22:55:04 +02:00
Paulus Schoutsen
f67693c56c Fix vacuum tests 2019-06-28 13:41:25 -07:00
Pascal Vizeli
9616fbdc36 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-28 22:31:27 +02:00
Pascal Vizeli
48dd5af9e3 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-28 22:18:52 +02:00
Pascal Vizeli
bc0fb5e3d9 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-28 22:08:29 +02:00
Pascal Vizeli
8e2bbf8c82 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-28 19:38:13 +02:00
Pascal Vizeli
538caafac2 Full speed azure 2019-06-28 17:35:17 +00:00
Paulus Schoutsen
0871d6c9c6 Merge pull request #24828 from home-assistant/rc
0.95.2
2019-06-28 10:30:01 -07:00
Luuk
468b0e8934 Add template vacuum support (#22904)
* Add template vacuum component

* Fix linting issues

* Make vacuum state optional

* Fix pylint issues

* Add context to template vacuum service calls

* Added tests to template vacuum

* Fix indent

* Fix docstrings

* Move files for new component folder structure

* Revert additions for template_vacuum tests to common.py

* Use existing constants for template vacuum config

* Handle invalid templates

* Add tests for unused services

* Add test for invalid templates

* Fix line too long

* Do not start template change tracking in case of MATCH_ALL

* Resolve review comments
2019-06-28 12:19:00 -04:00
Paulus Schoutsen
6cbfc63311 Bumped version to 0.95.2 2019-06-28 08:50:23 -07:00
Paulus Schoutsen
2886b217ab Fix calling empty script turn off (#24827) 2019-06-28 08:50:16 -07:00
Phil Bruckner
fafc68673a Fix another Life360 bug (#24805) 2019-06-28 08:50:16 -07:00
David F. Mulcahey
1990df63aa Bump ZHA quirks module (#24802)
* bump quirks version

* bump version - mija magnet
2019-06-28 08:50:15 -07:00
Paulus Schoutsen
e39f0f3e25 Make sure entity config is never none (#24801) 2019-06-28 08:50:14 -07:00
Pascal Vizeli
1f5e2fa3ce Update azure-pipelines-release.yml for Azure Pipelines (#24800) 2019-06-28 08:50:14 -07:00
cgtobi
204dd77404 Fix netatmo weatherstation setup error (#24788)
* Check if station data exists and reduce calls

* Fix module names list

* Add warning

* Remove dead code
2019-06-28 08:50:13 -07:00
Paulus Schoutsen
4e5b1ccde6 Fix calling empty script turn off (#24827) 2019-06-28 08:49:33 -07:00
Paulus Schoutsen
80844ae2ee Add developer tools panel (#24812) 2019-06-28 08:34:53 -07:00
cgtobi
a69a00785f Fix netatmo weatherstation setup error (#24788)
* Check if station data exists and reduce calls

* Fix module names list

* Add warning

* Remove dead code
2019-06-27 20:16:46 -07:00
Tejpal Sahota
41dd70f644 Changed default encoding to mp3 (#24808) 2019-06-27 20:16:22 -07:00
Paulus Schoutsen
e5b8d5f7ea Updated frontend to 20190627.0 2019-06-27 17:57:02 -07:00
Josh Anderson
c49869160b Use step from tado rather than assuming 0.1 (#24807) 2019-06-27 16:17:15 -07:00
Josh Anderson
69089da88e Use climate device's target temp step value (#24804) 2019-06-27 15:14:23 -07:00
Phil Bruckner
e43a733017 Fix another Life360 bug (#24805) 2019-06-27 15:11:32 -07:00
dreed47
3eb6b9d297 Zestimate fix for issue #23837 (#23838)
* Zestimate fix for issue #23837

removed references to MIN_TIME_BETWEEN_UPDATES
and replaced with SCAN_INTERVAL

* Zestimate fix for issue #23837

removed references to MIN_TIME_BETWEEN_UPDATES
and replaced with SCAN_INTERVAL
2019-06-27 15:09:33 -07:00
David F. Mulcahey
ac5ab52d01 Bump ZHA quirks module (#24802)
* bump quirks version

* bump version - mija magnet
2019-06-27 15:28:56 -04:00
Paulus Schoutsen
0d89b82bff Make sure entity config is never none (#24801) 2019-06-27 15:17:42 -04:00
Pascal Vizeli
0cde24e103 Update azure-pipelines-release.yml for Azure Pipelines (#24800) 2019-06-27 18:26:13 +02:00
Paulus Schoutsen
5598f05dee Merge pull request #24787 from home-assistant/rc
0.95.1
2019-06-27 08:55:10 -07:00
h3ndrik
e932fc832c Add time delta option when searching for deutsche_bahn connections (#24600)
* Add time delta option when searching for connections

Add another option 'in' to search for upcoming connections in the future.
Handy if you need a few minutes to get to the train station and need to add that to the queried departure time.

* correct style errors

* rename new option

* rename new option (2/2)

* add offset correctly
2019-06-27 15:53:05 +02:00
Paulus Schoutsen
01b6830fd2 Bumped version to 0.95.1 2019-06-26 21:25:33 -07:00
Paulus Schoutsen
c1d0ac7b9d Catch uncaught Alexa error (#24785) 2019-06-26 20:24:52 -07:00
William Scanlon
dce667fa07 Pubnub to 1.0.8 (#24781) 2019-06-26 20:24:52 -07:00
Phil Bruckner
a78361341e Fix life360 exception when no location provided (#24777) 2019-06-26 20:24:51 -07:00
Paulus Schoutsen
c87d6e4720 Catch uncaught Alexa error (#24785) 2019-06-26 20:24:20 -07:00
Ville Skyttä
71346760d0 Upgrade pytest to 4.6.3 (#24782)
* Upgrade pytest to 4.6.3

https://docs.pytest.org/en/latest/changelog.html#pytest-4-6-2-2019-06-03
https://docs.pytest.org/en/latest/changelog.html#pytest-4-6-3-2019-06-11

* Make litejet switch test work with pytest 4.6.3

Essentially reverts the corresponing change that was made for pytest
4.2 compatibility.
2019-06-26 20:01:03 -07:00
William Scanlon
f6c1f336d4 Pubnub to 1.0.8 (#24781) 2019-06-26 16:14:00 -07:00
Phil Bruckner
638c958acd Fix life360 exception when no location provided (#24777) 2019-06-26 16:03:11 -07:00
Paulus Schoutsen
b2231945dc Merge branch 'master' into dev 2019-06-26 10:42:25 -07:00
Paulus Schoutsen
4dbfafa8ca Merge pull request #24776 from home-assistant/rc
0.95.0
2019-06-26 10:41:11 -07:00
Andre Richter
56b8da133c Upgrade vallox to async client API (#24774) 2019-06-26 18:40:34 +02:00
Paulus Schoutsen
06af6f19a3 Entity to handle updates via events (#24733)
* Entity to handle updates via events

* Fix a bug

* Update entity.py
2019-06-26 09:22:51 -07:00
Paulus Schoutsen
5f37852695 Bumped version to 0.95.0 2019-06-26 09:17:45 -07:00
Daniel Høyer Iversen
5fe8a43e36 Return correct name for met.no (#24763) 2019-06-26 09:17:35 -07:00
Paulus Schoutsen
760b62e068 Ignore duplicate tradfri discovery (#24759)
* Ignore duplicate tradfri discovery

* Update name
2019-06-26 09:17:35 -07:00
John Dyer
9205334235 Update Waze route dependency to 0.10 (#24754)
* Update manifest.json

Update waze calculator to 0.10, this was supposed to have been done in #22428 but was missed. See discussion [here](https://community.home-assistant.io/t/waze-travel-time-update/50955/201)

* Update requirements_all.txt
2019-06-26 09:17:34 -07:00
cgtobi
ca4c6ffe8d Handle timeouts gracefully (#24752) 2019-06-26 09:17:33 -07:00
cgtobi
b47b555c4f Bump pyatmo to v2.1.0 (#24724) 2019-06-26 09:17:33 -07:00
Paulus Schoutsen
5d2f97de74 Updated frontend to 20190626.0 2019-06-26 09:16:04 -07:00
Paulus Schoutsen
9e0636eefa Updated frontend to 20190626.0 2019-06-26 09:15:54 -07:00
Alexei Chetroi
6ae1228e61 Enhancement/zha model manuf (#24771)
* Cleanup ZHA entities model and manufacturer usage.
Zigpy includes manufacturer and model as attributes of a zigpy
Device class, which simplifies handling of manufacturer and/or model
derived properties for the ZHA platform.

* Sort ZHA imports.
* Lint.
2019-06-26 09:31:19 -04:00
Matte23
29311e6391 Add support for IPP Printers to the CUPS integration (#24756)
* Add support for IPP Printers to the CUPS integration

* Fixed lint error

* Addressed comments, removed redundant check

* Simplified check, improved code readability
2019-06-25 16:13:08 -07:00
John Dyer
bd4f66fda3 Update Waze route dependency to 0.10 (#24754)
* Update manifest.json

Update waze calculator to 0.10, this was supposed to have been done in #22428 but was missed. See discussion [here](https://community.home-assistant.io/t/waze-travel-time-update/50955/201)

* Update requirements_all.txt
2019-06-25 15:25:53 -07:00
Daniel Høyer Iversen
dc89499116 Return correct name for met.no (#24763) 2019-06-25 13:09:04 -07:00
Alain Tavan
41b58b8bc1 fix an error in the description (#24735) 2019-06-25 10:37:25 -07:00
Emilv2
58df05a7e7 Remove obsolete comments in Dockerfile (#24748)
relevant lines were removed in e49b970665
2019-06-25 10:16:05 -07:00
Andre Richter
fb940e4269 Vallox: Fix missing hass member (#24753) 2019-06-25 10:15:41 -07:00
Paulus Schoutsen
26fc57d1b3 Ignore duplicate tradfri discovery (#24759)
* Ignore duplicate tradfri discovery

* Update name
2019-06-25 09:54:40 -07:00
cgtobi
da57f92796 Handle timeouts gracefully (#24752) 2019-06-25 08:57:43 -07:00
Andre Richter
236820d093 Add integration for Vallox Ventilation Units (#24660)
* Add integration for Vallox Ventilation Units.

* Address review comments #1

* Address review comments #2

* Replace IOError with OSError.

* Bump to fixed version of vallox_websocket_api.
2019-06-25 11:38:24 +02:00
Paulus Schoutsen
87712b9fa5 Bumped version to 0.95.0b4 2019-06-24 22:23:41 -07:00
Paulus Schoutsen
510d6d7874 Improve Alexa error handling (#24745) 2019-06-24 22:08:15 -07:00
Martin Hjelmare
8830054fad Fix locative device update (#24744)
* Add a test for two devices

* Fix locative updating all devices

* Add a guard clause that checks if correct device is passed.
2019-06-24 22:08:14 -07:00
Paulus Schoutsen
327fe63047 Clean up Google Config (#24663)
* Clean up Google Config

* Lint

* pylint

* pylint2
2019-06-24 22:08:13 -07:00
Paulus Schoutsen
0f5c9b4af3 Updated frontend to 20190624.1 2019-06-24 22:07:50 -07:00
Paulus Schoutsen
9813396880 Updated frontend to 20190624.1 2019-06-24 22:07:39 -07:00
Paulus Schoutsen
f5f86993f1 Improve Alexa error handling (#24745) 2019-06-24 22:04:31 -07:00
Martin Hjelmare
d4fc22add4 Fix locative device update (#24744)
* Add a test for two devices

* Fix locative updating all devices

* Add a guard clause that checks if correct device is passed.
2019-06-24 20:00:28 -07:00
Paulus Schoutsen
d699a550c8 Bumped version to 0.95.0b3 2019-06-24 15:01:17 -07:00
Anders Melchiorsen
f71d4312e2 Update pysonos to 0.0.17 (#24740) 2019-06-24 15:00:11 -07:00
Paulus Schoutsen
ec777a802c AdGuard to update entry (#24737) 2019-06-24 15:00:10 -07:00
Alexei Chetroi
82cad58b8d Update ZHA dependencies. (#24736) 2019-06-24 15:00:09 -07:00
Evan Bruhn
34231383ec Save cached logi_circle tokens in config folder (#24726)
Instead of the working directory, which it's doing currently. Matches pattern observed on Abode, Ring, Skybell integrations.
2019-06-24 15:00:08 -07:00
Anders Melchiorsen
6e14e8ed91 Update pysonos to 0.0.17 (#24740) 2019-06-24 14:59:15 -07:00
Paulus Schoutsen
4aedd3a09a AdGuard to update entry (#24737) 2019-06-24 14:46:32 -07:00
Alexei Chetroi
26dea0f247 Update ZHA dependencies. (#24736) 2019-06-24 16:57:07 -04:00
Conrad Juhl Andersen
0792e72f71 Add support for sensor state STATE_UNAVAILABLE (#24641)
* Fixed integration with ESPhome, which caused an error if ESPhome did not update fast enough on startup

* Set state to problem if sensor is unavailable

* Fix line length.
2019-06-24 11:30:44 -07:00
David F. Mulcahey
d9420c1f73 Remove device and entity registry entries when removing a ZHA device (#24369)
* cleanup when device is removed

fixes

* cleanup
2019-06-24 11:26:44 -07:00
Evan Bruhn
ee1884423a Save cached logi_circle tokens in config folder (#24726)
Instead of the working directory, which it's doing currently. Matches pattern observed on Abode, Ring, Skybell integrations.
2019-06-24 09:36:39 -07:00
Robin Wohlers-Reichel
17480a0398 Add 'unique_id' Property to Inverter Sensors (#24707)
* Option to change sensor names

* Python 3.5 compatibility

* Oops

* Get serial number at start

* Remove config opportunity

* Oops comma

* Changes from review

* Check yourself before you commit.
2019-06-24 08:34:20 -07:00
Paulus Schoutsen
75ec855822 Bumped version to 0.95.0b2 2019-06-24 08:33:21 -07:00
Phil Bruckner
2c5080e382 Add show_as_state options to Life360 (#24725) 2019-06-24 08:33:14 -07:00
David F. Mulcahey
48e9742658 Update ZHA dependencies (#24718)
* update deps and remove legacy constants bridge

* run deps script and fix test import
2019-06-24 08:33:13 -07:00
Oleg Kurapov
14b62120fd Extend websocket method usage to port 8002 in Samsung TV media player (#24716) 2019-06-24 08:33:12 -07:00
cgtobi
4a8149627e Bump version pyatmo to 2.0.1 (#24703) 2019-06-24 08:33:11 -07:00
David F. Mulcahey
9c85ba5b66 ZHA fix device type mappings (#24699) 2019-06-24 08:33:11 -07:00
Anders Melchiorsen
fb0cb43261 Fix time expression parsing (#24696) 2019-06-24 08:33:10 -07:00
Thomas Lovén
23722dc291 Allow extra js modules to be included in frontend (#24675)
* Add extra_module_url and extra_module_url_es5 to frontend options

* Address review comments
2019-06-24 08:33:09 -07:00
Paulus Schoutsen
e841f568c1 Update translations 2019-06-24 08:27:46 -07:00
Paulus Schoutsen
9b096322e1 Updated frontend to 20190624.0 2019-06-24 08:27:04 -07:00
Paulus Schoutsen
df32a81165 Updated frontend to 20190624.0 2019-06-24 08:26:50 -07:00
Phil Bruckner
8924d657a4 Add show_as_state options to Life360 (#24725) 2019-06-24 08:05:34 -07:00
endor
98ba529ead Add Trafikverket train component (#23470)
* Added Trafikverket train component

* Updated manifest with proper name and codeowner

* Updated requirements and manifest

* Updated CODEOWNERS

* Corrected requirements

* Added trafikverket_train/sensor.py to .coveragerc

* Added error handling and log if API call fails

* Corrected styles, removed dev log, improved validation

* Method calls to async_update(), improved error handling

* Minor cleanup/reorg for effeciency

* Added station cache and corrected to fit standards

* Simplified trainstop id  and cleaned up dict.get

* Corrected mistake after change from dict to array

* Change device class to timestamp
2019-06-24 10:38:50 +02:00
cgtobi
9a01cd84c2 Bump pyatmo to v2.1.0 (#24724) 2019-06-24 07:43:49 +02:00
John Luetke
09c6f57364 Expose ports 8123, 8300 and 51827 in Dockerfile (#24389) 2019-06-23 21:44:26 +02:00
Pascal Vizeli
a807572382 Add initial support for remote dev container (#24681)
* Add initial support for remote container

* Use constrain
2019-06-23 12:18:33 -07:00
Oleg Kurapov
dc6a44d0eb Extend websocket method usage to port 8002 in Samsung TV media player (#24716) 2019-06-23 12:11:25 -07:00
Paulus Schoutsen
c296e9b9bb Update owner stream integration 2019-06-23 12:00:06 -07:00
David F. Mulcahey
d22bb8fc7d Update ZHA dependencies (#24718)
* update deps and remove legacy constants bridge

* run deps script and fix test import
2019-06-23 13:43:19 -04:00
ktnrg45
b99275f6a5 Fix PS4 entities with shared host not updating and latency with multiple connections (#24642)
* correct assume info call

* 0.8.4

* 0.8.4

* 0.8.4

* 0.8.5

* 0.8.5

* 0.8.5

* revert condition
2019-06-23 09:52:53 -06:00
Robin Wohlers-Reichel
57502bc911 Solax update 0.1.0 (#24708)
* Update to solax 0.0.6

* Library version 0.1.0
2019-06-23 11:16:39 +02:00
cgtobi
128e66fa24 Bump version pyatmo to 2.0.1 (#24703) 2019-06-23 07:50:04 +02:00
Fabian Affolter
0132ac3c27 Upgrade Sphinx to 2.1.2 (#24693) 2019-06-23 07:49:40 +02:00
David F. Mulcahey
cfd8d70890 ZHA fix device type mappings (#24699) 2019-06-22 15:05:35 -04:00
Fabian Affolter
44d2871dc9 Upgrade youtube_dl to 2019.06.08 (#24692) 2019-06-22 14:45:39 +02:00
Fabian Affolter
821e3beab0 Upgrade discord.py to 1.2.2 (#24695) 2019-06-22 14:44:24 +02:00
Anders Melchiorsen
a439e087e1 Fix time expression parsing (#24696) 2019-06-22 13:39:33 +02:00
Andre Lengwenus
b8acbf3c3a Corrected number of default LCN segment coupler scan tryouts (#24678)
* Bump to pypck==0.6.2

* Set default segment coupler scan tryouts to 0
2019-06-22 13:27:41 +02:00
Jonathan
d25214beb1 Add aml_thermal label (#24665)
Added label for the CPU Temperature for AmLogic ARM chips.
2019-06-22 12:58:37 +02:00
Penny Wood
22d9bee41a Template: Expand method to expand groups, and closest as filter (#23691)
* Implement expand method

* Allow expand and closest to be used as filters

* Correct patch

* Addresses review comments
2019-06-22 00:32:32 -07:00
Ville Skyttä
a6eef22fbc Upgrade mypy to 0.710 (#24666)
* Upgrade mypy to 0.710

* Address mypy 0.710 errors
2019-06-22 10:19:36 +03:00
Steven Looman
f189367c02 Upgrade to async_upnp_client==0.14.10 and increase search timeout (#24685) 2019-06-22 09:12:27 +02:00
Aaron Bach
40fa4463de Change Ambient solar radiation units to lx (#24690) 2019-06-21 23:12:16 -06:00
Aaron Bach
729df112a7 Add RainMachine device classes where appropriate (#24682) 2019-06-21 17:12:28 -06:00
Thomas Lovén
9b52b9bf66 Allow extra js modules to be included in frontend (#24675)
* Add extra_module_url and extra_module_url_es5 to frontend options

* Address review comments
2019-06-21 13:16:28 -07:00
zewelor
c6d5a5a6cc Improve autodiscovered yeelights model detection (#24671)
* Improve autodiscovered yeelights model detection

* Lint fixes

* Logger warn fix
2019-06-21 15:50:25 -04:00
Pascal Vizeli
7f169e97ca Update azure-pipelines-release.yml for Azure Pipelines 2019-06-21 20:08:19 +02:00
Pascal Vizeli
560161bdbb Update azure-pipelines-release.yml for Azure Pipelines 2019-06-21 20:08:06 +02:00
Paulus Schoutsen
1761a71338 Bumped version to 0.95.0b1 2019-06-21 09:27:58 -07:00
Aaron Bach
3da3612c7b Add device class support for Ambient PWS sensors (#24677) 2019-06-21 10:27:53 -06:00
Pascal Vizeli
198432f222 Prefere binary with wheels (#24669) 2019-06-21 09:27:41 -07:00
Andrew Sayre
a868685ac9 Bump pysmartthings (#24659) 2019-06-21 09:27:41 -07:00
Paulus Schoutsen
d4cab60343 Warn when user tries run custom config flow (#24657) 2019-06-21 09:27:40 -07:00
Kevin Fronczak
da12ceae5b Upgrade blinkpy==0.14.1 for startup bugfix (#24656) 2019-06-21 09:27:39 -07:00
Anders Melchiorsen
79b10612aa Update LIFX brightness during long transitions (#24653) 2019-06-21 09:27:39 -07:00
Alexei Chetroi
d5edbb424a Bump ZHA dependencies. (#24637) 2019-06-21 09:27:38 -07:00
Martin Hjelmare
d527e2c926 Fix device tracker see for entity registry entities (#24633)
* Add a test for see service gaurd

* Guard from seeing devices part of entity registry

* Await registry task early

* Lint

* Correct comment

* Clean up wait for registry

* Fix spelling

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>

* Fix spelling

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>
2019-06-21 09:27:37 -07:00
Rodrigo Pérez
b899dd59c5 Vlc telnet (#24290)
* Vlc telnet first commit

First functional version, remains to add more functionality.

* New functions added and bugfixes

* Compliance with dev checklist

* Compliance with dev checklist

* Compliance with pydocstyle

* Removed unused import

* Fixed wrong reference for exception

* Module renamed

* Fixed module rename in other

* Fixed wrong reference for exception


Module renamed


Fixed module rename in other

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Suggestions by @OttoWinter

+Manage error when the VLC dissapears to show status unavailable.

* Removed error log, instead set unavailable state

* Changes suggested by @pvizeli

-Import location
-Use of constants

* Implemented available method

* Improved available method
2019-06-21 09:27:36 -07:00
Paulus Schoutsen
8f928982e0 Updated frontend to 20190620.0 2019-06-21 09:27:23 -07:00
Paulus Schoutsen
8f243ad59d Updated frontend to 20190620.0 2019-06-21 09:27:02 -07:00
Pascal Vizeli
c9453bab19 Prefere binary with wheels (#24669) 2019-06-21 08:47:56 -07:00
Paulus Schoutsen
78b7ed0ebe Clean up Google Config (#24663)
* Clean up Google Config

* Lint

* pylint

* pylint2
2019-06-21 11:17:21 +02:00
Rodrigo Pérez
d468d0f71b Vlc telnet (#24290)
* Vlc telnet first commit

First functional version, remains to add more functionality.

* New functions added and bugfixes

* Compliance with dev checklist

* Compliance with dev checklist

* Compliance with pydocstyle

* Removed unused import

* Fixed wrong reference for exception

* Module renamed

* Fixed module rename in other

* Fixed wrong reference for exception


Module renamed


Fixed module rename in other

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/vlc_telnet/media_player.py

Accepted suggestion by @OttoWinter

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Suggestions by @OttoWinter

+Manage error when the VLC dissapears to show status unavailable.

* Removed error log, instead set unavailable state

* Changes suggested by @pvizeli

-Import location
-Use of constants

* Implemented available method

* Improved available method
2019-06-21 11:13:47 +02:00
Pascal Vizeli
6bc636c2f2 Update azure-pipelines-wheels.yml for Azure Pipelines 2019-06-21 11:07:42 +02:00
mvn23
43a6be6471 Multiple devices support for opentherm_gw (#22932)
* Breaking change: Rewrite opentherm_gw to add support for more than one OpenTherm Gateway.
Breaks config layout and child entity ids and adds a required parameter to all service calls (gateway_id).

* Add schema and parameter description for service opentherm_gw.reset_gateway.

* Add optional name attribute in config to be used for friendly names.
Fix bugs in binary_sensor and climate platforms.

* pylint fixes

* Remove unused variables.

* Update manifest.json, remove REQUIREMENTS from .py file

* Update CODEOWNERS

* Address issues that were brought up (requested changes):
- Move imports to module level
- Change certain functions from async to sync
- Move constants to const.py (new file)
- Call gateway setup from outside of __init__()
- Move validation of monitored_variables to config schema

* Address requested changes:
- Make module imports relative
- Move more functions from async to sync, decorate with @callback where necessary
- Remove monitored_variables option, add all sensors by default
2019-06-21 10:52:25 +02:00
Pascal Vizeli
d9f2a406f6 Update azure-pipelines-wheels.yml for Azure Pipelines 2019-06-21 10:46:35 +02:00
sfjes
0bdbf007b2 Fix downloader_download_failed event not firing for HTTP response errors (#24640) 2019-06-20 13:59:17 -07:00
Ville Skyttä
f1cbb2a0b3 braviatv, nmap_tracker: use getmac for getting MAC addresses (#24628)
* braviatv, nmap_tracker: use getmac for getting MAC addresses

Refs https://github.com/home-assistant/home-assistant/pull/24601

* Move getmac imports to top level
2019-06-20 23:35:02 +03:00
foreign-sub
ecfbfb4527 Fix AttributeError: 'NoneType' object has no attribute 'group' with sytadin component (#24652)
* Fix AttributeError: 'NoneType' object has no attribute 'group'

* Update sensor.py
2019-06-20 13:28:39 -07:00
Andrew Sayre
d8690f426c Bump pysmartthings (#24659) 2019-06-20 13:25:32 -07:00
Anders Melchiorsen
39f2e49451 Update LIFX brightness during long transitions (#24653) 2019-06-20 13:24:45 -07:00
Kevin Fronczak
58f14c5fe2 Upgrade blinkpy==0.14.1 for startup bugfix (#24656) 2019-06-20 13:24:02 -07:00
Paulus Schoutsen
319ac23736 Warn when user tries run custom config flow (#24657) 2019-06-20 13:22:12 -07:00
Alexei Chetroi
86e50530b0 Bump ZHA dependencies. (#24637) 2019-06-19 22:32:31 -04:00
Martin Hjelmare
7881081207 Fix device tracker see for entity registry entities (#24633)
* Add a test for see service gaurd

* Guard from seeing devices part of entity registry

* Await registry task early

* Lint

* Correct comment

* Clean up wait for registry

* Fix spelling

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>

* Fix spelling

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>
2019-06-20 03:22:33 +02:00
Paulus Schoutsen
8623294fcd Bumped version to 0.95.0b0 2019-06-19 16:37:53 -07:00
Paulus Schoutsen
76537a7f41 Merge remote-tracking branch 'origin/master' into dev 2019-06-19 16:37:28 -07:00
Paulus Schoutsen
d85ae5dcae Merge pull request #24636 from home-assistant/rc
0.94.4
2019-06-19 16:36:04 -07:00
Paulus Schoutsen
4e0683565d Bumped version to 0.94.4 2019-06-19 16:33:27 -07:00
Penny Wood
4d6c07f18a Fixed issue #24335 (#24612) 2019-06-19 16:33:11 -07:00
Otto Winter
b0c68e0ea7 Fix zeroconf migration messing up ESPHome discovery (#24578) 2019-06-19 16:33:10 -07:00
Robert Van Gorkom
2858f56d4d Fixing tplink issues with offline devices during setup (#23668)
* Fixing tplink issues with offline devices during setup.

* Fixing circleci errors.

* Adding code to defer the creation of entities that are not online.

* Addressing code review changes and cleaning up a little.

* Fixing tests and static analysis.

* Adding test to satisfy coverage requirements.

* Resolving merge conflicts.

* Fixing issue where lights don't appear in the integration page.

* Using pyHS100 properties for most sysinfo.
Addressing some PR feedback.

* Addressing some PR feedback.

* Better testing async_add_entities_retry
Testing for static dimmers.
Making greater use of conf constants.

* Fixing all static analysis issues.

* Adding non-blocking call for getting discovering devices.

* Address PR feedback
2019-06-19 16:33:09 -07:00
Paulus Schoutsen
c5d443a710 Update translations 2019-06-19 16:22:13 -07:00
Paulus Schoutsen
96af0cffc8 Updated frontend to 20190619.0 2019-06-19 16:21:54 -07:00
Paulus Schoutsen
114af8e24b Add missing init file 2019-06-19 15:58:39 -07:00
majuss
14752baf27 Added ELV PCA 301 smart emeter switch (#23300)
* added pca

* removed req from py

* try to fix codeowners

* redo req

* ran codeowners

* processed comments

* fix style

* fix style

* fix style

* Set availalbe to False when communication fails.
2019-06-19 15:41:43 -07:00
Paulus Schoutsen
f2962a0d16 Set up Met during onboarding (#24622)
* Set up Met during onboarding

* Lint

* Add pyMetNo to test reqs
2019-06-19 14:41:27 -07:00
Oncleben31
6ea92f86a5 Add weather alert sensor to meteo france component (#23128)
* Quick & Dirty weather alert integration

* Add attributes in weather alert sensor.

* MeteoFranceUpdate returns dept to init the alert watcher

* add rain forecast to weather attribute

* Add checks when no weather alert data are available

* Improve date and state when online source is unreachable

* update to take into account new API of vigilancemeteo 3.0.0

* Clean local patchs and put requirements in manfiest.json

* Use only one proxy for weather alerts to avoid too much HTTP requests

* linting and comments style corrections

* Add error catching and debug logging

* Correction following PR checklist

 * Add code owners
 * Update requirements_all.txt

* Comment style

* Update CODEOWNERS after rebaseline with dev branch

* update requirements_all.txt
2019-06-19 14:39:13 -07:00
Johan Nenzén
55997c74b0 Uses signal dispatcher to invoke state update (#24627) 2019-06-19 17:26:08 -04:00
Paulus Schoutsen
4e066f4681 Fix sending update when not logged in (#24624)
* Fix sending update when not logged in

* Fix test
2019-06-19 13:58:00 -07:00
Javier González Calleja
dbc4f285f1 Tolerance configuration for dlib_face_identify (#24497)
* Adding tolerance configuration support for dlib_face_identify component

* Fix tolerance parameter

* Fix static-check

* Fix flake8 check

* Fix circleci tests

* Changes for improve maintainability

* Change type of confidence option
2019-06-19 13:54:24 -07:00
Tor Arne Vestbø
f5da0e341c tellstick: Add socat to package dependencies (#24531)
Otherwise the tellstick component will fail when used with a
remote host running tellcore-net.

Fixes #24113
2019-06-19 09:23:29 -07:00
Pascal Vizeli
21c96fa76c Add support for opencv wheels (#24620) 2019-06-19 09:23:05 -07:00
David Bonnes
c1d441b0ac Add incomfort sensor and binary_sensor (#23812)
* Initial commit - add sensors to incomfort

* improve temp heuristics

* remove self._hass

* device_state_attributes shoudln't be None

* bump client

* refactor to reduce duplication of attributes

* refactor binary_sensor to simplify

* refactor binary_sensor to simplify 2

* delint

* fix rebase regression

* small refactor

* delint

* remove DEVICE_CLASS for CV pressure

* tidy up exception handling

* delint

* fix exception handling

* use differnt icon for boiler temp
2019-06-19 09:03:18 -07:00
Penny Wood
d63c44f778 Fixed issue #24335 (#24612) 2019-06-19 07:25:15 -07:00
Malte Franken
03bb3d9ddc Queensland bushfire alert feed platform (#24473)
* initial version of qfes bushfire geolocation platform

* removed all occurrences of legally protected names; using new georss library

* regenerated codeowners

* fixed pylint

* added one more valid category

* moved library import to top and ran isort
2019-06-19 07:59:29 -04:00
Daniel Høyer Iversen
9413b5a415 check for None state in broadlink (#24589) 2019-06-19 10:10:37 +02:00
Anders Melchiorsen
08e2959742 Update pysonos to 0.0.16 (#24607) 2019-06-19 10:09:50 +02:00
Paulus Schoutsen
6d9f1b3fd3 Notify Alexa when exposed entities change (#24609) 2019-06-19 10:06:28 +02:00
Aaron Bach
a89c8eeabe Add config entry for Met.no (#24608)
* Add config entry for Met.no

* Fixed tests
2019-06-18 17:44:41 -06:00
Paulus Schoutsen
f382be4c15 Cloud: Make sure on_connect forwards platform only once (#24582)
* Make sure on_connect forwards platform only once

* Make sure right handler
2019-06-18 13:59:40 -07:00
Paulus Schoutsen
ca70b96005 Update translations 2019-06-18 11:54:56 -07:00
Paulus Schoutsen
37602647aa Updated frontend to 20190618.0 2019-06-18 11:54:38 -07:00
Andre Lengwenus
d22c3f13b2 Fix validator for lcn.send_keys service (#24580)
* Fix validator for lcn.send_keys service

* Removed lowercase table names from send_keys and lock_keys validators

* Revert lowercase regex.

* Fixed table name regex.
2019-06-18 09:04:36 -07:00
Otto Winter
024ce0e8eb Add ESPHome event generation and user-defined service array support (#24595)
* Add ESPHome event generation and user-defined service array support

* Comments

* Lint
2019-06-18 17:43:11 +02:00
Otto Winter
ee5540f351 ESPHome load platforms lazily (#24594) 2019-06-18 17:41:45 +02:00
Otto Winter
e669e1e2bf ESPHome config flow only connect when needed (#24593)
* ESPHome config flow only connect when needed

* Lint
2019-06-18 17:41:21 +02:00
David F. Mulcahey
227b8bdf8a Better pairing for Xiaomi devices in ZHA (#24564)
* better xiaomi pairing
* cleanup.
2019-06-18 11:36:28 -04:00
Ben Dews
76549beb96 Bump base Somfy MyLink library version (#24587) 2019-06-18 17:32:33 +02:00
David Bonnes
2e848c3f1f Fix honeywell issue #18932 (#24402)
* change us-based default temps to Fahrenheit

* update CODEOWNERS

* update CODEOWNERS

* tweak docstring

* tweak docstring

* Coerce Fahrenheit Temps to int
2019-06-17 20:32:53 -07:00
Johan Nenzén
266b3bc714 Adds integration for Plaato Airlock (#23727)
* Adds integration for Plaato Airlock

* Updates codeowners and coveragerc

* Fixes lint errors

* Fixers lint check error

* Removed sv translation file

* Adds en translation file

* Sets config flow to true in manifest

* Moves config flow and domain to seperate files

* Fixes lint errors

* Runs hassfest to regenerate config_flows.py

* Adds should poll property and fixes for loop

* Only log a warning when webhook data was broken

* Fixes static test failure

* Moves state update from async_update to state prop

* Unsubscribes the dispatch signal listener

* Update sensor.py
2019-06-17 20:23:59 -07:00
Paulus Schoutsen
f3e4e8dce8 Fix alarm control panel tests (#24586) 2019-06-17 20:23:12 -07:00
escoand
73008885c8 Add source selection to Samsung TV media player (#22612)
* add source selection

* return generic list

* remove useless timeout

* Fix test

* Add test for select_source

* Add negative source test

* Change order

* Arghhh

* Add hass object

* Simplify source list

Co-Authored-By: escoand <escoand@users.noreply.github.com>
2019-06-17 15:00:11 -07:00
Kevin Cooper
1460f7bd80 Add code_arm_required to manual alarm (#22618)
* Add code_arm_required to manual alarm

* Add fix for alarm front end more-info-alarm_control_panel
2019-06-17 14:59:20 -07:00
Kevin Cooper
f722a6c08d Add code_arm_required to manual alarm with MQTT (#22641)
* add code_arm_requited to manual-mqtt alarm

* Add fix for alarm front end more-info-alarm_control_panel

* Fix code mistake
2019-06-17 14:49:10 -07:00
Tommaso Marchionni
cb5426c1fa Added invert_percent configuration for zwave rollershutter (#23101)
* Added invert_percent configuration for zwave rollershutter

* Added invert_percent configuration for zwave rollershutter

* Fix typo in zwave default configuration
2019-06-17 14:44:47 -07:00
kbickar
7564d1fb52 Added toggle service to covers (#23198)
* Added toggle service to cover

* Added toggle tilt service and tilt closed property

* Added is_tilt_closed so tilt can be toggled

* Added toggle services

* Added toggle tilt service

* Removed spaces

* Added tests for tilt services

* Updated tests

* Added range conversion in comparison

* Added tests to cover broken areas

* Fixed open/close tilt values and added toggle function

* Added default toggle behavior using tilt_position of 0, reverted other changes

* blank space

* Added constants and swapped assert comparisons

* Fixed attribute name

* Added mqtt responses in test

* Added constants

* Space

* Fix tilt_optimistic flag being ignored if status topic set

* Added more tests

* Changed async toggle call

* Updated group tilt test

* Updated format of asserts

* Updated states calls

* Updated function variables

* merge fixes

* Added blank line

* Changed calls to async

* More async updates
2019-06-17 14:09:31 -07:00
Paulus Schoutsen
a02b69db38 Cloud: Add Alexa report state (#24536)
* Cloud: Add Alexa report state

* Lint

* Lint

* Only track state changes when we are logged in
2019-06-17 13:50:01 -07:00
Save me
5ab1996d3f Add sensitivity and sensitvity_max attributs for binary sensor (#24438)
* Add sensitivity ans sensitvity_max attributs for binary sensor

* Update binary_sensor.py

* Update binary_sensor.py

* Update binary_sensor.py

* Update binary_sensor.py
2019-06-17 09:33:56 -07:00
David Bonnes
ffce593cc8 Fix geniushub issue #24530 (via a client bump) & handle edge cases (#24546)
* bump client library to workaround #24530

* bump client library to workaround #24530 2/2

* bump client library to workaround #24530

* bump client library to workaround #24530 2/2

* bugfix: ghost devices cause TypeError: 'NoneType' object is not subscriptable

* bugfix: broken HW zones cause AttributeError: 'GeniusZone' object has no attribute 'temperature'

* delint
2019-06-17 09:27:06 -07:00
Johann Kellerman
56155740fe SMA sensor: Add optional path (#24558) 2019-06-17 09:26:35 -07:00
Clifford W. Hansen
0a13c47a8c Added percent to the disk,memory and swap percent labels (#24575) 2019-06-17 09:23:14 -07:00
Jeff Irion
d2022cae28 Bump androidtv to 0.0.16 (#24576)
* Bump androidtv to 0.0.16

* Bump androidtv to 0.0.16
2019-06-17 09:21:21 -07:00
Otto Winter
05bb645263 Fix zeroconf migration messing up ESPHome discovery (#24578) 2019-06-17 09:19:39 -07:00
GoNzCiD
ddeb6b6baa Battery attribute & accuracy filter (#24277)
* Extract const to a const file, Add battery as tracker attribute, add accuracy filter option

* Update homeassistant/components/traccar/device_tracker.py

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/traccar/device_tracker.py

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Update homeassistant/components/traccar/device_tracker.py

Use [] syntax for keys that are in the validated data.

Co-Authored-By: Otto Winter <otto@otto-winter.com>

* Fix indentation
2019-06-17 07:44:11 +02:00
zewelor
08eca4a237 Whitelist yeelight predefined effects per device type (#24544)
* Whitelist yeelight predefined effects per device type

* Fix support color
2019-06-16 16:38:15 -04:00
Anders Melchiorsen
1e248551d5 Update pysonos to 0.0.15 (#24565) 2019-06-16 19:41:13 +02:00
David F. Mulcahey
c173a3be44 Misc. ZHA enhancements (#24559)
* add nwk to device info
* input bind only cluster support
* cleanup channel only clusters
* dirty hack to correct xiaomi vibration sensor
* exclude remaining remote binary sensors
* review comments
* fix comment
2019-06-16 13:17:53 -04:00
Daniel Høyer Iversen
b782ed6bbb Update ambiclimate library (#24562) 2019-06-16 15:11:52 +02:00
lundan
a0b1b2e254 Update __init__.py (#24553)
Fix the broken charging status
2019-06-16 09:44:39 +02:00
Aaron Bach
c629f24f07 Fix a bug with Ambient PWS reconnection (#24540) 2019-06-15 12:49:40 -07:00
Matt Black
6b3c740dc3 Handle stacktrace when rtorrent host is unreachable (#24541) 2019-06-15 12:48:55 -07:00
David Bonnes
616301f7ee Fix incomfort issue #24478 & bump client (#24548)
* fix issue #24478 - missing climate entities

* bump client
2019-06-15 12:45:01 -07:00
Robert Svensson
e9b0f54a43 UniFi simplify update (#24304) 2019-06-15 17:38:22 +02:00
Penny Wood
aa8ddeca34 Flux switch (#24542)
* Updated to pytest

* Additional test case
2019-06-15 13:32:51 +08:00
Tomer Figenblat
fe8a330a45 Update requirement version and add switcher_kis services (#23477)
* Update aioswitcher requirement to 2019.4.26.

* Removed unnecessary legacy function call.

* Fixed log message capital first letter.

* Replaced None argument with empty dict.

* Replaced guard.

* Added ServiceCallType.

* Added set_auto_off and update_device_name services to the component.

* Added test cases for service calls.

* Conditioned the component services registry with the platform discovery.

* Update homeassistant/components/switcher_kis/__init__.py

Co-Authored-By: TomerFi <tomer.figenblat@gmail.com>

* Update homeassistant/components/switcher_kis/__init__.py

Co-Authored-By: TomerFi <tomer.figenblat@gmail.com>

* Resolved change requests.

* Added ContextType.

* Addes permission verification for service calls.

* Added test cases for permision verification and more.

* Replaced POLICY_CONTROL with the more suited POLICY_EDIT.

* More appropriate function name.

* Added domain and entity_id validation for calling services.

* Removed service for setting the vendor's device name.
2019-06-14 15:48:21 -07:00
Clifford W. Hansen
f9b3ba2887 Added name to sensors (#24525)
* Added name to sensors

Added name to sensors, should allow for multiple devices.

This should fix #22571 and #21591

* Update sensor.py

Fixed spelling issue, and line too long

* Update sensor.py

Removed _ as it is a friendly name
2019-06-14 15:36:38 -07:00
BackSlasher
50d282ff37 Pyyaml5.1 (#24529)
* Migrated to PyYAML 5.1

* More intelligent fixing of yaml safe_load

Based on https://circleci.com/gh/home-assistant/home-assistant/34831?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link
2019-06-14 15:30:47 -07:00
Paulus Schoutsen
970b00b8d6 Updated frontend to 20190614.0 2019-06-14 14:53:20 -07:00
Paulus Schoutsen
92816b57ef Update translations 2019-06-14 14:53:13 -07:00
ktnrg45
9a8b945118 PS4 bump to 0.8.3 (#24527)
* 0.8.3

* 0.8.3

* 0.8.3

* add unsubscribe method
2019-06-14 13:47:50 -07:00
rolfberkenbosch
d8f5e9b878 Update meteoalertapi to 0.1.5 (#24528) 2019-06-14 16:31:07 -04:00
Daniel Høyer Iversen
b0e6f34976 Improve stability of netatmo sensor (#24190)
* Improve stability of netatmo sensor

* Improve stability of netatmo sensor

* Improve stability of netatmo sensor

* netatmo, except timeout

* netatmo, except timeout

* netatmo, except timeout

* netatmo, except timeout

* Always release lock
2019-06-14 21:26:02 +02:00
Robert Svensson
9aeb75f28d deCONZ - Change attribute Watts to W (#24535) 2019-06-14 20:14:45 +02:00
ktnrg45
8951c80225 WIP Ps4 Convert entity to Async / Fix entity name changing (#24101)
* Convert ps4 to async

* Init client handler.

* Add PS4_DATA

* Move data class

* add handler

* add import

* Update __init__.py

* Change most functions to async

* bump 0.8.0

* bump 0.8.0

* bump 0.8.0

* Pylint

* whitespace

* Rewrite to use asyncio sockets.

* Remove unneeded log

* Add alias

* Update __init__.py

* Update config_flow.py

* Add alias

* Add search_all method

* Clean up

* whitespace

* change comment

* 0.8.2

* 0.8.2

* 0.8.2

* Pylint

* pylint

* faster updates

* Avoid scheduling update if state is the same.

* Better handling remove search all
2019-06-13 17:36:17 -07:00
Paulus Schoutsen
6c5124e12a Cloud: allow managing Alexa entities via UI (#24522)
* Clean up Alexa config

* Cloud: Manage Alexa entities via UI

* Add tests for new cloud APIs
2019-06-13 11:58:08 -07:00
Paulus Schoutsen
08591dae0e Migrate Sonos discovery to manifest (#24507) 2019-06-13 11:09:07 -07:00
zewelor
6d3c3ce449 Refactor yeelight code (#22547)
* Separate yeelight light classes

* Removed not used variable

* Allow to create device right away, when model is declared

* Lint fixes

* Use correct brightness, when nightlight mode is on

* Pylint fix

* Add power property

* Fix imports

* Update homeassistant/components/yeelight/light.py

Co-Authored-By: Teemu R. <tpr@iki.fi>

* Small PR fixes

* Simplify device to yeelight class mapping

* Simplify device initialization code

* Fix comment
2019-06-13 12:42:47 -04:00
Paulus Schoutsen
3d03a86b13 Remove conversation from default config (#24515) 2019-06-13 08:44:43 -07:00
Paulus Schoutsen
7e2278f1cc Clean up Alexa smart home code (#24514)
* Clean up Alexa smart home code

* lint

* Lint

* Lint
2019-06-13 08:43:57 -07:00
Guy Khmelnitsky
416ff10ba9 Update DelugeClient to 1.7.1 (#24518)
* Update DelugeClient to 1.7.1 

Due to update of Deluge to 2.0.3

* deluge-client==1.7.1 in requirements_all.txt
2019-06-13 12:28:44 +02:00
Paulus Schoutsen
aa91211229 Merge pull request #24516 from home-assistant/rc
0.94.3
2019-06-12 23:15:23 -07:00
Paulus Schoutsen
cc1de3191f Merge remote-tracking branch 'origin/rc' into dev 2019-06-12 22:50:59 -07:00
Paulus Schoutsen
10c8f21f79 Bumped version to 0.94.3 2019-06-12 22:48:17 -07:00
Phil Bruckner
3da0f5e384 Fix owntracks source_type for location messages with default trigger (#24503)
Some location update messages do not contain the 't' (trigger) key. Before the change in 0.94 to
entity based trackers, these would default to source_type of 'gps' (due to default parameter
value in async_see method.) To mirror this behavior in the new entity based tracker, the
source_type property should default to SOURCE_TYPE_GPS under the same conditions.
2019-06-12 22:47:56 -07:00
aidbish
7260cada90 missing comma preventing other voices (#24487) 2019-06-12 22:47:55 -07:00
Paulus Schoutsen
73d6dc6b6a Update hass-nabucasa to 0.14 (#24481)
* Update hass-nabucasa to 0.14

* Update owner of cloud

* Update codeowners
2019-06-12 22:47:29 -07:00
Andrey Kupreychik
4627d2c1fb Bumping Keenetic NDMS2 client to 0.0.8 (#24469)
Fixing issue with long strings in Telnet response
2019-06-12 19:12:55 -05:00
Paulus Schoutsen
f54ad26630 Migrate HEOS discovery to manifest (#24508)
* Migrate HEOS discovery to manifest

* Fix tests
2019-06-12 16:08:08 -07:00
aidbish
4c328e4959 missing comma preventing other voices (#24487) 2019-06-12 14:21:00 -07:00
cgtobi
1efccf2d90 Bump pyatmo to 2.00 (#24505)
* Bump pyatmo version to 1.13

* Bump to 2.00

* Fix version number
2019-06-12 14:14:00 -07:00
Paulus Schoutsen
6badd83c5d Add Cast discovery to manifest (#24504) 2019-06-12 13:54:53 -07:00
Phil Bruckner
b817609adc Fix owntracks source_type for location messages with default trigger (#24503)
Some location update messages do not contain the 't' (trigger) key. Before the change in 0.94 to
entity based trackers, these would default to source_type of 'gps' (due to default parameter
value in async_see method.) To mirror this behavior in the new entity based tracker, the
source_type property should default to SOURCE_TYPE_GPS under the same conditions.
2019-06-12 11:40:01 -07:00
Franck Nijhof
61f4c73aca Bump adguardhome to 0.2.1 (#24486)
Signed-off-by: Franck Nijhof <frenck@addons.community>
2019-06-12 09:32:01 -07:00
Paulus Schoutsen
24e1a568a2 remove docs from config entries file [skip ci] (#24488) 2019-06-12 09:29:28 -07:00
Paulus Schoutsen
06ca04c1c8 Update hass-nabucasa to 0.14 (#24481)
* Update hass-nabucasa to 0.14

* Update owner of cloud

* Update codeowners
2019-06-12 09:29:02 -07:00
Reinder Reinders
5698173c76 Version bump for toonapilib to include new API call for fetching thermostat states, which was sometimes missing causing errors in the library (#24459) 2019-06-12 10:31:55 -05:00
Anders Melchiorsen
d7fcb5268a Fix aprs imports (#24485) 2019-06-11 15:57:29 -07:00
kbickar
d041c62f55 Position is reversed for horizontal awnings (#23257)
* Position is reversed for awnings

* Changed device class function to use map

* It wanted more linebreak

* Updated defaults

* Shortened line

* space
2019-06-11 15:56:55 -07:00
Ties de Kock
0eb387916f Camera platform for buienradar imagery (#23358)
* Add camera for buienradar radar

* Use asyncio.Conditions instead of asyncio.Lock

* Add test and fix python 3.5 compatibility

* rename interval to delta for consistency with BOM integration

* fix linting error introduced during rebase

* Improved buienradar.camera documentation and tests

  * Incorporated one comment on a redundant/cargo cult function
  * Improved documentation
  * Increase test coverage by fixing one test by making it a coroutine
    (to make it actually run), adding another test case, and changing
    the flow in the implementation.

* style changes after review, additional test case

* Use python 3.5 style mypy type annotations in __init__

* Remove explicit passing of event loop

* Adopt buienradar camera as codeowner

* Update manifest.json

* Update CODEOWNERS through hassfest

Updated CODEOWNERS through hassfest (instead of manually), thanks to
@balloob for the hint.
2019-06-11 15:26:04 -07:00
Jurriaan Pruis
b87c541d3a Support ZLO device types to support newer Zigbee devices in ZHA (#24429)
* Support ZLO device types
Support the device types that are added in https://github.com/zigpy/zigpy/pull/176
so newer Zigbee devices can be supported.

* Remove BINARY_SENSOR mappings
* Add back ON_OFF_LIGHT_SWITCH, DIMMER_SWITCH and COLOR_DIMMABLE_LIGHT
Since they are target devices I've added them as switch and lights,
which matches the Zigbee documentation.

* Upgrade to zigpy-homeassistant v0.5.0
To be able to use the new DeviceTypes
2019-06-11 16:28:37 -04:00
Save me
a6a3555684 Add attributs and fix lightlevel inconsistency for LightLevel sensor (#24439)
* Add attributs and fix state level

* Update sensor.py

* Update sensor.py
2019-06-11 10:41:20 -07:00
Quentame
7559e70027 Add Linky sensors : yesterday + months + years (#23726)
* Add Linky sensors : yesterday + months + years

- SCAN_INTERVAL to 4 hours
- Always close_session after getting the data
- Add username attr
- Fix not updating Linky sensor when Enedis API fails

* Fix @balloob review: remove monitored_conditions
2019-06-11 10:18:41 -07:00
Philip Rosenberg-Watt
8fcfcc40fc Add APRS device tracker component (#22469)
* Add APRS device tracker component

This component keeps open a connection to the APRS-IS infrastructure so
messages generated by filtered callsigns can be immediately acted upon.
Any messages with certain values for the 'format' key are position
reports and are parsed into device tracker entities.

* Log errors and return if startup failure

* Fix unit tests
2019-06-11 10:16:13 -07:00
Paulus Schoutsen
c2218e8a64 Merge pull request #24465 from home-assistant/rc
0.94.2
2019-06-11 08:54:29 -07:00
tetienne
0a7919a279 Somfy open api (#19548)
* CREATE Somfy component

* CREATE cover Somfy platform

* USE somfy id as unique id

* UPDATE all the devices in one call to limit the number of call

* FIX Don't load devices if not yet configured

* IMP Replace configurator by a simple notification

* ADD log in case state does not match

* IMP wording

* REMOVE debug stuf

* ADD support for tilt position

* UPDATE requirements

* FIX Use code instead of authorization response

 - Will allow to setup Somfy without https

* HANDLE stateless devices (Somfy RTS)

* FIX import locally 3rd party library

* UPDATE pymfy to 0.4.3

* ADD missing docstring

* FIX For Somfy 100 means closed and 0 opened

* FIX position can be None

* ENHANCE error management when error 500 occurs at setup

* FIX indent

* ROLLBACK tilt modification

 - See https://community.home-assistant.io/t/somfy-tahoma-official-api/61448/90?u=tetienne

* FIX Look for capability instead of state

* DON'T use exception to test if a feature is available

* UPDATE dependency

* ADD device_info property

* AVOID object creation in each method

* REMOVE unused constants

* ADD missing doc

* IMP Only make one call to add_entities

* USE dict[key] instead of get method

* IMP Don't pass hass object to the entities

* FIX Don't end logging messages with period

* USE config entries instead of a cache file

* IMPLEMENT async_unload_entry

* CONSOLIDATE package

 - see home-assistant/architecture#124

* UPDATE to pymfy 0.5.1

* SIMPLIFY config flow

* ADD French translation

* FIX 80 vs 79 max length

* ABORT flow asap

* FIX A tupple was returned

* MIGRATE to manifest.json

* ADD a placeholder async_setup_platform coroutine

 - It's currently required and expected by the platform helper.

* FIX codeowner

* ADD missing translations file

* USE new external step

* UPGRADE pymfy version

* Close Somfy tab automatically

* ADD manufacturer

  - Somfy only for the moment.

* HANDLE missing code or state in Somfy request

* REMOVE unused strings

* DECLARE somfy component to use config_flow

* APPLY static check remarks

* FIX async method cannot be called from sync context

* FIX only unload what has been loaded during entry setup

* DON't catch them all

* DON'T log full stacktrace

* ABORT conflig flow if configuration missing

* OMIT Somfy files for coverage

* ADD tests about Somfy config flow

* ADD pymfy to the test dependencies
2019-06-11 08:45:34 -07:00
Miroslav Ždrale
046a4fc401 Bump pyubee to 0.7 to support more models (#24477)
* Bump pyubee to 0.7 to support more models

* Update requirements_all.txt
2019-06-11 08:43:58 -07:00
Thomas Lovén
70bbb867f9 Use met.no instead of yr.no in default config (#24470) 2019-06-11 08:34:02 -07:00
Robbie Trencheny
ae5f284d10 Uber API is going away on June 13, 2019, remove component (#24468)
* Uber API is going away on June 13, 2019, remove component

* Update CODEOWNERS

* Remove Uber component
2019-06-11 08:32:21 -07:00
Paulus Schoutsen
6ea0575a4a Update home zone when core config updated (#24237)
* Update home zone when core config updated

* Lint
2019-06-11 08:30:38 -07:00
Paulus Schoutsen
d88d57f3bb Bumped version to 0.94.2 2019-06-10 16:06:12 -07:00
Paulus Schoutsen
bd80346592 Sun listener to adapt to core config updates (#24464)
* Adaptable sun listener

* Lint
2019-06-10 16:06:07 -07:00
Paulus Schoutsen
7292f2be69 Update Hass.io when core config is updated (#24461)
* Update Hass.io when core config is updated

* Lint

* Fix tests

* Lint sigh
2019-06-10 16:06:06 -07:00
Andy Kittner
21d04b3e14 Remember gpslogger entities across restarts (fixes #24432) (#24444)
* Remember gpslogger entities across restarts (fixes #24432)

* oops, missed those changes

* Remove to do and set defaults to `None`
2019-06-10 16:06:06 -07:00
Robert Svensson
3c6235bee5 Axis discovery MAC filter (#24442)
* Make sure to abort if the MAC is not from Axis

* Fix tests

* Andrew Sayre suggestion

Co-Authored-By: Andrew Sayre <6730289+andrewsayre@users.noreply.github.com>
2019-06-10 16:06:05 -07:00
Julien Brochet
b0985bb459 Load the SSDP component only when it's needed (#24420)
* fix(hue): Load the SSDP component only when it's needed

* fix(deconz): Don't load the SSDP component when it's not needed

* Update config_flow.py

* Update test_config_flow.py
2019-06-10 16:06:04 -07:00
Robert Svensson
8e93d0a7a2 deCONZ fix retry set state(#24410) 2019-06-10 16:06:03 -07:00
Paulus Schoutsen
820b381a8d Update Hass.io when core config is updated (#24461)
* Update Hass.io when core config is updated

* Lint

* Fix tests

* Lint sigh
2019-06-10 16:05:43 -07:00
Paulus Schoutsen
236c5deeee Sun listener to adapt to core config updates (#24464)
* Adaptable sun listener

* Lint
2019-06-10 16:05:32 -07:00
Erik Montnemery
935240f8c3 Add websock command to query device for triggers (#24044)
* Add websock command to query device for triggers

* Lint

* Refactor

* Add support for domain automations

* Make device automation an automation platform

* lint

* Support device_id in light trigger

* Review comments

* Add tests

* Add tests

* lint
2019-06-10 15:36:11 -07:00
Paulus Schoutsen
168f20bdf4 Add default config to constaint file (#24423) 2019-06-10 14:38:14 -07:00
Andy Kittner
1810e459ee Remember gpslogger entities across restarts (fixes #24432) (#24444)
* Remember gpslogger entities across restarts (fixes #24432)

* oops, missed those changes

* Remove to do and set defaults to `None`
2019-06-10 12:46:38 -07:00
Phil Bruckner
d86837cc4d Life360: Fix config entry handling for accounts imported from configuration (#24455)
Was improperly generating a warning each restart.

Was not properly handling a password change in configuration.

Was not properly removing config entries for accounts removed from configuration.
2019-06-10 12:45:22 -07:00
Pascal Vizeli
af926db211 Publish test results (#24460) 2019-06-10 21:22:23 +02:00
jwater7
20ba80f934 Remove frequest asuswrt log spam (#24448) 2019-06-10 09:16:26 -07:00
Robert Svensson
34e3d2f997 Axis discovery MAC filter (#24442)
* Make sure to abort if the MAC is not from Axis

* Fix tests

* Andrew Sayre suggestion

Co-Authored-By: Andrew Sayre <6730289+andrewsayre@users.noreply.github.com>
2019-06-10 09:12:17 -07:00
Julien Brochet
fadfb89b4c Load the SSDP component only when it's needed (#24420)
* fix(hue): Load the SSDP component only when it's needed

* fix(deconz): Don't load the SSDP component when it's not needed

* Update config_flow.py

* Update test_config_flow.py
2019-06-10 09:11:07 -07:00
Penny Wood
84e6813779 Rename via_hub to via_device (#24360)
* Rename via_hub to via_device

* Fixed registry interactions
2019-06-10 09:10:44 -07:00
Daniel Høyer Iversen
4921d35e70 Upgrade ambiclimate library (#24449) 2019-06-10 17:39:35 +02:00
Daniel Høyer Iversen
cebb146e7c Upgrade broadlink library (#24450) 2019-06-10 17:39:12 +02:00
Pascal Vizeli
4e6b133a17 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 17:41:15 +02:00
Pascal Vizeli
0a5966c283 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 15:32:30 +02:00
Pascal Vizeli
3f6a30a974 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 14:47:03 +02:00
Pascal Vizeli
0db27f1cef Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 14:26:42 +02:00
Pascal Vizeli
628264be4e Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 12:41:14 +02:00
Pascal Vizeli
d286723087 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 12:38:01 +02:00
Pascal Vizeli
fb3d66e6e1 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 12:35:08 +02:00
Pascal Vizeli
795300848c Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 12:32:12 +02:00
Pascal Vizeli
b3b2e8ffb7 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 12:28:51 +02:00
Pascal Vizeli
6a4bf1f817 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 12:13:37 +02:00
Pascal Vizeli
7c27bab3c7 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 11:25:24 +02:00
Pascal Vizeli
accfedce87 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 11:20:18 +02:00
Pascal Vizeli
4cb0ff1f63 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 11:14:46 +02:00
Pascal Vizeli
896eaba2d6 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-09 11:11:29 +02:00
Franck Nijhof
d648eb1e4f Minor improvements to automation test suite (#24424)
* Minor improvements to automation test suite

* Removes unused asyncio imports

* Removes some vars that are not needed
2019-06-08 19:10:23 -05:00
Paulus Schoutsen
848a2a95a8 Fix recorder defaults (#24399)
* Fix recorder defaults

* Address comment
2019-06-08 18:18:28 -05:00
Franck Nijhof
9235b52828 Restore automation last_triggered with initial_state override (#24400)
* Restore automation last_triggered with initial_state override

* Made test async/await

* Fixes linter warning

* Update test_init.py
2019-06-08 12:48:36 -07:00
Robert Svensson
3fa84039f8 deCONZ fix retry set state(#24410) 2019-06-08 17:45:10 +02:00
Paulus Schoutsen
929f3c2594 Use loose version (#24394) 2019-06-08 08:19:00 -07:00
Franck Nijhof
95d460c8bd Fixes linter warning in ZHA sensor (#24406) 2019-06-08 07:29:35 -04:00
Pascal Vizeli
67e87f9048 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-08 11:43:33 +02:00
Pascal Vizeli
9924dd7aca Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-08 11:05:27 +02:00
Paulus Schoutsen
3ac8c6d1fe Bump version to 0.95.0.dev0 2019-06-07 23:47:13 -07:00
Paulus Schoutsen
b179dbcdcf Merge remote-tracking branch 'origin/master' into dev 2019-06-07 23:47:02 -07:00
Paulus Schoutsen
282b4f4927 Merge pull request #24396 from home-assistant/rc
0.94.1
2019-06-07 23:45:13 -07:00
Robert Svensson
b68a796c7c deCONZ - properly identify configured bridge (#24378) 2019-06-07 23:43:59 -07:00
Robert Svensson
48276b041c deCONZ - properly identify configured bridge (#24378) 2019-06-08 08:43:18 +02:00
Penny Wood
bfafe9ccbe Fix for sun issues (#24309) 2019-06-07 23:28:56 -07:00
Penny Wood
4cb1d77783 Fix for sun issues (#24309) 2019-06-07 23:21:41 -07:00
David F. Mulcahey
787bd75587 add device class to sensors (#24373) 2019-06-07 23:19:52 -07:00
Paulus Schoutsen
dc93779f02 Bumped version to 0.94.1 2019-06-07 23:13:57 -07:00
Paulus Schoutsen
14066dfb5a Check cloud trusted proxies (#24395) 2019-06-07 23:13:45 -07:00
Paulus Schoutsen
7d9988fd75 Add more HomeKit models for discovery (#24391)
* Add more HomeKit models for discovery

* Discover Tradfri with HomeKit

* Add Wemo device info

* Allow full match for HomeKit model

* Fix tests
2019-06-07 23:13:44 -07:00
Paulus Schoutsen
2fed016347 Fix automation failing to restore state (#24390)
* Fix automation off

* Fix tests
2019-06-07 23:13:43 -07:00
William Scanlon
d1b82e9ede Updated pubnubsub-handler to 1.0.7 to fix crash on slow startup (#24388) 2019-06-07 23:13:43 -07:00
Robert Svensson
b8e20fcadf Bump dependency (#24376) 2019-06-07 23:13:42 -07:00
Paulus Schoutsen
ebc09017b8 Initiate websession inside event loop (#24331) 2019-06-07 23:13:42 -07:00
Paulus Schoutsen
798b72e164 Add a discovery config flow to Wemo (#24208) 2019-06-07 23:13:41 -07:00
Paulus Schoutsen
f77514c6f2 Check cloud trusted proxies (#24395) 2019-06-07 23:08:55 -07:00
Paulus Schoutsen
7887d6d6e4 Fix automation failing to restore state (#24390)
* Fix automation off

* Fix tests
2019-06-07 23:08:22 -07:00
Paulus Schoutsen
0dc0706eb2 Add more HomeKit models for discovery (#24391)
* Add more HomeKit models for discovery

* Discover Tradfri with HomeKit

* Add Wemo device info

* Allow full match for HomeKit model

* Fix tests
2019-06-07 22:59:51 -07:00
Penny Wood
b30f4b8fc0 Improve boolean validator (#24294)
* Improve boolean validator

* Remove extra throw

* Remove None test as discussed

* Fix for tests depending on None == False
2019-06-07 22:18:02 -07:00
Phil Bruckner
233bc1a108 Improve amcrest error handling and bump amcrest package to 1.5.3 (#24262)
* Improve amcrest error handling and bump amcrest package to 1.5.3

amcrest package update fixes command retry, especially with Digest Authentication, and allows sending snapshot command without channel parameter.

Get rid of persistent_notification.

Errors at startup, other than login errors, are no longer fatal.

Display debug messages about how many times an error has occurred in a row.

Remove initial communications test. If camera is off line at startup this just delays the component setup.

Handle urllib3 errors when getting data from commands that were sent with stream=True.

If errors occur during camera update, try repeating until it works or the camera is determined to be off line.

Drop channel parameter in snapshot command which allows camera to use its default channel, which is different in different camera models and firmware versions.

Make entities unavailable if too many errors occur in a row.

Add new configuration variables to control how many errors in a row should be interpreted as camera being offline, and how frequently to "ping" camera to see when it becomes available again.

Add online binary_sensor option to indicate if camera is available (i.e., responding to commands.)

* Update per review comments

Remove max_errors and recheck_interval configuration variables and used fixed values instead.

Move definition of AmcrestChecker class to module level.

Change should_poll in camera.py to return a fixed value of True and move logic to update method.
2019-06-07 21:46:49 -07:00
Phil Bruckner
61dabae6ab Add for option for template triggers (#24330) 2019-06-07 21:45:37 -07:00
William Scanlon
d858e1be05 Updated pubnubsub-handler to 1.0.7 to fix crash on slow startup (#24388) 2019-06-07 23:29:31 -04:00
Andy Castille
4c3f39be02 Provide an option for the DD-WRT device tracker to include non-wireless devices (#24259)
* Use LAN status instead of wireless status for DD-WRT device tracking

* Use the previous DD-WRT device tracker behavior unless specified in the configuration
2019-06-07 19:45:57 -05:00
rolfberkenbosch
b5ada3bf10 Add ATTR_FORECAST_PRECIPITATION option (#24308)
* Add ATTR_FORECAST_PRECIPITATION option

* Remove blank line
2019-06-07 19:31:57 -05:00
Andre Lengwenus
a3794b3241 Fixed wrong setpoint value on startup when climate was previously turned off (#24377) 2019-06-07 19:29:51 -05:00
kvanhoorn
952d72fdd3 Add shuffle support for itunes component (#24319)
* added shuffle support for itunes component

* fixed pylint errors

* more pylint

* final pylint (have my own dev env now)
2019-06-07 19:05:08 -05:00
Pascal Vizeli
5a9db70d24 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-08 00:56:10 +02:00
Pascal Vizeli
17b59cd410 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-08 00:55:03 +02:00
Pascal Vizeli
eb3e53e2d3 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-08 00:54:14 +02:00
Pascal Vizeli
8af0747f95 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-07 22:43:07 +02:00
Pascal Vizeli
ceac04b82d Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-07 22:40:32 +02:00
Pascal Vizeli
e93fbcf701 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-07 22:36:42 +02:00
Pascal Vizeli
337cd40cb6 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-07 22:34:44 +02:00
Pascal Vizeli
3664f61e2d Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-07 22:24:43 +02:00
Pascal Vizeli
1acd34313b Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-07 22:06:27 +02:00
Fabian Affolter
888c5172bf Upgrade Mastodon.py to 1.4.3 (#24374) 2019-06-07 14:22:37 -05:00
Fabian Affolter
3d802afecb Upgrade discord.py to 1.1.1 (#24375) 2019-06-07 14:22:19 -05:00
Robert Svensson
1647ebaf31 Bump dependency (#24376) 2019-06-07 14:22:02 -05:00
Pascal Vizeli
ae1511d8f6 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-07 21:16:39 +02:00
Pascal Vizeli
85f4cecc64 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-07 18:54:28 +02:00
Pascal Vizeli
203c3a5175 Update azure-pipelines-ci.yml for Azure Pipelines 2019-06-07 18:42:47 +02:00
Pascal Vizeli
846d31c4f1 Create azure-pipelines-ci.yml 2019-06-07 18:38:05 +02:00
presslab-us
cb460a85ba Add support for ZHA door locks #2 (#24344)
* Add support for DoorLock cluster
* Add test for zha lock
* Change lock_state report to REPORT_CONFIG_IMMEDIATE
* Update channel command wrapper to return the entire result
This allows for return values other than result[1]

* Fix tests
* Fix lint
* Update DoorLock test to work with updated zigpy schema
* Fix lint
* Fix unlock test
2019-06-07 11:16:33 -04:00
David F. Mulcahey
592d30d495 Remove binary sensors for ZHA remotes and controllers (#24370)
* remove remote binary sensor profiles
* fix contact sensors
2019-06-07 11:13:55 -04:00
David F. Mulcahey
a79224aba8 Fix ZHA battery level when value is reported via signal (#24371)
* fix battery signal
* review comment
2019-06-07 11:02:35 -04:00
Paulus Schoutsen
7c5da67d74 Add service to update core location (#24328)
* Add service to update core location

* Update test_init.py
2019-06-07 09:09:25 -05:00
Daniel Perna
b71baef7c8 Update pyhomematic (#24368) 2019-06-07 12:46:47 +02:00
Petro31
2c341f2a65 Refactor Waze Travel Time & Update Requirements (#22428)
* Refactor Waze Travel Time & Update Requirements

Refactored Waze Travel Time to contain a data object.

Changed error retrieving data to a warning.
Added distance conversion depending on region.
Removed dependency on TRACKABLE_DOMAINS list.
Update to use WazeRouteCalculator 0.10

3rd time's a charm.  Deleted fork, caused last PR to screw up.  So here we are.

* Update requirements_all.txt

* Revert package upgrade.

* Revert package upgrade.
2019-06-06 16:25:14 -07:00
Phil Bruckner
1c1363875c Life360 integration (#24227) 2019-06-06 16:07:15 -07:00
Aaron Bach
156ab7dc2b Bump regenmaschine to 1.5.1 (#24358) 2019-06-06 15:31:17 -07:00
Fabian Affolter
4db0e7888a Upgrade ruamel.yaml to 0.15.97 (#24350)
* Upgrade ruamel.yaml to 0.15.97

* Fix req
2019-06-06 15:30:44 -07:00
Tommy Long
e98054accb Add templating to MQTT Cover tilt_status (#24355) 2019-06-06 15:30:27 -07:00
Andre Lengwenus
7771ecfe58 Bump to pypck==0.6.1 (#24356) 2019-06-06 15:30:14 -07:00
z0p
6cd9667364 Support for Salda Smarty XV/XP Ventilation Unit (#21491)
* Support for Salda Smarty XV/XP Ventilation Unit

* Update binary_sensor.py

* Update fan.py

* Update sensor.py

* Update __init__.py
2019-06-06 15:23:00 -07:00
Jonathan Keljo
bf7e09ce59 Bring the Sisyphus integration to silver quality (#22457)
* Bring the Sisyphus integration to silver quality

Checklist:
- [x] (N/A - push integration) Set an appropriate SCAN_INTERVAL (if a polling integration)
- [x] Raise PlatformNotReady if unable to connect during platform setup
- [x] (N/A - no credentials) Handles expiration of auth credentials. Refresh if possible or print correct error and fail setup. If based on a config entry, should trigger a new config entry flow to re-authorize.
- [x] (N/A - local integration) Handles internet unavailable. Log a warning once when unavailable, log once when reconnected.
- [x] Handles device/service unavailable. Log a warning once when unavailable, log once when reconnected.
- [x] Set available property to False if appropriate
- [x] Entities have unique ID (if available)

* Feedback (fix a couple verbose places)

* Use a task instead of a lock

* Initialize field in constructor

* Revert package upgrade.
2019-06-06 15:16:27 -07:00
Daniel Kucera
32844bb318 ebusd: added check for monitored conditions validity within correct circuit (#22461) 2019-06-06 14:59:57 -07:00
cpopp
1bca313421 Add Streamlabs Water Monitor (#21205)
* Add Streamlabs Water Monitor

* Fail Streamlabswater component setup when given invalid parameters

The Streamlabs Water component is unable to recover if it is given
an invalid API key or location id so this change is to ensure
we validate they are correct during setup and return a failure
if they are not.

* Prime Streamlabswater component sensors so data is available immediately

The sensors for the component were not causing an immediate load of
data from the API when being set up so there was some lag after
startup before values would show up.  This change does an explicit
update when the sensors are setup to ensure data is viewable
immediately after startup.

* Switch Streamlabswater logging to use %s for string formatting

* Update Streamlabswater component with correct dependencies

Dependencies were incorrectly specified using DEPENDS rather
than DEPENDENCIES

* Streamlabswater pull request feedback

Remove detailed class docstrings since they're in the documentation,
reduce code duplication in sensor classes, and remove periods from
the end of log messages.

* Reduce line length in Streamlabswater sensor

* Add docstring on Streamlabswater service callback method

* Get rid of unnecessary initializers in Streamlabswater sensor

* Add manifest file for Streamlabs Water Monitor

* Remove unused REQUIREMENTS
2019-06-06 13:55:08 -07:00
Дубовик Максим
984d41e334 Google Cloud Platform component (TTS) (#23629)
* Added Google Cloud TTS service component feature

* Added Neutral voice gender

* Added line break at the end of files

* Updated CODEOWNERS, reqirements_all.txt and .coveragerc

* Fixed some ci/circleci: static-check errors

* Fixed some ci/circleci: static-check error

* Fixed some ci/circleci: pylint errors

* Fixed some ci/circleci: pylint errors

* * made supported_options const
* fixed direct env variable access

* Fixed import order

* * Component renamed
* Added encoding parameter
* Other fixes

* Changed folder name in .coveragerc

* * Removed whitespaces in blank lines
* Split long line

* Removed whitespaces in blank lines

* ci/circleci: static-check

* Fixed requirements_all.txt

* Added speed, pitch and gain parameters

* Added speed, pitch and gain as supported options

* Split too long line

* * Added profiles parameter
* Changed supported languages and encodings values
* Added parameters validations

* Fixes

* Fixes

* Fixes

* Fixes

* Fixes

* Changed options validation

* Added ToggleEntity save and restore state mechanism

* Revert "Added ToggleEntity save and restore state mechanism"

This reverts commit 0e275014
2019-06-06 12:45:29 -07:00
michaeldavie
fcfbdd2d89 Add Environment Canada weather, sensor, and camera platforms (#21110)
* Added Environment Canada weather platform

* Added Environment Canada weather platform

* Migrate to new folder structure

* Migrate to new folder structure

* Fix updates

* Fix updates again

* Bump env_canada to 0.0.4

* Bump env_canada to 0.0.4

* Bump env_canada to 0.0.4 in requirements_all.txt

* Change daily forecast timestamp and high/low test

* Change daily forecast timestamp and high/low test

* Bump env_canada to 0.0.5

* Break alerts into multiple sensors, bump env_canada to 0.0.6

* Bump env_canada to 0.0.7

* Remove blank line

* Remove 'ec' sensor prefix, bump env_canada to 0.0.8

* Corrections

* Change to manifests.json

* Add docstring to __init.py__

* Update CODEOWNERS

* pylint correction

* pylint correction

* Add alert details, bump env_canada to 0.0.9

* Update requirements_all.txt

* Update .coveragerc

* Bump env_canada to 0.0.10

* Update requirements_all.txt
2019-06-06 11:47:27 -07:00
Sebastian Muszynski
4ec2af785a Fix set_cover_position of the xiaomi_aqara cover for LAN protocol v2 (#24333)
* Fix set_cover_position of the xiaomi_aqara cover for LAN protocol v2 (Closes: #24293)

* Fix lint
2019-06-06 20:09:10 +02:00
Sebastian Muszynski
0eba920075 Add new movement type "actively" of the Xiaomi Vibration Sensor (#24334) 2019-06-06 20:08:29 +02:00
Fabian Affolter
8f4bb8d445 UPgrade youtube_dl to 2019.05.20 (#24347) 2019-06-06 19:46:36 +02:00
David Barrera
3b8f254dfd Don't load last_checkpoint if shipment is pending (#24301) 2019-06-06 11:20:30 -05:00
Markus Jankowski
64d6fa8e86 Remove attribute lowBat (#24323) 2019-06-06 11:11:37 -05:00
Maciej Bieniek
3b4a9a337b Add abbreviation for light template variable names (#24336) 2019-06-06 18:10:23 +02:00
David F. Mulcahey
ae1bcd5fef Use node descriptor from Zigpy for ZHA (#24316)
* use zigpy node descriptor

* cleanup
2019-06-06 08:31:03 -04:00
Markus Jankowski
9fb1f2fa17 Remove deprecated AlarmControlPanel (#24322) 2019-06-06 12:09:02 +02:00
Paulus Schoutsen
d261c6ccc1 Initiate websession inside event loop (#24331) 2019-06-06 12:07:30 +02:00
cgtobi
9ca5bdda7f Add exception handling for Netatmo climate (#24311)
* Add exception handling

* Make pylint happy
2019-06-06 09:30:16 +02:00
Andre Richter
6cc1bf37cc components/cover: Typo in docstring. (#24329) 2019-06-05 19:34:09 -05:00
jjlawren
f5db7707bb Only update media icon when necessary (#24324)
* Only update media icon when necessary

* Lint

* Comment
2019-06-05 19:32:43 -05:00
Victor Cerutti
859ae2fbad Meteofrance fix 24244 (#24315)
* Update meteofrance package version

Fix https://github.com/home-assistant/home-assistant/issues/24244

* Add code owner to manifest

* Update CODEOWNERS
2019-06-05 20:09:11 -04:00
Aaron Bach
96a51d16a7 Bump simplipy to 3.4.2 (#24326)
* Bump simplipy to 3.4.2

* Updated requirements
2019-06-05 15:05:52 -06:00
Pascal Vizeli
09292d5918 Update azure-pipelines-release.yml for Azure Pipelines 2019-06-05 22:15:18 +02:00
Pascal Vizeli
f62d473fc4 Update azure-pipelines-release.yml for Azure Pipelines 2019-06-05 22:14:03 +02:00
Pascal Vizeli
607b44f7c0 Update azure-pipelines-wheels.yml for Azure Pipelines 2019-06-05 18:57:10 +02:00
Pascal Vizeli
d78e132007 Merge pull request #24305 from home-assistant/rc
0.94.0
2019-06-05 18:35:04 +02:00
Robert Svensson
8d3c9bc2d0 Don't let zeroconf be smart with addresses (#24321) 2019-06-05 18:33:31 +02:00
Oliver
6d4545cb3e Push to version 0.7.9 of denonavr (#24260) 2019-06-05 11:23:17 -05:00
Robert Svensson
c311e480fd Don't let zeroconf be smart with addresses (#24321) 2019-06-05 08:13:40 -07:00
David Roberts
4c6ddd435c SolarEdge Local Component (#23996)
* Basic local SolarEdge monitoring for energy / power

* Basic local SolarEdge monitoring for energy / power

* generated CODEOWNERS, requirements, excluded tests

* generated CODEOWNERS, requirements, excluded tests

* lint fixes, etc

* lint fixes, etc

* Fix docstyle for init

Of course thats the file I forgot to run tests on

* Load all sensors by default

They use the same API endpoint.  This changes was made per https://github.com/home-assistant/architecture/pull/244

* remve unneded date/time

* ran hassfest again

* add throttle when updating

* readd solax, mistakenly removed

* Update sensor.py
2019-06-05 16:45:05 +02:00
Johan Bloemberg
d31140f8cd Upgrade to newer version of rflink with improve error handling on incoming data. (#24263)
Related: https://github.com/home-assistant/home-assistant/issues/23942
2019-06-05 12:04:05 +02:00
Felipe Martins Diel
0ed9e185b2 Add support for learning new commands (#23888)
* Add support for learning new commands

This update creates a generic service in the 'remote' component to enable remote control platforms to learn new commands.

* Update __init__.py with the proposed changes

- Add 'supported_features' property and a constant related to the 'learn_command' functionality.
- Redefine 'async_learn_command' function as a coroutine.

* Update __init__.py

* Fix assertion error

Adding the 'supported_features' attribute generated an assertion error on the 'Demo Remote' platform. This update fixes this.

* Fix duplicated 'hass' object

This update fixes a typo that occurred at the last update.
2019-06-05 11:32:59 +02:00
Andre Lengwenus
408ae44bdd Add LCN scene platform (#24242) 2019-06-05 11:12:05 +02:00
Ville Skyttä
bf9c2c74fa Upgrade pytest and -cov (#24258)
* Upgrade pytest to 4.5.0

https://docs.pytest.org/en/latest/changelog.html#pytest-4-5-0-2019-05-11
https://docs.pytest.org/en/latest/changelog.html#pytest-4-4-2-2019-05-08

* Upgrade pytest to 4.6.0

https://docs.pytest.org/en/latest/changelog.html#pytest-4-6-0-2019-05-31

* Upgrade pytest-cov to 2.7.1

https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst#271-2019-05-03
https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst#270-2019-05-03

* Upgrade pytest to 4.6.1

https://docs.pytest.org/en/latest/changelog.html#pytest-4-6-1-2019-06-02
2019-06-05 11:09:23 +02:00
Pascal Vizeli
ce93a332a7 Update and rename azure-pipelines.yml to azure-pipelines-release.yml 2019-06-05 09:37:57 +02:00
Pascal Vizeli
bc15f11473 Rename azure-pipelines.yml to azure-pipelines-release.yml 2019-06-05 09:36:10 +02:00
Pascal Vizeli
fccbd41203 Update azure-pipelines-wheels.yml for Azure Pipelines 2019-06-05 09:30:08 +02:00
Pascal Vizeli
17b3d3a8e4 Update azure-pipelines-wheels.yml for Azure Pipelines 2019-06-05 09:25:46 +02:00
Pascal Vizeli
279192d317 Rename azure-pipelines-release.yml to azure-pipelines.yml 2019-06-05 09:25:24 +02:00
Pascal Vizeli
701d258076 Update and rename azure-pipelines.yml to azure-pipelines-release.yml 2019-06-05 09:24:14 +02:00
Pascal Vizeli
034bbb4f5f Create azure-pipelines-wheels.yml 2019-06-05 09:11:56 +02:00
rolfberkenbosch
2943ad15a5 Change meteoalertapi to version 0.1.3 (#24307)
* Change meteoalertapi to version 0.1.3

* Add requirements_all.txt file
2019-06-05 08:55:10 +02:00
Paulus Schoutsen
13c3833593 Bumped version to 0.94.0 2019-06-04 14:34:06 -07:00
Paulus Schoutsen
d0715c75c0 Merge remote-tracking branch 'origin/master' into rc 2019-06-04 14:33:49 -07:00
Paulus Schoutsen
eca424656a Fix OwnTracks race condition (#24303)
* Fix OwnTracks race condition

* Lint
2019-06-04 14:25:10 -07:00
Robert Svensson
3b60081e2a address is deprecated in favor of addresses (#24302) 2019-06-04 14:25:09 -07:00
Robert Svensson
fbfaa41cb0 address is deprecated in favor of addresses (#24302) 2019-06-04 14:14:51 -07:00
Paulus Schoutsen
df1da7554c Fix OwnTracks race condition (#24303)
* Fix OwnTracks race condition

* Lint
2019-06-04 14:06:49 -07:00
gibman
6d280084fb Expose specific device_class for Velux covers (#24279)
* Update cover.py

Blinds, Rollingshutters and Awnings did not set their respective device_class attribute
Previously they would all appear as device_class "window"

* fallback device class is always 'window'

fallback device class is always 'window' in the event we have an unknown cover type

* trailing whitespace removed, trimmed as well

* Update cover.py
2019-06-04 13:17:43 -07:00
Paulus Schoutsen
1096fe3d87 Bumped version to 0.94.0b8 2019-06-04 11:06:25 -07:00
Paulus Schoutsen
389da16947 Upgrade Zeroconf to 0.23 (#24300) 2019-06-04 11:06:19 -07:00
Paulus Schoutsen
185af1b42a Run SSDP discovery in parallel (#24299) 2019-06-04 11:06:18 -07:00
Pascal Vizeli
d17f27b65c Create progress file for pip installs (#24297)
* Create progress file for pip installs

* fix dedlock

* unflacky test

* Address comments

* Lint

* Types
2019-06-04 11:06:18 -07:00
Paulus Schoutsen
bb0867f1a8 Guard against bad states in Mobile App/OwnTracks (#24292) 2019-06-04 11:06:17 -07:00
Paulus Schoutsen
ac788a7ee7 Upgrade Zeroconf to 0.23 (#24300) 2019-06-04 11:05:11 -07:00
Pascal Vizeli
bf52aa8ccc Create progress file for pip installs (#24297)
* Create progress file for pip installs

* fix dedlock

* unflacky test

* Address comments

* Lint

* Types
2019-06-04 11:04:20 -07:00
Paulus Schoutsen
d7c8adc085 Run SSDP discovery in parallel (#24299) 2019-06-04 11:04:02 -07:00
Paulus Schoutsen
8b4ef3bbdd Guard against bad states in Mobile App/OwnTracks (#24292) 2019-06-04 10:18:26 -07:00
Paulus Schoutsen
b67d32824c Updated frontend to 20190604.0 2019-06-04 09:41:07 -07:00
Paulus Schoutsen
14c0ada9ac Update translations 2019-06-04 08:50:48 -07:00
Paulus Schoutsen
618039734a Updated frontend to 20190604.0 2019-06-04 08:50:25 -07:00
Brandon Davidson
0d5e151c60 Update pyvera to 0.3.1 for alert support (#24289) 2019-06-04 14:47:47 +02:00
Pascal Vizeli
bad920fa87 Bumped version to 0.94.0b7 2019-06-04 12:42:45 +02:00
Paulus Schoutsen
281fe93a26 Bumped version to 0.94.0b6 2019-06-03 12:41:45 -07:00
Paulus Schoutsen
4a71593ffd Remove deps folder in config when on Docker (#24284)
* Remove deps folder in config

* Fix tests

* Fix tests with docker check
2019-06-03 12:41:36 -07:00
Paulus Schoutsen
014cc14b7e Fix cors on the index view (#24283) 2019-06-03 12:41:35 -07:00
Otto Winter
ee71d2ca60 Bump aioesphomeapi to 2.1.0 (#24278)
* Bump aioesphomeapi to 2.1.0

* Update requirements txt
2019-06-03 12:41:34 -07:00
Paul Bottein
5085ce8ab1 Add temperature sensor support to google smarthome thermostat device (#24264)
* Add temperature sensor support to google smarthome thermostat device

* fix lint for trait_test

* Reset temperature unit in tests

* Address comment
2019-06-03 12:41:32 -07:00
Robert Svensson
9ed5b70d01 deCONZ migrate to SSDP discovery (#24252)
* Migrate deCONZ to use new SSDP discovery
Add new discovery info manufacturer URL to be able to separate Hue and deCONZ bridges

* Mark deCONZ as migrated in Discovery component

* Fix tests

* Fix Hue discovery ignore deCONZ bridge

* Less snake more badger

* Mushroom

* Fix indentation

* Config flow ignore manufacturer url that is not philips
2019-06-03 12:41:31 -07:00
Paul Bottein
976bf3e979 Add temperature sensor support to google smarthome thermostat device (#24264)
* Add temperature sensor support to google smarthome thermostat device

* fix lint for trait_test

* Reset temperature unit in tests

* Address comment
2019-06-03 12:40:15 -07:00
Paulus Schoutsen
0b70419859 Remove deps folder in config when on Docker (#24284)
* Remove deps folder in config

* Fix tests

* Fix tests with docker check
2019-06-03 12:37:27 -07:00
Paulus Schoutsen
6f903db8c4 Fix cors on the index view (#24283) 2019-06-03 11:43:13 -07:00
Paulus Schoutsen
4c88578371 Add a discovery config flow to Wemo (#24208) 2019-06-03 10:06:53 -07:00
Penny Wood
b1dcfaf6b3 Split devices of nodes with multiple instances (#24032)
* Split devices of nodes with multiple instances

* Note entities to register with device registry

* Use EntityPlatform
2019-06-03 09:40:40 -07:00
Robert Svensson
449a7d3fd5 deCONZ migrate to SSDP discovery (#24252)
* Migrate deCONZ to use new SSDP discovery
Add new discovery info manufacturer URL to be able to separate Hue and deCONZ bridges

* Mark deCONZ as migrated in Discovery component

* Fix tests

* Fix Hue discovery ignore deCONZ bridge

* Less snake more badger

* Mushroom

* Fix indentation

* Config flow ignore manufacturer url that is not philips
2019-06-03 09:26:01 -07:00
Fabian Affolter
7fd2e67d11 Remove icon() (#24280) 2019-06-03 16:31:32 +02:00
Otto Winter
34260ed09f Bump aioesphomeapi to 2.1.0 (#24278)
* Bump aioesphomeapi to 2.1.0

* Update requirements txt
2019-06-03 16:30:29 +02:00
Pascal Vizeli
a00d8a493d Update azure-pipelines.yml for Azure Pipelines 2019-06-03 12:31:31 +02:00
Pascal Vizeli
263c0322ee Update azure-pipelines.yml for Azure Pipelines 2019-06-03 12:31:03 +02:00
Pascal Vizeli
2b0e56932b Update azure-pipelines.yml for Azure Pipelines 2019-06-03 11:51:34 +02:00
Pascal Vizeli
e12cef8d77 Update azure-pipelines.yml for Azure Pipelines 2019-06-03 11:51:14 +02:00
Pascal Vizeli
704cdac874 Bumped version to 0.94.0b5 2019-06-03 08:36:38 +00:00
Paulus Schoutsen
89d7c0af91 Add restore state to Geofency (#24268)
* Add restore state to Geofency

* Lint
2019-06-03 08:35:44 +00:00
Paulus Schoutsen
5f3bcedbba Mobile app device tracker to restore state (#24266) 2019-06-03 08:35:43 +00:00
Paulus Schoutsen
d2d3f27f85 Add restore state to OwnTracks device tracker (#24256)
* Add restore state to OwnTracks device tracker

* Lint

* Also store entity devices

* Update test_device_tracker.py
2019-06-03 08:35:43 +00:00
Paulus Schoutsen
6795db9bd6 Mobile app device tracker to restore state (#24266) 2019-06-03 10:30:56 +02:00
Paulus Schoutsen
6a693546a3 Add restore state to Geofency (#24268)
* Add restore state to Geofency

* Lint
2019-06-03 10:29:45 +02:00
Paulus Schoutsen
a8c73ffb93 Updated frontend to 20190602.0 2019-06-02 14:00:52 -07:00
Paulus Schoutsen
411e36b0f8 Updated frontend to 20190602.0 2019-06-02 13:59:30 -07:00
Isabella Gross Alström
fbfc674ca5 Add service for adding event to google component (#22473)
* Add service for adding event to google component

* Add service examples for google.add_event

* add refactoring based on reviews

* Fix too long lines

* Order import

* Move to move line

* Remove parenthesis

* Add service for adding event to google component

* Add service examples for google.add_event

* add refactoring based on reviews

* Add check for correct scopes, otherwise re-authenticate

* fix build failure

* fix build failure
2019-06-02 13:58:27 -07:00
Paulus Schoutsen
ca20b0cf17 Add restore state to OwnTracks device tracker (#24256)
* Add restore state to OwnTracks device tracker

* Lint

* Also store entity devices

* Update test_device_tracker.py
2019-06-02 13:57:21 -07:00
Pascal Vizeli
05454b76a6 Update azure-pipelines.yml for Azure Pipelines 2019-06-02 22:32:56 +02:00
Pascal Vizeli
b4c858bcdf Update azure-pipelines.yml for Azure Pipelines 2019-06-02 22:31:44 +02:00
Robert Svensson
4d4fd19f87 Replace pyunifi with aiounifi in UniFi device tracker (#24149)
* Replace pyunifi with aiounifi

* Fix tests

* Add sslcontext

* Fix tests

* Fix import order
2019-06-02 18:24:13 +02:00
Pascal Vizeli
16a846b1e7 Update azure-pipelines.yml for Azure Pipelines 2019-06-02 17:09:04 +02:00
Pascal Vizeli
034b0e07d2 Update azure-pipelines.yml for Azure Pipelines 2019-06-02 14:26:12 +02:00
Emilv2
c486f794f9 Fix typo in integration component (#24250) 2019-06-02 01:07:17 -07:00
Franck Nijhof
9220270948 Adds AdGuard Home integration (#24219)
* Adds AdGuard Home integration

* 👕 Addresses linting warnings

* 🚑 Fixes typehint in async_setup_entry

* 👕 Take advantage of Python's coalescing operators

* 👕 Use adguard instance from outer scope directly in service calls

* 👕 Use more sensible scan_interval default for sensors

* 👕 Adds specific files to .coveragerc

*  Added tests and small changes to improve coverage

* 🔨 Import adguardhome dependencies at the top

* 🚑 Converted service handlers to be async

* 🔥 Removed init step from config flow
2019-06-01 22:13:14 -07:00
Paulus Schoutsen
22f68d70a7 Bumped version to 0.94.0b4 2019-06-01 14:34:39 -07:00
Paulus Schoutsen
bf85e18d45 Do not use the cache dir for PIP installs (#24233) 2019-06-01 14:34:27 -07:00
Paulus Schoutsen
09c43e8854 Updated frontend to 20190601.0 2019-06-01 14:34:06 -07:00
Paulus Schoutsen
7be7d3ffac Updated frontend to 20190601.0 2019-06-01 14:27:25 -07:00
Pascal Vizeli
2823ef84db Update azure-pipelines.yml for Azure Pipelines 2019-06-01 22:49:29 +02:00
Maikel Punie
4d07448cf8 Bump python-velbus version for velbus component (#24226)
* Bump python-velbus version

* Bump python velbus version
2019-06-01 13:15:41 -07:00
Austin Mroczek
12d59797a7 Add details to triggered state for total connect alarms (#24106)
* Bump skybellpy to 0.4.0

* Bump skybellpy to 0.4.0 in requirements_all.txt

* Added extra states for STATE_ALARM_TRIGGERED to allow users to know if
it is a burglar or fire or carbon monoxide so automations can take
appropriate actions.  Updated TotalConnect component to handle these new
states.

* Fix const import

* Fix const import

* Fix const imports

* Bump total-connect-client to 0.26.

* Catch details of alarm trigger in state attributes.

Also bumps total_connect_client to 0.27.

* Change state_attributes() to device_state_attributes()
2019-06-01 13:12:58 -07:00
Emilv2
673290d2e1 fix gitlab_ci sad icon (#24241) 2019-06-01 13:08:23 -07:00
kbickar
5a81ddd4e7 Sense update (#24220)
* Changed updates to be done by component and updates dispatched

* syntax updates

* Added code owner

* Removed whitespace

* Updated CODEOWNERS

* Added subscription undoer
2019-06-01 12:15:28 -07:00
Pascal Vizeli
ef820c3126 Update azure-pipelines.yml for Azure Pipelines 2019-06-01 20:07:54 +02:00
Jef D
278b9d0f71 Round Awair sensor values (#24093)
* Round sensor values

* Add code owner

* Update code owners

* Fix tests
2019-06-01 17:03:41 +02:00
Paulus Schoutsen
276ab191b5 Do not use the cache dir for PIP installs (#24233) 2019-06-01 10:04:12 +02:00
Paulus Schoutsen
e5cbf01ce1 Bumped version to 0.94.0b3 2019-05-31 23:05:57 -07:00
Paulus Schoutsen
fe2e5089ab Mobile app to use device tracker config entry (#24238)
* Mobile app to use device tracker config entry

* Lint

* Re-use device_info

* Lint
2019-05-31 23:05:36 -07:00
Teemu R
35ffac1e01 add a deprecation warning for tplink device_tracker (#24236)
* add a deprecation warning for tplink device_tracker

* reword the warning a bit
2019-05-31 23:05:35 -07:00
Paulus Schoutsen
362f23a950 GeoFency unique ID and device info (#24232) 2019-05-31 23:05:35 -07:00
Paulus Schoutsen
dc8d4ac8e4 Add GPSLogger device_info and unique_id (#24231) 2019-05-31 23:05:34 -07:00
Robert Svensson
0cdea28e2a Don't allow more than one config flow per discovered Axis device (#24230) 2019-05-31 23:05:33 -07:00
Paulus Schoutsen
7d1a02feb1 Log HomeKit model (#24229) 2019-05-31 23:05:32 -07:00
Paulus Schoutsen
b90636f640 Update home zone when core config updated (#24237)
* Update home zone when core config updated

* Lint
2019-05-31 23:03:45 -07:00
Paulus Schoutsen
b4374c8c4c Mobile app to use device tracker config entry (#24238)
* Mobile app to use device tracker config entry

* Lint

* Re-use device_info

* Lint
2019-05-31 23:01:45 -07:00
Teemu R
3076866ec6 add a deprecation warning for tplink device_tracker (#24236)
* add a deprecation warning for tplink device_tracker

* reword the warning a bit
2019-05-31 23:00:10 -07:00
Paulus Schoutsen
e6a54013dc GeoFency unique ID and device info (#24232) 2019-05-31 22:59:44 -07:00
Paulus Schoutsen
3edc58a04e Add GPSLogger device_info and unique_id (#24231) 2019-05-31 22:59:35 -07:00
Paulus Schoutsen
70fe4f22db Log HomeKit model (#24229) 2019-05-31 22:59:16 -07:00
Sören Oldag
9f1dc71320 Bump pychromecast (#24234) 2019-05-31 20:49:52 -07:00
Robert Svensson
f43eca248a Don't allow more than one config flow per discovered Axis device (#24230) 2019-05-31 15:51:55 -07:00
Pascal Vizeli
958b894020 Update azure-pipelines.yml for Azure Pipelines 2019-05-31 23:22:37 +02:00
Alexei Chetroi
0ba2b4e253 ZHA requirements version bump. (#24228)
* ZHA requirements version bump.
* zha-quirks version bump.
2019-05-31 17:15:27 -04:00
Pascal Vizeli
1e6b91b05a Update azure-pipelines.yml for Azure Pipelines 2019-05-31 23:10:09 +02:00
Paulus Schoutsen
5c8f209aa7 Bumped version to 0.94.0b2 2019-05-31 13:45:41 -07:00
Phil Bruckner
d966e0cfce Add control of Amcrest indicator light (#23986)
Enable feature by default but allow it to be disabled by "control_light: false" in config.

Get brand from camera instead of assuming Amcrest (since this works with other cameras, too.)

Retrieve RTSP URL in update method instead of in stream_source property and in handle_async_mjpeg_stream method.

Move amcrest imports from methods to global.
2019-05-31 13:41:48 -07:00
Paulus Schoutsen
3eeccc1a65 Add manifest support for homekit discovery (#24225)
* Add manifest support for homekit discovery

* Add a space after model check

* Update comment
2019-05-31 13:40:36 -07:00
Paulus Schoutsen
52e33c2aa2 Use resource for index routing. (#24223) 2019-05-31 13:40:36 -07:00
Pascal Vizeli
35f5784287 Don't follow redirect on ingress itself (#24218)
* Don't follow redirect on ingress itself

* Fix comment
2019-05-31 13:40:35 -07:00
Robert Svensson
46cc6e199b Axis - Handle Vapix error messages (#24215) 2019-05-31 13:40:34 -07:00
Paulus Schoutsen
6371eca14d Improve error handling (#24204) 2019-05-31 13:40:34 -07:00
Paulus Schoutsen
052641e620 Instantiate lock inside event loop (#24203) 2019-05-31 13:40:33 -07:00
Paulus Schoutsen
16edcd9938 Allow discovery flows to be discovered via zeroconf/ssdp (#24199) 2019-05-31 13:40:32 -07:00
Thomas Hervé
4fa6f2e54f Bump oauthlib version (#24111)
* Bump oauthlib version

* Bump fitbit instead

* Update requirements
2019-05-31 13:40:31 -07:00
Paulus Schoutsen
3c1cdecb88 Add manifest support for homekit discovery (#24225)
* Add manifest support for homekit discovery

* Add a space after model check

* Update comment
2019-05-31 11:58:48 -07:00
Robert Svensson
18286dbf4b Axis - Handle Vapix error messages (#24215) 2019-05-31 20:34:06 +02:00
Paulus Schoutsen
3a0616c680 Use resource for index routing. (#24223) 2019-05-31 11:27:05 -07:00
Paulus Schoutsen
440e4289e4 Instantiate lock inside event loop (#24203) 2019-05-31 11:26:05 -07:00
Pascal Vizeli
8fe1a84db2 Update azure-pipelines.yml for Azure Pipelines 2019-05-31 18:49:46 +02:00
Pascal Vizeli
5fa66ba4a3 Update azure-pipelines.yml for Azure Pipelines 2019-05-31 16:46:50 +02:00
Pascal Vizeli
261f3bcba6 Don't follow redirect on ingress itself (#24218)
* Don't follow redirect on ingress itself

* Fix comment
2019-05-31 14:30:58 +02:00
Otto Winter
9be1b72ed7 Fix ESPHome config flow with invalid config entry (#24213) 2019-05-31 11:33:31 +02:00
Otto Winter
5610541515 Fix ESPHome config flow with invalid config entry (#24213) 2019-05-31 11:27:27 +02:00
Pascal Vizeli
bfc8d2457c Update azure-pipelines.yml for Azure Pipelines 2019-05-31 10:57:53 +02:00
Pascal Vizeli
dedc2ef918 Update azure-pipelines.yml for Azure Pipelines 2019-05-31 10:53:34 +02:00
Thomas Hervé
a9c85b9944 Bump oauthlib version (#24111)
* Bump oauthlib version

* Bump fitbit instead

* Update requirements
2019-05-31 09:17:50 +02:00
Robert Van Gorkom
bf91a8c1b3 Fixing tplink issues with offline devices during setup (#23668)
* Fixing tplink issues with offline devices during setup.

* Fixing circleci errors.

* Adding code to defer the creation of entities that are not online.

* Addressing code review changes and cleaning up a little.

* Fixing tests and static analysis.

* Adding test to satisfy coverage requirements.

* Resolving merge conflicts.

* Fixing issue where lights don't appear in the integration page.

* Using pyHS100 properties for most sysinfo.
Addressing some PR feedback.

* Addressing some PR feedback.

* Better testing async_add_entities_retry
Testing for static dimmers.
Making greater use of conf constants.

* Fixing all static analysis issues.

* Adding non-blocking call for getting discovering devices.

* Address PR feedback
2019-05-31 01:51:04 -04:00
Paulus Schoutsen
6f299e7245 Improve error handling (#24204) 2019-05-30 16:23:42 -07:00
Paulus Schoutsen
1ad495070d Bumped version to 0.94.0b1 2019-05-30 14:59:14 -07:00
Paulus Schoutsen
84719d944a Update hass-nabucasa (#24197) 2019-05-30 14:59:08 -07:00
Jc2k
4ca588deae homekit_controller no longer logs with transient network errors causing crypto failures as it will auto recover (#24193) 2019-05-30 14:59:07 -07:00
Otto Winter
325001933d Fix ESPHome discovered when already exists (#24187)
* Fix ESPHome discovered when already exists

* Update .coveragerc
2019-05-30 14:59:07 -07:00
Paulus Schoutsen
acc9fd0382 Dynamic panels (#24184)
* Don't require all panel urls to be registered

* Allow removing panels, fire event when panels updated
2019-05-30 14:59:06 -07:00
Paulus Schoutsen
f32d1c0dea Allow discovery flows to be discovered via zeroconf/ssdp (#24199) 2019-05-30 14:08:05 -07:00
Pascal Vizeli
ca89d6184c Update azure-pipelines.yml for Azure Pipelines 2019-05-30 18:50:47 +02:00
Pascal Vizeli
2bfe7aa219 Update azure-pipelines.yml for check version (#24194) 2019-05-30 18:50:32 +02:00
Paulus Schoutsen
6fcd56c462 Update hass-nabucasa (#24197) 2019-05-30 09:49:21 -07:00
Otto Winter
1ce2d97d3d Fix ESPHome discovered when already exists (#24187)
* Fix ESPHome discovered when already exists

* Update .coveragerc
2019-05-30 09:48:58 -07:00
Pascal Vizeli
04c5cda7e5 Update azure-pipelines.yml for Azure Pipelines 2019-05-30 18:46:08 +02:00
Franck Nijhof
7692cffdbe ✏️ Corrects incorrect command in hassfest (#24188) 2019-05-30 09:41:30 -07:00
Daniel Høyer Iversen
7c093bd928 Update Tibber library (#24192) 2019-05-30 09:41:11 -07:00
Jc2k
bcee3f9570 homekit_controller no longer logs with transient network errors causing crypto failures as it will auto recover (#24193) 2019-05-30 09:40:38 -07:00
Paulus Schoutsen
78ffb6f3e6 Updated frontend to 20190530.0 2019-05-30 09:32:37 -07:00
Paulus Schoutsen
d1aa4f42e5 Updated frontend to 20190530.0 2019-05-30 09:32:29 -07:00
Pascal Vizeli
e7d34913c0 Update azure-pipelines.yml for check version (#24194) 2019-05-30 17:35:47 +02:00
Paulus Schoutsen
1a3a38d370 Dynamic panels (#24184)
* Don't require all panel urls to be registered

* Allow removing panels, fire event when panels updated
2019-05-30 13:37:01 +02:00
Paulus Schoutsen
59ce31f44f No longer allow invalid slugs or extra keys (#24176)
* No longer allow slugs

* Lint

* Remove HASchema

* Lint

* Fix tests
2019-05-30 13:33:26 +02:00
Daniel Høyer Iversen
b3d8f8620c danielhiversen as codeowner for yr (#24189) 2019-05-30 13:16:59 +02:00
Daniel Høyer Iversen
3eebb9d51d upgrade broadlink library, Use cryptography instead of pycryptodome (#24186) 2019-05-30 13:14:50 +02:00
Anders Melchiorsen
b6bb6919e6 Update pysonos to 0.0.14 (#24185) 2019-05-30 09:24:38 +02:00
Paulus Schoutsen
c08862679d Bumped version to 0.94.0b0 2019-05-29 16:01:51 -07:00
Andre Lengwenus
50db622689 Add service calls for LCN component (#24105) 2019-05-29 15:59:38 -07:00
Jc2k
9303a56d8f Fix duplicated discovered homekit devices (#24178) 2019-05-29 15:49:59 -07:00
Paulus Schoutsen
6667138b73 Remove discovery from initial config (#24183) 2019-05-29 15:32:36 -07:00
Pascal Vizeli
d9852bc75d Support Hass.io wheels / docker env (#24175)
* Support Hass.io wheels / docker env

* address comments

* fix lint
2019-05-29 15:30:09 -07:00
Paulus Schoutsen
6aeccf0330 Merge remote-tracking branch 'origin/master' into dev 2019-05-29 15:16:05 -07:00
Anders Melchiorsen
f8572c1d71 Avoid slow updates with unavailable Sonos devices (#24180) 2019-05-29 15:05:12 -07:00
Robert Svensson
e2e001d042 Keep integrations in discovery (#24179)
* Keep integrations that have been migrated to new discovery methods to avoid breaking changes

* Additional migrated services
2019-05-29 14:34:44 -07:00
Paulus Schoutsen
e3307213b1 Deprecate Python 3.5.3 (#24177) 2019-05-29 14:30:00 -07:00
Robert Svensson
84baaa324c Revert Zeroconf back to previously used library (#24139)
* Revert back to previously used library

* Fix test

* Remove unused import

* Fix import

* Update __init__.py

* Update __init__.py

* Fix test after rebase
2019-05-29 14:20:06 -07:00
Robert Svensson
42ee8eef50 Move Homekit controller component to user zeroconf discovery (#24042) 2019-05-29 11:20:04 -07:00
Robert Svensson
3fef9a93cf Trådfri component to use new zeroconf discovery (#24041)
* Move tradfri component to use new zeroconf discovery

* Will this work?

* Remove prints

* Correct order in generated zeroconf

* Update test_init.py

* Update test_init.py

* Update test_init.py

* Update test_init.py
2019-05-29 11:19:50 -07:00
Paulus Schoutsen
4b256f3466 Reinstate passing loop to DSMR (#24127)
* Reinstate passing loop

* Also pass loop into other part
2019-05-29 11:13:29 -07:00
Anders Melchiorsen
bebfc3d16e Remove unused Sonos turn on/off methods (#24174) 2019-05-29 11:12:44 -07:00
Paulus Schoutsen
fd3902f7e7 update translations 2019-05-29 10:16:58 -07:00
Paulus Schoutsen
dfb992adb2 Updated frontend to 20190529.0 2019-05-29 09:41:35 -07:00
Robbie Trencheny
a252065f99 Fix calling notify.notify with mobile_app targets in play. Fixes #24064 (#24156) 2019-05-29 09:09:24 -07:00
Paulus Schoutsen
6947f8cb2e Cloud: Websocket API to manage Google assistant entity config (#24153)
* Extract exposed devices function

* Add might_2fa info to trait

* Do not filter with should_expose in Google helper func

* Cloud: allow setting if Google entity is exposed

* Allow disabling 2FA via config

* Cloud: allow disabling 2FA

* Lint

* More changes

* Fix typing
2019-05-29 08:39:12 -07:00
Morten Trab
85dfea1642 Add Repetier-Server Component (#21658)
* Bumped to version 2.0

* Updated requirements

* Updated requirements and coveragerc

* Removed long lines, changes to coveragerc and requirements

* Fixed under-indented lines

* Fixed invalid syntax

* Updated .coveragerc to include repetier/__init__.py and sensor.py

* Module update

* Rebased to latest dev

* Blank lines fix

* Add missing manifest.json

* Update requirements

* Bumped component to new API module style

* Removed whitespaces and line feeds

* Added missing newline

* Added missing heated chamber sensor

* Fixed wrong indentation

* Various fixes

* Various build fixes

* Clean up

* Load platform only once

* Sort imports

* Add printer api

* Clean up

* Build out sensor classes

* Clarify temperature sensor variable names

* Move constants

* Clean up name

* Run script/gen_requirements_all.py

* Working code, missing auto add of new sensors

* Updated code to return proper device_class and timestamp

* Removed unnessecary code

* Renamed elapsed and remaining sensors

* Dynamically adding sensors as they become available

* Rebased .coveragerc due to conflicts

* Code changes and cleanup

* Removed whitespace and code simplification
2019-05-29 08:31:04 -04:00
Otto Winter
015c8811a5 Use global imports for ESPHome (#24158)
* Use global import for ESPHome

* Add aioesphomeapi to test requirements

aioesphomeapi is also shipped as a pure-python wheel, so this should not impact test install time
2019-05-29 13:33:49 +02:00
Robbie Trencheny
d9c78b77cb Use device name for device_tracker entry (#24155) 2019-05-28 19:52:47 -07:00
chmielowiec
1b543cf538 Upgrade huawei-lte-api to 1.2.0 (#24165) 2019-05-28 19:51:07 -07:00
Alexei Chetroi
9fb8144031 Debug log when polling ZHA light. (#24167) 2019-05-28 19:50:48 -07:00
William Scanlon
f2033c418f Pubnub to 1.0.6 (#24159) 2019-05-28 12:09:30 -04:00
William Scanlon
aa266cb630 pubnubsub-handler to 1.0.5 (#24154) 2019-05-27 22:09:05 -04:00
Sylvia van Os
9a5d783537 Don't crash on first EAN without installations (#24137)
* Don't crash on first EAN without installations

* Remove duplicated values

* Switch from Exception to persistent notification

* Make pylint happy
2019-05-27 22:36:15 +02:00
Jesse Rizzo
5800b57791 bump dependency envoy_reader to 0.4 (#24145)
* bump envoy_reader version to 0.4

* bump dependency envoy_reader to 0.4
2019-05-27 19:48:00 +02:00
maheus
c840771c0a Add station name for creating the unique_id in netatmo platform (#24141) 2019-05-27 18:07:59 +02:00
Julien Brochet
9678752480 Retrieve wire and wireless devices with the SRM device tracker (#24117) 2019-05-27 18:00:21 +02:00
Robert Svensson
31b2f331db Library refactorization of deCONZ (#23725)
* Improved sensors

* Lib update signalling

* Replace reason with changed

* Move imports to top of file

* Add support for secondary temperature reported by some Xiaomi devices

* Bump dependency to v59
2019-05-27 06:56:00 +02:00
jjlawren
0ba54ee9b7 Use central polling to update entities (#24059)
* Use central polling to update entities

* Fix for line length

* Remove unnecessary import

* Use interval

* Trigger entity refreshes after commands

* Lint
2019-05-26 21:39:50 -07:00
Bram Kragten
5c86a51b45 Lovelace: Fire event on save (#24104)
* Lovelace: Fire event on save

* Add event to whitelist
2019-05-26 20:27:07 -07:00
Paulus Schoutsen
9debbfb1a8 Add SSDP integration (#24090)
* Add SSDP integration

* Fix tests

* Sort all the things

* Add netdisco to test requirements
2019-05-26 19:48:27 -07:00
Anders Melchiorsen
97b671171b Avoid useless Sonos state updates (#24135) 2019-05-26 12:49:26 -07:00
Paulus Schoutsen
179fb0f3b5 Use importlib metadata to check installed packages (#24114)
* Use importlib metadata

* Fix script

* Remove unused import

* Update requirements"
2019-05-26 11:58:42 -07:00
David Bonnes
96b7bb625d geniushub: fix sensor battery level, and bump client (#24123)
* Initial commit

* bump client
2019-05-26 14:01:29 +02:00
Eduard van Valkenburg
afeb13d980 Azure Event Hub history component (#23878)
* v1 of Azure Event Hub History component

* updates to EH

* small fix

* small updates and changed requirements_all

* new version of Event Hub component

* redid config to just ask names

* small edit

* latest version of EH component

* updated codeowners

* codeowner fix

* typo in domain

* updates based on reviews.

* using built-in jsonencoder for DT

* delete unused import
2019-05-26 13:55:40 +02:00
jgriff2
6e1728542e Add Remote RPi Component (#23518)
* Add Remote RPi Component

* Add Remote RPi Component

* fix imports

* Added support for setup as switch and binary_sensor

* remove pylint error handling

* Changed to domain config

* Changed to domain config

* Changed to domain config

* Changed to domain config

* Update __init__.py

* Update manifest.json

* Update requirements_all.txt

* Update switch.py

* Update binary_sensor.py

* Changed to domain config
2019-05-26 13:52:06 +02:00
Otto Winter
9438dd1cbd Use name in ESPHome discovery title (#24100)
* Use name in ESPHome discovery title

* Add test

* Lint
2019-05-26 13:48:05 +02:00
Andrew Sayre
0194905e97 Move imports to top (#24108) 2019-05-26 13:47:11 +02:00
jjlawren
25505dc1d4 Remove custom entity_id naming (#24072)
* Remove custom entity_id naming

* Set entity_ids with 'plex'

* Set name instead of entity_id

* Lint

* Use a name template
2019-05-26 12:28:29 +02:00
Jardi Martinez
ce219ac6c7 Set assumed_state property to True. (#24118) 2019-05-26 12:26:51 +02:00
cgtobi
fa20957e01 Bump pyatmo version to 1.12 (#24088) 2019-05-26 12:09:02 +02:00
Robin Wohlers-Reichel
7959c04d1e Solax Inverter Sensor Component (#22579)
* Solax inverter direct API

* Linter compliance

* lint++

* move api communication to external lib

* lint++

* requirements

* Revert "requirements"

This reverts commit 82a6c0c095.

* potentially?

* Addressing review comments

* Also update CODEOWNERS

* Only update sensor state if data has changed
2019-05-25 21:55:30 -05:00
Paulus Schoutsen
e6d7f6ed71 Config entry device tracker (#24040)
* Move zone helpers to zone root

* Add config entry support to device tracker

* Convert Geofency

* Convert GPSLogger

* Track unsub per entry

* Convert locative

* Migrate OwnTracks

* Lint

* location -> latitude, longitude props

* Lint

* lint

* Fix test
2019-05-25 13:34:53 -07:00
Alex Bahm
144b530045 Issue #23514 - fix invalid hue response (#23909)
Based on the discoveries in issue #23514, the periodic lack of response from emulated hue was due to an invalid value (null) being returned.
2019-05-25 13:07:23 -07:00
Kevin Fronczak
39ba99005a Fix broken blink motion detection (#24097) 2019-05-25 17:58:44 +02:00
Simon Nørager Sørensen
f867b025e5 Update code owner for Xiaomi TV (#24102)
* Update code owner

* Update CODEOWNERS
2019-05-25 17:57:16 +02:00
Andre Lengwenus
c928f82cbf Refactoring of LCN component (#23824)
* Moved helper functions to const.py

* Removed pypck attribute from LcnDevice

* Bump to pypck==0.6.0

* Added myself as a codeowner

* Moved helper functions to helpers.py
2019-05-25 11:40:44 +02:00
Joakim Plate
9d7aa8f05d Remove device tracker unnecessary separate except clause (#24081)
Handle exception where it can be thrown.
2019-05-25 11:29:19 +02:00
Daniel Høyer Iversen
02f927ae2d typo for ambiclimate (#24083) 2019-05-25 09:26:46 +02:00
Jardi Martinez
1d022522cd MCP23017 (#23127)
* Added support for MCP23017 I2C GPIO extender.

* Updated .coveragerc to exclude mcp23017 component from tests.

* Generated CODEOWNERS for mcp23017 usign script.

* Removed .svn folder that had been accidentally uploaded.

* Added link to www.home-assistant.io docs in manifest.json

* Fixed logic error in switch platform.

* Cleaned up code and removed unnecessary should_poll() function.

* Limited the options for pull mode to UP and DOWN

* Fixed line too long in binary sensor.

* Fixed line too long on switch.py

* Changed to setup_platform.

* Reorder constants
2019-05-25 08:09:53 +02:00
terual
bad9ac5395 Fix Hue bridge timeout (#24084)
* Change timeout from 5 seconds to 10 seconds
Underpowered platforms timeout during configuration/discovery of a Hue bridge on a new install. Increasing this timeout fixes this.
2019-05-24 15:55:13 -07:00
Joakim Plate
e9f561e7ab Adjust logging (#24082)
* Make sure we log full path to debug log

* Make sure we log the exception to debug log
2019-05-24 15:54:04 -07:00
Jeff Irion
14d169558f Add 'adb_response' attribute to Android TV / Fire TV (#23960)
* Add 'adb_response' attribute to Android TV / Fire TV

* Use None instead of empty string for empty ADB responses

* Initialize self._adb_response as None, not empty string

* Update the state after sending an ADB command

This ensures that the `'adb_response'` attribute contains the response to the latest command
2019-05-24 18:43:35 -04:00
P0L0
ca2a68217d Added possibility to define the data type of Homematic (#24078)
* Homematic: Added possibility to define the data type for set_device_value

* Fixed coding style

* Fixed variable name
2019-05-24 17:28:45 +02:00
dreed47
0a9a8ecc4e Update the name of Zestimate sensors (#23770)
* Zestimate: fix for issue #23757
Changed name property to return Zestimate
and the property address.  This will make it easier
distinguish multiple Zestimate sensor entities
in the UI.

Also removed MIN_TIME_BETWEEN_UPDATES in
favor of SCAN_INTERVAL per suggestion from
amelchio#9580 on Discord

* Zestimate fix for issue #23757

Changed name property to return Zestimate
and the property address.  This will make it easier
distinguish multiple Zestimate sensor entities
in the UI.

* Changed name property to return Zestimate
and the property address.  This will make it easier
distinguish multiple Zestimate sensor entities
in the UI.

* moved code fix to the correct function

* removed code change from unique_id function
2019-05-24 16:01:55 +02:00
Daniel Høyer Iversen
6cef850497 Rfxtrx, add data types (#24066)
* Rfxtrx, add data types

* fix style
2019-05-24 09:46:59 +02:00
Paulus Schoutsen
66af4bd011 Fix zeroconf sorting (#24068) 2019-05-23 14:41:57 -07:00
Jeff Irion
03253f4598 Better logging of method used for ADB connection (#24037) 2019-05-23 13:57:00 -07:00
Fredrik Erlandsson
aa5d8e5a81 Daikin airbase beta fixes (#24050)
* values are strings not integers

* pydaikin version bump
2019-05-23 13:55:22 -07:00
Paulus Schoutsen
206029eadc Update translations 2019-05-23 13:32:35 -07:00
Paulus Schoutsen
958c5ecbfe Updated frontend to 20190523.0 2019-05-23 13:32:16 -07:00
Troels Agergaard Jacobsen
3d79bf2bfe Fix entity id naming when not using first install (#23606)
* Fix entity id naming when not using first install

Currently, the verisure component will use the alias of the first
installation to decide entity id of the alarm_control_panel even though
a different installation is configured through a specified giid. This
fixes that

* Fixed pulled request review comments

* Remove trailing whitespace

* Fix remaining pylint errors
2019-05-23 19:27:42 +02:00
Paulus Schoutsen
1de0a0bbb9 Convert stream source to method (#23905)
* Convert stream source to method

* Use async with
2019-05-23 09:45:30 -07:00
jjlawren
8d22479d24 Always update all Plex client types (#24038) 2019-05-23 14:00:41 +02:00
Daniel Høyer Iversen
7f7435f003 Add support for available property for broadlink (#23981)
* Add support for available property for broadlink

* Broadlink, except oserror

* Broadlink, except oserror
2019-05-23 09:52:30 +02:00
Pascal Vizeli
d2eb5bb0f3 [skip ci] Update azure-pipelines.yml for Azure Pipelines 2019-05-23 09:46:40 +02:00
Robert Svensson
085303c349 ESPHome component to use zeroconf discovery (#24043)
* Move ESPHome component to use zeroconf discovery

* Remove esphome from discovery component
2019-05-23 08:55:08 +02:00
Daniel Høyer Iversen
9ac6f906ff Update ambiclimate library (#24049) 2019-05-23 08:53:38 +02:00
Paulus Schoutsen
f995ab9d54 Don't pass in loop (#23984)
* Don't pass in loop

* Revert some changes

* Lint + Axis revert

* reinstate loop

* Fix a test

* Set loop

* Update camera.py

* Lint
2019-05-22 21:09:59 -07:00
Paulus Schoutsen
77f595c9a4 Merge pull request #24047 from home-assistant/rc
0.93.2
2019-05-22 20:34:12 -07:00
Paulus Schoutsen
8d0b1588be Bumped version to 0.93.2 2019-05-22 20:00:34 -07:00
Daniel Høyer Iversen
70c5c82541 upgrade broadlink library (#23966) 2019-05-22 20:00:12 -07:00
Cyro
bf910ef383 Make Discord payload data key not required (#23964) 2019-05-22 20:00:11 -07:00
Julien Brochet
99c49c0993 Setup integration dependencies before loading it (#23957) 2019-05-22 20:00:10 -07:00
Joakim Sørensen
f6e6c21ba6 Fixes issue with multiple alerts (#23945)
* Fixes issue with multiple alerts

* Adds missing new line

* Remove whitespace
2019-05-22 20:00:10 -07:00
Joakim Sørensen
41b7f5ab1c Bump pytraccar (#23939) 2019-05-22 20:00:09 -07:00
Pascal Vizeli
c5bd6b3d6b Fix auto version update Hass.io (#23935) 2019-05-22 20:00:08 -07:00
Paulus Schoutsen
9e96397e6a Require core config detection to be triggerd manually (#24019)
* Detect core config

* Remove elevation

* Lint

* Lint

* Fix type
2019-05-22 17:24:46 -07:00
Fabian Affolter
f207e01510 Upgrade Mastodon.py to 1.4.2 (#24004)
* Upgrade Mastodon.py to 1.4.2

* Update
2019-05-22 23:05:03 +02:00
Daniel Høyer Iversen
6b3bb3347b Ambiclimate test, mock (#24034) 2019-05-22 15:00:05 +02:00
Paulus Schoutsen
806903ffe0 Downgrade Hue warning (#24033) 2019-05-22 14:59:16 +02:00
zewelor
fdf1fa48e3 Improve yeelight imports (#24020)
* Improve yeelight imports

* Move import on top

* Fix lint
2019-05-21 22:47:10 -04:00
Robert Svensson
636077c74d Zeroconf discovery for config entries (#23919)
* Proof of concept

* Follow comments

* Fix line length and bad imports

* Move imports to top

* Exception handling for unicode decoding
Create debug print for new service types
Add empty test files

* First try at a test

* Add type and name to service info
Fix static check

* Add aiozeroconf to test dependencies
2019-05-21 15:36:26 -07:00
David Bonnes
e047e4dcff bump geniushub-client to 0.4.9 (#24022) 2019-05-21 15:57:24 -04:00
Tyler Page
eae306c3f1 Fix iterating over NoneType exception (#23648)
* Fix iterating over NoneType exception

When self._dark_sky is None, don't try to return self._dark_sky.units

* Fix wrong check
2019-05-21 08:26:11 -04:00
David Bonnes
fbd7c72283 Add geniushub sensors for issues (#23976)
* Inital commit

* delint - use new string formatting
2019-05-21 08:23:38 -04:00
Erik Montnemery
fc58746bc3 Add websocket API for updating core config (#24009)
* Add websocket API for updating core config
2019-05-21 07:21:31 +02:00
Erik Montnemery
9ae878d8f2 Update CODEOWNERS (#24015) 2019-05-21 07:20:23 +02:00
Erik Montnemery
afe9fc221e Fire event when core config is updated (#23922)
* Fire event when core config is updated
2019-05-20 20:02:36 +02:00
Robert Svensson
eb912be47a Axis IO-port support (#23312)
Support digital inputs and supervised inputs, digital outputs and relays
2019-05-20 07:45:31 +02:00
Paulus Schoutsen
5c346e8fb6 Update owner frontend integrations [skip ci] (#24001) 2019-05-20 05:01:02 +02:00
Greg Dowling
8d388c5e79 Bump loopenergy library version - catches runtime exception. (#23989)
* Bump loopenergy library version - catches runtime exception.

* Update requirements_all.
2019-05-19 12:51:10 -04:00
Fredrik Erlandsson
314574fc84 daikin version bump (#23991) 2019-05-19 12:49:03 -04:00
Paulus Schoutsen
e356d0bcda Better handle file not found when loading YAML (#23908)
* Better handle file not found

* Lint
2019-05-19 12:01:29 +02:00
Penny Wood
f991ec15f2 Delete devices / entities when we remove a config entry. (#23983)
* Remove device when last config entry removed

* Remove entities when config entry removed

* Update tests to use new behaviour
2019-05-19 11:41:39 +02:00
Tomer Figenblat
d7d83c683d Updated non-blocking timout to 10 seconds for fixing timeout issues. (#23930)
* Updated non-blocking timout to 10 seconds for fixing timeout issues.

* Added failed bridge fixture for faster unit tests.
2019-05-19 11:24:59 +02:00
Joakim Sørensen
ff867a7d57 Use the timezone defined in Home Assistant when making the API call (#23284)
* Use HA defined timezone

* Cleanup

* Use homeassistant.util.dt.now to get the correct time.

* Update homeassistant/components/vasttrafik/sensor.py

Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io>
2019-05-19 11:23:55 +02:00
Charles Garwood
1282370ccb Entity Cleanup on Z-Wave node removal (#23633)
* Initial groundwork for entity cleanup on node removal

* Connect node_removed to dispatcher

* update docstring

* Add node_removal test

* Address review comments

* Use hass.add_job instead of run_coroutine_threadsafe
2019-05-19 11:14:11 +02:00
András Rutkai
eebd094423 Adding Watson TTS (IBM Cloud) (#23299)
* Adding Watson TTS (IBM Cloud)

* Code review changes
2019-05-18 23:05:59 +02:00
Joakim Sørensen
57bd4185d4 Fixes issue with multiple alerts (#23945)
* Fixes issue with multiple alerts

* Adds missing new line

* Remove whitespace
2019-05-18 22:59:33 +02:00
Martin Donlon
91ba35c68e Update russound_rio dependency to version 0.1.7 (#23973)
v0.1.7 fixes async import issues in python 3.7+
2019-05-18 22:56:34 +02:00
Cyro
a99e15343c Make Discord payload data key not required (#23964) 2019-05-18 13:14:53 -07:00
Daniel Høyer Iversen
4583638b92 upgrade broadlink library (#23966) 2019-05-18 13:14:11 -07:00
Matt Snyder
10a1b156e3 Doorbird Refactor (#23892)
* Remove schedule management. Allow custom HTTP events defined in the configuration

* Consolidate doorbird request handling.  Make token a per device configuration item.

* Lint fixes

* Do not register dummy listener

* Remove punctuation
2019-05-18 21:46:00 +02:00
Daniel Høyer Iversen
a8286535eb Upate xiaomi voltage parser, fix #23898 (#23962) 2019-05-18 11:01:30 +02:00
Adrian Schröter
05146badf1 show battery level also when vacuum has no map support (#23947) 2019-05-18 10:27:05 +02:00
Josef Schlehofer
c483e4479e Update requests to 2.22.0 (#23958) 2019-05-17 20:41:22 -05:00
Julien Brochet
4a70c725b4 Setup integration dependencies before loading it (#23957) 2019-05-17 19:17:26 -05:00
SiliconAvatar
33ed017851 Add unit of measurement to Tautulli sensor (#23873)
Adds unit of measurement ("Watching") to sensor, so it can be graphed properly.
This is the same unit of measurement as the Plex sensor.
2019-05-17 23:02:56 +02:00
Joakim Sørensen
fffc4dd3fd Bump pytraccar (#23939) 2019-05-17 09:56:04 -04:00
bouni
e072981295 Added support for sensor other than temperature and humidity (#23863)
* Added support for sensor other than temperature and humidity

* fixed lint errors

* fixed minor issues pointed out by @fabaff
2019-05-17 09:47:10 +02:00
Pascal Vizeli
5d983d0b61 Fix auto version update Hass.io (#23935) 2019-05-17 09:39:36 +02:00
Fredrik Erlandsson
727f667cbc Fix fan rates for Daikin (#23860) 2019-05-17 09:36:47 +02:00
Fredrik Erlandsson
1b4fc2ae8d Fix for non existing Daikin zones (#23792) 2019-05-17 09:25:07 +02:00
Jc2k
5b0d1415ad Have homekit_controller use device registry (#23874)
* Add device registry support

* HK doesn't use mac as a connection id
2019-05-17 08:41:20 +02:00
Paulus Schoutsen
7818c98c67 Merge pull request #23932 from home-assistant/rc
0.93.1
2019-05-17 08:03:45 +02:00
Paulus Schoutsen
e12222697c Bumped version to 0.93.1 2019-05-17 06:35:20 +02:00
karlkar
58f28f177d Fix problem with cameras that don't support time (#23924)
Some onvif cameras don't support Date management. In that case None is returned and script crashes when trying to obtain date
2019-05-17 06:35:09 +02:00
Joakim Plate
6030e419c5 Switch media player to SWITCH type (#23914)
MEDIA device type is being rejected by google now.
2019-05-17 06:33:20 +02:00
Paulus Schoutsen
8d2a784831 Update Honeywell warning (#23913) 2019-05-17 06:33:20 +02:00
Pascal Vizeli
5dc841ecae Fix Hassio-version for Azure Pipelines (#23895) 2019-05-17 06:33:19 +02:00
karlkar
edf34eea94 Fix problem with cameras that don't support time (#23924)
Some onvif cameras don't support Date management. In that case None is returned and script crashes when trying to obtain date
2019-05-17 06:29:52 +02:00
Paulus Schoutsen
a303f67d3b Merge branch 'master' into dev 2019-05-17 06:28:36 +02:00
Aaron Bach
1b5f526e09 Fix additional IQVIA data bug (#23931) 2019-05-16 18:30:09 -06:00
Jc2k
03a0a3572b Fix icons for homekit_controller sensors (#23921) 2019-05-16 22:30:48 +01:00
Aaron Bach
297d24c5b0 Fix bug when IQVIA API fails to return data (#23916)
* Fix bug when IQVIA API fails to return data

* Updated requirements

* Fixed tests

* Linting

* Removed impossible case

* Removed extraneous comment
2019-05-16 15:19:53 -06:00
Joakim Plate
c8cf06b8b7 Switch media player to SWITCH type (#23914)
MEDIA device type is being rejected by google now.
2019-05-16 22:34:40 +02:00
David McNett
49d6d7c656 Version bump insteonplm to 0.15.4 (#23918)
* Version bump insteonplm to 0.15.4

* Package-level version change
2019-05-16 22:34:06 +02:00
Robbie Trencheny
96fd874090 Add @Kane610 to zeroconf CODEOWNERS 2019-05-16 12:28:24 -07:00
Paulus Schoutsen
c9703872e2 Update Honeywell warning (#23913) 2019-05-16 13:21:38 -06:00
Robbie Trencheny
2f5d7d4522 [WIP] Simplify zeroconf (#23890)
* Simplify zeroconf

* Remove unused imports
2019-05-16 12:04:20 -07:00
Daniel Høyer Iversen
7716e8fb68 Netatmo, handle offline device (#23907)
* Netatmo, handle offline device

* style
2019-05-16 18:07:37 +02:00
Erik Montnemery
c2fc8a0d61 Load HA core config from storage (#23872)
* Load HA core config from storage

* Tweak

* Lint, review comments

* Fix test

* Add tests

* Lint

* Address comments
2019-05-16 16:27:53 +02:00
Markus Jankowski
9be384690a Enable Homematic IP cloud climate device with HeatingThermostat only (#23776)
* Enable climate device with HeatingThermostat only

* Fix after review
2019-05-16 15:10:30 +02:00
Jc2k
692eeb3687 Fix ecobee 3 homekit pairing (#23882) 2019-05-16 14:32:13 +02:00
Pascal Vizeli
213c91ae73 Update azure-pipelines.yml for Azure Pipelines 2019-05-16 09:28:08 +02:00
Pascal Vizeli
36b1a89f93 Fix Hassio-version for Azure Pipelines (#23895) 2019-05-16 08:57:43 +02:00
Paulus Schoutsen
584bfbaa76 Merge pull request #23864 from home-assistant/rc
0.93.0
2019-05-16 07:08:27 +02:00
Paulus Schoutsen
0f140751b2 Fix PS4 blocking startup (#23893) 2019-05-16 05:43:45 +02:00
Paulus Schoutsen
6b359c95da Fix PS4 blocking startup (#23893) 2019-05-16 05:43:19 +02:00
starkillerOG
1fec64a1b3 Update Pynetgear to v0.6.1 (#23886)
* Update Pynetgear to v0.6.1

* update pynetgear to v0.6.1
2019-05-15 23:53:02 +02:00
Paulus Schoutsen
70ed58a78d Restructure device tracker (#23862)
* Restructure device tracker

* Docstyle

* Fix typing

* Lint

* Lint

* Fix tests
2019-05-15 23:43:45 +02:00
Pascal Vizeli
6aa9844f8f Fix auto discovery if the monitor condition (#23880) 2019-05-15 16:28:35 +02:00
Pascal Vizeli
7a4238095d Fix auto discovery if the monitor condition (#23880) 2019-05-15 16:27:41 +02:00
Paulus Schoutsen
177594f02c Update sensor.py 2019-05-15 14:00:42 +02:00
Ville Skyttä
cf89f45697 Fix homekit test assert no messages (#23856) 2019-05-15 13:13:56 +02:00
Penny Wood
2dc78e6f0c Take code owner for sun.sun (#23877)
* Take code owner

* Post hassfest
2019-05-15 03:14:35 -05:00
Penny Wood
9da74dda43 Quiet the chatty sun.sun (#23832)
* Split up method to allow caching event

* Lower frequency of updates.

* Code review patches.

* Minor changes to test

* Skip end of period at fixed multiple of delta.
Improved documentation.
2019-05-15 15:02:29 +08:00
David Bonnes
18149dcb8c Add geniushub sensor and binary_sensor (#23811)
* Initial commit

* add lastComms and de-lint

* dummy commit

* dummy commit 2

* refactor to temp in favour of battery

* back to battery, and no temp

* use snake_case

* Bump client

* only v3 API exposes device attributes

* delint

* delint2

* Change GeniusSwitch to GensiusBinarySensor
2019-05-14 23:30:26 +02:00
Pascal Vizeli
3f841a36a5 Update azure-pipelines.yml for Azure Pipelines
Automated version updates
2019-05-14 22:59:12 +02:00
damarco
80ae02cc49 Fix zha timed off (#23849) 2019-05-14 13:41:27 +02:00
Paulus Schoutsen
421b2962c6 Bumped version to 0.93.0 2019-05-14 13:18:36 +02:00
Paulus Schoutsen
bde5a9ef01 Bumped version to 0.93.0b4 2019-05-14 13:12:30 +02:00
Robbie Trencheny
b79886ad85 Fix improper usage of body attribute on web.Response. Should be text since we arent sending bytes (#23857) 2019-05-14 13:12:24 +02:00
Paulus Schoutsen
94a2fd542e Fix aiohttp response serialize (#23858)
* Fix aiohttp response serialize

* Suport bytes

* Handle None
2019-05-14 11:59:27 +02:00
Paulus Schoutsen
6fa8556033 Use Cloudhooks for OwnTracks (#23847)
* Use Cloudhooks for OwnTracks

* Update config_flow.py

* Update config_flow.py
2019-05-14 11:59:11 +02:00
Pascal Vizeli
19cfa8cf22 Update azure-pipelines.yml for Azure Pipelines
Automated version updates
2019-05-14 10:18:01 +02:00
Paulus Schoutsen
a859997190 Allow deletion of automations and scripts (#23845) 2019-05-14 09:16:36 +02:00
Robbie Trencheny
6f9860b25e Fix improper usage of body attribute on web.Response. Should be text since we arent sending bytes (#23857) 2019-05-14 09:12:05 +02:00
Paulus Schoutsen
f083abbed1 Bumped version to 0.93.0b3 2019-05-14 07:19:37 +02:00
David F. Mulcahey
4dd8423b9b bump zha-quirks (#23855) 2019-05-14 07:19:31 +02:00
David F. Mulcahey
8ba2ab567e Fix ZHA battery when readings produce an unknown value (#23854)
* check for unknown readings

* only publish valid readings

* remove unused constant
2019-05-14 07:19:30 +02:00
David F. Mulcahey
3d821b9148 Correct ZHA illumination conversion (#23853)
* fix illumination values

* correct formula

* update illuminance calculation

* update test
2019-05-14 07:19:30 +02:00
Jason Hunter
04720175b9 fix onvif wsdl import - take 2 (#23807) 2019-05-14 07:19:29 +02:00
Alexei Chetroi
93ad7b2e45 Do not add coordinator to the ZHA entities. (#23803) 2019-05-14 07:19:28 +02:00
David F. Mulcahey
128ce589e1 Correct ZHA illumination conversion (#23853)
* fix illumination values

* correct formula

* update illuminance calculation

* update test
2019-05-14 07:16:41 +02:00
David F. Mulcahey
9b21774392 Fix ZHA battery when readings produce an unknown value (#23854)
* check for unknown readings

* only publish valid readings

* remove unused constant
2019-05-14 07:16:21 +02:00
David F. Mulcahey
eaf4a75402 bump zha-quirks (#23855) 2019-05-14 07:15:31 +02:00
Paulus Schoutsen
a1a6d4a631 Updated frontend to 20190514.0 2019-05-14 07:14:40 +02:00
Paulus Schoutsen
de1fd5a7fa WS: Improve service calling errors (#23840)
* WS: Improve service calling errors

* Docstyle

* Types

* Update text
2019-05-14 07:09:11 +02:00
Paulus Schoutsen
9b12dd66e4 Updated frontend to 20190514.0 2019-05-14 07:08:06 +02:00
Robert Svensson
0d96095646 Zeroconf - replace library (#23835)
* Use aiozeroconf in preparation for new zeroconf discovery

* Update requirements

* Remove sleep

* Make stop zeroconf a coroutine

* Remove unused import

* Fix aiozeroconf dependency in default_config tests
2019-05-14 05:58:13 +02:00
Paulus Schoutsen
45085dd97f Better handle large amounts of data being sent over WS (#23842)
* Better handle large amounts of data being sent over WS

* Lint
2019-05-14 05:57:47 +02:00
sander76
b2a1204bc5 Fix for battery device: new_device referenced before assignment. (#23793)
* Fix for battery device: new_device referenced before assignment.

* Fix buttons and switches mixup

* Update __init__.py

* Update binary_sensor.py

* Update __init__.py

* Update __init__.py

* Update binary_sensor.py

* Update __init__.py

* Update binary_sensor.py

* typo and indentation fixes

* low_bat and lowbat to uppercase.
2019-05-13 20:52:55 +02:00
damarco
990a9e80a2 Fix zha timed off (#23849) 2019-05-13 13:13:57 -04:00
Fredrik Erlandsson
0ffcc197d4 Daikin adaptions for AirBase units (#23734)
* updated list of supported fan_modes

* AirBase units does not support Holiday-mode

* AirBase units does not support outside temp

* pydaikin version bump

* don't modify constant
2019-05-13 15:38:33 +02:00
Baptiste Candellier
1a051f038d Add new SmartHab light and cover platform (#21225)
* Add SmartHab platform

* Remove url config entry, improve error handling

* Upgrade smarthab dependency

* Address comments

* Lint
2019-05-13 03:35:31 -07:00
Paulus Schoutsen
1e22c8daca Automatically generate config flow list (#23802)
* Add config flow to manifest.json

* Still load config flows via config flow platform

* Fix typo

* Lint

* Update config_flows.py"

* Catch import error when setting up entry

* Lint

* Fix tests

* Fix imports

* Lint

* Fix Unifi tests

* Fix translation test

* Add homekit_controller config flow
2019-05-13 01:16:55 -07:00
Jc2k
b8cbd39985 HomeKit Controller: Adopt config entries for pairing with homekit accessories (#23825)
* Fix user initiated pairing + show more user friendly name

* Add lock around async_refresh_entity_map

* Migrate homekit_controller to config entries.

* Improve docstring

Co-Authored-By: Martin Hjelmare <marhje52@kth.se>

* Add dummy async_setup_platform

* add_service -> async_add_service

* Add missing returns

* Enable coverage checks for homekit_controller
2019-05-12 23:56:05 -07:00
Paulus Schoutsen
3508622e3b Remove badges from README [skipci] (#23815) 2019-05-12 23:55:16 -07:00
Paulus Schoutsen
b8f6d824fd Catch import error when processing config (#23833) 2019-05-12 23:54:55 -07:00
akloeckner
e687848152 Make broadlink switch restore its state (#23829)
* Make broadlink switch restore its state

Method copied from pilight switch

* style
2019-05-12 19:28:33 +02:00
David Bonnes
2a9fd9ae26 Add incomfort climate and bump client (#23830)
* Initial commit

* bump client for bugfix

* bump client for bugfix 2

* de-lint
2019-05-12 13:40:10 +02:00
Paulus Schoutsen
3ec4070d8c Fix patching right import (#23816) 2019-05-11 19:29:29 +02:00
mvn23
6f8038992c Bump pyotgw to 0.4b4, fix Opentherm Gateway name in manifest.json (#23810) 2019-05-11 16:15:35 +02:00
Fabian Affolter
5c9a58f3e6 Upgrade youtube_dl to 2019.05.11 (#23808) 2019-05-11 16:15:09 +02:00
Stephen Benjamin
d34214ad32 Bump venstarcolortouch to v0.7 (#23806) 2019-05-11 10:33:18 +02:00
Andre Lengwenus
2b7021407c Add LCN climate platform (#22542)
* Add LCN climate component

* Updates of ha_state are done async

* Changes due to manifest.json
2019-05-11 10:24:02 +02:00
Jason Hunter
03cd4480df fix onvif wsdl import - take 2 (#23807) 2019-05-10 23:15:21 -07:00
Alexei Chetroi
910825580e Do not add coordinator to the ZHA entities. (#23803) 2019-05-10 18:57:08 -04:00
Paulus Schoutsen
6d40980de1 Bumped version to 0.93.0b2 2019-05-10 14:32:51 -07:00
Anders Melchiorsen
d4f79fc88a Synchronize Sonos service calls (#23791) 2019-05-10 14:32:43 -07:00
Paulus Schoutsen
2d724f5cc9 Updated frontend to 20190510.0 2019-05-10 14:23:09 -07:00
Paulus Schoutsen
c8d479e594 Updated frontend to 20190510.0 2019-05-10 14:22:38 -07:00
Anders Melchiorsen
34f6245e74 Synchronize Sonos service calls (#23791) 2019-05-10 22:37:03 +02:00
Paulus Schoutsen
e9ea5c2ccb Move tests to right folder (#23790)
* Move tests to right folder

* Fix test leaving files behind
2019-05-10 13:20:50 -07:00
David Bonnes
4347a0f6b7 Centralize geniushub updates (#23764)
* add hub/parent/manager

* add hub/parent/manager 2

* working now

* delint

* add back water heater

* make water_heater a child

* make water_heater a child - delint

* make water_heater a child - delint 2

* improve turn_on logic, and small tidy-up

* improve turn_on logic 2

* improve turn_on logic 3 - better docstring

* improve turn_on logic 3 - better docstring

* remove unnecessary DICT.get()s

* remove unnecessary DICT.get()s 2

* code tidy-up

* de-lint

* refactor for GeniusData

* refactor for GeniusData 2

* code tidy-up

* add missing should_poll = False
2019-05-10 18:34:28 +02:00
Paulus Schoutsen
5888e32360 Add support for an external step in config flow (#23782)
* Add support for an external step in config flow

* Types

* Lint
2019-05-10 14:33:49 +02:00
Andrey Kupreychik
4214a354a7 Bumped keenetic NDMS2 client version (#23786) 2019-05-10 11:43:43 +02:00
Pascal Vizeli
61ed604fda Bump version 0.93.0b1 2019-05-10 06:17:26 +00:00
Paulus Schoutsen
f17259c705 Updated frontend to 20190509.0 2019-05-10 06:16:54 +00:00
Jason Hunter
d5533cc10f Beta Fix: ONVIF (#23787)
* bump package to include wsdl

* update requirements all
2019-05-10 06:16:02 +00:00
dreed47
e6c5cc92d1 Fix for issue #23739. Added unique_id property so (#23769)
that entities will always get mapped to the same
property ZPID code.
2019-05-10 06:16:00 +00:00
cgtobi
0caa27094e Bump pyatmo to v1.11 (#23766) 2019-05-10 06:16:00 +00:00
Steven Looman
01578f78f1 Sort discovered entries by 'st' to ensure getting the same device each discovery (#23763) 2019-05-10 06:15:59 +00:00
Paulus Schoutsen
369afd7ddd Update sensor.py 2019-05-09 22:01:37 -07:00
dreed47
281445917b Fix for issue #23739. Added unique_id property so (#23769)
that entities will always get mapped to the same
property ZPID code.
2019-05-09 20:18:28 -07:00
Jason Hunter
df6846344d Beta Fix: ONVIF (#23787)
* bump package to include wsdl

* update requirements all
2019-05-09 20:17:55 -07:00
Steven Looman
05960fa29c Sort discovered entries by 'st' to ensure getting the same device each discovery (#23763) 2019-05-09 16:17:46 -07:00
Pawel
068749bcbe fix two times creating JWT headers. (#23777) 2019-05-09 16:13:13 -07:00
Paulus Schoutsen
f21f32778f Updated frontend to 20190509.0 2019-05-09 15:49:12 -07:00
sander76
8ef3c6d4d3 Add battery binary sensor to homematic (#23067)
* first proposal

* parameter rename

* retrigger CI

* remove separate binary sensor

* remove batter_sensor

* battery device distinction at binary sensor discovery
2019-05-09 10:38:51 -07:00
Joakim Plate
c7a78ed522 Add stepped volume to demo (#23759)
* Add stepped volume to demo

* Simplify somewhat to avoid extra check
2019-05-09 10:18:22 -07:00
Aaron Bach
45adb5c9c7 Add config entry for IQVIA (#23765)
* Add config entry for IQVIA

* Updated tests and requirements

* Removed unnecessary dependency

* Fixed tests

* Reverted unintended change
2019-05-09 09:11:51 -07:00
Ties de Kock
4004867eda Split up yaml loaders into multiple files (#23774)
* Start moving parts of yaml utils to own module

Move parts of yaml loader out of the single large file and start
to create the structure of the yaml loaders in Ansible [0].

[0]: https://github.com/ansible/ansible/tree/devel/lib/ansible/parsing/yaml

* Finish yaml migration, update tests and mocks

  * Move code around to finish the migration
  * Update the mocks so that `open` is patched in
    `homeassistant.util.yaml.loader` instead of
    `homeassistant.util.yaml`.
  * Updated mypy ignores
  * Updated external API of `homeasistant.util.yaml`, see below:

Checked what part of the api of `homeassistant.util.yaml` was actually
called from outside the tests and added an `__ALL__` that contains only
these elements.

Updated the tests so that references to internal parts of the API (e.g.
the yaml module imported into `homeassistant.util.yaml.loader`) are
referenced directly from `homeassistant.util.yaml.loader`.

In `tests/test_yaml.py` the import `yaml` refers to
`homeassistant.util.yaml` and `yaml_loader` refers to `~.loader`.

Future work that remains for the next iteration is to create a custom
SafeConstructor and refers to that instead of monkey patching `yaml` with
custom loaders.

* Update mocks in yaml dumper, check_config
2019-05-09 09:07:56 -07:00
Markus Jankowski
118d3bc11c Add Presence Detector Indoor to Homematic IP (#23755)
* Add presence detector indoor

use device classes constants

* Add illuminance

* isort
2019-05-09 09:57:02 +02:00
cgtobi
0e9d71f232 Bump pyatmo to v1.11 (#23766) 2019-05-08 21:08:07 -07:00
Paulus Schoutsen
b552fbe312 Version bump to 0.94.0.dev0 2019-05-08 20:23:31 -07:00
Paulus Schoutsen
07b7d7b074 Bumped version to 0.93.0b0 2019-05-08 20:22:36 -07:00
Paulus Schoutsen
fb7343ecd2 Merge remote-tracking branch 'origin/master' into dev 2019-05-08 20:22:08 -07:00
Paulus Schoutsen
e51925fc58 Update translations 2019-05-08 20:20:58 -07:00
Paulus Schoutsen
d507adf13d Updated frontend to 20190508.0 2019-05-08 20:20:26 -07:00
Pascal Vizeli
c5230f7585 Update azure-pipelines.yml for Azure Pipelines 2019-05-08 23:47:01 +02:00
Paulus Schoutsen
cc13713abd No longer rely on requests (#23685)
* No longer rely on requests

* Lint

* Missed a few parts

* Fix types

* Fix more types

* Update __main__.py

* Fix tests

* Lint

* Fix script
2019-05-08 11:15:04 -07:00
Josef Schlehofer
f019e2a204 Upgrade zeroconf to 0.22.0 (#23524) 2019-05-08 08:40:00 -07:00
Jerry Chong
07126266dd Update Sesame component to use Candy House's library using the V3 API (#23621)
* Update Sesame component to use Candy House's library using the V3 API

* Updated requirements_all.txt

* Fix pylint warning

* Revert back to ATTR_DEVICE_ID
2019-05-08 08:34:00 -07:00
Martin Hjelmare
c26af22edd Refactor child validation (#23482)
* Try to make the process more readable and paritioned.
* Validate child values using set message.
* Only validate using relevant schemas.
* Extract node validation.
* Rework const types and schemas.
* Rework child validator.
* Enhance warning logging message.
2019-05-08 08:26:40 -07:00
Ville Skyttä
c384adeef4 Upgrade defusedxml to 0.6.0 (#23651) 2019-05-08 08:04:36 -07:00
Penny Wood
7f0953766b Prompt for pin only on open / unlock (#23751)
* Prompt for pin only on open / unlock

* Fixed test cases
2019-05-08 07:55:30 -07:00
Pascal Vizeli
ce1974b014 Update azure-pipelines.yml for Azure Pipelines 2019-05-08 16:02:19 +02:00
carstenschroeder
8822f0140d New cover platform for ADS integration (#23377)
* new cover platform

* improve logging II

* remove dependencies

* fix comment

* fix review findings
2019-05-08 14:08:26 +02:00
Fabian Affolter
45c041884a Upgrade Mastodon.py to 1.4.0 (#23753) 2019-05-08 11:20:22 +02:00
Fabian Affolter
1ecb3de643 Upgrade numpy to 1.16.3 (#23673) 2019-05-08 09:17:41 +02:00
cgtobi
f0f6787bf9 Merge netatmo_public sensor into the netatmo integration (#23531)
* Merge netatmo public into netatmo integration

* Remove netatmo_public platform

* Remove dev log messages

* Improve error handling

* Check config for unsupported conditions

* Fix linter

* Reduce nested blocks
2019-05-08 08:26:52 +02:00
Paulus Schoutsen
3e788aa1d6 Updated frontend to 20190507.0 2019-05-07 22:55:59 -07:00
Paulus Schoutsen
f4016b4aad Add integration step to onboarding (#23732)
* Return an extra oauth2 auth code during onboarding

* Areas in const

* Add integration step

* Lint

* Fix tests

* Fix test

* Verify integration added to done

* Verify step is marked as done
2019-05-07 22:51:24 -07:00
Paulus Schoutsen
07ee3b2eb9 Add update events to registries (#23746)
* Add update events to registries

* Add to websocket
2019-05-07 20:04:57 -07:00
Steven Looman
6e7a7ba4a0 Fix upnp logger name (#23724)
* Fix upnp logger name

* Fix more loggers
2019-05-07 15:52:48 -07:00
David Bonnes
7181d639fd Add Intergas InComfort Lan2RF gateway (#23736)
* fixed __init__.py

* add sensors

* switch to parent-child architecture

* make binary_sensor the parent

* revert parent - to water_heater

* first working version

* working, delinted (except TODO)

* update to latest client library

* remove debug code

* delint

* tweak device_state_attributes

* tweak device_state_attrbutes

* minor tweaks

* bump client library for bugfix

* improve state attributes for pumping

* update .coverage

* bugfix - binary sensors not updating

* rename to incomfort from intouch

* fix coveragerc regression

* bump client (bugfix for /protected URL)

* bump client (bugfix for /protected URL) 2

* bump client

* remove debug code

* ready for PR

* fix regression

* use xx._boiler instead of xx._objref

* improve current_temperature and delint

* use current_operation instead of state

* refactor vol.Schema

* remove unneeded instance attribute

* remove unneeded instance attribute 2

* refactor device_state_attributes

* change 'boiler' to 'heater'

* change 'boiler' to 'heater' 2

* correct a typo

* bugfix: add missing comma

* small tidy-up
2019-05-07 23:53:55 +02:00
Paulus Schoutsen
0f174250cc Update PR template (#23520)
* Update PR template

* Update config, PR template
2019-05-07 14:18:40 -07:00
Maciej Bieniek
16a27c3f2d Add abbreviation for position_topic (#23740) 2019-05-07 22:20:55 +02:00
Fabian Affolter
b253c7499d Upgrade aiodns to 2.0.0 (#23743) 2019-05-07 15:32:04 -04:00
Markus Jankowski
264e70922b Fix effects on HUE integration for Osram bulbs (#22789)
* Fix hue effect for others

* New suggestion

* switched implementation to remove colorloop for osram bulbs

* Check ATTR_EFFECT in kwargs

* Fix  tests
2019-05-07 09:53:14 -07:00
Richard Mitchell
482cb0146a Fix Hue sensor integration with multiple bridges. (#23713) 2019-05-07 09:45:04 -07:00
Andrew Sayre
02d8731a61 Add HEOS sign-in/out services (#23729)
* Add HEOS sign-in/out services

* Fix typo in comment
2019-05-07 09:39:42 -07:00
Erik Montnemery
102beaa044 Add debug prints to sun (#23598)
* Add debug prints to sun

* Review comment
2019-05-07 09:37:08 -07:00
David Bonnes
6611d585e6 Add water_heater to geniushub, bump client library (#23384)
* add water_heater

* add geniushub/water_heater.py

* de-lint

* de-lint 2

* remove temperature from device state attribs

* update to latest client library

* add me as CODEOWNER

* bump client

* bump client

* delint/refactor

* Update homeassistant/components/geniushub/water_heater.py

Co-Authored-By: zxdavb <david@bonnes.me>
2019-05-07 17:37:47 +02:00
unixko
f386088def add abbreviation for current_temperature_template (#23733) 2019-05-07 08:27:35 +02:00
rolfberkenbosch
c07c557298 Added new binary sensor meteoalarm to get weather alerts in Europe (#23663)
* Added new component meteoalarm

* Update sensor.py

* Update manifest.json

* Update manifest.json

* Update manifest.json

* Added file CODEOWNERS

* Modified some code, thanks @amelchio

* removed Throttle because is not being used anymore

* Update _attributes ad _state

* some cleanup

* Update sensor.py

Change sensor to binarysensor

* Rename sensor.py to binary_sensor.py

rename the file

* Update binary_sensor.py

Removed BinarySensorDevice from class

* Update binary_sensor.py

Made a mistake with BinarySensorDevice

* Update binary_sensor.py

clean up white spaces

* Update binary_sensor.py

Fix BinarySensorDevice

* Update binary_sensor.py

cleanup the import libs

* modified __init__

* fix

* final fix, thanks @amelchio

* forgot to change the sensor.py

* correct some typo in text

* fix typos

* fix another typo

* fix typo
2019-05-07 08:19:29 +02:00
Pawel
1f551e5f6f Add TTL support and custom headers support. (#22988)
* Add TTL custom support and custom headers support.

* fix pywebpush version

* removed whitespaces surrounding docstrings.

* fixes for tests

* priority option to data

* checking of ATTR_ENDPOINT

* change checking of target to vol.Schema

* more tests
2019-05-06 16:37:05 -07:00
Fabian Affolter
b60c815cde Share snmp constants across all platforms (#23678)
* Share constants across all platforms

* Update .coveragerc
2019-05-06 23:31:03 +02:00
Andrew Sayre
074142400a Fix SmartThings Samsung Air Conditioner Support (#23706)
* Bump pysmartthings to 0.6.8

* Fix AC climate device

* Fix stale comment
2019-05-06 10:21:16 -07:00
Daniel Høyer Iversen
d8a219fe0e Upgrade switchbot , fixes #23702 (#23716) 2019-05-06 10:18:50 -07:00
William Scanlon
a0230482bd Use the URL provided by the Wink API for subscriptions. (#23710)
* Use the URL provided by the Wink API for subscriptions.

* Changed python-wink version
2019-05-06 10:18:17 -07:00
Ville Skyttä
b9a72034f9 huawei_lte: handle icons for None sensor values gracefully (#23649) 2019-05-06 10:15:28 -07:00
Andrew Sayre
bf649e373c Update IDs after firmware upgrade in HEOS (#23641)
* Initial work

* Update tests
2019-05-06 17:53:11 +02:00
David F. Mulcahey
73aadbe8bc bump zha-quirks (#23714) 2019-05-06 08:35:11 -04:00
Fabian Affolter
e2afeca4fd Upgrade sendgrid to 6.0.5 (#23711) 2019-05-06 07:13:16 -05:00
Fredrik Erlandsson
0dfa5f9ffd Use local constant in Daikin for STATE_OFF (#23712) 2019-05-06 13:43:35 +02:00
Fabian Affolter
b331b081f0 Catch thethingsnetwork TypeError (#23667)
* Catch TypeError (fixes #23097)

* Re-add return values

* Update homeassistant/components/thethingsnetwork/sensor.py

Co-Authored-By: fabaff <mail@fabian-affolter.ch>
2019-05-06 09:47:46 +02:00
Andrew Sayre
cf03e42773 Bump pyheos to 0.5.2 (#23708) 2019-05-06 07:07:41 +02:00
droopanu
f87209605b Add a TCP timeout of 5 seconds to ffmpeg (#23617)
Add a TCP timeout of 5 seconds to ffmpeg to fix stream getting stuck when network connectivity is lost
https://github.com/home-assistant/home-assistant/issues/22741
2019-05-05 20:59:56 -04:00
ktnrg45
3e59e7f347 Add media_type_app to media_player (#23666)
* Add media_type_app

* Add MEDIA_TYPE_APP

* Bump 0.7.3

* Bump 0.7.3

* Bump 0.7.3

* typo
2019-05-05 18:53:08 -05:00
David F. Mulcahey
3dd1d3c418 Add additional single input cluster entries - ZHA (#23697)
* more profiles

* remove from binary sensor profile

* remove sensor profile mapping
2019-05-05 19:10:19 -04:00
Alexei Chetroi
8328ea6bd7 Bump ZHA modules versions. (#23705)
* Bump ZHA modules versions.

Bump bellows-homeassistant version.
Bump zigpy-homeassistant version.
Bump zigpy-xbee-homeassistant version.

* Update requirements_*.txt
2019-05-05 17:15:34 -04:00
Fredrik Erlandsson
9c1bbd1d9d Add support for SET_AWAY_MODE and TURN_ON/OFF on Daikin Climate (#23585)
* add support for on/off on daikin climate

* add support for away mode on daikin climate
2019-05-05 15:17:01 -05:00
Martin Hjelmare
8500244f8c Move owntracks device tracker test under owntracks (#23701) 2019-05-05 21:39:51 +02:00
Anders Melchiorsen
2efc1de349 Move Sonos services to sonos domain (#23670) 2019-05-05 14:25:57 -05:00
Martin Hjelmare
4796d674e6 Clean up device tracker tests (#23695)
* Clean up device tracker tests

* Fix async load config in device tracker tests.
* Clean up lint in device tracker tests.
* Sort device tracker tests imports.
* Patch config saving in device tracker tests.
* Rename fixture.
* Rename some tests that had long cryptic names.

* Replace calls  to device_tracker.async_setup
2019-05-05 14:14:46 -05:00
Martin Hjelmare
4fe0cd76f8 Clean up mqtt device tracker tests (#23700)
* Move mqtt device tracker test under mqtt dir

* Patch config file load and save

* Clean up

* Sort imports

* Put expected value last in assertions
2019-05-05 11:50:38 -07:00
Julius Mittenzwei
c0f9ccfdbb Update requirements for pyvlx. (#23694) 2019-05-05 19:19:35 +02:00
Martin Hjelmare
b9fda078a4 Clean and fix google calendar tests (#23608)
* Clean and fix google calendar tests

* Extract test calendar constant for google test
* Rewrite google calendar tests
* Clean and fix google calendar tests
* Clean and fix google component tests
* Add google conftest
* Skip flaky google calendar test

* Fix google calendar bug

* Fix yield fixture

* Set fixture names to avoid lint warning

* Fix yield fixture
2019-05-05 18:38:55 +02:00
Austin Drummond
e24d56aa5b Add HomeKit Television functionality (#22968) 2019-05-05 17:51:47 +02:00
UgaitzEtxebarria
8da600adff Add Bizkaibus, Biscays (Spain) bus service component (#22934)
* Updated to the current version of dev

* Added the component to .coveragerc

* Added __init__.py and manifest.json

* Changed the manifest to comply the json format

* Changes in for complete the PEP8 Code

* Fixed the api call to use PyPI package

* Fixed API correrct call

* Fixes for complete the requirements

* Added dependencies in manifest.json

* Changed the __init__.py to complete PEP8

* Simplified the __init__.py

* Runned codeowner script

* executed gen_requirements_all.py

* Direct call for dicts and unit changed to minutes

* Fixed the optional dict call, sorry, my bad, I did not that

* Deleted unused vars

* Changed optional parameter to required

* Remove blank first line
2019-05-05 11:00:15 +02:00
Fabian Affolter
9712bbc91c Upgrade spotcrime to 1.0.4 (fixes #13189) (#23679) 2019-05-05 07:29:04 +02:00
Fabian Affolter
fca0891320 Upgrade pysnmp to 4.4.9 (#23677) 2019-05-05 07:26:13 +02:00
Aaron Bach
1d2c5cb53c Remove extraneous update call in SimpliSafe (#23680) 2019-05-04 17:32:33 -06:00
Fabian Affolter
c309bd9ff0 Upgrade sqlalchemy to 1.3.3 (#23674) 2019-05-05 01:06:47 +02:00
Fabian Affolter
2f416b15c5 Upgrade tapsaff to 0.2.1 (#23676) 2019-05-05 00:07:55 +02:00
Fabian Affolter
85cd4ad022 Upgrade slacker to 0.13.0 (#23672) 2019-05-05 00:06:39 +02:00
Fabian Affolter
c8690865ec Upgrade shodan to 1.13.0 (#23675) 2019-05-05 00:05:01 +02:00
Fabian Affolter
8d8d2b6de9 Upgrade psutil to 5.6.2 (#23671) 2019-05-05 00:04:04 +02:00
SNoof85
97b5a38cb1 Bump pyteleloisirs version (#23661)
* Bump pyteleloisirs version

* requirements update
2019-05-04 12:53:06 +02:00
Geert van Horrik
8fc30569a9 Fix bad request for some IP ONVIF camera (#22972)
* Onvif camera improvements using zeep

* Fix static code checks

* Make obtain_input_uri async

* Convert several methods to async

* Fix static checks

* Fix static checks

* Fix requirements_all.txt

* Lint improvements

* Async services

* Use onvif-zeep-async and check if PTZ service is available before creating it

* Remove some hacks that are now defined in onvif-zeep-async

* Don't log input, it might contain sensitive information

* Static code analysis fixes

* Run requirements stuff

* Fix

* Remove suds requirement

* Onvif camera improvements using zeep

* Fix static code checks

* Make obtain_input_uri async

* Convert several methods to async

* Fix static checks

* Fix static checks

* Fix requirements_all.txt

* Lint improvements

* Async services

* Use onvif-zeep-async and check if PTZ service is available before creating it

* Remove some hacks that are now defined in onvif-zeep-async

* Don't log input, it might contain sensitive information

* Static code analysis fixes

* Run requirements stuff

* Fix

* Remove suds requirement

* Use dt_util.utcnow

* Platform setup should not have a return value

* Remove explicit dependency to zeep[async]

* Bump onvif-zeep-async to 0.1.2

* Update requirements_all.txt

* Add exception handling

* Fix static checks

* Don't catch generic exceptions

* Update camera.py
2019-05-03 10:01:12 -07:00
ThaStealth
0702407fac Added option to select photoblack cartridge (#23433)
* Added option to select photoblack cartridge

* Update sensor.py

* Name change
2019-05-03 18:57:41 +02:00
Robert Svensson
6e34015420 deCONZ - Retry on BridgeBusy errors (#23436) 2019-05-03 17:55:42 +02:00
Philippe Delodder
df9a9a1fec Add "soc-thermal 1" as CPU Temp label to Glances (#23635) 2019-05-03 15:43:51 +02:00
Daniel Høyer Iversen
9761c504eb update switchbot library (#23643) 2019-05-03 08:46:19 -04:00
Andrew Sayre
b30afde8ab Extend play_media support (#23580) 2019-05-02 19:54:36 -05:00
David Bonnes
6130831a43 Refactor evohome to prepare for water_heater (#23489)
* refactor - add const.py, change order of propertys, methods

* import client at top of file

* remove debug line

* de-lint

* delint

* add me as CODEOWNER

* remove lint hint

* delint
2019-05-03 01:43:19 +02:00
Penny Wood
3338f5c9b4 Further patch to fix of #22890 (#23627) 2019-05-02 14:05:16 -07:00
Paulus Schoutsen
592e99947d Convert frontend to do client-side modern JS detection (#23618)
* Convert frontend to do client-side async pick

* Further cleanup

* Updated frontend to 20190502.0

* Fix template caching

* Remove es5 test

* Lint

* Update description
2019-05-02 13:59:24 -07:00
Max
7331eb1f71 Allow removing Telegram reply keyboard (#23467)
*  Allow removing telegram reply keyboard by setting `keyboard` to an empty list

* Telegram keyboard: [] clearing in services.yaml
2019-05-02 15:14:40 -04:00
Ville Skyttä
f434e24252 Upgrade mypy (#23586)
* Upgrade mypy to 0.701

* Enable strict equality checks

* Strict equality error fixes

* StateMachine.is_state docstring fix
2019-05-02 21:18:20 +03:00
Ville Skyttä
b79d71065c Upgrade pytest to 4.4.1 (#23584) 2019-05-02 21:17:36 +03:00
Ville Skyttä
0a75a2c080 Clean up redundant same-package ..package imports (#23587) 2019-05-02 20:11:37 +03:00
Pascal Vizeli
41357965de Update azure-pipelines.yml for Azure Pipelines 2019-05-02 19:00:39 +02:00
Jc2k
1e6babe796 Loosen discovery config validation to avoid breaking changes (#23625)
* Allow optional service handlers to be promoted to config flow without a breaking change

* Updated wording

* Remove period
2019-05-02 16:57:42 +02:00
Daniel Høyer Iversen
04b680d9d0 Updgrade Tibber library (#23630)
* update tibber library

* update tibber library
2019-05-02 16:03:51 +02:00
Fabian Affolter
5267635d2c Polling is default (#23622) 2019-05-02 16:00:32 +02:00
Fabian Affolter
a6b898d702 Order imports (#23623) 2019-05-02 08:36:41 -04:00
Fabian Affolter
5c413eb497 Update docstrings (#23624) 2019-05-02 08:35:22 -04:00
Magnus Brange
21575938ef Prevent turning on tellduslive lights with 0 brightness (#23135)
* Prevent turning on tellduslive lights with 0 brightness

It was possible for the light compontent to get in a state where the last_brightness was set to zero, and when turning on (by calling turn_on) it would call the TellStick with 0 dim level, ergo not turning on the light.

With this, it will fall back on a 75% dim level if the level is set to zero.

* Wrap long log line over two lines

And using a more proper way of formatting the message

* Fallback to 100% instead of 75%
2019-05-02 12:53:32 +02:00
Pascal Vizeli
a7ef1eabb0 Update azure-pipelines.yml for Azure Pipelines 2019-05-02 10:29:16 +02:00
Pascal Vizeli
6124a6f7e5 Update azure-pipelines.yml for Azure Pipelines 2019-05-02 10:04:44 +02:00
Pascal Vizeli
d4ae73ce38 Merge pull request #23620 from home-assistant/rc
0.92.2
2019-05-02 09:49:23 +02:00
Brett T. Warden
2fbf29cda6 Update pyvesync_v2 version to 0.9.7 (#23603) 2019-05-02 09:48:22 +02:00
Erik Montnemery
3c5abcc71a Improve sun automation tests (#23588)
* Improve sun automation tests

* Lint

* Restore timezone after test
2019-05-02 09:46:32 +02:00
Martin Hjelmare
447440adc3 Clean caldav calendar tests (#23609) 2019-05-02 09:46:12 +02:00
Aaron Bach
daa1d103d4 Add support for flow sensor metrics in RainMachine (#23221)
* Initial commit

* In the clear
2019-05-02 09:45:51 +02:00
Paulus Schoutsen
58cde6b497 Bumped version to 0.92.2 2019-05-01 22:43:25 -07:00
Andrew Sayre
741d0fd09b Bump pyheos (#23616) 2019-05-01 22:43:17 -07:00
Robbie Trencheny
bc9548fdaf Fix unexpected error thrown if instance_domain is not set (#23615) 2019-05-01 22:43:17 -07:00
ehendrix23
35e9505ad5 Fix authentication issue (#23600)
Update to pymy1 version 1.2.1 to fix authentication issue
2019-05-01 22:43:16 -07:00
Klaas Schoute
38aa7d2c95 Fix problem with using Traccar event (#23543) 2019-05-01 22:43:15 -07:00
Pascal Vizeli
55a7ea6cc5 Fix media_player alexa power control bug (#23537) 2019-05-01 22:43:14 -07:00
Paulus Schoutsen
04bca7be6b Only include agent user ID in SYNC responses (#23497) 2019-05-01 22:43:14 -07:00
Paulus Schoutsen
8180797d2f Fix Hue sensors returning None value (#23478) 2019-05-01 22:43:13 -07:00
Erik Montnemery
0fe573ecc0 Fix cleanup of dynamic group (#23475) 2019-05-01 22:43:12 -07:00
Erik Montnemery
185595c113 Bump pychromecast (#23463) 2019-05-01 22:43:12 -07:00
cgtobi
ffdf48b15a Fix netatmo_public sensor to use netatmo authentication (#23455) 2019-05-01 22:43:11 -07:00
David Bonnes
fa4264be3f update geniushub client library to fix issue #23444 (#23450) 2019-05-01 22:43:10 -07:00
Steven Looman
c7a34d0222 Don't create connections between sensors. Fixes #22787 (#23202) 2019-05-01 22:43:09 -07:00
Robbie Trencheny
e054d68565 Further improve IndieAuth redirect_uri lookup failure logs (#23183) 2019-05-01 22:43:08 -07:00
Andrew Sayre
f3925b7ede Bump pyheos (#23616) 2019-05-01 22:39:59 -07:00
Robbie Trencheny
d1e44e35df Fix unexpected error thrown if instance_domain is not set (#23615) 2019-05-01 22:35:12 -07:00
Jc2k
0fe21f2015 Support STATE_AUTO in homekit_controller climate (#23583) 2019-05-01 22:44:54 -05:00
Aaron Bach
75abfd49ef Fixed unhandled exception in OpenUV data update (#23611) 2019-05-01 21:15:10 -06:00
4lloyd
f0c582ebbd Added message to data_template at notify REST (#23108)
* Added message to data_template at notify rest

* Added missing newlines
2019-05-01 17:04:05 -06:00
Jc2k
7ff77936ad Add and improve Homekit controller pairing messages and errors (#23532)
* Be clear about pairing code format

* Handle more homekit errors while pairing

* Update en translation

* Fix log message feedback
2019-05-01 17:02:29 -06:00
teliov
44d0d0624b updated manifest.json with correct version of hangup (#23596) 2019-05-01 17:02:03 -06:00
Paul Madden
a8c7804db2 Update bomradarloop to v0.1.3 (#23599) 2019-05-01 17:00:40 -06:00
Cyro
beb678e259 Move I/O to executor thread pool (#23589)
* Move I/O to executor thread pool

* Check if image is in whitelist_external_dir

* Move import to top of file

* Fix bad indentation
2019-05-01 17:00:17 -06:00
ehendrix23
d9d5c91adc Fix authentication issue (#23600)
Update to pymy1 version 1.2.1 to fix authentication issue
2019-05-01 16:05:35 -06:00
Daniel Høyer Iversen
19aee50bbc Ambiclimate (#22827)
* Ambiclimate

* Ambiclimate

* style

* Add config flow to ambicliamte

* Add config flow to ambicliamte

* update requirements_all.txt

* ambiclimate

* tests

* typo

* ambiclimate

* coverage

* add manifest.json

* services

* codeowner

* req

* ambicliamte

* style

* ambicliamte

* add to requirements all tests

* add to requirements all tests

* .coveragerc

* Add tests

* add doc

* style

* fix test

* update tests

* update tests

* update tests

* update tests

* update tests

* tests

* tests

* fix comment
2019-05-01 22:05:40 +02:00
Pascal Vizeli
bb6300efe3 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 21:49:08 +02:00
Markus Jankowski
dd53434742 Redesign AlarmControlPanel for Homematic IP (#23565)
* redesign AlarmControlPanel

* Fix lint

* Fixes after review
2019-05-01 21:35:57 +02:00
cdce8p
db2904624a Fix low_battery_threshold issue HomeKit (#23593) 2019-05-01 16:48:56 +02:00
Pascal Vizeli
d3cbd5b5e4 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 16:46:15 +02:00
Ville Skyttä
f9205d0ccc Simplify Travis cache config (#23592) 2019-05-01 16:08:57 +02:00
Pascal Vizeli
127cc5f942 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 14:49:12 +02:00
Pascal Vizeli
ab60235811 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 14:47:38 +02:00
Pascal Vizeli
7faa061b29 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 14:42:52 +02:00
Pascal Vizeli
c7d49a0c6a Update azure-pipelines.yml for Azure Pipelines 2019-05-01 14:38:51 +02:00
Pascal Vizeli
ac731a817a Update azure-pipelines.yml for Azure Pipelines 2019-05-01 14:28:35 +02:00
Pascal Vizeli
f0a34ddf46 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 14:23:54 +02:00
Pascal Vizeli
918ce74b26 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 14:14:26 +02:00
Pascal Vizeli
e8f496c016 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 14:09:34 +02:00
Pascal Vizeli
9b57075c3b Update azure-pipelines.yml for Azure Pipelines 2019-05-01 13:58:43 +02:00
William Scanlon
09cd302b46 Bumpped the pyeconet version (#23578) 2019-05-01 12:28:37 +02:00
Pascal Vizeli
bf25b74bf1 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 11:04:11 +02:00
Pascal Vizeli
3269da16f6 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 11:01:51 +02:00
Pascal Vizeli
0a428868fe Update azure-pipelines.yml for Azure Pipelines 2019-05-01 10:14:51 +02:00
Pascal Vizeli
8cfc316e06 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 10:06:08 +02:00
Pascal Vizeli
31e3c563b5 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 09:57:21 +02:00
Pascal Vizeli
f28ca34307 Update azure-pipelines.yml for Azure Pipelines 2019-05-01 09:56:09 +02:00
Pascal Vizeli
09296b4fd4 Set up CI with Azure Pipelines
[skip ci]
2019-05-01 09:54:48 +02:00
Fabian Affolter
0b9302ac3d Upgrade youtube_dl to 2019.04.30 (#23579) 2019-05-01 08:31:24 +02:00
Penny Wood
5b9d01139d render_with_collect method for template (#23283)
* Make entity_filter be a modifiable builder

* Add render_with_collect method

* Use sync render_with_collect and non-class based test case

* Refactor: Template renders to RenderInfo

* Freeze with exception too

* Finish merging test changes

* Removed unused sync interface

* Final bits of the diff
2019-05-01 10:54:25 +08:00
etheralm
581b16e9fa Fix failing state update tests (#23575) 2019-04-30 16:47:40 -07:00
Jc2k
1c4367e5a9 Fix min/max temp and humidity for homekit_controller climate (#23421)
* Fix min/max temp and humidity for homekit_controller climate.

* Fix typo
2019-05-01 00:08:30 +02:00
Penny Wood
b0843f4a38 Ptvsd debugger component. (#23336)
* ptvsd debugger component.

* Add test case

* ptvsd as test dependency

* Fix for 3.5

* Fixed bootstrap test

* Use dict direct lookup.

* Don't need to load dependencies.

* Get the test working.

* 3.5 fix

* Set mock return value

* Put tests back, but skip them

* Change log level
2019-05-01 00:07:34 +02:00
Jonas Pedersen
24060e0fb5 Add bypass and automatic bypass switch for Danfor Air. (#23572)
Add bypass and automatic bypass switch for Danfoss Air
2019-04-30 23:07:49 +02:00
Martin Hjelmare
5ded0dd3fa Update mysensors sensor icons (#23491)
* Add some icons.
* Sort sensor types according to mysensors serial api numbering.
2019-04-30 23:06:44 +02:00
Mike Miller
09012e7baa Always pad mac addresses from nmap tracker with leading zeros (#23492) 2019-04-30 22:43:21 +02:00
Cyro
75a2c057f2 Upgrade discord.py to v1.0.1 (#23523) 2019-04-30 22:12:39 +02:00
Sylvia van Os
603e2cd961 Essent sensor (#23513)
* Initial commit for Essent

* Cleanup Essent component

* Update CODEOWNERS

* Move stuff to PyEssent

* Update requirements_all

* Fix PyEssent

* Move meter list to PyEssent library

* Update requirements_all

* Only check for updates once an hour

* Use PyEssent 0.10

* Fixing up Essent component

* Fix crash

* Don't add unused meter/tariff combos

* Fix lint

* Get tariffs per meter

* Don't hammer Essent API

* Fix linting errors

* Fix old description

* Fix old call

* Cleanup Essent component
2019-04-30 21:02:16 +02:00
Andrew Sayre
cfaaae661a Add core APIs to migrate device identifiers and entity unique_id (#23481)
* Add device identifiers migration

* Add entity unique_id migration

* Update per arch issue

* Move to existing update methods
2019-04-30 10:04:37 -07:00
David F. Mulcahey
41f0066e76 bump zha-quirks version (#23568) 2019-04-30 12:57:06 -04:00
Erik Montnemery
407e0c58f9 Migrate tests to pytest (#23544)
* Migrate tests to pytest

* Fixup

* Use loop fixture in test_check_config

* Lint
2019-04-30 09:20:38 -07:00
David F. Mulcahey
d71424f285 Clean up ZHA discovery logic (#23563)
* use domain constants from HA

* cleanup endpoint processing in discovery

* Whitespace.
2019-04-30 10:40:52 -04:00
Anders Melchiorsen
6a6a999833 Upgrade pysonos to 0.0.12 (#23560) 2019-04-30 08:45:56 -04:00
Jc2k
7612703092 Bump homekit_python to 0.14.0 (#23562) 2019-04-30 08:44:48 -04:00
Klaas Schoute
5d5f073cff Fix problem with using Traccar event (#23543) 2019-04-30 08:02:45 +02:00
etheralm
1d70005b01 Add sensor support for dyson 2018 models (#22578)
fix check for already created entities

remove hepa and carbon filter

add AQI attribute

initial commit

fix check for already created entities

remove hepa and carbon filter

add AQI attribute

add air quality component tests

fix method call tests

fix line lengths

fix pylint issues

fix docstrings

revert fan related changes

remove whitespace change

fix fan update state test

add for loop for platform initialization

add requested changes to aiq platform

change string concatenation to new style string formatting

update air quality tests

update air quality tests

refactor sensor component changes

fix pylint issues

fix debug string in the air quality component

replace failing tests for older devices

fix line length fan tests

remove dependencies const and move imports

move back imports to methods

remove whitespace from blank line
2019-04-30 02:24:05 +02:00
Austin Drummond
b4e2a0ef84 Add HomeKit low battery threshold config (#23363) 2019-04-30 02:02:53 +02:00
David F. Mulcahey
2aee31ec6a Don't use zigpy profiles for ZHA entities (#22844)
* don't use zigpy profiles
* use sets as they're the correct structure to use
2019-04-29 19:31:27 -04:00
Erik Montnemery
8d775caaac Always print invalid configuration data (#21972)
* Always print invalide configuration data

* Print offending data as yaml

* Revert "Print offending data as yaml"

This reverts commit 01721a21a9ff918ed2c8595151ebfe55eb2f7d36.

* Do not print sensitive data

* Print MQTT topic

* Add line break

* Review comments

* review comments
2019-04-29 13:45:53 -07:00
Pascal Vizeli
4c4f0e38d4 Fix media_player alexa power control bug (#23537) 2019-04-29 22:40:55 +02:00
Paulus Schoutsen
5e3e730496 Install requirements when checking config (#23500)
* Install requirements when checking config

* PyLint
2019-04-29 09:54:42 -07:00
Erik Montnemery
84f778d23c Improve logging of exceptions in async_create_task (#22689)
* Improve logging of exceptions in async_create_task

* Move wrapping+logging to util.logging

* Minor refactor, fix typing

* Add test

* Remove useless @wraps, fix confusing parameter name

* Review comment
2019-04-29 09:53:22 -07:00
David F. Mulcahey
75f53b2799 Allow direct binding via ZHA for the ZLL profile (#23536)
* allow binding for zll profile
* update check - review comment
2019-04-29 11:35:18 -04:00
Aaron Bach
e08f2ad18d Add current disease data to IQVIA (#23052)
* Add current and historical disease data to IQVIA

* Added fetcher

* Added disease sensor mapping

* Changed incorrect key

* Removed other extraneous const usage
2019-04-29 09:06:23 -06:00
David F. Mulcahey
5aa9a1a7c2 limit concurrent updates to avoid network flood (#23534) 2019-04-29 09:39:37 -04:00
Penny Wood
5e045f3df2 Allow device_class for template covers
* #23486. Allows device_class to be set for template covers
2019-04-29 20:38:59 +08:00
Anders Melchiorsen
471a26bde1 Do not log tracebacks for influxdb write errors (#23522)
* Do not log influxdb write exceptions

* Log exception name
2019-04-29 06:39:45 -05:00
Anders Melchiorsen
2245ee98e3 Ignore stale directories (#23464)
* Ignore stale directories

* Remove redundant tests

* Revert "Remove redundant tests"

* Print warning when skipping directories

* Suggest to remove stale directory
2019-04-29 10:53:27 +02:00
Anders Melchiorsen
0ecf152153 Continuous discovery of Sonos speakers (#23484) 2019-04-29 10:20:09 +02:00
mcc05
5529bcc114 Fixed AlexaPowerController to report power state for thermostats (#23468)
Fixed AlexaPowerController to report power state for thermostats, to look if state is OFF return OFF, otherwise report ON as thermostats have multiple values for ON
2019-04-28 21:29:12 -04:00
Joakim Plate
b4a7980084 Update Philips js to v0.0.8 (#23462)
* Don't send volume on volume set

This needs updated lib

* Bump version and avoid getting channels explicitly

* Add myself as codeowner

* Use version 0.0.8 instead which doesn't reuse session

Some TV's doesn't play nice with HTTP/1.1 connection
re-use.

* Add new requirement to requirements_all.txt
2019-04-28 21:27:35 -04:00
Paulus Schoutsen
0f49a9cb7b Return state when changing optimistic covers (#23498) 2019-04-28 12:09:20 -07:00
Erik Montnemery
2f45a7e3b9 Fix cleanup of dynamic group (#23475) 2019-04-28 12:09:06 -07:00
Wojciech Mamak
b60c7ce479 Fixed bug with max_result (#23507)
The config option 'max_result' was assigned to not existing 'max_result' variable, it should be assigned to 'maxResult'.
The current version causes an error when max_result option is used.
2019-04-28 21:01:33 +02:00
Anders Melchiorsen
41d9bd42af Catch RequestException in influxdb writer (#23508) 2019-04-28 20:57:58 +02:00
Alok Saboo
2fecc7d5a4 Update aiolifx_effects to 0.2.2 (#23473) 2019-04-28 20:46:49 +02:00
Robin
687bbce900 Fixes local_file camera service (#23479)
* Fixes service

Fixes service so only the target camera is updated

* Update test_camera.py

* fix lint
2019-04-28 19:32:02 +01:00
chmielowiec
54c34bb224 Display person component as occupancy sensor HomeKit (#23451) 2019-04-28 18:38:21 +02:00
Anders Melchiorsen
37badbbf09 Skip flaky stream tests (#23493)
* Skip flaky test_hls tests

* Skip flaky test_recorder tests
2019-04-28 13:58:19 +02:00
Paulus Schoutsen
b09f5b6743 Only include agent user ID in SYNC responses (#23497) 2019-04-28 09:42:05 +02:00
Paulus Schoutsen
2dbe6d3289 Updated frontend to 20190427.0 2019-04-27 22:18:18 -07:00
Paulus Schoutsen
300d1f44a6 Updated frontend to 20190427.0 2019-04-27 22:18:05 -07:00
David Bonnes
7458f1f6ef Add a warning that honeywell/EU is to be deprecated (#23469)
* Add a warning that honeywell/EU is to be deprecated

* improve warning
2019-04-27 22:27:41 +02:00
Paulus Schoutsen
26bf1b2173 Fix Hue sensors returning None value (#23478) 2019-04-27 13:27:17 -07:00
Andrew Sayre
f1b2622d78 Use remote image for HEOS (#23420) 2019-04-27 13:02:42 -07:00
Anders Melchiorsen
5efe089699 Improve handling of unavailable Sonos speakers (#23472) 2019-04-27 19:05:50 +02:00
Erik Montnemery
b6a13262da Bump pychromecast (#23463) 2019-04-27 09:17:50 -07:00
Anders Melchiorsen
148860587c No longer promote imports inside methods (#23471) 2019-04-27 09:16:44 -07:00
anrudolph
6be798bffc Added option to use self-signed certificates (#23139)
* Added option to use self-signed certificates

I defined a new option for configuration.yaml, 'verify_ssl', which is set to 'True' by default for obvious security reasons. However, in order to work with self-signed certificates, it is now possible to disable the certificate validation.(eg, I use a nextcloud instance with self-signed certificates)
Credit for code in line 57 goes to user 'gen2' on the homeassistant community, who suggested this solution. 
https://community.home-assistant.io/t/caldav-configuration/38198/25
I only took it a step further and made it a config option.

* Update calendar.py

* Added the import of CONF_VERIFY_SSL

I hope this passes the test now...

* Update homeassistant/components/caldav/calendar.py

Cool! Didn't know about that possibility, my coding experience is literally two weeks. Thanks for sharing!

Co-Authored-By: anrudolph <49680492+anrudolph@users.noreply.github.com>

* Removed some lines of code

I think, in order for the last commit to work, these lines have to be removed. Correct?

* Trying to get this passing the checks

Trying around to get the simplified code to work
2019-04-27 10:40:20 -05:00
Phil Bruckner
1dbfa8f3be Bump amcrest to 1.4.0 and use new storage_all method (#23446)
Improve sdcard sensor so it only sends one command to camera per update as opposed to the four it used to send to reduce network traffic and make data consistent. Also better handle returned values of 'unknown'.
2019-04-27 10:24:07 -05:00
cgtobi
96fb311f6b Fix netatmo_public sensor to use netatmo authentication (#23455) 2019-04-27 10:18:55 -05:00
Aaron Bach
bdc95e76d0 Fix broken forecast trend attribute in IQVIA (#23454) 2019-04-27 10:17:57 -05:00
Anders Melchiorsen
c174b83f54 Return of travis (#23409)
* Return .travis.yml

This reverts commit a5b03541e9.

* Remove coveralls

* Remove deploy

* Support only the extreme Python versions

* Ignore bleeding edge

* Remove docker service
2019-04-27 12:30:24 +02:00
Aaron Bach
bf050adcf3 Remove historical allergen and asthma sensors from IQVIA (#23258)
* Remove historical sensors from IQVIA

* Removed old imports

* Removed "Yesterday" sensors
2019-04-26 23:28:55 -06:00
Ian
c2e7445271 Add new nextbus sensor (#20197)
* Added new nextbus sensor

* Fix order in requirements_all after merge

* Add more flexible parsing of JSON lists

* Undo tox change
2019-04-26 19:51:58 -05:00
David Bonnes
f25183ba30 update geniushub client library to fix issue #23444 (#23450) 2019-04-26 18:18:30 -04:00
Paulus Schoutsen
d6f6273ac2 Make setup more robust (#23414)
* Make setup more robust

* Fix typing
2019-04-26 21:41:29 +02:00
Fredrik Erlandsson
61ea6256c6 Fix point setup (#23441)
Fix point setup
2019-04-26 20:56:55 +02:00
Fredrik Erlandsson
08c36e0089 Fix daikin setup (#23440)
Fix daikin setup
2019-04-26 20:24:01 +02:00
Aaron Bach
8fe95f4bab Additional cleanup of IQVIA integration (#23403)
* Additional cleanup of IQVIA integration

* Task

* Moved import

* Fixed exception

* Member comments (round 1)

* Member comments (round 2)

* Member comments
2019-04-26 11:06:46 -06:00
Toon Willems
606dbb85d2 Fix Flux component (#23431)
* Fix Flux component

* Update manifest.json

* Update manifest.json
2019-04-26 08:55:30 -07:00
cgtobi
b84ba93c42 Refactor netatmo to use hass.data (#23429)
* Refactor NETATMO_AUTH to use hass.data

* Minor cleanup

* Rename conf to auth and other suggestions by Martin

* Revert webhook name change

* Rename constant

* Move auth

* Don't use hass.data.get()

* Fix auth string
2019-04-26 17:15:37 +02:00
Anders Melchiorsen
5dbf58d67f Remove support for deprecated Sonos configuration (#23385) 2019-04-26 08:56:43 +02:00
Andrew Sayre
d038d2426b Add missing feature support flag (#23417) 2019-04-26 08:47:40 +02:00
Andrew Sayre
b5725f8f19 Fix supported features gates in media_player volume up/down services (#23419)
* Correct media player feature gates

* Fix failing test

* Lint...
2019-04-25 21:42:39 -07:00
Tom Schneider
eefb9406c2 restore battery_quantity for zha devices (#23320) 2019-04-25 22:44:38 -05:00
Robert Svensson
c229a314c6 Bump requirement to v55 (#23410) 2019-04-25 22:42:07 -05:00
Joakim Plate
7d5c1ede72 Broadlink fixup unintended breakage from service refactor (#23408)
* Allow host/ipv6 address for broadlink service

This matches switch config and is a regression fix

* Restore padding of packets for broadlink

* Drop unused import

* Fix comment on test
2019-04-25 21:33:05 -05:00
Evan Bruhn
7a6acca6bb Add device info for Logi Circle camera and sensor entities (#23373) 2019-04-25 15:21:04 -07:00
Markus Jankowski
9d67c9feb6 Add Types to Homematic IP (#23401) 2019-04-25 15:13:07 -07:00
Markus Jankowski
cef7ce11ad check if sabotage attr is in device (#23397) 2019-04-25 15:12:36 -07:00
panosmz
e182b95921 add key parameter (#23381) 2019-04-25 23:35:30 +02:00
cgtobi
d2e0c6dbc2 Bump youtube-dl version to 2019.04.24 (#23398) 2019-04-25 23:21:23 +02:00
Joakim Plate
39932d132d Add device classes for media player and map to google types (#23236)
* Add device classes for media player and map to google types

* Switch default class for media_player to media
2019-04-25 13:12:11 -07:00
Jason Hu
7e8f2d72b6 Add error handling for migration failure (#23383) 2019-04-25 12:58:10 -07:00
Daniel Høyer Iversen
4816a24b3c Update xiaomi library (#23391) 2019-04-25 14:25:32 -04:00
Chuang Zheng
3d91d76d3d async_setup_component stage_1_domains (#23375) 2019-04-25 05:50:28 -07:00
Erik Montnemery
5376e15286 Convert some test helpers to coroutines and adjust tests (#23352)
* Convert some test helpers to coroutines

* Fix tests
2019-04-25 10:14:16 +02:00
Phil Bruckner
86b017e2f0 Add amcrest camera services and deprecate switches (#22949)
* Add amcrest camera services and deprecate switches

- Implement enabling and disabling motion detection from camera platform.
- Add amcrest specific camera services for controlling audio stream, motion recording, continuous recording and camera color mode, as well as moving camera to PTZ preset and starting and stopping PTZ tour function.
- Add camera attributes to indicate the state of the various camera settings controlled by the new services.
- Deprecate switches in favor of camera services and attributes.

* Rename services and move service handling to __init__.py

Rename services from 'camera.amcrest_xxx' to 'amcrest.xxx'. This allows services to be documented in services.yaml.

Add services.yaml.

Reorganize hass.data[DATA_AMCREST] and do some general cleanup to make various platform modules more consistent.

Move service handling code to __init__.py from camera.py.

* Update per review comments, part 1

- Rebase
- Add permission checking to services
- Change cv.ensure_list_csv to cv.ensure_list
- Add comment for "pointless-statement" in setup
- Change handler_services to handled_services
- Remove check if services have alreaday been registered
- Pass ffmpeg instead of hass to AmcrestCam __init__
- Remove writing motion_detection attr from device_state_attributes
- Change service methods from callbacks to coroutines

* Update per review comments, part 2

- Use dispatcher to signal camera entities to run services.
- Reorganize a bit, including moving a few things to new modules const.py & helpers.py.

* Update per review comments, part 3

Move call data extraction from camera.py to __init__.py.
2019-04-24 22:39:49 -07:00
Richard Mitchell
c216ac7260 Fix race condition. (#21244)
If the updater is running at the same time, this can result in this dict changing size during iteration, which Python does not like.
2019-04-24 22:38:10 -07:00
Paulus Schoutsen
de6fdb09f4 Add media player external url (#23337)
* Add media player external url

* Lint

* Simplify

* Update __init__.py

* Update __init__.py

* Use 302
2019-04-24 22:37:29 -07:00
Andrew Sayre
e3e7fb5ff6 Bump pyheos to 0.4.1 (#23360)
* Bump pyheos==0.4.1

* Refresh player after reconnection
2019-04-24 21:31:31 -07:00
Ian
6fb5b8467b Fix tox.ini lint target (#23359)
tox fails due to being unable to reference the `script` module when
trying to run `script/gen_requirements_all.py`. Instead it needs to be
run as a module.
2019-04-24 21:30:46 -07:00
Steven Looman
24766df179 Upgrade to pyubee==0.6 (#23355) 2019-04-24 21:13:31 -07:00
dreed47
ec9db7f9a2 fix for issue #21381 (#23306) 2019-04-24 21:11:07 -07:00
Aaron Bach
0d796a0fb9 Convert Pollen.com sensor into IQVIA component (#22986)
* Moved pollen integration to iqvia

* Stitched in new library

* Added __init__

* Completed component v1

* Updated requirements

* Updated CODEOWNERS

* Updated .coveragerc

* Removed requirements

* Static check
2019-04-24 21:09:01 -06:00
Beat
96735e41af Add support for a wider variety of EnOcean devices (#22052)
* Implement EnOcean temperature and humidity sensors.

* Bump EnOcean version to 0.50
* Refactor components for more generic device handling
* Move radio packet data interpretation to specific devices

* Update CODEOWNERS

* Implement code review changes
2019-04-25 00:30:46 +02:00
Greg Laabs
fef1dc8c54 Bump ecovacs lib 2 (#23354)
* Bump Ecovacs dependency (sucks)

Update to new version of sucks, which switches to a custom-built SleekXMPP that turns off certificate validation. This is to fix issues caused by Ecovacs serving invalid certificates.

* Update requirements file
2019-04-24 14:47:22 -07:00
Niels Mündler
ef5ca63bf0 Fix non-syncthru supporting printers (#21482)
* Fix non syncthru-syncthru supporting printers

* Formatting

* Update requirements_all

* Update syncthru.py

* Fix component to be async (as is the used SyncThru implementation)

* Add async syntax

* Omit loop passing

* Don't await async_add_platform

* Generate new all requirements

* Explain, why exception is caught in setuExplain, why exception is caught in setupp

* Handle failing initial setup correctly

* Formatting

* Formatting

* Fix requested changes

* Update requirements and add nielstron as codeowner

* Run codeowners script

* Make notification about missing syncthru support a warning

* Revert pure formatting

* Fix logging
2019-04-24 23:39:31 +02:00
Paulus Schoutsen
d218ba98e7 Fix config test when current version is 92 (#23356) 2019-04-24 13:37:08 -07:00
Paulus Schoutsen
d53a00d054 Updated frontend to 20190424.0 2019-04-24 11:15:56 -07:00
Joakim Plate
62fcb1895e Device type garage for binary sensor garage_door (#23345)
* Switch binary sensor to garage for garage_door

* Add test for cover garage device type
2019-04-24 09:56:22 -07:00
Jason Hu
843bad83fa Remove ghost folder (#23350) 2019-04-24 09:55:48 -07:00
Penny Wood
e850ccb82c Fixed test (#23343) 2019-04-24 09:55:37 -07:00
Pascal Vizeli
f4e7364651 Netatmo 5min fetch interval (#23341) 2019-04-24 09:54:51 -07:00
Fabian Affolter
82ff5cbe0f Upgrade ruamel.yaml to 0.15.94 (#23344) 2019-04-24 09:52:29 -07:00
Joakim Plate
e11e6e1b04 Volume trait for google assistant (#23237)
* Add action.devices.traits.Volume

* Drop media player from brightness trait

* Factor out commands into separate functions

* Drop support for explicit mute
2019-04-24 09:08:41 -07:00
Markus Jankowski
2863ac1068 Fix Homematic IP Cloud remaining light imports (#23339)
* Fix missing impor reorg

* Add brackets

* Removed trailing whitespaces
2019-04-24 13:27:45 +02:00
Fabian Affolter
3d04856cbd Upgrade youtube_dl to 2019.04.17 (#23342) 2019-04-24 11:56:43 +02:00
Joakim Plate
7c55b9f087 Expose door cover/binary_sensor as door type (#23307)
* Expose door cover/binary_sensor as door type

More logical to ask "What doors are open" than "What sensors are open"

* Add test for binary_sensor device_classes

* Cosmetic flake8

* Add test for device class for cover
2019-04-23 19:25:20 -07:00
Kyle Pinette
6681605c34 Added override for kwikset 888. (#23327) 2019-04-23 22:24:43 -04:00
Daniel Høyer Iversen
95bbea20a8 Fix Switchbot restore state (#23325)
* switchbot library

* req

* req

* issue #23039
2019-04-23 19:23:52 -07:00
Andre Lengwenus
662375bdd7 Changes due to manifest.json. Awaiting coroutines instead of creating tasks (#23321) 2019-04-23 19:20:20 -07:00
Paulus Schoutsen
aa26f90420 Add sensor and binary senseor to default expose (#23332) 2019-04-23 19:19:23 -07:00
Jason Hu
c61b6cf616 Support unicode in configuration migration (#23335) 2019-04-23 17:47:09 -07:00
Markus Jankowski
16d8e92b06 Reorg Homematic IP Cloud imports and minor fixes (#23330)
* reorg HmiP Imports after introduction of manifests

* add type to some functions

* fix usage of dimLevel (HomematicipDimmer,HomematicipNotificationLight)

* align naming to HomematicipMultiSwitch: channel_index -> channel for (HomematicipNotificationLight)

* fix lint

* Fix is_on for dimmers

* fix lint
2019-04-24 01:47:31 +02:00
ktnrg45
68d3e624e6 Fix ps4 not able to use different PSN accounts (#22799)
* Remove skipping of creds step.

* Check for device added per account

* typo

* lint

* Pylint

* Fix test

* Fix test

* Typo

* Add auto location

* blank space

* Add new identifier handling + fix select source

* Add cred_timeout error

* add credential timeout error

* Fix Tests

* patch decorator

* Update test_config_flow.py

* add test

* Revert

* Rename vars

* fix tests

* Add attr location

* Bump 0.6.0

* Bump 0.6.0

* Bump 0.6.0

* Update handling exception

* Update remove method

* Update tests

* Refactoring

* Pylint

* revert

* chmod

* 0.6.1

* 0.6.1

* 0.6.1

* Remove func

* Add migration

* Version 3

* Remove redefinition

* Add format unique id

* Add format unique id

* pylint

* pylint

* 0.7.1

* 0.7.1

* 0.7.1

* Changes with media_art call

* Add library exception

* 0.7.2

* 0.7.2

* 0.7.2

* Version and entry_version update

* Revert list comprehension

* Corrected exception handling

* Update media_player.py

* Update media_player.py

* white space
2019-04-24 01:32:36 +02:00
Paulus Schoutsen
d505f1c5f2 Always set latest pin (#23328) 2019-04-23 13:13:00 -07:00
dreed47
b252d8e2cd Zestimate - Added check for the existence of data in response (#23310) 2019-04-23 11:44:13 -07:00
Josef Schlehofer
c040f7abc0 Upgrade attrs to 19.1.0 (#23323) 2019-04-23 10:14:02 -07:00
Joakim Sørensen
2871a650f6 Handle traccar connection errors (#23289)
* Handle connection errors

* Fix lint issue E127

* Remove periods from logs

* Merge connection checks

* Fail with bad credentials

* Move stuff around for async_init

* Fix E128 linting issue

* Simplify
2019-04-23 08:46:11 -04:00
Paulus Schoutsen
5b0ee473b6 Add get_states faster (#23315) 2019-04-23 12:46:22 +02:00
Paulus Schoutsen
00d26b3049 Random hassfest fixes (#23314) 2019-04-23 08:34:36 +02:00
Joakim Sørensen
ddb5ff3b71 Show correct version for stable (#23291) 2019-04-22 22:07:56 -07:00
Paulus Schoutsen
72bbe2203e Dont cache integrations that are not found (#23316) 2019-04-22 22:06:58 -07:00
Pascal Vizeli
2a720efbd4 Fix hass.io panel_custom/frontend (#23313)
* Fix hass.io panel_custom/frontend

* Update manifest.json
2019-04-22 21:47:12 -07:00
Jc2k
baeb3cddc6 Set placeholders in homekit config flow title (#23311) 2019-04-22 21:32:39 -07:00
VDRainer
ee88433fb1 Create services.yaml for input_datetime (#23303)
* Create services.yaml for input_datetime

* HA error while parsing a flow mapping
2019-04-22 21:29:34 -07:00
Richard Mitchell
845d81bdae Correct calculation and units of light level values. (#23309) 2019-04-22 21:28:40 -07:00
Anders Melchiorsen
d0f9595ad9 Add connection control for netgear_lte (#22946) 2019-04-22 22:44:46 +02:00
Pawel
9007e17c3e MQTT Vacuum State Device (#23171)
* add StateVacuum MQTT
2019-04-22 21:49:15 +02:00
Joakim Plate
e85af58e43 RFC: Upgrade philips_js component version and support channels and sources (#23061)
* Drop unused constant

* Don't default to localhost

A philips tv will never run on localhost

* Use library internal state

* Add play media support for channels

* Control update manually

This allow us to delay update of state when we perform
and action.

* Bump version for support for api v1 again

* Consider missing source and only channels as channels

* Fix some flake8 tasks

* Fix some pylint errors

* Adjust requirements_all file

* Switch to async_add_executor_job

* Assume device turns of off a sucessfull standby call
2019-04-22 12:26:15 -07:00
Otto Winter
0c90bfb936 Fix ESPHome setup errors in beta (#23242)
* Fix ESPHome setup errors in beta

* Update requirements_all.txt
2019-04-22 12:13:21 -07:00
Andrew Sayre
8daba68dc1 Add support to play url (#23273) 2019-04-22 12:10:55 -07:00
Austin Mroczek
e3981b6498 Bump skybellpy to 0.4.0 (#23294)
* Bump skybellpy to 0.4.0

* Bump skybellpy to 0.4.0 in requirements_all.txt
2019-04-22 12:09:55 -07:00
Erik Montnemery
a89c7f8feb Improve MQTT tests (#23296)
* Improve MQTT tests

* Tweak
2019-04-22 08:48:50 -04:00
Markus Jankowski
357631d659 Add homematicip cloud temperature sensor from thermostats (#23263) 2019-04-22 09:30:49 +02:00
Josef Schlehofer
3b0660ae89 Upgrade pyotp to 2.2.7 (#23274) 2019-04-21 09:03:17 +02:00
Josef Schlehofer
a8632480ff Upgrade xmltodict to 0.12.0 (#23277) 2019-04-21 13:52:20 +09:00
Aaron Bach
80653824d9 Add ctags file to .gitignore (#23279) 2019-04-20 21:15:19 -06:00
damarco
b3c7142030 Bump zigpy and zigpy-xbee (#23275) 2019-04-20 18:04:30 -04:00
damarco
df32830f17 Bump zigpy-deconz (#23270) 2019-04-20 10:12:28 -04:00
Andrew Sayre
b697bb7a26 Update pyheos and log service errors in HEOS integration (#23222)
* Update pyheos and command error handling

* Correct comment and remove unnecessary autospec
2019-04-19 22:22:40 -04:00
Paulus Schoutsen
a3ecde01ee Updated frontend to 20190419.0 2019-04-19 16:57:45 -07:00
Andrew Sayre
e2ed2ecdc0 Return 0 instead of None (#23261) 2019-04-19 16:56:34 -07:00
Erik Montnemery
1e0bc97f56 Drop unnecessary block_till_done (#23256) 2019-04-19 16:08:11 -07:00
Erik Montnemery
eebb452fb5 Drop unnecessary block_till_done, improve tests for MQTT Cover tests (#23255) 2019-04-19 16:07:28 -07:00
Erik Montnemery
2c42e1a5cb Drop unnecessary block_till_done for MQTT tests (#23254)
* Drop unnecessary block_till_done

* Drop unnecessary block_till_done
2019-04-19 14:59:16 -07:00
Erik Montnemery
28c411c742 Drop unnecessary block_till_done for MQTT fan tests (#23253) 2019-04-19 14:58:44 -07:00
Tomer Figenblat
9d8d8afa82 Added component named switcher_kis switcher water heater integration. (#22325)
* Added component named switcher_kis switcher water heater integration.

* Fixed conflicts.

* Updated requirements.

* Added manifest.json file and updated CODEOWNERS.

* Fixed requirements_all.txt.

* Better component tests.

* Removed unnecessary parameter from fixture function.

* Removed tests section from mypy.ini.

* Remove unused ENTITY_ID_FORMAT.

* Stop udp bridge when failed to setup the component.

* Replace DISCOVERY_ constants prefix with DATA_.

* Various change requests.

* Fixed constant name change remifications.

* Added explicit name to fixture.

* Various change requests.

* More various change requests.

* Added EventType for homeassistant.core.Event.

* Switched from event driven data distribution to dispatcher type plus clean-ups.

* Removed name and icon keys from the component configuration.

* Various change requests.

* Various change reqeusts and clean-ups.

* Removed unnecessary DEPENDENCIES constant from swith platform.

* Replaced configuration data guard with assert.

* Removed unused constants.

* Removed confusing type casting for mypy sake.

* Refactor property device_name to name.

* Removed None guard effecting mypy only.

* Removed unnecessary function from switch entity.

* Removed None guard in use by mypy only.

* Removed unused constant.

* Removed unnecessary context manager.

* Stopped messing around with mypy.ini.

* Referring to typing.TYPE_CHECKING for non-runtime imports.

* Added test requierment correctyly.

* Replaced queue.get() with queue.get_nowait() to avoid backing up intervals requests.

* Revert changes in mypy.ini.

* Changed attributes content to device properties instead of entity properties.

* Fixed typo in constant name.

* Remove unnecessary async keyword from callable.

* Waiting for tasks on event loop to end.

* Added callback decorator to callable.
2019-04-19 16:54:48 -05:00
cgtobi
31e514ec15 Add missing services.yaml file for hue (#23217)
* Add hue services.yaml

* Add lifx services.yaml

* Add lutron services.yaml

* Update lifx services.yaml

* Update hue services.yaml

* Revert lifx services.yaml as it is not necessary

* Remove hue from lights/services.yaml
2019-04-19 14:53:58 -07:00
Erik Montnemery
73a7d5e6f4 Drop unnecessary block_till_done, improve tests (#23252) 2019-04-19 14:52:23 -07:00
Erik Montnemery
f584878204 Drop unnecessary block_till_done (#23251) 2019-04-19 14:51:48 -07:00
Paulus Schoutsen
0533f56fe3 Ask users for a pin when interacting with locks/garage doors (#23223)
* Ask users for a pin when interacting with locks/garage doors

* Deprecate allow_unlock option
2019-04-19 14:50:21 -07:00
Erik Montnemery
416af5cf57 Drop unnecessary block_till_done (#23250) 2019-04-19 14:10:48 -07:00
Erik Montnemery
557211240e Drop unnecessary block_till_done, improve tests (#23249) 2019-04-19 14:08:54 -07:00
Erik Montnemery
13e0691c90 Drop unnecessary block_till_done, improve tests (#23248) 2019-04-19 14:08:02 -07:00
Erik Montnemery
0e429cca33 Drop unnecessary block_till_done, improve tests (#23247) 2019-04-19 12:26:56 -07:00
Erik Montnemery
887e1cd8e3 Drop unnecessary block_till_done, improve tests (#23246) 2019-04-19 12:19:46 -07:00
Richard Mitchell
c899e2a662 Name sensors correctly (#23208)
* Hue motion senors are motion sensors, not presence sensors.

* Name the sensors 'motion' instead of 'presence' - match the HA paradigm.
2019-04-19 11:01:54 -07:00
Jc2k
e7054e0fd2 Avoid calling async code in sync context (#23235) 2019-04-19 10:59:54 -07:00
GoNzCiD
9cf9be8850 Add accuracy and status for Traccar (#23180)
* Fix read gps position accuracy & read device status

* Fix: W291 trailing whitespace & E501 line too long (80 > 79 characters)

* Upgrade pytraccar dependency to 0.7.0

* met snake case
2019-04-19 18:42:27 +02:00
Christopher Viel
b1b269b302 Add more CPU temp. labels to Glances (#23179) 2019-04-19 15:21:16 +02:00
Maciej Bieniek
6e300bd438 Add missing service for persistent_notification (#23230) 2019-04-19 15:14:48 +02:00
Jc2k
21a194f9d8 Review feedback from #23191 (#23233) 2019-04-19 08:39:06 -04:00
Jc2k
b3a8b0056b Add and use an async_fire_service_discovered helper (#23232) 2019-04-19 08:38:50 -04:00
Pascal Roeleven
b2a7699cdf Change configuration for orangepi (#23231) 2019-04-19 13:26:53 +02:00
Pascal Vizeli
3e443d253c Hass.io Add-on panel support for Ingress (#23185)
* Hass.io Add-on panel support for Ingress

* Revert part of discovery startup handling

* Add type

* Fix tests

* Add tests

* Fix lint

* Fix lint on test
2019-04-19 09:43:47 +02:00
Aaron Bach
6a7bd19a5a Remove archived 17track packages from the entity registry (#23049)
* Remove archived 17track packages from the entity registry

* Fix incorrect __init__.py

* Member comments

* Member comments

* Fix too many params

* Member comments

* Member comments
2019-04-19 09:14:14 +02:00
Paulus Schoutsen
dbe0ba87a3 Async fix for bluetooth stopping (#23225) 2019-04-19 08:56:24 +02:00
Erik Montnemery
bea7e2a7fa Fix clearing error message for MQTT vacuum (#23206)
* Fix clearing error message

* Remove redundant hass.async_block_till_done
2019-04-18 21:01:19 -07:00
Tsvi Mostovicz
eac2388d49 Set default value for input_datetime (#21919)
* Set default value for input_datetime

If no initial value is set and no value is available to be restored, set the default value as specified in the docs to 1970-01-01 00:00.

* Use regular if statement

Ternary statements can be tricky if you try to keep the value the same if not something

* Add test for default values

Check that if no initial value is set, state returns 1970-01-01 at 00:00

* Fix tests - was passing wrong args to time/date

* Verify we get a timestamp attribute for input_datetime

This adds a check that when using the default timestamp of 1970-1-1 00:00:00, we
get a timestamp attribute. This is waht prompted this PR in the first place, as
when specifying an automation trying to access the timestamp attribute for a non-
initialized input_datetime HASS wouldn't start.

* Simplify the change for a default value

Based on @balloob comment. Simplifying the code

* Revert "Simplify the change for a default value"

This reverts commit c2d67f19a6.
2019-04-18 21:00:35 -07:00
Erik Montnemery
7a84cfb0be Fix optimistic mode + other bugs, tests (#22976) 2019-04-18 20:59:41 -07:00
Paulus Schoutsen
b0ce3dc683 Only comment with changed coverage on release PRs [skip-ci] (#23224) 2019-04-18 20:58:35 -07:00
Erik Montnemery
70ba5eb0ef Add json_attributes_template (#22981) 2019-04-18 20:55:10 -07:00
Paulus Schoutsen
1761b25879 Remove copy paste error 2019-04-18 20:31:53 -07:00
David F. Mulcahey
c2b4e24372 update zha-quirks (#23215) 2019-04-18 20:23:48 -04:00
David F. Mulcahey
5e363d124e fix bindable devices (#23216) 2019-04-18 20:21:30 -04:00
Paulus Schoutsen
a52f96b23a Add stub services.yaml and make validation mandatory (#23213) 2019-04-18 15:13:35 -07:00
Raman Gupta
620c6a22ac Update vizio component to support latest pyvizio with soundbar support (#22294)
* update vizio component to support latest pyvizio with soundbar support

* Resolved Hound issues

* Additional Hound issue

* Updated based on feedback

* Style updates

* Additional code styling changes

* Added check for auth token not being set for tv device_class

* Limited lines to 80 characters

* moved MAX_VOLUME into base package

* fixed supported commands

* styling changes

* fix styling yet again

* remove unnecessary elif

* removed play/pause since I can't get current state

* changed value access method from config dict

* fixed flake failures

* try to fix docstring

* try to fix docstring

* fixed auth token validation

* rebase and regenerate requirements_all.txt

* updated log text

* line length fix

* added config validation to handle conditionally optional parameter

* updated validate setup log message and string formatting based on review

* fix pylint error

* less ugly
2019-04-18 22:48:05 +02:00
Steven Looman
e1d1f21a74 Don't create connections between sensors. Fixes #22787 (#23202) 2019-04-18 13:47:17 -07:00
Robbie Trencheny
66b2ed930c Set encoding before connecting (#23204) 2019-04-18 13:46:49 -07:00
Paulus Schoutsen
33b8241d26 Add services.yaml validator (#23205)
* Add services.yaml validator

* Fix path
2019-04-18 13:40:46 -07:00
Otto Winter
37cd711c96 Create empty services.yaml for esphome (#23200) 2019-04-18 13:10:36 -07:00
Alok Saboo
0eb8c77889 Create services.yaml for python_script and script (#23201)
* Create services.yaml for python_script

* Create services.yaml for script
2019-04-18 13:10:25 -07:00
Alok Saboo
4be30f7c88 create services.yaml for shell_command (#23210) 2019-04-18 13:10:10 -07:00
Alok Saboo
70c5bd4316 Create services.yaml for Tuya (#23209) 2019-04-18 13:09:41 -07:00
Florian Klien
daf2f30822 set myself as codeowner of xmpp, removed me from notify/* (#23207)
* set myself as codeowner of xmpp, removed me from notify/*

* changed the manifests as well
2019-04-18 12:26:02 -07:00
Paulus Schoutsen
fda483f482 Don't load component when fetching translations (#23196) 2019-04-18 11:11:43 -07:00
Robbie Trencheny
c2cce13e2a Migrating codeowners-mention to Heroku 2019-04-18 11:11:26 -07:00
David F. Mulcahey
38d23ba0af Misc. ZHA changes (#23190)
* handle the off part of on with timed off command

* use correct var

* only bind / configure cluster once

* clean up channel configuration

* additional debug logging

* add guard

* prevent multiple discoveries for a device

* cleanup and still configure on rejoin
2019-04-18 12:24:02 -04:00
Robbie Trencheny
5e1338a9e4 Further improve IndieAuth redirect_uri lookup failure logs (#23183) 2019-04-18 09:03:25 -07:00
Jc2k
4ac9a2e9de Add storage for cacheable homekit entity maps. (#23191) 2019-04-18 08:55:34 -07:00
Richard Mitchell
f57191e8dd Hue motion senors are motion sensors, not presence sensors. (#23193) 2019-04-18 08:53:02 -07:00
David Bonnes
11fb4866a8 Improve configuration schema for Geniushub integration (#23155)
* configuration for hub tokens are now separate from host addresses/credentials

* small change to docstring

* use *args **kwargs
2019-04-18 14:37:52 +02:00
Penny Wood
d9fb3c8c28 Potential None (#23187) 2019-04-18 14:04:30 +02:00
Pascal Roeleven
df475cb797 Adds Orange Pi GPIO platform (#22541)
* Adds Orange Pi GPIO platform

* Add manifest.json

* Remove cover platform

* Apply requested changes

* Remove switch platform

* Update CODEOWNERS

* Remove obsolete dependecies/requirements
2019-04-18 19:43:34 +09:00
Rohan Kapoor
f588fef3b4 Add minimum/maximum to counter (#22608)
* Added minimum/maximum to counter

* Added min/max testcases

* remove duplicate

* cosmetic changes

* removed blank lines at eof

* added newline at eof

* type cv -> vol

* more fixes

* - fixed min/max warnings
- fixed failing tests

* Added linewrap

* - Added cast to int
- Fixed double quotes

* - removed None check in __init__
- fixed failing test

* copy paste fix

* copy paste fix

* Added possibility to change counter properties trough service call

* fixed copy paste errors

* Added '.' to comment

* rephrased docstring

* Fix tests after rebase

* Clean up per previous code review comments

* Replace setup service with configure

* Update services description

* Update tests to use configure instead of setup
2019-04-18 19:02:01 +09:00
Dries De Peuter
6e4083d7f4 Fix niko home control dependency installation (#23176)
* Upgrade niko-home-control library

* Fix additional feedback

* Lint
2019-04-18 10:52:48 +02:00
Joakim Plate
4a2a130bfa Google assistant skip missing type (#23174)
* Skip entity if no device type found

* Add test for potentially skipped binary sensors

* Reorg code, add tests to ensure all exposed things have types

* Lint

* Fix tests

* Lint
2019-04-17 22:37:39 -07:00
Paulus Schoutsen
ce8ec3acb1 Don't warn for missing services (#23182) 2019-04-17 22:27:11 -07:00
Richard Mitchell
474ac8b09e Add basic support for native Hue sensors (#22598)
* Add basic support for native Hue sensors

* Update coveragerc

* Simplify attributes

* Remove config option

* Refactor and document device-ness and update mechanism

* Entity docstrings

* Remove lingering config for sensors

* Whitespace

* Remove redundant entity ID generation and hass assignment.

* More meaningful variable name.

* Add new 'not-darkness' pseudo-sensor.

* Refactor sensors into separate binary, non-binary, and shared modules.

* formatting

* make linter happy.

* Refactor again, fix update mechanism, and address comments.

* Remove unnecessary assignment

* Small fixes.

* docstring

* Another refactor: only call API once and make testing easier

* Tests & test fixes

* Flake & lint

* Use gather and dispatcher

* Remove unnecessary whitespace change.

* Move component related stuff out of the shared module

* Remove unused remnant of failed approach.

* Increase test coverage

* Don't get too upset if we're already trying to update an entity before it has finished adding

* relative imports
2019-04-17 22:13:03 -07:00
Paulus Schoutsen
77244eab1e Fix empty components (#23177) 2019-04-17 19:17:13 -07:00
Jc2k
6bb4199824 Add @Jc2k to codeowners for homekit_controller (#23173) 2019-04-17 19:16:20 -07:00
Richard Mitchell
f6349a6cf4 Kill bluetooth LE scanning gracefully when asked to shut down. (#22586)
* Kill bluetooth LE scanning gracefully when asked to shut down.

* Add missing argument.

* Refactor to use data instead of passing nonlocal variables about.

* Fix typo.
2019-04-17 13:48:17 -07:00
zewelor
fa73b8e37a Make less imports from yeelight (#23124) 2019-04-17 22:05:49 +02:00
Ingo Theiss
0afa01609c Pass configured host string instead of always forcing an ip-address (#23164)
* Pass host string instead of forcing an ip-address

Pass the configured host (https://www.home-assistant.io/components/homematic/#host) instead of always forcing an ip-address. This is required to get SSL certificate validation working.

* Remove unused 'socket' import
2019-04-17 21:35:16 +02:00
Paulus Schoutsen
723d00d33a Bumped version to 0.93.0.dev0 2019-04-17 10:49:25 -07:00
1757 changed files with 72767 additions and 33050 deletions

View File

@@ -57,7 +57,7 @@ commands:
<<# parameters.all >>pip install -q --progress-bar off -r requirements_all.txt -c homeassistant/package_constraints.txt<</ parameters.all>>
<<# parameters.test >>pip install -q --progress-bar off -r requirements_test.txt -c homeassistant/package_constraints.txt<</ parameters.test>>
<<# parameters.test_all >>pip install -q --progress-bar off -r requirements_test_all.txt -c homeassistant/package_constraints.txt<</ parameters.test_all>>
no_output_timeout: 15m
no_output_timeout: 15m
- save_cache:
paths:
- ./venv
@@ -90,7 +90,7 @@ jobs:
name: run static check
command: |
. venv/bin/activate
flake8
flake8 homeassistant tests script
- run:
name: run static type check

View File

@@ -13,3 +13,4 @@ coverage:
url: "secret:TgWDUM4Jw0w7wMJxuxNF/yhSOHglIo1fGwInJnRLEVPy2P2aLimkoK1mtKCowH5TFw+baUXVXT3eAqefbdvIuM8BjRR4aRji95C6CYyD0QHy4N8i7nn1SQkWDPpS8IthYTg07rUDF7s5guurkKv2RrgoCdnnqjAMSzHoExMOF7xUmblMdhBTWJgBpWEhASJy85w/xxjlsE1xoTkzeJu9Q67pTXtRcn+5kb5/vIzPSYg="
comment:
require_changes: yes
branches: master

View File

@@ -13,6 +13,10 @@ omit =
homeassistant/components/abode/*
homeassistant/components/acer_projector/switch.py
homeassistant/components/actiontec/device_tracker.py
homeassistant/components/adguard/__init__.py
homeassistant/components/adguard/const.py
homeassistant/components/adguard/sensor.py
homeassistant/components/adguard/switch.py
homeassistant/components/ads/*
homeassistant/components/aftership/sensor.py
homeassistant/components/airvisual/sensor.py
@@ -22,6 +26,7 @@ omit =
homeassistant/components/alarmdotcom/alarm_control_panel.py
homeassistant/components/alpha_vantage/sensor.py
homeassistant/components/amazon_polly/tts.py
homeassistant/components/ambiclimate/climate.py
homeassistant/components/ambient_station/*
homeassistant/components/amcrest/*
homeassistant/components/ampio/*
@@ -33,6 +38,8 @@ omit =
homeassistant/components/apple_tv/*
homeassistant/components/aqualogic/*
homeassistant/components/aquostv/media_player.py
homeassistant/components/arcam_fmj/media_player.py
homeassistant/components/arcam_fmj/__init__.py
homeassistant/components/arduino/*
homeassistant/components/arest/binary_sensor.py
homeassistant/components/arest/sensor.py
@@ -44,14 +51,17 @@ omit =
homeassistant/components/asterisk_mbox/*
homeassistant/components/asuswrt/device_tracker.py
homeassistant/components/august/*
homeassistant/components/aurora_abb_powerone/sensor.py
homeassistant/components/automatic/device_tracker.py
homeassistant/components/avion/light.py
homeassistant/components/azure_event_hub/*
homeassistant/components/baidu/tts.py
homeassistant/components/bbb_gpio/*
homeassistant/components/bbox/device_tracker.py
homeassistant/components/bbox/sensor.py
homeassistant/components/bh1750/sensor.py
homeassistant/components/bitcoin/sensor.py
homeassistant/components/bizkaibus/sensor.py
homeassistant/components/blink/*
homeassistant/components/blinksticklight/light.py
homeassistant/components/blinkt/light.py
@@ -150,6 +160,7 @@ omit =
homeassistant/components/eight_sleep/*
homeassistant/components/eliqonline/sensor.py
homeassistant/components/elkm1/*
homeassistant/components/elv/switch.py
homeassistant/components/emby/media_player.py
homeassistant/components/emoncms/sensor.py
homeassistant/components/emoncms_history/*
@@ -158,6 +169,7 @@ omit =
homeassistant/components/enocean/*
homeassistant/components/enphase_envoy/sensor.py
homeassistant/components/entur_public_transport/*
homeassistant/components/environment_canada/*
homeassistant/components/envirophat/sensor.py
homeassistant/components/envisalink/*
homeassistant/components/ephember/climate.py
@@ -169,10 +181,12 @@ omit =
homeassistant/components/esphome/camera.py
homeassistant/components/esphome/climate.py
homeassistant/components/esphome/cover.py
homeassistant/components/esphome/entry_data.py
homeassistant/components/esphome/fan.py
homeassistant/components/esphome/light.py
homeassistant/components/esphome/sensor.py
homeassistant/components/esphome/switch.py
homeassistant/components/essent/sensor.py
homeassistant/components/etherscan/sensor.py
homeassistant/components/eufy/*
homeassistant/components/everlights/light.py
@@ -203,6 +217,7 @@ omit =
homeassistant/components/fritzbox_callmonitor/sensor.py
homeassistant/components/fritzbox_netmonitor/sensor.py
homeassistant/components/fritzdect/switch.py
homeassistant/components/fronius/sensor.py
homeassistant/components/frontier_silicon/media_player.py
homeassistant/components/futurenow/light.py
homeassistant/components/garadget/cover.py
@@ -218,6 +233,7 @@ omit =
homeassistant/components/goalfeed/*
homeassistant/components/gogogate2/cover.py
homeassistant/components/google/*
homeassistant/components/google_cloud/tts.py
homeassistant/components/google_maps/device_tracker.py
homeassistant/components/google_travel_time/sensor.py
homeassistant/components/googlehome/*
@@ -247,7 +263,6 @@ omit =
homeassistant/components/hitron_coda/device_tracker.py
homeassistant/components/hive/*
homeassistant/components/hlk_sw16/*
homeassistant/components/homekit_controller/*
homeassistant/components/homematic/*
homeassistant/components/homematic/climate.py
homeassistant/components/homematic/cover.py
@@ -275,9 +290,11 @@ omit =
homeassistant/components/imap_email_content/sensor.py
homeassistant/components/influxdb/sensor.py
homeassistant/components/insteon/*
homeassistant/components/incomfort/*
homeassistant/components/ios/*
homeassistant/components/iota/*
homeassistant/components/iperf3/*
homeassistant/components/iqvia/*
homeassistant/components/irish_rail_transport/sensor.py
homeassistant/components/iss/binary_sensor.py
homeassistant/components/isy994/*
@@ -306,6 +323,7 @@ omit =
homeassistant/components/lcn/*
homeassistant/components/lg_netcast/media_player.py
homeassistant/components/lg_soundbar/media_player.py
homeassistant/components/life360/*
homeassistant/components/lifx/*
homeassistant/components/lifx_cloud/scene.py
homeassistant/components/lifx_legacy/light.py
@@ -339,11 +357,13 @@ omit =
homeassistant/components/mastodon/notify.py
homeassistant/components/matrix/*
homeassistant/components/maxcube/*
homeassistant/components/mcp23017/*
homeassistant/components/media_extractor/*
homeassistant/components/mediaroom/media_player.py
homeassistant/components/message_bird/notify.py
homeassistant/components/met/weather.py
homeassistant/components/meteo_france/*
homeassistant/components/meteoalarm/*
homeassistant/components/metoffice/sensor.py
homeassistant/components/metoffice/weather.py
homeassistant/components/microsoft/tts.py
@@ -389,6 +409,8 @@ omit =
homeassistant/components/nissan_leaf/*
homeassistant/components/nmap_tracker/device_tracker.py
homeassistant/components/nmbs/sensor.py
homeassistant/components/notion/binary_sensor.py
homeassistant/components/notion/sensor.py
homeassistant/components/noaa_tides/sensor.py
homeassistant/components/norway_air/air_quality.py
homeassistant/components/nsw_fuel_station/sensor.py
@@ -418,6 +440,7 @@ omit =
homeassistant/components/openweathermap/sensor.py
homeassistant/components/openweathermap/weather.py
homeassistant/components/opple/light.py
homeassistant/components/orangepi_gpio/*
homeassistant/components/orvibo/switch.py
homeassistant/components/osramlightify/light.py
homeassistant/components/otp/sensor.py
@@ -435,12 +458,12 @@ omit =
homeassistant/components/ping/device_tracker.py
homeassistant/components/pioneer/media_player.py
homeassistant/components/pjlink/media_player.py
homeassistant/components/plaato/*
homeassistant/components/plex/media_player.py
homeassistant/components/plex/sensor.py
homeassistant/components/plum_lightpad/*
homeassistant/components/pocketcasts/sensor.py
homeassistant/components/point/*
homeassistant/components/pollen/sensor.py
homeassistant/components/postnl/sensor.py
homeassistant/components/prezzibenzina/sensor.py
homeassistant/components/proliphix/climate.py
@@ -449,6 +472,7 @@ omit =
homeassistant/components/proxy/camera.py
homeassistant/components/ps4/__init__.py
homeassistant/components/ps4/media_player.py
homeassistant/components/ptvsd/*
homeassistant/components/pulseaudio_loopback/switch.py
homeassistant/components/pushbullet/notify.py
homeassistant/components/pushbullet/sensor.py
@@ -480,6 +504,9 @@ omit =
homeassistant/components/reddit/*
homeassistant/components/rejseplanen/sensor.py
homeassistant/components/remember_the_milk/__init__.py
homeassistant/components/repetier/__init__.py
homeassistant/components/repetier/sensor.py
homeassistant/components/remote_rpi_gpio/*
homeassistant/components/rest/binary_sensor.py
homeassistant/components/rest/notify.py
homeassistant/components/rest/switch.py
@@ -532,14 +559,17 @@ omit =
homeassistant/components/slack/notify.py
homeassistant/components/sma/sensor.py
homeassistant/components/smappee/*
homeassistant/components/smarty/*
homeassistant/components/smarthab/*
homeassistant/components/smtp/notify.py
homeassistant/components/snapcast/media_player.py
homeassistant/components/snmp/device_tracker.py
homeassistant/components/snmp/sensor.py
homeassistant/components/snmp/switch.py
homeassistant/components/snmp/*
homeassistant/components/sochain/sensor.py
homeassistant/components/socialblade/sensor.py
homeassistant/components/solaredge/sensor.py
homeassistant/components/solaredge_local/sensor.py
homeassistant/components/solax/sensor.py
homeassistant/components/somfy/*
homeassistant/components/somfy_mylink/*
homeassistant/components/sonarr/sensor.py
homeassistant/components/songpal/media_player.py
@@ -555,12 +585,14 @@ omit =
homeassistant/components/starlingbank/sensor.py
homeassistant/components/steam_online/sensor.py
homeassistant/components/stiebel_eltron/*
homeassistant/components/streamlabswater/*
homeassistant/components/stride/notify.py
homeassistant/components/supervisord/sensor.py
homeassistant/components/swiss_hydrological_data/sensor.py
homeassistant/components/swiss_public_transport/sensor.py
homeassistant/components/swisscom/device_tracker.py
homeassistant/components/switchbot/switch.py
homeassistant/components/switcher_kis/switch.py
homeassistant/components/switchmate/switch.py
homeassistant/components/syncthru/sensor.py
homeassistant/components/synology/camera.py
@@ -607,9 +639,11 @@ omit =
homeassistant/components/tplink/switch.py
homeassistant/components/tplink_lte/*
homeassistant/components/traccar/device_tracker.py
homeassistant/components/traccar/const.py
homeassistant/components/trackr/device_tracker.py
homeassistant/components/tradfri/*
homeassistant/components/tradfri/light.py
homeassistant/components/trafikverket_train/sensor.py
homeassistant/components/trafikverket_weatherstation/sensor.py
homeassistant/components/transmission/*
homeassistant/components/travisci/sensor.py
@@ -628,6 +662,7 @@ omit =
homeassistant/components/uptimerobot/binary_sensor.py
homeassistant/components/uscis/sensor.py
homeassistant/components/usps/*
homeassistant/components/vallox/*
homeassistant/components/vasttrafik/sensor.py
homeassistant/components/velbus/*
homeassistant/components/velux/*
@@ -638,6 +673,7 @@ omit =
homeassistant/components/viaggiatreno/sensor.py
homeassistant/components/vizio/media_player.py
homeassistant/components/vlc/media_player.py
homeassistant/components/vlc_telnet/media_player.py
homeassistant/components/volkszaehler/sensor.py
homeassistant/components/volumio/media_player.py
homeassistant/components/volvooncall/*
@@ -645,6 +681,7 @@ omit =
homeassistant/components/waqi/sensor.py
homeassistant/components/waterfurnace/*
homeassistant/components/watson_iot/*
homeassistant/components/watson_tts/tts.py
homeassistant/components/waze_travel_time/sensor.py
homeassistant/components/webostv/*
homeassistant/components/wemo/*
@@ -655,6 +692,8 @@ omit =
homeassistant/components/worldtidesinfo/sensor.py
homeassistant/components/worxlandroid/sensor.py
homeassistant/components/wunderlist/*
homeassistant/components/wwlln/__init__.py
homeassistant/components/wwlln/geo_location.py
homeassistant/components/x10/light.py
homeassistant/components/xbox_live/sensor.py
homeassistant/components/xeoma/camera.py

30
.devcontainer/Dockerfile Normal file
View File

@@ -0,0 +1,30 @@
FROM python:3.7
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libudev-dev \
libavformat-dev \
libavcodec-dev \
libavdevice-dev \
libavutil-dev \
libswscale-dev \
libswresample-dev \
libavfilter-dev \
git \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src
RUN git clone --depth 1 https://github.com/home-assistant/hass-release \
&& cd hass-release \
&& pip3 install -e .
WORKDIR /workspace
# Install Python dependencies from requirements.txt if it exists
COPY requirements_test_all.txt homeassistant/package_constraints.txt /workspace/
RUN pip3 install -r requirements_test_all.txt -c package_constraints.txt
# Set the default shell to bash instead of sh
ENV SHELL /bin/bash

View File

@@ -0,0 +1,24 @@
// See https://aka.ms/vscode-remote/devcontainer.json for format details.
{
"name": "Home Assistant Dev",
"context": "..",
"dockerFile": "Dockerfile",
"postCreateCommand": "pip3 install -e .",
"appPort": 8123,
"runArgs": [
"-e", "GIT_EDTIOR='code --wait'"
],
"extensions": [
"ms-python.python",
"ms-azure-devops.azure-pipelines",
"redhat.vscode-yaml"
],
"settings": {
"python.pythonPath": "/usr/local/bin/python",
"python.linting.pylintEnabled": true,
"python.linting.enabled": true,
"files.trimTrailingWhitespace": true,
"editor.rulers": [80],
"terminal.integrated.shell.linux": "/bin/bash"
}
}

View File

@@ -3,7 +3,7 @@
- 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
- Do not report issues for integrations if you are using custom integration: 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

@@ -9,7 +9,7 @@ about: Create a report to help us improve
- 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
- Do not report issues for integrations if you are using a custom integration: 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,7 +7,7 @@
**Related issue (if applicable):** fixes #<home-assistant issue number goes here>
**Pull request in [home-assistant.io](https://github.com/home-assistant/home-assistant.io) with documentation (if applicable):** home-assistant/home-assistant.io#<home-assistant.io PR number goes here>
**Pull request with documentation for [home-assistant.io](https://github.com/home-assistant/home-assistant.io) (if applicable):** home-assistant/home-assistant.io#<home-assistant.io PR number goes here>
## Example entry for `configuration.yaml` (if applicable):
```yaml
@@ -18,21 +18,18 @@
- [ ] The code change is tested and works locally.
- [ ] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
- [ ] There is no commented out code in this PR.
- [ ] I have followed the [development checklist][dev-checklist]
If user exposed functionality or configuration variables are added/changed:
- [ ] Documentation added/updated in [home-assistant.io](https://github.com/home-assistant/home-assistant.io)
If the code communicates with devices, web services, or third-party tools:
- [ ] [_The manifest file_][manifest-docs] has all fields filled out correctly ([example][ex-manifest]).
- [ ] New dependencies have been added to `requirements` in the manifest ([example][ex-requir]).
- [ ] New dependencies are only imported inside functions that use them ([example][ex-import]).
- [ ] New or updated dependencies have been added to `requirements_all.txt` by running `script/gen_requirements_all.py`.
- [ ] New files were added to `.coveragerc`.
- [ ] [_The manifest file_][manifest-docs] has all fields filled out correctly. Update and include derived files by running `python3 -m script.hassfest`.
- [ ] New or updated dependencies have been added to `requirements_all.txt` by running `python3 -m script.gen_requirements_all`.
- [ ] Untested files have been added to `.coveragerc`.
If the code does not interact with devices:
- [ ] Tests have been added to verify that the new code works.
[ex-manifest]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/mobile_app/manifest.json
[ex-requir]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/mobile_app/manifest.json#L5
[ex-import]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard/__init__.py#L23
[manifest-docs]: https://developers.home-assistant.io/docs/en/development_checklist.html#_the-manifest-file_
[dev-checklist]: https://developers.home-assistant.io/docs/en/development_checklist.html
[manifest-docs]: https://developers.home-assistant.io/docs/en/creating_integration_manifest.html

27
.github/lock.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
# Configuration for Lock Threads - https://github.com/dessant/lock-threads
# Number of days of inactivity before a closed issue or pull request is locked
daysUntilLock: 1
# Skip issues and pull requests created before a given timestamp. Timestamp must
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
skipCreatedBefore: 2019-07-01
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
exemptLabels: []
# Label to add before locking, such as `outdated`. Set to `false` to disable
lockLabel: false
# Comment to post before locking. Set to `false` to disable
lockComment: false
# Assign `resolved` as the reason for locking. Set to `false` to disable
setLockReason: false
# Limit to only `issues` or `pulls`
only: pulls
# Optionally, specify configuration settings just for `issues` or `pulls`
issues:
daysUntilLock: 30

14
.github/main.workflow vendored
View File

@@ -1,14 +0,0 @@
workflow "Mention CODEOWNERS of integrations when integration label is added to an issue" {
on = "issues"
resolves = "codeowners-mention"
}
workflow "Mention CODEOWNERS of integrations when integration label is added to an PRs" {
on = "pull_request"
resolves = "codeowners-mention"
}
action "codeowners-mention" {
uses = "home-assistant/codeowners-mention@master"
secrets = ["GITHUB_TOKEN"]
}

54
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,54 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 90
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
onlyLabels: []
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- under investigation
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: true
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
There hasn't been any activity on this issue recently. Due to the high number
of incoming GitHub notifications, we have to clean some of the old issues,
as many of them have already been resolved with the latest updates.
Please make sure to update to the latest Home Assistant version and check
if that solves the issue. Let us know if that works for you by adding a
comment 👍
This issue now has been marked as stale and will be closed if no further
activity occurs. Thank you for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
# closeComment: >
# Your comment here.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
only: issues

12
.gitignore vendored
View File

@@ -1,8 +1,13 @@
config/*
config2/*
tests/testing_config/deps
tests/testing_config/home-assistant.log
# hass-release
data/
.token
# Hide sublime text stuff
*.sublime-project
*.sublime-workspace
@@ -84,7 +89,7 @@ Scripts/
# vimmy stuff
*.swp
*.swo
tags
ctags.tmp
# vagrant stuff
@@ -93,7 +98,10 @@ virtualization/vagrant/.vagrant
virtualization/vagrant/config
# Visual Studio Code
.vscode
.vscode/*
!.vscode/cSpell.json
!.vscode/extensions.json
!.vscode/tasks.json
# Built docs
docs/build

33
.travis.yml Normal file
View File

@@ -0,0 +1,33 @@
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:
- python: "3.5.3"
env: TOXENV=lint
- python: "3.5.3"
env: TOXENV=pylint
- python: "3.5.3"
env: TOXENV=typing
- python: "3.5.3"
env: TOXENV=py35
- python: "3.7"
env: TOXENV=py37
cache: pip
install: pip install -U tox
language: python
script: travis_wait 40 tox --develop

92
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,92 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Preview",
"type": "shell",
"command": "hass -c ./config",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Pytest",
"type": "shell",
"command": "pytest --timeout=10 tests",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Flake8",
"type": "shell",
"command": "flake8 homeassistant tests",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Pylint",
"type": "shell",
"command": "pylint homeassistant",
"dependsOn": [
"Install all Requirements"
],
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Generate Requirements",
"type": "shell",
"command": "./script/gen_requirements_all.py",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Install all Requirements",
"type": "shell",
"command": "pip3 install -r requirements_all.txt -c homeassistant/package_constraints.txt",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
}
]
}

View File

@@ -17,32 +17,41 @@ virtualization/Docker/* @home-assistant/docker
homeassistant/scripts/check_config.py @kellerza
# Integrations
homeassistant/components/adguard/* @frenck
homeassistant/components/airvisual/* @bachya
homeassistant/components/alarm_control_panel/* @colinodell
homeassistant/components/alpha_vantage/* @fabaff
homeassistant/components/amazon_polly/* @robbiet480
homeassistant/components/ambiclimate/* @danielhiversen
homeassistant/components/ambient_station/* @bachya
homeassistant/components/api/* @home-assistant/core
homeassistant/components/aprs/* @PhilRW
homeassistant/components/arcam_fmj/* @elupus
homeassistant/components/arduino/* @fabaff
homeassistant/components/arest/* @fabaff
homeassistant/components/asuswrt/* @kennedyshead
homeassistant/components/aurora_abb_powerone/* @davet2001
homeassistant/components/auth/* @home-assistant/core
homeassistant/components/automatic/* @armills
homeassistant/components/automation/* @home-assistant/core
homeassistant/components/awair/* @danielsjf
homeassistant/components/aws/* @awarecan @robbiet480
homeassistant/components/axis/* @kane610
homeassistant/components/azure_event_hub/* @eavanvalkenburg
homeassistant/components/bitcoin/* @fabaff
homeassistant/components/bizkaibus/* @UgaitzEtxebarria
homeassistant/components/blink/* @fronzbot
homeassistant/components/bmw_connected_drive/* @ChristianKuehnel
homeassistant/components/braviatv/* @robbiet480
homeassistant/components/broadlink/* @danielhiversen
homeassistant/components/brunt/* @eavanvalkenburg
homeassistant/components/bt_smarthub/* @jxwolstenholme
homeassistant/components/buienradar/* @ties
homeassistant/components/cisco_ios/* @fbradyirl
homeassistant/components/cisco_mobility_express/* @fbradyirl
homeassistant/components/cisco_webex_teams/* @fbradyirl
homeassistant/components/ciscospark/* @fbradyirl
homeassistant/components/cloud/* @home-assistant/core
homeassistant/components/cloud/* @home-assistant/cloud
homeassistant/components/cloudflare/* @ludeeus
homeassistant/components/config/* @home-assistant/core
homeassistant/components/configurator/* @home-assistant/core
@@ -56,6 +65,7 @@ homeassistant/components/daikin/* @fredrike @rofrantz
homeassistant/components/darksky/* @fabaff
homeassistant/components/deconz/* @kane610
homeassistant/components/demo/* @home-assistant/core
homeassistant/components/device_automation/* @home-assistant/core
homeassistant/components/digital_ocean/* @fabaff
homeassistant/components/discogs/* @thibmaek
homeassistant/components/doorbird/* @oblogic7
@@ -64,12 +74,17 @@ homeassistant/components/ecovacs/* @OverloadUT
homeassistant/components/edp_redy/* @abmantis
homeassistant/components/egardia/* @jeroenterheerdt
homeassistant/components/eight_sleep/* @mezz64
homeassistant/components/elv/* @majuss
homeassistant/components/emby/* @mezz64
homeassistant/components/enigma2/* @fbradyirl
homeassistant/components/enocean/* @bdurrer
homeassistant/components/environment_canada/* @michaeldavie
homeassistant/components/ephember/* @ttroy50
homeassistant/components/epsonworkforce/* @ThaStealth
homeassistant/components/eq3btsmart/* @rytilahti
homeassistant/components/esphome/* @OttoWinter
homeassistant/components/essent/* @TheLastProject
homeassistant/components/evohome/* @zxdavb
homeassistant/components/file/* @fabaff
homeassistant/components/filter/* @dgomes
homeassistant/components/fitbit/* @robbiet480
@@ -78,11 +93,14 @@ homeassistant/components/flock/* @fabaff
homeassistant/components/flunearyou/* @bachya
homeassistant/components/foursquare/* @robbiet480
homeassistant/components/freebox/* @snoof85
homeassistant/components/frontend/* @home-assistant/core
homeassistant/components/fronius/* @nielstron
homeassistant/components/frontend/* @home-assistant/frontend
homeassistant/components/gearbest/* @HerrHofrat
homeassistant/components/geniushub/* @zxdavb
homeassistant/components/gitter/* @fabaff
homeassistant/components/glances/* @fabaff
homeassistant/components/gntp/* @robbiet480
homeassistant/components/google_cloud/* @lufton
homeassistant/components/google_translate/* @awarecan
homeassistant/components/google_travel_time/* @robbiet480
homeassistant/components/googlehome/* @ludeeus
@@ -98,14 +116,16 @@ homeassistant/components/history/* @home-assistant/core
homeassistant/components/history_graph/* @andrey-git
homeassistant/components/hive/* @Rendili @KJonline
homeassistant/components/homeassistant/* @home-assistant/core
homeassistant/components/homekit/* @cdce8p
homeassistant/components/homekit_controller/* @Jc2k
homeassistant/components/homematic/* @pvizeli @danielperna84
homeassistant/components/honeywell/* @zxdavb
homeassistant/components/html5/* @robbiet480
homeassistant/components/http/* @home-assistant/core
homeassistant/components/huawei_lte/* @scop
homeassistant/components/huawei_router/* @abmantis
homeassistant/components/hue/* @balloob
homeassistant/components/ign_sismologia/* @exxamalte
homeassistant/components/incomfort/* @zxdavb
homeassistant/components/influxdb/* @fabaff
homeassistant/components/input_boolean/* @home-assistant/core
homeassistant/components/input_datetime/* @home-assistant/core
@@ -115,6 +135,7 @@ homeassistant/components/input_text/* @home-assistant/core
homeassistant/components/integration/* @dgomes
homeassistant/components/ios/* @robbiet480
homeassistant/components/ipma/* @dgomes
homeassistant/components/iqvia/* @bachya
homeassistant/components/irish_rail_transport/* @ttroy50
homeassistant/components/jewish_calendar/* @tsvi
homeassistant/components/knx/* @Julius2342
@@ -122,21 +143,27 @@ homeassistant/components/kodi/* @armills
homeassistant/components/konnected/* @heythisisnate
homeassistant/components/lametric/* @robbiet480
homeassistant/components/launch_library/* @ludeeus
homeassistant/components/lcn/* @alengwenus
homeassistant/components/life360/* @pnbruckner
homeassistant/components/lifx/* @amelchio
homeassistant/components/lifx_cloud/* @amelchio
homeassistant/components/lifx_legacy/* @amelchio
homeassistant/components/linky/* @tiste @Quentame
homeassistant/components/linux_battery/* @fabaff
homeassistant/components/liveboxplaytv/* @pschmitt
homeassistant/components/logger/* @home-assistant/core
homeassistant/components/logi_circle/* @evanjd
homeassistant/components/lovelace/* @home-assistant/core
homeassistant/components/lovelace/* @home-assistant/frontend
homeassistant/components/luci/* @fbradyirl
homeassistant/components/luftdaten/* @fabaff
homeassistant/components/mastodon/* @fabaff
homeassistant/components/matrix/* @tinloaf
homeassistant/components/mcp23017/* @jardiamj
homeassistant/components/mediaroom/* @dgomes
homeassistant/components/melissa/* @kennedyshead
homeassistant/components/met/* @danielhiversen
homeassistant/components/meteo_france/* @victorcerutti @oncleben31
homeassistant/components/meteoalarm/* @rolfberkenbosch
homeassistant/components/miflora/* @danielhiversen @ChristianKuehnel
homeassistant/components/mill/* @danielhiversen
homeassistant/components/min_max/* @fabaff
@@ -150,32 +177,41 @@ homeassistant/components/nello/* @pschmitt
homeassistant/components/ness_alarm/* @nickw444
homeassistant/components/nest/* @awarecan
homeassistant/components/netdata/* @fabaff
homeassistant/components/nextbus/* @vividboarder
homeassistant/components/nissan_leaf/* @filcole
homeassistant/components/nmbs/* @thibmaek
homeassistant/components/no_ip/* @fabaff
homeassistant/components/notify/* @flowolf
homeassistant/components/notify/* @home-assistant/core
homeassistant/components/notion/* @bachya
homeassistant/components/nsw_fuel_station/* @nickw444
homeassistant/components/nuki/* @pschmitt
homeassistant/components/ohmconnect/* @robbiet480
homeassistant/components/onboarding/* @home-assistant/core
homeassistant/components/opentherm_gw/* @mvn23
homeassistant/components/openuv/* @bachya
homeassistant/components/openweathermap/* @fabaff
homeassistant/components/orangepi_gpio/* @pascallj
homeassistant/components/owlet/* @oblogic7
homeassistant/components/panel_custom/* @home-assistant/core
homeassistant/components/panel_iframe/* @home-assistant/core
homeassistant/components/panel_custom/* @home-assistant/frontend
homeassistant/components/panel_iframe/* @home-assistant/frontend
homeassistant/components/persistent_notification/* @home-assistant/core
homeassistant/components/philips_js/* @elupus
homeassistant/components/pi_hole/* @fabaff
homeassistant/components/plaato/* @JohNan
homeassistant/components/plant/* @ChristianKuehnel
homeassistant/components/point/* @fredrike
homeassistant/components/pollen/* @bachya
homeassistant/components/ps4/* @ktnrg45
homeassistant/components/ptvsd/* @swamp-ig
homeassistant/components/push/* @dgomes
homeassistant/components/pvoutput/* @fabaff
homeassistant/components/qld_bushfire/* @exxamalte
homeassistant/components/qnap/* @colinodell
homeassistant/components/quantum_gateway/* @cisasteelersfan
homeassistant/components/qwikswitch/* @kellerza
homeassistant/components/raincloud/* @vanstinator
homeassistant/components/rainmachine/* @bachya
homeassistant/components/random/* @fabaff
homeassistant/components/repetier/* @MTrab
homeassistant/components/rfxtrx/* @danielhiversen
homeassistant/components/rmvtransport/* @cgtobi
homeassistant/components/roomba/* @pschmitt
@@ -183,6 +219,7 @@ homeassistant/components/ruter/* @ludeeus
homeassistant/components/scene/* @home-assistant/core
homeassistant/components/scrape/* @fabaff
homeassistant/components/script/* @home-assistant/core
homeassistant/components/sense/* @kbickar
homeassistant/components/sensibo/* @andrey-git
homeassistant/components/serial/* @fabaff
homeassistant/components/seventeentrack/* @bachya
@@ -191,20 +228,28 @@ homeassistant/components/shiftr/* @fabaff
homeassistant/components/shodan/* @fabaff
homeassistant/components/simplisafe/* @bachya
homeassistant/components/sma/* @kellerza
homeassistant/components/smarthab/* @outadoc
homeassistant/components/smartthings/* @andrewsayre
homeassistant/components/smarty/* @z0mbieprocess
homeassistant/components/smtp/* @fabaff
homeassistant/components/solaredge_local/* @drobtravels
homeassistant/components/solax/* @squishykid
homeassistant/components/somfy/* @tetienne
homeassistant/components/sonos/* @amelchio
homeassistant/components/spaceapi/* @fabaff
homeassistant/components/spider/* @peternijssen
homeassistant/components/sql/* @dgomes
homeassistant/components/statistics/* @fabaff
homeassistant/components/stiebel_eltron/* @fucm
homeassistant/components/sun/* @home-assistant/core
homeassistant/components/stream/* @hunterjm
homeassistant/components/sun/* @Swamp-Ig
homeassistant/components/supla/* @mwegrzynek
homeassistant/components/swiss_hydrological_data/* @fabaff
homeassistant/components/swiss_public_transport/* @fabaff
homeassistant/components/switchbot/* @danielhiversen
homeassistant/components/switcher_kis/* @tomerfi
homeassistant/components/switchmate/* @danielhiversen
homeassistant/components/syncthru/* @nielstron
homeassistant/components/synology_srm/* @aerialls
homeassistant/components/syslog/* @fabaff
homeassistant/components/sytadin/* @gautric
@@ -223,10 +268,10 @@ homeassistant/components/toon/* @frenck
homeassistant/components/tplink/* @rytilahti
homeassistant/components/traccar/* @ludeeus
homeassistant/components/tradfri/* @ggravlingen
homeassistant/components/trafikverket_train/* @endor-force
homeassistant/components/tts/* @robbiet480
homeassistant/components/twilio_call/* @robbiet480
homeassistant/components/twilio_sms/* @robbiet480
homeassistant/components/uber/* @robbiet480
homeassistant/components/unifi/* @kane610
homeassistant/components/upcloud/* @scop
homeassistant/components/updater/* @home-assistant/core
@@ -235,28 +280,32 @@ homeassistant/components/uptimerobot/* @ludeeus
homeassistant/components/utility_meter/* @dgomes
homeassistant/components/velux/* @Julius2342
homeassistant/components/version/* @fabaff
homeassistant/components/vizio/* @raman325
homeassistant/components/vlc_telnet/* @rodripf
homeassistant/components/waqi/* @andrey-git
homeassistant/components/watson_tts/* @rutkai
homeassistant/components/weather/* @fabaff
homeassistant/components/weblink/* @home-assistant/core
homeassistant/components/websocket_api/* @home-assistant/core
homeassistant/components/wemo/* @sqldiablo
homeassistant/components/worldclock/* @fabaff
homeassistant/components/wwlln/* @bachya
homeassistant/components/xfinity/* @cisasteelersfan
homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi
homeassistant/components/xiaomi_miio/* @rytilahti @syssi
homeassistant/components/xiaomi_tv/* @fattdev
homeassistant/components/xmpp/* @fabaff
homeassistant/components/xiaomi_tv/* @simse
homeassistant/components/xmpp/* @fabaff @flowolf
homeassistant/components/yamaha_musiccast/* @jalmeroth
homeassistant/components/yeelight/* @rytilahti @zewelor
homeassistant/components/yeelightsunflower/* @lindsaymarkward
homeassistant/components/yessssms/* @flowolf
homeassistant/components/yi/* @bachya
homeassistant/components/zeroconf/* @robbiet480
homeassistant/components/yr/* @danielhiversen
homeassistant/components/zeroconf/* @robbiet480 @Kane610
homeassistant/components/zha/* @dmulcahey @adminiuga
homeassistant/components/zone/* @home-assistant/core
homeassistant/components/zoneminder/* @rohankapoorcom
homeassistant/components/zwave/* @home-assistant/z-wave
# Individual files
homeassistant/components/group/cover @cdce8p
homeassistant/components/demo/weather @fabaff

View File

@@ -24,12 +24,14 @@ RUN virtualization/Docker/setup_docker_prereqs
# Install hass component dependencies
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==0.12.2 cchardet cython tensorflow
# Copy source
COPY . .
EXPOSE 8123
EXPOSE 8300
EXPOSE 51827
CMD [ "python", "-m", "homeassistant", "--config", "/config" ]

View File

@@ -1,4 +1,4 @@
Home Assistant |Build Status| |CI Status| |Coverage Status| |Chat Status|
Home Assistant |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.
@@ -27,12 +27,6 @@ components <https://developers.home-assistant.io/docs/en/creating_component_inde
If you run into issues while using Home Assistant or during development
of a component, check the `Home Assistant help section <https://home-assistant.io/help/>`__ of our website for further help and information.
.. |Build Status| image:: https://travis-ci.org/home-assistant/home-assistant.svg?branch=dev
:target: https://travis-ci.org/home-assistant/home-assistant
.. |CI Status| image:: https://circleci.com/gh/home-assistant/home-assistant.svg?style=shield
:target: https://circleci.com/gh/home-assistant/home-assistant
.. |Coverage Status| image:: https://img.shields.io/coveralls/home-assistant/home-assistant.svg
: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
.. |screenshot-states| image:: https://raw.github.com/home-assistant/home-assistant/master/docs/screenshots.png

177
azure-pipelines-ci.yml Normal file
View File

@@ -0,0 +1,177 @@
# https://dev.azure.com/home-assistant
trigger:
batch: true
branches:
include:
- dev
pr: none
resources:
containers:
- container: 35
image: homeassistant/ci-azure:3.5
- container: 36
image: homeassistant/ci-azure:3.6
- container: 37
image: homeassistant/ci-azure:3.7
variables:
- name: ArtifactFeed
value: '2df3ae11-3bf6-49bc-a809-ba0d340d6a6d'
- name: PythonMain
value: '35'
stages:
- stage: 'Overview'
jobs:
- job: 'Lint'
pool:
vmImage: 'ubuntu-latest'
container: $[ variables['PythonMain'] ]
steps:
- script: |
python -m venv venv
. venv/bin/activate
pip install flake8
displayName: 'Setup Env'
- script: |
. venv/bin/activate
flake8 homeassistant tests script
displayName: 'Run flake8'
- job: 'Validate'
pool:
vmImage: 'ubuntu-latest'
container: $[ variables['PythonMain'] ]
steps:
- script: |
python -m venv venv
. venv/bin/activate
pip install -e .
displayName: 'Setup Env'
- script: |
. venv/bin/activate
python -m script.hassfest validate
displayName: 'Validate manifests'
- script: |
. venv/bin/activate
./script/gen_requirements_all.py validate
displayName: 'requirements_all validate'
- stage: 'Tests'
dependsOn:
- 'Overview'
jobs:
- job: 'PyTest'
pool:
vmImage: 'ubuntu-latest'
strategy:
maxParallel: 3
matrix:
Python35:
python.container: '35'
Python36:
python.container: '36'
Python37:
python.container: '37'
container: $[ variables['python.container'] ]
steps:
- script: |
python --version > .cache
displayName: 'Set python $(python.version) for requirement cache'
- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1
displayName: 'Restore artifacts based on Requirements'
inputs:
keyfile: 'requirements_test_all.txt, .cache'
targetfolder: './venv'
vstsFeed: '$(ArtifactFeed)'
- script: |
set -e
python -m venv venv
. venv/bin/activate
pip install -U pip setuptools
pip install -r requirements_test_all.txt -c homeassistant/package_constraints.txt
pip install pytest-azurepipelines -c homeassistant/package_constraints.txt
displayName: 'Create Virtual Environment & Install Requirements'
condition: and(succeeded(), ne(variables['CacheRestored'], 'true'))
- task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1
displayName: 'Save artifacts based on Requirements'
inputs:
keyfile: 'requirements_test_all.txt, .cache'
targetfolder: './venv'
vstsFeed: '$(ArtifactFeed)'
- script: |
. venv/bin/activate
pip install -e .
displayName: 'Install Home Assistant for python $(python.version)'
- script: |
. venv/bin/activate
pytest --timeout=9 --durations=10 --junitxml=junit/test-results.xml -qq -o console_output_style=count -p no:sugar tests
displayName: 'Run pytest for python $(python.version)'
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFiles: '**/test-*.xml'
testRunTitle: 'Publish test results for Python $(python.version)'
- stage: 'FullCheck'
dependsOn:
- 'Overview'
jobs:
- job: 'Pytlint'
pool:
vmImage: 'ubuntu-latest'
container: $[ variables['PythonMain'] ]
steps:
- script: |
python --version > .cache
displayName: 'Set python $(python.version) for requirement cache'
- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1
displayName: 'Restore artifacts based on Requirements'
inputs:
keyfile: 'requirements_all.txt, requirements_test.txt, .cache'
targetfolder: './venv'
vstsFeed: '$(ArtifactFeed)'
- script: |
set -e
python -m venv venv
. venv/bin/activate
pip install -U pip setuptools
pip install -r requirements_all.txt -c homeassistant/package_constraints.txt
pip install -r requirements_test.txt -c homeassistant/package_constraints.txt
displayName: 'Create Virtual Environment & Install Requirements'
condition: and(succeeded(), ne(variables['CacheRestored'], 'true'))
- task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1
displayName: 'Save artifacts based on Requirements'
inputs:
keyfile: 'requirements_all.txt, requirements_test.txt, .cache'
targetfolder: './venv'
vstsFeed: '$(ArtifactFeed)'
- script: |
. venv/bin/activate
pip install -e .
displayName: 'Install Home Assistant for python $(python.version)'
- script: |
. venv/bin/activate
pylint homeassistant
displayName: 'Run pylint'
- job: 'Mypy'
pool:
vmImage: 'ubuntu-latest'
container: $[ variables['PythonMain'] ]
steps:
- script: |
python -m venv venv
. venv/bin/activate
pip install -r requirements_test.txt
displayName: 'Setup Env'
- script: |
. venv/bin/activate
TYPING_FILES=$(cat mypyrc)
mypy $TYPING_FILES
displayName: 'Run mypy'

159
azure-pipelines-release.yml Normal file
View File

@@ -0,0 +1,159 @@
# https://dev.azure.com/home-assistant
trigger:
batch: true
tags:
include:
- '*'
pr: none
variables:
- name: versionBuilder
value: '5.2'
- group: docker
- group: github
- group: twine
stages:
- stage: 'Validate'
jobs:
- job: 'VersionValidate'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UsePythonVersion@0
displayName: 'Use Python 3.7'
inputs:
versionSpec: '3.7'
- script: |
setup_version="$(python setup.py -V)"
branch_version="$(Build.SourceBranchName)"
if [ "${setup_version}" != "${branch_version}" ]; then
echo "Version of tag ${branch_version} don't match with ${setup_version}!"
exit 1
fi
displayName: 'Check version of branch/tag'
- script: |
sudo apt-get install -y --no-install-recommends \
jq curl
release="$(Build.SourceBranchName)"
created_by="$(curl -s https://api.github.com/repos/home-assistant/home-assistant/releases/tags/${release} | jq --raw-output '.author.login')"
if [[ "${created_by}" =~ ^(balloob|pvizeli|fabaff|robbiet480)$ ]]; then
exit 0
fi
echo "${created_by} is not allowed to create an release!"
exit 1
displayName: 'Check rights'
- stage: 'Build'
jobs:
- job: 'ReleasePython'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UsePythonVersion@0
displayName: 'Use Python 3.7'
inputs:
versionSpec: '3.7'
- script: pip install twine wheel
displayName: 'Install tools'
- script: python setup.py sdist bdist_wheel
displayName: 'Build package'
- script: |
export TWINE_USERNAME="$(twineUser)"
export TWINE_PASSWORD="$(twinePassword)"
twine upload dist/* --skip-existing
displayName: 'Upload pypi'
- job: 'ReleaseDocker'
timeoutInMinutes: 240
pool:
vmImage: 'ubuntu-latest'
strategy:
maxParallel: 5
matrix:
amd64:
buildArch: 'amd64'
buildMachine: 'qemux86-64,intel-nuc'
i386:
buildArch: 'i386'
buildMachine: 'qemux86'
armhf:
buildArch: 'armhf'
buildMachine: 'qemuarm,raspberrypi'
armv7:
buildArch: 'armv7'
buildMachine: 'raspberrypi2,raspberrypi3,raspberrypi4,odroid-xu,tinker'
aarch64:
buildArch: 'aarch64'
buildMachine: 'qemuarm-64,raspberrypi3-64,raspberrypi4-64,odroid-c2,orangepi-prime'
steps:
- script: sudo docker login -u $(dockerUser) -p $(dockerPassword)
displayName: 'Docker hub login'
- script: sudo docker pull homeassistant/amd64-builder:$(versionBuilder)
displayName: 'Install Builder'
- script: |
set -e
sudo docker run --rm --privileged \
-v ~/.docker:/root/.docker \
-v /run/docker.sock:/run/docker.sock:rw \
homeassistant/amd64-builder:$(versionBuilder) \
--homeassistant $(Build.SourceBranchName) "--$(buildArch)" \
-r https://github.com/home-assistant/hassio-homeassistant \
-t generic --docker-hub homeassistant
sudo docker run --rm --privileged \
-v ~/.docker:/root/.docker \
-v /run/docker.sock:/run/docker.sock:rw \
homeassistant/amd64-builder:$(versionBuilder) \
--homeassistant-machine "$(Build.SourceBranchName)=$(buildMachine)" \
-r https://github.com/home-assistant/hassio-homeassistant \
-t machine --docker-hub homeassistant
displayName: 'Build Release'
- stage: 'Publish'
jobs:
- job: 'ReleaseHassio'
pool:
vmImage: 'ubuntu-latest'
steps:
- script: |
sudo apt-get install -y --no-install-recommends \
git jq curl
git config --global user.name "Pascal Vizeli"
git config --global user.email "pvizeli@syshack.ch"
git config --global credential.helper store
echo "https://$(githubToken):x-oauth-basic@github.com" > $HOME/.git-credentials
displayName: 'Install requirements'
- script: |
set -e
version="$(Build.SourceBranchName)"
git clone https://github.com/home-assistant/hassio-version
cd hassio-version
dev_version="$(jq --raw-output '.homeassistant.default' dev.json)"
beta_version="$(jq --raw-output '.homeassistant.default' beta.json)"
stable_version="$(jq --raw-output '.homeassistant.default' stable.json)"
if [[ "$version" =~ b ]]; then
sed -i "s|$dev_version|$version|g" dev.json
sed -i "s|$beta_version|$version|g" beta.json
else
sed -i "s|$dev_version|$version|g" dev.json
sed -i "s|$beta_version|$version|g" beta.json
sed -i "s|$stable_version|$version|g" stable.json
fi
git commit -am "Bump Home Assistant $version"
git push
displayName: 'Update version files'

View File

@@ -0,0 +1,99 @@
# https://dev.azure.com/home-assistant
trigger:
batch: true
branches:
include:
- dev
paths:
include:
- requirements_all.txt
pr: none
variables:
- name: versionWheels
value: '1.0-3.7-alpine3.10'
- group: wheels
jobs:
- job: 'Wheels'
timeoutInMinutes: 360
pool:
vmImage: 'ubuntu-latest'
strategy:
maxParallel: 5
matrix:
amd64:
buildArch: 'amd64'
i386:
buildArch: 'i386'
armhf:
buildArch: 'armhf'
armv7:
buildArch: 'armv7'
aarch64:
buildArch: 'aarch64'
steps:
- script: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
qemu-user-static \
binfmt-support \
curl
sudo mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
sudo update-binfmts --enable qemu-arm
sudo update-binfmts --enable qemu-aarch64
displayName: 'Initial cross build'
- script: |
mkdir -p .ssh
echo -e "-----BEGIN RSA PRIVATE KEY-----\n$(wheelsSSH)\n-----END RSA PRIVATE KEY-----" >> .ssh/id_rsa
ssh-keyscan -H $(wheelsHost) >> .ssh/known_hosts
chmod 600 .ssh/*
displayName: 'Install ssh key'
- script: sudo docker pull homeassistant/$(buildArch)-wheels:$(versionWheels)
displayName: 'Install wheels builder'
- script: |
cp requirements_all.txt requirements_wheels.txt
if [[ "$(Build.Reason)" =~ (Schedule|Manual) ]]; then
touch requirements_diff.txt
else
curl -s -o requirements_diff.txt https://raw.githubusercontent.com/home-assistant/home-assistant/master/requirements_all.txt
fi
requirement_files="requirements_wheels.txt requirements_diff.txt"
for requirement_file in ${requirement_files}; do
sed -i "s|# pytradfri|pytradfri|g" ${requirement_file}
sed -i "s|# pybluez|pybluez|g" ${requirement_file}
sed -i "s|# bluepy|bluepy|g" ${requirement_file}
sed -i "s|# beacontools|beacontools|g" ${requirement_file}
sed -i "s|# RPi.GPIO|RPi.GPIO|g" ${requirement_file}
sed -i "s|# raspihats|raspihats|g" ${requirement_file}
sed -i "s|# rpi-rf|rpi-rf|g" ${requirement_file}
sed -i "s|# blinkt|blinkt|g" ${requirement_file}
sed -i "s|# fritzconnection|fritzconnection|g" ${requirement_file}
sed -i "s|# pyuserinput|pyuserinput|g" ${requirement_file}
sed -i "s|# evdev|evdev|g" ${requirement_file}
sed -i "s|# smbus-cffi|smbus-cffi|g" ${requirement_file}
sed -i "s|# i2csense|i2csense|g" ${requirement_file}
sed -i "s|# python-eq3bt|python-eq3bt|g" ${requirement_file}
sed -i "s|# pycups|pycups|g" ${requirement_file}
sed -i "s|# homekit|homekit|g" ${requirement_file}
sed -i "s|# decora_wifi|decora_wifi|g" ${requirement_file}
sed -i "s|# decora|decora|g" ${requirement_file}
sed -i "s|# PySwitchbot|PySwitchbot|g" ${requirement_file}
sed -i "s|# pySwitchmate|pySwitchmate|g" ${requirement_file}
sed -i "s|# face_recognition|face_recognition|g" ${requirement_file}
done
displayName: 'Prepare requirements files for Hass.io'
- script: |
sudo docker run --rm -v $(pwd):/data:ro -v $(pwd)/.ssh:/root/.ssh:rw \
homeassistant/$(buildArch)-wheels:$(versionWheels) \
--apk "build-base;cmake;git;linux-headers;bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;autoconf;automake;cups-dev;linux-headers;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev" \
--index $(wheelsIndex) \
--requirement requirements_wheels.txt \
--requirement-diff requirements_diff.txt \
--upload rsync \
--remote wheels@$(wheelsHost):/opt/wheels
displayName: 'Run wheels build'

View File

@@ -7,8 +7,9 @@ import platform
import subprocess
import sys
import threading
from typing import List, Dict, Any # noqa pylint: disable=unused-import
from typing import ( # noqa pylint: disable=unused-import
List, Dict, Any, TYPE_CHECKING
)
from homeassistant import monkey_patch
from homeassistant.const import (
@@ -18,6 +19,9 @@ from homeassistant.const import (
RESTART_EXIT_CODE,
)
if TYPE_CHECKING:
from homeassistant import core
def set_loop() -> None:
"""Attempt to use uvloop."""
@@ -86,10 +90,12 @@ def ensure_config_path(config_dir: str) -> None:
sys.exit(1)
def ensure_config_file(config_dir: str) -> str:
async def ensure_config_file(hass: 'core.HomeAssistant', config_dir: str) \
-> str:
"""Ensure configuration file exists."""
import homeassistant.config as config_util
config_path = config_util.ensure_config_exists(config_dir)
config_path = await config_util.async_ensure_config_exists(
hass, config_dir)
if config_path is None:
print('Error getting configuration path')
@@ -261,6 +267,7 @@ def cmdline() -> List[str]:
async def setup_and_run_hass(config_dir: str,
args: argparse.Namespace) -> int:
"""Set up HASS and run."""
# pylint: disable=redefined-outer-name
from homeassistant import bootstrap, core
hass = core.HomeAssistant()
@@ -275,7 +282,7 @@ async def setup_and_run_hass(config_dir: str,
skip_pip=args.skip_pip, log_rotate_days=args.log_rotate_days,
log_file=args.log_file, log_no_color=args.log_no_color)
else:
config_file = ensure_config_file(config_dir)
config_file = await ensure_config_file(hass, config_dir)
print('Config directory:', config_dir)
await bootstrap.async_from_config_file(
config_file, hass, verbose=args.verbose, skip_pip=args.skip_pip,
@@ -390,7 +397,7 @@ def main() -> int:
if exit_code == RESTART_EXIT_CODE and not args.runner:
try_to_restart()
return exit_code # type: ignore # mypy cannot yet infer it
return exit_code # type: ignore
if __name__ == "__main__":

View File

@@ -547,7 +547,7 @@ class AuthStore:
def _set_defaults(self) -> None:
"""Set default values for auth store."""
self._users = OrderedDict() # type: Dict[str, models.User]
self._users = OrderedDict()
groups = OrderedDict() # type: Dict[str, models.Group]
admin_group = _system_admin_group()

View File

@@ -18,7 +18,7 @@ from homeassistant.helpers import config_validation as cv
from . import MultiFactorAuthModule, MULTI_FACTOR_AUTH_MODULES, \
MULTI_FACTOR_AUTH_MODULE_SCHEMA, SetupFlow
REQUIREMENTS = ['pyotp==2.2.6']
REQUIREMENTS = ['pyotp==2.2.7']
CONF_MESSAGE = 'message'

View File

@@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant
from . import MultiFactorAuthModule, MULTI_FACTOR_AUTH_MODULES, \
MULTI_FACTOR_AUTH_MODULE_SCHEMA, SetupFlow
REQUIREMENTS = ['pyotp==2.2.6', 'PyQRCode==1.2.1']
REQUIREMENTS = ['pyotp==2.2.7', 'PyQRCode==1.2.1']
CONFIG_SCHEMA = MULTI_FACTOR_AUTH_MODULE_SCHEMA.extend({
}, extra=vol.PREVENT_EXTRA)

View File

@@ -11,6 +11,7 @@ from .models import PermissionLookup
from .types import PolicyType
from .entities import ENTITY_POLICY_SCHEMA, compile_entities
from .merge import merge_policies # noqa
from .util import test_all
POLICY_SCHEMA = vol.Schema({
@@ -29,6 +30,10 @@ class AbstractPermissions:
"""Return a function that can test entity access."""
raise NotImplementedError
def access_all_entities(self, key: str) -> bool:
"""Check if we have a certain access to all entities."""
raise NotImplementedError
def check_entity(self, entity_id: str, key: str) -> bool:
"""Check if we can access entity."""
entity_func = self._cached_entity_func
@@ -48,6 +53,10 @@ class PolicyPermissions(AbstractPermissions):
self._policy = policy
self._perm_lookup = perm_lookup
def access_all_entities(self, key: str) -> bool:
"""Check if we have a certain access to all entities."""
return test_all(self._policy.get(CAT_ENTITIES), key)
def _entity_func(self) -> Callable[[str, str], bool]:
"""Return a function that can test entity access."""
return compile_entities(self._policy.get(CAT_ENTITIES),
@@ -65,6 +74,10 @@ class _OwnerPermissions(AbstractPermissions):
# pylint: disable=no-self-use
def access_all_entities(self, key: str) -> bool:
"""Check if we have a certain access to all entities."""
return True
def _entity_func(self) -> Callable[[str, str], bool]:
"""Return a function that can test entity access."""
return lambda entity_id, key: True

View File

@@ -3,6 +3,7 @@ from functools import wraps
from typing import Callable, Dict, List, Optional, Union, cast # noqa: F401
from .const import SUBCAT_ALL
from .models import PermissionLookup
from .types import CategoryType, SubCategoryDict, ValueType
@@ -96,3 +97,16 @@ def _gen_dict_test_func(
return schema.get(key)
return test_value
def test_all(policy: CategoryType, key: str) -> bool:
"""Test if a policy has an ALL access for a specific key."""
if not isinstance(policy, dict):
return bool(policy)
all_policy = policy.get(SUBCAT_ALL)
if not isinstance(all_policy, dict):
return bool(all_policy)
return all_policy.get(key, False)

View File

@@ -17,7 +17,6 @@ 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,6 +25,7 @@ ERROR_LOG_FILENAME = 'home-assistant.log'
# hass.data key for logging information.
DATA_LOGGING = 'logging'
DEBUGGER_INTEGRATIONS = {'ptvsd', }
CORE_INTEGRATIONS = ('homeassistant', 'persistent_notification')
LOGGING_INTEGRATIONS = {'logger', 'system_log'}
STAGE_1_INTEGRATIONS = {
@@ -93,49 +93,11 @@ 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()))
if sys.version_info[:3] < (3, 6, 0):
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"
"Python 3.5 support is deprecated and will "
"be removed in the first release after August 1. Please "
"upgrade Python.", "Python version", "python_version"
)
return hass
@@ -306,6 +268,15 @@ async def _async_set_up_integrations(
"""Set up all the integrations."""
domains = _get_domains(hass, config)
# Start up debuggers. Start these first in case they want to wait.
debuggers = domains & DEBUGGER_INTEGRATIONS
if debuggers:
_LOGGER.debug("Starting up debuggers %s", debuggers)
await asyncio.gather(*[
async_setup_component(hass, domain, config)
for domain in debuggers])
domains -= DEBUGGER_INTEGRATIONS
# Resolve all dependencies of all components so we can find the logging
# and integrations that need faster initialization.
resolved_domains_task = asyncio.gather(*[
@@ -339,7 +310,7 @@ async def _async_set_up_integrations(
stage_2_domains = domains - logging_domains - stage_1_domains
if logging_domains:
_LOGGER.debug("Setting up %s", logging_domains)
_LOGGER.info("Setting up %s", logging_domains)
await asyncio.gather(*[
async_setup_component(hass, domain, config)

View File

@@ -36,7 +36,7 @@ def is_on(hass, entity_id=None):
continue
if not hasattr(component, 'is_on'):
_LOGGER.warning("Component %s has no is_on method.", domain)
_LOGGER.warning("Integration %s has no is_on method.", domain)
continue
if component.is_on(ent_id):

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "S'ha actualitzat la configuraci\u00f3 existent.",
"single_instance_allowed": "Nom\u00e9s es permet una \u00fanica configuraci\u00f3 d'AdGuard Home."
},
"error": {
"connection_error": "No s'ha pogut connectar."
},
"step": {
"hassio_confirm": {
"description": "Vols configurar Home Assistant perqu\u00e8 es connecti amb l'AdGuard Home proporcionat pel complement de Hass.io: {addon}?",
"title": "AdGuard Home (complement de Hass.io)"
},
"user": {
"data": {
"host": "Amfitri\u00f3",
"password": "Contrasenya",
"port": "Port",
"ssl": "AdGuard Home utilitza un certificat SSL",
"username": "Nom d'usuari",
"verify_ssl": "AdGuard Home utilitza un certificat adequat"
},
"description": "Configuraci\u00f3 de la inst\u00e0ncia d'AdGuard Home, permet el control i la monitoritzaci\u00f3.",
"title": "Enlla\u00e7ar AdGuard Home."
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,29 @@
{
"config": {
"abort": {
"single_instance_allowed": "Es ist nur eine einzige Konfiguration von AdGuard Home zul\u00e4ssig."
},
"error": {
"connection_error": "Fehler beim Herstellen einer Verbindung."
},
"step": {
"hassio_confirm": {
"description": "M\u00f6chtest du Home Assistant so konfigurieren, dass eine Verbindung mit AdGuard Home als Hass.io-Add-On hergestellt wird: {addon}?",
"title": "AdGuard Home \u00fcber das Hass.io Add-on"
},
"user": {
"data": {
"host": "Host",
"password": "Passwort",
"port": "Port",
"ssl": "AdGuard Home verwendet ein SSL-Zertifikat",
"username": "Benutzername",
"verify_ssl": "AdGuard Home verwendet ein richtiges Zertifikat"
},
"description": "Richte deine AdGuard Home-Instanz ein um sie zu \u00dcberwachen und zu Steuern.",
"title": "Verkn\u00fcpfe AdGuard Home."
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "Updated existing configuration.",
"single_instance_allowed": "Only a single configuration of AdGuard Home is allowed."
},
"error": {
"connection_error": "Failed to connect."
},
"step": {
"hassio_confirm": {
"description": "Do you want to configure Home Assistant to connect to the AdGuard Home provided by the Hass.io add-on: {addon}?",
"title": "AdGuard Home via Hass.io add-on"
},
"user": {
"data": {
"host": "Host",
"password": "Password",
"port": "Port",
"ssl": "AdGuard Home uses a SSL certificate",
"username": "Username",
"verify_ssl": "AdGuard Home uses a proper certificate"
},
"description": "Set up your AdGuard Home instance to allow monitoring and control.",
"title": "Link your AdGuard Home."
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,27 @@
{
"config": {
"abort": {
"single_instance_allowed": "Solo se permite una \u00fanica configuraci\u00f3n de AdGuard Home."
},
"error": {
"connection_error": "Error al conectar."
},
"step": {
"hassio_confirm": {
"description": "\u00bfDesea configurar Home Assistant para conectarse a la p\u00e1gina principal de AdGuard proporcionada por el complemento Hass.io: {addon}?",
"title": "AdGuard Home a trav\u00e9s del complemento Hass.io"
},
"user": {
"data": {
"password": "Contrase\u00f1a",
"port": "Puerto",
"ssl": "AdGuard Home utiliza un certificado SSL",
"username": "Nombre de usuario",
"verify_ssl": "AdGuard Home utiliza un certificado adecuado"
},
"description": "Configure su instancia de AdGuard Home para permitir la supervisi\u00f3n y el control."
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,21 @@
{
"config": {
"abort": {
"single_instance_allowed": "\u00c8 consentita solo una singola configurazione di AdGuard Home."
},
"error": {
"connection_error": "Impossibile connettersi."
},
"step": {
"user": {
"data": {
"host": "Host",
"password": "Password",
"port": "Porta",
"ssl": "AdGuard Home utilizza un certificato SSL",
"username": "Nome utente"
}
}
}
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "\uae30\uc874 \uad6c\uc131\uc744 \uc5c5\ub370\uc774\ud2b8\ud588\uc2b5\ub2c8\ub2e4.",
"single_instance_allowed": "\ud558\ub098\uc758 AdGuard Home \ub9cc \uad6c\uc131 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4."
},
"error": {
"connection_error": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4."
},
"step": {
"hassio_confirm": {
"description": "Hass.io {addon} \uc560\ub4dc\uc628\uc73c\ub85c AdGuard Home \uc5d0 \uc5f0\uacb0\ud558\ub3c4\ub85d Home Assistant \ub97c \uad6c\uc131 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
"title": "Hass.io \uc560\ub4dc\uc628\uc758 AdGuard Home"
},
"user": {
"data": {
"host": "\ud638\uc2a4\ud2b8",
"password": "\ube44\ubc00\ubc88\ud638",
"port": "\ud3ec\ud2b8",
"ssl": "AdGuard Home \uc740 SSL \uc778\uc99d\uc11c\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4",
"username": "\uc0ac\uc6a9\uc790 \uc774\ub984",
"verify_ssl": "AdGuard Home \uc740 \uc62c\ubc14\ub978 \uc778\uc99d\uc11c\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4"
},
"description": "\ubaa8\ub2c8\ud130\ub9c1 \ubc0f \uc81c\uc5b4\uac00 \uac00\ub2a5\ud558\ub3c4\ub85d AdGuard Home \uc778\uc2a4\ud134\uc2a4\ub97c \uc124\uc815\ud574\uc8fc\uc138\uc694.",
"title": "AdGuard Home \uc5f0\uacb0"
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "D\u00e9i bestehend Konfiguratioun ass ge\u00e4nnert.",
"single_instance_allowed": "N\u00ebmmen eng eenzeg Konfiguratioun vun AdGuard Home ass erlaabt."
},
"error": {
"connection_error": "Feeler beim verbannen."
},
"step": {
"hassio_confirm": {
"description": "W\u00ebllt dir Home Assistant konfigur\u00e9iere fir sech mam AdGuard Home ze verbannen dee vum hass.io add-on {addon} bereet gestallt g\u00ebtt?",
"title": "AdGuard Home via Hass.io add-on"
},
"user": {
"data": {
"host": "Apparat",
"password": "Passwuert",
"port": "Port",
"ssl": "AdGuard Home benotzt een SSL Zertifikat",
"username": "Benotzernumm",
"verify_ssl": "AdGuard Home benotzt een eegenen Zertifikat"
},
"description": "Konfigur\u00e9iert \u00e4r AdGuard Home Instanz fir d'Iwwerwaachung an d'Kontroll z'erlaben.",
"title": "Verbannt \u00e4ren AdGuard Home"
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "Bestaande configuratie bijgewerkt.",
"single_instance_allowed": "Slechts \u00e9\u00e9n configuratie van AdGuard Home is toegestaan."
},
"error": {
"connection_error": "Kon niet verbinden."
},
"step": {
"hassio_confirm": {
"description": "Wilt u Home Assistant configureren om verbinding te maken met AdGuard Home van de Hass.io-add-on: {addon}?",
"title": "AdGuard Home via Hass.io add-on"
},
"user": {
"data": {
"host": "Host",
"password": "Wachtwoord",
"port": "Poort",
"ssl": "AdGuard Home maakt gebruik van een SSL certificaat",
"username": "Gebruikersnaam",
"verify_ssl": "AdGuard Home maakt gebruik van een goed certificaat"
},
"description": "Stel uw AdGuard Home-instantie in om toezicht en controle mogelijk te maken.",
"title": "Link uw AdGuard Home."
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "Oppdatert eksisterende konfigurasjon.",
"single_instance_allowed": "Kun \u00e9n enkelt konfigurasjon av AdGuard Hjemer tillatt."
},
"error": {
"connection_error": "Tilkobling mislyktes."
},
"step": {
"hassio_confirm": {
"description": "Vil du konfigurere Home Assistant til \u00e5 koble til AdGuard Hjem gitt av hass.io tillegget {addon}?",
"title": "AdGuard Hjem via Hass.io tillegg"
},
"user": {
"data": {
"host": "Vert",
"password": "Passord",
"port": "Port",
"ssl": "AdGuard Hjem bruker et SSL-sertifikat",
"username": "Brukernavn",
"verify_ssl": "AdGuard Home bruker et riktig sertifikat"
},
"description": "Sett opp din AdGuard Hjem instans for \u00e5 tillate overv\u00e5king og kontroll.",
"title": "Koble til ditt AdGuard Hjem."
}
},
"title": "AdGuard Hjem"
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "Zaktualizowano istniej\u0105c\u0105 konfiguracj\u0119.",
"single_instance_allowed": "Dozwolona jest tylko jedna konfiguracja AdGuard Home."
},
"error": {
"connection_error": "Po\u0142\u0105czenie nieudane."
},
"step": {
"hassio_confirm": {
"description": "Czy chcesz skonfigurowa\u0107 Home Assistant'a, aby po\u0142\u0105czy\u0142 si\u0119 z AdGuard Home przez dodatek Hass.io {addon}?",
"title": "AdGuard Home przez dodatek Hass.io"
},
"user": {
"data": {
"host": "Host",
"password": "Has\u0142o",
"port": "Port",
"ssl": "AdGuard Home u\u017cywa certyfikatu SSL",
"username": "Nazwa u\u017cytkownika",
"verify_ssl": "AdGuard Home u\u017cywa odpowiedniego certyfikatu."
},
"description": "Skonfiguruj swoj\u0105 instancj\u0119 AdGuard Home, aby umo\u017cliwi\u0107 monitorowanie i nadz\u00f3r sieci.",
"title": "Po\u0142\u0105cz sw\u00f3j AdGuard Home"
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "Configura\u00e7\u00e3o existente atualizada.",
"single_instance_allowed": "Apenas uma \u00fanica configura\u00e7\u00e3o do AdGuard Home \u00e9 permitida."
},
"error": {
"connection_error": "Falhou ao conectar."
},
"step": {
"hassio_confirm": {
"description": "Deseja configurar o Home Assistant para se conectar ao AdGuard Home fornecido pelo complemento Hass.io: {addon} ?",
"title": "AdGuard Home via add-on Hass.io"
},
"user": {
"data": {
"host": "Host",
"password": "Senha",
"port": "Porta",
"ssl": "O AdGuard Home usa um certificado SSL",
"username": "Nome de usu\u00e1rio",
"verify_ssl": "O AdGuard Home usa um certificado apropriado"
},
"description": "Configure sua inst\u00e2ncia do AdGuard Home para permitir o monitoramento e o controle.",
"title": "Vincule o seu AdGuard Home."
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430.",
"single_instance_allowed": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430."
},
"error": {
"connection_error": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f."
},
"step": {
"hassio_confirm": {
"description": "\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a AdGuard Home (\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f Hass.io \"{addon}\")?",
"title": "AdGuard Home (\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f Hass.io)"
},
"user": {
"data": {
"host": "\u0425\u043e\u0441\u0442",
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
"port": "\u041f\u043e\u0440\u0442",
"ssl": "AdGuard Home \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 SSL",
"username": "\u041b\u043e\u0433\u0438\u043d",
"verify_ssl": "AdGuard Home \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442"
},
"description": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f AdGuard Home.",
"title": "AdGuard Home"
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "Posodobljena obstoje\u010da konfiguracija.",
"single_instance_allowed": "Dovoljena je samo ena konfiguracija AdGuard Home."
},
"error": {
"connection_error": "Povezava ni uspela."
},
"step": {
"hassio_confirm": {
"description": "\u017delite konfigurirati Home Assistant-a za povezavo z AdGuard Home, ki ga ponuja hass.io add-on {addon} ?",
"title": "AdGuard Home preko dodatka Hass.io"
},
"user": {
"data": {
"host": "Gostitelj",
"password": "Geslo",
"port": "Vrata",
"ssl": "AdGuard Home uporablja SSL certifikat",
"username": "Uporabni\u0161ko ime",
"verify_ssl": "AdGuard Home uporablja ustrezen certifikat"
},
"description": "Nastavite primerek AdGuard Home, da omogo\u010dite spremljanje in nadzor.",
"title": "Pove\u017eite svoj AdGuard Home."
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,29 @@
{
"config": {
"abort": {
"single_instance_allowed": "Endast en enda konfiguration av AdGuard Home \u00e4r till\u00e5ten."
},
"error": {
"connection_error": "Det gick inte att ansluta."
},
"step": {
"hassio_confirm": {
"description": "Vill du konfigurera Home Assistant f\u00f6r att ansluta till AdGuard Home som tillhandah\u00e5lls av Hass.io Add-on: {addon}?",
"title": "AdGuard Home via Hass.io-till\u00e4gget"
},
"user": {
"data": {
"host": "V\u00e4rd",
"password": "L\u00f6senord",
"port": "Port",
"ssl": "AdGuard Home anv\u00e4nder ett SSL-certifikat",
"username": "Anv\u00e4ndarnamn",
"verify_ssl": "AdGuard Home anv\u00e4nder ett korrekt certifikat"
},
"description": "St\u00e4ll in din AdGuard Home-instans f\u00f6r att till\u00e5ta \u00f6vervakning och kontroll.",
"title": "L\u00e4nka din AdGuard Home."
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,14 @@
{
"config": {
"step": {
"user": {
"data": {
"host": "\u0110\u1ecba ch\u1ec9",
"password": "M\u1eadt kh\u1ea9u",
"port": "C\u1ed5ng",
"username": "T\u00ean \u0111\u0103ng nh\u1eadp"
}
}
}
}
}

View File

@@ -0,0 +1,30 @@
{
"config": {
"abort": {
"existing_instance_updated": "\u5df2\u66f4\u65b0\u73fe\u6709\u8a2d\u5b9a\u3002",
"single_instance_allowed": "\u50c5\u5141\u8a31\u8a2d\u5b9a\u4e00\u7d44 AdGuard Home\u3002"
},
"error": {
"connection_error": "\u9023\u7dda\u5931\u6557\u3002"
},
"step": {
"hassio_confirm": {
"description": "\u662f\u5426\u8981\u8a2d\u5b9a Home Assistant \u4ee5\u4f7f\u7528 Hass.io \u9644\u52a0\u7d44\u4ef6\uff1a{addon} \u9023\u7dda\u81f3 AdGuard Home\uff1f",
"title": "\u4f7f\u7528 Hass.io \u9644\u52a0\u7d44\u4ef6 AdGuard Home"
},
"user": {
"data": {
"host": "\u4e3b\u6a5f\u7aef",
"password": "\u5bc6\u78bc",
"port": "\u901a\u8a0a\u57e0",
"ssl": "AdGuard Home \u4f7f\u7528 SSL \u8a8d\u8b49",
"username": "\u4f7f\u7528\u8005\u540d\u7a31",
"verify_ssl": "AdGuard Home \u4f7f\u7528\u5c0d\u61c9\u8a8d\u8b49"
},
"description": "\u8a2d\u5b9a AdGuard Home \u4ee5\u9032\u884c\u76e3\u63a7\u3002",
"title": "\u9023\u7d50 AdGuard Home\u3002"
}
},
"title": "AdGuard Home"
}
}

View File

@@ -0,0 +1,180 @@
"""Support for AdGuard Home."""
import logging
from typing import Any, Dict
from adguardhome import AdGuardHome, AdGuardHomeError
import voluptuous as vol
from homeassistant.components.adguard.const import (
CONF_FORCE, DATA_ADGUARD_CLIENT, DATA_ADGUARD_VERION, DOMAIN,
SERVICE_ADD_URL, SERVICE_DISABLE_URL, SERVICE_ENABLE_URL, SERVICE_REFRESH,
SERVICE_REMOVE_URL)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_SSL, CONF_URL,
CONF_USERNAME, CONF_VERIFY_SSL)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
_LOGGER = logging.getLogger(__name__)
SERVICE_URL_SCHEMA = vol.Schema({vol.Required(CONF_URL): cv.url})
SERVICE_ADD_URL_SCHEMA = vol.Schema(
{vol.Required(CONF_NAME): cv.string, vol.Required(CONF_URL): cv.url}
)
SERVICE_REFRESH_SCHEMA = vol.Schema(
{vol.Optional(CONF_FORCE, default=False): cv.boolean}
)
async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool:
"""Set up the AdGuard Home components."""
return True
async def async_setup_entry(
hass: HomeAssistantType, entry: ConfigEntry
) -> bool:
"""Set up AdGuard Home from a config entry."""
session = async_get_clientsession(hass, entry.data[CONF_VERIFY_SSL])
adguard = AdGuardHome(
entry.data[CONF_HOST],
port=entry.data[CONF_PORT],
username=entry.data[CONF_USERNAME],
password=entry.data[CONF_PASSWORD],
tls=entry.data[CONF_SSL],
verify_ssl=entry.data[CONF_VERIFY_SSL],
loop=hass.loop,
session=session,
)
hass.data.setdefault(DOMAIN, {})[DATA_ADGUARD_CLIENT] = adguard
for component in 'sensor', 'switch':
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, component)
)
async def add_url(call) -> None:
"""Service call to add a new filter subscription to AdGuard Home."""
await adguard.filtering.add_url(
call.data.get(CONF_NAME), call.data.get(CONF_URL)
)
async def remove_url(call) -> None:
"""Service call to remove a filter subscription from AdGuard Home."""
await adguard.filtering.remove_url(call.data.get(CONF_URL))
async def enable_url(call) -> None:
"""Service call to enable a filter subscription in AdGuard Home."""
await adguard.filtering.enable_url(call.data.get(CONF_URL))
async def disable_url(call) -> None:
"""Service call to disable a filter subscription in AdGuard Home."""
await adguard.filtering.disable_url(call.data.get(CONF_URL))
async def refresh(call) -> None:
"""Service call to refresh the filter subscriptions in AdGuard Home."""
await adguard.filtering.refresh(call.data.get(CONF_FORCE))
hass.services.async_register(
DOMAIN, SERVICE_ADD_URL, add_url, schema=SERVICE_ADD_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_REMOVE_URL, remove_url, schema=SERVICE_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_ENABLE_URL, enable_url, schema=SERVICE_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_DISABLE_URL, disable_url, schema=SERVICE_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_REFRESH, refresh, schema=SERVICE_REFRESH_SCHEMA
)
return True
async def async_unload_entry(
hass: HomeAssistantType, entry: ConfigType
) -> bool:
"""Unload AdGuard Home config entry."""
hass.services.async_remove(DOMAIN, SERVICE_ADD_URL)
hass.services.async_remove(DOMAIN, SERVICE_REMOVE_URL)
hass.services.async_remove(DOMAIN, SERVICE_ENABLE_URL)
hass.services.async_remove(DOMAIN, SERVICE_DISABLE_URL)
hass.services.async_remove(DOMAIN, SERVICE_REFRESH)
for component in 'sensor', 'switch':
await hass.config_entries.async_forward_entry_unload(entry, component)
del hass.data[DOMAIN]
return True
class AdGuardHomeEntity(Entity):
"""Defines a base AdGuard Home entity."""
def __init__(self, adguard, name: str, icon: str) -> None:
"""Initialize the AdGuard Home entity."""
self._name = name
self._icon = icon
self._available = True
self.adguard = adguard
@property
def name(self) -> str:
"""Return the name of the entity."""
return self._name
@property
def icon(self) -> str:
"""Return the mdi icon of the entity."""
return self._icon
@property
def available(self) -> bool:
"""Return True if entity is available."""
return self._available
async def async_update(self) -> None:
"""Update AdGuard Home entity."""
try:
await self._adguard_update()
self._available = True
except AdGuardHomeError:
if self._available:
_LOGGER.debug(
"An error occurred while updating AdGuard Home sensor.",
exc_info=True,
)
self._available = False
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
raise NotImplementedError()
class AdGuardHomeDeviceEntity(AdGuardHomeEntity):
"""Defines a AdGuard Home device entity."""
@property
def device_info(self) -> Dict[str, Any]:
"""Return device information about this AdGuard Home instance."""
return {
'identifiers': {
(
DOMAIN,
self.adguard.host,
self.adguard.port,
self.adguard.base_path,
)
},
'name': 'AdGuard Home',
'manufacturer': 'AdGuard Team',
'sw_version': self.hass.data[DOMAIN].get(DATA_ADGUARD_VERION),
}

View File

@@ -0,0 +1,168 @@
"""Config flow to configure the AdGuard Home integration."""
import logging
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.components.adguard.const import DOMAIN
from homeassistant.config_entries import ConfigFlow
from homeassistant.const import (
CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_SSL, CONF_USERNAME,
CONF_VERIFY_SSL)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
_LOGGER = logging.getLogger(__name__)
@config_entries.HANDLERS.register(DOMAIN)
class AdGuardHomeFlowHandler(ConfigFlow):
"""Handle a AdGuard Home config flow."""
VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL
_hassio_discovery = None
def __init__(self):
"""Initialize AgGuard Home flow."""
pass
async def _show_setup_form(self, errors=None):
"""Show the setup form to the user."""
return self.async_show_form(
step_id='user',
data_schema=vol.Schema(
{
vol.Required(CONF_HOST): str,
vol.Required(CONF_PORT, default=3000): vol.Coerce(int),
vol.Optional(CONF_USERNAME): str,
vol.Optional(CONF_PASSWORD): str,
vol.Required(CONF_SSL, default=True): bool,
vol.Required(CONF_VERIFY_SSL, default=True): bool,
}
),
errors=errors or {},
)
async def _show_hassio_form(self, errors=None):
"""Show the Hass.io confirmation form to the user."""
return self.async_show_form(
step_id='hassio_confirm',
description_placeholders={
'addon': self._hassio_discovery['addon']
},
data_schema=vol.Schema({}),
errors=errors or {},
)
async def async_step_user(self, user_input=None):
"""Handle a flow initiated by the user."""
if self._async_current_entries():
return self.async_abort(reason='single_instance_allowed')
if user_input is None:
return await self._show_setup_form(user_input)
errors = {}
session = async_get_clientsession(
self.hass, user_input[CONF_VERIFY_SSL]
)
adguard = AdGuardHome(
user_input[CONF_HOST],
port=user_input[CONF_PORT],
username=user_input.get(CONF_USERNAME),
password=user_input.get(CONF_PASSWORD),
tls=user_input[CONF_SSL],
verify_ssl=user_input[CONF_VERIFY_SSL],
loop=self.hass.loop,
session=session,
)
try:
await adguard.version()
except AdGuardHomeConnectionError:
errors['base'] = 'connection_error'
return await self._show_setup_form(errors)
return self.async_create_entry(
title=user_input[CONF_HOST],
data={
CONF_HOST: user_input[CONF_HOST],
CONF_PASSWORD: user_input.get(CONF_PASSWORD),
CONF_PORT: user_input[CONF_PORT],
CONF_SSL: user_input[CONF_SSL],
CONF_USERNAME: user_input.get(CONF_USERNAME),
CONF_VERIFY_SSL: user_input[CONF_VERIFY_SSL],
},
)
async def async_step_hassio(self, user_input=None):
"""Prepare configuration for a Hass.io AdGuard Home add-on.
This flow is triggered by the discovery component.
"""
entries = self._async_current_entries()
if not entries:
self._hassio_discovery = user_input
return await self.async_step_hassio_confirm()
cur_entry = entries[0]
if (cur_entry.data[CONF_HOST] == user_input[CONF_HOST] and
cur_entry.data[CONF_PORT] == user_input[CONF_PORT]):
return self.async_abort(reason='single_instance_allowed')
is_loaded = cur_entry.state == config_entries.ENTRY_STATE_LOADED
if is_loaded:
await self.hass.config_entries.async_unload(cur_entry.entry_id)
self.hass.config_entries.async_update_entry(cur_entry, data={
**cur_entry.data,
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
})
if is_loaded:
await self.hass.config_entries.async_setup(cur_entry.entry_id)
return self.async_abort(reason='existing_instance_updated')
async def async_step_hassio_confirm(self, user_input=None):
"""Confirm Hass.io discovery."""
if user_input is None:
return await self._show_hassio_form()
errors = {}
session = async_get_clientsession(self.hass, False)
adguard = AdGuardHome(
self._hassio_discovery[CONF_HOST],
port=self._hassio_discovery[CONF_PORT],
tls=False,
loop=self.hass.loop,
session=session,
)
try:
await adguard.version()
except AdGuardHomeConnectionError:
errors['base'] = 'connection_error'
return await self._show_hassio_form(errors)
return self.async_create_entry(
title=self._hassio_discovery['addon'],
data={
CONF_HOST: self._hassio_discovery[CONF_HOST],
CONF_PORT: self._hassio_discovery[CONF_PORT],
CONF_PASSWORD: None,
CONF_SSL: False,
CONF_USERNAME: None,
CONF_VERIFY_SSL: True,
},
)

View File

@@ -0,0 +1,14 @@
"""Constants for the AdGuard Home integration."""
DOMAIN = 'adguard'
DATA_ADGUARD_CLIENT = 'adguard_client'
DATA_ADGUARD_VERION = 'adguard_version'
CONF_FORCE = 'force'
SERVICE_ADD_URL = 'add_url'
SERVICE_DISABLE_URL = 'disable_url'
SERVICE_ENABLE_URL = 'enable_url'
SERVICE_REFRESH = 'refresh'
SERVICE_REMOVE_URL = 'remove_url'

View File

@@ -0,0 +1,13 @@
{
"domain": "adguard",
"name": "AdGuard Home",
"config_flow": true,
"documentation": "https://www.home-assistant.io/components/adguard",
"requirements": [
"adguardhome==0.2.1"
],
"dependencies": [],
"codeowners": [
"@frenck"
]
}

View File

@@ -0,0 +1,232 @@
"""Support for AdGuard Home sensors."""
from datetime import timedelta
import logging
from adguardhome import AdGuardHomeConnectionError
from homeassistant.components.adguard import AdGuardHomeDeviceEntity
from homeassistant.components.adguard.const import (
DATA_ADGUARD_CLIENT, DATA_ADGUARD_VERION, DOMAIN)
from homeassistant.config_entries import ConfigEntry
from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers.typing import HomeAssistantType
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=300)
PARALLEL_UPDATES = 4
async def async_setup_entry(
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities
) -> None:
"""Set up AdGuard Home sensor based on a config entry."""
adguard = hass.data[DOMAIN][DATA_ADGUARD_CLIENT]
try:
version = await adguard.version()
except AdGuardHomeConnectionError as exception:
raise PlatformNotReady from exception
hass.data[DOMAIN][DATA_ADGUARD_VERION] = version
sensors = [
AdGuardHomeDNSQueriesSensor(adguard),
AdGuardHomeBlockedFilteringSensor(adguard),
AdGuardHomePercentageBlockedSensor(adguard),
AdGuardHomeReplacedParentalSensor(adguard),
AdGuardHomeReplacedSafeBrowsingSensor(adguard),
AdGuardHomeReplacedSafeSearchSensor(adguard),
AdGuardHomeAverageProcessingTimeSensor(adguard),
AdGuardHomeRulesCountSensor(adguard),
]
async_add_entities(sensors, True)
class AdGuardHomeSensor(AdGuardHomeDeviceEntity):
"""Defines a AdGuard Home sensor."""
def __init__(
self,
adguard,
name: str,
icon: str,
measurement: str,
unit_of_measurement: str,
) -> None:
"""Initialize AdGuard Home sensor."""
self._state = None
self._unit_of_measurement = unit_of_measurement
self.measurement = measurement
super().__init__(adguard, name, icon)
@property
def unique_id(self) -> str:
"""Return the unique ID for this sensor."""
return '_'.join(
[
DOMAIN,
self.adguard.host,
str(self.adguard.port),
'sensor',
self.measurement,
]
)
@property
def state(self):
"""Return the state of the sensor."""
return self._state
@property
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return self._unit_of_measurement
class AdGuardHomeDNSQueriesSensor(AdGuardHomeSensor):
"""Defines a AdGuard Home DNS Queries sensor."""
def __init__(self, adguard):
"""Initialize AdGuard Home sensor."""
super().__init__(
adguard,
'AdGuard DNS Queries',
'mdi:magnify',
'dns_queries',
'queries',
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.stats.dns_queries()
class AdGuardHomeBlockedFilteringSensor(AdGuardHomeSensor):
"""Defines a AdGuard Home blocked by filtering sensor."""
def __init__(self, adguard):
"""Initialize AdGuard Home sensor."""
super().__init__(
adguard,
'AdGuard DNS Queries Blocked',
'mdi:magnify-close',
'blocked_filtering',
'queries',
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.stats.blocked_filtering()
class AdGuardHomePercentageBlockedSensor(AdGuardHomeSensor):
"""Defines a AdGuard Home blocked percentage sensor."""
def __init__(self, adguard):
"""Initialize AdGuard Home sensor."""
super().__init__(
adguard,
'AdGuard DNS Queries Blocked Ratio',
'mdi:magnify-close',
'blocked_percentage',
'%',
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
percentage = await self.adguard.stats.blocked_percentage()
self._state = "{:.2f}".format(percentage)
class AdGuardHomeReplacedParentalSensor(AdGuardHomeSensor):
"""Defines a AdGuard Home replaced by parental control sensor."""
def __init__(self, adguard):
"""Initialize AdGuard Home sensor."""
super().__init__(
adguard,
'AdGuard Parental Control Blocked',
'mdi:human-male-girl',
'blocked_parental',
'requests',
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.stats.replaced_parental()
class AdGuardHomeReplacedSafeBrowsingSensor(AdGuardHomeSensor):
"""Defines a AdGuard Home replaced by safe browsing sensor."""
def __init__(self, adguard):
"""Initialize AdGuard Home sensor."""
super().__init__(
adguard,
'AdGuard Safe Browsing Blocked',
'mdi:shield-half-full',
'blocked_safebrowsing',
'requests',
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.stats.replaced_safebrowsing()
class AdGuardHomeReplacedSafeSearchSensor(AdGuardHomeSensor):
"""Defines a AdGuard Home replaced by safe search sensor."""
def __init__(self, adguard):
"""Initialize AdGuard Home sensor."""
super().__init__(
adguard,
'Searches Safe Search Enforced',
'mdi:shield-search',
'enforced_safesearch',
'requests',
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.stats.replaced_safesearch()
class AdGuardHomeAverageProcessingTimeSensor(AdGuardHomeSensor):
"""Defines a AdGuard Home average processing time sensor."""
def __init__(self, adguard):
"""Initialize AdGuard Home sensor."""
super().__init__(
adguard,
'AdGuard Average Processing Speed',
'mdi:speedometer',
'average_speed',
'ms',
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
average = await self.adguard.stats.avg_processing_time()
self._state = "{:.2f}".format(average)
class AdGuardHomeRulesCountSensor(AdGuardHomeSensor):
"""Defines a AdGuard Home rules count sensor."""
def __init__(self, adguard):
"""Initialize AdGuard Home sensor."""
super().__init__(
adguard,
'AdGuard Rules Count',
'mdi:counter',
'rules_count',
'rules',
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.filtering.rules_count()

View File

@@ -0,0 +1,37 @@
add_url:
description: Add a new filter subscription to AdGuard Home.
fields:
name:
description: The name of the filter subscription.
example: Example
url:
description: The filter URL to subscribe to, containing the filter rules.
example: https://www.example.com/filter/1.txt
remove_url:
description: Removes a filter subscription from AdGuard Home.
fields:
url:
description: The filter subscription URL to remove.
example: https://www.example.com/filter/1.txt
enable_url:
description: Enables a filter subscription in AdGuard Home.
fields:
url:
description: The filter subscription URL to enable.
example: https://www.example.com/filter/1.txt
disable_url:
description: Disables a filter subscription in AdGuard Home.
fields:
url:
description: The filter subscription URL to disable.
example: https://www.example.com/filter/1.txt
refresh:
description: Refresh all filter subscriptions in AdGuard Home.
fields:
force:
description: Force update (by passes AdGuard Home throttling).
example: '"true" to force, "false" or omit for a regular refresh.'

View File

@@ -0,0 +1,30 @@
{
"config": {
"title": "AdGuard Home",
"step": {
"user": {
"title": "Link your AdGuard Home.",
"description": "Set up your AdGuard Home instance to allow monitoring and control.",
"data": {
"host": "Host",
"password": "Password",
"port": "Port",
"username": "Username",
"ssl": "AdGuard Home uses a SSL certificate",
"verify_ssl": "AdGuard Home uses a proper certificate"
}
},
"hassio_confirm": {
"title": "AdGuard Home via Hass.io add-on",
"description": "Do you want to configure Home Assistant to connect to the AdGuard Home provided by the Hass.io add-on: {addon}?"
}
},
"error": {
"connection_error": "Failed to connect."
},
"abort": {
"single_instance_allowed": "Only a single configuration of AdGuard Home is allowed.",
"existing_instance_updated": "Updated existing configuration."
}
}
}

View File

@@ -0,0 +1,233 @@
"""Support for AdGuard Home switches."""
from datetime import timedelta
import logging
from adguardhome import AdGuardHomeConnectionError, AdGuardHomeError
from homeassistant.components.adguard import AdGuardHomeDeviceEntity
from homeassistant.components.adguard.const import (
DATA_ADGUARD_CLIENT, DATA_ADGUARD_VERION, DOMAIN)
from homeassistant.config_entries import ConfigEntry
from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers.typing import HomeAssistantType
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=10)
PARALLEL_UPDATES = 1
async def async_setup_entry(
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities
) -> None:
"""Set up AdGuard Home switch based on a config entry."""
adguard = hass.data[DOMAIN][DATA_ADGUARD_CLIENT]
try:
version = await adguard.version()
except AdGuardHomeConnectionError as exception:
raise PlatformNotReady from exception
hass.data[DOMAIN][DATA_ADGUARD_VERION] = version
switches = [
AdGuardHomeProtectionSwitch(adguard),
AdGuardHomeFilteringSwitch(adguard),
AdGuardHomeParentalSwitch(adguard),
AdGuardHomeSafeBrowsingSwitch(adguard),
AdGuardHomeSafeSearchSwitch(adguard),
AdGuardHomeQueryLogSwitch(adguard),
]
async_add_entities(switches, True)
class AdGuardHomeSwitch(ToggleEntity, AdGuardHomeDeviceEntity):
"""Defines a AdGuard Home switch."""
def __init__(self, adguard, name: str, icon: str, key: str):
"""Initialize AdGuard Home switch."""
self._state = False
self._key = key
super().__init__(adguard, name, icon)
@property
def unique_id(self) -> str:
"""Return the unique ID for this sensor."""
return '_'.join(
[
DOMAIN,
self.adguard.host,
str(self.adguard.port),
'switch',
self._key,
]
)
@property
def is_on(self) -> bool:
"""Return the state of the switch."""
return self._state
async def async_turn_off(self, **kwargs) -> None:
"""Turn off the switch."""
try:
await self._adguard_turn_off()
except AdGuardHomeError:
_LOGGER.error(
"An error occurred while turning off AdGuard Home switch."
)
self._available = False
async def _adguard_turn_off(self) -> None:
"""Turn off the switch."""
raise NotImplementedError()
async def async_turn_on(self, **kwargs) -> None:
"""Turn on the switch."""
try:
await self._adguard_turn_on()
except AdGuardHomeError:
_LOGGER.error(
"An error occurred while turning on AdGuard Home switch."
)
self._available = False
async def _adguard_turn_on(self) -> None:
"""Turn on the switch."""
raise NotImplementedError()
class AdGuardHomeProtectionSwitch(AdGuardHomeSwitch):
"""Defines a AdGuard Home protection switch."""
def __init__(self, adguard) -> None:
"""Initialize AdGuard Home switch."""
super().__init__(
adguard, "AdGuard Protection", 'mdi:shield-check', 'protection'
)
async def _adguard_turn_off(self) -> None:
"""Turn off the switch."""
await self.adguard.disable_protection()
async def _adguard_turn_on(self) -> None:
"""Turn on the switch."""
await self.adguard.enable_protection()
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.protection_enabled()
class AdGuardHomeParentalSwitch(AdGuardHomeSwitch):
"""Defines a AdGuard Home parental control switch."""
def __init__(self, adguard) -> None:
"""Initialize AdGuard Home switch."""
super().__init__(
adguard, "AdGuard Parental Control", 'mdi:shield-check', 'parental'
)
async def _adguard_turn_off(self) -> None:
"""Turn off the switch."""
await self.adguard.parental.disable()
async def _adguard_turn_on(self) -> None:
"""Turn on the switch."""
await self.adguard.parental.enable()
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.parental.enabled()
class AdGuardHomeSafeSearchSwitch(AdGuardHomeSwitch):
"""Defines a AdGuard Home safe search switch."""
def __init__(self, adguard) -> None:
"""Initialize AdGuard Home switch."""
super().__init__(
adguard, "AdGuard Safe Search", 'mdi:shield-check', 'safesearch'
)
async def _adguard_turn_off(self) -> None:
"""Turn off the switch."""
await self.adguard.safesearch.disable()
async def _adguard_turn_on(self) -> None:
"""Turn on the switch."""
await self.adguard.safesearch.enable()
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.safesearch.enabled()
class AdGuardHomeSafeBrowsingSwitch(AdGuardHomeSwitch):
"""Defines a AdGuard Home safe search switch."""
def __init__(self, adguard) -> None:
"""Initialize AdGuard Home switch."""
super().__init__(
adguard,
"AdGuard Safe Browsing",
'mdi:shield-check',
'safebrowsing',
)
async def _adguard_turn_off(self) -> None:
"""Turn off the switch."""
await self.adguard.safebrowsing.disable()
async def _adguard_turn_on(self) -> None:
"""Turn on the switch."""
await self.adguard.safebrowsing.enable()
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.safebrowsing.enabled()
class AdGuardHomeFilteringSwitch(AdGuardHomeSwitch):
"""Defines a AdGuard Home filtering switch."""
def __init__(self, adguard) -> None:
"""Initialize AdGuard Home switch."""
super().__init__(
adguard, "AdGuard Filtering", 'mdi:shield-check', 'filtering'
)
async def _adguard_turn_off(self) -> None:
"""Turn off the switch."""
await self.adguard.filtering.disable()
async def _adguard_turn_on(self) -> None:
"""Turn on the switch."""
await self.adguard.filtering.enable()
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.filtering.enabled()
class AdGuardHomeQueryLogSwitch(AdGuardHomeSwitch):
"""Defines a AdGuard Home query log switch."""
def __init__(self, adguard) -> None:
"""Initialize AdGuard Home switch."""
super().__init__(
adguard, "AdGuard Query Log", 'mdi:shield-check', 'querylog'
)
async def _adguard_turn_off(self) -> None:
"""Turn off the switch."""
await self.adguard.querylog.disable()
async def _adguard_turn_on(self) -> None:
"""Turn on the switch."""
await self.adguard.querylog.enable()
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
self._state = await self.adguard.querylog.enabled()

View File

@@ -31,9 +31,11 @@ CONF_ADS_TYPE = 'adstype'
CONF_ADS_VALUE = 'value'
CONF_ADS_VAR = 'adsvar'
CONF_ADS_VAR_BRIGHTNESS = 'adsvar_brightness'
CONF_ADS_VAR_POSITION = 'adsvar_position'
STATE_KEY_STATE = 'state'
STATE_KEY_BRIGHTNESS = 'brightness'
STATE_KEY_POSITION = 'position'
DOMAIN = 'ads'

View File

@@ -0,0 +1,165 @@
"""Support for ADS covers."""
import logging
import voluptuous as vol
from homeassistant.components.cover import (
PLATFORM_SCHEMA, SUPPORT_OPEN, SUPPORT_CLOSE, SUPPORT_STOP,
SUPPORT_SET_POSITION, ATTR_POSITION, DEVICE_CLASSES_SCHEMA,
CoverDevice)
from homeassistant.const import (
CONF_NAME, CONF_DEVICE_CLASS)
import homeassistant.helpers.config_validation as cv
from . import CONF_ADS_VAR, CONF_ADS_VAR_POSITION, DATA_ADS, \
AdsEntity, STATE_KEY_STATE, STATE_KEY_POSITION
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'ADS Cover'
CONF_ADS_VAR_SET_POS = 'adsvar_set_position'
CONF_ADS_VAR_OPEN = 'adsvar_open'
CONF_ADS_VAR_CLOSE = 'adsvar_close'
CONF_ADS_VAR_STOP = 'adsvar_stop'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_ADS_VAR_POSITION): cv.string,
vol.Optional(CONF_ADS_VAR_SET_POS): cv.string,
vol.Optional(CONF_ADS_VAR_CLOSE): cv.string,
vol.Optional(CONF_ADS_VAR_OPEN): cv.string,
vol.Optional(CONF_ADS_VAR_STOP): 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 cover platform for ADS."""
ads_hub = hass.data[DATA_ADS]
ads_var_is_closed = config.get(CONF_ADS_VAR)
ads_var_position = config.get(CONF_ADS_VAR_POSITION)
ads_var_pos_set = config.get(CONF_ADS_VAR_SET_POS)
ads_var_open = config.get(CONF_ADS_VAR_OPEN)
ads_var_close = config.get(CONF_ADS_VAR_CLOSE)
ads_var_stop = config.get(CONF_ADS_VAR_STOP)
name = config[CONF_NAME]
device_class = config.get(CONF_DEVICE_CLASS)
add_entities([AdsCover(ads_hub,
ads_var_is_closed,
ads_var_position,
ads_var_pos_set,
ads_var_open,
ads_var_close,
ads_var_stop,
name,
device_class)])
class AdsCover(AdsEntity, CoverDevice):
"""Representation of ADS cover."""
def __init__(self, ads_hub,
ads_var_is_closed, ads_var_position,
ads_var_pos_set, ads_var_open,
ads_var_close, ads_var_stop, name, device_class):
"""Initialize AdsCover entity."""
super().__init__(ads_hub, name, ads_var_is_closed)
if self._ads_var is None:
if ads_var_position is not None:
self._unique_id = ads_var_position
elif ads_var_pos_set is not None:
self._unique_id = ads_var_pos_set
elif ads_var_open is not None:
self._unique_id = ads_var_open
self._state_dict[STATE_KEY_POSITION] = None
self._ads_var_position = ads_var_position
self._ads_var_pos_set = ads_var_pos_set
self._ads_var_open = ads_var_open
self._ads_var_close = ads_var_close
self._ads_var_stop = ads_var_stop
self._device_class = device_class
async def async_added_to_hass(self):
"""Register device notification."""
if self._ads_var is not None:
await self.async_initialize_device(self._ads_var,
self._ads_hub.PLCTYPE_BOOL)
if self._ads_var_position is not None:
await self.async_initialize_device(self._ads_var_position,
self._ads_hub.PLCTYPE_BYTE,
STATE_KEY_POSITION)
@property
def device_class(self):
"""Return the class of this cover."""
return self._device_class
@property
def is_closed(self):
"""Return if the cover is closed."""
if self._ads_var is not None:
return self._state_dict[STATE_KEY_STATE]
if self._ads_var_position is not None:
return self._state_dict[STATE_KEY_POSITION] == 0
return None
@property
def current_cover_position(self):
"""Return current position of cover."""
return self._state_dict[STATE_KEY_POSITION]
@property
def supported_features(self):
"""Flag supported features."""
supported_features = SUPPORT_OPEN | SUPPORT_CLOSE
if self._ads_var_stop is not None:
supported_features |= SUPPORT_STOP
if self._ads_var_pos_set is not None:
supported_features |= SUPPORT_SET_POSITION
return supported_features
def stop_cover(self, **kwargs):
"""Fire the stop action."""
if self._ads_var_stop:
self._ads_hub.write_by_name(self._ads_var_stop, True,
self._ads_hub.PLCTYPE_BOOL)
def set_cover_position(self, **kwargs):
"""Set cover position."""
position = kwargs[ATTR_POSITION]
if self._ads_var_pos_set is not None:
self._ads_hub.write_by_name(self._ads_var_pos_set, position,
self._ads_hub.PLCTYPE_BYTE)
def open_cover(self, **kwargs):
"""Move the cover up."""
if self._ads_var_open is not None:
self._ads_hub.write_by_name(self._ads_var_open, True,
self._ads_hub.PLCTYPE_BOOL)
elif self._ads_var_pos_set is not None:
self.set_cover_position(position=100)
def close_cover(self, **kwargs):
"""Move the cover down."""
if self._ads_var_close is not None:
self._ads_hub.write_by_name(self._ads_var_close, True,
self._ads_hub.PLCTYPE_BOOL)
elif self._ads_var_pos_set is not None:
self.set_cover_position(position=0)
@property
def available(self):
"""Return False if state has not been updated yet."""
if self._ads_var is not None or self._ads_var_position is not None:
return self._state_dict[STATE_KEY_STATE] is not None or \
self._state_dict[STATE_KEY_POSITION] is not None
return True

View File

@@ -177,6 +177,11 @@ class AfterShipSensor(Entity):
if track['title'] is None
else track['title']
)
last_checkpoint = (
"Shipment pending"
if track['tag'] == "Pending"
else track['checkpoints'][-1]
)
status_counts[status] = status_counts.get(status, 0) + 1
trackings.append({
'name': name,
@@ -187,7 +192,7 @@ class AfterShipSensor(Entity):
'last_update': track['updated_at'],
'expected_delivery': track['expected_delivery'],
'status': track['tag'],
'last_checkpoint': track['checkpoints'][-1]
'last_checkpoint': last_checkpoint
})
if status not in status_to_ignore:

View File

@@ -19,6 +19,7 @@ SCAN_INTERVAL = timedelta(seconds=30)
ATTR_CHANGED_BY = 'changed_by'
FORMAT_TEXT = 'text'
FORMAT_NUMBER = 'number'
ATTR_CODE_ARM_REQUIRED = 'code_arm_required'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
@@ -87,6 +88,11 @@ class AlarmControlPanel(Entity):
"""Last change triggered by."""
return None
@property
def code_arm_required(self):
"""Whether the code is required for arm actions."""
return True
def alarm_disarm(self, code=None):
"""Send disarm command."""
raise NotImplementedError()
@@ -159,6 +165,7 @@ class AlarmControlPanel(Entity):
"""Return the state attributes."""
state_attr = {
ATTR_CODE_FORMAT: self.code_format,
ATTR_CHANGED_BY: self.changed_by
ATTR_CHANGED_BY: self.changed_by,
ATTR_CODE_ARM_REQUIRED: self.code_arm_required
}
return state_attr

View File

@@ -1,7 +1,7 @@
"""Support for repeating alerts when conditions are met."""
import asyncio
import logging
from datetime import datetime, timedelta
from datetime import timedelta
import voluptuous as vol
@@ -13,6 +13,7 @@ from homeassistant.const import (
SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE, ATTR_ENTITY_ID)
from homeassistant.helpers import service, event
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.util.dt import now
_LOGGER = logging.getLogger(__name__)
@@ -117,7 +118,7 @@ async def async_setup(hass, config):
tasks = [alert.async_update_ha_state() for alert in entities]
if tasks:
await asyncio.wait(tasks, loop=hass.loop)
await asyncio.wait(tasks)
return True
@@ -222,7 +223,7 @@ class Alert(ToggleEntity):
async def _schedule_notify(self):
"""Schedule a notification."""
delay = self._delay[self._next_delay]
next_msg = datetime.now() + delay
next_msg = 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)

View File

@@ -4,5 +4,8 @@
"documentation": "https://www.home-assistant.io/components/alert",
"requirements": [],
"dependencies": [],
"after_dependencies": [
"notify"
],
"codeowners": []
}

View File

@@ -5,12 +5,13 @@ import voluptuous as vol
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import entityfilter
from homeassistant.const import CONF_NAME
from . import flash_briefings, intent, smart_home
from . import flash_briefings, intent, smart_home_http
from .const import (
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)
CONF_ENTITY_CONFIG, CONF_DESCRIPTION, CONF_DISPLAY_CATEGORIES)
_LOGGER = logging.getLogger(__name__)
@@ -18,9 +19,9 @@ CONF_FLASH_BRIEFINGS = 'flash_briefings'
CONF_SMART_HOME = 'smart_home'
ALEXA_ENTITY_SCHEMA = vol.Schema({
vol.Optional(smart_home.CONF_DESCRIPTION): cv.string,
vol.Optional(smart_home.CONF_DISPLAY_CATEGORIES): cv.string,
vol.Optional(smart_home.CONF_NAME): cv.string,
vol.Optional(CONF_DESCRIPTION): cv.string,
vol.Optional(CONF_DISPLAY_CATEGORIES): cv.string,
vol.Optional(CONF_NAME): cv.string,
})
SMART_HOME_SCHEMA = vol.Schema({
@@ -65,6 +66,6 @@ async def async_setup(hass, config):
pass
else:
smart_home_config = smart_home_config or SMART_HOME_SCHEMA({})
await smart_home.async_setup(hass, smart_home_config)
await smart_home_http.async_setup(hass, smart_home_config)
return True

View File

@@ -9,7 +9,6 @@ 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__)
@@ -39,7 +38,7 @@ class Auth:
self._prefs = None
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY)
self._get_token_lock = asyncio.Lock(loop=hass.loop)
self._get_token_lock = asyncio.Lock()
async def async_do_auth(self, accept_grant_code):
"""Do authentication with an AcceptGrant code."""
@@ -97,7 +96,7 @@ class Auth:
try:
session = aiohttp_client.async_get_clientsession(self.hass)
with async_timeout.timeout(DEFAULT_TIMEOUT, loop=self.hass.loop):
with async_timeout.timeout(10):
response = await session.post(LWA_TOKEN_URI,
headers=LWA_HEADERS,
data=lwa_params,

View File

@@ -0,0 +1,604 @@
"""Alexa capabilities."""
from datetime import datetime
import logging
from homeassistant.const import (
ATTR_SUPPORTED_FEATURES,
ATTR_TEMPERATURE,
ATTR_UNIT_OF_MEASUREMENT,
STATE_LOCKED,
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
STATE_UNLOCKED,
)
import homeassistant.components.climate.const as climate
from homeassistant.components import (
light,
fan,
cover,
)
import homeassistant.util.color as color_util
from .const import (
API_TEMP_UNITS,
API_THERMOSTAT_MODES,
API_THERMOSTAT_PRESETS,
DATE_FORMAT,
PERCENTAGE_FAN_MAP,
)
from .errors import UnsupportedProperty
_LOGGER = logging.getLogger(__name__)
class AlexaCapibility:
"""Base class for Alexa capability interfaces.
The Smart Home Skills API defines a number of "capability interfaces",
roughly analogous to domains in Home Assistant. The supported interfaces
describe what actions can be performed on a particular device.
https://developer.amazon.com/docs/device-apis/message-guide.html
"""
def __init__(self, entity):
"""Initialize an Alexa capibility."""
self.entity = entity
def name(self):
"""Return the Alexa API name of this interface."""
raise NotImplementedError
@staticmethod
def properties_supported():
"""Return what properties this entity supports."""
return []
@staticmethod
def properties_proactively_reported():
"""Return True if properties asynchronously reported."""
return False
@staticmethod
def properties_retrievable():
"""Return True if properties can be retrieved."""
return False
@staticmethod
def get_property(name):
"""Read and return a property.
Return value should be a dict, or raise UnsupportedProperty.
Properties can also have a timeOfSample and uncertaintyInMilliseconds,
but returning those metadata is not yet implemented.
"""
raise UnsupportedProperty(name)
@staticmethod
def supports_deactivation():
"""Applicable only to scenes."""
return None
def serialize_discovery(self):
"""Serialize according to the Discovery API."""
result = {
'type': 'AlexaInterface',
'interface': self.name(),
'version': '3',
'properties': {
'supported': self.properties_supported(),
'proactivelyReported': self.properties_proactively_reported(),
'retrievable': self.properties_retrievable(),
},
}
# pylint: disable=assignment-from-none
supports_deactivation = self.supports_deactivation()
if supports_deactivation is not None:
result['supportsDeactivation'] = supports_deactivation
return result
def serialize_properties(self):
"""Return properties serialized for an API response."""
for prop in self.properties_supported():
prop_name = prop['name']
# pylint: disable=assignment-from-no-return
prop_value = self.get_property(prop_name)
if prop_value is not None:
yield {
'name': prop_name,
'namespace': self.name(),
'value': prop_value,
'timeOfSample': datetime.now().strftime(DATE_FORMAT),
'uncertaintyInMilliseconds': 0
}
class AlexaEndpointHealth(AlexaCapibility):
"""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):
"""Initialize the entity."""
super().__init__(entity)
self.hass = hass
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.EndpointHealth'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'connectivity'}]
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return False
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'connectivity':
raise UnsupportedProperty(name)
if self.entity.state == STATE_UNAVAILABLE:
return {'value': 'UNREACHABLE'}
return {'value': 'OK'}
class AlexaPowerController(AlexaCapibility):
"""Implements Alexa.PowerController.
https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.PowerController'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'powerState'}]
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return True
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'powerState':
raise UnsupportedProperty(name)
if self.entity.domain == climate.DOMAIN:
is_on = self.entity.state != climate.HVAC_MODE_OFF
else:
is_on = self.entity.state != STATE_OFF
return 'ON' if is_on else 'OFF'
class AlexaLockController(AlexaCapibility):
"""Implements Alexa.LockController.
https://developer.amazon.com/docs/device-apis/alexa-lockcontroller.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.LockController'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'lockState'}]
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'lockState':
raise UnsupportedProperty(name)
if self.entity.state == STATE_LOCKED:
return 'LOCKED'
if self.entity.state == STATE_UNLOCKED:
return 'UNLOCKED'
return 'JAMMED'
class AlexaSceneController(AlexaCapibility):
"""Implements Alexa.SceneController.
https://developer.amazon.com/docs/device-apis/alexa-scenecontroller.html
"""
def __init__(self, entity, supports_deactivation):
"""Initialize the entity."""
super().__init__(entity)
self.supports_deactivation = lambda: supports_deactivation
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.SceneController'
class AlexaBrightnessController(AlexaCapibility):
"""Implements Alexa.BrightnessController.
https://developer.amazon.com/docs/device-apis/alexa-brightnesscontroller.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.BrightnessController'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'brightness'}]
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return True
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'brightness':
raise UnsupportedProperty(name)
if 'brightness' in self.entity.attributes:
return round(self.entity.attributes['brightness'] / 255.0 * 100)
return 0
class AlexaColorController(AlexaCapibility):
"""Implements Alexa.ColorController.
https://developer.amazon.com/docs/device-apis/alexa-colorcontroller.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.ColorController'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'color'}]
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'color':
raise UnsupportedProperty(name)
hue, saturation = self.entity.attributes.get(
light.ATTR_HS_COLOR, (0, 0))
return {
'hue': hue,
'saturation': saturation / 100.0,
'brightness': self.entity.attributes.get(
light.ATTR_BRIGHTNESS, 0) / 255.0,
}
class AlexaColorTemperatureController(AlexaCapibility):
"""Implements Alexa.ColorTemperatureController.
https://developer.amazon.com/docs/device-apis/alexa-colortemperaturecontroller.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.ColorTemperatureController'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'colorTemperatureInKelvin'}]
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'colorTemperatureInKelvin':
raise UnsupportedProperty(name)
if 'color_temp' in self.entity.attributes:
return color_util.color_temperature_mired_to_kelvin(
self.entity.attributes['color_temp'])
return 0
class AlexaPercentageController(AlexaCapibility):
"""Implements Alexa.PercentageController.
https://developer.amazon.com/docs/device-apis/alexa-percentagecontroller.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.PercentageController'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'percentage'}]
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'percentage':
raise UnsupportedProperty(name)
if self.entity.domain == fan.DOMAIN:
speed = self.entity.attributes.get(fan.ATTR_SPEED)
return PERCENTAGE_FAN_MAP.get(speed, 0)
if self.entity.domain == cover.DOMAIN:
return self.entity.attributes.get(cover.ATTR_CURRENT_POSITION, 0)
return 0
class AlexaSpeaker(AlexaCapibility):
"""Implements Alexa.Speaker.
https://developer.amazon.com/docs/device-apis/alexa-speaker.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.Speaker'
class AlexaStepSpeaker(AlexaCapibility):
"""Implements Alexa.StepSpeaker.
https://developer.amazon.com/docs/device-apis/alexa-stepspeaker.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.StepSpeaker'
class AlexaPlaybackController(AlexaCapibility):
"""Implements Alexa.PlaybackController.
https://developer.amazon.com/docs/device-apis/alexa-playbackcontroller.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.PlaybackController'
class AlexaInputController(AlexaCapibility):
"""Implements Alexa.InputController.
https://developer.amazon.com/docs/device-apis/alexa-inputcontroller.html
"""
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.InputController'
class AlexaTemperatureSensor(AlexaCapibility):
"""Implements Alexa.TemperatureSensor.
https://developer.amazon.com/docs/device-apis/alexa-temperaturesensor.html
"""
def __init__(self, hass, entity):
"""Initialize the entity."""
super().__init__(entity)
self.hass = hass
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.TemperatureSensor'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'temperature'}]
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return True
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'temperature':
raise UnsupportedProperty(name)
unit = self.entity.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
temp = self.entity.state
if self.entity.domain == climate.DOMAIN:
unit = self.hass.config.units.temperature_unit
temp = self.entity.attributes.get(
climate.ATTR_CURRENT_TEMPERATURE)
return {
'value': float(temp),
'scale': API_TEMP_UNITS[unit],
}
class AlexaContactSensor(AlexaCapibility):
"""Implements Alexa.ContactSensor.
The Alexa.ContactSensor interface describes the properties and events used
to report the state of an endpoint that detects contact between two
surfaces. For example, a contact sensor can report whether a door or window
is open.
https://developer.amazon.com/docs/device-apis/alexa-contactsensor.html
"""
def __init__(self, hass, entity):
"""Initialize the entity."""
super().__init__(entity)
self.hass = hass
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.ContactSensor'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'detectionState'}]
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return True
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'detectionState':
raise UnsupportedProperty(name)
if self.entity.state == STATE_ON:
return 'DETECTED'
return 'NOT_DETECTED'
class AlexaMotionSensor(AlexaCapibility):
"""Implements Alexa.MotionSensor.
https://developer.amazon.com/docs/device-apis/alexa-motionsensor.html
"""
def __init__(self, hass, entity):
"""Initialize the entity."""
super().__init__(entity)
self.hass = hass
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.MotionSensor'
def properties_supported(self):
"""Return what properties this entity supports."""
return [{'name': 'detectionState'}]
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return True
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name != 'detectionState':
raise UnsupportedProperty(name)
if self.entity.state == STATE_ON:
return 'DETECTED'
return 'NOT_DETECTED'
class AlexaThermostatController(AlexaCapibility):
"""Implements Alexa.ThermostatController.
https://developer.amazon.com/docs/device-apis/alexa-thermostatcontroller.html
"""
def __init__(self, hass, entity):
"""Initialize the entity."""
super().__init__(entity)
self.hass = hass
def name(self):
"""Return the Alexa API name of this interface."""
return 'Alexa.ThermostatController'
def properties_supported(self):
"""Return what properties this entity supports."""
properties = [{'name': 'thermostatMode'}]
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & climate.SUPPORT_TARGET_TEMPERATURE:
properties.append({'name': 'targetSetpoint'})
if supported & climate.SUPPORT_TARGET_TEMPERATURE_RANGE:
properties.append({'name': 'lowerSetpoint'})
properties.append({'name': 'upperSetpoint'})
return properties
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return True
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name == 'thermostatMode':
preset = self.entity.attributes.get(climate.ATTR_PRESET_MODE)
if preset in API_THERMOSTAT_PRESETS:
mode = API_THERMOSTAT_PRESETS[preset]
else:
mode = API_THERMOSTAT_MODES.get(self.entity.state)
if mode is None:
_LOGGER.error(
"%s (%s) has unsupported state value '%s'",
self.entity.entity_id, type(self.entity),
self.entity.state)
raise UnsupportedProperty(name)
return mode
unit = self.hass.config.units.temperature_unit
if name == 'targetSetpoint':
temp = self.entity.attributes.get(ATTR_TEMPERATURE)
elif name == 'lowerSetpoint':
temp = self.entity.attributes.get(climate.ATTR_TARGET_TEMP_LOW)
elif name == 'upperSetpoint':
temp = self.entity.attributes.get(climate.ATTR_TARGET_TEMP_HIGH)
else:
raise UnsupportedProperty(name)
if temp is None:
return None
return {
'value': float(temp),
'scale': API_TEMP_UNITS[unit],
}

View File

@@ -0,0 +1,69 @@
"""Config helpers for Alexa."""
from .state_report import async_enable_proactive_mode
class AbstractConfig:
"""Hold the configuration for Alexa."""
_unsub_proactive_report = None
def __init__(self, hass):
"""Initialize abstract config."""
self.hass = hass
@property
def supports_auth(self):
"""Return if config supports auth."""
return False
@property
def should_report_state(self):
"""Return if states should be proactively reported."""
return False
@property
def endpoint(self):
"""Endpoint for report state."""
return None
@property
def entity_config(self):
"""Return entity config."""
return {}
@property
def is_reporting_states(self):
"""Return if proactive mode is enabled."""
return self._unsub_proactive_report is not None
async def async_enable_proactive_mode(self):
"""Enable proactive mode."""
if self._unsub_proactive_report is None:
self._unsub_proactive_report = self.hass.async_create_task(
async_enable_proactive_mode(self.hass, self)
)
try:
await self._unsub_proactive_report
except Exception: # pylint: disable=broad-except
self._unsub_proactive_report = None
raise
async def async_disable_proactive_mode(self):
"""Disable proactive mode."""
unsub_func = await self._unsub_proactive_report
if unsub_func:
unsub_func()
self._unsub_proactive_report = None
def should_expose(self, entity_id):
"""If an entity should be exposed."""
# pylint: disable=no-self-use
return False
async def async_get_access_token(self):
"""Get an access token."""
raise NotImplementedError
async def async_accept_grant(self, code):
"""Accept a grant."""
raise NotImplementedError

View File

@@ -1,4 +1,14 @@
"""Constants for the Alexa integration."""
from collections import OrderedDict
from homeassistant.const import (
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
)
from homeassistant.components.climate import const as climate
from homeassistant.components import fan
DOMAIN = 'alexa'
# Flash briefing constants
@@ -25,4 +35,74 @@ SYN_RESOLUTION_MATCH = 'ER_SUCCESS_MATCH'
DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.0Z'
DEFAULT_TIMEOUT = 30
API_DIRECTIVE = 'directive'
API_ENDPOINT = 'endpoint'
API_EVENT = 'event'
API_CONTEXT = 'context'
API_HEADER = 'header'
API_PAYLOAD = 'payload'
API_SCOPE = 'scope'
API_CHANGE = 'change'
CONF_DESCRIPTION = 'description'
CONF_DISPLAY_CATEGORIES = 'display_categories'
API_TEMP_UNITS = {
TEMP_FAHRENHEIT: 'FAHRENHEIT',
TEMP_CELSIUS: 'CELSIUS',
}
# Needs to be ordered dict for `async_api_set_thermostat_mode` which does a
# reverse mapping of this dict and we want to map the first occurrance of OFF
# back to HA state.
API_THERMOSTAT_MODES = OrderedDict([
(climate.HVAC_MODE_HEAT, 'HEAT'),
(climate.HVAC_MODE_COOL, 'COOL'),
(climate.HVAC_MODE_HEAT_COOL, 'AUTO'),
(climate.HVAC_MODE_AUTO, 'AUTO'),
(climate.HVAC_MODE_OFF, 'OFF'),
(climate.HVAC_MODE_FAN_ONLY, 'OFF'),
(climate.HVAC_MODE_DRY, 'OFF'),
])
API_THERMOSTAT_PRESETS = {
climate.PRESET_ECO: 'ECO'
}
PERCENTAGE_FAN_MAP = {
fan.SPEED_LOW: 33,
fan.SPEED_MEDIUM: 66,
fan.SPEED_HIGH: 100,
}
class Cause:
"""Possible causes for property changes.
https://developer.amazon.com/docs/smarthome/state-reporting-for-a-smart-home-skill.html#cause-object
"""
# Indicates that the event was caused by a customer interaction with an
# application. For example, a customer switches on a light, or locks a door
# using the Alexa app or an app provided by a device vendor.
APP_INTERACTION = 'APP_INTERACTION'
# Indicates that the event was caused by a physical interaction with an
# endpoint. For example manually switching on a light or manually locking a
# door lock
PHYSICAL_INTERACTION = 'PHYSICAL_INTERACTION'
# Indicates that the event was caused by the periodic poll of an appliance,
# which found a change in value. For example, you might poll a temperature
# sensor every hour, and send the updated temperature to Alexa.
PERIODIC_POLL = 'PERIODIC_POLL'
# Indicates that the event was caused by the application of a device rule.
# For example, a customer configures a rule to switch on a light if a
# motion sensor detects motion. In this case, Alexa receives an event from
# the motion sensor, and another event from the light to indicate that its
# state change was caused by the rule.
RULE_TRIGGER = 'RULE_TRIGGER'
# Indicates that the event was caused by a voice interaction with Alexa.
# For example a user speaking to their Echo device.
VOICE_INTERACTION = 'VOICE_INTERACTION'

View File

@@ -0,0 +1,457 @@
"""Alexa entity adapters."""
from typing import List
from homeassistant.core import callback
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_SUPPORTED_FEATURES,
ATTR_UNIT_OF_MEASUREMENT,
CLOUD_NEVER_EXPOSED_ENTITIES,
CONF_NAME,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
)
from homeassistant.util.decorator import Registry
from homeassistant.components.climate import const as climate
from homeassistant.components import (
alert, automation, binary_sensor, cover, fan, group,
input_boolean, light, lock, media_player, scene, script, sensor, switch)
from .const import CONF_DESCRIPTION, CONF_DISPLAY_CATEGORIES
from .capabilities import (
AlexaBrightnessController,
AlexaColorController,
AlexaColorTemperatureController,
AlexaContactSensor,
AlexaEndpointHealth,
AlexaInputController,
AlexaLockController,
AlexaMotionSensor,
AlexaPercentageController,
AlexaPlaybackController,
AlexaPowerController,
AlexaSceneController,
AlexaSpeaker,
AlexaStepSpeaker,
AlexaTemperatureSensor,
AlexaThermostatController,
)
ENTITY_ADAPTERS = Registry()
class DisplayCategory:
"""Possible display categories for Discovery response.
https://developer.amazon.com/docs/device-apis/alexa-discovery.html#display-categories
"""
# Describes a combination of devices set to a specific state, when the
# state change must occur in a specific order. For example, a "watch
# Netflix" scene might require the: 1. TV to be powered on & 2. Input set
# to HDMI1. Applies to Scenes
ACTIVITY_TRIGGER = "ACTIVITY_TRIGGER"
# Indicates media devices with video or photo capabilities.
CAMERA = "CAMERA"
# Indicates an endpoint that detects and reports contact.
CONTACT_SENSOR = "CONTACT_SENSOR"
# Indicates a door.
DOOR = "DOOR"
# Indicates light sources or fixtures.
LIGHT = "LIGHT"
# Indicates an endpoint that detects and reports motion.
MOTION_SENSOR = "MOTION_SENSOR"
# An endpoint that cannot be described in on of the other categories.
OTHER = "OTHER"
# Describes a combination of devices set to a specific state, when the
# order of the state change is not important. For example a bedtime scene
# might include turning off lights and lowering the thermostat, but the
# order is unimportant. Applies to Scenes
SCENE_TRIGGER = "SCENE_TRIGGER"
# Indicates an endpoint that locks.
SMARTLOCK = "SMARTLOCK"
# Indicates modules that are plugged into an existing electrical outlet.
# Can control a variety of devices.
SMARTPLUG = "SMARTPLUG"
# Indicates the endpoint is a speaker or speaker system.
SPEAKER = "SPEAKER"
# Indicates in-wall switches wired to the electrical system. Can control a
# variety of devices.
SWITCH = "SWITCH"
# Indicates endpoints that report the temperature only.
TEMPERATURE_SENSOR = "TEMPERATURE_SENSOR"
# Indicates endpoints that control temperature, stand-alone air
# conditioners, or heaters with direct temperature control.
THERMOSTAT = "THERMOSTAT"
# Indicates the endpoint is a television.
TV = "TV"
class AlexaEntity:
"""An adaptation of an entity, expressed in Alexa's terms.
The API handlers should manipulate entities only through this interface.
"""
def __init__(self, hass, config, entity):
"""Initialize Alexa Entity."""
self.hass = hass
self.config = config
self.entity = entity
self.entity_conf = config.entity_config.get(entity.entity_id, {})
@property
def entity_id(self):
"""Return the Entity ID."""
return self.entity.entity_id
def friendly_name(self):
"""Return the Alexa API friendly name."""
return self.entity_conf.get(CONF_NAME, self.entity.name)
def description(self):
"""Return the Alexa API description."""
return self.entity_conf.get(CONF_DESCRIPTION, self.entity.entity_id)
def alexa_id(self):
"""Return the Alexa API entity id."""
return self.entity.entity_id.replace('.', '#')
def display_categories(self):
"""Return a list of display categories."""
entity_conf = self.config.entity_config.get(self.entity.entity_id, {})
if CONF_DISPLAY_CATEGORIES in entity_conf:
return [entity_conf[CONF_DISPLAY_CATEGORIES]]
return self.default_display_categories()
def default_display_categories(self):
"""Return a list of default display categories.
This can be overridden by the user in the Home Assistant configuration.
See also DisplayCategory.
"""
raise NotImplementedError
def get_interface(self, capability):
"""Return the given AlexaInterface.
Raises _UnsupportedInterface.
"""
pass
def interfaces(self):
"""Return a list of supported interfaces.
Used for discovery. The list should contain AlexaInterface instances.
If the list is empty, this entity will not be discovered.
"""
raise NotImplementedError
def serialize_properties(self):
"""Yield each supported property in API format."""
for interface in self.interfaces():
for prop in interface.serialize_properties():
yield prop
def serialize_discovery(self):
"""Serialize the entity for discovery."""
return {
'displayCategories': self.display_categories(),
'cookie': {},
'endpointId': self.alexa_id(),
'friendlyName': self.friendly_name(),
'description': self.description(),
'manufacturerName': 'Home Assistant',
'capabilities': [
i.serialize_discovery() for i in self.interfaces()
]
}
@callback
def async_get_entities(hass, config) -> List[AlexaEntity]:
"""Return all entities that are supported by Alexa."""
entities = []
for state in hass.states.async_all():
if state.entity_id in CLOUD_NEVER_EXPOSED_ENTITIES:
continue
if state.domain not in ENTITY_ADAPTERS:
continue
alexa_entity = ENTITY_ADAPTERS[state.domain](hass, config, state)
if not list(alexa_entity.interfaces()):
continue
entities.append(alexa_entity)
return entities
@ENTITY_ADAPTERS.register(alert.DOMAIN)
@ENTITY_ADAPTERS.register(automation.DOMAIN)
@ENTITY_ADAPTERS.register(group.DOMAIN)
@ENTITY_ADAPTERS.register(input_boolean.DOMAIN)
class GenericCapabilities(AlexaEntity):
"""A generic, on/off device.
The choice of last resort.
"""
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.OTHER]
def interfaces(self):
"""Yield the supported interfaces."""
return [AlexaPowerController(self.entity),
AlexaEndpointHealth(self.hass, self.entity)]
@ENTITY_ADAPTERS.register(switch.DOMAIN)
class SwitchCapabilities(AlexaEntity):
"""Class to represent Switch capabilities."""
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.SWITCH]
def interfaces(self):
"""Yield the supported interfaces."""
return [AlexaPowerController(self.entity),
AlexaEndpointHealth(self.hass, self.entity)]
@ENTITY_ADAPTERS.register(climate.DOMAIN)
class ClimateCapabilities(AlexaEntity):
"""Class to represent Climate capabilities."""
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.THERMOSTAT]
def interfaces(self):
"""Yield the supported interfaces."""
# If we support two modes, one being off, we allow turning on too.
if (climate.HVAC_MODE_OFF in
self.entity.attributes[climate.ATTR_HVAC_MODES]):
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)
class CoverCapabilities(AlexaEntity):
"""Class to represent Cover capabilities."""
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.DOOR]
def interfaces(self):
"""Yield the supported interfaces."""
yield AlexaPowerController(self.entity)
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)
class LightCapabilities(AlexaEntity):
"""Class to represent Light capabilities."""
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.LIGHT]
def interfaces(self):
"""Yield the supported interfaces."""
yield AlexaPowerController(self.entity)
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & light.SUPPORT_BRIGHTNESS:
yield AlexaBrightnessController(self.entity)
if supported & light.SUPPORT_COLOR:
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)
class FanCapabilities(AlexaEntity):
"""Class to represent Fan capabilities."""
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.OTHER]
def interfaces(self):
"""Yield the supported interfaces."""
yield AlexaPowerController(self.entity)
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)
class LockCapabilities(AlexaEntity):
"""Class to represent Lock capabilities."""
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.SMARTLOCK]
def interfaces(self):
"""Yield the supported interfaces."""
return [AlexaLockController(self.entity),
AlexaEndpointHealth(self.hass, self.entity)]
@ENTITY_ADAPTERS.register(media_player.const.DOMAIN)
class MediaPlayerCapabilities(AlexaEntity):
"""Class to represent MediaPlayer capabilities."""
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.TV]
def interfaces(self):
"""Yield the supported interfaces."""
yield AlexaEndpointHealth(self.hass, self.entity)
yield AlexaPowerController(self.entity)
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & media_player.const.SUPPORT_VOLUME_SET:
yield AlexaSpeaker(self.entity)
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.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)
if supported & media_player.SUPPORT_SELECT_SOURCE:
yield AlexaInputController(self.entity)
@ENTITY_ADAPTERS.register(scene.DOMAIN)
class SceneCapabilities(AlexaEntity):
"""Class to represent Scene capabilities."""
def description(self):
"""Return the description of the entity."""
# Required description as per Amazon Scene docs
scene_fmt = '{} (Scene connected via Home Assistant)'
return scene_fmt.format(AlexaEntity.description(self))
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.SCENE_TRIGGER]
def interfaces(self):
"""Yield the supported interfaces."""
return [AlexaSceneController(self.entity,
supports_deactivation=False)]
@ENTITY_ADAPTERS.register(script.DOMAIN)
class ScriptCapabilities(AlexaEntity):
"""Class to represent Script capabilities."""
def default_display_categories(self):
"""Return the display categories for this entity."""
return [DisplayCategory.ACTIVITY_TRIGGER]
def interfaces(self):
"""Yield the supported interfaces."""
can_cancel = bool(self.entity.attributes.get('can_cancel'))
return [AlexaSceneController(self.entity,
supports_deactivation=can_cancel)]
@ENTITY_ADAPTERS.register(sensor.DOMAIN)
class SensorCapabilities(AlexaEntity):
"""Class to represent Sensor capabilities."""
def default_display_categories(self):
"""Return the display categories for this entity."""
# although there are other kinds of sensors, all but temperature
# sensors are currently ignored.
return [DisplayCategory.TEMPERATURE_SENSOR]
def interfaces(self):
"""Yield the supported interfaces."""
attrs = self.entity.attributes
if attrs.get(ATTR_UNIT_OF_MEASUREMENT) in (
TEMP_FAHRENHEIT,
TEMP_CELSIUS,
):
yield AlexaTemperatureSensor(self.hass, self.entity)
yield AlexaEndpointHealth(self.hass, self.entity)
@ENTITY_ADAPTERS.register(binary_sensor.DOMAIN)
class BinarySensorCapabilities(AlexaEntity):
"""Class to represent BinarySensor capabilities."""
TYPE_CONTACT = 'contact'
TYPE_MOTION = 'motion'
def default_display_categories(self):
"""Return the display categories for this entity."""
sensor_type = self.get_type()
if sensor_type is self.TYPE_CONTACT:
return [DisplayCategory.CONTACT_SENSOR]
if sensor_type is self.TYPE_MOTION:
return [DisplayCategory.MOTION_SENSOR]
def interfaces(self):
"""Yield the supported interfaces."""
sensor_type = self.get_type()
if sensor_type is self.TYPE_CONTACT:
yield AlexaContactSensor(self.hass, self.entity)
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
if attrs.get(ATTR_DEVICE_CLASS) in (
'door',
'garage_door',
'opening',
'window',
):
return self.TYPE_CONTACT
if attrs.get(ATTR_DEVICE_CLASS) == 'motion':
return self.TYPE_MOTION

View File

@@ -0,0 +1,91 @@
"""Alexa related errors."""
from homeassistant.exceptions import HomeAssistantError
from .const import API_TEMP_UNITS
class UnsupportedInterface(HomeAssistantError):
"""This entity does not support the requested Smart Home API interface."""
class UnsupportedProperty(HomeAssistantError):
"""This entity does not support the requested Smart Home API property."""
class NoTokenAvailable(HomeAssistantError):
"""There is no access token available."""
class AlexaError(Exception):
"""Base class for errors that can be serialized for the Alexa API.
A handler can raise subclasses of this to return an error to the request.
"""
namespace = None
error_type = None
def __init__(self, error_message, payload=None):
"""Initialize an alexa error."""
Exception.__init__(self)
self.error_message = error_message
self.payload = None
class AlexaInvalidEndpointError(AlexaError):
"""The endpoint in the request does not exist."""
namespace = 'Alexa'
error_type = 'NO_SUCH_ENDPOINT'
def __init__(self, endpoint_id):
"""Initialize invalid endpoint error."""
msg = 'The endpoint {} does not exist'.format(endpoint_id)
AlexaError.__init__(self, msg)
self.endpoint_id = endpoint_id
class AlexaInvalidValueError(AlexaError):
"""Class to represent InvalidValue errors."""
namespace = 'Alexa'
error_type = 'INVALID_VALUE'
class AlexaUnsupportedThermostatModeError(AlexaError):
"""Class to represent UnsupportedThermostatMode errors."""
namespace = 'Alexa.ThermostatController'
error_type = 'UNSUPPORTED_THERMOSTAT_MODE'
class AlexaTempRangeError(AlexaError):
"""Class to represent TempRange errors."""
namespace = 'Alexa'
error_type = 'TEMPERATURE_VALUE_OUT_OF_RANGE'
def __init__(self, hass, temp, min_temp, max_temp):
"""Initialize TempRange error."""
unit = hass.config.units.temperature_unit
temp_range = {
'minimumValue': {
'value': min_temp,
'scale': API_TEMP_UNITS[unit],
},
'maximumValue': {
'value': max_temp,
'scale': API_TEMP_UNITS[unit],
},
}
payload = {'validRange': temp_range}
msg = 'The requested temperature {} is out of range'.format(temp)
AlexaError.__init__(self, msg, payload)
class AlexaBridgeUnreachableError(AlexaError):
"""Class to represent BridgeUnreachable errors."""
namespace = 'Alexa'
error_type = 'BRIDGE_UNREACHABLE'

View File

@@ -0,0 +1,735 @@
"""Alexa message handlers."""
from datetime import datetime
import logging
import math
from homeassistant import core as ha
from homeassistant.components import cover, fan, group, light, media_player
from homeassistant.components.climate import const as climate
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, ATTR_TEMPERATURE, 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_DOWN, SERVICE_VOLUME_MUTE,
SERVICE_VOLUME_SET, SERVICE_VOLUME_UP, TEMP_CELSIUS, TEMP_FAHRENHEIT)
import homeassistant.util.color as color_util
from homeassistant.util.decorator import Registry
from homeassistant.util.temperature import convert as convert_temperature
from .const import (
API_TEMP_UNITS, API_THERMOSTAT_MODES, API_THERMOSTAT_PRESETS, Cause)
from .entities import async_get_entities
from .errors import (
AlexaInvalidValueError, AlexaTempRangeError,
AlexaUnsupportedThermostatModeError)
from .state_report import async_enable_proactive_mode
_LOGGER = logging.getLogger(__name__)
HANDLERS = Registry()
@HANDLERS.register(('Alexa.Discovery', 'Discover'))
async def async_api_discovery(hass, config, directive, context):
"""Create a API formatted discovery response.
Async friendly.
"""
discovery_endpoints = [
alexa_entity.serialize_discovery()
for alexa_entity in async_get_entities(hass, config)
if config.should_expose(alexa_entity.entity_id)
]
return directive.response(
name='Discover.Response',
namespace='Alexa.Discovery',
payload={'endpoints': discovery_endpoints},
)
@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 config.supports_auth:
await config.async_accept_grant(auth_code)
if config.should_report_state:
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."""
entity = directive.entity
domain = entity.domain
if domain == group.DOMAIN:
domain = ha.DOMAIN
service = SERVICE_TURN_ON
if domain == cover.DOMAIN:
service = cover.SERVICE_OPEN_COVER
elif domain == media_player.DOMAIN:
supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
power_features = (media_player.SUPPORT_TURN_ON |
media_player.SUPPORT_TURN_OFF)
if not supported & power_features:
service = media_player.SERVICE_MEDIA_PLAY
await hass.services.async_call(domain, service, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.PowerController', 'TurnOff'))
async def async_api_turn_off(hass, config, directive, context):
"""Process a turn off request."""
entity = directive.entity
domain = entity.domain
if entity.domain == group.DOMAIN:
domain = ha.DOMAIN
service = SERVICE_TURN_OFF
if entity.domain == cover.DOMAIN:
service = cover.SERVICE_CLOSE_COVER
elif domain == media_player.DOMAIN:
supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
power_features = (media_player.SUPPORT_TURN_ON |
media_player.SUPPORT_TURN_OFF)
if not supported & power_features:
service = media_player.SERVICE_MEDIA_STOP
await hass.services.async_call(domain, service, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.BrightnessController', 'SetBrightness'))
async def async_api_set_brightness(hass, config, directive, context):
"""Process a set brightness request."""
entity = directive.entity
brightness = int(directive.payload['brightness'])
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_BRIGHTNESS_PCT: brightness,
}, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.BrightnessController', 'AdjustBrightness'))
async def async_api_adjust_brightness(hass, config, directive, context):
"""Process an adjust brightness request."""
entity = directive.entity
brightness_delta = int(directive.payload['brightnessDelta'])
# read current state
try:
current = math.floor(
int(entity.attributes.get(light.ATTR_BRIGHTNESS)) / 255 * 100)
except ZeroDivisionError:
current = 0
# set brightness
brightness = max(0, brightness_delta + current)
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_BRIGHTNESS_PCT: brightness,
}, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.ColorController', 'SetColor'))
async def async_api_set_color(hass, config, directive, context):
"""Process a set color request."""
entity = directive.entity
rgb = color_util.color_hsb_to_RGB(
float(directive.payload['color']['hue']),
float(directive.payload['color']['saturation']),
float(directive.payload['color']['brightness'])
)
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_RGB_COLOR: rgb,
}, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.ColorTemperatureController', 'SetColorTemperature'))
async def async_api_set_color_temperature(hass, config, directive, context):
"""Process a set color temperature request."""
entity = directive.entity
kelvin = int(directive.payload['colorTemperatureInKelvin'])
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_KELVIN: kelvin,
}, blocking=False, context=context)
return directive.response()
@HANDLERS.register(
('Alexa.ColorTemperatureController', 'DecreaseColorTemperature'))
async def async_api_decrease_color_temp(hass, config, directive, context):
"""Process a decrease color temperature request."""
entity = directive.entity
current = int(entity.attributes.get(light.ATTR_COLOR_TEMP))
max_mireds = int(entity.attributes.get(light.ATTR_MAX_MIREDS))
value = min(max_mireds, current + 50)
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_COLOR_TEMP: value,
}, blocking=False, context=context)
return directive.response()
@HANDLERS.register(
('Alexa.ColorTemperatureController', 'IncreaseColorTemperature'))
async def async_api_increase_color_temp(hass, config, directive, context):
"""Process an increase color temperature request."""
entity = directive.entity
current = int(entity.attributes.get(light.ATTR_COLOR_TEMP))
min_mireds = int(entity.attributes.get(light.ATTR_MIN_MIREDS))
value = max(min_mireds, current - 50)
await hass.services.async_call(entity.domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id,
light.ATTR_COLOR_TEMP: value,
}, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.SceneController', 'Activate'))
async def async_api_activate(hass, config, directive, context):
"""Process an activate request."""
entity = directive.entity
domain = entity.domain
await hass.services.async_call(domain, SERVICE_TURN_ON, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False, context=context)
payload = {
'cause': {'type': Cause.VOICE_INTERACTION},
'timestamp': '%sZ' % (datetime.utcnow().isoformat(),)
}
return directive.response(
name='ActivationStarted',
namespace='Alexa.SceneController',
payload=payload,
)
@HANDLERS.register(('Alexa.SceneController', 'Deactivate'))
async def async_api_deactivate(hass, config, directive, context):
"""Process a deactivate request."""
entity = directive.entity
domain = entity.domain
await hass.services.async_call(domain, SERVICE_TURN_OFF, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False, context=context)
payload = {
'cause': {'type': Cause.VOICE_INTERACTION},
'timestamp': '%sZ' % (datetime.utcnow().isoformat(),)
}
return directive.response(
name='DeactivationStarted',
namespace='Alexa.SceneController',
payload=payload,
)
@HANDLERS.register(('Alexa.PercentageController', 'SetPercentage'))
async def async_api_set_percentage(hass, config, directive, context):
"""Process a set percentage request."""
entity = directive.entity
percentage = int(directive.payload['percentage'])
service = None
data = {ATTR_ENTITY_ID: entity.entity_id}
if entity.domain == fan.DOMAIN:
service = fan.SERVICE_SET_SPEED
speed = "off"
if percentage <= 33:
speed = "low"
elif percentage <= 66:
speed = "medium"
elif percentage <= 100:
speed = "high"
data[fan.ATTR_SPEED] = speed
elif entity.domain == cover.DOMAIN:
service = SERVICE_SET_COVER_POSITION
data[cover.ATTR_POSITION] = percentage
await hass.services.async_call(
entity.domain, service, data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.PercentageController', 'AdjustPercentage'))
async def async_api_adjust_percentage(hass, config, directive, context):
"""Process an adjust percentage request."""
entity = directive.entity
percentage_delta = int(directive.payload['percentageDelta'])
service = None
data = {ATTR_ENTITY_ID: entity.entity_id}
if entity.domain == fan.DOMAIN:
service = fan.SERVICE_SET_SPEED
speed = entity.attributes.get(fan.ATTR_SPEED)
if speed == "off":
current = 0
elif speed == "low":
current = 33
elif speed == "medium":
current = 66
elif speed == "high":
current = 100
# set percentage
percentage = max(0, percentage_delta + current)
speed = "off"
if percentage <= 33:
speed = "low"
elif percentage <= 66:
speed = "medium"
elif percentage <= 100:
speed = "high"
data[fan.ATTR_SPEED] = speed
elif entity.domain == cover.DOMAIN:
service = SERVICE_SET_COVER_POSITION
current = entity.attributes.get(cover.ATTR_POSITION)
data[cover.ATTR_POSITION] = max(0, percentage_delta + current)
await hass.services.async_call(
entity.domain, service, data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.LockController', 'Lock'))
async def async_api_lock(hass, config, directive, context):
"""Process a lock request."""
entity = directive.entity
await hass.services.async_call(entity.domain, SERVICE_LOCK, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False, context=context)
response = directive.response()
response.add_context_property({
'name': 'lockState',
'namespace': 'Alexa.LockController',
'value': 'LOCKED'
})
return response
# Not supported by Alexa yet
@HANDLERS.register(('Alexa.LockController', 'Unlock'))
async def async_api_unlock(hass, config, directive, context):
"""Process an unlock request."""
entity = directive.entity
await hass.services.async_call(entity.domain, SERVICE_UNLOCK, {
ATTR_ENTITY_ID: entity.entity_id
}, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.Speaker', 'SetVolume'))
async def async_api_set_volume(hass, config, directive, context):
"""Process a set volume request."""
volume = round(float(directive.payload['volume'] / 100), 2)
entity = directive.entity
data = {
ATTR_ENTITY_ID: entity.entity_id,
media_player.const.ATTR_MEDIA_VOLUME_LEVEL: volume,
}
await hass.services.async_call(
entity.domain, SERVICE_VOLUME_SET,
data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.InputController', 'SelectInput'))
async def async_api_select_input(hass, config, directive, context):
"""Process a set input request."""
media_input = directive.payload['input']
entity = directive.entity
# attempt to map the ALL UPPERCASE payload name to a source
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
formatted_source = source.lower().replace('-', ' ').replace('_', ' ')
if formatted_source in media_input.lower():
media_input = source
break
else:
msg = 'failed to map input {} to a media source on {}'.format(
media_input, entity.entity_id)
raise AlexaInvalidValueError(msg)
data = {
ATTR_ENTITY_ID: entity.entity_id,
media_player.const.ATTR_INPUT_SOURCE: media_input,
}
await hass.services.async_call(
entity.domain, media_player.SERVICE_SELECT_SOURCE,
data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.Speaker', 'AdjustVolume'))
async def async_api_adjust_volume(hass, config, directive, context):
"""Process an adjust volume request."""
volume_delta = int(directive.payload['volume'])
entity = directive.entity
current_level = entity.attributes.get(
media_player.const.ATTR_MEDIA_VOLUME_LEVEL)
# read current state
try:
current = math.floor(int(current_level * 100))
except ZeroDivisionError:
current = 0
volume = float(max(0, volume_delta + current) / 100)
data = {
ATTR_ENTITY_ID: entity.entity_id,
media_player.const.ATTR_MEDIA_VOLUME_LEVEL: volume,
}
await hass.services.async_call(
entity.domain, SERVICE_VOLUME_SET,
data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.StepSpeaker', 'AdjustVolume'))
async def async_api_adjust_volume_step(hass, config, directive, context):
"""Process an adjust volume step request."""
# media_player volume up/down service does not support specifying steps
# each component handles it differently e.g. via config.
# For now we use the volumeSteps returned to figure out if we
# should step up/down
volume_step = directive.payload['volumeSteps']
entity = directive.entity
data = {
ATTR_ENTITY_ID: entity.entity_id,
}
if volume_step > 0:
await hass.services.async_call(
entity.domain, SERVICE_VOLUME_UP,
data, blocking=False, context=context)
elif volume_step < 0:
await hass.services.async_call(
entity.domain, SERVICE_VOLUME_DOWN,
data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.StepSpeaker', 'SetMute'))
@HANDLERS.register(('Alexa.Speaker', 'SetMute'))
async def async_api_set_mute(hass, config, directive, context):
"""Process a set mute request."""
mute = bool(directive.payload['mute'])
entity = directive.entity
data = {
ATTR_ENTITY_ID: entity.entity_id,
media_player.const.ATTR_MEDIA_VOLUME_MUTED: mute,
}
await hass.services.async_call(
entity.domain, SERVICE_VOLUME_MUTE,
data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.PlaybackController', 'Play'))
async def async_api_play(hass, config, directive, context):
"""Process a play request."""
entity = directive.entity
data = {
ATTR_ENTITY_ID: entity.entity_id
}
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_PLAY,
data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.PlaybackController', 'Pause'))
async def async_api_pause(hass, config, directive, context):
"""Process a pause request."""
entity = directive.entity
data = {
ATTR_ENTITY_ID: entity.entity_id
}
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_PAUSE,
data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.PlaybackController', 'Stop'))
async def async_api_stop(hass, config, directive, context):
"""Process a stop request."""
entity = directive.entity
data = {
ATTR_ENTITY_ID: entity.entity_id
}
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_STOP,
data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.PlaybackController', 'Next'))
async def async_api_next(hass, config, directive, context):
"""Process a next request."""
entity = directive.entity
data = {
ATTR_ENTITY_ID: entity.entity_id
}
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_NEXT_TRACK,
data, blocking=False, context=context)
return directive.response()
@HANDLERS.register(('Alexa.PlaybackController', 'Previous'))
async def async_api_previous(hass, config, directive, context):
"""Process a previous request."""
entity = directive.entity
data = {
ATTR_ENTITY_ID: entity.entity_id
}
await hass.services.async_call(
entity.domain, SERVICE_MEDIA_PREVIOUS_TRACK,
data, blocking=False, context=context)
return directive.response()
def temperature_from_object(hass, temp_obj, interval=False):
"""Get temperature from Temperature object in requested unit."""
to_unit = hass.config.units.temperature_unit
from_unit = TEMP_CELSIUS
temp = float(temp_obj['value'])
if temp_obj['scale'] == 'FAHRENHEIT':
from_unit = TEMP_FAHRENHEIT
elif temp_obj['scale'] == 'KELVIN':
# convert to Celsius if absolute temperature
if not interval:
temp -= 273.15
return convert_temperature(temp, from_unit, to_unit, interval)
@HANDLERS.register(('Alexa.ThermostatController', 'SetTargetTemperature'))
async def async_api_set_target_temp(hass, config, directive, context):
"""Process a set target temperature request."""
entity = directive.entity
min_temp = entity.attributes.get(climate.ATTR_MIN_TEMP)
max_temp = entity.attributes.get(climate.ATTR_MAX_TEMP)
unit = hass.config.units.temperature_unit
data = {
ATTR_ENTITY_ID: entity.entity_id
}
payload = directive.payload
response = directive.response()
if 'targetSetpoint' in payload:
temp = temperature_from_object(hass, payload['targetSetpoint'])
if temp < min_temp or temp > max_temp:
raise AlexaTempRangeError(hass, temp, min_temp, max_temp)
data[ATTR_TEMPERATURE] = temp
response.add_context_property({
'name': 'targetSetpoint',
'namespace': 'Alexa.ThermostatController',
'value': {'value': temp, 'scale': API_TEMP_UNITS[unit]},
})
if 'lowerSetpoint' in payload:
temp_low = temperature_from_object(hass, payload['lowerSetpoint'])
if temp_low < min_temp or temp_low > max_temp:
raise AlexaTempRangeError(hass, temp_low, min_temp, max_temp)
data[climate.ATTR_TARGET_TEMP_LOW] = temp_low
response.add_context_property({
'name': 'lowerSetpoint',
'namespace': 'Alexa.ThermostatController',
'value': {'value': temp_low, 'scale': API_TEMP_UNITS[unit]},
})
if 'upperSetpoint' in payload:
temp_high = temperature_from_object(hass, payload['upperSetpoint'])
if temp_high < min_temp or temp_high > max_temp:
raise AlexaTempRangeError(hass, temp_high, min_temp, max_temp)
data[climate.ATTR_TARGET_TEMP_HIGH] = temp_high
response.add_context_property({
'name': 'upperSetpoint',
'namespace': 'Alexa.ThermostatController',
'value': {'value': temp_high, 'scale': API_TEMP_UNITS[unit]},
})
await hass.services.async_call(
entity.domain, climate.SERVICE_SET_TEMPERATURE, data, blocking=False,
context=context)
return response
@HANDLERS.register(('Alexa.ThermostatController', 'AdjustTargetTemperature'))
async def async_api_adjust_target_temp(hass, config, directive, context):
"""Process an adjust target temperature request."""
entity = directive.entity
min_temp = entity.attributes.get(climate.ATTR_MIN_TEMP)
max_temp = entity.attributes.get(climate.ATTR_MAX_TEMP)
unit = hass.config.units.temperature_unit
temp_delta = temperature_from_object(
hass, directive.payload['targetSetpointDelta'], interval=True)
target_temp = float(entity.attributes.get(ATTR_TEMPERATURE)) + temp_delta
if target_temp < min_temp or target_temp > max_temp:
raise AlexaTempRangeError(hass, target_temp, min_temp, max_temp)
data = {
ATTR_ENTITY_ID: entity.entity_id,
ATTR_TEMPERATURE: target_temp,
}
response = directive.response()
await hass.services.async_call(
entity.domain, climate.SERVICE_SET_TEMPERATURE, data, blocking=False,
context=context)
response.add_context_property({
'name': 'targetSetpoint',
'namespace': 'Alexa.ThermostatController',
'value': {'value': target_temp, 'scale': API_TEMP_UNITS[unit]},
})
return response
@HANDLERS.register(('Alexa.ThermostatController', 'SetThermostatMode'))
async def async_api_set_thermostat_mode(hass, config, directive, context):
"""Process a set thermostat mode request."""
entity = directive.entity
mode = directive.payload['thermostatMode']
mode = mode if isinstance(mode, str) else mode['value']
data = {
ATTR_ENTITY_ID: entity.entity_id,
}
ha_preset = next(
(k for k, v in API_THERMOSTAT_PRESETS.items() if v == mode),
None
)
if ha_preset:
presets = entity.attributes.get(climate.ATTR_PRESET_MODES, [])
if ha_preset not in presets:
msg = 'The requested thermostat mode {} is not supported'.format(
ha_preset
)
raise AlexaUnsupportedThermostatModeError(msg)
service = climate.SERVICE_SET_PRESET_MODE
data[climate.ATTR_PRESET_MODE] = climate.PRESET_ECO
else:
operation_list = entity.attributes.get(climate.ATTR_HVAC_MODES)
ha_mode = next(
(k for k, v in API_THERMOSTAT_MODES.items() if v == mode),
None
)
if ha_mode not in operation_list:
msg = 'The requested thermostat mode {} is not supported'.format(
mode
)
raise AlexaUnsupportedThermostatModeError(msg)
service = climate.SERVICE_SET_HVAC_MODE
data[climate.ATTR_HVAC_MODE] = ha_mode
response = directive.response()
await hass.services.async_call(
climate.DOMAIN, service, data,
blocking=False, context=context)
response.add_context_property({
'name': 'thermostatMode',
'namespace': 'Alexa.ThermostatController',
'value': mode,
})
return response
@HANDLERS.register(('Alexa', 'ReportState'))
async def async_api_reportstate(hass, config, directive, context):
"""Process a ReportState request."""
return directive.response(name='StateReport')

View File

@@ -0,0 +1,200 @@
"""Alexa models."""
import logging
from uuid import uuid4
from .const import (
API_CONTEXT,
API_DIRECTIVE,
API_ENDPOINT,
API_EVENT,
API_HEADER,
API_PAYLOAD,
API_SCOPE,
)
from .entities import ENTITY_ADAPTERS
from .errors import AlexaInvalidEndpointError
_LOGGER = logging.getLogger(__name__)
class AlexaDirective:
"""An incoming Alexa directive."""
def __init__(self, request):
"""Initialize a directive."""
self._directive = request[API_DIRECTIVE]
self.namespace = self._directive[API_HEADER]['namespace']
self.name = self._directive[API_HEADER]['name']
self.payload = self._directive[API_PAYLOAD]
self.has_endpoint = API_ENDPOINT in self._directive
self.entity = self.entity_id = self.endpoint = None
def load_entity(self, hass, config):
"""Set attributes related to the entity for this request.
Sets these attributes when self.has_endpoint is True:
- entity
- entity_id
- endpoint
Behavior when self.has_endpoint is False is undefined.
Will raise AlexaInvalidEndpointError if the endpoint in the request is
malformed or nonexistant.
"""
_endpoint_id = self._directive[API_ENDPOINT]['endpointId']
self.entity_id = _endpoint_id.replace('#', '.')
self.entity = hass.states.get(self.entity_id)
if not self.entity or not config.should_expose(self.entity_id):
raise AlexaInvalidEndpointError(_endpoint_id)
self.endpoint = ENTITY_ADAPTERS[self.entity.domain](
hass, config, self.entity)
def response(self,
name='Response',
namespace='Alexa',
payload=None):
"""Create an API formatted response.
Async friendly.
"""
response = AlexaResponse(name, namespace, payload)
token = self._directive[API_HEADER].get('correlationToken')
if token:
response.set_correlation_token(token)
if self.has_endpoint:
response.set_endpoint(self._directive[API_ENDPOINT].copy())
return response
def error(
self,
namespace='Alexa',
error_type='INTERNAL_ERROR',
error_message="",
payload=None
):
"""Create a API formatted error response.
Async friendly.
"""
payload = payload or {}
payload['type'] = error_type
payload['message'] = error_message
_LOGGER.info("Request %s/%s error %s: %s",
self._directive[API_HEADER]['namespace'],
self._directive[API_HEADER]['name'],
error_type, error_message)
return self.response(
name='ErrorResponse',
namespace=namespace,
payload=payload
)
class AlexaResponse:
"""Class to hold a response."""
def __init__(self, name, namespace, payload=None):
"""Initialize the response."""
payload = payload or {}
self._response = {
API_EVENT: {
API_HEADER: {
'namespace': namespace,
'name': name,
'messageId': str(uuid4()),
'payloadVersion': '3',
},
API_PAYLOAD: payload,
}
}
@property
def name(self):
"""Return the name of this response."""
return self._response[API_EVENT][API_HEADER]['name']
@property
def namespace(self):
"""Return the namespace of this response."""
return self._response[API_EVENT][API_HEADER]['namespace']
def set_correlation_token(self, token):
"""Set the correlationToken.
This should normally mirror the value from a request, and is set by
AlexaDirective.response() usually.
"""
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.
This should normally mirror the value from a request, and is set by
AlexaDirective.response() usually.
"""
self._response[API_EVENT][API_ENDPOINT] = endpoint
def _properties(self):
context = self._response.setdefault(API_CONTEXT, {})
return context.setdefault('properties', [])
def add_context_property(self, prop):
"""Add a property to the response context.
The Alexa response includes a list of properties which provides
feedback on how states have changed. For example if a user asks,
"Alexa, set theromstat to 20 degrees", the API expects a response with
the new value of the property, and Alexa will respond to the user
"Thermostat set to 20 degrees".
async_handle_message() will call .merge_context_properties() for every
request automatically, however often handlers will call services to
change state but the effects of those changes are applied
asynchronously. Thus, handlers should call this method to confirm
changes before returning.
"""
self._properties().append(prop)
def merge_context_properties(self, endpoint):
"""Add all properties from given endpoint if not already set.
Handlers should be using .add_context_property().
"""
properties = self._properties()
already_set = {(p['namespace'], p['name']) for p in properties}
for prop in endpoint.serialize_properties():
if (prop['namespace'], prop['name']) not in already_set:
self.add_context_property(prop)
def serialize(self):
"""Return response as a JSON-able data structure."""
return self._response

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,114 @@
"""Alexa HTTP interface."""
import logging
from homeassistant import core
from homeassistant.components.http.view import HomeAssistantView
from .auth import Auth
from .config import AbstractConfig
from .const import (
CONF_CLIENT_ID,
CONF_CLIENT_SECRET,
CONF_ENDPOINT,
CONF_ENTITY_CONFIG,
CONF_FILTER
)
from .state_report import async_enable_proactive_mode
from .smart_home import async_handle_message
_LOGGER = logging.getLogger(__name__)
SMART_HOME_HTTP_ENDPOINT = '/api/alexa/smart_home'
class AlexaConfig(AbstractConfig):
"""Alexa config."""
def __init__(self, hass, config):
"""Initialize Alexa config."""
super().__init__(hass)
self._config = config
if config.get(CONF_CLIENT_ID) and config.get(CONF_CLIENT_SECRET):
self._auth = Auth(hass, config[CONF_CLIENT_ID],
config[CONF_CLIENT_SECRET])
else:
self._auth = None
@property
def supports_auth(self):
"""Return if config supports auth."""
return self._auth is not None
@property
def should_report_state(self):
"""Return if we should proactively report states."""
return self._auth is not None
@property
def endpoint(self):
"""Endpoint for report state."""
return self._config.get(CONF_ENDPOINT)
@property
def entity_config(self):
"""Return entity config."""
return self._config.get(CONF_ENTITY_CONFIG) or {}
def should_expose(self, entity_id):
"""If an entity should be exposed."""
return self._config[CONF_FILTER](entity_id)
async def async_get_access_token(self):
"""Get an access token."""
return await self._auth.async_get_access_token()
async def async_accept_grant(self, code):
"""Accept a grant."""
return await self._auth.async_do_auth(code)
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
alexa configuration.
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.
"""
smart_home_config = AlexaConfig(hass, config)
hass.http.register_view(SmartHomeView(smart_home_config))
if smart_home_config.should_report_state:
await async_enable_proactive_mode(hass, smart_home_config)
class SmartHomeView(HomeAssistantView):
"""Expose Smart Home v3 payload interface via HTTP POST."""
url = SMART_HOME_HTTP_ENDPOINT
name = 'api:alexa:smart_home'
def __init__(self, smart_home_config):
"""Initialize."""
self.smart_home_config = smart_home_config
async def post(self, request):
"""Handle Alexa Smart Home requests.
The Smart Home API requires the endpoint to be implemented in AWS
Lambda, which will need to forward the requests to here and pass back
the response.
"""
hass = request.app['hass']
user = request['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,
context=core.Context(user_id=user.id)
)
_LOGGER.debug("Sending Alexa Smart Home response: %s", response)
return b'' if response is None else self.json(response)

View File

@@ -0,0 +1,185 @@
"""Alexa state report code."""
import asyncio
import json
import logging
import aiohttp
import async_timeout
from homeassistant.const import MATCH_ALL
from .const import API_CHANGE, Cause
from .entities import ENTITY_ADAPTERS
from .messages import AlexaResponse
_LOGGER = logging.getLogger(__name__)
DEFAULT_TIMEOUT = 10
async def async_enable_proactive_mode(hass, smart_home_config):
"""Enable the proactive mode.
Proactive mode makes this component report state changes to Alexa.
"""
# Validate we can get access token.
await smart_home_config.async_get_access_token()
async def async_entity_state_listener(changed_entity, old_state,
new_state):
if not new_state:
return
if new_state.domain not in ENTITY_ADAPTERS:
return
if not smart_home_config.should_expose(changed_entity):
_LOGGER.debug("Not exposing %s because filtered by config",
changed_entity)
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
return hass.helpers.event.async_track_state_change(
MATCH_ALL, async_entity_state_listener
)
async def async_send_changereport_message(hass, config, alexa_entity):
"""Send a ChangeReport message for an Alexa entity.
https://developer.amazon.com/docs/smarthome/state-reporting-for-a-smart-home-skill.html#report-state-with-changereport-events
"""
token = await config.async_get_access_token()
headers = {
"Authorization": "Bearer {}".format(token)
}
endpoint = alexa_entity.alexa_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()
session = hass.helpers.aiohttp_client.async_get_clientsession()
try:
with async_timeout.timeout(DEFAULT_TIMEOUT):
response = await session.post(config.endpoint,
headers=headers,
json=message_serialized,
allow_redirects=True)
except (asyncio.TimeoutError, aiohttp.ClientError):
_LOGGER.error("Timeout sending report to Alexa.")
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"])
async def async_send_add_or_update_message(hass, config, entity_ids):
"""Send an AddOrUpdateReport message for entities.
https://developer.amazon.com/docs/device-apis/alexa-discovery.html#add-or-update-report
"""
token = await config.async_get_access_token()
headers = {
"Authorization": "Bearer {}".format(token)
}
endpoints = []
for entity_id in entity_ids:
domain = entity_id.split('.', 1)[0]
alexa_entity = ENTITY_ADAPTERS[domain](
hass, config, hass.states.get(entity_id)
)
endpoints.append(alexa_entity.serialize_discovery())
payload = {
'endpoints': endpoints,
'scope': {
'type': 'BearerToken',
'token': token,
}
}
message = AlexaResponse(
name='AddOrUpdateReport', namespace='Alexa.Discovery', payload=payload)
message_serialized = message.serialize()
session = hass.helpers.aiohttp_client.async_get_clientsession()
return await session.post(config.endpoint, headers=headers,
json=message_serialized, allow_redirects=True)
async def async_send_delete_message(hass, config, entity_ids):
"""Send an DeleteReport message for entities.
https://developer.amazon.com/docs/device-apis/alexa-discovery.html#deletereport-event
"""
token = await config.async_get_access_token()
headers = {
"Authorization": "Bearer {}".format(token)
}
endpoints = []
for entity_id in entity_ids:
domain = entity_id.split('.', 1)[0]
alexa_entity = ENTITY_ADAPTERS[domain](
hass, config, hass.states.get(entity_id)
)
endpoints.append({
'endpointId': alexa_entity.alexa_id()
})
payload = {
'endpoints': endpoints,
'scope': {
'type': 'BearerToken',
'token': token,
}
}
message = AlexaResponse(name='DeleteReport', namespace='Alexa.Discovery',
payload=payload)
message_serialized = message.serialize()
session = hass.helpers.aiohttp_client.async_get_clientsession()
return await session.post(config.endpoint, headers=headers,
json=message_serialized, allow_redirects=True)

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "S'ha produ\u00eft un error desconegut al generat un testimoni d'acc\u00e9s.",
"already_setup": "El compte d\u2019Ambi Climate est\u00e0 configurat.",
"no_config": "Necessites configurar Ambi Climate abans de poder autenticar-t'hi. Llegeix les [instruccions](https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Autenticaci\u00f3 exitosa amb Ambi Climate."
},
"error": {
"follow_link": "V\u00e9s a l'enlla\u00e7 i autentica't abans de pr\u00e9mer Envia",
"no_token": "No autenticat amb Ambi Climate"
},
"step": {
"auth": {
"description": "V\u00e9s a l'[enlla\u00e7]({authorization_url}) i <b>Permet</b> l'acc\u00e9s al teu compte de Ambi Climate, despr\u00e9s torna i prem <b>Envia</b> (a sota).\n(Assegura't que l'enlla\u00e7 de retorn \u00e9s el seg\u00fcent {cb_url})",
"title": "Autenticaci\u00f3 amb Ambi Climate"
}
},
"title": "Ambi Climate"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"error": {
"follow_link": "N\u00e1sledujte odkaz a prove\u010fte ov\u011b\u0159en\u00ed p\u0159ed stisknut\u00edm tla\u010d\u00edtka Odeslat.",
"no_token": "Nen\u00ed ov\u011b\u0159en s Ambiclimate"
},
"step": {
"auth": {
"description": "N\u00e1sledujte tento [odkaz]({authorization_url}) a <b> Povolit </b> p\u0159\u00edstup k va\u0161emu \u00fa\u010dtu Ambiclimate, pot\u00e9 se vra\u0165te a stiskn\u011bte <b> Odeslat </b> n\u00ed\u017ee. \n (Ujist\u011bte se, \u017ee zadan\u00e1 adresa URL zp\u011btn\u00e9ho vol\u00e1n\u00ed je {cb_url} )",
"title": "Ov\u011b\u0159it Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Unbekannter Fehler beim Generieren eines Zugriffstokens.",
"already_setup": "Das Ambiclimate Konto ist konfiguriert.",
"no_config": "Ambiclimate muss konfiguriert sein, bevor die Authentifizierund durchgef\u00fchrt werden kann. [Bitte lies die Anleitung] (https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Erfolgreiche Authentifizierung mit Ambiclimate"
},
"error": {
"follow_link": "Bitte folge dem Link und authentifizieren dich, bevor du auf Senden klickst",
"no_token": "Nicht authentifiziert mit Ambiclimate"
},
"step": {
"auth": {
"description": "Bitte folge diesem [link] ({authorization_url}) und <b> Erlaube </b> Zugriff auf dein Ambiclimate-Konto, komme dann zur\u00fcck und dr\u00fccke <b> Senden </b> darunter.\n (Pr\u00fcfe, dass die Callback-URL {cb_url} ist.)",
"title": "Ambiclimate authentifizieren"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Unknown error generating an access token.",
"already_setup": "The Ambiclimate account is configured.",
"no_config": "You need to configure Ambiclimate before being able to authenticate with it. [Please read the instructions](https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Successfully authenticated with Ambiclimate"
},
"error": {
"follow_link": "Please follow the link and authenticate before pressing Submit",
"no_token": "Not authenticated with Ambiclimate"
},
"step": {
"auth": {
"description": "Please follow this [link]({authorization_url}) and <b>Allow</b> access to your Ambiclimate account, then come back and press <b>Submit</b> below.\n(Make sure the specified callback url is {cb_url})",
"title": "Authenticate Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,12 @@
{
"config": {
"abort": {
"access_token": "Error desconocido al generar un token de acceso.",
"already_setup": "La cuenta de Ambiclimate est\u00e1 configurada.",
"no_config": "Es necesario configurar Ambiclimate antes de poder autenticarse con \u00e9l. Por favor, lea las instrucciones](https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Autenticaci\u00f3n exitosa con Ambiclimate"
}
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Error desconocido al generar un token de acceso.",
"already_setup": "La cuenta de Ambiclimate est\u00e1 configurada.",
"no_config": "Es necesario configurar Ambiclimate antes de poder autenticarse con \u00e9l. [Por favor, lee las instrucciones](https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Autenticado correctamente con Ambiclimate"
},
"error": {
"follow_link": "Accede al enlace e identif\u00edcate antes de pulsar Enviar.",
"no_token": "No autenticado con Ambiclimate"
},
"step": {
"auth": {
"description": "Accede al siguiente [enlace]({authorization_url}) y <b>permite</b> el acceso a tu cuenta de Ambiclimate, despu\u00e9s vuelve y pulsa en <b>enviar</b> a continuaci\u00f3n.\n(Aseg\u00farate que la url de devoluci\u00f3n de llamada es {cb_url})",
"title": "Autenticaci\u00f3n de Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Erreur inconnue lors de la g\u00e9n\u00e9ration d'un jeton d'acc\u00e8s.",
"already_setup": "Le compte Ambiclimate est configur\u00e9.",
"no_config": "Vous devez configurer Ambiclimate avant de pouvoir vous authentifier aupr\u00e8s de celui-ci. [Veuillez lire les instructions] (https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Authentifi\u00e9 avec succ\u00e8s avec Ambiclimate"
},
"error": {
"follow_link": "Veuillez suivre le lien et vous authentifier avant d'appuyer sur Soumettre.",
"no_token": "Non authentifi\u00e9 avec Ambiclimate"
},
"step": {
"auth": {
"description": "Suivez ce [lien] ( {authorization_url} ) et <b> Autorisez </b> l'acc\u00e8s \u00e0 votre compte Ambiclimate, puis revenez et appuyez sur <b> Envoyer </b> ci-dessous. \n (Assurez-vous que l'URL de rappel sp\u00e9cifi\u00e9 est {cb_url} )",
"title": "Authentifier Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,8 @@
{
"config": {
"abort": {
"already_setup": "L'account Ambiclimate \u00e8 configurato."
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "\uc561\uc138\uc2a4 \ud1a0\ud070 \uc0dd\uc131\uc5d0 \uc54c \uc218 \uc5c6\ub294 \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4.",
"already_setup": "Ambi Climate \uacc4\uc815\uc774 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4.",
"no_config": "Ambi Climate \ub97c \uc778\uc99d\ud558\ub824\uba74 \uba3c\uc800 Ambi Climate \ub97c \uad6c\uc131\ud574\uc57c \ud569\ub2c8\ub2e4. [\uc548\ub0b4](https://www.home-assistant.io/components/ambiclimate/) \ub97c \uc77d\uc5b4\ubcf4\uc138\uc694."
},
"create_entry": {
"default": "Ambi Climate \ub85c \uc131\uacf5\uc801\uc73c\ub85c \uc778\uc99d\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
},
"error": {
"follow_link": "Submit \ubc84\ud2bc\uc744 \ub204\ub974\uae30 \uc804\uc5d0 \ub9c1\ud06c\ub97c \ub530\ub77c \uc778\uc99d\uc744 \ubc1b\uc544\uc8fc\uc138\uc694",
"no_token": "Ambi Climate \ub85c \uc778\uc99d\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4"
},
"step": {
"auth": {
"description": "[\ub9c1\ud06c]({authorization_url}) \ub97c \ud074\ub9ad\ud558\uc5ec Ambi Climate \uacc4\uc815\uc5d0 \ub300\ud574 <b>\ud5c8\uc6a9</b> \ud55c \ub2e4\uc74c, \ub2e4\uc2dc \ub3cc\uc544\uc640\uc11c \ud558\ub2e8\uc758 <b>Submit</b> \ubc84\ud2bc\uc744 \ub20c\ub7ec\uc8fc\uc138\uc694. \n(\ucf5c\ubc31 url \uc744 {cb_url} \ub85c \uad6c\uc131\ud588\ub294\uc9c0 \ud655\uc778\ud574\uc8fc\uc138\uc694)",
"title": "Ambi Climate \uc778\uc99d"
}
},
"title": "Ambi Climate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Onbekannte Feeler beim gener\u00e9ieren vum Acc\u00e8s Jeton.",
"already_setup": "Den Ambiclimate Kont ass konfigur\u00e9iert.",
"no_config": "Dir musst Ambiclimate konfigur\u00e9ieren, ier Dir d\u00ebs Authentifiz\u00e9ierung k\u00ebnnt benotzen.[Liest w.e.g. d'Instruktioune](https://www.home-assistant.io/components/ambiclimatet/)."
},
"create_entry": {
"default": "Erfollegr\u00e4ich mat Ambiclimate authentifiz\u00e9iert."
},
"error": {
"follow_link": "Follegt w.e.g. dem Link an authentifiz\u00e9iert de Kont ier dir op ofsch\u00e9cken dr\u00e9ckt.",
"no_token": "Net mat Ambiclimate authentifiz\u00e9iert"
},
"step": {
"auth": {
"description": "Follegt d\u00ebsem [Link]({authorization_url}) an <b>erlaabtt</b> den Acc\u00e8s zu \u00e4rem Ambiclimate Kont , a kommt dann zer\u00e9ck heihin an dr\u00e9ck op <b>ofsch\u00e9cken</b> hei \u00ebnnen.\n(Stellt s\u00e9cher dass den Type vun Callback {cb_url} ass.)",
"title": "Ambiclimate authentifiz\u00e9ieren"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Onbekende fout bij het genereren van een toegangstoken.",
"already_setup": "Het Ambiclimate-account is geconfigureerd.",
"no_config": "U moet Ambiclimate configureren voordat u zich ermee kunt authenticeren. (Lees de instructies) (https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Succesvol geverifieerd met Ambiclimate"
},
"error": {
"follow_link": "Gelieve de link te volgen en te verifi\u00ebren voordat u op Verzenden drukt.",
"no_token": "Niet geverifieerd met Ambiclimate"
},
"step": {
"auth": {
"description": "Volg deze [link] ( {authorization_url} ) en <b> Toestaan </b> toegang tot uw Ambiclimate-account, kom dan terug en druk hieronder op <b> Verzenden </b> . \n (Zorg ervoor dat de opgegeven callback-URL {cb_url} )",
"title": "Authenticatie Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Ukjent feil ved oppretting av tilgangstoken.",
"already_setup": "Ambiclimate-kontoen er konfigurert.",
"no_config": "Du m\u00e5 konfigurere Ambiclimate f\u00f8r du kan autentisere med den. [Vennligst les instruksjonene](https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Vellykket autentisering med Ambiclimate"
},
"error": {
"follow_link": "Vennligst f\u00f8lg lenken og godkjen f\u00f8r du trykker p\u00e5 Send",
"no_token": "Ikke autentisert med Ambiclimate"
},
"step": {
"auth": {
"description": "Vennligst f\u00f8lg denne [linken]({authorization_url}) og <b>Tillat</b> tilgang til din Ambiclimate konto, og kom s\u00e5 tilbake og trykk <b>Send</b> nedenfor.\n(Kontroller at den angitte URL-adressen for tilbakeringing er {cb_url})",
"title": "Autensiere Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Nieznany b\u0142\u0105d podczas generowania tokena dost\u0119pu.",
"already_setup": "Konto Ambiclimate jest skonfigurowane.",
"no_config": "Musisz skonfigurowa\u0107 Ambiclimate, zanim b\u0119dziesz m\u00f3g\u0142 si\u0119 z nim uwierzytelni\u0107. [Przeczytaj instrukcj\u0119](https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Pomy\u015blnie uwierzytelniono z Ambiclimate"
},
"error": {
"follow_link": "Prosz\u0119 klikn\u0105\u0107 link i uwierzytelni\u0107 przed naci\u015bni\u0119ciem przycisku Prze\u015blij",
"no_token": "Nie uwierzytelniony z Ambiclimate"
},
"step": {
"auth": {
"description": "Kliknij poni\u017cszy [link]({authorization_url}) i <b>Zezw\u00f3l</b> na dost\u0119p do swojego konta Ambiclimate, a nast\u0119pnie wr\u00f3\u0107 i naci\u015bnij <b>Prze\u015blij</b> poni\u017cej. \n(Upewnij si\u0119, \u017ce podany adres URL to {cb_url})",
"title": "Uwierzytelnienie Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Erro desconhecido ao gerar um token de acesso.",
"already_setup": "A conta Ambiclimate est\u00e1 configurada.",
"no_config": "Voc\u00ea precisa configurar o Ambiclimate antes de poder autenticar com ele. [Por favor, leia as instru\u00e7\u00f5es] (https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Autenticado com sucesso no Ambiclimate"
},
"error": {
"follow_link": "Por favor, siga o link e autentique-se antes de pressionar Enviar",
"no_token": "N\u00e3o autenticado com o Ambiclimate"
},
"step": {
"auth": {
"description": "Por favor, siga este [link]({authorization_url}) e <b>Permitir</b> acesso \u00e0 sua conta Ambiclimate, em seguida, volte e pressione <b>Enviar</b> abaixo. \n (Verifique se a URL de retorno de chamada especificada \u00e9 {cb_url})",
"title": "Autenticar Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0442\u043e\u043a\u0435\u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430.",
"already_setup": "\u0423\u0447\u0435\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c Ambi Climate \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0430.",
"no_config": "\u0412\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Ambi Climate \u043f\u0435\u0440\u0435\u0434 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. [\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u044c\u0442\u0435\u0441\u044c \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438](https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e."
},
"error": {
"follow_link": "\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0438 \u043f\u0440\u043e\u0439\u0434\u0438\u0442\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u044c \"\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c\".",
"no_token": "\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0435 \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u0430."
},
"step": {
"auth": {
"description": "\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043f\u043e [\u0441\u0441\u044b\u043b\u043a\u0435]({authorization_url}) \u0438 <b>\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u0435</b> \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0412\u0430\u0448\u0435\u0439 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Ambi Climate, \u0437\u0430\u0442\u0435\u043c \u0432\u0435\u0440\u043d\u0438\u0442\u0435\u0441\u044c \u0441\u044e\u0434\u0430 \u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 <b>\u041f\u041e\u0414\u0422\u0412\u0415\u0420\u0414\u0418\u0422\u042c</b>. \n(\u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 URL \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 {cb_url})",
"title": "Ambi Climate"
}
},
"title": "Ambi Climate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Neznana napaka pri ustvarjanju \u017eetona za dostop.",
"already_setup": "Ra\u010dun Ambiclimate je konfiguriran.",
"no_config": "Ambiclimat morate konfigurirati, preden lahko z njo preverjate pristnost. [Preberite navodila] (https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Uspe\u0161no overjeno z funkcijo Ambiclimate"
},
"error": {
"follow_link": "Preden pritisnete Po\u0161lji, sledite povezavi in preverite pristnost",
"no_token": "Ni overjeno z Ambiclimate"
},
"step": {
"auth": {
"description": "Sledite temu povezavi ( {authorization_url} in <b> Dovoli </b> dostopu do svojega ra\u010duna Ambiclimate, nato se vrnite in pritisnite <b> Po\u0161lji </b> spodaj. \n (Poskrbite, da je dolo\u010den url za povratni klic {cb_url} )",
"title": "Overi Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "Ok\u00e4nt fel vid generering av \u00e5tkomsttoken.",
"already_setup": "Ambiclientkontot \u00e4r konfigurerat",
"no_config": "Du m\u00e5ste konfigurera Ambiclimate innan du kan autentisera med den. [V\u00e4nligen l\u00e4s instruktionerna] (https://www.home-assistant.io/components/ambiclimate/)."
},
"create_entry": {
"default": "Lyckad autentisering med Ambiclimate"
},
"error": {
"follow_link": "V\u00e4nligen f\u00f6lj l\u00e4nken och autentisera dig innan du trycker p\u00e5 Skicka",
"no_token": "Inte autentiserad med Ambiclimate"
},
"step": {
"auth": {
"description": "V\u00e4nligen f\u00f6lj denna [l\u00e4nk] ({authorization_url}) och <b> till\u00e5ta </b> till g\u00e5ng till ditt Ambiclimate konto, kom sedan tillbaka och tryck p\u00e5 <b> Skicka </b> nedan.\n(Kontrollera att den angivna callback url \u00e4r {cb_url})",
"title": "Autentisera Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"abort": {
"access_token": "\u7522\u751f\u5b58\u53d6\u8a8d\u8b49\u78bc\u672a\u77e5\u932f\u8aa4\u3002",
"already_setup": "Ambiclimate \u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210",
"no_config": "\u5fc5\u9808\u5148\u8a2d\u5b9a Ambiclimate \u65b9\u80fd\u9032\u884c\u8a8d\u8b49\u3002[\u8acb\u53c3\u95b1\u6559\u5b78\u6307\u5f15]\uff08https://www.home-assistant.io/components/ambiclimate/\uff09\u3002"
},
"create_entry": {
"default": "\u5df2\u6210\u529f\u8a8d\u8b49 Ambiclimate \u88dd\u7f6e\u3002"
},
"error": {
"follow_link": "\u8acb\u65bc\u50b3\u9001\u524d\uff0c\u5148\u4f7f\u7528\u9023\u7d50\u4e26\u9032\u884c\u8a8d\u8b49\u3002",
"no_token": "Ambiclimate \u672a\u6388\u6b0a"
},
"step": {
"auth": {
"description": "\u8acb\u4f7f\u7528\u6b64[\u9023\u7d50]\uff08{authorization_url}\uff09\u4e26\u9ede\u9078<b>\u5141\u8a31</b>\u4ee5\u5b58\u53d6 Ambiclimate \u5e33\u865f\uff0c\u7136\u5f8c\u8fd4\u56de\u6b64\u9801\u9762\u4e26\u9ede\u9078\u4e0b\u65b9\u7684<b>\u50b3\u9001</b>\u3002\n\uff08\u78ba\u5b9a Callback url \u70ba {cb_url}\uff09",
"title": "\u8a8d\u8b49 Ambiclimate"
}
},
"title": "Ambiclimate"
}
}

View File

@@ -0,0 +1,44 @@
"""Support for Ambiclimate devices."""
import logging
import voluptuous as vol
from homeassistant.helpers import config_validation as cv
from . import config_flow
from .const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, DOMAIN
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN:
vol.Schema({
vol.Required(CONF_CLIENT_ID): cv.string,
vol.Required(CONF_CLIENT_SECRET): cv.string,
})
},
extra=vol.ALLOW_EXTRA,
)
async def async_setup(hass, config):
"""Set up Ambiclimate components."""
if DOMAIN not in config:
return True
conf = config[DOMAIN]
config_flow.register_flow_implementation(
hass, conf[CONF_CLIENT_ID],
conf[CONF_CLIENT_SECRET])
return True
async def async_setup_entry(hass, entry):
"""Set up Ambiclimate from a config entry."""
hass.async_create_task(hass.config_entries.async_forward_entry_setup(
entry, 'climate'))
return True

View File

@@ -0,0 +1,230 @@
"""Support for Ambiclimate ac."""
import asyncio
import logging
import ambiclimate
import voluptuous as vol
from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import (
SUPPORT_TARGET_TEMPERATURE, HVAC_MODE_OFF, HVAC_MODE_HEAT)
from homeassistant.const import ATTR_NAME, ATTR_TEMPERATURE, TEMP_CELSIUS
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import (ATTR_VALUE, CONF_CLIENT_ID, CONF_CLIENT_SECRET,
DOMAIN, SERVICE_COMFORT_FEEDBACK, SERVICE_COMFORT_MODE,
SERVICE_TEMPERATURE_MODE, STORAGE_KEY, STORAGE_VERSION)
_LOGGER = logging.getLogger(__name__)
SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE
SEND_COMFORT_FEEDBACK_SCHEMA = vol.Schema({
vol.Required(ATTR_NAME): cv.string,
vol.Required(ATTR_VALUE): cv.string,
})
SET_COMFORT_MODE_SCHEMA = vol.Schema({
vol.Required(ATTR_NAME): cv.string,
})
SET_TEMPERATURE_MODE_SCHEMA = vol.Schema({
vol.Required(ATTR_NAME): cv.string,
vol.Required(ATTR_VALUE): cv.string,
})
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the Ambicliamte device."""
async def async_setup_entry(hass, entry, async_add_entities):
"""Set up the Ambicliamte device from config entry."""
config = entry.data
websession = async_get_clientsession(hass)
store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY)
token_info = await store.async_load()
oauth = ambiclimate.AmbiclimateOAuth(config[CONF_CLIENT_ID],
config[CONF_CLIENT_SECRET],
config['callback_url'],
websession)
try:
token_info = await oauth.refresh_access_token(token_info)
except ambiclimate.AmbiclimateOauthError:
token_info = None
if not token_info:
_LOGGER.error("Failed to refresh access token")
return
await store.async_save(token_info)
data_connection = ambiclimate.AmbiclimateConnection(oauth,
token_info=token_info,
websession=websession)
if not await data_connection.find_devices():
_LOGGER.error("No devices found")
return
tasks = []
for heater in data_connection.get_devices():
tasks.append(heater.update_device_info())
await asyncio.wait(tasks)
devs = []
for heater in data_connection.get_devices():
devs.append(AmbiclimateEntity(heater, store))
async_add_entities(devs, True)
async def send_comfort_feedback(service):
"""Send comfort feedback."""
device_name = service.data[ATTR_NAME]
device = data_connection.find_device_by_room_name(device_name)
if device:
await device.set_comfort_feedback(service.data[ATTR_VALUE])
hass.services.async_register(DOMAIN,
SERVICE_COMFORT_FEEDBACK,
send_comfort_feedback,
schema=SEND_COMFORT_FEEDBACK_SCHEMA)
async def set_comfort_mode(service):
"""Set comfort mode."""
device_name = service.data[ATTR_NAME]
device = data_connection.find_device_by_room_name(device_name)
if device:
await device.set_comfort_mode()
hass.services.async_register(DOMAIN,
SERVICE_COMFORT_MODE,
set_comfort_mode,
schema=SET_COMFORT_MODE_SCHEMA)
async def set_temperature_mode(service):
"""Set temperature mode."""
device_name = service.data[ATTR_NAME]
device = data_connection.find_device_by_room_name(device_name)
if device:
await device.set_temperature_mode(service.data[ATTR_VALUE])
hass.services.async_register(DOMAIN,
SERVICE_TEMPERATURE_MODE,
set_temperature_mode,
schema=SET_TEMPERATURE_MODE_SCHEMA)
class AmbiclimateEntity(ClimateDevice):
"""Representation of a Ambiclimate Thermostat device."""
def __init__(self, heater, store):
"""Initialize the thermostat."""
self._heater = heater
self._store = store
self._data = {}
@property
def unique_id(self):
"""Return a unique ID."""
return self._heater.device_id
@property
def name(self):
"""Return the name of the entity."""
return self._heater.name
@property
def device_info(self):
"""Return the device info."""
return {
'identifiers': {
(DOMAIN, self.unique_id)
},
'name': self.name,
'manufacturer': 'Ambiclimate',
}
@property
def temperature_unit(self):
"""Return the unit of measurement which this thermostat uses."""
return TEMP_CELSIUS
@property
def target_temperature(self):
"""Return the target temperature."""
return self._data.get('target_temperature')
@property
def target_temperature_step(self):
"""Return the supported step of target temperature."""
return 1
@property
def current_temperature(self):
"""Return the current temperature."""
return self._data.get('temperature')
@property
def current_humidity(self):
"""Return the current humidity."""
return self._data.get('humidity')
@property
def min_temp(self):
"""Return the minimum temperature."""
return self._heater.get_min_temp()
@property
def max_temp(self):
"""Return the maximum temperature."""
return self._heater.get_max_temp()
@property
def supported_features(self):
"""Return the list of supported features."""
return SUPPORT_FLAGS
@property
def hvac_modes(self):
"""Return the list of available hvac operation modes."""
return [HVAC_MODE_HEAT, HVAC_MODE_OFF]
@property
def hvac_mode(self):
"""Return current operation."""
if self._data.get('power', '').lower() == 'on':
return HVAC_MODE_HEAT
return HVAC_MODE_OFF
async def async_set_temperature(self, **kwargs):
"""Set new target temperature."""
temperature = kwargs.get(ATTR_TEMPERATURE)
if temperature is None:
return
await self._heater.set_target_temperature(temperature)
async def async_set_hvac_mode(self, hvac_mode):
"""Set new target hvac mode."""
if hvac_mode == HVAC_MODE_HEAT:
await self._heater.turn_on()
return
if hvac_mode == HVAC_MODE_OFF:
await self._heater.turn_off()
async def async_update(self):
"""Retrieve latest state."""
try:
token_info = await self._heater.control.refresh_access_token()
except ambiclimate.AmbiclimateOauthError:
_LOGGER.error("Failed to refresh access token")
return
if token_info:
await self._store.async_save(token_info)
self._data = await self._heater.update_device()

View File

@@ -0,0 +1,153 @@
"""Config flow for Ambiclimate."""
import logging
import ambiclimate
from homeassistant import config_entries
from homeassistant.components.http import HomeAssistantView
from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import (AUTH_CALLBACK_NAME, AUTH_CALLBACK_PATH, CONF_CLIENT_ID,
CONF_CLIENT_SECRET, DOMAIN, STORAGE_VERSION, STORAGE_KEY)
DATA_AMBICLIMATE_IMPL = 'ambiclimate_flow_implementation'
_LOGGER = logging.getLogger(__name__)
@callback
def register_flow_implementation(hass, client_id, client_secret):
"""Register a ambiclimate implementation.
client_id: Client id.
client_secret: Client secret.
"""
hass.data.setdefault(DATA_AMBICLIMATE_IMPL, {})
hass.data[DATA_AMBICLIMATE_IMPL] = {
CONF_CLIENT_ID: client_id,
CONF_CLIENT_SECRET: client_secret,
}
@config_entries.HANDLERS.register('ambiclimate')
class AmbiclimateFlowHandler(config_entries.ConfigFlow):
"""Handle a config flow."""
VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
def __init__(self):
"""Initialize flow."""
self._registered_view = False
self._oauth = None
async def async_step_user(self, user_input=None):
"""Handle external yaml configuration."""
if self.hass.config_entries.async_entries(DOMAIN):
return self.async_abort(reason='already_setup')
config = self.hass.data.get(DATA_AMBICLIMATE_IMPL, {})
if not config:
_LOGGER.debug("No config")
return self.async_abort(reason='no_config')
return await self.async_step_auth()
async def async_step_auth(self, user_input=None):
"""Handle a flow start."""
if self.hass.config_entries.async_entries(DOMAIN):
return self.async_abort(reason='already_setup')
errors = {}
if user_input is not None:
errors['base'] = 'follow_link'
if not self._registered_view:
self._generate_view()
return self.async_show_form(
step_id='auth',
description_placeholders={'authorization_url':
await self._get_authorize_url(),
'cb_url': self._cb_url()},
errors=errors,
)
async def async_step_code(self, code=None):
"""Received code for authentication."""
if self.hass.config_entries.async_entries(DOMAIN):
return self.async_abort(reason='already_setup')
token_info = await self._get_token_info(code)
if token_info is None:
return self.async_abort(reason='access_token')
config = self.hass.data[DATA_AMBICLIMATE_IMPL].copy()
config['callback_url'] = self._cb_url()
return self.async_create_entry(
title="Ambiclimate",
data=config,
)
async def _get_token_info(self, code):
oauth = self._generate_oauth()
try:
token_info = await oauth.get_access_token(code)
except ambiclimate.AmbiclimateOauthError:
_LOGGER.error("Failed to get access token", exc_info=True)
return None
store = self.hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY)
await store.async_save(token_info)
return token_info
def _generate_view(self):
self.hass.http.register_view(AmbiclimateAuthCallbackView())
self._registered_view = True
def _generate_oauth(self):
config = self.hass.data[DATA_AMBICLIMATE_IMPL]
clientsession = async_get_clientsession(self.hass)
callback_url = self._cb_url()
oauth = ambiclimate.AmbiclimateOAuth(config.get(CONF_CLIENT_ID),
config.get(CONF_CLIENT_SECRET),
callback_url,
clientsession)
return oauth
def _cb_url(self):
return '{}{}'.format(self.hass.config.api.base_url,
AUTH_CALLBACK_PATH)
async def _get_authorize_url(self):
oauth = self._generate_oauth()
return oauth.get_authorize_url()
class AmbiclimateAuthCallbackView(HomeAssistantView):
"""Ambiclimate Authorization Callback View."""
requires_auth = False
url = AUTH_CALLBACK_PATH
name = AUTH_CALLBACK_NAME
async def get(self, request):
"""Receive authorization token."""
code = request.query.get('code')
if code is None:
return "No code"
hass = request.app['hass']
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={'source': 'code'},
data=code,
))
return "OK!"

View File

@@ -0,0 +1,14 @@
"""Constants used by the Ambiclimate component."""
ATTR_VALUE = 'value'
CONF_CLIENT_ID = 'client_id'
CONF_CLIENT_SECRET = 'client_secret'
DOMAIN = 'ambiclimate'
SERVICE_COMFORT_FEEDBACK = 'send_comfort_feedback'
SERVICE_COMFORT_MODE = 'set_comfort_mode'
SERVICE_TEMPERATURE_MODE = 'set_temperature_mode'
STORAGE_KEY = 'ambiclimate_auth'
STORAGE_VERSION = 1
AUTH_CALLBACK_NAME = 'api:ambiclimate'
AUTH_CALLBACK_PATH = '/api/ambiclimate'

View File

@@ -0,0 +1,13 @@
{
"domain": "ambiclimate",
"name": "Ambiclimate",
"config_flow": true,
"documentation": "https://www.home-assistant.io/components/ambiclimate",
"requirements": [
"ambiclimate==0.2.0"
],
"dependencies": [],
"codeowners": [
"@danielhiversen"
]
}

View File

@@ -0,0 +1,36 @@
# Describes the format for available services for ambiclimate
set_comfort_mode:
description: >
Enable comfort mode on your AC
fields:
Name:
description: >
String with device name.
example: Bedroom
send_comfort_feedback:
description: >
Send feedback for comfort mode
fields:
Name:
description: >
String with device name.
example: Bedroom
Value:
description: >
Send any of the following comfort values: too_hot, too_warm, bit_warm, comfortable, bit_cold, too_cold, freezing
example: bit_warm
set_temperature_mode:
description: >
Enable temperature mode on your AC
fields:
Name:
description: >
String with device name.
example: Bedroom
Value:
description: >
Target value in celsius
example: 22

View File

@@ -0,0 +1,23 @@
{
"config": {
"title": "Ambiclimate",
"step": {
"auth": {
"title": "Authenticate Ambiclimate",
"description": "Please follow this [link]({authorization_url}) and <b>Allow</b> access to your Ambiclimate account, then come back and press <b>Submit</b> below.\n(Make sure the specified callback url is {cb_url})"
}
},
"create_entry": {
"default": "Successfully authenticated with Ambiclimate"
},
"error": {
"no_token": "Not authenticated with Ambiclimate",
"follow_link": "Please follow the link and authenticate before pressing Submit"
},
"abort": {
"already_setup": "The Ambiclimate account is configured.",
"no_config": "You need to configure Ambiclimate before being able to authenticate with it. [Please read the instructions](https://www.home-assistant.io/components/ambiclimate/).",
"access_token": "Unknown error generating an access token."
}
}
}

View File

@@ -119,8 +119,8 @@ TYPE_WINDSPEEDMPH = 'windspeedmph'
TYPE_YEARLYRAININ = 'yearlyrainin'
SENSOR_TYPES = {
TYPE_24HOURRAININ: ('24 Hr Rain', 'in', TYPE_SENSOR, None),
TYPE_BAROMABSIN: ('Abs Pressure', 'inHg', TYPE_SENSOR, None),
TYPE_BAROMRELIN: ('Rel Pressure', 'inHg', TYPE_SENSOR, None),
TYPE_BAROMABSIN: ('Abs Pressure', 'inHg', TYPE_SENSOR, 'pressure'),
TYPE_BAROMRELIN: ('Rel Pressure', 'inHg', TYPE_SENSOR, 'pressure'),
TYPE_BATT10: ('Battery 10', None, TYPE_BINARY_SENSOR, 'battery'),
TYPE_BATT1: ('Battery 1', None, TYPE_BINARY_SENSOR, 'battery'),
TYPE_BATT2: ('Battery 2', None, TYPE_BINARY_SENSOR, 'battery'),
@@ -134,23 +134,23 @@ SENSOR_TYPES = {
TYPE_BATTOUT: ('Battery', None, TYPE_BINARY_SENSOR, 'battery'),
TYPE_CO2: ('co2', 'ppm', TYPE_SENSOR, None),
TYPE_DAILYRAININ: ('Daily Rain', 'in', TYPE_SENSOR, None),
TYPE_DEWPOINT: ('Dew Point', '°F', TYPE_SENSOR, None),
TYPE_DEWPOINT: ('Dew Point', '°F', TYPE_SENSOR, 'temperature'),
TYPE_EVENTRAININ: ('Event Rain', 'in', TYPE_SENSOR, None),
TYPE_FEELSLIKE: ('Feels Like', '°F', TYPE_SENSOR, None),
TYPE_FEELSLIKE: ('Feels Like', '°F', TYPE_SENSOR, 'temperature'),
TYPE_HOURLYRAININ: ('Hourly Rain Rate', 'in/hr', TYPE_SENSOR, None),
TYPE_HUMIDITY10: ('Humidity 10', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY1: ('Humidity 1', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY2: ('Humidity 2', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY3: ('Humidity 3', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY4: ('Humidity 4', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY5: ('Humidity 5', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY6: ('Humidity 6', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY7: ('Humidity 7', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY8: ('Humidity 8', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY9: ('Humidity 9', '%', TYPE_SENSOR, None),
TYPE_HUMIDITY: ('Humidity', '%', TYPE_SENSOR, None),
TYPE_HUMIDITYIN: ('Humidity In', '%', TYPE_SENSOR, None),
TYPE_LASTRAIN: ('Last Rain', None, TYPE_SENSOR, None),
TYPE_HUMIDITY10: ('Humidity 10', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY1: ('Humidity 1', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY2: ('Humidity 2', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY3: ('Humidity 3', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY4: ('Humidity 4', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY5: ('Humidity 5', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY6: ('Humidity 6', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY7: ('Humidity 7', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY8: ('Humidity 8', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY9: ('Humidity 9', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITY: ('Humidity', '%', TYPE_SENSOR, 'humidity'),
TYPE_HUMIDITYIN: ('Humidity In', '%', TYPE_SENSOR, 'humidity'),
TYPE_LASTRAIN: ('Last Rain', None, TYPE_SENSOR, 'timestamp'),
TYPE_MAXDAILYGUST: ('Max Gust', 'mph', TYPE_SENSOR, None),
TYPE_MONTHLYRAININ: ('Monthly Rain', 'in', TYPE_SENSOR, None),
TYPE_RELAY10: ('Relay 10', None, TYPE_BINARY_SENSOR, 'connectivity'),
@@ -163,39 +163,39 @@ SENSOR_TYPES = {
TYPE_RELAY7: ('Relay 7', None, TYPE_BINARY_SENSOR, 'connectivity'),
TYPE_RELAY8: ('Relay 8', None, TYPE_BINARY_SENSOR, 'connectivity'),
TYPE_RELAY9: ('Relay 9', None, TYPE_BINARY_SENSOR, 'connectivity'),
TYPE_SOILHUM10: ('Soil Humidity 10', '%', TYPE_SENSOR, None),
TYPE_SOILHUM1: ('Soil Humidity 1', '%', TYPE_SENSOR, None),
TYPE_SOILHUM2: ('Soil Humidity 2', '%', TYPE_SENSOR, None),
TYPE_SOILHUM3: ('Soil Humidity 3', '%', TYPE_SENSOR, None),
TYPE_SOILHUM4: ('Soil Humidity 4', '%', TYPE_SENSOR, None),
TYPE_SOILHUM5: ('Soil Humidity 5', '%', TYPE_SENSOR, None),
TYPE_SOILHUM6: ('Soil Humidity 6', '%', TYPE_SENSOR, None),
TYPE_SOILHUM7: ('Soil Humidity 7', '%', TYPE_SENSOR, None),
TYPE_SOILHUM8: ('Soil Humidity 8', '%', TYPE_SENSOR, None),
TYPE_SOILHUM9: ('Soil Humidity 9', '%', TYPE_SENSOR, None),
TYPE_SOILTEMP10F: ('Soil Temp 10', '°F', TYPE_SENSOR, None),
TYPE_SOILTEMP1F: ('Soil Temp 1', '°F', TYPE_SENSOR, None),
TYPE_SOILTEMP2F: ('Soil Temp 2', '°F', TYPE_SENSOR, None),
TYPE_SOILTEMP3F: ('Soil Temp 3', '°F', TYPE_SENSOR, None),
TYPE_SOILTEMP4F: ('Soil Temp 4', '°F', TYPE_SENSOR, None),
TYPE_SOILTEMP5F: ('Soil Temp 5', '°F', TYPE_SENSOR, None),
TYPE_SOILTEMP6F: ('Soil Temp 6', '°F', TYPE_SENSOR, None),
TYPE_SOILTEMP7F: ('Soil Temp 7', '°F', TYPE_SENSOR, None),
TYPE_SOILTEMP8F: ('Soil Temp 8', '°F', TYPE_SENSOR, None),
TYPE_SOILTEMP9F: ('Soil Temp 9', '°F', TYPE_SENSOR, None),
TYPE_SOLARRADIATION: ('Solar Rad', 'W/m^2', TYPE_SENSOR, None),
TYPE_TEMP10F: ('Temp 10', '°F', TYPE_SENSOR, None),
TYPE_TEMP1F: ('Temp 1', '°F', TYPE_SENSOR, None),
TYPE_TEMP2F: ('Temp 2', '°F', TYPE_SENSOR, None),
TYPE_TEMP3F: ('Temp 3', '°F', TYPE_SENSOR, None),
TYPE_TEMP4F: ('Temp 4', '°F', TYPE_SENSOR, None),
TYPE_TEMP5F: ('Temp 5', '°F', TYPE_SENSOR, None),
TYPE_TEMP6F: ('Temp 6', '°F', TYPE_SENSOR, None),
TYPE_TEMP7F: ('Temp 7', '°F', TYPE_SENSOR, None),
TYPE_TEMP8F: ('Temp 8', '°F', TYPE_SENSOR, None),
TYPE_TEMP9F: ('Temp 9', '°F', TYPE_SENSOR, None),
TYPE_TEMPF: ('Temp', '°F', TYPE_SENSOR, None),
TYPE_TEMPINF: ('Inside Temp', '°F', TYPE_SENSOR, None),
TYPE_SOILHUM10: ('Soil Humidity 10', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILHUM1: ('Soil Humidity 1', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILHUM2: ('Soil Humidity 2', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILHUM3: ('Soil Humidity 3', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILHUM4: ('Soil Humidity 4', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILHUM5: ('Soil Humidity 5', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILHUM6: ('Soil Humidity 6', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILHUM7: ('Soil Humidity 7', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILHUM8: ('Soil Humidity 8', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILHUM9: ('Soil Humidity 9', '%', TYPE_SENSOR, 'humidity'),
TYPE_SOILTEMP10F: ('Soil Temp 10', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOILTEMP1F: ('Soil Temp 1', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOILTEMP2F: ('Soil Temp 2', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOILTEMP3F: ('Soil Temp 3', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOILTEMP4F: ('Soil Temp 4', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOILTEMP5F: ('Soil Temp 5', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOILTEMP6F: ('Soil Temp 6', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOILTEMP7F: ('Soil Temp 7', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOILTEMP8F: ('Soil Temp 8', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOILTEMP9F: ('Soil Temp 9', '°F', TYPE_SENSOR, 'temperature'),
TYPE_SOLARRADIATION: ('Solar Rad', 'lx', TYPE_SENSOR, 'illuminance'),
TYPE_TEMP10F: ('Temp 10', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMP1F: ('Temp 1', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMP2F: ('Temp 2', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMP3F: ('Temp 3', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMP4F: ('Temp 4', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMP5F: ('Temp 5', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMP6F: ('Temp 6', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMP7F: ('Temp 7', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMP8F: ('Temp 8', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMP9F: ('Temp 9', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMPF: ('Temp', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TEMPINF: ('Inside Temp', '°F', TYPE_SENSOR, 'temperature'),
TYPE_TOTALRAININ: ('Lifetime Rain', 'in', TYPE_SENSOR, None),
TYPE_UV: ('uv', 'Index', TYPE_SENSOR, None),
TYPE_WEEKLYRAININ: ('Weekly Rain', 'in', TYPE_SENSOR, None),
@@ -327,7 +327,7 @@ class AmbientStation:
"""Define a handler to fire when the websocket is connected."""
_LOGGER.info('Connected to websocket')
_LOGGER.debug('Watchdog starting')
if self._watchdog_listener:
if self._watchdog_listener is not None:
self._watchdog_listener()
self._watchdog_listener = async_call_later(
self._hass, DEFAULT_WATCHDOG_SECONDS, _ws_reconnect)
@@ -404,9 +404,10 @@ class AmbientWeatherEntity(Entity):
def __init__(
self, ambient, mac_address, station_name, sensor_type,
sensor_name):
sensor_name, device_class):
"""Initialize the sensor."""
self._ambient = ambient
self._device_class = device_class
self._async_unsub_dispatcher_connect = None
self._mac_address = mac_address
self._sensor_name = sensor_name
@@ -420,6 +421,11 @@ class AmbientWeatherEntity(Entity):
return self._ambient.stations[self._mac_address][ATTR_LAST_DATA].get(
self._sensor_type) is not None
@property
def device_class(self):
"""Return the device class."""
return self._device_class
@property
def device_info(self):
"""Return device registry information for this entity."""

View File

@@ -39,20 +39,6 @@ async def async_setup_entry(hass, entry, async_add_entities):
class AmbientWeatherBinarySensor(AmbientWeatherEntity, BinarySensorDevice):
"""Define an Ambient binary sensor."""
def __init__(
self, ambient, mac_address, station_name, sensor_type, sensor_name,
device_class):
"""Initialize the sensor."""
super().__init__(
ambient, mac_address, station_name, sensor_type, sensor_name)
self._device_class = device_class
@property
def device_class(self):
"""Return the device class."""
return self._device_class
@property
def is_on(self):
"""Return the status of the sensor."""

View File

@@ -1,9 +1,10 @@
{
"domain": "ambient_station",
"name": "Ambient station",
"config_flow": true,
"documentation": "https://www.home-assistant.io/components/ambient_station",
"requirements": [
"aioambient==0.3.0"
"aioambient==0.3.1"
],
"dependencies": [],
"codeowners": [

View File

@@ -3,7 +3,7 @@ import logging
from homeassistant.const import ATTR_NAME
from . import SENSOR_TYPES, AmbientWeatherEntity
from . import SENSOR_TYPES, TYPE_SOLARRADIATION, AmbientWeatherEntity
from .const import ATTR_LAST_DATA, DATA_CLIENT, DOMAIN, TYPE_SENSOR
_LOGGER = logging.getLogger(__name__)
@@ -22,12 +22,12 @@ async def async_setup_entry(hass, entry, async_add_entities):
sensor_list = []
for mac_address, station in ambient.stations.items():
for condition in ambient.monitored_conditions:
name, unit, kind, _ = SENSOR_TYPES[condition]
name, unit, kind, device_class = SENSOR_TYPES[condition]
if kind == TYPE_SENSOR:
sensor_list.append(
AmbientWeatherSensor(
ambient, mac_address, station[ATTR_NAME], condition,
name, unit))
name, device_class, unit))
async_add_entities(sensor_list, True)
@@ -37,10 +37,15 @@ class AmbientWeatherSensor(AmbientWeatherEntity):
def __init__(
self, ambient, mac_address, station_name, sensor_type, sensor_name,
unit):
device_class, unit):
"""Initialize the sensor."""
super().__init__(
ambient, mac_address, station_name, sensor_type, sensor_name)
ambient,
mac_address,
station_name,
sensor_type,
sensor_name,
device_class)
self._unit = unit
@@ -56,5 +61,13 @@ class AmbientWeatherSensor(AmbientWeatherEntity):
async def async_update(self):
"""Fetch new state data for the sensor."""
self._state = self._ambient.stations[
new_state = self._ambient.stations[
self._mac_address][ATTR_LAST_DATA].get(self._sensor_type)
if self._sensor_type == TYPE_SOLARRADIATION:
# Ambient's units for solar radiation (illuminance) are
# W/m^2; since those aren't commonly used in the HASS
# world, transform them to lx:
self._state = round(float(new_state)/0.0079)
else:
self._state = new_state

View File

@@ -1,33 +1,49 @@
"""Support for Amcrest IP cameras."""
import logging
from datetime import timedelta
import threading
import aiohttp
from amcrest import AmcrestError, Http, LoginError
import voluptuous as vol
from homeassistant.auth.permissions.const import POLICY_CONTROL
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR
from homeassistant.components.camera import DOMAIN as CAMERA
from homeassistant.components.sensor import DOMAIN as SENSOR
from homeassistant.components.switch import DOMAIN as SWITCH
from homeassistant.const import (
CONF_NAME, CONF_HOST, CONF_PORT, CONF_USERNAME, CONF_PASSWORD,
CONF_BINARY_SENSORS, CONF_SENSORS, CONF_SWITCHES, CONF_SCAN_INTERVAL,
HTTP_BASIC_AUTHENTICATION)
ATTR_ENTITY_ID, CONF_AUTHENTICATION, CONF_BINARY_SENSORS, CONF_HOST,
CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_SCAN_INTERVAL, CONF_SENSORS,
CONF_SWITCHES, CONF_USERNAME, ENTITY_MATCH_ALL, HTTP_BASIC_AUTHENTICATION)
from homeassistant.exceptions import Unauthorized, UnknownUser
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import (
async_dispatcher_send, dispatcher_send)
from homeassistant.helpers.event import track_time_interval
from homeassistant.helpers.service import async_extract_entity_ids
from .binary_sensor import BINARY_SENSOR_MOTION_DETECTED, BINARY_SENSORS
from .camera import CAMERA_SERVICES, STREAM_SOURCE_LIST
from .const import CAMERAS, DOMAIN, DATA_AMCREST, DEVICES, SERVICE_UPDATE
from .helpers import service_signal
from .sensor import SENSOR_MOTION_DETECTOR, SENSORS
from .switch import SWITCHES
_LOGGER = logging.getLogger(__name__)
CONF_AUTHENTICATION = 'authentication'
CONF_RESOLUTION = 'resolution'
CONF_STREAM_SOURCE = 'stream_source'
CONF_FFMPEG_ARGUMENTS = 'ffmpeg_arguments'
CONF_CONTROL_LIGHT = 'control_light'
DEFAULT_NAME = 'Amcrest Camera'
DEFAULT_PORT = 80
DEFAULT_RESOLUTION = 'high'
DEFAULT_STREAM_SOURCE = 'snapshot'
DEFAULT_ARGUMENTS = '-pred 1'
TIMEOUT = 10
DATA_AMCREST = 'amcrest'
DOMAIN = 'amcrest'
MAX_ERRORS = 5
RECHECK_INTERVAL = timedelta(minutes=1)
NOTIFICATION_ID = 'amcrest_notification'
NOTIFICATION_TITLE = 'Amcrest Camera Setup'
@@ -43,104 +59,143 @@ AUTHENTICATION_LIST = {
'basic': 'basic'
}
STREAM_SOURCE_LIST = {
'mjpeg': 0,
'snapshot': 1,
'rtsp': 2,
}
BINARY_SENSORS = {
'motion_detected': 'Motion Detected'
}
# Sensor types are defined like: Name, units, icon
SENSOR_MOTION_DETECTOR = 'motion_detector'
SENSORS = {
SENSOR_MOTION_DETECTOR: ['Motion Detected', None, 'mdi:run'],
'sdcard': ['SD Used', '%', 'mdi:sd'],
'ptz_preset': ['PTZ Preset', None, 'mdi:camera-iris'],
}
# Switch types are defined like: Name, icon
SWITCHES = {
'motion_detection': ['Motion Detection', 'mdi:run-fast'],
'motion_recording': ['Motion Recording', 'mdi:record-rec']
}
def _deprecated_sensors(value):
if SENSOR_MOTION_DETECTOR in value:
def _deprecated_sensor_values(sensors):
if SENSOR_MOTION_DETECTOR in sensors:
_LOGGER.warning(
'sensors option %s is deprecated. '
'Please remove from your configuration and '
'use binary_sensors option motion_detected instead.',
SENSOR_MOTION_DETECTOR)
return value
"The '%s' option value '%s' is deprecated, "
"please remove it from your configuration and use "
"the '%s' option with value '%s' instead",
CONF_SENSORS, SENSOR_MOTION_DETECTOR, CONF_BINARY_SENSORS,
BINARY_SENSOR_MOTION_DETECTED)
return sensors
def _has_unique_names(value):
names = [camera[CONF_NAME] for camera in value]
def _deprecated_switches(config):
if CONF_SWITCHES in config:
_LOGGER.warning(
"The '%s' option (with value %s) is deprecated, "
"please remove it from your configuration and use "
"services and attributes instead",
CONF_SWITCHES, config[CONF_SWITCHES])
return config
def _has_unique_names(devices):
names = [device[CONF_NAME] for device in devices]
vol.Schema(vol.Unique())(names)
return value
return devices
AMCREST_SCHEMA = vol.Schema({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_AUTHENTICATION, default=HTTP_BASIC_AUTHENTICATION):
vol.All(vol.In(AUTHENTICATION_LIST)),
vol.Optional(CONF_RESOLUTION, default=DEFAULT_RESOLUTION):
vol.All(vol.In(RESOLUTION_LIST)),
vol.Optional(CONF_STREAM_SOURCE, default=DEFAULT_STREAM_SOURCE):
vol.All(vol.In(STREAM_SOURCE_LIST)),
vol.Optional(CONF_FFMPEG_ARGUMENTS, default=DEFAULT_ARGUMENTS):
cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL):
cv.time_period,
vol.Optional(CONF_BINARY_SENSORS):
vol.All(cv.ensure_list, [vol.In(BINARY_SENSORS)]),
vol.Optional(CONF_SENSORS):
vol.All(cv.ensure_list, [vol.In(SENSORS)], _deprecated_sensors),
vol.Optional(CONF_SWITCHES):
vol.All(cv.ensure_list, [vol.In(SWITCHES)]),
})
AMCREST_SCHEMA = vol.All(
vol.Schema({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_AUTHENTICATION, default=HTTP_BASIC_AUTHENTICATION):
vol.All(vol.In(AUTHENTICATION_LIST)),
vol.Optional(CONF_RESOLUTION, default=DEFAULT_RESOLUTION):
vol.All(vol.In(RESOLUTION_LIST)),
vol.Optional(CONF_STREAM_SOURCE, default=STREAM_SOURCE_LIST[0]):
vol.All(vol.In(STREAM_SOURCE_LIST)),
vol.Optional(CONF_FFMPEG_ARGUMENTS, default=DEFAULT_ARGUMENTS):
cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL):
cv.time_period,
vol.Optional(CONF_BINARY_SENSORS):
vol.All(cv.ensure_list, [vol.In(BINARY_SENSORS)]),
vol.Optional(CONF_SENSORS):
vol.All(cv.ensure_list, [vol.In(SENSORS)],
_deprecated_sensor_values),
vol.Optional(CONF_SWITCHES):
vol.All(cv.ensure_list, [vol.In(SWITCHES)]),
vol.Optional(CONF_CONTROL_LIGHT, default=True): cv.boolean,
}),
_deprecated_switches
)
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.All(cv.ensure_list, [AMCREST_SCHEMA], _has_unique_names)
}, extra=vol.ALLOW_EXTRA)
# pylint: disable=too-many-ancestors
class AmcrestChecker(Http):
"""amcrest.Http wrapper for catching errors."""
def __init__(self, hass, name, host, port, user, password):
"""Initialize."""
self._hass = hass
self._wrap_name = name
self._wrap_errors = 0
self._wrap_lock = threading.Lock()
self._unsub_recheck = None
super().__init__(host, port, user, password, retries_connection=1,
timeout_protocol=3.05)
@property
def available(self):
"""Return if camera's API is responding."""
return self._wrap_errors <= MAX_ERRORS
def command(self, cmd, retries=None, timeout_cmd=None, stream=False):
"""amcrest.Http.command wrapper to catch errors."""
try:
ret = super().command(cmd, retries, timeout_cmd, stream)
except AmcrestError:
with self._wrap_lock:
was_online = self.available
self._wrap_errors += 1
_LOGGER.debug('%s camera errs: %i', self._wrap_name,
self._wrap_errors)
offline = not self.available
if offline and was_online:
_LOGGER.error(
'%s camera offline: Too many errors', self._wrap_name)
dispatcher_send(
self._hass,
service_signal(SERVICE_UPDATE, self._wrap_name))
self._unsub_recheck = track_time_interval(
self._hass, self._wrap_test_online, RECHECK_INTERVAL)
raise
with self._wrap_lock:
was_offline = not self.available
self._wrap_errors = 0
if was_offline:
self._unsub_recheck()
self._unsub_recheck = None
_LOGGER.error('%s camera back online', self._wrap_name)
dispatcher_send(
self._hass, service_signal(SERVICE_UPDATE, self._wrap_name))
return ret
def _wrap_test_online(self, now):
"""Test if camera is back online."""
try:
self.current_time
except AmcrestError:
pass
def setup(hass, config):
"""Set up the Amcrest IP Camera component."""
from amcrest import AmcrestCamera, AmcrestError
hass.data.setdefault(DATA_AMCREST, {DEVICES: {}, CAMERAS: []})
hass.data.setdefault(DATA_AMCREST, {})
amcrest_cams = config[DOMAIN]
for device in amcrest_cams:
for device in config[DOMAIN]:
name = device[CONF_NAME]
username = device[CONF_USERNAME]
password = device[CONF_PASSWORD]
try:
camera = AmcrestCamera(device[CONF_HOST],
device[CONF_PORT],
username,
password).camera
# pylint: disable=pointless-statement
camera.current_time
api = AmcrestChecker(
hass, name,
device[CONF_HOST], device[CONF_PORT],
username, password)
except AmcrestError as ex:
_LOGGER.error("Unable to connect to %s camera: %s", name, 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)
except LoginError as ex:
_LOGGER.error("Login error for %s camera: %s", name, ex)
continue
ffmpeg_arguments = device[CONF_FFMPEG_ARGUMENTS]
@@ -148,7 +203,8 @@ def setup(hass, config):
binary_sensors = device.get(CONF_BINARY_SENSORS)
sensors = device.get(CONF_SENSORS)
switches = device.get(CONF_SWITCHES)
stream_source = STREAM_SOURCE_LIST[device[CONF_STREAM_SOURCE]]
stream_source = device[CONF_STREAM_SOURCE]
control_light = device.get(CONF_CONTROL_LIGHT)
# currently aiohttp only works with basic authentication
# only valid for mjpeg streaming
@@ -157,48 +213,99 @@ def setup(hass, config):
else:
authentication = None
hass.data[DATA_AMCREST][name] = AmcrestDevice(
camera, name, authentication, ffmpeg_arguments, stream_source,
resolution)
hass.data[DATA_AMCREST][DEVICES][name] = AmcrestDevice(
api, authentication, ffmpeg_arguments, stream_source,
resolution, control_light)
discovery.load_platform(
hass, 'camera', DOMAIN, {
hass, CAMERA, DOMAIN, {
CONF_NAME: name,
}, config)
if binary_sensors:
discovery.load_platform(
hass, 'binary_sensor', DOMAIN, {
hass, BINARY_SENSOR, DOMAIN, {
CONF_NAME: name,
CONF_BINARY_SENSORS: binary_sensors
}, config)
if sensors:
discovery.load_platform(
hass, 'sensor', DOMAIN, {
hass, SENSOR, DOMAIN, {
CONF_NAME: name,
CONF_SENSORS: sensors,
}, config)
if switches:
discovery.load_platform(
hass, 'switch', DOMAIN, {
hass, SWITCH, DOMAIN, {
CONF_NAME: name,
CONF_SWITCHES: switches
}, config)
return len(hass.data[DATA_AMCREST]) >= 1
if not hass.data[DATA_AMCREST][DEVICES]:
return False
def have_permission(user, entity_id):
return not user or user.permissions.check_entity(
entity_id, POLICY_CONTROL)
async def async_extract_from_service(call):
if call.context.user_id:
user = await hass.auth.async_get_user(call.context.user_id)
if user is None:
raise UnknownUser(context=call.context)
else:
user = None
if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_ALL:
# Return all entity_ids user has permission to control.
return [
entity_id for entity_id in hass.data[DATA_AMCREST][CAMERAS]
if have_permission(user, entity_id)
]
call_ids = await async_extract_entity_ids(hass, call)
entity_ids = []
for entity_id in hass.data[DATA_AMCREST][CAMERAS]:
if entity_id not in call_ids:
continue
if not have_permission(user, entity_id):
raise Unauthorized(
context=call.context,
entity_id=entity_id,
permission=POLICY_CONTROL
)
entity_ids.append(entity_id)
return entity_ids
async def async_service_handler(call):
args = []
for arg in CAMERA_SERVICES[call.service][2]:
args.append(call.data[arg])
for entity_id in await async_extract_from_service(call):
async_dispatcher_send(
hass,
service_signal(call.service, entity_id),
*args
)
for service, params in CAMERA_SERVICES.items():
hass.services.async_register(
DOMAIN, service, async_service_handler, params[0])
return True
class AmcrestDevice:
"""Representation of a base Amcrest discovery device."""
def __init__(self, camera, name, authentication, ffmpeg_arguments,
stream_source, resolution):
def __init__(self, api, authentication, ffmpeg_arguments,
stream_source, resolution, control_light):
"""Initialize the entity."""
self.device = camera
self.name = name
self.api = api
self.authentication = authentication
self.ffmpeg_arguments = ffmpeg_arguments
self.stream_source = stream_source
self.resolution = resolution
self.control_light = control_light

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