Compare commits

..

233 Commits

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

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

* Better labeling

* Owner comments
2019-02-28 17:46:28 -08:00
Robert Svensson
9e140d27bf Fix deCONZ retry mechanism for setup 2019-02-28 17:45:41 -08:00
Ben Randall
e6cbdf0645 Add PLATFORM_SCHEMA_BASE to telegram_bot component (#21155) 2019-02-28 17:44:04 -08:00
Paulus Schoutsen
1c889cfcc3 Updated frontend to 20190228.0 2019-02-28 17:43:48 -08:00
Paulus Schoutsen
45bbe75d29 Bumped version to 0.89.0b0 2019-02-27 16:45:14 -08:00
Victor Vostrikov
4a45510c88 Changed source priority for Person (#21479)
* Added gps accuracy to Person

* Corrected GPS accuracy for Person

* Added priority of sources to Person

* Fixed formatting

* Removed rounding of coordinates.

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

* Improved code style

* Code style cleanup

* Code style cleanup

* Code style cleanup

* Code style cleanup

* Code style cleanup

* Lint

* Lint
2019-02-27 16:40:23 -08:00
msvinth
070320a24a Bump ihc to 2.3.0 (#21494) 2019-02-27 16:39:11 -08:00
Nick Whyte
1ef3e32d4a ness_alarm: Bump nessclient version to 0.9.13 (#21466) 2019-02-27 16:38:53 -08:00
Paulus Schoutsen
c9ade6ee85 Merge remote-tracking branch 'origin/master' into dev 2019-02-27 16:34:47 -08:00
Paulus Schoutsen
78217fa9b0 Update translations 2019-02-27 16:34:13 -08:00
Paulus Schoutsen
f3bb9e870e Updated frontend to 20190227.0 2019-02-27 16:33:56 -08:00
Daniel Høyer Iversen
732110b4c3 Upgrade tibber lib (#21486) 2019-02-27 16:33:26 -08:00
Aaron Bach
ab2be6df48 Upgrade aioambient to 0.1.3 (#21510) 2019-02-27 16:27:26 -08:00
Aaron Bach
e4b2aab1e9 Bump simplisafe-python to 3.4.1 (#21511) 2019-02-27 16:27:13 -08:00
Aaron Bach
3749321fa5 Upgrade pyairvisual to 3.0.1 (#21512) 2019-02-27 16:26:59 -08:00
Jeff Irion
0ebd12fa6c Avoid unnecessary commands in Vizio update function (#20867) 2019-02-27 16:08:02 -08:00
CV
8a026bf214 HomeMatic: Add error-attribute (#21009)
Error attribute has different meanings depending on device
2019-02-27 23:09:49 +01:00
Daniel Høyer Iversen
519315f9c8 pylint 2.3.0 (#21485)
* pylint 2.3.0

* remove const

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

* added checks

* Fixes based on feedback

* Fix spelling

* Simplified implementation

On homematicip devices and the ap are created

* small fix with device.id

* hub/ap device creation moved to __init__.py

* Fixed result handling

* fixes after review.

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

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

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

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

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

* Add Device_Class_Battery to property

* Break long lines.

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

* Add support for showing station on map

* Add option to exclude via connections

* Cleanup the live sensor

* Perform better checking against false i/o None values

* Add support for excluding vias

* Add more details for via trains

* Lint file

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

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

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

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

* Lint

* Fix typing

* Fix pylint

* Fix lint

* Add some log information

* Add http.trusted_networks deprecated warning

* Remove log info

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

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

cr comments

cr comments

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

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

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

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

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

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

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

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

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

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

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

* Fixed failing tests after rebase

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

* switch to name_by_user

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

* lint

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

* PackageLoadable

* hound

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

* 🔥 Removed manual state from list

* 👕 Addresses code review comments

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

* 👕 Addresses linting warnings

* 👕 Addresses Hound CI warning

* 👕 Fixes small code styling issues

*  Sets an appropriate SCAN_INTERVAL

*  Sets min/max temperature for climate platform

* 👕 Makes imports more consistent with codebase

* 🚑 Fixes incorrect SCAN_INTERVAL value in climate platform

* 🚑 Uses OrderedDict for config_flow schema

* 👕 Adds return types for min/max temp

* 🚜 Refactors entities into their actual devices

* ⬆️ Updates toonapilib to 3.0.7

* 🚜 Refactors binary sensor state inversion

* 🚑 Fixes states of OpenTherm connection and Hot Tap Water

*  Adds Boiler Preheat binary sensor

*  Adds Toon Thermostat Program binary sensor

*  Adds Boiler Modulation Level sensor

*  Adds Daily Power Cost sensor

* 🔥 Cleanup of Toon Thermostat climate attributes

* 🚜 Adjusts config_flow with Tenant selection

* 🙋 Adds myself to codeowners file as maintainer

* ⬆️ Gen requirements

* ⬆️ Updates toonapilib to 3.0.9

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

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

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

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

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

* Add additional classes

* Removed device class descriptions

* Updates based on review feedback

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

* Update the 'update' function for Fire TV

* Return None for properties when unavailable

* Remove 'self.adb_lock' attribute

* Remove threading import

* Update configuration for Fire TV component

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

* Rename '__adb_decorator' to '_adb_exception_catcher'

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

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

This allows forced update of state

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

* Drop unused variables

* Only send mute if different from current state

* No need to update variables, will behandled on update

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

* Add discovery of multiple households

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

* Eliminate possibility of None in operation list

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

Fixes #20071 and #21051

* Update requirements_all.txt

* Update requirements_all.txt

* Update waze_travel_time.py

* Update waze_travel_time.py

* Update waze_travel_time.py

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

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

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

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

* Make it so name can still be configured

* Fix invalid syntax

* Use shared data object + 1 sensor

* Linting

* Remove straying comment

* Dont use async for non-async stuff

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

* Use consts for keys

* Copy dict to list for sensors

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

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

* Changes to reflect code review

* Added code per change requests

- Validation of connection during setup_platform
- Docs pending

* Removed blank lines per CI build

* Lint fix

* Update homeassistant/components/switch/sony_projector.py

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

* Updated .coveragerc, made requested logger changes

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

* Fixing line length and missing imports

* Line too long

* Adding details to the custom service

* Fix linting issues

* Reverting ACTION

* Code cleanup

* Typo

* Requested modifications

* Changing the custom service domain

* No service schema depency anymore

* Removing useless code

* Linting

* Requested changes

* Requested changes for domain

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

* Split out iperf3 into a component with a sensor platform

* Update coverage and requirements

* Add services.yaml

* Clean up a little bit

* Lint

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

* Update person on adding person if hass is running

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

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

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

* Fix PR issues around CI.

* Fix line length fallout.

* Change rollover to net_consumption.  Add unit tests.

* Fix test style issues.

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

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

* Filter store_raw as attribute instead of filter_state parameter

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

* Removed unused default value

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

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

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

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

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

* Update __init__.py

* Fix lint issue

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Support for 2 new PLC types

Sensor supports DINT and UDINT PLC types

* Update __init__.py

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

* Add migration functionality.

* Regenerate refresh token on periodic basis

* Fix regenerate and misc. optimizations

* Review feedback

* Subscription sync logic now performs a difference operation

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

* Start __init__() params with hass.

* Remove excess logging and downgrade remaining logging.

* Remove period from end of comment

* Decorate callback with @callback

* Use more descriptive variables than key and value.

* Inherit from BinarySensorDevice and overwrite is_on rather than state.

* Removed uncheckedreturn values.

* Use super() rather than explicit object.

* Use add_entities instead of add_devices.

* Don't use listener when calling immediately.

* Remove some excess logging.

* Switch to sync since pycarwings2 is sync.

* Remove RuntimeError exception matching.

* Add temporary reviewer comments.

* Add UI help descriptions for update service.

* Fix hound errors.

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

* Removed location_updateon_on attribute since on device_tracker.

* Use async_added_to_hass() and async_dispatcher_connect().

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

* Clarify variable names.

* Remove icon for charging switch.

* Convert LeafChargeSwitch into service and sensor.

* Use async_dispatcher_send().

* Add guard checks for discovery_info. Consistent logs.

* Use async_schedul_update_ha_state().

* Device tracker should return true.

* Remove icon for climate control.

* Really remove icon for climate control.

* Use register() instead of async_register().

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

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

* raise PlatformNotReady when no device is available

* Use mac instead of deviceid

* remove name option as obsolete

* Add support for configuration flow / integration

Allows activating automatic discovery of supported devices from the configuration

* Fix linting, update requirements_all.txt

* start cleaning up tplink component based on feedback

* add device info, improve config handling

* Allow overriding detected devices via configuration file

* Update requirements.txt

* Remove debug logging

* make hound happy

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

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

* add async_setup_platform emiting a deprecation warning

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

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

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

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

* add default values to schema, make hound happy

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

* Use constant for data structure access

* REWORD add a short note about async_unload_entry

* handle feedback from Martin, config_data is checked against Noneness

* use pop to remove the domain on unload

* First steps to add tests for the new tplink component

* embed platforms under the component directory

* Fix tests by mocking the pyhs100 internals

* Fix linting

* Test against multiple instances of devices, tidy up

* (hopefully) final linting round

* Add pyHS100 to test requirements

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

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

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

Thanks @MartinHjelmare for pointing this out!

* Fix linting

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

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

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

* Use new-style format string

* Fix indenting, uppercase the mock constant

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

* Updated code to meet requirements.

* Code clean-up.

* Code clean-up.

* Code clean-up.

* Minor error message update

* Ubee device tracker: Minor code clean-up

* Bump pyubee version

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

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

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

* add comment

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

* Fix tests
2019-02-21 09:41:36 +01:00
Fredrik Erlandsson
73099caede Alarm trigger support for Point (#21207) 2019-02-21 06:50:02 +01:00
Fabian Affolter
966fd1034d Upgrade opensensemap-api to 0.1.4 (#21240) 2019-02-20 17:46:37 -07:00
Paulus Schoutsen
ddd63c615f Remove constraint from regex (#21239) 2019-02-20 21:31:41 +01:00
Paulus Schoutsen
03573781c7 Updated frontend to 20190220.0 2019-02-20 08:55:42 -08:00
Finbarr Brady
54949cff5a Support OpenWRT 18.06 in luci device tracker (#21236)
* Got it right this time i hope

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

* Update requirements

* Update test requirements

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

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

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

* tail whitespace

* tail whitespaces

* new version

* fix params typs

* fix param type

* line length

* rytilahti tips

* houndci-bot

* fix trevis

* rytilahti tips

* service description

* syssi fix

* MartinHjelmare tips

* MartinHjelmare

* data_template schema

* line lenght

* line lenght

* line lenght

* data_template schema

* fix

* Update homeassistant/components/vacuum/xiaomi_miio.py

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

* Update homeassistant/components/vacuum/xiaomi_miio.py

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

* xiaomi vacuum with zone and reps

* tail whitespace

* new version

* fix param type

* rytilahti tips

* rytilahti tips

* MartinHjelmare

* data_template schema

* line lenght

* line lenght

* data_template schema

* fix

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

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

This reverts commit e1f370b3b45d2541c8117146b0940d7c2b5bc8b0.

* log fixed

* Revert "log fixed"

This reverts commit 1f0e7b35e8.

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

This reverts commit 1cf9e5ae1f.

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

This reverts commit 0e8d53449a.

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

* Lint
2019-02-20 08:02:56 +01:00
Daniel Perna
27d598fff8 Update pyhomematic to 0.1.56 (#21227) 2019-02-20 00:31:46 +01:00
Paulus Schoutsen
49995c2120 Fix the build (#21229) 2019-02-19 13:52:14 -08:00
Paulus Schoutsen
f452409cfa Updated frontend to 20190219.0 2019-02-19 10:14:33 -08:00
zewelor
fb820975b5 Add yeelight flow action support (#21195) 2019-02-19 19:06:40 +01:00
David F. Mulcahey
3be8178035 Refactor ZHA listeners into channels (#21196)
* refactor listeners to channels

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

See coreGreenberet/homematicip-rest-api@0b61954f6a

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

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

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

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

* Change logger warning for light update

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

* add space

* fix tests

* rename to swupdate2_bridge_state

* update aiohue to v1.9.1

* update aiohue to v1.9.1

* update aiohue to v1.9.1
2019-02-18 21:31:42 -08:00
Anders Melchiorsen
bc46e48d23 Upgrade aioimaplib for Python 3.7 compatibility (#21197) 2019-02-19 06:11:56 +01:00
OleksandrBerchenko
bdea222196 Expose effect_list attribute for turned off lights (#20750) 2019-02-18 21:01:26 -08:00
Paulus Schoutsen
d1ebe2cbac Updated frontend to 20190218.0 2019-02-18 13:25:43 -08:00
Paulus Schoutsen
d2fea76fd7 Add context to service call event (#21181) 2019-02-18 13:07:44 -08:00
sjabby
463c4ae5c9 Fix for #19072 (#21175)
* Fix for #19072

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

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

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

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

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

This change is fixing issue #20900.

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

* Added deprecation comment

* Fixed long line

* Fix: pylint comment

* Lint

* flake8

* flake8 again

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

User defined additional parameters to track from the traccar platform

* Version bump for pytraccar client

* Update traccar.py

* Remove default value

* Update homeassistant/components/device_tracker/traccar.py

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

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

* Create en.json

* Create config_flow.py

* Create const.py

* Create media_player.py

* Create services.yaml

* Create strings.json

* Create __init__.py

* Add test_config_flow.py/ Finished adding PS4 files

* Rewrote for loop into short-hand

* bumped pyps4 to 0.2.8

* Pass in helper()

* Rewrite func

* Fixed test

* Added import in init

* bump to 0.2.9

* bump to 0.3.0

* Removed line

* lint

* Add ps4 to flows list

* Added pyps4-homeassistant with script

* Added pyps4

* Added pypys4 to test

* removed list def

* reformatted service call dicts

* removed config from device class

* typo

* removed line

* reformatted .. format

* redefined property

* reformat load games func

* Add __init__ and media_player.py to coveragerc

* Fix for test

* remove init

* remove blank line

* remove mock_coro

* Revert "remove init"

This reverts commit b68996aa34699bf38781e153acdd597579e8131f.

* Correct permissions

* fixes

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

* Fixed trailing whitespace and indentation

* Update traccar.py

* Update homeassistant/components/device_tracker/traccar.py

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

* Corretly handle HomeCoach in manual setup

* Fix code reivew comments

* Move import back int methods

* Formatting fix

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

* Upgrade pytest to 4.2.1

* Make litejet switch test work with pytest 4.2
2019-02-17 09:55:33 +01:00
Jason Hu
2155a861cd Remove outdated url pattern match support for static file hosting (#21109) 2019-02-16 23:06:42 -08:00
Paulus Schoutsen
f1b84962ed Add legacy PLATFORM_SCHEMA config validation (#21072)
* Add legacy PLATFORM_SCHEMA config validation

* Fix tests

* Lint

* Add persistent notification

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

* Fix imports

* Removed config options from conflig_flow

* fix tests

* Removed config options

* reverted smaller code changes

* changes after review

* minor fix

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

* Update tests

* Fix Darksky tests

* Fix Darksky tests correctly

This reverts commit a73384a223ba8a93c682042d9351cd5a7a399183.

* Provide the default for the non deprecated option

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

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

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

* Set default value for index to avoid later checks
2019-02-16 09:29:24 +01:00
Aaron Bach
539d24dd60 Bump aioambient to 0.1.2 (#21098) 2019-02-15 10:28:23 -08:00
Phil Hawthorne
9203ae201f Set uvloop version consistent with hass.io (#21080)
This sets the uvloop version in Docker containers to 0.11.3, which is the
same version that hass.io uses.

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

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

* Sync up CachingStaticResource._handle() implementation from aiohttp

* Ignore pylint duplicate-base warning

* Try to disable pylint for http/static.py

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

* Remove pylint ignore

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

* Fixed line length

* Review comments and lint error

* Fixed mypy typeing error

* Moved migration logic to setup

* Use new migration error state

* Fix bug and ignore mypy type error

* Removed SmartThings example and added unit tests.

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

* Fix hue retry crash

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

* Prevent capabilities from being represented my multiple platforms

* Improved logging of received updates

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

* Solve lint issues.

* Correct style.

* Minor changes

* Minor changes

* Minor changes

* Update file header

* Remove space

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

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

* Added the warning notice.

* Async setup

* Still broken, but we're getting there.

* Back to synchronous, moved refresh stuff into DataStore

* Functional sensors!

* Added working switches, tweaked intervals a bit

* Fixed turn off result

* Moved plug status to binary_sensor, added smart intervals

* Documentation and car nickname stuff

* Syntax fixes and coveragerc additions

* Style fixes

* Fixing the final line length

* Fixed an issue with newer models and bad climate data

* Forgot to check my line endings.

* New icons for most of the components

* Hotfix for handling Nissan's awful servers

* Merge in fixes made by Phil Cole

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

commit 418b6bbcc49cf2909aac85869440435410abf3fd

* Add pycarwings2 to requirements_all.txt

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

* Request update from car after sending start charging command.

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

* Flake8 line length fixes

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

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

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

* Update to pycarwings2 2.3

* Update to pycarwings2 2.3 in requirements_all.txt

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

* Remove unneeded dispatcher_send()

* Remove unneeded requirements comments

* Combine excess debugging.

* Remove single line method signal_components()

* Bump to version 2.4 of pycarwings2

* Remove unused dispatcher_send

* Simplify logging of LeafEntity registration

* Update requirements_all.txt

* Multiple changes

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

* Fix line length

* Use pycarwings 2.5

* Remove pointless 'is True'

* Remove unnecessary 'is True/False'

* Remove unnecessary 'is True/False'

* Use LENGTH_MILES and LENGTH_KILOMETERS

* Remove excess logging in setup_platform()

* Remove unnecessary 'is True'

* Use pycarwings2 version 2.6

* Require pycarwings2 version 2.7.

* Increase sleep delay for climate and location reponses.

* Remove unnecessary 'is True'

* Increase frequent polling warning to _LOGGER.warning()

* Use DEVICE_CLASS_BATTERY

* Remove extraneous 'is True'.

* Move icon strings to constants.

* Remove unneeded key.

* LeafRangeSensor ac_on property is internal.

* Flake8 missing line

* Remove homebridge attributes.

* Remove round battery % and range to whole numbers

* Use pycarwings2 2.8

* Move to embedded component model

* Reduce maximum attempts to 10 (5 mins)

* Include attempt count in 'waiting' log message

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

* Add @filcole as nissan_leaf codeowner

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

* Exposed updated_on, update_in_progress and next_update attributes.

* Add nissan_leaf.update service that triggers an update.

* Flake8 line fixes

* Remove excess and double logging.

* Add updated_on attribute for device tracker.

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

* Minor changes

* Minor changes

* Minor changes

* Minor changes

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

* Times of the Day binary sensor added

* Python 3.5 fixes and logging removed

* Code refactored according to reviewer's suggestions

* Fixed config template with friendly name support

* Finall pep8 fixes

* Removed async_generate_entity_id and moved initial calculation to async_added_to_hass

* Change the configuration schema to follow the current requirements

* Update according latest suggestsion

* Fix typos and minor changes

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

* fixes for alarm_control

* arm home is the same as arm away

* updated documentation

* final fixes

* pypoint version up

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

* Move file

* Update .coveragerc

* Sort import and update file header

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

* Update homeassistant/components/sensor/irish_rail_transport.py

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

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

* Fix lint issue

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

* linting

* upgrade meteofrance package version

* Update .coveragerc

* Remove updates to the weather component architecture

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

* Update .coveragerc

* Update requirements_all.txt

* remove Weather Card option

* Update conf name

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

* Update meteofrance pypi package

* fix line too long

* Update requirements_all.txt

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

* fix stale url and remove blank line

* Insure that all cities are unique

* rename CONF_ATTRIBUTION

* Updating data from component setup

* fix missing extra lines
2019-02-14 14:40:27 +01:00
Paulus Schoutsen
801401e9cb Bumped version to 0.89.0.dev0 2019-02-13 20:47:04 -08:00
772 changed files with 15139 additions and 5018 deletions

View File

@@ -136,6 +136,7 @@ omit =
homeassistant/components/device_tracker/tplink.py
homeassistant/components/device_tracker/traccar.py
homeassistant/components/device_tracker/trackr.py
homeassistant/components/device_tracker/ubee.py
homeassistant/components/device_tracker/ubus.py
homeassistant/components/digital_ocean/*
homeassistant/components/dominos/*
@@ -204,6 +205,7 @@ omit =
homeassistant/components/insteon/*
homeassistant/components/ios/*
homeassistant/components/iota/*
homeassistant/components/iperf3/*
homeassistant/components/isy994/*
homeassistant/components/joaoapps_join/*
homeassistant/components/juicenet/*
@@ -317,6 +319,7 @@ omit =
homeassistant/components/media_player/yamaha_musiccast.py
homeassistant/components/media_player/yamaha.py
homeassistant/components/media_player/ziggo_mediabox_xl.py
homeassistant/components/meteo_france/*
homeassistant/components/mochad/*
homeassistant/components/modbus/*
homeassistant/components/mychevy/*
@@ -326,6 +329,7 @@ omit =
homeassistant/components/nest/*
homeassistant/components/netatmo/*
homeassistant/components/netgear_lte/*
homeassistant/components/nissan_leaf/*
homeassistant/components/notify/aws_lambda.py
homeassistant/components/notify/aws_sns.py
homeassistant/components/notify/aws_sqs.py
@@ -374,10 +378,13 @@ omit =
homeassistant/components/openuv/__init__.py
homeassistant/components/openuv/binary_sensor.py
homeassistant/components/openuv/sensor.py
homeassistant/components/owlet/*
homeassistant/components/pilight/*
homeassistant/components/plum_lightpad/*
homeassistant/components/point/*
homeassistant/components/prometheus/*
homeassistant/components/ps4/__init__.py
homeassistant/components/ps4/media_player.py
homeassistant/components/qwikswitch/*
homeassistant/components/rachio/*
homeassistant/components/rainbird/*
@@ -388,6 +395,7 @@ omit =
homeassistant/components/rainmachine/switch.py
homeassistant/components/raspihats/*
homeassistant/components/raspyrfm/*
homeassistant/components/reddit/*
homeassistant/components/remember_the_milk/__init__.py
homeassistant/components/remote/harmony.py
homeassistant/components/remote/itach.py
@@ -470,7 +478,6 @@ omit =
homeassistant/components/sensor/imap_email_content.py
homeassistant/components/sensor/imap.py
homeassistant/components/sensor/influxdb.py
homeassistant/components/sensor/iperf3.py
homeassistant/components/sensor/irish_rail_transport.py
homeassistant/components/sensor/kwb.py
homeassistant/components/sensor/lacrosse.py
@@ -482,7 +489,6 @@ omit =
homeassistant/components/sensor/loopenergy.py
homeassistant/components/sensor/lyft.py
homeassistant/components/sensor/magicseaweed.py
homeassistant/components/sensor/meteo_france.py
homeassistant/components/sensor/metoffice.py
homeassistant/components/sensor/miflora.py
homeassistant/components/sensor/mitemp_bt.py
@@ -609,6 +615,7 @@ omit =
homeassistant/components/switch/rest.py
homeassistant/components/switch/rpi_rf.py
homeassistant/components/switch/snmp.py
homeassistant/components/switch/sony_projector.py
homeassistant/components/switch/switchbot.py
homeassistant/components/switch/switchmate.py
homeassistant/components/switch/telnet.py

View File

@@ -2,6 +2,7 @@
- If you need additional help with this template please refer to https://www.home-assistant.io/help/reporting_issues/
- Make sure you are running the latest version of Home Assistant before reporting an issue: https://github.com/home-assistant/home-assistant/releases
- Frontend issues should be submitted to the home-assistant-polymer repository: https://github.com/home-assistant/home-assistant-polymer/issues
- iOS issues should be submitted to the home-assistant-iOS repository: https://github.com/home-assistant/home-assistant-iOS/issues
- Do not report issues for components if you are using custom components: files in <config-dir>/custom_components
- This is for bugs only. Feature and enhancement requests should go in our community forum: https://community.home-assistant.io/c/feature-requests
- Provide as many details as possible. Paste logs, configuration sample and code into the backticks. Do not delete any text from this template!

View File

@@ -8,6 +8,7 @@ about: Create a report to help us improve
- If you need additional help with this template please refer to https://www.home-assistant.io/help/reporting_issues/
- Make sure you are running the latest version of Home Assistant before reporting an issue: https://github.com/home-assistant/home-assistant/releases
- Frontend issues should be submitted to the home-assistant-polymer repository: https://github.com/home-assistant/home-assistant-polymer/issues
- iOS issues should be submitted to the home-assistant-iOS repository: https://github.com/home-assistant/home-assistant-iOS/issues
- Do not report issues for components if you are using custom components: files in <config-dir>/custom_components
- This is for bugs only. Feature and enhancement requests should go in our community forum: https://community.home-assistant.io/c/feature-requests
- Provide as many details as possible. Paste logs, configuration sample and code into the backticks. Do not delete any text from this template!

View File

@@ -34,7 +34,7 @@ cache:
- $HOME/.cache/pip
install: pip install -U tox coveralls
language: python
script: travis_wait 30 tox --develop
script: travis_wait 40 tox --develop
services:
- docker
before_deploy:

View File

@@ -28,7 +28,7 @@ homeassistant/components/panel_iframe/* @home-assistant/core
homeassistant/components/onboarding/* @home-assistant/core
homeassistant/components/persistent_notification/* @home-assistant/core
homeassistant/components/scene/__init__.py @home-assistant/core
homeassistant/components/scene/hass.py @home-assistant/core
homeassistant/components/scene/homeassistant.py @home-assistant/core
homeassistant/components/script/* @home-assistant/core
homeassistant/components/shell_command/* @home-assistant/core
homeassistant/components/sun/* @home-assistant/core
@@ -47,7 +47,6 @@ homeassistant/components/*/zwave.py @home-assistant/z-wave
homeassistant/components/hassio/* @home-assistant/hassio
# Individual platforms
homeassistant/components/alarm_control_panel/egardia.py @jeroenterheerdt
homeassistant/components/alarm_control_panel/manual_mqtt.py @colinodell
homeassistant/components/binary_sensor/hikvision.py @mezz64
homeassistant/components/binary_sensor/threshold.py @fabaff
@@ -68,10 +67,8 @@ homeassistant/components/device_tracker/quantum_gateway.py @cisasteelersfan
homeassistant/components/device_tracker/tile.py @bachya
homeassistant/components/device_tracker/traccar.py @ludeeus
homeassistant/components/device_tracker/bt_smarthub.py @jxwolstenholme
homeassistant/components/history_graph/* @andrey-git
homeassistant/components/influx/* @fabaff
homeassistant/components/device_tracker/synology_srm.py @aerialls
homeassistant/components/light/lifx_legacy.py @amelchio
homeassistant/components/light/tplink.py @rytilahti
homeassistant/components/light/yeelight.py @rytilahti
homeassistant/components/light/yeelightsunflower.py @lindsaymarkward
homeassistant/components/lock/nello.py @pschmitt
@@ -82,20 +79,15 @@ homeassistant/components/media_player/liveboxplaytv.py @pschmitt
homeassistant/components/media_player/mediaroom.py @dgomes
homeassistant/components/media_player/monoprice.py @etsinko
homeassistant/components/media_player/mpd.py @fabaff
homeassistant/components/media_player/sonos.py @amelchio
homeassistant/components/media_player/xiaomi_tv.py @fattdev
homeassistant/components/media_player/yamaha_musiccast.py @jalmeroth
homeassistant/components/no_ip/* @fabaff
homeassistant/components/notify/file.py @fabaff
homeassistant/components/notify/flock.py @fabaff
homeassistant/components/notify/instapush.py @fabaff
homeassistant/components/notify/mastodon.py @fabaff
homeassistant/components/notify/smtp.py @fabaff
homeassistant/components/notify/syslog.py @fabaff
homeassistant/components/notify/xmpp.py @fabaff
homeassistant/components/notify/yessssms.py @flowolf
homeassistant/components/plant/* @ChristianKuehnel
homeassistant/components/remote/harmony.py @ehendrix23
homeassistant/components/scene/lifx_cloud.py @amelchio
homeassistant/components/sensor/airvisual.py @bachya
homeassistant/components/sensor/alpha_vantage.py @fabaff
@@ -106,11 +98,12 @@ homeassistant/components/sensor/darksky.py @fabaff
homeassistant/components/sensor/file.py @fabaff
homeassistant/components/sensor/filter.py @dgomes
homeassistant/components/sensor/fixer.py @fabaff
homeassistant/components/sensor/flunearyou.py.py @bachya
homeassistant/components/sensor/flunearyou.py @bachya
homeassistant/components/sensor/gearbest.py @HerrHofrat
homeassistant/components/sensor/gitter.py @fabaff
homeassistant/components/sensor/glances.py @fabaff
homeassistant/components/sensor/gpsd.py @fabaff
homeassistant/components/sensor/integration.py @dgomes
homeassistant/components/sensor/irish_rail_transport.py @ttroy50
homeassistant/components/sensor/jewish_calendar.py @tsvi
homeassistant/components/sensor/launch_library.py @ludeeus
@@ -135,35 +128,28 @@ homeassistant/components/sensor/statistics.py @fabaff
homeassistant/components/sensor/swiss*.py @fabaff
homeassistant/components/sensor/sytadin.py @gautric
homeassistant/components/sensor/tautulli.py @ludeeus
homeassistant/components/sensor/time_data.py @fabaff
homeassistant/components/sensor/time_date.py @fabaff
homeassistant/components/sensor/version.py @fabaff
homeassistant/components/sensor/waqi.py @andrey-git
homeassistant/components/sensor/worldclock.py @fabaff
homeassistant/components/shiftr/* @fabaff
homeassistant/components/spaceapi/* @fabaff
homeassistant/components/switch/switchbot.py @danielhiversen
homeassistant/components/switch/switchmate.py @danielhiversen
homeassistant/components/switch/tplink.py @rytilahti
homeassistant/components/vacuum/roomba.py @pschmitt
homeassistant/components/weather/__init__.py @fabaff
homeassistant/components/weather/darksky.py @fabaff
homeassistant/components/weather/demo.py @fabaff
homeassistant/components/weather/met.py @danielhiversen
homeassistant/components/weather/openweathermap.py @fabaff
homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi
# A
homeassistant/components/ambient_station/* @bachya
homeassistant/components/arduino/* @fabaff
homeassistant/components/*/arduino.py @fabaff
homeassistant/components/axis/* @kane610
homeassistant/components/*/arest.py @fabaff
homeassistant/components/*/axis.py @kane610
# B
homeassistant/components/blink/* @fronzbot
homeassistant/components/*/blink.py @fronzbot
homeassistant/components/bmw_connected_drive/* @ChristianKuehnel
homeassistant/components/*/bmw_connected_drive.py @ChristianKuehnel
homeassistant/components/*/broadlink.py @danielhiversen
# C
@@ -172,51 +158,44 @@ homeassistant/components/counter/* @fabaff
# D
homeassistant/components/daikin/* @fredrike @rofrantz
homeassistant/components/*/daikin.py @fredrike @rofrantz
homeassistant/components/*/deconz.py @kane610
homeassistant/components/deconz/* @kane610
homeassistant/components/digital_ocean/* @fabaff
homeassistant/components/*/digital_ocean.py @fabaff
homeassistant/components/dweet/* @fabaff
homeassistant/components/*/dweet.py @fabaff
# E
homeassistant/components/ecovacs/* @OverloadUT
homeassistant/components/*/ecovacs.py @OverloadUT
homeassistant/components/*/edp_redy.py @abmantis
homeassistant/components/edp_redy/* @abmantis
homeassistant/components/eight_sleep/* @mezz64
homeassistant/components/*/eight_sleep.py @mezz64
homeassistant/components/egardia/* @jeroenterheerdt
homeassistant/components/esphome/*.py @OttoWinter
# F
homeassistant/components/freebox/*.py @snoof85
# G
homeassistant/components/googlehome/* @ludeeus
homeassistant/components/*/googlehome.py @ludeeus
# H
homeassistant/components/harmony/* @ehendrix23
homeassistant/components/history_graph/* @andrey-git
homeassistant/components/hive/* @Rendili @KJonline
homeassistant/components/*/hive.py @Rendili @KJonline
homeassistant/components/homekit/* @cdce8p
homeassistant/components/huawei_lte/* @scop
homeassistant/components/*/huawei_lte.py @scop
# I
homeassistant/components/influx/* @fabaff
homeassistant/components/ipma/* @dgomes
# K
homeassistant/components/knx/* @Julius2342
homeassistant/components/*/knx.py @Julius2342
homeassistant/components/konnected/* @heythisisnate
homeassistant/components/*/konnected.py @heythisisnate
# L
homeassistant/components/lifx/* @amelchio
homeassistant/components/*/lifx.py @amelchio
homeassistant/components/luftdaten/* @fabaff
homeassistant/components/*/luftdaten.py @fabaff
# M
homeassistant/components/matrix/* @tinloaf
homeassistant/components/*/matrix.py @tinloaf
homeassistant/components/melissa/* @kennedyshead
homeassistant/components/*/melissa.py @kennedyshead
homeassistant/components/*/mystrom.py @fabaff
@@ -224,59 +203,56 @@ homeassistant/components/*/mystrom.py @fabaff
# N
homeassistant/components/ness_alarm/* @nickw444
homeassistant/components/*/ness_alarm.py @nickw444
homeassistant/components/nissan_leaf/* @filcole
homeassistant/components/no_ip/* @fabaff
# O
homeassistant/components/openuv/* @bachya
# P
homeassistant/components/plant/* @ChristianKuehnel
homeassistant/components/point/* @fredrike
homeassistant/components/*/point.py @fredrike
# Q
homeassistant/components/qwikswitch/* @kellerza
homeassistant/components/*/qwikswitch.py @kellerza
# R
homeassistant/components/rainmachine/* @bachya
homeassistant/components/rfxtrx/* @danielhiversen
homeassistant/components/*/random.py @fabaff
homeassistant/components/*/rfxtrx.py @danielhiversen
# S
homeassistant/components/shiftr/* @fabaff
homeassistant/components/simplisafe/* @bachya
homeassistant/components/smartthings/* @andrewsayre
homeassistant/components/sonos/* @amelchio
homeassistant/components/spaceapi/* @fabaff
homeassistant/components/spider/* @peternijssen
# T
homeassistant/components/tahoma/* @philklei
homeassistant/components/*/tahoma.py @philklei
homeassistant/components/tellduslive/*.py @fredrike
homeassistant/components/*/tellduslive.py @fredrike
homeassistant/components/tesla/* @zabuldon
homeassistant/components/*/tesla.py @zabuldon
homeassistant/components/thethingsnetwork/* @fabaff
homeassistant/components/*/thethingsnetwork.py @fabaff
homeassistant/components/tibber/* @danielhiversen
homeassistant/components/*/tibber.py @danielhiversen
homeassistant/components/tplink/* @rytilahti
homeassistant/components/tradfri/* @ggravlingen
homeassistant/components/*/tradfri.py @ggravlingen
homeassistant/components/toon/* @frenck
# U
homeassistant/components/unifi/* @kane610
homeassistant/components/switch/unifi.py @kane610
homeassistant/components/upcloud/* @scop
homeassistant/components/*/upcloud.py @scop
homeassistant/components/utility_meter/* @dgomes
# V
homeassistant/components/velux/* @Julius2342
homeassistant/components/*/velux.py @Julius2342
# W
homeassistant/components/wemo/* @sqldiablo
homeassistant/components/*/wemo.py @sqldiablo
# X
homeassistant/components/*/xiaomi_aqara.py @danielhiversen @syssi
homeassistant/components/*/xiaomi_miio.py @rytilahti @syssi
homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi
homeassistant/components/xiaomi_miio/* @rytilahti @syssi
# Z
homeassistant/components/zoneminder/* @rohankapoorcom

View File

@@ -170,8 +170,7 @@ class AuthManager:
user = await self.async_get_user_by_credentials(credentials)
if user is None:
raise ValueError('Unable to find the user.')
else:
return user
return user
auth_provider = self._async_get_auth_provider(credentials)

View File

@@ -3,18 +3,23 @@
It shows list of users if access from trusted network.
Abort login flow if not access from trusted network.
"""
from typing import Any, Dict, Optional, cast
from ipaddress import ip_network, IPv4Address, IPv6Address, IPv4Network,\
IPv6Network
from typing import Any, Dict, List, Optional, Union, cast
import voluptuous as vol
from homeassistant.components.http import HomeAssistantHTTP # noqa: F401
import homeassistant.helpers.config_validation as cv
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from . import AuthProvider, AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, LoginFlow
from ..models import Credentials, UserMeta
IPAddress = Union[IPv4Address, IPv6Address]
IPNetwork = Union[IPv4Network, IPv6Network]
CONFIG_SCHEMA = AUTH_PROVIDER_SCHEMA.extend({
vol.Required('trusted_networks'): vol.All(cv.ensure_list, [ip_network])
}, extra=vol.PREVENT_EXTRA)
@@ -35,6 +40,11 @@ class TrustedNetworksAuthProvider(AuthProvider):
DEFAULT_TITLE = 'Trusted Networks'
@property
def trusted_networks(self) -> List[IPNetwork]:
"""Return trusted networks."""
return cast(List[IPNetwork], self.config['trusted_networks'])
@property
def support_mfa(self) -> bool:
"""Trusted Networks auth provider does not support MFA."""
@@ -49,7 +59,7 @@ class TrustedNetworksAuthProvider(AuthProvider):
if not user.system_generated and user.is_active}
return TrustedNetworksLoginFlow(
self, cast(str, context.get('ip_address')), available_users)
self, cast(IPAddress, context.get('ip_address')), available_users)
async def async_get_or_create_credentials(
self, flow_result: Dict[str, str]) -> Credentials:
@@ -80,19 +90,17 @@ class TrustedNetworksAuthProvider(AuthProvider):
raise NotImplementedError
@callback
def async_validate_access(self, ip_address: str) -> None:
def async_validate_access(self, ip_addr: IPAddress) -> None:
"""Make sure the access from trusted networks.
Raise InvalidAuthError if not.
Raise InvalidAuthError if trusted_networks is not configured.
"""
hass_http = getattr(self.hass, 'http', None) # type: HomeAssistantHTTP
if not hass_http or not hass_http.trusted_networks:
if not self.trusted_networks:
raise InvalidAuthError('trusted_networks is not configured')
if not any(ip_address in trusted_network for trusted_network
in hass_http.trusted_networks):
if not any(ip_addr in trusted_network for trusted_network
in self.trusted_networks):
raise InvalidAuthError('Not in trusted_networks')
@@ -100,12 +108,12 @@ class TrustedNetworksLoginFlow(LoginFlow):
"""Handler for the login flow."""
def __init__(self, auth_provider: TrustedNetworksAuthProvider,
ip_address: str, available_users: Dict[str, Optional[str]]) \
-> None:
ip_addr: IPAddress,
available_users: Dict[str, Optional[str]]) -> None:
"""Initialize the login flow."""
super().__init__(auth_provider)
self._available_users = available_users
self._ip_address = ip_address
self._ip_address = ip_addr
async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \

View File

@@ -85,14 +85,18 @@ async def async_from_config_dict(config: Dict[str, Any],
async_enable_logging(hass, verbose, log_rotate_days, log_file,
log_no_color)
hass.config.skip_pip = skip_pip
if skip_pip:
_LOGGER.warning("Skipping pip installation of required modules. "
"This may cause issues")
core_config = config.get(core.DOMAIN, {})
has_api_password = bool((config.get('http') or {}).get('api_password'))
has_trusted_networks = bool((config.get('http') or {})
.get('trusted_networks'))
has_api_password = bool(config.get('http', {}).get('api_password'))
trusted_networks = config.get('http', {}).get('trusted_networks')
try:
await conf_util.async_process_ha_core_config(
hass, core_config, has_api_password, has_trusted_networks)
hass, core_config, has_api_password, trusted_networks)
except vol.Invalid as config_err:
conf_util.async_log_exception(
config_err, 'homeassistant', core_config, hass)
@@ -105,11 +109,6 @@ async def async_from_config_dict(config: Dict[str, Any],
await hass.async_add_executor_job(
conf_util.process_ha_config_upgrade, hass)
hass.config.skip_pip = skip_pip
if skip_pip:
_LOGGER.warning("Skipping pip installation of required modules. "
"This may cause issues")
# Make a copy because we are mutating it.
config = OrderedDict(config)

View File

@@ -17,7 +17,8 @@ REQUIREMENTS = ['abodepy==0.15.0']
_LOGGER = logging.getLogger(__name__)
CONF_ATTRIBUTION = "Data provided by goabode.com"
ATTRIBUTION = "Data provided by goabode.com"
CONF_POLLING = 'polling'
DOMAIN = 'abode'
@@ -280,7 +281,7 @@ class AbodeDevice(Entity):
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
ATTR_ATTRIBUTION: ATTRIBUTION,
'device_id': self._device.device_id,
'battery_low': self._device.battery_low,
'no_response': self._device.no_response,
@@ -327,7 +328,7 @@ class AbodeAutomation(Entity):
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
ATTR_ATTRIBUTION: ATTRIBUTION,
'automation_id': self._automation.automation_id,
'type': self._automation.type,
'sub_type': self._automation.sub_type

View File

@@ -2,7 +2,7 @@
import logging
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.abode import CONF_ATTRIBUTION, AbodeDevice
from homeassistant.components.abode import ATTRIBUTION, AbodeDevice
from homeassistant.components.abode import DOMAIN as ABODE_DOMAIN
from homeassistant.const import (
ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
@@ -73,7 +73,7 @@ class AbodeAlarm(AbodeDevice, alarm.AlarmControlPanel):
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
ATTR_ATTRIBUTION: ATTRIBUTION,
'device_id': self._device.device_id,
'battery_backup': self._device.battery,
'cellular_backup': self._device.is_cellular,

View File

@@ -4,9 +4,11 @@ import struct
import logging
import ctypes
from collections import namedtuple
import voluptuous as vol
from homeassistant.const import CONF_DEVICE, CONF_PORT, CONF_IP_ADDRESS, \
EVENT_HOMEASSISTANT_STOP
from homeassistant.const import (
CONF_DEVICE, CONF_IP_ADDRESS, CONF_PORT, EVENT_HOMEASSISTANT_STOP)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyads==3.0.7']
@@ -16,18 +18,20 @@ _LOGGER = logging.getLogger(__name__)
DATA_ADS = 'data_ads'
# Supported Types
ADSTYPE_INT = 'int'
ADSTYPE_UINT = 'uint'
ADSTYPE_BYTE = 'byte'
ADSTYPE_BOOL = 'bool'
ADSTYPE_BYTE = 'byte'
ADSTYPE_DINT = 'dint'
ADSTYPE_INT = 'int'
ADSTYPE_UDINT = 'udint'
ADSTYPE_UINT = 'uint'
DOMAIN = 'ads'
CONF_ADS_FACTOR = 'factor'
CONF_ADS_TYPE = 'adstype'
CONF_ADS_VALUE = 'value'
CONF_ADS_VAR = 'adsvar'
CONF_ADS_VAR_BRIGHTNESS = 'adsvar_brightness'
CONF_ADS_TYPE = 'adstype'
CONF_ADS_FACTOR = 'factor'
CONF_ADS_VALUE = 'value'
DOMAIN = 'ads'
SERVICE_WRITE_DATA_BY_NAME = 'write_data_by_name'
@@ -41,7 +45,8 @@ CONFIG_SCHEMA = vol.Schema({
SCHEMA_SERVICE_WRITE_DATA_BY_NAME = vol.Schema({
vol.Required(CONF_ADS_TYPE):
vol.In([ADSTYPE_INT, ADSTYPE_UINT, ADSTYPE_BYTE, ADSTYPE_BOOL]),
vol.In([ADSTYPE_INT, ADSTYPE_UINT, ADSTYPE_BYTE, ADSTYPE_BOOL,
ADSTYPE_DINT, ADSTYPE_UDINT]),
vol.Required(CONF_ADS_VALUE): vol.Coerce(int),
vol.Required(CONF_ADS_VAR): cv.string,
})
@@ -61,15 +66,19 @@ def setup(hass, config):
AdsHub.ADS_TYPEMAP = {
ADSTYPE_BOOL: pyads.PLCTYPE_BOOL,
ADSTYPE_BYTE: pyads.PLCTYPE_BYTE,
ADSTYPE_DINT: pyads.PLCTYPE_DINT,
ADSTYPE_INT: pyads.PLCTYPE_INT,
ADSTYPE_UDINT: pyads.PLCTYPE_UDINT,
ADSTYPE_UINT: pyads.PLCTYPE_UINT,
}
AdsHub.ADSError = pyads.ADSError
AdsHub.PLCTYPE_BOOL = pyads.PLCTYPE_BOOL
AdsHub.PLCTYPE_BYTE = pyads.PLCTYPE_BYTE
AdsHub.PLCTYPE_DINT = pyads.PLCTYPE_DINT
AdsHub.PLCTYPE_INT = pyads.PLCTYPE_INT
AdsHub.PLCTYPE_UDINT = pyads.PLCTYPE_UDINT
AdsHub.PLCTYPE_UINT = pyads.PLCTYPE_UINT
AdsHub.ADSError = pyads.ADSError
try:
ads = AdsHub(client)
@@ -192,6 +201,10 @@ class AdsHub:
value = struct.unpack('<B', bytearray(data)[:1])[0]
elif notification_item.plc_datatype == self.PLCTYPE_UINT:
value = struct.unpack('<H', bytearray(data)[:2])[0]
elif notification_item.plc_datatype == self.PLCTYPE_DINT:
value = struct.unpack('<i', bytearray(data)[:4])[0]
elif notification_item.plc_datatype == self.PLCTYPE_UDINT:
value = struct.unpack('<I', bytearray(data)[:4])[0]
else:
value = bytearray(data)
_LOGGER.warning("No callback available for this datatype")

View File

@@ -20,7 +20,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_ADS_VAR): cv.string,
vol.Optional(CONF_ADS_FACTOR): cv.positive_int,
vol.Optional(CONF_ADS_TYPE, default=ads.ADSTYPE_INT):
vol.In([ads.ADSTYPE_INT, ads.ADSTYPE_UINT, ads.ADSTYPE_BYTE]),
vol.In([ads.ADSTYPE_INT, ads.ADSTYPE_UINT, ads.ADSTYPE_BYTE,
ads.ADSTYPE_DINT, ads.ADSTYPE_UDINT]),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_UNIT_OF_MEASUREMENT, default=''): cv.string,
})

View File

@@ -17,7 +17,7 @@ from homeassistant.const import (CONF_LATITUDE, CONF_LONGITUDE,
from homeassistant.helpers.aiohttp_client import async_get_clientsession
REQUIREMENTS = ['pyMetno==0.4.5']
REQUIREMENTS = ['pyMetno==0.4.6']
_LOGGER = logging.getLogger(__name__)
@@ -91,7 +91,9 @@ class AirSensor(AirQualityEntity):
@property
def device_state_attributes(self) -> dict:
"""Return other details about the sensor state."""
return {'level': self._api.data.get('level')}
return {'level': self._api.data.get('level'),
'location': self._api.data.get('location'),
}
@property
def name(self) -> str:

View File

@@ -1,9 +1,4 @@
"""
Support for openSenseMap Air Quality data.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/air_quality.opensensemap/
"""
"""Support for openSenseMap Air Quality data."""
from datetime import timedelta
import logging
@@ -16,7 +11,7 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle
REQUIREMENTS = ['opensensemap-api==0.1.3']
REQUIREMENTS = ['opensensemap-api==0.1.4']
_LOGGER = logging.getLogger(__name__)

View File

@@ -11,8 +11,9 @@ import aiohttp
import async_timeout
from homeassistant.components import (
alert, automation, binary_sensor, climate, cover, fan, group, http,
alert, automation, binary_sensor, cover, fan, group, http,
input_boolean, light, lock, media_player, scene, script, sensor, switch)
from homeassistant.components.climate import const as climate
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.event import async_track_state_change
from homeassistant.const import (
@@ -22,7 +23,7 @@ from homeassistant.const import (
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_UP, SERVICE_VOLUME_SET,
SERVICE_VOLUME_MUTE, STATE_LOCKED, STATE_ON, STATE_UNAVAILABLE,
SERVICE_VOLUME_MUTE, STATE_LOCKED, STATE_ON, STATE_OFF, STATE_UNAVAILABLE,
STATE_UNLOCKED, TEMP_CELSIUS, TEMP_FAHRENHEIT, MATCH_ALL)
import homeassistant.core as ha
import homeassistant.util.color as color_util
@@ -58,7 +59,7 @@ API_THERMOSTAT_MODES = OrderedDict([
(climate.STATE_AUTO, 'AUTO'),
(climate.STATE_ECO, 'ECO'),
(climate.STATE_MANUAL, 'AUTO'),
(climate.STATE_OFF, 'OFF'),
(STATE_OFF, 'OFF'),
(climate.STATE_IDLE, 'OFF'),
(climate.STATE_FAN_ONLY, 'OFF'),
(climate.STATE_DRY, 'OFF'),
@@ -765,7 +766,7 @@ class _AlexaThermostatController(_AlexaInterface):
unit = self.hass.config.units.temperature_unit
if name == 'targetSetpoint':
temp = self.entity.attributes.get(climate.ATTR_TEMPERATURE)
temp = self.entity.attributes.get(ATTR_TEMPERATURE)
elif name == 'lowerSetpoint':
temp = self.entity.attributes.get(climate.ATTR_TARGET_TEMP_LOW)
elif name == 'upperSetpoint':

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Anwendungsschl\u00fcssel und / oder API-Schl\u00fcssel bereits registriert",
"invalid_key": "Ung\u00fcltiger API Key und / oder Anwendungsschl\u00fcssel",
"no_devices": "Keine Ger\u00e4te im Konto gefunden"
},
"step": {
"user": {
"data": {
"api_key": "API Key",
"app_key": "Anwendungsschl\u00fcssel"
},
"title": "Gib deine Informationen ein"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Clave de aplicaci\u00f3n y/o clave de API ya registrada",
"invalid_key": "Clave de API y/o clave de aplicaci\u00f3n no v\u00e1lida",
"no_devices": "No se han encontrado dispositivos en la cuenta."
},
"step": {
"user": {
"data": {
"api_key": "Clave API",
"app_key": "Clave de aplicaci\u00f3n"
},
"title": "Completa tu informaci\u00f3n"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,9 @@
{
"config": {
"step": {
"user": {
"title": "Completa tu informaci\u00f3n"
}
}
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"error": {
"no_devices": "\u05dc\u05d0 \u05e0\u05de\u05e6\u05d0\u05d5 \u05d4\u05ea\u05e7\u05df \u05d1\u05d7\u05e9\u05d1\u05d5\u05df"
},
"step": {
"user": {
"data": {
"api_key": "\u05de\u05e4\u05ea\u05d7 API"
},
"title": "\u05de\u05dc\u05d0 \u05d0\u05ea \u05d4\u05e4\u05e8\u05d8\u05d9\u05dd \u05e9\u05dc\u05da"
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Alkalmaz\u00e1s kulcsot \u00e9s/vagy az API kulcsot m\u00e1r regisztr\u00e1lt\u00e1k",
"invalid_key": "\u00c9rv\u00e9nytelen API kulcs \u00e9s / vagy alkalmaz\u00e1skulcs",
"no_devices": "Nincs a fi\u00f3kodban tal\u00e1lhat\u00f3 eszk\u00f6z"
},
"step": {
"user": {
"data": {
"api_key": "API kulcs",
"app_key": "Alkalmaz\u00e1skulcs"
},
"title": "T\u00f6ltsd ki az adataid"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"error": {
"identifier_exists": "API Key e/o Application Key gi\u00e0 registrata",
"invalid_key": "API Key e/o Application Key non valida",
"no_devices": "Nessun dispositivo trovato nell'account"
},
"step": {
"user": {
"data": {
"api_key": "API Key",
"app_key": "Application Key"
},
"title": "Inserisci i tuoi dati"
}
}
}
}

View File

@@ -1,11 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Chave de aplica\u00e7\u00e3o e/ou chave de API j\u00e1 registradas.",
"invalid_key": "Chave de API e/ou chave de aplica\u00e7\u00e3o inv\u00e1lidas",
"no_devices": "Nenhum dispositivo encontrado na conta"
},
"step": {
"user": {
"data": {
"api_key": "Chave de API"
}
"api_key": "Chave de API",
"app_key": "Chave de aplica\u00e7\u00e3o"
},
"title": "Preencha as suas informa\u00e7\u00f5es"
}
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Aplikacijski klju\u010d in / ali klju\u010d API je \u017ee registriran",
"invalid_key": "Neveljaven klju\u010d API in / ali klju\u010d aplikacije",
"no_devices": "V ra\u010dunu ni najdene nobene naprave"
},
"step": {
"user": {
"data": {
"api_key": "API Klju\u010d",
"app_key": "Klju\u010d aplikacije"
},
"title": "Izpolnite svoje podatke"
}
},
"title": "Ambient PWS"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Applikationsnyckel och/eller API-nyckel \u00e4r redan registrerade",
"invalid_key": "Ogiltigt API-nyckel och/eller applikationsnyckel",
"no_devices": "Inga enheter hittades i kontot"
},
"step": {
"user": {
"data": {
"api_key": "API-nyckel",
"app_key": "Applikationsnyckel"
},
"title": "Fyll i dina uppgifter"
}
},
"title": "Ambient Weather PWS (Personal Weather Station)"
}
}

View File

@@ -20,13 +20,14 @@ from .const import (
ATTR_LAST_DATA, CONF_APP_KEY, DATA_CLIENT, DOMAIN, TOPIC_UPDATE,
TYPE_BINARY_SENSOR, TYPE_SENSOR)
REQUIREMENTS = ['aioambient==0.1.2']
REQUIREMENTS = ['aioambient==0.1.3']
_LOGGER = logging.getLogger(__name__)
DATA_CONFIG = 'config'
DEFAULT_SOCKET_MIN_RETRY = 15
DEFAULT_WATCHDOG_SECONDS = 5 * 60
TYPE_24HOURRAININ = '24hourrainin'
TYPE_BAROMABSIN = 'baromabsin'
@@ -296,6 +297,7 @@ class AmbientStation:
"""Initialize."""
self._config_entry = config_entry
self._hass = hass
self._watchdog_listener = None
self._ws_reconnect_delay = DEFAULT_SOCKET_MIN_RETRY
self.client = client
self.monitored_conditions = monitored_conditions
@@ -305,9 +307,18 @@ class AmbientStation:
"""Register handlers and connect to the websocket."""
from aioambient.errors import WebsocketError
async def _ws_reconnect(event_time):
"""Forcibly disconnect from and reconnect to the websocket."""
_LOGGER.debug('Watchdog expired; forcing socket reconnection')
await self.client.websocket.disconnect()
await self.client.websocket.connect()
def on_connect():
"""Define a handler to fire when the websocket is connected."""
_LOGGER.info('Connected to websocket')
_LOGGER.debug('Watchdog starting')
self._watchdog_listener = async_call_later(
self._hass, DEFAULT_WATCHDOG_SECONDS, _ws_reconnect)
def on_data(data):
"""Define a handler to fire when the data is received."""
@@ -317,6 +328,11 @@ class AmbientStation:
self.stations[mac_address][ATTR_LAST_DATA] = data
async_dispatcher_send(self._hass, TOPIC_UPDATE)
_LOGGER.debug('Resetting watchdog')
self._watchdog_listener()
self._watchdog_listener = async_call_later(
self._hass, DEFAULT_WATCHDOG_SECONDS, _ws_reconnect)
def on_disconnect():
"""Define a handler to fire when the websocket is disconnected."""
_LOGGER.info('Disconnected from websocket')

View File

@@ -15,7 +15,7 @@ REQUIREMENTS = ['pyarlo==0.2.3']
_LOGGER = logging.getLogger(__name__)
CONF_ATTRIBUTION = "Data provided by arlo.netgear.com"
ATTRIBUTION = "Data provided by arlo.netgear.com"
DATA_ARLO = 'data_arlo'
DEFAULT_BRAND = 'Netgear Arlo'

View File

@@ -9,7 +9,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.components.alarm_control_panel import (
AlarmControlPanel, PLATFORM_SCHEMA)
from homeassistant.components.arlo import (
DATA_ARLO, CONF_ATTRIBUTION, SIGNAL_UPDATE_ARLO)
DATA_ARLO, ATTRIBUTION, SIGNAL_UPDATE_ARLO)
from homeassistant.const import (
ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_NIGHT)
@@ -117,7 +117,7 @@ class ArloBaseStation(AlarmControlPanel):
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
ATTR_ATTRIBUTION: ATTRIBUTION,
'device_id': self._base_station.device_id
}

View File

@@ -6,7 +6,7 @@ import voluptuous as vol
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.components.arlo import (
CONF_ATTRIBUTION, DEFAULT_BRAND, DATA_ARLO, SIGNAL_UPDATE_ARLO)
ATTRIBUTION, DEFAULT_BRAND, DATA_ARLO, SIGNAL_UPDATE_ARLO)
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (
ATTR_ATTRIBUTION, CONF_MONITORED_CONDITIONS, TEMP_CELSIUS,
@@ -177,7 +177,7 @@ class ArloSensor(Entity):
"""Return the device state attributes."""
attrs = {}
attrs[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION
attrs[ATTR_ATTRIBUTION] = ATTRIBUTION
attrs['brand'] = DEFAULT_BRAND
if self._sensor_type != 'total_cameras':

View File

@@ -1,8 +1,27 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "No hay servicios de notificaci\u00f3n disponibles."
},
"error": {
"invalid_code": "C\u00f3digo inv\u00e1lido, por favor int\u00e9ntelo de nuevo."
},
"step": {
"init": {
"description": "Por favor seleccione uno de los servicios de notificaci\u00f3n:",
"title": "Configure la contrase\u00f1a de un solo uso entregada por el componente de notificaci\u00f3n"
},
"setup": {
"description": "Se ha enviado una contrase\u00f1a \u00fanica a trav\u00e9s de **notify.{notify_service}**. Por favor ingr\u00e9selo a continuaci\u00f3n:",
"title": "Verificar la configuracion"
}
}
},
"totp": {
"step": {
"init": {
"description": "Para activar la autenticaci\u00f3n de dos factores utilizando contrase\u00f1as de un solo uso basadas en el tiempo, escanee el c\u00f3digo QR con su aplicaci\u00f3n de autenticaci\u00f3n. Si no tiene uno, le recomendamos [Autenticador de Google] (https://support.google.com/accounts/answer/1066447) o [Authy] (https://authy.com/). \n\n {qr_code} \n \n Despu\u00e9s de escanear el c\u00f3digo, ingrese el c\u00f3digo de seis d\u00edgitos de su aplicaci\u00f3n para verificar la configuraci\u00f3n. Si tiene problemas para escanear el c\u00f3digo QR, realice una configuraci\u00f3n manual con el c\u00f3digo ** ` {code} ` **.",
"title": "Configurar la autenticaci\u00f3n de dos factores mediante TOTP"
}
},

View File

@@ -9,7 +9,8 @@
},
"step": {
"init": {
"description": "V\u00e1lassz \u00e9rtes\u00edt\u00e9si szolg\u00e1ltat\u00e1st:"
"description": "V\u00e1lassz \u00e9rtes\u00edt\u00e9si szolg\u00e1ltat\u00e1st:",
"title": "\u00c1ll\u00edtsa be az \u00e9rtes\u00edt\u00e9si \u00f6sszetev\u0151 \u00e1ltal megadott egyszeri jelsz\u00f3t"
},
"setup": {
"title": "Be\u00e1ll\u00edt\u00e1s ellen\u0151rz\u00e9se"

View File

@@ -9,7 +9,8 @@
},
"step": {
"init": {
"description": "Selezionare uno dei servizi di notifica:"
"description": "Selezionare uno dei servizi di notifica:",
"title": "Imposta la password one-time fornita dal componente di notifica"
},
"setup": {
"description": "\u00c8 stata inviata una password monouso tramite **notify.{notify_service}**. Per favore, inseriscila qui sotto:",

View File

@@ -21,11 +21,11 @@
},
"totp": {
"error": {
"invalid_code": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430. \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0435 \u044d\u0442\u0443 \u043e\u0448\u0438\u0431\u043a\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0447\u0430\u0441\u044b \u0432 \u0432\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 Home Assistant \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f."
"invalid_code": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430. \u0415\u0441\u043b\u0438 \u0412\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0435 \u044d\u0442\u0443 \u043e\u0448\u0438\u0431\u043a\u0443, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0447\u0430\u0441\u044b \u0432 \u0412\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 Home Assistant \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f."
},
"step": {
"init": {
"description": "\u0427\u0442\u043e\u0431\u044b \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0443\u044e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0434\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u044b\u0445 \u043f\u0430\u0440\u043e\u043b\u0435\u0439, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043e\u0442\u0441\u043a\u0430\u043d\u0438\u0440\u0443\u0439\u0442\u0435 QR-\u043a\u043e\u0434 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u043e\u0434\u043b\u0438\u043d\u043d\u043e\u0441\u0442\u0438. \u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0433\u043e \u043d\u0435\u0442, \u043c\u044b \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0431\u043e [Google Authenticator](https://support.google.com/accounts/answer/1066447), \u043b\u0438\u0431\u043e [Authy](https://authy.com/). \n\n {qr_code} \n \n\u041f\u043e\u0441\u043b\u0435 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f QR-\u043a\u043e\u0434\u0430 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0448\u0435\u0441\u0442\u0438\u0437\u043d\u0430\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438\u0437 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443. \u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u043e \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c QR-\u043a\u043e\u0434\u0430, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0434\u0430 **`{code}`**.",
"description": "\u0427\u0442\u043e\u0431\u044b \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0443\u044e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0434\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u044b\u0445 \u043f\u0430\u0440\u043e\u043b\u0435\u0439, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043e\u0442\u0441\u043a\u0430\u043d\u0438\u0440\u0443\u0439\u0442\u0435 QR-\u043a\u043e\u0434 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u043e\u0434\u043b\u0438\u043d\u043d\u043e\u0441\u0442\u0438. \u0415\u0441\u043b\u0438 \u0443 \u0412\u0430\u0441 \u0435\u0433\u043e \u043d\u0435\u0442, \u043c\u044b \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0431\u043e [Google Authenticator](https://support.google.com/accounts/answer/1066447), \u043b\u0438\u0431\u043e [Authy](https://authy.com/). \n\n {qr_code} \n \n\u041f\u043e\u0441\u043b\u0435 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f QR-\u043a\u043e\u0434\u0430 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0448\u0435\u0441\u0442\u0438\u0437\u043d\u0430\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438\u0437 \u0412\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443. \u0415\u0441\u043b\u0438 \u0443 \u0412\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u043e \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c QR-\u043a\u043e\u0434\u0430, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0434\u0430 **`{code}`**.",
"title": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c TOTP"
}
},

View File

@@ -19,8 +19,8 @@ from homeassistant.util import Throttle
_LOGGER = logging.getLogger(__name__)
CONF_ATTRIBUTION = "Data provided by the National Oceanic and Atmospheric" \
"Administration"
ATTRIBUTION = "Data provided by the National Oceanic and Atmospheric " \
"Administration"
CONF_THRESHOLD = 'forecast_threshold'
DEFAULT_DEVICE_CLASS = 'visible'
@@ -91,7 +91,7 @@ class AuroraSensor(BinarySensorDevice):
if self.aurora_data:
attrs['visibility_level'] = self.aurora_data.visibility_level
attrs['message'] = self.aurora_data.is_visible_text
attrs[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION
attrs[ATTR_ATTRIBUTION] = ATTRIBUTION
return attrs
def update(self):

View File

@@ -18,7 +18,7 @@ from homeassistant.const import (
CONF_SSL, EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START,
ATTR_LAST_TRIP_TIME, CONF_CUSTOMIZE)
REQUIREMENTS = ['pyhik==0.1.9']
REQUIREMENTS = ['pyhik==0.2.2']
_LOGGER = logging.getLogger(__name__)
CONF_IGNORED = 'ignored'
@@ -51,6 +51,8 @@ DEVICE_CLASS_MAP = {
'Unattended Baggage': 'motion',
'Attended Baggage': 'motion',
'Recording Failure': None,
'Exiting Region': 'motion',
'Entering Region': 'motion',
}
CUSTOMIZE_SCHEMA = vol.Schema({

View File

@@ -14,7 +14,7 @@ from homeassistant.components.binary_sensor import (
from homeassistant.components.sensor.rest import RestData
from homeassistant.const import (
CONF_PAYLOAD, CONF_NAME, CONF_VALUE_TEMPLATE, CONF_METHOD, CONF_RESOURCE,
CONF_VERIFY_SSL, CONF_USERNAME, CONF_PASSWORD,
CONF_VERIFY_SSL, CONF_USERNAME, CONF_PASSWORD, CONF_TIMEOUT,
CONF_HEADERS, CONF_AUTHENTICATION, HTTP_BASIC_AUTHENTICATION,
HTTP_DIGEST_AUTHENTICATION, CONF_DEVICE_CLASS)
import homeassistant.helpers.config_validation as cv
@@ -25,6 +25,7 @@ _LOGGER = logging.getLogger(__name__)
DEFAULT_METHOD = 'GET'
DEFAULT_NAME = 'REST Binary Sensor'
DEFAULT_VERIFY_SSL = True
DEFAULT_TIMEOUT = 10
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_RESOURCE): cv.url,
@@ -39,6 +40,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_USERNAME): cv.string,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
})
@@ -49,6 +51,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
method = config.get(CONF_METHOD)
payload = config.get(CONF_PAYLOAD)
verify_ssl = config.get(CONF_VERIFY_SSL)
timeout = config.get(CONF_TIMEOUT)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
headers = config.get(CONF_HEADERS)
@@ -65,7 +68,8 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
else:
auth = None
rest = RestData(method, resource, auth, headers, payload, verify_ssl)
rest = RestData(method, resource, auth, headers, payload, verify_ssl,
timeout)
rest.update()
if rest.data is None:
raise PlatformNotReady

View File

@@ -11,7 +11,7 @@ import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.ring import (
CONF_ATTRIBUTION, DEFAULT_ENTITY_NAMESPACE, DATA_RING)
ATTRIBUTION, DEFAULT_ENTITY_NAMESPACE, DATA_RING)
from homeassistant.const import (
ATTR_ATTRIBUTION, CONF_ENTITY_NAMESPACE, CONF_MONITORED_CONDITIONS)
@@ -47,18 +47,14 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
for device in ring.doorbells: # ring.doorbells is doing I/O
for sensor_type in config[CONF_MONITORED_CONDITIONS]:
if 'doorbell' in SENSOR_TYPES[sensor_type][1]:
sensors.append(RingBinarySensor(hass,
device,
sensor_type))
sensors.append(RingBinarySensor(hass, device, sensor_type))
for device in ring.stickup_cams: # ring.stickup_cams is doing I/O
for sensor_type in config[CONF_MONITORED_CONDITIONS]:
if 'stickup_cams' in SENSOR_TYPES[sensor_type][1]:
sensors.append(RingBinarySensor(hass,
device,
sensor_type))
sensors.append(RingBinarySensor(hass, device, sensor_type))
add_entities(sensors, True)
return True
class RingBinarySensor(BinarySensorDevice):
@@ -69,8 +65,8 @@ class RingBinarySensor(BinarySensorDevice):
super(RingBinarySensor, self).__init__()
self._sensor_type = sensor_type
self._data = data
self._name = "{0} {1}".format(self._data.name,
SENSOR_TYPES.get(self._sensor_type)[0])
self._name = "{0} {1}".format(
self._data.name, SENSOR_TYPES.get(self._sensor_type)[0])
self._device_class = SENSOR_TYPES.get(self._sensor_type)[2]
self._state = None
self._unique_id = '{}-{}'.format(self._data.id, self._sensor_type)
@@ -99,7 +95,7 @@ class RingBinarySensor(BinarySensorDevice):
def device_state_attributes(self):
"""Return the state attributes."""
attrs = {}
attrs[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION
attrs[ATTR_ATTRIBUTION] = ATTRIBUTION
attrs['device_id'] = self._data.id
attrs['firmware'] = self._data.firmware

View File

@@ -0,0 +1,217 @@
"""Support for representing current time of the day as binary sensors."""
from datetime import datetime, timedelta
import logging
import pytz
import voluptuous as vol
from homeassistant.components.binary_sensor import (
PLATFORM_SCHEMA, BinarySensorDevice)
from homeassistant.const import (
CONF_AFTER, CONF_BEFORE, CONF_NAME, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET)
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import async_track_point_in_utc_time
from homeassistant.helpers.sun import (
get_astral_event_date, get_astral_event_next)
from homeassistant.util import dt as dt_util
_LOGGER = logging.getLogger(__name__)
ATTR_AFTER = 'after'
ATTR_BEFORE = 'before'
ATTR_NEXT_UPDATE = 'next_update'
CONF_AFTER_OFFSET = 'after_offset'
CONF_BEFORE_OFFSET = 'before_offset'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_AFTER):
vol.Any(cv.time, vol.All(vol.Lower, cv.sun_event)),
vol.Required(CONF_BEFORE):
vol.Any(cv.time, vol.All(vol.Lower, cv.sun_event)),
vol.Required(CONF_NAME): cv.string,
vol.Optional(CONF_AFTER_OFFSET, default=timedelta(0)): cv.time_period,
vol.Optional(CONF_BEFORE_OFFSET, default=timedelta(0)): cv.time_period,
})
async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None):
"""Set up the ToD sensors."""
if hass.config.time_zone is None:
_LOGGER.error("Timezone is not set in Home Assistant configuration")
return
after = config[CONF_AFTER]
after_offset = config[CONF_AFTER_OFFSET]
before = config[CONF_BEFORE]
before_offset = config[CONF_BEFORE_OFFSET]
name = config[CONF_NAME]
sensor = TodSensor(name, after, after_offset, before, before_offset)
async_add_entities([sensor])
def is_sun_event(event):
"""Return true if event is sun event not time."""
return event in (SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET)
class TodSensor(BinarySensorDevice):
"""Time of the Day Sensor."""
def __init__(self, name, after, after_offset, before, before_offset):
"""Init the ToD Sensor..."""
self._name = name
self._time_before = self._time_after = self._next_update = None
self._after_offset = after_offset
self._before_offset = before_offset
self._before = before
self._after = after
@property
def should_poll(self):
"""Sensor does not need to be polled."""
return False
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def after(self):
"""Return the timestamp for the begining of the period."""
return self._time_after
@property
def before(self):
"""Return the timestamp for the end of the period."""
return self._time_before
@property
def is_on(self):
"""Return True is sensor is on."""
if self.after < self.before:
return self.after <= self.current_datetime < self.before
return False
@property
def current_datetime(self):
"""Return local current datetime according to hass configuration."""
return dt_util.utcnow()
@property
def next_update(self):
"""Return the next update point in the UTC time."""
return self._next_update
@property
def device_state_attributes(self):
"""Return the state attributes of the sensor."""
return {
ATTR_AFTER: self.after.astimezone(
self.hass.config.time_zone).isoformat(),
ATTR_BEFORE: self.before.astimezone(
self.hass.config.time_zone).isoformat(),
ATTR_NEXT_UPDATE: self.next_update.astimezone(
self.hass.config.time_zone).isoformat(),
}
def _calculate_initial_boudary_time(self):
"""Calculate internal absolute time boudaries."""
nowutc = self.current_datetime
# If after value is a sun event instead of absolute time
if is_sun_event(self._after):
# Calculate the today's event utc time or
# if not available take next
after_event_date = \
get_astral_event_date(self.hass, self._after, nowutc) or \
get_astral_event_next(self.hass, self._after, nowutc)
else:
# Convert local time provided to UTC today
# datetime.combine(date, time, tzinfo) is not supported
# in python 3.5. The self._after is provided
# with hass configured TZ not system wide
after_event_date = datetime.combine(
nowutc, self._after.replace(
tzinfo=self.hass.config.time_zone)).astimezone(tz=pytz.UTC)
self._time_after = after_event_date
# If before value is a sun event instead of absolute time
if is_sun_event(self._before):
# Calculate the today's event utc time or if not available take
# next
before_event_date = \
get_astral_event_date(self.hass, self._before, nowutc) or \
get_astral_event_next(self.hass, self._before, nowutc)
# Before is earlier than after
if before_event_date < after_event_date:
# Take next day for before
before_event_date = get_astral_event_next(
self.hass, self._before, after_event_date)
else:
# Convert local time provided to UTC today, see above
before_event_date = datetime.combine(
nowutc, self._before.replace(
tzinfo=self.hass.config.time_zone)).astimezone(tz=pytz.UTC)
# It is safe to add timedelta days=1 to UTC as there is no DST
if before_event_date < after_event_date + self._after_offset:
before_event_date += timedelta(days=1)
self._time_before = before_event_date
# Add offset to utc boundaries according to the configuration
self._time_after += self._after_offset
self._time_before += self._before_offset
def _turn_to_next_day(self):
"""Turn to to the next day."""
if is_sun_event(self._after):
self._time_after = get_astral_event_next(
self.hass, self._after,
self._time_after - self._after_offset)
self._time_after += self._after_offset
else:
# Offset is already there
self._time_after += timedelta(days=1)
if is_sun_event(self._before):
self._time_before = get_astral_event_next(
self.hass, self._before,
self._time_before - self._before_offset)
self._time_before += self._before_offset
else:
# Offset is already there
self._time_before += timedelta(days=1)
async def async_added_to_hass(self):
"""Call when entity about to be added to Home Assistant."""
await super().async_added_to_hass()
self._calculate_initial_boudary_time()
self._calculate_next_update()
self._point_in_time_listener(dt_util.now())
def _calculate_next_update(self):
"""Datetime when the next update to the state."""
now = self.current_datetime
if now < self.after:
self._next_update = self.after
return
if now < self.before:
self._next_update = self.before
return
self._turn_to_next_day()
self._next_update = self.after
@callback
def _point_in_time_listener(self, now):
"""Run when the state of the sensor should be updated."""
self._calculate_next_update()
self.async_schedule_update_ha_state()
async_track_point_in_utc_time(
self.hass, self._point_in_time_listener, self.next_update)

View File

@@ -1,9 +1,4 @@
"""
A sensor that monitors trends in other components.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.trend/
"""
"""A sensor that monitors trends in other components."""
from collections import deque
import logging
import math
@@ -22,7 +17,7 @@ from homeassistant.helpers.entity import generate_entity_id
from homeassistant.helpers.event import async_track_state_change
from homeassistant.util import utcnow
REQUIREMENTS = ['numpy==1.16.0']
REQUIREMENTS = ['numpy==1.16.1']
_LOGGER = logging.getLogger(__name__)

View File

@@ -19,7 +19,7 @@ _LOGGER = logging.getLogger(__name__)
ATTR_TARGET = 'target'
CONF_ATTRIBUTION = "Data provided by Uptime Robot"
ATTRIBUTION = "Data provided by Uptime Robot"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_API_KEY): cv.string,
@@ -78,7 +78,7 @@ class UptimeRobotBinarySensor(BinarySensorDevice):
def device_state_attributes(self):
"""Return the state attributes of the binary sensor."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
ATTR_ATTRIBUTION: ATTRIBUTION,
ATTR_TARGET: self._target,
}

View File

@@ -66,7 +66,7 @@ class BloomSky:
self.API_URL, headers={AUTHORIZATION: self._api_key}, timeout=10)
if response.status_code == 401:
raise RuntimeError("Invalid API_KEY")
elif response.status_code != 200:
if response.status_code != 200:
_LOGGER.error("Invalid HTTP response: %s", response.status_code)
return
# Create dictionary keyed off of the device unique id

View File

@@ -13,7 +13,7 @@ import voluptuous as vol
from homeassistant.helpers import config_validation as cv
from homeassistant.components.ring import (
DATA_RING, CONF_ATTRIBUTION, NOTIFICATION_ID)
DATA_RING, ATTRIBUTION, NOTIFICATION_ID)
from homeassistant.components.camera import Camera, PLATFORM_SCHEMA
from homeassistant.components.ffmpeg import DATA_FFMPEG
from homeassistant.const import ATTR_ATTRIBUTION, CONF_SCAN_INTERVAL
@@ -34,8 +34,7 @@ SCAN_INTERVAL = timedelta(seconds=90)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_FFMPEG_ARGUMENTS): cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL):
cv.time_period,
vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period,
})
@@ -106,7 +105,7 @@ class RingCam(Camera):
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
ATTR_ATTRIBUTION: ATTRIBUTION,
'device_id': self._camera.id,
'firmware': self._camera.firmware,
'kind': self._camera.kind,

View File

@@ -51,6 +51,17 @@ from .const import (
SERVICE_SET_OPERATION_MODE,
SERVICE_SET_SWING_MODE,
SERVICE_SET_TEMPERATURE,
SUPPORT_TARGET_TEMPERATURE_HIGH,
SUPPORT_TARGET_TEMPERATURE_LOW,
SUPPORT_TARGET_HUMIDITY,
SUPPORT_TARGET_HUMIDITY_HIGH,
SUPPORT_TARGET_HUMIDITY_LOW,
SUPPORT_FAN_MODE,
SUPPORT_OPERATION_MODE,
SUPPORT_HOLD_MODE,
SUPPORT_SWING_MODE,
SUPPORT_AWAY_MODE,
SUPPORT_AUX_HEAT,
)
from .reproduce_state import async_reproduce_states # noqa
@@ -62,29 +73,6 @@ DEFAULT_MAX_HUMIDITY = 99
ENTITY_ID_FORMAT = DOMAIN + '.{}'
SCAN_INTERVAL = timedelta(seconds=60)
STATE_HEAT = 'heat'
STATE_COOL = 'cool'
STATE_IDLE = 'idle'
STATE_AUTO = 'auto'
STATE_MANUAL = 'manual'
STATE_DRY = 'dry'
STATE_FAN_ONLY = 'fan_only'
STATE_ECO = 'eco'
SUPPORT_TARGET_TEMPERATURE = 1
SUPPORT_TARGET_TEMPERATURE_HIGH = 2
SUPPORT_TARGET_TEMPERATURE_LOW = 4
SUPPORT_TARGET_HUMIDITY = 8
SUPPORT_TARGET_HUMIDITY_HIGH = 16
SUPPORT_TARGET_HUMIDITY_LOW = 32
SUPPORT_FAN_MODE = 64
SUPPORT_OPERATION_MODE = 128
SUPPORT_HOLD_MODE = 256
SUPPORT_SWING_MODE = 512
SUPPORT_AWAY_MODE = 1024
SUPPORT_AUX_HEAT = 2048
SUPPORT_ON_OFF = 4096
CONVERTIBLE_ATTRIBUTE = [
ATTR_TEMPERATURE,
ATTR_TARGET_TEMP_LOW,

View File

@@ -20,6 +20,11 @@ ATTR_TARGET_TEMP_HIGH = 'target_temp_high'
ATTR_TARGET_TEMP_LOW = 'target_temp_low'
ATTR_TARGET_TEMP_STEP = 'target_temp_step'
DEFAULT_MIN_TEMP = 7
DEFAULT_MAX_TEMP = 35
DEFAULT_MIN_HUMITIDY = 30
DEFAULT_MAX_HUMIDITY = 99
DOMAIN = 'climate'
SERVICE_SET_AUX_HEAT = 'set_aux_heat'
@@ -30,3 +35,26 @@ SERVICE_SET_HUMIDITY = 'set_humidity'
SERVICE_SET_OPERATION_MODE = 'set_operation_mode'
SERVICE_SET_SWING_MODE = 'set_swing_mode'
SERVICE_SET_TEMPERATURE = 'set_temperature'
STATE_HEAT = 'heat'
STATE_COOL = 'cool'
STATE_IDLE = 'idle'
STATE_AUTO = 'auto'
STATE_MANUAL = 'manual'
STATE_DRY = 'dry'
STATE_FAN_ONLY = 'fan_only'
STATE_ECO = 'eco'
SUPPORT_TARGET_TEMPERATURE = 1
SUPPORT_TARGET_TEMPERATURE_HIGH = 2
SUPPORT_TARGET_TEMPERATURE_LOW = 4
SUPPORT_TARGET_HUMIDITY = 8
SUPPORT_TARGET_HUMIDITY_HIGH = 16
SUPPORT_TARGET_HUMIDITY_LOW = 32
SUPPORT_FAN_MODE = 64
SUPPORT_OPERATION_MODE = 128
SUPPORT_HOLD_MODE = 256
SUPPORT_SWING_MODE = 512
SUPPORT_AWAY_MODE = 1024
SUPPORT_AUX_HEAT = 2048
SUPPORT_ON_OFF = 4096

View File

@@ -9,10 +9,11 @@ import logging
import voluptuous as vol
from homeassistant.components.climate import (
PLATFORM_SCHEMA, STATE_AUTO, STATE_COOL, STATE_DRY, STATE_FAN_ONLY,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
STATE_AUTO, STATE_COOL, STATE_DRY, STATE_FAN_ONLY,
STATE_HEAT, SUPPORT_FAN_MODE, SUPPORT_ON_OFF, SUPPORT_OPERATION_MODE,
SUPPORT_TARGET_TEMPERATURE, ClimateDevice)
SUPPORT_TARGET_TEMPERATURE)
from homeassistant.const import (
ATTR_TEMPERATURE, CONF_HOST, CONF_PORT, TEMP_CELSIUS, TEMP_FAHRENHEIT)
import homeassistant.helpers.config_validation as cv

View File

@@ -4,8 +4,9 @@ Demo platform that offers a fake climate device.
For more details about this platform, please refer to the documentation
https://home-assistant.io/components/demo/
"""
from homeassistant.components.climate import (
ClimateDevice, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW,
from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import (
ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_TARGET_HUMIDITY,
SUPPORT_TARGET_HUMIDITY_LOW, SUPPORT_TARGET_HUMIDITY_HIGH,
SUPPORT_AWAY_MODE, SUPPORT_HOLD_MODE, SUPPORT_FAN_MODE,

View File

@@ -7,8 +7,9 @@ https://home-assistant.io/components/climate.dyson/
import logging
from homeassistant.components.dyson import DYSON_DEVICES
from homeassistant.components.climate import (
ClimateDevice, STATE_HEAT, STATE_COOL, STATE_IDLE,
from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import (
STATE_HEAT, STATE_COOL, STATE_IDLE,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE, SUPPORT_OPERATION_MODE)
from homeassistant.const import TEMP_CELSIUS, ATTR_TEMPERATURE

View File

@@ -8,12 +8,12 @@ import logging
from datetime import timedelta
import voluptuous as vol
from homeassistant.components.climate import (
ClimateDevice, PLATFORM_SCHEMA, STATE_HEAT, STATE_OFF,
STATE_AUTO, SUPPORT_AUX_HEAT, SUPPORT_OPERATION_MODE,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
STATE_HEAT, STATE_AUTO, SUPPORT_AUX_HEAT, SUPPORT_OPERATION_MODE,
SUPPORT_TARGET_TEMPERATURE)
from homeassistant.const import (
TEMP_CELSIUS, CONF_USERNAME, CONF_PASSWORD, ATTR_TEMPERATURE)
ATTR_TEMPERATURE, TEMP_CELSIUS, CONF_USERNAME, CONF_PASSWORD, STATE_OFF)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyephember==0.2.0']

View File

@@ -8,13 +8,14 @@ import logging
import voluptuous as vol
from homeassistant.components.climate import (
STATE_ON, STATE_OFF, STATE_HEAT, STATE_MANUAL, STATE_ECO, PLATFORM_SCHEMA,
ClimateDevice,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
STATE_HEAT, STATE_MANUAL, STATE_ECO,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, SUPPORT_AWAY_MODE,
SUPPORT_ON_OFF)
from homeassistant.const import (
CONF_MAC, CONF_DEVICES, TEMP_CELSIUS, ATTR_TEMPERATURE, PRECISION_HALVES)
ATTR_TEMPERATURE, CONF_MAC, CONF_DEVICES, STATE_ON, STATE_OFF,
TEMP_CELSIUS, PRECISION_HALVES)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['python-eq3bt==0.1.9', 'construct==2.9.45']

View File

@@ -17,8 +17,9 @@ import voluptuous as vol
from homeassistant.const import (
CONF_NAME, CONF_SLAVE, TEMP_CELSIUS,
ATTR_TEMPERATURE, DEVICE_DEFAULT_NAME)
from homeassistant.components.climate import (
ClimateDevice, PLATFORM_SCHEMA, SUPPORT_TARGET_TEMPERATURE,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
SUPPORT_TARGET_TEMPERATURE,
SUPPORT_FAN_MODE)
from homeassistant.components.modbus import (
CONF_HUB, DEFAULT_HUB, DOMAIN as MODBUS_DOMAIN)

View File

@@ -11,10 +11,11 @@ import voluptuous as vol
from homeassistant.core import callback
from homeassistant.core import DOMAIN as HA_DOMAIN
from homeassistant.components.climate import (
STATE_HEAT, STATE_COOL, STATE_IDLE, STATE_AUTO, ClimateDevice,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
STATE_HEAT, STATE_COOL, STATE_IDLE, STATE_AUTO,
ATTR_OPERATION_MODE, ATTR_AWAY_MODE, SUPPORT_OPERATION_MODE,
SUPPORT_AWAY_MODE, SUPPORT_TARGET_TEMPERATURE, PLATFORM_SCHEMA)
SUPPORT_AWAY_MODE, SUPPORT_TARGET_TEMPERATURE)
from homeassistant.const import (
STATE_ON, STATE_OFF, ATTR_TEMPERATURE, CONF_NAME, ATTR_ENTITY_ID,
SERVICE_TURN_ON, SERVICE_TURN_OFF, STATE_UNKNOWN, PRECISION_HALVES,

View File

@@ -8,8 +8,9 @@ import logging
import voluptuous as vol
from homeassistant.components.climate import (
ClimateDevice, PLATFORM_SCHEMA, SUPPORT_TARGET_TEMPERATURE)
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
SUPPORT_TARGET_TEMPERATURE)
from homeassistant.const import (
TEMP_CELSIUS, ATTR_TEMPERATURE, CONF_PORT, CONF_NAME, CONF_ID)
import homeassistant.helpers.config_validation as cv

View File

@@ -12,8 +12,9 @@ import requests
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.climate import (
ClimateDevice, PLATFORM_SCHEMA, ATTR_FAN_MODE, ATTR_FAN_LIST,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
ATTR_FAN_MODE, ATTR_FAN_LIST,
ATTR_OPERATION_MODE, ATTR_OPERATION_LIST, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_AWAY_MODE, SUPPORT_OPERATION_MODE)
from homeassistant.const import (

View File

@@ -6,8 +6,9 @@ https://home-assistant.io/components/climate.melissa/
"""
import logging
from homeassistant.components.climate import (
ClimateDevice, SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE,
from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import (
SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_ON_OFF, STATE_AUTO, STATE_HEAT, STATE_COOL, STATE_DRY,
STATE_FAN_ONLY, SUPPORT_FAN_MODE
)

View File

@@ -9,8 +9,9 @@ import logging
import voluptuous as vol
from homeassistant.components.climate import (
ClimateDevice, DOMAIN, PLATFORM_SCHEMA, STATE_HEAT,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
DOMAIN, STATE_HEAT,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE,
SUPPORT_ON_OFF, SUPPORT_OPERATION_MODE)
from homeassistant.const import (

View File

@@ -9,8 +9,8 @@ from datetime import timedelta
import voluptuous as vol
from homeassistant.components.climate import (
ClimateDevice,
from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import (
DOMAIN,
SUPPORT_HOLD_MODE,
SUPPORT_OPERATION_MODE,

View File

@@ -13,11 +13,12 @@ import requests
import voluptuous as vol
# Import the device class from the component that you want to support
from homeassistant.components.climate import (
ClimateDevice, PLATFORM_SCHEMA, STATE_HEAT, STATE_IDLE, ATTR_TEMPERATURE,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_AWAY_MODE)
from homeassistant.const import (CONF_HOST, CONF_USERNAME, CONF_PASSWORD,
CONF_PORT, TEMP_CELSIUS, CONF_NAME)
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
STATE_HEAT, STATE_IDLE, SUPPORT_TARGET_TEMPERATURE, SUPPORT_AWAY_MODE)
from homeassistant.const import (
ATTR_TEMPERATURE, CONF_HOST, CONF_USERNAME, CONF_PASSWORD,
CONF_PORT, TEMP_CELSIUS, CONF_NAME)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['oemthermostat==1.1']

View File

@@ -6,11 +6,12 @@ https://home-assistant.io/components/climate.proliphix/
"""
import voluptuous as vol
from homeassistant.components.climate import (
PRECISION_TENTHS, STATE_COOL, STATE_HEAT, STATE_IDLE,
ClimateDevice, PLATFORM_SCHEMA, SUPPORT_TARGET_TEMPERATURE)
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
STATE_COOL, STATE_HEAT, STATE_IDLE, SUPPORT_TARGET_TEMPERATURE)
from homeassistant.const import (
CONF_HOST, CONF_PASSWORD, CONF_USERNAME, TEMP_FAHRENHEIT, ATTR_TEMPERATURE)
CONF_HOST, CONF_PASSWORD, CONF_USERNAME, PRECISION_TENTHS, TEMP_FAHRENHEIT,
ATTR_TEMPERATURE)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['proliphix==0.4.1']

View File

@@ -9,12 +9,14 @@ import logging
import voluptuous as vol
from homeassistant.components.climate import (
STATE_AUTO, STATE_COOL, STATE_HEAT, STATE_IDLE, STATE_ON, STATE_OFF,
ClimateDevice, PLATFORM_SCHEMA, SUPPORT_TARGET_TEMPERATURE,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
STATE_AUTO, STATE_COOL, STATE_HEAT, STATE_IDLE,
SUPPORT_TARGET_TEMPERATURE,
SUPPORT_OPERATION_MODE, SUPPORT_FAN_MODE, SUPPORT_AWAY_MODE)
from homeassistant.const import (
CONF_HOST, TEMP_FAHRENHEIT, ATTR_TEMPERATURE, PRECISION_HALVES)
ATTR_TEMPERATURE, CONF_HOST, PRECISION_HALVES, TEMP_FAHRENHEIT, STATE_ON,
STATE_OFF)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['radiotherm==2.0.0']

View File

@@ -15,8 +15,9 @@ import voluptuous as vol
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_STATE, ATTR_TEMPERATURE, CONF_API_KEY, CONF_ID,
STATE_ON, STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT)
from homeassistant.components.climate import (
ATTR_CURRENT_HUMIDITY, ClimateDevice, DOMAIN, PLATFORM_SCHEMA,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
ATTR_CURRENT_HUMIDITY, DOMAIN,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE,
SUPPORT_FAN_MODE, SUPPORT_SWING_MODE,
SUPPORT_ON_OFF, STATE_HEAT, STATE_COOL, STATE_FAN_ONLY, STATE_DRY,

View File

@@ -8,8 +8,9 @@ import logging
import voluptuous as vol
from homeassistant.components.climate import (
ClimateDevice, PLATFORM_SCHEMA, SUPPORT_TARGET_TEMPERATURE)
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
SUPPORT_TARGET_TEMPERATURE)
from homeassistant.const import CONF_HOST, TEMP_CELSIUS, ATTR_TEMPERATURE
import homeassistant.helpers.config_validation as cv

View File

@@ -8,14 +8,14 @@ import logging
import voluptuous as vol
from homeassistant.components.climate import (
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
ATTR_OPERATION_MODE, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW,
PLATFORM_SCHEMA, STATE_AUTO, STATE_COOL, STATE_HEAT, SUPPORT_FAN_MODE,
STATE_AUTO, STATE_COOL, STATE_HEAT, SUPPORT_FAN_MODE,
SUPPORT_OPERATION_MODE, SUPPORT_TARGET_HUMIDITY, SUPPORT_AWAY_MODE,
SUPPORT_TARGET_HUMIDITY_HIGH, SUPPORT_TARGET_HUMIDITY_LOW,
SUPPORT_HOLD_MODE, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW,
ClimateDevice)
SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW)
from homeassistant.const import (
ATTR_TEMPERATURE, CONF_HOST, CONF_PASSWORD, CONF_SSL, CONF_TIMEOUT,
CONF_USERNAME, PRECISION_WHOLE, STATE_OFF, STATE_ON, TEMP_CELSIUS,

View File

@@ -8,10 +8,11 @@ import logging
import voluptuous as vol
from homeassistant.components.climate import (
ATTR_OPERATION_MODE, PLATFORM_SCHEMA, STATE_COOL, STATE_DRY,
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
ATTR_OPERATION_MODE, STATE_COOL, STATE_DRY,
STATE_FAN_ONLY, STATE_HEAT, SUPPORT_FAN_MODE, SUPPORT_ON_OFF,
SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE, ClimateDevice)
SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE)
from homeassistant.const import (ATTR_TEMPERATURE, CONF_HOST, CONF_PORT,
EVENT_HOMEASSISTANT_STOP, TEMP_CELSIUS)
import homeassistant.helpers.config_validation as cv

View File

@@ -17,6 +17,10 @@ async def async_setup(hass):
hass.http.register_view(
ConfigManagerFlowResourceView(hass.config_entries.flow))
hass.http.register_view(ConfigManagerAvailableFlowView)
hass.http.register_view(
OptionManagerFlowIndexView(hass.config_entries.options.flow))
hass.http.register_view(
OptionManagerFlowResourceView(hass.config_entries.options.flow))
return True
@@ -45,8 +49,9 @@ class ConfigManagerEntryIndexView(HomeAssistantView):
name = 'api:config:config_entries:entry'
async def get(self, request):
"""List flows in progress."""
"""List available config entries."""
hass = request.app['hass']
return self.json([{
'entry_id': entry.entry_id,
'domain': entry.domain,
@@ -54,6 +59,9 @@ class ConfigManagerEntryIndexView(HomeAssistantView):
'source': entry.source,
'state': entry.state,
'connection_class': entry.connection_class,
'supports_options': hasattr(
config_entries.HANDLERS[entry.domain],
'async_get_options_flow'),
} for entry in hass.config_entries.async_entries()])
@@ -145,3 +153,48 @@ class ConfigManagerAvailableFlowView(HomeAssistantView):
async def get(self, request):
"""List available flow handlers."""
return self.json(config_entries.FLOWS)
class OptionManagerFlowIndexView(FlowManagerIndexView):
"""View to create option flows."""
url = '/api/config/config_entries/entry/option/flow'
name = 'api:config:config_entries:entry:resource:option:flow'
# pylint: disable=arguments-differ
async def post(self, request):
"""Handle a POST request.
handler in request is entry_id.
"""
if not request['hass_user'].is_admin:
raise Unauthorized(
perm_category=CAT_CONFIG_ENTRIES, permission='edit')
# pylint: disable=no-value-for-parameter
return await super().post(request)
class OptionManagerFlowResourceView(ConfigManagerFlowResourceView):
"""View to interact with the option flow manager."""
url = '/api/config/config_entries/options/flow/{flow_id}'
name = 'api:config:config_entries:options:flow:resource'
async def get(self, request, flow_id):
"""Get the current state of a data_entry_flow."""
if not request['hass_user'].is_admin:
raise Unauthorized(
perm_category=CAT_CONFIG_ENTRIES, permission='edit')
return await super().get(request, flow_id)
# pylint: disable=arguments-differ
async def post(self, request, flow_id):
"""Handle a POST request."""
if not request['hass_user'].is_admin:
raise Unauthorized(
perm_category=CAT_CONFIG_ENTRIES, permission='edit')
# pylint: disable=no-value-for-parameter
return await super().post(request, flow_id)

View File

@@ -19,6 +19,7 @@ SCHEMA_WS_UPDATE = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_UPDATE,
vol.Required('device_id'): str,
vol.Optional('area_id'): vol.Any(str, None),
vol.Optional('name_by_user'): vol.Any(str, None),
})
@@ -49,11 +50,13 @@ async def websocket_update_device(hass, connection, msg):
"""Handle update area websocket command."""
registry = await async_get_registry(hass)
entry = registry.async_update_device(
msg['device_id'], area_id=msg['area_id'])
msg.pop('type')
msg_id = msg.pop('id')
entry = registry.async_update_device(**msg)
connection.send_message(websocket_api.result_message(
msg['id'], _entry_dict(entry)
msg_id, _entry_dict(entry)
))
@@ -70,4 +73,5 @@ def _entry_dict(entry):
'id': entry.id,
'hub_device_id': entry.hub_device_id,
'area_id': entry.area_id,
'name_by_user': entry.name_by_user,
}

View File

@@ -35,12 +35,27 @@ ENTITY_ID_ALL_COVERS = group.ENTITY_ID_FORMAT.format('all_covers')
ENTITY_ID_FORMAT = DOMAIN + '.{}'
# Refer to the cover dev docs for device class descriptions
DEVICE_CLASS_AWNING = 'awning'
DEVICE_CLASS_BLIND = 'blind'
DEVICE_CLASS_CURTAIN = 'curtain'
DEVICE_CLASS_DAMPER = 'damper'
DEVICE_CLASS_DOOR = 'door'
DEVICE_CLASS_GARAGE = 'garage'
DEVICE_CLASS_SHADE = 'shade'
DEVICE_CLASS_SHUTTER = 'shutter'
DEVICE_CLASS_WINDOW = 'window'
DEVICE_CLASSES = [
'damper',
'garage', # Garage door control
'window', # Window control
DEVICE_CLASS_AWNING,
DEVICE_CLASS_BLIND,
DEVICE_CLASS_CURTAIN,
DEVICE_CLASS_DAMPER,
DEVICE_CLASS_DOOR,
DEVICE_CLASS_GARAGE,
DEVICE_CLASS_SHADE,
DEVICE_CLASS_SHUTTER,
DEVICE_CLASS_WINDOW
]
DEVICE_CLASSES_SCHEMA = vol.All(vol.Lower, vol.In(DEVICE_CLASSES))
SUPPORT_OPEN = 1

View File

@@ -0,0 +1,17 @@
{
"config": {
"abort": {
"device_timeout": "Tiempo de espera de conexi\u00f3n al dispositivo."
},
"step": {
"user": {
"data": {
"host": "Host"
},
"description": "Introduzca la direcci\u00f3n IP de su Daikin AC.",
"title": "Configurar Daikin AC"
}
},
"title": "Daikin AC"
}
}

View File

@@ -1,11 +1,19 @@
{
"config": {
"abort": {
"already_configured": "Az eszk\u00f6zt m\u00e1r konfigur\u00e1ltuk",
"device_fail": "Az eszk\u00f6z l\u00e9trehoz\u00e1sakor v\u00e1ratlan hiba l\u00e9pett fel.",
"device_timeout": "Id\u0151t\u00fall\u00e9p\u00e9s a k\u00e9sz\u00fcl\u00e9k csatlakoz\u00e1sakor."
},
"step": {
"user": {
"data": {
"host": "Kiszolg\u00e1l\u00f3"
}
},
"description": "Add meg a Daikin l\u00e9gkond\u00edcion\u00e1l\u00f3 IP-c\u00edm\u00e9t.",
"title": "A Daikin l\u00e9gkond\u00edcion\u00e1l\u00f3 konfigur\u00e1l\u00e1sa"
}
}
},
"title": "Daikin L\u00e9gkond\u00edci\u00f3n\u00e1l\u00f3"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"abort": {
"already_configured": "Il dispositivo \u00e8 gi\u00e0 configurato",
"device_fail": "Errore inatteso durante la creazione del dispositivo.",
"device_timeout": "Tempo scaduto per la connessione al dispositivo."
},
"step": {
"user": {
"data": {
"host": "Host"
},
"description": "Inserisci l'indirizzo IP del tuo Daikin AC.",
"title": "Configura Daikin AC"
}
},
"title": "Daikin AC"
}
}

View File

@@ -10,7 +10,7 @@
"data": {
"host": "\u0425\u043e\u0441\u0442"
},
"description": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 IP-\u0430\u0434\u0440\u0435\u0441 \u0432\u0430\u0448\u0435\u0433\u043e Daikin AC.",
"description": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 IP-\u0430\u0434\u0440\u0435\u0441 \u0412\u0430\u0448\u0435\u0433\u043e Daikin AC.",
"title": "Daikin AC"
}
},

View File

@@ -0,0 +1,19 @@
{
"config": {
"abort": {
"already_configured": "Enheten \u00e4r redan konfigurerad",
"device_fail": "Ov\u00e4ntat fel vid skapande av enhet.",
"device_timeout": "Timeout f\u00f6r anslutning till enheten."
},
"step": {
"user": {
"data": {
"host": "V\u00e4rddatorn"
},
"description": "Ange IP-adressen f\u00f6r din Daikin AC.",
"title": "Konfigurera Daikin AC"
}
},
"title": "Daikin AC"
}
}

View File

@@ -4,17 +4,17 @@ import re
import voluptuous as vol
from homeassistant.components.climate import (
from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA
from homeassistant.components.climate.const import (
ATTR_CURRENT_TEMPERATURE, ATTR_FAN_MODE, ATTR_OPERATION_MODE,
ATTR_SWING_MODE, PLATFORM_SCHEMA, STATE_AUTO, STATE_COOL, STATE_DRY,
STATE_FAN_ONLY, STATE_HEAT, STATE_OFF, SUPPORT_FAN_MODE,
SUPPORT_OPERATION_MODE, SUPPORT_SWING_MODE, SUPPORT_TARGET_TEMPERATURE,
ClimateDevice)
ATTR_SWING_MODE, STATE_AUTO, STATE_COOL, STATE_DRY,
STATE_FAN_ONLY, STATE_HEAT, SUPPORT_FAN_MODE,
SUPPORT_OPERATION_MODE, SUPPORT_SWING_MODE, SUPPORT_TARGET_TEMPERATURE)
from homeassistant.components.daikin import DOMAIN as DAIKIN_DOMAIN
from homeassistant.components.daikin.const import (
ATTR_INSIDE_TEMPERATURE, ATTR_OUTSIDE_TEMPERATURE, ATTR_TARGET_TEMPERATURE)
from homeassistant.const import (
ATTR_TEMPERATURE, CONF_HOST, CONF_NAME, TEMP_CELSIUS)
ATTR_TEMPERATURE, CONF_HOST, CONF_NAME, STATE_OFF, TEMP_CELSIUS)
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)

View File

@@ -9,11 +9,11 @@ from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle
REQUIREMENTS = ['pydanfossair==0.0.6']
REQUIREMENTS = ['pydanfossair==0.0.7']
_LOGGER = logging.getLogger(__name__)
DANFOSS_AIR_PLATFORMS = ['sensor', 'binary_sensor']
DANFOSS_AIR_PLATFORMS = ['sensor', 'binary_sensor', 'switch']
DOMAIN = 'danfoss_air'
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60)
@@ -52,6 +52,10 @@ class DanfossAir:
"""Get value for sensor."""
return self._data.get(item)
def update_state(self, command, state_command):
"""Send update command to Danfoss Air CCM."""
self._data[state_command] = self._client.command(command)
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Use the data from Danfoss Air API."""
@@ -71,5 +75,17 @@ class DanfossAir:
= round(self._client.command(ReadCommand.filterPercent), 2)
self._data[ReadCommand.bypass] \
= self._client.command(ReadCommand.bypass)
self._data[ReadCommand.fan_step] \
= self._client.command(ReadCommand.fan_step)
self._data[ReadCommand.supply_fan_speed] \
= self._client.command(ReadCommand.supply_fan_speed)
self._data[ReadCommand.exhaust_fan_speed] \
= self._client.command(ReadCommand.exhaust_fan_speed)
self._data[ReadCommand.away_mode] \
= self._client.command(ReadCommand.away_mode)
self._data[ReadCommand.boost] \
= self._client.command(ReadCommand.boost)
self._data[ReadCommand.battery_percent] \
= self._client.command(ReadCommand.battery_percent)
_LOGGER.debug("Done fetching data from Danfoss Air CCM module")

View File

@@ -1,9 +1,4 @@
"""
Support for the for Danfoss Air HRV binary sensor platform.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.danfoss_air/
"""
"""Support for the for Danfoss Air HRV binary sensors."""
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.danfoss_air import DOMAIN \
as DANFOSS_AIR_DOMAIN
@@ -14,12 +9,16 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
from pydanfossair.commands import ReadCommand
data = hass.data[DANFOSS_AIR_DOMAIN]
sensors = [["Danfoss Air Bypass Active", ReadCommand.bypass]]
sensors = [
["Danfoss Air Bypass Active", ReadCommand.bypass, "opening"],
["Danfoss Air Away Mode Active", ReadCommand.away_mode, None],
]
dev = []
for sensor in sensors:
dev.append(DanfossAirBinarySensor(data, sensor[0], sensor[1]))
dev.append(DanfossAirBinarySensor(
data, sensor[0], sensor[1], sensor[2]))
add_entities(dev, True)
@@ -27,12 +26,13 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
class DanfossAirBinarySensor(BinarySensorDevice):
"""Representation of a Danfoss Air binary sensor."""
def __init__(self, data, name, sensor_type):
def __init__(self, data, name, sensor_type, device_class):
"""Initialize the Danfoss Air binary sensor."""
self._data = data
self._name = name
self._state = None
self._type = sensor_type
self._device_class = device_class
@property
def name(self):
@@ -47,7 +47,7 @@ class DanfossAirBinarySensor(BinarySensorDevice):
@property
def device_class(self):
"""Type of device class."""
return "opening"
return self._device_class
def update(self):
"""Fetch new state data for the sensor."""

View File

@@ -1,14 +1,15 @@
"""
Support for the for Danfoss Air HRV sensor platform.
"""Support for the for Danfoss Air HRV sensors."""
import logging
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/sensor.danfoss_air/
"""
from homeassistant.components.danfoss_air import DOMAIN \
as DANFOSS_AIR_DOMAIN
from homeassistant.const import TEMP_CELSIUS
from homeassistant.const import (
TEMP_CELSIUS, DEVICE_CLASS_BATTERY,
DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_HUMIDITY)
from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the available Danfoss Air sensors etc."""
@@ -18,23 +19,32 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
sensors = [
["Danfoss Air Exhaust Temperature", TEMP_CELSIUS,
ReadCommand.exhaustTemperature],
ReadCommand.exhaustTemperature, DEVICE_CLASS_TEMPERATURE],
["Danfoss Air Outdoor Temperature", TEMP_CELSIUS,
ReadCommand.outdoorTemperature],
ReadCommand.outdoorTemperature, DEVICE_CLASS_TEMPERATURE],
["Danfoss Air Supply Temperature", TEMP_CELSIUS,
ReadCommand.supplyTemperature],
ReadCommand.supplyTemperature, DEVICE_CLASS_TEMPERATURE],
["Danfoss Air Extract Temperature", TEMP_CELSIUS,
ReadCommand.extractTemperature],
ReadCommand.extractTemperature, DEVICE_CLASS_TEMPERATURE],
["Danfoss Air Remaining Filter", '%',
ReadCommand.filterPercent],
ReadCommand.filterPercent, None],
["Danfoss Air Humidity", '%',
ReadCommand.humidity]
ReadCommand.humidity, DEVICE_CLASS_HUMIDITY],
["Danfoss Air Fan Step", '%',
ReadCommand.fan_step, None],
["Dandoss Air Exhaust Fan Speed", 'RPM',
ReadCommand.exhaust_fan_speed, None],
["Dandoss Air Supply Fan Speed", 'RPM',
ReadCommand.supply_fan_speed, None],
["Dandoss Air Dial Battery", '%',
ReadCommand.battery_percent, DEVICE_CLASS_BATTERY]
]
dev = []
for sensor in sensors:
dev.append(DanfossAir(data, sensor[0], sensor[1], sensor[2]))
dev.append(DanfossAir(
data, sensor[0], sensor[1], sensor[2], sensor[3]))
add_entities(dev, True)
@@ -42,19 +52,25 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
class DanfossAir(Entity):
"""Representation of a Sensor."""
def __init__(self, data, name, sensor_unit, sensor_type):
def __init__(self, data, name, sensor_unit, sensor_type, device_class):
"""Initialize the sensor."""
self._data = data
self._name = name
self._state = None
self._type = sensor_type
self._unit = sensor_unit
self._device_class = device_class
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def device_class(self):
"""Return the device class of the sensor."""
return self._device_class
@property
def state(self):
"""Return the state of the sensor."""
@@ -74,3 +90,5 @@ class DanfossAir(Entity):
self._data.update()
self._state = self._data.get_value(self._type)
if self._state is None:
_LOGGER.debug("Could not get data for %s", self._type)

View File

@@ -0,0 +1,72 @@
"""Support for the for Danfoss Air HRV sswitches."""
import logging
from homeassistant.components.switch import (
SwitchDevice)
from homeassistant.components.danfoss_air import DOMAIN \
as DANFOSS_AIR_DOMAIN
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Danfoss Air HRV switch platform."""
from pydanfossair.commands import ReadCommand, UpdateCommand
data = hass.data[DANFOSS_AIR_DOMAIN]
switches = [
["Danfoss Air Boost",
ReadCommand.boost,
UpdateCommand.boost_activate,
UpdateCommand.boost_deactivate],
]
dev = []
for switch in switches:
dev.append(DanfossAir(
data, switch[0], switch[1], switch[2], switch[3]))
add_entities(dev)
class DanfossAir(SwitchDevice):
"""Representation of a Danfoss Air HRV Switch."""
def __init__(self, data, name, state_command, on_command, off_command):
"""Initialize the switch."""
self._data = data
self._name = name
self._state_command = state_command
self._on_command = on_command
self._off_command = off_command
self._state = None
@property
def name(self):
"""Return the name of the switch."""
return self._name
@property
def is_on(self):
"""Return true if switch is on."""
return self._state
def turn_on(self, **kwargs):
"""Turn the switch on."""
_LOGGER.debug("Turning on switch with command %s", self._on_command)
self._data.update_state(self._on_command, self._state_command)
def turn_off(self, **kwargs):
"""Turn the switch off."""
_LOGGER.debug("Turning of switch with command %s", self._off_command)
self._data.update_state(self._off_command, self._state_command)
def update(self):
"""Update the switch's state."""
self._data.update()
self._state = self._data.get_value(self._state_command)
if self._state is None:
_LOGGER.debug("Could not get data for %s", self._state_command)

View File

@@ -12,7 +12,7 @@
"init": {
"data": {
"host": "Host",
"port": "Puerto (valor predeterminado: '80')"
"port": "Puerto"
},
"title": "Definir el gateway deCONZ"
},
@@ -23,7 +23,8 @@
"data": {
"allow_clip_sensor": "Permitir la importaci\u00f3n de sensores virtuales",
"allow_deconz_groups": "Permitir la importaci\u00f3n de grupos deCONZ"
}
},
"title": "Opciones de configuraci\u00f3n adicionales para deCONZ"
}
},
"title": "deCONZ Zigbee gateway"

View File

@@ -12,7 +12,7 @@
"init": {
"data": {
"host": "H\u00e1zigazda (Host)",
"port": "Port (alap\u00e9rtelmezett \u00e9rt\u00e9k: '80')"
"port": "Port"
},
"title": "deCONZ \u00e1tj\u00e1r\u00f3 megad\u00e1sa"
},

View File

@@ -28,6 +28,6 @@
"title": "Opzioni di configurazione extra per deCONZ"
}
},
"title": "deCONZ"
"title": "Gateway Zigbee deCONZ"
}
}

View File

@@ -28,6 +28,6 @@
"title": "Extra konfigurationsalternativ f\u00f6r deCONZ"
}
},
"title": "deCONZ"
"title": "deCONZ Zigbee Gateway"
}
}

View File

@@ -12,10 +12,7 @@ from .config_flow import configured_hosts
from .const import DEFAULT_PORT, DOMAIN, _LOGGER
from .gateway import DeconzGateway
REQUIREMENTS = ['pydeconz==47']
SUPPORTED_PLATFORMS = ['binary_sensor', 'cover',
'light', 'scene', 'sensor', 'switch']
REQUIREMENTS = ['pydeconz==52']
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
@@ -71,11 +68,11 @@ async def async_setup_entry(hass, config_entry):
gateway = DeconzGateway(hass, config_entry)
hass.data[DOMAIN] = gateway
if not await gateway.async_setup():
return False
hass.data[DOMAIN] = gateway
device_registry = await \
hass.helpers.device_registry.async_get_registry()
device_registry.async_get_or_create(

View File

@@ -5,7 +5,8 @@ from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import (
ATTR_DARK, ATTR_ON, CONF_ALLOW_CLIP_SENSOR, DOMAIN as DECONZ_DOMAIN)
ATTR_DARK, ATTR_ON, CONF_ALLOW_CLIP_SENSOR, DOMAIN as DECONZ_DOMAIN,
NEW_SENSOR)
from .deconz_device import DeconzDevice
DEPENDENCIES = ['deconz']
@@ -34,7 +35,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
async_add_entities(entities, True)
gateway.listeners.append(
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_sensor))
async_dispatcher_connect(hass, NEW_SENSOR, async_add_sensor))
async_add_sensor(gateway.api.sensors.values())

View File

@@ -0,0 +1,111 @@
"""Support for deCONZ climate devices."""
from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import (
SUPPORT_ON_OFF, SUPPORT_TARGET_TEMPERATURE)
from homeassistant.const import (
ATTR_BATTERY_LEVEL, ATTR_TEMPERATURE, TEMP_CELSIUS)
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import (
ATTR_OFFSET, ATTR_VALVE, CONF_ALLOW_CLIP_SENSOR,
DOMAIN as DECONZ_DOMAIN, NEW_SENSOR)
from .deconz_device import DeconzDevice
DEPENDENCIES = ['deconz']
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the deCONZ climate devices.
Thermostats are based on the same device class as sensors in deCONZ.
"""
gateway = hass.data[DECONZ_DOMAIN]
@callback
def async_add_climate(sensors):
"""Add climate devices from deCONZ."""
from pydeconz.sensor import THERMOSTAT
entities = []
allow_clip_sensor = config_entry.data.get(CONF_ALLOW_CLIP_SENSOR, True)
for sensor in sensors:
if sensor.type in THERMOSTAT and \
not (not allow_clip_sensor and sensor.type.startswith('CLIP')):
entities.append(DeconzThermostat(sensor, gateway))
async_add_entities(entities, True)
gateway.listeners.append(
async_dispatcher_connect(hass, NEW_SENSOR, async_add_climate))
async_add_climate(gateway.api.sensors.values())
class DeconzThermostat(DeconzDevice, ClimateDevice):
"""Representation of a deCONZ thermostat."""
def __init__(self, device, gateway):
"""Set up thermostat device."""
super().__init__(device, gateway)
self._features = SUPPORT_ON_OFF
self._features |= SUPPORT_TARGET_TEMPERATURE
@property
def supported_features(self):
"""Return the list of supported features."""
return self._features
@property
def is_on(self):
"""Return true if on."""
return self._device.on
async def async_turn_on(self):
"""Turn on switch."""
data = {'mode': 'auto'}
await self._device.async_set_config(data)
async def async_turn_off(self):
"""Turn off switch."""
data = {'mode': 'off'}
await self._device.async_set_config(data)
@property
def current_temperature(self):
"""Return the current temperature."""
return self._device.temperature
@property
def target_temperature(self):
"""Return the target temperature."""
return self._device.heatsetpoint
async def async_set_temperature(self, **kwargs):
"""Set new target temperature."""
data = {}
if ATTR_TEMPERATURE in kwargs:
data['heatsetpoint'] = kwargs[ATTR_TEMPERATURE] * 100
await self._device.async_set_config(data)
@property
def temperature_unit(self):
"""Return the unit of measurement."""
return TEMP_CELSIUS
@property
def device_state_attributes(self):
"""Return the state attributes of the thermostat."""
attr = {}
if self._device.battery:
attr[ATTR_BATTERY_LEVEL] = self._device.battery
if self._device.offset:
attr[ATTR_OFFSET] = self._device.offset
if self._device.valve is not None:
attr[ATTR_VALVE] = self._device.valve
return attr

View File

@@ -10,13 +10,27 @@ DEFAULT_PORT = 80
CONF_ALLOW_CLIP_SENSOR = 'allow_clip_sensor'
CONF_ALLOW_DECONZ_GROUPS = 'allow_deconz_groups'
SUPPORTED_PLATFORMS = ['binary_sensor', 'cover',
SUPPORTED_PLATFORMS = ['binary_sensor', 'climate', 'cover',
'light', 'scene', 'sensor', 'switch']
DECONZ_REACHABLE = 'deconz_reachable'
NEW_GROUP = 'deconz_new_group'
NEW_LIGHT = 'deconz_new_light'
NEW_SCENE = 'deconz_new_scene'
NEW_SENSOR = 'deconz_new_sensor'
NEW_DEVICE = {
'group': NEW_GROUP,
'light': NEW_LIGHT,
'scene': NEW_SCENE,
'sensor': NEW_SENSOR
}
ATTR_DARK = 'dark'
ATTR_OFFSET = 'offset'
ATTR_ON = 'on'
ATTR_VALVE = 'valve'
DAMPERS = ["Level controllable output"]
WINDOW_COVERS = ["Window covering device"]

View File

@@ -5,7 +5,8 @@ from homeassistant.components.cover import (
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import COVER_TYPES, DAMPERS, DOMAIN as DECONZ_DOMAIN, WINDOW_COVERS
from .const import (
COVER_TYPES, DAMPERS, DOMAIN as DECONZ_DOMAIN, NEW_LIGHT, WINDOW_COVERS)
from .deconz_device import DeconzDevice
DEPENDENCIES = ['deconz']
@@ -39,7 +40,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
async_add_entities(entities, True)
gateway.listeners.append(
async_dispatcher_connect(hass, 'deconz_new_light', async_add_cover))
async_dispatcher_connect(hass, NEW_LIGHT, async_add_cover))
async_add_cover(gateway.api.lights.values())
@@ -48,7 +49,7 @@ class DeconzCover(DeconzDevice, CoverDevice):
"""Representation of a deCONZ cover."""
def __init__(self, device, gateway):
"""Set up cover and add update callback to get data from websocket."""
"""Set up cover device."""
super().__init__(device, gateway)
self._features = SUPPORT_OPEN

View File

@@ -8,7 +8,8 @@ from homeassistant.helpers.dispatcher import (
from homeassistant.util import slugify
from .const import (
DECONZ_REACHABLE, CONF_ALLOW_CLIP_SENSOR, SUPPORTED_PLATFORMS)
_LOGGER, DECONZ_REACHABLE, CONF_ALLOW_CLIP_SENSOR, NEW_DEVICE, NEW_SENSOR,
SUPPORTED_PLATFORMS)
class DeconzGateway:
@@ -44,7 +45,7 @@ class DeconzGateway:
self.listeners.append(
async_dispatcher_connect(
hass, 'deconz_new_sensor', self.async_add_remote))
hass, NEW_SENSOR, self.async_add_remote))
self.async_add_remote(self.api.sensors.values())
@@ -64,8 +65,7 @@ class DeconzGateway:
"""Handle event of new device creation in deCONZ."""
if not isinstance(device, list):
device = [device]
async_dispatcher_send(
self.hass, 'deconz_new_{}'.format(device_type), device)
async_dispatcher_send(self.hass, NEW_DEVICE[device_type], device)
@callback
def async_add_remote(self, sensors):
@@ -140,6 +140,7 @@ class DeconzEvent:
self._device.register_async_callback(self.async_update_callback)
self._event = 'deconz_{}'.format(CONF_EVENT)
self._id = slugify(self._device.name)
_LOGGER.debug("deCONZ event created: %s", self._id)
@callback
def async_will_remove_from_hass(self) -> None:

View File

@@ -9,8 +9,8 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
import homeassistant.util.color as color_util
from .const import (
CONF_ALLOW_DECONZ_GROUPS, DOMAIN as DECONZ_DOMAIN, COVER_TYPES,
SWITCH_TYPES)
CONF_ALLOW_DECONZ_GROUPS, DOMAIN as DECONZ_DOMAIN, COVER_TYPES, NEW_GROUP,
NEW_LIGHT, SWITCH_TYPES)
from .deconz_device import DeconzDevice
DEPENDENCIES = ['deconz']
@@ -36,7 +36,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
async_add_entities(entities, True)
gateway.listeners.append(
async_dispatcher_connect(hass, 'deconz_new_light', async_add_light))
async_dispatcher_connect(hass, NEW_LIGHT, async_add_light))
@callback
def async_add_group(groups):
@@ -49,7 +49,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
async_add_entities(entities, True)
gateway.listeners.append(
async_dispatcher_connect(hass, 'deconz_new_group', async_add_group))
async_dispatcher_connect(hass, NEW_GROUP, async_add_group))
async_add_light(gateway.api.lights.values())
async_add_group(gateway.api.groups.values())

View File

@@ -1,9 +1,10 @@
"""Support for deCONZ scenes."""
from homeassistant.components.deconz import DOMAIN as DECONZ_DOMAIN
from homeassistant.components.scene import Scene
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import DOMAIN as DECONZ_DOMAIN, NEW_SCENE
DEPENDENCIES = ['deconz']
@@ -25,7 +26,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(DeconzScene(scene, gateway))
async_add_entities(entities)
gateway.listeners.append(
async_dispatcher_connect(hass, 'deconz_new_scene', async_add_scene))
async_dispatcher_connect(hass, NEW_SCENE, async_add_scene))
async_add_scene(gateway.api.scenes.values())

View File

@@ -6,7 +6,8 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.util import slugify
from .const import (
ATTR_DARK, ATTR_ON, CONF_ALLOW_CLIP_SENSOR, DOMAIN as DECONZ_DOMAIN)
ATTR_DARK, ATTR_ON, CONF_ALLOW_CLIP_SENSOR, DOMAIN as DECONZ_DOMAIN,
NEW_SENSOR)
from .deconz_device import DeconzDevice
DEPENDENCIES = ['deconz']
@@ -29,7 +30,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
@callback
def async_add_sensor(sensors):
"""Add sensors from deCONZ."""
from pydeconz.sensor import DECONZ_SENSOR, SWITCH as DECONZ_REMOTE
from pydeconz.sensor import (
DECONZ_SENSOR, SWITCH as DECONZ_REMOTE)
entities = []
allow_clip_sensor = config_entry.data.get(CONF_ALLOW_CLIP_SENSOR, True)
for sensor in sensors:
@@ -43,7 +45,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
async_add_entities(entities, True)
gateway.listeners.append(
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_sensor))
async_dispatcher_connect(hass, NEW_SENSOR, async_add_sensor))
async_add_sensor(gateway.api.sensors.values())

View File

@@ -3,7 +3,7 @@ from homeassistant.components.switch import SwitchDevice
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import DOMAIN as DECONZ_DOMAIN, POWER_PLUGS, SIRENS
from .const import DOMAIN as DECONZ_DOMAIN, NEW_LIGHT, POWER_PLUGS, SIRENS
from .deconz_device import DeconzDevice
DEPENDENCIES = ['deconz']
@@ -34,7 +34,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
async_add_entities(entities, True)
gateway.listeners.append(
async_dispatcher_connect(hass, 'deconz_new_light', async_add_switch))
async_dispatcher_connect(hass, NEW_LIGHT, async_add_switch))
async_add_switch(gateway.api.lights.values())

View File

@@ -1,9 +1,4 @@
"""
Provides functionality to turn on lights based on the states.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/device_sun_light_trigger/
"""
"""Support to turn on lights based on the states."""
import logging
from datetime import timedelta

View File

@@ -291,7 +291,7 @@ class DeviceTracker:
"""
if mac is None and dev_id is None:
raise HomeAssistantError('Neither mac or device id passed in')
elif mac is not None:
if mac is not None:
mac = str(mac).upper()
device = self.mac_to_dev.get(mac)
if not device:
@@ -580,6 +580,7 @@ class Device(RestoreEntity):
return
self._state = state.state
self.last_update_home = (state.state == STATE_HOME)
self.last_seen = dt_util.utcnow()
for attr, var in (
(ATTR_SOURCE_TYPE, 'source_type'),

View File

@@ -61,8 +61,9 @@ class GoogleMapsScanner:
self.max_gps_accuracy = config[CONF_MAX_GPS_ACCURACY]
try:
self.service = Service(self.username, self.password,
hass.config.path(CREDENTIALS_FILE))
credfile = "{}.{}".format(hass.config.path(CREDENTIALS_FILE),
slugify(self.username))
self.service = Service(self.username, self.password, credfile)
self._update_info()
track_time_interval(

View File

@@ -4,21 +4,17 @@ Support for OpenWRT (luci) routers.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.luci/
"""
import json
import logging
import re
from collections import namedtuple
import requests
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.exceptions import HomeAssistantError
from homeassistant.components.device_tracker import (
DOMAIN, PLATFORM_SCHEMA, DeviceScanner)
from homeassistant.const import (
CONF_HOST, CONF_USERNAME, CONF_PASSWORD, CONF_SSL)
REQUIREMENTS = ['openwrt-luci-rpc==1.0.5']
_LOGGER = logging.getLogger(__name__)
DEFAULT_SSL = False
@@ -31,12 +27,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
class InvalidLuciTokenError(HomeAssistantError):
"""When an invalid token is detected."""
pass
def get_scanner(hass, config):
"""Validate the configuration and return a Luci scanner."""
scanner = LuciDeviceScanner(config[DOMAIN])
@@ -44,138 +34,58 @@ def get_scanner(hass, config):
return scanner if scanner.success_init else None
Device = namedtuple('Device', ['mac', 'ip', 'flags', 'device', 'host'])
class LuciDeviceScanner(DeviceScanner):
"""This class queries a wireless router running OpenWrt firmware."""
"""This class scans for devices connected to an OpenWrt router."""
def __init__(self, config):
"""Initialize the scanner."""
self.host = config[CONF_HOST]
protocol = 'http' if not config[CONF_SSL] else 'https'
self.origin = '{}://{}'.format(protocol, self.host)
self.username = config[CONF_USERNAME]
self.password = config[CONF_PASSWORD]
from openwrt_luci_rpc import OpenWrtRpc
self.parse_api_pattern = re.compile(r"(?P<param>\w*) = (?P<value>.*);")
self.router = OpenWrtRpc(config[CONF_HOST],
config[CONF_USERNAME],
config[CONF_PASSWORD],
config[CONF_SSL])
self.last_results = {}
self.refresh_token()
self.mac2name = None
self.success_init = self.token is not None
def refresh_token(self):
"""Get a new token."""
self.token = _get_token(self.origin, self.username, self.password)
self.success_init = self.router.is_logged_in()
def scan_devices(self):
"""Scan for new devices and return a list with found device IDs."""
self._update_info()
return [device.mac for device in self.last_results]
def get_device_name(self, device):
"""Return the name of the given device or None if we don't know."""
if self.mac2name is None:
url = '{}/cgi-bin/luci/rpc/uci'.format(self.origin)
result = _req_json_rpc(
url, 'get_all', 'dhcp', params={'auth': self.token})
if result:
hosts = [x for x in result.values()
if x['.type'] == 'host' and
'mac' in x and 'name' in x]
mac2name_list = [
(x['mac'].upper(), x['name']) for x in hosts]
self.mac2name = dict(mac2name_list)
else:
# Error, handled in the _req_json_rpc
return
return self.mac2name.get(device.upper(), None)
name = next((
result.hostname for result in self.last_results
if result.mac == device), None)
return name
def get_extra_attributes(self, device):
"""Return the IP of the given device."""
filter_att = next((
{
'ip': result.ip,
'flags': result.flags,
'device': result.device,
'host': result.host
} for result in self.last_results
"""
Get extra attributes of a device.
Some known extra attributes that may be returned in the device tuple
include Mac Address (mac), Network Device (dev), Ip Address
(ip), reachable status (reachable), Associated router
(host), Hostname if known (hostname) among others.
"""
device = next((
result for result in self.last_results
if result.mac == device), None)
return filter_att
return device._asdict()
def _update_info(self):
"""Ensure the information from the Luci router is up to date.
"""Check the Luci router for devices."""
result = self.router.get_all_connected_devices(
only_reachable=True)
Returns boolean if scanning successful.
"""
if not self.success_init:
return False
_LOGGER.debug("Luci get_all_connected_devices returned:"
" %s", result)
_LOGGER.info("Checking ARP")
last_results = []
for device in result:
last_results.append(device)
url = '{}/cgi-bin/luci/rpc/sys'.format(self.origin)
try:
result = _req_json_rpc(
url, 'net.arptable', params={'auth': self.token})
except InvalidLuciTokenError:
_LOGGER.info("Refreshing token")
self.refresh_token()
return False
if result:
self.last_results = []
for device_entry in result:
# Check if the Flags for each device contain
# NUD_REACHABLE and if so, add it to last_results
if int(device_entry['Flags'], 16) & 0x2:
self.last_results.append(Device(device_entry['HW address'],
device_entry['IP address'],
device_entry['Flags'],
device_entry['Device'],
self.host))
return True
return False
def _req_json_rpc(url, method, *args, **kwargs):
"""Perform one JSON RPC operation."""
data = json.dumps({'method': method, 'params': args})
try:
res = requests.post(url, data=data, timeout=5, **kwargs)
except requests.exceptions.Timeout:
_LOGGER.exception("Connection to the router timed out")
return
if res.status_code == 200:
try:
result = res.json()
except ValueError:
# If json decoder could not parse the response
_LOGGER.exception("Failed to parse response from luci")
return
try:
return result['result']
except KeyError:
_LOGGER.exception("No result in response from luci")
return
elif res.status_code == 401:
# Authentication error
_LOGGER.exception(
"Failed to authenticate, check your username and password")
return
elif res.status_code == 403:
_LOGGER.error("Luci responded with a 403 Invalid token")
raise InvalidLuciTokenError
else:
_LOGGER.error("Invalid response from luci: %s", res)
def _get_token(origin, username, password):
"""Get authentication token for the given configuration."""
url = '{}/cgi-bin/luci/rpc/auth'.format(origin)
return _req_json_rpc(url, 'login', username, password)
self.last_results = last_results

View File

@@ -13,7 +13,7 @@ from homeassistant.const import (
CONF_HOST, CONF_USERNAME, CONF_PASSWORD,
CONF_PORT, CONF_SSL, CONF_VERIFY_SSL)
REQUIREMENTS = ['synology-srm==0.0.4']
REQUIREMENTS = ['synology-srm==0.0.6']
_LOGGER = logging.getLogger(__name__)

View File

@@ -12,14 +12,15 @@ import voluptuous as vol
from homeassistant.components.device_tracker import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_HOST, CONF_PORT, CONF_SSL, CONF_VERIFY_SSL,
CONF_PASSWORD, CONF_USERNAME, ATTR_BATTERY_LEVEL)
CONF_PASSWORD, CONF_USERNAME, ATTR_BATTERY_LEVEL,
CONF_SCAN_INTERVAL, CONF_MONITORED_CONDITIONS)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.util import slugify
REQUIREMENTS = ['pytraccar==0.2.1']
REQUIREMENTS = ['pytraccar==0.3.0']
_LOGGER = logging.getLogger(__name__)
@@ -31,6 +32,7 @@ ATTR_SPEED = 'speed'
ATTR_TRACKER = 'tracker'
DEFAULT_SCAN_INTERVAL = timedelta(seconds=30)
SCAN_INTERVAL = DEFAULT_SCAN_INTERVAL
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_PASSWORD): cv.string,
@@ -39,6 +41,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_PORT, default=8082): cv.port,
vol.Optional(CONF_SSL, default=False): cv.boolean,
vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
vol.Optional(CONF_MONITORED_CONDITIONS,
default=[]): vol.All(cv.ensure_list, [cv.string]),
})
@@ -50,15 +54,22 @@ async def async_setup_scanner(hass, config, async_see, discovery_info=None):
api = API(hass.loop, session, config[CONF_USERNAME], config[CONF_PASSWORD],
config[CONF_HOST], config[CONF_PORT], config[CONF_SSL])
scanner = TraccarScanner(api, hass, async_see)
scanner = TraccarScanner(
api, hass, async_see,
config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL),
config[CONF_MONITORED_CONDITIONS])
return await scanner.async_init()
class TraccarScanner:
"""Define an object to retrieve Traccar data."""
def __init__(self, api, hass, async_see):
def __init__(self, api, hass, async_see, scan_interval, custom_attributes):
"""Initialize."""
self._custom_attributes = custom_attributes
self._scan_interval = scan_interval
self._async_see = async_see
self._api = api
self._hass = hass
@@ -70,14 +81,14 @@ class TraccarScanner:
await self._async_update()
async_track_time_interval(self._hass,
self._async_update,
DEFAULT_SCAN_INTERVAL)
self._scan_interval)
return self._api.authenticated
async def _async_update(self, now=None):
"""Update info from Traccar."""
_LOGGER.debug('Updating device data.')
await self._api.get_device_info()
await self._api.get_device_info(self._custom_attributes)
for devicename in self._api.device_info:
device = self._api.device_info[devicename]
attr = {}
@@ -94,6 +105,9 @@ class TraccarScanner:
attr[ATTR_BATTERY_LEVEL] = device['battery']
if device.get('motion') is not None:
attr[ATTR_MOTION] = device['motion']
for custom_attr in self._custom_attributes:
if device.get(custom_attr) is not None:
attr[custom_attr] = device[custom_attr]
await self._async_see(
dev_id=slugify(device['device_id']),
gps=(device.get('latitude'), device.get('longitude')),

View File

@@ -0,0 +1,92 @@
"""
Support for Ubee router.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.ubee/
"""
import logging
import voluptuous as vol
from homeassistant.components.device_tracker import (
DOMAIN, PLATFORM_SCHEMA, DeviceScanner)
from homeassistant.const import (
CONF_HOST, CONF_PASSWORD, CONF_USERNAME)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyubee==0.2']
_LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string,
})
def get_scanner(hass, config):
"""Validate the configuration and return a Ubee scanner."""
try:
return UbeeDeviceScanner(config[DOMAIN])
except ConnectionError:
return None
class UbeeDeviceScanner(DeviceScanner):
"""This class queries a wireless Ubee router."""
def __init__(self, config):
"""Initialize the Ubee scanner."""
from pyubee import Ubee
self.host = config[CONF_HOST]
self.username = config[CONF_USERNAME]
self.password = config[CONF_PASSWORD]
self.last_results = {}
self.mac2name = {}
self.ubee = Ubee(self.host, self.username, self.password)
_LOGGER.info("Logging in")
results = self.get_connected_devices()
self.success_init = results is not None
if self.success_init:
self.last_results = results
else:
_LOGGER.error("Login failed")
def scan_devices(self):
"""Scan for new devices and return a list with found device IDs."""
self._update_info()
return self.last_results
def get_device_name(self, device):
"""Return the name of the given device or None if we don't know."""
if device in self.mac2name:
return self.mac2name.get(device)
return None
def _update_info(self):
"""Retrieve latest information from the Ubee router."""
if not self.success_init:
return
_LOGGER.debug("Scanning")
results = self.get_connected_devices()
if results is None:
_LOGGER.warning("Error scanning devices")
return
self.last_results = results or []
def get_connected_devices(self):
"""List connected devices with pyubee."""
if not self.ubee.session_active():
self.ubee.login()
return self.ubee.get_connected_devices()

View File

@@ -216,8 +216,7 @@ def _req_json_rpc(url, session_id, rpcmethod, subsystem, method, **params):
if 'message' in response['error'] and \
response['error']['message'] == "Access denied":
raise PermissionError(response['error']['message'])
else:
raise HomeAssistantError(response['error']['message'])
raise HomeAssistantError(response['error']['message'])
if rpcmethod == "call":
try:

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"not_internet_accessible": "Su instancia de Home Assistant debe ser accesible desde Internet para recibir mensajes de Dialogflow.",
"one_instance_allowed": "Solo una instancia es necesaria."
},
"create_entry": {
"default": "Para enviar eventos a Home Assistant, deber\u00e1 configurar [integraci\u00f3n de webhook de Dialogflow] ( {dialogflow_url} ). \n\n Complete la siguiente informaci\u00f3n: \n\n - URL: ` {webhook_url} ` \n - M\u00e9todo: POST \n - Tipo de contenido: aplicaci\u00f3n / json \n\n Vea [la documentaci\u00f3n] ( {docs_url} ) para m\u00e1s detalles."
},
"step": {
"user": {
"description": "\u00bfEst\u00e1 seguro de que desea configurar Dialogflow?",
"title": "Configurar el Webhook de Dialogflow"
}
},
"title": "Dialogflow"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"not_internet_accessible": "La tua istanza di Home Assistant deve essere accessibile da Internet per ricevere messaggi da Dialogflow.",
"one_instance_allowed": "\u00c8 necessaria una sola istanza."
},
"create_entry": {
"default": "Per inviare eventi a Home Assistant, dovrai configurare [l'integrazione webhook di Dialogflow]({dialogflow_url})\n\n Compila le seguenti informazioni: \n\n - URL: ` {webhook_url} ` \n - Method: POST \n - Content Type: application/json \n\n Vedi [la documentazione]({docs_url}) for ulteriori dettagli."
},
"step": {
"user": {
"description": "Sei sicuro di voler configurare Dialogflow?",
"title": "Configura il webhook di Dialogflow"
}
},
"title": "Dialogflow"
}
}

View File

@@ -5,7 +5,7 @@
"one_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."
},
"create_entry": {
"default": "\u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 Home Assistant \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c [webhooks \u0434\u043b\u044f Dialogflow]({dialogflow_url}).\n\n\u0414\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/json\n\n\u041e\u0437\u043d\u0430\u043a\u043e\u043c\u044c\u0442\u0435\u0441\u044c \u0441 [\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439]({docs_url}) \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438."
"default": "\u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 Home Assistant \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c [webhooks \u0434\u043b\u044f Dialogflow]({dialogflow_url}).\n\n\u0414\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/json\n\n\u041e\u0437\u043d\u0430\u043a\u043e\u043c\u044c\u0442\u0435\u0441\u044c \u0441 [\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439]({docs_url}) \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438."
},
"step": {
"user": {

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