Compare commits

..

1844 Commits
0.29 ... 0.39

Author SHA1 Message Date
Paulus Schoutsen
f5a1cd5b3c Merge pull request #6229 from home-assistant/release-0-39
Fix recorder async (#6228)
2017-02-25 15:23:55 -08:00
Paulus Schoutsen
7b9f7889d2 Fix recorder async (#6228) 2017-02-25 15:22:23 -08:00
Paulus Schoutsen
58f9455604 Merge pull request #6227 from home-assistant/release-0-39
Release 0 39
2017-02-25 15:04:54 -08:00
Paulus Schoutsen
596f7b99f6 Update frontend 2017-02-25 15:03:54 -08:00
Johann Kellerman
94183e1992 No wait for start and more async 2017-02-25 15:03:54 -08:00
Johann Kellerman
0e5df9b641 Allow 4.5min startup time for recorder 2017-02-25 15:03:54 -08:00
Paulus Schoutsen
a19a285bb0 Merge pull request #6199 from home-assistant/release-0-39
0.39
2017-02-25 14:36:17 -08:00
Andrey
eb36174b51 Make glob preserve order (#6224) 2017-02-25 14:35:27 -08:00
Fabian Affolter
6e51f7d987 Update regex (#6216) 2017-02-25 14:35:27 -08:00
Lindsay Ward
4ba9020859 Update Yeelight Sunflower light platform to 0.0.6 (#6208)
Add an optional extended description…
2017-02-25 14:35:27 -08:00
Paulus Schoutsen
505725f9d3 Fix reporting on bad login (#6201) 2017-02-25 14:35:27 -08:00
Paulus Schoutsen
2566d01aaa Remove automatically reloading group config (#6197) 2017-02-25 14:35:27 -08:00
Johann Kellerman
477f621705 Bugfix restore startup state (#6189) 2017-02-25 14:35:27 -08:00
Pascal Vizeli
7fcc3ae00a Refactory of envisalink (#6160)
* Refactory of envisalink

* remove event buss

* init dispatcher from hass.

* Move platform to new dispatcher

* fix lint

* add unittest & threadded functions

* fix copy & past error
2017-02-25 14:35:27 -08:00
Paulus Schoutsen
a44d849405 Version bump to 0.39 2017-02-25 12:53:23 -08:00
Pascal Vizeli
1cd1facbd0 Add device_class to image_processing (#6186)
* Add image_processing device_class

* Fix comments

* address comments
2017-02-23 17:33:54 +01:00
Pascal Vizeli
b725eaf67f Homematic icon map / upper case on services (#6178)
* Set upper on service / add sensor icon mapper

* Add more icons

* fix id
2017-02-23 15:31:32 +01:00
Colin O'Dell
89807f24ad QNAP update (#6182)
* Bump qnapstats library to 0.2.3

* Expose the new timeout setting

* Show persistent notification if QNAP fails to set up

This sitaution will usually occur if the server configuration is wrong or the
timeout is set too low.  In both cases `api.update()` will fail, which is a
problem because we cannot initialize many of the sensors without having this
data.

* Add new system_temp condition to QNAP sensor
2017-02-23 15:01:25 +01:00
Erik Eriksson
7935c54420 's' is SI symbol for seconds (#6181) 2017-02-23 14:57:51 +01:00
Erik Eriksson
46d0d38444 Merge pull request #6180 from home-assistant/molobrakos-patch-1
volvooncall: icon and unit were mixed
2017-02-23 13:28:03 +01:00
Erik Eriksson
5da110d764 volvooncall: icon and unit were mixed 2017-02-23 13:27:17 +01:00
Erik Eriksson
c88527ce79 Merge pull request #6177 from molobrakos/volvooncall
volvooncall: support for naming vehicle and selecting what attributes to display
2017-02-23 13:00:11 +01:00
Erik Eriksson
6127173d2a cache name in entity so we can display it even if the connection is lost (#6176)
update tellduslive dependency
check return value from update
2017-02-23 12:37:25 +01:00
Erik
1c6ba989a9 Support for naming vehicle. Support for selecting what resources to display 2017-02-23 12:00:51 +01:00
Erik Eriksson
827e3c4395 Merge pull request #6162 from molobrakos/nut
sensor.nut: Handle multiple statuses returned
2017-02-23 11:56:25 +01:00
Pierre Ståhl
eefedaf332 Make it possible to ignore platforms in discovery (#6048)
* Make it possible to ignore platforms in discovery

* Add tests for discovery component

* small cleanups
2017-02-23 11:54:35 +01:00
Fabian Affolter
ac1e811dcd Upgrade slacker to 0.9.42 (#6173) 2017-02-23 10:56:35 +01:00
Fabian Affolter
49b4cd3c41 Upgrade fuzzywuzzy to 0.15.0 (#6175)
Add an optional extended description…
2017-02-23 10:56:00 +01:00
Barry Williams
960af20cc9 Added Openhome Support (#6153)
* Added Openhome Support

* added to coveragerc

* PR suggestions

* revert accidental deletion

* More PR suggestions and a lint fix

* Removed semicolons
2017-02-22 17:01:06 -05:00
Daniel Høyer Iversen
6c91e04852 Refactor broadlink (#6168)
* refactor broadlink

* typo
2017-02-22 22:11:49 +01:00
Johann Kellerman
74837dbf45 Restore for device_tracker (#6150) 2017-02-22 22:55:11 +02:00
Erik Eriksson
3b693d5e70 generic camera: improved exception handling (#6158)
Avoid unhandled exception and stack trace when server closes connection by changing from handle ClientDisconnectedError to DisconnectedError. Also added HttpProcessingError, which was missing.
2017-02-22 07:43:52 -08:00
Erik
23dd76cdc5 Handle UPS:es that returns more than one status (e.g. 'OL CHRG'). 2017-02-22 14:38:00 +01:00
Greg Dowling
896e0476ff Bump pywemo version. Improves notifications for insight devices. (#6159)
Add an optional extended description…
2017-02-22 12:23:25 +01:00
Pascal Vizeli
b0d3bbed79 Convert mqtt platforms to async (#6145)
* Convert mqtt platforms to async

* fix lint

* add more platforms

* convert mqtt_eventstream

* fix lint / add mqtt_room

* fix lint

* fix test part 1

* fix test part 2

* fix out of memory bug

* address comments
2017-02-22 09:43:22 +01:00
Erik Eriksson
65ed85c6eb volvooncall: fix missing property. see vehicle when discovered. (#6144) 2017-02-22 00:24:42 -08:00
Johann Kellerman
aee8758fc1 Restore input_select and test helper proposal (#6148)
* Restore input_select and test helper proposal

* DB still active
2017-02-22 00:15:48 -08:00
Pascal Vizeli
8983b826c4 Bugfix automation state linsteners (#6120)
* Bugfix automation state linsteners

* address paulus comments.

* fix lint

* fix lint v2
2017-02-22 00:02:37 -08:00
Johann Kellerman
11d3093a30 Restore: migrate fastdotcom and speedtest to restore (#6149) 2017-02-21 18:10:09 -08:00
Erik Eriksson
15e8a22100 dovado: GiB -> GB (#6143) 2017-02-21 18:54:20 -05:00
Pascal Vizeli
10fb30e924 Update jinja to 2.9.5 (#6146) 2017-02-21 09:05:44 -08:00
Justin Dray
b7b1429ac7 Add support for waking up Samsung TVs over the network (#6114)
* Add support for waking up Samsung TVs over the network

* Return the correct supported features for samsungtv

* Update requirements_all
2017-02-21 16:57:29 +01:00
Daniel Høyer Iversen
9f4a9585d2 miflora lib version (#6142) 2017-02-21 14:43:17 +01:00
Lev Aronsky
c1be5ede1c Add 'entity_picture' to Darksky component (#6141) 2017-02-21 00:01:44 -08:00
David McNett
3beb87c54d New component 'insteon_plm' and related platforms (#6104)
* Connect to PLM and process simple protocol callbacks

* Baseline commit

* Connect to PLM and process simple protocol callbacks

* Baseline commit

* Connection working again

* Async add devices is working via callback now

* Beginning to interface with PLM library for control and state

* Deal with brightness in 255 levels with library

* Change sub names to match API changes

* Remove PLM-level update callback

* Support dimmable based on underlying PLM device attributes

* Expand to non-light platforms

* Stubs for turn on and off

* Current version of Python library

* Amend to use switch device attributes

* Use asyncio endpoints for control

* Add logging line

* Bump module version to 0.7.1

* Auto-load platforms, display device info/attributes

* Unify method name for getting a device attribute

* Require Current version of insteonplm module

* Import the component function in each platform in the balloob-recommend manner

* For consistency, handle switch state as onlevel just like lights

* Use level 0xff for on state, even with binary switches

Observing the behavior of a 2477S switch, it looks like even the non-dimmable
devices use 0x00 and 0xff for off/on respectively.  I was using 0x01 for on
previously, but that yields unnecessary state change callbacks when message
traffic ends up flipping the onlevel from 0xff to 0x01 or 0x01 to 0xff.

* Use sensorstate attribute for sensor onoff

* Move new device callback to devices attribute

* Add support for platform override on a device

* Bump version of insteonplm module

* Default overrides is an empty list

* Avoid calling private methods when doing common attributes

* Remove unused CONF_DEBUG for now

* flake8 and pylint code cleanup

* Move get_component to local function where it is needed

* Update to include insteonplm module.

* New files for insteon_plm component

* Legitimate class doctring instead of stub

* Docstring changes.

* Style changes as requested by @SEJeff

* Changes requested by @pvizeli

* Add @callback decorator to callback functions

* Opportunistic platform loading triggered by qualifying device detection

Instead of loading all the constituent platforms that comprise the insteon_plm
component, instead we defer and wait until we receive a callback for a device
that requires the platform.
2017-02-21 08:53:39 +01:00
Johann Kellerman
fdc373f27e Restore_state helper to restore entity states from the DB on startup (#4614)
* Restore states

* feedback

* Remove component move into recorder

* space

* helper

* Address my own comments

* Improve test coverage

* Add test for light restore state
2017-02-20 23:40:27 -08:00
Matt N
2b9fb73032 zoneminder: Add camera mjpeg stream support (#6098) 2017-02-20 22:17:11 -08:00
Paulus Schoutsen
36cda8c6b2 Merge remote-tracking branch 'origin/master' into dev 2017-02-20 21:57:37 -08:00
Paulus Schoutsen
041f1edd35 Update frontend 2017-02-20 21:56:38 -08:00
Paulus Schoutsen
32873508b7 Add initial group config (#6135) 2017-02-20 21:53:55 -08:00
Paulus Schoutsen
addd955a6b Version bump to 0.38.4 (#6137) 2017-02-20 21:52:36 -08:00
Paulus Schoutsen
022afcf050 Merge pull request #6136 from home-assistant/release-0-38-4
0.38.4
2017-02-20 21:50:00 -08:00
Paulus Schoutsen
7ce2b9e018 Update frontend 2017-02-20 21:35:10 -08:00
Paulus Schoutsen
f256d1fe2f Bump netdisco to 0.8.3 2017-02-20 21:30:38 -08:00
Pascal Vizeli
1910440a3c Update aiohttp to 1.3.3 (#6129) 2017-02-20 21:29:38 -08:00
Lewis Juggins
1d4c3febee [google] suppress file_cache warning (#6128) 2017-02-20 14:14:45 -08:00
Pascal Vizeli
1d7ab0fa95 Cleanup some async stuff (#6127)
* Cleanup some async stuff

* change to schedule_update_ha_state()

* fix media player

* fix zigbee
2017-02-20 13:24:03 -08:00
Stefano Scipioni
14cf5b884b fixed error caused by POST call with no 'message' inside (for example… (#6038)
* fixed error caused by POST call with no 'message' inside (for example in edited messages)

* avoid assert
2017-02-20 21:15:45 +01:00
arraylabs
3d34368e6e myq cover support gates (#6123)
* update myq to 0.0.6

* update req to 0.0.6

Adds support for gates
2017-02-20 18:25:29 +01:00
Pascal Vizeli
e425801fe0 Homematic cleanup & hass best praxis (#6121) 2017-02-20 17:07:33 +01:00
John Arild Berentsen
73a4c09597 Set configurable refresh for zwave light to 5 seconds default. (#5957)
* Set configurable refresh value delay to 5 seconds

* Revert "Remove configurable refresh value delay, and fix it to 5 seconds"

This reverts commit edc2dc35d165e5e13b0f3cf4df40493a7ce764f1.

* Use default value of 5 sec for refresh, and still configurable

* Make default delay 5secs, but needs to be activated
2017-02-20 15:49:34 +01:00
Pascal Vizeli
1a4b62909b Pump ffmpeg to 1.5 (#6119) 2017-02-20 15:12:09 +01:00
Scott Bradshaw
37a8035c54 Added support for alternate SSH ports in AsusWRT (#4832) (#6109)
* Added support for alternate SSH ports in AsusWRT (#4832)

* Always set the SSH port in SSH arguments

* Removed whitespace

* Adding port=22 to the mock calls

* Changed config.get(CONF_PORT)  to config[CONF_PORT] per feedback from @pvizeli
2017-02-20 09:06:50 +01:00
Paulus Schoutsen
25408941de Mqtt fixes (#6116)
* Fix MQTT stop

* MQTT: Make sure to have connection setup at end of MQTT setup.

* Fix MQTT connect
2017-02-19 22:43:10 -08:00
Paulus Schoutsen
b969fea900 Z-Wave config panel fix (#6113) 2017-02-19 22:25:03 -08:00
Robbie Trencheny
2cc6fe6609 Fix links in template
Closes #6112
2017-02-19 21:00:54 -08:00
Tom Matheussen
66d8787d47 Weather platform Forecast (#4721)
* Added forecast functionality to the weather platform, updated OWM to get forecast data

* style fixes

* Changed returned forecast data to a more managable dict

* Fixed line length

* forecast will always be collected, data returned from owm is based on metric setting

* use list comprehension to create the forecast data

* Added forecast data to the weather demo

* Create dict directly in list comprehension

* Minor variable change in weather demo platform

* Convert forecast temperatures in weather component

* set forecast attributes as constants

* Style fixes and tests

* Copied forecast_entry instead of mutating data
2017-02-19 16:42:12 -08:00
Pascal Vizeli
5d8e219448 Update aiohttp handling with upc connect (#6108)
* Refactor upc connect

* fix aiohttp cleanup

* fix test

* fix tests

* allow status code for login
2017-02-19 23:25:45 +01:00
Daniel Høyer Iversen
58f813b518 broadlink (#6101) 2017-02-19 17:45:57 +01:00
normakm
dee4c85c32 Add support for aliased owfs sensors (#6043)
* Support aliased owfs sensors

Current implementation does not support OneWire OWFS sensors that are aliased by OWFS alias.txt file:
http://owfs.org/index.php?page=aliases
Assumption is that folder name == sensor address

This change reads the supported families from owfs "family" file and adds both aliased and unaliased sensors.
(this approach also skips the "management" folders.. eg simultaenous, bus, alarm, statistics etc. For example when adding "simultaneous" as sensor (it also has "temperature" file) then owfs crashes)

* Update onewire.py

lint suggested style fixes

* Update onewire.py

Empty line removed

* Update onewire.py

comments removed
2017-02-19 01:59:44 -08:00
William Scanlon
a4318c3125 Added tamper detection to Wink devices. (#6072)
* Added tamper detection to wink devices.
2017-02-18 23:00:27 -05:00
Adam Mills
5f095b5126 Add supported_features to cover component (#6082) 2017-02-18 18:11:03 -08:00
William Scanlon
3cb1a5dd89 SimpliSafe updates (#6034)
* SimpliSafe updates

* Check login status

* Fixed requirements_all.txt
2017-02-18 17:47:52 -08:00
Kevin Siml
dfbef45e49 Add pushsafer.com notification service (#6050)
* Add pushsafer.com notification service

* Add pushsafer.com notification service

* Add pushsafer.com notification service

* Add pushsafer.com notification service

* Update pushsafer.py

* Update pushsafer.py

* Update pushsafer.py

* Update README.rst
2017-02-18 17:36:28 -08:00
Erik Eriksson
9e73115337 Updated volvooncall library + support sensors, heater and lock (#6052) 2017-02-18 17:09:25 -08:00
Andrey
beb8b4b11f Zwave: add power_consumption attribute (#6067)
* Zwave: Pull power consumption value into attribute.

* Zwave: Add power_consumption attribute.

* fix condition

* Update __init__.py

* Update

* Simplify class condition

* Handle empty class_id
2017-02-18 16:51:13 -08:00
dramamoose
003815c91a Update FLUX_LED by adding Effects (#6083)
* Add FLUX_LED Effects

Add add the various supported FLUX_LED effects

* Correct Flux_LED Issues

* Whitespace Changes

* Feed the Hound

* Feed the hound better food
2017-02-18 18:45:21 -05:00
Pascal Vizeli
e1cbd6b4c0 MQTT convert to async (#6064)
* Migrate mqtt to async

* address paulus comment / convert it complet async

* adress paulus comment / remove future

* Automation triggers should be async

* Fix MQTT async calls

* Show that event helpers are callbacks

* Fix tests

* Lint
2017-02-18 14:17:18 -08:00
Lindsay Ward
fa2c1dafdf Add platform for Yeelight Sunflower lights (#6060) 2017-02-18 14:05:55 -08:00
Erik Eriksson
76d1ee9fc2 Support for Pocket Casts (#6084) 2017-02-18 13:52:37 -08:00
Paulus Schoutsen
f29ee24b72 Do not allow config dependency (#6036)
* Do not allow config dependency

* Prevent config in discovery

* Migrate to blacklist
2017-02-18 11:31:37 -08:00
Adam Mills
b277fd55f9 [media_player.kodi] Fix for when no item id is provided (#6088) 2017-02-18 19:09:17 +00:00
kitcorey
75df4be733 Fix colortemp conversion for lifx lights (#6087) 2017-02-18 20:42:57 +02:00
Adam Mills
86a1b0a6c6 Websocket push notifications for Kodi (#6063)
* Websocket push notifications for Kodi

* Only create ws server if ws enabled

* Fix conditional websocket server creation
2017-02-18 00:26:07 -08:00
John Arild Berentsen
799fbe42f8 zwave refactor, don't use ozw values directly in properties. (#5961)
* First round of not using values directly

* Round two

* lint

* Round four

* Conflict

* Round five

* Update zwave.py

* round six

* Docstring

* flakywakie

* Fetch values in constructor

* Blank line removal

* Set attributes in callback

* Docstring

* Round seven

* Ughgit add homeassistant/components/lock/zwave.py!

* Sloppy code
2017-02-17 23:56:05 -08:00
Andrey
c1eed148cc Clean up value_added in zwave light. (#6074) 2017-02-17 23:54:45 -08:00
Erik Eriksson
62fe9f955e update dovado version (#6081) 2017-02-18 08:15:32 +01:00
Daniel Høyer Iversen
b857f838df Broadlink (#6051)
* Add fail checking of broadlink data
2017-02-18 07:38:50 +01:00
Philipp Schmitt
c2dc940819 Update liveboxplaytv and catch connection errors (#6056)
* Update liveboxplaytv and catch connection errors

* Implement @pvizeli's suggestion

* lint
2017-02-17 21:40:19 +01:00
Fabian Affolter
ca9eb31d1d Upgrade aiohttp to 1.3.2 (#6059) 2017-02-17 21:39:29 +01:00
William Scanlon
8a5fe38d69 Slugify trackr device_id (#6062)
* Slugify trackr device_id

* Removed replace
2017-02-17 21:39:05 +01:00
Andrey
91c3a49a5b Zwave: Add forgotten service file (#6073)
* add print

* Add 'print_node' service to zwave.

* Add forgotten service file
2017-02-17 22:09:38 +02:00
Andrey
1f72506f9b Add 'print_node' service to zwave (#6069)
* add print

* Add 'print_node' service to zwave.
2017-02-17 22:03:55 +02:00
Adam Mills
843840b963 Add effect_list to hue light (#6065) 2017-02-17 20:37:45 +02:00
Andrey
bb64560089 Zwave: Make different messages for ignores by woraround and device config. (#6061) 2017-02-17 16:19:21 +01:00
Walker Boyle
ba305ee71c Add aurora sensor (#6003)
* Add aurora sensor

* allow custom forecast threshold for aurora binary sensor

* move AuroraGateway functionality to Aurora data object to conform with HA standards
2017-02-17 09:13:52 +01:00
Andrey
905f4bf994 Support zwave glob & domain device settings. (#6046)
* Support zwave glob & domain device settings.

* data[DATA_DEVICE_CONFIG].get() now always return non-None

* Update test

* Update tests2

* Lint fix
2017-02-16 15:19:22 -08:00
Pascal Vizeli
a496a7c792 Protect device_tracker scan interval / TTS logging (#6041)
* Protect device_tracker scan interval / TTS logging

* clear pass
2017-02-16 07:13:33 -08:00
Jose Juan Montes
714ba31b75 Mediaplayer clementine remote (#5877)
* Added Clementine Music Player Remote component.

* Remove stale stuff
2017-02-16 15:34:34 +01:00
Pascal Vizeli
2574b915dd Fix name in logging message (#6039)
Add an optional extended description…
2017-02-16 10:30:12 +01:00
Thibault Cohen
1eceb405ce [WIP] Hydroquebec plugin now use pyhydroquebec lib (#6000)
* Hydroquebec plugin now use pyhydroquebec lib

* Fix logger message

* Fix platform name
2017-02-16 10:22:21 +01:00
Thibault Cohen
8bef7d84bb Add Ebox sensor component (#5998)
* Add Ebox sensor component

* Fix PR #5998 comments

* Fix logger message
2017-02-16 09:29:43 +01:00
Paulus Schoutsen
75e41a21c9 Clean up mock_coro (#6037) 2017-02-15 23:19:34 -08:00
Jon Caruana
9c176ad85a LiteJet: Lights should have the option to dim in the UI. (#6031)
* LiteJet: Lights should have the option to dim in the UI.

* Fix lint error.
2017-02-15 22:41:03 -08:00
Paulus Schoutsen
0f1a254f3b Update frontend 2017-02-15 22:33:52 -08:00
Pascal Vizeli
6674a8ad57 [Device Tracker] Remove coro (#6014)
* Remove coro and make flow faster.

* fix lint

* address comments
2017-02-15 19:52:06 -08:00
Paulus Schoutsen
235d0057b1 Simplify customize (#6007)
* Simplify customize

* Maintain glob order

* Have glob overrule domain
2017-02-15 19:47:30 -08:00
Adam Mills
eb9400de4c cmus remove IO from properties (#6030) 2017-02-15 19:13:25 -08:00
Thibault Cohen
4addcccfac Update to pyfido 0.1.4 (#6033) 2017-02-15 19:12:29 -08:00
Thibault Cohen
5895f431b4 [WIP] Add Fido sensor (#5997)
* Add Fido sensor

* Fix PR #5997 comments

* Make error message usable
2017-02-15 21:21:38 +01:00
Erik Eriksson
0d06454a94 eliqonline lib upgrade (#6021) 2017-02-15 19:02:58 +01:00
Pierre Ståhl
fdb6dd81ce Add fake support for turn on/off for Apple TV (#5962)
* Add fake support for turn on/off for Apple TV

When the device is "turned off", no requests are sent to the device.
When the setting "start_off" is set to true, the device starts in off
state.

* Fix async comments

* Clean up supported features
2017-02-15 09:10:48 -08:00
Johan Bloemberg
2d33ee6258 Reconnect robustness, expose connection state. (#5869)
* Reconnect robustness, expose connection state.

- Expose connection status as rflink.connection_status state.
- Handle alternative timeout scenario.
- Explicitly set a timeout for connections.
- Error when trying to send commands if disconnected.
- Do not block component setup on gateway connection.

* Don't use coroutine where none is needed.

* Test disconnected behaviour.

* Use proper conventions for task creation.

* Possibly fix test race condition?

* Update hass import style
2017-02-15 16:10:19 +01:00
George.M
b1fa178df4 Added a config flag[Boolean] to declare if SenseHAT is attached (#5883)
* Added a config flag[Boolean] to declare if SenseHAT is attached to RaspberryPi

* Hound found a line too long violation - fix
2017-02-15 11:11:55 +01:00
Robbie Trencheny
cf99551110 Merge pull request #6008 from tdickman/dev
Fix abreviation for miles in darksky sensor
2017-02-14 23:57:33 -08:00
happyleavesaoc
58e707a264 Limitless light: bump version; fix conf (#6006) 2017-02-15 08:45:04 +02:00
Paulus Schoutsen
c1988acb36 Merge pull request #6010 from home-assistant/merge-master
Merge master
2017-02-14 21:55:30 -08:00
Paulus Schoutsen
7776bfefc2 Merge branch 'master' into merge-master 2017-02-14 21:53:07 -08:00
Paulus Schoutsen
ad95b2715e Merge pull request #6009 from home-assistant/release-0-38-3
0.38.3
2017-02-14 21:48:49 -08:00
Pascal Vizeli
d6f525a23f Bugfix sonos favorite_source after lost connection (#5996) 2017-02-14 21:38:56 -08:00
happyleavesaoc
b1eb3243bd timeMin fix (#5983)
Add an optional extended description…
2017-02-14 21:38:56 -08:00
William Scanlon
9bcc692ff2 Fix #5979 (#5980) 2017-02-14 21:38:56 -08:00
Fabian Affolter
91d2ba609e Remove unit of measurement 2017-02-14 21:38:43 -08:00
Martin Hjelmare
bbc5c3a300 Fix mysensors platforms version requirement (#5942)
* Notify and device tracker platforms require mysensors version 2.0 or
  greater.
2017-02-14 21:37:54 -08:00
Andrey
04f3fe0ba3 Point-fix zwave getter not to ignore label (#5938) 2017-02-14 21:37:32 -08:00
William Scanlon
ea26aa2c81 Fixed typos in wink climate (#5936) 2017-02-14 21:37:17 -08:00
Tom Dickman
71dc41655c Fix abreviation for miles in darksky sensor 2017-02-14 23:06:06 -06:00
Pascal Vizeli
80bc2666ac Make homematic climate dynamic for datapoints. (#5993)
* Make homematic climate dynamic for datapoints.

* Code cleanup

* Add more option

* add options

* Pump version 0.1.22

* optimaze
2017-02-14 23:19:57 +01:00
arraylabs
039559882b myq-cover updated to new requirement file, changed error message to be more informative (#5995) 2017-02-14 12:03:50 -08:00
Adam Mills
2993a4a7a5 Add object-assign polyfill support to polymer (#5994)
* Add object-assign polyfill support to polymer

* Conditionally load compatibility.js

* Remove compatibility preload

* Include newly compiled files

* Update compiled frontend with latest polymer
2017-02-14 12:00:45 -08:00
Pascal Vizeli
30ad8bcc80 Bugfix sonos favorite_source after lost connection (#5996) 2017-02-14 11:59:54 -08:00
Andrey
67d35e6454 Point-fix zwave getter not to ignore label (#5938) 2017-02-14 11:59:34 -08:00
Paulus Schoutsen
409b74b780 Update hassbian component with real output (#5989) 2017-02-14 09:34:17 -08:00
Pascal Vizeli
4b8e6e36b6 Make EntityComponent update process more robust. (#5943)
* Make EntityComponent update process more robust.

* address paulus comments

* Add platform to log message.
2017-02-14 09:32:40 -08:00
Fabian Affolter
cd9f3fa215 Upgrade pylast to 1.8.0 (#5991) 2017-02-14 13:10:38 +01:00
Sören Oldag
a06f89085d Added limitlessled support for bridge v6 and RGBWW bulbs. (#5958)
* Added limitlessled support for bridge v6 and RGBWW bulbs.

* Fix minor code style issue.

* Updated requirements_all.txt
2017-02-14 11:12:32 +01:00
happyleavesaoc
1bdd8e235a timeMin fix (#5983)
Add an optional extended description…
2017-02-14 10:30:16 +01:00
Erik Eriksson
39ca1a5a0d install libsodium to enable decryption of encrypted owntracks payload (#5976) 2017-02-13 23:59:09 -08:00
PetePriority
e17410c9a1 Added fritzbox_netmonitor.py (#5469)
* Added fritzbox_netmonitor.py

* Implemented changes
2017-02-13 23:58:23 -08:00
Fabian Affolter
f82ac0af60 Enable sensor for discovery (#5974)
* Enable sensor for discovery

* Remove blank line
2017-02-13 23:54:13 -08:00
Paulus Schoutsen
462b47c725 Update frontend (#5987) 2017-02-13 22:25:26 -08:00
Paulus Schoutsen
52567b1a48 Fix Z-Wave node config (#5986) 2017-02-13 22:16:39 -08:00
Andrey
ffb46ab541 Add 'days' flag to history fetch urls. (#5895)
* Add 'days' flag to history fetch urls.

* Fix unrenamed variable

* Switch to end_time param instead of days

* Checkthat end_time is parsed
2017-02-13 22:10:39 -08:00
Paulus Schoutsen
0effe14619 Z-Wave file name fix (#5985) 2017-02-13 21:58:16 -08:00
Andrey
e70b7ab509 Allow printing the number of states returned by history and time it took to extract. (#5973) 2017-02-13 21:48:53 -08:00
Paulus Schoutsen
36c196f9e8 Add initial Z-Wave config panel (#5937)
* Add Z-Wave config panel

* Add config to Z-Wave dependencies

* Lint

* lint

* Add tests

* Remove temp workaround

* Lint

* Fix tests

* Address comments

* Fix tests under Py34
2017-02-13 21:34:36 -08:00
Robbie Trencheny
6005933451 Merge pull request #5975 from fabaff/unit-moon
Remove unit of measurement
2017-02-13 18:08:49 -08:00
William Scanlon
41c2392f8b Fix #5979 (#5980) 2017-02-13 21:08:37 -05:00
Fabian Affolter
e866eeb518 Remove unit of measurement 2017-02-13 23:04:25 +01:00
Paulus Schoutsen
32fc164df3 Clean up HDMI_CEC [Breaking change] (#5932) 2017-02-13 13:52:11 -08:00
Gert-Jan van de Streek
5cad539859 Fix slow status updates from the knx bus (#5963)
* Fix slow status updates from the knx bus

The data set in the entity was an array, not the value.

@fixes https://github.com/home-assistant/home-assistant/issues/4407

* speed up status update
2017-02-13 22:48:48 +01:00
Josh Anderson
401263519d Only try to pair notify.webostv when not paired (#5967)
This allows the notify.webostv component to successfully register when
the TV is not currently powered on as long as a pairing record exists.
2017-02-13 22:29:18 +01:00
Andrey
0feb1c3e28 Add workaround for ignoring zwave devices and reversing cover open/close (#5922) 2017-02-13 20:59:42 +02:00
Paulus Schoutsen
b2d1774293 Fix Z-Wave (#5955) 2017-02-13 08:54:11 -08:00
Stuart Mumford
a8dc559519 Add support for the Open Energy Monitor Thermostat (#5583)
* Add support for the Open Energy Monitor Thermostat

* Fix linting errors

* Define an update method and local state

* fix linter

* Small tweaks.

Update oemthermostat version, default name and docstrings

* Fail to setup oem platform if connection fails.

* update requirements

* More tweaks to auth and exceptions

* Remove target temp
2017-02-13 16:45:04 +01:00
Philipp Schmitt
6d7041cd42 Reduce battery drain on Nuki Lock (#5945) 2017-02-13 14:43:12 +01:00
Valentin Alexeev
2ffdf1fdcd Bugfix/waqi sensor pwaqi version bump (#5944)
* Bump pwaqi to 1.4 to fix a typo in the underlying library.

* Update WAQI sensor to use pwaqi 2.0 which relies on AQICN public API.
This is a breaking change as the component now requires 'token' parameter.

* Fix lint
2017-02-13 14:28:40 +01:00
Fabian Affolter
f77eda2981 Upgrade thingspeak to 0.4.1 and use the correct API key (#5906) 2017-02-13 11:25:28 +01:00
Martin Hjelmare
b6404d70ec Fix mysensors platforms version requirement (#5942)
* Notify and device tracker platforms require mysensors version 2.0 or
  greater.
2017-02-13 11:23:28 +01:00
Fabian Affolter
9a5618fe96 Upgrade TwitterAPI to 2.4.4 (#5940) 2017-02-13 11:20:37 +01:00
arraylabs
bc1d14f9c3 Added myq cover component (#5886)
Add an optional extended description…
2017-02-13 11:20:07 +01:00
Alan Fischer
18f38229b2 iTach Remote Platform (#5660)
* Added itach remote device

* Added coverage & requirements

* Updated requirements

* Added schema, inline commands, and platform_setup failure if itach not found

* Removed unnecessary optional parameter

* Removed filename option for itach remote
2017-02-13 11:10:34 +01:00
Robbie Trencheny
feb2ebbc03 Fix AWS Lambda breakage after #5824 (#5935)
Add an optional extended description…
2017-02-13 09:27:50 +01:00
Paulus Schoutsen
7b56fe2af6 Update frontend (#5939) 2017-02-13 00:00:41 -08:00
Paulus Schoutsen
8ca3ca8564 Z-Wave: Rename customize to device_config [Breaking change] (#5933)
* Z-Wave: Rename customize to device_config

* Fix light

* Make entity id not required
2017-02-12 23:55:27 -08:00
Paulus Schoutsen
7401ec96b5 Version bump to 0.38.3 2017-02-12 23:31:04 -08:00
Pascal Vizeli
41849eab06 Core cleanup: two stage shutdown (#5876)
* Core cleanup: two stage shutdown

* fix spell

* fix

* add async logger to close

* change aiohttp to use CLOSE

* address paulus comments

* Fix tests

* Add unittest
2017-02-13 06:24:07 +01:00
William Scanlon
4623d1071e Fixed typos in wink climate (#5936) 2017-02-12 19:34:13 -08:00
Paulus Schoutsen
a37a3af126 Merge pull request #5928 from home-assistant/release-0-38-2
0.38.2
2017-02-12 15:49:58 -08:00
John Arild Berentsen
1a0a8f106e Bugfix for #5900 (#5901) 2017-02-12 15:47:20 -08:00
John Arild Berentsen
6311f21d31 Bugfix for #5900 (#5901) 2017-02-12 15:47:04 -08:00
Andrey
f4372a7df5 Fix getters that ignored labels. (#5903)
* Fix getters that ignored labels.

* Try 5 times for changed dict

* fix lint

* Add decorator with retrying functions.

* Fix lint

* use retries instead of decorator
2017-02-12 15:42:09 -08:00
Andrey
9b0a3e4c5a force_update zwave sensors. (#5844)
* force_update zwave sensors with polling_intensity.

* use bool to cast

* Make all zwave sensors force_update=True
2017-02-12 14:10:56 -08:00
Andrey
35118b6d9c Make hdmi_cec work with the new customize (#5916) 2017-02-12 14:02:45 -08:00
Fabian Affolter
8991fcf835 Fix name (#5912) 2017-02-12 14:02:45 -08:00
happyleavesaoc
15ef55a4c8 bump myusps version (#5911) 2017-02-12 14:02:45 -08:00
Philipp Schmitt
d3c444ff10 [lock.nuki] Fix Nuki lock for Python 3.4 and 3.5 (#5899) 2017-02-12 14:02:45 -08:00
Paulus Schoutsen
153e354002 Version bump to 0.38.2 2017-02-12 14:01:26 -08:00
Paulus Schoutsen
da5823becb Make check ha config file work with custom config dir 2017-02-12 14:00:06 -08:00
Paulus Schoutsen
8d0731e9fc Merge branch 'master' into dev 2017-02-12 13:58:09 -08:00
Pierre Ståhl
3a262cd7e0 Fix artwork in Apple TV platform (#5874) 2017-02-12 22:34:02 +01:00
Pascal Vizeli
9aac2113b6 Add 'wait_template' to script commands / Refactory track_template (#5827)
* Add 'wait' to script commands.

* Add track_template + unittest / rename wait_template

* fix lint & test

* Fix handling / change automation-template / add tests

* address paulus comments
2017-02-12 13:27:53 -08:00
happyleavesaoc
5f0b2a7d15 [WIP] gstreamer media player (#5839)
* gstreamer media player

* gstreamer meta
2017-02-12 13:00:27 -08:00
happyleavesaoc
64cb65a04e fedex sensor (#5891)
* fedex sensor

* fix fedex requirement
2017-02-12 12:47:27 -08:00
happyleavesaoc
3f675afd5b ups sensor (#5890) 2017-02-12 12:47:12 -08:00
Colin O'Dell
289767522b Update qnapstats library; add support for new verify_ssl config (#5919) 2017-02-12 12:38:29 -08:00
Per Sandström
675dd04e97 vasttrafik: update token on read error (#5875) 2017-02-12 11:57:29 -08:00
Pierre Ståhl
e5085bf620 Add media_image to media_player component (#5754) 2017-02-12 11:42:56 -08:00
Paulus Schoutsen
780173befb Update frontend (#5923) 2017-02-12 11:35:36 -08:00
Paulus Schoutsen
dab6d011ca Add check_config API (#5898)
* Add check_config API

* Add config panel to default config

* Add tests

* Lint

* lint
2017-02-12 11:31:46 -08:00
Andrey
dc6a28a8b2 Make hdmi_cec work with the new customize (#5916) 2017-02-12 11:19:15 -08:00
Fabian Affolter
b2fae212cb Fix name (#5912) 2017-02-12 11:16:06 -08:00
Greg Dowling
9c400de64b Bump pywemo - fix for latest bridge firmware. (#5921) 2017-02-12 11:14:23 -08:00
Adam Mills
e4bbe37112 Add device_class support to cover component (#5881) 2017-02-12 11:08:06 -08:00
Jose Juan Montes
2103bfc824 Fixed proximity zone incorrectly using name instead of zone setting. (#5862)
* Fixed proximity zone incorrectly using name instead of zone setting.

* Fixed proximity tests to suit change.
2017-02-12 11:03:53 -08:00
Pascal Bach
f8be731891 [google] Update google component dependencies (#5904) 2017-02-12 17:55:17 +00:00
happyleavesaoc
4af9d0f9ea bump myusps version (#5911) 2017-02-12 18:49:02 +01:00
Philipp Schmitt
533d28ce40 [lock.nuki] Fix Nuki lock for Python 3.4 and 3.5 (#5899) 2017-02-12 10:22:55 +00:00
Paulus Schoutsen
b59b42db2c 0.38.1 (#5889)
* Upgrade AppleTV dep to 0.1.4

* Version bump to 0.38.1

* Update logbook in frontend
2017-02-11 19:58:20 -08:00
Paulus Schoutsen
a25e394a11 Upgrade AppleTV dep to 0.1.4 2017-02-11 19:25:20 -08:00
Paulus Schoutsen
44311193ef Add config component and hassbian example panel (#5868)
* Add hassbian panel

* Rename to generic config panel

* Allow loading hassbian as test

* Add tests

* Update frontend

* Lint

* Lint
2017-02-11 17:29:05 -08:00
Robbie Trencheny
2b2c1562a5 Version bump to 0.39.0.dev0 2017-02-11 14:39:35 -08:00
Robbie Trencheny
e0f1c8ac67 Merge pull request #5833 from home-assistant/release-038
Release 0.38
2017-02-11 14:38:12 -08:00
Johann Kellerman
abaf9e53c2 Component set add unsing OR (#5880) 2017-02-11 23:27:06 +02:00
Paulus Schoutsen
5ad934907a Revert "Stop using entity_picture that is known to be bad." (#5882) 2017-02-11 13:10:28 -08:00
Fabian Affolter
88653e66c8 Style updates (#5878)
* Use consts, update quoting, and update comments

* Update log message

* Update docstrings

* Update log messages

* Update log messages

* Update style

* Fix typo

* Add newline

* Fix indent

* Fix line too long
2017-02-11 11:29:37 -08:00
Andrey
b981bfba7e Stop using entity_picture that is known to be bad. (#5856)
* Stop using entity_picture that is known to be bad.

* Only abandon image on 400 or 404 response

* Return is_permanent_failure as a third part of response

* Add debug printout

* Fix lint

* Fix lint
2017-02-11 20:33:41 +02:00
Fabian Affolter
2711c12928 Upgrade psutil to 5.1.3 (#5873) 2017-02-11 14:48:54 +01:00
Petr Vraník
0aad6c72d2 version bump (#5871) 2017-02-11 13:53:45 +01:00
Daniel Høyer Iversen
d32949b099 rfxtrx 0.17 (#5870) 2017-02-11 10:55:38 +01:00
Jose Juan Montes
f5c58748b7 Adds play URL support to mpd (makes it work with tts). (#5863)
* Adds play URL support to mpd (makes it work with tts).

* Removed extra line at the end of the file.
2017-02-11 10:07:31 +01:00
Paulus Schoutsen
3a7309ab62 Update frontend (#5866) 2017-02-10 21:06:42 -08:00
Paulus Schoutsen
d8a34877d4 Version bump to 0.38 2017-02-10 20:55:52 -08:00
Marcelo Moreira de Mello
3fb70afb14 Avoid traceback for Amcrest cameras/firmware that does not have the software_information API call (#5865)
* Avoid traceback for Amcrest cameras/firmware that does not have the software_information API call

* Make lint happy
2017-02-10 20:55:34 -08:00
Johan Bloemberg
bb043c47f8 Rflink update and small refactor. (#5789)
* Use same pattern for device defaults in both platforms.

* Update Rflink that passes loop downstream.

* Update requirements.
2017-02-10 20:55:34 -08:00
Paulus Schoutsen
849ae9903c Recorder run can be None (#5854) 2017-02-10 20:55:34 -08:00
Johann Kellerman
66088377e1 [recorder] Run end model changed in session scope (#5858) 2017-02-10 20:55:34 -08:00
Paulus Schoutsen
0e6ab3ace6 Update frontend (#5855) 2017-02-10 20:55:34 -08:00
Pascal Vizeli
eaa6392535 Fix check_config script. (#5853) 2017-02-10 20:55:34 -08:00
Petr Vraník
a071cd21f2 version bump (#5846)
Add an optional extended description…
2017-02-10 20:55:33 -08:00
Teemu R
0f6aed16a2 bump python-yeelight version (#5850)
Add an optional extended description…
2017-02-10 20:55:33 -08:00
Christian Brædstrup
cee389f621 D-Link switch version bump of external library (#5843) 2017-02-10 20:55:33 -08:00
Andrey
2b62e9f008 Fix zwave helper getter not to fail on some None results. (#5845) 2017-02-10 20:55:33 -08:00
Adam Mills
3d7b79f523 [recorder] Add tests for full schema migration (#5831)
* [recorder] Add tests for full schema migration

* Remove leftover code

* Fix duplicate creation of sqlalchemy Index object

* It's that kind of day...

* Improve models_original docstring
2017-02-10 20:55:33 -08:00
Philipp Schmitt
7bf7c727d1 Refactoring and JSON decode error handling (#5826)
* Refactoring and JSON decode error handling

* Catch ValueError instead of simplejson.scanner.JSONDecodeError
2017-02-10 20:55:33 -08:00
Pascal Vizeli
3f87d28616 Update aiohttp 1.3.1 (#5838) 2017-02-10 20:55:33 -08:00
Pierre Ståhl
7259082de5 Reuse default aiohttp session (#5836) 2017-02-10 20:55:33 -08:00
Pierre Ståhl
60f85b1e09 Handle connection errors when connecting to Apple TVs (#5829)
* Handle connection errors when connecting to Apple TVs

Also bump pyatv to 0.1.2 which fixes a request leak.

* Fix pylint error

* Fix import order
2017-02-10 20:55:33 -08:00
Erik Eriksson
0fdf1391e2 Don't thow exception if connection to server is lost (#5775) 2017-02-10 20:55:33 -08:00
Marcelo Moreira de Mello
75887e6069 Avoid traceback for Amcrest cameras/firmware that does not have the software_information API call (#5865)
* Avoid traceback for Amcrest cameras/firmware that does not have the software_information API call

* Make lint happy
2017-02-10 20:51:19 -08:00
Adam Mills
e877d572f5 binary_sensor sensor_class to entity device_class (#5860)
* binary_sensor sensor_class to entity device_class

* Linter fixes

* Should be it
2017-02-10 20:46:15 -08:00
Johan Bloemberg
67957cbfa8 Rflink update and small refactor. (#5789)
* Use same pattern for device defaults in both platforms.

* Update Rflink that passes loop downstream.

* Update requirements.
2017-02-11 00:24:07 +01:00
Paulus Schoutsen
b10d20bcab Recorder run can be None (#5854) 2017-02-10 12:55:59 -08:00
Johann Kellerman
cbf3a2ecae [recorder] Run end model changed in session scope (#5858) 2017-02-10 22:22:15 +02:00
Paulus Schoutsen
23ff2eb79c Update frontend (#5855) 2017-02-10 09:30:13 -08:00
Paulus Schoutsen
6ffab53377 Core: cleanup timer (#5825)
* Minor core cleanup

* Cleanup timer

* Lint

* timeout with correct loop

* Improve timer thanks to pvizeli

* Update core.py

* More tests
2017-02-10 09:00:17 -08:00
Erik Eriksson
c7c3b30e0a Do not call state if device isn't available (#5835) 2017-02-10 08:59:58 -08:00
Andrey
0b5191a247 Add support for zwave wakeup setting. (#5849)
* Add support for zwave wakeup setting.

* rename wakeup
2017-02-10 08:54:48 -08:00
Pascal Vizeli
4e8d20328a Fix check_config script. (#5853) 2017-02-10 08:51:08 -08:00
Pascal Vizeli
8785e5826e telegram small cleanup/style (#5852) 2017-02-10 16:39:02 +01:00
Teemu R
1da6181491 bump python-yeelight version (#5850)
Add an optional extended description…
2017-02-10 14:45:31 +01:00
Christian Brædstrup
a150a69cca D-Link switch version bump of external library (#5843) 2017-02-10 12:00:28 +01:00
Andrey
5bd54f69cc Fix zwave helper getter not to fail on some None results. (#5845) 2017-02-10 12:30:44 +02:00
Mark Oude Veldhuis
0d76d72b9f Add support for multiple devices to Tado device tracker (#5810)
* Add support for multiple devices to Tado device tracker

* Hound did not agree with my usage of spaces

* Two blank lines were expected

* Keep CONF_HOME_ID in the Tado file

* Make home_id optional

* Work with different API URLs depending on home_id being present

* Remove CONF_HOME_ID from HA's const.py file

* Missed removing CONF_HOME_ID from the import
2017-02-09 18:50:14 -08:00
Boris K
5ecef6aaac Add history_stats sensor (#5610)
* Add new sensor/history_stats component

* Add real unit tests

* Code style changes requested for pull request

* Remove time aliases & allow datetime values

* Reformat unit tests

* Remove all async behavior in history_stats

* Change duration format
2017-02-09 18:47:12 -08:00
Adam Mills
be08bf0ef7 [recorder] Add tests for full schema migration (#5831)
* [recorder] Add tests for full schema migration

* Remove leftover code

* Fix duplicate creation of sqlalchemy Index object

* It's that kind of day...

* Improve models_original docstring
2017-02-09 18:17:17 -08:00
Philipp Schmitt
4c5e6399e9 Refactoring and JSON decode error handling (#5826)
* Refactoring and JSON decode error handling

* Catch ValueError instead of simplejson.scanner.JSONDecodeError
2017-02-09 17:57:19 -08:00
Pascal Vizeli
2e8e5a35b5 Update aiohttp 1.3.1 (#5838) 2017-02-09 17:31:20 -08:00
Pierre Ståhl
841321f154 Reuse default aiohttp session (#5836) 2017-02-09 23:07:46 +01:00
Stefano Scipioni
ebfff6a907 Telegram webhooks (#5793)
* new component telegram_webhooks

* keyboard support in telegram notify

* telegram_webhooks has no tests

* requirement like notify/telegram

* ops, requirements_all.txt needed for travis

* ops, requirements_all.txt is generated by script/gen_requirements_all.py

* check telegram trusted networks in web handler

* raise an event now

* use of hass.config.api.base_url

* more readable

* small cleanups

* Small style change for HA guideline

* fix lint

* revert return to origin
2017-02-09 23:05:28 +01:00
Pierre Ståhl
ecbbb06b2f Handle connection errors when connecting to Apple TVs (#5829)
* Handle connection errors when connecting to Apple TVs

Also bump pyatv to 0.1.2 which fixes a request leak.

* Fix pylint error

* Fix import order
2017-02-09 22:25:06 +01:00
Paulus Schoutsen
c54517de90 Convert config.components to a set (#5824) 2017-02-09 20:21:57 +02:00
Erik Eriksson
f3b9fa2f41 Don't thow exception if connection to server is lost (#5775) 2017-02-09 09:00:18 -08:00
Paulus Schoutsen
e5256ccf1f Merge remote-tracking branch 'origin/master' into dev 2017-02-09 08:54:40 -08:00
John Arild Berentsen
298575f7cb Adding helper for get and set values (#5743)
* cleanup

* Update __init__.py

* Update __init__.py

* Update __init__.py
2017-02-09 13:40:35 +01:00
Paulus Schoutsen
c550a316a4 Make device sun light trigger async (#5823) 2017-02-09 00:10:53 -08:00
Paulus Schoutsen
4398b8b5c6 Deprecate event decorators (#5822) 2017-02-09 00:10:38 -08:00
Pascal Vizeli
2cbed9cd96 Move signal handling out of core to bootstrap (#5815)
* Move signal handling out of core to bootstrap

* Fix tests
2017-02-08 21:58:45 -08:00
Paulus Schoutsen
7eb4bdc37b Upgrade aiohttp to 1.3 (#5821) 2017-02-08 21:27:36 -08:00
Paulus Schoutsen
ebceca36ec Update frontend (#5820) 2017-02-08 20:55:15 -08:00
Paulus Schoutsen
03fe5b04b5 Remove non-working webfont preload (#5819) 2017-02-08 20:31:36 -08:00
Duoxilian
7fa08059dc Support away_mode as permanent hold and hold_mode as temporary hold. (#5725)
* Support away_mode as permanent hold and hold_mode as temporary hold.

* Add comments to explain code better. Remove indefinite hold preference
to be consistent with 'away_mode'.
2017-02-08 20:04:09 -08:00
John Arild Berentsen
fdcf5fe233 Bugfixes (#5740)
* wrong data for lock alarm_type

* missing whitespace

* Not possible to set codes starting with 0
2017-02-08 19:59:47 -08:00
Johann Kellerman
415500de23 [recorder] Protect against running in the event loop (#5812) 2017-02-08 19:58:43 -08:00
William Scanlon
628b169393 Fixed call to object_id() (#5814) 2017-02-08 19:57:58 -08:00
Sean Dague
49f2540730 Enhancements to ARWN platform (#5816)
* Fix arwn platform discover_sensors

The discover_sensors function can return either singletons or a list
of sensors. However the consumer was always expecting a list. This
fixes it to work in both cases.

* Add custom icons to arwn sensors.

This adds some custom icons for different kinds of weather sensors
that the arwn platform returns. Makes it a little easier to see what's
going on.
2017-02-08 19:56:44 -08:00
Teagan Glenn
76db4cc099 Change medium state for filtering (#5817) 2017-02-08 19:55:48 -08:00
Pascal Vizeli
d29b7f6910 Ffmpeg update 1.4 (#5813)
* Pump ffmpeg version

* update entity

* next 1.4
2017-02-08 23:18:23 +01:00
Johann Kellerman
612aa1cf21 Initial (#5811) 2017-02-08 13:16:39 -08:00
Andreas Cambitsis
4f20a2d3ea Upgrade Russound integration to v0.1.7 (#5756)
* Bumped up version to use 0.1.7 of Russound integration module.
Fixed bug arising from not supporting TURN_ON state (fixes issue https://github.com/home-assistant/home-assistant/issues/5012)
Implemented state support in 0.1.7 such that component state is returned from the actual AMP. (Still uses polling model though).
Tested it with home-assitant users @laf (original developer of the module) and @hofsta.  Works fine with their Russounds.

* Made styling / compliance changes and updated correct version of russound module on requirements_all.txt.

* Changed handling of properties to be compliant with https://github.com/home-assistant/home-assistant/issues/4210
(Specifcailly added member variables for state, volume and source to cache these values, and introduced Update() method to set their values).

Now returns None if the selected source index that is returned from russound is greater than the length of the specified source list in the yaml config.
Removed unnecesary comment.

* Removed blank line after docstring.

* Removed updated() in class init and added True paramter to add_devices in setup_platform.

* Dropped the no longer needed self.update()
2017-02-08 15:53:59 -05:00
Teemu R
061985bc65 Add available property and typing hints (#5593)
* light.demo: add available property, add typing hints

* light.demo: keep all lights available, fix init ordering

* Fix issues raised during review

* Update demo.py
2017-02-08 12:13:07 -08:00
Andrey
4b15946a9b Make sure workaround_component is not none (#5808) 2017-02-08 21:11:36 +02:00
Pascal Vizeli
881d53339b [Image_Processing][Breaking Change] Cleanup Base face class add support for microsoft face detect (#5802)
* [Image_Processing] Cleanup Base face class add support for microsoft face detect

* fix lint

* add unittest for micosoft detect

* fix test
2017-02-08 09:19:40 -08:00
Pascal Vizeli
3f82ef64a1 Move core service from core to components (#5787)
* Move core servcie from core to components

* add new handler for signals/exception

* Static persistent id

* Move unittest

* fix coro/callback

* Add more unittest for new services

* Address comments

* Update __init__.py
2017-02-08 09:17:52 -08:00
Daniel Høyer Iversen
08efe2bf6d Improve warning message in template rendering (#5806)
* improve warning message when template is none

* improve error message when template is none

* improve error message when template is none

* improve error message when template is none
2017-02-08 09:07:43 -08:00
Johann Kellerman
db6c166abe Update sma.py (#5807) 2017-02-08 09:07:03 -08:00
George.M
8951e1bdc0 The word router was misspelt (#5803)
fixed as this message is user facing
2017-02-08 12:28:45 +01:00
Pierre Ståhl
250523c1d8 Add discovery suppport to Apple TV (#5801)
Add an optional extended description…
2017-02-08 12:17:23 +01:00
Philipp Schmitt
2dab6cbb0e Mailgun notify service (#5782)
* Mailgun notify service

* Update dependency to version 1.3

- The provided credentials (including the domain) are now checked during
startup, as requested by @balloob
- The domain name is now optional
- There's a new config item "sandbox" which indicates whether to use the
sandboxed domain in case the domain is not set

* Fix a few lint issues

* Disable lint check no-value-for-parameter
2017-02-07 22:22:19 -08:00
Johan Bloemberg
0e6dd39c15 Add support for fluxled discovery. (#5784)
* Add support for fluxled discovery.

* Make use of device type/protocol auto detection.
2017-02-07 21:49:36 -08:00
Johann Kellerman
490ef6afad WIP: [component/recorder] Refactoring & better handling of SQLAlchemy Sessions (#5607)
* Refactor recorder and Sessions

* Cover #4352

* NO_reset_on_return

* contextmanager

* coverage
2017-02-07 21:47:41 -08:00
Paulus Schoutsen
bdebe5d53c Update frontend (#5800) 2017-02-07 21:30:24 -08:00
Adam Mills
ecfe8e0a9a Formalize supported_features as entity property (#5794)
* Formalize supported_features as entity property

* Remove extra emulated_hue conditions

* Generate log message in executor
2017-02-07 20:42:45 -08:00
Jeff Wilson
4fa4d7347f Fix climate.set_fan_mode yaml (#5799) 2017-02-07 20:38:16 -08:00
Andrey
1b54218d46 Create a file for zwave workarounds. (#5798)
* Create a file for zwave workarounds. Add sensor->binary_sensor for fgfs101 (#2)

* Don't use default None
2017-02-07 20:37:11 -08:00
Robbie Trencheny
b8a0792424 Bump netdisco to 0.8.2 2017-02-07 14:11:51 -08:00
Josh Wright
35f6dbc9dc Update python-nest dependency version (#5795)
The nest-cam changes have now been merged into the upstream library, so
there is no need to track a specific branch.

Updating to 3.1.0 also fixes a structure parsing bug I was experiencing.
2017-02-07 22:55:49 +01:00
Fabian Affolter
12bc7c7316 Upgrade pyasn1 to 0.2.2 (#5796) 2017-02-07 22:55:21 +01:00
Pascal Vizeli
acdda1f42b Revert last change on TTS cache load for more speed (#5797) 2017-02-07 22:54:52 +01:00
Martin Hjelmare
45a7c27280 Add mysensors device tracker and platform discovery (#5781)
* Add mysensors device_tracker platform

* Add discovery of device_tracker platforms

* Enable discovery of device_tracker platforms that are not
  DeviceScanner.
* Update signature of setup_scanner function in all affected platforms.
* Add test.
* Use discovery for mysensors device_tracker platform.

* Remove gps accuracy

* Small change to core like schema

* fix depency
2017-02-07 20:47:11 +01:00
Fabian Affolter
c7fd28c10f MQTT discovery (#5724)
* Change implementation

* Re-write

* Remove unused consts

* Update discovery.py

* Add tests

* fix other tests

* Fix check_config script test

* Lint

* Lint
2017-02-07 09:13:24 -08:00
Robbie Trencheny
45507cd9d1 TTS ID3 support (#5773)
* Add support for writing ID3 tags to the file for improved display in media players

* Lint and async fixes

* Use mutagen instead of taglib

* Fix tests

* Add fallback for album

* Requested changes

* move import

* Fix album name

* Change default options handling

* Move to member function / minor fix

* fix style

* fix lint

* change mutagen handling

* fix lint / add name to bytesio

* Update __init__.py

* Fix test, some cleanups

* Add mutagen exeption handling, fix tests

* fix mutagen taging
2017-02-07 12:07:11 +01:00
Trevor
063c0e8f44 Add icon_template to template sensor (#5766)
* Add icon_template to template sensor

* Update test_template.py

* Update test_template.py again

* Update template.py

* Update test_template.py

* Update test_template.py
2017-02-07 01:51:44 -08:00
Trevor
f0da576315 Fix Hue groups with same names (#5737)
* Revert "Fix hue lightgroups not syncing state (#5702)"

* Use light_id in unique_id for Hue groups

* Make sure HueLight unique_id is unique

* Update hue.py

* Update hue.py

* Update hue.py
2017-02-07 01:51:05 -08:00
andrey-git
f774538e66 Check config before restarting (#5609)
* Check config before restarting.

* Make check_config on restart async

* don't check if notification service exists

* Use .communicate()

* Reduce the number of notifications. Add tests.
2017-02-07 01:19:08 -08:00
Hermann Kraus
51810620fb Check for command topics when determinig the capabilities of an MQTT light. (#5770)
Previous code used the state topic which is obviously wrong:
- The state topic is already used to select optimistic mode.
- A light with only the state topic but no command topic would still announce the capability.
2017-02-07 01:13:00 -08:00
Pierre Ståhl
c7e282257a Initial support for Apple TV (#5698)
* Initial support for Apple TV

* hash_wip

* Add media_play support to Apple TV
2017-02-07 00:55:19 -08:00
Jesse Osiecki
9a2c84ee8a Added error checking to the MIMEImage encoding for smtp.py (#5753)
* Added error checking to the MIMEImage encoding for smtp.py

Added fallback to file attachment rather than inline image for images
without a known MIME

* PEP8 reqs to fix previous commit
2017-02-07 00:43:03 -08:00
Alessandro Mogavero
86da4f511d Improve Sky Hub error handling (#5762)
* Added error handling in function _get_skyhub_data

* Error line split for readability
2017-02-07 00:28:33 -08:00
Pascal Vizeli
48161697f8 Sonos fix favorite, coordinator, cleanup update (#5778)
* Sonos fix favorite, coordinator, cleanup update

* Bugfix snapshot restore
2017-02-07 00:27:55 -08:00
Stéphane Bidoul (ACSONE)
7927a6b588 add min and max jinja filters (#5765) 2017-02-07 00:25:47 -08:00
ray0711
1546ec7778 Fix brightness slider for mqtt template lights (#5780)
Add the missing supported_features declaration.
2017-02-07 09:52:07 +02:00
Marcelo Moreira de Mello
305d2612cf Fix attribute error for media_player/roku if roku device is unreachable and shows a persistent notification (#5785) (#5786) 2017-02-06 22:00:20 -08:00
Andrzej
34c7bac9b4 Update package.py (#5783) 2017-02-06 22:16:17 +01:00
Pascal Vizeli
2b124a008c Migrate lock component to async (#5748) 2017-02-06 21:25:34 +01:00
Alberto Arias Maestro
32dc276c53 Add support for position on wink cover (#5751)
Add support for position property for wink covers and fix state when stopped in the middle.
2017-02-06 15:43:36 +02:00
Adrián López
4cc711357a Allow to use data for enhanced messages (#5763)
Add notification data field to the message send to Facebook.
Allows to construct richer messages like cards, quick replies, attach
images, videos, etc
2017-02-06 14:01:41 +01:00
andrey-git
26a3ecc9d0 Merge pull request #5718 from benvm/modbus_write_register_array
Modbus write_register doesn't accept list
2017-02-06 13:55:48 +02:00
Johan Bloemberg
264bdc9d56 Make brightness display work for rgb devices. (#5675)
* Make brightness display work for rgb devices.

Non rgbw devices return 255 for getWarmWhite255. This is part 2 to make the brightness slider work for these devices.

https://github.com/Danielhiversen/flux_led/pull/25

* Query brightness property which return WW level or RGB brightness equivalent.

https://github.com/Danielhiversen/flux_led/pull/25
2017-02-06 11:32:51 +01:00
Daniel Høyer Iversen
150c8ac11c flux led o.13 (#5774) 2017-02-06 11:32:37 +01:00
Yannic-HAW
4a341ff55f - added send packet service to send ir packets directly from scripts (no need to define a switch for each command) (#5768)
- changed ip suffix of SERVICE_LEARN to use _ instead of . as ip seperator to avoid errors if used in yaml
2017-02-06 07:53:58 +01:00
Martin Hjelmare
0d89f2bc69 Update mysensors sensors (#5764)
* Add V_DIRECTION type for S_WIND.
* Add more predefined units of measurement.
2017-02-05 21:07:30 +01:00
Pascal Vizeli
2a139d6bc7 Add unittest for multible entities in one line (#5759) 2017-02-05 14:24:38 +01:00
Fabian Affolter
91bebca0b6 Upgrade pysnmp to 4.3.3 (#5757) 2017-02-05 11:22:32 +01:00
Philipp Schmitt
573fc651dc Store the key file in the config dir (#5732)
* webostv: Store the key file in the config dir

* Update the pylgtv source to use the repo by @TheRealLink

* Add missing config parameter
2017-02-05 10:39:04 +01:00
Fabian Affolter
d88c903537 Upgrade pyasn1 to 0.2.1 (#5755) 2017-02-05 10:16:57 +01:00
Martin Hjelmare
82c99f81fc Fix validation of serial port on windows (#5749)
* Fix validation of serial port on windows

* Use pyserial to check serial ports.
* Check that persistence file ends with either `.json` or `.pickle`.

* Change fix to not rely on pyserial

* Use generator expr instead of list comprehension
2017-02-04 21:54:20 -08:00
Fabian Affolter
02dfd9660e Upgrade zeroconf to 0.18.0 (#5746) 2017-02-04 20:52:11 +01:00
Fabian Affolter
6164b61e14 Upgrade psutil to 5.1.2 (#5745) 2017-02-04 20:51:49 +01:00
Fabian Affolter
4cb20ce6d9 Upgrade astral to 1.3.4 (#5744) 2017-02-04 20:51:22 +01:00
Joeboyc2
0ea81c1269 Change CONF_DEFAULT_COLOR CV type (#5700)
* Change CONF_DEFAULT_COLOR CV type

Changed  vol.Optional(CONF_DEFAULT_COLOR, default=DEFAULT_COLOR) from cv.string to cv.ensure_list

This allows the optional parameter default_color to be picked up correctly and to function

the option needs to be specifed as follows:

    default_color: [0,255,0]

Solution provided by @scossa2020 in issue #5338
https://github.com/home-assistant/home-assistant/issues/5338

* Update hyperion.py
2017-02-03 23:36:25 -08:00
Fabian Affolter
b29c167dde Upgrade psutil to 5.1.1 (#5736) 2017-02-03 09:09:14 -08:00
William Scanlon
25a68f3ce9 Update python-wink version (#5734) 2017-02-03 16:37:00 +01:00
Fabian Affolter
c0dcef6c3e Add wind bearing (#5730) 2017-02-03 09:44:07 +01:00
Fabian Affolter
6786f83c26 Upgrade pyowm to 2.6.1 (#5729) 2017-02-03 09:43:29 +01:00
Philipp Schmitt
7506569db9 Support for the Orange Livebox Play TV appliance (#5533)
* Support for the Orage Livebox Play TV appliance

* Add liveboxplaytv to coveragerc

* Minor refactoring

* Update requirements

* Adjust comments

* Fix alignment

* Fix some coding-style issues highlighted by Travis CI

* The livebox play TV does not support playing media

* Lint: shorten line

* Remove unused callback function

* Remove redundant backslash

* Implement changes requested by balloob

* Don't error out if channel name or media url could not be retrieved

* Support current program (media title property)

* Remove unnecessary check

* Clean up: Remove another unnecessary check, _CONFIGURING variable and _playing attribute

* Update liveboxplaytv dependency to version 1.4.4

* Fix liveboxplaytv requirement

* Improve media state (support for playing and pause state)

* Update liveboxplaytv.py
2017-02-02 23:52:52 -08:00
Fabian Affolter
f9ede73a55 Add moon sensor (#5726)
* Add moon sensor

* Update moon.py
2017-02-02 23:43:03 -08:00
Joseph Piron
4aa7f030e8 Adds average load to systemmonitor (#5686)
* Adds average load to systemmonitor

* split the values in 3 sensors

* hound ok
2017-02-02 23:33:15 -08:00
Wolf-Bastian Pöttner
e831a2705e Add support for FRITZ!DECT wireless switches based on fritzhome (#5541) 2017-02-02 23:29:18 -08:00
Ryan Kraus
537355924f Alert Component (#5201) 2017-02-03 07:20:51 +02:00
miniconfig
dbc2f6b9cd Merge pull request #5658 from miniconfig/openevse
Added new sensor component to monitor OpenEVSE chargers.
2017-02-02 23:52:11 -05:00
Adam Mills
6a64e79d7b [recorder] Index events time_fired to improve logbook performance (#5633)
* Index events time_fired to improve logbook perf.

* Updated implementation to track schema versions

* Added tests for schema migration support logic

* Rename check_schema to migrate_schema
2017-02-02 22:04:14 -05:00
miniconfig
4b62a0d924 Updated openvse sensor component to use new structure of openevsewifi library. 2017-02-02 21:46:35 -05:00
Valentin Alexeev
dfb991ce19 Bump pwaqi to 1.4 to fix a typo in the underlying library. (#5716) 2017-02-02 12:59:52 -08:00
Pascal Vizeli
f63874eb8c Migrate cover to async. (#5717) 2017-02-02 12:39:13 -08:00
Colin O'Dell
bc65452efb QNAP Sensor (#5666)
* Implement the QNAP sensor

* Add sensors immediately

* Remove unnecessary check

* Use CONF_SSL instead of CONF_PROTOCOL
2017-02-02 12:29:04 -08:00
Pascal Vizeli
2fc3dfff67 Migrate fan component to async. (#5723)
* Migrate fan component to async.

* Fix lint
2017-02-02 12:07:00 -08:00
Daniel Høyer Iversen
574384f446 update miflora lib and allow specification of bluetooth adapter (#5720) 2017-02-02 17:08:10 +01:00
Daniel Høyer Iversen
ee551e2a9c up rfxtrx lib (#5721) 2017-02-02 16:18:16 +01:00
Duoxilian
219337a574 Cleanup climate and ecobee (#5616)
* Remove redundant input validation which is already accomplished through
defined schemata.

* Rely on defined state attributes for hold mode.

* Remove misleading comment. This comment seems to assume that sleep
mode is a hold; it is a schedule instead. The code snippets in the
comment could never work.

* Remove use of constants for hold mode. Will be made irrelevant
by a planned change by nordlead2005.
2017-02-02 15:28:32 +01:00
Philipp Schmitt
ff65c2a114 Support for Nuki.io smart locks (#5715)
* Support for Nuki.io smart locks

* Update requirements and add lock.nuki to .coveragerc

* lint: Re-organize imports

* Schedule a state update instead of calling directly update_ha_state

* Remove update requests altogether

* Make sure there is no IO inside properties

* Fix: nuki lock are all initialized as "lock.unnamed_device"

* Update pynuki to 1.2 to avoid an extra REST API call for each lock init
2017-02-02 15:15:27 +01:00
Ben Van Mechelen
0ea9d935af Modbus write_register accept list 2017-02-02 10:23:13 +01:00
William Scanlon
80a794e587 Wink AC and addidtional sensor support (#5670)
* Added door bell sensors

* Initial support for AC units.

* Added new device service

* Quirky Aros AC unit support

* Use super() everywhere and error checking for token request.

* Ignore camera sensors during setup of alarms.

* Added manufacturer/device attributes to all wink devices.

* Fixed style errors

* Fixed remaining lint errors.
2017-02-01 22:43:12 -08:00
Trevor
b5f285a789 Fix OwnTracks state names (#5454)
* Fix OwnTracks state names (#5453)

* Update owntracks.py

* Update tests
2017-02-01 22:06:02 -08:00
Paulus Schoutsen
6e94f0d7cd Upgrade zeroconf dep" (#5706) 2017-02-01 21:48:30 -08:00
Pascal Vizeli
eefb603f17 Cleanup media_player universal platform / blocking platform. (#5671)
* Cleanup media_player universal platform / blocking platform.

* fix comments

* fix unittest

* fix lint

* fix unittest lint

* fix coro

* fix test

* fix tests part 2
2017-02-01 21:45:19 -08:00
Pascal Vizeli
10a104271e Cleanup climate platform for async update_ha_state / migrate generic thermostat (#5679)
* Cleanup climate from blocking stuff / migrate generic

* Migrate generic thermostat

* fix tests

* fix lint
2017-02-01 21:44:05 -08:00
Paulus Schoutsen
686c8466a0 Merge pull request #5707 from home-assistant/release-0-37-1
0.37.1
2017-02-01 21:34:52 -08:00
Paulus Schoutsen
181943e139 Version bump to 0.37.1 2017-02-01 21:19:45 -08:00
Trevor
e05c1bc160 Fix hue lightgroups not syncing state (#5702) 2017-02-01 21:19:28 -08:00
Johan Bloemberg
96745abf5d Prevent infinite loop in crossconfigured mqtt event streams (#5624)
* Prevent events about MQTT messages received to cause infinite loop when two HA instances are crossconfigured for mqtt_eventstream.

* Fix linting

* Publish all MQTT received events except incoming from eventstream. Also make it configurable.
2017-02-01 21:19:28 -08:00
John Arild Berentsen
17c4f4d391 [lock.zwave] Bugfix Zwave lock (#5619)
* Bugfix state

* remove debug
2017-02-01 21:19:28 -08:00
Pascal Vizeli
9ed8ee1261 Bugfix sonso source input (#5699) 2017-02-01 21:19:28 -08:00
Pascal Vizeli
df7ca22656 Fix bug for UNREACH devices / Variable handling and update. (#5689)
* Fix bug for UNREACH devices / Variable handling and update.

* fix track_time

* update after data after creation

* add message output

* change unreach

* change unreach code

* Revert "change unreach code"

This reverts commit f58430de3c.

* update pyhomematic
2017-02-01 21:19:28 -08:00
Hugo Dupras
9716cd3f48 Hotfix for netatmo cameras (#5644)
* Fix for missing netatmo tags in 0.37

Also fix issue with SSL certificate for vpn_url

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Netatmo welcome: vpn_url can be empty

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* add config floag to disable SSL verification for vpn_url

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Import CONF_VERIFY_SSL from const
2017-02-01 21:19:28 -08:00
Pascal Vizeli
6ee7878236 Bugfix async blocking loop with xml parser. (#5694) 2017-02-01 21:19:28 -08:00
Pascal Vizeli
bc7fd5611e Bugfix sonos group coordinator (#5691)
* Bugfix sonos group coordinator

* Fix tests
2017-02-01 21:19:28 -08:00
Erik Eriksson
27a91b357e Upgraded tellduslive (#5664) 2017-02-01 21:19:28 -08:00
Marcelo Moreira de Mello
26d0fd772b Fixes issue #5627 by bumping external Amcrest module to version 1.1.4 (#5662)
Add an optional extended description…
2017-02-01 21:19:27 -08:00
Daniel Høyer Iversen
a168bf64b6 bug fix in hue (#5623) 2017-02-01 21:19:27 -08:00
David-Leon Pohl
db09ef0a6f Fixes: Pilight Switch rejects alphanumeric IDs #5119 (#5601) 2017-02-01 21:19:27 -08:00
Trevor
647a93801c Fix hue lightgroups not syncing state (#5702) 2017-02-01 21:06:11 -08:00
Johann Kellerman
2fcaf8bda6 [sensor/sma] handle units correctly (#5657) 2017-02-01 21:01:06 -08:00
Johan Bloemberg
ae1f59970d Prevent infinite loop in crossconfigured mqtt event streams (#5624)
* Prevent events about MQTT messages received to cause infinite loop when two HA instances are crossconfigured for mqtt_eventstream.

* Fix linting

* Publish all MQTT received events except incoming from eventstream. Also make it configurable.
2017-02-01 21:00:05 -08:00
John Arild Berentsen
68d6bcd3ed [lock.zwave] Bugfix Zwave lock (#5619)
* Bugfix state

* remove debug
2017-02-01 20:57:57 -08:00
Pascal Vizeli
b2180fba63 Bugfix sonso source input (#5699) 2017-02-02 00:02:24 +01:00
Pascal Vizeli
b5b1d72ab6 Fix bug for UNREACH devices / Variable handling and update. (#5689)
* Fix bug for UNREACH devices / Variable handling and update.

* fix track_time

* update after data after creation

* add message output

* change unreach

* change unreach code

* Revert "change unreach code"

This reverts commit f58430de3c.

* update pyhomematic
2017-02-01 23:55:16 +01:00
Daniel Høyer Iversen
2a5ccff82e up rfxtrx lib (#5687) 2017-02-01 19:47:18 +01:00
Paulus Schoutsen
bdc62730bd Update frontend (#5696) 2017-02-01 09:03:35 -08:00
Hugo Dupras
676519d0cb Hotfix for netatmo cameras (#5644)
* Fix for missing netatmo tags in 0.37

Also fix issue with SSL certificate for vpn_url

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Netatmo welcome: vpn_url can be empty

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* add config floag to disable SSL verification for vpn_url

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Import CONF_VERIFY_SSL from const
2017-02-01 17:33:32 +01:00
Pascal Vizeli
a72d32b9af Bugfix async blocking loop with xml parser. (#5694) 2017-02-01 17:20:52 +01:00
Pascal Vizeli
32f8622bba Bugfix sonos group coordinator (#5691)
* Bugfix sonos group coordinator

* Fix tests
2017-02-01 16:53:02 +01:00
Johan Bloemberg
cabc4dff03 Use same pattern for device defaults in both platforms. (#5682) 2017-02-01 10:42:50 +01:00
Paulus Schoutsen
987f59e8d8 Update frontend (#5685) 2017-02-01 00:47:02 -08:00
Johan Bloemberg
7be3414785 Only set LANG=C.UTF8 during install. (#5648) 2017-01-31 19:30:53 -08:00
Paulus Schoutsen
8334bc908c Update frontend (#5683) 2017-01-31 19:29:07 -08:00
Michaël Arnauts
8247acb7b9 Move docker installation scripts to virtualization/Docker path. Splits out openalpr to seperate script. (#5676) 2017-01-31 19:02:06 -08:00
Erik Eriksson
89ec752064 Upgraded tellduslive (#5664) 2017-01-31 11:08:11 -08:00
Mathew Peterson
d65f07860c Refactors script/setup_docker_prereqs (#5506)
* Refactors script/setup_docker_prereqs

Refactors script/setup_docker_prereqs to allow toggling of packages
to being installed

* Adds support for openalpr to Docker

* Updates Dockerfile

Comments ENV directives in order to preserve cache.

* Fixes incorrect position of echo

* Fixes telldus installer by updating apt before pkg install
2017-01-31 18:11:51 +01:00
Johan Bloemberg
bbda2a72f4 Rflink 433Mhz gateway platform and components (#4547)
* Initial sketches of rflink component.

* Add requirement.

* Properly load configuration.

* Bump rflink for graceful parse errors and protocol callback.

* Cleanup, documentation and linting.

* More documentation, first sensor implementation (temp & hum).

* Add brightness/dim support for newkaku protocol.

* Use separate class for dimmables.

* Make sure non-dimmable newkaku devices are turned on.

* Move some code around, add switches. Support loading from config.

* Fix bug in ignoring devices.

* Fix initial state assumption.

* Improve reliability on invalid conditions.

* Allow configuration of group for new devices.

* Sensor icons.

* Fix parsing negative numbers.

* Correct icon.

* Allow sending commands serial.

* Pluralize.

* Allow adding sensors from config.

* Fix ignoring devices and bugs in previous commit.

* Share know devices so devices from configuration don't get added as lights.

* Lookup unit from value_key.

* Remove debug.

* Start implementing event protocol in place of packet protocol.

- Added first test suite for sensors.
- This currently breaks light and switch.

* Refactor switch component to fit new rflink changes. Add test suite.

* Fix style.

* Refactor and test lights. Bring coverage to 100%.

* Use non-broken and production tested rflink module.

* Update requirements.

* Bump for logging.

* Improve readability.

* Do not use global variable but keep known device state in intended place.

* Improve docs.

* Make icon support generic.

* Disable overriding icons in config, as it belongs in customization. Only keep custom icon for entities that are able to detect a icon based on the thing they represent (sensors in this case).

* Implement configuration schema, overall refactor of magic values.

* Fix bug in config/test wait_for_ack.

* Small refactors.

* Move command logic into separate class.

* Convert command sending logic to class based pattern instead of using the event bus.

* Start not using bus for rflink event propagation to platforms.

* Do not use event bus for all entity types.

* Fire an event on the bus for every switch incoming rflink command.

* Resolve lint errors, remove some old code.

* Known devices no longer need to be registered separately.

* Log bus events.

* Event callback is a..... callback.

* Use full entity id for events.

* Move event sending to entity.

* Log incoming events.

* Make firing events optional inline with rfxtrx.

* Add foundation for signal repetition.

* Add signal repetition config and tests.

* Make plain switchable type explicitly configurable.

* Enable default entity settings for automatically added entities as well.

* Prevent default configuration leaking accross entities.

* Make sure device defaults don't get overwritten by defaults further down.

* Don't let fast state switching and repetitions turn your house into a disco.

* Make repetitions more responsive.

* Disable on/off fallback on dimmables as it currently doesn't play nice with repetitions.

* Use rflink that allows send_command_ack to be safely cancelled.

* Reduce duplication and make repeat work for non-ack.

* Implement reconnection logic.

* Improve reconnection logic.

* Also cancel repetitions when entity state is changed due to external command.

* Update requirements.

* Fix linting.

* Fix spelling.

* Don't lie.

* Fix lint.

* Support for automatically creating protocol translation (fixes spaces in device names).

* Returned support for dimmable and on/off entity.

* Duplicate code to fix linting issues with inheritance.

* Allow overriding unit of measurement from config.
2017-01-31 08:11:52 -08:00
Johan Bloemberg
9925b2a8e0 Load mqtt_eventstream before any other component. (#5629)
This ensures that initial state changes for components are broadcasted on the MQTT bus.
2017-01-31 08:02:28 -08:00
Michaël Arnauts
b080ae154c Add devices detected by ping as SOURCE_TYPE_ROUTER instead of GPS (#5625) 2017-01-31 08:01:14 -08:00
Adrián López
14f8bc26d1 Voice command API.AI. First import (#5462)
* Voice command API.AI. First import

* Fixes suggested by hound

* Fixing comments

* Fix pylint and pydocstyle errors

* Change how speech is defined

Also clean some unused constants, remove card type (not used), define
a message when action is not defined and improve the message when
action is unknown.

* Change how speech is defined

Clean some constants.
Improve error messages.
Delete card type, not used.

* Tests for new Api.ai component

* Use async_add_job to python compatibility. New test to measure response time

* Add async_action option to choose between waiting or not for the action to execute

* Travis-ci needs more time

* Removed timeout tests

* Removed timeout tests

* Added apiai to .coveragerc as specified by PR doc
2017-01-31 07:54:54 -08:00
Pascal Vizeli
88d9d787a6 Add unittests for FFmpeg and spliting binary sensor (#5659)
* Spliting ffmpeg binary sensor and move service to component.

* unittests for component

* add unittest for binary_sensor

* exclude camera for tests
2017-01-31 07:48:03 -08:00
Paulus Schoutsen
9ae574c7d9 Update frontend (#5669) 2017-01-31 07:39:01 -08:00
Daniel Høyer Iversen
29816f3041 Vlc (#5665)
* vlc default name
2017-01-31 13:51:02 +01:00
Teemu R
5f0138f8e4 new yeelight backend lib, new features (#5296)
* initial yeelight based on python-yeelight

* adapt yeelight's discovery code & suppress exceptions on set_default

* Support flash & code cleanups

Adds simple pulse for flashing, needs to be refined.
This commit also includes changing transition from seconds to milliseconds,
and cleans up the code quite a bit.

* cleanup code, adjust default transition to 350

* bump required version to 0.0.13

* Cleaning up and marking todos, ready to be reviewed

* Renamed back to yeelight.
* Removed effect support for now until we have some sane effects available.
* Add "breath" notification for flash, currently hidden behind a False check due to unknown issue not accepting it.
* TODO/open points are marked as such.

* Fix a typo in rgb calculation

* yeelight_<bulbtype>_<mac> for autodetected bulbs

hostname from mdns seems to vary

* Lint fixes, add music mode, fix flash

* Flash transforms now to red and back
* Fix lint warnings
* Add initial music mode.

* remove unused mode logging, move set_mode to turn_on

* Add save_on_change configuration variable

* yeelight: check if music mode is on before enabling it.

* Fix linting, bump required python-yeelight version

* More linting fixes, use import when needed instead of saving the module handle

* Use OR instead of + for features assignment

* Fix color temperature support, convert non-rgb values to rgb values in rgb()

* Fix typo on duration, thanks @qzapwy for noticing

* yeelight: fix issues from review, behave when not available

* Implement available()
* Fix transition to take seconds instead of milliseconds
* Fix default configuration for detected bulbs
* Cache values fetched in update()
* Add return values for methods

* yeelight: kwarg-given transition overrides config, slight cleanups

* change settings back to optional, request update when calling add_devices

* As future version of python-yeelight will wrap exceptions, we can handle broken connections more nicely.

* bump yeelight library version

* Remove unused import

* set the default only when settings are changed and not, e.g., when turned on by automation

* update comment & fix linting
2017-01-31 10:01:11 +01:00
Teemu R
2c31e3ea8c Cleanup modes & available, bump version requirement (#5606)
* Cleanup modes & available, bump version requirement

* check for Noneness on available
2017-01-31 09:23:05 +01:00
Marcelo Moreira de Mello
976cd545fe Fixes issue #5627 by bumping external Amcrest module to version 1.1.4 (#5662)
Add an optional extended description…
2017-01-31 09:19:49 +01:00
Adam Mills
7f3ee8a83c [docker] cec install path fixed upstream (#5651) 2017-01-30 21:27:20 -05:00
miniconfig
495b0667e9 Added new sensor component to monitor OpenEVSE chargers equipped with the WiFi Kit. 2017-01-30 15:29:56 -05:00
Daniel Høyer Iversen
3b32afda01 bug fix in hue (#5623) 2017-01-30 09:20:35 -08:00
Daniel Høyer Iversen
3a1607500e Add set_options_service for input select (#5630) 2017-01-30 09:17:57 -08:00
Matt N
1bf3eba603 yarn setup_js_dev was deleted (#5639) 2017-01-30 09:15:26 -08:00
Fabian Affolter
ab019b9747 Upgrade slacker to 0.9.40 (#5650) 2017-01-30 09:14:00 -08:00
Paulus Schoutsen
55992468b0 Update frontend (#5652)
* Return empty result when history date is in future

* Update frontend
2017-01-30 09:12:07 -08:00
Fabian Affolter
87764a51ba Use device_state_attributes() for platforms (#5649)
* Use device_state_attributes() for platforms

* Update test

* Fix lint issue
2017-01-30 16:16:49 +01:00
Pascal Vizeli
ca558f6485 Add unittest for cleanup not validate ssl stuff. (#5643) 2017-01-30 13:09:36 +01:00
Paulus Schoutsen
f1d1f7d032 Update frontend (#5642) 2017-01-30 00:57:13 -08:00
Paulus Schoutsen
c8ff1094f8 Update frontend (#5640) 2017-01-30 00:20:51 -08:00
Paulus Schoutsen
318f3c9625 Update frontend (#5638)
* Ensure fonts get loaded quicker

* Update frontend
2017-01-29 23:26:35 -08:00
Paulus Schoutsen
da4f402ebe Update frontend (#5637) 2017-01-29 18:43:39 -08:00
Paulus Schoutsen
b5047bbaad Prioritize core.js (#5636)
* Prioritize loading app core script

* change app skeleton to be small
2017-01-29 18:36:48 -08:00
Pascal Vizeli
847a5a064d Aiohttp client unittest (#5635)
* add test for cleanup

* add test for mjpeg stream
2017-01-29 16:15:40 -08:00
Pascal Vizeli
261ffbbfea Move part of image_processing tests (#5634)
* Move part of image_processing tests

* fix lint
2017-01-29 14:40:37 -08:00
Martin Hjelmare
24f828d7eb Fix mysensors RGB and W light turn on (#5608)
* RGBW light needs a white value defined.
* Log error if V_RGB is not 6 characters and V_RGBW not 8 characters.
2017-01-29 12:59:13 +01:00
Kyle Hendricks
fddab7f2b4 Fixes the AsusWRT ip neigh regex to handle the possible IPv6 "router" flag (#5605)
See the last line here: http://linux-ip.net/gl/ip-cref/ip-cref-node62.html
2017-01-29 09:37:59 +01:00
David-Leon Pohl
a9325ea663 Fixes: Pilight Switch rejects alphanumeric IDs #5119 (#5601) 2017-01-28 17:49:16 -08:00
Fabian Affolter
5ae5d9b576 Upgrade rpi-rf to 0.9.6 (#5611) 2017-01-28 17:05:24 -08:00
Paulus Schoutsen
e32f933cb6 Version bump to 0.38.0.dev0 2017-01-28 15:13:59 -08:00
Paulus Schoutsen
46aa2e7ce1 Merge pull request #5530 from home-assistant/dev
0.37
2017-01-28 15:13:43 -08:00
Paulus Schoutsen
8bcb26b90c Version bump to 0.37 2017-01-28 15:13:17 -08:00
Johann Kellerman
b48a7e4007 Bugfix customize (#5613) 2017-01-28 23:52:30 +01:00
Robbie Trencheny
0f939d6906 Merge pull request #5580 from fakezeta/Added_notify.twilio_call
Added notify.twilio_call component for Voice calling with Twilio
2017-01-28 13:57:18 -08:00
Robbie Trencheny
b7bb31cb95 Allow both http and https URLs 2017-01-28 12:46:34 -08:00
Robbie Trencheny
379ae11405 Minor style fixes 2017-01-28 12:45:52 -08:00
Robbie Trencheny
8f418831a1 Update Twilio SDK version 2017-01-28 12:45:32 -08:00
andrey-git
1fb372ffdb Apply new customize format to Zwave (#5603) 2017-01-28 22:29:51 +02:00
Robbie Trencheny
405b2fdfa0 Correct project year, update license 2017-01-28 12:29:09 -08:00
Robbie Trencheny
1aa1074054 Update LICENSE.md and CLA.md to reflect the new Apache 2.0 license 2017-01-28 12:12:34 -08:00
Paulus Schoutsen
b0d07a414b Token tweaks (#5599)
* Base status code on auth when entity not found

* Also allow previous camera token

* Fix tests

* Address comments
2017-01-28 11:51:35 -08:00
Fabian Affolter
e1412a223c Update docstring (quotes, links, content) (#5602) 2017-01-28 16:02:19 +01:00
Teemu R
72bc8fc5bf eq3btsmart: add reporting for availability (#5594)
* eq3btsmart: add reporting for availability

* Update eq3btsmart.py
2017-01-27 23:52:46 -08:00
jeremydk
b7aba525ca Emulated Hue "host-ip" fails to bind when running in docker without --net=host (#5550)
* UPNP changes to allow a separate advertised IP and Port.

* Fixing lint.

* UPNP changes to allow a separate advertised IP and Port.

* Fixing lint.

* Update __init__.py

* Moved logic for advertised ip and port into config class.

* Commenting change for clarity.

* Spacing changes for PEP8

* Spacing Changes for PEP8

* Style Changes
2017-01-27 23:42:37 -08:00
Craig J. Ward
6ede1c08ca Insteon config (#5595)
* only check for devices when not defined in config

* lint

* performance fix
2017-01-27 23:31:36 -08:00
Paulus Schoutsen
b4c3de3215 Fix switch.tplink doing I/O in event bus (#5589)
* Fix switch.tplink doing I/O in event bus

* Update tplink.py
2017-01-27 22:45:57 -08:00
fakezeta
564aad0ab8 Removed Regexp and added error logging 2017-01-28 01:35:54 +01:00
fakezeta
549c3b2c84 Minor changes to pass lint check 2017-01-28 01:06:01 +01:00
fakezeta
db85e2bc2a Checking message if valid url or a string for TTS 2017-01-28 00:51:30 +01:00
Duoxilian
b732174def Hold mode (#5586)
* Initial commit of hold_mode feature.

* Added deprecation warning for climate.away_mode

* Add tests to demo environment.
2017-01-27 08:57:18 -08:00
Pascal Vizeli
1d4e967106 sonos set coordinator after join/unjoin (#5584)
* sonos set coordinator after join/unjoin

* fix unittest
2017-01-27 15:37:16 +01:00
Lukas
5a7a84fad1 Device Tracker for Linksys Access Points (#4933)
* Implementation for Linksys Access Points

* update .coveragerc

* update requirements

* add default timeout of 10sec

* address lint issues
2017-01-26 23:27:29 -08:00
Teemu R
86dfa7ad25 [switch.flux] Allow disabling setting the brightness (#5407)
* flux: allow disabling setting the brightness

* Use separate boolean for disabling brightness adjustment

* Update flux.py
2017-01-26 23:08:08 -08:00
Paulus Schoutsen
4aab72fe7c Update MDI 2017-01-26 22:59:32 -08:00
Paulus Schoutsen
5948b5e33a Update frontend 2017-01-26 22:59:13 -08:00
Pascal Vizeli
4831f57834 Bugfix sonos / refactor of sonos function for TTS (#5571)
* Bugfix sonos / refactor of sonos function for TTS

* fix unittest

* update service yaml

* restore group of a coordinator

* use group function to evaluate

* fix state flooting

* fix comments
2017-01-26 22:50:36 -08:00
Jan Losinski
41218e5a37 [switch.pilight] Implement echo config option (#5056)
* Implement echo config option for pilight

Pilight switches can get a receive code configured. If so they act on
received codes. In the current implementation "act on" means not only
to set the internal state, but also to send the code again. If the
receiver is directly parred with the switch, to act even if HA is not
running, this causes it to receive the signal twice because the HA
sends it again.

In my case this causes a dimmer to start dimming until I hit the switch
again.

This implements a "echo" argument for the receive codes that let the
user choose if a received signal should result in any sending or not.
If not, only the status of pilight will be updated.

The echo option defaults to True, as this was the default since now.
Simply set it to halse to disable this behaviour.

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>

* Add documentation to set_state in switch/pilight.

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>
2017-01-26 22:40:14 -08:00
nordlead2005
837994196e Added forecast support to DarkSky (#5264)
* Added forecast support to DarkSky

	modified:   homeassistant/components/sensor/darksky.py
	modified:   tests/components/sensor/test_darksky.py

* Fix async_volume_up / async_volume_down (#5249)

async_volume_up / async_volume_down should be async versions of
volume_up / volume_down, not a async version of the default variants of
volume_up / volume_down.

The previous code always called into the mediaplayers set_volume_level,
and never into volume_up / volume_down.

Signed-off-by: Anton Lundin <glance@acc.umu.se>

* adding a default icon "blind" to a PowerView blinds scene. (#5210)

* adding a default icon "blind" to a PowerView blinds scene.

* Adding icon property to define blind icon. Removed it from the state attributes dict.

* fixing lint error

* Added forecast support to DarkSky

	modified:   homeassistant/components/sensor/darksky.py
	modified:   tests/components/sensor/test_darksky.py

* Use SHA hash to make token harder to guess (#5258)

* Use SHA hash to make token harder to guess

Use hashlib SHA256 to encode object id instead of using it directly.

* Cache access token

Instead of generating a token on the fly cache it in the constructor.

* Fix lint

* Bugfix async device_tracker see callback (#5259)

* Add support for NAD receivers (#5191)

* Add support for NAD receivers

* remove self.update() in various methods

* remove setting attributes in various methods

* Change import to hass style

* Updated Config Validation, extended daily forecast to all supported types

* Fix style errors from previous commit, fix test since adding daily for all supported types

* Removed temperature from daily as it isn't supported

* Added forecast support to DarkSky

	modified:   homeassistant/components/sensor/darksky.py
	modified:   tests/components/sensor/test_darksky.py

* Updated Config Validation, extended daily forecast to all supported types

* Fix style errors from previous commit, fix test since adding daily for all supported types

* Removed temperature from daily as it isn't supported

* Revert "Bugfix camera streams (#5306)"

This reverts commit 4b43537801.

Revert "Version bump for kodi dependency (#5307)"

This reverts commit 6abad6b76e.

Revert "Add HMWIOSwitch to sensor, binary (#5304)"

This reverts commit 2c3f55acc4.

Revert "Remove GTFS default name & string change"

This reverts commit 6000c59bb5.

Revert "Update pyhomematic 1.19 & small cleanups (#5299)"

This reverts commit a30711f1a0.

Revert "[sensor] Add Dublin bus RTPI sensor (#5257)"

This reverts commit 1219ca3c3b.

Revert "Bugfix group reload (#5292)"

This reverts commit baa8e53e66.

Revert "Support for TrackR device trackers (#5010)"

This reverts commit f7a1d63d52.

Revert "Bump pywemo version."

This reverts commit dc937cc8cf.

Revert "Upgrade to voluptuous to 0.9.3 (#5288)"

This reverts commit d12decc471.

Revert "Upgrade distro to 1.0.2 (#5291)"

This reverts commit 64800fd48c.

Revert "Don't build Adafruit_BBIO - doesn't work on all platforms. (#5281)"

This reverts commit 9a3c0c8cd3.

Revert "Convert flic to synchronous platform. (#5276)"

This reverts commit eb9b95c292.

Revert "Upgrade to aiohttp 1.2 (#4964)"

This reverts commit e68e29e03e.

Revert "Fix TCP sensor to correctly use value_template (#5211)"

This reverts commit 1cf9ae5a01.

Revert "Cleanup language support on TTS (#5255)"

This reverts commit 3f3a3bcc8a.

Revert "Add last triggered to script (#5261)"

This reverts commit 467cb18625.

Revert "Bump flux_led version and make use of PyPi package (#5267)"

This reverts commit 34a9fb01ac.

Revert "Add support for NAD receivers (#5191)"

This reverts commit 3b59e169f1.

Revert "Bugfix async device_tracker see callback (#5259)"

This reverts commit 71fddd26eb.

Revert "Use SHA hash to make token harder to guess (#5258)"

This reverts commit 922308bc1f.

* Revert "Revert "Bugfix camera streams (#5306)""

This reverts commit 2ee8c44021.

* Update darksky.py
2017-01-26 22:32:45 -08:00
Johann Kellerman
f2870c3103 [core.config] Support customize in packages (#5543)
* Support customize in packages

* GMT

* Update test_config.py
2017-01-26 22:26:49 -08:00
Adam Mills
923431110a [*.zwave] Refactor of zwave value_changed (#5512)
* Refactor of zwave value_changed

* Rename update_properties to update

* Revert "Rename update_properties to update"

This reverts commit 723578e7d4.
2017-01-26 22:21:33 -08:00
John Arild Berentsen
d0538fe3aa [lock.zwave] Add set, get and clear usercodes for zwave locks (#5489)
* Add set, get and clear usercodes for zwave locks

* Fix CRLF
2017-01-26 21:45:04 -08:00
Robbie Trencheny
295a232374 Allow a protocol in the http.base_url parameter (#5557) 2017-01-26 21:43:45 -08:00
Johann Kellerman
3f2fdb97a0 check_config: Add support for packages (#5574) 2017-01-26 21:42:14 -08:00
Daniel Høyer Iversen
a465a45588 Fix for assumed state in command_line (#5578)
* Bug fix for assumed state in command_line

* command line

* command line

* command line

* command line test
2017-01-26 21:41:30 -08:00
fakezeta
e4f0b0a57f Updated requirements_all.txt 2017-01-27 01:12:28 +01:00
fakezeta
86b2db54be Merge remote-tracking branch 'home-assistant/dev' into Added_notify.twilio_call 2017-01-27 00:51:56 +01:00
fakezeta
3f13bdb1f7 Modified .coveragerc 2017-01-27 00:48:58 +01:00
fakezeta
61ad11fcd7 Added notify.twilio_call component for Voice calling with Twilio 2017-01-27 00:32:01 +01:00
John Mihalic
fb49c588e5 Handle Squeezebox issues (#5566)
* Handle Squeezebox issues

* Fix double logging
2017-01-26 18:30:42 -05:00
Pascal Vizeli
36e47473c5 pump ffmpeg version 1.2 to fix close bug (#5579) 2017-01-27 00:22:31 +01:00
Robbie Trencheny
7136fd0f0a Add an Amazon Polly TTS platform (#5169)
* Remove SPEED_MED from fan

* Add an Amazon Polly TTS platform

* Update boto library version for notify.aws_* platforms to match the tts.amazon_polly req

* Improve log line and add docstring to function

* Simplify config logic

* Remove duplicate logic

* Don't know how this got in here...

* initial options work

* Remove stale config option and only allow supported languages

* Make requested changes

* Polly is only supported in some regions

* Allow filename to contain underscores (for amazon_polly platform name), remove unnecessary default_lang, other small things

* Add options dict to service description
2017-01-26 23:22:47 +01:00
Pascal Vizeli
636e7aa31e [microsoft_face] Small error fixes (#5577)
* [microsoft_face] Small error fixes

* add array to exclusion
2017-01-26 23:18:15 +01:00
Pascal Vizeli
eadf67bd9a Update ha-ffmpeg version 1.1 (#5573) 2017-01-26 18:12:30 +01:00
Hugo Dupras
4fe54e1cbb Update Netatmo library to fix missing local_url (#5570) 2017-01-26 15:08:21 +01:00
John Mihalic
111b482be4 Update neurio library req. & fix keyerror (#5565) 2017-01-26 13:07:50 +01:00
Robbie Trencheny
2a897574a8 Merge pull request #5564 from home-assistant/readme-grammar-fix
Fix grammar in README
2017-01-25 17:39:32 -08:00
Robbie Trencheny
068369c008 Fix grammar in README 2017-01-25 15:35:52 -08:00
Robbie Trencheny
f25b34cafe Merge pull request #5558 from andrey-git/sonos
Fix empty image when Sonos is doing nothing.
2017-01-25 13:41:41 -08:00
Daniel Perna
7e7f9f6670 Merge pull request #5555 from jannau/max_shutter_contact
homematic: add MAX shutter contact class
2017-01-25 22:32:35 +01:00
Andrey
58e063a1b6 Fix empty image when Sonos is doing nothing. 2017-01-25 23:15:30 +02:00
Robbie Trencheny
7f5d6eb841 Add a is_coordinator attribute to Sonos (#5556) 2017-01-25 13:03:36 -08:00
Janne Grunau
0048267f3e homematic: add MAX shutter contact class 2017-01-25 21:15:04 +01:00
Gianluca Barbaro
9cad9c19f8 Update keyboard_remote.py (#5535)
* Update keyboard_remote.py

I added a couple of events: keyboard_remote_connected and keyboard_remote_disconnected, useful to trigger some action (for example: play a sound)
I changed the way the component refers to the keyboard: not by "descriptor", but by name.
The fact is that the udev system doesn't always give a name link in /dev/input/by-id folder and the actual /dev/input/eventX file changes automatically. 
For example, if I had my keyboard on /dev/input/event13 and then it disconnected, if something else connects to the system it will get the first input file available, that is /dev/input/event13. If the keyboard then reconnects, it will get /dev/input/event14, thus breaking the configuration.
Now it searches every time for the right input file.
The problem might be that, in case of ha upgrade, the pre-existing configuration won't work. I thing there are some guidelines here, but I am not sure.
I think it's inevitable: the initial idea to use a /dev/input/by-id/ symbolic link was good, but unfortunately it doesn't seem to work with bluetooth devices.

I haven't updated the documentation yet: I'm waiting for some ok about the change in configuration key names.

* Update keyboard_remote.py

That should do the trick.
You are right: device names can be duplicated, thus they're not reliable in case of multiple devices. Unfortunately, the only other information available is the physical address, even more complicated.
But in case you have just one keyboard remote of same model, the name works just fine. I'll put it in the documentation which, once the code is approved, I will promptly update.

* Update keyboard_remote.py

* Update keyboard_remote.py

* Update keyboard_remote.py

* Unwrap logger error
2017-01-25 13:58:34 -05:00
Pascal Vizeli
c3a55e7d82 Fix upc lint error (#5554) 2017-01-25 18:46:37 +01:00
Paulus Schoutsen
42d33ae26d Disable typing travis build 2017-01-25 09:32:39 -08:00
Johann Kellerman
d500ddac9a [script] Fix dodgy bash syntax for bootstrap (#5552) 2017-01-25 09:21:09 -08:00
Pascal Vizeli
393c7f2cf1 [device.upc_connect] Discount on STOP. (#5553)
* [device.upc_connect] Discount on STOP.

* close session it self

* Update upc_connect.py
2017-01-25 09:20:31 -08:00
thecynic
6015274ee2 Add initial support for Lutron RadioRA 2 using pylutron (#5337)
Signed-off-by: Dima Zavin <thecynic@gmail.com>
2017-01-25 09:11:37 +01:00
Oleksii Serdiuk
ca1dc202f9 ASUSWRT: Add IPv6 support when parsing neighbors (#5536)
* ASUSWRT: Add IPv6 support when parsing neighbors

The regex for IPv6 should cover most cases, but it doesn't validate
whether IP is correct. It also might fail for some edge cases.

Also, ignore 'duid xx:xx:xx:xx:xx:xx:xx:xx:xx:xx' line in leases.

Closes #2814 - ASUSWRT doesn't support ipv6

* Update asuswrt.py
2017-01-25 00:02:39 -08:00
Alessandro Mogavero
c7ff7af39d Sky hub (#5509)
* Added new platform sky_hub

* added env to virtual environment gitingore

* Removed unuseful imports

* BT home hub 5 renamed to sky hub in the comments

* Added sky_hub to .coveragerc

* Added example configuration in sky_hub docstring

* sky_hub made compliant with test style standards

* homehub functions renamed to skyhub

* Update .gitignore

* Update .coveragerc
2017-01-25 00:02:08 -08:00
Paulus Schoutsen
264310074f Update Wink requirement 2017-01-24 22:13:22 -08:00
Stu Gott
191d7b0a50 Add support for Wemo CoffeeMaker devices (#5505)
* Add support for Wemo CoffeeMaker devices

* Add CoffeeMaker to WEMO_MODEL_DISPATCH
2017-01-24 22:10:10 -08:00
Nick Touran
43e46154c6 Added new Washington State DOT sensor. (#5496)
* Added new Washington State DOT sensor.

* Minor changes from review for WSDOT.

* Update wsdot.py
2017-01-24 22:08:19 -08:00
Martin Hjelmare
a09a772f43 Add more validation for mysensors (#5493)
* Move isdevice validator under helpers.config_validation.
* Check that all persistence files are set and are unique if any is set
  by user. This is necessary to avoid file name clashes.
* Check that a set persistence file has an existing and writable
  directory.
* Check that a device is either a valid device file, "mqtt", or a valid
  domain name or ip address.
2017-01-24 22:04:44 -08:00
Pascal Vizeli
b57f5728c5 [image_processing/microsoft_face_identify] face recognition for automation (#5472)
* [image_processing/microsoft_face_verify] face recognition for automation

* Add platform for microsoft face identify

* add unittest for demo

* Add unittest for platform
2017-01-24 21:50:10 -08:00
Robbie Trencheny
c355def154 Merge pull request #5348 from freol35241/dev
Remove throttle decorator from miflora platform
2017-01-24 21:39:42 -08:00
happyleavesaoc
3d081c2564 bump dep version; add name conf (#5451) 2017-01-24 21:36:18 -08:00
snagytx
59cad0f6ef add a small sleep before reading the rpi-gpio sensor (#5446)
* add a small sleep before reading the sensor

The read of the sensor might be incorrect if it's read too soon after the setup_input call. It might be isolated to my case where I rely on the the PI internal PULL, but once I added this sleep I never get false initial read. If you think this change is appropriate please merge it.

* Update rpi_gpio.py

* Update rpi_gpio.py

* Update rpi_gpio.py
2017-01-24 21:35:12 -08:00
Jan Harkes
6adc5c318e Add missing dependency in emulated_hue component. (#5394)
* Add missing dependency in emulated_hue component.

On first startup after upgrade to 0.36, the emulated_hue componented failed to
start because the http component had installed the modules it depends on, in
this particular case 'aiohttp_cors' was missing.

* Include dependencies for the emulated_hue web server

Emulated_hue uses it's own 'web-server' component to handle hue related
discovery and config, so we need to make sure the required http modules are
made available before we are initialized.

We don't have to depend on the home-assistant http/api component because we do
not need to have the frontend to be initialized to handle emulated_hue, so we
can just import in the same set of requirements as the http component.

* Fix linting error
2017-01-24 21:29:34 -08:00
Robbie Trencheny
88e0bb6733 Merge pull request #5492 from kellerza/gen_requirements
[script] gen_requirement: Raise an error if REQUIREMENT not pinned
2017-01-24 21:23:22 -08:00
William Scanlon
47bbfc309c Support for python-wink 1.0.0 (#5534) 2017-01-24 21:11:18 -08:00
Robbie Trencheny
794852f76f Merge pull request #5497 from armills/test-port-fixes
Fix network tests to use get_test_instance_port
2017-01-24 21:10:00 -08:00
Robbie Trencheny
75c52ff9c4 Merge pull request #5545 from fabaff/waqi-pm10
[sensor.waqi] Add missing particle value and refactor attributes
2017-01-24 21:07:46 -08:00
Paulus Schoutsen
d8e5e60a08 Merge remote-tracking branch 'origin/master' into dev 2017-01-24 20:59:34 -08:00
Robbie Trencheny
9bd5378fe4 [component/ios] Discover notify.ios when iOS component loads (#5548) 2017-01-25 06:57:48 +02:00
Paulus Schoutsen
2cf2dcd9ba Emulated_hue: default type to Google [Breaking change] (#5549) 2017-01-24 20:25:08 -08:00
Johann Kellerman
e53b2fe121 [script] Only bootstrap frontend if npm installed (#5507)
* [scripts] Only bootstrap frontend if npm installed

* Message if not frontend dev possible

* yarn
2017-01-24 16:20:18 -08:00
Fabian Affolter
4462431c78 Add missing particle value and refactor attributes 2017-01-25 00:52:19 +01:00
David McNett
eb1e8ebc18 New version of anthemav python library (#5544) 2017-01-25 00:20:59 +01:00
Pascal Vizeli
92858554e6 Bugfix endless aiohttp streamreader (#5540) 2017-01-24 20:43:36 +01:00
Pascal Vizeli
c972e90580 Bugfix mjpeg camera (#5539) 2017-01-24 20:25:51 +01:00
Fabian Affolter
b2ecaa189a [binary_sensor.arest] Fix name for sensor and shorten logger messages (#5460)
* Fix name for sensor and shorten logger messages

* Use variable as name if none is given
2017-01-24 19:54:14 +01:00
ecksun
f5062b06a9 media_player.kodi: Add SSL config option (#5531)
This readds support for https for kodi, resolves issue #5527
2017-01-24 18:20:18 +01:00
Fabian Affolter
cd260d89cb Add location to attributes and option to show position on the map (sensor.iss) (#5465)
[sensor.iss] Add location to attributes and option to show position on the map
2017-01-24 10:02:17 +01:00
Aaron Polley
38d9dc996b Piglow support (#5302)
* Add support for Piglow

* Updated coverage and requirements

* Add support for Piglow

* Updated coverage and requirements

* Fix linting errors

* Fix linting errors

* Remove trailing whitespace

* Shorter lines

* Remove trailing whitespace

* Update piglow.py

* Pinned piglow version

* Remove unused method

* Remove unused imports

* Fix lint errors

* Update requirements all

* Updated Piglow to allow the component name to be changed

* Fix imports

* Pass in name

* The piglow platform now fails if it cannot detect the piglow device

* Tidy subprocess import
2017-01-24 09:41:33 +01:00
Robbie Trencheny
be2c9ccee2 Merge pull request #5529 from robbiet480/update-hdmi-cec
Update pyCEC version
2017-01-23 23:34:02 -08:00
Robbie Trencheny
dd0110e06d Update pyCEC version 2017-01-23 23:33:16 -08:00
Fabian Affolter
64fc6a08d3 Fix typos (#5522) 2017-01-23 13:25:38 -08:00
Fabian Affolter
a83b61ad58 Allow direct messaging to user (#5521) 2017-01-23 13:24:45 -08:00
andrey-git
b7e477fbba Copy val in config.py before modifying (#5520)
* Copy val before modifying

* Bad line location
2017-01-23 13:24:13 -08:00
Fabian Affolter
318b0f4f36 Upgrade beautifulsoup4 to 4.5.3 (#5519) 2017-01-23 13:23:41 -08:00
Petr Vraník
900868708e check cec message length when asking physical address (#5516)
* cec client object

* cec command structure

* autodetect source

* volume support and native source select

* switch device

* media player device

* detecting of state

* friendly names

* hdmi cec properties

* presence detection

* simplified callbacks

* stable names

* renamed methods

* code cleanup

* name with vendor

* fixed standby call name

* fake standby/poweron

* domain switch

* domain switch

* async updating

* update separated

* cec -> hass event bridge

* fixed name generation

* code cleanup

* code cleanup

* icon constants

* code cleanup

* do not register unavailable devices

* discovery of deevices

* code cleanup

* cec device discovery

* moved method implementation into child

* service descriptions

* service descriptions

* service descriptions

* changed entity init sequence

* logging cleanup

* add remove as job

* closing cec, no service schemas

* correct iterate over dictionary

* Volume by commands

* threading

* logging minimized

* get load out of main thread

* naming cleanup

* get load out of main thread

* optimized discovery

* async where possible

* cleanup logging, constructors first

* pydoc

* formatting

* no async_update from out of loop
no hiding entities
removed redundant device_state_attributes
async updating presence

* no async

* working async cec

* cec in thirdparty lib

* cec initialized oudsice

* working without SIGSEGV

* rollbacked file changed by mistake

* sending of commands

* working with ha

* using hass loop and device driven updates

* version up

* version up

* Command types in pycec, cleanup for HA integration

* Removed media player, state moved to switch

* service descriptions

* requirements: pyCEC

* line width to 79

* doc

* doc

* overindentation solved

* HDMI to uppercase

* minimal dependency on cec

* removed unwanted line

* doc wording

* margin 79

* line continuation indent

* imperative doc

* lint: indentation

* fixed overindented

* fixed overindented

* fixed overindented

* fixed overindented

* order of imports

* PEP8

* keep signature of overriding

* removed redundant blank line

* fixed update call method (#4)

* Preparation for merge to upstream (#5)

* newer version of pyCEC
* updated services.yaml
* fixed lint scrpt to operate only on python files

* pycec version up

* update services

* no coverage report

* exclude non python files from lint

* lint only on python files

* Dev (#6)

* reordered
* sending nonserialized data through hass.data
* code formatting
* code formatting
* import order

* Dev (#7)

* newer version of pyCEC
* updated services.yaml
* fixed lint scrpt to operate only on python files

* pycec version up

* update services

* no coverage report

* exclude non python files from lint

* lint only on python files

* reordered

* sending nonserialized data through hass.data

* import order

* fixed object handling

* code formatting

* Backwards compatibility of hdmi_cec (#10)

* services:
power_on
standby
active_source

* new version of pyCEC (#12)

* newer version of pyCEC

* devices config (#13)

* getting device name from config

* shutdown fix (#14)


* correct call on shutdown

* remove misplaced annotations (#15)

* Preparation for merge to upstream (#5)

* newer version of pyCEC
* updated services.yaml
* reordered
* sending nonserialized data through hass.data
* services:
power_on
standby
active_source
* code formatting
* getting device name from config
* correct call on shutdown

* pyCEC version 0.3.6 (#18)

* newer version of pyCEC
* updated services.yaml
* sending nonserialized data through hass.data
* services:
** power_on
** standby
** active_source
* getting device name from config
* correct call on shutdown
* fork new thread on multicore machines
* support both config schemas: original and new (#16)
* volume press and release support (#17)

* support for media_player (#21)

* accept hexadecimal format of commands
* support for media player
* platform customization
* type constants

* Dev (#23)

* accept hexadecimal format of commands
* support for media player
* platform customization

* TCP CEC support (#24)

* accept hexadecimal format of commands
* support for media player
* platform customization
* preparing tcp support

* volume handling (#25)

* Incorporated CR remarks (#26)

* cleanup imports
* cleanup and enhance services description
* removed unwanted file

* implemented CR remarks (#27)

* pyCEC v0.4.6
* pined dependency version
* tighten service schemas

* requirements (#28)

* incorporate remarks from users (#32)

* home-assistant-31 make mute schema better (#31)

* pycec-30 pyCEC version up (#30)

* pycec-30 pyCEC version up (#30)

* home-assistant-30 OSD display name from configuration (#30) (#33)

* Home assistant 29 (#34)

* home-assistant-29 counting from 0 (#29)

* Home assistant 31 (#35)

* home-assistant-31 add support for mute-on and mute-off (#31)

* home-assistant-31 pyCEC version up (#31)

* Home assistant 31 (#36)

* home-assistant-31 Limit OSD name to 13 chars (#31)

* home-assistant-31 Limit OSD name to 13 chars moved to CEC adapter (#31)

* home-assistant-31 version up (#31)

* home-assistant-31 formatting (#31)

* formatting

* service description

* service description

* single attribute for volume

* fixed mute on -> mute off

* moved config constant from core into component

* check cec message length when asking physical address (#38) (#38)

* cec turn on/turn off commands instead of power

* cec turn on/turn off commands instead of power
2017-01-23 13:22:39 -08:00
Fabian Affolter
d5119a0520 Use device_state_attributes (#5518) 2017-01-23 13:21:12 -08:00
Robbie Trencheny
9bc9e7fbc4 Dont set a speed when fan turns on (#5514) 2017-01-23 13:20:54 -08:00
Adam Mills
f54f68903d Fixes for rest tests (#5495)
* Fixes for rest tests

* Linter fixes

* Alternate test_setup_missing_config implementation
2017-01-23 10:17:29 -05:00
Adam Mills
8217a42960 Don't start test thread as daemon and wait until patching is done (#5494) 2017-01-23 07:03:55 +02:00
Robbie Trencheny
9442131373 Add organization docs 2017-01-22 16:21:20 -08:00
andrey-git
addc2c4340 Allow easier customization of whole domain, entity lists, globs. (#5215) 2017-01-22 21:19:50 +02:00
Johann Kellerman
699c615d23 Add url 2017-01-22 18:34:00 +02:00
Marcelo Moreira de Mello
ab19577322 Bump amcrest version and refactored to simplify code (#5499)
* Bumped version to Amcrest 1.1.3 and rebase self.base_url()

* Refactored amcrest camera and amcrest sensor to simply object reference
2017-01-22 14:22:25 +01:00
Daniel Perna
59b0491d29 Homematic fixes + device support (#5503)
* Using new MaxShutterContact class

* Skip unnecessary function calls

* Added casting for VALUE

* Some renaming to clarify what's happening

* Bumped dependency version

* Bumped version in requirements
2017-01-22 14:20:49 +01:00
Fabian Affolter
75adb7ff46 Upgrade Sphinx to 1.5.2 (#5502) 2017-01-22 11:36:29 +01:00
Adam Mills
df361dc1e1 Fix network tests to use get_test_instance_port 2017-01-21 22:15:05 -05:00
Johann Kellerman
7df51dc545 gen_requirement: Raise an error if REQUIREMENT not pinned 2017-01-22 01:37:08 +02:00
Matthew Garrett
2992cd35be Add support for Leviton Decora Bluetooth dimmer switches (#5434)
* Add support for Leviton Decora Bluetooth dimmer switches

Add support for the Decora Bluetooth smart dimmer switches from Leviton.

* Update decora.py
2017-01-21 14:14:08 -08:00
Petr Vraník
06361b1ed1 implementing users remarks (#5481)
* cec client object

* cec command structure

* autodetect source

* volume support and native source select

* switch device

* media player device

* detecting of state

* friendly names

* hdmi cec properties

* presence detection

* simplified callbacks

* stable names

* renamed methods

* code cleanup

* name with vendor

* fixed standby call name

* fake standby/poweron

* domain switch

* domain switch

* async updating

* update separated

* cec -> hass event bridge

* fixed name generation

* code cleanup

* code cleanup

* icon constants

* code cleanup

* do not register unavailable devices

* discovery of deevices

* code cleanup

* cec device discovery

* moved method implementation into child

* service descriptions

* service descriptions

* service descriptions

* changed entity init sequence

* logging cleanup

* add remove as job

* closing cec, no service schemas

* correct iterate over dictionary

* Volume by commands

* threading

* logging minimized

* get load out of main thread

* naming cleanup

* get load out of main thread

* optimized discovery

* async where possible

* cleanup logging, constructors first

* pydoc

* formatting

* no async_update from out of loop
no hiding entities
removed redundant device_state_attributes
async updating presence

* no async

* working async cec

* cec in thirdparty lib

* cec initialized oudsice

* working without SIGSEGV

* rollbacked file changed by mistake

* sending of commands

* working with ha

* using hass loop and device driven updates

* version up

* version up

* Command types in pycec, cleanup for HA integration

* Removed media player, state moved to switch

* service descriptions

* requirements: pyCEC

* line width to 79

* doc

* doc

* overindentation solved

* HDMI to uppercase

* minimal dependency on cec

* removed unwanted line

* doc wording

* margin 79

* line continuation indent

* imperative doc

* lint: indentation

* fixed overindented

* fixed overindented

* fixed overindented

* fixed overindented

* order of imports

* PEP8

* keep signature of overriding

* removed redundant blank line

* fixed update call method (#4)

* Preparation for merge to upstream (#5)

* newer version of pyCEC
* updated services.yaml
* fixed lint scrpt to operate only on python files

* pycec version up

* update services

* no coverage report

* exclude non python files from lint

* lint only on python files

* Dev (#6)

* reordered
* sending nonserialized data through hass.data
* code formatting
* code formatting
* import order

* Dev (#7)

* newer version of pyCEC
* updated services.yaml
* fixed lint scrpt to operate only on python files

* pycec version up

* update services

* no coverage report

* exclude non python files from lint

* lint only on python files

* reordered

* sending nonserialized data through hass.data

* import order

* fixed object handling

* code formatting

* Backwards compatibility of hdmi_cec (#10)

* services:
power_on
standby
active_source

* new version of pyCEC (#12)

* newer version of pyCEC

* devices config (#13)

* getting device name from config

* shutdown fix (#14)


* correct call on shutdown

* remove misplaced annotations (#15)

* Preparation for merge to upstream (#5)

* newer version of pyCEC
* updated services.yaml
* reordered
* sending nonserialized data through hass.data
* services:
power_on
standby
active_source
* code formatting
* getting device name from config
* correct call on shutdown

* pyCEC version 0.3.6 (#18)

* newer version of pyCEC
* updated services.yaml
* sending nonserialized data through hass.data
* services:
** power_on
** standby
** active_source
* getting device name from config
* correct call on shutdown
* fork new thread on multicore machines
* support both config schemas: original and new (#16)
* volume press and release support (#17)

* support for media_player (#21)

* accept hexadecimal format of commands
* support for media player
* platform customization
* type constants

* Dev (#23)

* accept hexadecimal format of commands
* support for media player
* platform customization

* TCP CEC support (#24)

* accept hexadecimal format of commands
* support for media player
* platform customization
* preparing tcp support

* volume handling (#25)

* Incorporated CR remarks (#26)

* cleanup imports
* cleanup and enhance services description
* removed unwanted file

* implemented CR remarks (#27)

* pyCEC v0.4.6
* pined dependency version
* tighten service schemas

* requirements (#28)

* incorporate remarks from users (#32)

* home-assistant-31 make mute schema better (#31)

* pycec-30 pyCEC version up (#30)

* pycec-30 pyCEC version up (#30)

* home-assistant-30 OSD display name from configuration (#30) (#33)

* Home assistant 29 (#34)

* home-assistant-29 counting from 0 (#29)

* Home assistant 31 (#35)

* home-assistant-31 add support for mute-on and mute-off (#31)

* home-assistant-31 pyCEC version up (#31)

* Home assistant 31 (#36)

* home-assistant-31 Limit OSD name to 13 chars (#31)

* home-assistant-31 Limit OSD name to 13 chars moved to CEC adapter (#31)

* home-assistant-31 version up (#31)

* home-assistant-31 formatting (#31)

* formatting

* service description

* service description

* single attribute for volume

* fixed mute on -> mute off

* moved config constant from core into component
2017-01-21 14:13:46 -08:00
Craig J. Ward
a89a4f39dc only check for devices when not defined in config (#5490)
* only check for devices when not defined in config

* lint
2017-01-21 14:00:56 -08:00
Greg Dowling
74989f7941 Bump pyvera version (add RFX device support) (#5487) 2017-01-21 12:26:57 -08:00
Stefan Jonasson
ed12f9e237 Tellstick light fix (#5482)
* Fixed crash when lights objects was inited

* Fixed initial value for tellstick lights

* Fixed problem with lights not working with the turn_on action.
2017-01-21 12:24:48 -08:00
Fabian Affolter
13d801e1c6 Upgrade sqlalchemy to 1.1.5 (#5484) 2017-01-21 12:24:23 -08:00
Fabian Affolter
f13774269d Upgrade speedtest-cli to 1.0.2 (#5483) 2017-01-21 18:26:17 +01:00
joopert
56ed00a1db update nad library version (#5478) 2017-01-21 13:24:38 +01:00
Dale Higgs
a6f341f06a Add exit code to check_config script (#5471) 2017-01-21 10:39:50 +03:00
Lupin Demid
ccd2588cf7 added speed and emotion to Yandex tts (#5431)
* Added speed and emotion  parameters. Refactored test's

* Fixed float point arfs in url and added test for float point values
2017-01-21 08:36:28 +01:00
Pascal Vizeli
2fff8a5a11 [TTS] options support for service calls (#5436)
* [TTS] Support now options like voice and age on service.

* Add unittest
2017-01-21 08:35:18 +01:00
Robbie Trencheny
074f9315d7 Fan improvements (#5457)
* Remove SPEED_MED from fan

* Correctly use the oscillation on/off payloads for MQTT fan

* Add set_direction service documentation

* Correct function name for Wink fans

* Check for existence of the correct topic

* Enable set fan speed in emulated_hue

* features -> functions

* Final emulated_hue fan fixes

* Fix linting issues

* Revert to supported features instead of supported functions

* Fix logic

* Add a test for emulated_hue fan support
2017-01-20 22:21:28 -08:00
Robbie Trencheny
2efd7d4e4a Hue improvements (#5474)
* Allow automatic removal of all Hue entities from emulated_hue

* Allow disabling of Hue groups

* Only add device state attributes if they need to be there
2017-01-20 22:20:07 -08:00
Paulus Schoutsen
14309401d0 Update frontend 2017-01-20 22:10:44 -08:00
Pascal Vizeli
b2203f7f41 [ffmpeg] Use new 1.0 version / migrate all asyncio (#5464)
* [ffmpeg] Use new 1.0 version / migrate all asyncio

* fix lint

* fix import

* Add new service to binary_sensors

* fix lint
2017-01-20 21:56:22 -08:00
Robbie Trencheny
dec2ddb393 Merge pull request #5405 from xhostplus/roku-idle
Updated Roku IDLE state
2017-01-20 21:54:04 -08:00
Robbie Trencheny
58b698400e Set Roku name to the device name instead of the serial number (#5475) 2017-01-20 21:28:29 -08:00
Robbie Trencheny
26f6a9ee20 Bump requirements 2017-01-20 20:24:00 -08:00
Robbie Trencheny
6b0a6b87de Use is_screensaver 2017-01-20 20:23:20 -08:00
Robbie Trencheny
db97ad4485 Merge pull request #5473 from stu-gott/tts-cache
TTS: Invalidate broken file cache entries
2017-01-20 17:44:32 -08:00
Stu Gott
ec4b148a71 TTS: Invalidate broken file cache entries
If a cached file cannot be read by the TTS component, then it should
be removed from the file cache--or it will remain broken.
2017-01-20 20:09:03 -05:00
John Arild Berentsen
41ee798b0f [WIP][ZWave][Lock] Further improvements to zwave lock platform (#5400)
* Further improvements to zwave lock platform

* Add missing notification

* Some improvements
2017-01-20 13:01:36 -08:00
Martin Vacula
f4d2d69a5d Beaglebone Black binary sensor (#5422)
* Configuration parameters defined

* Edge detection added

* Example configuration added and tipo corrected

* Comments updated, lint update

* Added check for input pull_mode

* Too long line

* trailing white space

* Configuration parameters defined

* Edge detection added

* Example configuration added and tipo corrected

* Comments updated, lint update

* Added check for input pull_mode

* Too long line

* trailing white space

* pylint disable import error

* read_input() changed to return boolean value, according changes in binary sensor

* example configuration in docstring changed to mention direct web link, pylint update

* read_input() updated according review
2017-01-20 12:55:28 -08:00
Petr Vraník
067e11ea5c HDMI CEC - support for devices and commands (#4781)
* cec client object

* cec command structure

* autodetect source

* volume support and native source select

* switch device

* media player device

* detecting of state

* friendly names

* hdmi cec properties

* presence detection

* simplified callbacks

* stable names

* renamed methods

* code cleanup

* name with vendor

* fixed standby call name

* fake standby/poweron

* domain switch

* domain switch

* async updating

* update separated

* cec -> hass event bridge

* fixed name generation

* code cleanup

* code cleanup

* icon constants

* code cleanup

* do not register unavailable devices

* discovery of deevices

* code cleanup

* cec device discovery

* moved method implementation into child

* service descriptions

* service descriptions

* service descriptions

* changed entity init sequence

* logging cleanup

* add remove as job

* closing cec, no service schemas

* correct iterate over dictionary

* Volume by commands

* threading

* logging minimized

* get load out of main thread

* naming cleanup

* get load out of main thread

* optimized discovery

* async where possible

* cleanup logging, constructors first

* pydoc

* formatting

* no async_update from out of loop
no hiding entities
removed redundant device_state_attributes
async updating presence

* no async

* working async cec

* cec in thirdparty lib

* cec initialized oudsice

* working without SIGSEGV

* rollbacked file changed by mistake

* sending of commands

* working with ha

* using hass loop and device driven updates

* version up

* version up

* Command types in pycec, cleanup for HA integration

* Removed media player, state moved to switch

* service descriptions

* requirements: pyCEC

* line width to 79

* doc

* doc

* overindentation solved

* HDMI to uppercase

* minimal dependency on cec

* removed unwanted line

* doc wording

* margin 79

* line continuation indent

* imperative doc

* lint: indentation

* fixed overindented

* fixed overindented

* fixed overindented

* fixed overindented

* order of imports

* PEP8

* keep signature of overriding

* removed redundant blank line

* fixed update call method (#4)

* Preparation for merge to upstream (#5)

* newer version of pyCEC
* updated services.yaml
* fixed lint scrpt to operate only on python files

* pycec version up

* update services

* no coverage report

* exclude non python files from lint

* lint only on python files

* Dev (#6)

* reordered
* sending nonserialized data through hass.data
* code formatting
* code formatting
* import order

* Dev (#7)

* newer version of pyCEC
* updated services.yaml
* fixed lint scrpt to operate only on python files

* pycec version up

* update services

* no coverage report

* exclude non python files from lint

* lint only on python files

* reordered

* sending nonserialized data through hass.data

* import order

* fixed object handling

* code formatting

* Backwards compatibility of hdmi_cec (#10)

* services:
power_on
standby
active_source

* new version of pyCEC (#12)

* newer version of pyCEC

* devices config (#13)

* getting device name from config

* shutdown fix (#14)


* correct call on shutdown

* remove misplaced annotations (#15)

* Preparation for merge to upstream (#5)

* newer version of pyCEC
* updated services.yaml
* reordered
* sending nonserialized data through hass.data
* services:
power_on
standby
active_source
* code formatting
* getting device name from config
* correct call on shutdown

* pyCEC version 0.3.6 (#18)

* newer version of pyCEC
* updated services.yaml
* sending nonserialized data through hass.data
* services:
** power_on
** standby
** active_source
* getting device name from config
* correct call on shutdown
* fork new thread on multicore machines
* support both config schemas: original and new (#16)
* volume press and release support (#17)

* support for media_player (#21)

* accept hexadecimal format of commands
* support for media player
* platform customization
* type constants

* Dev (#23)

* accept hexadecimal format of commands
* support for media player
* platform customization

* TCP CEC support (#24)

* accept hexadecimal format of commands
* support for media player
* platform customization
* preparing tcp support

* volume handling (#25)

* Incorporated CR remarks (#26)

* cleanup imports
* cleanup and enhance services description
* removed unwanted file

* implemented CR remarks (#27)

* pyCEC v0.4.6
* pined dependency version
* tighten service schemas

* requirements (#28)
2017-01-20 12:39:18 -08:00
Colin O'Dell
cb47d16282 Don't use Debian's httpredir for backports (#5392)
Hopefully this solves https://github.com/home-assistant/home-assistant/pull/5322#issuecomment-273041585
2017-01-20 12:30:09 -08:00
Adam Mills
5ff9dfa440 Use voluptuous for cast ignore-cec (#5468) 2017-01-20 12:21:27 -08:00
Adam Mills
a7e5c847fb Kodi supports volume stepping (#5467) 2017-01-20 20:52:55 +01:00
Daniel Høyer Iversen
72d63517ba Merge pull request #5420 from MrMep/patch-4
Update generic_thermostat.py
2017-01-20 18:16:40 +01:00
John Arild Berentsen
c41cf7c308 Bugfix Zwave Light: Use only supported features for devices (#5370)
* Use only supported features for devices

* Changes

* Holy Macarony!
2017-01-20 13:35:41 +01:00
Pascal Vizeli
8496975de8 Fix if none data is present for a sensor. (#5415) 2017-01-20 09:07:03 +01:00
Daniel Høyer Iversen
f669680b1e fix issue ##5398 in yr sensor (#5459) 2017-01-19 23:58:15 -08:00
Fabian Affolter
2ed0e76e7c Add elevation to as_dict and use unified style for quoting (#5448) 2017-01-19 23:55:29 -08:00
Adam Mills
1f6f9a1677 Filter new entities from logbook (#5402) 2017-01-19 23:30:47 -08:00
Ryan Kraus
5dd45efac3 Updated ISY component to not overwrite state_attributes. (#5433)
* Updated ISY component to not overwrite state_attributes.

The ISY component included an ISYDevice base class that is used by all
of the isy994 platforms. This still overwrote the state_attributes
property instead of the more appropriate device_state_attributes
property. This was also repeated in the isy994 light platform. Both of
these were addressed. This also fixes issue #5428.

* Removed custom state attributes from ISY lights.

The brightness attribute need not be manually reported by the isy994
light platform.

* Removed ISY Node cleanup.

The ISY entities don’t really need to unsubscribe themselves while hass
is shutting down. Because these updates are not sent in a thread, there
is no negative impact from shutting down without unsubscribing. This
greatly speeds up hass shutdown.

* Removed unused attribute from isy994 light platform.

* Cleaned up ISY994 light entity class.

1) Removed the state property. This property is set in the Entity base
class and shouldn’t be overridden here.
2) Set the brightness property. This is the proper way of setting the
brightness for the Light base class.
3) Removed properties that are now unused because of these changes.
2017-01-19 22:22:33 -08:00
Pascal Vizeli
fe6a8f3367 Remove old openalpr component (#5406)
* Remove old openalpr component

* update region support
2017-01-19 22:21:25 -08:00
Daniel Høyer Iversen
d1ec422eab Merge pull request #5447 from home-assistant/rfxtrx
update rfxtrx lib
2017-01-20 07:17:42 +01:00
happyleavesaoc
f17efc2168 log formats match (#5456) 2017-01-19 21:31:44 -08:00
Paulus Schoutsen
887a33c7d1 Persist emulated hue IDs (#5435) 2017-01-19 21:27:10 -08:00
HerrHofrat
dbcad34b47 Updated valid station id list (#5449) 2017-01-19 23:33:31 +01:00
Robbie Trencheny
738292f817 Ignore import error on avion 2017-01-19 13:25:35 -08:00
Robbie Trencheny
a74258db09 Block Avion from auto installing because only supported on Linux (cc #5414) 2017-01-19 13:14:48 -08:00
Daniel Hoyer Iversen
62b785c040 update rfxtrx lib 2017-01-19 22:08:55 +01:00
Gianluca Barbaro
64c9cd805a Update generic_thermostat.py 2017-01-19 21:26:12 +01:00
Matthew Garrett
3b25b5a6da Add support for Avion Bluetooth dimmer switches (#5414)
GE sell a range of Bluetooth dimmer switches based on Avi-on technology.
Add a module for controlling them. There's also a set of smart switches that
speak the same protocol, but I don't have any of those to test support with.
2017-01-19 21:07:37 +01:00
David McNett
1a82adb054 New platform media_player/anthemav (#5146)
* Initial commit of anthemav platform.  It loads but has no purpose.

* Now presents a card in the UI but the values aren't real

* Mute and volume polling/setting work now

* Source lists and selection works now.

* Reduce debug logging verbosity

* Support power on/off and skip polling for details if power is off

* Add some static tables to decode numerics from telnet commands

* Add stub for unsupported media_play

* New style anthemav uses native asyncio structure

* Add device callback for asyncio

* This is ugly but it works

* Simplify async setup and abstract class data retrieval

* Implement commands (power on and power off for now)

* Add support for scan_interval and set default to 120 seconds

* Pass-through to package handlers for volume and input selection

* Slight restructuring to satisfy anthemav 0.9

* Load anthemav package from pypi now that it's registered

* Proper app_name from a/v info

* Mispelled word

* media_player/anthemav initial commit of platform requirements

* Philio 3-in-1 Gen 4 zwave sensor needs the no-off-event workaround. (#5120)

* Add print_config_parameter service to Z-Wave (#5121)

* Add print_config_param service to z-wave

* Add print_config_parameter service to z-wave

* Add print_config_parameter service to z-wave

* Fix typos

* Fix typos

* Fix typo

* Conform to Python/project style requirements

* Making pylint happy

* Bring pip requirements in agreement with the code

* Bungled previous update

* Remove unnecessady SCAN_INTERVAL logic

I was unawre that this is performed as part of the normal platform behavior and
it's unnecessary for a platform to independently implement this logic.

* Refactor code based on @armills PR requests

* Re-add media_play stub to avoid traceback

* Align with platform reqirements

* Remove references to SCAN_INTERVAL and clean up _lookup logic

* Add DEFAULT_PORT assignment

* Code style changes and removal of vestigial structures

* CONF_NAME handling changes to allow local override to default from device

* Address PR feedback from @balloob

* Remove media_play function override

It's no longer necesary for the platform to implement a stub media_play
function override now that the Add SUPPORT_PLAY flag #5181 issue has been
resolved and merged into the dev branch.

* Rename callback function to async_ for clarity

* Use async routines for platform methods

* Convert update callback to coroutine for conformity

Underlying anthemav library now properly supports coroutine callbacks instead
of normal functions.  Converted the platform callback to a coroutine for
conformance with async operation for the device.

Special thanks to @pvizeli and @armills for their invaluable remedial Python
instruction!

* Further callback refinements

Altered the nature of callback handling based on suggestions from @pvizeli

* True not needed for local push update_ha_state

* Small style fix
2017-01-19 20:07:01 +01:00
Gianluca Barbaro
6ef9714dc1 Update generic_thermostat.py 2017-01-19 19:46:58 +01:00
Pascal Vizeli
3da25c227f lint v2 (#5444) 2017-01-19 19:33:15 +01:00
Pascal Vizeli
11083cf04b Fix lint (#5443) 2017-01-19 19:18:32 +01:00
Pascal Vizeli
8da398c0bd Proxy aiohttp websession / more rebust. (#5419) 2017-01-19 09:55:27 -08:00
Pascal Vizeli
9799631797 [camera/mjpeg] Support still image for thumbmail (#5440) 2017-01-19 09:53:08 -08:00
Touliloup
909978b0d1 [Device Tracker] Xiaomi Mi Router token refresh (#5437)
Device token is refreshed if not anymore valid (for example after router reboot).
Token refresh will only be tried once per update.
2017-01-19 15:05:37 +01:00
Gianluca Barbaro
a87d653077 Update generic_thermostat.py
As suggested, I added a callback on the heater switch state change.
Still it doesn't solve the problem.
2017-01-19 10:57:45 +01:00
Adam Mills
216ac14b3d Fix test for async media player volume helpers (#5432) 2017-01-18 19:15:51 -08:00
Pascal Vizeli
5299c92352 Bugfix volume up/down (#5426) 2017-01-18 22:52:11 +01:00
Gianluca Barbaro
72dca1da09 Update generic_thermostat.py 2017-01-18 12:39:16 +01:00
Gianluca Barbaro
b7bf07eaca Update generic_thermostat.py
After _control_heating() is executed, current_operation() is correctly called but _is_device_active() still reports the old state if the heater switch, at least in my case. The resulting climate state is incorrect until the next refresh, which apparently occurs only when _sensor_changed() gets called (it can be minutes after).

I think the state of the heater switch should be forced to update at the end of  _control_heating(), but I don't know how to do that...
A simple sleep() fixes it, but obviously is just a temporary workaround, I'm not really expecting this PR to be actually committed, unless there's no other solution.
2017-01-18 12:20:39 +01:00
Alex
3267aa8c08 WIP fritz install dependencies fix (#5399)
* updated fritzconnection dependency to 0.6 from pypi

* updated requirements_all for new dependencies of fritz platform
2017-01-18 11:01:31 +01:00
Adam Mills
eb06023aa5 Fix universal mp service call wth no child (#5411) 2017-01-17 22:15:37 -08:00
Pascal Vizeli
2a362fd1ff Asyncio notify component migration (#5377)
* Async migrate notify/platform

* convert group to async

* fix unittest
2017-01-17 22:08:03 -08:00
Paulus Schoutsen
f7ac644c11 Make SMTP tests fast 2017-01-17 22:00:23 -08:00
Paulus Schoutsen
6cd57ac02f Fix Yamaha doing I/O in event loop (#5387) 2017-01-17 21:53:03 -08:00
Paulus Schoutsen
283bcf367b Ignore python-eq3bt from auto-building 2017-01-17 21:48:33 -08:00
Paulus Schoutsen
50b326c7fc Upgrade somecomfort (#5413) 2017-01-17 21:04:56 -08:00
Fabian Affolter
4c52380519 Sync logger messages with Mi-Flora and link to docs (#5391) 2017-01-17 23:41:09 +01:00
Fabian Affolter
bfc0a6a17c Use constants (#5390) 2017-01-17 23:40:34 +01:00
Pascal Vizeli
cfc936761b Make upc more robust (#5404)
* Make upc more robust

* update unittest

* add test for parse error
2017-01-17 23:35:02 +01:00
Bill Nelson
d31f00f672 Updated Roku IDLE state 2017-01-17 13:53:35 -08:00
Whytey
298c1654f8 New zabbix (#5297)
* Hopefully a clean branch for merging

* Remove scan_interval, use defaults for now

* Fix code style error
2017-01-17 00:41:37 -08:00
R1chardTM
321a8be339 Move Nest sensors configuration to Nest component (#4983)
* Move Nest sensor config to Nest Component

* Ensure Nest Protect sensors are added without specified sensor config

* Fix pylint warnings

* Remove support for empty monitored condion list

* Remove scan interval

* Remove scan interval import

* Add Nest sensors by default with opt-out
2017-01-17 00:12:15 -08:00
anpetrov
d240ea56d8 Add Skybeacon BLE temperature/humidity sensor (#5183)
Signed-off-by: Andrey Petrov <andrey.petrov@gmail.com>
2017-01-17 00:01:11 -08:00
Johan Bloemberg
915a91dc1b DSMR: TCP, reconnecting and V4 CRC support (#5164)
* Add support for TCP connection.

* Implement reconnect logic.

* Actually register connect loop task and fix error handling.

* Fix lint, configure upstream requirement.

* Revert debug logging.

* Explicitly catch connection errors.

* Test reconnect on setup and reconnect after disconnect.

* Style.
2017-01-16 23:56:00 -08:00
Job Vermeulen
40ba4fd872 Tado device tracker support (#5046)
* Added tado device tracker

* Added tado device tracker to .converagerc

* Updated docs

* Code formatting and removed unused import

* Code formatting and removed unused import

* Respected the lint line length

* Respect pydocstyle rules

* Respect the lint line limit length

* Fixed reviewer feedback

* Changed the tracker to support async

* Respect the New line end of file rule

* Update .coveragerc
2017-01-16 23:15:11 -08:00
martst
e4a45fa857 Improved x10 state monitoring (#5115)
* Improved x10 state monitoring

* Improved x10 state monitoring

* Use update mthod to fetch state change

* Use update mthod to fetch state change

* Use update function to fetch status

* remove temp file

* Add doc string to update method
2017-01-16 23:11:02 -08:00
Giel Janssens
c72f8b1a06 Netatmo Presence (#5122)
* Netatmo Presence

* Travis

* Remove def camera_stream
2017-01-16 23:10:18 -08:00
Anton Lundin
fd5c2ad08f Denon improvements (#5251)
* denonavr: Expose input as title when in non playing modes

Signed-off-by: Anton Lundin <glance@acc.umu.se>

* denon: Pop from the intended end of the list

Pop from front of list, so we start with NSE0, then NSE1X and so on.

Signed-off-by: Anton Lundin <glance@acc.umu.se>

* denonavr: Don't provide broken media_url's

Only return a media_url if we're in a state that might provide one.

Signed-off-by: Anton Lundin <glance@acc.umu.se>

* denonavr: Only expose player support when in a player mode

This changes so the denonavr only exposes the media player support, when
in a mode that supports media playing.

Signed-off-by: Anton Lundin <glance@acc.umu.se>
2017-01-16 23:04:50 -08:00
Nick Touran
784b87eb2f Add listing and selection of available MPD playlists (#5237)
* Add listing and selection of available MPD playlists through input source UI.

* MPD support updating playlist list on the fly as well as at turn-on.

* Added no_throttle to force playlist update on mpd power cycle.

* Added kwargs signature to get Throttle working right.
2017-01-16 23:01:57 -08:00
Christiaan Blom
ef274c6914 New Discord notification component (#5330)
* Initial commit of discord notification component

* Fixed error where script added extra entries to .coveragerc

* Cleaned up code

* Compliance to PEP8

* removed dependencies

* readded dependencies

* changed name of client id to token for configuration

* Changes for Hound

* Incorporated Review Feedback

* Review feedback

* Updated requirements file

* Check compliance
2017-01-16 22:58:38 -08:00
Marcelo Moreira de Mello
b915cf776b Introduced Amcrest camera sensors and bump Amcrest module version (#5310)
* Introduced Amcrest camera sensors

* Makes script/gen_requirements_all.py happy

* Bump Amcrest version across all components

* - Adjusted scan_interval to 10 seconds

- Filtering HTTPError and ConnectTimeout exceptions

- Removed @Throttle decorator
2017-01-16 22:57:25 -08:00
Jesse Newland
41a6c35ea2 Install phantomjs in Docker container (#5368) 2017-01-16 22:55:42 -08:00
Tom Dickman
65bf30643a Use timezone aware timestamp in flux_update (#5378) 2017-01-16 22:55:05 -08:00
Teemu R
d62b1fc808 Make initial flux update directly when turning on (#5266) 2017-01-16 22:53:34 -08:00
Adam Mills
bae38ac17b Include .ignore file for search utilities (#5290)
* Include .ignore file for search utilities

This instructs search utilities to ignore generated html/js files.

* Panels has no js files
2017-01-16 22:52:53 -08:00
Bryce Edwards
8e17bf43e0 added upnp_bind_multicast option to emulated_hue component (#5381) 2017-01-16 22:52:21 -08:00
Tom Dickman
59f74896a0 Updated abreviation for miles in darksky sensor (#5382) 2017-01-16 22:45:44 -08:00
Paulus Schoutsen
48607d15e5 Merge pull request #5386 from home-assistant/Bug_#5374
fix bug #5374
2017-01-16 22:44:04 -08:00
Daniel Høyer Iversen
51dcd3de6d fix bug #5374 2017-01-17 07:35:09 +01:00
Paulus Schoutsen
2625fee861 Fix script release (#5345) 2017-01-16 22:25:38 -08:00
Paulus Schoutsen
4d96b12424 Merge pull request #5384 from home-assistant/release-0-36-1
Release 0 36 1
2017-01-16 22:24:12 -08:00
Paulus Schoutsen
4603cf4f38 Bump release to 0.36.1 2017-01-16 22:09:17 -08:00
Paulus Schoutsen
28e5659eee Fix load_yaml default value (#5383) 2017-01-16 22:08:57 -08:00
Paulus Schoutsen
7511a5842d Fix load_yaml default value (#5383) 2017-01-16 22:08:47 -08:00
Daniel Høyer Iversen
836eed2a15 fix bug in flux_led (#5373) 2017-01-16 22:08:24 -08:00
Daniel Høyer Iversen
372b54534a Fix python-nest release number (#5369)
* fix_#5365

* fix_#5365
2017-01-16 22:08:24 -08:00
Marcelo Moreira de Mello
7bad0171ec Fixes #5357 which especify absolute path to save cookie used by USPS sensor. (#5358)
Traceback (most recent call last):
  File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/helpers/entity_component.py", line 151, in _async_setup_platform
    entity_platform.add_entities, discovery_info
  File "/usr/local/lib/python3.5/asyncio/futures.py", line 361, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
    future.result()
  File "/usr/local/lib/python3.5/asyncio/futures.py", line 274, in result
    raise self._exception
  File "/usr/local/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/components/sensor/usps.py", line 48, in setup_platform
    add_devices([USPSSensor(session, config.get(CONF_UPDATE_INTERVAL))])
  File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/components/sensor/usps.py", line 58, in __init__
    self._profile = myusps.get_profile(session)
  File "/home/hass/.homeassistant/deps/myusps/__init__.py", line 100, in wrapped
    _login(*args)
  File "/home/hass/.homeassistant/deps/myusps/__init__.py", line 90, in _login
    _save_cookies(session.cookies, session.auth.cookie_path)
  File "/home/hass/.homeassistant/deps/myusps/__init__.py", line 41, in _save_cookies
    with open(filename, 'wb') as handle:
PermissionError: [Errno 13] Permission denied: './usps_cookies.pickle'
2017-01-16 22:08:24 -08:00
Pascal Vizeli
7af92d0bca Bugfix upc with aiohttp 1.2 (cookies) (#5362) 2017-01-16 22:08:24 -08:00
Teemu R
63bf453c60 Eq3bt bump version, expose away attribute (#5353)
* eq3bt: read away ends attr

* eq3bt: bump version to fix missing __init__, expose away_ends attribute.
2017-01-16 22:08:24 -08:00
Pascal Vizeli
8a95cc4104 Bugfix timedelta v2 (#5349)
* Bugfix timedelta v2

* fix volvo

* fix lint
2017-01-16 22:08:24 -08:00
Heiko Rothe
29e2613c75 Fixed the lannouncer platform get_service method (#5352) 2017-01-16 22:08:24 -08:00
Daniel Høyer Iversen
0bbb16626c fix bug in flux_led (#5373) 2017-01-16 21:52:12 -08:00
Duoxilian
d8560a244c Made target temperature sensitive to auto mode (#5312)
* Made target temperature sensitive to auto mode

* Used current_operation instead of operation_mode

* When not in auto_mode, the temperature is sent to set_temperature

* Low and high targets are switched in the call to set_temperature.

* Missed on current_operation. Use STATE_AUTO.

* Remove incorrectly checked in directory.

* Updated set_temperature based on Martin's feedback.

* Use ATTR_TEMPERATURE from const.py
2017-01-17 02:58:34 +01:00
Adam Mills
bd3117a0e7 Reserve a test port for broken api to fix race (#5371)
* Reserve a test port for broken api to fix race

* I cheated.
2017-01-16 12:56:47 -08:00
Daniel Høyer Iversen
196897fdfc Fix python-nest release number (#5369)
* fix_#5365

* fix_#5365
2017-01-16 18:03:26 +01:00
Marcelo Moreira de Mello
62f26fb701 Fixes #5357 which especify absolute path to save cookie used by USPS sensor. (#5358)
Traceback (most recent call last):
  File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/helpers/entity_component.py", line 151, in _async_setup_platform
    entity_platform.add_entities, discovery_info
  File "/usr/local/lib/python3.5/asyncio/futures.py", line 361, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
    future.result()
  File "/usr/local/lib/python3.5/asyncio/futures.py", line 274, in result
    raise self._exception
  File "/usr/local/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/components/sensor/usps.py", line 48, in setup_platform
    add_devices([USPSSensor(session, config.get(CONF_UPDATE_INTERVAL))])
  File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/components/sensor/usps.py", line 58, in __init__
    self._profile = myusps.get_profile(session)
  File "/home/hass/.homeassistant/deps/myusps/__init__.py", line 100, in wrapped
    _login(*args)
  File "/home/hass/.homeassistant/deps/myusps/__init__.py", line 90, in _login
    _save_cookies(session.cookies, session.auth.cookie_path)
  File "/home/hass/.homeassistant/deps/myusps/__init__.py", line 41, in _save_cookies
    with open(filename, 'wb') as handle:
PermissionError: [Errno 13] Permission denied: './usps_cookies.pickle'
2017-01-16 17:36:35 +01:00
whhsw
887c586aae Add station parameter to waqi sensor (#5239)
* Add station parameter to waqi sensor

* Update waqi.py

* Update waqi.py

* Update waqi.py

* add back 'waqi' prefix and add station_name prop

* Update waqi.py
2017-01-16 12:44:09 +01:00
Pascal Vizeli
f08e2648ae Bugfix upc with aiohttp 1.2 (cookies) (#5362) 2017-01-16 11:06:23 +01:00
Teemu R
7a1d4b96ef Eq3bt bump version, expose away attribute (#5353)
* eq3bt: read away ends attr

* eq3bt: bump version to fix missing __init__, expose away_ends attribute.
2017-01-16 06:48:36 +01:00
Pascal Vizeli
2e3d5302bf Bugfix timedelta v2 (#5349)
* Bugfix timedelta v2

* fix volvo

* fix lint
2017-01-15 23:53:37 +01:00
Gianluca Barbaro
6b91d9a75c Update keyboard_remote.py (#5341)
Now it fires events in case the keyboard disconnects and/or disconnects
2017-01-15 14:05:41 -08:00
Heiko Rothe
ad23613cdc Fixed the lannouncer platform get_service method (#5352) 2017-01-15 13:45:54 -08:00
freol35241
c8cf952e21 Remove import of datetime module 2017-01-15 21:10:02 +01:00
freol35241
01d9e6cdfe Removing throttle decorator
Removing redundant throttle decorator on update method. This ensures the existing 'cache-value' config option is respected. Also, UPDATE_INTERVAL is renamed to DEFAULT_UPDATE_INTERVAL for clarity.
2017-01-15 20:53:46 +01:00
Colin O'Dell
8200827a19 Add support for direct MJPEG streams from Amcrest cameras (#5217)
* Add support for direct MJPEG streams from Amcrest cameras

The previous implementation relied on using snapshots from the camera. However,
some Amcrest models cannot keep up with the large number of requests and
instead timeout, resulting in no video stream. These cameras do provide MJPEG
streams though, so this commit adds the option to use these instead of creating
one from snapshots.

Unfortunately, some cameras on newer firmwares do not support MJPEG streams at
high resolution - only at low resolution.

By providing users with both a `resolution` and `stream_source` option, we can
allow them to choose whichever combination works for their particular model
and firmware version.

* Close the stream instead of releasing it

* Close stream without creating a task

* Handle client aborts

* fix lint
2017-01-15 20:37:24 +01:00
Fabian Affolter
633c1408fb Upgrade pylast to 1.7.0 (#5344) 2017-01-15 09:37:17 -08:00
Paulus Schoutsen
82b84f480b Fix script release (#5345) 2017-01-15 09:16:46 -08:00
Paulus Schoutsen
bcfc30264d version bump to 0.37 2017-01-15 08:40:20 -08:00
Paulus Schoutsen
c21172dd36 Merge branch 'dev' 2017-01-15 08:39:56 -08:00
Paulus Schoutsen
24bc035e22 ps - version bump to 0.36 2017-01-15 08:38:41 -08:00
Paulus Schoutsen
36da5d9adb Merge pull request #5245 from home-assistant/dev
0.36
2017-01-15 08:36:53 -08:00
Pascal Vizeli
d7d428119b Bugfix stack trace from api (#5332) 2017-01-15 08:36:24 -08:00
Pascal Vizeli
c458ee29f2 Rename log message / handle cancellederror on image proxy (#5331) 2017-01-15 08:35:58 -08:00
Lupin Demid
85a84549eb Yandex tts component (#5342)
* Added Yandex SpeechKit TTS

* Added test stub

* Added two test and added property for yandex tts

* Copy all test from voice rss

* Added test vith different speaker and  code style changes

* Added new line to end of file

* Url format replaced with url_params
2017-01-15 15:43:10 +01:00
Fabian Affolter
2465aea63b Fix link (#5343) 2017-01-15 14:53:07 +01:00
Zac Hatfield Dodds
e00e6f9db6 Bom weather platform (#5153)
* Fix typo

* Auto-config for `sensor.bom`

Deprecate (but still support) the old two-part station ID, and move to a
single `station` identifier.  Any combination of these, including none,
is valid; most results in downloading and caching the station map to
work out any missing info.

* Add `weather.bom` platform

Very similar to `sensor.bom`, but supporting the lovely new `weather`
component interface.  Easier to configure, and does not support the
deprecated config options.

* Review improvements to BOM weather

Largely around better input validation.
2017-01-15 12:12:50 +01:00
Daniel Høyer Iversen
9fff634b9d Merge pull request #5334 from MrMep/patch-1
Update vlc.py
2017-01-15 10:42:13 +01:00
Adam Mills
e7c157e766 Tests for async volume up/down (#5265) 2017-01-15 08:27:56 +01:00
Martin Hjelmare
9db1aa7629 Add discovery notify support and mysensors notify (#5219)
* Add mysensors notify platform

* Make add_devices optional in platform callback function.
* Use new argument structure for all existing mysensors platforms.
* Add notify platform.
* Update mysensors gateway.

* Refactor notify setup

* Enable discovery of notify platforms.
* Update and add tests for notify component and some platforms.
* Continue setup of notify platforms if a platform fails setup.
* Remove notify tests that check platform config. These tests are not
  needed when config validation is used.
* Add config validation to APNS notify platform.
* Use discovery to set up mysensors notify platform.

* Add discovery_info to get_service and update tests

* Add discovery_info as keyword argument to the get_service function
  signature and update all notify platforms.
* Update existing notify tests to check config validation using test
  helper.
* Add removed tests back in that checked config in apns, command_line
  and file platforms, but use config validation test helper to verify
  config.
* Add a test for notify file to increase coverage.
* Fix some PEP issues.

* Fix comments and use more constants

* Move apns notify service under notify domain
2017-01-15 03:53:14 +01:00
Gianluca Barbaro
d998cba6a2 Update vlc.py
Added default value for "arguments"
2017-01-15 01:35:46 +01:00
Gianluca Barbaro
8013963784 Update vlc.py 2017-01-14 23:31:17 +01:00
Gianluca Barbaro
7436a96978 Update vlc.py 2017-01-14 22:32:50 +01:00
Gianluca Barbaro
3d9b2b5ed0 Update vlc.py
Added support for additional optional configuration

arguments:

to send to vlc.
It is useful for special configurations of VLC.
For example, I have two sound cards on my server, so I defined two vlc media players:

media_player:
- platform: vlc
  name: speaker_1
  arguments: '--alsa-audio-device=hw:1,0'
- platform: vlc
  name: speaker_2
  arguments: '--alsa-audio-device=hw:0,0'

This way, by specifying the corresponding entity_id, I can send the output to the desired speaker.
It is also useful for TTS.
2017-01-14 22:30:24 +01:00
Thibault Cohen
3b9fb6ccf5 Improve InfluxDB (#5238)
* Revert #4791 and fixes #4696

* Update influxDB based on PR comments

* Add migration script

* Update influxdb_migrator based on PR comments

* Add override_measurement option to influxdb_migrator

* Rename value field to state when data is string type

* Fix influxdb cloning query
2017-01-14 09:52:47 -08:00
Colin O'Dell
e3418f633c Add ffmpeg to Docker from jessie-backports (#5322) 2017-01-14 09:43:40 -08:00
Fabian Affolter
bf3e5b460e Clean-up (#5327) 2017-01-14 09:42:45 -08:00
Colin O'Dell
03a6aa48e0 Copy openzwave config to ensure it exists (fixes #5328) (#5329) 2017-01-14 09:41:38 -08:00
Fabian Affolter
2aa996b558 Update name (#5324) 2017-01-14 17:08:48 +01:00
Fabian Affolter
ef4a9bf354 Add timeout to requests, remove pylint disable, and docsstrings (#5326) 2017-01-14 17:08:21 +01:00
Michaël Arnauts
d4eabaf844 Remove build dirs from docker image to keep the layers small (#5243)
* Remove build dirs from docker image to keep the layers small

* Create setup_docker_prereqs script to prepare docker env

* Add documentation for required packages, drop colorlog and cython in first step of Dockerfile since it will be installed later on anyway. Drop libglib2.0-dev and libbluetooth-dev

* Also remove early install of colorlog and cython in Dockerfile.dev

* Re-add libglib2.0-dev and libbluetooth-dev for Bluetooth LE
2017-01-14 07:41:41 -08:00
Pascal Vizeli
7ed83306ea Add warning to openalpr (#5315)
* Add warning to openalpr

* fix lint

* update comment
2017-01-14 15:36:20 +01:00
Fabian Affolter
2e7ae1d5fe Update the link to the docs (#5321) 2017-01-14 15:16:42 +01:00
joopert
f2a42d767e fix hass.loop.run_in_executor in mediaplayer init (#5320) 2017-01-14 14:54:00 +01:00
Michaël Arnauts
c3783bf49b Bugfix for ping component now DEFAULT_SCAN_INTERVAL is a timedelta (#5318) 2017-01-14 11:55:29 +01:00
Pascal Vizeli
b817c7d0c2 Bugfix camera fake image (#5314)
* Bugfix camera fake image

* add logger
2017-01-14 11:53:00 +01:00
Pascal Vizeli
c2492d1493 Component "Image processing" (#5166)
* Init new component for image processing.

* Add demo platform

* address comments

* add unittest v1 for demo

* Add unittest for alpr

* Add openalpr local test

* Add openalpr cloud platform

* Add unittest openalpr cloud platform

* Update stale docstring

* Address paulus comments

* Update stale docstring

* Add coro to function

* Add coro to cloud
2017-01-14 08:18:03 +01:00
Teemu R
5bba9a63a5 switch.tplink: bump to the newest release of pyhs100 (#5308) 2017-01-13 22:20:47 -08:00
Matthew Garrett
d6747d6aaf Add support for Zengge Bluetooth bulbs (#5196)
* Add support for Zengge Bluetooth bulbs

Adds support for the Zengge Bluetooth RGBW bulbs. These are sold under a
number of brands, including Flux. The bulbs do not support full RGBW
control - they turn off the RGB LEDs when white is enabled, and vice versa.

* Update zengge.py
2017-01-13 22:15:43 -08:00
William Scanlon
0da8418f3f Wink fan support (#5174)
* Initial commit for Wink fan support

* Added fan to discovery list

* Raise NotImplementedError and fixed is_on

* Added speed property

* Update __init__.py
2017-01-13 22:08:13 -08:00
Johann Kellerman
9f765836f8 [core] Add 'packages' to the config (#5140)
* Initial

* Merge dicts and lists

* feedback

* Move to homeassistant

* feedback

* increase_coverage

* kick_the_hound
2017-01-13 22:01:47 -08:00
Teemu R
d58b901a78 eq3btsmart: support modes and clean up the code to use climatedevice's features (#4959)
* eq3btsmart: support modes and clean up the code to use climatedevice's features

* eq3btsmart: re-add device state attributes

adds reporting for is_locked, valve, window_open and low_battery,
exposing everything the device reports currently.

* eq3btsmart: bump version req

* eq3btsmart: fix a typo in mode name, report unknown when not initialized

* eq3btsmart: depend on newly forked python-eq3bt lib, pythonify states
2017-01-13 21:34:35 -08:00
Touliloup
394b52b9e8 Xiaomi device tracker (#5283)
* [Device Tracker] Xiaomi Mi Router integration as device tracker

    This device tracker allow to track device connected to Xiaomi Router.
    Parameter: host, username (default admin) and password.

* [Device Tracker] Addition of Xiaomi device tracker file in coverage
2017-01-13 21:24:58 -08:00
Johann Kellerman
b67cce7215 Add correct line numbers for yaml include directives (#5303) 2017-01-13 21:13:17 -08:00
Pascal Vizeli
0cf3c22da0 Bugfix media_player volume_ up and down (#5282)
* Bugfix media_player volume_ up and down

* fix lint

* make a coro
2017-01-13 21:09:02 -08:00
Martin Rowan
a7cb9bdfff Fixed bootstrap to upgrade pip if mininum version not present. As parameter --only-binary in requirements.txt doesn't work on pip < 7.0.0 so install fails. This is to simplify the setup of the development environment when using pyvenv. (#5301) 2017-01-13 21:03:50 -08:00
Dan Cinnamon
5f7d53c06b Bump pyenvisalink to version 2.0 (#5311) 2017-01-13 21:02:33 -08:00
Pascal Vizeli
4b43537801 Bugfix camera streams (#5306)
* fix mjpeg streams

* fix trow error on close by frontend

* fix ffmpeg
2017-01-13 15:57:38 -08:00
Adam Mills
6abad6b76e Version bump for kodi dependency (#5307)
Catches timeout exceptions
2017-01-14 00:16:38 +01:00
Robbie Trencheny
6000c59bb5 Remove GTFS default name & string change 2017-01-13 14:02:00 -08:00
Pascal Vizeli
2c3f55acc4 Add HMWIOSwitch to sensor, binary (#5304) 2017-01-13 22:39:42 +01:00
Pascal Vizeli
a30711f1a0 Update pyhomematic 1.19 & small cleanups (#5299) 2017-01-13 21:22:09 +01:00
Thom Troy
1219ca3c3b [sensor] Add Dublin bus RTPI sensor (#5257) 2017-01-13 19:15:46 +02:00
Pascal Vizeli
baa8e53e66 Bugfix group reload (#5292)
* Bugfix group / hit update

* try to fix round 2

* Convert it to coro

* Don't check statemachine, check unsub listener.
2017-01-13 03:29:20 -08:00
William Scanlon
f7a1d63d52 Support for TrackR device trackers (#5010)
* Support for TrackR device trackers

* Change small style for hass
2017-01-13 00:16:05 +01:00
Pascal Bach
d12decc471 Upgrade to voluptuous to 0.9.3 (#5288) 2017-01-12 23:56:37 +01:00
Pascal Bach
64800fd48c Upgrade distro to 1.0.2 (#5291) 2017-01-12 23:16:32 +01:00
Greg Dowling
9a3c0c8cd3 Don't build Adafruit_BBIO - doesn't work on all platforms. (#5281)
* Don't build Adafruit_BBIO - doesn't work on all platforms.

* Disable pylint import warning on BBIO.
2017-01-12 08:31:30 -08:00
Greg Dowling
d4a54acda0 Merge pull request #5280 from home-assistant/bump-pywemo-version
Bump pywemo version.
2017-01-11 23:26:06 +00:00
pavoni
dc937cc8cf Bump pywemo version. 2017-01-11 23:10:24 +00:00
Adam Mills
eb9b95c292 Convert flic to synchronous platform. (#5276)
* Convert flic to synchronous platform.

pyflic is a synchronous library

* Move pyflic event loop to dedicated thread.
2017-01-11 22:59:39 +01:00
Paulus Schoutsen
e68e29e03e Upgrade to aiohttp 1.2 (#4964)
* Upgrade to aiohttp 1.2

* Clean up emulated_hue tests
2017-01-11 21:25:02 +01:00
Andrew Williams
1cf9ae5a01 Fix TCP sensor to correctly use value_template (#5211)
* Fix TCP sensor to correctly use value_template

* Fix TCP component tests

* Update tcp.py
2017-01-11 17:26:29 +01:00
Pascal Vizeli
3f3a3bcc8a Cleanup language support on TTS (#5255)
* Cleanup language support on TTS

* change to default_language & address comments

* Cleanup not needed code / comment from paulus
2017-01-11 16:31:16 +01:00
Daniel Høyer Iversen
467cb18625 Add last triggered to script (#5261)
* Add last triggered to script

* Add tests for script last_triggered
2017-01-11 16:23:05 +01:00
Robbie Trencheny
82d037a828 Merge pull request #5117 from gopalkildoliya/dev
Notify component for Facebook Messenger
2017-01-10 23:16:43 -08:00
Marcelo Moreira de Mello
34a9fb01ac Bump flux_led version and make use of PyPi package (#5267)
* Bump flux_led version and make use of PyPi package

* Makes script/gen_requirements_all.py happy
2017-01-11 06:45:46 +01:00
joopert
3a4b4380a1 Add support for NAD receivers (#5191)
* Add support for NAD receivers

* remove self.update() in various methods

* remove setting attributes in various methods

* Change import to hass style
2017-01-10 22:32:43 +01:00
Pascal Vizeli
6b00f7ff28 Bugfix async device_tracker see callback (#5259) 2017-01-10 17:19:51 +01:00
Valentin Alexeev
f75e13f55e Use SHA hash to make token harder to guess (#5258)
* Use SHA hash to make token harder to guess

Use hashlib SHA256 to encode object id instead of using it directly.

* Cache access token

Instead of generating a token on the fly cache it in the constructor.

* Fix lint
2017-01-10 16:01:04 +01:00
sander76
6845a0974d adding a default icon "blind" to a PowerView blinds scene. (#5210)
* adding a default icon "blind" to a PowerView blinds scene.

* Adding icon property to define blind icon. Removed it from the state attributes dict.

* fixing lint error
2017-01-10 13:21:15 +01:00
Anton Lundin
7e1629a962 Fix async_volume_up / async_volume_down (#5249)
async_volume_up / async_volume_down should be async versions of
volume_up / volume_down, not a async version of the default variants of
volume_up / volume_down.

The previous code always called into the mediaplayers set_volume_level,
and never into volume_up / volume_down.

Signed-off-by: Anton Lundin <glance@acc.umu.se>
2017-01-10 10:58:39 +01:00
andrey-git
0b685a5b1e Expose supported_features of mqtt_json (#5250)
* Expose supported_features of mqtt_json

* Remove whitespace
2017-01-10 00:40:52 +01:00
Johann Kellerman
1f31dfe5d3 [recorder] Include & Exclude domain fix & unit tests (#5213)
* Tests & domain fix

* incl/excl combined
2017-01-09 21:53:30 +01:00
Fabian Affolter
6be19e8997 Update pytz to 2016.10 (#5247) 2017-01-09 21:50:38 +01:00
Johann Kellerman
e6a9b6404f [sensor/sma] SMA Solar Inverter sensor (#5118)
* Initial

* Rebase ensure_list

* timedelta & remove prints
2017-01-09 21:35:47 +01:00
Fabian Affolter
dd7cafd5e3 Upgrade TwitterAPI to 2.4.3 (#5244) 2017-01-09 21:34:18 +01:00
Adam Mills
c7249a3e3a Build libcec for Docker image (#5230)
* Build libcec for Docker image

* Update development dockerfile as well

* Dynamically load python paths for current version
2017-01-09 17:49:11 +01:00
Pascal Vizeli
bb02fc707c [device_traker/upc] New UPC connect box platform (#5100) 2017-01-09 18:08:37 +02:00
Michaël Arnauts
3ed7c1c6ad Add Lannouncer tts notify component (#5187)
* Add Lannouncer notify component

* Send message by opening a raw TCP socket instead of using requests. Cleanup of method validation.

* Use 'return' instead of 'return None'
2017-01-09 14:10:46 +01:00
Terry Carlin
ee055651cd Update insteon_local.py (#5236)
Correct typo
2017-01-09 12:11:15 +01:00
St. John Johnson
9fdefa5a1d Fix #5188 by Closing the stream instead of Releasing it (#5235)
* Fix #5188 by Closing the stream instead of Releasing it

Closing just terminates the connection, release attempts to download all the contents before closing.  Since the MJPEG stream is infinite, it loads and loads content until the python script runs out of memory.

Source: 50b1d30f41/aiohttp/client_reqrep.py (L668-L672)

* Update mjpeg.py
2017-01-09 10:35:38 +01:00
Paulus Schoutsen
f87016afe6 Update MDI 2017-01-09 01:38:27 +01:00
Paulus Schoutsen
b685e6e2b5 Update frontend 2017-01-09 01:38:04 +01:00
Paulus Schoutsen
5983dc232f Update frontend 2017-01-09 01:14:13 +01:00
Adam Mills
469472914b Add SUPPORT_PLAY flag (#5181)
* Add SUPPORT_PLAY flag

* Add SUPPPORT_PLAY to existing media players

* Leave usage of new flag to device devs
2017-01-09 01:09:30 +01:00
Craig J. Ward
a3971d7ad1 Insteon local (#5088)
* platform set-up begin components

* lights seem to be getting set up properly, not sure why they aren't being added...

* typo

* Dependencies line

* toggle working

* toggle working

* added the switch to insteon_local

First commit hope to test tonight or in the morning

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* Update insteon_local.py

* move dependency declaration before import?

* Move dependencies in Switch

* Update insteon_local.py

* wait for response

* switched the while to an if

switched the while 'cmd2' not in resp: to an if 'cmd2' not in resp: this seems to have the updater working

* Switched the while sleep loop to an if

switched the wile cmd2 not ins resp to be if cmd2 not in resp seems to be working.

* Update insteon_local.py

* import statement

Updated the import statement to import the instance of the insteon_local component not the hub Instance.

* updated import and the device assignment

update the import to import the instance of the insteon_local component not the hub.

* more changes to support the import change

* more changes to support the import change

* change to hass.data and add loop logic

* &&

* Update insteon_local.py

* Update insteon_local.py

* logic fixes and throttle

* reduce polling time

* brightness support

* import util

* hound fixes

* requirements file

* more hound fixes

* newline

* newline weirdness

* lint fixes

* more lint fixes

* switch state

* Update insteon_local.py

* log cmd2 for debugging

* assume success

* remove check for none

* fix comments

* fix comments again

* fix comments, add fixed version of lib, add support for timeout, add support for port, handle invalid login and connection problems

* fix logging exception

* fix hounceci-bot errors

* fix hounceci-bot errors

* requirements fix

* unique-id changes

* make dimmer off use saved ramp rate

* configurator working for lights

* configurator working for switches?

* configurator working for switches?

* include model names and fix lint errors

* lint fix

* fix exception order

* lint fixes

* fix lint errors

* update to use insteon local 0.38

* fix device id

* move status check to library

* move status check to library

* add SKU to setup

* lint fixes

* requirements

* linting
2017-01-09 00:33:35 +01:00
markferry
2b14d407c0 onkyo: fix selecting sources with only one name (#5221) 2017-01-08 23:59:26 +01:00
happyleavesaoc
81f988cf9e date fix (#5227) 2017-01-08 23:50:42 +01:00
happyleavesaoc
f643149d24 usps sensor: better delivery handling (#5202)
* better delivery handling

* bump dep version
2017-01-08 14:35:14 +01:00
dasos
fd50201407 Squeezebox JSON-RPC (#5084)
* Refactor of Squeezebox connection code

* Refactor of Squeezebox connection code

* Typos

* Make Python 3.4 friendly

* Addressing comments

* Improving docstring

* Using discovered port

* Style better

* Accept new disco object

* Revert "Accept new disco object"

* Make it obvious that port isn't discovered yet

* Flake8. ;)
2017-01-08 14:32:15 +01:00
Jan Losinski
469aad5fc8 Add teardown method to pilight tests (#5195)
* Add teardown method to pilight tests

This is necessary to stop the HomeAssistant instance that was started
in the setUp method. Without this there happen random test failures.

This is necessary to stabilize the tests for PR #5045.

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>

* Update test_pilight.py
2017-01-08 14:23:01 +01:00
Pascal Vizeli
a65388e778 Bugfix segfault with new helper track_time_interval (#5222)
* Bugfix sigfault with new helper track_time_interval

* Add none init also to sunrise/sunset for consistance
2017-01-08 14:06:15 +01:00
Lewis Juggins
41ef6228be [device_tracker] Use home zone GPS coordinates for router based devices. (#4852) 2017-01-07 23:09:07 +02:00
Pascal Vizeli
ca4a857532 Improve aiohttp default clientsession close with connector (#5208) 2017-01-07 21:11:19 +01:00
Lewis Juggins
81922b88a2 [calendar] Fix scan interval (#5205) 2017-01-07 11:24:25 +01:00
Paulus Schoutsen
aa1e4c564c Fix tests closing properly (#5203) 2017-01-07 01:47:25 +01:00
Pascal Vizeli
2b991e2f32 [new] component rest_command (#5055)
* New component rest_command

* add unittests

* change handling like other command

* change unittest

* address @balloob comments
2017-01-06 23:42:53 +01:00
Pascal Vizeli
1719d88602 Bugfix default values to timedelta (#5193)
* Bugfix default values to timedelta

* fix unittests
2017-01-06 00:16:12 +01:00
Jared J
c959637ebe Add Yeelight auto discovery, color temp (#5145)
* Add Yeelight auto discovery, color temp

* Fixing linting issues
2017-01-05 23:39:28 +01:00
Ryan Kraus
db623040a4 Re-enabled Weather Sensors for the ISY component. (#5148)
* Re-enabled Weather Sensors for the ISY component.

As the ISY component had been updated to support newer components and
have better UOM support, the support for ISY’s weather module was
dropped. This adds that support back into Home Assistant.

* Cleanup of the ISY Weather support.

Cleaned up the for loops used to generate nodes representing weather
data from the ISY. Moved the weather_node named tuple to the top of the
file so that it can be more easily identified.

* Update isy994.py
2017-01-05 23:33:52 +01:00
Michaël Arnauts
ba29ba0fc3 Universal media_player returns ATTR_MEDIA_POSITION and ATTR_MEDIA_POSITION_UPDATED_AT from it's active child now. (#5184) 2017-01-05 23:15:26 +01:00
Adam Mills
93d462b010 Fix for async device_tracker (#5192) 2017-01-05 23:10:43 +01:00
Pascal Vizeli
50a8ec7335 Bugfix aiohttp connector pool close on shutdown (#5190)
* Bugfix aiohttp connector pool close on shutdown

* fix circular import

* remove lint disable
2017-01-05 23:09:04 +01:00
Nick Touran
a36ca62445 Support longer-than-60-second scan_interval and interval_seconds (#5147)
* Update scan_interval and interval_seconds max to 1 day vs. 60 seconds

* Format fixes

* Add docstring on unittest.

* Added and implemented new async_track_time_interval helper.

* Format fixes, removed unused import.

* Undid whoops on unsub_polling.

* Updated unit tests for scan_interval.

* Added unit test for track_time_interval.

* Allow other forms of time interval input for scan_interval and interval_seconds
2017-01-05 23:05:16 +01:00
Paulus Schoutsen
f88b5a9c5e Update frontend 2017-01-05 22:28:48 +01:00
webworxshop
51446e0772 Add support for customised Kankun SP3 Wifi switches. (#5089)
* Add support for customised Kankun SP3 Wifi switches.

* Add config validation for Kankun SP3 wifi switch.

* Update kankun.py
2017-01-05 22:16:00 +01:00
MrMep
95ddef31fe Update keyboard_remote.py (#5112)
* Update keyboard_remote.py

I changed os.path.isFile() to os.path.exists: as far as I know isFile doesn't work with device files. At least on my Ubuntu it wasn't working.

Then I added some error control in case the keyboard disconnects: with bluetooth keyboards this happen often due to battery saving. Now it reconnects automatically when the keyboard wakes up.

We could fire an event to hass when the keyboard connects-disconnects, maybe I'll do this later.

We should also manage errors due to permissions problems on the device file, or at least give some info in the docs about how to allow HA to grab control over an system input file.

I'm sorry if my coding isn't up to some standard practice I'm not aware of: I'm new to HA and to python itself, I'm just trying to be of help.
Gianluca

* Update keyboard_remote.py

I changed some other few things.

Not the component gets loaded even if the keyboard is disconnected. When it connects, it starts to fire events when keys are pressed.

I also added a sleep(0.1) that reduces a lot the load on the CPU, but without many consequences on key pressed detection.
2017-01-05 22:03:05 +01:00
Adam Mills
276a29c8f4 Convert Kodi platform to async (#5167)
* Convert Kodi platform to async

* Remove unnecessary async_update_ha_state
2017-01-05 21:01:13 +01:00
Martin Vacula
6b682d0d81 Beaglebone black GPIO control by switch v2 (#4908)
* Added support for BBB GPIO

* Requirements updated

* unnecessary pylint statement removed

* Changed according arduino switch

* typo corrected

* Hound errors solved

* lint error

* Update bbb_gpio.py
2017-01-05 20:53:48 +01:00
Johann Kellerman
cbda516af9 ensure_list validator - Allow None to return an empty list (#5133) 2017-01-05 21:33:22 +02:00
Michaël Arnauts
cb85128304 Speeds up lint and test in docker by keeping the cache between invocations. (#5177)
* Add a volume to store the tox cache on the host. This gives quite some speed boost when running lint_docker and test_docker.

* Only map .tox directory for cache.
2017-01-05 09:45:14 +01:00
happyleavesaoc
74aa8194d7 USPS sensor (#5180)
* usps sensor

* Update usps.py
2017-01-05 09:44:15 +01:00
Sander de Leeuw
497a1c84b5 Fixed invalid response when sending a test-request from Locative iOS app (#5179) 2017-01-05 10:05:39 +02:00
Daniel Høyer Iversen
2f907696f3 [WIP] Spread the traffic to yr.no servers and remove yr.no from the default… (#5171)
* Spread the traffic to yr.no servers and remove yr.no from the default config

* use unique address for yr.no

* update yr tests

* Wait 10 min extra before requesting new data

* Update config.py

* Update yr.py
2017-01-04 23:20:30 +01:00
Brent Hughes
4ef7e08553 Rewrite influxdb metrics to be more consistent (#4791)
* Updated to make all metrics consistent

* Updated existing test for new format

* Updated checks on lists and dictionarys
2017-01-04 22:36:54 +01:00
Matthew Garrett
ff0788324c Add support for Tikteck Bluetooth bulbs (#4843)
* Add support for Tikteck Bluetooth bulbs

Adds support for the Tikteck RGBW BLE bulbs. These don't provide "true" RGBW
support - at a certain point in RGB space, the white LEDs turn on. Each bulb
has a specific key that needs to be extracted from the Android app.

* Update tikteck.py
2017-01-04 22:31:31 +01:00
doudz
9f65b8fef5 add offline tts using pico (#5005)
* add offline tts using pico

* Update picotts.py

* Update picotts.py

* Update picotts.py

* Update picotts.py

* Update picotts.py

* Update picotts.py

* Update picotts.py

* Update .coveragerc
2017-01-04 22:05:41 +01:00
Daniel Høyer Iversen
67ab1f69d8 user agent header (#5172)
* user agent in header

* update user agent info

* Use user-agent from lib
2017-01-04 21:15:50 +01:00
Michaël Arnauts
5e8e2a8312 Ping device tracker (#5176)
* Ping device tracker

* Style fixes
2017-01-04 21:06:09 +01:00
Dan Smith
6ed3c69604 Bump uvcclient to 0.10.0 (#5175)
This brings fixes for newer versions of unifi-video and a few
fixes.
2017-01-04 19:55:16 +01:00
Gopal
d09dcc4b03 Timeout and Constant added 2017-01-04 18:23:29 +05:30
Florian Holzapfel
3f7a629079 fix #5157 (#5173) 2017-01-04 13:16:52 +01:00
Oliver
8e61fab579 Pushed to another version of denonavr library with fixes for AVR-nonX devices (#5156) 2017-01-04 00:02:44 +01:00
Magnus Ihse Bursie
d9614cff46 Improve async/multithreaded behavior of tellstick code (#4989)
* Refactor tellstick code for increased readability. Especially highlight if "device" is a telldus core device or a HA entity.

* Refactor Tellstick object model for increased clarity.

* Update comments. Unify better with sensors. Fix typo bug. Add debug logging.

* Refactor tellstick code for increased readability. Especially highlight if "device" is a telldus core device or a HA entity.

* Refactor Tellstick object model for increased clarity.

* Update comments. Unify better with sensors. Fix typo bug. Add debug logging.

* Fix lint issues.

* Remove global variable according to hint from balloob.

* Better async/threading behavior for tellstick.

* Fix lint/style checks.

* Use hass.async_add_job
2017-01-03 23:54:11 +01:00
Adam Mills
2a7a419ff3 Async support in media player component (#4995)
* Async support in media player component

* Removed redundant new tests

* Update to new 'reduce coroutine' standards

* Remove extra create_task
2017-01-03 23:51:23 +01:00
Nathan Henrie
b78cf4772d Add ability to set rpi_rf tx_repeats attribute (#5070)
* Add ability to set rpi_rf `tx_repeats` attribute

Uses the current `rpi_rf` default of 10
Closes home-assistant/home-assistant#5069

* Use `signal_repetitions` instead of `repeats` for consistency
2017-01-03 23:46:30 +01:00
Daniel Høyer Iversen
ebfb2c9b26 Broadlink fix (#5065)
* Broadlink fix

* style fix

* style fix

* typo

* restructure

* Update broadlink.py

* Update broadlink.py

* Add support for more devices

* fix library version

* fix library version

* fix library version

* fix library version

* fix library version

* Update broadlink.py

* lib version

* remove lower

* remove lower

* refactor

* refactor

* refactor

* authorization

* authorization

* refactor

* lib version

* lib version
2017-01-03 23:45:11 +01:00
Thibault Cohen
e17ce4f374 Improve Sharp Aquos TV component - Fixes #4973 (#5108) 2017-01-03 23:38:21 +01:00
Giannie
67b74abf8d Allow selection of bluetooth device to use (#5104)
Adding the device_id key to the bevice tracker component allows selecting the bluetooth device to use in case the default device does not have BLE Capabilities
2017-01-03 23:34:51 +01:00
Brandon Weeks
c14a5fa7c1 Upgrade samsungctl to 0.6.0 (#5126) 2017-01-03 23:28:23 +01:00
Matthew Garrett
2970196f61 Add support for limiting which entities are recorded (#4733) 2017-01-04 00:19:28 +02:00
Johann Kellerman
4692ea85b7 [mqtt] Embedded MQTT server fix (#5132)
* Embedded MQTT server fix and schema

* feedback
2017-01-03 23:17:56 +01:00
Adam Mills
018d786f36 Kodi cleanup and config update (#5098) 2017-01-03 21:41:42 +01:00
Mike Hennessy
254eb4e88a Change zeroconf to use local ip not base_url (#5151)
Rather than rely on base_url being unconfigured and therefore be
set as the host ip in the api component, get the local ip directly.

Use server port from the http component instead of the api component
where it will be None if base_url is set.

Change the exception catch meant to check for ipv4 vs ipv6 to wrap the
address encoding only instead of the zeroconf service info declaration.
2017-01-03 21:39:42 +01:00
Paulus Schoutsen
9eed03108f Run tests on Python 3.6 (#5162)
* Run tests on Python 3.6

* Fix dsmr test

* Fix async util tests

* Fix rest sensor test
2017-01-03 21:33:48 +01:00
eieste
fdd3fa7d80 Apple TouchBar icon Support (mask-icon) (#5159)
* Update index.html

Add Apple TouchBar icon Color Support

* Add svg icon

* Change path to SVG icon

* Rename mask-icon.svg to home-assistant-icon.svg

* Remove useless whitespace

* Update index.html
2017-01-03 21:32:40 +01:00
Daniel Høyer Iversen
6ec500f2e7 issue #5101 (#5161) 2017-01-03 21:13:02 +01:00
andrey-git
a0a9f26312 Keep previous brightness of dimming zwave light upon turning it on/off (#5160)
* Keep previous brightness of dimming zwave light upon turning it on/off

* Fix initialization

* Use value 255 to set dimmer to previous value
2017-01-03 20:31:44 +01:00
Adam Mills
21f59a0732 Merge pull request #5150 from Zac-HD/fix-contrib-link
Fix link to pull request advice for contributors
2017-01-03 14:24:53 -05:00
Brandon Weeks
52f6fe3e06 Add version test for monkey_patch_asyncio() (#5127)
* Add version test for monkey_patch_asyncio()

* Update __main__.py
2017-01-03 17:47:33 +01:00
Dan Smith
f71027a9c7 Nx584 maint (#5149)
* Update nx584 requirement to 0.4

There have been a few bug fixes to nx584 since 0.2, so this just updates
our requirement to pull in the newer version.

* Fix nx584 if no partitions are found

If we succeed in our connection to the panel but find no
configured partitions, then we will fall through to the bypass
probe and fail because 'zones' is never initialized. This fixes
both exception paths and adds a test that would poke it.
2017-01-03 08:19:33 +01:00
Zac-HD
328ff6027b Fix link to pull request advice for contributors 2017-01-03 14:26:24 +11:00
Michaël Arnauts
c864ea60c9 Improve development workflow in docker (#5079)
* Allow bower install of frontend components as root. Needed for frontend development in docker since everything runs as root in the docker image.

* Improve development workflow in docker

* Use LANG=C.UTF-8 in tox. Fixes installation of libraries with UTF-8 in it's readme.

* Install mysqlclient psycopg2 uvloop after requirements_all.txt again, but with a --no-cache-dir this time. Allows bootstrap_frontend to be executed in a different path like the other scripts.
2017-01-02 22:04:09 +01:00
Pascal Vizeli
b2371c6614 Update device_traker for async platforms (#5102)
Async DeviceScanner object, migrate to async, cleanups
2017-01-02 21:50:42 +02:00
John Arild Berentsen
9c6a985c56 [zwave]Use schedule_ha_state and add debug message (#5143)
* Use schedule_ha_state and add debug message

* Logger not defined
2017-01-02 18:55:56 +01:00
John Arild Berentsen
5c006cd2d2 Prevent Homeassistant to create a segfault with OZW (#5085) 2017-01-02 18:53:46 +01:00
andrey-git
a7cc7ce476 Clean up DEFAULT_DEBUG constant in zwave (#5138)
Nice 👍
2017-01-02 18:45:44 +01:00
John Arild Berentsen
23f16bb68f Catch RuntimeError (#5134) 2017-01-02 18:45:10 +01:00
Greg Dowling
8a463ef7a4 Merge pull request #5142 from home-assistant/bump_loop_energy
Bump pyloopenergy to catch SSL exception.
2017-01-02 15:02:08 +00:00
pavoni
9af1e0ccf3 Bump pyloopenergy to catch SSL exception. 2017-01-02 14:15:38 +00:00
jtscott
a8a98f2585 [climate] Fix typo in services.yaml (#5136) 2017-01-02 10:17:52 +00:00
andrey-git
7fbf68df35 Add print_config_parameter service to Z-Wave (#5121)
* Add print_config_param service to z-wave

* Add print_config_parameter service to z-wave

* Add print_config_parameter service to z-wave

* Fix typos

* Fix typos

* Fix typo
2017-01-01 21:10:45 +01:00
Mark
01be70cda9 Philio 3-in-1 Gen 4 zwave sensor needs the no-off-event workaround. (#5120) 2017-01-01 20:40:34 +01:00
Gopal
e89aa6b2d6 File added to coveragerc 2016-12-31 10:11:30 +05:30
Gopal
227fb29cab Facebook notify updated 2016-12-31 09:59:44 +05:30
Felix
d04ee66669 Fixes moldindicator sensor after switch to asyncio (#5038) 2016-12-30 11:16:34 +01:00
Thibault Cohen
9e66755baf Fix proximity issue (#5109) 2016-12-30 08:51:37 +01:00
Pascal Vizeli
0ecd185f0d Bugfix close async log handler (#5086) 2016-12-29 17:27:58 +01:00
Jesse Newland
a2f17cccbb Replace dots in Alexa built-in intent slots w/ underscores (#5092)
* Replace dots in built-in intent slots w/ underscores

* Add a built-in intent test
2016-12-29 17:26:23 +01:00
Gopal
6892048de0 Facebook Notify Started 2016-12-29 18:19:11 +05:30
Johann Kellerman
aaff8d8602 Qwikswitch library PyPi update (#5099) 2016-12-29 11:08:11 +02:00
Brent Hughes
cf714f42df Added Ledenet protocol support to flux_led (#5097)
* Added Ledenet protocol support to flux_led

* Made the protocol config lowercase
2016-12-28 23:21:29 -06:00
Johann Kellerman
f0b1874d2d Fix up docstring for tests (#5090) 2016-12-28 20:04:59 +02:00
Magnus Ihse Bursie
98efbbc129 Fix typo. (#5087) 2016-12-28 08:12:10 +01:00
Magnus Ihse Bursie
d8ff22870a Include flake8-docstrings to test requirements to better mimic tox -e lint (#4926) 2016-12-28 07:26:27 +02:00
John Arild Berentsen
fee47f35b9 Improvements to zwave lock platform (#5066) 2016-12-27 22:08:35 +01:00
Brian Torres-Gil
7b6503c017 Ecobee service fix and new 'resume program' service (#4510)
* ecobee_set_fan_min_on_time: fix issue using 'entity_id' field and add service field help text

* climate.ecobee: add 'resume_program' service

* Add default value for resume_all and correct entity_id field name reference
2016-12-27 21:56:26 +01:00
Michaël Arnauts
c77b4a4806 Update icons from materialdesignicons.com (#5081) 2016-12-27 21:36:07 +01:00
andrey-git
4728fa8da6 Allow to specify TTS language in the service call. (#5047)
* Allow to specify TTS language in the service call.

* Allow to specify TTS language in the service call.

* Respect 79 char limit

* Fix "Too many blank lines"

* Fix "Too many blank lines"

* Fix "Too many blank lines"

* Change language to be optional parameter of *get_tts_audio

* Change language to be optional parameter of *get_tts_audio

* Respect 79 char limit

* Don't pass "None

* Use default of "None" for TTS language

* Use default of "None" for TTS language

* Don't pass "None"

* Change TTS cache key to be hash_lang_engine

* Change language from demo to en

* Fix wrong replace
2016-12-27 17:01:22 +01:00
Daniel Høyer Iversen
68865ec27b upgrade miflora (#5075)
Add an optional extended description…
2016-12-27 09:24:05 +01:00
Fabian Affolter
c5f70e8be3 Upgrade speedtest-cli to 1.0.1 (#5073) 2016-12-26 16:41:18 +01:00
Fabian Affolter
ec89accd29 Upgrade psutil to 5.0.1 (#5072) 2016-12-26 16:31:44 +01:00
Fabian Affolter
ac1063266c Upgrade pyowm to 2.6.0 (#5071) 2016-12-26 16:31:26 +01:00
Hydreliox
5b619a94ad Add sensor for International Space Station (#4968)
* Add sensor for International Space Station

* Change two sensors to one with attributes.

* Fix due to comments in HA PR. Thanks !

* Update Requirement
2016-12-26 16:02:11 +01:00
Pascal Vizeli
244cdf43d0 Async reduce coro (#5001)
* Asyncio coro reduce

* Replace comments
2016-12-26 14:10:23 +01:00
Pascal Vizeli
22d1bf0acd Async migrate climate (#5026)
* Async migrate climate

* Change update handling
2016-12-26 14:09:15 +01:00
Johan Bloemberg
43e5d28643 Fix and test for prefixed MAC addresses. (#5052)
* Fix and test for prefixed MAC addresses.

* Fix style.

* Don't commit old code.

* Fix style.
2016-12-26 14:02:12 +01:00
abmantis
e5dfcf7310 Emulated hue: add support for cover open/close (#5057)
* add support for cover open/close

* fix action compare; reduce line width
2016-12-26 14:00:43 +01:00
abmantis
1c1b04718f emulated_hue: fix alexa "device not responding" (#5058)
* emulated_hue: fix alexa "device not responding"

we need to set the brightness to 100 for devices that only turn on

* emulated_hue: dont override brightness for scenes/scripts

* emulated_hue: python and semi-colons

* emulated_hue: fix output brightness level
2016-12-26 13:58:32 +01:00
Paulus Schoutsen
ce24ef0c20 Merge branch 'master' into dev 2016-12-23 07:08:33 +01:00
Paulus Schoutsen
308d71c448 Merge pull request #5032 from home-assistant/release-0-35-3
0.35.3
2016-12-23 07:05:54 +01:00
Josh Nichols
203c1cfc96 Nest fixes (#5011)
* Updated Nest API to have logical names

* Fix NoneType not having replace method in NestSensor constructor

* Move name setting to constructor, in case zone.name causes IO.

* normalize is_online to online

* Updated python-nest API

* push is_* helpers down to python-nest, and use inheritence to implement rather than checking class name

* Update python-nest
2016-12-22 20:25:43 +01:00
Josh Nichols
6c50f53696 Nest fixes (#5011)
* Updated Nest API to have logical names

* Fix NoneType not having replace method in NestSensor constructor

* Move name setting to constructor, in case zone.name causes IO.

* normalize is_online to online

* Updated python-nest API

* push is_* helpers down to python-nest, and use inheritence to implement rather than checking class name

* Update python-nest
2016-12-22 20:22:07 +01:00
John Mihalic
5e1e5992af Update pyHik requirement version (#5040) 2016-12-22 18:45:05 +01:00
Pascal Vizeli
9bf4a53fbb Bugfix async log handle re-close bug (#5034)
* Bugfix async log handle re-close bug

* Check on running thread on async_close

* Fix now on right place
2016-12-22 16:09:16 +01:00
Pascal Vizeli
334b3b8636 Bugfix async log handle re-close bug (#5034)
* Bugfix async log handle re-close bug

* Check on running thread on async_close

* Fix now on right place
2016-12-22 16:08:01 +01:00
Pascal Vizeli
f18a88c2d4 Bugfix create a task from a task in component update (#5033) 2016-12-21 15:12:26 +01:00
Pascal Vizeli
9a16054867 Bugfix create a task from a task in component update (#5033) 2016-12-21 15:11:14 +01:00
Pascal Vizeli
35b4da0aa2 Bugfix voicerss post api (#5021)
* Bugfix voicerss post api

* fix unittest

* Add cache to service description
2016-12-21 11:49:56 +01:00
pvizeli
61fc4ca8fe Version bump to 0.35.3 2016-12-21 11:47:38 +01:00
Pascal Vizeli
4c9347eb2a Fix spell media_player service (#5030)
Add an optional extended description…
2016-12-21 11:39:59 +01:00
Pascal Vizeli
25469dd8ee Bugfix voicerss post api (#5021)
* Bugfix voicerss post api

* fix unittest

* Add cache to service description
2016-12-21 10:22:12 +01:00
Johann Kellerman
b170f4c399 Spread seconds (#5025) 2016-12-21 08:42:23 +01:00
Johann Kellerman
a8b3900913 device_tracker (#5023)
2
2016-12-21 08:40:44 +01:00
Daniel Høyer Iversen
39bdd5310b Merge pull request #5022 from home-assistant/broadlink_bug_fix
Solve some bugs in the broadlink switch
2016-12-21 05:24:16 +01:00
Daniel Høyer Iversen
133c03ee57 style fix 2016-12-20 21:16:18 +01:00
Daniel Høyer Iversen
f224ee7229 Solve some bugs in the bradlink switch 2016-12-20 21:05:54 +01:00
Petr Vraník
1aea3e0d51 script/lint only on python files (#5018) 2016-12-20 13:06:53 +02:00
Daniel Perna
877efac630 Add missing support for HMIP-PSM (#5013) 2016-12-20 11:39:29 +01:00
Hugo Dupras
ee6fb93018 Hotfix for Netatmo Camera (#4998)
Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>
2016-12-19 07:47:38 -08:00
Daniel Høyer Iversen
08591aacc9 Merge pull request #5000 from home-assistant/rfxtrx_lib_0.14
rfxtrx lib upgrade
2016-12-19 11:54:58 +01:00
Daniel Hoyer Iversen
2cb67eca46 rfxtrx lib upgrade 2016-12-19 11:35:00 +01:00
Daniel Høyer Iversen
00b80d4fe1 Support for broadlink sp (#4961)
* initial support for broadlink sp

* style fix

* style

* bug fix
2016-12-18 17:59:08 -08:00
Paulus Schoutsen
53dde0e4e1 Unbreak dev 2016-12-18 17:35:42 -08:00
Paulus Schoutsen
4778ec4f94 Merge branch 'master' into dev 2016-12-18 15:02:02 -08:00
Paulus Schoutsen
3ea984ca25 Version bump to 0.35.2 2016-12-18 15:00:37 -08:00
Paulus Schoutsen
1258c4c680 Base url: Fix external port different from internal port (#4990)
* Base url: Fix external port different from internal port

* Add base_url example to new config
2016-12-18 15:00:16 -08:00
Paulus Schoutsen
ed0d14c902 Base url: Fix external port different from internal port (#4990)
* Base url: Fix external port different from internal port

* Add base_url example to new config
2016-12-18 14:59:45 -08:00
Paulus Schoutsen
75dd391118 Merge pull request #4988 from home-assistant/release-0-35-1
0.35.1
2016-12-18 14:11:10 -08:00
Paulus Schoutsen
76a9eba744 Version bump to 0.35.1 2016-12-18 13:00:35 -08:00
Paulus Schoutsen
31fe1d28e8 Gracefully exit with async logger (#4965)
* Gracefully exit with async logger

* Lint
2016-12-18 13:00:21 -08:00
Pascal Vizeli
a4a38c8a00 Bugfix TTS clear cache (#4974)
* Bugfix TTS base url with certificate

* fix lint

* remove base_url stuff fix only clear_cache stuff

* cleanup
2016-12-18 13:00:21 -08:00
Paulus Schoutsen
3b74cc606e Allow setting base url (#4985) 2016-12-18 13:00:21 -08:00
Pascal Vizeli
b750319de4 Bugfix wait in automation (#4984) 2016-12-18 13:00:21 -08:00
andrey-git
744d00a36e Fix non-radio Sonos album-art by using track_info['album_art'] before checking other options. (#4958)
* Fix Sonos album art for non-radio streams

* Revert "Fix Sonos album art for non-radio streams"

This reverts commit d71502d18f.

* Fix Sonos album art for non-radio streams

* Move art existance check into _format_media_image_url
2016-12-18 12:58:59 -08:00
Pascal Vizeli
a6d995e394 Bugfix wait in automation (#4984) 2016-12-18 12:57:31 -08:00
Paulus Schoutsen
f8af6e7863 Allow setting base url (#4985) 2016-12-18 12:56:07 -08:00
Pascal Vizeli
fec33347fb Bugfix TTS clear cache (#4974)
* Bugfix TTS base url with certificate

* fix lint

* remove base_url stuff fix only clear_cache stuff

* cleanup
2016-12-18 11:26:40 -08:00
Nick Sabinske
44eaca5985 Add support for the Sonarr URL Base setting (#4975)
* Add support for the Sonarr URL Base setting

For those of us who have sonarr hidden behind reverse proxy under a path, we need to be able to pass the path

Adds urlbase: XXX to the sonarr yaml... Match it to what you have set in Sonarr (Settings>General>URL Base)

* Fix line lengths

* Fix trailing white space caused by last change

* Removing use of len()
2016-12-18 10:05:05 -08:00
Thibault Cohen
18cf6f6f99 Add HydroQuebec support (#4840) 2016-12-18 12:23:10 +01:00
Fabian Affolter
9f298a92f4 Remove and update docstrings (#4969) 2016-12-18 11:39:33 +01:00
Paulus Schoutsen
01e6bd2c92 Gracefully exit with async logger (#4965)
* Gracefully exit with async logger

* Lint
2016-12-18 00:14:59 -08:00
Paulus Schoutsen
a76684f203 Version bump to 0.36.0.dev0 2016-12-17 14:07:44 -08:00
Paulus Schoutsen
9bc16157af Merge pull request #4875 from home-assistant/dev
0.35
2016-12-17 14:07:28 -08:00
Paulus Schoutsen
35d7f2b8bb Version bump to 0.35.0 2016-12-17 14:07:13 -08:00
Georgi Kirichkov
7390f82e1f Updates TP-Link dependency (#4914)
* Updates TP-Link switches dependent module

Refactors code to use the new module API

* Set TP-Link Switch name from the device settings

If no name has been set in the configuration file the name set on the device will be used

* Removes default name for TP-Link switch

Fallback to device alias now works properly

* Removes logging

* Updates comment to denote support for HS200 switch
2016-12-17 13:49:43 -08:00
Paulus Schoutsen
cc9e5de503 Only report slowness warning once per entity (#4962) 2016-12-17 13:00:08 -08:00
Pascal Vizeli
50c8224365 Bugfix async log handler (#4954)
* Bugfix async log handler

* fix boostrap test

* Use hass.data for store handler and cleanup on async_stop

* Update bootstrap.py
2016-12-17 12:21:52 -08:00
Erik Eriksson
b08b376aa7 eliqonline lib upgrade (#4948) 2016-12-17 12:14:04 -08:00
Fabian Affolter
60ef0153a2 Upgrade Sphinx to 1.5.1 (#4957) 2016-12-17 19:30:54 +01:00
Fabian Affolter
44c4b25f2b Upgrade astral to 1.3.3 (#4956) 2016-12-17 19:29:36 +01:00
Fabian Affolter
4abcaea4b7 Upgrade python-telegram-bot to 5.3.0 (#4955) 2016-12-17 19:29:24 +01:00
Albert Lee
831cad4220 Use Wake-on-LAN to turn on LG webOS TV (#4808) 2016-12-16 23:24:35 -08:00
Daniel Perna
6c524594c1 Fixing issue #4899 (#4947) 2016-12-16 22:34:13 -08:00
Paulus Schoutsen
78f6cfd1eb Update coverage 2016-12-16 22:03:45 -08:00
Pascal Vizeli
6d6abab358 Async logging file handler (#4901)
* Async logging file handler

* add time rotation handle

* new layout

* address paulus comments

* fix lint
2016-12-16 15:51:06 -08:00
Ashura
326cc83a17 [media_player.braviatv] Add turn on capabilities. (#4938) 2016-12-16 17:41:31 +00:00
Pascal Vizeli
8358ab56ea Bugfix asyncio wait (#4946) 2016-12-16 08:36:50 -08:00
Albert Lee
32dc518971 Use Wake-on-LAN to turn on Panasonic Viera TV (#4809) 2016-12-16 08:16:46 -08:00
Paulus Schoutsen
b318a033bb Cast fix (#4939)
* Update frontend

* Fix exception on cast startup
2016-12-16 00:10:56 -08:00
Pascal Vizeli
a0b2105ea0 Add voicerss for TTS (#4916)
* Add voicerss for TTS

* add unittests

* fix tests

* fix status bug in google/voicerss

* remove ssl
2016-12-16 00:10:48 -08:00
Nolan Gilley
9f9b87692a add manual option to prevent scheduled tests. (#4906) 2016-12-15 22:55:51 -08:00
Roi Dayan
5c4f04e9fc Fix webostv component to accept any custom sources (#4915)
Updated the schema check to accept any string
Search custom sources in app title and app id
The makes the short list redundant and thus removed
Tested by adding livetv, netflix, youtube, makovod and others
This is also compatible with the list that was supported till now
so current users won't see any difference.

Signed-off-by: Roi Dayan <roi.dayan@gmail.com>
2016-12-15 22:51:08 -08:00
Erik Eriksson
757f6278eb initialize self._last_brightness (#4917) 2016-12-15 22:35:53 -08:00
Adam Mills
b9dcc2777b Setup DarkSky platform when offline during init (#4919)
* Setup DarkSky platform when offline during init

* Fail setup_platform if fetch was unsuccessful
2016-12-15 22:27:37 -08:00
Magnus Ihse Bursie
103fffa0f4 Add support for new netdisco detection of Samsung Smart TV. (#4925) 2016-12-15 22:20:00 -08:00
Fabian Affolter
7748867732 Avoid TypeError for state (#4897) 2016-12-15 22:14:59 -08:00
Paulus Schoutsen
02517ae5ec Fix synologydsm (#4895) 2016-12-15 22:13:38 -08:00
Fabian Affolter
2a31bb48c6 Clean-up (#4894) 2016-12-15 22:12:33 -08:00
Magas
5b70ada7b4 Panasonic viera fix (#4888)
* Removed return False so the Panasonic Viera TV can be added even if it doesn't connect

* Removed return False so the Panasonic Viera TV can be added even if it doesn't connect

* Removed return False so the Panasonic Viera TV can be added even if it doesn't connect

* Remove try/except to connect to the TV

* Update panasonic_viera.py

* Update panasonic_viera.py
2016-12-15 22:11:58 -08:00
Albert Lee
7b45cf8e59 Expose media volume as emulated Hue brightness (#4869)
* Allow virtual Hue bridge to set volume level of media_player entities
* Show correct states in all lights view
2016-12-15 21:47:23 -08:00
Daniel Høyer Iversen
394d53e748 Broadlink sensor and switch (#4834)
* Broadlink sensor and switch

* broadlink logging

* Use async

* style

* style
2016-12-15 21:42:00 -08:00
Hugo Dupras
c125c4af4f Fix for GTFS sensor (#4828)
* Fix for GTFS sensor

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* GTFS fix

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>
2016-12-15 21:40:33 -08:00
Joe Rocklin
f90b89bc74 Add nest hvac state (#4810)
* Add basic property details for Nest hvac_state

* Add the hvac_state sensor

* Update requirements and remove trailing whitespace

Clean up the multiline docstring

Adding a space between summary and description

* Removing the hvac_state as a property on the nest climate

* Update nest.py
2016-12-15 21:39:59 -08:00
Daniel Høyer Iversen
ceac9eab94 Bug fix for #4903 (#4927) 2016-12-15 21:35:47 -08:00
joopert
7bb0abdf09 kodi fanart fix basic auth (#4930) 2016-12-15 21:35:01 -08:00
Pascal Vizeli
1d60760e21 Protect add_job (#4932) 2016-12-15 21:30:09 -08:00
Pascal Vizeli
43d18daebd Homematic faster update with async (#4929) 2016-12-15 21:26:13 +01:00
Lewis Juggins
1a7895b1d8 [media_player.sonos] Bugfix, initalise source_name. (#4911) 2016-12-15 11:46:18 +00:00
Daniel Høyer Iversen
c2f31bbb38 Merge pull request #4924 from home-assistant/flux_lib
Update flux led lib
2016-12-15 08:26:24 +01:00
Daniel Høyer Iversen
a7e75dd01e Merge pull request #4907 from home-assistant/rpi_camera
Bug in rpi_camera
2016-12-15 08:09:23 +01:00
Daniel Hoyer Iversen
58ea3c25df Update flux led lib 2016-12-15 07:58:58 +01:00
Pascal Vizeli
6d2de67620 TTS add google language list for config check (#4912)
* Add config check for language

* update default

* move language from component to platform

* fix lint
2016-12-14 22:32:20 +01:00
Valentin Alexeev
a359d21799 [media_player.sonos] Source selection from favorites (#4804) 2016-12-14 18:05:03 +00:00
Daniel Høyer Iversen
be552a59c9 Bug in rpi_camera 2016-12-14 18:45:05 +01:00
Paulus Schoutsen
832f9737a8 Fix hue groups on older hubs (#4884) 2016-12-13 23:46:27 -08:00
Paulus Schoutsen
da6bdf275e Update frontend 2016-12-13 23:30:08 -08:00
Marcelo Moreira de Mello
7ca025f653 Fixes issues #4844 to avoid traceback when self.rest.data is None (#4886)
6-12-09 18:12:30 homeassistant.core: Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 237, in _step
    result = next(coro)
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/homeassistant/helpers/entity_component.py", line 386, in _update_entity_states
    yield from update_coro
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/homeassistant/helpers/entity.py", line 240, in async_update_ha_state
    self._attr_setter('entity_picture', str, ATTR_ENTITY_PICTURE, attr)
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/homeassistant/helpers/entity.py", line 307, in _attr_setter
    value = getattr(self, name)
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/homeassistant/components/sensor/wunderground.py", line 176, in entity_picture
    url = self.rest.data['icon_url']
TypeError: 'NoneType' object is not subscriptable
2016-12-13 23:01:14 -08:00
Erik Eriksson
570cfc60c5 bugfix: is_on is a property (#4889) 2016-12-13 22:58:43 -08:00
Oliver
dc551b825f Added a volume set option and autodiscovery functions to Denon AVR rece… (#4845)
* Added Volume Set option and autodiscovery functions to Denon AVR receivers

* Corrected issues in SSDP discovery and in case no host could be discovered

* Corrected discovery handling / added denonavr to discovery platform

* No needless discoveries anymore / add_devices() with list instead of loop
2016-12-13 20:04:40 -08:00
Erik Eriksson
6da3e23436 Update __init__.py (#4877)
Cleaner exit by not throwing exception if server was not set during initialization of component (ref https://github.com/home-assistant/home-assistant/pull/4866)
2016-12-13 08:57:33 -08:00
Pascal Vizeli
e4b6395250 Migrate REST switch to async (#4517)
* Migrate REST switch to async

* Update rest.py

* Address comments from paulus
2016-12-13 08:55:13 -08:00
Audun Ytterdal
72bd9fb5c7 Remove libtelldus-core-dev from Dockerfile (#4878)
Remove unnecessary  libtelldus-core-dev from Dockerfile . Ref https://github.com/home-assistant/home-assistant/pull/4680#issuecomment-266006310
2016-12-13 08:53:42 -08:00
Pascal Vizeli
2dec38d8d4 TTS Component / Google speech platform (#4837)
* TTS Component / Google speech platform

* Change file backend handling / cache

* Use mimetype / rename Provider function / allow cache on service call

* Add a memcache for faster response

* Add demo platform

* First version of unittest

* Address comments

* improve error handling / address comments

* Add google unittest & check http response code

* Change url param handling

* add test for other language

* Change hash to sha256 for same hash on every os/hardware

* add unittest for receive demo data

* add test for error cases

* Test case load from file to mem over aiohttp server

* Use cache SpeechManager level, address other comments

* Add service for clear cache

* Update service.yaml

* add support for spliting google message
2016-12-12 23:23:08 -08:00
John Mihalic
acb841a1f4 Add Hikvision binary sensor component (#4825)
* Add Hikvision binary sensor component

* Simplify customize configuration

* Add delay attribute

* Remove use of threading timer, fix delay functionality
2016-12-12 23:10:16 -08:00
Paulus Schoutsen
eeb8bc3913 Fix dev tag detection in release script (#4873) 2016-12-12 22:18:20 -08:00
Erik Eriksson
12f790c7cf Display error message instead of exception (#4866)
* Display error message instead of exception

Display error message in log instead of stack trace.
(Usually happens when a server is already running at the same port.)

* Update __init__.py

Better error handling when reading SSL certificate

* Update __init__.py

* Update __init__.py
2016-12-12 22:02:24 -08:00
Erik Eriksson
dbb4e4c3fa [tellduslive] Upgrade requirement (#4865) 2016-12-12 20:05:38 +02:00
Paulus Schoutsen
d51e62d0a3 Merge pull request #4863 from home-assistant/master
Backmerge point releases
2016-12-11 22:51:30 -08:00
Paulus Schoutsen
ab92a91ac5 Merge branch 'dev' into master 2016-12-11 22:49:06 -08:00
Paulus Schoutsen
cfa36f3546 Merge pull request #4862 from home-assistant/release-0-34-5
0.34.5
2016-12-11 22:46:19 -08:00
Paulus Schoutsen
96d8fbe513 Version bump to 0.34.5 2016-12-11 22:26:48 -08:00
Paulus Schoutsen
1e9d91be0e Fix Plex from doing I/O inside event loop (#4857) 2016-12-11 22:26:30 -08:00
Paulus Schoutsen
2402897f47 Fix Nest doing I/O inside event loop (#4855) 2016-12-11 22:26:30 -08:00
Josh Nichols
b857d5dad0 Bump python-nest to fix issue with Nest Cam without activity zones (#4820)
* Bump python-nest to fix issue with Nest Cam without activity zones

* bump to include fix python-nest dependency with hvac_state

* regenerate requirements_all.txt
2016-12-11 22:26:30 -08:00
R1chardTM
d17753009a Fix python-nest version bump (#4799)
* Fix python-nest version bump

* Change SHA so version in HASS and dependency are the same
2016-12-11 22:26:30 -08:00
Marcelo Moreira de Mello
3467020dbf Added resolution support to Amcrest cameras (#4860)
* Added resolution support to Amcrest cameras

* Ordered alphabetically DEFAULT_ options
2016-12-11 21:46:19 -08:00
Adam Mills
4114884cdc Flic: Support use of queued events within timeout (#4822)
* Flic: Support use of queued events within timeout

* Linter fixes
2016-12-11 21:43:59 -08:00
John Mihalic
d7ccf07922 Add media position support and trailer type to Emby (#4792)
* Add media position support and trailer type to Emby

* Adjustments to mitigate TypeError

* Simplify media_position property

* Update handling when data isn't available

* Update emby.py
2016-12-11 21:43:53 -08:00
Erik Eriksson
2a7fa5afc3 Telldus Live: (#4645)
- Implemented support for covers and dimmable lights.
- Removed global object, use hass.data.
- Disabled polling via update.
- Inherit from common TelldusLiveEntity device.
- Configurable polling interval
- Use https API endpoint
- Use tellduslive package
2016-12-11 21:39:37 -08:00
Anton Lundin
04aa4e898a Improve denon media_player (#4836)
* Add debug level logging of messages in denon

* Added media stop for Denon AVR Media Player

* Sort source list

* Rework input selection for Denon AVR

This reworks the input selection, adding more modes and making it so
that the media controls are only announced in modes where they actually
makes sense.

* Added real media info for Denon AVR Media modes

* Read more configuration from denon devices

This reads network name, and overrides the local name with that.

This also reads the source names and reconfigures the input list to
those names, and also reads the source deleted list and removes the
inputs that are set to deleted in the device.

* Discover and handle max volume in Denon media player

* Rework source discovery in Denon media player

This uses SSFUN as authorative source for which sources that we should
present.
2016-12-11 21:04:36 -08:00
Michaël Arnauts
b156ae7812 Add support for Hue LightGroups (#4744)
* Add support for Hue LightGroup entity

* Don't filter on LightGroup and add properties for a group

* Reuse code from HueLight in HueLightGroup

* Remove HueLightGroup and add is_group variable to HueLight

* Make linter happy

* Update light or lightgroup state when a new state is available

* Use schedule_update_ha_state() to schedule the state update. Drop new_lightgroups and use new_lights instead.

* code style fix
2016-12-11 17:59:30 -08:00
David-Leon Pohl
48928d1f9e Fix config validation (#4853) (#4854) 2016-12-11 17:38:33 -08:00
Paulus Schoutsen
df98d5b3c1 Fix Nest doing I/O inside event loop (#4855) 2016-12-11 17:34:26 -08:00
Paulus Schoutsen
f4b5c439a1 Fix Plex from doing I/O inside event loop (#4857) 2016-12-11 17:34:13 -08:00
Jeff Wilson
ecc514b7e4 Use current mode to determine which temperature attributes to use (#4858) 2016-12-11 15:48:47 -08:00
IoTGuy
6edb54052f adding sensehat plugin (#4775)
* adding sensehat plugin

* added

* fix PR

* requirement updated

* Update sensehat.py
2016-12-11 15:46:55 -08:00
Marcelo Moreira de Mello
4d2480bbd1 Added support to language codes on Weather Underground (#4815)
* Added supported to language codes to Weather Underground

* Removed unecessary None assigments
2016-12-11 15:43:42 -08:00
Daniel Høyer Iversen
2708e193ec vlc media player (#4800)
* vlc media player

* Update vlc.py
2016-12-11 14:59:12 -08:00
Jean-Philippe Bouillot
c3923b2768 Netatmo improving Battery info (#4724)
* Improving Battery info

Improving battery status info (to reflect NetAtmo API documentation and change deprecated DeviceList for WeatherStationData

* Fixes from previous update

Fix the hound issue.
add battery_lvl, WindAngle_value, GustAngle_value, rf_status_lvl, wifi_status_lvl
2016-12-11 14:47:27 -08:00
devdelay
080c4efb00 Ecobee detect Smart Away (#4769)
* Ecobee autoAway Event

* Update ecobee.py

Checking if event['running'] true is pointless because if false event['type'] will equal template and when true type will only be 'hold' or 'autoAway' so I've removed this check from the statement
2016-12-11 14:46:10 -08:00
Pascal Vizeli
99f1ea9b59 Migrate alarm control panel to async (#4807)
* Merge alarm control panel to async

* fix lint
2016-12-11 14:39:20 -08:00
Johann Kellerman
46cad514d4 Revert "[device_tracker] Don't clear GPS coordinates when using two device trackers." (#4851) 2016-12-11 19:18:11 +02:00
Lewis Juggins
e0552ad899 [device_tracker] Don't clear GPS coordinates if no GPS seen (#4848) 2016-12-11 15:13:43 +02:00
Daniel Høyer Iversen
5c99dd0e3d Merge pull request #4846 from lwis/gpslogger
[device_tracker.gpslogger] Add additional activity attribute.
2016-12-11 11:07:55 +01:00
Lewis Juggins
cdf9464698 [device_tracker.gpslogger] Add additional activity attribute. 2016-12-11 09:06:29 +00:00
Stefan Jonasson
7ba25f3526 Fixed crash during light objects initizilation (#4835)
* Fixed crash when lights objects was inited
2016-12-11 09:54:50 +01:00
Daniel Høyer Iversen
ee5b9e7291 Configurable scan options for nmap (#4838) 2016-12-10 19:53:25 +02:00
r-jordan
167260bcc6 [climate.generic_thermostat] Make tolerance work both ways (#4830) 2016-12-10 10:36:35 +00:00
Josh Nichols
64de1c9777 Bump python-nest to fix issue with Nest Cam without activity zones (#4820)
* Bump python-nest to fix issue with Nest Cam without activity zones

* bump to include fix python-nest dependency with hvac_state

* regenerate requirements_all.txt
2016-12-09 11:04:40 -08:00
Sören Oldag
1547045f2c Flic: Support ignoring individual click types. (#4827) 2016-12-09 08:52:14 -08:00
Keaton Taylor
d02899216d Prevent emulated hue discovery by hue component (#4819)
* Prevent emulated hue discovery

Test for “HASS Bridge” in discovery info, pass if found, else try and
setup the bridge.

* Solved coding error

Duplicate commands and return false added for component.
2016-12-09 08:45:14 -08:00
Albert Lee
0aac4d64e1 Add away mode for Radio Thermostat/3M Filtrete (#4793) 2016-12-08 23:26:02 -08:00
Pascal Vizeli
0bf9e6d4bb Bugfix error on automation reload (#4823) 2016-12-08 23:24:03 -08:00
Jan Losinski
f78246e686 Pilight receive match fix for bug 4637 (#4639)
* Pilight: dont protocol as list in COMMAND_SCHEMA

As described in bug #4637 the protocol should not be wrapped in a list
in the spec of COMMAND_SCHEMA because this causes the component to
never successfully match any received rf code.

As pointed ot in PR #4639 the easiest way to do this, is to not derive
COMMAND_SCHEMA from RF_CODE_SCHEMA and specify protocol as simple
string there.

This fixes bug #4637.

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>

* Pilight: Add "unitcode" to command schema.

This adds "unitcode" to the COMMAND_SCHEMA. It is used for example in
the brennenstuhl protocol of pilight.

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>
2016-12-08 23:19:14 -08:00
Paulus Schoutsen
c90a1b9760 Update frontend 2016-12-08 22:31:32 -08:00
Lewis Juggins
14446c5731 [media_player.sonos] Add stop support. (#4788) 2016-12-08 08:36:37 +00:00
Albert Lee
2e2b764dbe Add exception handling when turning on Onkyo receivers (#4813) 2016-12-07 21:46:42 -08:00
R1chardTM
695f062e29 Fix python-nest version bump (#4799)
* Fix python-nest version bump

* Change SHA so version in HASS and dependency are the same
2016-12-07 21:45:43 -08:00
Keaton Taylor
194b268ae3 Get entity name from entity.name (#4798)
Grabbing the ATTR_FRIENDLY_NAME directly produces an error. Instead
grab from entity.name.
2016-12-07 21:45:18 -08:00
Pascal Vizeli
8295fc8b4c Pararell execute state restore by domain (#4801)
* Pararell execute state restore per domain

* fix spell
2016-12-07 08:37:35 -08:00
Jan Losinski
d0dcd1bb73 Scene: add support for input_select (#4674)
This adds support for the scene component to handle input_select
devices and set their options.

This fixes bug #4673

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>
2016-12-07 05:33:41 -08:00
Nolan Gilley
82ad8b0a8f round $ to 2 decimals (#4786) 2016-12-07 09:15:48 +01:00
Paulus Schoutsen
91a9da8f0c Merge pull request #4796 from home-assistant/release-0-34-4
0.34.4
2016-12-06 22:44:57 -08:00
Paulus Schoutsen
e3415c4e22 Version bump to 0.34.4 2016-12-06 22:35:43 -08:00
Paulus Schoutsen
9bca3f3103 Update after service calls (#4795)
* Update after service calls

* Service update: wrap async_update in create_task
2016-12-06 22:35:24 -08:00
Pascal Vizeli
7c3ae884df Migrate remote to async (#4678)
* Migrate remote to async

* add coro

* remove sync from init since only used in harmony

* import ATTR from remote

* remove unused sync stuff from tests
2016-12-06 22:35:24 -08:00
Adam Mills
8a4aace789 Fix incorrect caching of /api/error_log (#4789) 2016-12-06 22:35:24 -08:00
Josh Nichols
0e74cd833d Updated python-nest dependency (#4785)
* Updated python-nest dependency

This sha fixes two issues:

- min and max temperatures not being set when temperature isn't locked
- fixes error when setting farenheit with a .5

* gen requirements all

* Add fix for https://github.com/home-assistant/home-assistant/issues/4731
2016-12-06 22:35:24 -08:00
Paulus Schoutsen
5e2911f071 Fix Kodi auth (#4770) 2016-12-06 22:35:24 -08:00
Paulus Schoutsen
7dacc4a7bb Fix default auth influxdb (#4771) 2016-12-06 22:35:24 -08:00
Paulus Schoutsen
98fe50d5ad Update after service calls (#4795)
* Update after service calls

* Service update: wrap async_update in create_task
2016-12-06 22:30:47 -08:00
Paulus Schoutsen
37e3c2a133 Contributing: add skip step 0 2016-12-06 21:48:44 -08:00
Paulus Schoutsen
76b79019ce Add faster reviews link to contributing 2016-12-06 21:48:02 -08:00
Adam Mills
c40ddf18c7 Fix incorrect caching of /api/error_log (#4789) 2016-12-06 21:03:49 -08:00
Josh Nichols
9a3fe691b1 Updated python-nest dependency (#4785)
* Updated python-nest dependency

This sha fixes two issues:

- min and max temperatures not being set when temperature isn't locked
- fixes error when setting farenheit with a .5

* gen requirements all

* Add fix for https://github.com/home-assistant/home-assistant/issues/4731
2016-12-06 20:31:07 -08:00
Audun Ytterdal
8826e6a8d0 Add support for telldus in the Docker image. (#4680)
* Add support for telldus in the Docker image. Start with -v /tmp/TelldusClient:/tmp/TelldusClient -v /tmp/TelldusEvents:/tmp/TelldusEvents

* Merged telldus install with the others

* Clean up indenting

* Stream apt-key
2016-12-06 09:01:47 -08:00
Paulus Schoutsen
860a12cffb Fix Kodi auth (#4770) 2016-12-06 07:43:11 -08:00
Fabian Affolter
76ff934bd3 Move details to docs, update doc strings, and use consts (#4777) 2016-12-06 15:49:59 +01:00
Lewis Juggins
d968e1d011 Add test to ensure device_tracker records state correctly. (#4776) 2016-12-06 15:01:24 +02:00
Paulus Schoutsen
fa0dbaf065 Fix default auth influxdb (#4771) 2016-12-05 23:39:22 -08:00
Paulus Schoutsen
4d0f19496a Merge remote-tracking branch 'origin/master' into dev 2016-12-05 23:35:36 -08:00
Paulus Schoutsen
0cc9555d14 Merge pull request #4774 from home-assistant/release-0-34-3
0.34.3
2016-12-05 23:35:09 -08:00
Paulus Schoutsen
d712a3dc38 Version bump to 0.34.3 2016-12-05 22:42:55 -08:00
rubund
84446bed14 Fix broken EnOcean support (#4710)
* ensure_list

* CONF_ID is not required configuration for enocean lights

* Use vol.All(cv.ensure_list, [vol.Coerce(int)]) as suggested in pull request review

* Fix line too long
2016-12-05 22:42:32 -08:00
Jeff Wilson
e92b15f966 Set hue-bridgeid in UPNP response (#4740) 2016-12-05 22:42:23 -08:00
Paulus Schoutsen
a458ce8069 Fix websocket async (#4752)
* Ensure we write to websocket from inside event loop

* Inline service call helper
2016-12-05 22:42:13 -08:00
dasos
5e492db9a3 Fix connection check (#4732)
* Fix connection check

* Release instead

* Remove if

* Update hook.py
2016-12-05 22:42:02 -08:00
Albert Lee
bc646070c8 Match uppercase MAC addresses in asuswrt 'arp -n' output (#4742) (#4764) 2016-12-05 22:20:21 -08:00
Paulus Schoutsen
64290d74f0 Update frontend 2016-12-05 21:40:45 -08:00
dasos
a11b68c560 Fix connection check (#4732)
* Fix connection check

* Release instead

* Remove if

* Update hook.py
2016-12-05 21:37:05 -08:00
Caleb
8ca2345fd4 Pyunifi dep (#4754)
* change unifi dependency to pyunifi

* Change dependency to fix #4336

* Run gen_requirements_all.py script

* Changed import statement to reflect new package

* Updated test_unifiy.py with different module

* Update requirements_all.txt
2016-12-05 21:35:54 -08:00
Hugo Dupras
8c628071f3 Add support for Netatmo tags (#4761)
* Add support for Netatmo Welcome Tags

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Add size parameter for WelcomeData

* minor fixes

* Add Throttling mechanism for update event

This will prevent to reach the API limit

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Change scan interval for Netatmo Binary sensors

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Minor fixes

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Update netatmo.py
2016-12-05 21:35:33 -08:00
Sören Oldag
81d38c3463 Add flic smart button component (#4681)
* Added component for flic smart buttons.

* Apply home-assistant coding styles.

* Fixed flic configuration.

* Made logging for scanning for new buttons less verbose.

* Fixed flic event data.

* Follow async conventions.

* Added new requirements to requirements_all.txt.

* Added flic component to .coveragerc

* Updated flic threshold configuration key names.

* Flic devices are now removed when they disconnect.

* Include review feedback.

* Fixed stopping of clients in flic component when home assistant is stopped.

* Updated flic component by integrating input of #4738.

Use library method to determine click type. Merge three click events into single one with click_type parameter.

* Use a single client for both handling click events and scanning for new buttons.

* Renamed flic ‘auto_scan’ configuration variable to ‘discovery’ using HA constants.
2016-12-05 21:12:24 -08:00
Adam Mills
776455030f Fix media_image_urls for universal media player (#4765)
* Fix media_image_urls for universal media player

* Linter fixes
2016-12-05 18:07:04 -08:00
Daniel Høyer Iversen
8afd30b7d4 fix setting battery in device_tracker (#4756) 2016-12-05 18:04:04 -08:00
Paulus Schoutsen
b60f5714fc Fix websocket async (#4752)
* Ensure we write to websocket from inside event loop

* Inline service call helper
2016-12-05 18:03:06 -08:00
John Arild Berentsen
fa8bc0a36c Add Verisure smartcam capture service (#4559)
* Add verisure capture as service

* docstyle
2016-12-05 17:51:58 -08:00
Martin J. Laubach
1ae8256ffd Add sensor for reading Austrian ZAMG weather conditions (#4347)
* Add sensor for reading ZAMG weather conditions

* Add to coveragerc; Correct some doc style problems

* More doc fixes

* More doc fixes

* Lose license and whatever.

* Don't return UNKNOWN for unknown variables

* Verify that the configured station id is actually one in the data set.

Don't warn about unknown stations, this cannot happen any more as the configuration parser now checks that.
This could still happen if the data set is incomplete though ...

* Clean up imports

* Clarify comment on throttling interval

* Base zamg sensor on Entity, not WeatherEntity, and delete unused code

* Fix formatting nits from flake8

* Use ATTR_FRIENDLY_NAME, clean up imports, remove unnecessary indirection.

* Use {}.format() instead of "" %

* Re-add unit of measurement that got lost somehow

* Use guard clauses instead of if-matroshka.
Wrap requests.get() in try/except for RequestException.

* Huh, how did this happen? White space corrections...

* Add sensor for reading ZAMG weather conditions

* Add to coveragerc; Correct some doc style problems

* More doc fixes

* More doc fixes

* Verify that the configured station id is actually one in the data set.

Don't warn about unknown stations, this cannot happen any more as the configuration parser now checks that.
This could still happen if the data set is incomplete though ...

* Lose license and whatever.

* Don't return UNKNOWN for unknown variables

* Clean up imports

* Clarify comment on throttling interval

* Base zamg sensor on Entity, not WeatherEntity, and delete unused code

* Fix formatting nits from flake8

* Use ATTR_FRIENDLY_NAME, clean up imports, remove unnecessary indirection.

* Use {}.format() instead of "" %

* Re-add unit of measurement that got lost somehow

* Use guard clauses instead of if-matroshka.
Wrap requests.get() in try/except for RequestException.

* Huh, how did this happen? White space corrections...

* Precipitation actually is a float, good it rained today

* Logger needs no module visibility

* Do not name sensors with _ to be in line with the other weather sensor platforms.

* Remove manually set friendly_name

* comment format police

* Less comments

* Update zamg.py
2016-12-05 17:50:50 -08:00
Jeff Wilson
b3253403aa Set hue-bridgeid in UPNP response (#4740) 2016-12-05 17:39:40 -08:00
Daniel Høyer Iversen
308744d8a0 Add additional attributes to GPSLogger (#4755) 2016-12-05 19:33:51 +00:00
Paulus Schoutsen
13006cee68 Device tracker attributes (#4753) 2016-12-05 19:32:17 +00:00
rubund
e21382cd3e Fix broken EnOcean support (#4710)
* ensure_list

* CONF_ID is not required configuration for enocean lights

* Use vol.All(cv.ensure_list, [vol.Coerce(int)]) as suggested in pull request review

* Fix line too long
2016-12-05 08:15:36 -08:00
Daniel Høyer Iversen
71fc446425 Merge pull request #4719 from home-assistant/device_tracker
device tracker
2016-12-05 16:32:29 +01:00
Fabian Affolter
03d19ec2f1 Netdata sensor (#4743)
* Added netdata sensor

* Typo

* Add netdata sensor

* Improvement of the work done by @ezar
2016-12-05 11:19:20 +01:00
Daniel Hoyer Iversen
5a7e446646 device tracker 2016-12-05 09:12:13 +01:00
Paulus Schoutsen
2b3caa716a Cast progress (#4735)
* add progress to google cast

* Add progress to media player demo
2016-12-04 15:30:55 -08:00
Paulus Schoutsen
6574dd8439 Merge branch 'release-0-34-2' into dev 2016-12-04 15:20:48 -08:00
Paulus Schoutsen
6d56519297 Merge pull request #4736 from home-assistant/release-0-34-2
0.34.2
2016-12-04 15:19:56 -08:00
Paulus Schoutsen
60bcb12a48 Version bump to 0.34.2 2016-12-04 15:08:38 -08:00
Lukas
58509f8bba [0.34] bugfix influxdb node_id (#4712)
* Bugfix for #4709 - do not convert node_id to float

* Update influxdb.py
2016-12-04 15:08:25 -08:00
Lukas
2099d023ef [0.34] bugfix influxdb node_id (#4712)
* Bugfix for #4709 - do not convert node_id to float

* Update influxdb.py
2016-12-04 15:08:14 -08:00
Paulus Schoutsen
db6a6fa4cb Lint 2016-12-04 14:45:25 -08:00
Josh Nichols
d89bfcdaa5 Make sure all nest platforms require discovery info (#4734) 2016-12-04 14:34:01 -08:00
Josh Nichols
64b1179c13 Make sure all nest platforms require discovery info (#4734) 2016-12-04 14:33:50 -08:00
Paulus Schoutsen
840e27adec Fix Nest interpreting Celsius temperature as Fahrenheit (#4729) 2016-12-04 14:32:59 -08:00
Paulus Schoutsen
31a8537ab5 Update frontend 2016-12-04 14:32:43 -08:00
Paulus Schoutsen
87dab37b8a Fix Nest interpreting Celsius temperature as Fahrenheit (#4729) 2016-12-04 13:49:46 -08:00
Paulus Schoutsen
3a2cdd3de0 Merge pull request #4728 from home-assistant/release-0-34-1
0.34.1
2016-12-04 11:18:46 -08:00
Paulus Schoutsen
2009e98497 Version bump to 0.34.1 2016-12-04 11:03:16 -08:00
Paulus Schoutsen
b354a18bf3 Fix CORS when static resources registered (#4727) 2016-12-04 11:02:33 -08:00
hexa-
1cd3cd8d77 Revert "Update reference to correct tplink switch" (#4722) 2016-12-04 11:02:33 -08:00
Pascal Vizeli
d9556392bc Protect hm thread for hangs on events (#4717) 2016-12-04 11:02:33 -08:00
Paulus Schoutsen
695fb412cd Re-org emulated_hue and fix google home (#4708) 2016-12-04 11:02:33 -08:00
Josh Nichols
93322b0251 Updated python-nest to fix a camera bug when loading images (#4701) 2016-12-04 11:02:33 -08:00
Paulus Schoutsen
9b9b625ac4 Fix synology dsm doing I/O inside loop (#4699) 2016-12-04 11:02:33 -08:00
Pascal Vizeli
0ae6585a90 Bugfix sonos hosts (#4698) 2016-12-04 11:02:33 -08:00
Paulus Schoutsen
cffc7ac4d8 Update netdisco to 0.8 (#4723) 2016-12-04 10:59:18 -08:00
Paulus Schoutsen
a9be6c36f1 Re-org emulated_hue and fix google home (#4708) 2016-12-04 10:57:48 -08:00
Paulus Schoutsen
1b35f0878e Fix CORS when static resources registered (#4727) 2016-12-04 10:57:24 -08:00
Paulus Schoutsen
93872590b6 Fix synology dsm doing I/O inside loop (#4699) 2016-12-04 09:54:49 -08:00
Paulus Schoutsen
b2a15e17d3 MQTT Automation: parse payload as JSON (#4703) 2016-12-04 09:53:05 -08:00
Johan Bloemberg
9bf13231f7 Actually test calling async macvendor lookup and fix it. (#4718) 2016-12-04 09:51:40 -08:00
hexa-
c8c6bee539 Revert "Update reference to correct tplink switch" (#4722) 2016-12-04 09:50:43 -08:00
Pascal Vizeli
b5c2be8ffa Protect hm thread for hangs on events (#4717) 2016-12-04 15:31:24 +01:00
DaveSergeant
4d35f2805f New support Digital Loggers relays (#4684)
* initial commit

Previous work included with no history.  Sorry, I was figuring out how to use git, branches and deal with open source projects.  At this point this is a working switch but with the shortcomings of each of the 8 ports causes a network query.  This needs to be rewritten so that the SwitchDevice is part of a larger device group that is only queried once, saving traffic and preventing the small device from timing out.

* Device polls independent of switches now

Used anel_pwrctrl.py as a basis to extract the per-switch polling out to per-device so it can be trottled properly.  Likewise, no longer touching the device independently for relay status AND relay name.  Getting them both from the same statuslist() return.

* Final comments and tweaks

Lowered cycle and update time since the device update is working so well now.  Effectively no timeouts anymore.

* Added dlipower to requirements

homeassistant.components.switch.digitalloggers

* Tox fixes

pydocstyle updates

* More tox errors

* Yet more tox

Removed useful future TODO and helpful details on the structure of the statuslocal list.
Good catch on not initializing .update(), though it worked.

* Blank line fix

* Added file to .coveragerc
2016-12-03 23:40:22 -08:00
Marcelo Moreira de Mello
53c1b93b61 Added persistent_notification in case of error during Unifi device_tracker setup (#4682) 2016-12-03 22:11:52 -08:00
Thibault Cohen
c25aa56751 Add Sharp AquosTV component (#4679) 2016-12-03 22:09:49 -08:00
Pascal Vizeli
e8c9dcf0fe Migrate remote to async (#4678)
* Migrate remote to async

* add coro

* remove sync from init since only used in harmony

* import ATTR from remote

* remove unused sync stuff from tests
2016-12-03 22:08:24 -08:00
William Scanlon
ca63e44227 Wink hub sensor (#4704) 2016-12-03 21:39:48 -08:00
Johan Bloemberg
776e53a7f0 Dsmr hourly gas usage. (#4609)
* Hourly rate of Gas consumption. Use proper unknown state.

* Import unknown state constant.

* doh

* Cleanup device add.

* Fix lint.

* Add test for derivative calculation.

* Remove conflict.

* Document and move calculation into update call.
2016-12-03 20:45:42 -08:00
Dan
a099430834 Universal source list (#4086)
* Add source_list to universal media player

* Expanded attirubte and command support for UMP

Added support to the universal media player
for the following:
    Volume Set
    Current Source
    Set Source
    Current Volume

The goal is to facilitate a single-card media player
that includes source selection and setting the volume
of the receiver.

Example setup:
```
media_player:
  - platform: universal
    name: Media Center
    children:
      - media_player.kodi
      - media_player.cast
    commands:
      select_source:
        service: media_player.select_source
        data:
          entity_id: media_player.receiver
      volume_set:
        service: media_player.volume_set
        data:
          entity_id: media_player.receiver
      volume_mute:
        service: media_player.volume_mute
        data:
          entity_id: media_player.receiver
      turn_on:
        service: homeassistant.turn_on
        data:
          entity_id: media_player.receiver
      turn_off:
        service: homeassistant.turn_off
        data:
          entity_id: media_player.receiver
    attributes:
      state: media_player.receiver
      is_volume_muted: media_player.receiver|is_volume_muted
      volume_level: media_player.receiver|volume_level
      source: media_player.receiver|source
      source_list: media_player.receiver|source_list
```

* Remove print statements

* Change service call back to use call_from_config

* Modified service calls to use template data

* linting fixes

* Add tests

* linting fices

* More pylinting
2016-12-03 20:09:28 -08:00
Pascal Vizeli
7746ecd98e Migrate weather to async (#4677) 2016-12-03 17:58:43 -08:00
Josh Nichols
10d1496f5a Updated python-nest to fix a camera bug when loading images (#4701) 2016-12-03 17:55:14 -08:00
Sebastian von Minckwitz
cf0ff54d14 Add option to hide the group card switch (#4631)
* Add option to hide the group card switch

* Disallow control of hidden group switches

* Revert "Disallow control of hidden group switches"

This reverts commit 75e5ddfe30.

* Changed hide_switch to control
2016-12-03 17:50:11 -08:00
Magnus Ihse Bursie
97cc76b43e Remove global variable from tellstick code (#4700)
* Refactor tellstick code for increased readability. Especially highlight if "device" is a telldus core device or a HA entity.

* Refactor Tellstick object model for increased clarity.

* Update comments. Unify better with sensors. Fix typo bug. Add debug logging.

* Refactor tellstick code for increased readability. Especially highlight if "device" is a telldus core device or a HA entity.

* Refactor Tellstick object model for increased clarity.

* Update comments. Unify better with sensors. Fix typo bug. Add debug logging.

* Fix lint issues.

* Remove global variable according to hint from balloob.
2016-12-03 17:27:55 -08:00
Jacob Minnis
c89e6ec915 Updated email message headers to have 'Date' and 'Message-Id' fields (#4693) (#4695) 2016-12-03 16:56:42 -08:00
Pascal Vizeli
efdf51b542 Bugfix sonos hosts (#4698) 2016-12-04 00:31:27 +01:00
Paulus Schoutsen
bbb251c0cf Version bump to 0.35.0dev0 2016-12-03 12:17:16 -08:00
Paulus Schoutsen
94b719e150 Merge pull request #4626 from home-assistant/dev
0.34
2016-12-03 12:17:02 -08:00
Paulus Schoutsen
69d3a3dd32 Version bump to 0.34 2016-12-03 12:16:18 -08:00
Paulus Schoutsen
4904653b70 Yarl has been fixed (#4694) 2016-12-03 11:59:05 -08:00
Fabian Affolter
dddf4d1460 Style 0.34 (#4689)
* Minor style updates

* Minor style updates

* Update validation and logger messages

* Update ordering

* Fix lint issue

* Fix line too long

* Update ordering

* update logger messages
2016-12-03 20:46:04 +01:00
GadgetReactor
9a6c9cff30 Update reference to correct tplink switch (#4670) 2016-12-03 11:38:14 -08:00
Paulus Schoutsen
d3b62e1fe1 Requirements use zip instead of git (#4692) 2016-12-03 10:18:00 -08:00
Paulus Schoutsen
f63a79ee8f Remove not dev related scripts (#4690) 2016-12-03 09:59:20 -08:00
Paulus Schoutsen
898ba56d9f Fix aiohttp build (#4691) 2016-12-03 09:49:10 -08:00
Josh Nichols
64a5bff5b2 Nest further improvements (#4655)
* Further improvements on nest platform

- fix binary sensor
- add deprecations for monitored_conditions
- better names for sensors (includes device type)

* lint

* Remove unused weather sensor

* Fix to python-nest to a specific commit

* lint

* lint

* lint

* lint
2016-12-03 09:26:47 -08:00
Paulus Schoutsen
af7de8d5ae Merge remote-tracking branch 'origin/master' into dev 2016-12-03 09:11:47 -08:00
Pascal Vizeli
754d98bcd5 Cleanups on homematic climate (#4685) 2016-12-03 14:06:08 +01:00
Paulus Schoutsen
4874030b70 Have api_streams sensor also monitor websocket connections (#4668) 2016-12-02 18:17:46 -08:00
Paulus Schoutsen
84c89686a9 Update __init__.py 2016-12-02 09:13:39 -08:00
Brent Hughes
48fd8f1f63 InfluxDB: Fixed attributes that are lists causing invalid syntax (#4642)
* Fixed attributes that are lists cuasing invalid influx syntax

* Added bool and fixed mixed data type issue

* Fixed changing nearly all data types to float causing some worse influxdb errors. whoops

* Added line to end of file
2016-12-01 23:02:58 -08:00
Lewis Juggins
83a108b20a Sonos specify IP for event subscription (#4177) 2016-12-01 22:22:03 -08:00
Alberto Arias Maestro
b0a800cc6d Update commands to match the strings in pynx584 (#4623)
The command string don't match the ones pynx584. See source code:

https://github.com/kk7ds/pynx584/blob/master/nx584/api.py#L68
2016-12-01 22:20:44 -08:00
Matt N
1f5f4e7a89 zoneminder: Support excluding archived events (#4445) 2016-12-01 22:17:38 -08:00
Fabian Affolter
b1fbada02d Update throttle and add more attributes (#4644) 2016-12-01 22:15:48 -08:00
Lewis Juggins
08909ed420 (InfluxDB) Configuration for a default measurement value for events without a unit. (#4632) 2016-12-01 22:13:55 -08:00
Nick Touran
ec8969351d Prevent Pandora component from crashing or hanging during shutdown. (#4255)
* Prevent Pandora component from crashing or hanging during shutdown.

* Update pandora.py

* Update pandora.py
2016-12-01 22:06:23 -08:00
Javier González Calleja
801a69be3a Extending efergy component for get the amount of energy consumed (#4202)
* Extending efergy component for get the amount of energy consumed

* Changing units from kW to kWh

* Chaning units for Instant Consumption from kWh to kW

* Adding timeout for get and removing pylint config

* Update efergy.py
2016-12-01 22:00:17 -08:00
Fabian Affolter
51e20c92f9 WIP Fix pylint and PEP257 issues (tests) (#4120)
* Fix pylint and PEP257 issues

* More PEP257 fixes
2016-12-01 21:45:19 -08:00
Russell Cloran
443553ff16 Handle IPv6 in zeroconf (#4052) 2016-12-01 21:43:33 -08:00
Pascal Vizeli
2e6a48ff5f WIP: Migrate scene to async + homeassistant scene async (#4665)
* Migrate scene to async + homeassistant scene async

* fix lint

* Update state.py

* Fix tests
2016-12-01 21:38:12 -08:00
Paulus Schoutsen
49cfe38cca Demo platform to group climate instead of thermostat 2016-12-01 21:11:13 -08:00
Pascal Vizeli
8a042586f1 Migrate sensor to async (#4663) 2016-12-01 18:31:55 -08:00
Johan Bloemberg
08f8e540e3 Macvendor (#4468)
* Add MAC vendor lookup for device_tracker.

* Test vendor mac lookup and fix device attribute.

* Generate requirements.

* Style.

* Use hyphen instead of underscore to satisfy 'idna'.

https://github.com/kjd/idna/issues/17

* Resort imports.

* Refactor macvendor to use macvendors.com API instead of netaddr library.

* Test vendor lookup using macvendors.com api.

* Remove debugging.

* Correct description.

* No longer needed.

* Device tracker is now an async component. Fix ddwrt tests.

* Fix linting.

* Add test case for error conditions.

* There is no reason to retry failes vendor loopups as they won't be saved to the file anyways at that point.

* Sorry, bad assumption, this only made things worse.

* Wait for async parts during setup component to complete before asserting results.

* Fix linting.

* Is generated when running 'coverage html'.

* Undo isort.

* Make aioclient_mock exception more generic.

* Only lookup mac vendor string with adding new device to known_devices.yaml.

* Undo isort.

* Revert unneeded change.

* Adjust to use new websession pattern.

* Always make sure to cleanup response.

* Use correct function to release response.

* Fix tests.
2016-12-01 18:30:41 -08:00
Brandon Weeks
f09b888a8a Fixes #3511 - handle multiple return values (#4659) 2016-12-01 18:28:52 -08:00
lichtteil
279f82acc4 Mutate values for light color temperature and white value (#4660)
* Mutate values for light color temperature and white value

* Fix lenght of line

* Fix under-indented line

* Fix cgl
2016-12-01 18:26:53 -08:00
iandday
de6c5a503b Remote Component and Harmony Platform (#4254)
* Initial Harmony device support, working current activity sensor and switch for each activity
TODO: add new device per hub to send device specific activity

 Changes to be committed:
	new file:   homeassistant/components/harmony.py
	new file:   homeassistant/components/sensor/harmony.py
	new file:   homeassistant/components/switch/harmony.py

* ready for beta, I think

 Changes to be committed:
	modified:   homeassistant/components/harmony.py
	modified:   homeassistant/components/sensor/harmony.py
	modified:   homeassistant/components/switch/harmony.py

*  Changes to be committed:
	modified:   homeassistant/components/harmony.py
	new file:   homeassistant/components/remote/__init__.py
	new file:   homeassistant/components/remote/harmony.py
	new file:   homeassistant/components/remote/services.yaml
	modified:   homeassistant/components/sensor/harmony.py
	modified:   homeassistant/components/switch/harmony.py
Implemented remote component and harmony platform

* streamlined harmony support

* typo

* Initial Harmony device support, working current activity sensor and switch for each activity
TODO: add new device per hub to send device specific activity

 Changes to be committed:
	new file:   homeassistant/components/harmony.py
	new file:   homeassistant/components/sensor/harmony.py
	new file:   homeassistant/components/switch/harmony.py

* ready for beta, I think

 Changes to be committed:
	modified:   homeassistant/components/harmony.py
	modified:   homeassistant/components/sensor/harmony.py
	modified:   homeassistant/components/switch/harmony.py

*  Changes to be committed:
	modified:   homeassistant/components/harmony.py
	new file:   homeassistant/components/remote/__init__.py
	new file:   homeassistant/components/remote/harmony.py
	new file:   homeassistant/components/remote/services.yaml
	modified:   homeassistant/components/sensor/harmony.py
	modified:   homeassistant/components/switch/harmony.py
Implemented remote component and harmony platform

* streamlined harmony support

* typo

* reworked token generation

* delete

* Initial Harmony device support, working current activity sensor and switch for each activity
TODO: add new device per hub to send device specific activity

 Changes to be committed:
	new file:   homeassistant/components/harmony.py
	new file:   homeassistant/components/sensor/harmony.py
	new file:   homeassistant/components/switch/harmony.py

* Initial Harmony device support, working current activity sensor and switch for each activity
TODO: add new device per hub to send device specific activity

 Changes to be committed:
	new file:   homeassistant/components/harmony.py
	new file:   homeassistant/components/sensor/harmony.py
	new file:   homeassistant/components/switch/harmony.py

* ready for beta, I think

 Changes to be committed:
	modified:   homeassistant/components/harmony.py
	modified:   homeassistant/components/sensor/harmony.py
	modified:   homeassistant/components/switch/harmony.py

* ready for beta, I think

 Changes to be committed:
	modified:   homeassistant/components/harmony.py
	modified:   homeassistant/components/sensor/harmony.py
	modified:   homeassistant/components/switch/harmony.py

*  Changes to be committed:
	modified:   homeassistant/components/harmony.py
	new file:   homeassistant/components/remote/__init__.py
	new file:   homeassistant/components/remote/harmony.py
	new file:   homeassistant/components/remote/services.yaml
	modified:   homeassistant/components/sensor/harmony.py
	modified:   homeassistant/components/switch/harmony.py
Implemented remote component and harmony platform

* streamlined harmony support

* typo

* reworked token generation

* delete

* readded after rebase

* cleaning up style errors

* modified .coveragerc

* moved import statements

* added more debug logging

* Added URL encoding of token received from Logitech

* Corrected import for python 3

* new pyharmony version

* new pyharmony version

* remote tests

* only write config file if not present or sync service is called

* more tests

* more tests

* bumped pyharmony version to work with new auth

* bumped pyharmony version to work with new auth

* style corrections

* harmony local auth and remote demo platform

* style fix

* PR refinements and permission issues

* forgot a blank line

* removed sync test from test_init

* removed sync test from test_init

* visual indent

* send_command test in demo platform
2016-12-01 12:48:08 -08:00
Jesse Newland
898f89ffc7 Make trusted_networks iterable (#4649) 2016-12-01 12:28:59 -08:00
Jan Losinski
5c807c6bd9 MPD: Reconnect mpd client afetr OSError (#4651)
If the mpd client ran into an socket timeout, the socket will raise an
OSError on every further request. This adds OSError to the list of
excptions, that causes a client reconnect.

This fixes #4650

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>
2016-12-01 12:28:31 -08:00
Jan Losinski
dd84b4e237 Mpd: Use "file" instead "id" for media_content_id (#4653)
In media_content_id() the "id" of the current song was returned. as
stated in bug #4652 the id is only the Tracklist-Id in the current
tracklist and is omitted if the track is not part of a tracklist (what
caused the bug in the first place).

To match the semantics described in the dockstring, to return a "Content
ID", this chooses the filename of the current song as id and returns
it.

It also uses get() instead of [] to prevent KeyError.

This fixes bug #4652

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>
2016-12-01 12:20:42 -08:00
John Mihalic
6dfae7a259 Add support for NUT (Network UPS Tools) sensor. (#4551)
* Add support for NUT (Network UPS Tools) sensor.

* Address comments

* Fix issues

* Fix issues 2

* Fix unhandled exception
2016-12-01 08:58:16 +01:00
Johann Kellerman
c6c8cd4f51 Yr.no: New aiohttp client needs params to form websession URL (#4634)
* Yr.no: New aiohttp client needs params to form websession URL
* Support params in aiohttp mocking
2016-12-01 08:20:21 +02:00
Pascal Vizeli
bde7176b3c Migrate light component to async (#4635) 2016-11-30 13:33:38 -08:00
William Scanlon
4c03d670c1 Wink PubNub v4 (#4561)
* PubNub v4

* Updated to pubnubsub-handler 0.0.5

* Updated requirements_all.txt
2016-11-30 13:12:26 -08:00
Johan Bloemberg
406afbb369 Philips controls (#4441)
* Add channel switching for philips tvs.

* Disable track buttons when not watching tv.

* Undo isort config.

* Yes it does.

* Just testing some assumption on hound's flake8 behaviour.

* Revert "Just testing some assumption on hound's flake8 behaviour."

This reverts commit ff9940b39e.

* poke
2016-11-30 13:07:57 -08:00
Marcelo Moreira de Mello
9c6609cb79 Added support to Amcrest camera (#4573)
* Introduced support to Amcrest IP Cameras

* Fixed lint issues

* Fixed requirements test

* * Implemented test to verify crendentials during camera setup

* Added persistent_notification in case of error when during Amcrest setup
2016-11-30 13:07:17 -08:00
Paulus Schoutsen
e5504b39ec Close aiohttp responses (#4624)
* Close aiohttp responses

* Update generic.py
2016-11-30 13:05:58 -08:00
Paulus Schoutsen
b1ef5042f9 Make updater more robust (#4625) 2016-11-30 13:03:09 -08:00
Paulus Schoutsen
b35fa4f1c1 Finish all tasks before setup phase is done (#4606) 2016-11-30 13:02:45 -08:00
Martin Hjelmare
71da9d2f50 Fix mysensors ir switch overwriting devices (#4612) 2016-11-30 13:02:18 -08:00
Fabian Affolter
86388f5af2 Upgrade Sphinx to 1.4.9 (#4641) 2016-11-30 14:21:00 +01:00
Pascal Vizeli
17f0fb69bd Homematic update with HomematicIP/HomematicWired support and multible… (#4568)
* Homematic update with HomematicIP/HomematicWired support and multible connections

* fix bug in virtualkey service

* create new service & cleanups

* fix lint

* Pump pyhomematic 0.1.18
2016-11-29 20:53:02 +01:00
DaveSergeant
2d02baf3d0 Default dimmable brightness to 255 from 100 (#4621)
* Default dimmable brightness to 255 from 100

Full brightness for ISY dimmers is 255. The current 100 value turns dimmer switches on to just under half brightness.  Probably just an oversight from the Sept implementation.

* Brightness change for turn_on, ramp for turn_off.

Per discussion with Teagan42 and jbcodemonkey, the brightness should rightfully be None and not an explicit value.  There is a continuing issue that the ISY modules don't respect HA's brightness customization values.  A new issue will be opened for this.
Additionally, turn_off was using ISY's fastoff() which didn't respect the ramping time.  The default behavior should just be off().
2016-11-29 09:50:12 -07:00
Lewis Juggins
66473120ab Add test for delay on automations (#4630) 2016-11-29 08:45:04 -08:00
Christian Brædstrup
6ddbb4d568 Improved exception handling for D-Link switch (#4633) 2016-11-29 08:40:51 -08:00
Valentin Alexeev
154c69a454 Bump version of pwaqi module to 1.3. Fixes #4595. (#4610) 2016-11-28 23:11:21 -08:00
Charles Spirakis
ad4ec49f9c Update color names to follow w3.org list. (#4374)
The color names -> rgb dictionary now follows the
color names listed in the w3.org site for css3,
section 4.3. Extended color keywords:

https://www.w3.org/TR/2010/PR-css3-color-20101028/#svg-color
2016-11-28 22:59:46 -08:00
Fabian Affolter
e8367f245a Update ordering and sync logger messages (#4615) 2016-11-28 20:50:42 +01:00
Fabian Affolter
4bc37bd661 Add timeout to request, update ordering, make dev info message shorter, and (#4613)
update the other logger messages
2016-11-28 20:49:01 +01:00
Pascal Vizeli
b4841a17a6 Hotfix device_tracker yaml config (#4611) 2016-11-28 18:43:47 +01:00
Valentin Alexeev
3b9d5cdf73 DuneHD media player (#4588)
* Implement WAQI sensor

* Corrections based on CI check.

* Updated requirements_all.txt for pwaqi==1.2

* Require latest version of pwaqi

* Initial implementation of DuneHD media player component based on pdunehd.

* Major: avoid update() in property fetch,
Major: implement source support,
Major: single device per media player instance,
Major: support for volume / mute controls

* Pythonify pdunehd.
Support media_title.

* Fix pylint.

* Further pylint.

* docstring

* Formatting and indentation.

* Change indentation to spaces.

* Update coverage and recorded requirements before PR.

* Further pylint / fake8 / pydocstyle fixes.

* Implement next / prev track,
Properly decode blu-ray playback,
Attempt to decode media title

* Fix play / pause
Linting

* Update requirements.
Fix lint.

* Fix lint and syntax error

* Yet more linting.

* Yet more linting.

* Fix lint: line too long.

* Force update of HA state.
2016-11-27 23:42:57 -08:00
Daniel Perna
77d568dc47 Fixed incorrect event-order (#4605) 2016-11-27 22:29:21 -08:00
Paulus Schoutsen
9db1ff8cd4 Update frontend 2016-11-27 22:27:02 -08:00
Oliver
248a90b71d Added denon media player controls via denonavr library (#4580)
* Added denonavr module again

* Edited requirements_all.txt

* Edited .coveragerc

* Fixed error with AUX1 input source in library

* Adding device should not fail on connection timeout

* Changed method to select source

* Update requirements_all.txt
2016-11-27 22:13:22 -08:00
Mark King
d8c4af9c81 TEMPer component: reset devices on address change (#4596)
Fixes https://github.com/home-assistant/home-assistant/issues/4389

The USB address of these devices periodically changes, causing
home-assistant to fail to read the temperature data. This PR fixes this
by re-reading the available devices on failure. I've been running this
for several days and for the first time have consistent temperature
data without having to restart home-assistant.
2016-11-27 22:01:13 -08:00
Fabian Affolter
1e6c660f59 Threshold sensor (#4216)
* Add threshold sensor

* New config requirement, update async, other changes, and update tests

* Update threshold.py
2016-11-27 21:55:26 -08:00
Harris Borawski
44a508e86c Add exception handling to Sonarr (#4569)
* Add exception handling to request call to prevent
failure in setup_platform if host is down

* update for comments

* update test for state being none

* remove unused import
2016-11-27 21:11:49 -08:00
Bjarni Ivarsson
92c6cee2a1 Support for media_position property on media_player (#4172)
* Added support for media_position property to media_player + implementation for sonos.

* Pla yback progress now updates without needed state transitions in HA.

* Linting fixes

* media_position_update_at property is now a datetime.

* Minor fix.

* Linting fixes.
2016-11-27 17:45:49 -08:00
Paulus Schoutsen
d4bc8e23af Update frontend 2016-11-27 17:21:11 -08:00
Antoine Bertin
f0db698f75 Light effects (#4538)
* Add support for light effects

* Move PLATFORM_SCHEMA changes in light to mqtt_template

* Add effect validation

* Add unittests

* Add light effect to demo and unittests

* Use cv.string for config validation

* Use cv.ensure_list for config validation

* Fix typo

* Remove unused exception management for effect
2016-11-27 17:15:28 -08:00
Pascal Vizeli
cf57db919e Refactory aiohttp clientsession handling in HA (#4602)
* Refactory aiohttp clientsession handling in HA

* remove from core / update platforms / rename file
2016-11-27 16:26:46 -08:00
Josh Nichols
84b12ab007 Nest Cam support (#4292)
* start nestcam support

* start nestcam support

* introduce a access_token_cache_file

* Bare minimum to get nest thermostat loading

* occaisonally the image works

* switch to nest-aware interval for testing

* Add Nest Aware awareness

* remove duplicate error logging line

* Fix nest protect support

* address baloobot

* fix copy pasta

* fix more baloobot

* last baloobot thing for now?

* Use streaming status to determine online or not. online from nest means its on the network

* Fix temperature scale for climate

* Add support for eco mode

* Fix auto mode for nest climate

* update update current_operation and set_operation mode to use constant when possible. try to get setting something working

* remove stale comment

* unused-argument already disabled globally

* Add eco to the end, instead of after off

* Simplify conditional when the hass mode is the same as the nest one

* away_temperature became eco_temperature, and works with eco mode

* Update min/max temp based on locked temperature

* Forgot to set locked stuff during construction

* Cache image instead of throttling (which returns none), respect NestAware subscription

* Fix _time_between_snapshots before the first update

* WIP pin authorization

* Add some more logging

* Working configurator, woo. Fix some hound errors

* Updated pin workflow

* Deprecate more sensors

* Don't update during access of name

* Don't update during access of name

* Add camera brand

* Fix up some syntastic errors

* Fix ups ome hound errors

* Maybe fix some more?

* Move snapshot simulator url checking down into python-nest

* Rename _ready_to_update_camera_image to _ready_for_snapshot

* More fixes

* Set the next time a snapshot can be taken when one is taken to simplify logic

* Add a FIXME about update not getting called

* Call update during constructor, so values get set at least once

* Fix up names

* Remove todo about eco, since that's pretty nest

* thanks hound

* Fix temperature being off for farenheight.

* Fix some lint errors, which includes using a git version of python-nest with updated code

* generate requirements_all.py

* fix pylint

* Update nestcam before adding

* Fix polling of NestCamera

* Lint
2016-11-27 16:18:47 -08:00
Johan Bloemberg
601193b1d2 Expose isort preferences for tools. (#4481)
* Expose isort preferences for tools.

* Adhere to pylints sorted imports requirement.

* More documentation, set typing in between stdlib and 3rd party.
2016-11-27 14:33:30 -08:00
Sean Dague
038b1c1fc6 precision properties for climate components (#4562)
This lets components declare their precision for temperatures. If
nothing is declared, we assume 0.1 C and whole integer precision in
F. Currently this supports only WHOLE, HALVES, and TENTHS for
precision, but adding other precision levels is pretty straight
forward.

This also uses proliphix as an example of changing the precision for a
platform.

Closes bug #4350
2016-11-27 14:19:12 -08:00
Paulus Schoutsen
0d734303a4 HTTP: Fix registering views after start (#4604) 2016-11-27 14:01:12 -08:00
Lewis Juggins
ff4cb23f2a Update nginx docs (#4603) 2016-11-27 13:49:21 -08:00
Paulus Schoutsen
e94b4ec006 Tweak services return result (#4600)
* Tweak services return result

* Lint
2016-11-27 12:33:02 -08:00
Paulus Schoutsen
be91207830 Upgrade HBMQTT (#4599) 2016-11-27 12:21:20 -08:00
Ron Klinkien
ecf285105c Fixed unit_of_measurement functionality for knx sensor (#4594) 2016-11-27 12:21:05 -08:00
Paulus Schoutsen
767f3d58ff Add websocket_api as frontend dependency 2016-11-27 12:13:01 -08:00
Lewis Juggins
34097cda24 Allow generic thermostat tolerance to be customisable to determine the temperature difference required to turn switch on. (#4585) 2016-11-27 09:31:00 +00:00
Michaël Arnauts
0ce3703e30 Remove fixed throttle for binary_sensor.command_line and sensor.command_line since the scan_interval is configured trough YAML since #1059 (#4586)
* Remove fixed throttle for binary_sensor.command_line and sensor.command_line since the scan_interval is configured trough YAML since #1059

* Clean up imports

* Add SCAN_INTERVAL=60 to put default scan_inteval back to 60
2016-11-27 00:29:49 -08:00
Paulus Schoutsen
464e843186 Update frontend 2016-11-26 23:44:20 -08:00
Paulus Schoutsen
5d2b7a6e0b Add ping to websockets API (#4592) 2016-11-26 23:22:34 -08:00
Paulus Schoutsen
914a868fbd Add websocket API (#4582)
* Add websocket API

* Add identifiers to interactions

* Allow unsubscribing event listeners

* Add support for fetching data

* Clean up handling code websockets api

* Lint

* Add Home Assistant version to auth messages

* Py.test be less verbose in tox
2016-11-26 18:23:28 -08:00
Paulus Schoutsen
03e0c7c71c Prevent edimax from doing I/O in event loop (#4584) 2016-11-26 10:10:29 -08:00
Paulus Schoutsen
32ffd006fa Reorganize HTTP component (#4575)
* Move HTTP to own folder

* Break HTTP into middlewares

* Lint

* Split tests per middleware

* Clean up HTTP tests

* Make HomeAssistantViews more stateless

* Lint

* Make HTTP setup async
2016-11-25 13:04:06 -08:00
Fabian Affolter
58b85b2e0e Upgrade speedtest-cli to 1.0.0 (#4578) 2016-11-25 12:30:53 -08:00
Marcelo Moreira de Mello
61653a517d #4421 - Forced icons to be displayed via SSL to avoid Mixed Content warnings (#4544)
* #4421 - Forced icons to be displayed via SSL to avoid Mixed Content warnings

* Fixed houndci-bot whitespace

* Using regex to replace http:// for https://

* Created assert test to verify https translation
2016-11-25 20:03:12 +00:00
Vlad Korniev
2a7bc0e55c Advanced Ip filtering (#4424)
* Added IP Bans configuration

* Fixing warnings

* Added ban enabled option and unit tests

* Fixed py34 tox

* http: requested changes fix

* Requested changes fix
2016-11-24 21:52:10 -08:00
Lewis Juggins
95b439fbd5 Upgrade aiohttp to 1.1.5 (#4213) 2016-11-24 21:37:56 -08:00
Paulus Schoutsen
1872481f47 Merge pull request #4572 from home-assistant/release-0-33-4
0.33.4
2016-11-24 15:37:38 -08:00
Paulus Schoutsen
44b6d23e0f Version bump to 0.33.4 2016-11-24 14:57:12 -08:00
Paulus Schoutsen
58eb0ec52a Set executor pool size to 10 (#4571) 2016-11-24 14:56:59 -08:00
Paulus Schoutsen
febe16d700 Set executor pool size to 10 (#4571) 2016-11-24 14:56:33 -08:00
Pascal Vizeli
8c56091af7 Hotfix executor pool size (#4552) 2016-11-24 14:53:46 -08:00
Paulus Schoutsen
eacdce9ed9 Track tasks only during shutdown and tests (#4428)
* Track tasks only when needed

* Tweak async_block_till_done
2016-11-24 14:49:29 -08:00
Paulus Schoutsen
42c99b0ccb Pass hass object to ServiceRegistry constructor (#4570) 2016-11-24 14:02:39 -08:00
Jon Caruana
2a6c0cfc17 LiteJet: Unit tests and new trigger options held_more_than and held_less_than. (#4473)
* LiteJet: Unit tests and new trigger options held_more_than and held_less_than.
* Unit tests for the LiteJet component and associated platforms. Coverage is almost 100% -- just misses one line.
* The automation LiteJet trigger returns an empty "removal" function to ensure the automation base is happy with it. The pylitejet library doesn't actually support a real removal.
* The automation LiteJet trigger can detect hold time and act appropriately to support things like short tap or long hold.

* LiteJet: Fix indent in unit test source code.

* LiteJet: Fix test_include_switches_* unit tests on Python 3.5

* LiteJet: Remove wait for state existence from unit tests. Recent fixes to discovery make this no longer necessary.
2016-11-24 09:52:15 -08:00
Fabian Affolter
84040892df Remove globally disable pylint issue (#4565) 2016-11-24 12:25:01 +01:00
Fabian Affolter
345008c673 Fix docstring (#4564) 2016-11-24 10:15:00 +01:00
Matt N
14d1494cd2 systemmonitor: Support monitoring removable network interfaces (#4462) 2016-11-24 10:14:38 +01:00
Marcel030nl
f1d11e77ed Update pvoutput.py (#4557)
This addition could be usefull when working with the template sensor using the data of this sensor.
2016-11-24 09:58:38 +01:00
Fabian Affolter
b1b8715f7d Minor comment updates and ordering (#4554) 2016-11-24 00:27:31 +01:00
Fabian Affolter
b6d559da1f Add timeout to requests, use consts, and add link to docs (#4555) 2016-11-24 00:26:59 +01:00
Fabian Affolter
475c412ae4 Minor changes (switch.hook) (#4553)
* Use string formatting, add link to docs, and pylint

* Extent platform for validation
2016-11-24 00:21:48 +01:00
Pascal Vizeli
c04a002c55 Hotfix executor pool size (#4552) 2016-11-23 09:52:03 -08:00
dasos
5013a82655 Hook Smart Home support (#4392)
* Support for Hook (hooksmarthome.com)

* Linting

* Add asyncio

* Move to aiohttp

* Yield more
2016-11-23 14:52:14 +00:00
Johan Bloemberg
05181bf232 0.4 release upstream. (#4545) 2016-11-23 10:44:37 +00:00
Marcelo Moreira de Mello
c22a73e1d0 Removed raise statement to don't pollute the user log. (#4536)
* Removed raise statement to don't polute the user log.
Only the error message should be displayed.

Nov 22 11:28:32 tchellopi hass[20138]: 16-11-22 11:28:32 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Nov 22 11:28:32 tchellopi hass[20138]: Traceback (most recent call last):
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/asyncio/tasks.py", line 241, in _step
Nov 22 11:28:32 tchellopi hass[20138]: result = coro.throw(exc)
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/helpers/entity_component.py", line 386, in _update_entity_states
Nov 22 11:28:32 tchellopi hass[20138]: yield from update_coro
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 213, in async_update_ha_state
Nov 22 11:28:32 tchellopi hass[20138]: yield from self.hass.loop.run_in_executor(None, self.update)
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/asyncio/futures.py", line 361, in __iter__
Nov 22 11:28:32 tchellopi hass[20138]: yield self  # This tells Task to wait for completion.
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
Nov 22 11:28:32 tchellopi hass[20138]: future.result()
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/asyncio/futures.py", line 274, in result
Nov 22 11:28:32 tchellopi hass[20138]: raise self._exception
Nov 22 11:28:32 tchellopi hass[20138]: File "/usr/local/lib/python3.5/concurrent/futures/thread.py", line 55, in run
Nov 22 11:28:32 tchellopi hass[20138]: result = self.fn(*self.args, **self.kwargs)
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.homeassistant/custom_components/sensor/wunderground.py", line 187, in update
Nov 22 11:28:32 tchellopi hass[20138]: self.rest.update()
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.virtualenvs/home_assistant/lib/python3.5/site-packages/homeassistant/util/__init__.py", line 296, in wrapper
Nov 22 11:28:32 tchellopi hass[20138]: result = method(*args, **kwargs)
Nov 22 11:28:32 tchellopi hass[20138]: File "/home/hass/.homeassistant/custom_components/sensor/wunderground.py", line 222, in update
Nov 22 11:28:32 tchellopi hass[20138]: ["description"])
Nov 22 11:28:32 tchellopi hass[20138]: ValueError: you must supply a key

* Updated unittest since we are just printing the error instead raising
2016-11-22 23:41:51 -08:00
Charles Blonde
c9b353f7a7 Add Bose SoundTouch device support - v2 (#4523)
* Add Bose SoundTouch device support

* Update soundtouch.py
2016-11-22 23:22:52 -08:00
Johan Bloemberg
64cfc4ff02 DSMR sensor (#4309)
* Initial implemenation of DSMR component.

* Fix linting

* Remove protocol V2.2 support until merged upstream.

* Generate requirements using script.

* Use updated dsmr-parser with protocol 2.2 support.

* Add tests.

* Isort and input validation.

* Add entities for gas and actual meter reading. Error handling. Use Throttle.

* Implement non-blocking serial reader.

* Improve logging.

* Merge entities into one, add icons, fix tests for asyncio.

* Add error logging for serial reader.

* Refactoring and documentation.

- refactor asyncio reader task to make sure it stops with HA
- document general principle of this component
- refactor entity reading to be more clear
- remove cruft from split entity implementation

* Use `port` configuration key.

* DSMR V2.2 seems to conflict in explaining which tariff is high and low.

http://www.netbeheernederland.nl/themas/hotspot/hotspot-documenten/?dossierid=11010056&title=Slimme%20meter&onderdeel=Documenten
> DSMR v2.2 Final P1
>> 6.1: table vs table note

    Meter Reading electricity delivered to client normal tariff) in 0,01 kWh - 1-0:1.8.1.255
    Meter Reading electricity delivered to client (low tariff) in 0,01 kWh - 1-0:1.8.2.255

    Note: Tariff code 1 is used for low tariff and tariff code 2 is used for normal tariff.

* Refactor to use asyncio.Protocol instead of loop+queue.

* Fix requirements

* Close transport when HA stops.

* Cleanup.

* Include as dependency for testing (until merged upstream.)

* Fix style.

* Update setup.cfg
2016-11-22 23:03:39 -08:00
Valentin Alexeev
bb46009efa World Air Quality Index sensor (#4434)
* Implement WAQI sensor

* Corrections based on CI check.

* Updated requirements_all.txt for pwaqi==1.2

* Require latest version of pwaqi

* Fix lint: single argument for .exception and no more pass statement.

* Further lint fixes.

* pydocstyle fix

* Implement rate throttle.
Data on WAQI is usually updated once an hour - make it refresh every thirty minutes.

* Implement schema validation with voluptuous.
Change exception handling scope.
Move messages to debug().

* Fix lint (empty indented line).

* Sort lines correctly.

* Fix last lint issue.

* Provide additional sensor data as received from WAQI.
Easier-to-read throttle timing.

* Additional object attributes to be unrolled later.
2016-11-22 22:59:27 -08:00
Paulus Schoutsen
3f9250415f Skip broken tests (#4543) 2016-11-22 22:58:14 -08:00
Pascal Vizeli
c294a534d0 Migrate binary_sensor to async (#4516) 2016-11-22 22:47:43 -08:00
Harris Borawski
85d6970df8 Add Sensor for Sonarr (#4496)
* Add sonarr sensor and tests for sensor

* Fixed some linting errors and removed unused import

* Add SSL option for those who use SSL from within Sonarr

* Add requirements to all requirements, and sensor to coveragerc

* remove unused variable

* move methods to functions, and other lint fixes

* linting fixes

* linting is clean now

* Remove double requirement

* fix linting for docstrings, this should probably be a part of the script/lint and not just travis
2016-11-22 22:32:45 -08:00
dainok
260a619a40 Added GPSLogger API (#4089)
* Added GPSLogger API, check https://goo.gl/eJnKw5 for details.

* Switched to debug severity and added to coveragerc

* Switched to debug severity for logs

* Updated .coveragerc

* Update .coveragerc

* Merged from sfiorini

* Merged from sfiorini

* Update .coveragerc
2016-11-22 22:19:57 -08:00
Michaël Arnauts
0c6ef3b7f9 Try to register a Chromecast anyway, even if it could not be detected by get_chromecasts(), since it might be on a other network. Fixes #4469. (#4470) 2016-11-22 22:16:01 -08:00
Thomas Friedel
0c47434aad Change Osram to use Github lightify dep (#4256)
* used MindrustUK's version ( https://github.com/MindrustUK/python-lightify/commits/master/osramlightify.py ) from Oct 2, 2016 and changed the REQUIRMENTS line to use the fixed lightify component with thread safety fixes

* reformatted long lines

* updated osramlightify requirements in requirements_all.txt

* ran script gen_requirements_all.py

* rerun requirements gen script on linux

* fixed some inspection warnings

* zip file points to a specific commit

* no requests to lights in properties, instead instance variables are update in update method

* regenerated requirements_all.txt

* removed call to update from is_on() property
2016-11-22 22:10:45 -08:00
Magnus Ihse Bursie
1d8a1df2c4 Refactor tellstick code (#4460)
* Refactor tellstick code for increased readability. Especially highlight if "device" is a telldus core device or a HA entity.

* Refactor Tellstick object model for increased clarity.

* Update comments. Unify better with sensors. Fix typo bug. Add debug logging.

* Refactor tellstick code for increased readability. Especially highlight if "device" is a telldus core device or a HA entity.

* Refactor Tellstick object model for increased clarity.

* Update comments. Unify better with sensors. Fix typo bug. Add debug logging.

* Fix lint issues.
2016-11-22 21:48:22 -08:00
Aaron Morris
65b85ec6c0 Fix missing space in error message between "accuracy" and "is" (#4542) 2016-11-22 20:45:06 -08:00
Paulus Schoutsen
b6b9da7e6e Merge pull request #4541 from home-assistant/release-0-33-3
0.33.3
2016-11-22 20:35:55 -08:00
Paulus Schoutsen
d18f2684fb Version bump to 0.33.3 2016-11-22 19:39:15 -08:00
Paulus Schoutsen
e93b079ef4 Fix platform discovery when platform discovered during discovery of a (#4529)
component
2016-11-22 19:38:34 -08:00
Paulus Schoutsen
356ad6e468 Bump netdisco (#4539) 2016-11-22 19:36:39 -08:00
Johann Kellerman
8f35212dd6 Yr.no update entities every hour (#4521) 2016-11-22 19:35:49 -08:00
Johann Kellerman
0827a26642 Yr.no update entities every hour (#4521) 2016-11-22 19:28:31 -08:00
Paulus Schoutsen
b4756e6dda Bump netdisco (#4539) 2016-11-22 18:36:10 -08:00
Paulus Schoutsen
4cc192e445 Disable broken google offset test (#4540) 2016-11-22 18:34:48 -08:00
mnestor
962e5315ab Mock call to google servers (#4532)
* Fix for #4520

* mock call to do_auth to prevent call to google servers
2016-11-22 18:19:32 -08:00
Paulus Schoutsen
2c7e895105 Entity and climate: do not convert temperature unnecessary (#4522)
* Climate: more consistent units

* Prevent unnecessary conversion in entity component

* int -> round

* Disable Google tests because they connect to the internet

* Remove default conversion rounding F->C

* Add rounding of temp to weather comp

* Fix equality

* Maintain precision when converting temp in entity

* Revert "Disable Google tests because they connect to the internet"

This reverts commit b60485dc19.
2016-11-22 17:38:04 -08:00
Paulus Schoutsen
00019b9ff0 Fix warning in test 2016-11-22 12:48:35 -08:00
Pascal Vizeli
8e776b4dc0 Fix wrong name handling in rfxtrx sensor (#4531) 2016-11-22 12:47:37 -08:00
mnestor
ce13b0989d Fix for #4520 (#4526)
* Fix for #4520

* fix lint
2016-11-22 10:15:39 -08:00
Paulus Schoutsen
c81735cc84 Fix platform discovery when platform discovered during discovery of a (#4529)
component
2016-11-22 08:21:08 -08:00
Fabian Affolter
5d18759146 Upgrade miflora to 0.1.13 (fixes #4479) (#4524) 2016-11-22 15:41:37 +01:00
Malte Franken
9cdcfae8f3 New config parameter for min_max sensor to specify number of digits for rounding mean value (#4237)
* new config parameter to specify number of digits for rounding average value

* fixed two `line too long` errors

* added three new tests for the mean sensor including test for precision of mean value
2016-11-22 15:36:29 +01:00
Gilles Margerie
547d93f631 Added source selection for Denon AVR Media Player (#4304)
* Added source selection for Denon AVR Media Player

* Update denon.py

* Update denon.py

* Update denon.py

* Update denon.py

* Update denon.py

slight format update (space issue and new line)

* Further update regarding formatting

* Updated the source name with lowercase

* Update denon.py
2016-11-21 23:45:17 -08:00
Paulus Schoutsen
d841ddc50b Merge pull request #4519 from home-assistant/release-0-33-2
0.33.2
2016-11-21 20:42:21 -08:00
Paulus Schoutsen
40b5824230 Skip google calendar offset test (#4520) 2016-11-21 20:16:50 -08:00
Paulus Schoutsen
86f3e2455d Skip google calendar offset test (#4520) 2016-11-21 20:16:34 -08:00
Paulus Schoutsen
9a065cc536 Version bump to 0.33.2 2016-11-21 19:40:19 -08:00
Richard Cox
8e4dbcaf21 Fixing 'Unknown' status for Nest Protect devices (#4475)
* Fixing 'Unknown' status for Nest Protect devices

* Fixing bad formatting
2016-11-21 19:39:38 -08:00
Richard Cox
6863d2e0af Fixing 'Unknown' status for Nest Protect devices (#4475)
* Fixing 'Unknown' status for Nest Protect devices

* Fixing bad formatting
2016-11-21 19:39:23 -08:00
John Arild Berentsen
c23809488b Neato Fixes (#4490)
* Fix, switch state. Move constants to hub

* Responsiveness

* Whitespace

* Delay was not needed as commands does not return until done.
2016-11-21 19:36:54 -08:00
John Arild Berentsen
248f5c0209 Neato Fixes (#4490)
* Fix, switch state. Move constants to hub

* Responsiveness

* Whitespace

* Delay was not needed as commands does not return until done.
2016-11-21 19:36:44 -08:00
Jack Chapple
e5aa40fa5d Fixes #4500 (#4502) 2016-11-21 19:35:49 -08:00
Jack Chapple
1f573b46a4 Fixes #4500 (#4502) 2016-11-21 19:35:36 -08:00
hexa-
0647bb7f6b switch.tplink: expect daily stats to be empty (#4504)
Signed-off-by: Martin Weinelt <hexa@darmstadt.ccc.de>
2016-11-21 19:34:58 -08:00
hexa-
a73fbbaf7a switch.tplink: expect daily stats to be empty (#4504)
Signed-off-by: Martin Weinelt <hexa@darmstadt.ccc.de>
2016-11-21 19:34:48 -08:00
Pascal Vizeli
755f5b61b7 Bugfix discovery use wrong time async (#4515)
* Bugfix discovery use wrong time async

* fix lint
2016-11-21 19:33:32 -08:00
Pascal Vizeli
6869c7401e Bugfix device_tracker init tracker scan (#4514) 2016-11-21 19:33:32 -08:00
Pascal Vizeli
835577b2bc Bugfix discovery use wrong time async (#4515)
* Bugfix discovery use wrong time async

* fix lint
2016-11-21 19:33:08 -08:00
Pascal Vizeli
859d0d5ad6 Bugfix device_tracker init tracker scan (#4514) 2016-11-21 19:32:21 -08:00
Fabian Affolter
aed797f438 Upgrade freesms to 0.1.1 (#4491) 2016-11-21 17:32:05 +01:00
Fabian Affolter
eb8093934f Upgrade python-hpilo to 3.9 (#4482) 2016-11-21 17:31:14 +01:00
Fabian Affolter
608b482906 Upgrade sqlalchemy to 1.1.4 (#4486) 2016-11-21 17:29:06 +01:00
Fabian Affolter
7207c2cca1 Upgrade sendgrid to 3.6.3 (#4485) 2016-11-21 17:28:31 +01:00
Fabian Affolter
ed1d0b4197 Upgrade astral to 1.3.2 (#4505) 2016-11-21 17:27:48 +01:00
Fabian Affolter
63461e9007 Upgrade slacker to 0.9.30 (#4484) 2016-11-21 17:27:15 +01:00
Fabian Affolter
40a2145558 Upgrade yahoo-finance to 1.4.0 (#4483) 2016-11-21 17:25:43 +01:00
Sean Dague
d883b18751 Merge pull request #4503 from sdague/pyvera_bump
Bump pyvera to 0.2.21
2016-11-21 06:09:54 -05:00
Sean Dague
b8e462cf5b Bump pyvera to 0.2.21
pyvera 0.2.21 fixes the fact that use of requests.get was not using a
timeout. Some times (after a few days of use) the pyvera poll loop
would hang indefinitely on a requests.get of the event interface. This
would cause the pyvera thread to hang completely. It would also
prevent graceful shutdown, as pyvera does a thread join.

The new version uses a timeout, so that we won't lock up any more.
2016-11-21 06:06:17 -05:00
Paulus Schoutsen
11df7becd3 Merge pull request #4492 from home-assistant/release-0-33-1
0.33.1
2016-11-20 13:58:01 -08:00
Paulus Schoutsen
99f5db8c02 Version bump to 0.33.1 2016-11-20 12:11:07 -08:00
John Arild Berentsen
19b08a975a ZWave lights: Not use super() (#4476)
* Not use super

* Review changes
2016-11-20 12:10:50 -08:00
John Arild Berentsen
123f4acfc1 ZWave lights: Not use super() (#4476)
* Not use super

* Review changes
2016-11-20 11:49:54 -08:00
Paulus Schoutsen
0f90426023 Version bump to 0.34.0.dev0 2016-11-19 16:06:42 -08:00
Paulus Schoutsen
8b6a94b0f5 Merge pull request #4446 from home-assistant/dev
0.33
2016-11-19 16:06:26 -08:00
Paulus Schoutsen
0a333230c1 Version bump to 0.33 2016-11-19 16:05:56 -08:00
Paulus Schoutsen
455e1df7cb Fix typo 2016-11-19 16:05:33 -08:00
Matt N
f71396c293 Fix nmap_tracker documentation link (#4471) 2016-11-19 15:31:45 -08:00
Paulus Schoutsen
d930c399fe Better locking while setting up components + discovery (#4463) 2016-11-19 08:18:33 -08:00
Bjarni Ivarsson
f3748ce535 Sonos line-in and tv source fixes + Sonos discovery fix. (#4440)
* Fixes line-in and tv sources on Sonos + Sonos discovery fixes.

* Style fix.
2016-11-19 15:29:00 +00:00
John Arild Berentsen
8beefcfc69 Switch did not update (#4466) 2016-11-19 15:52:42 +01:00
John Arild Berentsen
93747f2766 switch base cover did not appear (#4454)
Thanks for testing the PR @emilhetty 👍
2016-11-19 12:33:08 +01:00
John Arild Berentsen
7af438fa2f Hound for zwave climate (#4465) 2016-11-19 10:19:22 +01:00
Fabian Affolter
2b5fcd737b PVOutput sensor (#4203)
* Add PVOutput sensor

* Remove attributes

* Revert `verify_ssl` back to true
2016-11-19 10:04:03 +01:00
John Arild Berentsen
2b320f23fc Hound comments (#4464) 2016-11-19 09:46:02 +01:00
John Arild Berentsen
679d500e61 Neato refactor and support for sensors (#4319)
* Imporvements to neato

* Review changes
2016-11-19 00:14:40 -08:00
mnestor
613615433a Google Calendar round 2 (#4161)
* Google Calendar round 2

* Add google back to .coveragerc

* Update __init__.py
2016-11-18 22:29:20 -08:00
Fabian Affolter
f70ff66d11 Upgrade batinfo to 0.4.2 (#4452) 2016-11-18 22:04:15 -08:00
Paulus Schoutsen
d2bbc6ef70 Upgrade linter (#4461) 2016-11-18 21:47:59 -08:00
Paulus Schoutsen
37e28428c1 Merge remote-tracking branch 'origin/master' into dev 2016-11-18 18:39:11 -08:00
Pascal Vizeli
c56f99baaf Async migration device_tracker (#4406)
* Async migration device_tracker

* change location stuff to async

* address paulus comments

* fix lint & add async discovery listener

* address paulus comments v2

* fix tests

* fix test_mqtt

* fix test_init

* fix gps_acc

* fix lint

* change async_update_stale to callback
2016-11-18 23:35:08 +01:00
Erik Eriksson
265232af98 only check heater status if present (#4459) 2016-11-18 14:12:51 -08:00
Fabian Affolter
e6c4113c5b Fix lint issues for 0.33 (#4451)
* Fix PEP257 issues

* Fix ident

* Fix lint issues

* Update docstrings

* Fix indent

* Fix indent

* Fix lint issues

* Fix lint issue

* Again lint
2016-11-18 23:05:03 +01:00
Igor Shults
c86e1b31b3 Fix typo in OWM (#4458) 2016-11-18 22:54:46 +01:00
Lewis Juggins
5912316496 pywebpush update to 0.6.1 (#4449) 2016-11-18 13:03:44 -08:00
John Arild Berentsen
58f0655298 ZWave Light: Use Configurable refresh (#4437)
* Use Configurable refresh

* Use super instead of object
2016-11-18 21:59:01 +01:00
John Arild Berentsen
43a93fb345 ZWave: Fix missing battery_level, node_id and location (#4422)
* Fix missing battery_level, node_id and location

* use super instead of object
2016-11-18 21:42:30 +01:00
Daniel Høyer Iversen
36b338051b Merge pull request #4450 from home-assistant/flux_led_lib_09
Upgrade flux led lib
2016-11-18 14:18:12 +01:00
Daniel Hoyer Iversen
fc566309c1 Upgrade flux led lib 2016-11-18 13:20:51 +01:00
Sean Dague
23ce9949b1 Merge pull request #4447 from sdague/proliphix
bump proliphix library version
2016-11-18 06:56:04 -05:00
Sean Dague
275c80183c bump proliphix library version
This fixes an upstream bug with daylight savings time handling
2016-11-18 05:05:05 -05:00
Sean Dague
cd1655f43b create light.hue_activate_scene service (#4425)
* create light.hue_activate_scene service

This creates a light.hue_activate_scene service that takes group_name
and scene_name, and calls phue's bridge.run_scene with those
parameters. This allows calling hue bridge stored scene names by name
during automation.

This only currently works reliably in 1 hue hub configurations (which
is most of them). Phue will be further enhanced to display warnings
when it can't figure out what to do with the parameters passed in to HA.

* Update hue.py
2016-11-17 22:14:06 -08:00
jnimmo
1a117d0bea Add keypress & output control services to Envisalink component (#3932)
* Add keypress & output control services to Envisalink component

Add services to allow sending custom keypresses and activating
programmable outputs on an alarm control panel.
Implemented for the Envisalink alarm, and moving to new version of
pyenvisalink to support this.

Replicated the service handler mapping code from Cover component into
Alarm Control Panel to allow handling alternative schemas if required
by new services.

* Update requirements_all.txt

* Updated services.yaml

* Removed requirement to enter code in HA UI

Incorporated changes suggested by @sriram
https://github.com/srirams/home-assistant/commit/2f8deb70cb5f3621a69b6b9
acb72f8e29123650c

Including pending state for exit/entry delay

Clarified services to use the code passed to them as a first priority,
otherwise use the code from configuration

Swapped back to using NotImplementedError for the service definitions

* - Add support for alarm_keypress to manual alarm (functions like a standard alarm keypad where entering the code disarms or arms the alarm)
- Add tests for alarm_keypress to manual alarm
- Style corrections (too many returns, comment & whitespace issues)

* Removed alarm_output_control service as unable to incorporate in the demo/test in a meaningful way

* Add keypress & output control services to Envisalink component

Add services to allow sending custom keypresses and activating
programmable outputs on an alarm control panel.
Implemented for the Envisalink alarm, and moving to new version of
pyenvisalink to support this.

Replicated the service handler mapping code from Cover component into
Alarm Control Panel to allow handling alternative schemas if required
by new services.

* Update requirements_all.txt

* Updated services.yaml

* Removed requirement to enter code in HA UI

Incorporated changes suggested by @sriram
https://github.com/srirams/home-assistant/commit/2f8deb70cb5f3621a69b6b9
acb72f8e29123650c

Including pending state for exit/entry delay

Clarified services to use the code passed to them as a first priority,
otherwise use the code from configuration

Swapped back to using NotImplementedError for the service definitions

* - Add support for alarm_keypress to manual alarm (functions like a standard alarm keypad where entering the code disarms or arms the alarm)
- Add tests for alarm_keypress to manual alarm
- Style corrections (too many returns, comment & whitespace issues)

* Removed alarm_output_control service as unable to incorporate in the demo/test in a meaningful way

* Moved the Alarm_Keypress service into Envisalink component out of the generic

* Update envisalink.py

* Update services.yaml
2016-11-17 22:13:22 -08:00
Fabian Affolter
944bb8474f Change validation to optional (#4400) 2016-11-17 22:09:57 -08:00
Magnus Ihse Bursie
779f520c56 Make UI more responsive to power off for Samsung Smart TV (#4438) 2016-11-17 22:00:18 -08:00
Magnus Ihse Bursie
82ed7b6b08 Fix so shell script adheres to posix standards. (#4439) 2016-11-17 21:59:53 -08:00
Paulus Schoutsen
af77341494 Add sensor to show how many clients are connected. (#4430)
* Add sensor to show how many clients are connected.

* Lint

* Fix tests
2016-11-17 21:54:47 -08:00
Paulus Schoutsen
23fb8c4cdd Convert script component to async (#4427) 2016-11-17 21:50:01 -08:00
Paulus Schoutsen
726bc5b670 Do not report on shutting down errors (#4431)
* Do not report on shutting down errors

* Lint
2016-11-17 12:02:43 -08:00
Open Home Automation
b615b3349f Fix for Miflora 2.6.6 firmware (#4436) 2016-11-17 08:40:21 -08:00
Paulus Schoutsen
0f59bb208c Migrate callbacks to use schedule_update_ha_state (#4426)
* Migrate callbacks to use schedule_update_ha_state

* Migrate MQTT sensor callback to async

* Migrate wemo to not update inside schedule_update_ha_state

* Make MQTT switch async

* Fix nx584 test

* Migrate tellstick callback

* Migrate vera callback

* Alarm control panel - manual: use async callbacks

* Run the switch rest tests that work
2016-11-17 07:34:46 -08:00
Paulus Schoutsen
38d201a54a Increase logging level of errors while doing jobs (#4429) 2016-11-16 23:01:14 -08:00
Pascal Vizeli
c8bc1e3c5d change add_job to use call_soon_threadsafe (#4410)
* change add_job to use call_soon_threadsafe

* address comments from paulus

* Tweak core tests

* Fix tests Python 3.4.2
2016-11-16 20:00:08 -08:00
Lewis Juggins
a862bc4edc Fix DLink async I/O (#4301) 2016-11-16 18:55:58 -08:00
Magnus Ihse Bursie
b0e3d5a576 Better handling of accented characters in slugify (#4399) (#4423)
* Better handling of accented characters in slugify (#4399)

* Update __init__.py
2016-11-16 15:05:10 -08:00
Paulus Schoutsen
f006b00dc1 Fix spelling schedule_update_ha_state (#4415) 2016-11-16 08:26:29 -08:00
bestlibre
1fff6ce438 Deduplicate MQTT_PUBLISH_SCHEMA definition (#4411) 2016-11-16 08:19:00 -08:00
Sean Dague
c06c82905a dynamically fetch yamaha media playback support (#4385)
This makes it so that media playback support for inputs is dynamically
fetched from the receiver, instead of assuming that all playback
commands work for all inputs.

Tests are added for this, using a FakeYamaha class, which has some
sample data stubbed in for key methods that need to be called. We also
include an example of the desc.xml needed to dynamically parse these
features for these tests (as this is done in platform init).
2016-11-15 21:56:40 -08:00
Paulus Schoutsen
2b86d89bb4 Fix tplink test 2016-11-15 21:26:03 -08:00
Sean Dague
7bdb79bd54 bump phue to 0.9 (#4404)
This increases the phue library to 0.9, which includes some basic
Scene support that could be consumed from home assistant.
2016-11-15 21:14:54 -08:00
Pascal Vizeli
41aaeb715a Convert switch to AsnycIO (#4382)
* Convert switch to AsnycIO

* Move update entity to service

* use time better for faster handling

* Change to suggestion from paulus

* Use new shedule_update_ha_state

* fix lint

* minimize executor calls
2016-11-15 21:06:50 -08:00
Fabian Affolter
5d8a465c18 Add timeout to requests (#4398) 2016-11-15 21:02:17 -08:00
John Arild Berentsen
c6f5a5443f Make zwave climate entities contain it's respective setpoints (#4357)
* Make zwave entities contain it's respective setpoints

* Add fan state
2016-11-15 13:14:29 +01:00
Fabian Affolter
d6cb102f63 Merge pull request #4144 from dasos/squeezebox_name_fix
Squeezebox name
2016-11-15 10:06:10 +01:00
Fabian Affolter
edde76e544 Fix validation and use consts (mqtt) (#4396) 2016-11-15 08:33:42 +01:00
Fabian Affolter
d5fff2f94a Fix validation and use consts (mqtt) 2016-11-15 08:21:44 +01:00
bestlibre
0e0ba28249 support for last will and birth message for mqtt (#4381) 2016-11-14 22:18:33 -08:00
Paulus Schoutsen
6745e83a6c Merge pull request #4394 from home-assistant/release-0-32-4
0.32.4
2016-11-14 22:04:43 -08:00
Paulus Schoutsen
44bc057fdb Version bump to 0.32.4 2016-11-14 21:34:40 -08:00
hexa-
96b8d8fcfa http: reimplement X-Forwarded-For parsing (#4355)
This feature needs to be enabled through the `http.use_x_forwarded_for` option,
satisfying security concerns of spoofed remote addresses in untrusted network
environments.

The testsuite was enhanced to explicitly test the functionality of the
header.

Fixes #4265.

Signed-off-by: Martin Weinelt <hexa@darmstadt.ccc.de>
2016-11-14 21:33:34 -08:00
Sean Dague
fc2df34206 Pin versions on linters for tests
The linters really need to specify an exact version, because when
either flake8 or pylint release a new version, a whole lot of new
issues are caught, causing failures on the code unrelated to the
patches being pushed.

Pinning is a best practice for linters. This allows patches which move
forward the linter version to happen with any code fixes required for
it to pass.
2016-11-14 21:32:02 -08:00
Paulus Schoutsen
09c29737de Fix device tracker sending invalid event data 2016-11-14 21:31:17 -08:00
Paulus Schoutsen
4c01b47945 device_tracker.see should not call async methods (#4377) 2016-11-14 21:31:06 -08:00
Paulus Schoutsen
7aaf3a46db Fix device tracker sending invalid event data (#4393) 2016-11-14 21:28:57 -08:00
Paulus Schoutsen
d774ba46c7 Fix device tracker sending invalid event data 2016-11-14 20:59:29 -08:00
Lewis Juggins
4c37ee8884 Handle live content better in Kodi (#4388) 2016-11-14 20:11:22 -08:00
Paulus Schoutsen
7f5f458074 Faster async entity update on component. (#4384) 2016-11-14 18:54:38 -08:00
Paulus Schoutsen
479457d6ec device_tracker.see should not call async methods (#4377) 2016-11-14 18:35:58 -08:00
Paulus Schoutsen
7e73d27dd1 Do not serve HTTP requests while stopping (#4378) 2016-11-14 18:33:53 -08:00
Martin Wood
e7ffec87ac Squeezebox name fix #4019 2016-11-14 21:46:05 +00:00
Robbie Trencheny
2d47b187c5 notify.html5: decode bytes values in registration data (#4379)
Occassionally the values of `keys` and `p256h` are bytes objects instead of
strings. As JSON by default does not serialize bytes objects let's decode
bytes objects to unicode strings.

Resolves the registration issue mentioned in #4012.

Signed-off-by: Martin Weinelt <hexa@darmstadt.ccc.de>
2016-11-14 11:35:31 -08:00
Sean Dague
fe2103dedb Merge pull request #4386 from sdague/lint
Pin versions on linters for tests
2016-11-14 13:58:50 -05:00
Sean Dague
7bf5d1c662 Pin versions on linters for tests
The linters really need to specify an exact version, because when
either flake8 or pylint release a new version, a whole lot of new
issues are caught, causing failures on the code unrelated to the
patches being pushed.

Pinning is a best practice for linters. This allows patches which move
forward the linter version to happen with any code fixes required for
it to pass.
2016-11-14 13:50:27 -05:00
pvizeli
cb24282040 Faster async entity update on component. 2016-11-14 14:18:04 +01:00
Fabian Affolter
bd9429d3af Upgrade sendgrid to 3.6.2 (#4370) 2016-11-14 09:35:08 +01:00
Martin Weinelt
d7a005ad0f notify.html5: decode bytes values in registration data
Occassionally the values of `keys` and `p256h` are bytes objects instead of
strings. As JSON by default does not serialize bytes objects let's decode
bytes objects to unicode strings.

Resolves the registration issue mentioned in #4012.

Signed-off-by: Martin Weinelt <hexa@darmstadt.ccc.de>
2016-11-14 05:14:18 +01:00
Paulus Schoutsen
2e2a996a8e Do not serve HTTP requests while stopping 2016-11-13 18:12:50 -08:00
Paulus Schoutsen
0364498dee Add .hound.yml 2016-11-13 11:34:09 -08:00
Daniel Høyer Iversen
c5fdd4392a Merge pull request #4373 from home-assistant/flux_led_color_bright
support color and brightness in flux_led light
2016-11-13 20:33:48 +01:00
Daniel Hoyer Iversen
895454b6c3 support color and brightness in flux_led light 2016-11-13 11:10:27 +01:00
Nathan Henrie
2109b7a1b9 Use entity_id for backend, friendly name for frontend (#4343)
* Use entity_id for backend, friendly name for frontend

Closes https://github.com/home-assistant/home-assistant/issues/3434

Command line switches had the option to set a `friendly_name` reportedly
for use in the front end. However, if set, it was also being used as the
`entity_id`.

This did not seem like obvious behavior to me. This PR changes the
behavior so the entity_id is the object_id, which must already be
unique, and is an obvious place to have a very predictable slug (even if
long or unsightly), and the friendly name (if set) is used for the
display.

Example:

```yaml
switch:
  platform: command_line
  switches:
    rf_kitchen_light_one:
      command_on: switch_command on kitchen
      command_off: switch_command off kitchen
      command_state: query_command kitchen
      value_template: '{{ value == "online" }}'
      friendly_name: "Beautiful bright kitchen light!"
```

If you were using in an automation or from dev tools, would use:
`switch.rf_kitchen_light_one`, but your front end would still show `Beautiful
bright kitchen light!`

* Add new arg to test_assumed_state_should_be_true_if_command_state_is_false

* Import ENTITY_ID _FORMAT from existing, rename device_name to object_id

* Rename `device_name` to `object_id`

* Test that `entity_id` and `name` are set as expected
2016-11-12 22:46:23 -08:00
Pascal Vizeli
71a305ea45 Hotfix deadlock on platform setup (#4354)
* Hotfix deadlock on platform setup

* fix wrong import
2016-11-12 16:19:13 -08:00
hexa-
e73634e6c7 http: reimplement X-Forwarded-For parsing (#4355)
This feature needs to be enabled through the `http.use_x_forwarded_for` option,
satisfying security concerns of spoofed remote addresses in untrusted network
environments.

The testsuite was enhanced to explicitly test the functionality of the
header.

Fixes #4265.

Signed-off-by: Martin Weinelt <hexa@darmstadt.ccc.de>
2016-11-12 16:14:39 -08:00
Pascal Vizeli
3d47ad5018 Use hass aiohttp connector for ssl connection (#4344) 2016-11-12 16:00:31 -08:00
Erik Eriksson
c823ea9f2a Don't fail if component name is None. Fixes (#4345)
https://github.com/home-assistant/home-assistant/issues/4326

Might fix https://github.com/home-assistant/home-assistant/issues/4326
2016-11-12 14:16:27 -08:00
Fabian Affolter
75bcb1ff0f Upgrade schiene to 0.18 (#4359) 2016-11-12 12:30:05 -08:00
Sean Dague
1663cc9084 Fix typo in generic thermostat (#4348)
It looks like a copy / paste error was made when doing the min/max
code. This fixes that.
2016-11-11 17:42:58 +01:00
Christian Brædstrup
17cfcc981d D-Link switch version bump of external library (#4351) 2016-11-11 17:38:12 +01:00
Hugo Dupras
60fabaec24 Add timeout for Netatmo binary sensor (#4280)
* Add time limit for Netatmo binary sensor

* Change limit to timeout

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Update requirements_all.txt
2016-11-10 23:04:11 -08:00
Marcelo Moreira de Mello
5e44934e7e Added some extra options to Weather Underground component (#4306)
* Added some extra options to Weather Underground component

* Added Location and Elevation options

* Fixed if statement

* Fixed lint

* Updated tests including  elevation and location

* Update wunderground.py
2016-11-10 23:01:20 -08:00
Lewis Juggins
01a6c1c1c8 Add strptime template function (#3950) 2016-11-10 22:57:44 -08:00
Jeffrey Lin
cd1b0ac67d Added NVRAM-based MAC to IP mapping as backup to ARP tables (#4189) 2016-11-10 22:46:58 -08:00
Paulus Schoutsen
2bfded7153 MQTT.Server will use HASS eventloop (#3429) 2016-11-10 22:45:38 -08:00
Javier González Calleja
20af5cb5b4 Daily consumption information for HS110 (#4206)
* Add daily consumption information for HS110

* Fixing code review

* Fixing code review

* Fixing code review
2016-11-10 22:43:16 -08:00
Paulus Schoutsen
080f56e0f5 Merge pull request #4342 from home-assistant/release-0-32-3
0.32.3
2016-11-10 21:59:39 -08:00
Paulus Schoutsen
173e15e733 Version bump to 0.32.3 2016-11-10 21:50:05 -08:00
Paulus Schoutsen
72407c2f95 Make yr compatible with 0.32 2016-11-10 21:49:56 -08:00
Paulus Schoutsen
1b79722b69 Fix KNX async I/O (#4267) 2016-11-10 21:43:50 -08:00
Pascal Vizeli
cc5233103c Fix rest switch default template (#4331) 2016-11-10 21:43:50 -08:00
Daniel Høyer Iversen
2feea1d1eb Add support for rgb light in led flux, fixes issue #4303 (#4332) 2016-11-10 21:43:50 -08:00
Johann Kellerman
2c39c39d52 Improve async generic camera's error handling (#4316)
* Handle errors

* Feedback

* DisconnectedError
2016-11-10 21:43:48 -08:00
Paulus Schoutsen
6e6b1ef7ab fix panasonic viera doing I/O in event loop (#4341) 2016-11-10 21:42:41 -08:00
Pascal Vizeli
55ddaf1ee7 Synology SSL fix & Error handling (#4325)
* Synology SSL fix & Error handling

* change handling for cookies/ssl

* fix use not deprecated functions

* fix lint

* change verify

* fix connector close to coro

* fix force close

* not needed since websession close connector too

* fix params

* fix lint
2016-11-10 21:42:37 -08:00
Pascal Vizeli
6860d9b096 Update SoCo to 0.12 (#4337)
* Update SoCo to 0.12

* fix req
2016-11-10 21:41:28 -08:00
Sean Dague
3e1cc4282e Fix "argument of type 'NoneType' is not iterable" during discovery (#4279)
* Fix "argument of type 'NoneType' is not iterable" during discovery

When yamaha receivers are dynamically discovered, there config is
empty, which means that we need to set zone_ignore to [] otherwise the
iteration over receivers fails.

* Bump rxv library version to fix play_status bug

rxv version 0.3 will issue the play_status command even for sources
that don't support it, causing stack traces during updates when
receivers are on HDMI inputs.

This was fixed in rxv 0.3.1. Bump to fix bug #4226.

* Don't discovery receivers that we've already configured

The discovery component doesn't know anything about already configured
receivers. This means that specifying a receiver manually will make it
show up twice if you have the discovery component enabled.

This puts a platform specific work around here that ensures that if
the media_player is found, we ignore the discovery system.
2016-11-10 21:41:28 -08:00
Jan Losinski
200bdb30ff Change pilight systemcode validation to integer (#4286)
* Change pilight systemcode validation to integer

According to the pilight code the systemcode should be an integer and
not a string (it is an int in the pilight code). Passing this as a
string caused errors from pilight:
"ERROR: elro_800_switch: insufficient number of arguments"

This fixes #4282

* Change pilight unit-id to positive integer

According to the pilight code the unit of an entity is also evrywhere
handled as an integer. So converting and passing this as string causes
pilight not to work.

This fixes #4282

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>
2016-11-10 21:41:28 -08:00
Paulus Schoutsen
eb17ba970c Increase update delay (#4321) 2016-11-10 21:41:28 -08:00
Paulus Schoutsen
ffe4c425af Fix Tellstick doing I/O inside event loop (#4268) 2016-11-10 21:41:28 -08:00
Jesse Newland
a18fdbfbb8 Fix alarm.com I/O inside properties (#4307)
* Fix alarm.com I/O inside properties

* First line should end with a period

* Not needed

* Fetch state on init
2016-11-10 21:41:28 -08:00
Lewis Juggins
58600f25b3 Fix OWM async I/O (#4298) 2016-11-10 21:41:28 -08:00
Pascal Vizeli
749fc583ea Fix rest switch default template (#4331) 2016-11-10 21:32:08 -08:00
Daniel Høyer Iversen
b07d887d77 Add support for rgb light in led flux, fixes issue #4303 (#4332) 2016-11-10 21:30:52 -08:00
Johann Kellerman
9bb94a4512 Improve async generic camera's error handling (#4316)
* Handle errors

* Feedback

* DisconnectedError
2016-11-10 21:28:22 -08:00
Paulus Schoutsen
e76d553513 fix panasonic viera doing I/O in event loop (#4341) 2016-11-10 21:17:44 -08:00
Pascal Vizeli
844799a1f7 Synology SSL fix & Error handling (#4325)
* Synology SSL fix & Error handling

* change handling for cookies/ssl

* fix use not deprecated functions

* fix lint

* change verify

* fix connector close to coro

* fix force close

* not needed since websession close connector too

* fix params

* fix lint
2016-11-10 21:04:47 -08:00
Pascal Vizeli
e005ebe989 Update SoCo to 0.12 (#4337)
* Update SoCo to 0.12

* fix req
2016-11-10 21:01:42 -08:00
Sean Dague
e9d19c1dcc Fix "argument of type 'NoneType' is not iterable" during discovery (#4279)
* Fix "argument of type 'NoneType' is not iterable" during discovery

When yamaha receivers are dynamically discovered, there config is
empty, which means that we need to set zone_ignore to [] otherwise the
iteration over receivers fails.

* Bump rxv library version to fix play_status bug

rxv version 0.3 will issue the play_status command even for sources
that don't support it, causing stack traces during updates when
receivers are on HDMI inputs.

This was fixed in rxv 0.3.1. Bump to fix bug #4226.

* Don't discovery receivers that we've already configured

The discovery component doesn't know anything about already configured
receivers. This means that specifying a receiver manually will make it
show up twice if you have the discovery component enabled.

This puts a platform specific work around here that ensures that if
the media_player is found, we ignore the discovery system.
2016-11-10 20:44:38 -08:00
Jan Losinski
7d2ab4fce6 Change pilight systemcode validation to integer (#4286)
* Change pilight systemcode validation to integer

According to the pilight code the systemcode should be an integer and
not a string (it is an int in the pilight code). Passing this as a
string caused errors from pilight:
"ERROR: elro_800_switch: insufficient number of arguments"

This fixes #4282

* Change pilight unit-id to positive integer

According to the pilight code the unit of an entity is also evrywhere
handled as an integer. So converting and passing this as string causes
pilight not to work.

This fixes #4282

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>
2016-11-10 13:14:40 -08:00
Pascal Vizeli
ba2ea35089 Add logging to platform/component setup (#4300)
* Add timeout to platform/component

* Revert "Add timeout to platform/component"

This reverts commit 280a311e48.

* Add logging data

* Change log message with paulus comments
2016-11-10 18:46:31 +01:00
Erik Eriksson
ade62faa38 Don't fail if component name is None. Fixes (#4334)
https://github.com/home-assistant/home-assistant/issues/4326

Might fix https://github.com/home-assistant/home-assistant/issues/4326
2016-11-10 08:46:32 -08:00
Finbarr Brady
ee322dbbdc Cisco IOS device tracker support (#4193) 2016-11-09 22:36:57 +02:00
John Arild Berentsen
0d4141bf13 Add missing Index labels (#4328) 2016-11-09 19:11:24 +01:00
Christopher Viel
d404ac8978 Add support for off script to WOL switch (#4258) 2016-11-09 08:44:30 -08:00
Pascal Vizeli
71da21dcc8 Change pending task sheduler to time based cleanup (#4324)
* Change pending task sheduler to time based cleanup

* update unittest
2016-11-09 08:41:17 -08:00
Paulus Schoutsen
04dbc992ec Increase update delay (#4321) 2016-11-09 07:21:58 -08:00
Paulus Schoutsen
6d0e08cf7d Fix KNX async I/O (#4267) 2016-11-08 21:00:33 -08:00
Paulus Schoutsen
1e0025acae Fix Tellstick doing I/O inside event loop (#4268) 2016-11-08 20:25:19 -08:00
Pascal Vizeli
8fc853ba11 Add more unittest for async_add_job (#4320)
* Add more unittest for async_add_job

* fix test

* lint
2016-11-08 20:01:05 -08:00
sustah
8cbb8f6527 Update dlink.py (#4317)
corrected "total consumption" units from W to kWh
2016-11-08 19:58:27 -08:00
Jesse Newland
4f86c9ecda Fix alarm.com I/O inside properties (#4307)
* Fix alarm.com I/O inside properties

* First line should end with a period

* Not needed

* Fetch state on init
2016-11-08 19:57:46 -08:00
Lewis Juggins
9561fed650 Fix Dark Sky async I/O (#4299) 2016-11-08 19:46:44 -08:00
Lewis Juggins
67b599475e Fix OWM async I/O (#4298) 2016-11-08 18:57:56 -08:00
Pascal Vizeli
114ece1848 Fix possible sigterm / unittest / Fix all lazy test (#4297)
* replace weakref with a list

* add unittest

* fix lint

* fix handling

* fix unittest

* change code style

* fix lazy tests
2016-11-08 10:24:50 +01:00
Fabian Affolter
c05815cced Upgrade sqlalchemy to 1.1.3 (#4277) 2016-11-07 23:08:17 -08:00
Pascal Vizeli
2e0c185740 Async cleanup part 3 (#4302) 2016-11-07 22:31:40 -08:00
Johann Kellerman
231ef40f53 iOS links (#4295) 2016-11-08 00:07:24 +01:00
Fabian Affolter
b4159c7dc9 Upgrade python-digitalocean to 1.10.1 (#4276) 2016-11-06 23:49:25 -08:00
Fabian Affolter
8cc5fc1369 Upgrade psutil to 5.0.0 (#4275) 2016-11-06 23:49:11 -08:00
Paulus Schoutsen
fc3235fb6d Merge pull request #4271 from home-assistant/release-0-32-2
Release 0 32 2
2016-11-06 23:40:06 -08:00
David-Leon Pohl
d129df93dd Hotfix #4272 (#4273) 2016-11-06 23:34:45 -08:00
David-Leon Pohl
67336a111b Hotfix #4272 (#4273) 2016-11-06 23:34:32 -08:00
Paulus Schoutsen
0af1a96f14 Lint 2016-11-06 23:24:25 -08:00
andyat
272899ec96 Fix setting temperature in Celsius on radiotherm CT50 (#4270) 2016-11-06 23:21:08 -08:00
andyat
7d28d9d6b4 Fix setting temperature in Celsius on radiotherm CT50 (#4270) 2016-11-06 23:18:06 -08:00
Paulus Schoutsen
6a92e27e2f Version bump to 0.32.2 2016-11-06 23:12:37 -08:00
Paulus Schoutsen
faceb4c1dc Sequential updates for non-async entities 2016-11-06 23:12:20 -08:00
Paulus Schoutsen
6d5f00098a Move Honeywell I/O out of event loop (#4244) 2016-11-06 23:09:31 -08:00
Pascal Vizeli
618a86a37c Set executor to 15 and help to reduce flooting async core with updates (#4252)
* Set executor to 15 and help to reduce flooting async core with udpates

* fix typing

* if it a executor, wait

* address comments from paulus

* add space for style :)

* fix spell

* Update entity_component.py

* Update entity_component.py
2016-11-06 22:28:03 -08:00
Paulus Schoutsen
880ef8af48 Remove broken disable verify ssl synology (#4269) 2016-11-06 22:17:56 -08:00
William Scanlon
95124c7ddb Revert "Catch AttributeError on Wink PubNub update" (#4263) 2016-11-06 20:05:42 -08:00
William Scanlon
0aba227300 Catch AttributeError (#4253) 2016-11-06 16:04:57 -08:00
Martin Hjelmare
734bd75fd3 Fix mysensors overwriting gateway in GATEWAYS (#4013)
GATEWAYS was a dict, so would overwrite item if key was the same. This
would happen when using multiple MQTT gateways, since the device id is
the same (`mqtt`).

* Fix by changing GATEWAYS from dict into list.
* Use hass data to store mysensors gateways instead of having GATEWAYS
  be a global.
2016-11-06 10:49:43 -08:00
Frantz
0c5e077091 Updated netdisco to 0.7.6 (#4250) 2016-11-06 10:43:13 -08:00
Nicolas Graziano
1ed2f8ae91 Update braviarc to 0.3.6 (#4246)
Add HDMI sources.
Sources ordered.
2016-11-06 09:27:55 -08:00
Paulus Schoutsen
a343c20404 Async gather wait (#4247)
* Fix config validation for input_*, script

* Allow scheduling coroutines

* Validate entity ids when entity ids set by platform

* Async: gather -> wait

* Script/Group: use async_add_job instead of create_task
2016-11-06 09:26:40 -08:00
Antoine Bertin
d4e8b831a0 Add mqtt_template light component (#4233)
* Add mqtt_template component

* Docstring copy paste party on overriden methods

* pep8 E501 🌟

* Add missing docstrings on unittests
2016-11-06 09:09:01 -08:00
Paulus Schoutsen
98f41d6b84 Tweak block_till_done (#4245) 2016-11-06 08:43:32 -08:00
Paulus Schoutsen
7774a03a55 Move Honeywell I/O out of event loop (#4244) 2016-11-06 07:53:54 -08:00
Fabian Affolter
c35e5c9997 Upgrade astral to 1.3 (#4238) 2016-11-06 07:36:16 -08:00
Fabian Affolter
5d862e426e Upgrade fuzzywuzzy to 0.14.0 (#4240) 2016-11-06 07:36:03 -08:00
William Scanlon
bab8d574fe Wink Thermostat support and NoneType error fixes (#4175) 2016-11-06 07:27:15 -08:00
Fabian Affolter
c980d26aae Upgrade distro to 1.0.1 (#4239) 2016-11-06 14:00:41 +02:00
Paulus Schoutsen
08f75f7935 Merge pull request #4235 from home-assistant/release-0-32-1
0.32.1
2016-11-05 17:09:10 -07:00
Brent Hughes
1ad14b8227 Updated Emulated_Hue to send request info as variables to scripts (#4010)
* Updated Emulated_Hue to send request info as variables to scripts

* Updated tests to not use the old mqtt

* Updated test to actualy use and validate the script variables

* Fixed the removal of time in a recent merge

* fixed test to not use a timer
2016-11-05 17:08:54 -07:00
Pascal Vizeli
382ac5c3b5 Async cleanups with new handling and executor (#4234) 2016-11-06 01:01:03 +01:00
Paulus Schoutsen
af297aa0dc Version bump to 0.32.1 2016-11-05 17:00:06 -07:00
Paulus Schoutsen
20e1b3eae0 Fix radiotherm I/O inside properties (#4227) 2016-11-05 16:59:52 -07:00
Paulus Schoutsen
28861221ae Remove chunked encoding (#4230) 2016-11-05 16:59:52 -07:00
Pascal Vizeli
f367c49fb9 Sonos fix for slow update (#4232)
* Sonos fix for slow update

* fix auto update on discovery

* fix unittest
2016-11-05 16:59:52 -07:00
Pascal Vizeli
ad8645baf4 Sonos fix for slow update (#4232)
* Sonos fix for slow update

* fix auto update on discovery

* fix unittest
2016-11-05 16:58:29 -07:00
Paulus Schoutsen
62785c2431 More async tests (#4223)
* Annotate test callbacks to be async

* Convert device_sun_light_trigger to be async
2016-11-05 16:36:20 -07:00
Paulus Schoutsen
22c3d014aa Remove chunked encoding (#4230) 2016-11-05 15:29:22 -07:00
Paulus Schoutsen
3f3127a290 Fix radiotherm I/O inside properties (#4227) 2016-11-05 13:28:11 -07:00
Danijel Stojnic
88fc64c8a0 Add Map support for Locative component (#4174)
* Add Map support for Locative component

The Locative App on the mobile is sending an HTTP request to the
server where also the GPS location is sent.
But the GPS location was not passed to the event device_tracker.see.

Use the passed GPS location from Locative and pass it to the
device_tracker.see event.

With this the device is then also shown on the HA Map component.

* Use existing constants for latitude and longitude

Use the existing constants from homeassistant.consts:

ATTR_LATITUDE for 'latitude'
ATTR_LONGITUDE for 'longitude'

* Reuse the "yield from self.hass.loop.run_in_executor" again

* Use variable gps_location
2016-11-05 13:05:15 -07:00
Samuel Bétrisey
1463fc4fe0 Add Swisscom Internet-Box device tracker (#4123)
* Add Swisscom Internet-Box device tracker

* Add Swisscom device tracker to .coveragerc

* Add timeout to requests
Fix formatting and add missing comments to pass the lint test

* Remove authentication which was not required

I realised that there was no need to be authenticated to get the
connected devices. Thanks Swisscom :/

* Moving config to a PLATFORM_SCHEMA and using voluptuous
2016-11-05 13:04:44 -07:00
Pascal Vizeli
ece58ce78f Remove ThreadPool with async executor (#4154)
* Remove ThreadPool with async executor

* Fix zigbee

* update unittest

* fix remote api

* add pending task to remote

* fix lint

* remove unused import

* remove old stuff for lazy tests

* fix bug and add a exception handler to executor

* change executor handling

* change to wait from gather

* fix unittest
2016-11-05 09:27:55 -07:00
Paulus Schoutsen
b67f1fed52 Version bump to 0.33.0.dev0 2016-11-05 08:53:13 -07:00
Paulus Schoutsen
4770888d22 Merge pull request #4166 from home-assistant/dev
0.32
2016-11-05 08:52:57 -07:00
Paulus Schoutsen
1d0f3b930f Version bump to 0.32.0 2016-11-05 08:40:32 -07:00
Paulus Schoutsen
22e2262f8e Merge remote-tracking branch 'origin/master' into dev 2016-11-05 08:40:04 -07:00
William Scanlon
53d1a040d4 Stop Octoprint from logging errors during startup (#4220)
* Fix log errors

* Remove discovery code
2016-11-05 07:55:59 -07:00
Fabian Affolter
d7d71c97e2 Make the wind details more robust (weather.openweathermap) (#4215)
* Make the wind details more robust

* Return None if values is not available
2016-11-05 09:15:59 +01:00
Paulus Schoutsen
c15fd4323e Disable insteon hub (#4221) 2016-11-04 23:38:27 -07:00
Pascal Vizeli
91227d9a2e Refactory nest component/platforms (#4219)
* Refactory nest component/platforms
2016-11-04 20:22:47 -04:00
jbcodemonkey
a3db0ec231 add dimmer slide control to imported isy lights (#4152)
Supported attribute added and checks appear to pass. 🐬
2016-11-04 15:28:22 -06:00
Paulus Schoutsen
18e965c3cd Fix flaky group notify test (#4212) 2016-11-03 22:56:55 -07:00
Paulus Schoutsen
4cc417677e Add link to issue in warning slow entity update (#4211) 2016-11-03 22:45:01 -07:00
Paulus Schoutsen
525d735f21 Warn if fetching properties takes too long (#4208)
* Warn if fetching properties takes too long

* Update entity.py
2016-11-03 21:58:25 -07:00
Paulus Schoutsen
e88b98f5fa Clean up tests (#4209) 2016-11-03 21:58:18 -07:00
Lewis Juggins
6f68752d1e Speed up Sonos tests (#4196) 2016-11-03 21:23:37 -07:00
Fabian Affolter
61a0976752 Use port instead of url and fix PEP257 issues (#4192) 2016-11-03 18:43:42 -07:00
Pascal Vizeli
d7b3c9c38e Fix log owntrack log flooting (#4198) 2016-11-03 18:42:22 -07:00
jgriff2
a01939c6e9 Fix Synology Camera SSL certificate option (#4201) [BREAKING CHANGE]
* Fix Synology SSL config

* Revert "Fix Synology SSL config"

This reverts commit b8dc2a92abee6249b3dd42c99d0786820ebbeb72.

* Revert "Fix Synology SSL config"

This reverts commit 805e87f3af300a1b7627bb5df0792285fcf38901.

* Fix Synology SSL config
2016-11-03 18:41:32 -07:00
Fabian Affolter
c128919b5f Remove globally disabled pylint warnings (#4204) 2016-11-03 18:40:43 -07:00
Pascal Vizeli
e5d69feb93 Fix blocking/stack trace with empty list (#4191) 2016-11-03 18:33:18 -07:00
Paulus Schoutsen
ee5f228309 Make services yield (#4187)
* Make services yield

* Disable pylint abstract-method check

* add input_select

* add input_slider

* change to async vers.

* fix lint

* yield on add_entities as other components does
2016-11-03 18:32:14 -07:00
John Arild Berentsen
15dde7925a Prevent multiple instances of device initialzed (#4179) 2016-11-03 13:08:23 +01:00
Pascal Vizeli
fcf318cf53 Bugfix windows have a other default loop now (#4195)
* Bugfix windows have a other default loop now

* fix handling with 3.4.2 that not support ensure_future

* make the same as ensure_future does

* fix spell

* fix lazy test
2016-11-03 11:07:47 +01:00
Pascal Vizeli
c2a5f63b1f Bugfix async Yr.no (#4190) 2016-11-03 11:09:03 +02:00
Fabian Affolter
79fa2d4175 CUPS sensor (#4142)
* Add CUPS sensor

* Use CupsData

* Fix requirement
2016-11-03 09:31:50 +01:00
Erik Eriksson
214a18f08c Support for Dovado routers (#4176)
* Implemented support for the Dovado router

* Update .coveragerc
2016-11-02 21:20:21 -07:00
Ferry van Zeelst
ded2ea8b19 Synology DSM sensor (#4156)
* Added Synology DSM Sensor

* Fixed balloobbot's comments

* Fixed mistake (should have run lint and flake8 before committing

* Fixed update mechanisme according to balloobs feedback

* Requesting retest as test failure isn't related to changes made
2016-11-02 21:17:29 -07:00
Paulus Schoutsen
1d100dcac9 Bugfix/frontend group urls (#4185)
* Remove unnecessary sleeps

* Frontend: fix serving index when refreshing view page.
2016-11-02 21:15:23 -07:00
Bart274
a3ae96440b Update the icloud device_tracker (#4081)
* Update the icloud device_tracker

* addressed @kellerza 's comments

* GMTT config needs an entity_id

* renamed services

* fix cookiedir and clean up keep_alive function

* fix travis errors

* forgot a self.

* update devices after initializing the API

* changed wording

* addressed changes from @kellerza

* Syntax error solved

* Update icloud.py

* Only use account of username instead of whole username as default for account name

* use slugify instead of slug for schema

* remove Google Maps Travel Time

* Add comment from original tracker back
2016-11-02 21:07:23 -07:00
devdelay
0235626f40 yet another command_line sensor update (#4184) 2016-11-02 21:00:32 -07:00
Paulus Schoutsen
d7dd7df5e7 Update frontend 2016-11-02 20:39:42 -07:00
Nicolas Graziano
1e28851280 Media player BraviaTv : Try to connect only if tv is not in off state. (#4140)
When HA is restart with the TV in off state there was error log every 10s until the TV is set ON.
2016-11-02 19:51:53 -07:00
bestlibre
df68de8032 Influxdb sensor state set to unknown if query return no points (#4148)
* Influxdb sensor state set to unknown if query return no points

* Update influxdb.py
2016-11-02 19:50:18 -07:00
Johann Kellerman
f3595f790a Async version of Yr.no (#4158)
* initial

* feedback

* More feedback. Still need to fix match_url

* url_match

* split_lines
2016-11-02 19:34:12 -07:00
Johann Kellerman
0d14920758 Component setup error messages with markdown (#3919)
* Remove_dev_link_async

* callback
2016-11-02 19:31:09 -07:00
Paulus Schoutsen
2940fb72fb EntityComponent.add_entities now converts generators to a list (#4183) 2016-11-02 19:24:25 -07:00
Daniel Perna
8e0838adeb Added support for Philips TVs with jointSPACE API (#4157)
* Added support for Philips Tvs with JointSpace API

* Flake + Lint fixes

* Lint be like "lol fu"

* Changes as requested by reviewers, except lib-requirement

* Switched to library-usage

* lint... newline-bingo...
2016-11-02 19:19:53 -07:00
Paulus Schoutsen
4e820ea30a Move mocks to async_start (#4182) 2016-11-02 19:16:59 -07:00
Pascal Vizeli
26490109ac Change event loop on windows (#4075)
* Change event loop on windows

* fix

* split PR

* remove set event loop

* Add paulus suggestion

* fix missing import

* revert stuff from PR Splitting

* fix event loop on test
2016-11-02 21:53:52 +01:00
Georgi Kirichkov
e4a713207d Fixes in TP-Link Switch logging 0 values on init (#4026)
* Fixes in TP-Link Switch logging 0 values on init

On init of component the emeter would log to influxdb and possibly other inputs a 0 value, instead of not logging anything.
Initial polling should circumvent that behavior and avoid logging inconsistencies.

* Refactors update call in __init__
2016-11-02 12:23:43 -07:00
Greg Dowling
cc0d0a38d7 Get temparature units from vera controller. (#4130)
Alrighty 👯‍♀️
2016-11-02 14:20:44 +01:00
Erik Eriksson
afde5a6b26 extracted logic into an external package. monitor more attributes. support for more than one vehicle (#4170) 2016-11-01 22:01:00 -07:00
Lewis Juggins
a5fb284717 Add new_device_discovered event (#4132) 2016-11-01 21:52:27 -07:00
Johann Kellerman
e487a09190 Remove None value before writing known_devices (#4098)
* Remove None

* Replace null
2016-11-01 21:51:31 -07:00
Jan Losinski
52eb816c62 Introduce a send_delay for pilight component (#4051)
* Add a method to throttle calls to services

This adds CallRateDelayThrottle. This is a class that provides an
decorator to throttle calls to services. Instead of the Throttle in
homeassistant.util it does this by delaying all subsequent calls
instead of just dropping them. Dropping of calls would be bad if we
call services to actual change the state of a connected hardware (like
rf controlled power plugs).

Ihe delay is done by rescheduling the call using
track_point_in_utc_time from homeassistant.helpers.event so it should
not block the mainloop at all.

* Add unittests for CallRateDelayThrottle

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>

* Introduce a send_delay for pilight component

If pilight is used with a "pilight USB Nano" between the daemon and the
hardware, we must use a delay between sending multiple signals.
Otherwise the hardware will just skip random codes. We hit this
condition for example, if we switch a group of pilight switches on or
off. Without the delay, random switch signals will not be transmitted by
the RF transmitter.

As this seems not necessary, if the transmitter is directly connected
via GPIO, we introduce a optional configuration to set the delay.

* Add unittests for pilight send_delay handling

This adds an unittest to test the delayed calls to the send_code
service.
2016-11-01 21:50:27 -07:00
Jason Carter
90d894a499 Garadget (#4031)
* Initial attempt at implementation

* Adding Garadget cover component

* Updating Device to be Required

* Updating .coveragerc to exclude from testing

* Updating code review items

* Updating per 2nd code review

* Updating configuration to be more like command-line
2016-11-01 21:49:27 -07:00
Jon Caruana
ba13951fff Add LiteJet (a lighting control system) component (#4125)
* Initial submission of LiteJet integration.

* Add LiteJet switch pressed automation trigger. (State changes are too slow to catch a press-release.)
Add LiteJet scene, replacing commented out code that treated these as lights.
Include LiteJet numbers in the device state so that it is easy to lookup entity -> number.

* Fix missing global.

* Allow light's brightness to be set explicitly.

* Support optional 'ignore' key to ignore prefixes of loads, switches, and scenes that weren't configured for use in the LiteJet system.

* Fix lint errors and warnings.

* Cleanup header comments.
Default to not creating LiteJet switches as these are generally not useful.

* Lint fixes.

* Fixes from pull request feedback.

* Use hass.data instead of globals for data storage.

* Fix lint warnings.
2016-11-01 20:44:25 -07:00
Sean Dague
2a7b7ebd6a Merge pull request #3985 from postlund/yamaha_additions
Improve support for Yamaha receiver
2016-11-01 21:50:03 -04:00
Bjarni Ivarsson
df7d9c3bb2 Fallback to read volume and mute state from speaker. (#4173) 2016-11-01 15:12:18 -07:00
Bjarni Ivarsson
c549ea115d Sonos responsiveness improvements + enhancements (#4063)
* Sonos responsiveness improvements (async_ coroutines, event based updating, album art caching) + Better radio station information

* Docstring fixes.

* Docstring fixes.

* Updated SoCo dependency + fixed file permissions.

* Only fetch speaker info if needed.

* PEP8 fixes

* Fixed SoCoMock.get_speaker_info to get test to pass.

* Regenerated requirements_all.txt + async fetching of album art with caching + added http_session to HomeAssistant object.

* Unit test fixed.

* Add blank line as per flake8

* Fixed media image proxy unit test.

* Removed async stuff.

* Removed last remnants of async stuff.
2016-11-01 10:42:38 -07:00
Fabian Affolter
dad54bb993 Update to make the sample file validate (#4168) 2016-11-01 15:11:42 +01:00
Fabian Affolter
0211cf29eb Change behavior to be more natural and fix test (#4150) 2016-11-01 10:43:48 +01:00
Nicholas Sideras
1d9ac5f8b3 Update __init__.py (#4155)
Changed manifest.json to respect Android screen rotate lock.
2016-10-31 13:04:54 -07:00
Paulus Schoutsen
7f699b4261 Lazy initialise the worker pool (#4110)
* Lazy initialise the worker pool

* Minimize pool initialization in core tests

* Fix tests on Python 3.4

* Remove passing in thread count to mock HASS

* Tests: Allow pool by default for threaded, disable for async

* Remove JobPriority for thread pool

* Fix wrong block_till_done

* EmulatedHue: Remove unused test code

* Zigbee: do not touch hass.pool

* Init loop in add_job

* Fix core test

* Fix random sensor test
2016-10-31 08:47:29 -07:00
Paulus Schoutsen
a1e910f1cf Disable rest switch tests 2016-10-31 08:22:49 -07:00
Fabian Affolter
b4899ec469 Allow multiple symbols (sensor.yahoo_finance) (#4126)
* Allow multiple symbols

* Update test
2016-10-31 13:31:09 +01:00
John
06de7053ce Add Emby Server media_player component (#3862)
* Add Emby Server media_player component

* Code cleanup, move to request sessions, generate UUID per session

* Make media image fetch more robust

* Allow for http or https

* Cleanup some Keyerror conditions found through more testing

* Move EmbyRemote to pip, update requirements

* Code cleanup, add SSL config option
2016-10-31 13:29:08 +01:00
Fabian Affolter
4484a7a94b Use voluptuous for Pilight switch (#3819)
* Migrate to voluptuous

* Add protocol

* Update
2016-10-31 13:18:47 +01:00
Jared Beckham
a89e635bf3 Added tests for REST switches (#4016)
* Added tests for REST switches

* Remove REST switch from test coverage exclusions
2016-10-31 13:14:23 +01:00
Daniel Høyer Iversen
3ab056ba69 Merge pull request #4149 from home-assistant/flux_led_library
flux led lib
2016-10-31 11:56:00 +01:00
Daniel
5ba815ab21 flux led lib 2016-10-31 09:23:34 +01:00
Fabian Affolter
274e9799b3 Add random number sensor (#4139) 2016-10-31 00:01:25 -07:00
Jared Beckham
5ce9aea65d Added tests for REST sensors (#4115) 2016-10-30 21:51:03 -07:00
Michael
705814cb08 Catch all errors when doing mqtt message unicode-decode. (#4143)
* catch all errors when doing mqtt message unicode-decode.

* added AttributeError and UnicodeDecodeError to exception when decoding an mqtt message payload
2016-10-30 23:17:41 +01:00
Alok Saboo
8e695d1eb0 Fixed typo (#4145) 2016-10-30 23:13:27 +01:00
Fabian Affolter
be272ac64a Disable too-many-* (#4107)
* Disable too-many-* and too-few-public-methods

* Remove globally disabled pylint warnings
2016-10-30 22:18:53 +01:00
Fabian Affolter
b910a9917d Migrate to async (sensor.statistics) (#4138)
* Migrate to async

* Add async_ prefix and remove stale print
2016-10-30 18:56:26 +01:00
Fabian Affolter
9649097b32 Migrate to async (sensor.min_max) (#4136)
* Migrate to async

* Add async_ prefix
2016-10-30 16:45:53 +01:00
Fabian Affolter
5e76a51db4 Migrate to async (#4135) 2016-10-30 15:23:47 +01:00
Fabian Affolter
27abac85b6 Migrate to async (sensor.time_date) (#4100)
* Migrate to async

* Update acc. #4114
2016-10-30 15:21:23 +01:00
Fabian Affolter
9f2aae1357 Maintenance 2nd (#4106)
* Add link to docs

* Fix link

* Update line breaks

* Update ordering

* Align vera platofrm to only use add_devices
(instead od add_devices_callback)

* Remove line break

* Use consts

* Update ordering

* Update ordering

* Use const, create default name, use string formatting

* Update ordering

* Use const

* Update import style

* Update ordering and line breaks

* update line breaks

* Set default port

* Set defaults and update ordering

* Update ordering

* Minor style updates

* Update ordering, defaults, line breaks, and readability

* Use constants

* Add line breaks

* use string formatting

* Update line breaks

* Update logger
2016-10-30 09:58:34 +01:00
Adam Mills
e6ece4bf6d Fix initialization of zwave color bulbs (#4085)
* Fix initialization of zwave color bulbs

Zwave values can be added to the node in any order. This change allows
proper initialization when the multilevel value is added before the
color value.

* Fix incorrect rename of color command class
2016-10-29 17:14:28 -07:00
Hydreliox
aea2d1b317 Add support for Yeelight Wifi bulbs (#4065)
* Add support for Yeelight Wifi bulbs

* Fix cache property in instance
2016-10-29 17:03:26 -07:00
Pierre Ståhl
33e46b484f Add service to change visibility of a group (#3998) 2016-10-29 16:54:26 -07:00
wokar
3f6a5564ad lg_netcast platform fails to load if no channels defined (#4083)
* fixes loading of lg_netcast platform if no channels are defined

* turned list comprehension into for loop
2016-10-29 16:52:53 -07:00
Erik Eriksson
3317b4916b OSError is alias for IOException and base class for many other exceptions - no need to catch redundant exceptions if OSError already present in except-clause (#4111) 2016-10-29 15:33:56 -07:00
Pascal Vizeli
9c0455e3dc Allow update entities on add_entities callback (#4114)
* Allow udpate entities on add_entities callback

* fix wrong position

* update force_update to update_before_add

* add unittest for update_befor_add

* fix unittest

* change mocking
2016-10-29 15:33:11 -07:00
Fabian Affolter
5d43d3eb1c Fix error message (#4122) 2016-10-29 15:30:23 -07:00
Paulus Schoutsen
4163e55dbd Introducing hass.data (#4121)
* Hello hass.data

* Migrate setup_component to hass.data
2016-10-29 14:51:17 -07:00
Paulus Schoutsen
3cc4fdaa34 Fix HTTP static file singular (#4118) 2016-10-29 14:45:31 -07:00
Pascal Vizeli
edeb31d74e Fix bug with aioHTTP and none authentification (#4116) 2016-10-29 22:47:46 +02:00
Fabian Affolter
54d19e3c53 Maintenance (sensor.currencylayer, sensor.fixer) (#4103)
* Add new const (base)

* Use constant

* Remove second error message, use const, add attribution, add link
to docs, remove unused vars, and a little simplification

* Add quote

* Use const

* Add attribution, simplify the code, and use consts
2016-10-29 13:27:02 -07:00
Fabian Affolter
892f455aee Maintenance (sensor.bitcoin, sensor.yahoo_finance) (#4104)
* Add attribution

* Update ordering

* Update ordering
2016-10-29 13:21:09 -07:00
Fabian Affolter
942d630762 Maintenance zoneminder (#4102)
* Add timeout to requests, fix typos, and defaults

* Clean-up
2016-10-29 13:10:42 -07:00
Paulus Schoutsen
9ea1101aba Fix bootstrap circular imports (#4108)
* Fix bootstrap circular imports

* fix test

* Lint
2016-10-29 12:54:47 -07:00
Pascal Vizeli
08a65a3b31 Async input_*/zone migration (#4095)
* Async input_*

* Async zone component

* rename service callback
2016-10-29 12:19:27 -07:00
Fabian Affolter
d4b3f56d53 Maintenance (#4101)
* UPdate ordering, fix typos, and align logger messages

* Update import style, fix PEP257 issue, and align logger messages

* Updaate import style and align logger messages

* Update import style and align logger messages

* Update ordering

* Update import style and ordering

* Update quotes

* Make logger messages more clear

* Fix indentation
2016-10-29 09:12:43 -07:00
Paulus Schoutsen
5a2b4a5376 Core Async improvements (#4087)
* Clean up HomeAssistant.start

* Add missing pieces to remote HA constructor

* Make HomeAssistant constructor async safe

* Code cleanup

* Init websession lazy
2016-10-29 08:57:59 -07:00
Sean Dague
9d836a115a Add zone_ignore option for yamaha. (#4091)
* Add zone_ignore option for yamaha.

We attempt to discover all zones for yamaha receivers. There are times
when users may want to suppress some zones from showing up. When a
Zone isn't actually connected to speakers, or on some newer receivers
where Zone_4 is an HDMI only zone, that doesn't support even basic
media_player UI.

This provide a mechanism for users to do that.

Fixes #4088

* Update yamaha.py
2016-10-28 19:18:31 -07:00
Fabian Affolter
bf92aedd38 Add hddtemp sensor (#4092) 2016-10-28 19:06:24 -07:00
devdelay
230c3815f2 Update command_line sensor to use STATE_UNKNOWN (#4093) 2016-10-28 19:03:40 -07:00
Pascal Vizeli
9afe066ec8 Fix name in openalpr cloud api (#4097) 2016-10-28 19:01:14 -07:00
Pascal Vizeli
66541a6a19 Update ha-ffmpeg to version 0.15 (#4096) 2016-10-29 00:12:53 +02:00
Pascal Vizeli
825ee3612d fix some comments spell (#4082)
* fix some comments

* fix in an executor

* address paulus comments
2016-10-28 21:26:52 +02:00
Abhishek Anand
65bd7d2326 Generalized REST switch to enable templating and configurable timeout. (#3329)
* successfully tested the "remote temperature mode" switch for the radio thermostat

* removed logging and interpreted None as Off.

* turn_off value is also templated now -- can depend on state

Also, undid accidental removal of error logging.

* ensured backward compatibility of config file

if value_template is not provided, the update function behaves as before

* ran autopep8 --in-place

* fixed another complaint of tox

* addressed the comments of balloob

* undid acccidental log.error to log.info

* timeout : 50 -> 10

* added a timeout parameter

* removed the stray '-', better names for the failure case

* string comparisons after .lower(), as suggested by balloob

* addressed balloob's latest requests

* making flake happy

* value_template --> is_on_template in config file

* moved CONF_IS_ON_TEMPLATE to local file

* null checks

* addressed flake error

* properly comparing template text when is_on is not a template.
2016-10-27 22:34:22 -07:00
John Arild Berentsen
d8c1013b09 Zwave climate, add operating state to attributes (#4069)
* Zwave climate, add operating state to attributes

* Reversed assisgnment
2016-10-27 22:25:17 -07:00
Fabian Affolter
02d1dc6247 Upgrade psutil to 4.4.2 (#4079) 2016-10-27 22:22:43 -07:00
Paulus Schoutsen
726d950522 Update aiohttp.py 2016-10-27 21:45:35 -07:00
Pascal Vizeli
3324995e70 Async clientsession / fix stuff on aiohttp and camera platform (#4084)
* add websession

* convert to websession

* convert camera to async

* fix lint

* fix spell

* add import

* create task to loop

* fix test

* update aiohttp

* fix tests part 2

* Update aiohttp.py
2016-10-27 21:40:10 -07:00
Fabian Affolter
85747fe2ef Upgrade python-telegram-bot to 5.2.0 (#4080) 2016-10-27 21:28:09 -07:00
Pascal Vizeli
09db875ace Fix async bug in automation (#4078) 2016-10-27 18:26:55 +02:00
bestlibre
7d407756c3 Converting unit_of_measurement variable to optional, to be consistent with other sensors (#4076) 2016-10-27 08:50:36 -07:00
Richard Cox
91d682d02c Adding ssl option to zoneminder (#4074) 2016-10-27 15:54:03 +02:00
Benoit BESSET
b75c103db4 fixed Up/Down (#4064) 2016-10-27 12:10:38 +02:00
Richard Cox
bba323d226 [media_player/onkyo] host should be optional (#4073) 2016-10-27 10:33:35 +02:00
Paulus Schoutsen
7564d539c1 Lint 2016-10-27 00:37:02 -07:00
Paulus Schoutsen
33439aaa22 Update frontend 2016-10-27 00:21:55 -07:00
Pascal Vizeli
d5368f6f78 Async bootstrap / component init (#3991)
* Async bootstrap

* Adress comments

* Fix tests

* More fixes

* Tests fixes
2016-10-27 00:16:23 -07:00
Simon Szustkowski
d9999f36e8 Added a ThingSpeak component (#4027)
* Added a ThingSpeak component

* Forgot a colon. Fixed it

* Some config variables are better required

* New requirements created by the script

* Updated the .coveragerc

* Fixed small linting errors

* Removed unneccessary validation

* Even more linting error fixes

* Changed the way the component listens to state changes

* Removed unneccessary declaration of 'state' variable, referring to new_state instead
2016-10-26 23:56:51 -07:00
Pierre Ståhl
235e1a0885 Minor improvements to RPi camera platform (#4059)
* Try to create output file instead of checking write permissions

* Kill raspistill process during shutdown
2016-10-26 23:51:13 -07:00
Paulus Schoutsen
541fec0534 Sort .coveragerc alphabetically. 2016-10-26 23:50:11 -07:00
bestlibre
b3ad7989ae Influxdb sensor (#4060)
* Influxdb sensor with voluptuous configuration validation

* Adding sensor to coveragerc since there is no test for now
2016-10-26 23:48:57 -07:00
Sean Dague
3d897e0e52 Add discovery for yamaha component (#4061)
This uses the discovery code from netdisco/ha to discover yamaha
receivers. The old discovery code remains if discovery is turned of in
HA, at least for now. Though it probably is worth turning that off in
the future.
2016-10-26 23:46:44 -07:00
Alok Saboo
c6d5987109 Create Currencylayer exchange rate sensor (#4062)
* Added Currencylayer exchange rate sensor

* Updated .coveragerc to include currencylayer

* Update currencylayer.py

* Added Conf_name
2016-10-26 23:46:13 -07:00
Matthew Treinish
5d3956ea98 Cleanup use of MQTT in emulated_hue tests (#4068)
* Use unix newlines on test_emulated_hue

This commit switches the test_emulated_hue module to use unix newlines
instead of the DOS style that were there before. (using dos2unix on
the file) This makes it consistent with the other files in the repo.

* Cleanup emulated_hue tests

Previously these tests relied on the mqtt light platform as test devices
to control with the emulated hue. However, this was pretty heavyweight
and required running an MQTT broker in the tests. Instead this commit
switches it to use the demo light platform which is strictly in memory.

Fixes #3549
2016-10-26 23:33:43 -07:00
Marcelo Moreira de Mello
4fb0b27310 Wunderground sensor with alerts exceeds API limits (#4070)
* Fixes issue #4067 - Wunderground sensor with alerts exceeds API limits

 To avoid hitting the max limit of 500 calls per day, this patch keeps weather conditions being updated each 5 minutes
  and weather advisories each 15 minutes.

 This formula will result the following:

   conditions -> 300 seconds -> 5 minutes -> 12 req/h -> 288 req/day
   alerts -> 900 seconds -> 15 minutes -> 4 req/h -> 96 req/day

* Using timedelta in minutes instead seconds
2016-10-26 23:31:49 -07:00
Paulus Schoutsen
4833e992fb Pin cython==0.24.1 (#4057) 2016-10-25 23:38:32 -07:00
Paulus Schoutsen
fe3aed0f0c Update .coveragerc 2016-10-25 23:32:58 -07:00
Paulus Schoutsen
57402bcb43 Update .coveragerc 2016-10-25 23:30:43 -07:00
Scott O'Neil
7f48c00793 Adding timer setting functionality to sonos component (#3941)
* Adding timer setting functionality to sonos component

* Adding clear sleep timer for Sonos
2016-10-25 23:22:17 -07:00
Paulus Schoutsen
f58647849a Fix Z-Wave: Pin cython in Dockerfile (#4055) 2016-10-25 23:17:34 -07:00
Marcelo Moreira de Mello
1f468fc94d If no weather advisories were issued, state should return 0 instead Unknown (#4029)
* If no weather advisories were issued, state should return 0 instead Unknown

* Updated to keep on the same if statement

* Revert "Updated to keep on the same if statement"

This reverts commit 0e6a94aa0f.
2016-10-25 22:49:51 -07:00
Bjarni Ivarsson
961c02f72a Sonos improvements (#3997)
* Sonos improvements: media_* properties delegate to coordinator if speaker is a slave, media_image_url and media_title now works for radio streams, source selection/list takes speaker model into account, commands on slaves delegate to coordinator.

* Fixed failing unit tests.
2016-10-26 00:37:47 +02:00
Robbie Trencheny
79da1ec0d9 Merge pull request #4037 from home-assistant/remove-deprecated-things
Remove deprecated things
2016-10-25 14:28:01 -07:00
Robbie Trencheny
fe174402d2 Remove more deprecated things 2016-10-25 14:16:08 -07:00
Matthew Treinish
1b2dfb8ed1 Handle FreeBSD version in updater component (#4048) 2016-10-25 22:38:22 +02:00
Pierre Ståhl
297a6f6f03 Improve support for Yamaha receiver
* Playback (play, pause, stop, next, previous)

* Media title, artist and album
2016-10-25 20:53:04 +02:00
Per Sandström
0dfcf40d37 [WIP] Config validation error line numbers (#3976)
Config validation error line numbers
2016-10-25 20:13:32 +02:00
Fabian Affolter
d308ea69ce Upgrade yahoo-finance to 1.3.2 (#4040) 2016-10-25 08:36:20 -07:00
Sean Dague
a8c5c995a0 Merge pull request #4042 from sdague/typo
fix typos in script module strings
2016-10-25 07:40:11 -04:00
Sean Dague
86b318e992 fix typos in script module strings
It looks like some copy / paste in docstrings, clean them up for
posterity.
2016-10-25 07:20:40 -04:00
Bart274
53ea926292 Fix for see service attributes (#4023) 2016-10-25 10:59:20 +02:00
Robbie Trencheny
2b1f4123db Update requirements_all.txt 2016-10-24 22:36:04 -07:00
Robbie Trencheny
b36e346ccb Fix helpers.state tests 2016-10-24 22:33:54 -07:00
Adam Mills
89e8fb4066 Configurator support for entity_picture (#4028) 2016-10-24 22:28:34 -07:00
David-Leon Pohl
e2d23d902a Unittests for ddwrt device tracker and bugfix (#3996)
* BUG Message data cannot be changed thus use voluptuous to ensure format

* Pilight daemon expects JSON serializable data

Thus dict is needed and not a mapping proxy.

* Add explanation why dict as message data is needed

* Use more obvious voluptuous validation scheme

* Pylint:  Trailing whitespace

* Pilight sensor component

* Python 3.4 compatibility

* D202

* Use pytest-caplog and no unittest.TestCase

* Fix setup/teardown of unittests

* Activate coverage testing

* Bugfix whitelist filter and use bugfixed pilight library

* Use newest pilight library that has a bugfix

* Add unittest for pilight hub component

* PEP257 for docstrings

* Bugfix setting device name from host name and small cleanup

- Init with connection error handling is more clear
- Comments clean-up

* PEP257

* New unittest with full coverage

* Upload missing testfixtures

* D209

* Handle double quotes in reply

* Formatting
2016-10-24 22:18:24 -07:00
Fabian Affolter
2604dd89a6 Add test (#3999) 2016-10-24 22:01:38 -07:00
Robbie Trencheny
044b9caa76 Remove garage_door, hvac, rollershutter and thermostat components/platforms 2016-10-24 22:00:43 -07:00
Daniel Perna
1707cdf9f3 Added support for Notifications for Android TV / FireTV (#3978)
* Added support for Notifications for Android TV / FireTV

* Silly me forgot to commit coverage

* Fixed pylint

* Fixed flake8

* Fixed another flake8 -.-

* Changed option 'ip' to 'host' like most other platforms do
2016-10-24 21:59:09 -07:00
Fabian Affolter
4c86721e70 Update tests, rename variable, and change conversion (#3546) 2016-10-24 21:53:03 -07:00
Matthew Treinish
0ff500ca25 Add mochad component (#3970)
This commit adds a new component for communicating with mochad[1] a
socket interface for the CM15A and CM19A USB X10 controllers. This
commit leverages the pymochad library to interface with a mochad socket
either on a local or remote machine. Mochad is added as as a generic
platform because it supports multiple different classes of device,
however in this patch only the switch device implemented as a starting
point. Future patches will include other devices types. (although
that's dependent on someone gaining access to those)

[1] https://sourceforge.net/projects/mochad/
2016-10-24 21:49:49 -07:00
Robbie Trencheny
23f54b07c7 Dont load notify.ios if no devices exist. Thanks @arsaboo for catching this. 2016-10-24 18:46:47 -07:00
Robbie Trencheny
f25ddef4d7 More iOS HTTP Async updates 2016-10-24 17:31:45 -07:00
Robbie Trencheny
7158919346 Missed a wsgi->http on iOS component 2016-10-24 15:03:51 -07:00
Fabian Affolter
627517cbbc Upgrade psutil to 4.4.0 (#4032) 2016-10-24 22:24:33 +02:00
Fabian Affolter
4ecfc7d066 Upgrade sqlalchemy to 1.1.2 (#4003) 2016-10-24 22:00:22 +02:00
Fabian Affolter
72751b95b5 Upgrade slacker to 0.9.29 (#4000) 2016-10-24 22:00:02 +02:00
Fabian Affolter
fc3b7907ed Upgrade python-telegram-bot to 5.1.1 (#4001) 2016-10-24 21:59:48 +02:00
Paulus Schoutsen
f26a7fc6bb Update http 2016-10-24 00:09:20 -07:00
Robbie Trencheny
0c563f7b14 Minor updater... updates (#4020)
* Enable updater in dev versions

* Code clarity

* Add log line about being on the current version already

* Remove dev check test
2016-10-24 00:01:56 -07:00
Paulus Schoutsen
519d9f2fd0 async HTTP component (#3914)
* Migrate WSGI to asyncio

* Rename wsgi -> http

* Python 3.4 compat

* Move linting to Python 3.4

* lint

* Lint

* Fix Python 3.4 mock_open + binary data

* Surpress logging aiohttp.access

* Spelling

* Sending files is a coroutine

* More callback annotations and naming fixes

* Fix ios
2016-10-23 23:48:01 -07:00
Paulus Schoutsen
3701ac292c Merge pull request #4017 from home-assistant/release-0-31-1
0.31.1
2016-10-23 21:57:38 -07:00
Lewis Juggins
1db18478d2 Exclude dirs/files prefixed with . (#3986) 2016-10-23 21:08:56 -07:00
Robbie Trencheny
3230869f74 Fix a spelling problem on user-facing error 2016-10-23 20:34:31 -07:00
Robbie Trencheny
9aa88819a5 Fix a spelling problem on user-facing error 2016-10-23 20:33:49 -07:00
Paulus Schoutsen
3e92318cb2 Version bump to 0.31.1 2016-10-23 19:20:30 -07:00
Johann Kellerman
f0a38dded6 Catch UnicodeDecodeError Error (#4007)
* Catch UnicodeDecodeError Error

Error for #3933

* Forgot (exc)

* catch...

* Tests by @lwis

* Docstring

* Create open
2016-10-23 19:20:13 -07:00
Robbie Trencheny
c32f47aea6 iOS component hotfixes (#4015)
* iOS component hot fixes around component/platform loading, logging, and more

* Load device_tracker and zeroconf in deps instead of bootstraping

* Change conditional check on status code
2016-10-23 19:18:13 -07:00
Robbie Trencheny
626763a7c3 iOS component hotfixes (#4015)
* iOS component hot fixes around component/platform loading, logging, and more

* Load device_tracker and zeroconf in deps instead of bootstraping

* Change conditional check on status code
2016-10-23 19:17:34 -07:00
Johann Kellerman
5df8477536 Catch UnicodeDecodeError Error (#4007)
* Catch UnicodeDecodeError Error 

Error for #3933

* Forgot (exc)

* catch...

* Tests by @lwis

* Docstring

* Create open
2016-10-23 18:55:06 -07:00
Fabian Affolter
1f89e6ddba Upgrade pytz to 2016.7 (#4002) 2016-10-23 20:51:41 +02:00
Lewis Juggins
13ab2be5f6 Exclude dirs/files prefixed with . (#3986) 2016-10-23 16:47:06 +02:00
Robbie Trencheny
2bc84af87e Version bump to 0.32.0.dev0 2016-10-22 15:23:01 -07:00
Robbie Trencheny
ef2ed7bfc9 Merge pull request #3937 from home-assistant/dev
0.31
2016-10-22 15:22:07 -07:00
Robbie Trencheny
6040a40af2 Update version 2016-10-22 15:09:05 -07:00
jbags81
fb352c20d9 Update wink.py (#3957)
* Update wink.py

added lambda and smoke detector call in component loading routine to fix broken functionality.

* Update wink.py

fixed extra space.

* Update wink.py

applied cleaner refactor per comments

* Update wink.py

fixed spacing

* Update wink.py

fixed lint error #1
2016-10-22 16:59:20 -04:00
John Arild Berentsen
678f30def1 Prevent Verisure cam to delete a file when it is None (#3988) 2016-10-22 21:01:12 +02:00
Paulus Schoutsen
0fce5ccc7f Update frontend 2016-10-22 11:24:06 -07:00
John Arild Berentsen
02afc98668 Prevent zwave from firing event at shutdown (#3987) 2016-10-22 14:08:24 +02:00
Eric Hagan
57777ef79a Adds support for Pioneer AVR interface port number (#3878)
* Adds support for Pioneer AVR interface port number

https://community.home-assistant.io/t/support-for-pioneer-avr/503
telnetlib supports a port number so adding port as
an optional config element with a default of 23 resolves this.

* Adds timeout to Pioneer AVR

timeout in telnetlib defaults to socket._GLOBAL_DEFAULT_TIMEOUT
which is not a value, but rather a bare Object used for comparison.

telnetlib says the following about the timeout optional argument:
"The optional timeout parameter specifies a timeout in seconds
 for blocking operations like the connection attempt (if not
 specified, the global default timeout setting will be used)."

From the documentation for sockets:
"Sockets are by default always created in blocking mode"

Catching connect and timeout errors, logging to debug
and continuing.

* Catches timeout exceptions, logs and continues.
2016-10-22 11:05:00 +02:00
Paulus Schoutsen
ca6fa1313e Fix updater, add new fields (#3982)
* Fix updater

* Add Docker and virtualenv checks

* Add log line informing user of update/analytics

* Remove str
2016-10-21 23:30:40 -07:00
Robbie Trencheny
ea91d24eb2 HA iOS support (#3752)
* Initial commit of the iOS component and platform

* Allow extra

* Add battery to identify, a new function to get devices, and load the upcoming sensor

* Add iOS sensor platform, currently for battery state & level

* Add discoverability for the iOS app

* Convert single quote to double quotes

* Load all required components and platforms when loading the iOS component for the best experience

* Unify quote style to double

* Change to hass_ios

* Update push URL, add support for logging based on status code, log rate limit updates

* Block iOS from coverage checks for now...
2016-10-21 23:20:15 -07:00
Brent Hughes
6e5a3c0a94 Fixed statsd stopping if state is not numeric or only attributes changed (#3981)
* Fixed statsd stopping if attribute changed by not the state

* Fixed tests which exposed a new bug.

* Fixed another issue. whoops
2016-10-21 23:18:13 -07:00
dasos
754d536974 Work better with password-protected Squeezebox / LMS servers (#3953)
* Work better with password-protected Squeezebox / LMS servers, including getting file art. Refactored to only have a single method calling the telent lib. (Should make it easier to convert to the more appropriate JSON interface)

* Update squeezebox.py

* Update squeezebox.py

* Update squeezebox.py

* Update squeezebox.py

* Update squeezebox.py
2016-10-21 22:37:35 -07:00
Georgi Kirichkov
4f6ed09a99 Adds energy monitoring capabilities to the TP-Link HS110 (#3917)
* Adds energy monitoring capabilities to the TP-Link HS110

Energy monitoring works only on the HS110 model

* Reverts to using GadgetReactor's module

* Updates requirements_all.txt

* Refactors tplink switch to use attribute caching

* Update tplink.py
2016-10-21 21:45:36 -07:00
Johann Kellerman
8d375e2d47 Improve known_device.yaml writing (#3955)
* Better known_device.yaml writing

* yaml dump
2016-10-21 21:41:27 -07:00
Hydreliox
1d2d338cd0 Add Bbox Router bandwidth as sensors (#3956)
* Add Bbox Routeur bandwidth as sensors

Add possibility to monitor max and currently used bandwidth of your xdsl connection for Bbox Routeur

* Minor Fixes

Unit constant get back into the main sensor file

* Unused round removed
2016-10-21 21:34:22 -07:00
Hugo Dupras
cb47507002 Add support for Neato Connected robot as a switch (#3935)
* Add support for Neato Connected robot as a switch

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Add checklist items

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Add missing docstring

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* [Neato] Add update function to retrieve robot state

* Add docstring for update function + catch exception when retrieving state

* Change type of HTTPError when updating state

* Fix pylint errors
2016-10-21 21:14:45 -07:00
Fabian Affolter
fae620f3b3 Migrate to voluptuous (#3748) 2016-10-21 21:14:35 -07:00
Paulus Schoutsen
b821a82417 Merge remote-tracking branch 'origin/master' into dev 2016-10-21 20:57:07 -07:00
Paulus Schoutsen
da7837af73 Update frontend 2016-10-21 20:52:58 -07:00
Johann Kellerman
6e903fd429 Updater component - rename opt_out to reporting (#3979)
* Updater component - rename opt_out to reporting

* Fix tests
2016-10-21 20:40:23 -07:00
Martin Hjelmare
9f7e167669 Fix test using libsodium and SECRET_KEY (#3975)
* Move test to class with custom config setups and with config
  validation.
2016-10-21 20:23:29 -07:00
John Arild Berentsen
54a64fb8d9 Add support for verisure file camera. (#3952) 2016-10-21 22:41:17 +02:00
Nick Vella
2d89c3ecf4 Telstra SMS API notification component (#3949)
* Telstra API component

* import PLATFORM_SCHEMA

* Exclude Telstra notify component in coveragerc

* fix authentication issues

* Include title in SMS if it's provided

* pass lint

* Fix many code styling issues

* Confirm credentials are correct on component setup
2016-10-20 23:47:21 -07:00
Teemu Mikkonen
9f6d1c4e7b Device tracker: SNMPv3 (#3961)
* Add initial SNMPv3 support for better security

* Fixed indentation errors

* Fixed flake8 E128 on row 65

* Disabled warning about too many instance-attributes

* Removed extra code, added Inclusive to make better config validation
2016-10-20 23:01:30 -07:00
AlucardZero
62b8e54235 Upgrade SoCo to 0.12 (#3951)
Changelog: https://github.com/SoCo/SoCo/releases/tag/v0.12

Backwards Compatability changes:

    Dropped support for Python 3.2
    Methods relating to the music library (get_artists, get_album_artists, get_albums and others) have been moved to the music_library module. Instead of device.get_album_artists(), please now use device.music_library.get_album_artists() etc. Old code will continue to work for the moment, but will raise deprecation warnings
    Made a hard deprecation of the Spotify plugin since the API it relied on has been deprecated and it therefore no longer worked
    Dropped pylint checks for Python 2.6
2016-10-20 22:51:00 -07:00
Dustin S
1ceac8407d Adding security contexts to the resources. (#3840) 2016-10-20 22:43:39 -07:00
Jason Carter
0c0b02eb3d Moving updates out of state property (#3966) 2016-10-20 22:35:25 -07:00
Johann Kellerman
c70722dbae Updater component with basic system reporting (#3781) 2016-10-20 21:30:44 +02:00
Martin Hjelmare
a05fb4cef8 Upgrade pymysensors to 0.8 (#3954) 2016-10-20 20:56:26 +02:00
Marcelo Moreira de Mello
fee01fcccc Added unit test to the Yahoo Finance sensor (#3943) 2016-10-20 20:14:50 +02:00
henryk
2b37b4251b Fritzbox - Only report a MAC address if it's really there (#3964)
Fixes 'Neither mac or device id passed in'
2016-10-20 20:04:11 +02:00
Fabian Affolter
3aa1b6a3f8 Fix PEP257 issues (#3962) 2016-10-20 19:10:12 +02:00
Pascal Vizeli
c32afcd961 Bugfix sonos (#3926)
* Bugfix Sonos

* lint

* Use player uid for looking of exists

* fix lint

* fix unittest

* Change player_id to unique_id
2016-10-20 08:36:48 -07:00
hcooper
d60c2d604f Add support for multiple inputs to nmap tracking module as a list (#3944) 2016-10-20 07:15:00 +02:00
David-Leon Pohl
081e61528d Bugfixes for pilight hub component and unit tests (#3948) 2016-10-19 22:02:11 +02:00
Richard Cox
5799d1aec9 Fixing verbage (#3940) 2016-10-18 18:25:47 -07:00
Adam Mills
7d32e5eeeb Logbook filtering of automations by entity_id (#3927)
* Logbook filtering of automations by entity_id

* Trigger action function parameters required
2016-10-18 18:11:35 -07:00
Johann Kellerman
57f32fa629 Fixup device_tracekt.mqtt voluptuous & unit tests (#3904) 2016-10-18 18:10:28 -07:00
Sean Dague
7da47852d4 Yamaha zones (#3920)
* Enhance yamaha component

This enhances the yamaha component to create 1 player per zone,
instead of only one play, which provides direct control of the various
zones for the player.

It also exposes play_media for NET_RADIO sources, which allows direct
setting of that.

This requires code changes in rxv 0.2.0, so the requirement dependency
is raised.

* Support current playback metadata for NET_RADIO

When on NET RADIO, support the currently playing information.
2016-10-18 18:04:15 -07:00
Justin Weberg
f1b658ea5d Fix Typo (#3942) 2016-10-18 17:59:14 -07:00
Pascal Vizeli
754e93ff6a Rename add_devices to async_add_devices like dev guide (#3938) 2016-10-19 00:35:22 +02:00
David-Leon Pohl
947c1efca2 New pilight sensor component (#3822)
* Pilight daemon expects JSON serializable data. Thus dict is needed and not a mapping proxy.
* Add explanation why dict as message data is needed
* Use pytest-caplog and no unittest.TestCase
2016-10-18 23:16:20 +02:00
hexa-
a1239077d9 Add support for matrix notifications (#3827) 2016-10-18 21:13:00 +02:00
Paulus Schoutsen
53b5dc8e84 Build frontend 2016-10-18 09:10:22 -07:00
Lewis Juggins
09bcd7321a Reset Bravia playing info to ensure state reflects correctly (#3903) 2016-10-17 23:13:35 -07:00
Pascal Vizeli
14ef0ca786 Bugfix Template sensors (#3931) 2016-10-18 07:27:32 +02:00
Rob Capellini
272539105f Replacing tempfile with mock_open in tests (#3753)
- test_bootstrap.py
- test_config.py
- components/test_init.py
- components/test_panel_custom.py
- components/test_api.py
- components/notify/test_file.py
- components/notify/test_demo.py
- components/camera/test_local_file.py
- helpers/test_config_validation.py
- util/test_package.py
- util/test_yaml.py

No changes needed in:
- components/cover/test_command_line.py
- components/switch/test_command_line.py
- components/rollershutter/test_command_line.py
- components/test_shell_command.py
- components/notify/test_command_line.py

Misc changes in:
- components/mqtt/test_server.py

Also, removed some unused mock parameters in tests/components/mqtt/test_server.py.
2016-10-17 20:16:36 -07:00
Fabian Affolter
7d67017de7 Upgrade python-digitalocean to 1.10.0 (#3921) 2016-10-17 20:13:43 -07:00
juggie
d921073e77 Ecobee - Celsius (#3906)
* #3899 - Ecobee tempoeratures

* #3899 Remove unused import

* #3899 Implement min/max_temp in ecobee.py as these temperatures have to be in F for ecobee api.

* #3899 Stale print

* #3899 Use min/max_temp from base class

* #3899 Removed unused import (again) so tests pass since changing to use super class

* #3899 Fix long lines

* #3899 Install tox locally... make it happy, commit

* #3899 Remove overridden min/max_temp and instead update __init__:min/max_temp to convert to self.temperature_unit (of the thermostat) as opposed to self.unit_of_measurement (of the system), which is wrong

* Remove unused import from ecobee
2016-10-17 20:06:03 -07:00
Jason Carter
9cf2acb495 Concord232 alarm panel (#3842)
* Adding Concord232 Alarm Panel

* Adding Concord232 Zones as Sensors

* Updating requirements_all.txt

* Adding DOCType and making helper function a closure for clarity

* Fixing D400 error in build

* Fixing pylint errors

* Adding # pylint: disable=too-many-locals

* Updating with proper polling methods

* Fixing Merge issues

* Fixing DocStyle Issue

* Moving Import out of setup

* Fixing DocString

* Removing overthought GLOBAL
2016-10-17 19:59:41 -07:00
Giel Janssens
3b424b034a Netatmo thermostat (#3888)
* Added Netatmo-thermostat

* Remove-CONF_DEVICES
2016-10-17 19:57:02 -07:00
Marcelo Moreira de Mello
76598bc4d2 #3829 - Fixed issued LowHighTuple doesn't define __round__ method for Nest Sensor (#3881)
* #3829 - Fixed type LowHighTuple doesn't define __round__ method issue when Nest is operating in range mode

* Testing if temperature is a tuple instead int or float
2016-10-17 19:55:53 -07:00
William Scanlon
c54476b62f Protocol is an int (#3928) 2016-10-17 19:53:50 -07:00
sam-io
ae8a8e22ad Support for Apple Push Notification Service (#3756)
* added push notification implementation

* some lint changes

* added docs

* added push notification implementation

* some lint changes

* added docs

* Fixed comment formatting issues

* Added requirments

* Update requirements_all.txt

* Update apns.py

* re-generated requirments_all.txt

* Added link to online docs

* added push notification implementation

* some lint changes

* added docs

* added push notification implementation

* some lint changes

* added docs

* Fixed comment formatting issues

* Added requirments

* Update requirements_all.txt

* Update apns.py

* re-generated requirments_all.txt

* Added link to online docs

* changed to use http/2 library for push notifications

* fixed lint issue

* fixed test that fails on CI

* another go at fixing test that fails on CI

* another go at fixing test that fails on CI

* another go at fixing test that fails on CI

* added missing docstring

* moved service description to main services.yaml file

* renamed apns service
2016-10-17 19:41:49 -07:00
Paulus Schoutsen
4c8d1d9d2f Clean up some async stuff (#3915)
* Clean up some async stuff

* Adjust comments

* Pass hass instance to eventbus
2016-10-17 19:38:41 -07:00
Sean Dague
daea93d9f9 Suppress requests/urllib3 connection pool log messages (#3854)
requests/urllib3 is notorious for using the INFO log level for very
DEBUG kinds of information. Given the configurability of python
logging it's actually pretty easy to just set requests to WARN by
default. This cleans out a bunch of largely unuseful log lines from
home assistant output.
2016-10-17 21:14:10 +02:00
Pascal Vizeli
1540bb1279 Async template (#3909)
* port binary_sensor/template

* port sensor/template

* port switch/template

* fix unittest

* fix

* use task instead yield on it

* fix unittest

* fix unittest v2

* fix invalid config

* fix lint

* fix unuset import
2016-10-17 07:00:55 +02:00
Jan Harkes
555e533f67 Added tests for the template is_defined filter 2016-10-17 03:20:07 +02:00
Jan Harkes
118f2f0bad Use a filter to fail rendering undefined variables
Instead of globally using StrictUndefined, introduce a filter that
will trigger a render failure on undefined variables.

Use as `{{ value_json.someval | is_defined }}`.
2016-10-17 03:20:07 +02:00
Jan Harkes
c8add59ea5 Fail when rendering undefined objects in Jinja2 templates
By not successfully rendering unknown objects to an empty string
the caller provided error_value actually gets used.

This allows, for instance, the MQTT sensor to retain its state when an
unexpected or unwanted message (#2733/#3834) is received.
2016-10-17 03:20:07 +02:00
Willems Davy
18f5258aaf Emoncms history component (#3531)
* Emoncms_history component, fix git mess

* - switch to track_point_in_time to send all data at foxed interval
- don't use json_dump
- switch to http post instead of http get
2016-10-16 17:05:01 -07:00
Justin Weberg
207c9e8575 Fix Comment (#3913) 2016-10-16 16:56:02 -07:00
Rob Capellini
4891ca1610 Removing calls to mock.assert_called_once_with (#3896)
If a mock's assert_called_once_with method is misspelled (e.g. asert_called_once_with) then the test will appear as passing.  Therefore, this commit removes all instances of assert_called_once_with calls and replaces them with two assertions:

        self.assertEqual(mock.call_count, 1)
        self.assertEqual(mock.call_args, mock.call(call_args))
2016-10-16 16:13:27 -07:00
Lewis Juggins
10c9132046 Resolve issue with delay not passing variables to render (#3901) 2016-10-16 16:08:12 -07:00
Fabian Affolter
71ee847aee Add web scrape sensor (#3841)
* Add web scrape sensor

* Add support for 'value_template', set 'verify_ssl' to true,
and remove 'before', 'after' & 'element'

* Fix pylint issue
2016-10-16 16:06:07 -07:00
Per Sandström
d9ae7ceb0c Tellstick switch force update (#3874) 2016-10-16 15:56:55 -07:00
Justin Weberg
2a972b2334 Move micromarkdown to HA (#3908)
* Move micromarkdown to HA

* Fix requests

* Update micromarkdown-js.html& .gz

* Update micromarkdown-js files
2016-10-16 15:47:34 -07:00
Pascal Vizeli
7484152be1 Async speedup add_device callback (#3910)
* Speed up entities processing from add_device callback

* fix lint

* fix bug
2016-10-17 00:35:57 +02:00
Paulus Schoutsen
6581dc2381 Document more core pieces 2016-10-16 13:45:17 -07:00
Paulus Schoutsen
31ec0ac6a7 Add util.async to the dev docs 2016-10-16 13:35:01 -07:00
John Arild Berentsen
8b2edc1514 ZWave: Add association service (#3894)
* Add association service

* Refactor service

* Requested changes

* Grammar in pydocstyle
2016-10-16 20:36:06 +02:00
Adam Mills
2612c6d6b8 Zwave alt delay workaround for HS-WD100+ (#3893) 2016-10-16 20:35:39 +02:00
Pascal Vizeli
0b8b9ecb94 Async EntitiesComponent (#3820)
* first version

* First draft component entities

* Change add_entities to callback from coroutine

* Fix bug add async_prepare_reload

* Group draft v1

* group async

* bugfix

* bugfix v2

* fix lint

* fix extract_entity_ids

* fix other things

* move get_component out of executor

* bugfix

* Address minor changes

* lint

* bugfix - should work now

* make group init async only

* change update handling to old stuff

* fix group handling, remove generator from init

* fix lint

* protect loop for spaming with updates

* fix lint

* update test_group

* fix

* update group handling

* fix __init__ async trouble

* move device_tracker to new layout

* lint

* fix group unittest

* Test with coroutine

* fix bug

* now it works 💯

* ups

* first part of suggestion

* add_entities to coroutine

* change group

* convert add async_add_entity to coroutine

* fix unit tests

* fix lint

* fix lint part 2

* fix wrong import delete

* change async_update_tracked_entity_ids to coroutine

* fix

* revert last change

* fix unittest entity id

* fix unittest

* fix unittest

* fix unittest entity_component

* fix group

* fix group_test

* try part 2 to fix test_group

* fix all entity_component

* rename _process_config

* Change Group to init with factory

* fix lint

* fix lint

* fix callback

* Tweak entity component and group

* More fixes

* Final fixes

* No longer needed blocks

* Address @bbangert comments

* Add test for group.stop

* More callbacks for automation
2016-10-16 09:35:46 -07:00
Fabian Affolter
a0fdb2778d Fix name allocation (#3890) 2016-10-16 18:07:34 +02:00
Fabian Affolter
5ef8ca9b03 Upgrade sendgrid to 3.6.0 (#3887) 2016-10-16 09:09:48 +02:00
Fabian Affolter
a10fa90357 Update link to docs repo (#3886) 2016-10-15 13:46:45 +02:00
Fabian Affolter
9743e17d62 Minimum/maximum/mean sensor (#3852)
* Add min/max sensor

* Update min_max.py
2016-10-14 21:43:46 -07:00
Marcelo Moreira de Mello
6fcb1b548e Added the ability to Weather Underground to track severe weather alerts (#3505)
*  Added the ability to Weather Underground to track severe weather alerts

*   * Added message on the advisory attr

  * Updated tests

* * Making use of guard clause

* Checking multiple_alerts prior loop

* Using a better way to create dict

* Fixed issue to set to None only the object that failed

* Added unittest

* Split update() method to different calls with their one throttle control to minimize API calls

* Updated unittest and make sure the alert sensor will not return 'unknown' status'

* Removed update() method from state property

* Branch rebased and include Weather Underground attribution

* Update wunderground.py
2016-10-14 21:35:27 -07:00
Adam Mills
1bf5554017 Zwave rgb fix (#3879)
* _zw098 must be set before update_properties

* Fix problematic zwave color light value matching

See https://community.home-assistant.io/t/color-issues-with-aeotec-zwave-zw098/2830
2016-10-14 21:17:48 -07:00
Georgi Kirichkov
49b1643ff0 Relaxes the configuration options for influxdb (#3869)
* Relaxes the configuration options for influxdb

By default influxdb allows unauthenticated access
Home Assistant required at least username and password to be present to properly submit data to influxdb

* Removes unused import of 'copy'

The copy module was used only in the removed test case responsible for testing the missing keys

* Updates InfluxDB config schema to require user and password

Current InfluxDB (v 1.0) can work without any authentication, but when authentication is enabled both username and password should be set.

* Removes extra white space in test_influxdb.py
2016-10-14 21:10:04 -07:00
Michael
ce19e6367f Catch MQTT encoding errors (#3749)
* added error handling to mqtt message receive if payload is not utf-8 unicode
added mqtt test for above code as well

* change permission back to 644

* attempting to test new code

* changed exception to AttributeError
fixed test for above

* fixed lint errors I made in tests....mqtt/test_init.py

* more lint fixes for my added test

* remove dual decode of MQTT payload

* convert if to try, except, else statement for mqtt payload decode

* rework mqtt unicode testing code to properly check for log file entriy on unicode decode exception

* fixed lint error

* Update test_init.py
2016-10-14 21:08:44 -07:00
Fabian Affolter
180e146e14 Upgrade uber_rides to 0.2.7 (#3876) 2016-10-14 21:00:27 -07:00
Fabian Affolter
bead274b20 Upgrade slacker to 0.9.28 (#3877) 2016-10-14 20:58:49 -07:00
Richard Cox
1cbf8c8049 Zoneminder component (#3795)
* Initial Zoneminder commit

* Fixing bug when ZM sets its function to 'None'

* Adding zoneminder to coverage

* Quick Doc fix

* Update zoneminder.py

Doc Fix

* making the url base optional
2016-10-14 20:56:40 -07:00
Lukas
ad259ead50 Add ignore option to zwave customize configuration (#3865) 2016-10-14 08:36:55 -07:00
Daniel Høyer Iversen
bb457f47cc Merge pull request #3868 from home-assistant/flux_led_lib
update flux led library
2016-10-14 11:41:18 +02:00
Daniel
df3e904fe7 update flux led library 2016-10-14 11:17:03 +02:00
Hugo Dupras
7697cdef0a Pushbullet push an url note if an url is provided inside data (#3758) 2016-10-14 00:11:48 -07:00
Igor Shults
6951b6f60b Allow any positive integer for Z-Wave polling intensity (#3859) 2016-10-14 00:09:52 -07:00
John Arild Berentsen
6ca0d4cd14 Use pass instead of return None (#3856) 2016-10-14 00:09:24 -07:00
Sean Dague
a5b756e1e5 Bump proliphix library to 0.4.0 (#3855)
There was a bug in setback setting which is now fixed in 0.4.0. This
ensures that any users have working setback code.
2016-10-14 00:06:53 -07:00
Sean Dague
7848791a04 add arwn sensor platform (#3846)
This adds a sensor component that builds sensors based on the arwn
project (https://github.com/sdague/arwn). This uses a 433mhz receiver
to collect weather data and publish it over mqtt in a well defined
schema, which home-assistant can display as sensors.
2016-10-14 00:06:04 -07:00
Paulus Schoutsen
f916fc04f9 Update frontend 2016-10-14 00:02:21 -07:00
John Arild Berentsen
8f4608c654 Use only node id to identify node in set_config_parameter (#3801) 2016-10-13 23:45:00 -07:00
Per Sandström
399a0b470a select next and previous of input select (#3839) 2016-10-13 21:53:47 -07:00
Jan Harkes
4d716cec2b Bump pychromecast dependency to 0.7.6 (#3864) 2016-10-13 21:24:54 -07:00
Lukas
1373db8b60 Include index and instance in object_id of zwave devices (#3759)
* Include index and instance in object_id of zwave devices

* Add the instance id if there is more than one instance for the value
2016-10-13 21:13:05 -07:00
Hydreliox
7771cc2ccf Add Bbox Modem Routeur for device tracker (#3848) 2016-10-13 19:43:51 -07:00
Per Sandström
c5ad7996fb Merge pull request #3857 from persandstrom/vsure0.11.1
vsure 0.11.1
2016-10-13 22:18:42 +02:00
Per Sandström
3d94f77998 vsure 0.11.1 2016-10-13 21:53:50 +02:00
Marcelo Moreira de Mello
6330d9cde6 Fixed Fitbit resting heart rate attribute (#3835)
* Fixed Fitbit restingHeartRate field to grab the correct field from dictionary

In [31]: r['activities-heart'][-1].get('value')
Out[31]:
{'customHeartRateZones': [],
 'heartRateZones': [{'caloriesOut': 126.18348,
   'max': 94,
   'min': 30,
   'minutes': 67,
   'name': 'Out of Range'},
  {'caloriesOut': 27.21339,
   'max': 131,
   'min': 94,
   'minutes': 5,
   'name': 'Fat Burn'},
  {'caloriesOut': 0, 'max': 159, 'min': 131, 'minutes': 0, 'name': 'Cardio'},
  {'caloriesOut': 0, 'max': 220, 'min': 159, 'minutes': 0, 'name': 'Peak'}],
 'restingHeartRate': 69}

In [32]: r['activities-heart'][-1].get('value').get('restingHeartRate')
Out[32]: 69

* Renamed sensor to Resting Heart Rate to match it

* Fixed lint style
2016-10-13 09:22:05 -07:00
Hugo Dupras
9a0bb62654 Hotfix for Netatmo discovery (#3837)
This should definetly fix #2601

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>
2016-10-13 09:21:22 -07:00
Fabian Affolter
d873a7baf0 Use async_render_* and fix config validation (#3847) 2016-10-13 09:20:49 -07:00
Robbie Trencheny
c663d85129 Add Alexa Flash Briefing Skill API support (#3745)
* Add Alexa Flash Briefing Skill API support

* Set default value for text to empty string as per API docs

* Clean up existing Alexa tests

* Update configuration parsing and validation

* Add tests for the Flash Briefing API

* Update test_alexa.py
2016-10-13 09:14:22 -07:00
John
8c13d3ed4c Update zwave lights to increase update delay timer as needed (#3741)
Fix permissions
2016-10-13 09:09:41 -07:00
Johann Kellerman
cb322f72db Add persistent notifications to bootstrap (#3738)
* Add persistent notifications to bootstrap

* Rebase, Fix test
2016-10-13 09:09:07 -07:00
Scott Reston
39a446c43c Proper title, added album and artist for Squeezebox (#3735)
* Proper title, added album and artist

Title had previously concatenated artist - title.

* Made changes suggested by @balloobbot
2016-10-13 09:07:10 -07:00
wokar
aa8622f8e8 Added include and exclude functionality to history component (#3674)
* added include and exclude functionality to history component

* fixed summary lines in test method doc.

* cleanup of query filter creation

* o improved config validation
o move move IGNORE_DOMAINS to Filter.apply()
o removed config from Last5StatesView
o Filters instance is now created on setup
o config values are processed in setup and set to the Filters instance
o function _set_filters_in_query() moved to Filters class and renamed to apply()

* added unittests for more include/exclude filter combinations

* make pylint happy
2016-10-13 08:54:45 -07:00
Vittorio Monaco
e031b8078f Fixes an issue where Chromecast audio groups were not properly discovered (#3630)
* Fixes an issue where Chromecast audio groups were not properly discovered

* Forgot to commit the main fix

* Removes unused variable

* Doesn't use a protected API anymore

* PR remarks

* Fixes tests, adds comment

* Restores line as it was in the original commit, rephrases comment

* Should fix lint issues

* Trailing whitespace

* Some more lint
2016-10-13 08:51:43 -07:00
jgriff2
e1647fb6ac Add synology ss cameras (#3626)
* Add files via upload

* Update .coveragerc

* test

* Update synology camera

* Use voluptuous for synology

* Use voluptuous for synology

* Use voluptuous for synology

* Use voluptuous for synology

* Conform synology to flake8

* Added Whitelist to synology

* Sync to dev branch

* Added helper function to synology
2016-10-13 08:49:58 -07:00
Lewis Juggins
10feac11d9 Support recursive config inclusions (#3783) 2016-10-12 12:05:41 +02:00
Paulus Schoutsen
d4e2332ce0 Merge pull request #3814 from home-assistant/release-0-30-1
0.30.2
2016-10-11 22:28:00 -07:00
Jean Regisser
1d7169403b Add again certifi to Docker image (#3813)
Latest versions of certifi (>= 2016.8.31) don't seem to break anything
anymore.
See home-assistant/home-assistant#2554
2016-10-11 22:25:17 -07:00
Keith Lamprecht
e4685de459 Restore Optional Target Config Attribute (notify.pushover) (#3769)
* Restore Optional Target Config Attribute

* Fix Tabs

* Change indents to spaces

* Make a target fix

* Change to simpler not syntax
2016-10-11 21:59:45 -07:00
Keith Lamprecht
d83de36c32 Restore Optional Target Config Attribute (notify.pushover) (#3769)
* Restore Optional Target Config Attribute

* Fix Tabs

* Change indents to spaces

* Make a target fix

* Change to simpler not syntax
2016-10-11 21:59:34 -07:00
Fabian Affolter
73547c8c4b Fix slack targets (#3826) 2016-10-11 21:58:54 -07:00
Fabian Affolter
40094cecae Fix slack targets (#3826) 2016-10-11 21:16:11 -07:00
Robbie Trencheny
0b327cd4d9 Notify: Only attach target if in call data (#3831)
* Only pass through the target if it has a value

* Target will no longer be none
2016-10-11 20:34:14 -07:00
Robbie Trencheny
d302dbec2d Notify: Only attach target if in call data (#3831)
* Only pass through the target if it has a value

* Target will no longer be none
2016-10-11 20:33:41 -07:00
Fabian Affolter
e135691bd6 Migrate to voluptuous (#3817) 2016-10-11 08:33:22 -07:00
Fabian Affolter
d4dc2707a1 Use voluptuous for eQ-3 thermostat (#3729)
* Migrate to voluptuous

* Fix requirement and typo
2016-10-11 11:27:31 +02:00
Paulus Schoutsen
a8cdf36d5c Update recorder callback (#3812) 2016-10-11 00:58:43 -07:00
Fabian Affolter
a99f36f519 Migrate to voluptuous (#3737) 2016-10-11 00:56:57 -07:00
Fabian Affolter
0568ef025b Use voluptuous for Heatmiser (#3732) 2016-10-11 00:53:24 -07:00
Fabian Affolter
8ded8f572a Add/adjust attribution of sensor platform (#3719)
* Add/adjust attribution

* Fix typo
2016-10-11 00:28:19 -07:00
Fabian Affolter
7cf2c48175 Use voluptuous for FitBit (#3686)
* Migrate to voluptuous

* Fix default
2016-10-11 00:27:15 -07:00
Fabian Affolter
7cf9ff83bc Migrate to voluptuous (#3293) [BREAKING CHANGE] 2016-10-11 00:26:11 -07:00
Paulus Schoutsen
dfe9af7110 Version bump to 0.30.2 2016-10-11 00:21:01 -07:00
Erik Eriksson
016e8f833d slugify (#3777) 2016-10-11 00:20:49 -07:00
Teemu Mikkonen
574df0f420 Fix for html5 notification tag problem. Fixes #3774 (#3790) 2016-10-11 00:20:49 -07:00
Pascal Vizeli
f18f181962 Hotfix device name with autodiscovery (#3791) 2016-10-11 00:20:49 -07:00
Ellis Percival
4754455295 Make 'pin' optional for zigbee device config. (#3799) 2016-10-11 00:20:49 -07:00
Robbie Trencheny
8c1317f278 Wrap found target in list (#3809)
* Wrap found target in list

* Fix test_messages_to_targets_route
2016-10-11 00:20:49 -07:00
Russell Cloran
7c2cb6cffd Separate climate platform and presentation units (#3755)
* Separate platform and presentation units in climate

* Fix unit tests

Maybe

* Fix unit tests some more

Maybe

* Rename _platform_unit_of_measurement to temperature_unit

* Fix tests for renamed attribute
2016-10-11 00:00:29 -07:00
Ferry van Zeelst
8c9d1d9af1 Added additional checks which hides functions which are not supported by Nest (#3751)
* Added additional checks which hides functions which are not support (like fans / humidity / cooling)

* Fixed pylint and flake8 errors (not test file available)

* Fixed pydocstyle error

* Refactored Code and Comments as described in pull-request

* Added additional comment and requesting retest

* Upgraded to python-nest 2.11 which contains previously hidden functions
2016-10-10 23:57:14 -07:00
Lukas
941fccd3fc Update python-lirc to 1.2.3 (#3784)
* Upgrade to latest python-lirc 1.2.3

* update requirements_all.txt
2016-10-10 23:44:41 -07:00
Clemens Wolff
711526e574 Cache condition in helpers.Script (#3797)
* Cache condition in helpers.Script

The caching is a simple in-memory, per-instance dictionary.
We use __str__ to format cache keys.

This naive implementation has some disadvantages (e.g., we won't be able
to cache two conditions that contain references to
distinct-but-equivalent object instances and we don't have any control
over the size of the condition cache), but for most simple use-cases the
approach should be good enough.

Resolves #3629

* Fix docstring style
2016-10-10 23:36:38 -07:00
Fabian Affolter
a2503e4d13 Upgrade sqlalchemy to 1.1.1 (#3796) 2016-10-10 23:29:43 -07:00
Fabian Affolter
656ee52435 Upgrade cherrypy to 8.1.2 (#3805) 2016-10-10 23:27:53 -07:00
Fabian Affolter
002660fd9e Upgrade dnspython3 to 1.15.0 (#3804) 2016-10-10 23:24:10 -07:00
Fabian Affolter
63580f9e03 Upgrade pyowm to 2.5.0 (#3806) 2016-10-10 23:23:32 -07:00
Teemu Mikkonen
87d9cdd78f Fix for html5 notification tag problem. Fixes #3774 (#3790) 2016-10-10 23:17:27 -07:00
phardy
c8ca66b671 Stop GTFS component from overwriting friendly_name (#3798)
* Prevent update from clobbering configured name.

* linted

* Fixing awkward line breaking.
2016-10-10 22:36:20 -07:00
Robbie Trencheny
9b98d470c2 Wrap found target in list (#3809)
* Wrap found target in list

* Fix test_messages_to_targets_route
2016-10-10 22:31:15 -07:00
sander76
b19ec21e88 Changing import as powerview api did change. (#3780) 2016-10-10 22:30:27 -07:00
Fabian Affolter
3b331eac56 Update docstrings (sensor.pi_hole, sensor.haveibeenpwned) (#3793)
* Fix docstrings

* Update docstrings
2016-10-10 19:38:32 +02:00
Fabian Affolter
552265bc31 No longer use old name (#3792) 2016-10-10 19:38:20 +02:00
Ellis Percival
df58f718ab Make 'pin' optional for zigbee device config. (#3799) 2016-10-10 16:53:18 +02:00
Pascal Vizeli
76a1a54369 Hotfix device name with autodiscovery (#3791) 2016-10-10 13:46:23 +02:00
Per Sandström
b6e008be71 Merge pull request #3782 from persandstrom/vsure0.11.0
vsure0.11.0
2016-10-09 22:01:46 +02:00
Per Sandström
9d5c20b629 vsure0.11.0 2016-10-09 21:47:35 +02:00
Erik Eriksson
63d9ea6643 slugify (#3777) 2016-10-09 09:15:58 -07:00
Hugo Dupras
1d0df63615 Netatmo binary sensor (#3455)
* Basic support for Netatmo welcome binary sensors

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Bug fixes and optimization for Netatmo devices

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* pylint fixes

* Bug Fixing and optimization for Netatmo devices

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Add unique_id for cameras to avoid duplicate
And global config to disable discovery for netatmo devices

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>
2016-10-09 08:45:12 -07:00
hexa-
154eacef6c Http: Change approved_ips from string to cidr validation (#3532) [BREAKING CHANGE]
* Change approved_ips from string to cidr validation

Relabel to trusted_networks, better reflecting its expected inputs,
everything that ipaddress.ip_networks recognizes as an ip network
is possible:
- 127.0.0.1      (single ipv4 addresses)
- 192.168.0.0/24 (ipv4 networks)
- ::1            (single ipv6 addresses)
- 2001:DB8::/48  (ipv6 networks)

* Add support for the X-Forwarded-For header
2016-10-09 08:13:30 -07:00
Fabian Affolter
dc95b28487 Use voluptuous for Russound RNET (#3689)
* Migrate to voluptuous

* Remove wrong default
2016-10-09 16:40:54 +02:00
Paulus Schoutsen
c9a88322d6 Merge pull request #3765 from home-assistant/hotfix-0-30-1
0.30.1
2016-10-08 14:50:52 -07:00
Paulus Schoutsen
46b58db2ff Version bump to 0.30.1 2016-10-08 14:42:47 -07:00
mtl010957
78cbfa3f96 Fixed issue #3760, handle X10 unit numbers greater than 9. (#3763) 2016-10-08 14:42:24 -07:00
Roi Dayan
dba5c74c8f Fix command line cover template (#3754)
The command line cover value template is optional so we
need to check it's not none before assigning hass to it.

Fixes #3649

Signed-off-by: Roi Dayan <roi.dayan@gmail.com>
2016-10-08 14:42:24 -07:00
Johann Kellerman
a94a5ac9b5 Coerce device IDs from known_devices to be slugs (#3764)
* Slugify & consider_home test fix [due to load valid PR]

* undo schema change

* Fix slugify error
2016-10-08 14:42:24 -07:00
Johann Kellerman
4d9bac6f9c Coerce device IDs from known_devices to be slugs (#3764)
* Slugify & consider_home test fix [due to load valid PR]

* undo schema change

* Fix slugify error
2016-10-08 14:40:50 -07:00
Roi Dayan
6419d273ea Fix command line cover template (#3754)
The command line cover value template is optional so we
need to check it's not none before assigning hass to it.

Fixes #3649

Signed-off-by: Roi Dayan <roi.dayan@gmail.com>
2016-10-08 13:03:32 -07:00
mtl010957
7882b19dc5 Fixed issue #3760, handle X10 unit numbers greater than 9. (#3763) 2016-10-08 12:57:40 -07:00
Willems Davy
8f8bba4ad7 Haveibeenpwned sensor platform (#3618)
* Initial version of "haveibeenpwned" sensor component

* 2 flake8 fixes

* remove debugging error message

* Increase scan_interval as well as throttle to make sure that during initial startup of hass the request happens with 5 seconds delays and after startup with 15 minutes delays. Scan_interval is increased also to not call update as often

* update .coveragerc

* remove (ssl) verify=False

* - use dict to keep the request values with email as key
- use track_point_in_time system to make sure data updates initially at 5 seconds between each call until all sensor's email have a result in the dict.

* fix a pylint error that happend on the py35 tests
2016-10-08 11:38:58 -07:00
Johann Kellerman
7b40a641ec Continue on invalid platforms and new setup_component unit tests (#3736) 2016-10-08 11:27:35 -07:00
wokar
1b26b5ad14 add include configuration to logbook (#3739) 2016-10-08 11:26:14 -07:00
Hugo Dupras
bbbb4441ea Add discovery support for Netatmo weather Station (#3714)
* Add discovery support for Netatmo Weather station

Only The weather information are currently supported (No battery or wifi status supported)

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Add unique_id for netatmo sensors to avoid duplicate

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>

* Update requirements_all.txt and PEP8 fixes

Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>
2016-10-08 11:26:01 -07:00
Paulus Schoutsen
1e2e877302 Version bump to 0.31.0.dev0 2016-10-08 09:58:28 -07:00
Paulus Schoutsen
4239a2b844 Merge pull request #3715 from home-assistant/dev
0.30
2016-10-08 09:58:08 -07:00
Paulus Schoutsen
408b68bfac Version bump to 0.30.0 2016-10-08 09:57:51 -07:00
Paulus Schoutsen
fe317b806f Close event loop to avoid error on exiting HASS (#3762) 2016-10-08 18:56:36 +02:00
Paulus Schoutsen
09cbf68637 Update frontend 2016-10-08 09:23:45 -07:00
Johann Kellerman
fb94aaa5a1 Load yaml using validator and include consider_home (#3743)
* Load yaml using validator, consider_home

* timedelta, track_if_away

* improve voluptuous

* Add default back

* Change time_period validation order
2016-10-07 18:08:33 -07:00
Fabian Affolter
b09b13f552 Catch exception (fixes #3699) (#3727) 2016-10-07 17:30:59 -07:00
Erik Eriksson
2d4df42a65 improved error handling (#3725) 2016-10-07 17:25:51 -07:00
Erik Eriksson
fccc7e69d0 Improved exception handling. Don't stop updating from server because of exception. (#3724) 2016-10-07 17:24:02 -07:00
Pascal Vizeli
f1e5d32ef5 Async exception handling (#3731)
* remove unused exception

* add logging

* disable pylint broad-except

* add exception handler

* fix lint

* update log output

* change log message in async with exc_info

* Add exc_info to asyncio exception handler
2016-10-07 17:20:39 -07:00
Erik Eriksson
1c24018fbb Improved exception handling (#3746) 2016-10-07 17:16:35 -07:00
Robbie Trencheny
f37038921f Fix E501 line too long error 2016-10-07 11:48:38 -07:00
Robbie Trencheny
f030ff67ad Set anel_pwrctrl switch to specific commit instead of master 2016-10-07 11:38:39 -07:00
Robbie Trencheny
3cfec2b5e2 Set TP-Link switch to specific commit instead of master 2016-10-07 11:36:43 -07:00
Robbie Trencheny
58b3dd7cc0 Set specific commit for Hunter Douglas API package due to upstream rename 2016-10-07 11:34:41 -07:00
Fabian Affolter
5e16dc6307 Fix typo (#3744) 2016-10-07 00:00:12 -07:00
Fabian Affolter
8b059e9aad Migrate to voluptuous (#3687) 2016-10-06 16:11:08 +02:00
Fabian Affolter
12f1be9b1c Fix PEP257 issues and ordering (#3720) 2016-10-05 17:32:29 -07:00
Robbie Trencheny
519f400175 Merge branch 'master' into dev 2016-10-05 15:35:01 -07:00
Fabian Affolter
a94571fd10 Change name of Forecast.io platform to Dark Sky (#3698)
* Rename Forecast.io platform to Dark Sky

* Upgrade to python-forecastio to 1.3.5

* Update to reflect name change (Forecast.io -> Dark Sky)

* Rename forecast to darksky
2016-10-05 21:42:58 +02:00
Fabian Affolter
cb3a78b330 Adjust vol to accept filenames (fixes #3701) (#3707) 2016-10-05 18:02:45 +02:00
John
1bc6366051 Increase allowable polling intensity values (#3711) 2016-10-05 16:58:06 +02:00
Fabian Affolter
5d339fb141 Fix sentence (#3709) 2016-10-05 16:28:38 +02:00
Fabian Affolter
0c68f381b0 Migrate to voluptuous (#3679) 2016-10-05 14:40:08 +02:00
Daniel Høyer Iversen
3e40b24293 Merge pull request #3708 from home-assistant/flux_led
Update flux led library
2016-10-05 11:12:56 +02:00
Daniel Høyer Iversen
4b828d225e Merge pull request #3656 from home-assistant/pushetta
customize if pushetta should send test message on start up
2016-10-05 11:03:35 +02:00
Daniel
201294e481 Update flux led library 2016-10-05 10:49:33 +02:00
Daniel
350d23f7eb customize if pushetta should send test message on start up 2016-10-05 10:45:41 +02:00
Daniel Høyer Iversen
b8beae9c6c Merge pull request #3651 from home-assistant/automation
Customize initial state of automation
2016-10-05 09:48:55 +02:00
Daniel
46f3337b07 Customize initial state of automation 2016-10-05 09:20:51 +02:00
John Arild Berentsen
b2354f45be Add possibility to set temperature to a given operation_mode (#3646)
* Add possibility to set temperature to a given operation_mode

* Correctly break

* Review changes
2016-10-04 23:48:25 -07:00
Paulus Schoutsen
e4e13b59cf Update frontend 2016-10-04 23:15:10 -07:00
Paulus Schoutsen
8c694eb279 Speed up MQTT server test (#3703) 2016-10-04 22:49:43 -07:00
Paulus Schoutsen
9d085a023c Merge pull request #3706 from home-assistant/hotfix-0-29-7b
Fix broken unit tests
2016-10-04 22:47:46 -07:00
Martin Hjelmare
c06313a897 Set force_update to true for mysensors sensors (#3648) 2016-10-04 22:45:38 -07:00
Per Sandström
ed490b1c11 Add västtrafik sensor (#3640) 2016-10-04 22:37:45 -07:00
Marcelo Moreira de Mello
70fc94003d Fixed issue #3624 and bumped python-nest to 2.10.0 version (#3665)
* Fixed issue #3624 and bumped python-nest to 2.10.0 version

*    Fixed return state when accessing attribute operation_mode

* Fixed typo
2016-10-04 22:29:21 -07:00
Paulus Schoutsen
114fae76e1 Fix broken unit tests 2016-10-04 22:23:58 -07:00
Paulus Schoutsen
4f0064b00e Fix broken tests (#3704)
* Fix broken tests

* Lint
2016-10-04 22:19:12 -07:00
Fabian Affolter
dc53c21548 Check that no configuration is provided (#3675) 2016-10-04 22:10:31 -07:00
Pascal Vizeli
b9b41d3855 Update ha-alpr / change default interval (#3691) 2016-10-04 22:04:50 -07:00
John Arild Berentsen
17a8dd3f70 Add set_config_parameter service (#3696) 2016-10-04 22:04:19 -07:00
gwendalg
03d6a7c42a Add Ted5000 Sensor (#3559)
* Add Ted5000 Sensor

Signed-off-by: Gwendal Grignou <gwendal@gmail.com>

* sensors: ted5000: use requests instead of urllib.

Signed-off-by: Gwendal Grignou <gwendal@gmail.com>

* Update ted5000.py

Add timeout to requests call.
2016-10-04 21:57:40 -07:00
Daniel Høyer Iversen
d2d393feb5 Add automations and scripts to group.all_automations and group.all_scripts (#3664)
* Add automations to group.all_automations

* Add scripts to group.all_scripts
2016-10-04 21:20:48 -07:00
Paulus Schoutsen
e49651cdeb Merge pull request #3702 from home-assistant/hotfix-0-29-7
0.29.7
2016-10-04 21:03:47 -07:00
Paulus Schoutsen
a60e845203 Version bump to 0.29.7 2016-10-04 21:01:28 -07:00
Pascal Vizeli
f23eb9336f Service & signal (stop/restart) fix (#3690)
* Bugfix signhandling/services

* change from coroutine to callback

* add error handling

* fix bug with endless running

* fix unit test

* Revert "fix unit test"

This reverts commit 31135c7709.

* Disable sigterm/sighup test
2016-10-04 21:01:08 -07:00
Pascal Vizeli
0bf8bb62ad Service & signal (stop/restart) fix (#3690)
* Bugfix signhandling/services

* change from coroutine to callback

* add error handling

* fix bug with endless running

* fix unit test

* Revert "fix unit test"

This reverts commit 31135c7709.

* Disable sigterm/sighup test
2016-10-04 21:00:36 -07:00
Paulus Schoutsen
5085cdb0f7 Add async_safe annotation (#3688)
* Add async_safe annotation

* More async_run_job

* coroutine -> async_save

* Lint

* Rename async_safe -> callback

* Add tests to core for different job types

* Add one more test with different type of callbacks

* Fix typing signature for callback methods

* Fix callback service executed method

* Fix method signatures for callback
2016-10-04 20:44:32 -07:00
Robbie Trencheny
8358f938b5 Now no one wants to be blacklisted, so lets remove the configuration entirely 2016-10-04 13:39:48 -07:00
Robbie Trencheny
be7401f4a2 Now no one wants to be blacklisted, so lets remove the configuration entirely 2016-10-04 13:38:56 -07:00
Robbie Trencheny
760117167d Update .mention-bot to add more users to blacklist and remove skipAlreadyMentionedPR 2016-10-04 13:25:57 -07:00
Robbie Trencheny
2fd83b439c Update .mention-bot to add more users to blacklist and remove skipAlreadyMentionedPR 2016-10-04 13:25:16 -07:00
Robbie Trencheny
e523c3d196 Add @mention-bot configuration 2016-10-04 13:22:35 -07:00
Per Sandström
d9e73d1d71 Merge pull request #3697 from persandstrom/verisure_0.10.3
vsure 0.10.3
2016-10-04 22:20:12 +02:00
Per Sandström
5d3e93b4ef vsure 0.10.3 2016-10-04 22:01:36 +02:00
sam-io
85782f9c29 fix for date formatting issue (#3693) 2016-10-04 08:41:39 -07:00
William Scanlon
2cf49f3de6 Added support for Wink Smoke and CO detectors (#3645) 2016-10-04 01:07:50 -07:00
Fabian Affolter
a072047d9d Auth and headers support for REST sensor (#3592)
* Add auth and header support

* Update header part
2016-10-04 01:07:17 -07:00
Fabian Affolter
74b0e4cb45 Statistics sensor (#3513)
* Initial stats sensor

* Add total and tests

* Use deque, rename var, set default, and only update sensor
2016-10-04 01:04:00 -07:00
Rob Capellini
694983379f test: mocking IO in HTML5 notify tests (#3685)
Replacing temporary file creation in tests with mock's mock_open for faster IO.
2016-10-04 01:01:41 -07:00
Erik Eriksson
5900d8a2c1 only query vehicle attributes once (#3668)
use registration number as dev id
2016-10-04 00:58:25 -07:00
Erik Eriksson
287a7e2720 Support for encrypted payload (#3587) 2016-10-04 00:57:37 -07:00
William Scanlon
8592ba3cb9 Report availability of arest (#3614) 2016-10-04 00:51:45 -07:00
deisi
c93b63963b Fix 3621 (#3642)
Happens when the scanner searches for a mac address, that has been forgotten
by the fritzbox.
2016-10-04 00:47:58 -07:00
Fabian Affolter
194402f7e7 Upgrade Sphinx to 1.4.8 and set missing variables (#3650) 2016-10-04 00:47:28 -07:00
Paulus Schoutsen
d58548dd1c Address asyncio comments (#3663)
* Template platforms: create_task instead of yield from

* Automation: less yielding, more create_tasking

* Helpers.script: less yielding, more create_tasking

* Deflake logbook test

* Deflake automation reload config test

* MQTT: Use async_add_job and threaded_listener_factory

* Deflake other logbook test

* lint

* Add test for automation trigger service

* MQTT client can be called from within async
2016-10-03 22:39:27 -07:00
Robbie Trencheny
f2a12b7ac2 Add @mention-bot configuration 2016-10-03 17:36:00 -07:00
Pascal Vizeli
625319846c Big Homematic update (#3677)
* Update homeassistant with new pyhomematic layout

* fix linter
2016-10-03 23:21:53 +02:00
Daniel Høyer Iversen
c3ea04f2dd revert update of input_boolean 2016-10-03 22:05:06 +02:00
Daniel Høyer Iversen
4a5a1e1e96 Ensure unique entity id for input_boolean 2016-10-03 22:03:16 +02:00
Pascal Vizeli
41aff96375 Bugfix temp convert on none temp attribute / unittest for that (#3654) 2016-10-03 10:46:31 +02:00
Justin Weberg
0219df17f5 Expose Configuration path to frontend (#3660)
* Expose config path to frontend

* Fix typo

* Add deleted code.
2016-10-03 00:04:43 -07:00
Robbie Trencheny
b586e80977 Squashed commit of the following:
commit 220331260e9748ac8e17b3ce776330c1dfb7725b
Merge: 73d93e5 c891820
Author: Robbie Trencheny <me@robbiet.us>
Date:   Sun Oct 2 17:57:24 2016 -0700

    Merge branch 'color_temp_for_mqtt_light' of https://github.com/alterscape/home-assistant into alterscape-color_temp_for_mqtt_light

commit c89182008a
Author: Ryan Spicer <ryanspicer@gmail.com>
Date:   Sun Sep 18 23:06:34 2016 -0700

    fix missing docstring.

commit e61dda4dd3
Author: Ryan Spicer <ryanspicer@gmail.com>
Date:   Sun Sep 18 22:43:04 2016 -0700

    fix pep8 errors and typos in tests.

commit 559d1752d2
Author: Ryan Spicer <ryanspicer@gmail.com>
Date:   Sun Sep 18 21:41:07 2016 -0700

    add tests for mqtt color temp support

commit 702defb932
Author: Ryan Spicer <ryanspicer@gmail.com>
Date:   Sun Sep 18 20:55:07 2016 -0700

    Add color temp support to mqtt lights.
2016-10-02 18:04:00 -07:00
hexa-
73d93e526e Add anel_pwrctrl platform to control switches on ANEL PwrCtrl devices (#3644)
* Add pwrctrl platform to control switches on ANEL PwrCtrl devices

* make requested changes
2016-10-02 16:51:15 -07:00
Paulus Schoutsen
148ea82513 Update frontend 2016-10-02 15:38:18 -07:00
Paulus Schoutsen
abb8bcb6d9 Protect waiting for event loop from within event loop (#3658)
* Protect waiting for event loop from within event loop

* Faster fetching of loop attribute for ident check
2016-10-02 15:07:23 -07:00
John Arild Berentsen
e455daa61d Make sure temperature slider is shown if reported temp is 0 (#3653) 2016-10-02 17:47:04 +02:00
Martin Hjelmare
b6b0bad0c7 Add new mysensors types (#3637)
* Add S_INFO, S_GAS, S_GPS, S_WATER_QUALITY.
* Extend S_CUSTOM, S_POWER.
* Add more units.
2016-10-01 23:23:31 -07:00
Paulus Schoutsen
d5ab292ff3 Sensor.emoncms: Never disable SSL verification. 2016-10-01 23:13:07 -07:00
Erik Eriksson
9f8acbec95 Add support for tracking position and status for a Volvo car (#3617) 2016-10-01 23:00:01 -07:00
Jeff Wilson
d55ed7a3a2 Flux switch improvements (#3615)
* Make flux always adjust brightness of light (even when not in XY mode)

* Remove kelvin mode from flux switch

The light/turn_on service only works with mired values, kelvin values
are out of range per the schema.

* Use already defined min/max values for light/turn_on schema

* Clamp temp value to light/turn_on allowed values
2016-10-01 22:57:15 -07:00
Greg Dowling
fcbfcf0aa7 Bump pywemo version - changes port order for faster startup. (#3612) 2016-10-01 22:53:24 -07:00
Simon Szustkowski
183936375f Add a Timeout for InfluxDB connections (#3563)
* Add a Timeout for InfluxDB connections

* Removed trailing whitespace
2016-10-01 22:29:06 -07:00
Paulus Schoutsen
1f1ac02457 Merge branch 'pr/3552' into dev 2016-10-01 22:20:58 -07:00
Robbie Trencheny
646eaccd4d Update notify to expect a list of string targets instead of a single … (#3548)
* Update notify to expect a list of string targets instead of a single string

* Actually do the thing I set out to do

* Fix notify.group test to expect an array of targets

* REST platform will only use the first target in the list

* Update notify platforms to expect a list of targets

* Update notify services.yaml
2016-10-01 22:19:17 -07:00
Pascal Vizeli
c189c05676 Add temp convert to climate base object (#3611)
* Add temp convert to climate base object

* fix nest

* fix lint
2016-10-01 22:15:19 -07:00
Lewis Juggins
9683e3e3ad Correctly define requirements for emulated hue (#3535) 2016-10-01 21:56:45 -07:00
Fabian Affolter
a61e08680a Add persistent notification for failed login attempts (#3528) 2016-10-01 21:20:16 -07:00
Klaas Hoekema
9da2d6edd0 Make forecast.io update interval configurable (#3520)
Adds a config parameter (`update_interval`) to the `forecast` sensor to
set the minimum update interval. The default remains 120 seconds.
2016-10-01 21:18:10 -07:00
William Scanlon
1f38e9fa57 Support for wink oath2 and relay sensors (#3496) 2016-10-01 20:45:39 -07:00
Paulus Schoutsen
996d7cf1cd Merge pull request #3627 from home-assistant/async-entity-update
Add async updates to entities
2016-10-01 16:20:48 -07:00
Paulus Schoutsen
c36d30f4fe Typo 2016-10-01 15:43:33 -07:00
Paulus Schoutsen
8f3e12c9b8 Make Automation.reload_service_handler async 2016-10-01 15:42:17 -07:00
Paulus Schoutsen
56fdc2a625 Automation: call prepare_setup_platform in executor 2016-10-01 14:11:16 -07:00
Paulus Schoutsen
e18825ba20 Automation: only call executor once when processing config 2016-10-01 14:11:16 -07:00
Paulus Schoutsen
7ab7edd81c Make automation async 2016-10-01 14:11:16 -07:00
Paulus Schoutsen
16ff68ca84 Add mqtt.async_subscribe 2016-10-01 14:11:16 -07:00
Paulus Schoutsen
b8504f8fc8 Make helpers.script async 2016-10-01 14:11:16 -07:00
Paulus Schoutsen
185bd6c28a Make helpers.condition.* async 2016-10-01 14:11:16 -07:00
Paulus Schoutsen
33a51623f8 Make Service.call_from_config async 2016-10-01 14:11:16 -07:00
Paulus Schoutsen
4198c42736 Have template platforms never leave the event loop 2016-10-01 14:11:16 -07:00
Paulus Schoutsen
3e24a35c1e Skip RFXtrx tests unless RFXTRX=RUN (#3625)
* Skip RFXtrx tests unless RFXTRX=RUN

* Remove my previous hacks to slightly speed up rfxtrx

* Exclude RFXTRX tests from coverage

* Remove unused import in rfxtrx tstt

* Add close connection back to RFXtrx tests

* Typo
2016-10-01 13:57:10 -07:00
Paulus Schoutsen
651f3ab55c Merge pull request #3641 from home-assistant/hotfix-0-29-6
0.29.6
2016-10-01 12:12:56 -07:00
Paulus Schoutsen
756f23f0b4 Version bump to 0.29.6 2016-10-01 12:10:00 -07:00
Paulus Schoutsen
ef0e018cbb Service config calls will no longer mutate original config (#3628) 2016-10-01 12:09:25 -07:00
Ben Bangert
9cf2ad0b55 Monkey-patch a weakref set in Task to be a no-op. (#3639)
* Monkey-patch a weakref set in Task to be a no-op.

* Fix linting issues
2016-10-01 12:08:56 -07:00
Ben Bangert
892bbdc2dd Monkey-patch a weakref set in Task to be a no-op. (#3639)
* Monkey-patch a weakref set in Task to be a no-op.

* Fix linting issues
2016-10-01 12:08:25 -07:00
Paulus Schoutsen
bb03960ba5 Voluptuous arest (#3558)
* Migrate to voluptuous

* Adjust sensor.arest for new template system

* Use items() to align the var section with the pins
2016-10-01 18:45:43 +02:00
Fabian Affolter
15ed8c6332 Add units (fixes #3619) (#3633) 2016-10-01 17:35:32 +02:00
Paulus Schoutsen
412b5350ce Service config calls will no longer mutate original config (#3628) 2016-09-30 23:26:15 -07:00
Otto Winter
d5f8aa52c4 Add support for MySensors cover (#3512)
* Added support for MySensors cover device

* Fixed set_req not defined

* Fixed V_PERCENTAGE is str

* Removed set_cover_position

The MySensors documentation doesn’t specify when sending a V_PERCENTAGE
is allowed.

* Fixed homeassistant/components/mysensors.py line too long

* Fixed lint ATTR_POSITION imported but unused

* Use V_PERCENTAGE for MySensors cover

* Revert "Removed set_cover_position"

This reverts commit d78cb3a04d.

* Fix set_req, ATTR_POSITION not defined

* Added support for non-exactly positionable covers

* Fixed V_PERCENTAGE cast to bool

* Ported MySensors cover back to v1.4

`V_PERCENTAGE` and `V_DIMMER` are aliases just like `V_STATUS` and
`V_LIGHT`, so the code inside `MySensorsCover` doesn’t need to be
updated.

* Fixed v1.5 V_TYPES not in in v1.4 gateway SetReq
2016-10-01 01:36:04 +02:00
Paulus Schoutsen
b650b2b0db Spread async love (#3575)
* Convert Entity.update_ha_state to be async

* Make Service.call async

* Update entity.py

* Add Entity.async_update

* Make automation zone trigger async

* Fix linting

* Reduce flakiness in hass.block_till_done

* Make automation.numeric_state async

* Make mqtt.subscribe async

* Make automation.mqtt async

* Make automation.time async

* Make automation.sun async

* Add async_track_point_in_utc_time

* Make helpers.track_sunrise/set async

* Add async_track_state_change

* Make automation.state async

* Clean up helpers/entity.py tests

* Lint

* Lint

* Core.is_state and Core.is_state_attr are async friendly

* Lint

* Lint
2016-09-30 12:57:24 -07:00
Fabian Affolter
7e50ccd32a Component for Digital Ocean (#3322)
* Add Digital Ocean implementation

* Remove kernel
2016-09-30 18:30:44 +02:00
John Arild Berentsen
521080d1b0 Zwave: Update commandclasses and deviceclasses according to sigma SDK (#3495)
* Update Command classes and device types to Sigma SDK

* Fix some pylint

* Seperate constants to file

* Flake8

* coverage and flake8 pylint

* Add services.yaml

* Service descriptions was missing

* Spelling :)

* grammar

* Remove zwave service descriptions from main
2016-09-30 08:43:18 -07:00
Paulus Schoutsen
d76cf092c3 Merge pull request #3610 from home-assistant/hotfix-0-29-5
0.29.5
2016-09-30 00:24:59 -07:00
Paulus Schoutsen
dfb92fa836 Version bump to 0.29.5 2016-09-30 00:15:14 -07:00
Paulus Schoutsen
5cb8ce71ef Lint 2016-09-30 00:14:59 -07:00
Jeff Wilson
099e983ca0 Nest operation modes (#3609)
* Add ability to change Nest mode to all available options

* Make Nest state reflect current operation not current operation mode

* Update Nest sensor to use operation mode

* Fix linting

* Revert "Make Nest state reflect current operation not current operation mode"

This reverts commit 573ba028d8.

Conflicts:
	homeassistant/components/climate/nest.py
2016-09-30 00:14:59 -07:00
Marcelo Moreira de Mello
39514be1f9 Fixed issue #3574 - Temperature slider fixed on frontend on heat/cool mode (#3606)
* Fixed issue #3574 - Temperature slider fixed on frontend on heat/cool mode

* Fixed target_temperature to return None when self.is_away_mode_on is True
2016-09-30 00:14:59 -07:00
Paulus Schoutsen
234f4449b0 Lint 2016-09-30 00:14:08 -07:00
Jeff Wilson
a89d036e26 Nest operation modes (#3609)
* Add ability to change Nest mode to all available options

* Make Nest state reflect current operation not current operation mode

* Update Nest sensor to use operation mode

* Fix linting

* Revert "Make Nest state reflect current operation not current operation mode"

This reverts commit 573ba028d8.

Conflicts:
	homeassistant/components/climate/nest.py
2016-09-29 23:44:14 -07:00
Marcelo Moreira de Mello
9ea030f42e Fixed issue #3574 - Temperature slider fixed on frontend on heat/cool mode (#3606)
* Fixed issue #3574 - Temperature slider fixed on frontend on heat/cool mode

* Fixed target_temperature to return None when self.is_away_mode_on is True
2016-09-29 22:17:13 -07:00
Paulus Schoutsen
7ac8425099 Fix tests 2016-09-29 21:42:36 -07:00
Fabian Affolter
c000e74d0a Migrate to voluptuous (#3374) 2016-09-29 19:07:35 -07:00
Fabian Affolter
6632747543 Migrate to voluptuous (#3341) 2016-09-29 19:06:28 -07:00
Fabian Affolter
a7266ae6cf Check that no configuration is provided (#3553) 2016-09-29 19:02:22 -07:00
Paulus Schoutsen
4031f70665 Merge pull request #3603 from home-assistant/hotfix-0-29-4
Hotfix 0 29 4
2016-09-29 18:59:09 -07:00
Paulus Schoutsen
2b59409e52 Version 0.29.4 2016-09-29 18:57:33 -07:00
Dan Cinnamon
b41c795d34 Passing original config reference to load_platform. (#3602) 2016-09-29 18:56:09 -07:00
Pascal Vizeli
db56ed400d Bugfix voluptuous acer_projector (#3598) 2016-09-29 18:56:09 -07:00
Paulus Schoutsen
c603ffbe26 Fix voluptuous alexa config (#3596) 2016-09-29 18:56:09 -07:00
Dan Cinnamon
68028afb98 Passing original config reference to load_platform. (#3602) 2016-09-29 18:55:43 -07:00
Paulus Schoutsen
733120c577 Fix voluptuous alexa config (#3596) 2016-09-29 18:45:55 -07:00
Pascal Vizeli
01435f7f42 Bugfix voluptuous acer_projector (#3598) 2016-09-29 18:36:20 -07:00
Paulus Schoutsen
77c91c8a5e Merge pull request #3590 from home-assistant/hotfix-0-29-3
Hotfix 0 29 3
2016-09-29 09:09:51 -07:00
Paulus Schoutsen
a321c2f0d8 Version bump to 0.29.3 2016-09-29 09:07:19 -07:00
Pascal Vizeli
807daf8f5d Bugfix voluptuous for hue (#3589) 2016-09-29 09:07:00 -07:00
Pascal Vizeli
08bacd8e31 Bugfix voluptuous for hue (#3589) 2016-09-29 09:06:41 -07:00
Paulus Schoutsen
f79d762e66 Merge pull request #3585 from home-assistant/hotfix-29-2
Hotfix 29 2
2016-09-29 08:18:51 -07:00
Paulus Schoutsen
30aa67b789 Version bump to 0.29.2 2016-09-29 07:50:34 -07:00
Hugo Dupras
883e45c476 Netatmo: Hotfix for hass 0.29 (#3576)
Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>
2016-09-29 07:46:04 -07:00
Hugo Dupras
dd551cf056 Netatmo: Hotfix for hass 0.29 (#3576)
Signed-off-by: Hugo D. (jabesq) <jabesq@gmail.com>
2016-09-29 07:45:54 -07:00
Fabian Affolter
47a3adb6b3 Remove duplicate port entry (fixes #3583) (#3584) 2016-09-29 07:45:39 -07:00
Fabian Affolter
7d86fb8c72 Remove duplicate port entry (fixes #3583) (#3584) 2016-09-29 07:45:25 -07:00
Greg Dowling
e87467cb20 Merge pull request #3577 from home-assistant/fix_loopenergy_exceptions
Loopenergy library - bump to catch more exceptions in poll thread.
2016-09-29 10:49:14 +01:00
pavoni
abd1213cc4 Bump library to catch more exceptions in poll thread. 2016-09-29 09:55:05 +01:00
Paulus Schoutsen
f3d838c448 Version bump to 0.29.1 2016-09-28 22:08:02 -07:00
Marcelo Moreira de Mello
574e3231d0 Fixed typo (#3569)
Sep 29 00:59:22 pi hass[21333]: if self.device.measurment_scale == 'F':
Sep 29 00:59:22 pi hass[21333]: AttributeError: 'Device' object has no attribute 'measurment_scale'
2016-09-28 22:07:40 -07:00
Marcelo Moreira de Mello
48ffdea31f Fixed typo (#3569)
Sep 29 00:59:22 pi hass[21333]: if self.device.measurment_scale == 'F':
Sep 29 00:59:22 pi hass[21333]: AttributeError: 'Device' object has no attribute 'measurment_scale'
2016-09-28 22:07:23 -07:00
Paulus Schoutsen
6e80581b30 Version bump to 0.30.0.dev0 2016-09-28 21:21:03 -07:00
Paulus Schoutsen
9780ea5c52 Version bump to 0.29 2016-09-28 21:20:47 -07:00
happyleaves
559f63bfc3 bump limitlessled version 2016-09-27 16:30:26 -04:00
1047 changed files with 87591 additions and 24237 deletions

View File

@@ -5,6 +5,7 @@ omit =
homeassistant/__main__.py
homeassistant/scripts/*.py
homeassistant/helpers/typing.py
homeassistant/helpers/signal.py
# omit pieces of code that rely on external devices being present
homeassistant/components/apcupsd.py
@@ -13,9 +14,15 @@ omit =
homeassistant/components/arduino.py
homeassistant/components/*/arduino.py
homeassistant/components/bbb_gpio.py
homeassistant/components/*/bbb_gpio.py
homeassistant/components/bloomsky.py
homeassistant/components/*/bloomsky.py
homeassistant/components/digital_ocean.py
homeassistant/components/*/digital_ocean.py
homeassistant/components/dweet.py
homeassistant/components/*/dweet.py
@@ -25,12 +32,27 @@ omit =
homeassistant/components/envisalink.py
homeassistant/components/*/envisalink.py
homeassistant/components/google.py
homeassistant/components/*/google.py
homeassistant/components/insteon_hub.py
homeassistant/components/*/insteon_hub.py
homeassistant/components/insteon_local.py
homeassistant/components/*/insteon_local.py
homeassistant/components/insteon_plm.py
homeassistant/components/*/insteon_plm.py
homeassistant/components/ios.py
homeassistant/components/*/ios.py
homeassistant/components/isy994.py
homeassistant/components/*/isy994.py
homeassistant/components/lutron.py
homeassistant/components/*/lutron.py
homeassistant/components/modbus.py
homeassistant/components/*/modbus.py
@@ -46,6 +68,9 @@ omit =
homeassistant/components/qwikswitch.py
homeassistant/components/*/qwikswitch.py
homeassistant/components/rfxtrx.py
homeassistant/components/*/rfxtrx.py
homeassistant/components/rpi_gpio.py
homeassistant/components/*/rpi_gpio.py
@@ -66,6 +91,9 @@ omit =
homeassistant/components/verisure.py
homeassistant/components/*/verisure.py
homeassistant/components/volvooncall.py
homeassistant/components/*/volvooncall.py
homeassistant/components/*/webostv.py
homeassistant/components/wemo.py
@@ -77,7 +105,7 @@ omit =
homeassistant/components/zigbee.py
homeassistant/components/*/zigbee.py
homeassistant/components/zwave.py
homeassistant/components/zwave/*
homeassistant/components/*/zwave.py
homeassistant/components/enocean.py
@@ -86,91 +114,138 @@ omit =
homeassistant/components/netatmo.py
homeassistant/components/*/netatmo.py
homeassistant/components/neato.py
homeassistant/components/*/neato.py
homeassistant/components/homematic.py
homeassistant/components/*/homematic.py
homeassistant/components/pilight.py
homeassistant/components/*/pilight.py
homeassistant/components/knx.py
homeassistant/components/*/knx.py
homeassistant/components/ffmpeg.py
homeassistant/components/*/ffmpeg.py
homeassistant/components/zoneminder.py
homeassistant/components/*/zoneminder.py
homeassistant/components/mochad.py
homeassistant/components/*/mochad.py
homeassistant/components/zabbix.py
homeassistant/components/*/zabbix.py
homeassistant/components/alarm_control_panel/alarmdotcom.py
homeassistant/components/alarm_control_panel/concord232.py
homeassistant/components/alarm_control_panel/nx584.py
homeassistant/components/alarm_control_panel/simplisafe.py
homeassistant/components/apiai.py
homeassistant/components/binary_sensor/arest.py
homeassistant/components/binary_sensor/concord232.py
homeassistant/components/binary_sensor/flic.py
homeassistant/components/binary_sensor/hikvision.py
homeassistant/components/binary_sensor/iss.py
homeassistant/components/binary_sensor/rest.py
homeassistant/components/browser.py
homeassistant/components/camera/amcrest.py
homeassistant/components/camera/bloomsky.py
homeassistant/components/camera/ffmpeg.py
homeassistant/components/camera/foscam.py
homeassistant/components/camera/mjpeg.py
homeassistant/components/camera/rpi_camera.py
homeassistant/components/camera/synology.py
homeassistant/components/climate/eq3btsmart.py
homeassistant/components/climate/heatmiser.py
homeassistant/components/climate/homematic.py
homeassistant/components/climate/knx.py
homeassistant/components/climate/oem.py
homeassistant/components/climate/proliphix.py
homeassistant/components/climate/radiotherm.py
homeassistant/components/cover/garadget.py
homeassistant/components/cover/homematic.py
homeassistant/components/cover/myq.py
homeassistant/components/cover/rpi_gpio.py
homeassistant/components/cover/scsgate.py
homeassistant/components/cover/wink.py
homeassistant/components/device_tracker/actiontec.py
homeassistant/components/device_tracker/aruba.py
homeassistant/components/device_tracker/asuswrt.py
homeassistant/components/device_tracker/bluetooth_tracker.py
homeassistant/components/device_tracker/bbox.py
homeassistant/components/device_tracker/bluetooth_le_tracker.py
homeassistant/components/device_tracker/bluetooth_tracker.py
homeassistant/components/device_tracker/bt_home_hub_5.py
homeassistant/components/device_tracker/ddwrt.py
homeassistant/components/device_tracker/cisco_ios.py
homeassistant/components/device_tracker/fritz.py
homeassistant/components/device_tracker/gpslogger.py
homeassistant/components/device_tracker/icloud.py
homeassistant/components/device_tracker/linksys_ap.py
homeassistant/components/device_tracker/luci.py
homeassistant/components/device_tracker/netgear.py
homeassistant/components/device_tracker/nmap_tracker.py
homeassistant/components/device_tracker/ping.py
homeassistant/components/device_tracker/sky_hub.py
homeassistant/components/device_tracker/snmp.py
homeassistant/components/device_tracker/swisscom.py
homeassistant/components/device_tracker/thomson.py
homeassistant/components/device_tracker/tomato.py
homeassistant/components/device_tracker/tado.py
homeassistant/components/device_tracker/tplink.py
homeassistant/components/device_tracker/trackr.py
homeassistant/components/device_tracker/ubus.py
homeassistant/components/discovery.py
homeassistant/components/device_tracker/xiaomi.py
homeassistant/components/downloader.py
homeassistant/components/emoncms_history.py
homeassistant/components/emulated_hue/upnp.py
homeassistant/components/fan/mqtt.py
homeassistant/components/feedreader.py
homeassistant/components/foursquare.py
homeassistant/components/garage_door/rpi_gpio.py
homeassistant/components/garage_door/wink.py
homeassistant/components/hdmi_cec.py
homeassistant/components/ifttt.py
homeassistant/components/joaoapps_join.py
homeassistant/components/keyboard.py
homeassistant/components/keyboard_remote.py
homeassistant/components/light/avion.py
homeassistant/components/light/blinksticklight.py
homeassistant/components/light/decora.py
homeassistant/components/light/flux_led.py
homeassistant/components/light/hue.py
homeassistant/components/light/hyperion.py
homeassistant/components/light/lifx.py
homeassistant/components/light/limitlessled.py
homeassistant/components/light/osramlightify.py
homeassistant/components/light/tikteck.py
homeassistant/components/light/x10.py
homeassistant/components/light/yeelight.py
homeassistant/components/light/yeelightsunflower.py
homeassistant/components/light/piglow.py
homeassistant/components/light/zengge.py
homeassistant/components/lirc.py
homeassistant/components/lock/nuki.py
homeassistant/components/media_player/anthemav.py
homeassistant/components/media_player/apple_tv.py
homeassistant/components/media_player/aquostv.py
homeassistant/components/media_player/braviatv.py
homeassistant/components/media_player/cast.py
homeassistant/components/media_player/clementine.py
homeassistant/components/media_player/cmus.py
homeassistant/components/media_player/denon.py
homeassistant/components/media_player/denonavr.py
homeassistant/components/media_player/directv.py
homeassistant/components/media_player/dunehd.py
homeassistant/components/media_player/emby.py
homeassistant/components/media_player/firetv.py
homeassistant/components/media_player/gpmdp.py
homeassistant/components/media_player/gstreamer.py
homeassistant/components/media_player/hdmi_cec.py
homeassistant/components/media_player/itunes.py
homeassistant/components/media_player/kodi.py
homeassistant/components/media_player/lg_netcast.py
homeassistant/components/media_player/liveboxplaytv.py
homeassistant/components/media_player/mpchc.py
homeassistant/components/media_player/mpd.py
homeassistant/components/media_player/nad.py
homeassistant/components/media_player/onkyo.py
homeassistant/components/media_player/openhome.py
homeassistant/components/media_player/panasonic_viera.py
homeassistant/components/media_player/pandora.py
homeassistant/components/media_player/philips_js.py
homeassistant/components/media_player/pioneer.py
homeassistant/components/media_player/plex.py
homeassistant/components/media_player/roku.py
@@ -179,22 +254,30 @@ omit =
homeassistant/components/media_player/snapcast.py
homeassistant/components/media_player/sonos.py
homeassistant/components/media_player/squeezebox.py
homeassistant/components/media_player/vlc.py
homeassistant/components/media_player/yamaha.py
homeassistant/components/notify/aws_lambda.py
homeassistant/components/notify/aws_sns.py
homeassistant/components/notify/aws_sqs.py
homeassistant/components/notify/discord.py
homeassistant/components/notify/facebook.py
homeassistant/components/notify/free_mobile.py
homeassistant/components/notify/gntp.py
homeassistant/components/notify/group.py
homeassistant/components/notify/instapush.py
homeassistant/components/notify/joaoapps_join.py
homeassistant/components/notify/kodi.py
homeassistant/components/notify/lannouncer.py
homeassistant/components/notify/llamalab_automate.py
homeassistant/components/notify/mailgun.py
homeassistant/components/notify/matrix.py
homeassistant/components/notify/message_bird.py
homeassistant/components/notify/nfandroidtv.py
homeassistant/components/notify/nma.py
homeassistant/components/notify/pushbullet.py
homeassistant/components/notify/pushetta.py
homeassistant/components/notify/pushover.py
homeassistant/components/notify/pushsafer.py
homeassistant/components/notify/rest.py
homeassistant/components/notify/sendgrid.py
homeassistant/components/notify/simplepush.py
@@ -202,89 +285,132 @@ omit =
homeassistant/components/notify/smtp.py
homeassistant/components/notify/syslog.py
homeassistant/components/notify/telegram.py
homeassistant/components/notify/telstra.py
homeassistant/components/notify/twilio_sms.py
homeassistant/components/notify/twilio_call.py
homeassistant/components/notify/twitter.py
homeassistant/components/notify/xmpp.py
homeassistant/components/nuimo_controller.py
homeassistant/components/openalpr.py
homeassistant/components/remote/harmony.py
homeassistant/components/remote/itach.py
homeassistant/components/scene/hunterdouglas_powerview.py
homeassistant/components/sensor/amcrest.py
homeassistant/components/sensor/arest.py
homeassistant/components/sensor/arwn.py
homeassistant/components/sensor/bbox.py
homeassistant/components/sensor/bitcoin.py
homeassistant/components/sensor/bom.py
homeassistant/components/sensor/broadlink.py
homeassistant/components/sensor/dublin_bus_transport.py
homeassistant/components/sensor/coinmarketcap.py
homeassistant/components/sensor/cpuspeed.py
homeassistant/components/sensor/cups.py
homeassistant/components/sensor/currencylayer.py
homeassistant/components/sensor/darksky.py
homeassistant/components/sensor/deutsche_bahn.py
homeassistant/components/sensor/dht.py
homeassistant/components/sensor/dovado.py
homeassistant/components/sensor/dte_energy_bridge.py
homeassistant/components/sensor/ebox.py
homeassistant/components/sensor/efergy.py
homeassistant/components/sensor/eliqonline.py
homeassistant/components/sensor/emoncms.py
homeassistant/components/sensor/fastdotcom.py
homeassistant/components/sensor/fedex.py
homeassistant/components/sensor/fido.py
homeassistant/components/sensor/fitbit.py
homeassistant/components/sensor/fixer.py
homeassistant/components/sensor/forecast.py
homeassistant/components/sensor/fritzbox_callmonitor.py
homeassistant/components/sensor/fritzbox_netmonitor.py
homeassistant/components/sensor/glances.py
homeassistant/components/sensor/google_travel_time.py
homeassistant/components/sensor/gpsd.py
homeassistant/components/sensor/gtfs.py
homeassistant/components/sensor/haveibeenpwned.py
homeassistant/components/sensor/hddtemp.py
homeassistant/components/sensor/hp_ilo.py
homeassistant/components/sensor/hydroquebec.py
homeassistant/components/sensor/imap.py
homeassistant/components/sensor/imap_email_content.py
homeassistant/components/sensor/influxdb.py
homeassistant/components/sensor/lastfm.py
homeassistant/components/sensor/linux_battery.py
homeassistant/components/sensor/loopenergy.py
homeassistant/components/sensor/mhz19.py
homeassistant/components/sensor/miflora.py
homeassistant/components/sensor/mqtt_room.py
homeassistant/components/sensor/netdata.py
homeassistant/components/sensor/neurio_energy.py
homeassistant/components/sensor/nut.py
homeassistant/components/sensor/nzbget.py
homeassistant/components/sensor/ohmconnect.py
homeassistant/components/sensor/onewire.py
homeassistant/components/sensor/openevse.py
homeassistant/components/sensor/openexchangerates.py
homeassistant/components/sensor/openweathermap.py
homeassistant/components/sensor/pi_hole.py
homeassistant/components/sensor/plex.py
homeassistant/components/sensor/rest.py
homeassistant/components/sensor/pocketcasts.py
homeassistant/components/sensor/pvoutput.py
homeassistant/components/sensor/qnap.py
homeassistant/components/sensor/sabnzbd.py
homeassistant/components/sensor/scrape.py
homeassistant/components/sensor/sensehat.py
homeassistant/components/sensor/serial_pm.py
homeassistant/components/sensor/skybeacon.py
homeassistant/components/sensor/sma.py
homeassistant/components/sensor/snmp.py
homeassistant/components/sensor/sonarr.py
homeassistant/components/sensor/speedtest.py
homeassistant/components/sensor/steam_online.py
homeassistant/components/sensor/supervisord.py
homeassistant/components/sensor/swiss_hydrological_data.py
homeassistant/components/sensor/swiss_public_transport.py
homeassistant/components/sensor/synologydsm.py
homeassistant/components/sensor/systemmonitor.py
homeassistant/components/sensor/ted5000.py
homeassistant/components/sensor/temper.py
homeassistant/components/sensor/time_date.py
homeassistant/components/sensor/torque.py
homeassistant/components/sensor/transmission.py
homeassistant/components/sensor/twitch.py
homeassistant/components/sensor/uber.py
homeassistant/components/sensor/worldclock.py
homeassistant/components/sensor/ups.py
homeassistant/components/sensor/usps.py
homeassistant/components/sensor/vasttrafik.py
homeassistant/components/sensor/waqi.py
homeassistant/components/sensor/xbox_live.py
homeassistant/components/sensor/yahoo_finance.py
homeassistant/components/sensor/yweather.py
homeassistant/components/sensor/zamg.py
homeassistant/components/switch/acer_projector.py
homeassistant/components/switch/anel_pwrctrl.py
homeassistant/components/switch/arest.py
homeassistant/components/switch/broadlink.py
homeassistant/components/switch/digitalloggers.py
homeassistant/components/switch/dlink.py
homeassistant/components/switch/edimax.py
homeassistant/components/switch/fritzdect.py
homeassistant/components/switch/hdmi_cec.py
homeassistant/components/switch/hikvisioncam.py
homeassistant/components/switch/hook.py
homeassistant/components/switch/kankun.py
homeassistant/components/switch/mystrom.py
homeassistant/components/switch/netio.py
homeassistant/components/switch/orvibo.py
homeassistant/components/switch/pilight.py
homeassistant/components/switch/pulseaudio_loopback.py
homeassistant/components/switch/rest.py
homeassistant/components/switch/rpi_rf.py
homeassistant/components/switch/tplink.py
homeassistant/components/switch/transmission.py
homeassistant/components/switch/wake_on_lan.py
homeassistant/components/thermostat/eq3btsmart.py
homeassistant/components/thermostat/heatmiser.py
homeassistant/components/thermostat/homematic.py
homeassistant/components/thermostat/proliphix.py
homeassistant/components/thermostat/radiotherm.py
homeassistant/components/telegram_webhooks.py
homeassistant/components/thingspeak.py
homeassistant/components/tts/amazon_polly.py
homeassistant/components/tts/picotts.py
homeassistant/components/upnp.py
homeassistant/components/weather/bom.py
homeassistant/components/weather/openweathermap.py
homeassistant/components/zeroconf.py

View File

@@ -1,9 +1,9 @@
**Description:**
**Related issue (if applicable):** fixes #
**Related issue (if applicable):** fixes #<home-assistant issue number goes here>
**Pull request in [home-assistant.io](https://github.com/home-assistant/home-assistant.io) with documentation (if applicable):** home-assistant/home-assistant.io#
**Pull request in [home-assistant.github.io](https://github.com/home-assistant/home-assistant.github.io) with documentation (if applicable):** home-assistant/home-assistant.github.io#<home-assistant.github.io PR number goes here>
**Example entry for `configuration.yaml` (if applicable):**
```yaml
@@ -13,9 +13,9 @@
**Checklist:**
If user exposed functionality or configuration variables are added/changed:
- [ ] Documentation added/updated in [home-assistant.io](https://github.com/home-assistant/home-assistant.io)
- [ ] Documentation added/updated in [home-assistant.github.io](https://github.com/home-assistant/home-assistant.github.io)
If code communicates with devices, web services, or a:
If the code communicates with devices, web services, or third-party tools:
- [ ] Local tests with `tox` run successfully. **Your PR cannot be merged unless tests pass**
- [ ] New dependencies have been added to the `REQUIREMENTS` variable ([example][ex-requir]).
- [ ] New dependencies are only imported inside functions that use them ([example][ex-import]).
@@ -26,5 +26,5 @@ If the code does not interact with devices:
- [ ] Local tests with `tox` run successfully. **Your PR cannot be merged unless tests pass**
- [ ] Tests have been added to verify that the new code works.
[ex-requir]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard.py#L16
[ex-import]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard.py#L51
[ex-requir]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard.py#L14
[ex-import]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard.py#L54

1
.gitignore vendored
View File

@@ -62,6 +62,7 @@ pip-log.txt
.coverage
.tox
nosetests.xml
htmlcov/
# Translations
*.mo

2
.hound.yml Normal file
View File

@@ -0,0 +1,2 @@
python:
enabled: true

6
.ignore Normal file
View File

@@ -0,0 +1,6 @@
# Patterns matched in this file will be ignored by supported search utilities
# Ignore generated html and javascript files
/homeassistant/components/frontend/www_static/*.html
/homeassistant/components/frontend/www_static/*.js
/homeassistant/components/frontend/www_static/panels/*.html

View File

@@ -2,19 +2,22 @@ sudo: false
matrix:
fast_finish: true
include:
- python: "3.4"
- python: "3.4.2"
env: TOXENV=py34
- python: "3.4"
- python: "3.4.2"
env: TOXENV=requirements
- python: "3.5"
- python: "3.4.2"
env: TOXENV=lint
- python: "3.5"
env: TOXENV=typing
# - python: "3.5"
# env: TOXENV=typing
- python: "3.5"
env: TOXENV=py35
allow_failures:
- python: "3.5"
env: TOXENV=typing
- python: "3.6"
env: TOXENV=py36
# allow_failures:
# - python: "3.5"
# env: TOXENV=typing
cache:
directories:
- $HOME/.cache/pip

39
CLA.md Normal file
View File

@@ -0,0 +1,39 @@
# Contributor License Agreement
```
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the Apache 2.0 license; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the Apache 2.0 license; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it) is maintained indefinitely
and may be redistributed consistent with this project or the open
source license(s) involved.
```
## Attribution
The text of this license is available under the [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/). It is based on the Linux [Developer Certificate Of Origin](http://elinux.org/Developer_Certificate_Of_Origin), but is modified to explicitly use the Apache 2.0 license
and not mention sign-off.
## Signing
To sign this CLA you must first submit a pull request to a repository under the Home Assistant organization.
## Adoption
This Contributor License Agreement (CLA) was first announced on January 21st, 2017 in [this][cla-blog] blog post and adopted January 28th, 2017.
[cla-blog]: https://home-assistant.io/blog/2017/01/21/home-assistant-governance/

80
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,80 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [safety@home-assistant.io][email]. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available [here][version].
## Adoption
This Code of Conduct was first adopted January 21st, 2017 and announced in [this][coc-blog] blog post.
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
[email]: mailto:safety@home-assistant.io
[coc-blog]: https://home-assistant.io/blog/2017/01/21/home-assistant-governance/

View File

@@ -1,13 +1,14 @@
# Contributing to Home Assistant
Everybody is invited and welcome to contribute to Home Assistant. There is a lot to do...if you are not a developer perhaps you would like to help with the documentation on [home-assistant.io](https://home-assistant.io/)? If you are a developer and have devices in your home which aren't working with Home Assistant yet, why not spent a couple of hours and help to integrate them?
Everybody is invited and welcome to contribute to Home Assistant. There is a lot to do...if you are not a developer perhaps you would like to help with the documentation on [home-assistant.io](https://home-assistant.io/)? If you are a developer and have devices in your home which aren't working with Home Assistant yet, why not spent a couple of hours and help to integrate them?
The process is straight-forward.
- Read [How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/devel/faster_reviews.md) by Kubernetes (but skip step 0)
- Fork the Home Assistant [git repository](https://github.com/home-assistant/home-assistant).
- Write the code for your device, notification service, sensor, or IoT thing.
- Ensure tests work.
- Create a Pull Request against the [**dev**](https://github.com/home-assistant/home-assistant/tree/dev) branch of Home Assistant.
Still interested? Then you should take a peak at the [developer documentation](https://home-assistant.io/developers/) to get more details.
Still interested? Then you should take a peak at the [developer documentation](https://home-assistant.io/developers/) to get more details.

View File

@@ -1,29 +1,29 @@
FROM python:3.5
MAINTAINER Paulus Schoutsen <Paulus@PaulusSchoutsen.nl>
# Uncomment any of the following lines to disable the installation.
#ENV INSTALL_TELLSTICK no
#ENV INSTALL_OPENALPR no
#ENV INSTALL_FFMPEG no
#ENV INSTALL_OPENZWAVE no
#ENV INSTALL_LIBCEC no
#ENV INSTALL_PHANTOMJS no
VOLUME /config
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN pip3 install --no-cache-dir colorlog cython
# For the nmap tracker, bluetooth tracker, Z-Wave
RUN apt-get update && \
apt-get install -y --no-install-recommends nmap net-tools cython3 libudev-dev sudo libglib2.0-dev bluetooth libbluetooth-dev && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
COPY script/build_python_openzwave script/build_python_openzwave
RUN script/build_python_openzwave && \
mkdir -p /usr/local/share/python-openzwave && \
ln -sf /usr/src/app/build/python-openzwave/openzwave/config /usr/local/share/python-openzwave/config
# Copy build scripts
COPY virtualization/Docker/ virtualization/Docker/
RUN virtualization/Docker/setup_docker_prereqs
# Install hass component dependencies
COPY requirements_all.txt requirements_all.txt
# certifi breaks Debian based installs
RUN pip3 install --no-cache-dir -r requirements_all.txt && pip3 uninstall -y certifi && \
pip3 install mysqlclient psycopg2 uvloop
RUN pip3 install --no-cache-dir -r requirements_all.txt && \
pip3 install --no-cache-dir mysqlclient psycopg2 uvloop
# Copy source
COPY . .
CMD [ "python", "-m", "homeassistant", "--config", "/config" ]
CMD [ "python", "-m", "homeassistant", "--config", "/config" ]

20
LICENSE
View File

@@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2016 Paulus Schoutsen
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

194
LICENSE.md Normal file
View File

@@ -0,0 +1,194 @@
Apache License
==============
_Version 2.0, January 2004_
_&lt;<http://www.apache.org/licenses/>&gt;_
### Terms and Conditions for use, reproduction, and distribution
#### 1. Definitions
“License” shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, “control” means **(i)** the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
outstanding shares, or **(iii)** beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising
permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
“Object” form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
“submitted” means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
#### 2. Grant of Copyright License
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
#### 3. Grant of Patent License
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
#### 4. Redistribution
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
this License; and
* **(b)** You must cause any modified files to carry prominent notices stating that You
changed the files; and
* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
#### 5. Submission of Contributions
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
#### 6. Trademarks
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
#### 7. Disclaimer of Warranty
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
#### 8. Limitation of Liability
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
#### 9. Accepting Warranty or Additional Liability
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
_END OF TERMS AND CONDITIONS_
### APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets `[]` replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same “printed page” as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -26,7 +26,8 @@ Examples of devices Home Assistant can interface with:
`Netgear <http://netgear.com>`__,
`DD-WRT <http://www.dd-wrt.com/site/index>`__,
`TPLink <http://www.tp-link.us/>`__,
`ASUSWRT <http://event.asus.com/2013/nw/ASUSWRT/>`__ and any SNMP
`ASUSWRT <http://event.asus.com/2013/nw/ASUSWRT/>`__,
`Xiaomi <http://miwifi.com/>`__ and any SNMP
capable Linksys WAP/WRT
- `Philips Hue <http://meethue.com>`__ lights,
`WeMo <http://www.belkin.com/us/Products/home-automation/c/wemo-home-automation/>`__
@@ -74,7 +75,8 @@ Build home automation on top of your devices:
`Instapush <https://instapush.im>`__, `Notify My Android
(NMA) <http://www.notifymyandroid.com/>`__,
`PushBullet <https://www.pushbullet.com/>`__,
`PushOver <https://pushover.net/>`__, `Slack <https://slack.com/>`__,
`PushOver <https://pushover.net/>`__,
`Slack <https://slack.com/>`__,
`Telegram <https://telegram.org/>`__, `Join <http://joaoapps.com/join/>`__, and `Jabber
(XMPP) <http://xmpp.org>`__
@@ -86,7 +88,7 @@ components <https://home-assistant.io/developers/creating_components/>`__.
If you run into issues while using Home Assistant or during development
of a component, check the `Home Assistant help
section <https://home-assistant.io/help/>`__ how to reach us.
section <https://home-assistant.io/help/>`__ of our website for further help and information.
.. |Build Status| image:: https://travis-ci.org/home-assistant/home-assistant.svg?branch=master
:target: https://travis-ci.org/home-assistant/home-assistant

View File

@@ -1,7 +1,7 @@
homeassistant:
# Omitted values in this section will be auto detected using freegeoip.io
# Location required to calculate the time the sun rises and sets.
# Location required to calculate the time the sun rises and sets.
# Coordinates are also used for location for weather related components.
# Google Maps can be used to determine more precise GPS coordinates.
latitude: 32.87336
@@ -43,12 +43,10 @@ device_tracker:
username: admin
password: PASSWORD
chromecast:
switch:
platform: wemo
thermostat:
climate:
platform: nest
# Required: username and password that are used to login to the Nest thermostat.
username: myemail@mydomain.com
@@ -79,7 +77,6 @@ group:
entities:
- group.awesome_people
- group.climate
kitchen:
name: Kitchen
entities:
@@ -92,52 +89,23 @@ group:
- input_boolean.notify_home
- camera.demo_camera
example:
simple_alarm:
# Which light/light group has to flash when a known device comes home
known_light: light.Bowl
# Which light/light group has to flash red when light turns on while no one home
unknown_light: group.living_room
browser:
keyboard:
# https://home-assistant.io/getting-started/automation/
automation:
- alias: 'Rule 1 Light on in the evening'
trigger:
- platform: sun
- alias: Turn on light when sun sets
trigger:
platform: sun
event: sunset
offset: "-01:00:00"
- platform: state
condition:
condition: state
entity_id: group.all_devices
state: home
condition:
- platform: state
entity_id: group.all_devices
state: home
- platform: time
after: "16:00:00"
before: "23:00:00"
action:
service: homeassistant.turn_on
entity_id: group.living_room
state: 'home'
action:
service: light.turn_on
- alias: 'Rule 2 - Away Mode'
trigger:
- platform: state
entity_id: group.all_devices
state: 'not_home'
condition: use_trigger_values
action:
service: light.turn_off
entity_id: group.all_lights
# Sensors need to be added into the configuration.yaml as sensor:, sensor 2:, sensor 3:, etc.
# Each sensor label should be unique or your sensors might not load correctly.
# Another way to do is to collect all entries under one "sensor:"
# sensor:
# - platform: mqtt
@@ -154,34 +122,30 @@ sensor:
arg: '/'
- type: 'disk_use_percent'
arg: '/home'
- type: 'disk_use'
arg: '/home'
sensor 2:
platform: forecast
api_key: <register on Forecast.io for your PRIVATE API>
monitored_conditions:
- summary
- precip_type
- precip_intensity
- temperature
platform: cpuspeed
script:
# Turns on the bedroom lights and then the living room lights 1 minute later
wakeup:
alias: Wake Up
sequence:
# alias is optional
- event: LOGBOOK_ENTRY
event_data:
name: Paulus
message: is waking up
entity_id: device_tracker.paulus
domain: light
- alias: Bedroom lights on
execute_service: light.turn_on
service_data:
service: light.turn_on
data:
entity_id: group.bedroom
brightness: 100
- delay:
# supports seconds, milliseconds, minutes, hours, etc.
minutes: 1
- alias: Living room lights on
execute_service: light.turn_on
service_data:
service: light.turn_on
data:
entity_id: group.living_room
scene:

View File

@@ -8,11 +8,31 @@
.. autoclass:: Config
:members:
.. autoclass:: Event
:members:
.. autoclass:: EventBus
:members:
.. autoclass:: HomeAssistant
:members:
.. autoclass:: State
:members:
.. autoclass:: StateMachine
:members:
.. autoclass:: ServiceCall
:members:
.. autoclass:: ServiceRegistry
:members:
Module contents
---------------
.. automodule:: homeassistant.core
:members:
:undoc-members:
:show-inheritance:

View File

@@ -4,6 +4,14 @@ homeassistant.util package
Submodules
----------
homeassistant.util.async module
-------------------------------
.. automodule:: homeassistant.util.async
:members:
:undoc-members:
:show-inheritance:
homeassistant.util.color module
-------------------------------

View File

@@ -340,8 +340,8 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'Home-Assistant.tex', 'Home-Assistant Documentation',
'Home-Assistant Team', 'manual'),
(master_doc, 'home-assistant.tex', 'Home Assistant Documentation',
'Home Assistant Team', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -382,7 +382,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'home-assistant', 'Home-Assistant Documentation',
(master_doc, 'home-assistant', 'Home Assistant Documentation',
[author], 1)
]
@@ -397,8 +397,8 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Home-Assistant', 'Home-Assistant Documentation',
author, 'Home-Assistant', 'One line description of project.',
(master_doc, 'Home-Assistant', 'Home Assistant Documentation',
author, 'Home Assistant', 'Open-source home automation platform.',
'Miscellaneous'),
]

View File

@@ -2,7 +2,7 @@ swagger: '2.0'
info:
title: Home Assistant
description: Home Assistant REST API
version: "1.0.0"
version: "1.0.1"
# the domain of the service
host: localhost:8123
@@ -12,17 +12,17 @@ schemes:
- https
securityDefinitions:
api_key:
type: apiKey
description: API password
name: api_password
in: query
# api_key:
#api_key:
# type: apiKey
# description: API password
# name: x-ha-access
# in: header
# name: api_password
# in: query
api_key:
type: apiKey
description: API password
name: x-ha-access
in: header
# will be prefixed to all paths
basePath: /api
@@ -38,6 +38,8 @@ paths:
description: Returns message if API is up and running.
tags:
- Core
security:
- api_key: []
responses:
200:
description: API is up and running
@@ -53,6 +55,8 @@ paths:
description: Returns the current configuration as JSON.
tags:
- Core
security:
- api_key: []
responses:
200:
description: Current configuration
@@ -81,6 +85,8 @@ paths:
summary: Returns all data needed to bootstrap Home Assistant.
tags:
- Core
security:
- api_key: []
responses:
200:
description: Bootstrap information
@@ -96,6 +102,8 @@ paths:
description: Returns an array of event objects. Each event object contain event name and listener count.
tags:
- Events
security:
- api_key: []
responses:
200:
description: Events
@@ -113,6 +121,8 @@ paths:
description: Returns an array of service objects. Each object contains the domain and which services it contains.
tags:
- Services
security:
- api_key: []
responses:
200:
description: Services
@@ -130,6 +140,8 @@ paths:
description: Returns an array of state changes in the past. Each object contains further detail for the entities.
tags:
- State
security:
- api_key: []
responses:
200:
description: State changes
@@ -148,6 +160,8 @@ paths:
Returns an array of state objects. Each state has the following attributes: entity_id, state, last_changed and attributes.
tags:
- State
security:
- api_key: []
responses:
200:
description: States
@@ -166,6 +180,8 @@ paths:
Returns a state object for specified entity_id.
tags:
- State
security:
- api_key: []
parameters:
- name: entity_id
in: path
@@ -223,6 +239,8 @@ paths:
Retrieve all errors logged during the current session of Home Assistant as a plaintext response.
tags:
- Core
security:
- api_key: []
produces:
- text/plain
responses:
@@ -239,6 +257,8 @@ paths:
Returns the data (image) from the specified camera entity_id.
tags:
- Camera
security:
- api_key: []
produces:
- image/jpeg
parameters:
@@ -262,6 +282,8 @@ paths:
Fires an event with event_type
tags:
- Events
security:
- api_key: []
consumes:
- application/json
parameters:
@@ -286,6 +308,8 @@ paths:
Calls a service within a specific domain. Will return when the service has been executed or 10 seconds has past, whichever comes first.
tags:
- Services
security:
- api_key: []
consumes:
- application/json
parameters:
@@ -317,6 +341,8 @@ paths:
Render a Home Assistant template.
tags:
- Template
security:
- api_key: []
consumes:
- application/json
produces:
@@ -338,6 +364,8 @@ paths:
Setup event forwarding to another Home Assistant instance.
tags:
- Core
security:
- api_key: []
consumes:
- application/json
parameters:
@@ -376,6 +404,8 @@ paths:
tags:
- Core
- Events
security:
- api_key: []
produces:
- text/event-stream
parameters:
@@ -420,8 +450,16 @@ definitions:
location_name:
type: string
unit_system:
type: string
description: The system for measurement units
type: object
properties:
length:
type: string
mass:
type: string
temperature:
type: string
volume:
type: string
time_zone:
type: string
version:

View File

@@ -14,14 +14,62 @@ from homeassistant.const import (
__version__,
EVENT_HOMEASSISTANT_START,
REQUIRED_PYTHON_VER,
REQUIRED_PYTHON_VER_WIN,
RESTART_EXIT_CODE,
)
from homeassistant.util.async import run_callback_threadsafe
def monkey_patch_asyncio():
"""Replace weakref.WeakSet to address Python 3 bug.
Under heavy threading operations that schedule calls into
the asyncio event loop, Task objects are created. Due to
a bug in Python, GC may have an issue when switching between
the threads and objects with __del__ (which various components
in HASS have).
This monkey-patch removes the weakref.Weakset, and replaces it
with an object that ignores the only call utilizing it (the
Task.__init__ which calls _all_tasks.add(self)). It also removes
the __del__ which could trigger the future objects __del__ at
unpredictable times.
The side-effect of this manipulation of the Task is that
Task.all_tasks() is no longer accurate, and there will be no
warning emitted if a Task is GC'd while in use.
On Python 3.6, after the bug is fixed, this monkey-patch can be
disabled.
See https://bugs.python.org/issue26617 for details of the Python
bug.
"""
# pylint: disable=no-self-use, protected-access, bare-except
import asyncio.tasks
class IgnoreCalls:
"""Ignore add calls."""
def add(self, other):
"""No-op add."""
return
asyncio.tasks.Task._all_tasks = IgnoreCalls()
try:
del asyncio.tasks.Task.__del__
except:
pass
def validate_python() -> None:
"""Validate we're running the right Python version."""
if sys.version_info[:3] < REQUIRED_PYTHON_VER:
if sys.platform == "win32" and \
sys.version_info[:3] < REQUIRED_PYTHON_VER_WIN:
print("Home Assistant requires at least Python {}.{}.{}".format(
*REQUIRED_PYTHON_VER_WIN))
sys.exit(1)
elif sys.version_info[:3] < REQUIRED_PYTHON_VER:
print("Home Assistant requires at least Python {}.{}.{}".format(
*REQUIRED_PYTHON_VER))
sys.exit(1)
@@ -308,6 +356,9 @@ def try_to_restart() -> None:
def main() -> int:
"""Start Home Assistant."""
if sys.version_info[:3] < (3, 5, 3):
monkey_patch_asyncio()
validate_python()
args = get_arguments()

View File

@@ -1,11 +1,10 @@
"""Provides methods to bootstrap a home assistant instance."""
import asyncio
import logging
import logging.handlers
import os
import sys
from collections import defaultdict
from threading import RLock
from collections import OrderedDict
from types import ModuleType
from typing import Any, Optional, Dict
@@ -17,42 +16,64 @@ import homeassistant.components as core_components
from homeassistant.components import persistent_notification
import homeassistant.config as conf_util
import homeassistant.core as core
from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE
import homeassistant.loader as loader
import homeassistant.util.package as pkg_util
from homeassistant.util.async import (
run_coroutine_threadsafe, run_callback_threadsafe)
from homeassistant.util.logging import AsyncHandler
from homeassistant.util.yaml import clear_secret_cache
from homeassistant.const import EVENT_COMPONENT_LOADED, PLATFORM_FORMAT
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import (
event_decorators, service, config_per_platform, extract_domain_configs)
from homeassistant.helpers.signal import async_register_signal_handling
_LOGGER = logging.getLogger(__name__)
_SETUP_LOCK = RLock()
_CURRENT_SETUP = []
ATTR_COMPONENT = 'component'
ERROR_LOG_FILENAME = 'home-assistant.log'
_PERSISTENT_ERRORS = {}
HA_COMPONENT_URL = '[{}](https://home-assistant.io/components/{}/)'
def setup_component(hass: core.HomeAssistant, domain: str,
config: Optional[Dict]=None) -> bool:
"""Setup a component and all its dependencies."""
return run_coroutine_threadsafe(
async_setup_component(hass, domain, config), loop=hass.loop).result()
@asyncio.coroutine
def async_setup_component(hass: core.HomeAssistant, domain: str,
config: Optional[Dict]=None) -> bool:
"""Setup a component and all its dependencies.
This method is a coroutine.
"""
if domain in hass.config.components:
_LOGGER.debug('Component %s already set up.', domain)
return True
_ensure_loader_prepared(hass)
if not loader.PREPARED:
yield from hass.loop.run_in_executor(None, loader.prepare, hass)
if config is None:
config = defaultdict(dict)
config = {}
components = loader.load_order_component(domain)
# OrderedSet is empty if component or dependencies could not be resolved
if not components:
_async_persistent_notification(hass, domain, True)
return False
for component in components:
if not _setup_component(hass, component, config):
res = yield from _async_setup_component(hass, component, config)
if not res:
_LOGGER.error('Component %s failed to setup', component)
_async_persistent_notification(hass, component, True)
return False
return True
@@ -60,7 +81,10 @@ def setup_component(hass: core.HomeAssistant, domain: str,
def _handle_requirements(hass: core.HomeAssistant, component,
name: str) -> bool:
"""Install the requirements for a component."""
"""Install the requirements for a component.
This method needs to run in an executor.
"""
if hass.config.skip_pip or not hasattr(component, 'REQUIREMENTS'):
return True
@@ -68,70 +92,109 @@ def _handle_requirements(hass: core.HomeAssistant, component,
if not pkg_util.install_package(req, target=hass.config.path('deps')):
_LOGGER.error('Not initializing %s because could not install '
'dependency %s', name, req)
_async_persistent_notification(hass, name)
return False
return True
def _setup_component(hass: core.HomeAssistant, domain: str, config) -> bool:
"""Setup a component for Home Assistant."""
# pylint: disable=too-many-return-statements,too-many-branches
# pylint: disable=too-many-statements
@asyncio.coroutine
def _async_setup_component(hass: core.HomeAssistant,
domain: str, config) -> bool:
"""Setup a component for Home Assistant.
This method is a coroutine.
"""
# pylint: disable=too-many-return-statements
if domain in hass.config.components:
return True
with _SETUP_LOCK:
# It might have been loaded while waiting for lock
if domain in hass.config.components:
return True
setup_lock = hass.data.get('setup_lock')
if setup_lock is None:
setup_lock = hass.data['setup_lock'] = asyncio.Lock(loop=hass.loop)
if domain in _CURRENT_SETUP:
_LOGGER.error('Attempt made to setup %s during setup of %s',
domain, domain)
return False
setup_progress = hass.data.get('setup_progress')
if setup_progress is None:
setup_progress = hass.data['setup_progress'] = []
config = prepare_setup_component(hass, config, domain)
if domain in setup_progress:
_LOGGER.error('Attempt made to setup %s during setup of %s',
domain, domain)
_async_persistent_notification(hass, domain, True)
return False
try:
# Used to indicate to discovery that a setup is ongoing and allow it
# to wait till it is done.
did_lock = False
if not setup_lock.locked():
yield from setup_lock.acquire()
did_lock = True
setup_progress.append(domain)
config = yield from async_prepare_setup_component(hass, config, domain)
if config is None:
return False
component = loader.get_component(domain)
_CURRENT_SETUP.append(domain)
if component is None:
_async_persistent_notification(hass, domain)
return False
async_comp = hasattr(component, 'async_setup')
try:
result = component.setup(hass, config)
if result is False:
_LOGGER.error('component %s failed to initialize', domain)
return False
elif result is not True:
_LOGGER.error('component %s did not return boolean if setup '
'was successful. Disabling component.', domain)
loader.set_component(domain, None)
return False
_LOGGER.info("Setting up %s", domain)
if async_comp:
result = yield from component.async_setup(hass, config)
else:
result = yield from hass.loop.run_in_executor(
None, component.setup, hass, config)
except Exception: # pylint: disable=broad-except
_LOGGER.exception('Error during setup of component %s', domain)
_async_persistent_notification(hass, domain, True)
return False
finally:
_CURRENT_SETUP.remove(domain)
hass.config.components.append(component.DOMAIN)
if result is False:
_LOGGER.error('component %s failed to initialize', domain)
_async_persistent_notification(hass, domain, True)
return False
elif result is not True:
_LOGGER.error('component %s did not return boolean if setup '
'was successful. Disabling component.', domain)
_async_persistent_notification(hass, domain, True)
loader.set_component(domain, None)
return False
# Assumption: if a component does not depend on groups
# it communicates with devices
if 'group' not in getattr(component, 'DEPENDENCIES', []) and \
hass.pool.worker_count <= 10:
hass.pool.add_worker()
hass.config.components.add(component.DOMAIN)
hass.bus.fire(
hass.bus.async_fire(
EVENT_COMPONENT_LOADED, {ATTR_COMPONENT: component.DOMAIN}
)
return True
finally:
setup_progress.remove(domain)
if did_lock:
setup_lock.release()
def prepare_setup_component(hass: core.HomeAssistant, config: dict,
domain: str):
"""Prepare setup of a component and return processed config."""
return run_coroutine_threadsafe(
async_prepare_setup_component(hass, config, domain), loop=hass.loop
).result()
@asyncio.coroutine
def async_prepare_setup_component(hass: core.HomeAssistant, config: dict,
domain: str):
"""Prepare setup of a component and return processed config.
This method is a coroutine.
"""
# pylint: disable=too-many-return-statements
component = loader.get_component(domain)
missing_deps = [dep for dep in getattr(component, 'DEPENDENCIES', [])
@@ -147,7 +210,7 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
try:
config = component.CONFIG_SCHEMA(config)
except vol.Invalid as ex:
log_exception(ex, domain, config)
async_log_exception(ex, domain, config, hass)
return None
elif hasattr(component, 'PLATFORM_SCHEMA'):
@@ -157,8 +220,8 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
try:
p_validated = component.PLATFORM_SCHEMA(p_config)
except vol.Invalid as ex:
log_exception(ex, domain, config)
return None
async_log_exception(ex, domain, config, hass)
continue
# Not all platform components follow same pattern for platforms
# So if p_name is None we are not going to validate platform
@@ -167,20 +230,21 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
platforms.append(p_validated)
continue
platform = prepare_setup_platform(hass, config, domain,
p_name)
platform = yield from async_prepare_setup_platform(
hass, config, domain, p_name)
if platform is None:
return None
continue
# Validate platform specific schema
if hasattr(platform, 'PLATFORM_SCHEMA'):
try:
# pylint: disable=no-member
p_validated = platform.PLATFORM_SCHEMA(p_validated)
except vol.Invalid as ex:
log_exception(ex, '{}.{}'.format(domain, p_name),
p_validated)
return None
async_log_exception(ex, '{}.{}'.format(domain, p_name),
p_validated, hass)
continue
platforms.append(p_validated)
@@ -191,7 +255,9 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
if key not in filter_keys}
config[domain] = platforms
if not _handle_requirements(hass, component, domain):
res = yield from hass.loop.run_in_executor(
None, _handle_requirements, hass, component, domain)
if not res:
return None
return config
@@ -200,7 +266,22 @@ def prepare_setup_component(hass: core.HomeAssistant, config: dict,
def prepare_setup_platform(hass: core.HomeAssistant, config, domain: str,
platform_name: str) -> Optional[ModuleType]:
"""Load a platform and makes sure dependencies are setup."""
_ensure_loader_prepared(hass)
return run_coroutine_threadsafe(
async_prepare_setup_platform(hass, config, domain, platform_name),
loop=hass.loop
).result()
@asyncio.coroutine
def async_prepare_setup_platform(hass: core.HomeAssistant, config, domain: str,
platform_name: str) \
-> Optional[ModuleType]:
"""Load a platform and makes sure dependencies are setup.
This method is a coroutine.
"""
if not loader.PREPARED:
yield from hass.loop.run_in_executor(None, loader.prepare, hass)
platform_path = PLATFORM_FORMAT.format(domain, platform_name)
@@ -209,6 +290,7 @@ def prepare_setup_platform(hass: core.HomeAssistant, config, domain: str,
# Not found
if platform is None:
_LOGGER.error('Unable to find platform %s', platform_path)
_async_persistent_notification(hass, platform_path)
return None
# Already loaded
@@ -217,20 +299,27 @@ def prepare_setup_platform(hass: core.HomeAssistant, config, domain: str,
# Load dependencies
for component in getattr(platform, 'DEPENDENCIES', []):
if not setup_component(hass, component, config):
if component in loader.DEPENDENCY_BLACKLIST:
raise HomeAssistantError(
'{} is not allowed to be a dependency.'.format(component))
res = yield from async_setup_component(hass, component, config)
if not res:
_LOGGER.error(
'Unable to prepare setup for platform %s because '
'dependency %s could not be initialized', platform_path,
component)
_async_persistent_notification(hass, platform_path, True)
return None
if not _handle_requirements(hass, platform, platform_path):
res = yield from hass.loop.run_in_executor(
None, _handle_requirements, hass, platform, platform_path)
if not res:
return None
return platform
# pylint: disable=too-many-branches, too-many-statements, too-many-arguments
def from_config_dict(config: Dict[str, Any],
hass: Optional[core.HomeAssistant]=None,
config_dir: Optional[str]=None,
@@ -250,59 +339,115 @@ def from_config_dict(config: Dict[str, Any],
hass.config.config_dir = config_dir
mount_local_lib_path(config_dir)
@asyncio.coroutine
def _async_init_from_config_dict(future):
try:
re_hass = yield from async_from_config_dict(
config, hass, config_dir, enable_log, verbose, skip_pip,
log_rotate_days)
future.set_result(re_hass)
# pylint: disable=broad-except
except Exception as exc:
future.set_exception(exc)
# run task
future = asyncio.Future(loop=hass.loop)
hass.async_add_job(_async_init_from_config_dict(future))
hass.loop.run_until_complete(future)
return future.result()
@asyncio.coroutine
def async_from_config_dict(config: Dict[str, Any],
hass: core.HomeAssistant,
config_dir: Optional[str]=None,
enable_log: bool=True,
verbose: bool=False,
skip_pip: bool=False,
log_rotate_days: Any=None) \
-> Optional[core.HomeAssistant]:
"""Try to configure Home Assistant from a config dict.
Dynamically loads required components and its dependencies.
This method is a coroutine.
"""
hass.async_track_tasks()
setup_lock = hass.data.get('setup_lock')
if setup_lock is None:
setup_lock = hass.data['setup_lock'] = asyncio.Lock(loop=hass.loop)
yield from setup_lock.acquire()
core_config = config.get(core.DOMAIN, {})
try:
conf_util.process_ha_core_config(hass, core_config)
yield from conf_util.async_process_ha_core_config(hass, core_config)
except vol.Invalid as ex:
log_exception(ex, 'homeassistant', core_config)
async_log_exception(ex, 'homeassistant', core_config, hass)
return None
conf_util.process_ha_config_upgrade(hass)
yield from hass.loop.run_in_executor(
None, conf_util.process_ha_config_upgrade, hass)
if enable_log:
enable_logging(hass, verbose, log_rotate_days)
async_enable_logging(hass, verbose, log_rotate_days)
hass.config.skip_pip = skip_pip
if skip_pip:
_LOGGER.warning('Skipping pip installation of required modules. '
'This may cause issues.')
_ensure_loader_prepared(hass)
if not loader.PREPARED:
yield from hass.loop.run_in_executor(None, loader.prepare, hass)
# Merge packages
conf_util.merge_packages_config(
config, core_config.get(conf_util.CONF_PACKAGES, {}))
# Make a copy because we are mutating it.
# Convert it to defaultdict so components can always have config dict
# Use OrderedDict in case original one was one.
# Convert values to dictionaries if they are None
config = defaultdict(
dict, {key: value or {} for key, value in config.items()})
new_config = OrderedDict()
for key, value in config.items():
new_config[key] = value or {}
config = new_config
# Filter out the repeating and common config section [homeassistant]
components = set(key.split(' ')[0] for key in config.keys()
if key != core.DOMAIN)
# Setup in a thread to avoid blocking
def component_setup():
"""Set up a component."""
if not core_components.setup(hass, config):
_LOGGER.error('Home Assistant core failed to initialize. '
'Further initialization aborted.')
return hass
# setup components
# pylint: disable=not-an-iterable
res = yield from core_components.async_setup(hass, config)
if not res:
_LOGGER.error('Home Assistant core failed to initialize. '
'Further initialization aborted.')
return hass
persistent_notification.setup(hass, config)
yield from persistent_notification.async_setup(hass, config)
_LOGGER.info('Home Assistant core initialized')
_LOGGER.info('Home Assistant core initialized')
# Give event decorators access to HASS
event_decorators.HASS = hass
service.HASS = hass
# Give event decorators access to HASS
event_decorators.HASS = hass
service.HASS = hass
# Setup the components
for domain in loader.load_order_components(components):
_setup_component(hass, domain, config)
# Setup the components
dependency_blacklist = loader.DEPENDENCY_BLACKLIST - set(components)
hass.loop.run_until_complete(
hass.loop.run_in_executor(None, component_setup)
)
for domain in loader.load_order_components(components):
if domain in dependency_blacklist:
raise HomeAssistantError(
'{} is not allowed to be a dependency'.format(domain))
yield from _async_setup_component(hass, domain, config)
setup_lock.release()
yield from hass.async_stop_track_tasks()
async_register_signal_handling(hass)
return hass
@@ -319,35 +464,79 @@ def from_config_file(config_path: str,
if hass is None:
hass = core.HomeAssistant()
@asyncio.coroutine
def _async_init_from_config_file(future):
try:
re_hass = yield from async_from_config_file(
config_path, hass, verbose, skip_pip, log_rotate_days)
future.set_result(re_hass)
# pylint: disable=broad-except
except Exception as exc:
future.set_exception(exc)
# run task
future = asyncio.Future(loop=hass.loop)
hass.loop.create_task(_async_init_from_config_file(future))
hass.loop.run_until_complete(future)
return future.result()
@asyncio.coroutine
def async_from_config_file(config_path: str,
hass: core.HomeAssistant,
verbose: bool=False,
skip_pip: bool=True,
log_rotate_days: Any=None):
"""Read the configuration file and try to start all the functionality.
Will add functionality to 'hass' parameter.
This method is a coroutine.
"""
# Set config dir to directory holding config file
config_dir = os.path.abspath(os.path.dirname(config_path))
hass.config.config_dir = config_dir
mount_local_lib_path(config_dir)
yield from hass.loop.run_in_executor(
None, mount_local_lib_path, config_dir)
enable_logging(hass, verbose, log_rotate_days)
async_enable_logging(hass, verbose, log_rotate_days)
try:
config_dict = conf_util.load_yaml_config_file(config_path)
config_dict = yield from hass.loop.run_in_executor(
None, conf_util.load_yaml_config_file, config_path)
except HomeAssistantError:
return None
finally:
clear_secret_cache()
return from_config_dict(config_dict, hass, enable_log=False,
skip_pip=skip_pip)
hass = yield from async_from_config_dict(
config_dict, hass, enable_log=False, skip_pip=skip_pip)
return hass
def enable_logging(hass: core.HomeAssistant, verbose: bool=False,
log_rotate_days=None) -> None:
"""Setup the logging."""
@core.callback
def async_enable_logging(hass: core.HomeAssistant, verbose: bool=False,
log_rotate_days=None) -> None:
"""Setup the logging.
This method must be run in the event loop.
"""
logging.basicConfig(level=logging.INFO)
fmt = ("%(log_color)s%(asctime)s %(levelname)s (%(threadName)s) "
"[%(name)s] %(message)s%(reset)s")
fmt = ("%(asctime)s %(levelname)s (%(threadName)s) "
"[%(name)s] %(message)s")
colorfmt = "%(log_color)s{}%(reset)s".format(fmt)
datefmt = '%y-%m-%d %H:%M:%S'
# suppress overly verbose logs from libraries that aren't helpful
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("aiohttp.access").setLevel(logging.WARNING)
try:
from colorlog import ColoredFormatter
logging.getLogger().handlers[0].setFormatter(ColoredFormatter(
fmt,
datefmt='%y-%m-%d %H:%M:%S',
colorfmt,
datefmt=datefmt,
reset=True,
log_colors={
'DEBUG': 'cyan',
@@ -377,11 +566,21 @@ def enable_logging(hass: core.HomeAssistant, verbose: bool=False,
err_log_path, mode='w', delay=True)
err_handler.setLevel(logging.INFO if verbose else logging.WARNING)
err_handler.setFormatter(
logging.Formatter('%(asctime)s %(name)s: %(message)s',
datefmt='%y-%m-%d %H:%M:%S'))
err_handler.setFormatter(logging.Formatter(fmt, datefmt=datefmt))
async_handler = AsyncHandler(hass.loop, err_handler)
@asyncio.coroutine
def async_stop_async_handler(event):
"""Cleanup async handler."""
logging.getLogger('').removeHandler(async_handler)
yield from async_handler.async_close(blocking=True)
hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_CLOSE, async_stop_async_handler)
logger = logging.getLogger('')
logger.addHandler(err_handler)
logger.addHandler(async_handler)
logger.setLevel(logging.INFO)
else:
@@ -389,36 +588,62 @@ def enable_logging(hass: core.HomeAssistant, verbose: bool=False,
'Unable to setup error log %s (access denied)', err_log_path)
def _ensure_loader_prepared(hass: core.HomeAssistant) -> None:
"""Ensure Home Assistant loader is prepared."""
if not loader.PREPARED:
loader.prepare(hass)
def log_exception(ex, domain, config):
def log_exception(ex, domain, config, hass):
"""Generate log exception for config validation."""
run_callback_threadsafe(
hass.loop, async_log_exception, ex, domain, config, hass).result()
@core.callback
def _async_persistent_notification(hass: core.HomeAssistant, component: str,
link: Optional[bool]=False):
"""Print a persistent notification.
This method must be run in the event loop.
"""
_PERSISTENT_ERRORS[component] = _PERSISTENT_ERRORS.get(component) or link
_lst = [HA_COMPONENT_URL.format(name.replace('_', '-'), name)
if link else name for name, link in _PERSISTENT_ERRORS.items()]
message = ('The following components and platforms could not be set up:\n'
'* ' + '\n* '.join(list(_lst)) + '\nPlease check your config')
persistent_notification.async_create(
hass, message, 'Invalid config', 'invalid_config')
@core.callback
def async_log_exception(ex, domain, config, hass):
"""Generate log exception for config validation.
This method must be run in the event loop.
"""
message = 'Invalid config for [{}]: '.format(domain)
if hass is not None:
_async_persistent_notification(hass, domain, True)
if 'extra keys not allowed' in ex.error_message:
message += '[{}] is an invalid option for [{}]. Check: {}->{}.'\
.format(ex.path[-1], domain, domain,
'->'.join('%s' % m for m in ex.path))
'->'.join(str(m) for m in ex.path))
else:
message += '{}.'.format(humanize_error(config, ex))
if hasattr(config, '__line__'):
message += " (See {}:{})".format(
config.__config_file__, config.__line__ or '?')
domain_config = config.get(domain, config)
message += " (See {}, line {}). ".format(
getattr(domain_config, '__config_file__', '?'),
getattr(domain_config, '__line__', '?'))
if domain != 'homeassistant':
message += (' Please check the docs at '
message += ('Please check the docs at '
'https://home-assistant.io/components/{}/'.format(domain))
_LOGGER.error(message)
def mount_local_lib_path(config_dir: str) -> str:
"""Add local library to Python Path."""
"""Add local library to Python Path.
Async friendly.
"""
deps_dir = os.path.join(config_dir, 'deps')
if deps_dir not in sys.path:
sys.path.insert(0, os.path.join(config_dir, 'deps'))

View File

@@ -7,18 +7,24 @@ Component design guidelines:
format "<DOMAIN>.<OBJECT_ID>".
- Each component should publish services only under its own domain.
"""
import asyncio
import itertools as it
import logging
import homeassistant.core as ha
import homeassistant.config as conf_util
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.service import extract_entity_ids
from homeassistant.loader import get_component
from homeassistant.const import (
ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE)
ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE,
SERVICE_HOMEASSISTANT_STOP, SERVICE_HOMEASSISTANT_RESTART,
RESTART_EXIT_CODE)
_LOGGER = logging.getLogger(__name__)
SERVICE_RELOAD_CORE_CONFIG = 'reload_core_config'
SERVICE_CHECK_CONFIG = 'check_config'
def is_on(hass, entity_id=None):
@@ -74,14 +80,31 @@ def toggle(hass, entity_id=None, **service_data):
hass.services.call(ha.DOMAIN, SERVICE_TOGGLE, service_data)
def stop(hass):
"""Stop Home Assistant."""
hass.services.call(ha.DOMAIN, SERVICE_HOMEASSISTANT_STOP)
def restart(hass):
"""Stop Home Assistant."""
hass.services.call(ha.DOMAIN, SERVICE_HOMEASSISTANT_RESTART)
def check_config(hass):
"""Check the config files."""
hass.services.call(ha.DOMAIN, SERVICE_CHECK_CONFIG)
def reload_core_config(hass):
"""Reload the core config."""
hass.services.call(ha.DOMAIN, SERVICE_RELOAD_CORE_CONFIG)
def setup(hass, config):
@asyncio.coroutine
def async_setup(hass, config):
"""Setup general services related to Home Assistant."""
def handle_turn_service(service):
@asyncio.coroutine
def async_handle_turn_service(service):
"""Method to handle calls to homeassistant.turn_on/off."""
entity_ids = extract_entity_ids(hass, service)
@@ -96,6 +119,8 @@ def setup(hass, config):
by_domain = it.groupby(sorted(entity_ids),
lambda item: ha.split_entity_id(item)[0])
tasks = []
for domain, ent_ids in by_domain:
# We want to block for all calls and only return when all calls
# have been processed. If a service does not exist it causes a 10
@@ -111,27 +136,61 @@ def setup(hass, config):
# ent_ids is a generator, convert it to a list.
data[ATTR_ENTITY_ID] = list(ent_ids)
hass.services.call(domain, service.service, data, blocking)
tasks.append(hass.services.async_call(
domain, service.service, data, blocking))
hass.services.register(ha.DOMAIN, SERVICE_TURN_OFF, handle_turn_service)
hass.services.register(ha.DOMAIN, SERVICE_TURN_ON, handle_turn_service)
hass.services.register(ha.DOMAIN, SERVICE_TOGGLE, handle_turn_service)
yield from asyncio.wait(tasks, loop=hass.loop)
def handle_reload_config(call):
"""Service handler for reloading core config."""
from homeassistant.exceptions import HomeAssistantError
from homeassistant import config as conf_util
hass.services.async_register(
ha.DOMAIN, SERVICE_TURN_OFF, async_handle_turn_service)
hass.services.async_register(
ha.DOMAIN, SERVICE_TURN_ON, async_handle_turn_service)
hass.services.async_register(
ha.DOMAIN, SERVICE_TOGGLE, async_handle_turn_service)
@asyncio.coroutine
def async_handle_core_service(call):
"""Service handler for handling core services."""
if call.service == SERVICE_HOMEASSISTANT_STOP:
hass.async_add_job(hass.async_stop())
return
try:
path = conf_util.find_config_file(hass.config.config_dir)
conf = conf_util.load_yaml_config_file(path)
errors = yield from conf_util.async_check_ha_config_file(hass)
except HomeAssistantError:
return
if errors:
notif = get_component('persistent_notification')
_LOGGER.error(errors)
notif.async_create(
hass, "Config error. See dev-info panel for details.",
"Config validating", "{0}.check_config".format(ha.DOMAIN))
return
if call.service == SERVICE_HOMEASSISTANT_RESTART:
hass.async_add_job(hass.async_stop(RESTART_EXIT_CODE))
hass.services.async_register(
ha.DOMAIN, SERVICE_HOMEASSISTANT_STOP, async_handle_core_service)
hass.services.async_register(
ha.DOMAIN, SERVICE_HOMEASSISTANT_RESTART, async_handle_core_service)
hass.services.async_register(
ha.DOMAIN, SERVICE_CHECK_CONFIG, async_handle_core_service)
@asyncio.coroutine
def async_handle_reload_config(call):
"""Service handler for reloading core config."""
try:
conf = yield from conf_util.async_hass_config_yaml(hass)
except HomeAssistantError as err:
_LOGGER.error(err)
return
conf_util.process_ha_core_config(hass, conf.get(ha.DOMAIN) or {})
yield from conf_util.async_process_ha_core_config(
hass, conf.get(ha.DOMAIN) or {})
hass.services.register(ha.DOMAIN, SERVICE_RELOAD_CORE_CONFIG,
handle_reload_config)
hass.services.async_register(
ha.DOMAIN, SERVICE_RELOAD_CORE_CONFIG, async_handle_reload_config)
return True

View File

@@ -4,6 +4,8 @@ Component to interface with an alarm control panel.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel/
"""
import asyncio
from datetime import timedelta
import logging
import os
@@ -19,7 +21,7 @@ from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
DOMAIN = 'alarm_control_panel'
SCAN_INTERVAL = 30
SCAN_INTERVAL = timedelta(seconds=30)
ATTR_CHANGED_BY = 'changed_by'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
@@ -42,36 +44,6 @@ ALARM_SERVICE_SCHEMA = vol.Schema({
})
def setup(hass, config):
"""Track states and offer events for sensors."""
component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
component.setup(config)
def alarm_service_handler(service):
"""Map services to methods on Alarm."""
target_alarms = component.extract_from_service(service)
code = service.data.get(ATTR_CODE)
method = SERVICE_TO_METHOD[service.service]
for alarm in target_alarms:
getattr(alarm, method)(code)
if alarm.should_poll:
alarm.update_ha_state(True)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
for service in SERVICE_TO_METHOD:
hass.services.register(DOMAIN, service, alarm_service_handler,
descriptions.get(service),
schema=ALARM_SERVICE_SCHEMA)
return True
def alarm_disarm(hass, code=None, entity_id=None):
"""Send the alarm the command for disarm."""
data = {}
@@ -116,6 +88,53 @@ def alarm_trigger(hass, code=None, entity_id=None):
hass.services.call(DOMAIN, SERVICE_ALARM_TRIGGER, data)
@asyncio.coroutine
def async_setup(hass, config):
"""Track states and offer events for sensors."""
component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
yield from component.async_setup(config)
@asyncio.coroutine
def async_alarm_service_handler(service):
"""Map services to methods on Alarm."""
target_alarms = component.async_extract_from_service(service)
code = service.data.get(ATTR_CODE)
method = "async_{}".format(SERVICE_TO_METHOD[service.service])
for alarm in target_alarms:
yield from getattr(alarm, method)(code)
update_tasks = []
for alarm in target_alarms:
if not alarm.should_poll:
continue
update_coro = hass.loop.create_task(
alarm.async_update_ha_state(True))
if hasattr(alarm, 'async_update'):
update_tasks.append(update_coro)
else:
yield from update_coro
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.loop.run_in_executor(
None, load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
for service in SERVICE_TO_METHOD:
hass.services.async_register(
DOMAIN, service, async_alarm_service_handler,
descriptions.get(service), schema=ALARM_SERVICE_SCHEMA)
return True
# pylint: disable=no-self-use
class AlarmControlPanel(Entity):
"""An abstract class for alarm control devices."""
@@ -134,18 +153,50 @@ class AlarmControlPanel(Entity):
"""Send disarm command."""
raise NotImplementedError()
def async_alarm_disarm(self, code=None):
"""Send disarm command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.loop.run_in_executor(
None, self.alarm_disarm, code)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
raise NotImplementedError()
def async_alarm_arm_home(self, code=None):
"""Send arm home command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.loop.run_in_executor(
None, self.alarm_arm_home, code)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
raise NotImplementedError()
def async_alarm_arm_away(self, code=None):
"""Send arm away command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.loop.run_in_executor(
None, self.alarm_arm_away, code)
def alarm_trigger(self, code=None):
"""Send alarm trigger command."""
raise NotImplementedError()
def async_alarm_trigger(self, code=None):
"""Send alarm trigger command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.loop.run_in_executor(
None, self.alarm_trigger, code)
@property
def state_attributes(self):
"""Return the state attributes."""

View File

@@ -39,11 +39,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
add_devices([AlarmDotCom(hass, name, code, username, password)])
add_devices([AlarmDotCom(hass, name, code, username, password)], True)
# pylint: disable=too-many-arguments, too-many-instance-attributes
# pylint: disable=abstract-method
class AlarmDotCom(alarm.AlarmControlPanel):
"""Represent an Alarm.com status."""
@@ -56,11 +54,11 @@ class AlarmDotCom(alarm.AlarmControlPanel):
self._code = str(code) if code else None
self._username = username
self._password = password
self._state = STATE_UNKNOWN
@property
def should_poll(self):
"""No polling needed."""
return True
def update(self):
"""Fetch the latest state."""
self._state = self._alarm.state
@property
def name(self):
@@ -75,11 +73,11 @@ class AlarmDotCom(alarm.AlarmControlPanel):
@property
def state(self):
"""Return the state of the device."""
if self._alarm.state == 'Disarmed':
if self._state == 'Disarmed':
return STATE_ALARM_DISARMED
elif self._alarm.state == 'Armed Stay':
elif self._state == 'Armed Stay':
return STATE_ALARM_ARMED_HOME
elif self._alarm.state == 'Armed Away':
elif self._state == 'Armed Away':
return STATE_ALARM_ARMED_AWAY
else:
return STATE_UNKNOWN

View File

@@ -0,0 +1,124 @@
"""
Support for Concord232 alarm control panels.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.concord232/
"""
import datetime
from datetime import timedelta
import logging
import requests
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_PORT, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['concord232==0.14']
_LOGGER = logging.getLogger(__name__)
DEFAULT_HOST = 'localhost'
DEFAULT_NAME = 'CONCORD232'
DEFAULT_PORT = 5007
SCAN_INTERVAL = timedelta(seconds=1)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Concord232 alarm control panel platform."""
name = config.get(CONF_NAME)
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
url = 'http://{}:{}'.format(host, port)
try:
add_devices([Concord232Alarm(hass, url, name)])
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to Concord232: %s", str(ex))
return False
class Concord232Alarm(alarm.AlarmControlPanel):
"""Represents the Concord232-based alarm panel."""
def __init__(self, hass, url, name):
"""Initialize the Concord232 alarm panel."""
from concord232 import client as concord232_client
self._state = STATE_UNKNOWN
self._hass = hass
self._name = name
self._url = url
try:
client = concord232_client.Client(self._url)
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to Concord232: %s", str(ex))
self._alarm = client
self._alarm.partitions = self._alarm.list_partitions()
self._alarm.last_partition_update = datetime.datetime.now()
self.update()
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def code_format(self):
"""The characters if code is defined."""
return '[0-9]{4}([0-9]{2})?'
@property
def state(self):
"""Return the state of the device."""
return self._state
def update(self):
"""Update values from API."""
try:
part = self._alarm.list_partitions()[0]
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to %(host)s: %(reason)s",
dict(host=self._url, reason=ex))
newstate = STATE_UNKNOWN
except IndexError:
_LOGGER.error("Concord232 reports no partitions")
newstate = STATE_UNKNOWN
if part['arming_level'] == 'Off':
newstate = STATE_ALARM_DISARMED
elif 'Home' in part['arming_level']:
newstate = STATE_ALARM_ARMED_HOME
else:
newstate = STATE_ALARM_ARMED_AWAY
if not newstate == self._state:
_LOGGER.info("State Chnage from %s to %s", self._state, newstate)
self._state = newstate
return self._state
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._alarm.disarm(code)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self._alarm.arm('home')
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self._alarm.arm('auto')

View File

@@ -4,108 +4,172 @@ Support for Envisalink-based alarm control panels (Honeywell/DSC).
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.envisalink/
"""
import asyncio
import logging
import os
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.envisalink import (EVL_CONTROLLER,
EnvisalinkDevice,
PARTITION_SCHEMA,
CONF_CODE,
CONF_PANIC,
CONF_PARTITIONNAME,
SIGNAL_PARTITION_UPDATE,
SIGNAL_KEYPAD_UPDATE)
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.components.envisalink import (
DATA_EVL, EnvisalinkDevice, PARTITION_SCHEMA, CONF_CODE, CONF_PANIC,
CONF_PARTITIONNAME, SIGNAL_KEYPAD_UPDATE, SIGNAL_PARTITION_UPDATE)
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_UNKNOWN, STATE_ALARM_TRIGGERED)
STATE_UNKNOWN, STATE_ALARM_TRIGGERED, STATE_ALARM_PENDING, ATTR_ENTITY_ID)
DEPENDENCIES = ['envisalink']
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['envisalink']
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
SERVICE_ALARM_KEYPRESS = 'envisalink_alarm_keypress'
ATTR_KEYPRESS = 'keypress'
ALARM_KEYPRESS_SCHEMA = vol.Schema({
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
vol.Required(ATTR_KEYPRESS): cv.string
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Perform the setup for Envisalink alarm panels."""
_configured_partitions = discovery_info['partitions']
_code = discovery_info[CONF_CODE]
_panic_type = discovery_info[CONF_PANIC]
for part_num in _configured_partitions:
_device_config_data = PARTITION_SCHEMA(
_configured_partitions[part_num])
_device = EnvisalinkAlarm(
configured_partitions = discovery_info['partitions']
code = discovery_info[CONF_CODE]
panic_type = discovery_info[CONF_PANIC]
devices = []
for part_num in configured_partitions:
device_config_data = PARTITION_SCHEMA(configured_partitions[part_num])
device = EnvisalinkAlarm(
hass,
part_num,
_device_config_data[CONF_PARTITIONNAME],
_code,
_panic_type,
EVL_CONTROLLER.alarm_state['partition'][part_num],
EVL_CONTROLLER)
add_devices_callback([_device])
device_config_data[CONF_PARTITIONNAME],
code,
panic_type,
hass.data[DATA_EVL].alarm_state['partition'][part_num],
hass.data[DATA_EVL]
)
devices.append(device)
yield from async_add_devices(devices)
@callback
def alarm_keypress_handler(service):
"""Map services to methods on Alarm."""
entity_ids = service.data.get(ATTR_ENTITY_ID)
keypress = service.data.get(ATTR_KEYPRESS)
target_devices = [device for device in devices
if device.entity_id in entity_ids]
for device in target_devices:
device.async_alarm_keypress(keypress)
# Register Envisalink specific services
descriptions = yield from hass.loop.run_in_executor(
None, load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
alarm.DOMAIN, SERVICE_ALARM_KEYPRESS, alarm_keypress_handler,
descriptions.get(SERVICE_ALARM_KEYPRESS), schema=ALARM_KEYPRESS_SCHEMA)
return True
class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
"""Represents the Envisalink-based alarm panel."""
"""Representation of an Envisalink-based alarm panel."""
# pylint: disable=too-many-arguments
def __init__(self, partition_number, alarm_name,
code, panic_type, info, controller):
def __init__(self, hass, partition_number, alarm_name, code, panic_type,
info, controller):
"""Initialize the alarm panel."""
from pydispatch import dispatcher
self._partition_number = partition_number
self._code = code
self._panic_type = panic_type
_LOGGER.debug('Setting up alarm: ' + alarm_name)
EnvisalinkDevice.__init__(self, alarm_name, info, controller)
dispatcher.connect(self._update_callback,
signal=SIGNAL_PARTITION_UPDATE,
sender=dispatcher.Any)
dispatcher.connect(self._update_callback,
signal=SIGNAL_KEYPAD_UPDATE,
sender=dispatcher.Any)
_LOGGER.debug("Setting up alarm: %s", alarm_name)
super().__init__(alarm_name, info, controller)
async_dispatcher_connect(
hass, SIGNAL_KEYPAD_UPDATE, self._update_callback)
async_dispatcher_connect(
hass, SIGNAL_PARTITION_UPDATE, self._update_callback)
@callback
def _update_callback(self, partition):
"""Update HA state, if needed."""
if partition is None or int(partition) == self._partition_number:
self.hass.async_add_job(self.update_ha_state)
self.hass.async_add_job(self.async_update_ha_state())
@property
def code_format(self):
"""The characters if code is defined."""
return self._code
"""Regex for code format or None if no code is required."""
if self._code:
return None
else:
return '^\\d{4,6}$'
@property
def state(self):
"""Return the state of the device."""
state = STATE_UNKNOWN
if self._info['status']['alarm']:
return STATE_ALARM_TRIGGERED
state = STATE_ALARM_TRIGGERED
elif self._info['status']['armed_away']:
return STATE_ALARM_ARMED_AWAY
state = STATE_ALARM_ARMED_AWAY
elif self._info['status']['armed_stay']:
return STATE_ALARM_ARMED_HOME
state = STATE_ALARM_ARMED_HOME
elif self._info['status']['exit_delay']:
state = STATE_ALARM_PENDING
elif self._info['status']['entry_delay']:
state = STATE_ALARM_PENDING
elif self._info['status']['alpha']:
return STATE_ALARM_DISARMED
else:
return STATE_UNKNOWN
state = STATE_ALARM_DISARMED
return state
def alarm_disarm(self, code=None):
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
"""Send disarm command."""
if self._code:
EVL_CONTROLLER.disarm_partition(str(code),
self._partition_number)
if code:
self.hass.data[DATA_EVL].disarm_partition(
str(code), self._partition_number)
else:
self.hass.data[DATA_EVL].disarm_partition(
str(self._code), self._partition_number)
def alarm_arm_home(self, code=None):
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
if self._code:
EVL_CONTROLLER.arm_stay_partition(str(code),
self._partition_number)
if code:
self.hass.data[DATA_EVL].arm_stay_partition(
str(code), self._partition_number)
else:
self.hass.data[DATA_EVL].arm_stay_partition(
str(self._code), self._partition_number)
def alarm_arm_away(self, code=None):
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
if self._code:
EVL_CONTROLLER.arm_away_partition(str(code),
self._partition_number)
if code:
self.hass.data[DATA_EVL].arm_away_partition(
str(code), self._partition_number)
else:
self.hass.data[DATA_EVL].arm_away_partition(
str(self._code), self._partition_number)
def alarm_trigger(self, code=None):
@asyncio.coroutine
def async_alarm_trigger(self, code=None):
"""Alarm trigger command. Will be used to trigger a panic alarm."""
if self._code:
EVL_CONTROLLER.panic_alarm(self._panic_type)
self.hass.data[DATA_EVL].panic_alarm(self._panic_type)
@callback
def async_alarm_keypress(self, keypress=None):
"""Send custom keypress."""
if keypress:
self.hass.data[DATA_EVL].keypresses_to_partition(
self._partition_number, keypress)

View File

@@ -50,8 +50,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
)])
# pylint: disable=too-many-arguments, too-many-instance-attributes
# pylint: disable=abstract-method
class ManualAlarm(alarm.AlarmControlPanel):
"""
Represents an alarm status.
@@ -118,7 +116,7 @@ class ManualAlarm(alarm.AlarmControlPanel):
self._state = STATE_ALARM_DISARMED
self._state_ts = dt_util.utcnow()
self.update_ha_state()
self.schedule_update_ha_state()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
@@ -127,11 +125,11 @@ class ManualAlarm(alarm.AlarmControlPanel):
self._state = STATE_ALARM_ARMED_HOME
self._state_ts = dt_util.utcnow()
self.update_ha_state()
self.schedule_update_ha_state()
if self._pending_time:
track_point_in_time(
self._hass, self.update_ha_state,
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time)
def alarm_arm_away(self, code=None):
@@ -141,11 +139,11 @@ class ManualAlarm(alarm.AlarmControlPanel):
self._state = STATE_ALARM_ARMED_AWAY
self._state_ts = dt_util.utcnow()
self.update_ha_state()
self.schedule_update_ha_state()
if self._pending_time:
track_point_in_time(
self._hass, self.update_ha_state,
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time)
def alarm_trigger(self, code=None):
@@ -153,15 +151,15 @@ class ManualAlarm(alarm.AlarmControlPanel):
self._pre_trigger_state = self._state
self._state = STATE_ALARM_TRIGGERED
self._state_ts = dt_util.utcnow()
self.update_ha_state()
self.schedule_update_ha_state()
if self._trigger_time:
track_point_in_time(
self._hass, self.update_ha_state,
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time)
track_point_in_time(
self._hass, self.update_ha_state,
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time + self._trigger_time)
def _validate_code(self, code, state):

View File

@@ -4,10 +4,12 @@ This platform enables the possibility to control a MQTT alarm.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.mqtt/
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.components.alarm_control_panel as alarm
import homeassistant.components.mqtt as mqtt
from homeassistant.const import (
@@ -41,10 +43,10 @@ PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup the MQTT platform."""
add_devices([MqttAlarm(
hass,
yield from async_add_devices([MqttAlarm(
config.get(CONF_NAME),
config.get(CONF_STATE_TOPIC),
config.get(CONF_COMMAND_TOPIC),
@@ -55,16 +57,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
config.get(CONF_CODE))])
# pylint: disable=too-many-arguments, too-many-instance-attributes
# pylint: disable=abstract-method
class MqttAlarm(alarm.AlarmControlPanel):
"""Representation of a MQTT alarm status."""
def __init__(self, hass, name, state_topic, command_topic, qos,
payload_disarm, payload_arm_home, payload_arm_away, code):
def __init__(self, name, state_topic, command_topic, qos, payload_disarm,
payload_arm_home, payload_arm_away, code):
"""Initalize the MQTT alarm panel."""
self._state = STATE_UNKNOWN
self._hass = hass
self._name = name
self._state_topic = state_topic
self._command_topic = command_topic
@@ -74,6 +73,12 @@ class MqttAlarm(alarm.AlarmControlPanel):
self._payload_arm_away = payload_arm_away
self._code = code
def async_added_to_hass(self):
"""Subscribe mqtt events.
This method must be run in the event loop and returns a coroutine.
"""
@callback
def message_received(topic, payload, qos):
"""A new MQTT message has been received."""
if payload not in (STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
@@ -82,9 +87,10 @@ class MqttAlarm(alarm.AlarmControlPanel):
_LOGGER.warning('Received unexpected payload: %s', payload)
return
self._state = payload
self.update_ha_state()
self.hass.async_add_job(self.async_update_ha_state())
mqtt.subscribe(hass, self._state_topic, message_received, self._qos)
return mqtt.async_subscribe(
self.hass, self._state_topic, message_received, self._qos)
@property
def should_poll(self):
@@ -106,26 +112,38 @@ class MqttAlarm(alarm.AlarmControlPanel):
"""One or more characters if code is defined."""
return None if self._code is None else '.+'
def alarm_disarm(self, code=None):
"""Send disarm command."""
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
"""Send disarm command.
This method is a coroutine.
"""
if not self._validate_code(code, 'disarming'):
return
mqtt.publish(self.hass, self._command_topic,
self._payload_disarm, self._qos)
mqtt.async_publish(
self.hass, self._command_topic, self._payload_disarm, self._qos)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
"""Send arm home command.
This method is a coroutine.
"""
if not self._validate_code(code, 'arming home'):
return
mqtt.publish(self.hass, self._command_topic,
self._payload_arm_home, self._qos)
mqtt.async_publish(
self.hass, self._command_topic, self._payload_arm_home, self._qos)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
"""Send arm away command.
This method is a coroutine.
"""
if not self._validate_code(code, 'arming away'):
return
mqtt.publish(self.hass, self._command_topic,
self._payload_arm_away, self._qos)
mqtt.async_publish(
self.hass, self._command_topic, self._payload_arm_away, self._qos)
def _validate_code(self, code, state):
"""Validate given code."""

View File

@@ -16,7 +16,7 @@ from homeassistant.const import (
STATE_UNKNOWN, CONF_NAME, CONF_HOST, CONF_PORT)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pynx584==0.2']
REQUIREMENTS = ['pynx584==0.4']
_LOGGER = logging.getLogger(__name__)
@@ -60,11 +60,7 @@ class NX584Alarm(alarm.AlarmControlPanel):
# talk to the API and trigger a requests exception for setup_platform()
# to catch
self._alarm.list_zones()
@property
def should_poll(self):
"""Polling needed."""
return True
self._state = STATE_UNKNOWN
@property
def name(self):
@@ -79,16 +75,22 @@ class NX584Alarm(alarm.AlarmControlPanel):
@property
def state(self):
"""Return the state of the device."""
return self._state
def update(self):
"""Process new events from panel."""
try:
part = self._alarm.list_partitions()[0]
zones = self._alarm.list_zones()
except requests.exceptions.ConnectionError as ex:
_LOGGER.error('Unable to connect to %(host)s: %(reason)s',
dict(host=self._url, reason=ex))
return STATE_UNKNOWN
self._state = STATE_UNKNOWN
zones = []
except IndexError:
_LOGGER.error('nx584 reports no partitions')
return STATE_UNKNOWN
self._state = STATE_UNKNOWN
zones = []
bypassed = False
for zone in zones:
@@ -100,11 +102,11 @@ class NX584Alarm(alarm.AlarmControlPanel):
break
if not part['armed']:
return STATE_ALARM_DISARMED
self._state = STATE_ALARM_DISARMED
elif bypassed:
return STATE_ALARM_ARMED_HOME
self._state = STATE_ALARM_ARMED_HOME
else:
return STATE_ALARM_ARMED_AWAY
self._state = STATE_ALARM_ARMED_AWAY
def alarm_disarm(self, code=None):
"""Send disarm command."""
@@ -112,12 +114,8 @@ class NX584Alarm(alarm.AlarmControlPanel):
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self._alarm.arm('home')
self._alarm.arm('stay')
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self._alarm.arm('auto')
def alarm_trigger(self, code=None):
"""Alarm trigger command."""
raise NotImplementedError()
self._alarm.arm('exit')

View File

@@ -41,3 +41,14 @@ alarm_trigger:
code:
description: An optional code to trigger the alarm control panel with
example: 1234
envisalink_alarm_keypress:
description: Send custom keypresses to the alarm
fields:
entity_id:
description: Name of the alarm control panel to trigger
example: 'alarm_control_panel.downstairs'
keypress:
description: 'String to send to the alarm panel (1-6 characters)'
example: '*71'

View File

@@ -12,16 +12,19 @@ import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_PASSWORD, CONF_USERNAME, STATE_UNKNOWN, CONF_CODE, CONF_NAME,
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY)
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY,
EVENT_HOMEASSISTANT_STOP)
import homeassistant.helpers.config_validation as cv
import homeassistant.loader as loader
REQUIREMENTS = ['https://github.com/w1ll1am23/simplisafe-python/archive/'
'586fede0e85fd69e56e516aaa8e97eb644ca8866.zip#'
'simplisafe-python==0.0.1']
REQUIREMENTS = ['simplisafe-python==1.0.2']
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'SimpliSafe'
DOMAIN = 'simplisafe'
NOTIFICATION_ID = 'simplisafe_notification'
NOTIFICATION_TITLE = 'SimpliSafe Setup'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_PASSWORD): cv.string,
@@ -33,39 +36,44 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the SimpliSafe platform."""
from simplipy.api import SimpliSafeApiInterface, get_systems
name = config.get(CONF_NAME)
code = config.get(CONF_CODE)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
add_devices([SimpliSafeAlarm(name, username, password, code)])
persistent_notification = loader.get_component('persistent_notification')
simplisafe = SimpliSafeApiInterface()
status = simplisafe.set_credentials(username, password)
if status:
hass.data[DOMAIN] = simplisafe
locations = get_systems(simplisafe)
for location in locations:
add_devices([SimpliSafeAlarm(location, name, code)])
else:
message = 'Failed to log into SimpliSafe. Check credentials.'
_LOGGER.error(message)
persistent_notification.create(
hass, message,
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
def logout(event):
"""Logout of the SimpliSafe API."""
hass.data[DOMAIN].logout()
hass.bus.listen(EVENT_HOMEASSISTANT_STOP, logout)
# pylint: disable=abstract-method
class SimpliSafeAlarm(alarm.AlarmControlPanel):
"""Representation a SimpliSafe alarm."""
def __init__(self, name, username, password, code):
def __init__(self, simplisafe, name, code):
"""Initialize the SimpliSafe alarm."""
from simplisafe import SimpliSafe
self.simplisafe = SimpliSafe(username, password)
self.simplisafe = simplisafe
self._name = name
self._code = str(code) if code else None
self._id = self.simplisafe.get_id()
status = self.simplisafe.get_state()
if status == 'Off':
self._state = STATE_ALARM_DISARMED
elif status == 'Home':
self._state = STATE_ALARM_ARMED_HOME
elif status == 'Away':
self._state = STATE_ALARM_ARMED_AWAY
else:
self._state = STATE_UNKNOWN
@property
def should_poll(self):
"""Poll the SimpliSafe API."""
return True
@property
def name(self):
@@ -73,7 +81,7 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
if self._name is not None:
return self._name
else:
return 'Alarm {}'.format(self._id)
return 'Alarm {}'.format(self.simplisafe.location_id())
@property
def code_format(self):
@@ -83,21 +91,32 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
@property
def state(self):
"""Return the state of the device."""
return self._state
status = self.simplisafe.state()
if status == 'Off':
state = STATE_ALARM_DISARMED
elif status == 'Home':
state = STATE_ALARM_ARMED_HOME
elif status == 'Away':
state = STATE_ALARM_ARMED_AWAY
else:
state = STATE_UNKNOWN
return state
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'temperature': self.simplisafe.temperature(),
'co': self.simplisafe.carbon_monoxide(),
'fire': self.simplisafe.fire(),
'alarm': self.simplisafe.alarm(),
'last_event': self.simplisafe.last_event(),
'flood': self.simplisafe.flood()
}
def update(self):
"""Update alarm status."""
self.simplisafe.get_location()
status = self.simplisafe.get_state()
if status == 'Off':
self._state = STATE_ALARM_DISARMED
elif status == 'Home':
self._state = STATE_ALARM_ARMED_HOME
elif status == 'Away':
self._state = STATE_ALARM_ARMED_AWAY
else:
self._state = STATE_UNKNOWN
self.simplisafe.update()
def alarm_disarm(self, code=None):
"""Send disarm command."""
@@ -105,7 +124,6 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
return
self.simplisafe.set_state('off')
_LOGGER.info('SimpliSafe alarm disarming')
self.update()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
@@ -113,7 +131,6 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
return
self.simplisafe.set_state('home')
_LOGGER.info('SimpliSafe alarm arming home')
self.update()
def alarm_arm_away(self, code=None):
"""Send arm away command."""
@@ -121,7 +138,6 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
return
self.simplisafe.set_state('away')
_LOGGER.info('SimpliSafe alarm arming away')
self.update()
def _validate_code(self, code, state):
"""Validate given code."""

View File

@@ -28,7 +28,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(alarms)
# pylint: disable=abstract-method
class VerisureAlarm(alarm.AlarmControlPanel):
"""Represent a Verisure alarm status."""
@@ -85,18 +84,15 @@ class VerisureAlarm(alarm.AlarmControlPanel):
hub.my_pages.alarm.set(code, 'DISARMED')
_LOGGER.info('verisure alarm disarming')
hub.my_pages.alarm.wait_while_pending()
self.update()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
hub.my_pages.alarm.set(code, 'ARMED_HOME')
_LOGGER.info('verisure alarm arming home')
hub.my_pages.alarm.wait_while_pending()
self.update()
def alarm_arm_away(self, code=None):
"""Send arm away command."""
hub.my_pages.alarm.set(code, 'ARMED_AWAY')
_LOGGER.info('verisure alarm arming away')
hub.my_pages.alarm.wait_while_pending()
self.update()

View File

@@ -0,0 +1,75 @@
"""
Interfaces with Wink Cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.wink/
"""
import logging
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.const import (STATE_UNKNOWN,
STATE_ALARM_DISARMED,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY)
from homeassistant.components.wink import WinkDevice, DOMAIN
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['wink']
STATE_ALARM_PRIVACY = 'Private'
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Wink platform."""
import pywink
for camera in pywink.get_cameras():
# get_cameras returns multiple device types.
# Only add those that aren't sensors.
try:
camera.capability()
except AttributeError:
_id = camera.object_id() + camera.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_devices([WinkCameraDevice(camera, hass)])
class WinkCameraDevice(WinkDevice, alarm.AlarmControlPanel):
"""Representation a Wink camera alarm."""
def __init__(self, wink, hass):
"""Initialize the Wink alarm."""
super().__init__(wink, hass)
@property
def state(self):
"""Return the state of the device."""
wink_state = self.wink.state()
if wink_state == "away":
state = STATE_ALARM_ARMED_AWAY
elif wink_state == "home":
state = STATE_ALARM_DISARMED
elif wink_state == "night":
state = STATE_ALARM_ARMED_HOME
else:
state = STATE_UNKNOWN
return state
def alarm_disarm(self, code=None):
"""Send disarm command."""
self.wink.set_mode("home")
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self.wink.set_mode("night")
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self.wink.set_mode("away")
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'private': self.wink.private()
}

View File

@@ -0,0 +1,279 @@
"""
Support for repeating alerts when conditions are met.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alert/
"""
import asyncio
from datetime import datetime, timedelta
import logging
import os
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
CONF_ENTITY_ID, STATE_IDLE, CONF_NAME, CONF_STATE, STATE_ON, STATE_OFF,
SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE, ATTR_ENTITY_ID)
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers import service, event
from homeassistant.util.async import run_callback_threadsafe
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'alert'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
CONF_CAN_ACK = 'can_acknowledge'
CONF_NOTIFIERS = 'notifiers'
CONF_REPEAT = 'repeat'
CONF_SKIP_FIRST = 'skip_first'
DEFAULT_CAN_ACK = True
DEFAULT_SKIP_FIRST = False
ALERT_SCHEMA = vol.Schema({
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_ENTITY_ID): cv.entity_id,
vol.Required(CONF_STATE, default=STATE_ON): cv.string,
vol.Required(CONF_REPEAT): vol.All(cv.ensure_list, [vol.Coerce(float)]),
vol.Required(CONF_CAN_ACK, default=DEFAULT_CAN_ACK): cv.boolean,
vol.Required(CONF_SKIP_FIRST, default=DEFAULT_SKIP_FIRST): cv.boolean,
vol.Required(CONF_NOTIFIERS): cv.ensure_list})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: ALERT_SCHEMA,
}),
}, extra=vol.ALLOW_EXTRA)
ALERT_SERVICE_SCHEMA = vol.Schema({
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
})
def is_on(hass, entity_id):
"""Return if the alert is firing and not acknowledged."""
return hass.states.is_state(entity_id, STATE_ON)
def turn_on(hass, entity_id):
"""Reset the alert."""
run_callback_threadsafe(
hass.loop, async_turn_on, hass, entity_id).result()
@callback
def async_turn_on(hass, entity_id):
"""Async reset the alert."""
data = {ATTR_ENTITY_ID: entity_id}
hass.async_add_job(
hass.services.async_call(DOMAIN, SERVICE_TURN_ON, data))
def turn_off(hass, entity_id):
"""Acknowledge alert."""
run_callback_threadsafe(
hass.loop, async_turn_off, hass, entity_id).result()
@callback
def async_turn_off(hass, entity_id):
"""Async acknowledge the alert."""
data = {ATTR_ENTITY_ID: entity_id}
hass.async_add_job(
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF, data))
def toggle(hass, entity_id):
"""Toggle acknowledgement of alert."""
run_callback_threadsafe(hass.loop, async_toggle, hass, entity_id)
@callback
def async_toggle(hass, entity_id):
"""Async toggle acknowledgement of alert."""
data = {ATTR_ENTITY_ID: entity_id}
hass.async_add_job(
hass.services.async_call(DOMAIN, SERVICE_TOGGLE, data))
@asyncio.coroutine
def async_setup(hass, config):
"""Set up the Alert component."""
alerts = config.get(DOMAIN)
all_alerts = {}
@asyncio.coroutine
def async_handle_alert_service(service_call):
"""Handle calls to alert services."""
alert_ids = service.extract_entity_ids(hass, service_call)
for alert_id in alert_ids:
alert = all_alerts[alert_id]
if service_call.service == SERVICE_TURN_ON:
yield from alert.async_turn_on()
elif service_call.service == SERVICE_TOGGLE:
yield from alert.async_toggle()
else:
yield from alert.async_turn_off()
# Setup alerts
for entity_id, alert in alerts.items():
entity = Alert(hass, entity_id,
alert[CONF_NAME], alert[CONF_ENTITY_ID],
alert[CONF_STATE], alert[CONF_REPEAT],
alert[CONF_SKIP_FIRST], alert[CONF_NOTIFIERS],
alert[CONF_CAN_ACK])
all_alerts[entity.entity_id] = entity
# Read descriptions
descriptions = yield from hass.loop.run_in_executor(
None, load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
descriptions = descriptions.get(DOMAIN, {})
# Setup service calls
hass.services.async_register(
DOMAIN, SERVICE_TURN_OFF, async_handle_alert_service,
descriptions.get(SERVICE_TURN_OFF), schema=ALERT_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TURN_ON, async_handle_alert_service,
descriptions.get(SERVICE_TURN_ON), schema=ALERT_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, async_handle_alert_service,
descriptions.get(SERVICE_TOGGLE), schema=ALERT_SERVICE_SCHEMA)
tasks = [alert.async_update_ha_state() for alert in all_alerts.values()]
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
return True
class Alert(ToggleEntity):
"""Representation of an alert."""
def __init__(self, hass, entity_id, name, watched_entity_id, state,
repeat, skip_first, notifiers, can_ack):
"""Initialize the alert."""
self.hass = hass
self._name = name
self._alert_state = state
self._skip_first = skip_first
self._notifiers = notifiers
self._can_ack = can_ack
self._delay = [timedelta(minutes=val) for val in repeat]
self._next_delay = 0
self._firing = False
self._ack = False
self._cancel = None
self.entity_id = ENTITY_ID_FORMAT.format(entity_id)
event.async_track_state_change(
hass, watched_entity_id, self.watched_entity_change)
@property
def name(self):
"""Return the name of the alert."""
return self._name
@property
def should_poll(self):
"""HASS need not poll these entities."""
return False
@property
def state(self):
"""Return the alert status."""
if self._firing:
if self._ack:
return STATE_OFF
return STATE_ON
return STATE_IDLE
@property
def hidden(self):
"""Hide the alert when it is not firing."""
return not self._can_ack or not self._firing
@asyncio.coroutine
def watched_entity_change(self, entity, from_state, to_state):
"""Determine if the alert should start or stop."""
_LOGGER.debug("Watched entity (%s) has changed", entity)
if to_state.state == self._alert_state and not self._firing:
yield from self.begin_alerting()
if to_state.state != self._alert_state and self._firing:
yield from self.end_alerting()
@asyncio.coroutine
def begin_alerting(self):
"""Begin the alert procedures."""
_LOGGER.debug("Beginning Alert: %s", self._name)
self._ack = False
self._firing = True
self._next_delay = 0
if not self._skip_first:
yield from self._notify()
else:
yield from self._schedule_notify()
self.hass.async_add_job(self.async_update_ha_state)
@asyncio.coroutine
def end_alerting(self):
"""End the alert procedures."""
_LOGGER.debug("Ending Alert: %s", self._name)
self._cancel()
self._ack = False
self._firing = False
self.hass.async_add_job(self.async_update_ha_state)
@asyncio.coroutine
def _schedule_notify(self):
"""Schedule a notification."""
delay = self._delay[self._next_delay]
next_msg = datetime.now() + delay
self._cancel = \
event.async_track_point_in_time(self.hass, self._notify, next_msg)
self._next_delay = min(self._next_delay + 1, len(self._delay) - 1)
@asyncio.coroutine
def _notify(self, *args):
"""Send the alert notification."""
if not self._firing:
return
if not self._ack:
_LOGGER.info("Alerting: %s", self._name)
for target in self._notifiers:
yield from self.hass.services.async_call(
'notify', target, {'message': self._name})
yield from self._schedule_notify()
@asyncio.coroutine
def async_turn_on(self):
"""Async Unacknowledge alert."""
_LOGGER.debug("Reset Alert: %s", self._name)
self._ack = False
yield from self.async_update_ha_state()
@asyncio.coroutine
def async_turn_off(self):
"""Async Acknowledge alert."""
_LOGGER.debug("Acknowledged Alert: %s", self._name)
self._ack = True
yield from self.async_update_ha_state()
@asyncio.coroutine
def async_toggle(self):
"""Async toggle alert."""
if self._ack:
return self.async_turn_on()
return self.async_turn_off()

View File

@@ -4,19 +4,25 @@ Support for Alexa skill service end point.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alexa/
"""
import asyncio
import copy
import enum
import logging
import uuid
from datetime import datetime
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import HTTP_BAD_REQUEST
from homeassistant.helpers import template, script, config_validation as cv
from homeassistant.components.http import HomeAssistantView
import homeassistant.util.dt as dt_util
_LOGGER = logging.getLogger(__name__)
API_ENDPOINT = '/api/alexa'
INTENTS_API_ENDPOINT = '/api/alexa'
FLASH_BRIEFINGS_API_ENDPOINT = '/api/alexa/flash_briefings/{briefing_id}'
CONF_ACTION = 'action'
CONF_CARD = 'card'
@@ -28,6 +34,23 @@ CONF_TITLE = 'title'
CONF_CONTENT = 'content'
CONF_TEXT = 'text'
CONF_FLASH_BRIEFINGS = 'flash_briefings'
CONF_UID = 'uid'
CONF_DATE = 'date'
CONF_TITLE = 'title'
CONF_AUDIO = 'audio'
CONF_TEXT = 'text'
CONF_DISPLAY_URL = 'display_url'
ATTR_UID = 'uid'
ATTR_UPDATE_DATE = 'updateDate'
ATTR_TITLE_TEXT = 'titleText'
ATTR_STREAM_URL = 'streamUrl'
ATTR_MAIN_TEXT = 'mainText'
ATTR_REDIRECTION_URL = 'redirectionURL'
DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.0Z'
DOMAIN = 'alexa'
DEPENDENCIES = ['http']
@@ -61,28 +84,41 @@ CONFIG_SCHEMA = vol.Schema({
vol.Required(CONF_TEXT): cv.template,
}
}
},
CONF_FLASH_BRIEFINGS: {
cv.string: vol.All(cv.ensure_list, [{
vol.Required(CONF_UID, default=str(uuid.uuid4())): cv.string,
vol.Optional(CONF_DATE, default=datetime.utcnow()): cv.string,
vol.Required(CONF_TITLE): cv.template,
vol.Optional(CONF_AUDIO): cv.template,
vol.Required(CONF_TEXT, default=""): cv.template,
vol.Optional(CONF_DISPLAY_URL): cv.template,
}]),
}
}
})
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Activate Alexa component."""
hass.wsgi.register_view(AlexaView(hass,
config[DOMAIN].get(CONF_INTENTS, {})))
intents = config[DOMAIN].get(CONF_INTENTS, {})
flash_briefings = config[DOMAIN].get(CONF_FLASH_BRIEFINGS, {})
hass.http.register_view(AlexaIntentsView(hass, intents))
hass.http.register_view(AlexaFlashBriefingView(hass, flash_briefings))
return True
class AlexaView(HomeAssistantView):
class AlexaIntentsView(HomeAssistantView):
"""Handle Alexa requests."""
url = API_ENDPOINT
url = INTENTS_API_ENDPOINT
name = 'api:alexa'
def __init__(self, hass, intents):
"""Initialize Alexa view."""
super().__init__(hass)
super().__init__()
intents = copy.deepcopy(intents)
template.attach(hass, intents)
@@ -94,9 +130,10 @@ class AlexaView(HomeAssistantView):
self.intents = intents
@asyncio.coroutine
def post(self, request):
"""Handle Alexa."""
data = request.json
data = yield from request.json()
_LOGGER.debug('Received Alexa request: %s', data)
@@ -113,7 +150,7 @@ class AlexaView(HomeAssistantView):
return None
intent = req.get('intent')
response = AlexaResponse(self.hass, intent)
response = AlexaResponse(request.app['hass'], intent)
if req_type == 'LaunchRequest':
response.add_speech(
@@ -142,7 +179,7 @@ class AlexaView(HomeAssistantView):
action = config.get(CONF_ACTION)
if action is not None:
action.run(response.variables)
yield from action.async_run(response.variables)
# pylint: disable=unsubscriptable-object
if speech is not None:
@@ -166,11 +203,12 @@ class AlexaResponse(object):
self.reprompt = None
self.session_attributes = {}
self.should_end_session = True
self.variables = {}
if intent is not None and 'slots' in intent:
self.variables = {key: value['value'] for key, value
in intent['slots'].items() if 'value' in value}
else:
self.variables = {}
for key, value in intent['slots'].items():
if 'value' in value:
underscored_key = key.replace('.', '_')
self.variables[underscored_key] = value['value']
def add_card(self, card_type, title, content):
"""Add a card to the response."""
@@ -184,8 +222,8 @@ class AlexaResponse(object):
self.card = card
return
card["title"] = title.render(self.variables)
card["content"] = content.render(self.variables)
card["title"] = title.async_render(self.variables)
card["content"] = content.async_render(self.variables)
self.card = card
def add_speech(self, speech_type, text):
@@ -195,7 +233,7 @@ class AlexaResponse(object):
key = 'ssml' if speech_type == SpeechType.ssml else 'text'
if isinstance(text, template.Template):
text = text.render(self.variables)
text = text.async_render(self.variables)
self.speech = {
'type': speech_type.value,
@@ -210,7 +248,7 @@ class AlexaResponse(object):
self.reprompt = {
'type': speech_type.value,
key: text.render(self.variables)
key: text.async_render(self.variables)
}
def as_dict(self):
@@ -235,3 +273,69 @@ class AlexaResponse(object):
'sessionAttributes': self.session_attributes,
'response': response,
}
class AlexaFlashBriefingView(HomeAssistantView):
"""Handle Alexa Flash Briefing skill requests."""
url = FLASH_BRIEFINGS_API_ENDPOINT
name = 'api:alexa:flash_briefings'
def __init__(self, hass, flash_briefings):
"""Initialize Alexa view."""
super().__init__()
self.flash_briefings = copy.deepcopy(flash_briefings)
template.attach(hass, self.flash_briefings)
@callback
def get(self, request, briefing_id):
"""Handle Alexa Flash Briefing request."""
_LOGGER.debug('Received Alexa flash briefing request for: %s',
briefing_id)
if self.flash_briefings.get(briefing_id) is None:
err = 'No configured Alexa flash briefing was found for: %s'
_LOGGER.error(err, briefing_id)
return b'', 404
briefing = []
for item in self.flash_briefings.get(briefing_id, []):
output = {}
if item.get(CONF_TITLE) is not None:
if isinstance(item.get(CONF_TITLE), template.Template):
output[ATTR_TITLE_TEXT] = item[CONF_TITLE].async_render()
else:
output[ATTR_TITLE_TEXT] = item.get(CONF_TITLE)
if item.get(CONF_TEXT) is not None:
if isinstance(item.get(CONF_TEXT), template.Template):
output[ATTR_MAIN_TEXT] = item[CONF_TEXT].async_render()
else:
output[ATTR_MAIN_TEXT] = item.get(CONF_TEXT)
if item.get(CONF_UID) is not None:
output[ATTR_UID] = item.get(CONF_UID)
if item.get(CONF_AUDIO) is not None:
if isinstance(item.get(CONF_AUDIO), template.Template):
output[ATTR_STREAM_URL] = item[CONF_AUDIO].async_render()
else:
output[ATTR_STREAM_URL] = item.get(CONF_AUDIO)
if item.get(CONF_DISPLAY_URL) is not None:
if isinstance(item.get(CONF_DISPLAY_URL),
template.Template):
output[ATTR_REDIRECTION_URL] = \
item[CONF_DISPLAY_URL].async_render()
else:
output[ATTR_REDIRECTION_URL] = item.get(CONF_DISPLAY_URL)
if isinstance(item[CONF_DATE], str):
item[CONF_DATE] = dt_util.parse_datetime(item[CONF_DATE])
output[ATTR_UPDATE_DATE] = item[CONF_DATE].strftime(DATE_FORMAT)
briefing.append(output)
return self.json(briefing)

View File

@@ -7,7 +7,9 @@ https://home-assistant.io/developers/api/
import asyncio
import json
import logging
import queue
from aiohttp import web
import async_timeout
import homeassistant.core as ha
import homeassistant.remote as rem
@@ -21,7 +23,7 @@ from homeassistant.const import (
URL_API_STATES, URL_API_STATES_ENTITY, URL_API_STREAM, URL_API_TEMPLATE,
__version__)
from homeassistant.exceptions import TemplateError
from homeassistant.helpers.state import TrackStates
from homeassistant.helpers.state import AsyncTrackStates
from homeassistant.helpers import template
from homeassistant.components.http import HomeAssistantView
@@ -36,20 +38,20 @@ _LOGGER = logging.getLogger(__name__)
def setup(hass, config):
"""Register the API with the HTTP interface."""
hass.wsgi.register_view(APIStatusView)
hass.wsgi.register_view(APIEventStream)
hass.wsgi.register_view(APIConfigView)
hass.wsgi.register_view(APIDiscoveryView)
hass.wsgi.register_view(APIStatesView)
hass.wsgi.register_view(APIEntityStateView)
hass.wsgi.register_view(APIEventListenersView)
hass.wsgi.register_view(APIEventView)
hass.wsgi.register_view(APIServicesView)
hass.wsgi.register_view(APIDomainServicesView)
hass.wsgi.register_view(APIEventForwardingView)
hass.wsgi.register_view(APIComponentsView)
hass.wsgi.register_view(APIErrorLogView)
hass.wsgi.register_view(APITemplateView)
hass.http.register_view(APIStatusView)
hass.http.register_view(APIEventStream)
hass.http.register_view(APIConfigView)
hass.http.register_view(APIDiscoveryView)
hass.http.register_view(APIStatesView)
hass.http.register_view(APIEntityStateView)
hass.http.register_view(APIEventListenersView)
hass.http.register_view(APIEventView)
hass.http.register_view(APIServicesView)
hass.http.register_view(APIDomainServicesView)
hass.http.register_view(APIEventForwardingView)
hass.http.register_view(APIComponentsView)
hass.http.register_view(APIErrorLogView)
hass.http.register_view(APITemplateView)
return True
@@ -60,6 +62,7 @@ class APIStatusView(HomeAssistantView):
url = URL_API
name = "api:status"
@ha.callback
def get(self, request):
"""Retrieve if API is running."""
return self.json_message('API running.')
@@ -71,12 +74,15 @@ class APIEventStream(HomeAssistantView):
url = URL_API_STREAM
name = "api:stream"
@asyncio.coroutine
def get(self, request):
"""Provide a streaming interface for the event bus."""
# pylint: disable=no-self-use
hass = request.app['hass']
stop_obj = object()
to_write = queue.Queue()
to_write = asyncio.Queue(loop=hass.loop)
restrict = request.args.get('restrict')
restrict = request.GET.get('restrict')
if restrict:
restrict = restrict.split(',') + [EVENT_HOMEASSISTANT_STOP]
@@ -96,38 +102,43 @@ class APIEventStream(HomeAssistantView):
else:
data = json.dumps(event, cls=rem.JSONEncoder)
to_write.put(data)
yield from to_write.put(data)
def stream():
"""Stream events to response."""
unsub_stream = self.hass.bus.listen(MATCH_ALL, forward_events)
response = web.StreamResponse()
response.content_type = 'text/event-stream'
yield from response.prepare(request)
try:
_LOGGER.debug('STREAM %s ATTACHED', id(stop_obj))
unsub_stream = hass.bus.async_listen(MATCH_ALL, forward_events)
# Fire off one message so browsers fire open event right away
to_write.put(STREAM_PING_PAYLOAD)
try:
_LOGGER.debug('STREAM %s ATTACHED', id(stop_obj))
while True:
try:
payload = to_write.get(timeout=STREAM_PING_INTERVAL)
# Fire off one message so browsers fire open event right away
yield from to_write.put(STREAM_PING_PAYLOAD)
if payload is stop_obj:
break
while True:
try:
with async_timeout.timeout(STREAM_PING_INTERVAL,
loop=hass.loop):
payload = yield from to_write.get()
msg = "data: {}\n\n".format(payload)
_LOGGER.debug('STREAM %s WRITING %s', id(stop_obj),
msg.strip())
yield msg.encode("UTF-8")
except queue.Empty:
to_write.put(STREAM_PING_PAYLOAD)
except GeneratorExit:
if payload is stop_obj:
break
finally:
_LOGGER.debug('STREAM %s RESPONSE CLOSED', id(stop_obj))
unsub_stream()
return self.Response(stream(), mimetype='text/event-stream')
msg = "data: {}\n\n".format(payload)
_LOGGER.debug('STREAM %s WRITING %s', id(stop_obj),
msg.strip())
response.write(msg.encode("UTF-8"))
yield from response.drain()
except asyncio.TimeoutError:
yield from to_write.put(STREAM_PING_PAYLOAD)
except asyncio.CancelledError:
_LOGGER.debug('STREAM %s ABORT', id(stop_obj))
finally:
_LOGGER.debug('STREAM %s RESPONSE CLOSED', id(stop_obj))
unsub_stream()
class APIConfigView(HomeAssistantView):
@@ -136,9 +147,10 @@ class APIConfigView(HomeAssistantView):
url = URL_API_CONFIG
name = "api:config"
@ha.callback
def get(self, request):
"""Get current configuration."""
return self.json(self.hass.config.as_dict())
return self.json(request.app['hass'].config.as_dict())
class APIDiscoveryView(HomeAssistantView):
@@ -148,12 +160,14 @@ class APIDiscoveryView(HomeAssistantView):
url = URL_API_DISCOVERY_INFO
name = "api:discovery"
@ha.callback
def get(self, request):
"""Get discovery info."""
needs_auth = self.hass.config.api.api_password is not None
hass = request.app['hass']
needs_auth = hass.config.api.api_password is not None
return self.json({
'base_url': self.hass.config.api.base_url,
'location_name': self.hass.config.location_name,
'base_url': hass.config.api.base_url,
'location_name': hass.config.location_name,
'requires_api_password': needs_auth,
'version': __version__
})
@@ -165,53 +179,62 @@ class APIStatesView(HomeAssistantView):
url = URL_API_STATES
name = "api:states"
@ha.callback
def get(self, request):
"""Get current states."""
return self.json(self.hass.states.all())
return self.json(request.app['hass'].states.async_all())
class APIEntityStateView(HomeAssistantView):
"""View to handle EntityState requests."""
url = "/api/states/<entity(exist=False):entity_id>"
url = "/api/states/{entity_id}"
name = "api:entity-state"
@ha.callback
def get(self, request, entity_id):
"""Retrieve state of entity."""
state = self.hass.states.get(entity_id)
state = request.app['hass'].states.get(entity_id)
if state:
return self.json(state)
else:
return self.json_message('Entity not found', HTTP_NOT_FOUND)
@asyncio.coroutine
def post(self, request, entity_id):
"""Update state of entity."""
hass = request.app['hass']
try:
new_state = request.json['state']
except KeyError:
data = yield from request.json()
except ValueError:
return self.json_message('Invalid JSON specified',
HTTP_BAD_REQUEST)
new_state = data.get('state')
if not new_state:
return self.json_message('No state specified', HTTP_BAD_REQUEST)
attributes = request.json.get('attributes')
force_update = request.json.get('force_update', False)
attributes = data.get('attributes')
force_update = data.get('force_update', False)
is_new_state = self.hass.states.get(entity_id) is None
is_new_state = hass.states.get(entity_id) is None
# Write state
self.hass.states.set(entity_id, new_state, attributes, force_update)
hass.states.async_set(entity_id, new_state, attributes, force_update)
# Read the state back for our response
resp = self.json(self.hass.states.get(entity_id))
if is_new_state:
resp.status_code = HTTP_CREATED
status_code = HTTP_CREATED if is_new_state else 200
resp = self.json(hass.states.get(entity_id), status_code)
resp.headers.add('Location', URL_API_STATES_ENTITY.format(entity_id))
return resp
@ha.callback
def delete(self, request, entity_id):
"""Remove entity."""
if self.hass.states.remove(entity_id):
if request.app['hass'].states.async_remove(entity_id):
return self.json_message('Entity removed')
else:
return self.json_message('Entity not found', HTTP_NOT_FOUND)
@@ -223,20 +246,23 @@ class APIEventListenersView(HomeAssistantView):
url = URL_API_EVENTS
name = "api:event-listeners"
@ha.callback
def get(self, request):
"""Get event listeners."""
return self.json(events_json(self.hass))
return self.json(async_events_json(request.app['hass']))
class APIEventView(HomeAssistantView):
"""View to handle Event requests."""
url = '/api/events/<event_type>'
url = '/api/events/{event_type}'
name = "api:event"
@asyncio.coroutine
def post(self, request, event_type):
"""Fire events."""
event_data = request.json
body = yield from request.text()
event_data = json.loads(body) if body else None
if event_data is not None and not isinstance(event_data, dict):
return self.json_message('Event data should be a JSON object',
@@ -251,7 +277,8 @@ class APIEventView(HomeAssistantView):
if state:
event_data[key] = state
self.hass.bus.fire(event_type, event_data, ha.EventOrigin.remote)
request.app['hass'].bus.async_fire(event_type, event_data,
ha.EventOrigin.remote)
return self.json_message("Event {} fired.".format(event_type))
@@ -262,24 +289,30 @@ class APIServicesView(HomeAssistantView):
url = URL_API_SERVICES
name = "api:services"
@ha.callback
def get(self, request):
"""Get registered services."""
return self.json(services_json(self.hass))
return self.json(async_services_json(request.app['hass']))
class APIDomainServicesView(HomeAssistantView):
"""View to handle DomainServices requests."""
url = "/api/services/<domain>/<service>"
url = "/api/services/{domain}/{service}"
name = "api:domain-services"
@asyncio.coroutine
def post(self, request, domain, service):
"""Call a service.
Returns a list of changed states.
"""
with TrackStates(self.hass) as changed_states:
self.hass.services.call(domain, service, request.json, True)
hass = request.app['hass']
body = yield from request.text()
data = json.loads(body) if body else None
with AsyncTrackStates(hass) as changed_states:
yield from hass.services.async_call(domain, service, data, True)
return self.json(changed_states)
@@ -291,11 +324,15 @@ class APIEventForwardingView(HomeAssistantView):
name = "api:event-forward"
event_forwarder = None
@asyncio.coroutine
def post(self, request):
"""Setup an event forwarder."""
data = request.json
if data is None:
hass = request.app['hass']
try:
data = yield from request.json()
except ValueError:
return self.json_message("No data received.", HTTP_BAD_REQUEST)
try:
host = data['host']
api_password = data['api_password']
@@ -311,21 +348,25 @@ class APIEventForwardingView(HomeAssistantView):
api = rem.API(host, api_password, port)
if not api.validate_api():
valid = yield from hass.loop.run_in_executor(
None, api.validate_api)
if not valid:
return self.json_message("Unable to validate API.",
HTTP_UNPROCESSABLE_ENTITY)
if self.event_forwarder is None:
self.event_forwarder = rem.EventForwarder(self.hass)
self.event_forwarder = rem.EventForwarder(hass)
self.event_forwarder.connect(api)
self.event_forwarder.async_connect(api)
return self.json_message("Event forwarding setup.")
@asyncio.coroutine
def delete(self, request):
"""Remove event forwarer."""
data = request.json
if data is None:
"""Remove event forwarder."""
try:
data = yield from request.json()
except ValueError:
return self.json_message("No data received.", HTTP_BAD_REQUEST)
try:
@@ -342,7 +383,7 @@ class APIEventForwardingView(HomeAssistantView):
if self.event_forwarder is not None:
api = rem.API(host, None, port)
self.event_forwarder.disconnect(api)
self.event_forwarder.async_disconnect(api)
return self.json_message("Event forwarding cancelled.")
@@ -353,9 +394,10 @@ class APIComponentsView(HomeAssistantView):
url = URL_API_COMPONENTS
name = "api:components"
@ha.callback
def get(self, request):
"""Get current loaded components."""
return self.json(self.hass.config.components)
return self.json(request.app['hass'].config.components)
class APIErrorLogView(HomeAssistantView):
@@ -364,9 +406,12 @@ class APIErrorLogView(HomeAssistantView):
url = URL_API_ERROR_LOG
name = "api:error-log"
@asyncio.coroutine
def get(self, request):
"""Serve error log."""
return self.file(request, self.hass.config.path(ERROR_LOG_FILENAME))
resp = yield from self.file(
request, request.app['hass'].config.path(ERROR_LOG_FILENAME))
return resp
class APITemplateView(HomeAssistantView):
@@ -375,23 +420,25 @@ class APITemplateView(HomeAssistantView):
url = URL_API_TEMPLATE
name = "api:template"
@asyncio.coroutine
def post(self, request):
"""Render a template."""
try:
tpl = template.Template(request.json['template'], self.hass)
return tpl.render(request.json.get('variables'))
except TemplateError as ex:
data = yield from request.json()
tpl = template.Template(data['template'], request.app['hass'])
return tpl.async_render(data.get('variables'))
except (ValueError, TemplateError) as ex:
return self.json_message('Error rendering template: {}'.format(ex),
HTTP_BAD_REQUEST)
def services_json(hass):
def async_services_json(hass):
"""Generate services data to JSONify."""
return [{"domain": key, "services": value}
for key, value in hass.services.services.items()]
for key, value in hass.services.async_services().items()]
def events_json(hass):
def async_events_json(hass):
"""Generate event data to JSONify."""
return [{"event": key, "listener_count": value}
for key, value in hass.bus.listeners.items()]
for key, value in hass.bus.async_listeners().items()]

View File

@@ -0,0 +1,172 @@
"""
Support for API.AI webhook.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/apiai/
"""
import asyncio
import copy
import logging
import voluptuous as vol
from homeassistant.const import PROJECT_NAME, HTTP_BAD_REQUEST
from homeassistant.helpers import template, script, config_validation as cv
from homeassistant.components.http import HomeAssistantView
_LOGGER = logging.getLogger(__name__)
INTENTS_API_ENDPOINT = '/api/apiai'
CONF_INTENTS = 'intents'
CONF_SPEECH = 'speech'
CONF_ACTION = 'action'
CONF_ASYNC_ACTION = 'async_action'
DEFAULT_CONF_ASYNC_ACTION = False
DOMAIN = 'apiai'
DEPENDENCIES = ['http']
CONFIG_SCHEMA = vol.Schema({
DOMAIN: {
CONF_INTENTS: {
cv.string: {
vol.Optional(CONF_SPEECH): cv.template,
vol.Optional(CONF_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_ASYNC_ACTION,
default=DEFAULT_CONF_ASYNC_ACTION): cv.boolean
}
}
}
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Activate API.AI component."""
intents = config[DOMAIN].get(CONF_INTENTS, {})
hass.http.register_view(ApiaiIntentsView(hass, intents))
return True
class ApiaiIntentsView(HomeAssistantView):
"""Handle API.AI requests."""
url = INTENTS_API_ENDPOINT
name = 'api:apiai'
def __init__(self, hass, intents):
"""Initialize API.AI view."""
super().__init__()
self.hass = hass
intents = copy.deepcopy(intents)
template.attach(hass, intents)
for name, intent in intents.items():
if CONF_ACTION in intent:
intent[CONF_ACTION] = script.Script(
hass, intent[CONF_ACTION], "Apiai intent {}".format(name))
self.intents = intents
@asyncio.coroutine
def post(self, request):
"""Handle API.AI."""
data = yield from request.json()
_LOGGER.debug("Received api.ai request: %s", data)
req = data.get('result')
if req is None:
_LOGGER.error("Received invalid data from api.ai: %s", data)
return self.json_message(
"Expected result value not received", HTTP_BAD_REQUEST)
action_incomplete = req['actionIncomplete']
if action_incomplete:
return None
# use intent to no mix HASS actions with this parameter
intent = req.get('action')
parameters = req.get('parameters')
# contexts = req.get('contexts')
response = ApiaiResponse(parameters)
# Default Welcome Intent
# Maybe is better to handle this in api.ai directly?
#
# if intent == 'input.welcome':
# response.add_speech(
# "Hello, and welcome to the future. How may I help?")
# return self.json(response)
if intent == "":
_LOGGER.warning("Received intent with empty action")
response.add_speech(
"You have not defined an action in your api.ai intent.")
return self.json(response)
config = self.intents.get(intent)
if config is None:
_LOGGER.warning("Received unknown intent %s", intent)
response.add_speech(
"Intent '%s' is not yet configured within Home Assistant." %
intent)
return self.json(response)
speech = config.get(CONF_SPEECH)
action = config.get(CONF_ACTION)
async_action = config.get(CONF_ASYNC_ACTION)
if action is not None:
# API.AI expects a response in less than 5s
if async_action:
# Do not wait for the action to be executed.
# Needed if the action will take longer than 5s to execute
self.hass.async_add_job(action.async_run(response.parameters))
else:
# Wait for the action to be executed so we can use results to
# render the answer
yield from action.async_run(response.parameters)
# pylint: disable=unsubscriptable-object
if speech is not None:
response.add_speech(speech)
return self.json(response)
class ApiaiResponse(object):
"""Help generating the response for API.AI."""
def __init__(self, parameters):
"""Initialize the response."""
self.speech = None
self.parameters = {}
# Parameter names replace '.' and '-' for '_'
for key, value in parameters.items():
underscored_key = key.replace('.', '_').replace('-', '_')
self.parameters[underscored_key] = value
def add_speech(self, text):
"""Add speech to the response."""
assert self.speech is None
if isinstance(text, template.Template):
text = text.async_render(self.parameters)
self.speech = text
def as_dict(self):
"""Return response in an API.AI valid dict."""
return {
'speech': self.speech,
'displayText': self.speech,
'source': PROJECT_NAME,
}

View File

@@ -4,13 +4,14 @@ Allow to setup simple automation rules via the config file.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/automation/
"""
import asyncio
from functools import partial
import logging
import os
import voluptuous as vol
from homeassistant.bootstrap import prepare_setup_platform
from homeassistant.bootstrap import async_prepare_setup_platform
from homeassistant import config as conf_util
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_PLATFORM, STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF,
@@ -29,6 +30,8 @@ ENTITY_ID_FORMAT = DOMAIN + '.{}'
DEPENDENCIES = ['group']
GROUP_NAME_ALL_AUTOMATIONS = 'all automations'
CONF_ALIAS = 'alias'
CONF_HIDE_ENTITY = 'hide_entity'
@@ -36,6 +39,7 @@ CONF_CONDITION = 'condition'
CONF_ACTION = 'action'
CONF_TRIGGER = 'trigger'
CONF_CONDITION_TYPE = 'condition_type'
CONF_INITIAL_STATE = 'initial_state'
CONDITION_USE_TRIGGER_VALUES = 'use_trigger_values'
CONDITION_TYPE_AND = 'and'
@@ -43,9 +47,7 @@ CONDITION_TYPE_OR = 'or'
DEFAULT_CONDITION_TYPE = CONDITION_TYPE_AND
DEFAULT_HIDE_ENTITY = False
METHOD_TRIGGER = 'trigger'
METHOD_IF_ACTION = 'if_action'
DEFAULT_INITIAL_STATE = True
ATTR_LAST_TRIGGERED = 'last_triggered'
ATTR_VARIABLES = 'variables'
@@ -55,21 +57,15 @@ SERVICE_RELOAD = 'reload'
_LOGGER = logging.getLogger(__name__)
def _platform_validator(method, schema):
"""Generate platform validator for different steps."""
def validator(config):
"""Validate it is a valid platform."""
platform = get_platform(DOMAIN, config[CONF_PLATFORM])
def _platform_validator(config):
"""Validate it is a valid platform."""
platform = get_platform(DOMAIN, config[CONF_PLATFORM])
if not hasattr(platform, method):
raise vol.Invalid('invalid method platform')
if not hasattr(platform, 'TRIGGER_SCHEMA'):
return config
if not hasattr(platform, schema):
return config
return getattr(platform, 'TRIGGER_SCHEMA')(config)
return getattr(platform, schema)(config)
return validator
_TRIGGER_SCHEMA = vol.All(
cv.ensure_list,
@@ -78,33 +74,19 @@ _TRIGGER_SCHEMA = vol.All(
vol.Schema({
vol.Required(CONF_PLATFORM): cv.platform_validator(DOMAIN)
}, extra=vol.ALLOW_EXTRA),
_platform_validator(METHOD_TRIGGER, 'TRIGGER_SCHEMA')
_platform_validator
),
]
)
_CONDITION_SCHEMA = vol.Any(
CONDITION_USE_TRIGGER_VALUES,
vol.All(
cv.ensure_list,
[
vol.All(
vol.Schema({
CONF_PLATFORM: str,
CONF_CONDITION: str,
}, extra=vol.ALLOW_EXTRA),
cv.has_at_least_one_key(CONF_PLATFORM, CONF_CONDITION),
),
]
)
)
_CONDITION_SCHEMA = vol.All(cv.ensure_list, [cv.CONDITION_SCHEMA])
PLATFORM_SCHEMA = vol.Schema({
CONF_ALIAS: cv.string,
vol.Optional(CONF_INITIAL_STATE,
default=DEFAULT_INITIAL_STATE): cv.boolean,
vol.Optional(CONF_HIDE_ENTITY, default=DEFAULT_HIDE_ENTITY): cv.boolean,
vol.Required(CONF_TRIGGER): _TRIGGER_SCHEMA,
vol.Required(CONF_CONDITION_TYPE, default=DEFAULT_CONDITION_TYPE):
vol.All(vol.Lower, vol.Any(CONDITION_TYPE_AND, CONDITION_TYPE_OR)),
vol.Optional(CONF_CONDITION): _CONDITION_SCHEMA,
vol.Required(CONF_ACTION): cv.SCRIPT_SCHEMA,
})
@@ -161,47 +143,81 @@ def reload(hass):
hass.services.call(DOMAIN, SERVICE_RELOAD)
def setup(hass, config):
@asyncio.coroutine
def async_setup(hass, config):
"""Setup the automation."""
component = EntityComponent(_LOGGER, DOMAIN, hass)
component = EntityComponent(_LOGGER, DOMAIN, hass,
group_name=GROUP_NAME_ALL_AUTOMATIONS)
success = _process_config(hass, config, component)
success = yield from _async_process_config(hass, config, component)
if not success:
return False
descriptions = conf_util.load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
descriptions = yield from hass.loop.run_in_executor(
None, conf_util.load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
@asyncio.coroutine
def trigger_service_handler(service_call):
"""Handle automation triggers."""
for entity in component.extract_from_service(service_call):
entity.trigger(service_call.data.get(ATTR_VARIABLES))
tasks = []
for entity in component.async_extract_from_service(service_call):
tasks.append(entity.async_trigger(
service_call.data.get(ATTR_VARIABLES), True))
def service_handler(service_call):
"""Handle automation service calls."""
for entity in component.extract_from_service(service_call):
getattr(entity, service_call.service)()
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
@asyncio.coroutine
def turn_onoff_service_handler(service_call):
"""Handle automation turn on/off service calls."""
tasks = []
method = 'async_{}'.format(service_call.service)
for entity in component.async_extract_from_service(service_call):
tasks.append(getattr(entity, method)())
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
@asyncio.coroutine
def toggle_service_handler(service_call):
"""Handle automation toggle service calls."""
tasks = []
for entity in component.async_extract_from_service(service_call):
if entity.is_on:
tasks.append(entity.async_turn_off())
else:
tasks.append(entity.async_turn_on())
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
@asyncio.coroutine
def reload_service_handler(service_call):
"""Remove all automations and load new ones from config."""
conf = component.prepare_reload()
conf = yield from component.async_prepare_reload()
if conf is None:
return
_process_config(hass, conf, component)
yield from _async_process_config(hass, conf, component)
hass.services.register(DOMAIN, SERVICE_TRIGGER, trigger_service_handler,
descriptions.get(SERVICE_TRIGGER),
schema=TRIGGER_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TRIGGER, trigger_service_handler,
descriptions.get(SERVICE_TRIGGER), schema=TRIGGER_SERVICE_SCHEMA)
hass.services.register(DOMAIN, SERVICE_RELOAD, reload_service_handler,
descriptions.get(SERVICE_RELOAD),
schema=RELOAD_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_RELOAD, reload_service_handler,
descriptions.get(SERVICE_RELOAD), schema=RELOAD_SERVICE_SCHEMA)
for service in (SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE):
hass.services.register(DOMAIN, service, service_handler,
descriptions.get(service),
schema=SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, toggle_service_handler,
descriptions.get(SERVICE_TOGGLE), schema=SERVICE_SCHEMA)
for service in (SERVICE_TURN_ON, SERVICE_TURN_OFF):
hass.services.async_register(
DOMAIN, service, turn_onoff_service_handler,
descriptions.get(service), schema=SERVICE_SCHEMA)
return True
@@ -209,15 +225,15 @@ def setup(hass, config):
class AutomationEntity(ToggleEntity):
"""Entity to show status of entity."""
# pylint: disable=too-many-arguments, too-many-instance-attributes
def __init__(self, name, attach_triggers, cond_func, action, hidden):
def __init__(self, name, async_attach_triggers, cond_func, async_action,
hidden):
"""Initialize an automation entity."""
self._name = name
self._attach_triggers = attach_triggers
self._detach_triggers = attach_triggers(self.trigger)
self._async_attach_triggers = async_attach_triggers
self._async_detach_triggers = None
self._cond_func = cond_func
self._action = action
self._enabled = True
self._async_action = async_action
self._enabled = False
self._last_triggered = None
self._hidden = hidden
@@ -248,41 +264,65 @@ class AutomationEntity(ToggleEntity):
"""Return True if entity is on."""
return self._enabled
def turn_on(self, **kwargs) -> None:
"""Turn the entity on."""
@asyncio.coroutine
def async_turn_on(self, **kwargs) -> None:
"""Turn the entity on and update the state."""
if self._enabled:
return
self._detach_triggers = self._attach_triggers(self.trigger)
self._enabled = True
self.update_ha_state()
yield from self.async_enable()
yield from self.async_update_ha_state()
def turn_off(self, **kwargs) -> None:
@asyncio.coroutine
def async_turn_off(self, **kwargs) -> None:
"""Turn the entity off."""
if not self._enabled:
return
self._detach_triggers()
self._detach_triggers = None
self._async_detach_triggers()
self._async_detach_triggers = None
self._enabled = False
self.update_ha_state()
yield from self.async_update_ha_state()
def trigger(self, variables):
"""Trigger automation."""
if self._cond_func(variables):
self._action(variables)
@asyncio.coroutine
def async_trigger(self, variables, skip_condition=False):
"""Trigger automation.
This method is a coroutine.
"""
if skip_condition or self._cond_func(variables):
yield from self._async_action(self.entity_id, variables)
self._last_triggered = utcnow()
self.update_ha_state()
yield from self.async_update_ha_state()
def remove(self):
@asyncio.coroutine
def async_remove(self):
"""Remove automation from HASS."""
self.turn_off()
super().remove()
yield from self.async_turn_off()
yield from super().async_remove()
@asyncio.coroutine
def async_enable(self):
"""Enable this automation entity.
This method is a coroutine.
"""
if self._enabled:
return
self._async_detach_triggers = yield from self._async_attach_triggers(
self.async_trigger)
self._enabled = True
def _process_config(hass, config, component):
"""Process config and add automations."""
success = False
@asyncio.coroutine
def _async_process_config(hass, config, component):
"""Process config and add automations.
This method is a coroutine.
"""
entities = []
tasks = []
for config_key in extract_domain_configs(config, DOMAIN):
conf = config[config_key]
@@ -293,10 +333,11 @@ def _process_config(hass, config, component):
hidden = config_block[CONF_HIDE_ENTITY]
action = _get_action(hass, config_block.get(CONF_ACTION, {}), name)
action = _async_get_action(hass, config_block.get(CONF_ACTION, {}),
name)
if CONF_CONDITION in config_block:
cond_func = _process_if(hass, config, config_block)
cond_func = _async_process_if(hass, config, config_block)
if cond_func is None:
continue
@@ -305,101 +346,79 @@ def _process_config(hass, config, component):
"""Condition will always pass."""
return True
attach_triggers = partial(_process_trigger, hass, config,
config_block.get(CONF_TRIGGER, []), name)
entity = AutomationEntity(name, attach_triggers, cond_func, action,
hidden)
component.add_entities((entity,))
success = True
async_attach_triggers = partial(
_async_process_trigger, hass, config,
config_block.get(CONF_TRIGGER, []), name)
entity = AutomationEntity(name, async_attach_triggers, cond_func,
action, hidden)
if config_block[CONF_INITIAL_STATE]:
tasks.append(entity.async_enable())
entities.append(entity)
return success
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
if entities:
yield from component.async_add_entities(entities)
return len(entities) > 0
def _get_action(hass, config, name):
def _async_get_action(hass, config, name):
"""Return an action based on a configuration."""
script_obj = script.Script(hass, config, name)
def action(variables=None):
@asyncio.coroutine
def action(entity_id, variables):
"""Action to be executed."""
_LOGGER.info('Executing %s', name)
logbook.log_entry(hass, name, 'has been triggered', DOMAIN)
script_obj.run(variables)
logbook.async_log_entry(
hass, name, 'has been triggered', DOMAIN, entity_id)
yield from script_obj.async_run(variables)
return action
def _process_if(hass, config, p_config):
def _async_process_if(hass, config, p_config):
"""Process if checks."""
cond_type = p_config.get(CONF_CONDITION_TYPE,
DEFAULT_CONDITION_TYPE).lower()
# Deprecated since 0.19 - 5/5/2016
if cond_type != DEFAULT_CONDITION_TYPE:
_LOGGER.warning('Using condition_type: "or" is deprecated. Please use '
'"condition: or" instead.')
if_configs = p_config.get(CONF_CONDITION)
use_trigger = if_configs == CONDITION_USE_TRIGGER_VALUES
if use_trigger:
if_configs = p_config[CONF_TRIGGER]
checks = []
for if_config in if_configs:
# Deprecated except for used by use_trigger_values
# since 0.19 - 5/5/2016
if CONF_PLATFORM in if_config:
if not use_trigger:
_LOGGER.warning("Please switch your condition configuration "
"to use 'condition' instead of 'platform'.")
if_config = dict(if_config)
if_config[CONF_CONDITION] = if_config.pop(CONF_PLATFORM)
# To support use_trigger_values with state trigger accepting
# multiple entity_ids to monitor.
if_entity_id = if_config.get(ATTR_ENTITY_ID)
if isinstance(if_entity_id, list) and len(if_entity_id) == 1:
if_config[ATTR_ENTITY_ID] = if_entity_id[0]
try:
checks.append(condition.from_config(if_config))
checks.append(condition.async_from_config(if_config, False))
except HomeAssistantError as ex:
# Invalid conditions are allowed if we base it on trigger
if use_trigger:
_LOGGER.warning('Ignoring invalid condition: %s', ex)
else:
_LOGGER.warning('Invalid condition: %s', ex)
return None
_LOGGER.warning('Invalid condition: %s', ex)
return None
if cond_type == CONDITION_TYPE_AND:
def if_action(variables=None):
"""AND all conditions."""
return all(check(hass, variables) for check in checks)
else:
def if_action(variables=None):
"""OR all conditions."""
return any(check(hass, variables) for check in checks)
def if_action(variables=None):
"""AND all conditions."""
return all(check(hass, variables) for check in checks)
return if_action
def _process_trigger(hass, config, trigger_configs, name, action):
"""Setup the triggers."""
@asyncio.coroutine
def _async_process_trigger(hass, config, trigger_configs, name, action):
"""Setup the triggers.
This method is a coroutine.
"""
removes = []
for conf in trigger_configs:
platform = _resolve_platform(METHOD_TRIGGER, hass, config,
conf.get(CONF_PLATFORM))
if platform is None:
continue
platform = yield from async_prepare_setup_platform(
hass, config, DOMAIN, conf.get(CONF_PLATFORM))
remove = platform.trigger(hass, conf, action)
if platform is None:
return None
remove = yield from platform.async_trigger(hass, conf, action)
if not remove:
_LOGGER.error("Error setting up rule %s", name)
_LOGGER.error("Error setting up trigger %s", name)
continue
_LOGGER.info("Initialized rule %s", name)
_LOGGER.info("Initialized trigger %s", name)
removes.append(remove)
if not removes:
@@ -411,17 +430,3 @@ def _process_trigger(hass, config, trigger_configs, name, action):
remove()
return remove_triggers
def _resolve_platform(method, hass, config, platform):
"""Find the automation platform."""
if platform is None:
return None
platform = prepare_setup_platform(hass, config, DOMAIN, platform)
if platform is None or not hasattr(platform, method):
_LOGGER.error("Unknown automation platform specified for %s: %s",
method, platform)
return None
return platform

View File

@@ -9,6 +9,7 @@ import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import CONF_PLATFORM
from homeassistant.helpers import config_validation as cv
@@ -24,21 +25,22 @@ TRIGGER_SCHEMA = vol.Schema({
})
def trigger(hass, config, action):
@asyncio.coroutine
def async_trigger(hass, config, action):
"""Listen for events based on configuration."""
event_type = config.get(CONF_EVENT_TYPE)
event_data = config.get(CONF_EVENT_DATA)
@asyncio.coroutine
@callback
def handle_event(event):
"""Listen for events and calls the action when data matches."""
if not event_data or all(val == event.data.get(key) for key, val
in event_data.items()):
hass.async_add_job(action, {
hass.async_run_job(action, {
'trigger': {
'platform': 'event',
'event': event,
},
})
return hass.bus.listen(event_type, handle_event)
return hass.bus.async_listen(event_type, handle_event)

View File

@@ -0,0 +1,100 @@
"""
Trigger an automation when a LiteJet switch is released.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/automation.litejet/
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import CONF_PLATFORM
import homeassistant.helpers.config_validation as cv
import homeassistant.util.dt as dt_util
from homeassistant.helpers.event import track_point_in_utc_time
DEPENDENCIES = ['litejet']
_LOGGER = logging.getLogger(__name__)
CONF_NUMBER = 'number'
CONF_HELD_MORE_THAN = 'held_more_than'
CONF_HELD_LESS_THAN = 'held_less_than'
TRIGGER_SCHEMA = vol.Schema({
vol.Required(CONF_PLATFORM): 'litejet',
vol.Required(CONF_NUMBER): cv.positive_int,
vol.Optional(CONF_HELD_MORE_THAN):
vol.All(cv.time_period, cv.positive_timedelta),
vol.Optional(CONF_HELD_LESS_THAN):
vol.All(cv.time_period, cv.positive_timedelta)
})
@asyncio.coroutine
def async_trigger(hass, config, action):
"""Listen for events based on configuration."""
number = config.get(CONF_NUMBER)
held_more_than = config.get(CONF_HELD_MORE_THAN)
held_less_than = config.get(CONF_HELD_LESS_THAN)
pressed_time = None
cancel_pressed_more_than = None
@callback
def call_action():
"""Call action with right context."""
hass.async_run_job(action, {
'trigger': {
CONF_PLATFORM: 'litejet',
CONF_NUMBER: number,
CONF_HELD_MORE_THAN: held_more_than,
CONF_HELD_LESS_THAN: held_less_than
},
})
# held_more_than and held_less_than: trigger on released (if in time range)
# held_more_than: trigger after pressed with calculation
# held_less_than: trigger on released with calculation
# neither: trigger on pressed
@callback
def pressed_more_than_satisfied(now):
"""Handle the LiteJet's switch's button pressed >= held_more_than."""
call_action()
def pressed():
"""Handle the press of the LiteJet switch's button."""
nonlocal cancel_pressed_more_than, pressed_time
nonlocal held_less_than, held_more_than
pressed_time = dt_util.utcnow()
if held_more_than is None and held_less_than is None:
call_action()
if held_more_than is not None and held_less_than is None:
cancel_pressed_more_than = track_point_in_utc_time(
hass,
pressed_more_than_satisfied,
dt_util.utcnow() + held_more_than)
def released():
"""Handle the release of the LiteJet switch's button."""
nonlocal cancel_pressed_more_than, pressed_time
nonlocal held_less_than, held_more_than
# pylint: disable=not-callable
if cancel_pressed_more_than is not None:
cancel_pressed_more_than()
cancel_pressed_more_than = None
held_time = dt_util.utcnow() - pressed_time
if held_less_than is not None and held_time < held_less_than:
if held_more_than is None or held_time > held_more_than:
call_action()
hass.data['litejet_system'].on_switch_pressed(number, pressed)
hass.data['litejet_system'].on_switch_released(number, released)
def async_remove():
"""Remove all subscriptions used for this trigger."""
return
return async_remove

View File

@@ -4,8 +4,12 @@ Offer MQTT listening automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation/#mqtt-trigger
"""
import asyncio
import json
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.components.mqtt as mqtt
from homeassistant.const import (CONF_PLATFORM, CONF_PAYLOAD)
import homeassistant.helpers.config_validation as cv
@@ -21,21 +25,32 @@ TRIGGER_SCHEMA = vol.Schema({
})
def trigger(hass, config, action):
@asyncio.coroutine
def async_trigger(hass, config, action):
"""Listen for state changes based on configuration."""
topic = config.get(CONF_TOPIC)
payload = config.get(CONF_PAYLOAD)
@callback
def mqtt_automation_listener(msg_topic, msg_payload, qos):
"""Listen for MQTT messages."""
if payload is None or payload == msg_payload:
action({
'trigger': {
'platform': 'mqtt',
'topic': msg_topic,
'payload': msg_payload,
'qos': qos,
}
data = {
'platform': 'mqtt',
'topic': msg_topic,
'payload': msg_payload,
'qos': qos,
}
try:
data['payload_json'] = json.loads(msg_payload)
except ValueError:
pass
hass.async_run_job(action, {
'trigger': data
})
return mqtt.subscribe(hass, topic, mqtt_automation_listener)
remove = yield from mqtt.async_subscribe(
hass, topic, mqtt_automation_listener)
return remove

View File

@@ -4,14 +4,16 @@ Offer numeric state listening automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation/#numeric-state-trigger
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import (
CONF_VALUE_TEMPLATE, CONF_PLATFORM, CONF_ENTITY_ID,
CONF_BELOW, CONF_ABOVE)
from homeassistant.helpers.event import track_state_change
from homeassistant.helpers.event import async_track_state_change
from homeassistant.helpers import condition, config_validation as cv
TRIGGER_SCHEMA = vol.All(vol.Schema({
@@ -25,7 +27,8 @@ TRIGGER_SCHEMA = vol.All(vol.Schema({
_LOGGER = logging.getLogger(__name__)
def trigger(hass, config, action):
@asyncio.coroutine
def async_trigger(hass, config, action):
"""Listen for state changes based on configuration."""
entity_id = config.get(CONF_ENTITY_ID)
below = config.get(CONF_BELOW)
@@ -34,7 +37,7 @@ def trigger(hass, config, action):
if value_template is not None:
value_template.hass = hass
# pylint: disable=unused-argument
@callback
def state_automation_listener(entity, from_s, to_s):
"""Listen for state changes and calls action."""
if to_s is None:
@@ -50,19 +53,19 @@ def trigger(hass, config, action):
}
# If new one doesn't match, nothing to do
if not condition.numeric_state(
if not condition.async_numeric_state(
hass, to_s, below, above, value_template, variables):
return
# Only match if old didn't exist or existed but didn't match
# Written as: skip if old one did exist and matched
if from_s is not None and condition.numeric_state(
if from_s is not None and condition.async_numeric_state(
hass, from_s, below, above, value_template, variables):
return
variables['trigger']['from_state'] = from_s
variables['trigger']['to_state'] = to_s
action(variables)
hass.async_run_job(action, variables)
return track_state_change(hass, entity_id, state_automation_listener)
return async_track_state_change(hass, entity_id, state_automation_listener)

View File

@@ -4,11 +4,14 @@ Offer state listening automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation/#state-trigger
"""
import asyncio
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.util.dt as dt_util
from homeassistant.const import MATCH_ALL, CONF_PLATFORM
from homeassistant.helpers.event import track_state_change, track_point_in_time
from homeassistant.helpers.event import (
async_track_state_change, async_track_point_in_utc_time)
import homeassistant.helpers.config_validation as cv
CONF_ENTITY_ID = "entity_id"
@@ -32,22 +35,37 @@ TRIGGER_SCHEMA = vol.All(
)
def trigger(hass, config, action):
@asyncio.coroutine
def async_trigger(hass, config, action):
"""Listen for state changes based on configuration."""
entity_id = config.get(CONF_ENTITY_ID)
from_state = config.get(CONF_FROM, MATCH_ALL)
to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL
time_delta = config.get(CONF_FOR)
remove_state_for_cancel = None
remove_state_for_listener = None
async_remove_state_for_cancel = None
async_remove_state_for_listener = None
@callback
def clear_listener():
"""Clear all unsub listener."""
nonlocal async_remove_state_for_cancel, async_remove_state_for_listener
# pylint: disable=not-callable
if async_remove_state_for_listener is not None:
async_remove_state_for_listener()
async_remove_state_for_listener = None
if async_remove_state_for_cancel is not None:
async_remove_state_for_cancel()
async_remove_state_for_cancel = None
@callback
def state_automation_listener(entity, from_s, to_s):
"""Listen for state changes and calls action."""
nonlocal remove_state_for_cancel, remove_state_for_listener
nonlocal async_remove_state_for_cancel, async_remove_state_for_listener
def call_action():
"""Call action with right context."""
action({
hass.async_run_job(action, {
'trigger': {
'platform': 'state',
'entity_id': entity,
@@ -61,35 +79,37 @@ def trigger(hass, config, action):
call_action()
return
@callback
def state_for_listener(now):
"""Fire on state changes after a delay and calls action."""
remove_state_for_cancel()
nonlocal async_remove_state_for_listener
async_remove_state_for_listener = None
clear_listener()
call_action()
@callback
def state_for_cancel_listener(entity, inner_from_s, inner_to_s):
"""Fire on changes and cancel for listener if changed."""
if inner_to_s.state == to_s.state:
return
remove_state_for_listener()
remove_state_for_cancel()
clear_listener()
remove_state_for_listener = track_point_in_time(
# cleanup previous listener
clear_listener()
async_remove_state_for_listener = async_track_point_in_utc_time(
hass, state_for_listener, dt_util.utcnow() + time_delta)
remove_state_for_cancel = track_state_change(
async_remove_state_for_cancel = async_track_state_change(
hass, entity, state_for_cancel_listener)
unsub = track_state_change(hass, entity_id, state_automation_listener,
from_state, to_state)
unsub = async_track_state_change(
hass, entity_id, state_automation_listener, from_state, to_state)
def remove():
"""Remove state listeners."""
@callback
def async_remove():
"""Remove state listeners async."""
unsub()
# pylint: disable=not-callable
if remove_state_for_cancel is not None:
remove_state_for_cancel()
clear_listener()
if remove_state_for_listener is not None:
remove_state_for_listener()
return remove
return async_remove

View File

@@ -4,14 +4,16 @@ Offer sun based automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation/#sun-trigger
"""
import asyncio
from datetime import timedelta
import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import (
CONF_EVENT, CONF_OFFSET, CONF_PLATFORM, SUN_EVENT_SUNRISE)
from homeassistant.helpers.event import track_sunrise, track_sunset
from homeassistant.helpers.event import async_track_sunrise, async_track_sunset
import homeassistant.helpers.config_validation as cv
DEPENDENCIES = ['sun']
@@ -25,14 +27,16 @@ TRIGGER_SCHEMA = vol.Schema({
})
def trigger(hass, config, action):
@asyncio.coroutine
def async_trigger(hass, config, action):
"""Listen for events based on configuration."""
event = config.get(CONF_EVENT)
offset = config.get(CONF_OFFSET)
@callback
def call_action():
"""Call action with right context."""
action({
hass.async_run_job(action, {
'trigger': {
'platform': 'sun',
'event': event,
@@ -42,6 +46,6 @@ def trigger(hass, config, action):
# Do something to call action
if event == SUN_EVENT_SUNRISE:
return track_sunrise(hass, call_action, offset)
return async_track_sunrise(hass, call_action, offset)
else:
return track_sunset(hass, call_action, offset)
return async_track_sunset(hass, call_action, offset)

View File

@@ -9,9 +9,9 @@ import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import CONF_VALUE_TEMPLATE, CONF_PLATFORM
from homeassistant.helpers import condition
from homeassistant.helpers.event import track_state_change
from homeassistant.helpers.event import async_track_template
import homeassistant.helpers.config_validation as cv
@@ -23,33 +23,22 @@ TRIGGER_SCHEMA = IF_ACTION_SCHEMA = vol.Schema({
})
def trigger(hass, config, action):
@asyncio.coroutine
def async_trigger(hass, config, action):
"""Listen for state changes based on configuration."""
value_template = config.get(CONF_VALUE_TEMPLATE)
value_template.hass = hass
# Local variable to keep track of if the action has already been triggered
already_triggered = False
@asyncio.coroutine
def state_changed_listener(entity_id, from_s, to_s):
@callback
def template_listener(entity_id, from_s, to_s):
"""Listen for state changes and calls action."""
nonlocal already_triggered
template_result = condition.async_template(hass, value_template)
hass.async_run_job(action, {
'trigger': {
'platform': 'template',
'entity_id': entity_id,
'from_state': from_s,
'to_state': to_s,
},
})
# Check to see if template returns true
if template_result and not already_triggered:
already_triggered = True
hass.async_add_job(action, {
'trigger': {
'platform': 'template',
'entity_id': entity_id,
'from_state': from_s,
'to_state': to_s,
},
})
elif not template_result:
already_triggered = False
return track_state_change(hass, value_template.extract_entities(),
state_changed_listener)
return async_track_template(hass, value_template, template_listener)

View File

@@ -4,13 +4,15 @@ Offer time listening automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation/#time-trigger
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import CONF_AFTER, CONF_PLATFORM
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.event import track_time_change
from homeassistant.helpers.event import async_track_time_change
CONF_HOURS = "hours"
CONF_MINUTES = "minutes"
@@ -28,7 +30,8 @@ TRIGGER_SCHEMA = vol.All(vol.Schema({
CONF_SECONDS, CONF_AFTER))
def trigger(hass, config, action):
@asyncio.coroutine
def async_trigger(hass, config, action):
"""Listen for state changes based on configuration."""
if CONF_AFTER in config:
after = config.get(CONF_AFTER)
@@ -38,14 +41,15 @@ def trigger(hass, config, action):
minutes = config.get(CONF_MINUTES)
seconds = config.get(CONF_SECONDS)
@callback
def time_automation_listener(now):
"""Listen for time changes and calls action."""
action({
hass.async_run_job(action, {
'trigger': {
'platform': 'time',
'now': now,
},
})
return track_time_change(hass, time_automation_listener,
hour=hours, minute=minutes, second=seconds)
return async_track_time_change(hass, time_automation_listener,
hour=hours, minute=minutes, second=seconds)

View File

@@ -4,11 +4,13 @@ Offer zone automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation/#zone-trigger
"""
import asyncio
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import (
CONF_EVENT, CONF_ENTITY_ID, CONF_ZONE, MATCH_ALL, CONF_PLATFORM)
from homeassistant.helpers.event import track_state_change
from homeassistant.helpers.event import async_track_state_change
from homeassistant.helpers import (
condition, config_validation as cv, location)
@@ -25,12 +27,14 @@ TRIGGER_SCHEMA = vol.Schema({
})
def trigger(hass, config, action):
@asyncio.coroutine
def async_trigger(hass, config, action):
"""Listen for state changes based on configuration."""
entity_id = config.get(CONF_ENTITY_ID)
zone_entity_id = config.get(CONF_ZONE)
event = config.get(CONF_EVENT)
@callback
def zone_automation_listener(entity, from_s, to_s):
"""Listen for state changes and calls action."""
if from_s and not location.has_location(from_s) or \
@@ -47,7 +51,7 @@ def trigger(hass, config, action):
# pylint: disable=too-many-boolean-expressions
if event == EVENT_ENTER and not from_match and to_match or \
event == EVENT_LEAVE and from_match and not to_match:
action({
hass.async_run_job(action, {
'trigger': {
'platform': 'zone',
'entity_id': entity,
@@ -58,5 +62,5 @@ def trigger(hass, config, action):
},
})
return track_state_change(hass, entity_id, zone_automation_listener,
MATCH_ALL, MATCH_ALL)
return async_track_state_change(hass, entity_id, zone_automation_listener,
MATCH_ALL, MATCH_ALL)

View File

@@ -0,0 +1,74 @@
"""
Support for controlling GPIO pins of a Beaglebone Black.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/bbb_gpio/
"""
import logging
from homeassistant.const import (
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
REQUIREMENTS = ['Adafruit_BBIO==1.0.0']
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'bbb_gpio'
# pylint: disable=no-member
def setup(hass, config):
"""Set up the BeagleBone Black GPIO component."""
# pylint: disable=import-error
import Adafruit_BBIO.GPIO as GPIO
def cleanup_gpio(event):
"""Stuff to do before stopping."""
GPIO.cleanup()
def prepare_gpio(event):
"""Stuff to do when home assistant starts."""
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, cleanup_gpio)
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, prepare_gpio)
return True
# noqa: F821
def setup_output(pin):
"""Setup a GPIO as output."""
# pylint: disable=import-error,undefined-variable
import Adafruit_BBIO.GPIO as GPIO
GPIO.setup(pin, GPIO.OUT)
def setup_input(pin, pull_mode):
"""Setup a GPIO as input."""
# pylint: disable=import-error,undefined-variable
import Adafruit_BBIO.GPIO as GPIO
GPIO.setup(pin, GPIO.IN, # noqa: F821
GPIO.PUD_DOWN if pull_mode == 'DOWN' # noqa: F821
else GPIO.PUD_UP) # noqa: F821
def write_output(pin, value):
"""Write a value to a GPIO."""
# pylint: disable=import-error,undefined-variable
import Adafruit_BBIO.GPIO as GPIO
GPIO.output(pin, value)
def read_input(pin):
"""Read a value from a GPIO."""
# pylint: disable=import-error,undefined-variable
import Adafruit_BBIO.GPIO as GPIO
return GPIO.input(pin) is GPIO.HIGH
def edge_detect(pin, event_callback, bounce):
"""Add detection for RISING and FALLING events."""
# pylint: disable=import-error,undefined-variable
import Adafruit_BBIO.GPIO as GPIO
GPIO.add_event_detect(
pin, GPIO.BOTH, callback=event_callback, bouncetime=bounce)

View File

@@ -4,6 +4,8 @@ Component to interface with binary sensors.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/binary_sensor/
"""
import asyncio
from datetime import timedelta
import logging
import voluptuous as vol
@@ -12,13 +14,13 @@ from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity import Entity
from homeassistant.const import (STATE_ON, STATE_OFF)
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.helpers.deprecation import deprecated_substitute
DOMAIN = 'binary_sensor'
SCAN_INTERVAL = 30
SCAN_INTERVAL = timedelta(seconds=30)
ENTITY_ID_FORMAT = DOMAIN + '.{}'
SENSOR_CLASSES = [
None, # Generic on/off
DEVICE_CLASSES = [
'cold', # On means cold (or too cold)
'connectivity', # On means connection present, Off = no connection
'gas', # CO, CO2, etc.
@@ -36,16 +38,16 @@ SENSOR_CLASSES = [
'vibration', # On means vibration detected, Off means no vibration
]
SENSOR_CLASSES_SCHEMA = vol.All(vol.Lower, vol.In(SENSOR_CLASSES))
DEVICE_CLASSES_SCHEMA = vol.All(vol.Lower, vol.In(DEVICE_CLASSES))
def setup(hass, config):
@asyncio.coroutine
def async_setup(hass, config):
"""Track states and offer events for binary sensors."""
component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
component.setup(config)
yield from component.async_setup(config)
return True
@@ -64,16 +66,7 @@ class BinarySensorDevice(Entity):
return STATE_ON if self.is_on else STATE_OFF
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
@deprecated_substitute('sensor_class')
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return None
@property
def state_attributes(self):
"""Return device specific state attributes."""
attr = {}
if self.sensor_class is not None:
attr['sensor_class'] = self.sensor_class
return attr

View File

@@ -1,5 +1,5 @@
"""
Support for exposed aREST RESTful API of a device.
Support for an exposed aREST RESTful API of a device.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.arest/
@@ -8,72 +8,69 @@ import logging
from datetime import timedelta
import requests
import voluptuous as vol
from homeassistant.components.binary_sensor import (
BinarySensorDevice, SENSOR_CLASSES)
from homeassistant.const import CONF_RESOURCE, CONF_PIN
BinarySensorDevice, PLATFORM_SCHEMA, DEVICE_CLASSES_SCHEMA)
from homeassistant.const import (
CONF_RESOURCE, CONF_PIN, CONF_NAME, CONF_SENSOR_CLASS, CONF_DEVICE_CLASS)
from homeassistant.util import Throttle
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
_LOGGER = logging.getLogger(__name__)
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_RESOURCE): cv.url,
vol.Optional(CONF_NAME): cv.string,
vol.Required(CONF_PIN): cv.string,
vol.Optional(CONF_SENSOR_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the aREST binary sensor."""
"""Set up the aREST binary sensor."""
resource = config.get(CONF_RESOURCE)
pin = config.get(CONF_PIN)
sensor_class = config.get('sensor_class')
if sensor_class not in SENSOR_CLASSES:
_LOGGER.warning('Unknown sensor class: %s', sensor_class)
sensor_class = None
if None in (resource, pin):
_LOGGER.error('Not all required config keys present: %s',
', '.join((CONF_RESOURCE, CONF_PIN)))
return False
device_class = get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
try:
response = requests.get(resource, timeout=10).json()
except requests.exceptions.MissingSchema:
_LOGGER.error('Missing resource or schema in configuration. '
'Add http:// to your URL.')
_LOGGER.error("Missing resource or schema in configuration. "
"Add http:// to your URL")
return False
except requests.exceptions.ConnectionError:
_LOGGER.error('No route to device at %s. '
'Please check the IP address in the configuration file.',
resource)
_LOGGER.error("No route to device at %s", resource)
return False
arest = ArestData(resource, pin)
add_devices([ArestBinarySensor(
arest,
resource,
config.get('name', response['name']),
sensor_class,
pin)])
arest, resource, config.get(CONF_NAME, response[CONF_NAME]),
device_class, pin)])
# pylint: disable=too-many-instance-attributes, too-many-arguments
class ArestBinarySensor(BinarySensorDevice):
"""Implement an aREST binary sensor for a pin."""
def __init__(self, arest, resource, name, sensor_class, pin):
def __init__(self, arest, resource, name, device_class, pin):
"""Initialize the aREST device."""
self.arest = arest
self._resource = resource
self._name = name
self._sensor_class = sensor_class
self._device_class = device_class
self._pin = pin
self.update()
if self._pin is not None:
request = requests.get('{}/mode/{}/i'.format
(self._resource, self._pin), timeout=10)
request = requests.get(
'{}/mode/{}/i'.format(self._resource, self._pin), timeout=10)
if request.status_code is not 200:
_LOGGER.error("Can't set mode. Is device offline?")
_LOGGER.error("Can't set mode of %s", self._resource)
@property
def name(self):
@@ -86,16 +83,15 @@ class ArestBinarySensor(BinarySensorDevice):
return bool(self.arest.data.get('state'))
@property
def sensor_class(self):
def device_class(self):
"""Return the class of this sensor."""
return self._sensor_class
return self._device_class
def update(self):
"""Get the latest data from aREST API."""
self.arest.update()
# pylint: disable=too-few-public-methods
class ArestData(object):
"""Class for handling the data retrieval for pins."""
@@ -113,5 +109,4 @@ class ArestData(object):
self._resource, self._pin), timeout=10)
self.data = {'state': response.json()['return_value']}
except requests.exceptions.ConnectionError:
_LOGGER.error("No route to device '%s'. Is device offline?",
self._resource)
_LOGGER.error("No route to device '%s'", self._resource)

View File

@@ -0,0 +1,148 @@
"""
Support for aurora forecast data sensor.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.aurora/
"""
from datetime import timedelta
import logging
import requests
import voluptuous as vol
from homeassistant.components.binary_sensor \
import (BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.const import (CONF_NAME)
import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle
CONF_THRESHOLD = "forecast_threshold"
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'Aurora Visibility'
DEFAULT_DEVICE_CLASS = "visible"
DEFAULT_THRESHOLD = 75
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=5)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_THRESHOLD, default=DEFAULT_THRESHOLD): cv.positive_int,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the aurora sensor."""
if None in (hass.config.latitude, hass.config.longitude):
_LOGGER.error("Lat. or long. not set in Home Assistant config")
return False
name = config.get(CONF_NAME)
threshold = config.get(CONF_THRESHOLD)
try:
aurora_data = AuroraData(
hass.config.latitude,
hass.config.longitude,
threshold
)
aurora_data.update()
except requests.exceptions.HTTPError as error:
_LOGGER.error(
"Connection to aurora forecast service failed: %s", error)
return False
add_devices([AuroraSensor(aurora_data, name)], True)
class AuroraSensor(BinarySensorDevice):
"""Implementation of an aurora sensor."""
def __init__(self, aurora_data, name):
"""Initialize the sensor."""
self.aurora_data = aurora_data
self._name = name
@property
def name(self):
"""Return the name of the sensor."""
return '{}'.format(self._name)
@property
def is_on(self):
"""Return true if aurora is visible."""
return self.aurora_data.is_visible if self.aurora_data else False
@property
def device_class(self):
"""Return the class of this device."""
return DEFAULT_DEVICE_CLASS
@property
def device_state_attributes(self):
"""Return the state attributes."""
attrs = {}
if self.aurora_data:
attrs["visibility_level"] = self.aurora_data.visibility_level
attrs["message"] = self.aurora_data.is_visible_text
return attrs
def update(self):
"""Get the latest data from Aurora API and updates the states."""
self.aurora_data.update()
class AuroraData(object):
"""Get aurora forecast."""
def __init__(self, latitude, longitude, threshold):
"""Initialize the data object."""
self.latitude = latitude
self.longitude = longitude
self.number_of_latitude_intervals = 513
self.number_of_longitude_intervals = 1024
self.api_url = \
"http://services.swpc.noaa.gov/text/aurora-nowcast-map.txt"
self.headers = {"User-Agent": "Home Assistant Aurora Tracker v.0.1.0"}
self.threshold = int(threshold)
self.is_visible = None
self.is_visible_text = None
self.visibility_level = None
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Get the latest data from the Aurora service."""
try:
self.visibility_level = self.get_aurora_forecast()
if int(self.visibility_level) > self.threshold:
self.is_visible = True
self.is_visible_text = "visible!"
else:
self.is_visible = False
self.is_visible_text = "nothing's out"
except requests.exceptions.HTTPError as error:
_LOGGER.error(
"Connection to aurora forecast service failed: %s", error)
return False
def get_aurora_forecast(self):
"""Get forecast data and parse for given long/lat."""
raw_data = requests.get(self.api_url, headers=self.headers).text
forecast_table = [
row.strip(" ").split(" ")
for row in raw_data.split("\n")
if not row.startswith("#")
]
# convert lat and long for data points in table
converted_latitude = round((self.latitude / 180)
* self.number_of_latitude_intervals)
converted_longitude = round((self.longitude / 360)
* self.number_of_longitude_intervals)
return forecast_table[converted_latitude][converted_longitude]

View File

@@ -0,0 +1,89 @@
"""
Support for binary sensor using Beaglebone Black GPIO.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.bbb_gpio/
"""
import logging
import voluptuous as vol
import homeassistant.components.bbb_gpio as bbb_gpio
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.const import (DEVICE_DEFAULT_NAME, CONF_NAME)
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['bbb_gpio']
CONF_PINS = 'pins'
CONF_BOUNCETIME = 'bouncetime'
CONF_INVERT_LOGIC = 'invert_logic'
CONF_PULL_MODE = 'pull_mode'
DEFAULT_BOUNCETIME = 50
DEFAULT_INVERT_LOGIC = False
DEFAULT_PULL_MODE = 'UP'
PIN_SCHEMA = vol.Schema({
vol.Required(CONF_NAME): cv.string,
vol.Optional(CONF_BOUNCETIME, default=DEFAULT_BOUNCETIME): cv.positive_int,
vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean,
vol.Optional(CONF_PULL_MODE, default=DEFAULT_PULL_MODE):
vol.In(['UP', 'DOWN'])
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_PINS, default={}):
vol.Schema({cv.string: PIN_SCHEMA}),
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Beaglebone Black GPIO devices."""
pins = config.get(CONF_PINS)
binary_sensors = []
for pin, params in pins.items():
binary_sensors.append(BBBGPIOBinarySensor(pin, params))
add_devices(binary_sensors)
class BBBGPIOBinarySensor(BinarySensorDevice):
"""Represent a binary sensor that uses Beaglebone Black GPIO."""
def __init__(self, pin, params):
"""Initialize the Beaglebone Black binary sensor."""
self._pin = pin
self._name = params.get(CONF_NAME) or DEVICE_DEFAULT_NAME
self._bouncetime = params.get(CONF_BOUNCETIME)
self._pull_mode = params.get(CONF_PULL_MODE)
self._invert_logic = params.get(CONF_INVERT_LOGIC)
bbb_gpio.setup_input(self._pin, self._pull_mode)
self._state = bbb_gpio.read_input(self._pin)
def read_gpio(pin):
"""Read state from GPIO."""
self._state = bbb_gpio.read_input(self._pin)
self.schedule_update_ha_state()
bbb_gpio.edge_detect(self._pin, read_gpio, self._bouncetime)
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def is_on(self):
"""Return the state of the entity."""
return self._state != self._invert_logic

View File

@@ -64,8 +64,8 @@ class BloomSkySensor(BinarySensorDevice):
return self._unique_id
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return SENSOR_TYPES.get(self._sensor_name)
@property

View File

@@ -4,18 +4,19 @@ Support for custom shell commands to retrieve values.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.command_line/
"""
import logging
from datetime import timedelta
import logging
import voluptuous as vol
from homeassistant.components.binary_sensor import (
BinarySensorDevice, SENSOR_CLASSES_SCHEMA, PLATFORM_SCHEMA)
BinarySensorDevice, DEVICE_CLASSES_SCHEMA, PLATFORM_SCHEMA)
from homeassistant.components.sensor.command_line import CommandSensorData
from homeassistant.const import (
CONF_PAYLOAD_OFF, CONF_PAYLOAD_ON, CONF_NAME, CONF_VALUE_TEMPLATE,
CONF_SENSOR_CLASS, CONF_COMMAND)
CONF_SENSOR_CLASS, CONF_COMMAND, CONF_DEVICE_CLASS)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
_LOGGER = logging.getLogger(__name__)
@@ -23,14 +24,15 @@ DEFAULT_NAME = 'Binary Command Sensor'
DEFAULT_PAYLOAD_ON = 'ON'
DEFAULT_PAYLOAD_OFF = 'OFF'
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60)
SCAN_INTERVAL = timedelta(seconds=60)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_COMMAND): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(CONF_SENSOR_CLASS): SENSOR_CLASSES_SCHEMA,
vol.Optional(CONF_SENSOR_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
})
@@ -42,28 +44,27 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
command = config.get(CONF_COMMAND)
payload_off = config.get(CONF_PAYLOAD_OFF)
payload_on = config.get(CONF_PAYLOAD_ON)
sensor_class = config.get(CONF_SENSOR_CLASS)
device_class = get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
value_template = config.get(CONF_VALUE_TEMPLATE)
if value_template is not None:
value_template.hass = hass
data = CommandSensorData(command)
add_devices([CommandBinarySensor(
hass, data, name, sensor_class, payload_on, payload_off,
hass, data, name, device_class, payload_on, payload_off,
value_template)])
# pylint: disable=too-many-arguments, too-many-instance-attributes
class CommandBinarySensor(BinarySensorDevice):
"""Represent a command line binary sensor."""
def __init__(self, hass, data, name, sensor_class, payload_on,
def __init__(self, hass, data, name, device_class, payload_on,
payload_off, value_template):
"""Initialize the Command line binary sensor."""
self._hass = hass
self.data = data
self._name = name
self._sensor_class = sensor_class
self._device_class = device_class
self._state = False
self._payload_on = payload_on
self._payload_off = payload_off
@@ -81,9 +82,9 @@ class CommandBinarySensor(BinarySensorDevice):
return self._state
@ property
def sensor_class(self):
def device_class(self):
"""Return the class of the binary sensor."""
return self._sensor_class
return self._device_class
def update(self):
"""Get the latest data and updates the state."""

View File

@@ -0,0 +1,136 @@
"""
Support for exposing Concord232 elements as sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.concord232/
"""
import datetime
import logging
import requests
import voluptuous as vol
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA, DEVICE_CLASSES)
from homeassistant.const import (CONF_HOST, CONF_PORT)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['concord232==0.14']
_LOGGER = logging.getLogger(__name__)
CONF_EXCLUDE_ZONES = 'exclude_zones'
CONF_ZONE_TYPES = 'zone_types'
DEFAULT_HOST = 'localhost'
DEFAULT_NAME = 'Alarm'
DEFAULT_PORT = '5007'
DEFAULT_SSL = False
SCAN_INTERVAL = datetime.timedelta(seconds=1)
ZONE_TYPES_SCHEMA = vol.Schema({
cv.positive_int: vol.In(DEVICE_CLASSES),
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_EXCLUDE_ZONES, default=[]):
vol.All(cv.ensure_list, [cv.positive_int]),
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_ZONE_TYPES, default={}): ZONE_TYPES_SCHEMA,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Concord232 binary sensor platform."""
from concord232 import client as concord232_client
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
exclude = config.get(CONF_EXCLUDE_ZONES)
zone_types = config.get(CONF_ZONE_TYPES)
sensors = []
try:
_LOGGER.debug("Initializing Client")
client = concord232_client.Client('http://{}:{}'.format(host, port))
client.zones = client.list_zones()
client.last_zone_update = datetime.datetime.now()
except requests.exceptions.ConnectionError as ex:
_LOGGER.error("Unable to connect to Concord232: %s", str(ex))
return False
for zone in client.zones:
_LOGGER.info("Loading Zone found: %s", zone['name'])
if zone['number'] not in exclude:
sensors.append(
Concord232ZoneSensor(
hass, client, zone, zone_types.get(zone['number'],
get_opening_type(zone)))
)
add_devices(sensors)
return True
def get_opening_type(zone):
"""Helper function to try to guess sensor type from name."""
if 'MOTION' in zone['name']:
return 'motion'
if 'KEY' in zone['name']:
return 'safety'
if 'SMOKE' in zone['name']:
return 'smoke'
if 'WATER' in zone['name']:
return 'water'
return 'opening'
class Concord232ZoneSensor(BinarySensorDevice):
"""Representation of a Concord232 zone as a sensor."""
def __init__(self, hass, client, zone, zone_type):
"""Initialize the Concord232 binary sensor."""
self._hass = hass
self._client = client
self._zone = zone
self._number = zone['number']
self._zone_type = zone_type
self.update()
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return self._zone_type
@property
def should_poll(self):
"""No polling needed."""
return True
@property
def name(self):
"""Return the name of the binary sensor."""
return self._zone['name']
@property
def is_on(self):
"""Return true if the binary sensor is on."""
# True means "faulted" or "open" or "abnormal state"
return bool(self._zone['state'] == 'Normal')
def update(self):
""""Get updated stats from API."""
last_update = datetime.datetime.now() - self._client.last_zone_update
_LOGGER.debug("Zone: %s ", self._zone)
if last_update > datetime.timedelta(seconds=1):
self._client.zones = self._client.list_zones()
self._client.last_zone_update = datetime.datetime.now()
_LOGGER.debug("Updated from Zone: %s", self._zone['name'])
if hasattr(self._client, 'zones'):
self._zone = next((x for x in self._client.zones
if x['number'] == self._number), None)

View File

@@ -18,14 +18,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class DemoBinarySensor(BinarySensorDevice):
"""A Demo binary sensor."""
def __init__(self, name, state, sensor_class):
def __init__(self, name, state, device_class):
"""Initialize the demo sensor."""
self._name = name
self._state = state
self._sensor_type = sensor_class
self._sensor_type = device_class
@property
def sensor_class(self):
def device_class(self):
"""Return the class of this sensor."""
return self._sensor_type

View File

@@ -0,0 +1,91 @@
"""
Support for monitoring the state of Digital Ocean droplets.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.digital_ocean/
"""
import logging
import voluptuous as vol
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.components.digital_ocean import (
CONF_DROPLETS, ATTR_CREATED_AT, ATTR_DROPLET_ID, ATTR_DROPLET_NAME,
ATTR_FEATURES, ATTR_IPV4_ADDRESS, ATTR_IPV6_ADDRESS, ATTR_MEMORY,
ATTR_REGION, ATTR_VCPUS)
from homeassistant.loader import get_component
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'Droplet'
DEFAULT_SENSOR_CLASS = 'motion'
DEPENDENCIES = ['digital_ocean']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_DROPLETS): vol.All(cv.ensure_list, [cv.string]),
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Digital Ocean droplet sensor."""
digital_ocean = get_component('digital_ocean')
droplets = config.get(CONF_DROPLETS)
dev = []
for droplet in droplets:
droplet_id = digital_ocean.DIGITAL_OCEAN.get_droplet_id(droplet)
dev.append(DigitalOceanBinarySensor(
digital_ocean.DIGITAL_OCEAN, droplet_id))
add_devices(dev)
class DigitalOceanBinarySensor(BinarySensorDevice):
"""Representation of a Digital Ocean droplet sensor."""
def __init__(self, do, droplet_id):
"""Initialize a new Digital Ocean sensor."""
self._digital_ocean = do
self._droplet_id = droplet_id
self._state = None
self.update()
@property
def name(self):
"""Return the name of the sensor."""
return self.data.name
@property
def is_on(self):
"""Return true if the binary sensor is on."""
return self.data.status == 'active'
@property
def device_class(self):
"""Return the class of this sensor."""
return DEFAULT_SENSOR_CLASS
@property
def device_state_attributes(self):
"""Return the state attributes of the Digital Ocean droplet."""
return {
ATTR_CREATED_AT: self.data.created_at,
ATTR_DROPLET_ID: self.data.id,
ATTR_DROPLET_NAME: self.data.name,
ATTR_FEATURES: self.data.features,
ATTR_IPV4_ADDRESS: self.data.ip_address,
ATTR_IPV6_ADDRESS: self.data.ip_v6_address,
ATTR_MEMORY: self.data.memory,
ATTR_REGION: self.data.region['name'],
ATTR_VCPUS: self.data.vcpus,
}
def update(self):
"""Update state of sensor."""
self._digital_ocean.update()
for droplet in self._digital_ocean.data:
if droplet.id == self._droplet_id:
self.data = droplet

View File

@@ -38,7 +38,7 @@ class EcobeeBinarySensor(BinarySensorDevice):
self.sensor_name = sensor_name
self.index = sensor_index
self._state = None
self._sensor_class = 'occupancy'
self._device_class = 'occupancy'
self.update()
@property
@@ -57,9 +57,9 @@ class EcobeeBinarySensor(BinarySensorDevice):
return "binary_sensor_ecobee_{}_{}".format(self._name, self.index)
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
return self._sensor_class
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return self._device_class
def update(self):
"""Get the latest state of the sensor."""

View File

@@ -9,10 +9,12 @@ import logging
import voluptuous as vol
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA, SENSOR_CLASSES_SCHEMA)
BinarySensorDevice, PLATFORM_SCHEMA, DEVICE_CLASSES_SCHEMA)
from homeassistant.components import enocean
from homeassistant.const import (CONF_NAME, CONF_ID, CONF_SENSOR_CLASS)
from homeassistant.const import (
CONF_NAME, CONF_ID, CONF_SENSOR_CLASS, CONF_DEVICE_CLASS)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
_LOGGER = logging.getLogger(__name__)
@@ -20,9 +22,10 @@ DEPENDENCIES = ['enocean']
DEFAULT_NAME = 'EnOcean binary sensor'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_ID): cv.string,
vol.Required(CONF_ID): vol.All(cv.ensure_list, [vol.Coerce(int)]),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_SENSOR_CLASS, default=None): SENSOR_CLASSES_SCHEMA,
vol.Optional(CONF_SENSOR_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
@@ -30,15 +33,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Binary Sensor platform fo EnOcean."""
dev_id = config.get(CONF_ID)
devname = config.get(CONF_NAME)
sensor_class = config.get(CONF_SENSOR_CLASS)
device_class = get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
add_devices([EnOceanBinarySensor(dev_id, devname, sensor_class)])
add_devices([EnOceanBinarySensor(dev_id, devname, device_class)])
class EnOceanBinarySensor(enocean.EnOceanDevice, BinarySensorDevice):
"""Representation of EnOcean binary sensors such as wall switches."""
def __init__(self, dev_id, devname, sensor_class):
def __init__(self, dev_id, devname, device_class):
"""Initialize the EnOcean binary sensor."""
enocean.EnOceanDevice.__init__(self)
self.stype = "listener"
@@ -46,7 +49,7 @@ class EnOceanBinarySensor(enocean.EnOceanDevice, BinarySensorDevice):
self.which = -1
self.onoff = -1
self.devname = devname
self._sensor_class = sensor_class
self._device_class = device_class
@property
def name(self):
@@ -54,9 +57,9 @@ class EnOceanBinarySensor(enocean.EnOceanDevice, BinarySensorDevice):
return self.devname
@property
def sensor_class(self):
def device_class(self):
"""Return the class of this sensor."""
return self._sensor_class
return self._device_class
def value_changed(self, value, value2):
"""Fire an event with the data that have changed.

View File

@@ -4,49 +4,56 @@ Support for Envisalink zone states- represented as binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.envisalink/
"""
import asyncio
import logging
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.envisalink import (EVL_CONTROLLER,
ZONE_SCHEMA,
CONF_ZONENAME,
CONF_ZONETYPE,
EnvisalinkDevice,
SIGNAL_ZONE_UPDATE)
from homeassistant.components.envisalink import (
DATA_EVL, ZONE_SCHEMA, CONF_ZONENAME, CONF_ZONETYPE, EnvisalinkDevice,
SIGNAL_ZONE_UPDATE)
from homeassistant.const import ATTR_LAST_TRIP_TIME
DEPENDENCIES = ['envisalink']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup Envisalink binary sensor devices."""
_configured_zones = discovery_info['zones']
for zone_num in _configured_zones:
_device_config_data = ZONE_SCHEMA(_configured_zones[zone_num])
_device = EnvisalinkBinarySensor(
configured_zones = discovery_info['zones']
devices = []
for zone_num in configured_zones:
device_config_data = ZONE_SCHEMA(configured_zones[zone_num])
device = EnvisalinkBinarySensor(
hass,
zone_num,
_device_config_data[CONF_ZONENAME],
_device_config_data[CONF_ZONETYPE],
EVL_CONTROLLER.alarm_state['zone'][zone_num],
EVL_CONTROLLER)
add_devices_callback([_device])
device_config_data[CONF_ZONENAME],
device_config_data[CONF_ZONETYPE],
hass.data[DATA_EVL].alarm_state['zone'][zone_num],
hass.data[DATA_EVL]
)
devices.append(device)
yield from async_add_devices(devices)
class EnvisalinkBinarySensor(EnvisalinkDevice, BinarySensorDevice):
"""Representation of an Envisalink binary sensor."""
# pylint: disable=too-many-arguments
def __init__(self, zone_number, zone_name, zone_type, info, controller):
def __init__(self, hass, zone_number, zone_name, zone_type, info,
controller):
"""Initialize the binary_sensor."""
from pydispatch import dispatcher
self._zone_type = zone_type
self._zone_number = zone_number
_LOGGER.debug('Setting up zone: ' + zone_name)
EnvisalinkDevice.__init__(self, zone_name, info, controller)
dispatcher.connect(self._update_callback,
signal=SIGNAL_ZONE_UPDATE,
sender=dispatcher.Any)
super().__init__(zone_name, info, controller)
async_dispatcher_connect(
hass, SIGNAL_ZONE_UPDATE, self._update_callback)
@property
def device_state_attributes(self):
@@ -61,11 +68,12 @@ class EnvisalinkBinarySensor(EnvisalinkDevice, BinarySensorDevice):
return self._info['status']['open']
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return self._zone_type
@callback
def _update_callback(self, zone):
"""Update the zone's state, if needed."""
if zone is None or int(zone) == self._zone_number:
self.hass.async_add_job(self.update_ha_state)
self.hass.async_add_job(self.async_update_ha_state())

View File

@@ -1,224 +0,0 @@
"""
Provides a binary sensor which is a collection of ffmpeg tools.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.ffmpeg/
"""
import logging
from os import path
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA, DOMAIN)
from homeassistant.components.ffmpeg import (
get_binary, run_test, CONF_INPUT, CONF_OUTPUT, CONF_EXTRA_ARGUMENTS)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (EVENT_HOMEASSISTANT_STOP, CONF_NAME,
ATTR_ENTITY_ID)
DEPENDENCIES = ['ffmpeg']
_LOGGER = logging.getLogger(__name__)
SERVICE_RESTART = 'ffmpeg_restart'
FFMPEG_SENSOR_NOISE = 'noise'
FFMPEG_SENSOR_MOTION = 'motion'
MAP_FFMPEG_BIN = [
FFMPEG_SENSOR_NOISE,
FFMPEG_SENSOR_MOTION
]
CONF_TOOL = 'tool'
CONF_PEAK = 'peak'
CONF_DURATION = 'duration'
CONF_RESET = 'reset'
CONF_CHANGES = 'changes'
CONF_REPEAT = 'repeat'
CONF_REPEAT_TIME = 'repeat_time'
DEFAULT_NAME = 'FFmpeg'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_TOOL): vol.In(MAP_FFMPEG_BIN),
vol.Required(CONF_INPUT): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_EXTRA_ARGUMENTS): cv.string,
vol.Optional(CONF_OUTPUT): cv.string,
vol.Optional(CONF_PEAK, default=-30): vol.Coerce(int),
vol.Optional(CONF_DURATION, default=1):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Optional(CONF_RESET, default=10):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Optional(CONF_CHANGES, default=10):
vol.All(vol.Coerce(float), vol.Range(min=0, max=99)),
vol.Optional(CONF_REPEAT, default=0):
vol.All(vol.Coerce(int), vol.Range(min=0)),
vol.Optional(CONF_REPEAT_TIME, default=0):
vol.All(vol.Coerce(int), vol.Range(min=0)),
})
SERVICE_RESTART_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
})
def restart(hass, entity_id=None):
"""Restart a ffmpeg process on entity."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {}
hass.services.call(DOMAIN, SERVICE_RESTART, data)
# list of all ffmpeg sensors
DEVICES = []
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Create the binary sensor."""
from haffmpeg import SensorNoise, SensorMotion
# check source
if not run_test(config.get(CONF_INPUT)):
return
# generate sensor object
if config.get(CONF_TOOL) == FFMPEG_SENSOR_NOISE:
entity = FFmpegNoise(SensorNoise, config)
else:
entity = FFmpegMotion(SensorMotion, config)
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, entity.shutdown_ffmpeg)
# add to system
add_entities([entity])
DEVICES.append(entity)
# exists service?
if hass.services.has_service(DOMAIN, SERVICE_RESTART):
return
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
# register service
def _service_handle_restart(service):
"""Handle service binary_sensor.ffmpeg_restart."""
entity_ids = service.data.get('entity_id')
if entity_ids:
_devices = [device for device in DEVICES
if device.entity_id in entity_ids]
else:
_devices = DEVICES
for device in _devices:
device.restart_ffmpeg()
hass.services.register(DOMAIN, SERVICE_RESTART,
_service_handle_restart,
descriptions.get(SERVICE_RESTART),
schema=SERVICE_RESTART_SCHEMA)
class FFmpegBinarySensor(BinarySensorDevice):
"""A binary sensor which use ffmpeg for noise detection."""
def __init__(self, ffobj, config):
"""Constructor for binary sensor noise detection."""
self._state = False
self._config = config
self._name = config.get(CONF_NAME)
self._ffmpeg = ffobj(get_binary(), self._callback)
self._start_ffmpeg(config)
def _callback(self, state):
"""HA-FFmpeg callback for noise detection."""
self._state = state
self.update_ha_state()
def _start_ffmpeg(self, config):
"""Start a FFmpeg instance."""
raise NotImplementedError
def shutdown_ffmpeg(self, event):
"""For STOP event to shutdown ffmpeg."""
self._ffmpeg.close()
def restart_ffmpeg(self):
"""Restart ffmpeg with new config."""
self._ffmpeg.close()
self._start_ffmpeg(self._config)
@property
def is_on(self):
"""True if the binary sensor is on."""
return self._state
@property
def should_poll(self):
"""Return True if entity has to be polled for state."""
return False
@property
def name(self):
"""Return the name of the entity."""
return self._name
@property
def available(self):
"""Return True if entity is available."""
return self._ffmpeg.is_running
class FFmpegNoise(FFmpegBinarySensor):
"""A binary sensor which use ffmpeg for noise detection."""
def _start_ffmpeg(self, config):
"""Start a FFmpeg instance."""
# init config
self._ffmpeg.set_options(
time_duration=config.get(CONF_DURATION),
time_reset=config.get(CONF_RESET),
peak=config.get(CONF_PEAK),
)
# run
self._ffmpeg.open_sensor(
input_source=config.get(CONF_INPUT),
output_dest=config.get(CONF_OUTPUT),
extra_cmd=config.get(CONF_EXTRA_ARGUMENTS),
)
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
return "sound"
class FFmpegMotion(FFmpegBinarySensor):
"""A binary sensor which use ffmpeg for noise detection."""
def _start_ffmpeg(self, config):
"""Start a FFmpeg instance."""
# init config
self._ffmpeg.set_options(
time_reset=config.get(CONF_RESET),
time_repeat=config.get(CONF_REPEAT_TIME),
repeat=config.get(CONF_REPEAT),
changes=config.get(CONF_CHANGES),
)
# run
self._ffmpeg.open_sensor(
input_source=config.get(CONF_INPUT),
extra_cmd=config.get(CONF_EXTRA_ARGUMENTS),
)
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
return "motion"

View File

@@ -0,0 +1,127 @@
"""
Provides a binary sensor which is a collection of ffmpeg tools.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.ffmpeg_motion/
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.components.ffmpeg import (
FFmpegBase, DATA_FFMPEG, CONF_INPUT, CONF_EXTRA_ARGUMENTS,
CONF_INITIAL_STATE)
from homeassistant.const import CONF_NAME
DEPENDENCIES = ['ffmpeg']
_LOGGER = logging.getLogger(__name__)
CONF_RESET = 'reset'
CONF_CHANGES = 'changes'
CONF_REPEAT = 'repeat'
CONF_REPEAT_TIME = 'repeat_time'
DEFAULT_NAME = 'FFmpeg Motion'
DEFAULT_INIT_STATE = True
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_INPUT): cv.string,
vol.Optional(CONF_INITIAL_STATE, default=DEFAULT_INIT_STATE): cv.boolean,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_EXTRA_ARGUMENTS): cv.string,
vol.Optional(CONF_RESET, default=10):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Optional(CONF_CHANGES, default=10):
vol.All(vol.Coerce(float), vol.Range(min=0, max=99)),
vol.Inclusive(CONF_REPEAT, 'repeat'):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Inclusive(CONF_REPEAT_TIME, 'repeat'):
vol.All(vol.Coerce(int), vol.Range(min=1)),
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Create the binary sensor."""
manager = hass.data[DATA_FFMPEG]
# check source
if not manager.async_run_test(config.get(CONF_INPUT)):
return
# generate sensor object
entity = FFmpegMotion(hass, manager, config)
# add to system
manager.async_register_device(entity)
yield from async_add_devices([entity])
class FFmpegBinarySensor(FFmpegBase, BinarySensorDevice):
"""A binary sensor which use ffmpeg for noise detection."""
def __init__(self, hass, config):
"""Constructor for binary sensor noise detection."""
super().__init__(config.get(CONF_INITIAL_STATE))
self._state = False
self._config = config
self._name = config.get(CONF_NAME)
@callback
def _async_callback(self, state):
"""HA-FFmpeg callback for noise detection."""
self._state = state
self.hass.async_add_job(self.async_update_ha_state())
@property
def is_on(self):
"""True if the binary sensor is on."""
return self._state
@property
def name(self):
"""Return the name of the entity."""
return self._name
class FFmpegMotion(FFmpegBinarySensor):
"""A binary sensor which use ffmpeg for noise detection."""
def __init__(self, hass, manager, config):
"""Initialize ffmpeg motion binary sensor."""
from haffmpeg import SensorMotion
super().__init__(hass, config)
self.ffmpeg = SensorMotion(
manager.binary, hass.loop, self._async_callback)
def async_start_ffmpeg(self):
"""Start a FFmpeg instance.
This method must be run in the event loop and returns a coroutine.
"""
# init config
self.ffmpeg.set_options(
time_reset=self._config.get(CONF_RESET),
time_repeat=self._config.get(CONF_REPEAT_TIME, 0),
repeat=self._config.get(CONF_REPEAT, 0),
changes=self._config.get(CONF_CHANGES),
)
# run
return self.ffmpeg.open_sensor(
input_source=self._config.get(CONF_INPUT),
extra_cmd=self._config.get(CONF_EXTRA_ARGUMENTS),
)
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return "motion"

View File

@@ -0,0 +1,96 @@
"""
Provides a binary sensor which is a collection of ffmpeg tools.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.ffmpeg_noise/
"""
import asyncio
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import PLATFORM_SCHEMA
from homeassistant.components.binary_sensor.ffmpeg_motion import (
FFmpegBinarySensor)
from homeassistant.components.ffmpeg import (
DATA_FFMPEG, CONF_INPUT, CONF_OUTPUT, CONF_EXTRA_ARGUMENTS,
CONF_INITIAL_STATE)
from homeassistant.const import CONF_NAME
DEPENDENCIES = ['ffmpeg']
_LOGGER = logging.getLogger(__name__)
CONF_PEAK = 'peak'
CONF_DURATION = 'duration'
CONF_RESET = 'reset'
DEFAULT_NAME = 'FFmpeg Noise'
DEFAULT_INIT_STATE = True
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_INPUT): cv.string,
vol.Optional(CONF_INITIAL_STATE, default=DEFAULT_INIT_STATE): cv.boolean,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_EXTRA_ARGUMENTS): cv.string,
vol.Optional(CONF_OUTPUT): cv.string,
vol.Optional(CONF_PEAK, default=-30): vol.Coerce(int),
vol.Optional(CONF_DURATION, default=1):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Optional(CONF_RESET, default=10):
vol.All(vol.Coerce(int), vol.Range(min=1)),
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Create the binary sensor."""
manager = hass.data[DATA_FFMPEG]
# check source
if not manager.async_run_test(config.get(CONF_INPUT)):
return
# generate sensor object
entity = FFmpegNoise(hass, manager, config)
# add to system
manager.async_register_device(entity)
yield from async_add_devices([entity])
class FFmpegNoise(FFmpegBinarySensor):
"""A binary sensor which use ffmpeg for noise detection."""
def __init__(self, hass, manager, config):
"""Initialize ffmpeg noise binary sensor."""
from haffmpeg import SensorNoise
super().__init__(hass, config)
self.ffmpeg = SensorNoise(
manager.binary, hass.loop, self._async_callback)
def async_start_ffmpeg(self):
"""Start a FFmpeg instance.
This method must be run in the event loop and returns a coroutine.
"""
# init config
self.ffmpeg.set_options(
time_duration=self._config.get(CONF_DURATION),
time_reset=self._config.get(CONF_RESET),
peak=self._config.get(CONF_PEAK),
)
# run
return self.ffmpeg.open_sensor(
input_source=self._config.get(CONF_INPUT),
output_dest=self._config.get(CONF_OUTPUT),
extra_cmd=self._config.get(CONF_EXTRA_ARGUMENTS),
)
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return "sound"

View File

@@ -0,0 +1,238 @@
"""Contains functionality to use flic buttons as a binary sensor."""
import logging
import threading
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.const import (
CONF_HOST, CONF_PORT, CONF_DISCOVERY, CONF_TIMEOUT,
EVENT_HOMEASSISTANT_STOP)
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
REQUIREMENTS = ['https://github.com/soldag/pyflic/archive/0.4.zip#pyflic==0.4']
_LOGGER = logging.getLogger(__name__)
DEFAULT_TIMEOUT = 3
CLICK_TYPE_SINGLE = "single"
CLICK_TYPE_DOUBLE = "double"
CLICK_TYPE_HOLD = "hold"
CLICK_TYPES = [CLICK_TYPE_SINGLE, CLICK_TYPE_DOUBLE, CLICK_TYPE_HOLD]
CONF_IGNORED_CLICK_TYPES = "ignored_click_types"
EVENT_NAME = "flic_click"
EVENT_DATA_NAME = "button_name"
EVENT_DATA_ADDRESS = "button_address"
EVENT_DATA_TYPE = "click_type"
EVENT_DATA_QUEUED_TIME = "queued_time"
# Validation of the user's configuration
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_HOST, default='localhost'): cv.string,
vol.Optional(CONF_PORT, default=5551): cv.port,
vol.Optional(CONF_DISCOVERY, default=True): cv.boolean,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
vol.Optional(CONF_IGNORED_CLICK_TYPES): vol.All(cv.ensure_list,
[vol.In(CLICK_TYPES)])
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Setup the flic platform."""
import pyflic
# Initialize flic client responsible for
# connecting to buttons and retrieving events
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
discovery = config.get(CONF_DISCOVERY)
try:
client = pyflic.FlicClient(host, port)
except ConnectionRefusedError:
_LOGGER.error("Failed to connect to flic server.")
return
def new_button_callback(address):
"""Setup newly verified button as device in home assistant."""
setup_button(hass, config, add_entities, client, address)
client.on_new_verified_button = new_button_callback
if discovery:
start_scanning(config, add_entities, client)
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP,
lambda event: client.close())
# Start the pyflic event handling thread
threading.Thread(target=client.handle_events).start()
def get_info_callback(items):
"""Add entities for already verified buttons."""
addresses = items["bd_addr_of_verified_buttons"] or []
for address in addresses:
setup_button(hass, config, add_entities, client, address)
# Get addresses of already verified buttons
client.get_info(get_info_callback)
def start_scanning(config, add_entities, client):
"""Start a new flic client for scanning & connceting to new buttons."""
import pyflic
scan_wizard = pyflic.ScanWizard()
def scan_completed_callback(scan_wizard, result, address, name):
"""Restart scan wizard to constantly check for new buttons."""
if result == pyflic.ScanWizardResult.WizardSuccess:
_LOGGER.info("Found new button (%s)", address)
elif result != pyflic.ScanWizardResult.WizardFailedTimeout:
_LOGGER.warning("Failed to connect to button (%s). Reason: %s",
address, result)
# Restart scan wizard
start_scanning(config, add_entities, client)
scan_wizard.on_completed = scan_completed_callback
client.add_scan_wizard(scan_wizard)
def setup_button(hass, config, add_entities, client, address):
"""Setup single button device."""
timeout = config.get(CONF_TIMEOUT)
ignored_click_types = config.get(CONF_IGNORED_CLICK_TYPES)
button = FlicButton(hass, client, address, timeout, ignored_click_types)
_LOGGER.info("Connected to button (%s)", address)
add_entities([button])
class FlicButton(BinarySensorDevice):
"""Representation of a flic button."""
def __init__(self, hass, client, address, timeout, ignored_click_types):
"""Initialize the flic button."""
import pyflic
self._hass = hass
self._address = address
self._timeout = timeout
self._is_down = False
self._ignored_click_types = ignored_click_types or []
self._hass_click_types = {
pyflic.ClickType.ButtonClick: CLICK_TYPE_SINGLE,
pyflic.ClickType.ButtonSingleClick: CLICK_TYPE_SINGLE,
pyflic.ClickType.ButtonDoubleClick: CLICK_TYPE_DOUBLE,
pyflic.ClickType.ButtonHold: CLICK_TYPE_HOLD,
}
self._channel = self._create_channel()
client.add_connection_channel(self._channel)
def _create_channel(self):
"""Create a new connection channel to the button."""
import pyflic
channel = pyflic.ButtonConnectionChannel(self._address)
channel.on_button_up_or_down = self._on_up_down
# If all types of clicks should be ignored, skip registering callbacks
if set(self._ignored_click_types) == set(CLICK_TYPES):
return channel
if CLICK_TYPE_DOUBLE in self._ignored_click_types:
# Listen to all but double click type events
channel.on_button_click_or_hold = self._on_click
elif CLICK_TYPE_HOLD in self._ignored_click_types:
# Listen to all but hold click type events
channel.on_button_single_or_double_click = self._on_click
else:
# Listen to all click type events
channel.on_button_single_or_double_click_or_hold = self._on_click
return channel
@property
def name(self):
"""Return the name of the device."""
return "flic_%s" % self.address.replace(":", "")
@property
def address(self):
"""Return the bluetooth address of the device."""
return self._address
@property
def is_on(self):
"""Return true if sensor is on."""
return self._is_down
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def device_state_attributes(self):
"""Return device specific state attributes."""
return {"address": self.address}
def _queued_event_check(self, click_type, time_diff):
"""Generate a log message and returns true if timeout exceeded."""
time_string = "{:d} {}".format(
time_diff, "second" if time_diff == 1 else "seconds")
if time_diff > self._timeout:
_LOGGER.warning(
"Queued %s dropped for %s. Time in queue was %s.",
click_type, self.address, time_string)
return True
else:
_LOGGER.info(
"Queued %s allowed for %s. Time in queue was %s.",
click_type, self.address, time_string)
return False
def _on_up_down(self, channel, click_type, was_queued, time_diff):
"""Update device state, if event was not queued."""
import pyflic
if was_queued and self._queued_event_check(click_type, time_diff):
return
self._is_down = click_type == pyflic.ClickType.ButtonDown
self.schedule_update_ha_state()
def _on_click(self, channel, click_type, was_queued, time_diff):
"""Fire click event, if event was not queued."""
# Return if click event was queued beyond allowed timeout
if was_queued and self._queued_event_check(click_type, time_diff):
return
# Return if click event is in ignored click types
hass_click_type = self._hass_click_types[click_type]
if hass_click_type in self._ignored_click_types:
return
self._hass.bus.fire(EVENT_NAME, {
EVENT_DATA_NAME: self.name,
EVENT_DATA_ADDRESS: self.address,
EVENT_DATA_QUEUED_TIME: time_diff,
EVENT_DATA_TYPE: hass_click_type
})
def _connection_status_changed(self, channel,
connection_status, disconnect_reason):
"""Remove device, if button disconnects."""
import pyflic
if connection_status == pyflic.ConnectionStatus.Disconnected:
_LOGGER.info("Button (%s) disconnected. Reason: %s",
self.address, disconnect_reason)
self.remove()

View File

@@ -0,0 +1,262 @@
"""
Support for Hikvision event stream events represented as binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.hikvision/
"""
import logging
from datetime import timedelta
import voluptuous as vol
from homeassistant.helpers.event import track_point_in_utc_time
from homeassistant.util.dt import utcnow
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
import homeassistant.helpers.config_validation as cv
from homeassistant.const import (
CONF_HOST, CONF_PORT, CONF_NAME, CONF_USERNAME, CONF_PASSWORD,
CONF_SSL, EVENT_HOMEASSISTANT_STOP, ATTR_LAST_TRIP_TIME, CONF_CUSTOMIZE)
REQUIREMENTS = ['pyhik==0.0.7', 'pydispatcher==2.0.5']
_LOGGER = logging.getLogger(__name__)
CONF_IGNORED = 'ignored'
CONF_DELAY = 'delay'
DEFAULT_PORT = 80
DEFAULT_IGNORED = False
DEFAULT_DELAY = 0
ATTR_DELAY = 'delay'
DEVICE_CLASS_MAP = {
'Motion': 'motion',
'Line Crossing': 'motion',
'IO Trigger': None,
'Field Detection': 'motion',
'Video Loss': None,
'Tamper Detection': 'motion',
'Shelter Alarm': None,
'Disk Full': None,
'Disk Error': None,
'Net Interface Broken': 'connectivity',
'IP Conflict': 'connectivity',
'Illegal Access': None,
'Video Mismatch': None,
'Bad Video': None,
'PIR Alarm': 'motion',
'Face Detection': 'motion',
}
CUSTOMIZE_SCHEMA = vol.Schema({
vol.Optional(CONF_IGNORED, default=DEFAULT_IGNORED): cv.boolean,
vol.Optional(CONF_DELAY, default=DEFAULT_DELAY): cv.positive_int
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=None): cv.string,
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_SSL, default=False): cv.boolean,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_CUSTOMIZE, default={}):
vol.Schema({cv.string: CUSTOMIZE_SCHEMA}),
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Setup Hikvision binary sensor devices."""
name = config.get(CONF_NAME)
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
customize = config.get(CONF_CUSTOMIZE)
if config.get(CONF_SSL):
protocol = "https"
else:
protocol = "http"
url = '{}://{}'.format(protocol, host)
data = HikvisionData(hass, url, port, name, username, password)
if data.sensors is None:
_LOGGER.error('Hikvision event stream has no data, unable to setup.')
return False
entities = []
for sensor in data.sensors:
# Build sensor name, then parse customize config.
sensor_name = sensor.replace(' ', '_')
custom = customize.get(sensor_name.lower(), {})
ignore = custom.get(CONF_IGNORED)
delay = custom.get(CONF_DELAY)
_LOGGER.debug('Entity: %s - %s, Options - Ignore: %s, Delay: %s',
data.name, sensor_name, ignore, delay)
if not ignore:
entities.append(HikvisionBinarySensor(hass, sensor, data, delay))
add_entities(entities)
class HikvisionData(object):
"""Hikvision camera event stream object."""
def __init__(self, hass, url, port, name, username, password):
"""Initialize the data oject."""
from pyhik.hikvision import HikCamera
self._url = url
self._port = port
self._name = name
self._username = username
self._password = password
# Establish camera
self._cam = HikCamera(self._url, self._port,
self._username, self._password)
if self._name is None:
self._name = self._cam.get_name
# Start event stream
self._cam.start_stream()
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self.stop_hik)
def stop_hik(self, event):
"""Shutdown Hikvision subscriptions and subscription thread on exit."""
self._cam.disconnect()
@property
def sensors(self):
"""Return list of available sensors and their states."""
return self._cam.current_event_states
@property
def cam_id(self):
"""Return camera id."""
return self._cam.get_id
@property
def name(self):
"""Return camera name."""
return self._name
class HikvisionBinarySensor(BinarySensorDevice):
"""Representation of a Hikvision binary sensor."""
def __init__(self, hass, sensor, cam, delay):
"""Initialize the binary_sensor."""
from pydispatch import dispatcher
self._hass = hass
self._cam = cam
self._name = self._cam.name + ' ' + sensor
self._id = self._cam.cam_id + '.' + sensor
self._sensor = sensor
if delay is None:
self._delay = 0
else:
self._delay = delay
self._timer = None
# Form signal for dispatcher
signal = 'ValueChanged.{}'.format(self._cam.cam_id)
dispatcher.connect(self._update_callback,
signal=signal,
sender=self._sensor)
def _sensor_state(self):
"""Extract sensor state."""
return self._cam.sensors[self._sensor][0]
def _sensor_last_update(self):
"""Extract sensor last update time."""
return self._cam.sensors[self._sensor][3]
@property
def name(self):
"""Return the name of the Hikvision sensor."""
return self._name
@property
def unique_id(self):
"""Return an unique ID."""
return '{}.{}'.format(self.__class__, self._id)
@property
def is_on(self):
"""Return true if sensor is on."""
return self._sensor_state()
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
try:
return DEVICE_CLASS_MAP[self._sensor]
except KeyError:
# Sensor must be unknown to us, add as generic
return None
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def device_state_attributes(self):
"""Return the state attributes."""
attr = {}
attr[ATTR_LAST_TRIP_TIME] = self._sensor_last_update()
if self._delay != 0:
attr[ATTR_DELAY] = self._delay
return attr
def _update_callback(self, signal, sender):
"""Update the sensor's state, if needed."""
_LOGGER.debug('Dispatcher callback, signal: %s, sender: %s',
signal, sender)
if sender is not self._sensor:
return
if self._delay > 0 and not self.is_on:
# Set timer to wait until updating the state
def _delay_update(now):
"""Timer callback for sensor update."""
_LOGGER.debug('%s Called delayed (%ssec) update.',
self._name, self._delay)
self.schedule_update_ha_state()
self._timer = None
if self._timer is not None:
self._timer()
self._timer = None
self._timer = track_point_in_utc_time(
self._hass, _delay_update,
utcnow() + timedelta(seconds=self._delay))
elif self._delay > 0 and self.is_on:
# For delayed sensors kill any callbacks on true events and update
if self._timer is not None:
self._timer()
self._timer = None
self.schedule_update_ha_state()
else:
self.schedule_update_ha_state()

View File

@@ -7,7 +7,7 @@ https://home-assistant.io/components/binary_sensor.homematic/
import logging
from homeassistant.const import STATE_UNKNOWN
from homeassistant.components.binary_sensor import BinarySensorDevice
import homeassistant.components.homematic as homematic
from homeassistant.components.homematic import HMDevice, ATTR_DISCOVER_DEVICES
_LOGGER = logging.getLogger(__name__)
@@ -16,6 +16,8 @@ DEPENDENCIES = ['homematic']
SENSOR_TYPES_CLASS = {
"Remote": None,
"ShutterContact": "opening",
"MaxShutterContact": "opening",
"IPShutterContact": "opening",
"Smoke": "smoke",
"SmokeV2": "smoke",
"Motion": "motion",
@@ -26,19 +28,21 @@ SENSOR_TYPES_CLASS = {
}
def setup_platform(hass, config, add_callback_devices, discovery_info=None):
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Homematic binary sensor platform."""
if discovery_info is None:
return
return homematic.setup_hmdevice_discovery_helper(
HMBinarySensor,
discovery_info,
add_callback_devices
)
devices = []
for config in discovery_info[ATTR_DISCOVER_DEVICES]:
new_device = HMBinarySensor(hass, config)
new_device.link_homematic()
devices.append(new_device)
add_devices(devices)
class HMBinarySensor(homematic.HMDevice, BinarySensorDevice):
class HMBinarySensor(HMDevice, BinarySensorDevice):
"""Representation of a binary Homematic device."""
@property
@@ -49,11 +53,8 @@ class HMBinarySensor(homematic.HMDevice, BinarySensorDevice):
return bool(self._hm_get_state())
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
if not self.available:
return None
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
# If state is MOTION (RemoteMotion works only)
if self._state == "MOTION":
return "motion"

View File

@@ -0,0 +1,87 @@
"""
Support for INSTEON dimmers via PowerLinc Modem.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/insteon_plm/
"""
import logging
import asyncio
from homeassistant.core import callback
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.loader import get_component
DEPENDENCIES = ['insteon_plm']
_LOGGER = logging.getLogger(__name__)
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the INSTEON PLM device class for the hass platform."""
plm = hass.data['insteon_plm']
device_list = []
for device in discovery_info:
name = device.get('address')
address = device.get('address_hex')
_LOGGER.info('Registered %s with binary_sensor platform.', name)
device_list.append(
InsteonPLMBinarySensorDevice(hass, plm, address, name)
)
hass.async_add_job(async_add_devices(device_list))
class InsteonPLMBinarySensorDevice(BinarySensorDevice):
"""A Class for an Insteon device."""
def __init__(self, hass, plm, address, name):
"""Initialize the binarysensor."""
self._hass = hass
self._plm = plm.protocol
self._address = address
self._name = name
self._plm.add_update_callback(
self.async_binarysensor_update, {'address': self._address})
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def address(self):
"""Return the the address of the node."""
return self._address
@property
def name(self):
"""Return the the name of the node."""
return self._name
@property
def is_on(self):
"""Return the boolean response if the node is on."""
sensorstate = self._plm.get_device_attr(self._address, 'sensorstate')
_LOGGER.info('sensor state for %s is %s', self._address, sensorstate)
return bool(sensorstate)
@property
def device_state_attributes(self):
"""Provide attributes for display on device card."""
insteon_plm = get_component('insteon_plm')
return insteon_plm.common_attributes(self)
def get_attr(self, key):
"""Return specified attribute for this device."""
return self._plm.get_device_attr(self.address, key)
@callback
def async_binarysensor_update(self, message):
"""Receive notification from transport that new data exists."""
_LOGGER.info('Received update calback from PLM for %s', self._address)
self._hass.async_add_job(self.async_update_ha_state())

View File

@@ -0,0 +1,131 @@
"""
Support for International Space Station data sensor.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.iss/
"""
import logging
from datetime import timedelta
import requests
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.const import (CONF_NAME, ATTR_LONGITUDE, ATTR_LATITUDE)
from homeassistant.util import Throttle
REQUIREMENTS = ['pyiss==1.0.1']
_LOGGER = logging.getLogger(__name__)
ATTR_ISS_NEXT_RISE = 'next_rise'
ATTR_ISS_NUMBER_PEOPLE_SPACE = 'number_of_people_in_space'
CONF_SHOW_ON_MAP = 'show_on_map'
DEFAULT_NAME = 'ISS'
DEFAULT_DEVICE_CLASS = 'visible'
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_SHOW_ON_MAP, default=False): cv.boolean,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the ISS sensor."""
if None in (hass.config.latitude, hass.config.longitude):
_LOGGER.error("Latitude or longitude not set in Home Assistant config")
return False
try:
iss_data = IssData(hass.config.latitude, hass.config.longitude)
iss_data.update()
except requests.exceptions.HTTPError as error:
_LOGGER.error(error)
return False
name = config.get(CONF_NAME)
show_on_map = config.get(CONF_SHOW_ON_MAP)
add_devices([IssBinarySensor(iss_data, name, show_on_map)], True)
class IssBinarySensor(BinarySensorDevice):
"""Implementation of the ISS binary sensor."""
def __init__(self, iss_data, name, show):
"""Initialize the sensor."""
self.iss_data = iss_data
self._state = None
self._name = name
self._show_on_map = show
self.update()
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def is_on(self):
"""Return true if the binary sensor is on."""
return self.iss_data.is_above if self.iss_data else False
@property
def device_class(self):
"""Return the class of this sensor."""
return DEFAULT_DEVICE_CLASS
@property
def device_state_attributes(self):
"""Return the state attributes."""
if self.iss_data:
attrs = {
ATTR_ISS_NUMBER_PEOPLE_SPACE:
self.iss_data.number_of_people_in_space,
ATTR_ISS_NEXT_RISE: self.iss_data.next_rise,
}
if self._show_on_map:
attrs[ATTR_LONGITUDE] = self.iss_data.position.get('longitude')
attrs[ATTR_LATITUDE] = self.iss_data.position.get('latitude')
else:
attrs['long'] = self.iss_data.position.get('longitude')
attrs['lat'] = self.iss_data.position.get('latitude')
return attrs
def update(self):
"""Get the latest data from ISS API and updates the states."""
self.iss_data.update()
class IssData(object):
"""Get data from the ISS API."""
def __init__(self, latitude, longitude):
"""Initialize the data object."""
self.is_above = None
self.next_rise = None
self.number_of_people_in_space = None
self.position = None
self.latitude = latitude
self.longitude = longitude
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Get the latest data from the ISS API."""
import pyiss
try:
iss = pyiss.ISS()
self.is_above = iss.is_ISS_above(self.latitude, self.longitude)
self.next_rise = iss.next_rise(self.latitude, self.longitude)
self.number_of_people_in_space = iss.number_of_people_in_space()
self.position = iss.current_location()
except requests.exceptions.HTTPError as error:
_LOGGER.error(error)
return False

View File

@@ -4,18 +4,21 @@ Support for MQTT binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.mqtt/
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.components.mqtt as mqtt
from homeassistant.components.binary_sensor import (
BinarySensorDevice, SENSOR_CLASSES)
BinarySensorDevice, DEVICE_CLASSES_SCHEMA)
from homeassistant.const import (
CONF_NAME, CONF_VALUE_TEMPLATE, CONF_PAYLOAD_ON, CONF_PAYLOAD_OFF,
CONF_SENSOR_CLASS)
CONF_SENSOR_CLASS, CONF_DEVICE_CLASS)
from homeassistant.components.mqtt import (CONF_STATE_TOPIC, CONF_QOS)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
_LOGGER = logging.getLogger(__name__)
@@ -28,22 +31,25 @@ PLATFORM_SCHEMA = mqtt.MQTT_RO_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(CONF_SENSOR_CLASS, default=None):
vol.Any(vol.In(SENSOR_CLASSES), vol.SetTo(None)),
vol.Optional(CONF_SENSOR_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the MQTT binary sensor."""
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the MQTT binary sensor."""
if discovery_info is not None:
config = PLATFORM_SCHEMA(discovery_info)
value_template = config.get(CONF_VALUE_TEMPLATE)
if value_template is not None:
value_template.hass = hass
add_devices([MqttBinarySensor(
hass,
yield from async_add_devices([MqttBinarySensor(
config.get(CONF_NAME),
config.get(CONF_STATE_TOPIC),
config.get(CONF_SENSOR_CLASS),
get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS),
config.get(CONF_QOS),
config.get(CONF_PAYLOAD_ON),
config.get(CONF_PAYLOAD_OFF),
@@ -51,35 +57,41 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
)])
# pylint: disable=too-many-arguments, too-many-instance-attributes
class MqttBinarySensor(BinarySensorDevice):
"""Representation a binary sensor that is updated by MQTT."""
def __init__(self, hass, name, state_topic, sensor_class, qos, payload_on,
def __init__(self, name, state_topic, device_class, qos, payload_on,
payload_off, value_template):
"""Initialize the MQTT binary sensor."""
self._hass = hass
self._name = name
self._state = False
self._state_topic = state_topic
self._sensor_class = sensor_class
self._device_class = device_class
self._payload_on = payload_on
self._payload_off = payload_off
self._qos = qos
self._template = value_template
def async_added_to_hass(self):
"""Subscribe mqtt events.
This method must be run in the event loop and returns a coroutine.
"""
@callback
def message_received(topic, payload, qos):
"""A new MQTT message has been received."""
if value_template is not None:
payload = value_template.render_with_possible_json_value(
if self._template is not None:
payload = self._template.async_render_with_possible_json_value(
payload)
if payload == self._payload_on:
self._state = True
self.update_ha_state()
elif payload == self._payload_off:
self._state = False
self.update_ha_state()
mqtt.subscribe(hass, self._state_topic, message_received, self._qos)
self.hass.async_add_job(self.async_update_ha_state())
return mqtt.async_subscribe(
self.hass, self._state_topic, message_received, self._qos)
@property
def should_poll(self):
@@ -97,6 +109,6 @@ class MqttBinarySensor(BinarySensorDevice):
return self._state
@property
def sensor_class(self):
def device_class(self):
"""Return the class of this sensor."""
return self._sensor_class
return self._device_class

View File

@@ -7,7 +7,7 @@ https://home-assistant.io/components/binary_sensor.mysensors/
import logging
from homeassistant.components import mysensors
from homeassistant.components.binary_sensor import (SENSOR_CLASSES,
from homeassistant.components.binary_sensor import (DEVICE_CLASSES,
BinarySensorDevice)
from homeassistant.const import STATE_ON
@@ -22,7 +22,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if discovery_info is None:
return
for gateway in mysensors.GATEWAYS.values():
gateways = hass.data.get(mysensors.MYSENSORS_GATEWAYS)
if not gateways:
return
for gateway in gateways:
# Define the S_TYPES and V_TYPES that the platform should handle as
# states. Map them in a dict of lists.
pres = gateway.const.Presentation
@@ -43,7 +47,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
devices = {}
gateway.platform_callbacks.append(mysensors.pf_callback_factory(
map_sv_types, devices, add_devices, MySensorsBinarySensor))
map_sv_types, devices, MySensorsBinarySensor, add_devices))
class MySensorsBinarySensor(
@@ -58,8 +62,8 @@ class MySensorsBinarySensor(
return False
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
pres = self.gateway.const.Presentation
class_map = {
pres.S_DOOR: 'opening',
@@ -74,5 +78,5 @@ class MySensorsBinarySensor(
pres.S_VIBRATION: 'vibration',
pres.S_MOISTURE: 'moisture',
})
if class_map.get(self.child_type) in SENSOR_CLASSES:
if class_map.get(self.child_type) in DEVICE_CLASSES:
return class_map.get(self.child_type)

View File

@@ -4,40 +4,88 @@ Support for Nest Thermostat Binary Sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.nest/
"""
import voluptuous as vol
from itertools import chain
import logging
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.components.binary_sensor import (BinarySensorDevice)
from homeassistant.components.sensor.nest import NestSensor
from homeassistant.const import (CONF_SCAN_INTERVAL, CONF_MONITORED_CONDITIONS)
import homeassistant.components.nest as nest
import homeassistant.helpers.config_validation as cv
from homeassistant.const import CONF_MONITORED_CONDITIONS
from homeassistant.components.nest import DATA_NEST
DEPENDENCIES = ['nest']
BINARY_TYPES = ['fan',
'hvac_ac_state',
'hvac_aux_heater_state',
'hvac_heater_state',
'hvac_heat_x2_state',
'hvac_heat_x3_state',
'hvac_alt_heat_state',
'hvac_alt_heat_x2_state',
'hvac_emer_heat_state',
'online']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_SCAN_INTERVAL):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Required(CONF_MONITORED_CONDITIONS):
vol.All(cv.ensure_list, [vol.In(BINARY_TYPES)]),
})
BINARY_TYPES = ['online']
CLIMATE_BINARY_TYPES = ['fan',
'is_using_emergency_heat',
'is_locked',
'has_leaf']
CAMERA_BINARY_TYPES = [
'motion_detected',
'sound_detected',
'person_detected']
_BINARY_TYPES_DEPRECATED = [
'hvac_ac_state',
'hvac_aux_heater_state',
'hvac_heater_state',
'hvac_heat_x2_state',
'hvac_heat_x3_state',
'hvac_alt_heat_state',
'hvac_alt_heat_x2_state',
'hvac_emer_heat_state']
_VALID_BINARY_SENSOR_TYPES = BINARY_TYPES + CLIMATE_BINARY_TYPES \
+ CAMERA_BINARY_TYPES
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Nest binary sensors."""
for structure, device in nest.devices():
add_devices([NestBinarySensor(structure, device, variable)
for variable in config[CONF_MONITORED_CONDITIONS]])
if discovery_info is None:
return
nest = hass.data[DATA_NEST]
# Add all available binary sensors if no Nest binary sensor config is set
if discovery_info == {}:
conditions = _VALID_BINARY_SENSOR_TYPES
else:
conditions = discovery_info.get(CONF_MONITORED_CONDITIONS, {})
for variable in conditions:
if variable in _BINARY_TYPES_DEPRECATED:
wstr = (variable + " is no a longer supported "
"monitored_conditions. See "
"https://home-assistant.io/components/binary_sensor.nest/ "
"for valid options.")
_LOGGER.error(wstr)
sensors = []
device_chain = chain(nest.thermostats(),
nest.smoke_co_alarms(),
nest.cameras())
for structure, device in device_chain:
sensors += [NestBinarySensor(structure, device, variable)
for variable in conditions
if variable in BINARY_TYPES]
sensors += [NestBinarySensor(structure, device, variable)
for variable in conditions
if variable in CLIMATE_BINARY_TYPES
and device.is_thermostat]
if device.is_camera:
sensors += [NestBinarySensor(structure, device, variable)
for variable in conditions
if variable in CAMERA_BINARY_TYPES]
for activity_zone in device.activity_zones:
sensors += [NestActivityZoneSensor(structure,
device,
activity_zone)]
add_devices(sensors, True)
class NestBinarySensor(NestSensor, BinarySensorDevice):
@@ -46,4 +94,27 @@ class NestBinarySensor(NestSensor, BinarySensorDevice):
@property
def is_on(self):
"""True if the binary sensor is on."""
return bool(getattr(self.device, self.variable))
return self._state
def update(self):
"""Retrieve latest state."""
self._state = bool(getattr(self.device, self.variable))
class NestActivityZoneSensor(NestBinarySensor):
"""Represents a Nest binary sensor for activity in a zone."""
def __init__(self, structure, device, zone):
"""Initialize the sensor."""
super(NestActivityZoneSensor, self).__init__(structure, device, "")
self.zone = zone
self._name = "{} {} activity".format(self._name, self.zone.name)
@property
def name(self):
"""Return the name of the nest, if any."""
return self._name
def update(self):
"""Retrieve latest state."""
self._state = self.device.has_ongoing_motion_in_zone(self.zone.zone_id)

View File

@@ -0,0 +1,223 @@
"""
Support for the Netatmo binary sensors.
The binary sensors based on events seen by the Netatmo cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.netatmo/.
"""
import logging
import voluptuous as vol
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.components.netatmo import CameraData
from homeassistant.loader import get_component
from homeassistant.const import CONF_TIMEOUT, CONF_OFFSET
from homeassistant.helpers import config_validation as cv
DEPENDENCIES = ["netatmo"]
_LOGGER = logging.getLogger(__name__)
# These are the available sensors mapped to binary_sensor class
WELCOME_SENSOR_TYPES = {
"Someone known": "motion",
"Someone unknown": "motion",
"Motion": "motion",
}
PRESENCE_SENSOR_TYPES = {
"Outdoor motion": "motion",
"Outdoor human": "motion",
"Outdoor animal": "motion",
"Outdoor vehicle": "motion"
}
TAG_SENSOR_TYPES = {
"Tag Vibration": 'vibration',
"Tag Open": 'opening'
}
CONF_HOME = 'home'
CONF_CAMERAS = 'cameras'
CONF_WELCOME_SENSORS = 'welcome_sensors'
CONF_PRESENCE_SENSORS = 'presence_sensors'
CONF_TAG_SENSORS = 'tag_sensors'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_HOME): cv.string,
vol.Optional(CONF_TIMEOUT): cv.positive_int,
vol.Optional(CONF_OFFSET): cv.positive_int,
vol.Optional(CONF_CAMERAS, default=[]):
vol.All(cv.ensure_list, [cv.string]),
vol.Optional(
CONF_WELCOME_SENSORS, default=WELCOME_SENSOR_TYPES.keys()):
vol.All(cv.ensure_list, [vol.In(WELCOME_SENSOR_TYPES)]),
vol.Optional(
CONF_PRESENCE_SENSORS, default=PRESENCE_SENSOR_TYPES.keys()):
vol.All(cv.ensure_list, [vol.In(PRESENCE_SENSOR_TYPES)]),
})
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup access to Netatmo binary sensor."""
netatmo = get_component('netatmo')
home = config.get(CONF_HOME, None)
timeout = config.get(CONF_TIMEOUT, 15)
offset = config.get(CONF_OFFSET, 90)
module_name = None
import lnetatmo
try:
data = CameraData(netatmo.NETATMO_AUTH, home)
if data.get_camera_names() == []:
return None
except lnetatmo.NoDevice:
return None
welcome_sensors = config.get(
CONF_WELCOME_SENSORS, WELCOME_SENSOR_TYPES)
presence_sensors = config.get(
CONF_PRESENCE_SENSORS, PRESENCE_SENSOR_TYPES)
tag_sensors = config.get(CONF_TAG_SENSORS, TAG_SENSOR_TYPES)
for camera_name in data.get_camera_names():
camera_type = data.get_camera_type(camera=camera_name, home=home)
if camera_type == "NACamera":
if CONF_CAMERAS in config:
if config[CONF_CAMERAS] != [] and \
camera_name not in config[CONF_CAMERAS]:
continue
for variable in welcome_sensors:
add_devices([NetatmoBinarySensor(data, camera_name,
module_name, home, timeout,
offset, camera_type,
variable)])
if camera_type == "NOC":
if CONF_CAMERAS in config:
if config[CONF_CAMERAS] != [] and \
camera_name not in config[CONF_CAMERAS]:
continue
for variable in presence_sensors:
add_devices([NetatmoBinarySensor(data, camera_name,
module_name, home, timeout,
offset, camera_type,
variable)])
for module_name in data.get_module_names(camera_name):
for variable in tag_sensors:
camera_type = None
add_devices([NetatmoBinarySensor(data, camera_name,
module_name, home,
timeout, offset,
camera_type,
variable)])
class NetatmoBinarySensor(BinarySensorDevice):
"""Represent a single binary sensor in a Netatmo Camera device."""
def __init__(self, data, camera_name, module_name, home,
timeout, offset, camera_type, sensor):
"""Setup for access to the Netatmo camera events."""
self._data = data
self._camera_name = camera_name
self._module_name = module_name
self._home = home
self._timeout = timeout
self._offset = offset
if home:
self._name = home + ' / ' + camera_name
else:
self._name = camera_name
if module_name:
self._name += ' / ' + module_name
self._sensor_name = sensor
self._name += ' ' + sensor
camera_id = data.camera_data.cameraByName(camera=camera_name,
home=home)['id']
self._unique_id = "Netatmo_binary_sensor {0} - {1}".format(self._name,
camera_id)
self._cameratype = camera_type
self.update()
@property
def name(self):
"""The name of the Netatmo device and this sensor."""
return self._name
@property
def unique_id(self):
"""Return the unique ID for this sensor."""
return self._unique_id
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
if self._cameratype == "NACamera":
return WELCOME_SENSOR_TYPES.get(self._sensor_name)
elif self._cameratype == "NOC":
return PRESENCE_SENSOR_TYPES.get(self._sensor_name)
else:
return TAG_SENSOR_TYPES.get(self._sensor_name)
@property
def is_on(self):
"""Return true if binary sensor is on."""
return self._state
def update(self):
"""Request an update from the Netatmo API."""
self._data.update()
self._data.update_event()
if self._cameratype == "NACamera":
if self._sensor_name == "Someone known":
self._state =\
self._data.camera_data.someoneKnownSeen(self._home,
self._camera_name,
self._timeout*60)
elif self._sensor_name == "Someone unknown":
self._state =\
self._data.camera_data.someoneUnknownSeen(
self._home, self._camera_name, self._timeout*60)
elif self._sensor_name == "Motion":
self._state =\
self._data.camera_data.motionDetected(self._home,
self._camera_name,
self._timeout*60)
elif self._cameratype == "NOC":
if self._sensor_name == "Outdoor motion":
self._state =\
self._data.camera_data.outdoormotionDetected(
self._home, self._camera_name, self._offset)
elif self._sensor_name == "Outdoor human":
self._state =\
self._data.camera_data.humanDetected(self._home,
self._camera_name,
self._offset)
elif self._sensor_name == "Outdoor animal":
self._state =\
self._data.camera_data.animalDetected(self._home,
self._camera_name,
self._offset)
elif self._sensor_name == "Outdoor vehicle":
self._state =\
self._data.camera_data.carDetected(self._home,
self._camera_name,
self._offset)
if self._sensor_name == "Tag Vibration":
self._state =\
self._data.camera_data.moduleMotionDetected(self._home,
self._module_name,
self._camera_name,
self._timeout*60)
elif self._sensor_name == "Tag Open":
self._state =\
self._data.camera_data.moduleOpened(self._home,
self._module_name,
self._camera_name)
else:
return None

View File

@@ -1,41 +1,56 @@
"""
Support for exposing nx584 elements as sensors.
Support for exposing NX584 elements as sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.nx584/
https://home-assistant.io/components/binary_sensor.nx584/
"""
import logging
import threading
import time
import requests
import voluptuous as vol
from homeassistant.components.binary_sensor import (
SENSOR_CLASSES, BinarySensorDevice)
DEVICE_CLASSES, BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.const import (CONF_HOST, CONF_PORT)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pynx584==0.4']
REQUIREMENTS = ['pynx584==0.2']
_LOGGER = logging.getLogger(__name__)
CONF_EXCLUDE_ZONES = 'exclude_zones'
CONF_ZONE_TYPES = 'zone_types'
DEFAULT_HOST = 'localhost'
DEFAULT_PORT = '5007'
DEFAULT_SSL = False
ZONE_TYPES_SCHEMA = vol.Schema({
cv.positive_int: vol.In(DEVICE_CLASSES),
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_EXCLUDE_ZONES, default=[]):
vol.All(cv.ensure_list, [cv.positive_int]),
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_ZONE_TYPES, default={}): ZONE_TYPES_SCHEMA,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup nx584 binary sensor platform."""
"""Setup the NX584 binary sensor platform."""
from nx584 import client as nx584_client
host = config.get('host', 'localhost:5007')
exclude = config.get('exclude_zones', [])
zone_types = config.get('zone_types', {})
if not all(isinstance(zone, int) for zone in exclude):
_LOGGER.error('Invalid excluded zone specified (use zone number)')
return False
if not all(isinstance(zone, int) and ztype in SENSOR_CLASSES
for zone, ztype in zone_types.items()):
_LOGGER.error('Invalid zone_types entry')
return False
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
exclude = config.get(CONF_EXCLUDE_ZONES)
zone_types = config.get(CONF_ZONE_TYPES)
try:
client = nx584_client.Client('http://%s' % host)
client = nx584_client.Client('http://{}:{}'.format(host, port))
zones = client.list_zones()
except requests.exceptions.ConnectionError as ex:
_LOGGER.error('Unable to connect to NX584: %s', str(ex))
@@ -43,7 +58,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
version = [int(v) for v in client.get_version().split('.')]
if version < [1, 1]:
_LOGGER.error('NX584 is too old to use for sensors (>=0.2 required)')
_LOGGER.error("NX584 is too old to use for sensors (>=0.2 required)")
return False
zone_sensors = {
@@ -57,13 +72,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
watcher = NX584Watcher(client, zone_sensors)
watcher.start()
else:
_LOGGER.warning('No zones found on NX584')
_LOGGER.warning("No zones found on NX584")
return True
class NX584ZoneSensor(BinarySensorDevice):
"""Represents a NX584 zone as a sensor."""
"""Representation of a NX584 zone as a sensor."""
def __init__(self, zone, zone_type):
"""Initialize the nx594 binary sensor."""
@@ -71,8 +85,8 @@ class NX584ZoneSensor(BinarySensorDevice):
self._zone_type = zone_type
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return self._zone_type
@property
@@ -96,7 +110,7 @@ class NX584Watcher(threading.Thread):
"""Event listener thread to process NX584 events."""
def __init__(self, client, zone_sensors):
"""Initialize nx584 watcher thread."""
"""Initialize NX584 watcher thread."""
super(NX584Watcher, self).__init__()
self.daemon = True
self._client = client
@@ -109,7 +123,7 @@ class NX584Watcher(threading.Thread):
if not zone_sensor:
return
zone_sensor._zone['state'] = event['zone_state']
zone_sensor.update_ha_state()
zone_sensor.schedule_update_ha_state()
def _process_events(self, events):
for event in events:
@@ -130,5 +144,5 @@ class NX584Watcher(threading.Thread):
try:
self._run()
except requests.exceptions.ConnectionError:
_LOGGER.error('Failed to reach NX584 server')
_LOGGER.error("Failed to reach NX584 server")
time.sleep(10)

View File

@@ -58,11 +58,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(devices)
# pylint: disable=too-many-instance-attributes
class OctoPrintBinarySensor(BinarySensorDevice):
"""Representation an OctoPrint binary sensor."""
# pylint: disable=too-many-arguments
def __init__(self, api, condition, sensor_type, sensor_name, unit,
endpoint, group, tool=None):
"""Initialize a new OctoPrint sensor."""
@@ -101,8 +99,8 @@ class OctoPrintBinarySensor(BinarySensorDevice):
return STATE_OFF
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return None
def update(self):

View File

@@ -7,14 +7,18 @@ https://home-assistant.io/components/binary_sensor.rest/
import logging
import voluptuous as vol
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
from homeassistant.components.binary_sensor import (
BinarySensorDevice, SENSOR_CLASSES_SCHEMA, PLATFORM_SCHEMA)
BinarySensorDevice, DEVICE_CLASSES_SCHEMA, PLATFORM_SCHEMA)
from homeassistant.components.sensor.rest import RestData
from homeassistant.const import (
CONF_PAYLOAD, CONF_NAME, CONF_VALUE_TEMPLATE, CONF_METHOD, CONF_RESOURCE,
CONF_SENSOR_CLASS, CONF_VERIFY_SSL)
CONF_SENSOR_CLASS, CONF_VERIFY_SSL, CONF_USERNAME, CONF_PASSWORD,
CONF_HEADERS, CONF_AUTHENTICATION, HTTP_BASIC_AUTHENTICATION,
HTTP_DIGEST_AUTHENTICATION, CONF_DEVICE_CLASS)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
_LOGGER = logging.getLogger(__name__)
@@ -24,16 +28,21 @@ DEFAULT_VERIFY_SSL = True
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_RESOURCE): cv.url,
vol.Optional(CONF_AUTHENTICATION):
vol.In([HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION]),
vol.Optional(CONF_HEADERS): {cv.string: cv.string},
vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(['POST', 'GET']),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PASSWORD): cv.string,
vol.Optional(CONF_PAYLOAD): cv.string,
vol.Optional(CONF_SENSOR_CLASS): SENSOR_CLASSES_SCHEMA,
vol.Optional(CONF_SENSOR_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_USERNAME): cv.string,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
})
# pylint: disable=unused-variable
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the REST binary sensor."""
name = config.get(CONF_NAME)
@@ -41,31 +50,42 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
method = config.get(CONF_METHOD)
payload = config.get(CONF_PAYLOAD)
verify_ssl = config.get(CONF_VERIFY_SSL)
sensor_class = config.get(CONF_SENSOR_CLASS)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
headers = config.get(CONF_HEADERS)
device_class = get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
value_template = config.get(CONF_VALUE_TEMPLATE)
if value_template is not None:
value_template.hass = hass
rest = RestData(method, resource, payload, verify_ssl)
if username and password:
if config.get(CONF_AUTHENTICATION) == HTTP_DIGEST_AUTHENTICATION:
auth = HTTPDigestAuth(username, password)
else:
auth = HTTPBasicAuth(username, password)
else:
auth = None
rest = RestData(method, resource, auth, headers, payload, verify_ssl)
rest.update()
if rest.data is None:
_LOGGER.error('Unable to fetch REST data')
_LOGGER.error("Unable to fetch REST data from %s", resource)
return False
add_devices([RestBinarySensor(
hass, rest, name, sensor_class, value_template)])
hass, rest, name, device_class, value_template)])
# pylint: disable=too-many-arguments
class RestBinarySensor(BinarySensorDevice):
"""Representation of a REST binary sensor."""
def __init__(self, hass, rest, name, sensor_class, value_template):
def __init__(self, hass, rest, name, device_class, value_template):
"""Initialize a REST binary sensor."""
self._hass = hass
self.rest = rest
self._name = name
self._sensor_class = sensor_class
self._device_class = device_class
self._state = False
self._previous_data = None
self._value_template = value_template
@@ -77,9 +97,9 @@ class RestBinarySensor(BinarySensorDevice):
return self._name
@property
def sensor_class(self):
def device_class(self):
"""Return the class of this sensor."""
return self._sensor_class
return self._device_class
@property
def is_on(self):
@@ -88,8 +108,8 @@ class RestBinarySensor(BinarySensorDevice):
return False
if self._value_template is not None:
response = self._value_template.render_with_possible_json_value(
self.rest.data, False)
response = self._value_template.\
async_render_with_possible_json_value(self.rest.data, False)
try:
return bool(int(response))

View File

@@ -51,10 +51,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
for port_num, port_name in ports.items():
binary_sensors.append(RPiGPIOBinarySensor(
port_name, port_num, pull_mode, bouncetime, invert_logic))
add_devices(binary_sensors)
add_devices(binary_sensors, True)
# pylint: disable=too-many-arguments, too-many-instance-attributes
class RPiGPIOBinarySensor(BinarySensorDevice):
"""Represent a binary sensor that uses Raspberry Pi GPIO."""
@@ -66,14 +65,14 @@ class RPiGPIOBinarySensor(BinarySensorDevice):
self._pull_mode = pull_mode
self._bouncetime = bouncetime
self._invert_logic = invert_logic
self._state = None
rpi_gpio.setup_input(self._port, self._pull_mode)
self._state = rpi_gpio.read_input(self._port)
def read_gpio(port):
"""Read state from GPIO."""
self._state = rpi_gpio.read_input(self._port)
self.update_ha_state()
self.schedule_update_ha_state()
rpi_gpio.edge_detect(self._port, read_gpio, self._bouncetime)
@@ -91,3 +90,7 @@ class RPiGPIOBinarySensor(BinarySensorDevice):
def is_on(self):
"""Return the state of the entity."""
return self._state != self._invert_logic
def update(self):
"""Update the GPIO state."""
self._state = rpi_gpio.read_input(self._port)

View File

@@ -1,9 +0,0 @@
# Describes the format for available binary_sensor services
ffmpeg_restart:
description: Send a restart command to a ffmpeg based sensor (party mode).
fields:
entity_id:
description: Name(s) of entites that will restart. Platform dependent.
example: 'binary_sensor.ffmpeg_noise'

View File

@@ -25,7 +25,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(dev)
# pylint: disable=too-many-instance-attributes
class IsInBedBinarySensor(sleepiq.SleepIQSensor, BinarySensorDevice):
"""Implementation of a SleepIQ presence sensor."""
@@ -43,7 +42,7 @@ class IsInBedBinarySensor(sleepiq.SleepIQSensor, BinarySensorDevice):
return self._state is True
@property
def sensor_class(self):
def device_class(self):
"""Return the class of this sensor."""
return "occupancy"

View File

@@ -7,21 +7,20 @@ https://home-assistant.io/components/binary_sensor.tcp/
import logging
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.sensor.tcp import Sensor, CONF_VALUE_ON
from homeassistant.components.sensor.tcp import (
TcpSensor, CONF_VALUE_ON, PLATFORM_SCHEMA)
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Create the binary sensor."""
if not BinarySensor.validate_config(config):
return False
add_entities((BinarySensor(hass, config),))
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({})
class BinarySensor(BinarySensorDevice, Sensor):
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the TCP binary sensor."""
add_devices([TcpBinarySensor(hass, config)])
class TcpBinarySensor(BinarySensorDevice, TcpSensor):
"""A binary sensor which is on when its state == CONF_VALUE_ON."""
required = (CONF_VALUE_ON,)

View File

@@ -4,20 +4,23 @@ Support for exposing a templated binary sensor.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.template/
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.components.binary_sensor import (
BinarySensorDevice, ENTITY_ID_FORMAT, PLATFORM_SCHEMA,
SENSOR_CLASSES_SCHEMA)
DEVICE_CLASSES_SCHEMA)
from homeassistant.const import (
ATTR_FRIENDLY_NAME, ATTR_ENTITY_ID, CONF_VALUE_TEMPLATE,
CONF_SENSOR_CLASS, CONF_SENSORS)
CONF_SENSOR_CLASS, CONF_SENSORS, CONF_DEVICE_CLASS)
from homeassistant.exceptions import TemplateError
from homeassistant.helpers.entity import generate_entity_id
from homeassistant.helpers.event import track_state_change
from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.event import async_track_state_change
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
_LOGGER = logging.getLogger(__name__)
@@ -25,7 +28,8 @@ SENSOR_SCHEMA = vol.Schema({
vol.Required(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(ATTR_FRIENDLY_NAME): cv.string,
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
vol.Optional(CONF_SENSOR_CLASS, default=None): SENSOR_CLASSES_SCHEMA
vol.Optional(CONF_SENSOR_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@@ -33,7 +37,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup template binary sensors."""
sensors = []
@@ -42,7 +47,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
entity_ids = (device_config.get(ATTR_ENTITY_ID) or
value_template.extract_entities())
friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device)
sensor_class = device_config.get(CONF_SENSOR_CLASS)
device_class = get_deprecated(
device_config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
if value_template is not None:
value_template.hass = hass
@@ -52,40 +58,39 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
hass,
device,
friendly_name,
sensor_class,
device_class,
value_template,
entity_ids)
)
if not sensors:
_LOGGER.error('No sensors added')
return False
add_devices(sensors)
yield from async_add_devices(sensors, True)
return True
class BinarySensorTemplate(BinarySensorDevice):
"""A virtual binary sensor that triggers from another sensor."""
# pylint: disable=too-many-arguments
def __init__(self, hass, device, friendly_name, sensor_class,
def __init__(self, hass, device, friendly_name, device_class,
value_template, entity_ids):
"""Initialize the Template binary sensor."""
self.hass = hass
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device,
hass=hass)
self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device,
hass=hass)
self._name = friendly_name
self._sensor_class = sensor_class
self._device_class = device_class
self._template = value_template
self._state = None
self.update()
@callback
def template_bsensor_state_listener(entity, old_state, new_state):
"""Called when the target device changes state."""
self.update_ha_state(True)
hass.async_add_job(self.async_update_ha_state, True)
track_state_change(hass, entity_ids, template_bsensor_state_listener)
async_track_state_change(
hass, entity_ids, template_bsensor_state_listener)
@property
def name(self):
@@ -98,24 +103,26 @@ class BinarySensorTemplate(BinarySensorDevice):
return self._state
@property
def sensor_class(self):
def device_class(self):
"""Return the sensor class of the sensor."""
return self._sensor_class
return self._device_class
@property
def should_poll(self):
"""No polling needed."""
return False
def update(self):
"""Get the latest data and update the state."""
@asyncio.coroutine
def async_update(self):
"""Update the state from the template."""
try:
self._state = self._template.render().lower() == 'true'
self._state = self._template.async_render().lower() == 'true'
except TemplateError as ex:
if ex.args and ex.args[0].startswith(
"UndefinedError: 'None' has no attribute"):
# Common during HA startup - so just a warning
_LOGGER.warning(ex)
_LOGGER.warning('Could not render template %s,'
' the state is unknown.', self._name)
return
_LOGGER.error(ex)
_LOGGER.error('Could not render template %s: %s', self._name, ex)
self._state = False

View File

@@ -0,0 +1,130 @@
"""
Support for monitoring if a sensor value is below/above a threshold.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.threshold/
"""
import asyncio
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA, DEVICE_CLASSES_SCHEMA)
from homeassistant.const import (
CONF_NAME, CONF_ENTITY_ID, CONF_TYPE, STATE_UNKNOWN, CONF_SENSOR_CLASS,
ATTR_ENTITY_ID, CONF_DEVICE_CLASS)
from homeassistant.core import callback
from homeassistant.helpers.deprecation import get_deprecated
from homeassistant.helpers.event import async_track_state_change
_LOGGER = logging.getLogger(__name__)
ATTR_SENSOR_VALUE = 'sensor_value'
ATTR_THRESHOLD = 'threshold'
ATTR_TYPE = 'type'
CONF_LOWER = 'lower'
CONF_THRESHOLD = 'threshold'
CONF_UPPER = 'upper'
DEFAULT_NAME = 'Threshold'
SENSOR_TYPES = [CONF_LOWER, CONF_UPPER]
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_ENTITY_ID): cv.entity_id,
vol.Required(CONF_THRESHOLD): vol.Coerce(float),
vol.Required(CONF_TYPE): vol.In(SENSOR_TYPES),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_SENSOR_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the Threshold sensor."""
entity_id = config.get(CONF_ENTITY_ID)
name = config.get(CONF_NAME)
threshold = config.get(CONF_THRESHOLD)
limit_type = config.get(CONF_TYPE)
device_class = get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
yield from async_add_devices(
[ThresholdSensor(hass, entity_id, name, threshold, limit_type,
device_class)], True)
return True
class ThresholdSensor(BinarySensorDevice):
"""Representation of a Threshold sensor."""
def __init__(self, hass, entity_id, name, threshold, limit_type,
device_class):
"""Initialize the Threshold sensor."""
self._hass = hass
self._entity_id = entity_id
self.is_upper = limit_type == 'upper'
self._name = name
self._threshold = threshold
self._device_class = device_class
self._deviation = False
self.sensor_value = 0
@callback
# pylint: disable=invalid-name
def async_threshold_sensor_state_listener(
entity, old_state, new_state):
"""Called when the sensor changes state."""
if new_state.state == STATE_UNKNOWN:
return
try:
self.sensor_value = float(new_state.state)
except ValueError:
_LOGGER.error("State is not numerical")
hass.async_add_job(self.async_update_ha_state, True)
async_track_state_change(
hass, entity_id, async_threshold_sensor_state_listener)
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def is_on(self):
"""Return true if sensor is on."""
return self._deviation
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def device_class(self):
"""Return the sensor class of the sensor."""
return self._device_class
@property
def device_state_attributes(self):
"""Return the state attributes of the sensor."""
return {
ATTR_ENTITY_ID: self._entity_id,
ATTR_SENSOR_VALUE: self.sensor_value,
ATTR_THRESHOLD: self._threshold,
ATTR_TYPE: CONF_UPPER if self.is_upper else CONF_LOWER,
}
@asyncio.coroutine
def async_update(self):
"""Get the latest data and updates the states."""
if self.is_upper:
self._deviation = bool(self.sensor_value > self._threshold)
else:
self._deviation = bool(self.sensor_value < self._threshold)

View File

@@ -4,20 +4,25 @@ A sensor that monitors trands in other components.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.trend/
"""
import asyncio
import logging
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import (
BinarySensorDevice,
ENTITY_ID_FORMAT,
PLATFORM_SCHEMA,
SENSOR_CLASSES_SCHEMA)
DEVICE_CLASSES_SCHEMA)
from homeassistant.const import (
ATTR_FRIENDLY_NAME,
ATTR_ENTITY_ID,
CONF_SENSOR_CLASS,
CONF_DEVICE_CLASS,
STATE_UNKNOWN,)
from homeassistant.helpers.deprecation import get_deprecated
from homeassistant.helpers.entity import generate_entity_id
from homeassistant.helpers.event import track_state_change
@@ -31,8 +36,8 @@ SENSOR_SCHEMA = vol.Schema({
vol.Optional(CONF_ATTRIBUTE): cv.string,
vol.Optional(ATTR_FRIENDLY_NAME): cv.string,
vol.Optional(CONF_INVERT, default=False): cv.boolean,
vol.Optional(CONF_SENSOR_CLASS, default=None): SENSOR_CLASSES_SCHEMA
vol.Optional(CONF_SENSOR_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@@ -49,7 +54,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
entity_id = device_config[ATTR_ENTITY_ID]
attribute = device_config.get(CONF_ATTRIBUTE)
friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device)
sensor_class = device_config[CONF_SENSOR_CLASS]
device_class = get_deprecated(
device_config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
invert = device_config[CONF_INVERT]
sensors.append(
@@ -59,7 +65,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
friendly_name,
entity_id,
attribute,
sensor_class,
device_class,
invert)
)
if not sensors:
@@ -72,9 +78,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class SensorTrend(BinarySensorDevice):
"""Representation of a trend Sensor."""
# pylint: disable=too-many-arguments, too-many-instance-attributes
def __init__(self, hass, device_id, friendly_name,
target_entity, attribute, sensor_class, invert):
target_entity, attribute, device_class, invert):
"""Initialize the sensor."""
self._hass = hass
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id,
@@ -82,19 +87,18 @@ class SensorTrend(BinarySensorDevice):
self._name = friendly_name
self._target_entity = target_entity
self._attribute = attribute
self._sensor_class = sensor_class
self._device_class = device_class
self._invert = invert
self._state = None
self.from_state = None
self.to_state = None
self.update()
@callback
def trend_sensor_state_listener(entity, old_state, new_state):
"""Called when the target device changes state."""
self.from_state = old_state
self.to_state = new_state
self.update_ha_state(True)
hass.async_add_job(self.async_update_ha_state(True))
track_state_change(hass, target_entity,
trend_sensor_state_listener)
@@ -110,16 +114,17 @@ class SensorTrend(BinarySensorDevice):
return self._state
@property
def sensor_class(self):
def device_class(self):
"""Return the sensor class of the sensor."""
return self._sensor_class
return self._device_class
@property
def should_poll(self):
"""No polling needed."""
return False
def update(self):
@asyncio.coroutine
def async_update(self):
"""Get the latest data and update the states."""
if self.from_state is None or self.to_state is None:
return

View File

@@ -16,9 +16,9 @@ DEPENDENCIES = ['vera']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Perform the setup for Vera controller devices."""
add_devices_callback(
add_devices(
VeraBinarySensor(device, VERA_CONTROLLER)
for device in VERA_DEVICES['binary_sensor'])

View File

@@ -0,0 +1,40 @@
"""
Support for VOC.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.volvooncall/
"""
import logging
from homeassistant.components.volvooncall import VolvoEntity
from homeassistant.components.binary_sensor import BinarySensorDevice
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Volvo sensors."""
if discovery_info is None:
return
add_devices([VolvoSensor(hass, *discovery_info)])
class VolvoSensor(VolvoEntity, BinarySensorDevice):
"""Representation of a Volvo sensor."""
@property
def is_on(self):
"""Return True if the binary sensor is on."""
val = getattr(self.vehicle, self._attribute)
if self._attribute == 'bulb_failures':
return len(val) > 0
elif self._attribute in ['doors', 'windows']:
return any([val[key] for key in val if 'Open' in key])
else:
return val != 'Normal'
@property
def device_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
return 'safety'

View File

@@ -45,10 +45,10 @@ class WemoBinarySensor(BinarySensorDevice):
_LOGGER.info(
'Subscription update for %s',
_device)
self.update()
if not hasattr(self, 'hass'):
self.update()
return
self.update_ha_state(True)
self.schedule_update_ha_state()
@property
def should_poll(self):

View File

@@ -4,12 +4,13 @@ Support for Wink binary sensors.
For more details about this platform, please refer to the documentation at
at https://home-assistant.io/components/binary_sensor.wink/
"""
import json
import logging
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.sensor.wink import WinkDevice
from homeassistant.components.wink import WinkDevice, DOMAIN
from homeassistant.helpers.entity import Entity
from homeassistant.loader import get_component
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['wink']
@@ -19,8 +20,14 @@ SENSOR_TYPES = {
"brightness": "light",
"vibration": "vibration",
"loudness": "sound",
"noise": "sound",
"capturing_audio": "sound",
"liquid_detected": "moisture",
"motion": "motion"
"motion": "motion",
"presence": "occupancy",
"co_detected": "gas",
"smoke_detected": "smoke",
"capturing_video": None
}
@@ -29,48 +36,160 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
import pywink
for sensor in pywink.get_sensors():
if sensor.capability() in SENSOR_TYPES:
add_devices([WinkBinarySensorDevice(sensor)])
_id = sensor.object_id() + sensor.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
if sensor.capability() in SENSOR_TYPES:
add_devices([WinkBinarySensorDevice(sensor, hass)])
for key in pywink.get_keys():
add_devices([WinkBinarySensorDevice(key)])
_id = key.object_id() + key.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_devices([WinkBinarySensorDevice(key, hass)])
for sensor in pywink.get_smoke_and_co_detectors():
_id = sensor.object_id() + sensor.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_devices([WinkSmokeDetector(sensor, hass)])
for hub in pywink.get_hubs():
_id = hub.object_id() + hub.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_devices([WinkHub(hub, hass)])
for remote in pywink.get_remotes():
_id = remote.object_id() + remote.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_devices([WinkRemote(remote, hass)])
for button in pywink.get_buttons():
_id = button.object_id() + button.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_devices([WinkButton(button, hass)])
for gang in pywink.get_gangs():
_id = gang.object_id() + gang.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_devices([WinkGang(gang, hass)])
for door_bell_sensor in pywink.get_door_bells():
_id = door_bell_sensor.object_id() + door_bell_sensor.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
add_devices([WinkBinarySensorDevice(door_bell_sensor, hass)])
for camera_sensor in pywink.get_cameras():
_id = camera_sensor.object_id() + camera_sensor.name()
if _id not in hass.data[DOMAIN]['unique_ids']:
try:
if camera_sensor.capability() in SENSOR_TYPES:
add_devices([WinkBinarySensorDevice(camera_sensor, hass)])
except AttributeError:
_LOGGER.info("Device isn't a sensor, skipping.")
class WinkBinarySensorDevice(WinkDevice, BinarySensorDevice, Entity):
"""Representation of a Wink binary sensor."""
def __init__(self, wink):
def __init__(self, wink, hass):
"""Initialize the Wink binary sensor."""
super().__init__(wink)
wink = get_component('wink')
self._unit_of_measurement = self.wink.UNIT
self.capability = self.wink.capability()
def _pubnub_update(self, message, channel):
if 'data' in message:
json_data = json.dumps(message.get('data'))
super().__init__(wink, hass)
if hasattr(self.wink, 'unit'):
self._unit_of_measurement = self.wink.unit()
else:
json_data = message
self.wink.pubnub_update(json.loads(json_data))
self.update_ha_state()
self._unit_of_measurement = None
if hasattr(self.wink, 'capability'):
self.capability = self.wink.capability()
else:
self.capability = None
@property
def is_on(self):
"""Return true if the binary sensor is on."""
if self.capability == "loudness":
return self.wink.loudness_boolean()
elif self.capability == "vibration":
return self.wink.vibration_boolean()
elif self.capability == "brightness":
return self.wink.brightness_boolean()
elif self.capability == "liquid_detected":
return self.wink.liquid_boolean()
elif self.capability == "motion":
return self.wink.motion_boolean()
else:
return self.wink.state()
return self.wink.state()
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return SENSOR_TYPES.get(self.capability)
class WinkSmokeDetector(WinkBinarySensorDevice):
"""Representation of a Wink Smoke detector."""
def __init__(self, wink, hass):
"""Initialize the Wink binary sensor."""
super().__init__(wink, hass)
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'test_activated': self.wink.test_activated()
}
class WinkHub(WinkBinarySensorDevice):
"""Representation of a Wink Hub."""
def __init__(self, wink, hass):
"""Initialize the Wink binary sensor."""
super().__init__(wink, hass)
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'update needed': self.wink.update_needed(),
'firmware version': self.wink.firmware_version()
}
class WinkRemote(WinkBinarySensorDevice):
"""Representation of a Wink Lutron Connected bulb remote."""
def __init__(self, wink, hass):
"""Initialize the Wink binary sensor."""
super().__init__(wink, hass)
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'button_on_pressed': self.wink.button_on_pressed(),
'button_off_pressed': self.wink.button_off_pressed(),
'button_up_pressed': self.wink.button_up_pressed(),
'button_down_pressed': self.wink.button_down_pressed()
}
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return None
class WinkButton(WinkBinarySensorDevice):
"""Representation of a Wink Relay button."""
def __init__(self, wink, hass):
"""Initialize the Wink binary sensor."""
super().__init__(wink, hass)
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
'pressed': self.wink.pressed(),
'long_pressed': self.wink.long_pressed()
}
class WinkGang(WinkBinarySensorDevice):
"""Representation of a Wink Relay gang."""
def __init__(self, wink, hass):
"""Initialize the Wink binary sensor."""
super().__init__(wink, hass)
@property
def is_on(self):
"""Return true if the gang is connected."""
return self.wink.state()

View File

@@ -8,8 +8,8 @@ import logging
import datetime
import homeassistant.util.dt as dt_util
from homeassistant.helpers.event import track_point_in_time
from homeassistant.helpers.entity import Entity
from homeassistant.components import zwave
from homeassistant.components.zwave import workaround
from homeassistant.components.binary_sensor import (
DOMAIN,
BinarySensorDevice)
@@ -17,74 +17,55 @@ from homeassistant.components.binary_sensor import (
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = []
PHILIO = 0x013c
PHILIO_SLIM_SENSOR = 0x0002
PHILIO_SLIM_SENSOR_MOTION = (PHILIO, PHILIO_SLIM_SENSOR, 0)
WENZHOU = 0x0118
WENZHOU_SLIM_SENSOR_MOTION = (WENZHOU, PHILIO_SLIM_SENSOR, 0)
WORKAROUND_NO_OFF_EVENT = 'trigger_no_off_event'
DEVICE_MAPPINGS = {
PHILIO_SLIM_SENSOR_MOTION: WORKAROUND_NO_OFF_EVENT,
WENZHOU_SLIM_SENSOR_MOTION: WORKAROUND_NO_OFF_EVENT,
}
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Z-Wave platform for binary sensors."""
if discovery_info is None or zwave.NETWORK is None:
return
node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]]
value = node.values[discovery_info[zwave.ATTR_VALUE_ID]]
node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]]
value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]]
value.set_change_verified(False)
# Make sure that we have values for the key before converting to int
if (value.node.manufacturer_id.strip() and
value.node.product_id.strip()):
specific_sensor_key = (int(value.node.manufacturer_id, 16),
int(value.node.product_id, 16),
value.index)
device_mapping = workaround.get_device_mapping(value)
if device_mapping == workaround.WORKAROUND_NO_OFF_EVENT:
# Default the multiplier to 4
re_arm_multiplier = (zwave.get_config_value(value.node, 9) or 4)
add_devices([
ZWaveTriggerSensor(value, "motion",
hass, re_arm_multiplier * 8)
])
return
if specific_sensor_key in DEVICE_MAPPINGS:
if DEVICE_MAPPINGS[specific_sensor_key] == WORKAROUND_NO_OFF_EVENT:
# Default the multiplier to 4
re_arm_multiplier = (zwave.get_config_value(value.node,
9) or 4)
add_devices([
ZWaveTriggerSensor(value, "motion",
hass, re_arm_multiplier * 8)
])
return
if workaround.get_device_component_mapping(value) == DOMAIN:
add_devices([ZWaveBinarySensor(value, None)])
return
if value.command_class == zwave.COMMAND_CLASS_SENSOR_BINARY:
if value.command_class == zwave.const.COMMAND_CLASS_SENSOR_BINARY:
add_devices([ZWaveBinarySensor(value, None)])
class ZWaveBinarySensor(BinarySensorDevice, zwave.ZWaveDeviceEntity, Entity):
class ZWaveBinarySensor(BinarySensorDevice, zwave.ZWaveDeviceEntity):
"""Representation of a binary sensor within Z-Wave."""
def __init__(self, value, sensor_class):
def __init__(self, value, device_class):
"""Initialize the sensor."""
self._sensor_type = sensor_class
# pylint: disable=import-error
from openzwave.network import ZWaveNetwork
from pydispatch import dispatcher
zwave.ZWaveDeviceEntity.__init__(self, value, DOMAIN)
self._sensor_type = device_class
self._state = self._value.data
dispatcher.connect(
self.value_changed, ZWaveNetwork.SIGNAL_VALUE_CHANGED)
def update_properties(self):
"""Callback on data changes for node values."""
self._state = self._value.data
@property
def is_on(self):
"""Return True if the binary sensor is on."""
return self._value.data
return self._state
@property
def sensor_class(self):
"""Return the class of this sensor, from SENSOR_CLASSES."""
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return self._sensor_type
@property
@@ -92,44 +73,35 @@ class ZWaveBinarySensor(BinarySensorDevice, zwave.ZWaveDeviceEntity, Entity):
"""No polling needed."""
return False
def value_changed(self, value):
"""Called when a value has changed on the network."""
if self._value.value_id == value.value_id or \
self._value.node == value.node:
self.update_ha_state()
class ZWaveTriggerSensor(ZWaveBinarySensor, Entity):
class ZWaveTriggerSensor(ZWaveBinarySensor):
"""Representation of a stateless sensor within Z-Wave."""
def __init__(self, sensor_value, sensor_class, hass, re_arm_sec=60):
def __init__(self, value, device_class, hass, re_arm_sec=60):
"""Initialize the sensor."""
super(ZWaveTriggerSensor, self).__init__(sensor_value, sensor_class)
super(ZWaveTriggerSensor, self).__init__(value, device_class)
self._hass = hass
self.re_arm_sec = re_arm_sec
self.invalidate_after = dt_util.utcnow() + datetime.timedelta(
seconds=self.re_arm_sec)
# If it's active make sure that we set the timeout tracker
if sensor_value.data:
track_point_in_time(
self._hass, self.update_ha_state,
self.invalidate_after)
track_point_in_time(
self._hass, self.async_update_ha_state,
self.invalidate_after)
def value_changed(self, value):
"""Called when a value has changed on the network."""
if self._value.value_id == value.value_id:
self.update_ha_state()
if value.data:
# only allow this value to be true for re_arm secs
self.invalidate_after = dt_util.utcnow() + datetime.timedelta(
seconds=self.re_arm_sec)
track_point_in_time(
self._hass, self.update_ha_state,
self.invalidate_after)
def update_properties(self):
"""Called when a value for this entity's node has changed."""
self._state = self._value.data
# only allow this value to be true for re_arm secs
self.invalidate_after = dt_util.utcnow() + datetime.timedelta(
seconds=self.re_arm_sec)
track_point_in_time(
self._hass, self.async_update_ha_state,
self.invalidate_after)
@property
def is_on(self):
"""Return True if movement has happened within the rearm time."""
return self._value.data and \
return self._state and \
(self.invalidate_after is None or
self.invalidate_after > dt_util.utcnow())

View File

@@ -33,7 +33,7 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA)
# pylint: disable=unused-argument,too-few-public-methods
# pylint: disable=unused-argument
def setup(hass, config):
"""Setup BloomSky component."""
api_key = config[DOMAIN][CONF_API_KEY]

View File

@@ -0,0 +1,186 @@
"""
Support for Google Calendar event device sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/calendar/
"""
import logging
from datetime import timedelta
import re
from homeassistant.components.google import (CONF_OFFSET,
CONF_DEVICE_ID,
CONF_NAME)
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.helpers.config_validation import time_period_str
from homeassistant.helpers.entity import Entity, generate_entity_id
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.template import DATE_STR_FORMAT
from homeassistant.util import dt
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=60)
DOMAIN = 'calendar'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
def setup(hass, config):
"""Track states and offer events for calendars."""
component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL, DOMAIN)
component.setup(config)
return True
DEFAULT_CONF_TRACK_NEW = True
DEFAULT_CONF_OFFSET = '!!'
# pylint: disable=too-many-instance-attributes
class CalendarEventDevice(Entity):
"""A calendar event device."""
# Classes overloading this must set data to an object
# with an update() method
data = None
# pylint: disable=too-many-arguments
def __init__(self, hass, data):
"""Create the Calendar Event Device."""
self._name = data.get(CONF_NAME)
self.dev_id = data.get(CONF_DEVICE_ID)
self._offset = data.get(CONF_OFFSET, DEFAULT_CONF_OFFSET)
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT,
self.dev_id,
hass=hass)
self._cal_data = {
'all_day': False,
'offset_time': dt.dt.timedelta(),
'message': '',
'start': None,
'end': None,
'location': '',
'description': '',
}
self.update()
def offset_reached(self):
"""Have we reached the offset time specified in the event title."""
if self._cal_data['start'] is None or \
self._cal_data['offset_time'] == dt.dt.timedelta():
return False
return self._cal_data['start'] + self._cal_data['offset_time'] <= \
dt.now(self._cal_data['start'].tzinfo)
@property
def name(self):
"""Return the name of the entity."""
return self._name
@property
def device_state_attributes(self):
"""State Attributes for HA."""
start = self._cal_data.get('start', None)
end = self._cal_data.get('end', None)
start = start.strftime(DATE_STR_FORMAT) if start is not None else None
end = end.strftime(DATE_STR_FORMAT) if end is not None else None
return {
'message': self._cal_data.get('message', ''),
'all_day': self._cal_data.get('all_day', False),
'offset_reached': self.offset_reached(),
'start_time': start,
'end_time': end,
'location': self._cal_data.get('location', None),
'description': self._cal_data.get('description', None),
}
@property
def state(self):
"""Return the state of the calendar event."""
start = self._cal_data.get('start', None)
end = self._cal_data.get('end', None)
if start is None or end is None:
return STATE_OFF
now = dt.now()
if start <= now and end > now:
return STATE_ON
if now >= end:
self.cleanup()
return STATE_OFF
def cleanup(self):
"""Cleanup any start/end listeners that were setup."""
self._cal_data = {
'all_day': False,
'offset_time': 0,
'message': '',
'start': None,
'end': None,
'location': None,
'description': None
}
def update(self):
"""Search for the next event."""
if not self.data or not self.data.update():
# update cached, don't do anything
return
if not self.data.event:
# we have no event to work on, make sure we're clean
self.cleanup()
return
def _get_date(date):
"""Get the dateTime from date or dateTime as a local."""
if 'date' in date:
return dt.start_of_local_day(dt.dt.datetime.combine(
dt.parse_date(date['date']), dt.dt.time.min))
else:
return dt.as_local(dt.parse_datetime(date['dateTime']))
start = _get_date(self.data.event['start'])
end = _get_date(self.data.event['end'])
summary = self.data.event['summary']
# check if we have an offset tag in the message
# time is HH:MM or MM
reg = '{}([+-]?[0-9]{{0,2}}(:[0-9]{{0,2}})?)'.format(self._offset)
search = re.search(reg, summary)
if search and search.group(1):
time = search.group(1)
if ':' not in time:
if time[0] == '+' or time[0] == '-':
time = '{}0:{}'.format(time[0], time[1:])
else:
time = '0:{}'.format(time)
offset_time = time_period_str(time)
summary = (summary[:search.start()] + summary[search.end():]) \
.strip()
else:
offset_time = dt.dt.timedelta() # default it
# cleanup the string so we don't have a bunch of double+ spaces
self._cal_data['message'] = re.sub(' +', '', summary).strip()
self._cal_data['offset_time'] = offset_time
self._cal_data['location'] = self.data.event.get('location', '')
self._cal_data['description'] = self.data.event.get('description', '')
self._cal_data['start'] = start
self._cal_data['end'] = end
self._cal_data['all_day'] = 'date' in self.data.event['start']

View File

@@ -0,0 +1,82 @@
"""
Demo platform that has two fake binary sensors.
For more details about this platform, please refer to the documentation
https://home-assistant.io/components/demo/
"""
import homeassistant.util.dt as dt_util
from homeassistant.components.calendar import CalendarEventDevice
from homeassistant.components.google import CONF_DEVICE_ID, CONF_NAME
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Demo binary sensor platform."""
calendar_data_future = DemoGoogleCalendarDataFuture()
calendar_data_current = DemoGoogleCalendarDataCurrent()
add_devices([
DemoGoogleCalendar(hass, calendar_data_future, {
CONF_NAME: 'Future Event',
CONF_DEVICE_ID: 'future_event',
}),
DemoGoogleCalendar(hass, calendar_data_current, {
CONF_NAME: 'Current Event',
CONF_DEVICE_ID: 'current_event',
}),
])
class DemoGoogleCalendarData(object):
"""Setup base class for data."""
# pylint: disable=no-self-use
def update(self):
"""Return true so entity knows we have new data."""
return True
class DemoGoogleCalendarDataFuture(DemoGoogleCalendarData):
"""Setup future data event."""
def __init__(self):
"""Set the event to a future event."""
one_hour_from_now = dt_util.now() \
+ dt_util.dt.timedelta(minutes=30)
self.event = {
'start': {
'dateTime': one_hour_from_now.isoformat()
},
'end': {
'dateTime': (one_hour_from_now + dt_util.dt.
timedelta(minutes=60)).isoformat()
},
'summary': 'Future Event',
}
class DemoGoogleCalendarDataCurrent(DemoGoogleCalendarData):
"""Create a current event we're in the middle of."""
def __init__(self):
"""Set the event data."""
middle_of_event = dt_util.now() \
- dt_util.dt.timedelta(minutes=30)
self.event = {
'start': {
'dateTime': middle_of_event.isoformat()
},
'end': {
'dateTime': (middle_of_event + dt_util.dt.
timedelta(minutes=60)).isoformat()
},
'summary': 'Current Event',
}
class DemoGoogleCalendar(CalendarEventDevice):
"""A Demo binary sensor."""
def __init__(self, hass, calendar_data, data):
"""The same as a google calendar but without the api calls."""
self.data = calendar_data
super().__init__(hass, data)

View File

@@ -0,0 +1,79 @@
"""
Support for Google Calendar Search binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.google_calendar/
"""
# pylint: disable=import-error
import logging
from datetime import timedelta
from homeassistant.components.calendar import CalendarEventDevice
from homeassistant.components.google import (CONF_CAL_ID, CONF_ENTITIES,
CONF_TRACK, TOKEN_FILE,
GoogleCalendarService)
from homeassistant.util import Throttle, dt
DEFAULT_GOOGLE_SEARCH_PARAMS = {
'orderBy': 'startTime',
'maxResults': 1,
'singleEvents': True,
}
# Return cached results if last scan was less then this time ago
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=15)
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, disc_info=None):
"""Setup the calendar platform for event devices."""
if disc_info is None:
return
if not any([data[CONF_TRACK] for data in disc_info[CONF_ENTITIES]]):
return
calendar_service = GoogleCalendarService(hass.config.path(TOKEN_FILE))
add_devices([GoogleCalendarEventDevice(hass, calendar_service,
disc_info[CONF_CAL_ID], data)
for data in disc_info[CONF_ENTITIES] if data[CONF_TRACK]])
# pylint: disable=too-many-instance-attributes
class GoogleCalendarEventDevice(CalendarEventDevice):
"""A calendar event device."""
def __init__(self, hass, calendar_service, calendar, data):
"""Create the Calendar event device."""
self.data = GoogleCalendarData(calendar_service, calendar,
data.get('search', None))
super().__init__(hass, data)
class GoogleCalendarData(object):
"""Class to utilize calendar service object to get next event."""
def __init__(self, calendar_service, calendar_id, search=None):
"""Setup how we are going to search the google calendar."""
self.calendar_service = calendar_service
self.calendar_id = calendar_id
self.search = search
self.event = None
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Get the latest data."""
service = self.calendar_service.get()
params = dict(DEFAULT_GOOGLE_SEARCH_PARAMS)
params['timeMin'] = dt.now().isoformat('T')
params['calendarId'] = self.calendar_id
if self.search:
params['q'] = self.search
events = service.events() # pylint: disable=no-member
result = events.list(**params).execute()
items = result.get('items', [])
self.event = items[0] if len(items) == 1 else None
return True

View File

@@ -5,17 +5,32 @@ Component to interface with cameras.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/camera/
"""
import asyncio
import collections
from datetime import timedelta
import logging
import time
import hashlib
from random import SystemRandom
import aiohttp
from aiohttp import web
import async_timeout
from homeassistant.core import callback
from homeassistant.const import ATTR_ENTITY_PICTURE
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http import HomeAssistantView, KEY_AUTHENTICATED
from homeassistant.helpers.event import async_track_time_interval
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'camera'
DEPENDENCIES = ['http']
SCAN_INTERVAL = 30
SCAN_INTERVAL = timedelta(seconds=30)
ENTITY_ID_FORMAT = DOMAIN + '.{}'
STATE_RECORDING = 'recording'
@@ -24,18 +39,63 @@ STATE_IDLE = 'idle'
ENTITY_IMAGE_URL = '/api/camera_proxy/{0}?token={1}'
TOKEN_CHANGE_INTERVAL = timedelta(minutes=5)
_RND = SystemRandom()
# pylint: disable=too-many-branches
def setup(hass, config):
@asyncio.coroutine
def async_get_image(hass, entity_id, timeout=10):
"""Fetch a image from a camera entity."""
websession = async_get_clientsession(hass)
state = hass.states.get(entity_id)
if state is None:
raise HomeAssistantError(
"No entity '{0}' for grab a image".format(entity_id))
url = "{0}{1}".format(
hass.config.api.base_url,
state.attributes.get(ATTR_ENTITY_PICTURE)
)
response = None
try:
with async_timeout.timeout(timeout, loop=hass.loop):
response = yield from websession.get(url)
if response.status != 200:
raise HomeAssistantError("Error {0} on {1}".format(
response.status, url))
image = yield from response.read()
return image
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
raise HomeAssistantError("Can't connect to {0}".format(url))
finally:
if response is not None:
yield from response.release()
@asyncio.coroutine
def async_setup(hass, config):
"""Setup the camera component."""
component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
hass.wsgi.register_view(CameraImageView(hass, component.entities))
hass.wsgi.register_view(CameraMjpegStream(hass, component.entities))
hass.http.register_view(CameraImageView(component.entities))
hass.http.register_view(CameraMjpegStream(component.entities))
component.setup(config)
yield from component.async_setup(config)
@callback
def update_tokens(time):
"""Update tokens of the entities."""
for entity in component.entities.values():
entity.async_update_token()
hass.async_add_job(entity.async_update_ha_state())
async_track_time_interval(hass, update_tokens, TOKEN_CHANGE_INTERVAL)
return True
@@ -45,11 +105,8 @@ class Camera(Entity):
def __init__(self):
"""Initialize a camera."""
self.is_streaming = False
@property
def access_token(self):
"""Access token for this camera."""
return str(id(self))
self.access_tokens = collections.deque([], 2)
self.async_update_token()
@property
def should_poll(self):
@@ -59,7 +116,7 @@ class Camera(Entity):
@property
def entity_picture(self):
"""Return a link to the camera feed as entity picture."""
return ENTITY_IMAGE_URL.format(self.entity_id, self.access_token)
return ENTITY_IMAGE_URL.format(self.entity_id, self.access_tokens[-1])
@property
def is_recording(self):
@@ -80,33 +137,61 @@ class Camera(Entity):
"""Return bytes of camera image."""
raise NotImplementedError()
def mjpeg_stream(self, response):
"""Generate an HTTP MJPEG stream from camera images."""
def stream():
"""Stream images as mjpeg stream."""
try:
last_image = None
while True:
img_bytes = self.camera_image()
def async_camera_image(self):
"""Return bytes of camera image.
if img_bytes is not None and img_bytes != last_image:
yield bytes(
'--jpegboundary\r\n'
'Content-Type: image/jpeg\r\n'
'Content-Length: {}\r\n\r\n'.format(
len(img_bytes)), 'utf-8') + img_bytes + b'\r\n'
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.loop.run_in_executor(None, self.camera_image)
last_image = img_bytes
@asyncio.coroutine
def handle_async_mjpeg_stream(self, request):
"""Generate an HTTP MJPEG stream from camera images.
time.sleep(0.5)
except GeneratorExit:
pass
This method must be run in the event loop.
"""
response = web.StreamResponse()
return response(
stream(),
content_type=('multipart/x-mixed-replace; '
'boundary=--jpegboundary')
)
response.content_type = ('multipart/x-mixed-replace; '
'boundary=--jpegboundary')
yield from response.prepare(request)
def write(img_bytes):
"""Write image to stream."""
response.write(bytes(
'--jpegboundary\r\n'
'Content-Type: image/jpeg\r\n'
'Content-Length: {}\r\n\r\n'.format(
len(img_bytes)), 'utf-8') + img_bytes + b'\r\n')
last_image = None
try:
while True:
img_bytes = yield from self.async_camera_image()
if not img_bytes:
break
if img_bytes is not None and img_bytes != last_image:
write(img_bytes)
# Chrome seems to always ignore first picture,
# print it twice.
if last_image is None:
write(img_bytes)
last_image = img_bytes
yield from response.drain()
yield from asyncio.sleep(.5)
except (asyncio.CancelledError, ConnectionResetError):
_LOGGER.debug("Close stream by frontend.")
response = None
finally:
if response is not None:
yield from response.write_eof()
@property
def state(self):
@@ -122,7 +207,7 @@ class Camera(Entity):
def state_attributes(self):
"""Camera state attributes."""
attr = {
'access_token': self.access_token,
'access_token': self.access_tokens[-1],
}
if self.model:
@@ -133,33 +218,43 @@ class Camera(Entity):
return attr
@callback
def async_update_token(self):
"""Update the used token."""
self.access_tokens.append(
hashlib.sha256(
_RND.getrandbits(256).to_bytes(32, 'little')).hexdigest())
class CameraView(HomeAssistantView):
"""Base CameraView."""
requires_auth = False
def __init__(self, hass, entities):
def __init__(self, entities):
"""Initialize a basic camera view."""
super().__init__(hass)
self.entities = entities
@asyncio.coroutine
def get(self, request, entity_id):
"""Start a get request."""
camera = self.entities.get(entity_id)
if camera is None:
return self.Response(status=404)
status = 404 if request[KEY_AUTHENTICATED] else 401
return web.Response(status=status)
authenticated = (request.authenticated or
request.args.get('token') == camera.access_token)
authenticated = (request[KEY_AUTHENTICATED] or
request.GET.get('token') in camera.access_tokens)
if not authenticated:
return self.Response(status=401)
return web.Response(status=401)
return self.handle(camera)
response = yield from self.handle(request, camera)
return response
def handle(self, camera):
@asyncio.coroutine
def handle(self, request, camera):
"""Hanlde the camera request."""
raise NotImplementedError()
@@ -167,25 +262,31 @@ class CameraView(HomeAssistantView):
class CameraImageView(CameraView):
"""Camera view to serve an image."""
url = "/api/camera_proxy/<entity(domain=camera):entity_id>"
url = "/api/camera_proxy/{entity_id}"
name = "api:camera:image"
def handle(self, camera):
@asyncio.coroutine
def handle(self, request, camera):
"""Serve camera image."""
response = camera.camera_image()
try:
image = yield from camera.async_camera_image()
if response is None:
return self.Response(status=500)
if image is None:
return web.Response(status=500)
return self.Response(response)
return web.Response(body=image)
except asyncio.CancelledError:
_LOGGER.debug("Close stream by frontend.")
class CameraMjpegStream(CameraView):
"""Camera View to serve an MJPEG stream."""
url = "/api/camera_proxy_stream/<entity(domain=camera):entity_id>"
url = "/api/camera_proxy_stream/{entity_id}"
name = "api:camera:stream"
def handle(self, camera):
@asyncio.coroutine
def handle(self, request, camera):
"""Serve camera image."""
return camera.mjpeg_stream(self.Response)
yield from camera.handle_async_mjpeg_stream(request)

View File

@@ -0,0 +1,133 @@
"""
This component provides basic support for Amcrest IP cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.amcrest/
"""
import asyncio
import logging
import aiohttp
import voluptuous as vol
import homeassistant.loader as loader
from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA)
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_PORT)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import (
async_get_clientsession, async_aiohttp_proxy_stream)
REQUIREMENTS = ['amcrest==1.1.4']
_LOGGER = logging.getLogger(__name__)
CONF_RESOLUTION = 'resolution'
CONF_STREAM_SOURCE = 'stream_source'
DEFAULT_NAME = 'Amcrest Camera'
DEFAULT_PORT = 80
DEFAULT_RESOLUTION = 'high'
DEFAULT_STREAM_SOURCE = 'mjpeg'
NOTIFICATION_ID = 'amcrest_notification'
NOTIFICATION_TITLE = 'Amcrest Camera Setup'
RESOLUTION_LIST = {
'high': 0,
'low': 1,
}
STREAM_SOURCE_LIST = {
'mjpeg': 0,
'snapshot': 1
}
CONTENT_TYPE_HEADER = 'Content-Type'
TIMEOUT = 5
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_RESOLUTION, default=DEFAULT_RESOLUTION):
vol.All(vol.In(RESOLUTION_LIST)),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_STREAM_SOURCE, default=DEFAULT_STREAM_SOURCE):
vol.All(vol.In(STREAM_SOURCE_LIST)),
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up an Amcrest IP Camera."""
from amcrest import AmcrestCamera
camera = AmcrestCamera(
config.get(CONF_HOST), config.get(CONF_PORT),
config.get(CONF_USERNAME), config.get(CONF_PASSWORD)).camera
persistent_notification = loader.get_component('persistent_notification')
try:
camera.current_time
# pylint: disable=broad-except
except Exception as ex:
_LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex))
persistent_notification.create(
hass, 'Error: {}<br />'
'You will need to restart hass after fixing.'
''.format(ex),
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
add_devices([AmcrestCam(hass, config, camera)])
return True
class AmcrestCam(Camera):
"""An implementation of an Amcrest IP camera."""
def __init__(self, hass, device_info, camera):
"""Initialize an Amcrest camera."""
super(AmcrestCam, self).__init__()
self._camera = camera
self._base_url = self._camera.get_base_url()
self._hass = hass
self._name = device_info.get(CONF_NAME)
self._resolution = RESOLUTION_LIST[device_info.get(CONF_RESOLUTION)]
self._stream_source = STREAM_SOURCE_LIST[
device_info.get(CONF_STREAM_SOURCE)
]
self._token = self._auth = aiohttp.BasicAuth(
device_info.get(CONF_USERNAME),
password=device_info.get(CONF_PASSWORD)
)
def camera_image(self):
"""Return a still image reponse from the camera."""
# Send the request to snap a picture and return raw jpg data
response = self._camera.snapshot(channel=self._resolution)
return response.data
@asyncio.coroutine
def handle_async_mjpeg_stream(self, request):
"""Return an MJPEG stream."""
# The snapshot implementation is handled by the parent class
if self._stream_source == STREAM_SOURCE_LIST['snapshot']:
yield from super().handle_async_mjpeg_stream(request)
return
# Otherwise, stream an MJPEG image stream directly from the camera
websession = async_get_clientsession(self.hass)
streaming_url = '{0}mjpg/video.cgi?channel=0&subtype={1}'.format(
self._base_url, self._resolution)
stream_coro = websession.get(
streaming_url, auth=self._token, timeout=TIMEOUT)
yield from async_aiohttp_proxy_stream(self.hass, request, stream_coro)
@property
def name(self):
"""Return the name of this camera."""
return self._name

View File

@@ -4,13 +4,15 @@ Support for Cameras with FFmpeg as decoder.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.ffmpeg/
"""
import asyncio
import logging
import voluptuous as vol
from aiohttp import web
from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA)
from homeassistant.components.camera import Camera, PLATFORM_SCHEMA
from homeassistant.components.ffmpeg import (
run_test, get_binary, CONF_INPUT, CONF_EXTRA_ARGUMENTS)
DATA_FFMPEG, CONF_INPUT, CONF_EXTRA_ARGUMENTS)
import homeassistant.helpers.config_validation as cv
from homeassistant.const import CONF_NAME
@@ -27,42 +29,66 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
def setup_platform(hass, config, add_devices, discovery_info=None):
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup a FFmpeg Camera."""
if not run_test(config.get(CONF_INPUT)):
if not hass.data[DATA_FFMPEG].async_run_test(config.get(CONF_INPUT)):
return
add_devices([FFmpegCamera(config)])
yield from async_add_devices([FFmpegCamera(hass, config)])
class FFmpegCamera(Camera):
"""An implementation of an FFmpeg camera."""
def __init__(self, config):
def __init__(self, hass, config):
"""Initialize a FFmpeg camera."""
super().__init__()
self._manager = hass.data[DATA_FFMPEG]
self._name = config.get(CONF_NAME)
self._input = config.get(CONF_INPUT)
self._extra_arguments = config.get(CONF_EXTRA_ARGUMENTS)
def camera_image(self):
@asyncio.coroutine
def async_camera_image(self):
"""Return a still image response from the camera."""
from haffmpeg import ImageSingle, IMAGE_JPEG
ffmpeg = ImageSingle(get_binary())
from haffmpeg import ImageFrame, IMAGE_JPEG
ffmpeg = ImageFrame(self._manager.binary, loop=self.hass.loop)
return ffmpeg.get_image(self._input, output_format=IMAGE_JPEG,
extra_cmd=self._extra_arguments)
image = yield from ffmpeg.get_image(
self._input, output_format=IMAGE_JPEG,
extra_cmd=self._extra_arguments)
return image
def mjpeg_stream(self, response):
@asyncio.coroutine
def handle_async_mjpeg_stream(self, request):
"""Generate an HTTP MJPEG stream from the camera."""
from haffmpeg import CameraMjpeg
stream = CameraMjpeg(get_binary())
stream.open_camera(self._input, extra_cmd=self._extra_arguments)
return response(
stream,
mimetype='multipart/x-mixed-replace;boundary=ffserver',
direct_passthrough=True
)
stream = CameraMjpeg(self._manager.binary, loop=self.hass.loop)
yield from stream.open_camera(
self._input, extra_cmd=self._extra_arguments)
response = web.StreamResponse()
response.content_type = 'multipart/x-mixed-replace;boundary=ffserver'
yield from response.prepare(request)
try:
while True:
data = yield from stream.read(102400)
if not data:
break
response.write(data)
except asyncio.CancelledError:
_LOGGER.debug("Close stream by frontend.")
response = None
finally:
yield from stream.close()
if response is not None:
yield from response.write_eof()
@property
def name(self):

View File

@@ -36,7 +36,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices([FoscamCamera(config)])
# pylint: disable=too-many-instance-attributes
class FoscamCamera(Camera):
"""An implementation of a Foscam IP camera."""

View File

@@ -4,10 +4,13 @@ Support for IP Cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.generic/
"""
import asyncio
import logging
import aiohttp
import async_timeout
import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
from requests.auth import HTTPDigestAuth
import voluptuous as vol
from homeassistant.const import (
@@ -15,7 +18,9 @@ from homeassistant.const import (
HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION)
from homeassistant.exceptions import TemplateError
from homeassistant.components.camera import (PLATFORM_SCHEMA, Camera)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers import config_validation as cv
from homeassistant.util.async import run_coroutine_threadsafe
_LOGGER = logging.getLogger(__name__)
@@ -35,13 +40,13 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup a generic IP Camera."""
add_devices([GenericCamera(hass, config)])
yield from async_add_devices([GenericCamera(hass, config)])
# pylint: disable=too-many-instance-attributes
class GenericCamera(Camera):
"""A generic implementation of an IP camera."""
@@ -49,6 +54,7 @@ class GenericCamera(Camera):
"""Initialize a generic camera."""
super().__init__()
self.hass = hass
self._authentication = device_info.get(CONF_AUTHENTICATION)
self._name = device_info.get(CONF_NAME)
self._still_image_url = device_info[CONF_STILL_IMAGE_URL]
self._still_image_url.hass = hass
@@ -58,10 +64,10 @@ class GenericCamera(Camera):
password = device_info.get(CONF_PASSWORD)
if username and password:
if device_info[CONF_AUTHENTICATION] == HTTP_DIGEST_AUTHENTICATION:
if self._authentication == HTTP_DIGEST_AUTHENTICATION:
self._auth = HTTPDigestAuth(username, password)
else:
self._auth = HTTPBasicAuth(username, password)
self._auth = aiohttp.BasicAuth(username, password=password)
else:
self._auth = None
@@ -69,9 +75,15 @@ class GenericCamera(Camera):
self._last_image = None
def camera_image(self):
"""Return bytes of camera image."""
return run_coroutine_threadsafe(
self.async_camera_image(), self.hass.loop).result()
@asyncio.coroutine
def async_camera_image(self):
"""Return a still image response from the camera."""
try:
url = self._still_image_url.render()
url = self._still_image_url.async_render()
except TemplateError as err:
_LOGGER.error('Error parsing template %s: %s',
self._still_image_url, err)
@@ -80,16 +92,41 @@ class GenericCamera(Camera):
if url == self._last_url and self._limit_refetch:
return self._last_image
kwargs = {'timeout': 10, 'auth': self._auth}
# aiohttp don't support DigestAuth yet
if self._authentication == HTTP_DIGEST_AUTHENTICATION:
def fetch():
"""Read image from a URL."""
try:
response = requests.get(url, timeout=10, auth=self._auth)
return response.content
except requests.exceptions.RequestException as error:
_LOGGER.error('Error getting camera image: %s', error)
return self._last_image
try:
response = requests.get(url, **kwargs)
except requests.exceptions.RequestException as error:
_LOGGER.error('Error getting camera image: %s', error)
return None
self._last_image = yield from self.hass.loop.run_in_executor(
None, fetch)
# async
else:
response = None
try:
websession = async_get_clientsession(self.hass)
with async_timeout.timeout(10, loop=self.hass.loop):
response = yield from websession.get(
url, auth=self._auth)
self._last_image = yield from response.read()
except asyncio.TimeoutError:
_LOGGER.error('Timeout getting camera image')
return self._last_image
except (aiohttp.errors.ClientError,
aiohttp.errors.DisconnectedError,
aiohttp.errors.HttpProcessingError) as err:
_LOGGER.error('Error getting new camera image: %s', err)
return self._last_image
finally:
if response is not None:
yield from response.release()
self._last_url = url
self._last_image = response.content
return self._last_image
@property

View File

@@ -4,9 +4,12 @@ Support for IP Cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.mjpeg/
"""
import asyncio
import logging
from contextlib import closing
import aiohttp
import async_timeout
import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
import voluptuous as vol
@@ -15,17 +18,21 @@ from homeassistant.const import (
CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_AUTHENTICATION,
HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION)
from homeassistant.components.camera import (PLATFORM_SCHEMA, Camera)
from homeassistant.helpers.aiohttp_client import (
async_get_clientsession, async_aiohttp_proxy_stream)
from homeassistant.helpers import config_validation as cv
_LOGGER = logging.getLogger(__name__)
CONF_MJPEG_URL = 'mjpeg_url'
CONF_STILL_IMAGE_URL = 'still_image_url'
CONTENT_TYPE_HEADER = 'Content-Type'
DEFAULT_NAME = 'Mjpeg Camera'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_MJPEG_URL): cv.url,
vol.Optional(CONF_STILL_IMAGE_URL): cv.url,
vol.Optional(CONF_AUTHENTICATION, default=HTTP_BASIC_AUTHENTICATION):
vol.In([HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION]),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
@@ -34,10 +41,11 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
@asyncio.coroutine
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup a MJPEG IP Camera."""
add_devices([MjpegCamera(config)])
yield from async_add_devices([MjpegCamera(hass, config)])
def extract_image_from_mjpeg(stream):
@@ -52,11 +60,10 @@ def extract_image_from_mjpeg(stream):
return jpg
# pylint: disable=too-many-instance-attributes
class MjpegCamera(Camera):
"""An implementation of an IP camera that is reachable over a URL."""
def __init__(self, device_info):
def __init__(self, hass, device_info):
"""Initialize a MJPEG camera."""
super().__init__()
self._name = device_info.get(CONF_NAME)
@@ -64,33 +71,74 @@ class MjpegCamera(Camera):
self._username = device_info.get(CONF_USERNAME)
self._password = device_info.get(CONF_PASSWORD)
self._mjpeg_url = device_info[CONF_MJPEG_URL]
self._still_image_url = device_info.get(CONF_STILL_IMAGE_URL)
def camera_stream(self):
"""Return a MJPEG stream image response directly from the camera."""
self._auth = None
if self._username and self._password:
if self._authentication == HTTP_BASIC_AUTHENTICATION:
self._auth = aiohttp.BasicAuth(
self._username, password=self._password
)
@asyncio.coroutine
def async_camera_image(self):
"""Return a still image response from the camera."""
# DigestAuth is not supported
if self._authentication == HTTP_DIGEST_AUTHENTICATION or \
self._still_image_url is None:
image = yield from self.hass.loop.run_in_executor(
None, self.camera_image)
return image
websession = async_get_clientsession(self.hass)
response = None
try:
with async_timeout.timeout(10, loop=self.hass.loop):
response = yield from websession.get(
self._still_image_url, auth=self._auth)
image = yield from response.read()
return image
except asyncio.TimeoutError:
_LOGGER.error('Timeout getting camera image')
except (aiohttp.errors.ClientError,
aiohttp.errors.ClientDisconnectedError) as err:
_LOGGER.error('Error getting new camera image: %s', err)
finally:
if response is not None:
yield from response.release()
def camera_image(self):
"""Return a still image response from the camera."""
if self._username and self._password:
if self._authentication == HTTP_DIGEST_AUTHENTICATION:
auth = HTTPDigestAuth(self._username, self._password)
else:
auth = HTTPBasicAuth(self._username, self._password)
return requests.get(self._mjpeg_url,
auth=auth,
stream=True, timeout=10)
req = requests.get(
self._mjpeg_url, auth=auth, stream=True, timeout=10)
else:
return requests.get(self._mjpeg_url, stream=True, timeout=10)
req = requests.get(self._mjpeg_url, stream=True, timeout=10)
def camera_image(self):
"""Return a still image response from the camera."""
with closing(self.camera_stream()) as response:
return extract_image_from_mjpeg(response.iter_content(1024))
with closing(req) as response:
return extract_image_from_mjpeg(response.iter_content(102400))
def mjpeg_stream(self, response):
@asyncio.coroutine
def handle_async_mjpeg_stream(self, request):
"""Generate an HTTP MJPEG stream from the camera."""
stream = self.camera_stream()
return response(
stream.iter_content(chunk_size=1024),
mimetype=stream.headers[CONTENT_TYPE_HEADER],
direct_passthrough=True
)
# aiohttp don't support DigestAuth -> Fallback
if self._authentication == HTTP_DIGEST_AUTHENTICATION:
yield from super().handle_async_mjpeg_stream(request)
return
# connect to stream
websession = async_get_clientsession(self.hass)
stream_coro = websession.get(self._mjpeg_url, auth=self._auth)
yield from async_aiohttp_proxy_stream(self.hass, request, stream_coro)
@property
def name(self):

View File

@@ -0,0 +1,109 @@
"""
Support for Nest Cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.nest/
"""
import logging
from datetime import timedelta
import requests
import homeassistant.components.nest as nest
from homeassistant.components.camera import (PLATFORM_SCHEMA, Camera)
from homeassistant.util.dt import utcnow
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['nest']
NEST_BRAND = 'Nest'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up a Nest Cam."""
if discovery_info is None:
return
camera_devices = hass.data[nest.DATA_NEST].cameras()
cameras = [NestCamera(structure, device)
for structure, device in camera_devices]
add_devices(cameras, True)
class NestCamera(Camera):
"""Representation of a Nest Camera."""
def __init__(self, structure, device):
"""Initialize a Nest Camera."""
super(NestCamera, self).__init__()
self.structure = structure
self.device = device
self._location = None
self._name = None
self._online = None
self._is_streaming = None
self._is_video_history_enabled = False
# Default to non-NestAware subscribed, but will be fixed during update
self._time_between_snapshots = timedelta(seconds=30)
self._last_image = None
self._next_snapshot_at = None
@property
def name(self):
"""Return the name of the nest, if any."""
return self._name
@property
def should_poll(self):
"""Nest camera should poll periodically."""
return True
@property
def is_recording(self):
"""Return true if the device is recording."""
return self._is_streaming
@property
def brand(self):
"""Return the brand of the camera."""
return NEST_BRAND
# This doesn't seem to be getting called regularly, for some reason
def update(self):
"""Cache value from Python-nest."""
self._location = self.device.where
self._name = self.device.name
self._online = self.device.online
self._is_streaming = self.device.is_streaming
self._is_video_history_enabled = self.device.is_video_history_enabled
if self._is_video_history_enabled:
# NestAware allowed 10/min
self._time_between_snapshots = timedelta(seconds=6)
else:
# Otherwise, 2/min
self._time_between_snapshots = timedelta(seconds=30)
def _ready_for_snapshot(self, now):
return (self._next_snapshot_at is None or
now > self._next_snapshot_at)
def camera_image(self):
"""Return a still image response from the camera."""
now = utcnow()
if self._ready_for_snapshot(now):
url = self.device.snapshot_url
try:
response = requests.get(url)
except requests.exceptions.RequestException as error:
_LOGGER.error("Error getting camera image: %s", error)
return None
self._next_snapshot_at = now + self._time_between_snapshots
self._last_image = response.content
return self._last_image

View File

@@ -1,16 +1,16 @@
"""
Support for the Netatmo Welcome camera.
Support for the Netatmo cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.netatmo/
https://home-assistant.io/components/camera.netatmo/.
"""
import logging
from datetime import timedelta
import requests
import voluptuous as vol
from homeassistant.util import Throttle
from homeassistant.const import CONF_VERIFY_SSL
from homeassistant.components.netatmo import CameraData
from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA)
from homeassistant.loader import get_component
from homeassistant.helpers import config_validation as cv
@@ -22,9 +22,8 @@ _LOGGER = logging.getLogger(__name__)
CONF_HOME = 'home'
CONF_CAMERAS = 'cameras'
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
vol.Optional(CONF_HOME): cv.string,
vol.Optional(CONF_CAMERAS, default=[]):
vol.All(cv.ensure_list, [cv.string]),
@@ -33,33 +32,46 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup access to Netatmo Welcome cameras."""
"""Setup access to Netatmo cameras."""
netatmo = get_component('netatmo')
home = config.get(CONF_HOME)
data = WelcomeData(netatmo.NETATMO_AUTH, home)
for camera_name in data.get_camera_names():
if CONF_CAMERAS in config:
if camera_name not in config[CONF_CAMERAS]:
continue
add_devices([WelcomeCamera(data, camera_name, home)])
verify_ssl = config.get(CONF_VERIFY_SSL, True)
import lnetatmo
try:
data = CameraData(netatmo.NETATMO_AUTH, home)
for camera_name in data.get_camera_names():
camera_type = data.get_camera_type(camera=camera_name, home=home)
if CONF_CAMERAS in config:
if config[CONF_CAMERAS] != [] and \
camera_name not in config[CONF_CAMERAS]:
continue
add_devices([NetatmoCamera(data, camera_name, home,
camera_type, verify_ssl)])
except lnetatmo.NoDevice:
return None
class WelcomeCamera(Camera):
"""Representation of the images published from Welcome camera."""
class NetatmoCamera(Camera):
"""Representation of the images published from a Netatmo camera."""
def __init__(self, data, camera_name, home):
"""Setup for access to the BloomSky camera images."""
super(WelcomeCamera, self).__init__()
def __init__(self, data, camera_name, home, camera_type, verify_ssl):
"""Setup for access to the Netatmo camera images."""
super(NetatmoCamera, self).__init__()
self._data = data
self._camera_name = camera_name
self._verify_ssl = verify_ssl
if home:
self._name = home + ' / ' + camera_name
else:
self._name = camera_name
self._vpnurl, self._localurl = self._data.welcomedata.cameraUrls(
camera_id = data.camera_data.cameraByName(camera=camera_name,
home=home)['id']
self._unique_id = "Welcome_camera {0} - {1}".format(self._name,
camera_id)
self._vpnurl, self._localurl = self._data.camera_data.cameraUrls(
camera=camera_name
)
self._cameratype = camera_type
def camera_image(self):
"""Return a still image response from the camera."""
@@ -67,47 +79,44 @@ class WelcomeCamera(Camera):
if self._localurl:
response = requests.get('{0}/live/snapshot_720.jpg'.format(
self._localurl), timeout=10)
else:
elif self._vpnurl:
response = requests.get('{0}/live/snapshot_720.jpg'.format(
self._vpnurl), timeout=10)
self._vpnurl), timeout=10, verify=self._verify_ssl)
else:
_LOGGER.error('Welcome VPN url is None')
self._data.update()
(self._vpnurl, self._localurl) = \
self._data.camera_data.cameraUrls(camera=self._camera_name)
return None
except requests.exceptions.RequestException as error:
_LOGGER.error('Welcome VPN url changed: %s', error)
_LOGGER.error('Welcome url changed: %s', error)
self._data.update()
(self._vpnurl, self._localurl) = \
self._data.welcomedata.cameraUrls(camera=self._camera_name)
self._data.camera_data.cameraUrls(camera=self._camera_name)
return None
return response.content
@property
def name(self):
"""Return the name of this Netatmo Welcome device."""
"""Return the name of this Netatmo camera device."""
return self._name
@property
def brand(self):
"""Camera brand."""
return "Netatmo"
class WelcomeData(object):
"""Get the latest data from NetAtmo."""
def __init__(self, auth, home=None):
"""Initialize the data object."""
self.auth = auth
self.welcomedata = None
self.camera_names = []
self.home = home
def get_camera_names(self):
"""Return all module available on the API as a list."""
self.update()
if not self.home:
for home in self.welcomedata.cameras:
for camera in self.welcomedata.cameras[home].values():
self.camera_names.append(camera['name'])
@property
def model(self):
"""Camera model."""
if self._cameratype == "NOC":
return "Presence"
elif self._cameratype == "NACamera":
return "Welcome"
else:
for camera in self.welcomedata.cameras[self.home].values():
self.camera_names.append(camera['name'])
return self.camera_names
return None
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Call the NetAtmo API to update the data."""
import lnetatmo
self.welcomedata = lnetatmo.WelcomeData(self.auth)
@property
def unique_id(self):
"""Return the unique ID for this sensor."""
return self._unique_id

View File

@@ -12,7 +12,8 @@ import shutil
import voluptuous as vol
from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA)
from homeassistant.const import (CONF_NAME, CONF_FILE_PATH)
from homeassistant.const import (CONF_NAME, CONF_FILE_PATH,
EVENT_HOMEASSISTANT_STOP)
from homeassistant.helpers import config_validation as cv
_LOGGER = logging.getLogger(__name__)
@@ -35,10 +36,10 @@ DEFAULT_TIMELAPSE = 1000
DEFAULT_VERTICAL_FLIP = 0
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_FILE_PATH): cv.isfile,
vol.Optional(CONF_FILE_PATH): cv.string,
vol.Optional(CONF_HORIZONTAL_FLIP, default=DEFAULT_HORIZONTAL_FLIP):
vol.All(vol.Coerce(int), vol.Range(min=0, max=1)),
vol.Optional(CONF_IMAGE_HEIGHT, default=DEFAULT_HORIZONTAL_FLIP):
vol.Optional(CONF_IMAGE_HEIGHT, default=DEFAULT_IMAGE_HEIGHT):
vol.Coerce(int),
vol.Optional(CONF_IMAGE_QUALITY, default=DEFAULT_IMAGE_QUALITIY):
vol.All(vol.Coerce(int), vol.Range(min=0, max=100)),
@@ -53,6 +54,13 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
def kill_raspistill(*args):
"""Kill any previously running raspistill process.."""
subprocess.Popen(['killall', 'raspistill'],
stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Raspberry Camera."""
if shutil.which("raspistill") is None:
@@ -75,11 +83,20 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
}
)
if not os.access(setup_config[CONF_FILE_PATH], os.W_OK):
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, kill_raspistill)
try:
# Try to create an empty file (or open existing) to ensure we have
# proper permissions.
open(setup_config[CONF_FILE_PATH], 'a').close()
add_devices([RaspberryCamera(setup_config)])
except PermissionError:
_LOGGER.error("File path is not writable")
return False
add_devices([RaspberryCamera(setup_config)])
except FileNotFoundError:
_LOGGER.error("Could not create output file (missing directory?)")
return False
class RaspberryCamera(Camera):
@@ -93,9 +110,7 @@ class RaspberryCamera(Camera):
self._config = device_info
# Kill if there's raspistill instance
subprocess.Popen(['killall', 'raspistill'],
stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT)
kill_raspistill()
cmd_args = [
'raspistill', '--nopreview', '-o', device_info[CONF_FILE_PATH],

View File

@@ -0,0 +1,263 @@
"""
Support for Synology Surveillance Station Cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.synology/
"""
import asyncio
import logging
import voluptuous as vol
import aiohttp
import async_timeout
from homeassistant.const import (
CONF_NAME, CONF_USERNAME, CONF_PASSWORD,
CONF_URL, CONF_WHITELIST, CONF_VERIFY_SSL)
from homeassistant.components.camera import (
Camera, PLATFORM_SCHEMA)
from homeassistant.helpers.aiohttp_client import (
async_get_clientsession, async_create_clientsession,
async_aiohttp_proxy_stream)
import homeassistant.helpers.config_validation as cv
from homeassistant.util.async import run_coroutine_threadsafe
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'Synology Camera'
DEFAULT_STREAM_ID = '0'
TIMEOUT = 5
CONF_CAMERA_NAME = 'camera_name'
CONF_STREAM_ID = 'stream_id'
QUERY_CGI = 'query.cgi'
QUERY_API = 'SYNO.API.Info'
AUTH_API = 'SYNO.API.Auth'
CAMERA_API = 'SYNO.SurveillanceStation.Camera'
STREAMING_API = 'SYNO.SurveillanceStation.VideoStream'
SESSION_ID = '0'
WEBAPI_PATH = '/webapi/'
AUTH_PATH = 'auth.cgi'
CAMERA_PATH = 'camera.cgi'
STREAMING_PATH = 'SurveillanceStation/videoStreaming.cgi'
CONTENT_TYPE_HEADER = 'Content-Type'
SYNO_API_URL = '{0}{1}{2}'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_URL): cv.string,
vol.Optional(CONF_WHITELIST, default=[]): cv.ensure_list,
vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup a Synology IP Camera."""
verify_ssl = config.get(CONF_VERIFY_SSL)
websession_init = async_get_clientsession(hass, verify_ssl)
# Determine API to use for authentication
syno_api_url = SYNO_API_URL.format(
config.get(CONF_URL), WEBAPI_PATH, QUERY_CGI)
query_payload = {
'api': QUERY_API,
'method': 'Query',
'version': '1',
'query': 'SYNO.'
}
query_req = None
try:
with async_timeout.timeout(TIMEOUT, loop=hass.loop):
query_req = yield from websession_init.get(
syno_api_url,
params=query_payload
)
query_resp = yield from query_req.json()
auth_path = query_resp['data'][AUTH_API]['path']
camera_api = query_resp['data'][CAMERA_API]['path']
camera_path = query_resp['data'][CAMERA_API]['path']
streaming_path = query_resp['data'][STREAMING_API]['path']
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
_LOGGER.exception("Error on %s", syno_api_url)
return False
finally:
if query_req is not None:
yield from query_req.release()
# Authticate to NAS to get a session id
syno_auth_url = SYNO_API_URL.format(
config.get(CONF_URL), WEBAPI_PATH, auth_path)
session_id = yield from get_session_id(
hass,
websession_init,
config.get(CONF_USERNAME),
config.get(CONF_PASSWORD),
syno_auth_url
)
# init websession
websession = async_create_clientsession(
hass, verify_ssl, cookies={'id': session_id})
# Use SessionID to get cameras in system
syno_camera_url = SYNO_API_URL.format(
config.get(CONF_URL), WEBAPI_PATH, camera_api)
camera_payload = {
'api': CAMERA_API,
'method': 'List',
'version': '1'
}
try:
with async_timeout.timeout(TIMEOUT, loop=hass.loop):
camera_req = yield from websession.get(
syno_camera_url,
params=camera_payload
)
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
_LOGGER.exception("Error on %s", syno_camera_url)
return False
camera_resp = yield from camera_req.json()
cameras = camera_resp['data']['cameras']
yield from camera_req.release()
# add cameras
devices = []
for camera in cameras:
if not config.get(CONF_WHITELIST):
camera_id = camera['id']
snapshot_path = camera['snapshot_path']
device = SynologyCamera(
hass,
websession,
config,
camera_id,
camera['name'],
snapshot_path,
streaming_path,
camera_path,
auth_path
)
devices.append(device)
yield from async_add_devices(devices)
@asyncio.coroutine
def get_session_id(hass, websession, username, password, login_url):
"""Get a session id."""
auth_payload = {
'api': AUTH_API,
'method': 'Login',
'version': '2',
'account': username,
'passwd': password,
'session': 'SurveillanceStation',
'format': 'sid'
}
auth_req = None
try:
with async_timeout.timeout(TIMEOUT, loop=hass.loop):
auth_req = yield from websession.get(
login_url,
params=auth_payload
)
auth_resp = yield from auth_req.json()
return auth_resp['data']['sid']
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
_LOGGER.exception("Error on %s", login_url)
return False
finally:
if auth_req is not None:
yield from auth_req.release()
class SynologyCamera(Camera):
"""An implementation of a Synology NAS based IP camera."""
def __init__(self, hass, websession, config, camera_id,
camera_name, snapshot_path, streaming_path, camera_path,
auth_path):
"""Initialize a Synology Surveillance Station camera."""
super().__init__()
self.hass = hass
self._websession = websession
self._name = camera_name
self._synology_url = config.get(CONF_URL)
self._camera_name = config.get(CONF_CAMERA_NAME)
self._stream_id = config.get(CONF_STREAM_ID)
self._camera_id = camera_id
self._snapshot_path = snapshot_path
self._streaming_path = streaming_path
self._camera_path = camera_path
self._auth_path = auth_path
def camera_image(self):
"""Return bytes of camera image."""
return run_coroutine_threadsafe(
self.async_camera_image(), self.hass.loop).result()
@asyncio.coroutine
def async_camera_image(self):
"""Return a still image response from the camera."""
image_url = SYNO_API_URL.format(
self._synology_url, WEBAPI_PATH, self._camera_path)
image_payload = {
'api': CAMERA_API,
'method': 'GetSnapshot',
'version': '1',
'cameraId': self._camera_id
}
try:
with async_timeout.timeout(TIMEOUT, loop=self.hass.loop):
response = yield from self._websession.get(
image_url,
params=image_payload
)
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
_LOGGER.exception("Error on %s", image_url)
return None
image = yield from response.read()
yield from response.release()
return image
@asyncio.coroutine
def handle_async_mjpeg_stream(self, request):
"""Return a MJPEG stream image response directly from the camera."""
streaming_url = SYNO_API_URL.format(
self._synology_url, WEBAPI_PATH, self._streaming_path)
streaming_payload = {
'api': STREAMING_API,
'method': 'Stream',
'version': '1',
'cameraId': self._camera_id,
'format': 'mjpeg'
}
stream_coro = self._websession.get(
streaming_url, params=streaming_payload)
yield from async_aiohttp_proxy_stream(self.hass, request, stream_coro)
@property
def name(self):
"""Return the name of this device."""
return self._name

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