Compare commits

...

1263 Commits
0.43.1 ... 0.52

Author SHA1 Message Date
Paulus Schoutsen
50e5032f86 Merge pull request #9131 from home-assistant/release-0-52
0.52
2017-08-25 22:11:12 -07:00
Martin Hjelmare
1d615ea6c3 Refactor mysensors callback and add validation (#9069)
* Refactor mysensors callback and add validation

* Add mysensors entity class. The mysensors entity class inherits from
  a more general mysensors device class.
* Extract mysensors name function.
* Add setup_mysensors_platform for mysensors platforms.
* Add mysensors const schemas.
* Update mysensors callback and add child validation.
* Remove gateway wrapper class.
* Add better logging for mysensors callback.
* Add discover_persistent_devices function.
* Remove discovery in mysensors component setup.
* Clean up gateway storage in hass.data.
* Update all mysensors platforms.
  * Add repr for MySensorsNotificationDevice.
  * Fix bug in mysensors climate target temperatures.
  * Clean up platforms. Child validation simplifies assumptions in
    platforms.
  * Remove not needed try except statements. All messages are validated
    already in pymysensors.
* Clean up logging.
* Add timer debug logging if callback is slow.
* Upgrade pymysensors to 0.11.0.

* Make dispatch callback async

* Pass tuple device_args and optional add_devices

* Also return new_devices as list instead of dictionary.
2017-08-25 21:47:22 -07:00
Paulus Schoutsen
2e1b1635b1 Version bump to 0.52 2017-08-25 08:44:02 -07:00
Paulus Schoutsen
fe7dca5144 Merge remote-tracking branch 'origin/master' into dev 2017-08-25 08:43:26 -07:00
Fabian Affolter
fdeef2f707 Use const (#9127)
* Use const

* Align quotes
2017-08-25 13:30:00 +02:00
PhracturedBlue
2ec0d25a38 optimistic mode for template covers (w/o timed movement) (#8402)
* Emulate set_current_position in cover.template

* Add opportunistic mode

* Prevent another move when cover is already moving.  Add tests for opotunistic/timed-delay mode

* Remove timed-move capabilities

* Set init state to unknown

* cleanup template

* Update test_template.py
2017-08-25 12:33:53 +02:00
Daniel Høyer Iversen
fb5019e73f refactor pushbullet (#9125)
* refactor push bullet
2017-08-25 11:25:06 +02:00
Daniel Høyer Iversen
1e276a7b07 Xiaomi (#9126)
* small fixes xiaomi
2017-08-25 10:22:32 +02:00
Daniel Høyer Iversen
d72a181e30 Update flux_led.py (#9122) 2017-08-24 23:31:57 +02:00
lekobob
698d133455 Simplisafe unknown status fix (#9111)
* Simplisafe unknown status fix

Changed simplisafe-python requirement to 1.0.5 and changed state return
case statements to lower case

* Bump requirements_all.txt
2017-08-24 08:09:50 +02:00
Jeroen ter Heerdt
0dccef4063 pythonegardia package requirement to .18 (#9104)
* Bumping pythonegardia package requirement up to .18

* Updating requirements_all to reflect updated pythonegardia package .18
2017-08-23 17:11:13 +02:00
Daniel Høyer Iversen
feb85b90b4 upgrade Xiaomi Gateway lib to 0.3 (#9101) 2017-08-23 12:37:17 +02:00
Robin
48909539be Fix issue 8894 with uk_transport component if no next_buses or next_trains (#9046)
* Fix bug if no next_buses or trains

Fixes https://github.com/home-assistant/home-assistant/issues/8894

* Requested fixes
2017-08-23 00:05:06 -07:00
Fabian Affolter
2355216f61 Catch exceptions (#9085)
* Catch exceptions

* Fix pylint disable

* Move check for emtpy target list
2017-08-22 22:21:09 -07:00
Teemu R
55a44b0a1c Yeelight fix updates on hsv mode (#9093)
* cast strings to integers for hsv_to_rgb conversion, fixes #6473

* remove type_checking, flake8 does not like that.

* use hsv_to_rgb to convert to correct rgb value
2017-08-22 22:19:33 -07:00
happyleavesaoc
27b0d648a6 bump fedex version (#9099) 2017-08-22 22:14:06 -07:00
happyleavesaoc
90724847a3 bump snapcast version (#9100) 2017-08-22 22:13:52 -07:00
Teemu R
90fb33f610 Support changing the bulb color for tplink smartbulbs, fixes #8766 (#8780)
* Support changing the bulb color for tplink smartbulbs, related to #8766

* existence of ATTR_RGB_COLOR in kwargs, not just its existence...

* return modified supported features

* rgb-hsv conversion utils from hass return bogus values (at least for this device), so doing conversions directly with colorsys

* add typing & documentation for color model conversions

* make linters happy

* cast hsv to integer before passing it to the backend library

* make sure the bulb is on before adjusting the other settings

* allow floats as inputs for conversions, return always integers

* use typing hint in the parameter list instead of at assignment

* do not assign local color state inside turn_on, but let update handle doing it

* use forward declaration for typing, fixes travis requirements build hopefully

* rename hsv and rgb

* remove type-checking check, forward declarations should work just fine without it

* disable (broken) pylint warnings, these can be removed after astroid is updated from 1.4.9 to 1.5
2017-08-22 22:11:44 -07:00
aetolus
cb59b3fee1 Add worldtidesinfo sensor component (#8860)
* Style fixes for worldtidesinfo sensor component

* Fix D202 for worldtidesinfo sensor component

* Multiple fixes

* Multiple fixes

* Fixes

* more

* working with changes

* changes

* changes

* fix style errors

* fix style errors

* Complete rewrite

* worldtidesinfo

Fix D202 for worldtidesinfo sensor component

Multiple fixes

Multiple fixes

Fixes

more

working with changes

changes

changes

fix style errors

fix style errors

Complete rewrite

PR Changes

* Fix

* fix scan interval & lint
2017-08-23 00:40:16 +02:00
Michaël Arnauts
90689c38f7 Fix netdata system_load and add disk_free. (#9091) 2017-08-22 17:52:29 +02:00
Jan Losinski
fd6fd765b2 Pilight switch: restore last state after restart (#8580)
* Pilight switch: restore last state after restart

This uses the restore_state helper to set the last known state to
pilight switches when the devices are initialized after a HA
restart.

Without this HA forget the state on every restart and needs to be told
the sttae by retoggling the switches. This can cause unwanted effects
as a switch toggling may emit an RF signal.

* Make hound happy

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

* Remove entity_id generation as requested in review.

* Make hound happy again.

* fix comments

* fix lint
2017-08-22 16:40:14 +02:00
William Scanlon
06a20d0d15 Fix octoprint errors when printer is off/disconnected (#8988)
* Fix octoprint errors when printer is off/disconnected
2017-08-22 09:37:06 -04:00
Fabian Affolter
252aea37d2 Don't redefine consts (#9086) 2017-08-22 13:12:01 +02:00
Alex
5a3a43cd5b 9043 Fixed error while running dev docker (#9044) 2017-08-22 13:48:50 +03:00
Fabian Affolter
dd0ca0adc4 Upgrade credstash to 1.13.3 (#9088) 2017-08-22 13:32:46 +03:00
Fabian Affolter
c77d2ea341 Remove dash (#9089) 2017-08-22 13:31:53 +03:00
Fabian Affolter
4a3be6d514 Upgrade youtube_dl to 2017.8.18 (#9079) 2017-08-22 10:26:31 +03:00
Max
da2cb8e97e Fix device attribute in fritz_callmonitor.py (fixes #9055) (#9081) 2017-08-22 10:24:36 +03:00
Fabian Affolter
42fcaf9a75 Upgrade discord.py to 0.16.10 (#9082) 2017-08-22 10:24:02 +03:00
Fabian Affolter
af8aec001c Upgrade uber_rides to 0.5.1 (#9080) 2017-08-22 10:23:11 +03:00
Tom Harris
f6c5e5ff00 Added insteonplm device_override multiple capabilities (#9078) 2017-08-22 10:22:37 +03:00
Erik Eriksson
398735c9be async_query returns False if connection to server failed, handle this properly (#9070) 2017-08-22 07:09:11 +02:00
Alok Saboo
8ceeee032c Bump abodepy to 0.7.1 (#9077)
* Version bump to 0.7.1

* Update abodepy version
2017-08-22 07:08:27 +02:00
Nolan Gilley
54f01f3f11 bump python-ecobee-api version to 0.0.8 (#9074) 2017-08-21 23:16:17 +02:00
Alok Saboo
bc549e9525 Use builtin constants for Abode alarm_control_panel (#9059)
* Use builtin constants for alarm_control_panel

* Made it consistent with other alarm panels

* Replaced STATE_UNKNOWN with None
2017-08-21 22:20:38 +02:00
Erik Eriksson
4bb78097a7 eliqonline: channel id is an integer (#9072) 2017-08-21 21:57:12 +02:00
Ståle Semb Hauknes
7c380588a0 Workday sensor offset (#8824)
* Add support for offset for the workday sensor

* Update tests for workday sensor

* Changed from 'offset' to 'days_offset'

* Attributes bugfix (dictionary key variable repeated with different values)
2017-08-21 13:24:30 +02:00
Fabian Affolter
f7daefd7a5 Upgrade onkyo-eiscp to 1.2.4 (fixes #8995) (#9068) 2017-08-21 11:25:34 +02:00
Martin Berg
97e6a69adb Add support for Prowl notifications. (#9028)
* Add support for Prowl notifications.

* Use HA session handler.

* Simplify http request logic.

* flake

* fix double fetch data

* Remove periods from log messages
2017-08-21 10:46:07 +02:00
Fabian Affolter
fe7384a4ef Upgrade slacker to 0.9.60 (#9065)
* Upgrade slacker to 0.9.60

* Group imports
2017-08-21 10:23:29 +02:00
Fabian Affolter
3c9e09ce16 Upgrade sendgrid to 5.0.0 (#9062) 2017-08-21 07:15:37 +02:00
Matt Schmitt
c3d548a0dd Update fitbit.py (#9064)
Minor format update, set ‘type’ attribute to lowercase (Fitbit returns
all uppercase currently)
2017-08-21 07:15:15 +02:00
Alok Saboo
ebd64cded9 Bump dlib face_recognition to 0.2.2 (#9060) 2017-08-20 22:30:35 +02:00
Anders Melchiorsen
fee89d8d16 LIFX: avoid rare NoneType errors (#9054)
* Get full multizone state during registration

We used to rely on the periodic update to get the state of each zone, only
establishing the number of zones during registration. This resulted in errors
if the current state was needed for a partial color change before the first
async_update happened.

Now we do a full update before adding the light. Thus async_update can no
longer assume device.color_zones to be defined and must instead use the
response message to decide the total number of zones.

* Insist on getting the initial state

If a response to the initial state query is lost we used to just carry on.
This resulted in type errors when we next tried to access the undefined state.

After this commit the light is not added before we have the full state.

This scenario mostly happens when something is misbehaving and the type errors
were actually useful in figuring out what happend. So an error message is
logged in their place.

* Remove lint
2017-08-20 20:29:54 +02:00
Alok Saboo
b3d16e8f89 Add Abode home security component (#9030)
* Add Abode home security component

* Remove protected member

* Remove debug messages

* Remove unwanted debug messages

* Updated based on script/gen_requirements_all

* Commit to restart the build process

* Remove unwanted return

* Removed unused listener

* Address Pascal's comments

* Updated alarm control panel based on Pascal's comments

* Removed debug messages

* Removed unused hass object
2017-08-20 16:55:48 +02:00
Matt Schmitt
c059dfdb67 Update Fitbit sensor (icons, formatting, client update) (#9031)
* Update fitbit.py

Add variable icon for battery status, clean up formatting for resource
names and values

* Update fitbit.py and requirements_all.txt

Fix PR comments and update client

* Update fitbit.py

Add dict map for battery levels and use icon util
2017-08-19 22:47:31 +02:00
boojew
d153ee0b9f Add speeds to fan dropdown in ISY fan component (#9004)
* Add speeds to fan dropdown in ISY fan component

* Update isy994.py

* Update isy994.py

* Update isy994.py

* Update isy994.py

* Update isy994.py

* Update isy994.py

* Update isy994.py

* Update isy994.py
2017-08-19 21:17:47 +02:00
David
0f9ae8827c Upgrade python-pushover to 0.3 (#9045)
* Upgrade python-pushover

* Upgrade python-pushover
2017-08-19 17:00:07 +02:00
Steve
5d52993231 Support Windows in UPNP discovery (#8936)
* Support WIndows and Linix

* Correct indentation

* reduce line length

* Lint
2017-08-19 15:26:27 +02:00
Matt Schmitt
84025e46ff Update ios.py (#9041)
Use battery icon util for charging condition also
2017-08-19 15:24:13 +02:00
Sören Oldag
bf66019c66 Configurable timeout for webostv. (#9042)
* Configurable timeout for webostv.

* Make PEP257 validation to pass
2017-08-19 15:14:02 +02:00
Sören Oldag
a748b5ee5e Update pwmled to 1.2.1. (#9040) 2017-08-19 13:23:46 +02:00
Robin
98370560e1 Adds London_air component (#9020)
* Adds London_air component

* Fix lints

* Reduce fixture

* Fix config validate

* Fix naming

* fix tests
2017-08-19 11:05:16 +02:00
Matt Schmitt
597f53ae30 Update iOS sensor (battery icon fix and format updates) (#9032)
* Update ios.py

Clean up battery and charging icons (MDI was missing some versions),
fix minor bug when battery level = 95%

* Update ios.py

Migrated function to battery icon util
2017-08-19 10:59:54 +02:00
Steven Looman
7ac1e469b7 Set password after connecting. Fixes #8983 (#9039) 2017-08-19 10:58:42 +02:00
John Mihalic
ecc249aa27 Refactor USPS into component with Sensors+Camera (#8679)
* Inital USPS Camera expansion

* Cleanup debugging, add camera change interval

* Change to local nomail image

* Explicitly pass in date

* Move camera date info to model property

* Fix copy typo

* Fix hound line-length

* Fix lint whitespace

* Fix requirements

* Bump myusps version, clarify interval, alter update scheme

* Add units

* Code cleanup, address comments

* Use built-in scan interval, remove nomail image

* Remove logging line
2017-08-18 23:47:36 +02:00
celeroll
6215e27de4 Fix Geizhals index issue when not 4 prices available (#9035)
* Out of index issue, when not 4 prices are available

* Removed the parenthesis, to fix the lint error.
2017-08-18 19:59:20 +02:00
Paulus Schoutsen
b282167f26 Add state_with_unit property to state objects in templates (#9014)
* Wrap state objects in templates

* Fix tests

* Fix bugs

* Lint

* Remove invalid state warning
2017-08-17 23:19:35 -07:00
Pascal Vizeli
c278209c7b Update ffmpeg to 1.7 to fix severals problems (#9029)
* Update ffmpeg to 1.7 to fix severals problems

* Update ffmpeg.py

* Update requirements_test_all.txt
2017-08-18 00:51:52 +02:00
Tom Matheussen
427d7ee1fc Check if album image(s) exist in spotify (#9024)
* Check if album image(s) exist in spotify

* Actually set the image to None

* Simplified using ternary operator
2017-08-17 22:39:20 +02:00
Dan
55234a7fa3 Update onkyo-eiscp to 1.2.3 (#9019) 2017-08-16 21:51:03 -07:00
BioSehnsucht
3765f882c7 Add HipChat notify service. (#8918)
* Add HipChat notify service.

* Change HipChat notify service to use python-simple-hipchat-v2.

* Change HipChat notify service to use hipnotify

* Change HipChat notify service to remove redundant validation
2017-08-16 19:26:30 -04:00
Michael Hertig
b75ce4f1b2 Fix #9010 - Swiss Public Transportation shows departure time in the past (#9011) 2017-08-16 21:28:51 +02:00
Dan Cinnamon
95663f8126 Update to pyenvisalink 2.2, and remove range validation on zonedump i… (#8981)
* Update to pyenvisalink 2.2, and remove range validation on zonedump interval.

* Keep using default timer dump variable, only remove minimum check.

* Fix lint issue

* Indentation issue
2017-08-16 12:08:15 +02:00
karlkar
f114263845 Pushbullet, fix multiple messages sent when url param is set (#9006) 2017-08-16 09:29:42 +02:00
mjj4791
e7ce110dc6 Buienradar newconditions (#8897)
* new monitored conditions and support for new weathercard

* new monitored conditions and support for new weathercard

* minor changes
2017-08-15 23:07:04 -07:00
timstanley1985
3342db33e4 MQTT Switch - Add configurable availability payload (#8934)
* Add configurable availabilty payload

* Fix

* Fix

* Lint fixes

* Fix tests

* Fix tests

* Move from const.py to mqtt switch

* New test

* Fix flake*
2017-08-15 23:04:57 -07:00
Paulus Schoutsen
0fb281c5b3 Update frontend 2017-08-15 22:34:46 -07:00
Paulus Schoutsen
2dab239021 Add scripts editor backend (#8993)
* Add scripts editor backend

* Fix docstrings
2017-08-15 22:09:10 -07:00
Adam Mills
95c57412ff Automatic device tracker remove password (#9002)
* Remove now disabled password auth from automatic

* Fallback to configurator more permissively

* Fix test for changes

* Bump lib
2017-08-15 21:04:44 -04:00
Aaron Bach
eb42d59210 Adds port/SSL config options for RainMachine (#8986)
* Adding port/SSL config updates

* New requirements generated

* Made `port` and `ssl` parameters optional

* Add defaults for new parameters

* Re-adding guard clause

* pass > continue
2017-08-15 20:03:40 +02:00
Tim Lyakhovetskiy
6507cc1dc8 Fix #8960 - Decora Wi-Fi Switch unable to set brightness (#8989) 2017-08-15 16:12:16 +02:00
Daniel Høyer Iversen
1892eb654f Is_allowed_path raise for None path (#8953)
* is_allowed_path

* Fix #8948

* assert path is not None

* Update test_core.py

* Update test_core.py

* Update test_core.py
2017-08-15 15:41:37 +02:00
Jack
5309006494 Added continue-on-errors, added value template (#8971)
* Added continue-on-errors, added value template

* Refactored long lines

* Fixed whitespace issues
2017-08-14 16:31:06 +02:00
Philipp Schmitt
e2920ce5e5 Nello.io lock support (#8957)
* Initial Nello.io lock support

* Log an error when unlocking failed

* Make the lock's state always locked
2017-08-14 10:02:37 +02:00
Adam Mills
19d1d748d4 Add support for Automatic OAuth2 authentication (#8962)
* Add support for Automatic OAuth2 authentication

* Fix async conversion of configurator

* Rename method for async

* Use hass.components to get configurator component

* Fix typo

* Move session data to hidden directory

* Make configurator callback optional
2017-08-13 22:37:50 -07:00
Paulus Schoutsen
8d661f8dea Merge pull request #8980 from home-assistant/release-0-51-2
0.51.2
2017-08-13 22:18:05 -07:00
Paulus Schoutsen
9363b189ba Sabnzbd: do not assume discovery info is a dict (#8951) 2017-08-13 21:54:21 -07:00
Eugenio Panadero
4da876e5c2 fix DeviceException handling when updating xiaomi vacuum (#8954)
* Fix DeviceException handling when updating entity

* add DeviceException error handling to generic request
2017-08-13 21:54:21 -07:00
Martin Hjelmare
335008ae5c Fix call to ha_send_commands (#8956)
* Name keyword arguments correctly according to dependency lib.
* Only pass keyword arguments that are not None.
2017-08-13 21:54:20 -07:00
Paulus Schoutsen
a4da31b573 fix issue #8948 in pushbullet (#8965)
* fix issue #8948 in pushbullet

* pushbullet
2017-08-13 21:54:20 -07:00
Andrey
cd795489ca Turn foscam verbose mode off (#8967) 2017-08-13 21:54:20 -07:00
Andrey
a8a037db49 Fix zwave power_consumption attribute (#8968) 2017-08-13 21:54:19 -07:00
Paulus Schoutsen
fc8e8e5d8c Update frontend 2017-08-13 21:53:26 -07:00
Paulus Schoutsen
56597d290c Version bump to 0.51.2 2017-08-13 21:53:22 -07:00
Paulus Schoutsen
8fcec03adf Update frontend 2017-08-13 21:52:36 -07:00
Andrey
a0ddb24245 Turn foscam verbose mode off (#8967) 2017-08-13 18:16:38 -07:00
Andrey
23273d3e88 Fix zwave power_consumption attribute (#8968) 2017-08-13 18:15:59 -07:00
Paulus Schoutsen
74adebc2fd fix issue #8948 in pushbullet (#8965)
* fix issue #8948 in pushbullet

* pushbullet
2017-08-13 13:28:36 -07:00
Paulus Schoutsen
4b3a932d88 Sabnzbd: do not assume discovery info is a dict (#8951) 2017-08-13 11:29:48 -07:00
Martin Hjelmare
cbe5225e04 Fix call to ha_send_commands (#8956)
* Name keyword arguments correctly according to dependency lib.
* Only pass keyword arguments that are not None.
2017-08-13 11:28:33 -07:00
Matt Schmitt
811fdc5533 Add service to alarm control panel for night mode arming (#8614)
* Update const.py

* Update __init__.py

* Update services.yaml

* Update totalconnect.py

* Update manual.py

Add night arm service for manual alarm control panel

* Update test_manual.py

Add tests for night mode arming

* Update manual.py

Fix docstring
2017-08-13 19:57:48 +02:00
Eugenio Panadero
c92e5c147a fix DeviceException handling when updating xiaomi vacuum (#8954)
* Fix DeviceException handling when updating entity

* add DeviceException error handling to generic request
2017-08-13 15:02:48 +02:00
Sebastian Muszynski
73d6227021 Remove spaces from Xiami switch attributes (#8952)
* Attributes of the xiaomi zigbee plug changed.

* Reformat.
2017-08-13 09:54:43 +02:00
Alok Saboo
79f45b5176 Fixed cert_expiry sensor to delay firing on HA startup (#8920)
* Fixed cert_expiry sensor to delay firing on HA startup

* Addressed Travis complaints

* Added imports

* Fixed cert_expiry sensor to delay firing on HA startup

* Changed comment
2017-08-12 23:49:15 -07:00
Paulus Schoutsen
b18679ec0b Merge pull request #8942 from home-assistant/release-0-51-1
0.51.1
2017-08-12 14:59:38 -07:00
Paulus Schoutsen
7d566c2c3d Version bump to 0.51.1 2017-08-12 14:56:34 -07:00
Paulus Schoutsen
46d9d77d03 Update frontend 2017-08-12 14:56:24 -07:00
Paulus Schoutsen
4a98b32a03 Update frontend 2017-08-12 14:54:50 -07:00
Paulus Schoutsen
adbcbe3a67 Merge pull request #8919 from home-assistant/release-0-51
0.51
2017-08-12 11:31:30 -07:00
Martin Hjelmare
eef3dda1e9 Fix SET_TEMPERATURE_SCHEMA in climate component (#8879)
* Require either temperature or high/low target temperatures.
* Add tests.
2017-08-12 10:57:10 -07:00
William Scanlon
08899ade00 Update python-wink version to fix Dome water valve bug. (#8923) 2017-08-12 10:57:10 -07:00
Philipp Schmitt
5814fdadd0 Update roombapy to 1.3.1 to avoid installing all the mapping dependencies (#8925) 2017-08-12 10:57:09 -07:00
cribbstechnologies
daf7d9ea7f fixing emulated hue issue and testing it (#8928)
* fixing emulated hue issue and testing it

* fixing hound issues

* I should probably stop using vim

* Check against dict directly instead of items.
2017-08-12 10:57:09 -07:00
Martin Hjelmare
956543ae1e Remove not needed call to update (#8930)
* This will ensure no I/O in entity properties.
2017-08-12 10:57:09 -07:00
Martin Hjelmare
fbb6782081 Fix SET_TEMPERATURE_SCHEMA in climate component (#8879)
* Require either temperature or high/low target temperatures.
* Add tests.
2017-08-12 09:39:05 -07:00
cribbstechnologies
369caeedbd fixing emulated hue issue and testing it (#8928)
* fixing emulated hue issue and testing it

* fixing hound issues

* I should probably stop using vim

* Check against dict directly instead of items.
2017-08-12 08:50:02 -07:00
groth-its
489a02b2c2 Fix hue lights for Philips and non-philips lights (#8905) 2017-08-12 08:38:12 -07:00
Fabian Affolter
c4550d02c5 Add version sensor (#8912)
* Add version sensor

* Set version directly

* Rework tests and fix typo

* Remove additional blank line
2017-08-12 08:52:56 +02:00
Martin Hjelmare
49733b7fdf Remove not needed call to update (#8930)
* This will ensure no I/O in entity properties.
2017-08-11 19:55:57 -07:00
Philipp Schmitt
0999e2ddc4 Update roombapy to 1.3.1 to avoid installing all the mapping dependencies (#8925) 2017-08-11 11:22:22 +02:00
William Scanlon
d427063acd Update python-wink version to fix Dome water valve bug. (#8923) 2017-08-11 08:35:45 +02:00
Fabian Affolter
ff3a4637a4 Version bump to 0.52.0.dev0 2017-08-10 23:28:04 +02:00
Fabian Affolter
8523aaca64 Prepare for release 2017-08-10 23:26:19 +02:00
Fabian Affolter
e3236d1a3b Honor PEP8 naming convention (#8909)
* Honor PEP8 naming convention

* Update validator
2017-08-10 19:31:28 +02:00
Marcus Schmidt
d7e8616651 Added possibilities to use template in the command_line sensor (#8505)
* Added possibilities to use template in the command_line sensor

* Minor style guideline conforms

* Minor style guideline conforms

* Added new test for template rendering

* Minor style guideline conforms

* Minor style guideline conforms

* Fixed failing testcases

* Fix style violations

* fix code pretty
2017-08-10 18:52:52 +02:00
Fabian Affolter
c0663bf722 Add Shodan sensor (#8902) 2017-08-10 17:27:49 +02:00
Abílio Costa
d195fd47f7 Add new device tracker for Huawei Routers. (#8488)
* Add new device tracker for Huawei Routers.

	This was tested with the HG8247H model, used by Vodafone
	Portugal for the Fiber service.

* add to .coveragerc; remove import and space

* add comments and fix lint

* rename methods

* huawei_router: add constants to scanner class

* huawei_router: remove lock; use format() in string

* huawei_router: use tupple instead of member only class

* huawei_router: reduce min scan time

* huawei_router: lint

* huawei_router: lint

* huawei_router: add missing lines in imports

* huawei_router: correctly decode string after router firmware update

* Remove things that is done on core now
2017-08-10 17:01:52 +02:00
Erik Eriksson
e84ff61d4a Support media position and media duration (will display progressbar in ui) (#8904) 2017-08-10 16:56:34 +02:00
Anders Melchiorsen
317bc10ccb LIFX: improve performance of multi-light transitions (#8873)
* LIFX: improve performance of multi-light transitions

To avoid hub overload, the light.turn_on call will change each light
sequentially.

As LIFX has no hub we can safely increase performance by starting all
light transitions concurrently.

* Improve state updates after light changes

The light.turn_on call will set a new state and then immediately read it
back. However, reading the state of a LIFX light right after a state
change can still return the old value.

To handle this situation we have previously delayed the update request a
little while to allow a potential state change to settle. Because light
updates are now run in parallel, this delay might be too short when many
lights are set at once.

This commit introduces a per-light Lock to make it explicit when the
state cannot yet be trusted.

We must then do the state update ourselves. This was already done at the
end of a long transition and that code can be reused for also doing the
update at the start of a transition.
2017-08-10 10:29:04 +02:00
William Scanlon
1cb42087f9 Update simplisafe-python version (#8908) 2017-08-10 07:58:39 +02:00
karlkar
b035577cf5 Fix for Neato D3 Connected state obtaining (#8817) 2017-08-09 23:22:08 +02:00
Paulus Schoutsen
55c84eaee3 Update frontend 2017-08-09 00:47:29 -07:00
kfcook
eb6017e16c added support for setting/getting position of lutron caseta covers (#8898) 2017-08-09 06:57:32 +02:00
PhracturedBlue
19ee3c42b6 Add longer text strings to mailbox demo to test string truncation (#8893)
* Add longer text strings to mailbox demo to test string truncation in frontend

* Remove lorem ipsum txt file

* Use format instead of %
2017-08-08 23:37:16 +02:00
Aaron Bach
af70054692 Changed Pi-hole graphs from stacked bar to line (#8896) 2017-08-08 22:57:35 +02:00
Fabian Affolter
be94f6e939 Do not call update() in constructor (#8892) 2017-08-08 22:36:59 +02:00
Fabian Affolter
f513f6271e Do not call update() in constructor (#8878)
* Do not call update() in constructor

* Fix lint issues
2017-08-08 20:21:33 +02:00
Alexey
588b36dff2 Fix media_extractor for some sites (#8887) 2017-08-08 15:21:32 +02:00
Fabian Affolter
cc5893ed8b Upgrade youtube_dl to 2017.8.6 (#8880) 2017-08-08 11:53:19 +02:00
Fabian Affolter
124a6cc8c0 Change level (#8883) 2017-08-08 11:53:04 +02:00
Fabian Affolter
0fe4245620 Allow usage of colorlog 3.0.1 (#8885) 2017-08-08 10:16:04 +02:00
Aaron Bach
289c88ff71 Add RainMachine switch platform (#8827)
* Add RainMachine switch platform

* Updated requirements_all.txt

* Cleaning up CI and coverage results

* Small update to deal with older pylint

* Fixed small indentation-based error

* Added some more defensive try/except logic around calls

* I'm not a fan of importing a library multiple times :)

* Making PR-requested changes

* Fixed ref to positional parameter

* Attempting to fix broken linting

* Ignoring no-value-for-parameter pylint error
2017-08-08 09:49:25 +02:00
Fabian Affolter
57f3bed465 Do not call update() in constructor (#8881) 2017-08-08 06:52:27 +02:00
Oleksii Serdiuk
62e86270e6 RFLink: Add send_command service (#8876)
Add an optional extended description…
2017-08-07 17:37:30 +02:00
Philipp Schmitt
3aceca9d8a Add nuki lock'n'go and unlatch services and add attributes (#8687)
* Add lock'n'go service

* Add unlatch service

* Implement changes requested by @MartinHjelmare

* Fix service domain
2017-08-07 14:58:31 +02:00
Philipp Schmitt
e81b3f7bc0 Implement Roomba fan speed (#8863)
* Implement Roomba fanspeed

* Fix: fan_speed_list is always empty

* Log instead of raising an exception when incorrect fan speed has been provided

* Don't attempt to set any preference if fan speed is invalid
2017-08-06 23:43:33 +02:00
Andy Castille
cc6c2bf25e Fix spelling error and update link (#8869) 2017-08-06 21:18:44 +02:00
Paulus Schoutsen
9575cbde09 Consolidate config panels (#8857)
* Remove automation panel registration

* Move Z-Wave config API to config.zwave

* Remove no longer needed test

* Lint

* Update frontend
2017-08-06 12:05:34 -07:00
Paulus Schoutsen
4e79517971 Update mailbox panel icon 2017-08-06 11:51:58 -07:00
Tim Lyakhovetskiy
4ec4cfc44e Add Leviton Decora Smart WiFi Device Platform (#8529)
* Add Leviton Decora Smart WiFi Device Platform

* Decora WiFi Code Review Fixes
2017-08-06 11:30:28 -07:00
PhracturedBlue
d74f4eaf52 Add Initial Mailbox panel and sensor (#8233)
* Initial implementation of Asterisk Mailbox

* Rework asterisk_mbox handler to avoid using the hass.data hash.  Fix requirements.

* Handle potential asterisk server disconnect.  bump asterisk_mbox requirement to 0.4.0

* Use async method for mp3 fetch from server

* Add http as dependency

* Minor log fix. try to force Travis to rebuild

* Updates based on review

* Fix error handling as per review

* Fix error handling as per review

* Refactor voicemail into mailbox component

* Hide mailbox component from front page

* Add demo for mailbox

* Add tests for mailbox

* Remove asterisk_mbox sensor and replace with a generic mailbox sensor

* Fix linting errors

* Remove mailbox sensor.  Remove demo.mp3.  Split entity from platform object.

* Update mailbox test

* Update mailbox test

* Use events to indicate state change rather than entity last-updated

* Make mailbox platform calls async.  Fix other review concerns

* Rewrite mailbox tests to live at root level and be async.  Fixmailbox dependency on http

* Only store number of messages not content in mailbox entity
2017-08-06 11:19:47 -07:00
Paulus Schoutsen
5696e38dd6 Warn instead of raise on duplicate YAML key (#8834)
* Warn instead of raise on duplicate key

* Update test_yaml.py

* Lint

* Change to error
2017-08-06 10:47:19 -07:00
Eugenio Panadero
c6aaacbb08 Add new service clean_spot to vacuums (#8862)
* Add new service `clean_spot` to vacuums

    - Add as base component service, with associated support flag to make it optional
    - Implement on Demo vacuum
    - Implement on Xiaomi vacuum
    - Update tests for platforms Demo and Xiaomi
    - Change default icon for vacuums to `mdi:roomba`, but keep the one for the Xiaomi
    - (In a polymer PR: add new service to command toolbar in the 'more-info' card)

* Add `clean_spot` service description

* fix default properties for vacuum component
2017-08-06 10:23:22 -07:00
Fabian Affolter
d8ca04a4bc Do not call update() in constructor (#8859) 2017-08-06 10:21:55 -07:00
Paulus Schoutsen
ac9c1235bb Allow get local ip to work without internet (#8855) 2017-08-06 09:15:17 -07:00
Andrey Kupreychik
c49cce7243 Do not use pychromecast.Chromecast for Cast Groups (#8786)
* Do not use pychromecast.Chromecast for Cast Groups

pychromecast.Chromecast creates Chromecast instance with friendly_name and cast_type of the device and not of a group.
Which leads to collisions

* Update cast.py

* using hass.data

* Fixed and extended tests

* Line length in tests

* Lint in tests
2017-08-06 09:15:01 -07:00
John Arild Berentsen
99a20c845c Fix off_delay for zwave trigger sensors (#8864) 2017-08-06 18:31:32 +03:00
Kevin Fronczak
3723f67dc1 Added rounding to Google Wifi (#8866) 2017-08-06 18:29:52 +03:00
Fabian Affolter
b655fe6e04 Allow to set coordinates (#8858) 2017-08-06 15:20:51 +02:00
Fabian Affolter
24e9fa238a Upgrade pyasn1 to 0.3.2 and pyasn1-modules to 0.0.11 (#8856) 2017-08-06 15:20:13 +02:00
Charles Blonde
83afd12807 Add support to Dyson 360 Eye robot vacuum using new vacuum platform (#8852)
* Add support to Dyson 360 Eye robot vacuum using new vacuum platform

* Fix tests with Python 3.5

* Code review

* Code review - v2

* Code review - v3
2017-08-06 13:08:46 +02:00
Philipp Schmitt
82a7dffc03 Wi-Fi enabled Roomba support (#8825)
* Roomba vacuum component

* Update requirements and coveragerc

* Update error handling message

* Implement changes requested by @azogue

* Add missing import

* Don't wrap commands with functools.partial

* Refactoring

* Remove state attribute and use double quotes for log messages strings

* Remove unused constants

* Sorting

* Sorting + remove None arg from dict.get() calls

* Re-sort imports
2017-08-06 11:08:45 +02:00
Fabian Affolter
c11b6798dc Upgrade pylast to 1.9.0 (#8854) 2017-08-06 10:08:45 +02:00
Fabian Affolter
8e4c799ad1 Upgrade sqlalchemy to 1.1.13 (#8850) 2017-08-06 10:08:24 +02:00
Fabian Affolter
5059d4c54b Catch ConnectionRefusedError (#8844)
* Do not call update() in constructor

* Catch ConnectionRefusedError
2017-08-06 10:08:00 +02:00
Fabian Affolter
569d9764ab Do not call update() in constructor (#8847) 2017-08-06 10:07:45 +02:00
Fabian Affolter
058deb5be3 Make 'monitored_conditions' optional (#8848)
* Do not call update() in constructor

* Update tests
2017-08-06 10:07:22 +02:00
Fabian Affolter
cd36a71f64 Do not call update() in constructor (#8849)
* Do not call update() in constructor

* Fix pylint issues
2017-08-06 10:07:05 +02:00
Fabian Affolter
6832a2e642 Make 'monitored_conditions' optional (#8843)
* Do not call update() in constructor

* Make 'monitored_conditions' optional

* Update tests
2017-08-06 10:05:37 +02:00
Fabian Affolter
2c7b2fe19e Do not call update() in constructor (#8840) 2017-08-06 10:03:57 +02:00
Fabian Affolter
45ec7f6180 Upgrade sendgrid to 4.2.1 (#8839) 2017-08-06 10:03:32 +02:00
Fabian Affolter
cb8517834a Do not call update() in constructor. (#8837) 2017-08-06 10:03:09 +02:00
Jeroen ter Heerdt
f41ef5d727 Egardia (#8389)
* Added support for Egardia / Woonveilig alarm control panel

* Added support for Egardia / Woonveilig alarm control panel

* Added support for Egardia / Woonveilig alarms

* Updating egardia support with exception handling and other fixes

* Egardia platform, requirements file updated

* Fixing state checking

* Adding exception handling

* Removing unnecessary logging

* Removing unnecessary logging

* Updating to egardiadevice component 1.0.10

* Improving exception handling

* Adding implementation of egardiaserver for alarm triggered status

* Clean-up

* Fix my previous change
2017-08-05 22:04:00 +02:00
Eugenio Panadero
a221b10694 Update xiaomi vacuum tests and include in coverage (#8845)
* Fix tests for Demo vacuum platform (and increase coverage)

* increase coverage of xiaomi vacuum tests and include in coverage

Also little fixes

* remove print statement
2017-08-05 21:45:59 +02:00
Greg Laabs
6e1785173f History query and schema optimizations for huge performance boost (#8748)
* Add DEBUG-level log for db row to native object conversion

This is now the bottleneck (by a large margin) for big history queries, so I'm leaving this log feature in to help diagnose users with a slow history page

* Rewrite of the "first synthetic datapoint" query for multiple entities

The old method was written in a manner that prevented an index from being used in the inner-most GROUP BY statement, causing massive performance issues especially when querying for a large time period.

The new query does have one material change that will cause it to return different results than before: instead of using max(state_id) to get the latest entry, we now get the max(last_updated). This is more appropriate (primary key should not be assumed to be in order of event firing) and allows an index to be used on the inner-most query. I added another JOIN layer to account for cases where there are two entries on the exact same `last_created` for a given entity. In this case we do use `state_id` as a tiebreaker.

For performance reasons the domain filters were also moved to the outermost query, as it's way more efficient to do it there than on the innermost query as before (due to indexing with GROUP BY problems)

The result is a query that only needs to do a filesort on the final result set, which will only be as many rows as there are entities.

* Remove the ORDER BY entity_id when fetching states, and add logging

Having this ORDER BY in the query prevents it from using an index due to the range filter, so it has been removed.

We already do a `groupby` in the `states_to_json` method which accomplishes exactly what the ORDER BY in the query was trying to do anyway, so this change causes no functional difference.

Also added DEBUG-level logging to allow diagnosing a user's slow history page.

* Add DEBUG-level logging for the synthetic-first-datapoint query

For diagnosing a user's slow history page

* Missed a couple instances of `created` that should be `last_updated`

* Remove `entity_id` sorting from state_changes; match significant_update

This is the same change as 09b3498f41 , but applied to the `state_changes_during_period` method which I missed before. This should give the same performance boost to the history sensor component!

* Bugfix in History query used for History Sensor

The date filter was using a different column for the upper and lower bounds. It would work, but it would be slow!

* Update Recorder purge script to use more appropriate columns

Two reasons: 1. the `created` column's meaning is fairly arbitrary and does not represent when an event or state change actually ocurred. It seems more correct to purge based on the event date than the time the database row was written.
2. The new columns are indexed, which will speed up this purge script by orders of magnitude

* Updating db model to match new query optimizations

A few things here: 1. New schema version with a new index and several removed indexes
2. A new method in the migration script to drop old indexes
3. Added an INFO-level log message when a new index will be added, as this can take quite some time on a Raspberry Pi
2017-08-04 23:16:53 -07:00
Fabian Affolter
52cff83267 Upgrade aiohttp to 2.2.5 (#8828) 2017-08-04 23:14:05 -07:00
Paulus Schoutsen
e49b970665 Block dependencies that depend on enum34 (#8698)
* Block dependencies that depend on enum34

* Remove uninstalling enum34

* Update validation script

* Add constraints to tox.ini

* Upgrade yeelight to version that uses enum-compat

* Disable sensor.skybeacon

* Lint
2017-08-04 23:06:10 -07:00
Paulus Schoutsen
a0530d8b9c Update frontend 2 2017-08-04 23:02:07 -07:00
Paulus Schoutsen
99d4021f47 Update frontend 2017-08-04 22:58:19 -07:00
Charles Blonde
7f0d0607f1 Fix Dyson sensors if devices are configured without standby monitoring. Fixes #8569 (#8826)
Upgrade libpurecoolink libraries without unused enum34 dependency
2017-08-04 14:27:23 -07:00
Hellowlol
cf298c2435 Make HA discover sabnzbd and add it to the Configurator (#8634)
* Init discover sab.

* Fix hound errors

Nobody likes being hound at :(

* sabnzbd discovery says if ssl is active.

* Fixups after codereview.
2017-08-04 23:24:55 +02:00
Boyi C
77cdc833f0 Update yweather.py (#8820)
Fix missing weather unit support.
Move some weather code to their correct classes.
2017-08-04 17:22:38 +02:00
Eugenio Panadero
96f8c37dcd Xiaomi vacuum as platform of new vacuum component derived from ToggleEntity, and services (#8623)
* Xiaomi vacuum as component with switch, sensors and services

- Conversion from switch platform to async component.
- Add services proposed in #8416 to the new component, with shorter names.
- Add sensors for the vacuum robot as a selectable list from `battery`, `state`, `error`, `fanspeed`, `clean_time` and `clean_area` (the state attributes of the switch). The sensors don't poll, but listen to a signal to update the state, the switch fires this signal when updating.
- Assign default icons to sensors and the switch (`mdi:google-circles-group` looks like the robot!)

* path change in requirements_all (from switch platform to component)

* copy pasting is a bad habit

* services to the components services.yaml, modify .coveragerc

* review: use with multiple hosts, fix calls to async_add_devices, fix ranges for services

* `icon_for_battery_level` util method

* Xiaomi vacuum as platform of new component vacuum

- Created new component `vacuum` from a ToggleEntity.
- Add services `turn_on`, `turn_off`, `cleaning_play_pause`, `stop`, `return_to_base`, `locate`, `set_fanspeed` and `send_command`.
- Remove the main switch for the xiaomi vacuum (the toggable main entity is the switch).
- Add `support flags` for the common services
- Assign default icons to sensors and the switch (`mdi:google-circles-group` looks like the robot!)
- Move services descriptions to a yaml file for the new component.
- Update requirements_all.
- Update coveragerc.

* fix coveragerc

* fix battery icon helper to use more icons

* remove sensors, create properties and support flags for custom UI

* cleaning

* updated state_attrs for filtering in UI, renamed platform to simply `xiaomi`

* fix platform rename

* change fanspeed and expose `fanspeed_list` to use speed steps

* minor fixes

- Rename service `start_pause`
- Add 'Error' attribute only if `got_error`.
- Minor changes

* rename state attrs

* rename state attrs

* review changes: cut fan__speed, style changes, remove logging, and more

* add ATTR_COMMAND = 'command' to const

* pop entity_id from service data

* remove property accessor for vacuum object

* lint fix

* fix extra attrs names

* module level functions for calling the services

* params as optional keyword for `send_command`

* params as optional keyword for `send_command`, remove debug logs

* explicit parameters for `set_fan_speed` and `send_command`

* Demo platform for the vacuum component

* vacuum tests for the Demo platform

* some fixes

* don't omit vacuum

* vacuum tests for the Xiaomi platform

* fix test

* fix

* fix xiaomi test

* fix coveragerc

* test send command

* fix coveragerc

* fix string formatting

* The coverage is to low. It need 93% or more
2017-08-04 15:27:10 +02:00
Julian Kahnert
5b4e30cde3 geizhals sensor component (#8458)
* initial create of the geizhals component

* only .coveragerc, geizhals.py, and requirements_all.txt included
2017-08-04 12:11:33 +02:00
Paulus Schoutsen
d4dfb4d80c Polymer 2 (#8815)
* Update build for Polymer 2

* Update webcomponents polyfills/helpers

* Load ES5 class adapter when not in dev mode

* Update frontend
2017-08-03 23:46:57 -07:00
Andrey
c895f1f1db When Sonos gets a tts source - dont't show an image (#8777) 2017-08-03 17:39:11 +03:00
Haim Gelfenbeyn
944af9cd7d InfluxDB component improvements (#8633)
* Allow reporting some state attributes as tags to InfluxDB

Some state attributes should really be tags in InfluxDB. E.g.
it is helpful to be able to group by friendly_name, or add a custom
attribute like "location" and group by that. Graphs in Grafana are much
easier to read when friendly names are used, and not node ids.

This commit adds an optional setting to InfluxDB config:
'tags_attributes'. Any attribute on this list will be reported as tag
and not as field to InfluxDB.

* Allow overriding InfluxDB measurement for each reported item separately

Bundling all items with the same "unit of measurement" together does not
always makes sense. For example, both "relatively humidity" and "battery
level" are reported as "%", but I'd rather see them as separate
measurements in InfluxDB. This commit allows for 'influxdb_measurement'
attribute. When set on node, it will take precedence over the global
'override_measurement' and component-specific 'unit_of_measurement'.

* Minor updates to InfluxDB component improvements, as suggested by
@MartinHjelmare.

* Moved per-component config from 'customize' into 'influxdb'
configuration section. The following three sub-sections were added:
'component_config', 'component_config_domain' and
'component_config_glob'. The sole supported per-component attribute
at this point is 'override_measurement'.

* Lint

* Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id
format, to satisfy EntityValues requirements.

* Added tests for new InfluxDB configuration parameters

* Fixes to some docstrings
2017-08-03 16:26:01 +02:00
John Mihalic
f3e16ca304 Catch divide by zero errors when a sleep type is 0 (#8809)
Add an optional extended description…
2017-08-03 15:58:40 +02:00
Fabian Affolter
6de38cb941 Upgrade aiohttp to 2.2.4 (#8805) 2017-08-03 11:37:02 +02:00
Pascal Vizeli
8e51e66c9b Update numpy 1.13.1 (#8806)
* Update opencv.py

* Update requirements_all.txt
2017-08-03 11:36:50 +02:00
Matthew Treinish
57dfe378a1 Add mochad light component (#8476)
* Add mochad light component

This commit adds a new component to control x10 dimmers/lights with
mochad.

* Create comm_type and address constants

The comm_type and address conf constants are shared between all mochad
devices because they are required information used for configuring a
device. This commit moves the definition into const.py so they're
consistent between all component types.
2017-08-03 10:51:01 +02:00
Fabian Affolter
d8cded637c Revert "Upgrade aiohttp to 2.2.4"
This reverts commit 7c92f7e1ad.
2017-08-03 10:11:32 +02:00
Fabian Affolter
7c92f7e1ad Upgrade aiohttp to 2.2.4 2017-08-03 10:08:09 +02:00
Abílio Costa
ccf0559059 mqtt switch: add voluptuous for availability topic (#8797) 2017-08-03 07:18:18 +02:00
Paulus Schoutsen
2d38e70268 Merge branch 'polymer-build' into dev 2017-08-02 21:34:20 -07:00
Paulus Schoutsen
9dae1ca5c2 Update frontend 2017-08-02 21:34:04 -07:00
Luuk
6ac8caa857 Fix referencing unset variable in tado climate component (causes update to fail when tado zone is in manual mode) (#8723)
Add an optional extended description…
2017-08-02 15:07:03 +02:00
Fabian Affolter
39131d06ba Improvements (configuration and validation) (#8785) 2017-08-02 14:51:09 +02:00
Fabian Affolter
8a626e1572 Upgrade sphinx-autodoc-typehints to 1.2.1 (#8783)
Add an optional extended description…
2017-08-02 14:15:00 +02:00
Fabian Affolter
bc376f7045 Upgrade pyasn1 to 0.3.1 and pyasn1-modules to 0.0.10 (#8787) 2017-08-02 14:14:01 +02:00
Paulus Schoutsen
cad1de790e Build frontend with polymer-build 2017-08-02 01:46:08 -07:00
Sebastian Muszynski
32b7f4d16f Fixes UnboundLocalError: local variable 'setting' referenced before assignment (#8782) 2017-08-02 09:14:28 +02:00
Steve Rhoades
1adb5040e7 Feature alexa launch request (#8730)
* Add support for LaunchRequest alexa intent

* Support LaunchRequest for multiple skills

* formatting

* adding tests to cover launch request

* formatting
2017-08-01 22:53:36 -07:00
Lukas Barth
47dad547eb Add 'forecast' ability to yr weather sensor (#8650)
* Add forecast option to YR sensor

* Fix some style issues

* Fix linting
2017-08-01 22:42:51 -07:00
thrawnarn
86c06ad76e New component: bluesound (#7192)
* New component: bluesound

* New component: bluesound

* Removed response.release()
Fixed update_sync_status bug
Changed should_poll to True

* Fix lint error

* Changes to init

* Fixed blank line

* updated requirements

* bump to xmltodict 0.11.0
2017-08-01 22:41:51 -07:00
pezinek
7dbcf63543 flux_led: support for property "available" (#8764)
* flux_led: support for property "available"

* Implemented changes from code review

* Implemented changes from code review

* Implemented changes from code review
2017-08-01 21:26:27 -07:00
Thomas Friedel
6ff340492b use updated osram lightify 1.0.6 component, including bugfix allowing more than 27 devices (#8774) 2017-08-01 20:36:31 +02:00
Fabian Affolter
50cd6c9a9c Catch exception (fixes #8724) (#8731) 2017-08-01 19:30:26 +02:00
Dan Sarginson
365f21b209 Honeywell fixes and improvements (#8756)
* Honeywell fixes and improvements

Give the Honeywell device a state ('On', 'Off', etc) that
can be displayed to user and understood by other components.
Previously this was always 'Unknown'. Update also raises a
state_changed event when a new temperature is polled.

These two together fix an issue (#8688) where Honeywell
climate data couldn't be logged in InfluxDB.

* Roll back some changes

These were not necessary to achieve the result I wanted.

* Renamed RoundThermostat's 'device' member for greater clarity

Now called 'client'

* Improve and simplify discovering thermostat mode

Per code review, this is a rather neater way to discover the thermostat mode

* Update tests for compatibility with new component

The tests previously relied upon the update() method being
called in the constructor. This is no longer the case.

* Address formatting review comment

Parens not necessary

* This system mode is not certain to apply to domestic hot water

Moved the mode lookup to only happen on update of radiator devices,
since hot water devices seem to be treated differently and I can't test.
2017-08-01 16:18:14 +02:00
Tsvi Mostovicz
075422e7ad Add support for file attachments in pushbullet (#8763)
* Add support for file attachments in pishbullet

* Check filepath is allowed
2017-08-01 14:55:46 +02:00
Steven Looman
342ec8ec99 mpd improvements (#8655)
* Don't require the MPD device to online during HASS startup

* Hide private variables

* Keep tox/flake8 happy

* Fix typo

* Force direct update

* Implement MpdDevice.available

* Fix typo
2017-07-31 23:18:26 -07:00
Matt Colyer
2b59b917c4 Allow sonos to select playlists as a source (#8258)
* Allow sonos to select playlists as a source

Most of this was taken from
https://github.com/home-assistant/home-assistant/issues/5598#issuecomment-278229895
however I made a few small improvements so that it works for other
services than Spotify and it should properly switch to playing the queue
if you had another song playing previously.

/cc @PatBoud

* Attempt to fix style issues

* More indent changes

* Fix misplaced period

* Move playlist replacement to function

* Privatize replace_queue_with_playlist and explain

* Remove unneeded decorator

* Fix doc formatting
2017-07-31 23:16:05 -07:00
viswa-swami
e40388e7ad Enable/Disable Motion detection for Foscam Cameras (#8582)
* Added support to enable/disable motion detection for foscam cameras. This support was added in 0.48.1 as a generic service for cameras. Motion detection can be enabled/disabled for foscam cameras with this code-set.

* Fixed the violation identified by hound-bot

* Fixed the comment posted by HoundCI-Bot regarding using imperative mood statement for pydocstyle

* Fixed the error that travis-ci bot found.

* As per comment from @balloob, Instead of directly using the URL to talk to foscam, used a 3rd party foscam library to communicate with it. This library already has support to enable/disable motion detection and also APIs to change the motion detection schedule etc. Need to add more support in the pyfoscam 3rd party library for checking if motion was detected or even if sound was detected. Once that is done, we can add that into HASS as well.

* Lint

* Removed the requests library import which is not used anymore

* Updating requirements_all.txt based on the code-base of home assistant that i have. Generated using the gen_requirements_all.py script

* Updating requirements_all.txt and requirements_test_all.txt generated by gen_requirements_all.py after latest pull from origin/dev

* Updated requirements_all.txt with script

* Updated the foscam camera code to fix lint errors

* Fixed houndci violation
2017-07-31 23:14:34 -07:00
William Scanlon
cb292a0b18 Wink discovery (#8739)
* Support for Wink discovery

* Switched try/except for if/else
2017-07-31 20:54:07 -07:00
Martin Hjelmare
33663f9502 Clean up remote component (#8728)
* Clean up remote component

* Don't have device be required in send_command service and method.
* Don't have entity_id be required in the base service schema.
* Don't always add activity in the data dict for a service call.
* Update harmony remote platform according to new service schema.
* Remove not needed properties and attributes from the Kira remote
  platform.
* Add send_command method to demo platform.
* Add tests and remove duplicate tests.

* Break out required argument as positional argument
2017-07-31 20:52:39 -07:00
emlt
e57d6f679a Change units from KW to W (#8761)
* Change units from KW to W

Change power unit from KW to W to be consistent with other energy sensors.

* Change units from kW to W
2017-07-31 20:41:45 -07:00
mjj4791
775185896a buienradar dates tz-aware (#8767) 2017-07-31 20:37:33 -07:00
Paulus Schoutsen
e6331aafb2 Merge remote-tracking branch 'origin/master' into dev 2017-07-31 18:30:40 -07:00
Paulus Schoutsen
fbb4c43353 Merge pull request #8757 from home-assistant/release-0-50-2
0.50.2
2017-07-31 18:28:14 -07:00
gwhiteCL
455ac9724a added invert_state optional parameter (#8695)
* added invert_state optional parameter

* removed superfluous parens

* moved state inversion to the is_closed method

* added relay_invert feature

* fixed syntax to comply with houndci-bot rules

* changed state_invert to invert_state and relay_invert to invert_relay
2017-07-31 20:24:21 -04:00
Alan Fischer
e6be560e00 Add toggle to remotes (#8483)
* Add toggle to remotes

* Only include activity if specified, and add service description
2017-07-31 19:46:12 +02:00
Adam Mills
59891fa838 Fix Z-Wave barrier discovery for new API (#8706) 2017-07-31 09:15:10 -07:00
Adam Mills
475ab68853 Correctly discover GE Fan Controllers (#8682) 2017-07-31 09:15:10 -07:00
Paulus Schoutsen
d3f8ad15a4 Version bump to 0.50.2 2017-07-31 09:14:07 -07:00
Sean Gollschewsky
c45fc84859 Move I/O outside of properties for light/tplink platform (#8699)
* Add new component for TPLink light bulbs.

* Update with result of gen_requirements_all.

* Add new component light.tplink.

* Move I/O outside of properties as per https://goo.gl/Nvioub.
2017-07-31 09:10:04 -07:00
Adam Mills
2a09ac017f Fix Kodi reconnection after websocket disconnect (#8704) 2017-07-31 09:10:04 -07:00
Paulus Schoutsen
f9e8d4237d Fix alexa cards (#8708) 2017-07-31 09:10:04 -07:00
Kevin Fronczak
30e16c97fc Fixed sensor issue with Google Wifi routers in bridge mode (#8710)
* Fixed issue with routers in bridge mode

- Router in brdige mode apparently don't report all of the stats
- Re-wrote the data_format function so it's a bit easier to follow and able to log keys that aren't supported by a router in a given mode
- Changed config so that it properly ignores conditions when not explicitly listed
- Added tests to check for the above and also to verify we log that a key doesn't exist rather than throwing an exception

* Mistakenly was calling MONITORED_CONDITIONS in data_format

- Changed to be the actual config values to prevent log error
2017-07-31 09:10:04 -07:00
Eugenio Panadero
0e1f664102 Retry set_webhook up to three times, reduce timeout to 5s again (#8716) 2017-07-31 09:10:04 -07:00
Fabian Affolter
60ca79ce35 Supress exception if host is not available (fixes #8684) (#8732) 2017-07-31 09:10:04 -07:00
Martin Hjelmare
f576b37e9f Fix tradfri error spam (#8738)
* Catch tradfri timout exception

* Remove not needed return statement

* Remove test logging

* Log warning instead of error
2017-07-31 09:10:04 -07:00
Nathan Henrie
592f9901f9 Fix typo (#8754) 2017-07-31 09:10:04 -07:00
Sean Gollschewsky
7991e2df5f Fix brightness issue #8744. (#8755) 2017-07-31 09:10:04 -07:00
Paulus Schoutsen
91b062f9b7 Update frontend 2017-07-31 09:06:50 -07:00
Sean Gollschewsky
9919eec596 Fix brightness issue #8744. (#8755) 2017-07-31 09:02:04 -07:00
Nathan Henrie
e525d13a5d Fix typo (#8754) 2017-07-31 09:00:09 -07:00
Martin Hjelmare
ce67be2fff Fix tradfri error spam (#8738)
* Catch tradfri timout exception

* Remove not needed return statement

* Remove test logging

* Log warning instead of error
2017-07-31 08:58:47 -07:00
Fabian Affolter
53048f71a0 Supress exception if host is not available (fixes #8684) (#8732) 2017-07-31 08:58:13 -07:00
Martin Donlon
164e953e8c New media_player platform for Russound devices using the RIO protocol (#8448)
* New media_player platform for Russound devices using the RIO protocol
Auto discovers zones and sources
Handles media metadata from sources that support it
asyncio implementation
Push updates for any zone or source changes so no polling required.

* Fixed up linting issues

* Addressing PR feedback

Updated russound_rio dependency to 0.1.3
Use enumerate_zones and enumerate_sources methods instead of doing it in
the platform.
Register callbacks in async_added_to_hass coroutine
Corrected behavior of async methods
2017-07-31 14:42:55 +02:00
David McNett
7156e4782e python-insteonplm module version bump (#8736)
Requiring python-insteonplm v0.7.5 (up from 0.7.4) now
2017-07-31 14:33:51 +02:00
Eugenio Panadero
37fef4016e Add proxy support for telegram_bot (#8717)
* Add proxy support for telegram_bot

New optional config parameters `proxy_url` and `proxy_params` (a dict)
```yaml
telegram_bot:
  platform: polling
  api_key: !secret telegram_bot_api_key
  allowed_chat_ids:
    - !secret telegram_bot_chatid
  proxy_url: socks5://proxy_ip:proxy_port
  proxy_params:
    username: my-username
password: my-secret-password
```

* change `ATTR_` for `CONF_` for config params
2017-07-30 12:08:19 +02:00
Eugenio Panadero
cee49f313f Retry set_webhook up to three times, reduce timeout to 5s again (#8716) 2017-07-30 11:14:28 +02:00
Eugenio Panadero
05330ac763 bump python-telegram-bot to 7.0.1 for fully support Bot API 3.2 (#8715) 2017-07-30 11:13:51 +02:00
Nicholas Sielicki
6884965c80 directv: add configuration glue for Genie slaves (#8713)
DirectPy, the third party library used for controlling directv boxes,
has the ability to accept an ID in order to act as a remote for Genie
slaves instead of just the master directv box. This commit adds glue
such that one can configure home assistant to interface with these slave
genie boxes.

Signed-off-by: Nicholas Sielicki <sielicki@yandex.com>
2017-07-30 10:17:56 +02:00
Adam Mills
e992527c68 Fix Kodi reconnection after websocket disconnect (#8704) 2017-07-29 21:55:08 -07:00
Sean Gollschewsky
431a381c8d Move I/O outside of properties for light/tplink platform (#8699)
* Add new component for TPLink light bulbs.

* Update with result of gen_requirements_all.

* Add new component light.tplink.

* Move I/O outside of properties as per https://goo.gl/Nvioub.
2017-07-29 21:53:37 -07:00
Paulus Schoutsen
22088d192a Fix alexa cards (#8708) 2017-07-29 21:52:26 -07:00
Kevin Fronczak
418a8bab11 Fixed sensor issue with Google Wifi routers in bridge mode (#8710)
* Fixed issue with routers in bridge mode

- Router in brdige mode apparently don't report all of the stats
- Re-wrote the data_format function so it's a bit easier to follow and able to log keys that aren't supported by a router in a given mode
- Changed config so that it properly ignores conditions when not explicitly listed
- Added tests to check for the above and also to verify we log that a key doesn't exist rather than throwing an exception

* Mistakenly was calling MONITORED_CONDITIONS in data_format

- Changed to be the actual config values to prevent log error
2017-07-29 21:50:02 -07:00
Adam Mills
a94e7ec25d Fix Z-Wave barrier discovery for new API (#8706) 2017-07-30 00:40:56 -04:00
Adam Mills
8ac63fd70c Remove deprecated sensor_class config options (#8702) 2017-07-29 19:46:27 -04:00
Adam Mills
8ba9e8016b Remove deprecated substitute interfaces (#8701) 2017-07-29 19:18:06 -04:00
Adam Mills
750ea44b4b Remove deprecated host and ssl logic from Kodi (#8700) 2017-07-29 19:17:41 -04:00
Paulus Schoutsen
5876d6766d Version bump to 0.50.1 2017-07-29 15:11:45 -07:00
Paulus Schoutsen
78428b0acd Version bump to 0.51.0.dev0 2017-07-29 13:33:52 -07:00
Paulus Schoutsen
72db28abac Merge remote-tracking branch 'origin/master' into dev 2017-07-29 13:33:15 -07:00
Paulus Schoutsen
e13fd05e7d Merge pull request #8685 from home-assistant/release-0-50
0.50
2017-07-29 13:28:22 -07:00
Adam Mills
80ab02c3e8 Correctly discover GE Fan Controllers (#8682) 2017-07-29 16:24:15 -04:00
Paulus Schoutsen
a760673ad6 Persist shopping list + clear completed (#8697) 2017-07-29 12:22:52 -07:00
Paulus Schoutsen
0bde0a6f3a Persist shopping list + clear completed (#8697) 2017-07-29 12:22:38 -07:00
Paulus Schoutsen
12dec93565 Update frontend 2017-07-29 12:18:50 -07:00
William Scanlon
c376bc2e45 Support for Wink local control (#8607)
* Support for Wink local control
2017-07-29 10:50:56 -07:00
Paulus Schoutsen
f0e5f68865 Shopping List: edit name / complete status (#8666)
* Shopping List: edit name / complete status

* Change ID to be UUID based
2017-07-29 10:50:56 -07:00
Paulus Schoutsen
56f4486e0b Update frontend 2017-07-29 10:45:14 -07:00
kfcook
d1b73a96f4 Added Lutron Caseta Scene Support (#8690)
* added scene support

* Updated pylutron_caseta version number

* Updated pylutron_caseta version number

* Fixed lint errors

* fix style
2017-07-29 18:07:28 +02:00
Paulus Schoutsen
1749859cdf Shopping List: edit name / complete status (#8666)
* Shopping List: edit name / complete status

* Change ID to be UUID based
2017-07-29 17:48:09 +02:00
Fabian Affolter
931f4d8161 Upgrade mypy to 0.521 (#8692) 2017-07-28 23:22:56 -07:00
Fabian Affolter
61508deed3 Upgrade pushbullet.py to 0.11.0 (#8691)
* Upgrade pushbullet.py to 0.11.0

* Update sensor as well
2017-07-28 23:22:35 -07:00
Paulus Schoutsen
828c469ef7 Fix Lint 2017-07-28 20:53:15 -07:00
William Scanlon
1b57566e8e Support for Wink local control (#8607)
* Support for Wink local control
2017-07-28 12:02:16 -04:00
Paulus Schoutsen
0a6d519b9d Merge remote-tracking branch 'origin/master' into release-0-50 2017-07-28 02:42:58 -07:00
Paulus Schoutsen
0c97fe7eac Version bump to 0.50 2017-07-28 02:38:06 -07:00
Chris
e8ce41874c Fix COMMAND_CLASS_BARRIER_OPERATOR for dev branch of OpenZwave (#8574)
* Update zwave.py to work with updated OpenZwave library

Update zwave.py to work with updated OpenZwave library

* Update zwave.py

* Update zwave.py

* Update to fix garage door openers

Update to fix garage door support for latest version of openzwavelib

* Update to cover.zwave list of states

Update to cover.zwave to provide list of states based on dev version of
openzwave lib

* Some values not saved

* Formatting fix

* Formatting fix

* Variable typo

* Formatting fix

* Formatting

* Variable Update

Variable Update and properties added

* Formatting fixes

* Formatting Fix

* Update test case for door states

* Formatting / Testing process fix

* Formatting

* Formatting / Test Fixes

* Variable rename

* Added members to CoverDevice

* Removed un-needed else

* Formatting

* Formatting

* Variable name changes and const updates

* Changed variable names to cover_state
* Added constains into const.py
* Updated to change the main state on the cover device

* Fixes

* Formatting fixes

* Formatting/Variables

* Formatting

* Variable fixes

* Import update

* Formatting  / Variables

* Update test for new states

* Revert state changes

* Test fix

* Variable Fix

* Formatting

* Variable typo

* Missing constant

* Variable fix

* Requested changes

* Added is_opening
* Added is_closing
* Updated test based on changes

* Formatting

* Changed cover_state back to _state

* Formatting and variable fixes

* Test fixes

* Formatting and variable touchup

* Formatting

* Optimizations

* Add new cover features to demo

* Add tests for demo cover closing/opening

* Remove unused STATE_STOPPED

* Add tests for new zwave cover values
2017-07-27 18:57:30 -04:00
Brian Gehrich
0ab0e35d59 Updated pysnmp to 4.3.9 (#8675) 2017-07-27 22:33:17 +02:00
Pascal Vizeli
51108b8fe9 Hass.io: logo support / timeout handling (#8668)
* Disable auth on logo / no timeout for addons update/install

* fix tests
2017-07-27 12:23:22 -07:00
Daniel Perna
9e6817b6d0 Upgrade pyhomematic to 0.1.30 (#8673) 2017-07-27 17:45:59 +02:00
Fabian Affolter
74581b57f8 Upgrade sqlalchemy to 1.1.12 (#8669) 2017-07-27 17:23:51 +02:00
Fabian Affolter
4fcaea23a8 Upgrade libnacl to 1.5.2 (#8670) 2017-07-27 17:23:07 +02:00
Fabian Affolter
b59c29943b Upgrade fuzzywuzzy to 0.15.1 (#8671) 2017-07-27 17:22:40 +02:00
Richard Cox
1e8c00ac02 Adding support for mapping keys to value in statsd (#8665)
* Adding ability to map specific states to values

* Adding test for mapping
2017-07-27 08:58:34 +02:00
Abílio Costa
9d5c61b2f0 MQTT Switch: add availability_topic for online/offline status (#8593)
* mqtt switch: add availability_topic for online/offline status

* fix method doc strings

* MQTT Switch: add test
2017-07-27 08:24:15 +02:00
kfcook
f5eeb252a7 Added support for SerenaHoneycombShades to Lutron Caseta (#8662)
Add an optional extended description…
2017-07-27 08:14:12 +02:00
Robin
3b4ea864a1 Add uk_transport component. (#8600) 2017-07-26 20:49:52 +01:00
Jeff Wilson
3318f02664 Add transition support to light.zha (#8548)
* Add transition support to light.zha

* Address hound formatting

* Address hound comments

Look, nobody is perfect... alright?

* Update zha.py
2017-07-26 17:22:31 +02:00
Greg Laabs
438edc5ca1 History performance improvements for single-entity requests (#8632)
* Bugfix: remove superfluous domain filter

This filter is already applied later in the function by the `filters` object, where it is conditionally applied when appropriate. This fixes the problem where we get a domain filter even when searching for a single entity_id, which needlessly harms the query's performance.

* Performance: build different query when only getting single entity

When querying the history of a single entity, we can use an entirely different method for the "synthetic zero data point" by simply sorting by date and doing a LIMIT 1. This performs thousands of times better than the multi-entity query when the current recorder_run has been going for a while.

* Add entity_id filter to single-entity request

The entity_id filter was handled inside the `filters.apply` logic which is used in most cases, BUT didn't work when no `filters` was passed in to the method. Now it'll work even if no `filters` object is passed in.

* Fix linting errors in history.py

* Undo removal of domain filter

Putting back the domain filter that was removed in 76a6371705 - there are use-cases where get_states is called without a filter object, so we need the domain filter to work in those cases as well.

* Fix truncated comment
2017-07-26 11:22:01 -04:00
Boyi C
abcfcdd887 Yahoo Weather update, supports forecast for more days (#8626)
* work on weather panel

* update yahooweather with more forecast details

* Update yweather to allow user input forecast date

* fix for houndci

* fix long line

* fix1

* Revert "work on weather panel"

This reverts commit 28b4972233.

revert unintentional submodule change

* fix2

fix typo, add try catch to another int()

* fix pylint

* fix3

* fix4

* Update yweather.py

* Update yweather.py

* Remove global data construct

* Yahoo API support only 5 days forecast

* remove forecast

* fix lint

* fix lint p2

* Update yweather.py
2017-07-26 16:46:21 +02:00
Thomas Delaet
fff269e790 Velbus (#8076)
* add Velbus changes

* update library version

* fix python-velbus version

* bug fix and update python-velbus

* change config handling

* update velbus components/platforms

* add support for Velbus switches

* fix bugs

* typo

* add velbus fan

* update velbus library

* bug fix in logic of fan handling of speed settings

* add Velbus changes

change config handling

update velbus components/platforms

add support for Velbus switches

add velbus fan

* remove duplicate entry

* fix documentation links

* fix linting error

* regen requirements_all.txt

* add support for Velbus cover

* bugfix in cover component

* bugfix in cover component

* remove unused imports

* Travis fixes

* fix style

* fix style

* Update velbus.py

* Update velbus.py

* Update velbus.py

* Update requirements_all.txt

* Update velbus.py

* Update velbus.py

* Update velbus.py

* Update velbus.py

* fix style

* Update velbus.py

* Update velbus.py

* Update velbus.py

* Update velbus.py

* Update velbus.py

* Update velbus.py
2017-07-26 14:03:29 +02:00
Anders Melchiorsen
81a27e726c Upgrade aiolifx (#8648)
This release includes a fix for multizone lights with zone counts that are not
a multiple of eight.
2017-07-26 12:33:00 +02:00
Marcelo Moreira de Mello
7c120748ce Fixes Fitbit sensor to report battery level with the expected device (#8647)
Add an optional extended description…
2017-07-26 11:05:48 +02:00
Sean Gollschewsky
e83816c055 Add component Light TPLink (#8643)
* Add new component for TPLink light bulbs.

* Update with result of gen_requirements_all.

* Add new component light.tplink.
2017-07-26 09:04:40 +02:00
Paulus Schoutsen
cd2703e121 Update dependencies cast + discovery (#8646) 2017-07-25 23:35:05 -07:00
Paulus Schoutsen
c2828bac2c Tweak conversation/intent/shopping list (#8636) 2017-07-25 00:42:59 -07:00
Paulus Schoutsen
ad7370e1c2 Update frontend 2017-07-25 00:29:05 -07:00
Adam Mills
3b7f16f189 Catch and log Lyft API errors (#8635) 2017-07-25 00:05:47 -04:00
Colin O'Dell
cc03f7ee6a Manual alarm with MQTT control (#8257)
* Manual alarm with MQTT control

* Duplicate manual control panel code instead of extending it

* Duplicate manual alarm test as well; modify for manual_mqtt

* Add MQTT-specific tests for manual_mqtt alarm
2017-07-24 09:06:38 -07:00
Corey Pauley
ecc1429453 Added support for default value when environment variable is missing (#8484)
* Added support for a default value when an environment variable is missing

* Shouldn't have used docstring
2017-07-24 09:00:01 -07:00
Justin Dray
98568b5eb7 Add support for using credstash as a secret store (#8494) 2017-07-24 08:59:10 -07:00
Paulus Schoutsen
9d9ca64f26 Update README.rst 2017-07-24 07:53:14 -07:00
Paulus Schoutsen
1d31137616 Update README.rst 2017-07-24 07:47:57 -07:00
Pascal Vizeli
f86bd15580 Cleanup old device_tracker stuff (#8627)
* Cleanup old device_tracker stuff

* Fix lint
2017-07-24 07:45:02 -07:00
Paulus Schoutsen
cbf65220aa Merge pull request #8625 from home-assistant/release-0-49-1
0.49.1
2017-07-24 07:35:29 -07:00
Daniel Høyer Iversen
c100b8cb52 Add is_lighting4 to RfxtrxBinarySensor (#8563) 2017-07-24 07:33:37 -07:00
matt2005
654ad41464 added onvif camera fix for non-virtual env installations (#8592)
* added fix for non-virtual env installations

* fixed new line at end of file

* moved import os to top of file
2017-07-24 15:22:12 +02:00
Paulus Schoutsen
a2abb4ae0a Update frontend 2017-07-24 00:11:58 -07:00
Jeff Wilson
36e266442f Properly slugify switch.flux update service name (#8545) 2017-07-23 23:53:21 -07:00
Jeff Wilson
f3d9086ff4 Properly slugify switch.flux update service name (#8545) 2017-07-23 23:53:03 -07:00
Anton Lundin
0c09cfc6c4 ubus: Make multiple instances work again (#8571)
Back in "ubus: Refresh session on Access denied (#8111)" I added the
decorator _refresh_on_acccess_denied. Somehow that stopped multiple ubus
trackers from working in parallel, and only the one first init'ed
worked.

Changing the order of the decorators fixes the issue but, I'm sorry to
say I can't figure out why. There's some magic somewhere which I'm
missing.

Signed-off-by: Anton Lundin <glance@acc.umu.se>
2017-07-23 23:51:25 -07:00
Anton Lundin
b0b6026c68 ubus: Make multiple instances work again (#8571)
Back in "ubus: Refresh session on Access denied (#8111)" I added the
decorator _refresh_on_acccess_denied. Somehow that stopped multiple ubus
trackers from working in parallel, and only the one first init'ed
worked.

Changing the order of the decorators fixes the issue but, I'm sorry to
say I can't figure out why. There's some magic somewhere which I'm
missing.

Signed-off-by: Anton Lundin <glance@acc.umu.se>
2017-07-23 23:51:07 -07:00
Russell Cloran
8f47a9109c prometheus: Fix zwave battery level (#8615) 2017-07-23 23:49:22 -07:00
Russell Cloran
f0293eeac2 prometheus: Fix zwave battery level (#8615) 2017-07-23 23:49:03 -07:00
Phil Cole
e4317a6741 Tado Fix #8606 (#8621)
Handle case where 'mode' and 'fanSpeed' are missing JSON. Based on
changes in commit
adfb608f86
2017-07-23 23:48:33 -07:00
Phil Cole
4b449f5f93 Tado Fix #8606 (#8621)
Handle case where 'mode' and 'fanSpeed' are missing JSON. Based on
changes in commit
adfb608f86
2017-07-23 23:48:20 -07:00
Daniel Schaal
8760dc9b29 Check if /dev/input/by-id exists (#8601) 2017-07-23 23:47:52 -07:00
Daniel Schaal
1831a7da68 Check if /dev/input/by-id exists (#8601) 2017-07-23 23:47:38 -07:00
Marcelo Moreira de Mello
3e34f34f6b Bumped Amcrest version (#8624) 2017-07-23 23:46:35 -07:00
Marcelo Moreira de Mello
3fec2955a5 Bumped Amcrest version (#8624) 2017-07-23 23:46:23 -07:00
Chia-liang Kao
2cf9254a08 Fix STATION_SCHEMA validation on longitude (#8610) 2017-07-23 23:35:49 -07:00
Russell Cloran
333da0dc6d zha: Update to bellows 0.3.4 (#8594) 2017-07-23 23:35:49 -07:00
Yannick POLLART
7b10f0a14f Fix broken status update for lighting4 devices (#8543)
* Fix broken status update for lighting4 devices

* Fixed indentation
2017-07-23 23:35:49 -07:00
Anders Melchiorsen
fb6bdfaba9 LIFX: assume default features for unknown products (#8553)
This makes the detection work for prototypes as well.
2017-07-23 23:35:48 -07:00
Pierre Ståhl
d7da90ae54 Fix support for multiple Apple TVs (#8539) 2017-07-23 23:35:48 -07:00
Eugenio Panadero
a5bfcceacd Attach the chat_id for a callback query from a chat group (fixes #8461) (#8523) 2017-07-23 23:35:48 -07:00
Pascal Vizeli
4961ece931 Realfix for dlib (#8517)
* Update dlib_face_detect.py

* fix lint

* Update dlib_face_detect.py
2017-07-23 23:35:48 -07:00
Pascal Vizeli
7d99d6aad9 Update dlib_face_detect.py (#8516) 2017-07-23 23:35:48 -07:00
Russell Cloran
6dc93c2751 prometheus: Convert fahrenheit to celsius (#8511) 2017-07-23 23:35:48 -07:00
Maikel Wever
5c39eebea8 Fix TP-Link device tracker regression since 0.49 (#8497)
* Fix TP-Link device tracker regression since 0.49

This regression was introduced by #8322.

Fix is to utf encode the password like the other TP-Link backends do.

* Fix linting issue introduced in previous commit

Commit in question: 677f3fbb7f
2017-07-23 23:35:48 -07:00
Paulus Schoutsen
ffd295b38b Update to 0.49.1 2017-07-23 23:34:08 -07:00
Phil Hawthorne
5d810dae86 REST binary sensor value_template optional (#8596)
According to the documentation, the `value_template` for the REST
binary_sensor is not required. However, if you don't provide this when
setting up a binary sensor, the component fails. Looks like a variable
was not being set, which I've now included.

This should make the REST binary sensor act the same way as the REST
sensor now.
2017-07-23 22:42:41 +02:00
Fabian Affolter
486bcc4cae Upgrade mypy to 0.520 (#8616) 2017-07-23 20:20:38 +02:00
Fabian Affolter
cc2de5e1dc Upgrade youtube_dl to 2017.7.23 (#8617) 2017-07-23 20:20:23 +02:00
cribbstechnologies
77d8e393a1 better but still not great (#8618) 2017-07-23 20:19:58 +02:00
Koen Ekelschot
c6bf529d38 Allow set_cover_position in scenes (#8613) 2017-07-23 15:59:27 +02:00
Chia-liang Kao
dac9716cf4 Fix STATION_SCHEMA validation on longitude (#8610) 2017-07-23 10:22:49 +02:00
Thomas Klingbeil
9043895407 make attributes in the fritzdect module easier to process (#8436)
* make attributes in the fritzdect module easier to process
* remove spaces in attribute names
* move units to separate attributes

* make attributes in the fritzdect module easier to process
* remove spaces in attribute names
* move units to separate attributes

* Use new python formating syntax and attribute constant

* Shorten too long line

* Fix indent
2017-07-22 20:34:58 +02:00
Open Home Automation
2f08a91fdd Simplified percent conversion, better logging (#8568)
* Simplified percent conversion, better logging

*  Unnecessary pass statement (unnecessary-pass)
2017-07-22 20:00:13 +02:00
Sean Gollschewsky
1807b45222 Binary sensor ping fixed for hassio (#8573)
* Add support for multiple ping utilities.

* Added support for differing flavours of ping included with
different distributions (specifically alpine linux for hassio's
homeassistant).

* Updated as per comments in PR
2017-07-22 19:50:31 +02:00
Teemu R
b4f392b181 bump python-mirobo version for more robust protocol handling, make the platform to update on startup (#8602) 2017-07-22 19:36:14 +02:00
William Scanlon
8e8ec7a7c3 Remove code in wink.py overwriting hass.data configurator (#8595) 2017-07-22 09:21:38 -04:00
Paulus Schoutsen
7edf14e55f Add Intent component (#8434)
* Add intent component

* Add intent script component

* Add shopping list component

* Convert Snips to use intent component

* Convert Alexa to use intent component

* Lint

* Fix Alexa tests

* Update snips test

* Add intent support to conversation

* Add API to view shopping list contents

* Lint

* Fix demo test

* Lint

* lint

* Remove type from slot schema

* Add dependency to conversation

* Move intent to be a helper

* Fix conversation

* Clean up intent helper

* Fix Alexa

* Snips to use new hass.components

* Allow registering intents with conversation at any point in time

* Shopping list to register sentences

* Add HTTP endpoint to Conversation

* Add async action option to intent_script

* Update API.ai to use intents

* Cleanup Alexa

* Shopping list component to register built-in panel

* Rename shopping list intent to inlude Hass name
2017-07-21 21:38:53 -07:00
Paulus Schoutsen
7bea69ce83 update frontend 2017-07-21 21:29:58 -07:00
Russell Cloran
8d31c5fbf6 zha: Update to bellows 0.3.4 (#8594) 2017-07-21 21:22:43 -07:00
William Scanlon
dc42b6358a Support for Wink oauth application authorization (#8208) 2017-07-21 20:18:57 -04:00
Per Osbäck
06ceadfd54 upgrade pywebpush and PyJWT (#8588) 2017-07-21 22:35:19 +02:00
Daniel Høyer Iversen
4359e0babf xiaomi binary sensor bug fix (#8586)
* xiaomi binary sensor bug fig

* Is not need on binary_sensor
2017-07-21 12:39:25 +02:00
Marcelo Moreira de Mello
ee153062ab Extends Fitbit sensors to track the device battery level (#8583)
* Extends Fitbit sensors to track the device battery level

* cleanup old stuff

* remove update from init
2017-07-21 10:19:26 +02:00
Sebastian Muszynski
fada6d3f49 Device support for different new sensors of the xiaomi aqara gateway (#8577)
* The gateway configuration accepts a MAC address or a SID value in uppercase already.
The ringtone services accepts the same values now. I hope it will avoid confusion.

* Device support for the new wall switches with neutral lead (ctrl_ln1, ctrl_ln2) added.

* Measurement unit from pressure of weather.v1 fixed.

* Device support for sensor_magnet.aq2 added.

* Device support for sensor_motion.aq2 (motion and lux) added.

* Code reformatted.

* The ringtone service (start/stop) uses the parameter gw_mac instead of gw_sid now.

* Version of the required library updated.
2017-07-21 10:13:42 +02:00
Daniel Høyer Iversen
f6a5e0887d upgade xiaomi lib to 0.2 (#8584) 2017-07-21 10:10:03 +02:00
William Scanlon
4f8d2ec317 Added Time Remaining and Time Elapsed sensors for octoprint (#8581)
Add an optional extended description…
2017-07-21 09:40:07 +02:00
Aaron Bach
e63a96cf53 Bumped python-simplisafe version (#8578)
* Bumped python-simplisafe version
2017-07-20 18:59:41 -04:00
Daniel Høyer Iversen
a5c0831dc1 xiaomi bug fix (#8576) 2017-07-20 23:04:21 +02:00
namadori
718949481f fix #8263 corrected Adafruit DHT library version from 1.3.0 to 1.3.2 (#8562)
Add an optional extended description…
2017-07-20 15:53:06 +02:00
Daniel Høyer Iversen
90639d33ab Xiaomi gw support (#8555)
* xiaomi support

* xiaomi support

* style

* style

* style

* style

* style

* coveragerc

* Update xiaomi.py

* Update xiaomi.py

* Update xiaomi.py

* refactorization

* refactorization

* config validation

* style

* package

* refactorization

* refactorization

* refactorization

* HA integration
2017-07-20 15:20:00 +02:00
Greg Dowling
966809c1a1 Merge pull request #8564 from home-assistant/bump_pyvera
Bump pyvera to fix colour exception
2017-07-20 11:53:53 +01:00
pavoni
bc27d173d0 Bump pyver to fix exception in fetching colours. 2017-07-20 10:21:08 +01:00
Daniel Høyer Iversen
fde291f866 Add is_lighting4 to RfxtrxBinarySensor (#8563) 2017-07-20 11:12:42 +02:00
Paulus Schoutsen
49c399c358 Update persistent deps dir version in config.py (#8479)
* Update persistent deps dir version in config.py

* Update last version to remove deps dir in tests
2017-07-19 22:59:21 -07:00
Sean Dague
8d1999dc12 Enhance python_script to support "_getitem_" (#8541)
* Enhance python_script to support "_getitem_"

In order to use dict / list structures in python scripts we need
_getitem_ allowed in the RestrictedPython environment. There is a
default_guarded_getitem included with RestrictedPython, which is a
pass through used in the Eval code paths.

* Add tests for dict/list support in python_scripts

* Lint
2017-07-19 22:56:24 -07:00
Yannick POLLART
ee05a4ab89 Fix broken status update for lighting4 devices (#8543)
* Fix broken status update for lighting4 devices

* Fixed indentation
2017-07-19 22:56:11 -07:00
Anders Melchiorsen
8a42e1551a LIFX: assume default features for unknown products (#8553)
This makes the detection work for prototypes as well.
2017-07-19 22:54:46 -07:00
Jeff Wilson
9cc3e7e47b Handle manual edits to emulated_hue_ids.json (#8560) 2017-07-19 22:51:50 -07:00
Open Home Automation
54755df9ea Added a service to write to KNX group addressed including documentation (#8491)
* Added a service to write to KNX group addressed including documentation

* Define parameters as required

* Reformating

* Moved service documentation to service.yaml

* Moved service documentation to services.yaml

* Update knx.py
2017-07-20 07:01:05 +02:00
William Scanlon
84ebcd8a59 Support for Wink Switch and Light groups also fix fan speed selection (#8501)
* Support for Switch and Light groups, fix fan speed

* Fixed hound violations
2017-07-20 00:27:39 +02:00
Marcelo Moreira de Mello
f1280d3edb Extends Pi-hole sensor to support the new sensors: (#8549)
- domains_being_blocked
  - queries_cached
  - queries_forwarded
  - unique_clients
  - unique_domains
2017-07-19 19:45:53 +02:00
Eugenio Panadero
c27074e6f7 turn_on_action and turn_off_action with script syntax (#8558) 2017-07-19 13:33:16 -04:00
viswa-swami
c8bfcd2ed4 Upgrade the alarmdecoder dependency library from 0.12.1 to 0.12.3. (#8542)
* Upgrade the alarmdecoder dependency library from 0.12.1 to 0.12.3. Nutech software who owns this library have upgraded this library with some fixes regarding arming it to home/away and then disarming the alarm. Without this upgraded library, HASS is having a problem when we try to disarm an armed alarm after around 8 hours or so.

* Updated the requirements_all.txt by running the script gen_requirements_all.py
2017-07-19 12:21:39 +02:00
Jeff Wilson
42699b7a60 Report Harmony remote off if state is unknown (#8547)
Add an optional extended description…
2017-07-19 12:20:45 +02:00
Aliaksandr
6bc07298d3 [media_extractor] Add support for custom stream queries for media_extractor (#8538)
* Add support for different stream formats

* Encapsulate logic inside MediaExtractor class

* Add CONFIG_SCHEMA

* Fix for cases when youtube-dl returns content of playlist as list
2017-07-19 08:14:48 +01:00
Marcelo Moreira de Mello
4ece4bf241 Fix exception dlib_face_identify when image is not recognized by face_recognition module (#8552)
*   Some images are not supported by face_recognition, so this patch treats the error
  messages instead throwing a traceback. Fixes #7867

* Makes lint happy
2017-07-19 09:04:01 +02:00
Kevin Fronczak
1a86fa5a02 Initial support for Google Wifi/OnHub (#8485)
* Initial support for Google Wifi/OnHub

* Moved state logic to update function of API class

- Throttle added to update
- State logic implementation is cleaner
- Modified tests to work with the new throttle on update
2017-07-19 00:16:32 +02:00
Paulus Schoutsen
d54a634f11 Update demo.py 2017-07-18 15:11:17 -07:00
Thibault Cohen
5e1ff20b09 Decora: Fix set brightness and improve reconnection (#8522) 2017-07-19 00:02:42 +02:00
Pierre Ståhl
29266213a0 Fix support for multiple Apple TVs (#8539) 2017-07-18 19:19:36 +01:00
Fabian Affolter
2aa89cfe07 Upgrade TwitterAPI to 2.4.6 (#8535) 2017-07-18 16:24:32 +02:00
Fabian Affolter
879c816f5c Update docstrings (#8536) 2017-07-18 16:23:57 +02:00
Thibault Cohen
4ae11c009d Fix #6469 and #6828 (#8537) 2017-07-18 16:23:39 +02:00
Phil Lavin
dcd6f7a29e Return a 0 temperature value when none is found (#8518)
* Return a 0 temperature value when none is found

It's well documented that these TRVs will only return the current temperature
for a short time after the actuator has moved. This means that, usually, they will
not return the current temperature. Setting a non-value here causes errors in the logs
and for the TRV to not show on the dashboard at all

* Fix lint issue
2017-07-17 23:34:38 +02:00
Jan Losinski
fde4a7d029 Citybikes: Allow None as result for empty slots (#8528)
The citibykes API returns "null" as value for empty_slots on some
stations (see #8527). This causes the component to not process the data.

This is fixed by accepting None as valid data. The row in the frontend
is left empty if "null" was returned by the service.

fixes #8527
2017-07-17 22:50:55 +02:00
Anders Melchiorsen
b83ff739bc Remove deprecated automation keywords (#8510)
* Remove deprecated automation keywords

* Remove retired test case

* Remove retired keyword
2017-07-17 22:24:05 +02:00
Eugenio Panadero
8c9b3898fc handle timeout errors without logging.exception when updating hue lights; double quotes in log msgs (#8524) 2017-07-17 22:16:18 +02:00
Fabian Affolter
95e0027924 Fix KeyError 2017-07-17 20:21:16 +02:00
Mike Christianson
c67c20f752 fix for a bug introduced with media support in #8282 (#8513)
data may be None if twitter data property unconfigured:
  File "/opt/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/components/notify/twitter.py", line 63, in send_message
    media = data.get(ATTR_MEDIA)
2017-07-17 19:45:42 +02:00
Kevin Fronczak
1a1571cd52 Added sensor state rounding (#8499) 2017-07-17 19:21:41 +02:00
Eugenio Panadero
cca0d3ed44 Attach the chat_id for a callback query from a chat group (fixes #8461) (#8523) 2017-07-17 13:47:28 +02:00
Pascal Vizeli
f0479855bd Realfix for dlib (#8517)
* Update dlib_face_detect.py

* fix lint

* Update dlib_face_detect.py
2017-07-17 12:09:42 +02:00
Russell Cloran
40aafcdf5d prometheus: Convert fahrenheit to celsius (#8511) 2017-07-17 11:25:20 +02:00
Pascal Vizeli
8c9557401f Update dlib_face_detect.py (#8516) 2017-07-17 11:03:16 +02:00
Alexander Rust
ffd3081743 Added additional attributes to OwnTracks device_tracker (#8503)
* Added additional attributes to OwnTracks device_tracker

* Added missing space after :
2017-07-16 21:43:47 +02:00
Paulus Schoutsen
d0275c8075 Persistent notification import (#8507)
* Rewrite persistent notification creation

* Update components.is_on to use auto loading

* Fix two hass parameters
2017-07-16 21:39:38 +02:00
Maikel Wever
f6c3832e90 Fix TP-Link device tracker regression since 0.49 (#8497)
* Fix TP-Link device tracker regression since 0.49

This regression was introduced by #8322.

Fix is to utf encode the password like the other TP-Link backends do.

* Fix linting issue introduced in previous commit

Commit in question: 677f3fbb7f
2017-07-16 10:27:48 -07:00
Paulus Schoutsen
d29bdddaa7 Add bind_hass to components (#8502)
* Add bind_hass to components

* Add bind_hass to group
2017-07-16 10:14:46 -07:00
Paulus Schoutsen
d3be056d15 Expose all components on hass [Concept] (#8490)
* Add components concept

* Lint

* Raise ImportError if component not found
2017-07-16 09:23:06 -07:00
Open Home Automation
bffa0d2b04 Bump to KNXIP 0.5 (#8492)
* Bump to KNXIP 0.5

* Updated requirements file
2017-07-16 13:34:13 +02:00
Paulus Schoutsen
23b65bfb30 Version bump to 0.50.0dev0 2017-07-15 21:07:15 -07:00
Paulus Schoutsen
1d4a7f1160 Version bump to 0.49 2017-07-15 21:06:20 -07:00
Paulus Schoutsen
dc08852fc2 Merge pull request #8468 from home-assistant/release-0-49
0.49
2017-07-15 21:05:07 -07:00
Andrey
3377f30613 Make themes API work even when themes are not defined. (#8473) 2017-07-15 19:43:06 -07:00
Anders Melchiorsen
84ca4d2a21 Accept transition for light.toggle (#8466) 2017-07-15 19:43:06 -07:00
Bryce Edwards
1366c93c83 Radarr sensor fix for issue #8250 (#8456)
* Radarr sensor fix for issue #8250

* Radarr sensor fix for issue #8250
2017-07-15 19:43:06 -07:00
Sean Gollschewsky
e5e2a151aa Remove km from visibility, add visibility_distance (#8454)
* Remove km from visibility, add visibility_distance

* Fix line length

* Fix trailing space and line break indentation

* Indentation

* More whitespace
2017-07-15 19:43:06 -07:00
dersger
bd1e533409 Fix media_position for cast component (#8452)
* Make it available during state paused.

* Don't adjust for media_position_updated_at. I.e. do as vlc, sonos etc
  so that returned position is the position at the time of
  media_position_updated_at, not now.
2017-07-15 19:43:06 -07:00
Dougal Matthews
21e82bd037 Add RGB support to switch.flux (#8417) 2017-07-15 19:43:06 -07:00
Anders Melchiorsen
af9a0e8fea LIFX: support for multizone (#8399)
* Make aiolifx modules easily available

* Use aiolifx features_map for deciding bulb features

Also move the feature detection out of Light so it is available even
during the initial detection.

* Move each LIFX light type to a separate class

* Simplify AwaitAioLIFX

This has become possible with recent aiolifx that calls the callback even
when a message is lost.

Now the wrapper can be used also before a Light is added though the register
callback then has to become a coroutine.

* Refactor send_color

* Add support for multizone

This lets lifx_set_state work on individual zones.

Also update to aiolifx_effects 0.1.1 that restores the state for individual
zones.
2017-07-15 19:43:05 -07:00
Paulus Schoutsen
abc5c3e128 Fix iFrame panel test 2017-07-15 19:42:17 -07:00
Martin Hjelmare
543e8bb62e Fix check for running inside venv (#8481)
* Import and use the function from pip instead of defining it
  ourselves.
* Fix tests.
2017-07-15 07:25:02 -07:00
Andrey
6ca828fd14 Make themes API work even when themes are not defined. (#8473) 2017-07-14 11:26:26 -07:00
Anders Melchiorsen
87b83f3602 Accept transition for light.toggle (#8466) 2017-07-13 20:04:23 -07:00
Bryce Edwards
5829cdfdf1 Radarr sensor fix for issue #8250 (#8456)
* Radarr sensor fix for issue #8250

* Radarr sensor fix for issue #8250
2017-07-13 20:02:07 -07:00
Sean Gollschewsky
d473f3407b Remove km from visibility, add visibility_distance (#8454)
* Remove km from visibility, add visibility_distance

* Fix line length

* Fix trailing space and line break indentation

* Indentation

* More whitespace
2017-07-13 20:01:25 -07:00
dersger
9373d5e901 Fix media_position for cast component (#8452)
* Make it available during state paused.

* Don't adjust for media_position_updated_at. I.e. do as vlc, sonos etc
  so that returned position is the position at the time of
  media_position_updated_at, not now.
2017-07-13 20:00:23 -07:00
Dougal Matthews
d8abef9210 Add RGB support to switch.flux (#8417) 2017-07-13 19:53:19 -07:00
Anders Melchiorsen
4fde0ffe9c LIFX: support for multizone (#8399)
* Make aiolifx modules easily available

* Use aiolifx features_map for deciding bulb features

Also move the feature detection out of Light so it is available even
during the initial detection.

* Move each LIFX light type to a separate class

* Simplify AwaitAioLIFX

This has become possible with recent aiolifx that calls the callback even
when a message is lost.

Now the wrapper can be used also before a Light is added though the register
callback then has to become a coroutine.

* Refactor send_color

* Add support for multizone

This lets lifx_set_state work on individual zones.

Also update to aiolifx_effects 0.1.1 that restores the state for individual
zones.
2017-07-13 19:38:36 -07:00
Martin Hjelmare
ba019c799a Make deps directory persistent over upgrades (#7801)
* Use pip install --user if venv not active

* Set PYTHONUSERBASE to deps directory, when installing with --user
  option.
* Reset --prefix option to workaround incompatability when installing
  with --user option. This requires pip version 8.0.0 or greater.
* Require pip version 8.0.3.
* Do not delete deps directory on home assistant upgrade.
* Fix local lib mount and check package exist.

* Update and add tests

* Fix upgrade from before version 0.46

* Extract function to get user site

* Add function(s) to package util to get user site.
* Use async subprocess for one of the functions to get user site.
* Add function to package util to check if virtual environment is
  active.
* Add and update tests.

* Update version for last removal of deps dir

* Address comments

* Rewrite package util tests with pytest

* Rewrite all existing unittest class based tests for package util as
  test functions, and capitalize pytest fixtures.
* Add test for installing with target inside venv.
2017-07-13 19:26:21 -07:00
Paulus Schoutsen
5581c6295e Fix iFrame panel test 2017-07-13 10:19:59 -07:00
Paulus Schoutsen
192db5bec3 Update frontend 2017-07-13 09:22:15 -07:00
Andrey
b8eaec565a Add kiosk-mode panel (#8457) 2017-07-13 09:11:49 -07:00
Daniel Perna
e0f35c0279 HomeMatic dependency upgrade + IP Wall Thermostat support (#8465)
* Upgrade dependency + added IP Wall Thermostat
2017-07-13 17:55:30 +02:00
Abílio Costa
2eeeb9075a Plex: Add exception handler when connection fails (#8179)
* add exception handler when connection fails

* plex: improve exception handling

* remove uneeded exception handler
2017-07-13 08:01:12 -07:00
Daniel Høyer Iversen
71ee290bfd upgrade rfxtrx lib (#8463) 2017-07-13 14:57:44 +02:00
Daniel Høyer Iversen
7aad93e90d upgrade broadlink (#8462) 2017-07-13 14:42:30 +02:00
Andrey
a65f22378e Backend support for themes (#8419)
* Backend support for themes

* Fix test

* Add theme_updated event

* Shorten name

* Add tests
2017-07-12 18:08:13 -07:00
Anders Melchiorsen
bb9db28c95 LIFX: make broadcast address configurable (#8453) 2017-07-12 23:08:18 +02:00
Anders Melchiorsen
d10f017441 LIFX: improve light availability (#8451)
The default aiolifx timers are tuned for a network with few lost packets.
This means that lights can become "unavailable" from just a two second
dropout. An unavailable light is completely useless for HA until it is
rediscovered so this is an undesirable state to be in.

These tweaks make aiolifx try harder to get its messages through to the
bulbs, at the cost of some latency in detecting lights that actually are
unavailable.
2017-07-12 19:24:24 +02:00
Open Home Automation
b6e0286d71 Implement a bridge between HASS event bus and KNX bus to send events (#8449)
* Implement a bridge between HASS event bus and KNX bus to send events as KNX messages

* Formatting
2017-07-12 12:21:15 +02:00
Fabian Affolter
4451d2e847 Upgrade youtube_dl to 2017.7.9 (#8450) 2017-07-12 10:38:08 +02:00
Niccolò Maggioni
229000b834 Support for Plex servers with enforced SSL (#8341)
* Support for Plex servers with enforced SSL

* Fixed HoundCI warnings

* Fixed HoundCI warnings (2nd)

* Configurator data validation

* Travis linting
2017-07-11 23:26:29 -07:00
viswa-swami
9704057959 Fix Arlo Q not working with 0.48.1 (#8446)
* This change will enable the functionality for Arlo Q cameras. When we added the code to enable/disable motion detection, we assumed that base station will be present for all arlo type of cameras. But found recently that Arlo Q cameras does not have base station. So, removed the base_station dependency in the init code. Also added code in enable/disable motion detection code to first check if base station is detected by library. If base station is detected then it will use it to enable the motion detection. If not detected, even if service was called, it will not do anything.  Enabling/disabling the motion detection for Arlo Q cameras have to added by someone who has that camera.  I don't have the Arlo Q cameras.

* Fixed a typo in the code.
2017-07-11 23:25:55 -07:00
Paulus Schoutsen
effb9e9d23 Hass.io: Disable timeout when updating OS/supervisor/hass (#8447) 2017-07-11 23:24:35 -07:00
Sean Dague
effbb3bd4c Add support for rain and moisture sensors (#8440) 2017-07-11 23:09:05 +02:00
gitmopp
471501d386 DHT support for humidity and temperature offset (#8238)
* Added support for temperature_offset and humidity_offset

Some DHT sensors require some offsets to work.

* Support for temperature and humidity offset

* Changed lines with 79 characters

* Moved const to dht.py from const.py

* Changed temperature_offset range

* Removed the const

const.py is at original state.

* Fixed continuation line under-indented

* Removed first round and added debug info
2017-07-11 23:04:00 +02:00
Vlad Korniev
ef94b5c77a Vizio SmartCast support (#8260)
* Vizio SmartCast support

* Requested changes
Added new config params

* Vizio SmartCast support

* Requested changes
Added new config params
2017-07-11 22:55:46 +02:00
Andrey
60dcc9a5c0 Switch pyW215 to pypi (#8445) 2017-07-11 22:44:01 +02:00
Fabian Affolter
5b4862cc3c Exclude 'TAXI' product (fixes #8401) (#8438) 2017-07-11 21:23:23 +02:00
Fabian Affolter
fbf945c18b Add effects (#8442) 2017-07-11 21:22:00 +02:00
Fabian Affolter
609c25691a Upgrade phue to 1.0 (fixes #7749) (#8444) 2017-07-11 21:21:17 +02:00
Paulus Schoutsen
6e77877743 Update frontend 2017-07-11 09:11:36 -07:00
Alan Fischer
7b105a2150 Updated pyvera (#8437) 2017-07-11 15:14:46 +02:00
Aliaksandr
ee57a823af Added media_helper service (#8369)
* Added media_helper service

* Fixed lint warning

* media_helper renamed to media_extractor
2017-07-11 10:16:34 +02:00
Andrew
04b1621b65 Fix radiothermostat -1 value issue (#8395)
* Fix -1 value issue

Fixed issue where thermostat will sometimes return a current temperature or set temperature value of -1

* Update radiotherm.py

* Update radiotherm.py

* Update radiotherm.py

Added retry limit

* Update radiotherm.py

* Update radiotherm.py
2017-07-11 10:12:51 +02:00
Marcelo Moreira de Mello
f5e24cb0bb Refactored Amcrest to use central hub component (#8184)
* Refactored Amcrest to use central hub component

* Set default streaming source to snapshot

* Simplified code by using discovery platforms

* Makes lint happy

* Update authentication method to basic

* Fixed lint issues

* Makes Amcrest hub async

*  Make Amcrest hub IO synchronous and disabled ffmpeg dependency on sensor/amcrest.

* Removed async to load component

* Organized import order

* Update amcrest.py
2017-07-11 10:10:10 +02:00
Russell Cloran
ac72dea09a Add support for Prometheus (#8211)
Prometheus (https://prometheus.io/) is an open source metric and alerting
system. This adds support for exporting some metrics to Prometheus, using
its Python client library.
2017-07-10 21:20:17 -07:00
Russell Cloran
2f474a0ed8 zha: Handle both input and output clusters (#8410)
bellows 0.3.0 changes the API to have both, renaming the attribute which used
to be for input clusters in the process.

This is in preparation for remotes.
2017-07-10 21:16:44 -07:00
thecynic
7a4cc8e082 Fix typo (sending USERNAME instead of PASSWORD) introduced in #7963 (#8433) 2017-07-10 20:52:37 -07:00
Mike Christianson
92dc76773a Allow Twitter notifications to include media (#8282)
* Allow notifications to include media, with Twitter as the first implementation. The Twitter notifier uses the Twitter-recommended async chunked media/upload approach and tries to convey the correct mime type of the media. Twitter implementation based on https://github.com/geduldig/TwitterAPI/blob/master/examples/upload_video.py.

* Changes based on balloob's review:
balloob: "Please remove this file. We fixed the issue in our tests that left this artifact."
balloob: "…prefer a guard clause"
balloob: "This is very inefficient. You are now generating up to 99 values."
balloob: "Since media_id is going to be None, why not just return None and you can remove the else."

* balloob: "Other notify platforms are using ATTR_DATA for it. That way if a platform requires extra metadata, we don't need to add extra fields. So please add it to Twitter via ATTR_DATA."
2017-07-10 19:58:01 -07:00
Open Home Automation
fe4abc8454 Integrate utility functions into restricted Python environment (#8427) 2017-07-10 18:42:42 -07:00
Eugenio Panadero
821d01f82c New service send_magic_packet with new component wake_on_lan (#8397)
* New service `send_magic_packet` in new component `wake_on_lan`

* fix

* Unit tests for new component wake_on_lan

* Add wakeonlan to tests requirements

* remove wakeonlan from tests requirements and remake the component tests

* remove wakeonlan from tests requirements

* link domain and service names to component

* fix mocking in test_setup_component

* send_magic_packet as coroutine, better use of mock_calls in tests

* fix imports

* review changes

* better async calls

* Update test_wake_on_lan.py
2017-07-10 18:37:51 -07:00
Teemu R
b453834b2f bump python-mirobo requirement to support newer firmwares and more (#8431) 2017-07-10 23:18:58 +02:00
Fabian Affolter
97f14015ea Use HA lat/long for the start (fixes #3971) (#8429) 2017-07-10 23:16:37 +02:00
Fabian Affolter
4fb25cf16d Fix KeyError (fixes #3721, fixes #7241) (#8428) 2017-07-10 23:15:59 +02:00
Julius Mittenzwei
e7b5c5812c Fixed link to documentation (#8424)
* Issue #8203: fixed link to documentation

* Revert URL change

* Minor changes to docstring
2017-07-10 12:11:16 +02:00
James Marsh
2ac423bd9d Do not overwrite a custom hyperion light name with the hostname of the server. (#8391)
Do not overwrite a custom name with the hostname of the hyperion server.
Correct comment in name() method.

Fixes #8390
2017-07-10 00:06:31 +02:00
Adam Mills
ec7ca9a560 Make gzips reproducible by excluding timestamp (#8420) 2017-07-09 16:21:17 -04:00
Matthew Treinish
cb298123d4 Add set_operation_mode support to generic_thermostat (#8392)
This commit adds support for the set_operation_mode system call to the
generic thermostat component. This enables users to set whether the
thermostat is enabled or not by either setting it to auto or off.
2017-07-08 09:21:10 -07:00
Andrey
c5bf4fe339 Properly handle the case when a group includes itself. (#8398)
* Properly handle the case when a group includes itself.

* Fix lint
2017-07-08 09:20:11 -07:00
Julius Mittenzwei
57c5ed33ee New component to connect to VELUX KLF 200 Interface (#8203)
* New component to connect to VELUX KLF 200 Interface

* Issue #8203: modifications as suggested by hound

* Issue #8203: added entries to .coveragerc

* moving velux/__init__p.y to velux.py

* Issue #8203: Using hass.data for storing global object, updated docstrings

* Issue #8203: validation of config, using standard approach for getting config values

* Issue #8203: Exception handling if connection to velux component fails

* Issue #8203: removed unused import

* Issue #8203: Some minor changes within docstrings

* Issue #8203: Some minor changes within docstrings

* Issue #8203: added dependency for pyvlx to requirements_all.txt

* Issue #8203: less broad exception

* Issue #8203: increased version

* Issue #8203: changed position of pyvlx within requirements_all.txt

* Issue #8203: bumped version of pyvlx to 0.1.3 (better handling of retries when token expires)

* reset pointer to home-assistant-polymer

* Issue #8203: modifications as suggested by fabaff

* hound *sigh*
2017-07-08 16:12:19 +02:00
Oliver
3be0103259 Marrantz SR5006 & SR5006 treated as AVR-X device | Fixed Mapping of Media Player and AUX input functions (#8409) 2017-07-08 16:02:59 +02:00
Andy Castille
614b5da170 Use upstream RachioPy, fix manual run switches (#8286)
* use upstream RachioPy, fix manual run switches

* Update requirements for PyPi version of rachiopy

* Use upstream RachioPy 0.1.2 (partial revert of 39c6484d89)

* Revert rachiopy downgrade
2017-07-08 11:34:34 +02:00
Fabian Affolter
acf6d4ab82 Upgrade Sphinx to 1.6.3 (#8405) 2017-07-08 11:57:24 +03:00
Adam Mills
d3acb25070 Fix CODEOWNERS z-wave team name (#8400) 2017-07-07 17:00:14 -07:00
Charles Blonde
222ad3ab6d Add new Dyson sensors (#8199)
* Add new Dyson sensors

* Add unit of measurement for dust and air quality

* Code review
2017-07-07 16:59:41 -07:00
Paulus Schoutsen
5ae2bcdbb7 Code owners (#8393)
* Add initial code owners file

* Add component author owners

* Add link to blog

* Sort

* Add setup.py

* Update CODEOWNERS
2017-07-07 11:40:04 -07:00
Anders Melchiorsen
6c9742afc4 Update aiolifx (#8396) 2017-07-07 19:57:14 +02:00
Andrey
cf924cd14d Update waqi sensor (#8385) 2017-07-07 07:55:58 -07:00
Paulus Schoutsen
f2267437df Update snips.py 2017-07-07 07:53:04 -07:00
Tom Matheussen
233920f22c Sets spotify media_type to music (#8387)
* Sets spotify media_type to music

* Removed whitespace

* Update spotify.py
2017-07-07 07:52:11 -07:00
Open Home Automation
7536e825fa LaMetric platform and notify module (#8230)
* First version of a LaMetrci platform with a Notify module

* Cleanup, fix formatting bugs

* More formatting

* Formatting

* Updated requirements

* formatting

* Formatting

* More formatting

* Dummy commit for new Travis CI run

* Refactoring class methods to instance methods

* Cleanup unused classed

* Removed Eddystone_weatherurl that had nothing to do with this component

* Cleanup class methods

* Cleanup requirements

* Removed broad excepts
Removed storage of LaMetric devices

* Removed unused import
2017-07-07 08:21:06 +02:00
Pascal Vizeli
e12a9eaadd Update avion.py (#8364)
* Update avion.py

* Update decora.py

* Update decora.py

* Update decora.py

* Update avion.py

* Update decora.py

* Update decora.py

* Update decora.py

* Update decora.py
2017-07-06 23:20:39 -07:00
Simao
fb184b4b6f Added support for upload of remote or local files to slack (#8278)
* Added support for upload of remote or local files to slack

* Checking local file with hass.config.is_allowed_path prior to posting it
2017-07-06 23:14:24 -07:00
Andy Castille
63ff173305 Use user-set device names for Linksys Smart Wi-Fi routers (3) (#8300)
* Use user-set device names for Linksys Smart Wi-Fi routers (3)

* Newline at end of linksys_smart.py

* Remove spaces in last line of linksys_smart.py

* Update linksys_smart.py
2017-07-06 23:07:12 -07:00
Diogo Gomes
903e6b5aee Upnp mapping notification (#8303)
* make port mapping optional

* dependencies + improvements

* Added bytes and packets sensors from IGD

* flake8 check

* new sensor with upnp counters

* checks

* whitespaces in blank line

* requirements update

* added sensor.upnp to .coveragerc

* downgrade miniupnpc

Latest version of miniupnpc is 2.0, but pypi only has 1.9

Fortunately it is enough

* revert to non async

miniupnpc will do network calls, so this component can’t be moved to
coroutine

* hof hof

forgot to remove import ot asyncio

* UPnP mapping overlap

Addressing: https://community.home-assistant.io/t/upnp-new-module/20839

* removed whitespaces
2017-07-06 23:05:09 -07:00
Russell Cloran
46ce26eb7a zha: Try multiple reads to get manufacturer/model (#8308)
Some devices don't seem to return the information properly when asked for
multiple attributes in one read. This separates out the reads if it didn't
work as expected the first time.

Because this data is cached in bellows, I don't expect any extra reads in
the "happy" case.
2017-07-06 23:02:22 -07:00
Russell Cloran
b1bba3675d zha light: Refresh at startup (#8310)
* zha light: Refresh at startup

* Add asyncio.coroutine annotation
2017-07-06 22:59:17 -07:00
Alex
ed5d10448e Presence detection for tp link eap225 (#8322)
* Added support for TP-Link EAP 225

* code style changes

* more code style changes

* more understandable variable name

* Added support for TP-Link EAP 225

* code style changes

* more code style changes

* more understandable variable name

* Fix pylint issue (#8325)

* Added support for TP-Link EAP 225

* code style changes

* more code style changes

* more understandable variable name

* Added support for TP-Link EAP 225

* code style changes

* Update snips.py
2017-07-06 22:52:40 -07:00
William Scanlon
652c006cbc Prevent errors on Octoprint sensors and binary_sensors when Octoprint and/or Printer are off (#8343)
* Added platformnotready

* Only log the first failure if octoprint/printer isn't up

Remove blank line
2017-07-06 22:39:11 -07:00
PhracturedBlue
b67c5df525 cover_template:i open/close/stop actions no longer required. Improve tests (#8344) 2017-07-06 22:35:59 -07:00
Matthew Schick
a7d5a8d93e Cleanup the asuswrt component (#8359)
* Get the list of wireless interfaces from nvram so tri-band routers
  work
* ARP checks don't work reliably for ap mode so remove it, associated
  list seems pretty solid
* Match on 'mac' instead of 'ip' since we can't use it for ap mode
* The `client_info_tmp` nvram reference, Asus removed it some time ago
* Update AsusWrtResult
2017-07-06 22:34:21 -07:00
Sabesto
c48c2b00a8 Modbus fixes to work with pymodbus 1.3.1 (#8365)
* Fixed a bug where changing fan speed was not possible

* Bump pymodbus version to 1.3.1 to fix issue #8285

* Changed all modbus components so that they use CONF_SLAVE from const.py

* Fix checking result from a modbus transaction

* Add missing decorator

* Added modbus write coil service and added descriptions

* Removed a hiding debug print
2017-07-06 22:30:23 -07:00
Charles Blonde
9bc5cd2d4b Add Soundtouch support for playing an HTTP url (#8370) 2017-07-06 22:28:09 -07:00
Open Home Automation
ecf3a9cb36 Implement KNX dimming functionality (#8371)
* Implement KNX dimming functionality

* Formatting

* Formatting

* Formatting
2017-07-06 22:24:25 -07:00
Marc Plano-Lesay
074e31bcf9 GTFS: check start/end date on services (#8373)
Fixes #8372
2017-07-06 22:22:31 -07:00
Open Home Automation
63cc658010 Add address-specific KNX listeners that fire events on the HASS bus (#8374)
* Add address-specific KNX listeners that fire events on the HASS bus

* Added docstring
1-byte messages will be converted from a list to the value

* Formating
2017-07-06 22:21:40 -07:00
Charles Blonde
8682f21fc5 Fix TTS options. #8375 (#8376) 2017-07-06 22:20:49 -07:00
Charles Blonde
aa28e6727d Fix Amazon Polly with non english voices. #8377 (#8378) 2017-07-06 22:19:05 -07:00
Sean
12129f0e6a Try catch around database updates in recorder. Resolves 6919 (#8349)
* Try catch around database updates in recorder. Resolves 6919

* Fixing failed test for line length

* Catch only OperationalError and retry connections before giving up

* Including alchemy exceptions in single function
2017-07-06 21:46:50 -07:00
Teemu R
8a7cfce67b Add component for xiaomi robot vacuum (switch.xiaomi_vacuum) (#7913)
* add component for xiaomi robot vacuum (switch.xiaomi_vacuum)

* enforce token length, update requirements_all.txt and .coveragerc

* bump version to avoid catching generic exception
2017-07-06 21:44:34 -07:00
mjj4791
5e71e9b826 buienradar==0.7, fix winddirection/azimuth, logging (#8281)
* buienradar==0.7, fix winddirection/azimuth, logging

* prevent multiple update cycles

* prevent multiple update cycles

* prevent multiple sensor updates for precipitation forecast

* prevent multiple sensor updates for precipitation forecast

* Update comments

* Adapted logging

* Adapted logging
2017-07-06 21:39:28 -07:00
Pierre Ståhl
db8bb53984 Add One-Time Password sensor (OTP) (#8332) 2017-07-06 21:25:54 -07:00
Craig J. Ward
692f4c293b update version (#8380) 2017-07-06 21:24:04 -07:00
John Mihalic
da37380410 Update pyHik to catch XML errors (#8384) 2017-07-06 21:23:47 -07:00
Paulus Schoutsen
fa4aa2244e Allow all panel urls (#8368)
* Allow all panel urls

* Lint
2017-07-06 20:58:21 -07:00
Michael Heinemann
c63bdd5afe Mqtt client_id fix for #8315 (#8366)
This applies what was the intended fix in #8336.

moves the fallback for setting client_id to the case when no mqtt config was provided at all. This should reflect the most common use case that fails.

This commit is a workaround and should be reverted when hbmqtt is fixed to allow empty client_id again.
2017-07-06 14:47:30 -07:00
clarkewd
20a9899354 Allow Pilight Binary Sensor to control reset_delay_sec through configuration (#8358)
* Allow Pilight Binary Sensor to control reset_delay_sec through configuration

* Define constant in platform

* Don't define constant twice
2017-07-06 21:09:31 +02:00
Johan Bloemberg
fe6a4b8ae5 Correct spelling of aliases, deprecate old config options. (#8348)
* correct spelling of aliases

* add deprecation

* Fix style.
2017-07-06 15:59:54 +02:00
Paulus Schoutsen
143044f8f1 Remove some more usage of run_in_executor (#8352)
* Remove usage of run_in_executor

* Lint
2017-07-06 14:08:32 +02:00
Fabian Affolter
d655c0e358 Upgrade aiohttp to 2.2.3 (#8363) 2017-07-06 13:56:50 +02:00
Paulus Schoutsen
46e030662d Fix pylint 1.7.2 no-else-return issues (#8361)
* Fix pylint 1.7.2 no-else-return issues

* Update tomato.py
2017-07-05 23:30:01 -07:00
Paulus Schoutsen
5779d64e98 Fix some issues for PyLint 1.7.2 (#8356)
* Fix some issues for PyLint 1.7.2

* More fixes

* Revert position change for cover
2017-07-05 20:02:16 -07:00
Lev Aronsky
83a5f932d1 Add citybikes platform (#8202)
* Initial commit - new CityBikes platform

* Several syntax fixes.

* Added imperial unit support.

* Added station list lenght validation.

* Style fixes.

* Updated requirements.

* Updated .coveragerc.

* Fixed style problems according to pylint output.

* Updated SCAN_INTERVAL value.

* Fixed station names.
Removed unnecessary calls to `slugify`.
Changed the base name to reflect the name of the bike sharing
network, instead of the more generic `citybikes`.

* Small style fix.

* Use async version of python-citybikes

* Made platform setup async.

* Made some more things async.

* Switched to constants.

* WIP: different approach to async.

* Removed python-citybikes depnedency to fix async issues.

* Removed unnecessary hidden property.

* Style fixes.

* Retry network detection.

* Style fixes, and base name usage.

* Fixes according to comments.

* Use cv.latitude instead of coercing to float.

* Updated requirements.

* Several fixes and improvements.

* Started using PlatformNotReady exception.
* Cached the networks list result to avoid unnecessary API requests.
* Switched the asyncio.timeout to use a constant.
* Refactored CityBikes API requests into a separate function

* Fixed linting errors.

* Removed unnecessary requirement.
2017-07-04 22:55:21 -07:00
Paulus Schoutsen
a12fa2e5bf Merge branch 'master' into dev 2017-07-04 21:53:35 -07:00
Paulus Schoutsen
ee37fc344b Merge pull request #8351 from home-assistant/release-0-48-1
0.48.1
2017-07-04 21:51:57 -07:00
Fabian Affolter
8cc0748db3 Temporary fix for the client_id generation (fixes #8315) (#8336)
* Temporary fix for the client_id generation (fixes #8315)

* Fix comment

* Move client id setting.

* Lint
2017-07-04 21:47:48 -07:00
Fabian Affolter
0ecceb601b Temporary fix for the client_id generation (fixes #8315) (#8336)
* Temporary fix for the client_id generation (fixes #8315)

* Fix comment

* Move client id setting.

* Lint
2017-07-04 21:47:30 -07:00
Fabian Affolter
2a1a5e53a1 Fix hass.data (fixes #8288) (#8290) 2017-07-04 21:43:15 -07:00
Paulus Schoutsen
c8b782189e Fix harmony (#8302)
* Fix harmony

* Fix 1 reference
2017-07-04 21:43:15 -07:00
Pascal Vizeli
74016c4179 Fix pathlib resolve (#8311)
* Fix pathlib resolve

* fix test
2017-07-04 21:43:15 -07:00
Adrien Ball
c30c8df449 Fix Snips json schema (#8317)
* Fix Snips json schema

* Fix test
2017-07-04 21:43:14 -07:00
Eugenio Panadero
58de661ad5 API POST has new state validation (fix for state = 0) (#8324)
* Fix validation of get new state

* Add unittest to check posting a state with zero value
2017-07-04 21:43:14 -07:00
bergemalm
f4a97db783 Fix arlo sensors. (#8333) 2017-07-04 21:43:14 -07:00
Paulus Schoutsen
b220ceec9c Update frontend 2017-07-04 21:41:22 -07:00
Paulus Schoutsen
fb796b5481 Version bump to 0.48.1 2017-07-04 21:38:48 -07:00
Pierre Ståhl
ea5bec3ef4 Add new feature to Apple TV platform (#8122)
* Lift Apple TV to pyatv 0.3.2

Update code to use basic new features.

* Support button presses in Apple TV

* Support device authentication

* Convert Apple TV to a component

A media_player platform and a remote platform will be loaded for each
manually configured or discovered device.

* Move device auth to apple_tv component

* Update requirements and coverage config

* Add scan support to apple_tv
2017-07-04 21:37:18 -07:00
Flavien Charlon
8185587100 Fix the "302" error in the UPC Connect component and remove the need to specify the router password (#8335)
* Remove the need to login on the UPC Connect component

* Remove unnecessary imports

* Update the unit tests for the UPC Connect component

* Fix the "302" error with the UPC Connect component

* Fix a flake8 error

* Update the unit tests for the UPC Connect component
2017-07-04 21:06:24 -07:00
Matthew Garrett
061a38cc3b Update Avion and Decora switches to match upstream changes (#7903)
The upstream Avion and Decora code has changed to punt retry logic out to
consumers, so update to match. As a bonus, Avion also gains support for
pulling switch configuration off the web rather than requiring manual
configuration.
2017-07-05 00:39:51 +02:00
Pascal Vizeli
23fc5e2c9f Bump dlib face_recognition to 0.2.0 (#8345)
* Update dlib_face_detect.py

* Update dlib_face_identify.py

* Update requirements_all.txt
2017-07-04 23:07:53 +02:00
Sabesto
6496c38ce6 Fix issue #8285 (#8340)
* Fixed a bug where changing fan speed was not possible

* Bump pymodbus version to 1.3.1 to fix issue #8285

* Changed all modbus components so that they use CONF_SLAVE from const.py
2017-07-04 17:01:35 +02:00
Fabian Affolter
3363b88a73 Only allow 'tls_insecure_set()' if cert is present (fixes #8329) (#8337)
Add an optional extended description…
2017-07-04 15:22:05 +02:00
Fabian Affolter
2e17d0926a Revert "Only allow 'tls_insecure_set()' if cert is present (fixes #8329)"
This reverts commit 85ac50cc77.
2017-07-04 13:46:38 +02:00
Fabian Affolter
85ac50cc77 Only allow 'tls_insecure_set()' if cert is present (fixes #8329) 2017-07-04 13:40:38 +02:00
Fabian Affolter
da61b18392 Partially revert #7931 (#8326) 2017-07-04 10:07:06 +02:00
bergemalm
8a88af20da Fix arlo sensors. (#8333) 2017-07-04 10:06:46 +02:00
John Mihalic
f8527e9773 Update pyEmby to fix media images (#8331) 2017-07-04 08:02:29 +02:00
Per Sandström
7977996c0d vsure 1.3.7 (#8321) 2017-07-04 06:26:55 +02:00
Eugenio Panadero
22681fbe08 API POST has new state validation (fix for state = 0) (#8324)
* Fix validation of get new state

* Add unittest to check posting a state with zero value
2017-07-03 23:35:57 +02:00
Fabian Affolter
1e655eea74 Fix pylint issue (#8325) 2017-07-03 22:02:43 +02:00
Adrien Ball
8d940fb585 Fix Snips json schema (#8317)
* Fix Snips json schema

* Fix test
2017-07-03 15:07:59 +02:00
Fabian Affolter
afe3dd8dbb Upgrade aiohttp to 2.2.2 (#8314)
* Upgrade aiohttp to 2.2.1

* Upgrade to aiohttp to 2.2.2
2017-07-03 13:48:53 +02:00
Fabian Affolter
bf96f28e95 Upgrade chardet to 3.0.4 (#8313) 2017-07-03 11:49:23 +02:00
Russell Cloran
5cba3085b4 zha: Strip whitespace from device names (#8306) 2017-07-03 08:31:16 +02:00
Fabian Affolter
407a419c83 Upgrade discord.py to 0.16.8 (#8304) 2017-07-03 08:30:54 +02:00
Robin
4ab778fd97 Fix doc link in header (#8305)
* Fix doc link in header

* Add missing `/`
2017-07-03 08:30:42 +02:00
Pascal Vizeli
ee7d4710c4 Fix pathlib resolve (#8311)
* Fix pathlib resolve

* fix test
2017-07-03 07:24:08 +02:00
Paulus Schoutsen
3a6434f566 Fix harmony (#8302)
* Fix harmony

* Fix 1 reference
2017-07-02 13:05:07 -07:00
Wolfgang Malgadey
a2f5b630d6 pytado moved to pypi (#8298) 2017-07-02 12:54:59 -07:00
Paulus Schoutsen
3f2fa0ed5a Disable Python 3.6-dev while it's broken 2017-07-02 11:52:24 -07:00
Robin
865865ca0f Add london_underground (#8272)
* Add tube_state

Add tube_state sensor

* Final cleanup

* Make corrections

Correct PLATFORM_SCHEMA

* Fix space

* Make test pass

* Correct format of test

Test still failing, don’t understand why

* correct description

* Make test pass

Preferred method below returns None

state = self.hass.states.get('sensor.london_overground')

* Format for hound

* indent

* Make requested changes to test, not working

Test fails with:

AssertionError: assert 0 > 0
where 0 = len([])

Surely I need tube_state.setup_platform ?

* Fixed test

Config was wrong

* Change component name to london_tube

* Update name to london_underground

Make consistent

* cleanup
2017-07-02 11:32:38 -07:00
Open Home Automation
05ced33648 Update knxip to 0.4 (better handling of reconnects) (#8289) 2017-07-02 12:59:45 +02:00
Fabian Affolter
b4165fe9f3 Fix hass.data (fixes #8288) (#8290) 2017-07-02 12:02:41 +02:00
Michaël Arnauts
47aa8c387a Update apcaccess to 0.0.13. Add "Percent Load Capacity" to INFERRED_UNITS. (#8277) 2017-07-02 11:24:07 +02:00
Paulus Schoutsen
2b94857ffd Merge branch 'master' into dev 2017-07-01 17:42:23 -07:00
Paulus Schoutsen
7461c57542 Merge pull request #8270 from home-assistant/release-0-48
0.48
2017-07-01 16:58:10 -07:00
Paulus Schoutsen
632f9a21b6 Update frontend 2017-07-01 16:53:50 -07:00
Mike Megally
da44f80b32 Create an index on the states table to help hass startup time (#8255) 2017-07-01 14:10:39 -07:00
Mike Megally
0bf5021c2c Create an index on the states table to help hass startup time (#8255) 2017-07-01 14:10:17 -07:00
Michael Fester
8fb49e8687 Snips ASR and NLU component (#8156)
* Snips ASR and NLU component

* Fix warning

* Fix warnings

* Fix lint issues

* Add tests

* Fix tabs

* Fix newline

* Fix quotes

* Fix docstrings

* Update tests

* Remove logs

* Fix lint warning

* Update API

* Fix Snips
2017-07-01 13:58:35 -07:00
Michael Fester
b82003ae08 Snips ASR and NLU component (#8156)
* Snips ASR and NLU component

* Fix warning

* Fix warnings

* Fix lint issues

* Add tests

* Fix tabs

* Fix newline

* Fix quotes

* Fix docstrings

* Update tests

* Remove logs

* Fix lint warning

* Update API

* Fix Snips
2017-07-01 13:58:12 -07:00
Will W
5f8dc8af20 components.knx - KNXMultiAddressDevice corrections (#8275)
1. The has_attributes was comparing names to addresses
2. Some errors outside of an except block were using
_LOGGER.except. This will cause an exception itself because there is no
trance context available to the logger
3. Added alias names for the address and state addresses so that they
can be accessed with the same
4. Added return values for the set_int_value and set_percentage methods
to allow error checking similar to the set_value method
5. Added the name of the configured object to the log messages to make
them more meaningful (otherwise multiple similar log messages are
received without any hint as to the target device)
2017-07-01 13:31:01 -07:00
Will W
c13fdd23c1 components.knx - KNXMultiAddressDevice corrections (#8275)
1. The has_attributes was comparing names to addresses
2. Some errors outside of an except block were using
_LOGGER.except. This will cause an exception itself because there is no
trance context available to the logger
3. Added alias names for the address and state addresses so that they
can be accessed with the same
4. Added return values for the set_int_value and set_percentage methods
to allow error checking similar to the set_value method
5. Added the name of the configured object to the log messages to make
them more meaningful (otherwise multiple similar log messages are
received without any hint as to the target device)
2017-07-01 13:30:39 -07:00
Fabian Affolter
e6e0e5263a Don't call update() in constructor (#8276) 2017-07-01 16:14:18 +02:00
Fabian Affolter
0981956caa Upgrade pyowm to 2.7.1 (#8274) 2017-07-01 12:53:29 +02:00
lrmate
d267fc608f Update modbus.py (#8256)
* Update modbus.py

Prevents Modbus binary sensors showing up as "unnamed_device".
Originally proposed here https://community.home-assistant.io/t/modbus-sensor/6751/11 by user Pjeter

* Update modbus.py
2017-06-30 23:56:46 -07:00
lrmate
e077998d38 Update modbus.py (#8256)
* Update modbus.py

Prevents Modbus binary sensors showing up as "unnamed_device".
Originally proposed here https://community.home-assistant.io/t/modbus-sensor/6751/11 by user Pjeter

* Update modbus.py
2017-06-30 23:32:10 -07:00
Paulus Schoutsen
d3bc8519c0 Update frontend 2017-06-30 22:34:55 -07:00
viswa-swami
d3adc6ddfb Camera services arm disarm including Netgear Arlo (#7961)
* Added camera service calls to arm/disarm the cameras. Entity id is optional so that with a single call we can arm all the cameras or specify a particular entity id to arm if applicable and possible in that camera type.

* Added camera service calls to arm/disarm the cameras. Entity id is optional so that with a single call we can arm all the cameras or specify a particular entity id to arm if applicable and possible in that camera type.

* Added camera service calls to arm/disarm the cameras. Entity id is optional so that with a single call we can arm all the cameras or specify a particular entity id to arm if applicable and possible in that camera type.

* Fixed the spaces and indentation related issues that houndci found

* Fixed the spaces and indentation related issues that houndci found

* Missed the const file which has the macros defined.

* Fixed the CI build error

* Fixed the CI build error because of unused variable in exception case

* Updating the arlo code based on comment from @balloob. Changed the arm and disarm to enable_motion_detection and disable_motion_detection respectively. Similarly fixed the AttributeError handling. Added dummy code to the demo camera also. Moved out the definitions in const.py into the camera __init__ file

* Fixed the comments posted by houndci-bot

* Fixed the comments posted by houndci-bot

* Fixed the comments posted by houndci-bot

* Fixed the comments posted by travis-ci integration bot

* Fixed the comments posted by travis-ci integration bot

* Fixed the comments posted by travis-ci integration bot for demo.py: expected 2 lines, found 1

* Updated code in camera __init__.py to use the get function instead of directly calling the member in the structure.

* Updated code in camera __init__.py

* Posting the updated code for PR based on @balloob's suggestions/recommendations

* Removed the arlo reference from demo code. Copy-paste error

* Removed the unused import found by hound bot

* Expected 2 lines before function, but found only 1.

* Based on @balloob's comments, moved these constants to the camera/arlo.py

* Added test_demo.py to test the motion enabled and motion disabled in camera component

* Fixing issues found by houndci-bot

* Fixing issues found by houndci-bot

* Fixing the code as per @balloob's suggestions

* Fixing the code as per @balloob's suggestions

* Fixing the test_demo failure. Tried to rewrite a base function to enable the motion in __init__.py and missed to add it to as a job.

* Fixing the hound bot comment

* Update arlo.py

* Update arlo.py
2017-06-30 22:24:36 -07:00
Josh
a3f586d097 Adding done_message to alert (#8116)
* Adding done_message to alert

Adding an optional entry to the config that will send a notification when an
alarm goes from on to off.

* Update test_alert.py

* Update test_alert.py
2017-06-30 22:24:36 -07:00
Paulus Schoutsen
f8c7fd212f Revert "Make Android app shortcut use 'Home Assistant' as name." (#8271)
* Revert "Version bump to 0.49.0.dev0 (#8266)"

This reverts commit 8e4394f173.

* Revert "Adding done_message to alert (#8116)"

This reverts commit 5e56bc7464.

* Revert "Camera services arm disarm including Netgear Arlo (#7961)"

This reverts commit ed20f7e359.

* Revert "Make Android app shortcut use 'Home Assistant' as name instead of just 'Assistant'. (#8261)"

This reverts commit 0bcb7839fb.
2017-06-30 22:24:36 -07:00
Paulus Schoutsen
b1f3492fd0 Notify.smtp: default to STARTTLS 2017-06-30 22:15:41 -07:00
Paulus Schoutsen
7123ec14be Revert "Make Android app shortcut use 'Home Assistant' as name." (#8271)
* Revert "Version bump to 0.49.0.dev0 (#8266)"

This reverts commit 8e4394f173.

* Revert "Adding done_message to alert (#8116)"

This reverts commit 5e56bc7464.

* Revert "Camera services arm disarm including Netgear Arlo (#7961)"

This reverts commit ed20f7e359.

* Revert "Make Android app shortcut use 'Home Assistant' as name instead of just 'Assistant'. (#8261)"

This reverts commit 0bcb7839fb.
2017-06-30 21:57:38 -07:00
Fabian Affolter
8e4394f173 Version bump to 0.49.0.dev0 (#8266) 2017-06-30 21:07:50 -07:00
Josh
5e56bc7464 Adding done_message to alert (#8116)
* Adding done_message to alert

Adding an optional entry to the config that will send a notification when an
alarm goes from on to off.

* Update test_alert.py

* Update test_alert.py
2017-06-30 21:07:12 -07:00
viswa-swami
ed20f7e359 Camera services arm disarm including Netgear Arlo (#7961)
* Added camera service calls to arm/disarm the cameras. Entity id is optional so that with a single call we can arm all the cameras or specify a particular entity id to arm if applicable and possible in that camera type.

* Added camera service calls to arm/disarm the cameras. Entity id is optional so that with a single call we can arm all the cameras or specify a particular entity id to arm if applicable and possible in that camera type.

* Added camera service calls to arm/disarm the cameras. Entity id is optional so that with a single call we can arm all the cameras or specify a particular entity id to arm if applicable and possible in that camera type.

* Fixed the spaces and indentation related issues that houndci found

* Fixed the spaces and indentation related issues that houndci found

* Missed the const file which has the macros defined.

* Fixed the CI build error

* Fixed the CI build error because of unused variable in exception case

* Updating the arlo code based on comment from @balloob. Changed the arm and disarm to enable_motion_detection and disable_motion_detection respectively. Similarly fixed the AttributeError handling. Added dummy code to the demo camera also. Moved out the definitions in const.py into the camera __init__ file

* Fixed the comments posted by houndci-bot

* Fixed the comments posted by houndci-bot

* Fixed the comments posted by houndci-bot

* Fixed the comments posted by travis-ci integration bot

* Fixed the comments posted by travis-ci integration bot

* Fixed the comments posted by travis-ci integration bot for demo.py: expected 2 lines, found 1

* Updated code in camera __init__.py to use the get function instead of directly calling the member in the structure.

* Updated code in camera __init__.py

* Posting the updated code for PR based on @balloob's suggestions/recommendations

* Removed the arlo reference from demo code. Copy-paste error

* Removed the unused import found by hound bot

* Expected 2 lines before function, but found only 1.

* Based on @balloob's comments, moved these constants to the camera/arlo.py

* Added test_demo.py to test the motion enabled and motion disabled in camera component

* Fixing issues found by houndci-bot

* Fixing issues found by houndci-bot

* Fixing the code as per @balloob's suggestions

* Fixing the code as per @balloob's suggestions

* Fixing the test_demo failure. Tried to rewrite a base function to enable the motion in __init__.py and missed to add it to as a job.

* Fixing the hound bot comment

* Update arlo.py

* Update arlo.py
2017-06-30 21:06:56 -07:00
Fabian Affolter
74acc5cf41 Merge branch 'master' into dev 2017-06-30 18:56:26 +02:00
Michaël Arnauts
0bcb7839fb Make Android app shortcut use 'Home Assistant' as name instead of just 'Assistant'. (#8261) 2017-06-30 18:51:07 +02:00
PhracturedBlue
17237e9d3f Implement templates for covers (#8100)
* Implement templates for covers

* Fix a few remaining pylint warnings

* Fix hound line-length warnings

* Fix one more hound line-length warning

* Fix quadruple-quotes an line length code-quality issues

* Irrelevant change to retrigger travis due to timeout

* Use volutuous Exclusive to check for mutex condition

* Fix incorrect state check
2017-06-30 08:24:29 -07:00
Michaël Arnauts
a663dbada0 Docker cleanup. (#8226) 2017-06-30 08:07:33 -07:00
Fabian Affolter
96e1d5524a Upgrade libnacl to 1.5.1 (#8259) 2017-06-30 11:12:21 +02:00
JudgeDredd
33fd2250fd further document add_node_secure (#8229)
added documentation to *attempt* explanation that add_node_secure will also function for adding unsecure nodes.
2017-06-30 10:00:38 +03:00
Per Sandström
31f17a91e6 verisure component names (#8251) 2017-06-30 08:53:14 +02:00
Andrey
d0720ac699 Add PlatformNotReady support for Sensibo (#8252) 2017-06-30 08:50:25 +02:00
Fabian Affolter
05acf1c10a Use constant and update ordering (#8246) 2017-06-30 08:46:22 +02:00
Fabian Affolter
27c92937f2 Use 'hass.data' instead of global (#8245) 2017-06-30 08:46:03 +02:00
Anders Melchiorsen
a328df6014 LIFX: Small code cleanups (#8228) 2017-06-30 02:10:28 +02:00
Eugenio Panadero
1fb4eefc2c better logging to debug when a message is not sent (#8248) 2017-06-29 21:13:46 +02:00
Fabian Affolter
0f12b4c955 Do not call update() in constructor (#8247)
Add an optional extended description…
2017-06-29 16:21:29 +02:00
Fabian Affolter
a9f14b67a8 Update docstrings (#8244) 2017-06-29 11:44:35 +02:00
Eugenio Panadero
445065700c update i2csense requirement (#8242) 2017-06-29 11:03:52 +02:00
Fabian Affolter
4bd96fd437 Upgrade python-digitalocean to 1.12 (#8241) 2017-06-29 10:52:12 +02:00
Michaël Arnauts
5dde0c2201 Comfoconnect fan component (#8073)
* Comfoconnect fan component.

* Fix linter. Don't store hass object when not needed.

* More code style.

* Rebase to dev and add to coverage ignore list.

* Use published package from pypi.
2017-06-28 18:04:54 +02:00
Open Home Automation
6846a76c46 KNX Cover tilt control (#8159)
* Added invert flag for position for actuators that uses 100% for fully closed position

* Implementation of tilt functionality

* Bugfix check tilt

* Formatting

* Formatting fixes

* Formatting

* Bugfix set_tilt

* Minor modifications in configuration section

* Formatting

* Update knx.py
2017-06-28 14:08:07 +02:00
Fabian Affolter
fa6e93f0c7 Do not call update() in constructor (#8148)
* Do not call update() in constructor

* Move handling to update and re-add throttle

* Fix indent

* Fix interval
2017-06-27 10:56:25 +02:00
Paulus Schoutsen
5ef274adce Cleanup automations yaml (#8223) 2017-06-27 10:36:26 +02:00
Eugenio Panadero
e39f7d3ef5 Fix homeassistant.start trigger (#8220)
* Fix homeassistant.start trigger

* ooops

* set sleep(0) just before changing to running state, revert async_block_till_done changes
2017-06-27 10:36:00 +02:00
Will W
88b9503962 add percentage (DPT_Scaling) KNX sensors (#8168)
* add percentage (DPT_Scaling) KNX sensors

1. moved basic functionality to KNXSensorBaseClass instead of
KNXSensorFloatClass
2. added "if" clause in setup for a "percentage" sensor type and added KNXSensorDPTScalingClass

* support-knx-percentage-sensor: lint correction

Updated convert method base sensor class to avoid lint warning
(R201 - Method could be a function)

* added PLATFORM_SCHEMA for configuration

1. added SCHEMA extension for defined keywords
2. moved fixed data for internal settings out of sensor logic
3. moved everything into standard KNXSensor object
4. added parsing of extra config parameters in __init__

* correct lint errors on support-knx-percentage-sensor
2017-06-26 22:25:54 -07:00
Eugenio Panadero
596093d564 telegram_bot platform to only send messages (#8186)
* add new telegram_bot platform to only send messages

* Fix async
2017-06-26 22:22:33 -07:00
natemason
23400c4b0a Fixed mqtt subscription filter on sys $ topics (#8166)
* Fixed mqtt subscription filter on sys $ topics

* fixed linting issue

* added unit tests for $ topics and changed fix to use re.escape

* merge upstream/dev mqtt unit tests

* Update test_init.py
2017-06-26 22:17:55 -07:00
Anders Melchiorsen
af54311718 LIFX: Move light effects to external library (#8222)
* LIFX: Move light effects to external library

This moves the LIFX light effects to the external library aiolifx_effects.

To get the light state synchronized between that library and HA, the LIFX
platform no longer maintains the light state itself. Instead, it uses the
cached state that aiolifx maintains.

The reorganization also includes the addition of a cleanup handler.

* Fix style
2017-06-26 22:05:32 -07:00
Pascal Vizeli
442dcd584b Improve executor pool size / speedup python 3.5 (#8215)
* Improve executor pool size / speedup python36

* fix style

* Add comment
2017-06-26 18:18:42 -07:00
Eugenio Panadero
1e4aec63ed guess the content_type in local_file cameras (#8217)
* guess the content_type in local_file cameras

* add unittest to check content_type of local_file cameras
2017-06-26 22:36:35 +02:00
Per Sandström
80c187f8ea WIP: Verisure app api (#7394)
update to verisure app api
2017-06-26 22:30:25 +02:00
Paulus Schoutsen
d73b695e73 EntityComponent to retry platforms that are not ready yet (#8209)
* Add PlatformNotReady Exception

* lint

* Remove cap, adjust algorithm
2017-06-26 09:41:48 -07:00
Adam Baxter
f02d169864 Fix Plex component to use port number in discovery. (#8197)
* Fix Plex component to use port number in discovery.

* Break line

* Correctly save port to config

* Handle port with fewer code changes

* This is stuck configuring and I'm not sure why

* Changes suggested by @dale3h
2017-06-25 18:06:15 -05:00
Pascal Vizeli
2dd7f0616e Add security layer to send file output things (#8189)
* Add security layer to send file output things

* Make telegram secure

* fix lint

* fix handling

* invert check

* resolve relative paths

* add test for relative paths

* fix lint

* fix tests

* Address paulus comments

* fix style

* fix tests

* Add more tests

* fix tests

* fix tests

* fix test p2

* fix lint

* fix tests

* Make it available for windows

* Change name / address comments

* fix set

* fix test

* fix tests

* fix test

* fix lint
2017-06-26 00:10:30 +02:00
Wim Haanstra
2f2952e0ec Openhardwaremonitor (#8056)
* Open Hardware Monitor sensor

Platform which is able to connect to the JSON API of Open Hardware Monitor and adds sensors for the devices.

* Remove copyright in header, not needed.

* - Removed old code
- Fixed typo’s in comments
- Removed log spamming
- Removed code that was unnecessary
- Use requests instead of urllib
- Moved sensor update functionality to data handler, to remove unwanted constructor parameters

* Fixed typo in comment
Added tests

* Added default fixture, to stabilize tests

* - Fix for values deeper than 4 levels, no longer relies on fixed level
- Fixed tests

* Removed timer in preference of helper methods

* Moved update functionality back to Entity….
Updated SCAN INTERVAL

* Added timeout to request
Removed retry when Open Hardware Monitor API is not reachable
Fixed naming of sensors
Flow optimalisations
Fixed tests to use states

* Remove unused import
2017-06-25 13:48:05 -07:00
Adam Mills
8358542ce0 Remove unnecessary thread_ident assignment (#8194)
* Remove mocking of _thread_ident

* Re-add run_loop thread_ident assignment
2017-06-25 16:39:05 -04:00
Eugenio Panadero
4ca5ed25bc add option to set content_type in camera.generic to support 'svg cameras' (#8188)
* add custom content_type to support 'generic svg cameras'

* add unittest to check content_type for svg generic camera

* Tweak tests
2017-06-25 12:25:14 -07:00
Paulus Schoutsen
7bf6ceafec Split mock_service (#8198) 2017-06-25 10:53:15 -07:00
Paulus Schoutsen
1cfed4f015 Fix plants calling async methods from sync context (#8200) 2017-06-25 10:07:28 -07:00
Paulus Schoutsen
a082ffca1d Fix MySensors climate (#8193) 2017-06-24 18:11:34 -07:00
Oliver
1b563b0640 Pushed to version 0.5.1 of the library (#8190) 2017-06-24 12:14:57 -07:00
Adam Mills
1fe189e9cb Switch to new zwave entity ids by default (#8192) 2017-06-24 15:01:57 -04:00
Marc Plano-Lesay
edeb92ea42 Add offset option to sensor.gtfs (#7980)
* Add offset option to sensor.gtfs

* Fix long lines in sensor.gtfs

* Expose GTFS offset as an attribute
2017-06-24 17:45:14 +02:00
Alex Mekkering
c1095665e9 added optional node_id to MQTT discovery (#8096) 2017-06-24 00:46:41 -07:00
Kane610
2a1f8af10a Axis service vapix call (#7794)
* Initial commit for an Axis service to do Vapix calls to device

* Added check to see if metadatastream initiated properly

* Make sure to configure the correct IP address when setting up registered devices on system start

* Manage reconnection when device is discovered with a different IP

* Cleaned up setting new IP

* Better naming of event for new IP

* New version of dependency axis

* Fix flake8 failing

* Break out service default strings to constants

* Use the dispatcher and not the core event bus for internal communication
2017-06-24 00:14:57 -07:00
Bas Schipper
6234f2d73f Added buienradar precipitation forecast average & total sensors (#8171)
* Added precipitation forecast average & total sensors

* Fixed some code style issues

* Fixed some code style issues

* Minor fix default timeframe

* Update buienradar.py

* Update buienradar.py
2017-06-24 00:12:52 -07:00
Paulus Schoutsen
b488663f2c Update Dockerfile 2017-06-23 23:13:38 -07:00
Sean Dague
a55d8776ff Throw exception if _convert_for_display called on non Number (#8178)
In trying to come up for some reason behind issue #6365 (which only
happens on some platforms) the best guess is that some components are
managing to get a string value all the way up to the Polymer UI for
temperature, which then an increment of +0.5 is treating as a string
concat operation instead of addition. So 20 + 0.5 becomes 200.5 hits
the max thermostat value.

This will throw an exception if the climate temp value isn't a
number. That's going to turn a soft fail into a hard fail on
potentially a number of platforms. Mysensors is one of the platforms
that was reported as having the issue. So put some explicit float
casts where that might be coming from as well.
2017-06-23 23:03:37 -07:00
Ryan Nowakowski
5ceb4c404d Fix radiotherm model CT50 (#8181)
Model CT50 has an "Auto" mode.  When mode is set to auto we need to ask
what the current state is: cool or heat.  Then we can query the
appropriate target temperature.

Without this fix, the target temperature shows up blank in the UI and
setting the mode fails.
2017-06-23 22:53:10 -07:00
lrmate
0061cece0c Update buienradar.py (#8173)
Swapped unit of measurement 'winddirection' vs 'windazimuth'
2017-06-23 22:51:45 -07:00
Morten Lied Johansen
0099168ff8 Add device tracker for Linksys Smart Wifi devices (#8144)
* Add device tracker for Linksys Smart Wifi devices

* Fixing code style
2017-06-23 22:36:04 -07:00
Paulus Schoutsen
87c89752ab Revert "Add libboost-python1.62-dev (fixes #7851)" (#8182)
* Revert "Uninstall enum34 in python3.6 docker image (#8103)"

This reverts commit 45f6f4443a.

* Revert "Add libboost-python1.62-dev (fixes #7851) (#7868)"

This reverts commit f1290d3135.
2017-06-23 22:33:33 -07:00
Jean Regisser
45f6f4443a Uninstall enum34 in python3.6 docker image (#8103)
* Uninstall enum34 in python3.6 docker image

This is a short term fix for #7733

What's happening is the following dependencies are pulling enum34:
- pygatt
- libsoundtouch
- yeelight
However, enum34 is not meant to be installed in Python versions 3.4+
and causing the `AttributeError: module 'enum' has no attribute 'IntFlag'``

I've submitted patches to these projects so we don't have to do this
manual uninstall in the future.

* Update Dockerfile
2017-06-23 22:29:39 -07:00
Fabian Affolter
f1290d3135 Add libboost-python1.62-dev (fixes #7851) (#7868) 2017-06-23 22:16:19 -07:00
Omar Usman
746aae51ec Add ClickSend notify service. (#8135)
* Add ClickSend notify service.

* PR #8135 changes.

- Some code spacing fixes.
- Add timeout to requests.
- Change doc url.
- Use const.py as much as possible.
- Check credentials to determine if setup fails or not.
- Add docstrings.
- Use string formatting.

* PR #8135 changes.

- Remove unused variables.
- Continuation line under-indented for visual indent.

* PR #8135 changes.

- Format code based on PEP8.

* PR #8135 changes.

- Remove unused base64 dependency.

* PR #8135 changes.

- Fix: D205: 1 blank line required between summary line and description (found 0)
- Fix: standard import "import json" comes before "import requests"

* PR #8135 changes.

- Add files to .coveragerc

* Remove obvious comments and set constant
2017-06-23 22:51:41 +02:00
Wolfgang Malgadey
da9430ed12 Tado climate device (#8041)
* added default parameter

* zone overlay can be set with or without a temperature and with or without a duration. Duration is not supported by hass

* Fixes issue #7059 with missing sensorDataPoints

* Fixes issue #6943 added ac_mode

* ac_mode cases
* added fan modes
* changed handling of device state OFF

* fixed an error initializing a dictionary (#6943)

* changed pytado version

* activated pytado debugging

* Changed pyTado version

* mytado.com changed authentication challenge

* Fixed linelength and whitespace issues

* requirements to pytado changed
2017-06-23 18:45:44 +02:00
Tim Wilde
bef22076ea Use version 1.3 of radiotherm (#8164)
Add an optional extended description…
2017-06-23 11:08:23 +02:00
Bas Schipper
fe93b51017 Fixed rfxtrx binary_sensor off command (#8160)
* Fixed applying rfxtrx binary off command

* Fixed some deprecation issues
2017-06-22 23:00:44 +02:00
Eugenio Panadero
07293e8d1e add telegram_bot service: delete_message (#8153)
* add telegram_bot service: delete_message

* better validating for `last` message_id option
2017-06-22 15:03:11 +02:00
Open Home Automation
ca71d34076 Added invert flag for position for actuators that uses 100% for fully closed position (#8147) 2017-06-22 13:42:13 +02:00
Anton Lundin
548417761e ubus: Refresh session on Access denied (#8111)
When a openwrt router reboots, all the session ids gets invalidated.
In that case we need to log in again and get a new session id.

Signed-off-by: Anton Lundin <glance@acc.umu.se>
2017-06-22 13:34:57 +02:00
Andrey
7b8ad1d365 Switch rachiopy to pypi (#8040)
* Switch rachiopy t pypi

* Update rachio.py

* Update requirements_all.txt
2017-06-22 13:34:00 +02:00
Fabian Affolter
61cb6ec3dc Upgrade libsoundtouch to 0.6.2 (#8149) 2017-06-22 13:27:42 +02:00
Fabian Affolter
349746f5f2 Upgrade python-telegram-bot to 6.1.0 (#8151) 2017-06-22 13:27:02 +02:00
Oliver
2e3b279873 Add support of Zone2 and Zone3 (#8025)
* Add support of Zone2 and Zone3

* Changes from balloobs feedback
2017-06-21 22:54:10 -07:00
Yannick POLLART
f26861976d Rfxtrx binary sensor (#6794)
* Added rfxtrx binary sensors to a new branch

* binary_sensor/rfxtrx: added support for automatic_add

* Fixed pylint warnings

* off_delay is set wit clearer time specifiers (cv.time_period)

* fire_event config attribute is now supported by rfxtrx binary sensors.

* Cosmetic ordering

* Fix lint errors for PR requirements.

* Fixed indents, line length and comment problems.

* Yet another line too long fix...

* Using existing attributes and config constants.

* Cosmetic fix (ATTR_DATABITS -> ATTR_DATA_BITS)

* Removed unused attribute

* FIX masked device id logging message

* FIX line too long

* FIX trailing white space

* FIX: rfxtrx binary_sensor manages its own devices only.

* Added a basic config helper for pt2262 devices

* Make pylint happy

* Fixed most houndci-bot-detected issues

* Fix TOX complaint about blank line after function docstring

* Fix data bit value calculation

* Fixed line too long

* Removed unnecessary code.

* remove trailing whitespace

* Added hass property to device object.
2017-06-21 22:48:45 -07:00
Anthony Hughes
6bfeac7f80 Harmony auto discovery via netdisco (#7741)
* Use netdisco to automatically discover harmony hubs.

* Allow some settings in configuration.yml to override even on discovered hubs.

* Global is not required as no assignment on variable

* Use `set` instead of list for perf

* Store cache of discovered devices against `hass.data` rather than in global

* Handle case if the device cache is empty

* Fix indentation issue
2017-06-21 22:43:35 -07:00
Miha Lunar
a95fe588ca LimitlessLED: Configurable fade-out behavior (#7369)
* Configurable fade-out behavior

Adds a per-group "fade" option with values of "out" (default) or "none".
By default, the lights are faded out when turned off, but this can cause usability issues when manually switching wall switches, since the bulbs turn back on at minimum brightness.

* Changed fade value from enum to boolean

* No need to fall back to default since voluptuous takes care of that.
2017-06-21 22:22:24 -07:00
Eugenio Panadero
e5d11dd1a5 Add new BH1750 light level sensor (#8050)
* new sensor platform
* requirements_all and .coveragerc update
2017-06-22 07:09:08 +02:00
Eugenio Panadero
435e5c8a91 Add I2c HTU21D temperature and humidity sensor for Raspberry Pi (#8049)
* Add new HTU21D temperature and humidity sensor

* new sensor platform
* requirements_all and .coveragerc update

* fix lint

* review changes: move sensor code to external module

* remove debug log msg

* add i2csense to COMMENT_REQUIREMENTS, require i2csense 0.0.3

* Add new HTU21D temperature and humidity sensor

* new sensor platform
* requirements_all and .coveragerc update

* fix lint

* review changes: move sensor code to external module

* remove debug log msg

* add i2csense to COMMENT_REQUIREMENTS, require i2csense 0.0.3

* change style for hass

* fix requirements
2017-06-22 07:05:58 +02:00
Jose Juan Montes
8d0553d9e6 Adds CPU temp monitoring, and allow startup when endpoint is not yet available. (#8093)
* Adds CPU temp monitoring, and allow startup when endpoint is not yet available.

* Added support for available() to glances sensor.
2017-06-21 22:45:15 +02:00
Charles Blonde
9a239d1afb Upgrade libsoundtouch to prevent Python3.6 errors with enum. #7733 #8103 (#8143) 2017-06-21 22:20:30 +02:00
Paulus Schoutsen
9252854f99 Merge pull request #8141 from home-assistant/release-0-47-1
0.47.1
2017-06-21 09:24:12 -07:00
Paulus Schoutsen
8d76e2679d Allow iteration in python_script (#8134)
* Allow iteration in python_script

* Add tests
2017-06-21 09:09:08 -07:00
Alan Fischer
4b1dcad7ae Fixed iTach command parsing with empty data (#8104)
* Fixed iTach command parsing with empty data

* Switched to using format
2017-06-21 09:09:08 -07:00
Phil Hawthorne
b45c386fd6 Update InfluxDB to handle datetime objects and multiple decimal points (#8080)
* Update InfluxDB to handle datetime objects

Updates the InfluxDB regex to ignore datetime objects being coverted
into float values.

Adds tests to the component to ensure datetime objects are corectly
handled.

* Fix Hound errors

Fixes errors from Hound bot

* Update InfluxDB to handle multiple decimal points

Changes the way InfluxDB handles values such as 1.2.3.4 to be 1.234 so
it stores in InfluxDB as a valid float value

* Fix lint issues

Reduce the size of a line for the linter

* Update InfluxDB to pass on unknown variable

If we get an error trying to convert a variable to a float, let's ignore
it completely

* Make InfluxDB Regex constants

Makes the Regex's used by InfluxDB constants so they don't need to be
compiled each time

* cleanup

* fix lint

* Update regex

* fix tests

* Fix JSON body missing new line character

* fix exceptions
2017-06-21 09:09:08 -07:00
Charles Blonde
cb5fa79835 Fix Dyson async_add_job (#8113) 2017-06-21 09:09:08 -07:00
Tsvi Mostovicz
b74217bec2 Fix lights issue #8098 (#8101)
* Fix lights issue #8098

* Don't check self._color to decide whether to calll get_color()

self._color is None on init, so get_color() will never be called.
2017-06-21 09:09:08 -07:00
Paulus Schoutsen
fcf60e740d Version bump to 0.47.1 2017-06-21 09:08:20 -07:00
Eugenio Panadero
bb05600010 Add I2c BME280 temperature, humidity and pressure sensor for Raspberry Pi (#7989)
* Add new BME280 temperature, humidity and pressure sensor

* Add BME280 sensor to optional requirements and .coveragerc

* move validation to sensor handler, async fix in setup

* fix Invalid attribute name

* review changes: move sensor code to external module

* async fix

* add i2csense to COMMENT_REQUIREMENTS, require i2csense 0.0.3, round prec to 1 dec

* change style for hass

* fix lint

* fix lint part 2
2017-06-21 17:24:39 +02:00
Thibault Cohen
d3bb6d3988 Decora light: Fix brightness level in UI (#8139) 2017-06-21 16:37:27 +02:00
Thibault Cohen
f3945147a4 Add current balance to hydroquebec sensor (#8138) 2017-06-21 16:36:20 +02:00
Paulus Schoutsen
6398e92836 Allow iteration in python_script (#8134)
* Allow iteration in python_script

* Add tests
2017-06-21 13:32:50 +02:00
Steven Conaway
4d2b79156d Change Error Message when Turning off ISY994 Light (#8131) 2017-06-21 09:38:12 +02:00
Fabian Affolter
b6d335f993 Do not call update() in constructor (#8120) 2017-06-21 09:35:44 +02:00
lunar-consultancy
4b82c34b8f Added RFXTRX UV badge (#8129) 2017-06-21 08:55:51 +02:00
Paulus Schoutsen
66fc852363 Update frontend 2017-06-20 21:10:53 -07:00
Paulus Schoutsen
87274879a8 Upgrade RestrictedPython dependency (#8132) 2017-06-20 19:30:01 -07:00
Fabian Affolter
e4dbf8033c Upgrade aiohttp to 2.2.0 (#8121) 2017-06-21 00:35:49 +02:00
Fabian Affolter
43db94d62d Upgrade sqlalchemy to 1.1.11 (#8124) 2017-06-21 00:32:49 +02:00
Fabian Affolter
6d5fca2db1 Upgrade paho-mqtt to 1.3.0 (#8125) 2017-06-21 00:32:04 +02:00
Fabian Affolter
d5e55448ef Upgrade mutagen to 1.38 (#8126) 2017-06-21 00:29:35 +02:00
Alan Fischer
4ad998378f Fixed iTach command parsing with empty data (#8104)
* Fixed iTach command parsing with empty data

* Switched to using format
2017-06-20 15:26:18 +02:00
Fabian Affolter
d46607c0d0 Add option to specify the location of the API (fixes #8115) (#8118) 2017-06-20 14:09:54 +02:00
Luar Roji
04920fa0bf Only mark active DHCP clients as present (#8110)
We only want to know which of the DHCP clients are indeed active.

For example: I've a table of static DHCP leases with most of the IPs of my network, so this module is always detecting them as present. With my patch only the active ones will be detected as present.

I already mentioned here: https://github.com/home-assistant/home-assistant/pull/7366#issuecomment-302950139
2017-06-20 12:16:56 +02:00
Fabian Affolter
1928da1fae Remove config details (see docs) (#8119) 2017-06-20 12:09:42 +02:00
Phil Hawthorne
06b051c53d Update InfluxDB to handle datetime objects and multiple decimal points (#8080)
* Update InfluxDB to handle datetime objects

Updates the InfluxDB regex to ignore datetime objects being coverted
into float values.

Adds tests to the component to ensure datetime objects are corectly
handled.

* Fix Hound errors

Fixes errors from Hound bot

* Update InfluxDB to handle multiple decimal points

Changes the way InfluxDB handles values such as 1.2.3.4 to be 1.234 so
it stores in InfluxDB as a valid float value

* Fix lint issues

Reduce the size of a line for the linter

* Update InfluxDB to pass on unknown variable

If we get an error trying to convert a variable to a float, let's ignore
it completely

* Make InfluxDB Regex constants

Makes the Regex's used by InfluxDB constants so they don't need to be
compiled each time

* cleanup

* fix lint

* Update regex

* fix tests

* Fix JSON body missing new line character

* fix exceptions
2017-06-20 07:53:13 +02:00
Charles Blonde
473d765bb9 Fix Dyson async_add_job (#8113) 2017-06-19 23:50:27 +02:00
sn0oz
8e34c27b63 Added SMTP SSL/TLS support (#7960)
* Added SMTP SSL/TLS support

* added new encryption option

* validation of encryption option

* Fix lint issues

* Rename var
2017-06-19 14:19:31 +02:00
Eugenio Panadero
77aa2e940d increase timeout for setWebhook to 10s (#8102)
Add an optional extended description…
2017-06-19 12:03:58 +02:00
Tsvi Mostovicz
3bbaf37193 Fix lights issue #8098 (#8101)
* Fix lights issue #8098

* Don't check self._color to decide whether to calll get_color()

self._color is None on init, so get_color() will never be called.
2017-06-19 09:54:13 +02:00
Andrey
b2d6ff9783 More updates to zwave services.yaml file (#8083) 2017-06-18 22:38:14 -07:00
Will W
4fdde4f0e2 add knx cover support (#7997)
* add knx cover

also corrected bugs in device config

1. overwriting of addresses in KNXMultiAddressDevice
2. setting and getting int values
3. added percentage scaling

* Update __init__.py
2017-06-18 22:30:39 -07:00
Jeff Wilson
756768e745 Add support for Insteon FanLinc fan (#6959)
* Add support for Insteon FanLinc fan

* Upgrade insteonlocal dependency to 0.49

* Lint/flake fixes

* Remove configurator

* Make Hound fixes

* Revert "Make Hound fixes" and "Remove configurator"

This reverts commit 04d1f7fdb1.
This reverts commit 7b8278d7cf.
2017-06-18 21:43:10 -07:00
Diogo Gomes
83b791489b Upnp properties (#8067)
* make port mapping optional

* dependencies + improvements

* Added bytes and packets sensors from IGD

* flake8 check

* new sensor with upnp counters

* checks

* whitespaces in blank line

* requirements update

* added sensor.upnp to .coveragerc

* downgrade miniupnpc

Latest version of miniupnpc is 2.0, but pypi only has 1.9

Fortunately it is enough

* revert to non async

miniupnpc will do network calls, so this component can’t be moved to
coroutine

* hof hof

forgot to remove import ot asyncio
2017-06-18 21:32:39 -07:00
Eugenio Panadero
35132f9836 media player Kodi: handle TransportError exceptions when calling JSONRPC API methods (#8047)
* handle TransportError exceptions when calling JSONRPC API

* use double quotes for log messages; show TransportErrors as in async_ws_connect

* fix spaces around keyword / parameter

* fix logging message

* review changes
2017-06-18 23:00:02 +02:00
Paulus Schoutsen
0e08785373 Update frontend 2017-06-18 11:37:15 -07:00
Per Osbäck
bf0dbdfd6a update pywebpush to 1.0.5 (#8084) 2017-06-18 10:51:37 -07:00
Michaël Arnauts
04407b8623 Cleanup .coveragerc (#8088) 2017-06-18 10:50:35 -07:00
Michael Auchter
fb0ee34f10 mpd: implement support for seek, shuffle, and clear playlist (#8090)
* mpd: add shuffle and clear_playlist support

* mpd: implement seek
2017-06-18 18:31:45 +02:00
Myles Eftos
ef63cfe8e4 Stopping the logfile spam by piping STDERR to /dev/null (#8081) 2017-06-18 11:44:41 +02:00
Paulus Schoutsen
e40f72e773 Merge branch 'master' into dev 2017-06-17 12:13:59 -07:00
Paulus Schoutsen
cec8ccb1a4 Version bump to 0.48.0.dev0 2017-06-17 12:13:46 -07:00
Paulus Schoutsen
9b1ed4e79b Merge pull request #8055 from home-assistant/release-0-47
0.47
2017-06-17 12:07:58 -07:00
happyleavesaoc
8fffaebe50 bump ups (#8075) 2017-06-17 11:12:50 -07:00
happyleavesaoc
84aab1c973 bump usps version (#8074) 2017-06-17 11:12:50 -07:00
Caleb
a2fbc0d2ef Update pyunifi component to use APIError passed from pyunifi 2.13. Better accommodate login failures with wrapper in pyunifi 2.13. (#7899)
* Pyunifi update

* Update pyunifi_test

* Import API Error

* Adjust test_unifi.py to import APIError

* Remove urllib import

* Remove urllib import from test

* Try fix mock

* Remove automations.yaml

* Lint
2017-06-17 11:09:44 -07:00
Caleb
6a017efc0e Update pyunifi component to use APIError passed from pyunifi 2.13. Better accommodate login failures with wrapper in pyunifi 2.13. (#7899)
* Pyunifi update

* Update pyunifi_test

* Import API Error

* Adjust test_unifi.py to import APIError

* Remove urllib import

* Remove urllib import from test

* Try fix mock

* Remove automations.yaml

* Lint
2017-06-17 11:09:27 -07:00
Paulus Schoutsen
363a429c41 Fix EntityComponent handle entities without a name (#8065)
* Fix EntityComponent handle entities without a name

* Implement solution by Anders
2017-06-17 10:59:18 -07:00
Lev Aronsky
9fc22ee47a Added 'all_plants' group and support for plant groups state. (#8063)
* Added 'all_plants' group and support for plant groups state.

* Reversed the group states.
2017-06-17 10:59:18 -07:00
Pascal Vizeli
a250f583eb Fix attribute entity (#8066)
* Bugfix entity attribute setter

* Fix tests

* Fix tests part 2

* Change filter only None

* Fix tests part 3

* Update entity.py

* Fix tests
2017-06-17 10:59:18 -07:00
Andrey
bf495edbb5 Add to zwave services descriptions (#8072) 2017-06-17 10:59:18 -07:00
Paulus Schoutsen
3ea7dee83d Always enable monkey patch (#8054) 2017-06-17 10:59:18 -07:00
pezinek
d796e8db5c No update in MQTT Binary Sensor #7478 (#8057) 2017-06-17 10:59:18 -07:00
Pascal Vizeli
d24b45054a Update numpy 1.13.0 (#8059) 2017-06-17 10:59:18 -07:00
Paulus Schoutsen
18935440ed Fix EntityComponent handle entities without a name (#8065)
* Fix EntityComponent handle entities without a name

* Implement solution by Anders
2017-06-17 10:50:59 -07:00
Lev Aronsky
2ba6b3a2ab Added 'all_plants' group and support for plant groups state. (#8063)
* Added 'all_plants' group and support for plant groups state.

* Reversed the group states.
2017-06-17 10:22:23 -07:00
Pascal Vizeli
2438c6b7c2 Fix attribute entity (#8066)
* Bugfix entity attribute setter

* Fix tests

* Fix tests part 2

* Change filter only None

* Fix tests part 3

* Update entity.py

* Fix tests
2017-06-17 10:03:49 -07:00
Andrey
32a84f1466 Add to zwave services descriptions (#8072) 2017-06-17 10:02:37 -07:00
happyleavesaoc
0002a895ca bump usps version (#8074) 2017-06-17 18:42:56 +02:00
happyleavesaoc
d0b43b187a bump ups (#8075) 2017-06-17 18:42:12 +02:00
John Mihalic
33d381731f Bump pyEmby version to account for API changes (#8070) 2017-06-17 18:41:35 +02:00
Eugenio Panadero
18f81d7824 Add option to set language of openweathermap sensor, and handle updating errors (#8046)
* Add option to set language of openweathermap sensor messages

* handle error updating openweathermap sensor
2017-06-17 12:37:34 +02:00
Fabian Affolter
844c8149d7 Add initial support for Shiftr.io (#7974)
* Add initial support for Shiftr.io

* Fix lint issue

* Use paho-mqtt instead of internal MQTT object

* remove async flavor while paho is not async
2017-06-17 12:34:12 +02:00
pezinek
7617864ba5 Failed to parse response from WU API: 'record' (and 'recordyear') #7747 (#8058) 2017-06-17 12:32:22 +02:00
jshore1296
58c234466c Allow config of latitude and longitude (#8068)
This will allow for dynamically updating weather states, for instance if
you wanted to use the latitude and longitude of a phone or other device
to get the weather for your current location.
2017-06-17 10:41:11 +02:00
Phil Hawthorne
9071946e87 Remove % sign from Vera Battery Levels (#8069)
Vera devices are reporting battery levels as a sting by appending a
percentage sign (%) on the end.

To make the Vera component act like other Home Assistant components,
let's remove the percentage sign from the battery report levels so that
we only display the battery level.

This may be a "breaking change" if people are relying on the Vera
battery levels to be a string instead of an int. However, this will make
the battery level reports compatible with everything else.
2017-06-17 10:38:15 +02:00
Paulus Schoutsen
b24aa24f6a Always enable monkey patch (#8054) 2017-06-16 17:17:18 -07:00
Andrey
1fde234c78 Fix some warnings found by quantifiedcode (#8027)
* Cleanup of warnings by quantifiedcode

* Fix lint

* Fix test

* Delete insteon_hub component

* Also update .coveragerc
2017-06-16 22:44:14 +03:00
Adam Mills
d67f3b8060 Use standard entity_ids for zwave entities (#7786)
* Use standard entity_ids for zwave entities

* Include temporary opt-in for new entity ids

* Update link to blog post

* Update tests

* Add old entity_id as state attribute

* Expose ZWave value details

* Update tests

* Also show new_entity_id

* Just can't win with this one
2017-06-16 13:25:12 -04:00
Adam Mills
afb9cba806 Use standard entity_ids for zwave entities (#7786)
* Use standard entity_ids for zwave entities

* Include temporary opt-in for new entity ids

* Update link to blog post

* Update tests

* Add old entity_id as state attribute

* Expose ZWave value details

* Update tests

* Also show new_entity_id

* Just can't win with this one
2017-06-16 13:07:17 -04:00
pezinek
1c2f4866e2 No update in MQTT Binary Sensor #7478 (#8057) 2017-06-16 14:55:59 +02:00
Pascal Vizeli
e90ae2fb75 Update numpy 1.13.0 (#8059) 2017-06-16 11:47:48 +02:00
Paulus Schoutsen
4339e9aab1 version bump to 0.47 2017-06-15 22:51:13 -07:00
Paulus Schoutsen
9b640f6a81 Add comment to default config 2017-06-15 22:31:22 -07:00
Alex Harvey
437ddb8dea Updater improvements to send option component information (#7720)
* Setup to send component data is option is enabled

* testcases, as well as moved to a single boolean, passed to the function

* fixed pep8 failures

* Clarify config option.
2017-06-15 22:29:18 -07:00
Erik Eriksson
a119bd0056 Provide entity_id to avoid sensor mixup (fixes #7636). Use async_dispatcher. Provide icon. (#7946)
* Avoid sensor mixup. Fixes #7636. Also provide icon. Plus some smaller
fixes.

* fix async p1

* Create volvooncall.py
2017-06-15 22:28:30 -07:00
matt2005
0eaad46d93 Added ONVIF camera component (#7979)
* Added ONVIF camera component

* added requirements

* corrected long lines

* fixed indenting

* fixed indenting

* removed bad whitespace

* updated coveragerc

* Added ONVIF camera component

* added requirements

* corrected long lines

* fixed indenting

* fixed indenting

* removed bad whitespace

* updated requirements

* updated requirements

* Added ONVIF camera component

* added requirements

* corrected long lines

* fixed indenting

* fixed pylink error indenting

* Added ONVIF camera component

* added requirements

* corrected long lines

* fixed indenting

* fixed indenting

* removed bad whitespace

* updated requirements

* fixed indenting

* removed bad whitespace

* updated requirements

* fixed pylink error indenting

* rebased and fixed requirements

* Removed Debug logging

* Added info logging to show URL being used.

* corrected spacing

* Tidied up and renamed input to host

* fixed typo

* corrected line lengths

* added default to ffmpeg_arguments

* removed unecessary ffmpeg arguements

* changed to use .format instead of +

* fixed indenting

* cleanup & make it more readable
2017-06-15 22:28:17 -07:00
Jean-Michel Ruiz
8af6bacfd0 media_player.firetv - Adding support for https. (#8022)
* Adding support for https.

This change allows to access a firetv-server instance that runs over https (via a reverse proxy for exemple).
Default stays http, but if `ssl: true` is set in the configuration the connection goes over https.

Successfully tested.

* respecting the 79 characters line limit
2017-06-15 22:23:10 -07:00
Giuseppe
09ca440c20 Fixed the Wind sensor following new release of netatmo-api-python (#8030)
* Fixed the Wind sensor following new release of netatmo-api-python

The NetAtmo PR was at:
https://github.com/jabesq/netatmo-api-python/pull/5

Essentially, this commit adds a protection when adding an incorrect
monitored conditions to avoid to fail the entire NetAtmo component,
plus for consistency reasons all conditions are now in lower case.

* Fixes following the CI tests
2017-06-15 22:14:46 -07:00
Paulus Schoutsen
74cc675a38 Restrict Python Script (#8053) 2017-06-15 22:13:10 -07:00
boojew
c478f2c7d0 Added host variable to Splunk.py and updated tox tests (#8052)
* Added host variable to Splunk.py and updated tox tests

* Update splunk.py

* Update splunk.py
2017-06-15 20:41:19 -07:00
Martin Tremblay
a3a702b269 Adding ssocr to docker to support Seven Segments Display (#8028)
* Adding ssocr to docker to support Seven Segments Display

* Adding cleanup
2017-06-15 20:31:30 -07:00
Paulus Schoutsen
92a6f21cc2 Update frontend 2017-06-15 20:29:11 -07:00
Pascal Vizeli
814834512a Group service / dynamic handling (#7971)
* Add Service to group

* Finish service

* Add service functions

* fix lint

* Address paulus comments

* fix lint & cleanup

* fix lint

* fix lint

* fix lint p3

* add test for check group

* add more tests

* fix lint

* Update service.yaml

* Fix order for tests

* Fix comment

* Fix test

* Fix tests

* Fix name in tests

* Fix view

* Fix default value

* Fix lint

* Fix key error

* add name

* migrate component entity

* fix tests

* fix import

* migrate device tracker

* fix lint

* fix bug

* fix logic

* fix lint

* fix tests

* fix generator

* fix group

* fix other tests.

* Not need to load group on first stage anymore.

* fix service

* add more group depency

* fix tests

* Revert "fix tests"

This reverts commit 35a922b3a8.

* Real fix

* fix test p2

* fix test p3

* fix test p4

* fix test p5

* fix test p6

* fix lint

* fix test p7

* Rename attribute

* fix group test

* fix bug

* fix flagy tests

* fix service.yaml

* fix lint
2017-06-16 00:52:28 +02:00
Alan Fischer
46f3088a70 Vera fix for dimmable vs rgb lights (#8007)
* Differentiate between dimmable & rgb lights

* Updated requirements

* Cache _has_color for supported_features

* simplify & cleanup code

* Create vera.py
2017-06-16 00:28:24 +02:00
Fabian Affolter
deed760008 Upgrade zeroconf to 0.19.1 (#8043) 2017-06-15 21:25:19 +02:00
Fabian Affolter
d1da53615f Upgrade pysnmp to 4.3.8 (#8044) 2017-06-15 21:24:31 +02:00
Fabian Affolter
69c919183a Do not call update() in constructor (#8048) 2017-06-15 21:23:55 +02:00
Anders Melchiorsen
8eb29787a5 LIFX: add multiple modes to pulse effect (#8016)
* blink: the existing 50/50 flashing between base color and effect color
* breathe: a lifx_effect_breathe replacement
* ping: mostly base color with a short flash at the end of the cycle
* strobe: dark base color and short cycles by default
* solid: temporary color change, base color never visible

Adding a service call for each mode is a bit extravagant so instead
lifx_effect_breathe has been folded in as an option and that service
call is deprecated.
2017-06-15 07:59:11 +02:00
Adam Mills
ae3973144c Discover Z-Wave values by index (#7853)
* Discover Z-Wave values by index

* Add URLs for enums (Some Assembly Required)

* URLs on one line

* Move lint suppression to single line
2017-06-14 08:41:20 -04:00
Andrey
02f7eb9675 Allow device_tracker platforms to specify picture and icon upon discovery (#8018)
* Allow device tracker platforms to specify picture

* Allow device tracker to specify icon during discovery

* Clean up and add tests

* Fix lint

* Fix test
2017-06-14 14:39:18 +02:00
Charles Blonde
8c0967a190 Add Dyson Pure Cool Link support (#7795)
* Add Dyson Pure Cool Link support

* Code review

* Improve auto/night mode

* Move night_mode to Dyson fan component

* Code review

* fix asynchrone/sync

* Create dyson.py
2017-06-14 13:56:03 +02:00
Tom Matheussen
bf2fe60cb5 Take in account Spotify account permissions (#8012)
* only show Spotify actions when Premium account is used

* Fix indentation, stupid autoformat
2017-06-14 00:45:00 +02:00
Phil Hawthorne
1ddcab5e26 Make percentage string values as floats/ints in InfluxDB (#7879)
* Make percentage string values as floats in InfluxDB

Currently Z-wave and other compontents report an attributes battery
level as an integer, for example

```yaml
{
"is_awake": false,
"battery_level": 61,
}
```

However, some other components like Vera add the battery level as a
string

```yaml
{
"Vera Device Id": 25,
"device_armed": "False",
"battery_level": "63%",
"device_tripped": "False",
}
```

By removing any % signs in the field, this will send the value to
InfluxDB as an int, which can then be used to plot the data in graphs
correctly, like other percentage fields.

* Add tests and remove all trailing non digits

Adds tests and now removes all trailing non-numeric characters for
better use

* Update variable name for InfluxDB digit checks

Updates the variable used for the regex to remove trailing non digits

* Fix linting errors for InfluxDB component

Fixes a small linting error on the InfluxDB component
2017-06-14 00:42:55 +02:00
Thiago Oliveira
09fec29537 entity_id for service fan.turn_off is optional (#7982)
* entity id is optional

* use a simple if/else to set the data for the fan.turn_off service
2017-06-13 17:28:05 +02:00
Fabian Affolter
9189cbdc8b Remove globally disabled pylint issues (#8005) 2017-06-13 11:10:32 +02:00
Marco Sirabella
7fae8cd0f1 Configure conversation for custom actions with keywords (#7734)
* - Simple keyword to action config

* - Added more fuzzy stuff

* - Logging & a bit of commenting

* - pep8?

* - pep8 and quick formatting fixes

* - Changed configuration a bit

* - Backwards compatibility tests

* - Fallback or

* - Added custom configuration for conversation

* - Moved imports inside function

* - pep8

* - Pass tests better

* - Removed unused imports

* - Moved warning ignore to above import for fuzzy

* - Moved return for consistent return types

* - Fallback if no choices to listen for

* - Fixed linting errors

* - Better logging and fixed linting errors(?)

* - Fixed continuation

* - Added one blank line after class docstring

* Create conversation.py

* Create test_conversation.py

* Create test_conversation.py

* Update test_conversation.py
2017-06-12 23:34:20 -07:00
Fabian Affolter
843f8ce9ee Allow put as method (#8004) 2017-06-12 22:27:25 -07:00
Nolan Gilley
2bf781185f update pyripple (#8015) 2017-06-13 07:22:46 +02:00
Sabesto
1e1d4c2013 Add Flexit AC climate platform (#7871)
* Add Flexit AC climate platform

* Protocol extracted to third party lib
2017-06-12 22:06:47 -07:00
Fabian Affolter
bde711a9ff Make it more flexible (fixes #7954) (#8001)
* Make it more flexible (fixes #7954)

* Fix var name
2017-06-12 09:13:03 +02:00
cribbstechnologies
dc45ed38e7 fixing potential null issue with optional param being parsed as a script (#7928)
* fixing potential null issue with optional param being parsed as a script

* Create template.py
2017-06-11 22:58:20 -07:00
Sören Oldag
03f916ed10 Fixed bug in spotify component. (#7976) 2017-06-11 22:24:01 -07:00
happyleavesaoc
6e33c12008 Update mailgun (#7984)
* add mailgun component

* add to coveragerc
2017-06-11 22:19:10 -07:00
Adam Mills
401309c3b2 Additional demo fan with only speed support (#7985)
* Additional demo fan with only speed support

* Update demo fan tests
2017-06-11 22:12:56 -07:00
sander76
1c06b51968 Fixing Client connection error (#7991) 2017-06-11 21:42:35 -07:00
Fabian Affolter
e7de1fb9ae Add Gitter.im sensor (#7998) 2017-06-11 21:40:06 -07:00
tedstriker
de0f6b781e dismiss service for persistent notifications (#7996)
* dismiss service for persistent notifications

Unnecessary notifications can now be removed automatically. Added a
dismiss service to remove persistent notifications via script and/or
automation.

* removed unnecessary loop

loop removed
2017-06-11 22:54:10 +02:00
Anders Melchiorsen
314bce1073 LIFX: add support for setting infrared level (#8000)
* LIFX: update aiolifx

This adds support for infrared and multizone.

* LIFX: add support for infrared
2017-06-11 22:38:07 +02:00
Anders Melchiorsen
9e16be3173 LIFX: clean up internal color conversions (#7964)
* Add color_util.color_hsv_to_RGB

* Use helper functions for LIFX conversions

The LIFX API uses 16 bits for saturation/brightness while HA uses 8 bits.
Using helper functions makes the conversion a bit nicer and less prone
to off-by-one issues.

The colorsys library uses 0.0-1.0 but we can avoid that by using the HA
color_util converters instead.
2017-06-11 21:19:58 +02:00
Fabian Affolter
1b1619fbf1 Upgrade py-cpuinfo to 3.3.0 (#7992) 2017-06-11 12:03:02 +02:00
Oliver
1f226cffe9 Bugfixing with version 0.4.4 of denonavr (#7995) 2017-06-11 12:02:32 +02:00
Eugenio Panadero
b9ee5fb867 make last_name field optional (#7988) 2017-06-10 22:19:13 +02:00
Thiago Oliveira
ba80d5e52a test that all lights turn off when no entity id is given (#7981) 2017-06-10 10:13:52 +02:00
Erik Eriksson
f2feabcf0b Update eliqonline.py (#7977)
Print error
2017-06-10 10:12:30 +02:00
Daniel Perna
a19e7ba3f1 HomeMatic optimizations and code cleanup (#7986)
* Cleanup and optimizations

* Cleanup

* Typo -.-

* Linting
2017-06-10 10:08:36 +02:00
mwsluis
49d642741d Nadtcp component (#7955)
* initial commit

* class name and requirements_all.txt

* removed mentions of D7050

* changed default name

* catch oserror in update, travis errors.

* use nad_receiver pip version

* update coveragerc
2017-06-09 14:53:07 -04:00
Paulus Schoutsen
db0efc647d New component: Python Script (#7950)
* Add initial version

* Fix requirements

* Prefer logging over printing

* Set executor thread name on >Py36 only

* Add tests

* Lint

* Add restrictedpython to test dependencies

* Create python_script.py

From doc:
```
However, an empty dict ({}) is treated as is. If you want to specify a list that can contain anything, specify it as dict:
>>> schema = Schema({}, extra=ALLOW_EXTRA)  # don't do this
>>> try:
...   schema({'extra': 1})
...   raise AssertionError('MultipleInvalid not raised')
... except MultipleInvalid as e:
...   exc = e
>>> str(exc) == "not a valid value"
True
>>> schema({})
{}
>>> schema = Schema(dict)  # do this instead
>>> schema({})
{}
>>> schema({'extra': 1})
{'extra': 1}

```
2017-06-09 12:38:40 +02:00
Paulus Schoutsen
640c692e1f Fix platforms being able to block startup (#7970) 2017-06-09 12:11:58 +02:00
Paulus Schoutsen
4aef0b68bc Merge branch 'master' into dev 2017-06-08 22:21:25 -07:00
Paulus Schoutsen
c2b7c93375 Merge pull request #7968 from home-assistant/release-0-46-1
0.46.1
2017-06-08 22:20:32 -07:00
Paulus Schoutsen
8cc759ea4b Prevent Roku doing I/O in event loop (#7969) 2017-06-08 22:18:48 -07:00
Paulus Schoutsen
a223efb840 Prevent Roku doing I/O in event loop (#7969) 2017-06-08 22:18:33 -07:00
Jacob Mansfield
c32807803e Create metoffice.py (#7965)
Fix met office sensor
2017-06-08 21:44:33 -07:00
Jacob Mansfield
24a172163a Create metoffice.py (#7965)
Fix met office sensor
2017-06-08 21:44:24 -07:00
Barry Williams
372169a03a Fixed metadata issue (#7932) 2017-06-08 21:41:42 -07:00
Barry Williams
e4d100d54d Fixed metadata issue (#7932) 2017-06-08 21:41:24 -07:00
cribbstechnologies
bfd9623d8b Mqtt cover modifications (#7841)
* adding set position ability
removing command_topic being required

* flaking

* flaking test

* updating docs

* requested updates

* Revert "updating docs"

This reverts commit 9cfc5ed7a8.

* forgot to update constructor calls in tests
2017-06-08 21:35:38 -07:00
mje-nz
3464454662 Fix typos in Wunderground component (Percipitation -> Precipitation) (#7901) 2017-06-08 21:35:26 -07:00
Johan Bloemberg
533bb5565b Dsmr5 revert (#7900)
* Revert "Update to dsmr_parser supporting v5 arguments."

This reverts commit 3567de4b90.

* Revert "Using dev branch until released upstream."

This reverts commit 53e8de112c.

* Revert "Give good example."

This reverts commit 4f90fc4be6.

* Revert "Allow configuring DSMR5 protocol."

This reverts commit 9fa0e14187.
2017-06-08 21:35:26 -07:00
Adam Mills
a8709a6988 Support for renaming ZWave values (#7780)
* Support for renaming ZWave values

* Improve test
2017-06-08 21:35:26 -07:00
Paulus Schoutsen
4b767b088e Version bump to 0.46.1 2017-06-08 21:34:39 -07:00
Albert Lee
c52b18d7c8 lock.sesame: Update pysesame, add state attributes (#7953)
* Update pysesame requirement to 0.1.0 to support caching

* Set `available` property based on API enabled status

* Add state attributes for device ID and battery level
2017-06-09 00:21:56 +02:00
Fabian Affolter
aaaf9637eb Add configuration check and use default var names (#7963) 2017-06-09 00:21:06 +02:00
Riccardo Canta
055db05946 Osram lightify, removed double set to the lightify bridge in case of brightness changes (#7662)
* osram lightify removed duplicated set in case of brightness changes

* lightify component: anticipate brightness evaluation to handle unconsidered scenario described in the PR request comments (light turned on with color/temperature)

* Correction for travis ci error:
undefined name 'transition'
2017-06-08 20:17:28 +02:00
Fabian Affolter
0863d50210 Fix typos (#7957)
Add an optional extended description…
2017-06-08 15:53:12 +02:00
Alan Fischer
1e352d37d0 Vera colored light support (#7942)
* Added support for color to vera lights

* Updated requirements
2017-06-08 12:28:03 +02:00
Boris K
620197b276 Fix the negative values bug in history_stats (#7934) 2017-06-08 12:27:43 +02:00
Michael Heinemann
727a22f925 test connection without needing admin rights (#7947)
SHOW DIAGNOSTICS always needs admin privileges on influxdb. For
the purposes of home-assistant this is too much.
Use 'SHOW SERIES' to have a relatively lightweight query which
only needs READ privileges.
2017-06-08 12:26:37 +02:00
Fabian Affolter
9bea7d7d8b Upgrade coinmarketcap to 3.0.1 (#7951) 2017-06-08 12:15:46 +02:00
Teagan Glenn
97f62cfb78 [WIP] Fix opencv (#7864)
* Updates to opencv image processor

* Remove opencv hub

* Requirements

* Remove extra line

* Fix linting errors

* Indentation

* Requirements

* Linting

* Check for import on platform setup

* Remove opencv requirement

* Linting

* fix style

* fix lint
2017-06-08 11:26:24 +02:00
Oliver
482db94372 Add option to display all input sources / Add support for favourite channels / Treat Marantz SR5008 as Denon AVR-X device (#7949)
* add option to display all sources / pushed to version 0.4.3 of library

* Add show_all_sources option for auto discovery too

* change code style for hass

* fix lint
2017-06-08 09:46:26 +02:00
vrs01
8a4e993183 Update ping.py (#7944) 2017-06-08 07:30:51 +02:00
joopert
790610525b update to 006 (#7945) 2017-06-08 07:30:07 +02:00
Daniel Perna
7e668ef9e3 Merge pull request #7948 from danielperna84/HomeMatic
HomeMatic: Updated dependency
2017-06-08 00:09:53 +02:00
Daniel Perna
4dbf7be267 Updated dependency 2017-06-07 23:55:42 +02:00
Juggels
36eb0ceff3 [media_player.sonos] Send media_stop on turn_off (#7940) 2017-06-07 13:15:29 +01:00
Fabian Affolter
d38acfbd39 Add Yahoo! weather platform (#7939) 2017-06-07 10:49:54 +02:00
Nolan Gilley
b87e31617a add ripple sensor (#7935) 2017-06-07 10:24:07 +02:00
Jacob Minnis
bb6fe822f9 Added 'change' field to statistics sensor (#7820)
* Added 'change' field to statistics sensor

* Updated statistics sensor test

* Updated statistics sensor test complaint
2017-06-07 09:38:00 +02:00
Stephan Auerhahn
5504a511e3 Add service_url config option to volvooncall (#7919)
* Add service_url config option to volvooncall

* Import default value from volvooncall lib
2017-06-07 08:52:36 +02:00
Fabian Affolter
5c96936eb4 Do not call update() in constructor (#7931) 2017-06-06 19:15:03 +02:00
Fabian Affolter
cbbb15fa48 Fix changes introduced with #7917 (#7930) 2017-06-06 19:14:41 +02:00
Fabian Affolter
760138ac52 Do not call update() in constructor (#7917) 2017-06-05 21:28:13 +02:00
Per Osbäck
b1f538b622 update to pywebpush 1.0.4 which allows install on system with openssl-1.1.0 (cryptography dep) (#7915) 2017-06-05 17:46:51 +02:00
John Mihalic
ac8592587f Bump pyEight version to fix 0hr session errors (#7916) 2017-06-05 17:44:13 +02:00
Jesse Hills
aee25a020d Add juicenet platform (#7668)
* Add juicenet platform

* Update missing variable
Add missing blank lines

* Remove unnecessary override

* Update juicenet.py

* Remove whitespace
Add missing docstring

* Remove unused services
Use the hass built in unique_id

* Fix lint issues

* Update python-juicenet library version

* Update python-juicenet library version

* Remove unnecessary code

* Remove unused import

* Remove super call
2017-06-05 08:39:31 -07:00
Fabian Affolter
13df925795 Do not call update() in constructor (#7912)
* Do not call update() in constructor

* Do not call update() in constructor

* Remove unused import
2017-06-05 17:35:26 +02:00
PhracturedBlue
2b850f417e Minor cleanup - Define 'CONF_ICON_TEMPLATE' constant centrally (#7910)
* Add 'icon_template' to switch templates (similar to sensor template)

* Add test for template switch 'icon_template'

* Define 'CONF_ICON_TEMPLATE' constant centrally

* Missed a redundant definition
2017-06-05 17:33:57 +02:00
Fabian Affolter
f303f6a191 Move consts to 'const.py' (#7909) 2017-06-05 16:59:59 +02:00
Fabian Affolter
f8cfa15152 Sync crypto-currency platforms (#7906) 2017-06-05 13:36:39 +02:00
Fabian Affolter
12f731b32c Fix docstring (#7907) 2017-06-05 13:16:53 +02:00
PhracturedBlue
11dcbd4449 Add 'icon_template' to switch templates (similar to sensor template) (#7862)
* Add 'icon_template' to switch templates (similar to sensor template)

* Add test for template switch 'icon_template'
2017-06-05 11:27:48 +02:00
Paulus Schoutsen
fa6a089fb3 Lint 2017-06-05 00:10:57 -07:00
florincosta
87da2ff1d7 Add raspihats switch (#7665) 2017-06-04 23:56:21 -07:00
Paulus Schoutsen
b576df53e9 Update .coveragerc 2017-06-04 23:54:15 -07:00
Martin Berg
b90964faad Add support for Vanderbilt SPC alarm panels and attached sensors (#7663)
* Add support for Vanderbilt SPC alarm panels.

 * Arm/disarm + read state

 * Autodiscover and add motion sensors

* Fix code formatting.

* Use asyncio.async for Python < 3.4.4.

* Fix for moved aiohttp exceptions.

* Add docstrings.

* Fix tests and add docstrings.
2017-06-04 23:53:25 -07:00
mjj4791
549133a062 Added buienradar sensor and weather (#7592)
* Added buienradar sensor and weather

* used external library for parsing

* used external library for parsing

* updated buienradar lib to 0.4

* Make sure you import 3rd party libraries inside methods.

* Make sure you import 3rd party libraries inside methods.

* clean up code; optimized

* imports, sensor name and attributes

* updated requirements to match imports

* use asyncio for http get
2017-06-04 23:48:11 -07:00
Matthew Schick
c29553517f Add service to set nest away/home modes (#7619)
* Add service to set nest away/home modes

* New service `nest.set_mode`
* Update the NestDevice object to export the local structures

* Validation and structure cleanup
2017-06-04 23:45:24 -07:00
Trevor
2e27c0d5ec Add Radarr sensor (#7318)
* Add radarr.py

* Update radarr.py

* Update radarr.py

* Add test_radarr.py

* Update test_radarr.py

* Update test_radarr.py

* Update radarr.py

* Update .coveragerc

* Fix hound.
2017-06-04 23:44:24 -07:00
cribbstechnologies
774f584ba8 Mqtt cover modifications (#7841)
* adding set position ability
removing command_topic being required

* flaking

* flaking test

* updating docs

* requested updates

* Revert "updating docs"

This reverts commit 9cfc5ed7a8.

* forgot to update constructor calls in tests
2017-06-04 22:55:06 -07:00
Nolan Gilley
81b1446aad blockchain.info sensor (#7856)
* blockchain sensor

* Update blockchain.py

* Update blockchain.py

* add validation of btc addresses
2017-06-04 22:48:38 -07:00
Nolan Gilley
6bfd52ada8 Etherscan.io sensor (#7855)
* etherscan sensor

* Update etherscan.py
2017-06-04 22:48:04 -07:00
Per Osbäck
0646d01152 Add support for the expirationTime parameter. (#7895)
Enabled by default in Chrome 60.
Only accepts the param, doesn't act on the actual expiration date. Chrome will always pass NULL for now.

https://github.com/w3c/push-api/pull/248
https://www.chromestatus.com/feature/4929396687241216
https://bugs.chromium.org/p/chromium/issues/detail?id=718837
2017-06-04 22:46:18 -07:00
mje-nz
da5f5335eb Fix typos in Wunderground component (Percipitation -> Precipitation) (#7901) 2017-06-04 22:37:16 -07:00
Johan Bloemberg
c9d55cff23 Dsmr5 revert (#7900)
* Revert "Update to dsmr_parser supporting v5 arguments."

This reverts commit 3567de4b90.

* Revert "Using dev branch until released upstream."

This reverts commit 53e8de112c.

* Revert "Give good example."

This reverts commit 4f90fc4be6.

* Revert "Allow configuring DSMR5 protocol."

This reverts commit 9fa0e14187.
2017-06-04 22:36:19 -07:00
Albert Lee
aeb1d3d3fe lock.sesame: New lock platform for Sesame smart locks (#7873)
* Manage Sesame devices through CANDY HOUSE's cloud API
* Add dependency on new pysesame library
2017-06-04 22:06:18 -07:00
Barry Williams
a1c119adb6 Added a Taps Aff binary sensor (#7880)
* Added a Taps Aff binary sensor

* PR Review updates

* Added a Taps Aff binary sensor

* PR Review updates

* Improved error handling

* Cosmetic changes (ordering, docstings, etc.)
2017-06-04 13:35:19 +02:00
Paulus Schoutsen
e9f273e7e0 Merge pull request #7866 from home-assistant/release-0-46
0.46
2017-06-03 19:16:35 -07:00
Paulus Schoutsen
7ebf36bb70 Fix MQTT camera test (#7878) 2017-06-03 18:57:05 -07:00
Paulus Schoutsen
84fe4f75df Fix MQTT camera test (#7878) 2017-06-03 18:51:29 -07:00
Fabian Affolter
c07bf551d9 Upgrade python-telegram-bot to 6.0.3 (#7885) 2017-06-03 22:36:41 +02:00
Fabian Affolter
a745bf83ef Upgrade sendgrid to 4.2.0 (#7886) 2017-06-03 22:34:17 +02:00
Fabian Affolter
1432ae649a Upgrade pyasn1-modules to 0.0.9 (#7887) 2017-06-03 22:33:43 +02:00
Fabian Affolter
cf1a27bd7c Use constants (#7888) 2017-06-03 22:33:12 +02:00
Andrey
3d8b7a4122 Switch pymyq to pypi (#7884) 2017-06-03 17:12:36 +02:00
joopert
e50588afe1 Change nad_receiver to pypi (#7852)
* Change to pypi

* add requirements
2017-06-03 17:01:51 +03:00
Anders Melchiorsen
4dc4a98caa [light.lifx] Update aiolifx (#7882)
This makes LIFX Gen3 lights work with the current firmware.
2017-06-03 13:21:31 +01:00
Anders Melchiorsen
423e809e45 [light.lifx] Update aiolifx (#7882)
This makes LIFX Gen3 lights work with the current firmware.
2017-06-03 13:20:55 +01:00
Paulus Schoutsen
a79f1d4d40 Fix telegram_bot (#7877) 2017-06-03 10:52:00 +01:00
Paulus Schoutsen
8461cf2717 Fix telegram_bot (#7877) 2017-06-03 10:50:37 +01:00
Adam Mills
9c9f5068b7 Support for renaming ZWave values (#7780)
* Support for renaming ZWave values

* Improve test
2017-06-02 23:03:00 -07:00
twendt
6d41024e76 Enocean Binary Sensor: Handle click of both rockers (#7770) 2017-06-02 22:12:41 -07:00
Kevin
7d24efc690 Added effects to Yeelight bulbs (#7152)
* Added effects to Yeelight bulbs

* Fix Typo and Use randint instead of randrange

* Added Effects

* updated requirements_all.txt

* fix empty line

* minor fixes

* fix passing effects as parameter
2017-06-02 21:35:32 -07:00
Paulus Schoutsen
7d4adbbef5 Fix html5 unsub (#7874)
* Fix #7758 subscription expiration/removal

Removes a subscription after receiving an HTTP 410 response when trying to send a new message.

* Fix tests failing due to additional call

* Fix code style

* Lint
2017-06-02 20:56:16 -07:00
Erik Eriksson
e11ec88482 Update squeezebox.py (#7617)
Do not fail in case no players are connected, in which case squeezeserver will return a result without player_loop.
2017-06-02 00:26:54 -07:00
Paulus Schoutsen
e39bdf8763 Version bump to 0.47.0dev0 2017-06-02 00:24:40 -07:00
Paulus Schoutsen
a33bcdf270 Version bump to 0.46 2017-06-02 00:24:19 -07:00
Paulus Schoutsen
f056cbc641 Update frontend 2017-06-02 00:20:53 -07:00
Paulus Schoutsen
4163bcebbc Update netdisco (#7865) 2017-06-02 00:13:17 -07:00
Johan Bloemberg
d472d81538 Align switch group handling with light. (#7577) 2017-06-02 00:05:34 -07:00
David-Leon Pohl
2b70b1881a Quickfix Bug #7384 (#7582)
* Quickfix Bug #7384

* Fix devices not available runtime bug
2017-06-02 00:05:07 -07:00
Juggels
12607aeaea Check if media commands are actually applicable (#7595)
* Check if media commands are actually applicable

- Explicitly allow ‘stop’ and ‘play’ on radio streams
- Disallow media commands when the playlist is empty
- Check if command is supported when calling `turn_on` and `turn_off`

* Suppress UPnP error 701 on media commands

* Clean up soco_filter_upnperror

Clean up soco_filter_upnperror and fix small bug in support_previous_track determination
2017-06-02 00:03:10 -07:00
Erik Eriksson
1855f1ae85 fix for https://github.com/home-assistant/home-assistant/issues/7019 (#7618) 2017-06-02 00:02:26 -07:00
Thibault Cohen
613da308f2 Query in InfluxDB sensor is now templatable (#7634) 2017-06-02 00:01:14 -07:00
Teagan Glenn
cefacf9ce4 Spotify aliases (#7702)
* Alias support for spotify devices

* Fix log

* Formatting/Fixes

* Remove default arg

* Add default keyword

* None check
2017-06-01 23:53:23 -07:00
Alex Harvey
78887c5d5c Start of migration framework, to allow moving of files in the config … (#7740)
* Start of migration framework, to allow moving of files in the config directory to be hidden, ios.conf used as the first one to undergo this change.

* Update const.py

* Update test_config.py

* improvement to syntax
2017-06-01 23:50:04 -07:00
Craig J. Ward
3a92bd78ea fix permissions issue for Insteon Local #6558 (#7860)
* fix unlinked commit

* Update insteon_local.py
2017-06-01 23:36:47 -07:00
Paulus Schoutsen
d0021a6171 Make monkey patch work in Python 3.6 (#7848)
* Make monkey patch work in Python 3.6

* Update dockerfiles back to 3.6

* Lint

* Do not set env variable for dockerfile

* Lint
2017-06-01 23:23:39 -07:00
Anders Melchiorsen
e2cfdbff06 Disallow ambiguous color descriptors in the light.turn_on schema (#7765)
* Disallow ambiguous color descriptors in the light.turn_on schema

* Update tests
2017-06-01 23:05:05 -07:00
abmantis
9480f41210 dont use default for switch name, so that the object id is used (#7845) 2017-06-01 22:58:57 -07:00
Boris K
1b5f6aa1b9 Optimize history_stats efficiency and database usage (#7858) 2017-06-01 22:52:55 -07:00
Eugenio Panadero
2065426b16 log time delay of domain setup in info level (#7808)
* log time delay of domain setup in info level

 * when setup problems appear, it's difficult to debug which are the components that took a lot to set up. This minimal change goes further than the 'slow setup warning' and measures the setup time interval for each domain.

* use timer as in helpers/entity
2017-06-01 22:44:44 -07:00
Adam Mills
beb8c05d91 Use expected behvaior for above/below (#7857) 2017-06-01 22:43:24 -07:00
Adam Mills
cf42303afb Rename time trigger 'after' to 'at' (#7846) 2017-06-01 22:40:27 -07:00
Daniel Perna
4bcbeef480 Bumped pyhomematic version (#7861) 2017-06-01 22:33:53 -07:00
Adam Mills
e0712ba329 Expose the node name on the zwave node entity (#7787) 2017-06-01 22:33:16 -07:00
Fabian Affolter
66d6f5174d Allow 'base_url' (fixes #7784) (#7796) 2017-05-31 09:08:53 -07:00
Marcelo Moreira de Mello
9762e1613d Introduced support to Netgear Arlo Cameras (#7826)
*  Introduced support to Netgear Arlo Cameras

* Using async_setup_platform() and applied other changes

* Removed unecessary variables

* Using asyncio for sensor/arlo

* Update arlo.py

* Removed entity_namespace
2017-05-31 09:25:25 +02:00
Phil Hawthorne
bb92ef5497 Downgrade Docker to Python 3.5 to solve Segmentation Faults (#7799)
Downgrades the Dockerfiles used by Home Assistant to Python 3.5, after
Python 3.6 base image was causing segmentation faults.

See home-assistant/home-assistant#7752
2017-05-30 23:56:20 -07:00
Paulus Schoutsen
9f5bfe28d1 Add initial benchmark framework (#7827)
* Add initial benchmark framework

* Use timer from timeit
2017-05-30 21:34:40 -07:00
Marcelo Moreira de Mello
8ee32a8fbd Added persistent error message if cover.myq fails to load (#7700)
* Show persistent error if cover.myq fails

* Fixed typo on getLogger()

* Added ValueError on except condition

* Make pylint happy

* Removed DEFAULT_ENTITY_NAMESPACE since it is not being used
2017-05-30 23:17:32 +02:00
Fabian Affolter
052cd3fc53 Upgrade PyMVGLive to 1.1.4 (#7832) 2017-05-30 18:26:26 +02:00
Fabian Affolter
0ccaf97924 Update docstrings and log messages (#7709) 2017-05-30 11:52:26 +02:00
happyleavesaoc
96b20b3a97 update snapcast media player (#7079)
* update snapcast

* fix docstrings

* bump dep version

* address snapcast review comments

* add snapcast group volume support

* fix snapcast requirements

* update snapcast client entity id

* snapshot/restore functions

* refactor snapshot/restore services

* clean up

* update snapcast req

* bump version

* fix async updates
2017-05-30 11:34:39 +02:00
Daniel Høyer Iversen
91806bfa2a Flux led fix (#7829)
* Update flux_led.py

* style fix
2017-05-30 10:46:18 +02:00
Fabian Affolter
1c4e097bed Upgrade pysnmp to 4.3.7 (#7828) 2017-05-30 09:08:57 +02:00
Pascal Vizeli
2df6aabbf3 Cleanup telegram / Add url to webhook (#7824)
* Cleanup telegram / Add url to webhook

* fix lint

* Fix lint
2017-05-30 06:55:06 +02:00
John Mihalic
81b2111751 Bump aiohttp to 2.1.0 (#7825) 2017-05-30 06:54:16 +02:00
Eugenio Panadero
f7e0d13fe6 Telegram send image: fix mimetype detection (#7802)
* Add `name` var to BytesIO content to get recognized

Sometimes the python-telegram-bot doesn't recognize the mimetype of the file and looks after a name variable to deduce it. Fixes #7413

* bytesio stream recycle less explicit
2017-05-29 22:59:44 +02:00
Johan Bloemberg
5e5c0daa87 Allow configuring DSMR5 protocol. (#7535)
* Allow configuring DSMR5 protocol.

* Give good example.

* Using dev branch until released upstream.

* Update to dsmr_parser supporting v5 arguments.
2017-05-29 16:19:50 +02:00
Fabian Affolter
a7277db4d7 Upgrade mypy to 0.511 (#7809)
Add an optional extended description…
2017-05-29 15:39:24 +02:00
Fabian Affolter
ba44b7edb3 Upgrade sqlalchemy to 1.1.10 (#7807) 2017-05-29 15:38:56 +02:00
Lev Aronsky
8fcc750998 Added handling of an AssertionError from pxssh failed login (#7750)
* Added handling of an AssertionError from pxssh failed login

* Destory and re-create pxssh instance, to fix behavior upon router restart.
2017-05-29 11:22:20 +02:00
Teagan Glenn
eff619a58f Rest notify data (#7757)
* Rest notify data

* Cleanup

* Fix spaces
2017-05-29 11:20:23 +02:00
Andy Castille
fc1bb58247 Rachio (Sprinklers) (#7600)
* Rachio platform started

* Rachio tests

* detect bad api token

* Documentation, Code cleanup

* Docstrings end with a period, log uses %

* Fix arguments, default run time is now 10 minutes

* Fix typo, remove todo (GH issue exists)

* Revert polymer submodule commit

* Use a RachioPy version with SSL cert validation

* Update requirements
2017-05-29 11:15:27 +02:00
Fabian Affolter
c12b8f763c Upgrade pysnmp to 4.3.6 (#7806) 2017-05-29 10:28:31 +02:00
Dan Cinnamon
ef51d8518a Bump pyenvisalink to version 2.1 (#7803) 2017-05-29 10:27:36 +02:00
Fabian Affolter
8b7894fb86 Upgrade slacker to 0.9.50 (#7797) 2017-05-29 10:26:56 +02:00
Fabian Affolter
010f098df3 Upgrade Sphinx to 1.6.2 (#7805) 2017-05-29 10:26:33 +02:00
Oliver
1f3bb51821 Add Marantz SSDP discovery / Detect error string in AppCommand.xml body (#7779) 2017-05-29 10:26:10 +02:00
CTLS
10367eb250 Fix home/stay in concord232 (#7789) 2017-05-28 12:06:18 +02:00
sander76
7fb5488058 Powerview to async (#7682)
* first commit

* first commit

* first commit

* first commit

* changing requirements

* updated requirements_all.txt

* various changes as suggested in the comments.

* using global values for dict keys.
2017-05-26 22:19:19 +02:00
Paulus Schoutsen
e68bd0457c Fix more deprecation warnings (#7778)
* Remove setting up an hbmqtt broker

* Don't pass loop to web.Application in tests

* Use .query instead of deprecated .GET for aiohttp requests

* Fix closing file resource

* Do not use asyncio mark

* Notify.html5 - PyJWT: Use options to disable verify

* Yamaha: Test was still using deprecated ip

* Remove pytest-asyncio
2017-05-26 13:12:17 -07:00
Eugenio Panadero
910020bc5f Fix Telegram Bot send file to multiple targets, snapshots of HA cameras, variable templating, digest auth (#7771)
* fix double template rendering when messages come from notify.telegram

* fix 'chat' information not present in callback queries

* better inline keyboards with yaml

To make a row of InlineKeyboardButtons you pass:
- a list of tuples like: `[(text_b1, data_callback_b1), (text_b2, data_callback_b2), ...]
- a string like: `/cmd1, /cmd2, /cmd3`
- or a string like: `text_b1:/cmd1, text_b2:/cmd2`

Example:
```yaml
data:
   message: 'TV is off'
   disable_notification: true
   inline_keyboard:
     - TV ON:/service_call switch.turn_on switch.tv, Other:/othercmd
     - /help, /init
```

* fix send file to multiple targets

* fix message templating, multiple file targets, HA cameras

- Allow templating for caption, url, file, longitude and latitude fields
- Fix send a file to multiple targets
- Load data with some retrying for HA cameras, which return 500 one or two times sometimes (generic cams, always!).
- Doc in services for new inline keyboards yaml syntax: `Text button:/command`

* HttpDigest authentication as proposed in #7396

* review changes

- Don't use `file` as variable name.
- For loop
- Simplify filter allowed `chat_id`s.

* Don't use `file` as variable name!

* make params outside the while loop

* fix chat_id validation when editing sent messages
2017-05-26 21:05:12 +02:00
Paulus Schoutsen
f43db3c615 Replace executor with async_add_job (#7658)
* Remove executor

* Lint

* Lint

* Fix tests
2017-05-26 08:28:07 -07:00
Adam Mills
9e9705d6b2 Support for GE Zwave fan controller (#7767)
* Support for GE Zwave fan controller

* Tests for zwave fan

* Add additional fan workarounds
2017-05-25 22:55:00 -07:00
Paulus Schoutsen
6899c7b6f7 assertEquals is deprecated (#7777) 2017-05-25 22:21:22 -07:00
Paulus Schoutsen
d0c9d6b69a Remove usage of event_loop fixture (#7776) 2017-05-25 21:40:36 -07:00
Paulus Schoutsen
81aaeaaf11 Get rid of mock http component app (#7775)
* Remove mock_http_component from config tests

* Remove mock_http_component_app from emulated hue test
2017-05-25 21:13:53 -07:00
Adam Mills
65c3201fa6 Rename of the zwave hass.data constants (#7768)
* Rename of the zwave hass.data constants

* Remove zwave since it is already implied
2017-05-25 21:11:02 -07:00
Anton Sarukhanov
3a843e1817 Add icons to device tracker. (#7759) 2017-05-24 19:12:26 -07:00
Paulus Schoutsen
0c7f8e910e Merge branch 'master' into dev 2017-05-24 19:05:01 -07:00
Hugo Herter
0abde3aa57 Change setup script to use pip install instead of setup.py develop (#7756)
Using `python setup.py develop` did not manage to install the required dependencies.
This updates `script/setup` to use `pip install -e .` instead in order to resolve the required dependencies.
2017-05-24 15:31:51 -07:00
amigian74
775d45ae5a Exclude filter for event types (#7627)
* add exclude filter for event types to recorder component

* corrected long line (279)

* change source code structure
add test for exclude event types

* code cleanup

* change source code structure

* Update __init__.py

* Update test_init.py
2017-05-24 15:23:52 -07:00
Paulus Schoutsen
e7d783ca2a Update links.html 2017-05-24 14:47:22 -07:00
cribbstechnologies
ef4ef2d383 Template light (#7657)
* starting light template component

* linting/flaking

* starting unit tests from copypasta

* working on unit testing

* forgot to commit the test

* wrapped up unit testing

* adding remote back

* updates post running tox

* Revert "adding remote back"

This reverts commit 852c87ff96.

* adding submodule back from origin

* updating submodule

* removing a line to commit

* re-adding line

* trying to update line endings

* trying to fix line endings

* trying a different approach

* making requested changes, need to fix tests

* flaking

* union rather than intersect; makes a big difference

* more tests passing, not sure why this one's failing

* got it working

* most of the requested changes

* hopefully done now

* sets; the more you know
2017-05-24 14:32:22 -04:00
everix1992
3638b21bcb Added new commands and functionality to the harmony remote component. (#7113)
* Added new commands and functionality to the harmony remote component.

-This includes the ability to optionally specify a number of times to repeat a specific command, such as pressing the volume button multiple times.
-Also added a new command that allows you to send multiple commands to the harmony at once, such as sending a set of channel numbers.
-Updated the unit tests for these changes.

* Fix flake8 coding violations

* Remove send_commands command and make send_command handle a single or list of commands

* Remove send_commands tests

* Update itach and kira remotes for new send_command structure. Fix pyharmony version in requirements_all.txt

* Fix incorrect variable name

* Fix a couple minor issues with remote tests
2017-05-23 17:00:52 -07:00
Stu Gott
54c45f80c1 Fix time_date sensor to update at predictable intervals (#7644)
* Fix time_date sensor to update at predictable intervals

* Delete automations.yaml
2017-05-23 16:00:26 -07:00
Juggels
e3307fb1c2 Redesign monitored variables for hp_ilo sensor (#7534)
* Redesign monitored variables

Allow generating specific sensors without the need for template sensors

* Import 3rd party library inside update method

* Remove jsonpath_rw dependency

* Do not interfere with value_template or ilo_data output

Do not interfere with value_template or ilo_data output, this is now the responsibility of the user and should be handled in `configuration.yaml`

Fix UnusedImportStatement

Fix newline after function docstring

* Always output results to state
2017-05-23 14:56:00 -07:00
William Scanlon
b5f20c9b64 Always return rgb color of bulbs (#7743) 2017-05-23 14:49:20 -07:00
Anton Sarukhanov
7055fddfb4 Don't block startup more than 60 seconds while waiting for components. (#7739) 2017-05-23 14:29:27 -07:00
Anders Melchiorsen
fce09f624b LIFX: disable color features for white-only bulbs (#7742)
The product type is already established in order to decide the Kelvin range
so just reuse that information to disable color features for white-only lights.

Also change the breathe/pulse effects to be more useful for white-only
bulbs. For consistency, color bulbs set to a desaturated (i.e. white-ish)
color get the same default treatment as white-only bulbs.
2017-05-23 22:35:19 +02:00
nordeep
be53cc7068 Don't initialize mqtt components which have already been discovered (#7625)
* Don't initialize mqtt components which have already been discovered

* Fix string length

* Fix blank lines, fix constant name

* Remove globals. Remove JSON dump

* Add tests. Update grammar

* PEP8 style issue

* Add hyphen to object_id regex

* PEP8 style fix
2017-05-23 11:08:12 -07:00
Anton Sarukhanov
f3dabe21ab Prevent the random template filter from caching its output. Fixes #5678 (#7716) 2017-05-23 10:32:06 -07:00
Brenton Zillins
228fb8c072 Ensure https base_url in telegram bot (#7726) 2017-05-23 10:16:54 -07:00
Lev Aronsky
c556b619b7 Asuswrt continuous ssh (#7728)
* Make ssh and telnet connections continuous in asuswrt

* Refactored SSH and Telnet connections into respective classes.

* Fixed several copy-paste typos and errors.

* More typos fixed.

* Small changes to arguments, to pass automated tests.

* Removed unsupported named arguments.

* Fixed a couple of mistakes in Telnet, and other lint errors.

* Added Telnet tests, and added lint exceptions.

* Removed comments from tests, as they irritated the hound.
2017-05-23 09:55:01 -07:00
Paulus Schoutsen
2682996939 Constrain requests to a version (#7725)
Add an optional extended description…
2017-05-23 15:45:22 +02:00
Alex Harvey
6872daab89 update apcacccess used in apcupsd to 0.0.10, which fixes random file drop from apcaccess (#7722) 2017-05-22 17:00:41 -07:00
Paulus Schoutsen
6d183e8bb3 Merge pull request #7686 from home-assistant/release-0-45-1
0.45.1
2017-05-22 11:36:21 -07:00
Paulus Schoutsen
cdc8628e5a Allow fetching hass.io panel without auth (#7714) 2017-05-22 11:06:04 -07:00
tobygray
dc4b0695b5 device_tracker.ubus: Handle empty results (#7673)
If OpenWRT isn't running the DHCP server then some OpenWRT hardware,
such as TP-Link TL-WDR3600 v1, can't determine the host
corresponding to an associated wifi client. This change handles that
by returning None when the request has no data in the result.
2017-05-22 11:06:04 -07:00
cgtobi
3fb691ead6 Fix playback control of web streams (#7683)
Web streams can't be paused and resumed later. That's why volumio stops them instead of pausing them.
2017-05-22 11:06:04 -07:00
Eugenio Panadero
a9926e355f Fix telegram chats (#7689)
* bugfix for Telegram chat_ids

- Negative `chat_id`s for groups.
- Include `chat_id` in event data.
- Handle KeyError when receiving other types of messages, as `new_chat_member` ones, and send them as text.

* unused import

* fix double quote style, fix boolean expr, change warning msg

* mistake

* some more fixes

- fix if condition for msg bad fields.
- return True for a correct but not allowed or not recognized message: if not, the message arrives continuously.
- Allow to receive messages from unauthorized users if they come from authorized groups.

* support for `edited_message`s

- They come as normal messages, except for the 'edited_message' field instead of 'message'.
2017-05-22 11:06:04 -07:00
Paulus Schoutsen
17cbe0c6ce Allow fetching hass.io panel without auth (#7714) 2017-05-22 11:00:02 -07:00
Fabian Affolter
783abc7996 Make 'sender' as requirement for the config (fixes #7698) (#7706) 2017-05-22 15:17:15 +02:00
Fabian Affolter
47355eed41 Upgrade python-telegram-bot to 6.0.1 (#7704) 2017-05-22 13:56:36 +02:00
John Mihalic
d5642a5faf Bump pyEight version (#7701) 2017-05-22 07:54:01 +02:00
tobygray
ca3f07cdef device_tracker.ubus: Handle empty results (#7673)
If OpenWRT isn't running the DHCP server then some OpenWRT hardware,
such as TP-Link TL-WDR3600 v1, can't determine the host
corresponding to an associated wifi client. This change handles that
by returning None when the request has no data in the result.
2017-05-21 17:26:05 -07:00
LvivEchoes
99ea1e3f4f Continue tracking device over dhcp lease table if wireless adapter not installed (#7690) 2017-05-21 17:18:55 -07:00
Anders Melchiorsen
bb8de5845a Sort entities in default groups by name (#7681)
* Sort entities in default groups by name

* Cleanups from review
2017-05-21 17:05:48 -07:00
cgtobi
b3cb057aac Fix playback control of web streams (#7683)
Web streams can't be paused and resumed later. That's why volumio stops them instead of pausing them.
2017-05-21 17:05:04 -07:00
Eugenio Panadero
922303fd4b Fix telegram chats (#7689)
* bugfix for Telegram chat_ids

- Negative `chat_id`s for groups.
- Include `chat_id` in event data.
- Handle KeyError when receiving other types of messages, as `new_chat_member` ones, and send them as text.

* unused import

* fix double quote style, fix boolean expr, change warning msg

* mistake

* some more fixes

- fix if condition for msg bad fields.
- return True for a correct but not allowed or not recognized message: if not, the message arrives continuously.
- Allow to receive messages from unauthorized users if they come from authorized groups.

* support for `edited_message`s

- They come as normal messages, except for the 'edited_message' field instead of 'message'.
2017-05-21 17:02:22 -07:00
Adam Mills
8c1181f8e3 Remove defunct INSTALL_OPENZWAVE from Dockerfile (#7697) 2017-05-21 17:01:42 -07:00
John Arild Berentsen
4a0d6e73f4 ZWave: Add reset service to meters (#7676)
* Add reset service for command_class meters.

* Add reset service for command_class meters.

* cast index to const.py
2017-05-21 20:15:24 +02:00
Paulus Schoutsen
171086229a Guard against new and removed state change events (#7687) 2017-05-21 07:41:33 -07:00
Andrey
927024714b Zwave: Apply refresh_node workaround on 1st instance only (#7579)
* Apply refresh_node workaround on 1st instance only

* Add another test
2017-05-21 17:33:42 +03:00
tobygray
24b7fd3694 zoneminder: fix incorrect use of logging.exception. (#7675)
Prior to this change the zoneminder component was attempting to
use logging.exception outside of exception handling code. This
would lead to the traceback module throwing an exception when
trying to work out the traceback for the exception.

This fixes the issue by changing the exception call into a
plain error logging call.
2017-05-21 11:11:33 +02:00
Paulus Schoutsen
d6f43ba839 Version bump to 0.45.1 2017-05-20 22:34:59 -07:00
Paulus Schoutsen
3492545ec1 Update state automation to work with new and deleted state changes 2017-05-20 22:34:53 -07:00
Fabian Affolter
ceff9981be Merge branch 'master' into dev 2017-05-21 00:47:42 +02:00
Fabian Affolter
70ea16bdc0 Merge pull request #7648 from home-assistant/release-0-45
0.45
2017-05-21 00:34:44 +02:00
Marcelo Moreira de Mello
943958b140 Added support to Amcrest camera to feed using RTSP via ffmpeg (#7646)
* Implemented ffmpeg option on Amcrest camera and upgraded to version 1.2.0

* Added ffmpeg arguments and binary options to Amcrest camera

* Added ffmpeg as dependencies

* Makes lint happy and fixed requirements_all.txt

* Inherent the ffmpeg.binary configuration from ffmpeg component

* Update amcrest.py
2017-05-20 23:55:15 +02:00
John Arild Berentsen
23c5fc0aad Bugfix #7586 (#7661) 2017-05-20 23:53:48 +02:00
Fabian Affolter
45b4ef46cc Align with OpenALPR platform for naming conf variables (#7650) 2017-05-20 23:51:16 +02:00
Andrey
44edf3e105 Switch pymodbus to pypi (#7677) 2017-05-20 21:19:22 +02:00
Anders Melchiorsen
81f0826550 Ignore attribute changes in automation trigger from/to (#7651)
* Ignore attribute changes in automation trigger from/to

* Quote names in deprecation warnings

This makes it somewhat easier to read if the suggestion happens to be
named "to".

* Add test with same state, new attribute value
2017-05-20 15:18:59 -04:00
Barry Williams
adde9e6231 Upgrade Openhome library (#7671)
* Added support for openhome devices using transport service

* Style cleanup
2017-05-20 17:43:35 +02:00
Paulus Schoutsen
de85d38aa5 Update frontend 2017-05-20 08:08:06 -07:00
Paulus Schoutsen
f637a07016 Update frontend 2017-05-20 08:07:32 -07:00
thecynic
9e153119ef Point pylutron to pypi (#7664) 2017-05-20 14:27:35 +03:00
Fabian Affolter
b5c54864ac Change line endings to LN (#7660) 2017-05-19 07:39:13 -07:00
Paulus Schoutsen
d369d70ca5 Fix tests (#7659)
* Remove global hass

* Http.auth test no longer spin up server

* Remove server usage from http.ban test

* Remove setupModule from test device_sun_light_trigger

* Update common.py
2017-05-19 07:37:39 -07:00
John Arild Berentsen
5aa72562a7 Bugfix #7586 (#7661) 2017-05-19 13:40:26 +02:00
Robbie Trencheny
c4da921cb5 Add network_key as a config option (#7637)
* Add network_key as a config option

* Update __init__.py
2017-05-18 23:49:37 -07:00
Robbie Trencheny
7daa92249a Add network_key as a config option (#7637)
* Add network_key as a config option

* Update __init__.py
2017-05-18 23:49:15 -07:00
John Arild Berentsen
4a3d9a956d Final tweaks for Zwave panel (#7652)
* # This is a combination of 3 commits.
# The first commit's message is:
Add seperate zwave panel

# The 2nd commit message will be skipped:

#	unused import

# The 3rd commit message will be skipped:

#	Use get for config

* Add seperate zwave panel

* Modify set_config_parameter to accept setting string values

* descriptions

* Tweaks

* Tweaks

* Tweaks

* Tweaks

* lint

* Fallback if no config parameteres are available

* Update services.yaml

* review changes
2017-05-18 17:41:31 -07:00
Paulus Schoutsen
6662b7f52d Update frontend 2017-05-18 17:41:26 -07:00
Paulus Schoutsen
e91fe94585 Update frontend 2017-05-18 17:41:03 -07:00
John Arild Berentsen
88ffe39945 Final tweaks for Zwave panel (#7652)
* # This is a combination of 3 commits.
# The first commit's message is:
Add seperate zwave panel

# The 2nd commit message will be skipped:

#	unused import

# The 3rd commit message will be skipped:

#	Use get for config

* Add seperate zwave panel

* Modify set_config_parameter to accept setting string values

* descriptions

* Tweaks

* Tweaks

* Tweaks

* Tweaks

* lint

* Fallback if no config parameteres are available

* Update services.yaml

* review changes
2017-05-18 17:39:31 -07:00
happyleavesaoc
e479324db9 update usps (#7655)
* update usps

* fix doc
2017-05-18 17:30:43 -07:00
happyleavesaoc
f65cc68705 bump ups version (#7654) 2017-05-18 23:38:50 +02:00
happyleavesaoc
238921b681 bump fedex version (#7653) 2017-05-18 23:37:39 +02:00
Marcelo Moreira de Mello
0fd415d7fb Added support to Amcrest camera to feed using RTSP via ffmpeg (#7646)
* Implemented ffmpeg option on Amcrest camera and upgraded to version 1.2.0

* Added ffmpeg arguments and binary options to Amcrest camera

* Added ffmpeg as dependencies

* Makes lint happy and fixed requirements_all.txt

* Inherent the ffmpeg.binary configuration from ffmpeg component

* Update amcrest.py
2017-05-18 10:06:24 +02:00
Fabian Affolter
0eb6540fe7 Align with OpenALPR platform for naming conf variables (#7650) 2017-05-18 09:57:38 +02:00
Paulus Schoutsen
fc0c8540d3 Version bump to 0.46.0.dev0 2017-05-17 23:03:47 -07:00
Paulus Schoutsen
eb473600f6 Version bump to 0.45 2017-05-17 23:03:27 -07:00
Paulus Schoutsen
de999d8439 Merge remote-tracking branch 'origin/master' into dev 2017-05-17 23:03:00 -07:00
Paulus Schoutsen
6d97546f40 Update frontend 2017-05-17 22:29:46 -07:00
Paulus Schoutsen
e773133bcf Fix automation failing to setup if no automations specified (#7647) 2017-05-17 21:57:50 -07:00
Anders Melchiorsen
3d4b2436db Coerce color_temp to int even when passed in as kelvin (#7640) 2017-05-17 19:20:59 -07:00
Paulus Schoutsen
a068efcd47 Abort tests when instances leaked (#7623) 2017-05-18 00:19:40 +02:00
Fabian Affolter
f86edd4f24 Seven segments OCR image processing (#7632)
* Add initial seven segments OCR image processing

* Fix typo
2017-05-18 00:07:02 +02:00
Daniel Perna
a24aebd5ae Updated dependency (#7638) 2017-05-17 23:57:34 +02:00
Riccardo Canta
f3b9e1e988 Osram lightify Removed wrong assignment (#7615)
self._brightness is assigned with the returned value of the
set_luminance() function, which is always equal to None.
2017-05-17 23:26:58 +02:00
corneyl
76b747edd6 Updated limitlessled requirement to v1.0.8 (#7629) 2017-05-17 09:05:34 -07:00
Eugenio Panadero
f7d25396a4 Kodi specific service to call Kodi API methods (#7603)
* Kodi specific services to call Kodi API methods

 - new service: `kodi_execute_addon` to run a Kodi Addon with optional parameters. Results of the Kodi API call, if any, are redirected in a Home Assistant event: `kodi_execute_addon_result`.
 - new service: `kodi_run_method` to run a Kodi JSONRPC API method with optional parameters. Results of the Kodi API call are redirected in a Home Assistant event: `kodi_run_method_result`.
 - Add descriptions in services.yaml.
 - Add `timeout` parameter to yaml config (needed to make slow queries to the JSONRPC API, default timeout is set to 5s).
 - Trigger events with the results of the Kodi API calls, with:
 ```
 event_data = {
   'result': api_call_results,
   'result_ok': boolean,
   'input': api_call_parameters,
   'entity_id': 'media_player.kodi'}
```

* no need to clean OrderedDicts; no need for the `kodi_execute_addon` service

* no need for the `kodi_execute_addon` service

* unused import

* naming changes
2017-05-17 08:42:47 -04:00
Fabian Affolter
0e9728d94a Update docstrings (#7630) 2017-05-17 10:10:35 +02:00
Fabian Affolter
3b69de8a1a Upgrade Sphinx to 1.6.1 (#7624) 2017-05-17 09:14:28 +02:00
Fabian Affolter
f0b2a6d0e6 Update docstrings and comments (#7626) 2017-05-17 09:14:11 +02:00
Conrad Juhl Andersen
d2ed3a131f Add support for disabling tradfri groups (#7593)
* Add support for disabling tradfri groups

* Fixed styleguide problems

* Fix style problems

* Use default for groups when setting up in UI
2017-05-16 23:26:57 -07:00
Anders Melchiorsen
ed5f94fd8a Add kelvin/brightness_pct alternatives to light.turn_on (#7596)
* Refactor color profiles to a class

* Refactor into preprocess_turn_on_alternatives

* LIFX: use light.preprocess_turn_on_alternatives

This avoids the color_name duplication and gains support for profile.

* Add kelvin parameter to light.turn_on

* Add brightness_pct parameter to light.turn_on

* LIFX: accept brightness_pct in effects

* Add test of kelvin/brightness_pct conversions
2017-05-16 23:00:46 -07:00
Greg Dowling
9dcc0b5ef5 Bump pyvera - fixes issue with % in brightness levels. (#7622) 2017-05-16 20:01:29 -07:00
Fabian Affolter
1fafa34eb1 Fix typo and update style to match the other platforms (#7621) 2017-05-16 21:57:00 +02:00
Ole-Kenneth
71ed17b836 Add Content-type: image/jpeg for camera proxy (#7581)
* Add Content-type: image/jpeg for camera proxy

* Set content_type in constructur
2017-05-16 09:11:44 -07:00
Philipp Schmitt
a7f933966b Update Docker base image to python 3.6 (#7613) 2017-05-16 09:09:21 -07:00
Paulus Schoutsen
641ba014f2 Update frontend 2017-05-15 23:17:33 -07:00
Paulus Schoutsen
d5ca6a5aed Force automation ids to always be a string (#7612) 2017-05-15 23:15:06 -07:00
Marc Egli
d6081f3dc5 Make miflora monitored_conditions parameter optional (#7598)
* Make miflora monitored_conditions parameter optional.

* Use default keyword instead.

* Use list instead of tuple

* Simplify even more
2017-05-15 23:13:41 -07:00
Fabian Affolter
f25347d98d File sensor (#7569)
* Add File sensor

* Use None and return

* Remove I/O

* Use less memory

* No traceback if file is empty
2017-05-15 14:25:46 +02:00
John Mihalic
a1dc35fc75 Fix handling of single user (#7587) 2017-05-15 00:46:43 -07:00
Marc Egli
4da91d6a8b Add sonos alarm clock update service (#7521)
* Add sonos alarm clock update service

* Add tests and break lines

* Fix style errors

* Make test work with python<3.6

* Fix last two pylint errors

* fix new line to long errors
2017-05-15 00:42:45 -07:00
jhemzal
5c4a21efac Add posibility to specify snmp protocol version (#7564)
* snmp sensor protocol version configuration option

* fixed lint findings.
2017-05-15 00:34:51 -07:00
Adam Mills
e2e58e6acc Automation State Change For timer attribute fix (#7584) 2017-05-15 00:34:30 -07:00
Eugenio Panadero
d0304198de SMTP notify enhancements: full HTML emails and custom product_name in email headers (#7533)
* SMTP notify enhancements: HTML emails and customization options

- Send full HTML emails, with or without inline attached images.
- Custom `timeout`.
- Custom `product_name` identifier for the `FROM` and `X-MAILER` email headers.
- New HTML email test

* `sender_name` instead of product_name

 - Change `sender_name` instead of `product_name`.
 - No changes in `X-Mailer` header.
 - `From` header as always unless you define the new `sender_name` parameter.
2017-05-15 00:23:57 -07:00
Paulus Schoutsen
36d7fe72eb Fix websocket api reaching queue (#7590)
* Fix websocket api reaching queue

* Fix outside task message sending

* Fix Py34 tests
2017-05-15 00:10:06 -07:00
Marc Egli
6d245c43fc Pass additional arguments to tox in test_docker (#7591) 2017-05-14 23:21:39 -07:00
Matt N
e1a4d51fa2 camera.zoneminder: Handle old versions of zoneminder (#7589) 2017-05-13 23:09:44 -07:00
Paulus Schoutsen
352cca1037 Remove more test requirements (#7574)
* No longer require pyunify during tests

* No longer require cast during tests

* No longer required dependency for tests

* No longer require pymochad for tests

* Astral is a core dependency

* Avoid having to install datadog dependency during tests

* CMUS test doesn't test anything

* Frontier Silicon doesn't test anything

* No longer require mutagen

* Update requirements_test_all.txt

* Remove stale comment
2017-05-13 21:25:54 -07:00
Paulus Schoutsen
206d02d531 Websocket_api: avoid parallel drain (#7576)
* Websocket_api: avoid parallel drain

* Remove send_message method
2017-05-13 16:34:45 -07:00
William Scanlon
cfbbade6d1 Additional Wink lock features (#7445)
* Additional Wink lock features
2017-05-13 14:09:00 -04:00
Adam Mills
cfea4b17e3 Add tests for zwave network events (#7573) 2017-05-12 23:06:32 -07:00
Stu Gott
9c4bc2a47f Add Kira component to sensor and remote platforms (#7479)
* Add Kira component to sensor and remote platforms

* Test cases for Kira component and platforms
2017-05-12 21:12:47 -07:00
Eugenio Panadero
4cdf0b4969 Fix Kodi specific services registry and add descriptions (#7551)
* Fix Kodi specific services, add descriptions, add more handled exceptions

 - Fixes issue #7528
 - Add descriptions for Kodi specific services in services.yaml.
 - Error handling in Kodi API errors.
 - Make compatible the existent specific service `media_player.kodi_set_shuffle` with the general `media_player.shuffle_set` service (both use the same method but with different named parameter, I think the Kodi specific service should be eliminated, since it is not)

* fix line too long

* removed new services (for another PR); removed `kodi_set_shuffle` service

* requested changes

 - Removed `kodi_set_shuffle` service.
 - Optional `media_name` and `artist_name` parameters. `media_name` defaults to 'ALL'.
 - Guard clause to check if the services are already registered.
2017-05-12 20:48:57 -07:00
bestlibre
ad15844cf4 Fix systematic warning in influxdb sensor (#7541) 2017-05-12 20:47:12 -07:00
Kevin Fronczak
25cb7c652b Blink version bump (#7571)
Bumped blink version to support automatic reauthorization when tokens expire. Changed the battery sensor call to a string version so that the battery reports back "Low" or "OK" rather than a cryptic integer
2017-05-12 20:30:07 -07:00
Adam Mills
189023821b Tests for zwave setup features (#7570)
* Tests for zwave setup features

* Add test for frontend panel register
2017-05-12 20:27:44 -07:00
Adam Mills
c118be6639 Tests for zwave discovery logic (#7566)
* Tests for zwave discovery logic

* Simplify patching

* Test ignored node
2017-05-12 20:18:20 -07:00
Mitesh Patel
11a3dc268f Support lutron serena shades (#7565)
* Adds support for the Lutron Caseta Serena shades hardware

* fixes typos
2017-05-12 20:17:11 -07:00
Paulus Schoutsen
f0ce6c8210 Update netdisco (#7563) 2017-05-12 20:14:17 -07:00
Juggels
ed0ec613c3 Comment RasPi specific requirements (#7562) 2017-05-12 20:06:28 -07:00
Johan Bloemberg
4a3048b370 Initialize sun with correct values. (#7559)
* Initialize sun with unknown values.

Initial values should be `unknown` instead of `0`. Otherwise on HA restart the value of `0` is pushed to metrics databases (graphite/influx/recorder).

* Update sun position before emitting initial update

* Simplify based on armills comment.

* Use provided time for calculation.
2017-05-12 16:04:30 -07:00
Per Osbäck
fdb7371256 update pywebpush to 1.0.0 (#7561) 2017-05-12 09:25:34 -07:00
florincosta
a96a98a260 Add raspihats binary sensor (#7508)
* Added raspihats binary_sensor platform

* Updated .coveragerc to ommit raspihats platforms.

* Using vol.Coerce(int) for validation and casting of I2CHat config address
2017-05-12 09:20:48 -07:00
Anders Melchiorsen
1ab7103aea LIFX: add lifx_set_state service call (#7552)
* Move service helpers to LifxManager

* Add lifx_set_color

This is a synonym for light.turn_on except it does not actually turn on the
light unless asked to.

Thus, turn_on can be implemented just by asking.

* Rename set_color to set_state

* Support power=False with lifx_set_state
2017-05-12 09:19:51 -07:00
Kane610
416b8e0efe Axis component (#7381)
* Added Axis hub, binary sensors and camera

* Added Axis logo to static images

* Added Axis logo to configurator
Added Axis mdns discovery

* Fixed flake8 and pylint comments

* Missed a change from list to function call
V5 of axis py

* Added dependencies to requirements_all.txt

* Clean up

* Added files to coveragerc

* Guide lines says to import function when needed, this makes Tox pass

* Removed storing hass in config until at the end where I send it to axisdevice

* Don't call update in the constructor

* Don't keep hass private

* Unnecessary lint ignore, following Baloobs suggestion of using NotImplementedError

* Axis package not in pypi yet

* Do not catch bare excepts. Device schema validations raise vol.Invalid.

* setup_device still adds hass object to the config, so the need to remove it prior to writing config file still remains

* Don't expect axis.conf contains correct values

* Improved configuration validation

* Trigger time better explains functionality than scan interval

* Forgot to remove this earlier

* Guideline says double qoutes for sentences

* Return false from discovery if config file contains bad data

* Keys in AXIS_DEVICES are serialnumber

* Ordered imports in alphabetical order

* Moved requirement to pypi

* Moved update callback that handles trigger time to axis binary sensor

* Renamed configurator instance to request_id since that is what it really is

* Removed unnecessary configurator steps

* Changed link in configurator to platform documentation

* Add not-context-manager (#7523)

* Add not-context-manager

* Add missing comma

* Threadsafe configurator (#7536)

* Make Configurator thread safe, get_instance timing issues breaking configurator working on multiple devices

* No blank lines allowed after function docstring

* Fix comment Tox

* Added Axis hub, binary sensors and camera

* Added Axis logo to static images

* Added Axis logo to configurator
Added Axis mdns discovery

* Fixed flake8 and pylint comments

* Missed a change from list to function call
V5 of axis py

* Added dependencies to requirements_all.txt

* Clean up

* Added files to coveragerc

* Guide lines says to import function when needed, this makes Tox pass

* Removed storing hass in config until at the end where I send it to axisdevice

* Don't call update in the constructor

* Don't keep hass private

* Unnecessary lint ignore, following Baloobs suggestion of using NotImplementedError

* Axis package not in pypi yet

* Do not catch bare excepts. Device schema validations raise vol.Invalid.

* setup_device still adds hass object to the config, so the need to remove it prior to writing config file still remains

* Don't expect axis.conf contains correct values

* Improved configuration validation

* Trigger time better explains functionality than scan interval

* Forgot to remove this earlier

* Guideline says double qoutes for sentences

* Return false from discovery if config file contains bad data

* Keys in AXIS_DEVICES are serialnumber

* Ordered imports in alphabetical order

* Moved requirement to pypi

* Moved update callback that handles trigger time to axis binary sensor

* Renamed configurator instance to request_id since that is what it really is

* Removed unnecessary configurator steps

* Changed link in configurator to platform documentation

* No blank lines allowed after function docstring

* No blank lines allowed after function docstring

* Changed discovery to use axis instead of axis_mdns

* Travis CI requested rerun of script/gen_requirements_all.py
2017-05-12 08:51:54 -07:00
Andrey
5b3ef0f76f Treat swing and fan level as optional in Sensibo Climate. (#7560) 2017-05-12 18:28:58 +03:00
Tsvi Mostovicz
452c3a1b25 Support adding different server locations for Microsoft face component (#7532)
* Support adding different server locations

* Rename variables and move CONF_ const into component as requested in review

* Fix unittests

* Forgot to add tests for microsoft_face_identify
2017-05-12 10:53:25 +02:00
Paulus Schoutsen
8da10f670b Only install tox in dev mode (#7557) 2017-05-12 00:01:06 -07:00
Adam Mills
b805d8a844 Hide proximity updates in logbook (#7549) 2017-05-11 19:37:32 -07:00
Paulus Schoutsen
76675a54f8 Do not install all dependencies in dev mode (#7548)
* ps - do not install all dependencies

* Comment out blinkt because it depends on GPIO

* Add pip upgrade check back

* Disable import error blinkt

* Update comment

* Fix comment
2017-05-11 19:20:23 -07:00
Trevor
0e246059f9 Add SSL support to NZBGet sensor (#7553) 2017-05-11 23:05:06 +02:00
Fabian Affolter
0e41342a40 Upgrade dweepy to 0.3.0 (#7550) 2017-05-11 22:48:03 +02:00
Adam Mills
04f1054d07 Automatic version bump (#7555) 2017-05-11 22:47:47 +02:00
Fabian Affolter
966bda079e Upgrade sendgrid to 4.1.0 (#7538) 2017-05-11 09:06:22 -07:00
jumpkick
ef4587f994 Fix for #7459 (#7544)
* Generate a new updateDate with every call

This should fix #7459
Tests need to be updated in another commit.

* Replace STATIC_TIME with datetime object check

Removing the "DATE" argument from the Alexa component's configuration (because it is now dynamically generated) requires this commit's changes to the test cases to check that the updateDate data is a datetime type rather than a specific hardcoded value ('2016-10-10T19:51:42.0Z').

* Fix brackets
2017-05-11 09:04:17 -07:00
Kane610
2c8f6a0ad0 Threadsafe configurator (#7536)
* Make Configurator thread safe, get_instance timing issues breaking configurator working on multiple devices

* No blank lines allowed after function docstring

* Fix comment Tox
2017-05-11 10:24:36 +03:00
Fabian Affolter
8cdadd2aa0 Add not-context-manager (#7523)
* Add not-context-manager

* Add missing comma
2017-05-11 09:14:52 +02:00
Fabian Affolter
3bdf77ad62 Add myStrom binary sensor (#7530) 2017-05-10 16:58:03 +02:00
Adam Mills
8c90fd19ff Try to request current_location Automatic scope (#7447) 2017-05-10 05:44:52 -07:00
Fabian Affolter
71b4afb780 Update docstrings and log messages (#7526) 2017-05-10 12:06:57 +02:00
corneyl
6e6a000217 Upgrade limitlessled to 1.0.7 (#7525) 2017-05-10 10:45:33 +02:00
Bas Schipper
85e71fc785 Support for the PiFace Digital I/O module (#7494)
* Added rpi_pfio component supporting the PiFace I/O module

* Fixed some code style issues

* Removed global listener

* Update rpi_pfio.py
2017-05-09 22:36:33 -07:00
Fabian Affolter
216199556a Don't interact with hass directly (#7099) 2017-05-09 21:56:17 -07:00
Nuno Sousa
89d950c73a Add password parameter to uvc component (#7499) 2017-05-09 21:54:38 -07:00
Eugenio Panadero
b30c352e37 Telegram Bot enhancements with callback queries and new notification services (#7454)
* telegram_bot and notify.telegram enhancements:
- Receive callback queries and produce `telegram_callback` events.
- Custom reply_markup (keyboard or inline_keyboard) for every type of message (message, photo, location & document).
- `disable_notification`, `disable_web_page_preview`, `reply_to_message_id` and `parse_mode` optional keyword args.
- Line break between title and message fields: `'{}\n{}'.format(title, message)`
- Move Telegram notification services to `telegram_bot` component and forward service calls from the telegram notify service to the telegram component, so now the `notify.telegram` platform depends of `telegram_bot`, and there is no need for `api_key` in the notifier configuration. The notifier calls the new notification services of the bot component:
	- telegram_bot/send_message
	- telegram_bot/send_photo
	- telegram_bot/send_document
	- telegram_bot/send_location
	- telegram_bot/edit_message
	- telegram_bot/edit_caption
	- telegram_bot/edit_replymarkup
	- telegram_bot/answer_callback_query
- Added descriptions of the new notification services with a services.yaml file.
- CONFIG_SCHEMA instead of PLATFORM_SCHEMA for the `telegram_bot` component, so only one platform is allowed.
- Async component setup.

* telegram_bot and notify.telegram enhancements: change in requirements_all.txt.
2017-05-09 21:42:17 -07:00
Gergely Imreh
1312ee0f7d sensor.envirophat: do not set up platform if hardware is not attached (#7438)
* sensor.envirophat: do not set up platform if hardware is not attached

Fixes comment from:
https://github.com/home-assistant/home-assistant/pull/7427#discussion_r114703904

* Fix update logic.
2017-05-09 21:29:38 -07:00
Andrey
f4915ddb0b Switch basicmodem and python-roku to pypi (#7514) 2017-05-09 20:23:19 -07:00
Marc Egli
43296069c3 Update docker dev environment to python3.6 (#7520)
* Update docker dev environment to python3.6

* comment out disable switches again
2017-05-09 20:16:46 -07:00
John Arild Berentsen
1eaec8f406 Zwave panel api (#7456)
* # This is a combination of 3 commits.
# The first commit's message is:
Add seperate zwave panel

# The 2nd commit message will be skipped:

#	unused import

# The 3rd commit message will be skipped:

#	Use get for config

* Add seperate zwave panel

* more info

* Add usercodeview

* Improve api

* Improve api

* Separate api into own file.

* disable missing import

* review changes

* Tests 1

* Verify that we fetch data from groups

* Tests groups

* config 1

* usercode 1

* Api mods

* Tweak API

* docstrings

* 100% api testing
2017-05-09 18:56:41 -07:00
Paulus Schoutsen
5d820ec188 Add support for automation config panel (#7509)
* Add support for automation config

* Build fromtend

* Lint
2017-05-09 18:44:00 -07:00
Marc Egli
d86dfb6336 Fix sonos sleep timer (#7503) 2017-05-09 18:35:51 +02:00
Josh Anderson
b34c58386c Correct retrieval of spotify shuffle state (#7505)
Returned on the current playback response itself, not the device
2017-05-09 17:35:30 +02:00
abmantis
5cb3382425 new source only forces "play" if the current state is "playing" (#7506) 2017-05-09 17:34:17 +02:00
Adam Mills
40d27cde0e Refactor sun component for correctness (#7295)
* Refactor sun component for correctness

* Convert datetimes to dates for astral

* Fix tests for updated code

* Fix times now that calcs are fixed

* Move sun functions to helpers

* Fix flake on new file

* Additional tweaks from review

* Update requirements
2017-05-09 00:03:34 -07:00
Oliver
419d97fc06 Fixed potential AttributeError when checking for deleted sources (#7502) 2017-05-09 07:24:18 +02:00
Andrey
1cd51bc6a8 Switch onkyo to pypi (#7497) 2017-05-09 08:13:29 +03:00
Fabian Affolter
c12c742297 Upgrade beautifulsoup4 to 4.6.0 (#7491) 2017-05-08 19:39:40 +02:00
Johan Bloemberg
ce879b7eb8 Prevent printing of packets. (#7492)
A small bug in the python-rflink library caused packets to be printed. This update prevents this from happening.
2017-05-08 17:04:17 +02:00
Fabian Affolter
d7e3962cc0 Upgrade async_timeout to 1.2.1 (#7490) 2017-05-08 17:02:37 +02:00
Anders Melchiorsen
86b34b40a1 LIFX: avoid out-of-bounds hue aborting the colorloop effect (#7495)
The hue is now a float but the hsbk conversion still believed it to be
an integer that could not be larger than 359. The float can in fact be,
for example, 359.9 and this would cause an out-of-bounds error in the
set_color call.

For completeness, the initial hue is also changed to a float.
2017-05-08 16:51:27 +02:00
Paulus Schoutsen
12293d6600 0.44.2 (#7488)
* Version bump to 0.44.2

* Update frontend
2017-05-07 22:07:52 -07:00
Mitesh Patel
66cbdc3043 Uses pypi for deps (#7485) 2017-05-07 17:32:13 -07:00
Paulus Schoutsen
e1d1385358 Fix travis 2017-05-07 16:55:22 -07:00
Paulus Schoutsen
bafc04ca42 Update tox.ini 2017-05-07 16:53:28 -07:00
Paulus Schoutsen
5717c87097 Update tox.ini 2017-05-07 16:51:46 -07:00
Paulus Schoutsen
ab9c394e93 Version bump to 0.44.1 2017-05-07 15:09:53 -07:00
Paulus Schoutsen
5d13f36a4b Merge pull request #7482 from home-assistant/release-0-44-1
0.44.1
2017-05-07 15:08:37 -07:00
Caleb
4165629f97 Update to pyunifi 2.12 (#7468)
* Update to pyunifi 2.12

* Update requirements_all.txt
2017-05-07 14:03:39 -07:00
Marc Egli
f87b9b7b85 Fix plant MIN_TEMPERATURE, MAX_TEMPERATURE validation (#7476)
* Fix plant MIN_TEMPERATURE, MAX_TEMPERATURE validation

small_float only allows values from 0 to 1 so we should use float instead

* Do not use vol.All for a single validation
2017-05-07 14:03:14 -07:00
Martin Hjelmare
2ab45441a8 Upgrade pymysensors to 0.10.0 (#7469) 2017-05-07 14:02:53 -07:00
pezinek
fcdfebefd9 Forecasts for weather underground (#7062) 2017-05-07 13:56:19 -07:00
Brian Cribbs
9b920b3b40 fixing nits 2017-05-07 13:56:05 -07:00
Brian Cribbs
0c94df9fcf fixing documentation 2017-05-07 13:56:05 -07:00
Brian Cribbs
1ba4435693 repairing functionality for non-zero based ranges 2017-05-07 13:56:05 -07:00
Paulus Schoutsen
00ec50da4b Update frontend 2017-05-07 13:50:07 -07:00
Marc Egli
c1056ea4d4 Fix plant MIN_TEMPERATURE, MAX_TEMPERATURE validation (#7476)
* Fix plant MIN_TEMPERATURE, MAX_TEMPERATURE validation

small_float only allows values from 0 to 1 so we should use float instead

* Do not use vol.All for a single validation
2017-05-07 15:15:18 +02:00
Paulus Schoutsen
9440ff881f Remove listening to homeassistant_start with event automation (#7474) 2017-05-06 23:52:39 -07:00
Robbie Trencheny
c525ee9daa Make this an error instead of an info 2017-05-06 23:11:11 -07:00
Paulus Schoutsen
79ca47640e Update requirements_test_all.txt 2017-05-06 23:02:12 -07:00
Caleb
41212b90c4 Update to pyunifi 2.12 (#7468)
* Update to pyunifi 2.12

* Update requirements_all.txt
2017-05-06 22:39:21 -07:00
Paulus Schoutsen
aa6339818e Test only dependencies (#7472)
* Generate requirements file for tests

* Update tox

* Update validate

* Lint

* Tweak order in travis.yml to run longest job first
2017-05-06 22:37:31 -07:00
Paulus Schoutsen
305309a59e Upgrade Dockerfile to Python 3.6 (#7471) 2017-05-06 20:16:40 -07:00
Paulus Schoutsen
ea095de98e Demo: Update old group member thermostat.ecobee -> climate 2017-05-06 19:40:59 -07:00
Paulus Schoutsen
e8a33758c1 Capitalize group names in demo 2017-05-06 19:38:48 -07:00
Martin Hjelmare
47034f83f4 Upgrade pymysensors to 0.10.0 (#7469) 2017-05-06 19:10:17 -07:00
Andrey
2c1df75c07 Switch russound, pymysensors, and pocketcasts to pypi (#7449)
* Switch russound to pypi

* Switch pymysensors to pypi

* Switch pocketcasts to pypi
2017-05-07 02:22:38 +02:00
Paulus Schoutsen
43ff95ad3b Merge pull request #7444 from home-assistant/release-0-44
0.44
2017-05-06 10:38:45 -07:00
Josh Wright
e2559fd6cf Fix object type for default KNX port
#7429 describes a TypeError that is raised if the port is omitted in the config for the KNX component (integer is required (got type str)). This commit changes the default port from a string to an integer. I expect this will resolve that issue...
2017-05-06 10:27:36 -07:00
Gergely Imreh
abe6f9343f sensor.envirophat: add missing requirement (#7451)
Adding requirements that is not explicitly pulled in by the library
that manages the Enviro pHAT.
2017-05-06 10:27:17 -07:00
pezinek
7a70496b11 Forecasts for weather underground (#7062) 2017-05-06 10:11:31 -07:00
Adam Mills
7dd7f509ca Add tests for deprecation helpers (#7452) 2017-05-06 10:10:48 -07:00
Robbie Trencheny
6cc85adb81 Merge pull request #7460 from home-assistant/fix/default-knx-port
Fix object type for default KNX port
2017-05-05 18:03:46 -07:00
Josh Wright
2971a24c56 Fix object type for default KNX port
#7429 describes a TypeError that is raised if the port is omitted in the config for the KNX component (integer is required (got type str)). This commit changes the default port from a string to an integer. I expect this will resolve that issue...
2017-05-05 19:19:24 -04:00
Nuno Sousa
20ded1ba3e Add datadog component (#7158)
* Add datadog component

* Improve test_invalid_config datadog test

* Use assert_setup_component for test setup
2017-05-06 00:34:40 +02:00
Josh Wright
2e4ae3e73d PyPI Openzwave (#7415)
* Remove default zwave config path

PYOZW now has much more comprehensive default handling for the config
path (in src-lib/libopenzwave/libopenzwave.pyx:getConfig()). It looks in
the same place we were looking, plus _many_ more. It will certainly do a
much better job of finding the config files than we will (and will be
updated as the library is changed, so we don't end up chasing it). The
getConfig() method has been there for a while, but was subsntially
improved recently.

This change simply leaves the config_path as None if it is not
specified, which will trigger the default handling in PYOZW.

* Install python-openzwave from PyPI

As of version 0.4, python-openzwave supports installation from PyPI,
which means we can use our 'normal' dependency management tooling to
install it. Yay.

This uses the default 'embed' build (which goes and downloads
statically sources to avoid having to compile anything locally). Check
out the python-openzwave readme for more details.

* Add python-openzwave deps to .travis.yml

Python OpenZwave require the libudev headers to build. This adds the
libudev-dev package to Travis runs via the 'apt' addon for Travis.

Thanks to @MartinHjelmare for this fix.

* Update docker build for PyPI openzwave

Now that PYOZW can be install from PyPI, the docker image build process
can be simplified to remove the explicit compilation of PYOZW.
2017-05-05 14:57:14 -07:00
Gergely Imreh
4b5be750b2 sensor.envirophat: add missing requirement (#7451)
Adding requirements that is not explicitly pulled in by the library
that manages the Enviro pHAT.
2017-05-05 11:37:54 -07:00
florincosta
92411cdc18 Add new raspihats component (#7392)
* Add new raspihats component

* added raspihats to COMMENT_REQUIREMENTS in gen_requirements_all.py

* disabled pylint import errors

* using hass.data for storing i2c-hats manager
2017-05-05 00:02:47 -07:00
Daniel Høyer Iversen
94f7c397d7 Add hass to rfxtrx object (#6844) 2017-05-04 23:51:35 -07:00
Daniel Høyer Iversen
526abdd329 Add hass to rfxtrx object (#6844) 2017-05-04 23:50:53 -07:00
Paulus Schoutsen
61196b1c83 Version bump to 0.45.0.dev0 2017-05-04 21:41:32 -07:00
Paulus Schoutsen
03e3fb77c4 Version bump to 0.44 2017-05-04 21:41:11 -07:00
Anders Melchiorsen
bfd6110091 LIFX: handle unavailable lights gracefully
Recent aiolifx allow sending messages to unregistered devices (as a
no-op). This is handy because bulbs can disappear anytime we yield and
constantly testing for availability is both error-prone and annoying.

So keep the aiolifx device around until a new one registers on the same
mac_addr.
2017-05-04 21:40:35 -07:00
Anders Melchiorsen
71f9507df7 LIFX: fix color restore after running effects
State restoration takes up to a second because bulbs can be slow to react.
During this time an effect could keep running, overwriting the state that we
were trying to restore.

Now the effect forgets the light immediately and it thus avoids further
changes while the restored state settles.
2017-05-04 21:40:35 -07:00
Anders Melchiorsen
1c5eb88368 LIFX: avoid warnings about already running updates
Forcing a refresh will log a warning if the periodic async_update happens
to be running already.

So let's do the refresh locally and remove the force_refresh.
2017-05-04 21:40:35 -07:00
Anders Melchiorsen
4be89521d4 LIFX: Update aiolifx requirement
This update silences some warnings (frawau/aiolifx#7).
2017-05-04 21:40:35 -07:00
Anders Melchiorsen
1e4b56c4d4 LIFX: Move random hue initial color to the LIFXEffect base class
It's a reasonable default for several light effects.
2017-05-04 21:40:35 -07:00
Anders Melchiorsen
655b82c1e2 LIFX: Use 3500K as neutral white
This does not really matter because the colorloop uses saturated colors
(without much white). Anyway, just copy the 3500K that the LIFX app uses.
2017-05-04 21:40:35 -07:00
Anders Melchiorsen
81b567b68f LIFX: refresh state after stopping an effect
This clears the internal cache in case polling picked up the state as set by
an effect.

For example, aborting an effect by selecting a new brightness could keep a
color set by the effect.
2017-05-04 21:40:34 -07:00
Paulus Schoutsen
009a9d59ed Update frontend 2017-05-04 21:38:50 -07:00
Paulus Schoutsen
629bf3eefd Update frontend 2017-05-04 21:38:28 -07:00
Paulus Schoutsen
3b237795ba Merge branch 'release-0-44' into dev 2017-05-04 21:23:40 -07:00
Paulus Schoutsen
80e55fb286 Merge remote-tracking branch 'origin/master' into release-0-44 2017-05-04 21:23:18 -07:00
Robbie Trencheny
12910de9ae Merge pull request #7289 from jminardi/jminardi/tplink-logout
Log out of TP-Link router after devices are recorded.
2017-05-04 18:47:25 -07:00
Robbie Trencheny
2f686124c8 Merge pull request #7446 from amelchio/lifx-misc
LIFX: small error corrections
2017-05-04 18:45:14 -07:00
Robbie Trencheny
b59ca034ae Merge pull request #7393 from cribbstechnologies/dev
MQTT Cover: Fixed status reporting for range with non-zero base
2017-05-04 18:32:24 -07:00
Anders Melchiorsen
78a3f259d6 LIFX: handle unavailable lights gracefully
Recent aiolifx allow sending messages to unregistered devices (as a
no-op). This is handy because bulbs can disappear anytime we yield and
constantly testing for availability is both error-prone and annoying.

So keep the aiolifx device around until a new one registers on the same
mac_addr.
2017-05-04 22:51:00 +02:00
William Scanlon
1d0acb5a2c Get new token to keep pubnub updates working (#7437) 2017-05-04 13:17:35 -07:00
Daniel Perna
ea36c91919 Fix for broken virtual keys (#7439) 2017-05-04 13:15:36 -07:00
Greg Dowling
1d9f1487c3 Bump pyvera version - handle malformed json replies in poll thread. (#7440) 2017-05-04 13:14:36 -07:00
Nolan Gilley
d251621f2b Update join (#7443)
* update python-join-api to 0.0.2

* bump python-join-api to 0.0.2
2017-05-04 13:14:14 -07:00
William Scanlon
8d50045971 Suppress logs when octorpint goes offline (#7441)
* Suppress logs when octorpint goes offline

* Fixed line length
2017-05-04 13:13:09 -07:00
Philipp Schmitt
cc0299d046 Replace pymailgun with pymailgunner (#7436)
* mailgun: Replace pymailgun with pymailgunner

* Fix imports
2017-05-04 20:34:00 +03:00
Pascal Vizeli
7e539a3cb2 Add support for face recognition with dlib (#7421)
* Add support for face recognition with dlib

* fix lint

* fix lint p2

* update library

* dlib can not build

* fix lint

* Fix int p1

* Update dlib_face_detect.py

* Update dlib_face_detect.py

* Update dlib_face_detect.py
2017-05-04 16:03:50 +02:00
deisi
e3bb45c906 Added osramlightify groups. (#7376)
* Added osramlighrify groups.

Allows you to make use of the build in osram lightify groups. Group states get
handeled similar as in the case of phillips hue. A lightify group shows up as
light in the homeassistant webinterface. If one light of the
group is on, the complete group is considered to be on.

To use this feature, first define some groups within your lighrify bridge, then
set add `allow_lightify_groups=true` to you osramlightify config.

It might look like:
````yaml
- platform: osramlightify
  host: IP-ADDRES
  allow_lightify_groups: true
```

* Fixed Pylint errors.

* Included requests.

* Included more requests.

* Fixed setup bridge and removed _light attribute.

* Update osramlightify.py
2017-05-03 23:11:27 -07:00
Gergely Imreh
df13352989 Add new sensor: Enviro pHAT (#7427)
* Add new sensor: Enviro pHAT

Add support for the Enviro pHAT for Raspberry Pi, see hardware
info at https://shop.pimoroni.com/products/enviro-phat

* Move update to add_devices call
2017-05-03 22:59:50 -07:00
Nolan Gilley
05a3c463bf update for pypi (#7430) 2017-05-04 07:48:43 +02:00
Fabian Affolter
c44ebbefc4 Upgrade temperusb to 1.5.3 (#7428) 2017-05-04 07:46:43 +02:00
Paulus Schoutsen
fab533de87 ps - fix websocket yielding pt2 (#7434) 2017-05-03 21:12:08 -07:00
Paulus Schoutsen
ad5a9bf5ac wsock.send_json is a coroutine (#7433) 2017-05-03 20:27:03 -07:00
Paulus Schoutsen
c5a91393e4 Guard against no content type (#7432) 2017-05-03 20:12:51 -07:00
Anders Melchiorsen
494a776959 LIFX: avoid warnings about already running updates
Forcing a refresh will log a warning if the periodic async_update happens
to be running already.

So let's do the refresh locally and remove the force_refresh.
2017-05-04 00:21:24 +02:00
Anders Melchiorsen
193270c4fb LIFX: Update aiolifx requirement
This update silences some warnings (frawau/aiolifx#7).
2017-05-04 00:21:24 +02:00
Anders Melchiorsen
ec490070ca LIFX: Move random hue initial color to the LIFXEffect base class
It's a reasonable default for several light effects.
2017-05-04 00:21:24 +02:00
Anders Melchiorsen
8233f086cd LIFX: Use 3500K as neutral white
This does not really matter because the colorloop uses saturated colors
(without much white). Anyway, just copy the 3500K that the LIFX app uses.
2017-05-04 00:21:24 +02:00
Anders Melchiorsen
99e34539b9 LIFX: fix color restore after running effects
State restoration takes up to a second because bulbs can be slow to react.
During this time an effect could keep running, overwriting the state that we
were trying to restore.

Now the effect forgets the light immediately and it thus avoids further
changes while the restored state settles.
2017-05-04 00:21:24 +02:00
Anders Melchiorsen
71d909483c LIFX: refresh state after stopping an effect
This clears the internal cache in case polling picked up the state as set by
an effect.

For example, aborting an effect by selecting a new brightness could keep a
color set by the effect.
2017-05-04 00:21:24 +02:00
Anders Melchiorsen
dbd6f7e4ed Reverse limitlessled color_temp range (#7359)
Reverse limitlessled color_temp range
2017-05-03 23:32:49 +02:00
Andrey
403a721e91 Comment out opencv-python that is not installable on arm (#7426)
* Comment out opencv-python that is not installable on arm

* Disable import-error
2017-05-03 21:08:21 +03:00
Paulus Schoutsen
af5439860f Update opencv.py 2017-05-03 08:29:17 -07:00
Paulus Schoutsen
0f94c8a2e7 ps - fix opencv (#7419)
* ps - fix opencv

* fix lint
2017-05-03 12:15:04 +02:00
Fabian Affolter
203f48cadc Update docstrings (#7420) 2017-05-03 10:11:39 +02:00
Luar Roji
1a74c41056 Fixed extra R in variable name. (#7418) 2017-05-03 08:32:19 +02:00
Teagan Glenn
b321e0ef80 Opencv (#7261)
* OpenCV

* Fix

* Type-o

* Remove unused opencv camera component discovery.
2017-05-02 21:55:51 -07:00
Gergely Imreh
70ad06d71c light.piglow update (#7408)
* light.piglow: brightness control logic update

Do not reset brightness when brightness is not explicitly supplied.
Based on conversation at:
https://github.com/home-assistant/home-assistant/pull/7377#discussion_r114102005

* light.piglow: add assumed state
2017-05-02 21:21:37 -07:00
Adam Mills
c35d09d5f0 Convert automatic device tracker to push updates (#7404)
* Convert automatic device tracker to push updates

* Update test

* Add to coveragerc

* Fire hass events when automatic update received

* Change brace indentation
2017-05-02 21:21:17 -07:00
Henrik Nicolaisen
f389266f5f remove charset if set in content type header (#7411)
* remove charset if set in content type header like this “Content-Type: image/jpeg;charset=UTF-8”

* fixed lint error
2017-05-02 21:19:16 -07:00
wokar
f9627a5646 applx suggested fix from issue #6573 (#7390) 2017-05-02 21:04:00 -07:00
zeltom
517bd39015 Pilight binary sensor components (#6774)
* Add files via upload

Pilight binary sensor components.

* Pep8 fixed

* Remove unused imports

* Remove STATE_UNKNOWN import

* Grouping import

* New import grouping

* Update pilight.py

* Update pilight.py

* Update pilight.py

* Prevent multiple timer call

* Update .coveragerc

* Fix alphabet ordre

* Fix & clean code (change payload comparaison, delete state function)

* Fix payload comparison and remove state methode

* Fix unused import, whitespaces

* Fix ident error
2017-05-02 20:48:49 -07:00
Andrey
11dc7246af Add Sensibo climate platform (#7379)
* Add Sensibo climate platform

* Force update after running a service

* Add sensibo to .coveragerc

* Use 10s timeout

* Fix schema. Remove print.

* Better handle unit conversions.
2017-05-02 17:23:36 -07:00
Gergely Imreh
8654993b18 light.sensehat: brightness control logic update (#7409)
Do not reset brightness when brightness is not explicitly supplied.
Based on conversation at:
https://github.com/home-assistant/home-assistant/pull/7377#discussion_r114102005
2017-05-02 17:02:13 -07:00
Anders Melchiorsen
1aa3ab52b7 LIFX: Add transition option to colorloop effect (#7410)
This allows for more of a disco mode where lights change so fast that you
actually notice it.

Also change the valid period to the maximum 20 msgs/sec that LIFX bulbs
can handle.
2017-05-03 00:41:43 +02:00
Anders Melchiorsen
d68f59ca6c Update LIFX default color for breathe/pulse effects (#7407)
First, move the default away from turn_on so we do not have to test for
the current service.

Next, change the default color away from random. The new default is that
saturated colors will flash white and desatured colors will flash to their
fully satured color. Always with full brightness.

After many experiments, this was the method that best produced results that
are both visually pleasing and always noticeable as a flash.
2017-05-03 00:05:11 +02:00
Fabian Affolter
4d52b0ecd5 Update docstrings (#7405)
* Update docstrings

* Fix lint issues

* Update docstrings
2017-05-02 22:47:20 +02:00
Brian Cribbs
1b2c83145c fixing nits 2017-05-02 15:41:45 -04:00
Gergely Imreh
12c8266942 light.blinkt: update brightness control logic (#7389)
Always use the current brightness, as per discussion at
https://github.com/home-assistant/home-assistant/pull/7377#discussion_r114102005
2017-05-02 18:35:23 +02:00
Fabian Affolter
a4f1f6e724 Update docstrings (#7374)
* Update docstrings

* Update docstrings

* Update docstrings

* Update docstrings

* Update docstrings

* Update docstrings

* Update docstring

* Update docstrings

* Update docstrings

* Fix lint issues

* Update docstrings

* Revert changes in dict
2017-05-02 09:18:47 -07:00
amigian74
0e08925259 correct MQTT subscription filter (#7269)
* correct MQTT subscription filter

* wildcard handling (#) fixed

* wildcard handling (#) fixed

* added tests for topic subscription like +/something/#

* function names changed (line too long)

* using raw strings for regular expression
import order changed
2017-05-02 09:18:34 -07:00
Andrey
570c5549a9 Clean up requirements (#7391) 2017-05-02 09:15:02 -07:00
Scott Bradshaw
f4f06af0c5 OpenGarage support (#7338)
* OpenGarage.io support

Cleaned up component and ran lint checking

* Fixing lint errors

* Added supported_features and device_class

* Added timeout to HTTP Requests and other changes based on feedback.

* Removed watcher. It provided little value and could cause issues if status was stuck in a state.

* Changes based on feedback. Added error checking for invalid device_key.

* Lint
2017-05-02 08:46:56 -07:00
John Mihalic
752a4b958e Add Eight sleep component (#7275)
* Eight Sleep Implementation

* Update coverage

* Update hass requirements

* Remove unnecessary debug statements

* Bump version to fix date error

* Address comments

* Update requirements
2017-05-02 08:38:27 -07:00
Paulus Schoutsen
350a6fd5fa Lint 2017-05-02 07:47:02 -07:00
Paulus Schoutsen
f17c1090e1 Remove path whitelisting for hassio (#7399)
* Remove path whitelisting for hassio

* Update frontend

* Lint
2017-05-02 00:27:50 -07:00
Paulus Schoutsen
8ea6c7319a Migrate updater to aiohttp (#7387)
* Migrate updater to aiohttp

* Fix tests

* Update updater.py

* Docs
2017-05-01 23:29:01 -07:00
Paulus Schoutsen
da2521a299 Fix YAML dump (#7388)
* Fix YAML dump

* Add test
2017-05-01 20:09:49 -07:00
Brian Cribbs
098e28534b fixing documentation 2017-05-01 13:34:34 -04:00
Brian Cribbs
dc716cd971 repairing functionality for non-zero based ranges 2017-05-01 13:22:54 -04:00
Jack Minardi
7a24e210ae Try again to pass string to error msg 2017-05-01 09:31:23 -04:00
Daniel Perna
fafd0d4e4c Fix impulse events, added error event for Homegear (#7349)
* Fix impulse event, added error event

* Requested changes
2017-05-01 06:37:00 +02:00
Robbie Trencheny
8ba7e61ed6 Merge pull request #7385 from robbiet480/dont-validate-ios-identify
Disable iOS device identify schema validation for now
2017-04-30 20:11:21 -07:00
Alok Saboo
86cfc2a0ed Updated docstrings (#7383)
* Updated docstrings

* Updated docstrings

* Updated docstrings

* Update docstrings

* Update more docstrings
2017-04-30 20:10:08 -07:00
Marcelo Moreira de Mello
6aac53399d Upgrade Ring to 0.1.4 (#7386) 2017-04-30 20:08:14 -07:00
Jack Minardi
bc0559813c Dont add two strings inside logger call 2017-04-30 22:26:16 -04:00
Jack Minardi
dd7690f265 Use % formatting 2017-04-30 21:31:55 -04:00
Jack Minardi
b6827ce57a Use throwaray variable name 2017-04-30 21:02:03 -04:00
Robbie Trencheny
ae93cf702a Merge pull request #7347 from cribbstechnologies/dev
Adding tilt functionality for MQTT cover
2017-04-30 15:56:45 -07:00
Robbie Trencheny
ecf511ff35 Remove unused dependency 2017-04-30 15:55:34 -07:00
Robbie Trencheny
87ef26be22 Disable identify schema validation for now 2017-04-30 15:23:49 -07:00
Brian Cribbs
0fe0f1918a more requested changes 2017-04-30 16:33:29 -04:00
abmantis
c085f06df5 Add support for shuffle toggling on Spotify component. (#7339)
* add support for shuffle toggling on Spotify component.

	this also required adding support for shuffle on the
	media_player component.

* lint

* Use ATTR_MEDIA_SHUFFLING for service handler param

* Line too long fix

* fix tests

* add shuffle set to demo mediaplayer

* rename shuffle attribute
2017-04-30 12:41:21 -07:00
ChristianKuehnel
5d7403bd81 Plant (replacement for MiGardener) (#7131)
* new implementation without mqtt

* fixed lint findings

* fixed more lint findings

* fixed final flak8 error

* added unit tests for platform "plant"

* - changed status to "OK" / "problem"
- added attribute "problem" with details on the problems
- removed unused constant
- setting icon to "?" until we have meaningful data

* reformatted code to meet line length requirements
2017-04-30 12:32:32 -07:00
Wojciech Bederski
c14b829f27 improve handling of flux_led lights in RGBW mode (#7221)
allows simultaneous control of both RGB and White
channels.
2017-04-30 12:03:03 -07:00
Gergely Imreh
f20a81d0c5 light.blinkt: add support for Blinkt! lights on Raspberry Pi (#7377) 2017-04-30 11:48:54 -07:00
Paulus Schoutsen
9afbbbf3fe Remove ordered_dict validator (#7375)
* Remove ordered_dict validator

* Lint

* Update test_config_validation.py
2017-04-30 10:55:03 -07:00
Fabian Affolter
1f4f2d7086 Upgrade voluptuous to 0.10.5 (#7107)
* Upgrade voluptuous to 0.10.5

* Fix tests
2017-04-30 00:42:19 -07:00
Dan Ports
7ff1ded0b5 binary_sensor.workday: fix handling of states vs provinces (#7162)
* binary_sensor.workday: fix handling of states vs provinces

* Add test cases for workday sensor with states

* remove redundant assignment

* Repair unit test to improve coverage

Patch from Wolf-Bastian Pöttner

* Fix handling of invalid states/provinces

* fix indentation to satisfy pylint
2017-04-30 00:31:46 -07:00
Henrik Nicolaisen
8df5de2bb8 optimize remote calls and apps on webostv media_player (#7191)
* - changed updater to only do updated if they succed and handle calls when tv is off better by only doing 1 remote call
- show all sources instead of only connected, to fix source selection when unit is powered off
- fixed sources so they can launch apps and select sources

* fixed lint errors

* show all sources and apps if no custom options are defined in the conf

* fixed indentation for lint

* set _current_source when state is off and fixed timeout exception
2017-04-30 00:30:37 -07:00
Brent Hughes
955e3e0542 Zoneminder: Fixed undefined index error (#7340)
* Zoneminder: Fixed undefined index error

* Add Pascal's correct fix.
2017-04-30 00:18:00 -07:00
Anders Melchiorsen
9f68fd9184 Flux switch: avoid updates when off (#7363)
* Flux switch: avoid updates when off

Calling turn_on when the switch is already on would orphan the existing
time tracker, losing our ability to cancel it when turn_off is called.

* Cleanups

The self.is_on property can now be found from self.unsub_tracker, so
get rid of the self._state attribute.

Add an entry guard to turn_on, making further conditionals unnecessary.
2017-04-30 00:05:29 -07:00
Paulus Schoutsen
85b7433bc4 Update sensehat.py 2017-04-29 22:42:12 -07:00
Fabian Affolter
3ee4d1060f Update docstrings (#7361)
* Update docstrings

* Update docstrings

* Update docstrings

* Update docstrings

* update docstrings

* Update docstrings

* Update docstrings

* Update docstrings

* Update docstrings

* Update docstrings

* Update tomato.py

* Update isy994.py

* Lint + fix tests

* Lint
2017-04-29 22:04:49 -07:00
Paulus Schoutsen
e22e70a01a Update sensehat.py 2017-04-29 21:40:10 -07:00
Paulus Schoutsen
cf664e42cc Add assumed state to sensehat light. 2017-04-29 21:39:27 -07:00
Gergely Imreh
b815ccc3b8 light.sensehat: plugin to control the 8x8 LED matrix on a Sense hat (#7365)
* light.sensehat: adding plugin to control the 8x8 LED matrix on a Sense Hat

* add new .coveragerc entry

* light.sensehat: formatting and removing unused import

* light.sensehat: add to requirements list

* light.sensehat: update docstrings to the linter's specs

* light.sensehat: add a bit more docstring
2017-04-29 21:34:31 -07:00
onsmam
7b1e948e8d Create knx.py (#7356)
* Create knx.py

light device for the knx component

* Fix doc strings
2017-04-29 21:20:46 -07:00
Jason Carter
607394a0a0 Netdisco now returns a dictionary while it used to be a tuple, fixed (#7350) 2017-04-29 20:54:45 -07:00
LvivEchoes
e4ebae55d5 Feature/add mikrotik device tracker (#7366)
* Add Mikroik device tracker platform

* Update coveragerc with mikrotik.py

* Update coveragerc with mikrotik.py

* Fix lint errors
2017-04-29 20:39:11 -07:00
Paulus Schoutsen
ce3d8be72b Remove binary sensor platforms implementing state property (#7371)
* Remove binary sensor platforms implementing state property

* Fix workday inheritance
2017-04-29 20:36:50 -07:00
Brian Cribbs
a1be80d5d4 added optimistic configuration for tilt state 2017-04-29 19:27:19 -04:00
Brian Cribbs
dc3706523a I was thinking *far* too hard about this 2017-04-29 19:19:24 -04:00
Paulus Schoutsen
55731b759f Fix lint 2017-04-29 15:47:21 -07:00
Paulus Schoutsen
064b2cdb9f Remove state property from alarmdecoder binary sensor (#7370) 2017-04-29 15:12:18 -07:00
Anders Melchiorsen
64a7be66b1 Remove global limit on white light temperature (#7206)
* Remove global limit on white light temperature

Here are the supported temperatures of some popular bulbs:

 Philips Hue: 2000K-6500K (the current 500-154 mired range)
 LIFX Color 1000: 2500K-9000K
 IKEA TRÅDFRI: 2200K, 2700K, 4000K

Obviously, Home Assistant cannot enforce a global limit and work properly
with all of these bulbs. So just remove the limit and leave it up to each
platform to work it out.

This commit updates the existing users and adds a clamp to Hue (where the
limit appears to have originated). It does not attempt to update other
platforms that might need extra handling of the larger range that is now
possible.

* Add min_mireds/max_mireds state attributes to lights

* Support min_mireds/max_mireds with LIFX lights
2017-04-29 15:04:20 -07:00
Fabian Affolter
ae9f44c708 Upgrade speedtest-cli to 1.0.6 (#7354) 2017-04-30 00:00:04 +02:00
Fabian Affolter
74362df19c Upgrade xmltodict to 0.11.0 (#7355) 2017-04-29 23:59:38 +02:00
Greg Dowling
d8afea64af Add debug logging to pyvera events. (#7364) 2017-04-29 17:19:22 +01:00
Daniel Høyer Iversen
b853fb2178 Upgrade Flux led lb to 0.19 (#7352) 2017-04-29 07:46:34 +02:00
Brian Cribbs
5b22e57643 some changes requested on PR 2017-04-28 21:41:50 -04:00
Brian Cribbs
88782fa90a added coroutine annotation to async method 2017-04-28 16:32:06 -04:00
Brian Cribbs
4c06cca3e1 left trailing whitespace 2017-04-28 13:58:01 -04:00
Brian Cribbs
d3042a8199 forgot to remove constructor arg 2017-04-28 13:57:13 -04:00
Brian Cribbs
e61c1ffbc2 fixing hound violations 2017-04-28 13:25:15 -04:00
Brian Cribbs
6cfc1b6af8 removing unnecessary payload value for tilt 2017-04-28 13:15:05 -04:00
Brian Cribbs
c120c47bc1 style changes 2017-04-28 12:14:17 -04:00
Brian Cribbs
44dbf2678b adding tests to cover new functionality 2017-04-28 11:32:42 -04:00
Brian Cribbs
bbe8b2019b style/lint updates 2017-04-28 10:45:32 -04:00
Fabian Affolter
f9c9b3c1b8 Multiple changes (typo, ordering, docstrings, timeouts) (#7343)
* Multiple changes (typo, ordering, docstrings, timeouts)

* Remove debug output

* Catch exception

* Separate URL
2017-04-28 13:25:39 +02:00
Robbie Trencheny
9dd28ac18f Properly return self._unit_of_measurement in the unit_of_measurement function (#7341)
Add an optional extended description…
2017-04-28 12:26:17 +02:00
Thibault Cohen
8114c45b3d Add auxheat to ecobee climate (#6562)
* Add auxheat to ecobee

* Add is_aux_heat_on property in ecobee climate
2017-04-28 11:52:48 +02:00
Anders Melchiorsen
89164d0244 Allow multiple recipients for SMTP notify (#7319)
The existing (singular) configuration keyword is kept for compatibility.
2017-04-28 11:29:30 +02:00
Brian Cribbs
79e134b076 removing accidentally added file 2017-04-27 23:43:54 -04:00
Brian Cribbs
630516f309 slider and tilt open/close seem to work 2017-04-27 23:42:50 -04:00
Paulus Schoutsen
6902e522b9 Merge pull request #7335 from home-assistant/release-0-43-2
0.43.2
2017-04-27 12:42:25 -07:00
Fabian Affolter
0298522fd5 Use four-digits year (#7336) 2017-04-27 09:30:34 -07:00
Paulus Schoutsen
6750e33525 Right fix for Python Open Z-Wave in Docker (#7337) 2017-04-27 09:28:40 -07:00
Paulus Schoutsen
9a67111a0f Right fix for Python Open Z-Wave in Docker (#7337) 2017-04-27 09:28:08 -07:00
Paulus Schoutsen
e6a690558b Fix breaking SSL in test HTML5 (#7310) 2017-04-27 09:27:31 -07:00
Adam Mills
a3bc559fa3 Version bump for automatic (#7329) 2017-04-27 09:05:58 -07:00
Adam Mills
3a1072a158 Version bump of aioautomatic (#7300)
* Version bump of aioautomatic

* Update requirements_all.txt
2017-04-27 09:05:58 -07:00
Paulus Schoutsen
0841bf8529 Update frontend (#7324)
* Initial version of hassio panel

* Update frontend
2017-04-27 09:03:54 -07:00
Fabian Affolter
2b82c222b0 Upgrade python-telegram-bot to 5.3.1 (#7311) 2017-04-27 09:03:46 -07:00
Paulus Schoutsen
d966129fd8 Upgrade pytradfri to 1.1 (#7290) 2017-04-27 09:03:25 -07:00
Paulus Schoutsen
84752b3b13 Hassio api v3 (#7323)
* HassIO rest API v3

* fix content type

* fix lint

* Update comment

* fix content type

* change proxy handling

* fix handling

* fix register

* fix addons

* fix routing

* Update hassio to just proxy

* Fix tests

* Lint
2017-04-27 09:02:43 -07:00
Pascal Vizeli
3735c2e761 Fix HassIO bug with supervisor update & log (#7282) 2017-04-27 09:02:43 -07:00
Pascal Vizeli
9fc89ba744 WIP: HassIO allow to access to container logs. (#7271)
* HassIO allow to access to container logs.

* Add unittest & make a fixture for env

* Add unittest to check if no env exists

* Fix lint
2017-04-27 09:02:43 -07:00
Paulus Schoutsen
f7603a421f Version bump to 0.43.2 2017-04-27 09:02:08 -07:00
Adam Mills
6631e9e939 Version bump for automatic (#7329) 2017-04-27 08:01:30 -04:00
Paulus Schoutsen
3e4e84e3a7 Re-enable Open Z-Wave in Dockerfile (#7325)
Turbo fixed it in #7316
2017-04-27 01:02:14 -07:00
John Arild Berentsen
ce63bb0842 Fix broken docker build (#7316)
* Fix broken docker build

python3 branch

* Update python_openzwave
2017-04-27 01:00:07 -07:00
Anders Melchiorsen
d1121478ab Reduce color_xy_brightness_to_hsv to color_xy_to_hs (#7320)
This makes more sense because the input and output brightness is the same.

We currently convert through RGB which does contain a brightness so we supply
an arbitrary value as input and discard the output.
2017-04-27 00:59:49 -07:00
Paulus Schoutsen
9527390736 Update frontend (#7324)
* Initial version of hassio panel

* Update frontend
2017-04-27 00:57:40 -07:00
Paulus Schoutsen
a732271793 HassIO API fix 2017-04-26 23:24:02 -07:00
Paulus Schoutsen
b532267596 HassIO API fix 2017-04-26 23:23:18 -07:00
Paulus Schoutsen
b14c07a60c Hassio api v3 (#7323)
* HassIO rest API v3

* fix content type

* fix lint

* Update comment

* fix content type

* change proxy handling

* fix handling

* fix register

* fix addons

* fix routing

* Update hassio to just proxy

* Fix tests

* Lint
2017-04-26 22:36:48 -07:00
Jan Losinski
3374169c74 Allow InfluxDB to blacklist domains (#7264)
* Allow InfluxDB to blacklist domains

This adds an option to InfluxDB to blacklist whole domains. This is
useful for domains like automation or script, where no statistic data
is needed.

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

* Add unittest for InfluxDB domain blacklist

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

* Use common include/exclude config for InfluxDB.

Its now the same syntax as it is for recorder.

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

* Add unittests for InfluxDB include whitelist.

There where no tests for that feature before.

Signed-off-by: Jan Losinski <losinski@wh2.tu-dresden.de>
2017-04-26 21:14:52 +02:00
Anders Melchiorsen
ffb8872f95 LIFX: use white light when setting a specific temperature (#7256)
* Default to white when setting LIFX temperature

Changing the temperature of a saturated color is possible but not very
interesting. So assume that a change of the temperature implies setting
the color to white, unless a different color is actually specified.

This makes the frontend temperature picker much more useful because it can
now be used to get away from a colored light.

* Default to a neutral white temperature when setting LIFX colors

This means that setting a particular color will always give the same output,
no matter what the temperature was previously at.

* Find brightness after colors

Now the color_temp logic will not see a changed color when setting
temperature+brightness and thus we will actually get a white light in
this situation.

The XY conversion can then not use brightness as input. This is not
an issue because XY only affects hue and saturation, not brightness. So
we can just use an arbitrary value as brightness input.

* Add a simple comment to a complex conditional
2017-04-26 17:21:14 +02:00
Paulus Schoutsen
d2fb4675e1 Disable Open Z-Wave in Docker (#7315) 2017-04-26 07:37:05 -07:00
Fabian Affolter
569ea0cc01 Upgrade python-telegram-bot to 5.3.1 (#7311) 2017-04-26 10:50:08 +02:00
Adam Mills
00f034cef2 Version bump of aioautomatic (#7300)
* Version bump of aioautomatic

* Update requirements_all.txt
2017-04-25 20:21:16 -07:00
Henrik Nicolaisen
615691efc3 Issue 7218 update pylgtv to 0.1.7 (#7302)
* update pylgtv module to 0.1.7

* update pylgtv to 0.1.7 requirements
2017-04-25 20:20:54 -07:00
Daniel Perna
760d2f1f0a Upgrade pyhomematic, extend device support (#7303) 2017-04-25 20:20:10 -07:00
Paulus Schoutsen
8bb952e416 Fix breaking SSL in test HTML5 (#7310) 2017-04-25 20:18:23 -07:00
Fabian Affolter
f29e0bf53e Don't stack up error messages, fix link, and ordering (#7291) 2017-04-25 12:40:13 +02:00
Alan Fischer
28aab33cd1 Added scene controller support to the vera component, along with proper polling when a vera device needs it (#7234)
Add an optional extended description…
2017-04-25 09:17:25 +02:00
Russell Cloran
d79f89e168 Add support for Zigbee Home Automation (#6263)
* Add support for Zigbee Home Automation

* Fewer magic numbers

* Make optional device config work

* Remove non-zha device_tracker stuff

* Always return boolean from is_on

* Only pass through JSON serializable discovery_info

* Update to bellows 0.2.4

* Fewer magic numbers in binary sensor

* Populate const structures from a function

* Update bellows to 0.2.6

* Fewer magic numbers in light

* Take all possible clusters when overriding

* Update bellows to 0.2.7
2017-04-24 22:24:57 -07:00
micw
699cc7213d Feature/rss feed template (#7032)
* rss_feed_template initial checking

* lint

* Remove use of deprecated cgi-escape()

* Switching back to chardet==2.3 (resolve failing tests with 3.0)

* Code and test improvments

* Option 'requires_api_password', default is True
2017-04-24 22:16:47 -07:00
Ron Klinkien
f65d8e1254 Adding group control to tradfri light component (#7248)
* Added initial support for tradfri group control

* Tried to keep original variable structure

* pylint and pep8 fixes

* Fixed lint error about docstring

* Removed unneeded stuff, renamed _light. Needs to be released pytradfri version.

* Better naming of variables inside add_devices call.
2017-04-24 21:57:38 -07:00
Paulus Schoutsen
fb297981af Upgrade pytradfri to 1.1 (#7290) 2017-04-24 21:57:27 -07:00
Jack Minardi
8bf1c21738 Add space 2017-04-25 00:48:23 -04:00
Jack Minardi
943861a8a3 Remove unused var 2017-04-25 00:45:59 -04:00
Jack Minardi
450fd7f2b5 Log out of router admin interface after devices are recorded. 2017-04-25 00:34:26 -04:00
Jack Minardi
2d5da3e958 Catch KeyError; Add response.text to error message 2017-04-25 00:32:31 -04:00
Paulus Schoutsen
66a63b983e Merge branch 'master' into dev 2017-04-24 21:10:03 -07:00
Paulus Schoutsen
335362ffc4 Recorder: Check for ENTITY_ID key that contains None value (#7287) 2017-04-24 20:51:03 -07:00
Keaton Taylor
17bdb9558a Fixes utf-8 encoding no longer required by python-openzwave0.3.3 (#7266)
* Fixes utf-8 encoding no longer required by libopenzwave0.3.3

Removes byte encoding for values operation mode, fan mode and swing
mode.

* Fix zwave climate tests for utf-8 change
2017-04-24 17:59:51 -07:00
Patrick Easters
9738bffc3f Updating ping binary sensor with Windows support (#7253)
Fixed ping command syntax and updated regex match
2017-04-24 23:32:12 +02:00
Pascal Vizeli
f58d200ecb Fix HassIO bug with supervisor update & log (#7282) 2017-04-24 23:22:40 +02:00
Jan Losinski
215987d5a7 Add script to import state events to InfluxDB (#7254)
* Add script to import state events to InfluxDB

This adds a script to import recorded events from a recorder database
to a InfluxDB instance. This can be useful for initial importing after
setup of a InfluxDB.

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

* Fix step argument handling in Influx import

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

* Correct typo in InfluxDB Importer

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

* Update influxdb_import.py
2017-04-24 23:01:09 +02:00
Nils Uliczka
16227704d7 Fix telegram_polling no first_name or last_name (#7281)
* Default to 'N/A' if sender has no first_name or last_name

* Fixed as requested
2017-04-24 22:08:06 +02:00
Fabrizio Furnari
aad375b713 Add https certificate expiry sensor (#7272)
* fixing rebase issues

* cert_expiry: added .coveragerc entry

* cert_expiry: renamed to SCAN_INTERVAL, removed Throttle

* cert_expiry: better socket exception management

* cert_expiry: splitted line too long

* Update cert_expiry.py

* Fix hass style
2017-04-24 22:01:00 +02:00
LvivEchoes
104d372dfa Add support for Ukrainian Language in Google TTS (#7278) 2017-04-24 21:43:56 +02:00
Stuart Mumford
7960206e2e Refactor matrix notify service (#7122)
* Refactor matrix notify service.

This refactor aims to close #6118 by making the save / restore of the
authentication tokens much more resilient to failure.

It also refactors the module so that all the functionality is part of the class
and that a login failure causes the service to fail on setup rather than at
message send time.

* Make the linter overlords happy

* Improve logger levels and messages

* small style change

* Fix indentation issue
2017-04-24 21:43:02 +02:00
Anders Melchiorsen
4f5ec3e360 Update aiolifx (#7279)
This contains a fix for TypeError bug seen only with LIFX Z.
2017-04-24 21:09:14 +02:00
Pascal Vizeli
ead457f312 WIP: HassIO allow to access to container logs. (#7271)
* HassIO allow to access to container logs.

* Add unittest & make a fixture for env

* Add unittest to check if no env exists

* Fix lint
2017-04-24 15:16:28 +02:00
Daniel Høyer Iversen
575f57a24e Rfxtrx upgrade lib 0.18 (#7273) 2017-04-24 13:42:26 +02:00
Klaas Hoekema
64da8cd47d Work around bad content-type in Hook api response (#7267) 2017-04-23 23:58:17 -07:00
Martin Hjelmare
0e662c4007 Fix telegram webhooks (#7236)
* Always register the view if a webhook exists.
* Return True if platform is set up succesfully, False otherwise.
* Remove the webhook when home assistant stops. Webhooks and long
  polling are mutually excklusive. If a webhook is left after home
  assistant is stopped, a polling telegram bot is unable to be set up,
  on next start of home assistant.
2017-04-23 23:20:04 -07:00
Greg Dowling
6a8a656fef Workround for wemo subscription bug. (#7245) 2017-04-23 23:18:43 -07:00
Fabian Affolter
cfc023e128 Don't use len(SEQUENCE) as condition value (#7249)
* Don't use len(SEQUENCE) as condition value

* Update volvooncall.py
2017-04-23 20:41:09 -07:00
Fabian Affolter
15b2473224 Iterating the dictionary directly (#7251) 2017-04-23 20:16:52 -07:00
clayton craft
48eeb55198 Add notice regarding submission of analytics (#7263) 2017-04-23 19:59:26 -07:00
Oliver
4cd024d91e Pushed to version 0.4.0 of denonavr which also includes experimental support for Marantz receivers (#7250) 2017-04-23 21:00:00 +02:00
Fabian Affolter
fa4a912a86 Use consts and string formatting (#7243) 2017-04-23 13:54:39 +02:00
Fabian Affolter
209da6f338 Upgrade aiohttp_cors to 0.5.3 (#7213) 2017-04-23 09:25:58 +02:00
Fabian Affolter
ec5e9fcd0d Upgrade paho-mqtt to 1.2.3 (#7214) 2017-04-23 09:25:34 +02:00
Fabian Affolter
e9eb7edda6 Upgrade speedtest-cli to 1.0.5 (#7215) 2017-04-23 09:25:11 +02:00
Fabian Affolter
b60b06a062 Upgrade mutagen to 1.37.0 (#7216) 2017-04-23 09:24:53 +02:00
Fabian Affolter
efe8b46576 Upgrade pygatt to 3.1.1 (#7220)
* Upgrade pygatt to 3.1.1

* Fix mess
2017-04-23 09:24:26 +02:00
Anders Melchiorsen
91b8eea6ad LIFX: avoid "Unable to remove unknown listener" warning (#7235)
Forget the cancelled update handler so it is not cancelled a second time
later on (if when <= BULB_LATENCY) and thus invoking the warning.
2017-04-23 09:24:08 +02:00
Adam Mills
b6a4a0d9af Refactor lyft sensor update (#7233) 2017-04-23 09:23:00 +02:00
Matthew Garrett
7b3cc9fe1f Bump a couple of dependencies (#7231)
* avion light: Bump python-avion dependency version

The dependencies in python-avion weren't sufficiently strict. This is now
fixed, but means we need to depend on a new version.

* decora light: Bump python-decora dependency

There's a new version of python-decora with a reliability fix, so depend on
that.
2017-04-23 09:20:58 +02:00
Dan Ports
2c39038507 lyft sensor: re-enable Prime Time rate attribute (#6982)
Turns out this does work correctly even without a user login
(assuming that sandbox mode is disabled)
2017-04-22 21:16:06 +02:00
Fabian Affolter
5bfe5b3f70 Remove superfluous comments and update ordering (#7227)
* Remove superfluous comments and update ordering

* Fix pylint issues
2017-04-22 21:13:04 +02:00
Alok Saboo
d229787fa6 Fixed typo and clarified details for Lifx effects (#7226)
* Fixed typo

* Update services.yaml

* Clarified service details for Lifx effects
2017-04-22 20:43:17 +02:00
John Arild Berentsen
1836c7a358 Zwave cover workaround for graber shades. (#7204)
* wierd pylint complaint

* Workaround for Graber csz1 shades

* logging

* Try direct

* Try direct

* Use workaround

* Review changes and tests

* test

* reset test

* Use Bright and Dim also as open and close is
2017-04-22 16:23:39 +02:00
Joakim af Sandeberg
1b83ce8759 Pushbullet notification sensor (#7182)
* Added the pushbullet sensor component

* Updated requirements_all.txt and .coveragerc with the new sensor

* Updated acording to houndci-bots comments

* Some more changes

* Final change by the hound (?)

* Fixes from balloobs review and from houndci-bot

This changes the sensors information to only contain one attribute
as information, and the rest as device_state_attributes.

* Added leading space to comments

* Added docstrings, removed API_KEY from log, changed imports

* The hound is at it again

* Fix remaining issues

* Fix pylint issue
2017-04-22 14:01:30 +02:00
Fabian Affolter
8c72a57344 Bump version to 0.44.0.dev0 (#7217) 2017-04-22 11:52:24 +02:00
Martin Hjelmare
3f47bf6b77 Fix tradfri lights (#7212)
* Remove leftover use of slugify

* The IKEA manufacturer key is now exactly as found in device info.

* Fix bitwise addition of supported features
2017-04-22 00:31:23 -07:00
Paulus Schoutsen
40f480c24e tradfri: Improve color temp support detection (#7211) 2017-04-21 23:32:51 -07:00
Henrik Nicolaisen
8e716780b7 Issue 6749 updated pylgtv to 0.1.6 to fix thread leak in asyncio loop (#7199)
* updated pylgtv module to fix problems with timeouts

* - update pylgtv to 0.1.6
- handle new TimeoutError exception from pylgtv

* used full name for exception handling of concurrent.futures._base.TimeoutError

* the exception handling should now follow the rules

* float typecasting should not be necessary

* use asyncio for TimeoutError it’s an alias for concurrent.futures.TimeoutError
2017-04-21 20:24:21 -07:00
Sean Dague
b77b22b01a Fix arwn platform to update hass state when events are received (#7202)
The arwn platform was refactored to be asyncio friendly, however in
doing so one thing was missed which was explicitly telling hass when
something interesting has happened. This led to the very interesting
to debug issue that the state cards were all out of date, even though
the graphs were not.
2017-04-21 20:22:36 -07:00
Nikolas Beutler
1194690c42 Update ios.py (#7160)
* Update ios.py

as discussed. the part: 
       if battery_state == ios.ATTR_BATTERY_STATE_FULL:
            returning_icon_level = DEFAULT_ICON_LEVEL
kinda screws up the charging icon.

i might just miss a logical solution for that though.
let me know what you think. it might not be beautiful but i think its an overall improve over the current "double battery" solution

* Update ios.py

chound fix and full_battery_charge fix

* Update ios.py

removed new line

* Update ios.py

* Update ios.py

* Update ios.py

* Update ios.py

* Update ios.py

* Update ios.py

* merged request from robbie

* Update ios.py

* Update ios.py

* Update ios.py
2017-04-21 20:16:59 -07:00
Anders Melchiorsen
2657668a86 Support xy_color with LIFX lights (#7208) 2017-04-21 20:16:36 -07:00
Pierre Ståhl
f5dd25c87f Capture and log pip install error output (#7200)
Add an optional extended description…
2017-04-21 14:15:05 +02:00
Pascal Vizeli
0acc52b23b HassIO API v2 (#7201)
Add an optional extended description…
2017-04-21 12:20:19 +02:00
Anders Melchiorsen
d4b085081a LIFX light effects (#7145)
* Refactor into find_hsbk

This will be useful for new methods that also have to find passed in colors.

* Add AwaitAioLIFX

This encapsulates the callback and Event that aiolifx needs and thus avoids an
explosion of those when new calls are added.

The refresh_state is now generally useful, so move it into its own method.

* Initial effects support for LIFX

These effects are useful as notifications. They mimic the breathe and pulse
effects from the LIFX HTTP API:

    https://api.developer.lifx.com/docs/breathe-effect
    https://api.developer.lifx.com/docs/pulse-effect

However, this implementation runs locally with the LIFX LAN protocol.

* Saturate LIFX no color value

Now the color is "full saturation, no brightness". This avoids a lot of
temporary white when fading from the "no color" value and into a real color.

* Organize LIFX effects in classes

This is to move the setup/restore away from the actual effect, making it quite
simple to add additional effects.

* Stop running LIFX effects on conflicting service calls

Turning the light on/off or starting a new effect will now stop the running
effect.

* Present default LIFX effects as light.turn_on effects

This makes the effects (with default parameters) easily accessible from
the UI.

* Add LIFX colorloop effect

This cycles the HSV colors, so that is added as an internal way to set a
color.

* Move lifx to its own package and split effects into a separate file

* Always show LIFX light name in logs

The name is actually the easiest way to identify a bulb so just using it
as a fallback was a bit odd.

* Compact effect getter

* Always use full brightness for random flash color

This is a stopgap. When a bit more infrastructure is in place, the intention
is to turn the current hue some degrees. This will guarantee a flash color
that is both unlike the current color and unlike white.

* Clear effects concurrently

We have to wait for the bulbs, so let us wait for all of them at once.

* Add lifx_effect_stop

The colorloop effect is most impressive if run on many lights. Testing
this has revealed the need for an easy way to stop effects on all lights
and return to the initial state of each bulb. This new call does just that.

Calling turn_on/turn_off could also stop the effect but that would not
restore the initial state.

* Always calculate the initial effect color

To fade nicely from power off, the breathe effect needs to keep an
unchanging hue. So give up on using a static start color and just find the
correct hue from the target color.

The colorloop effect can start from anything but we use a random color
just to keep things a little interesting during power on.

* Fix lint

* Update .coveragerc
2017-04-20 22:46:12 -07:00
1155 changed files with 60106 additions and 18484 deletions

View File

@@ -8,18 +8,36 @@ omit =
homeassistant/helpers/signal.py
# omit pieces of code that rely on external devices being present
homeassistant/components/abode.py
homeassistant/components/*/abode.py
homeassistant/components/alarmdecoder.py
homeassistant/components/*/alarmdecoder.py
homeassistant/components/amcrest.py
homeassistant/components/*/amcrest.py
homeassistant/components/apcupsd.py
homeassistant/components/*/apcupsd.py
homeassistant/components/apple_tv.py
homeassistant/components/*/apple_tv.py
homeassistant/components/arduino.py
homeassistant/components/*/arduino.py
homeassistant/components/android_ip_webcam.py
homeassistant/components/*/android_ip_webcam.py
homeassistant/components/arlo.py
homeassistant/components/*/arlo.py
homeassistant/components/asterisk_mbox.py
homeassistant/components/*/asterisk_mbox.py
homeassistant/components/axis.py
homeassistant/components/*/axis.py
homeassistant/components/bbb_gpio.py
homeassistant/components/*/bbb_gpio.py
@@ -29,23 +47,35 @@ omit =
homeassistant/components/bloomsky.py
homeassistant/components/*/bloomsky.py
homeassistant/components/comfoconnect.py
homeassistant/components/*/comfoconnect.py
homeassistant/components/digital_ocean.py
homeassistant/components/*/digital_ocean.py
homeassistant/components/dweet.py
homeassistant/components/*/dweet.py
homeassistant/components/eight_sleep.py
homeassistant/components/*/eight_sleep.py
homeassistant/components/ecobee.py
homeassistant/components/*/ecobee.py
homeassistant/components/enocean.py
homeassistant/components/*/enocean.py
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/hdmi_cec.py
homeassistant/components/*/hdmi_cec.py
homeassistant/components/homematic.py
homeassistant/components/*/homematic.py
homeassistant/components/insteon_local.py
homeassistant/components/*/insteon_local.py
@@ -59,36 +89,81 @@ omit =
homeassistant/components/isy994.py
homeassistant/components/*/isy994.py
homeassistant/components/joaoapps_join.py
homeassistant/components/*/joaoapps_join.py
homeassistant/components/juicenet.py
homeassistant/components/*/juicenet.py
homeassistant/components/kira.py
homeassistant/components/*/kira.py
homeassistant/components/knx.py
homeassistant/components/*/knx.py
homeassistant/components/lametric.py
homeassistant/components/*/lametric.py
homeassistant/components/lutron.py
homeassistant/components/*/lutron.py
homeassistant/components/lutron_caseta.py
homeassistant/components/*/lutron_caseta.py
homeassistant/components/mailgun.py
homeassistant/components/*/mailgun.py
homeassistant/components/maxcube.py
homeassistant/components/*/maxcube.py
homeassistant/components/mochad.py
homeassistant/components/*/mochad.py
homeassistant/components/modbus.py
homeassistant/components/*/modbus.py
homeassistant/components/mysensors.py
homeassistant/components/*/mysensors.py
homeassistant/components/neato.py
homeassistant/components/*/neato.py
homeassistant/components/nest.py
homeassistant/components/*/nest.py
homeassistant/components/netatmo.py
homeassistant/components/*/netatmo.py
homeassistant/components/octoprint.py
homeassistant/components/*/octoprint.py
homeassistant/components/opencv.py
homeassistant/components/*/opencv.py
homeassistant/components/qwikswitch.py
homeassistant/components/*/qwikswitch.py
homeassistant/components/rachio.py
homeassistant/components/*/rachio.py
homeassistant/components/raspihats.py
homeassistant/components/*/raspihats.py
homeassistant/components/rfxtrx.py
homeassistant/components/*/rfxtrx.py
homeassistant/components/rpi_gpio.py
homeassistant/components/*/rpi_gpio.py
homeassistant/components/rpi_pfio.py
homeassistant/components/*/rpi_pfio.py
homeassistant/components/scsgate.py
homeassistant/components/*/scsgate.py
homeassistant/components/tado.py
homeassistant/components/*/tado.py
homeassistant/components/tellduslive.py
homeassistant/components/*/tellduslive.py
@@ -104,6 +179,15 @@ omit =
homeassistant/components/notify/twilio_sms.py
homeassistant/components/notify/twilio_call.py
homeassistant/components/usps.py
homeassistant/components/*/usps.py
homeassistant/components/velbus.py
homeassistant/components/*/velbus.py
homeassistant/components/velux.py
homeassistant/components/*/velux.py
homeassistant/components/vera.py
homeassistant/components/*/vera.py
@@ -121,41 +205,30 @@ omit =
homeassistant/components/wink.py
homeassistant/components/*/wink.py
homeassistant/components/zigbee.py
homeassistant/components/*/zigbee.py
homeassistant/components/enocean.py
homeassistant/components/*/enocean.py
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/knx.py
homeassistant/components/*/knx.py
homeassistant/components/zoneminder.py
homeassistant/components/*/zoneminder.py
homeassistant/components/mochad.py
homeassistant/components/*/mochad.py
homeassistant/components/xiaomi.py
homeassistant/components/binary_sensor/xiaomi.py
homeassistant/components/cover/xiaomi.py
homeassistant/components/light/xiaomi.py
homeassistant/components/sensor/xiaomi.py
homeassistant/components/switch/xiaomi.py
homeassistant/components/zabbix.py
homeassistant/components/*/zabbix.py
homeassistant/components/maxcube.py
homeassistant/components/*/maxcube.py
homeassistant/components/zha/__init__.py
homeassistant/components/zha/const.py
homeassistant/components/*/zha.py
homeassistant/components/tado.py
homeassistant/components/*/tado.py
homeassistant/components/zigbee.py
homeassistant/components/*/zigbee.py
homeassistant/components/zoneminder.py
homeassistant/components/*/zoneminder.py
homeassistant/components/alarm_control_panel/alarmdotcom.py
homeassistant/components/alarm_control_panel/concord232.py
homeassistant/components/alarm_control_panel/egardia.py
homeassistant/components/alarm_control_panel/manual_mqtt.py
homeassistant/components/alarm_control_panel/nx584.py
homeassistant/components/alarm_control_panel/simplisafe.py
homeassistant/components/alarm_control_panel/totalconnect.py
@@ -165,32 +238,39 @@ omit =
homeassistant/components/binary_sensor/flic.py
homeassistant/components/binary_sensor/hikvision.py
homeassistant/components/binary_sensor/iss.py
homeassistant/components/binary_sensor/mystrom.py
homeassistant/components/binary_sensor/pilight.py
homeassistant/components/binary_sensor/ping.py
homeassistant/components/binary_sensor/rest.py
homeassistant/components/binary_sensor/tapsaff.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/onvif.py
homeassistant/components/camera/synology.py
homeassistant/components/climate/eq3btsmart.py
homeassistant/components/climate/flexit.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/climate/sensibo.py
homeassistant/components/cover/garadget.py
homeassistant/components/cover/homematic.py
homeassistant/components/cover/knx.py
homeassistant/components/cover/myq.py
homeassistant/components/cover/opengarage.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/automatic.py
homeassistant/components/device_tracker/bbox.py
homeassistant/components/device_tracker/bluetooth_le_tracker.py
homeassistant/components/device_tracker/bluetooth_tracker.py
@@ -198,9 +278,12 @@ omit =
homeassistant/components/device_tracker/cisco_ios.py
homeassistant/components/device_tracker/fritz.py
homeassistant/components/device_tracker/gpslogger.py
homeassistant/components/device_tracker/huawei_router.py
homeassistant/components/device_tracker/icloud.py
homeassistant/components/device_tracker/linksys_ap.py
homeassistant/components/device_tracker/linksys_smart.py
homeassistant/components/device_tracker/luci.py
homeassistant/components/device_tracker/mikrotik.py
homeassistant/components/device_tracker/netgear.py
homeassistant/components/device_tracker/nmap_tracker.py
homeassistant/components/device_tracker/ping.py
@@ -213,43 +296,50 @@ omit =
homeassistant/components/device_tracker/tplink.py
homeassistant/components/device_tracker/trackr.py
homeassistant/components/device_tracker/ubus.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/hdmi_cec.py
homeassistant/components/ifttt.py
homeassistant/components/joaoapps_join.py
homeassistant/components/image_processing/dlib_face_detect.py
homeassistant/components/image_processing/dlib_face_identify.py
homeassistant/components/image_processing/seven_segments.py
homeassistant/components/keyboard.py
homeassistant/components/keyboard_remote.py
homeassistant/components/light/avion.py
homeassistant/components/light/blinkt.py
homeassistant/components/light/blinksticklight.py
homeassistant/components/light/decora.py
homeassistant/components/light/decora_wifi.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/lifx.py
homeassistant/components/light/lifx_legacy.py
homeassistant/components/light/limitlessled.py
homeassistant/components/light/mystrom.py
homeassistant/components/light/osramlightify.py
homeassistant/components/light/rpi_gpio_pwm.py
homeassistant/components/light/piglow.py
homeassistant/components/light/sensehat.py
homeassistant/components/light/tikteck.py
homeassistant/components/light/tplink.py
homeassistant/components/light/tradfri.py
homeassistant/components/light/x10.py
homeassistant/components/light/yeelight.py
homeassistant/components/light/yeelightsunflower.py
homeassistant/components/light/zengge.py
homeassistant/components/lirc.py
homeassistant/components/lock/nello.py
homeassistant/components/lock/nuki.py
homeassistant/components/lock/lockitron.py
homeassistant/components/lock/sesame.py
homeassistant/components/media_extractor.py
homeassistant/components/media_player/anthemav.py
homeassistant/components/media_player/apple_tv.py
homeassistant/components/media_player/aquostv.py
homeassistant/components/media_player/bluesound.py
homeassistant/components/media_player/braviatv.py
homeassistant/components/media_player/cast.py
homeassistant/components/media_player/clementine.py
@@ -263,7 +353,6 @@ omit =
homeassistant/components/media_player/frontier_silicon.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
@@ -271,6 +360,7 @@ omit =
homeassistant/components/media_player/mpchc.py
homeassistant/components/media_player/mpd.py
homeassistant/components/media_player/nad.py
homeassistant/components/media_player/nadtcp.py
homeassistant/components/media_player/onkyo.py
homeassistant/components/media_player/openhome.py
homeassistant/components/media_player/panasonic_viera.py
@@ -279,12 +369,14 @@ omit =
homeassistant/components/media_player/pioneer.py
homeassistant/components/media_player/plex.py
homeassistant/components/media_player/roku.py
homeassistant/components/media_player/russound_rio.py
homeassistant/components/media_player/russound_rnet.py
homeassistant/components/media_player/samsungtv.py
homeassistant/components/media_player/snapcast.py
homeassistant/components/media_player/sonos.py
homeassistant/components/media_player/spotify.py
homeassistant/components/media_player/squeezebox.py
homeassistant/components/media_player/vizio.py
homeassistant/components/media_player/vlc.py
homeassistant/components/media_player/volumio.py
homeassistant/components/media_player/yamaha.py
@@ -292,21 +384,22 @@ omit =
homeassistant/components/notify/aws_sns.py
homeassistant/components/notify/aws_sqs.py
homeassistant/components/notify/ciscospark.py
homeassistant/components/notify/clicksend.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/hipchat.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/prowl.py
homeassistant/components/notify/pushbullet.py
homeassistant/components/notify/pushetta.py
homeassistant/components/notify/pushover.py
@@ -322,19 +415,24 @@ omit =
homeassistant/components/notify/twitter.py
homeassistant/components/notify/xmpp.py
homeassistant/components/nuimo_controller.py
homeassistant/components/prometheus.py
homeassistant/components/remote/harmony.py
homeassistant/components/remote/itach.py
homeassistant/components/scene/hunterdouglas_powerview.py
homeassistant/components/scene/lifx_cloud.py
homeassistant/components/sensor/amcrest.py
homeassistant/components/sensor/arest.py
homeassistant/components/sensor/arwn.py
homeassistant/components/sensor/bbox.py
homeassistant/components/sensor/bh1750.py
homeassistant/components/sensor/bitcoin.py
homeassistant/components/sensor/blockchain.py
homeassistant/components/sensor/bme280.py
homeassistant/components/sensor/bom.py
homeassistant/components/sensor/broadlink.py
homeassistant/components/sensor/dublin_bus_transport.py
homeassistant/components/sensor/buienradar.py
homeassistant/components/sensor/citybikes.py
homeassistant/components/sensor/coinmarketcap.py
homeassistant/components/sensor/cert_expiry.py
homeassistant/components/sensor/comed_hourly_pricing.py
homeassistant/components/sensor/cpuspeed.py
homeassistant/components/sensor/crimereports.py
@@ -346,10 +444,13 @@ omit =
homeassistant/components/sensor/dnsip.py
homeassistant/components/sensor/dovado.py
homeassistant/components/sensor/dte_energy_bridge.py
homeassistant/components/sensor/dublin_bus_transport.py
homeassistant/components/sensor/ebox.py
homeassistant/components/sensor/eddystone_temperature.py
homeassistant/components/sensor/eliqonline.py
homeassistant/components/sensor/emoncms.py
homeassistant/components/sensor/envirophat.py
homeassistant/components/sensor/etherscan.py
homeassistant/components/sensor/fastdotcom.py
homeassistant/components/sensor/fedex.py
homeassistant/components/sensor/fido.py
@@ -357,6 +458,8 @@ omit =
homeassistant/components/sensor/fixer.py
homeassistant/components/sensor/fritzbox_callmonitor.py
homeassistant/components/sensor/fritzbox_netmonitor.py
homeassistant/components/sensor/geizhals.py
homeassistant/components/sensor/gitter.py
homeassistant/components/sensor/glances.py
homeassistant/components/sensor/google_travel_time.py
homeassistant/components/sensor/gpsd.py
@@ -364,6 +467,7 @@ omit =
homeassistant/components/sensor/haveibeenpwned.py
homeassistant/components/sensor/hddtemp.py
homeassistant/components/sensor/hp_ilo.py
homeassistant/components/sensor/htu21d.py
homeassistant/components/sensor/hydroquebec.py
homeassistant/components/sensor/imap.py
homeassistant/components/sensor/imap_email_content.py
@@ -388,15 +492,20 @@ omit =
homeassistant/components/sensor/openexchangerates.py
homeassistant/components/sensor/opensky.py
homeassistant/components/sensor/openweathermap.py
homeassistant/components/sensor/otp.py
homeassistant/components/sensor/pi_hole.py
homeassistant/components/sensor/plex.py
homeassistant/components/sensor/pocketcasts.py
homeassistant/components/sensor/pushbullet.py
homeassistant/components/sensor/pvoutput.py
homeassistant/components/sensor/qnap.py
homeassistant/components/sensor/radarr.py
homeassistant/components/sensor/ripple.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/shodan.py
homeassistant/components/sensor/skybeacon.py
homeassistant/components/sensor/sma.py
homeassistant/components/sensor/snmp.py
@@ -415,13 +524,16 @@ omit =
homeassistant/components/sensor/transmission.py
homeassistant/components/sensor/twitch.py
homeassistant/components/sensor/uber.py
homeassistant/components/sensor/upnp.py
homeassistant/components/sensor/ups.py
homeassistant/components/sensor/usps.py
homeassistant/components/sensor/vasttrafik.py
homeassistant/components/sensor/waqi.py
homeassistant/components/sensor/worldtidesinfo.py
homeassistant/components/sensor/xbox_live.py
homeassistant/components/sensor/yweather.py
homeassistant/components/sensor/zamg.py
homeassistant/components/shiftr.py
homeassistant/components/spc.py
homeassistant/components/switch/acer_projector.py
homeassistant/components/switch/anel_pwrctrl.py
homeassistant/components/switch/arest.py
@@ -430,7 +542,6 @@ omit =
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
@@ -439,6 +550,7 @@ omit =
homeassistant/components/switch/orvibo.py
homeassistant/components/switch/pilight.py
homeassistant/components/switch/pulseaudio_loopback.py
homeassistant/components/switch/rainmachine.py
homeassistant/components/switch/rest.py
homeassistant/components/switch/rpi_rf.py
homeassistant/components/switch/tplink.py
@@ -449,9 +561,12 @@ omit =
homeassistant/components/tts/amazon_polly.py
homeassistant/components/tts/picotts.py
homeassistant/components/upnp.py
homeassistant/components/vacuum/roomba.py
homeassistant/components/weather/bom.py
homeassistant/components/weather/buienradar.py
homeassistant/components/weather/metoffice.py
homeassistant/components/weather/openweathermap.py
homeassistant/components/weather/yweather.py
homeassistant/components/weather/zamg.py
homeassistant/components/zeroconf.py
homeassistant/components/zwave/util.py

View File

@@ -1,2 +1,14 @@
.tox
# General files
.git
.github
config
# Test related files
.tox
# Other virtualization methods
venv
.vagrant
# Temporary files
**/__pycache__

4
.gitignore vendored
View File

@@ -73,6 +73,7 @@ pyvenv.cfg
pip-selfcheck.json
venv
.venv
Pipfile*
# vimmy stuff
*.swp
@@ -93,3 +94,6 @@ docs/build
# Windows Explorer
desktop.ini
/home-assistant.pyproj
/home-assistant.sln
/.vs/home-assistant/v14

View File

@@ -1,21 +1,25 @@
sudo: false
addons:
apt:
packages:
- libudev-dev
matrix:
fast_finish: true
include:
- python: "3.4.2"
env: TOXENV=py34
- python: "3.4.2"
env: TOXENV=requirements
- python: "3.4.2"
env: TOXENV=lint
- python: "3.4.2"
env: TOXENV=py34
# - python: "3.5"
# env: TOXENV=typing
- python: "3.5"
env: TOXENV=py35
- python: "3.6"
env: TOXENV=py36
- python: "3.6-dev"
env: TOXENV=py36
# - python: "3.6-dev"
# env: TOXENV=py36
- python: "3.4.2"
env: TOXENV=requirements
# allow_failures:
# - python: "3.5"
# env: TOXENV=typing
@@ -25,5 +29,5 @@ cache:
- $HOME/.cache/pip
install: pip install -U tox coveralls
language: python
script: tox
script: travis_wait tox
after_success: coveralls

41
CODEOWNERS Normal file
View File

@@ -0,0 +1,41 @@
# People marked here will be automatically requested for a review
# when the code that they own is touched.
# https://github.com/blog/2392-introducing-code-owners
setup.py @home-assistant/core
homeassistant/*.py @home-assistant/core
homeassistant/helpers/* @home-assistant/core
homeassistant/util/* @home-assistant/core
homeassistant/components/api.py @home-assistant/core
homeassistant/components/automation/* @home-assistant/core
homeassistant/components/configurator.py @home-assistant/core
homeassistant/components/group.py @home-assistant/core
homeassistant/components/history.py @home-assistant/core
homeassistant/components/http/* @home-assistant/core
homeassistant/components/input_*.py @home-assistant/core
homeassistant/components/introduction.py @home-assistant/core
homeassistant/components/logger.py @home-assistant/core
homeassistant/components/mqtt/* @home-assistant/core
homeassistant/components/panel_custom.py @home-assistant/core
homeassistant/components/panel_iframe.py @home-assistant/core
homeassistant/components/persistent_notification.py @home-assistant/core
homeassistant/components/scene/__init__.py @home-assistant/core
homeassistant/components/scene/hass.py @home-assistant/core
homeassistant/components/script.py @home-assistant/core
homeassistant/components/shell_command.py @home-assistant/core
homeassistant/components/sun.py @home-assistant/core
homeassistant/components/updater.py @home-assistant/core
homeassistant/components/weblink.py @home-assistant/core
homeassistant/components/websocket_api.py @home-assistant/core
homeassistant/components/zone.py @home-assistant/core
Dockerfile @home-assistant/docker
virtualization/Docker/* @home-assistant/docker
homeassistant/components/zwave/* @home-assistant/z-wave
homeassistant/components/*/zwave.py @home-assistant/z-wave
# Indiviudal components
homeassistant/components/cover/template.py @PhracturedBlue
homeassistant/components/device_tracker/automatic.py @armills
homeassistant/components/media_player/kodi.py @armills

View File

@@ -4,11 +4,11 @@ Everybody is invited and welcome to contribute to Home Assistant. There is a lot
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)
- Read [How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/devel/pull-requests.md#best-practices-for-faster-reviews) 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 peek at the [developer documentation](https://home-assistant.io/developers/) to get more details.

View File

@@ -1,14 +1,18 @@
FROM python:3.5
# Notice:
# When updating this file, please also update virtualization/Docker/Dockerfile.dev
# This way, the development image and the production image are kept in sync.
FROM python:3.6
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
#ENV INSTALL_COAP_CLIENT no
#ENV INSTALL_SSOCR no
VOLUME /config
@@ -21,10 +25,13 @@ RUN virtualization/Docker/setup_docker_prereqs
# Install hass component dependencies
COPY requirements_all.txt requirements_all.txt
# Uninstall enum34 because some depenndecies install it but breaks Python 3.4+.
# See PR #8103 for more info.
RUN pip3 install --no-cache-dir -r requirements_all.txt && \
pip3 install --no-cache-dir mysqlclient psycopg2 uvloop cchardet
# Copy source
COPY . .
CMD [ "python", "-m", "homeassistant", "--config", "/config" ]
CMD [ "python", "-m", "homeassistant", "--config", "/config" ]

View File

@@ -1,5 +1,5 @@
Home Assistant |Build Status| |Coverage Status| |Join the chat at https://gitter.im/home-assistant/home-assistant| |Join the dev chat at https://gitter.im/home-assistant/home-assistant/devs|
==============================================================================================================================================================================================
Home Assistant |Build Status| |Coverage Status| |Chat Status|
=============================================================
Home Assistant is a home automation platform running on Python 3. It is able to track and control all devices at home and offer a platform for automating control.
@@ -31,6 +31,8 @@ of a component, check the `Home Assistant help section <https://home-assistant.i
:target: https://travis-ci.org/home-assistant/home-assistant
.. |Coverage Status| image:: https://img.shields.io/coveralls/home-assistant/home-assistant.svg
:target: https://coveralls.io/r/home-assistant/home-assistant?branch=master
.. |Chat Status| image:: https://img.shields.io/discord/330944238910963714.svg
:target: https://discord.gg/c5DvZ4e
.. |Join the chat at https://gitter.im/home-assistant/home-assistant| image:: https://img.shields.io/badge/gitter-general-blue.svg
:target: https://gitter.im/home-assistant/home-assistant?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
.. |Join the dev chat at https://gitter.im/home-assistant/home-assistant/devs| image:: https://img.shields.io/badge/gitter-development-yellowgreen.svg

View File

@@ -1,8 +1,6 @@
<ul>
<li><a href="https://community.home-assistant.io">📌 Community Forums</a></li>
<li><a href="https://github.com/home-assistant/home-assistant">🚀 GitHub</a></li>
<li><a href="https://home-assistant.io/">🏡 Homepage</a></li>
<li><a href="https://gitter.im/home-assistant/home-assistant">💬 Gitter</a></li>
<li><a href="https://pypi.python.org/pypi/homeassistant">💾 Download Releases</a></li>
<li><a href="https://home-assistant.io/">Homepage</a></li>
<li><a href="https://community.home-assistant.io">Community Forums</a></li>
<li><a href="https://github.com/home-assistant/home-assistant">GitHub</a></li>
<li><a href="https://gitter.im/home-assistant/home-assistant">Gitter</a></li>
</ul>
<hr>

View File

@@ -1,4 +1,4 @@
"""Starts home assistant."""
"""Start Home Assistant."""
from __future__ import print_function
import argparse
@@ -10,6 +10,7 @@ import threading
from typing import Optional, List
from homeassistant import monkey_patch
from homeassistant.const import (
__version__,
EVENT_HOMEASSISTANT_START,
@@ -17,7 +18,6 @@ from homeassistant.const import (
REQUIRED_PYTHON_VER_WIN,
RESTART_EXIT_CODE,
)
from homeassistant.util.async import run_callback_threadsafe
def attempt_use_uvloop():
@@ -31,50 +31,8 @@ def attempt_use_uvloop():
pass
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."""
"""Validate that the right Python version is running."""
if sys.platform == "win32" and \
sys.version_info[:3] < REQUIRED_PYTHON_VER_WIN:
print("Home Assistant requires at least Python {}.{}.{}".format(
@@ -215,7 +173,7 @@ def daemonize() -> None:
def check_pid(pid_file: str) -> None:
"""Check that HA is not already running."""
"""Check that Home Assistant is not already running."""
# Check pid file
try:
pid = int(open(pid_file, 'r').readline())
@@ -271,13 +229,13 @@ def cmdline() -> List[str]:
os.environ['PYTHONPATH'] = os.path.dirname(modulepath)
return [sys.executable] + [arg for arg in sys.argv if
arg != '--daemon']
else:
return [arg for arg in sys.argv if arg != '--daemon']
return [arg for arg in sys.argv if arg != '--daemon']
def setup_and_run_hass(config_dir: str,
args: argparse.Namespace) -> Optional[int]:
"""Setup HASS and run."""
"""Set up HASS and run."""
from homeassistant import bootstrap
# Run a simple daemon runner process on Windows to handle restarts
@@ -310,6 +268,9 @@ def setup_and_run_hass(config_dir: str,
return None
if args.open_ui:
# Imported here to avoid importing asyncio before monkey patch
from homeassistant.util.async import run_callback_threadsafe
def open_browser(event):
"""Open the webinterface in a browser."""
if hass.config.api is not None:
@@ -326,7 +287,7 @@ def setup_and_run_hass(config_dir: str,
def try_to_restart() -> None:
"""Attempt to clean up state and start a new homeassistant instance."""
"""Attempt to clean up state and start a new Home Assistant instance."""
# Things should be mostly shut down already at this point, now just try
# to clean up things that may have been left behind.
sys.stderr.write('Home Assistant attempting to restart.\n')
@@ -358,11 +319,11 @@ def try_to_restart() -> None:
else:
os.closerange(3, max_fd)
# Now launch into a new instance of Home-Assistant. If this fails we
# Now launch into a new instance of Home Assistant. If this fails we
# fall through and exit with error 100 (RESTART_EXIT_CODE) in which case
# systemd will restart us when RestartForceExitStatus=100 is set in the
# systemd.service file.
sys.stderr.write("Restarting Home-Assistant\n")
sys.stderr.write("Restarting Home Assistant\n")
args = cmdline()
os.execv(args[0], args)
@@ -371,10 +332,12 @@ def main() -> int:
"""Start Home Assistant."""
validate_python()
attempt_use_uvloop()
if os.environ.get('HASS_NO_MONKEY') != '1':
if sys.version_info[:2] >= (3, 6):
monkey_patch.disable_c_asyncio()
monkey_patch.patch_weakref_tasks()
if sys.version_info[:3] < (3, 5, 3):
monkey_patch_asyncio()
attempt_use_uvloop()
args = get_arguments()

View File

@@ -1,4 +1,4 @@
"""Provides methods to bootstrap a home assistant instance."""
"""Provide methods to bootstrap a Home Assistant instance."""
import asyncio
import logging
import logging.handlers
@@ -19,6 +19,7 @@ from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE
from homeassistant.setup import async_setup_component
import homeassistant.loader as loader
from homeassistant.util.logging import AsyncHandler
from homeassistant.util.package import async_get_user_site, get_user_site
from homeassistant.util.yaml import clear_secret_cache
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.signal import async_register_signal_handling
@@ -39,7 +40,7 @@ def from_config_dict(config: Dict[str, Any],
skip_pip: bool=False,
log_rotate_days: Any=None) \
-> Optional[core.HomeAssistant]:
"""Try to configure Home Assistant from a config dict.
"""Try to configure Home Assistant from a configuration dictionary.
Dynamically loads required components and its dependencies.
"""
@@ -48,7 +49,8 @@ def from_config_dict(config: Dict[str, Any],
if config_dir is not None:
config_dir = os.path.abspath(config_dir)
hass.config.config_dir = config_dir
mount_local_lib_path(config_dir)
hass.loop.run_until_complete(
async_mount_local_lib_path(config_dir, hass.loop))
# run task
hass = hass.loop.run_until_complete(
@@ -69,7 +71,7 @@ def async_from_config_dict(config: Dict[str, Any],
skip_pip: bool=False,
log_rotate_days: Any=None) \
-> Optional[core.HomeAssistant]:
"""Try to configure Home Assistant from a config dict.
"""Try to configure Home Assistant from a configuration dictionary.
Dynamically loads required components and its dependencies.
This method is a coroutine.
@@ -83,19 +85,18 @@ def async_from_config_dict(config: Dict[str, Any],
conf_util.async_log_exception(ex, 'homeassistant', core_config, hass)
return None
yield from hass.loop.run_in_executor(
None, conf_util.process_ha_config_upgrade, hass)
yield from hass.async_add_job(conf_util.process_ha_config_upgrade, hass)
if enable_log:
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.')
_LOGGER.warning("Skipping pip installation of required modules. "
"This may cause issues")
if not loader.PREPARED:
yield from hass.loop.run_in_executor(None, loader.prepare, hass)
yield from hass.async_add_job(loader.prepare, hass)
# Merge packages
conf_util.merge_packages_config(
@@ -117,13 +118,13 @@ def async_from_config_dict(config: Dict[str, Any],
# 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.')
_LOGGER.error("Home Assistant core failed to initialize. "
"further initialization aborted")
return hass
yield from persistent_notification.async_setup(hass, config)
_LOGGER.info('Home Assistant core initialized')
_LOGGER.info("Home Assistant core initialized")
# stage 1
for component in components:
@@ -142,7 +143,7 @@ def async_from_config_dict(config: Dict[str, Any],
yield from hass.async_block_till_done()
stop = time()
_LOGGER.info('Home Assistant initialized in %.2fs', stop-start)
_LOGGER.info("Home Assistant initialized in %.2fs", stop-start)
async_register_signal_handling(hass)
return hass
@@ -184,16 +185,15 @@ def async_from_config_file(config_path: str,
# Set config dir to directory holding config file
config_dir = os.path.abspath(os.path.dirname(config_path))
hass.config.config_dir = config_dir
yield from hass.loop.run_in_executor(
None, mount_local_lib_path, config_dir)
yield from async_mount_local_lib_path(config_dir, hass.loop)
async_enable_logging(hass, verbose, log_rotate_days)
try:
config_dict = yield from hass.loop.run_in_executor(
None, conf_util.load_yaml_config_file, config_path)
config_dict = yield from hass.async_add_job(
conf_util.load_yaml_config_file, config_path)
except HomeAssistantError as err:
_LOGGER.error('Error loading %s: %s', config_path, err)
_LOGGER.error("Error loading %s: %s", config_path, err)
return None
finally:
clear_secret_cache()
@@ -206,7 +206,7 @@ def async_from_config_file(config_path: str,
@core.callback
def async_enable_logging(hass: core.HomeAssistant, verbose: bool=False,
log_rotate_days=None) -> None:
"""Setup the logging.
"""Set up the logging.
This method must be run in the event loop.
"""
@@ -214,12 +214,12 @@ def async_enable_logging(hass: core.HomeAssistant, verbose: bool=False,
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'
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)
# 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
@@ -274,15 +274,27 @@ def async_enable_logging(hass: core.HomeAssistant, verbose: bool=False,
else:
_LOGGER.error(
'Unable to setup error log %s (access denied)', err_log_path)
"Unable to setup error log %s (access denied)", err_log_path)
def mount_local_lib_path(config_dir: str) -> str:
"""Add local library to Python Path."""
deps_dir = os.path.join(config_dir, 'deps')
lib_dir = get_user_site(deps_dir)
if lib_dir not in sys.path:
sys.path.insert(0, lib_dir)
return deps_dir
@asyncio.coroutine
def async_mount_local_lib_path(config_dir: str,
loop: asyncio.AbstractEventLoop) -> str:
"""Add local library to Python Path.
Async friendly.
This function is a coroutine.
"""
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'))
lib_dir = yield from async_get_user_site(deps_dir, loop=loop)
if lib_dir not in sys.path:
sys.path.insert(0, lib_dir)
return deps_dir

View File

@@ -15,7 +15,6 @@ 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,
SERVICE_HOMEASSISTANT_STOP, SERVICE_HOMEASSISTANT_RESTART,
@@ -33,25 +32,27 @@ def is_on(hass, entity_id=None):
If there is no entity id given we will check all.
"""
if entity_id:
group = get_component('group')
entity_ids = group.expand_entity_ids(hass, [entity_id])
entity_ids = hass.components.group.expand_entity_ids([entity_id])
else:
entity_ids = hass.states.entity_ids()
for entity_id in entity_ids:
domain = ha.split_entity_id(entity_id)[0]
module = get_component(domain)
for ent_id in entity_ids:
domain = ha.split_entity_id(ent_id)[0]
try:
if module.is_on(hass, entity_id):
return True
component = getattr(hass.components, domain)
except AttributeError:
# module is None or method is_on does not exist
_LOGGER.exception("Failed to call %s.is_on for %s",
module, entity_id)
except ImportError:
_LOGGER.error('Failed to call %s.is_on: component not found',
domain)
continue
if not hasattr(component, 'is_on'):
_LOGGER.warning("Component %s has no is_on method.", domain)
continue
if component.is_on(ent_id):
return True
return False
@@ -102,10 +103,10 @@ def reload_core_config(hass):
@asyncio.coroutine
def async_setup(hass, config):
"""Setup general services related to Home Assistant."""
"""Set up general services related to Home Assistant."""
@asyncio.coroutine
def async_handle_turn_service(service):
"""Method to handle calls to homeassistant.turn_on/off."""
"""Handle calls to homeassistant.turn_on/off."""
entity_ids = extract_entity_ids(hass, service)
# Generic turn on/off method requires entity id
@@ -161,10 +162,9 @@ def async_setup(hass, config):
return
if errors:
notif = get_component('persistent_notification')
_LOGGER.error(errors)
notif.async_create(
hass, "Config error. See dev-info panel for details.",
hass.components.persistent_notification.async_create(
"Config error. See dev-info panel for details.",
"Config validating", "{0}.check_config".format(ha.DOMAIN))
return

View File

@@ -0,0 +1,75 @@
"""
This component provides basic support for Abode Home Security system.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/abode/
"""
import logging
import voluptuous as vol
from requests.exceptions import HTTPError, ConnectTimeout
from homeassistant.helpers import discovery
from homeassistant.helpers import config_validation as cv
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD, CONF_NAME
REQUIREMENTS = ['abodepy==0.7.1']
_LOGGER = logging.getLogger(__name__)
CONF_ATTRIBUTION = "Data provided by goabode.com"
DOMAIN = 'abode'
DEFAULT_NAME = 'Abode'
DATA_ABODE = 'data_abode'
DEFAULT_ENTITY_NAMESPACE = 'abode'
NOTIFICATION_ID = 'abode_notification'
NOTIFICATION_TITLE = 'Abode Security Setup'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
}),
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Set up Abode component."""
conf = config[DOMAIN]
username = conf.get(CONF_USERNAME)
password = conf.get(CONF_PASSWORD)
try:
data = AbodeData(username, password)
hass.data[DATA_ABODE] = data
for component in ['binary_sensor', 'alarm_control_panel']:
discovery.load_platform(hass, component, DOMAIN, {}, config)
except (ConnectTimeout, HTTPError) as ex:
_LOGGER.error("Unable to connect to Abode: %s", str(ex))
hass.components.persistent_notification.create(
'Error: {}<br />'
'You will need to restart hass after fixing.'
''.format(ex),
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
return True
class AbodeData:
"""Shared Abode data."""
def __init__(self, username, password):
"""Initialize Abode oject."""
import abodepy
self.abode = abodepy.Abode(username, password)
self.devices = self.abode.get_devices()
_LOGGER.debug("Abode Security set up with %s devices",
len(self.devices))

View File

@@ -13,8 +13,10 @@ import voluptuous as vol
from homeassistant.const import (
ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, SERVICE_ALARM_TRIGGER,
SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY)
SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY,
SERVICE_ALARM_ARM_NIGHT)
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import bind_hass
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
@@ -30,6 +32,7 @@ SERVICE_TO_METHOD = {
SERVICE_ALARM_DISARM: 'alarm_disarm',
SERVICE_ALARM_ARM_HOME: 'alarm_arm_home',
SERVICE_ALARM_ARM_AWAY: 'alarm_arm_away',
SERVICE_ALARM_ARM_NIGHT: 'alarm_arm_night',
SERVICE_ALARM_TRIGGER: 'alarm_trigger'
}
@@ -44,6 +47,7 @@ ALARM_SERVICE_SCHEMA = vol.Schema({
})
@bind_hass
def alarm_disarm(hass, code=None, entity_id=None):
"""Send the alarm the command for disarm."""
data = {}
@@ -55,6 +59,7 @@ def alarm_disarm(hass, code=None, entity_id=None):
hass.services.call(DOMAIN, SERVICE_ALARM_DISARM, data)
@bind_hass
def alarm_arm_home(hass, code=None, entity_id=None):
"""Send the alarm the command for arm home."""
data = {}
@@ -66,6 +71,7 @@ def alarm_arm_home(hass, code=None, entity_id=None):
hass.services.call(DOMAIN, SERVICE_ALARM_ARM_HOME, data)
@bind_hass
def alarm_arm_away(hass, code=None, entity_id=None):
"""Send the alarm the command for arm away."""
data = {}
@@ -77,6 +83,19 @@ def alarm_arm_away(hass, code=None, entity_id=None):
hass.services.call(DOMAIN, SERVICE_ALARM_ARM_AWAY, data)
@bind_hass
def alarm_arm_night(hass, code=None, entity_id=None):
"""Send the alarm the command for arm night."""
data = {}
if code:
data[ATTR_CODE] = code
if entity_id:
data[ATTR_ENTITY_ID] = entity_id
hass.services.call(DOMAIN, SERVICE_ALARM_ARM_NIGHT, data)
@bind_hass
def alarm_trigger(hass, code=None, entity_id=None):
"""Send the alarm the command for trigger."""
data = {}
@@ -123,8 +142,8 @@ def async_setup(hass, config):
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(
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
for service in SERVICE_TO_METHOD:
@@ -158,8 +177,7 @@ class AlarmControlPanel(Entity):
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)
return self.hass.async_add_job(self.alarm_disarm, code)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
@@ -170,8 +188,7 @@ class AlarmControlPanel(Entity):
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)
return self.hass.async_add_job(self.alarm_arm_home, code)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
@@ -182,8 +199,18 @@ class AlarmControlPanel(Entity):
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)
return self.hass.async_add_job(self.alarm_arm_away, code)
def alarm_arm_night(self, code=None):
"""Send arm night command."""
raise NotImplementedError()
def async_alarm_arm_night(self, code=None):
"""Send arm night command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_job(self.alarm_arm_night, code)
def alarm_trigger(self, code=None):
"""Send alarm trigger command."""
@@ -194,8 +221,7 @@ class AlarmControlPanel(Entity):
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)
return self.hass.async_add_job(self.alarm_trigger, code)
@property
def state_attributes(self):

View File

@@ -0,0 +1,82 @@
"""
This component provides HA alarm_control_panel support for Abode System.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.abode/
"""
import logging
from homeassistant.components.abode import (DATA_ABODE, DEFAULT_NAME)
from homeassistant.const import (STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED)
import homeassistant.components.alarm_control_panel as alarm
DEPENDENCIES = ['abode']
_LOGGER = logging.getLogger(__name__)
ICON = 'mdi:security'
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up a sensor for an Abode device."""
data = hass.data.get(DATA_ABODE)
add_devices([AbodeAlarm(hass, data, data.abode.get_alarm())])
class AbodeAlarm(alarm.AlarmControlPanel):
"""An alarm_control_panel implementation for Abode."""
def __init__(self, hass, data, device):
"""Initialize the alarm control panel."""
super(AbodeAlarm, self).__init__()
self._device = device
self._name = "{0}".format(DEFAULT_NAME)
@property
def should_poll(self):
"""Return the polling state."""
return True
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def icon(self):
"""Return icon."""
return ICON
@property
def state(self):
"""Return the state of the device."""
if self._device.mode == "standby":
state = STATE_ALARM_DISARMED
elif self._device.mode == "away":
state = STATE_ALARM_ARMED_AWAY
elif self._device.mode == "home":
state = STATE_ALARM_ARMED_HOME
else:
state = None
return state
def alarm_disarm(self, code=None):
"""Send disarm command."""
self._device.set_standby()
self.schedule_update_ha_state()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
self._device.set_home()
self.schedule_update_ha_state()
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self._device.set_away()
self.schedule_update_ha_state()
def update(self):
"""Update the device state."""
self._device.refresh()

View File

@@ -25,7 +25,7 @@ DEPENDENCIES = ['alarmdecoder']
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Perform the setup for AlarmDecoder alarm panels."""
"""Set up for AlarmDecoder alarm panels."""
_LOGGER.debug("AlarmDecoderAlarmPanel: setup")
device = AlarmDecoderAlarmPanel("Alarm Panel", hass)
@@ -44,7 +44,7 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
self._name = name
self._state = STATE_UNKNOWN
_LOGGER.debug("AlarmDecoderAlarm: Setting up panel")
_LOGGER.debug("Setting up panel")
@asyncio.coroutine
def async_added_to_hass(self):
@@ -78,12 +78,12 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
@property
def should_poll(self):
"""No polling needed."""
"""Return the polling state."""
return False
@property
def code_format(self):
"""Regex for code format or None if no code is required."""
"""Return the regex for code format or None if no code is required."""
return '^\\d{4,6}$'
@property
@@ -94,26 +94,23 @@ class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel):
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
"""Send disarm command."""
_LOGGER.debug("AlarmDecoderAlarm::alarm_disarm: %s", code)
_LOGGER.debug("alarm_disarm: %s", code)
if code:
_LOGGER.debug("AlarmDecoderAlarm::alarm_disarm: sending %s1",
str(code))
_LOGGER.debug("alarm_disarm: sending %s1", str(code))
self.hass.data[DATA_AD].send("{!s}1".format(code))
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
_LOGGER.debug("AlarmDecoderAlarm::alarm_arm_away: %s", code)
_LOGGER.debug("alarm_arm_away: %s", code)
if code:
_LOGGER.debug("AlarmDecoderAlarm::alarm_arm_away: sending %s2",
str(code))
_LOGGER.debug("alarm_arm_away: sending %s2", str(code))
self.hass.data[DATA_AD].send("{!s}2".format(code))
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
_LOGGER.debug("AlarmDecoderAlarm::alarm_arm_home: %s", code)
_LOGGER.debug("alarm_arm_home: %s", code)
if code:
_LOGGER.debug("AlarmDecoderAlarm::alarm_arm_home: sending %s3",
str(code))
_LOGGER.debug("alarm_arm_home: sending %s3", str(code))
self.hass.data[DATA_AD].send("{!s}3".format(code))

View File

@@ -1,5 +1,4 @@
"""
Interfaces with Alarm.com alarm control panels.
For more details about this platform, please refer to the documentation at
@@ -33,7 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup a Alarm.com control panel."""
"""Set up a Alarm.com control panel."""
name = config.get(CONF_NAME)
code = config.get(CONF_CODE)
username = config.get(CONF_USERNAME)
@@ -93,8 +92,7 @@ class AlarmDotCom(alarm.AlarmControlPanel):
return STATE_ALARM_ARMED_HOME
elif self._alarm.state.lower() == 'armed away':
return STATE_ALARM_ARMED_AWAY
else:
return STATE_UNKNOWN
return STATE_UNKNOWN
@asyncio.coroutine
def async_alarm_disarm(self, code=None):

View File

@@ -51,7 +51,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class Concord232Alarm(alarm.AlarmControlPanel):
"""Represents the Concord232-based alarm panel."""
"""Representation of the Concord232-based alarm panel."""
def __init__(self, hass, url, name):
"""Initialize the Concord232 alarm panel."""
@@ -79,7 +79,7 @@ class Concord232Alarm(alarm.AlarmControlPanel):
@property
def code_format(self):
"""The characters if code is defined."""
"""Return the characters if code is defined."""
return '[0-9]{4}([0-9]{2})?'
@property
@@ -117,7 +117,7 @@ class Concord232Alarm(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."""

View File

@@ -8,7 +8,7 @@ import homeassistant.components.alarm_control_panel.manual as manual
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Demo alarm control panel platform."""
"""Set up the Demo alarm control panel platform."""
add_devices([
manual.ManualAlarm(hass, 'Alarm', '1234', 5, 10, False),
])

View File

@@ -0,0 +1,182 @@
"""
Interfaces with Egardia/Woonveilig alarm control panel.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.egardia/
"""
import logging
import requests
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
import homeassistant.exceptions as exc
import homeassistant.helpers.config_validation as cv
from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_PORT, CONF_HOST, CONF_PASSWORD, CONF_USERNAME, STATE_UNKNOWN,
CONF_NAME, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_TRIGGERED)
REQUIREMENTS = ['pythonegardia==1.0.18']
_LOGGER = logging.getLogger(__name__)
CONF_REPORT_SERVER_CODES = 'report_server_codes'
CONF_REPORT_SERVER_ENABLED = 'report_server_enabled'
CONF_REPORT_SERVER_PORT = 'report_server_port'
DEFAULT_NAME = 'Egardia'
DEFAULT_PORT = 80
DEFAULT_REPORT_SERVER_ENABLED = False
DEFAULT_REPORT_SERVER_PORT = 85
DOMAIN = 'egardia'
NOTIFICATION_ID = 'egardia_notification'
NOTIFICATION_TITLE = 'Egardia'
STATES = {
'ARM': STATE_ALARM_ARMED_AWAY,
'DAY HOME': STATE_ALARM_ARMED_HOME,
'DISARM': STATE_ALARM_DISARMED,
'HOME': STATE_ALARM_ARMED_HOME,
'TRIGGERED': STATE_ALARM_TRIGGERED,
'UNKNOWN': STATE_UNKNOWN,
}
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_REPORT_SERVER_CODES): vol.All(cv.ensure_list),
vol.Optional(CONF_REPORT_SERVER_ENABLED,
default=DEFAULT_REPORT_SERVER_ENABLED): cv.boolean,
vol.Optional(CONF_REPORT_SERVER_PORT, default=DEFAULT_REPORT_SERVER_PORT):
cv.port,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Egardia platform."""
from pythonegardia import egardiadevice
name = config.get(CONF_NAME)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
rs_enabled = config.get(CONF_REPORT_SERVER_ENABLED)
rs_port = config.get(CONF_REPORT_SERVER_PORT)
rs_codes = config.get(CONF_REPORT_SERVER_CODES)
try:
egardiasystem = egardiadevice.EgardiaDevice(
host, port, username, password, '')
except requests.exceptions.RequestException:
raise exc.PlatformNotReady()
except egardiadevice.UnauthorizedError:
_LOGGER.error("Unable to authorize. Wrong password or username")
return False
add_devices([EgardiaAlarm(
name, egardiasystem, hass, rs_enabled, rs_port, rs_codes)], True)
class EgardiaAlarm(alarm.AlarmControlPanel):
"""Representation of a Egardia alarm."""
def __init__(self, name, egardiasystem, hass, rs_enabled=False,
rs_port=None, rs_codes=None):
"""Initialize object."""
self._name = name
self._egardiasystem = egardiasystem
self._status = STATE_UNKNOWN
self._rs_enabled = rs_enabled
self._rs_port = rs_port
self._hass = hass
if rs_codes is not None:
self._rs_codes = rs_codes[0]
else:
self._rs_codes = rs_codes
if self._rs_enabled:
self.listen_to_system_status()
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def state(self):
"""Return the state of the device."""
return self._status
def handle_system_status_event(self, event):
"""Handle egardia_system_status_event."""
if event.data.get('status') is not None:
statuscode = event.data.get('status')
status = self.lookupstatusfromcode(statuscode)
self.parsestatus(status)
def listen_to_system_status(self):
"""Subscribe to egardia_system_status event."""
self._hass.bus.listen(
'egardia_system_status', self.handle_system_status_event)
def lookupstatusfromcode(self, statuscode):
"""Look at the rs_codes and returns the status from the code."""
status = 'UNKNOWN'
if self._rs_codes is not None:
statuscode = str(statuscode).strip()
for i in self._rs_codes:
val = str(self._rs_codes[i]).strip()
if ',' in val:
splitted = val.split(',')
for code in splitted:
code = str(code).strip()
if statuscode == code:
status = i.upper()
break
elif statuscode == val:
status = i.upper()
break
return status
def parsestatus(self, status):
"""Parse the status."""
newstatus = ([v for k, v in STATES.items()
if status.upper() == k][0])
self._status = newstatus
def update(self):
"""Update the alarm status."""
status = self._egardiasystem.getstate()
self.parsestatus(status)
def alarm_disarm(self, code=None):
"""Send disarm command."""
try:
self._egardiasystem.alarm_disarm()
except requests.exceptions.RequestException as err:
_LOGGER.error("Egardia device exception occurred when "
"sending disarm command: %s", err)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
try:
self._egardiasystem.alarm_arm_home()
except requests.exceptions.RequestException as err:
_LOGGER.error("Egardia device exception occurred when "
"sending arm home command: %s", err)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
try:
self._egardiasystem.alarm_arm_away()
except requests.exceptions.RequestException as err:
_LOGGER.error("Egardia device exception occurred when "
"sending arm away command: %s", err)

View File

@@ -70,8 +70,8 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
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(
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
@@ -104,7 +104,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
@callback
def _update_callback(self, partition):
"""Update HA state, if needed."""
"""Update Home Assistant state, if needed."""
if partition is None or int(partition) == self._partition_number:
self.hass.async_add_job(self.async_update_ha_state())
@@ -113,8 +113,7 @@ class EnvisalinkAlarm(EnvisalinkDevice, alarm.AlarmControlPanel):
"""Regex for code format or None if no code is required."""
if self._code:
return None
else:
return '^\\d{4,6}$'
return '^\\d{4,6}$'
@property
def state(self):

View File

@@ -12,9 +12,10 @@ import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
import homeassistant.util.dt as dt_util
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, CONF_PLATFORM, CONF_NAME,
CONF_CODE, CONF_PENDING_TIME, CONF_TRIGGER_TIME, CONF_DISARM_AFTER_TRIGGER)
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_DISARMED, STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED,
CONF_PLATFORM, CONF_NAME, CONF_CODE, CONF_PENDING_TIME, CONF_TRIGGER_TIME,
CONF_DISARM_AFTER_TRIGGER)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import track_point_in_time
@@ -39,7 +40,7 @@ _LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the manual alarm platform."""
"""Set up the manual alarm platform."""
add_devices([ManualAlarm(
hass,
config[CONF_NAME],
@@ -52,7 +53,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class ManualAlarm(alarm.AlarmControlPanel):
"""
Represents an alarm status.
Representation of an alarm status.
When armed, will be pending for 'pending_time', after that armed.
When triggered, will be pending for 'trigger_time'. After that will be
@@ -62,7 +63,7 @@ class ManualAlarm(alarm.AlarmControlPanel):
def __init__(self, hass, name, code, pending_time,
trigger_time, disarm_after_trigger):
"""Initalize the manual alarm panel."""
"""Init the manual alarm panel."""
self._state = STATE_ALARM_DISARMED
self._hass = hass
self._name = name
@@ -75,7 +76,7 @@ class ManualAlarm(alarm.AlarmControlPanel):
@property
def should_poll(self):
"""No polling needed."""
"""Return the plling state."""
return False
@property
@@ -87,7 +88,8 @@ class ManualAlarm(alarm.AlarmControlPanel):
def state(self):
"""Return the state of the device."""
if self._state in (STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY) and \
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_NIGHT) and \
self._pending_time and self._state_ts + self._pending_time > \
dt_util.utcnow():
return STATE_ALARM_PENDING
@@ -99,8 +101,7 @@ class ManualAlarm(alarm.AlarmControlPanel):
self._trigger_time) < dt_util.utcnow():
if self._disarm_after_trigger:
return STATE_ALARM_DISARMED
else:
return self._pre_trigger_state
return self._pre_trigger_state
return self._state
@@ -146,6 +147,20 @@ class ManualAlarm(alarm.AlarmControlPanel):
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time)
def alarm_arm_night(self, code=None):
"""Send arm night command."""
if not self._validate_code(code, STATE_ALARM_ARMED_NIGHT):
return
self._state = STATE_ALARM_ARMED_NIGHT
self._state_ts = dt_util.utcnow()
self.schedule_update_ha_state()
if self._pending_time:
track_point_in_time(
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time)
def alarm_trigger(self, code=None):
"""Send alarm trigger command. No code needed."""
self._pre_trigger_state = self._state
@@ -166,5 +181,5 @@ class ManualAlarm(alarm.AlarmControlPanel):
"""Validate given code."""
check = self._code is None or code == self._code
if not check:
_LOGGER.warning('Invalid code given for %s', state)
_LOGGER.warning("Invalid code given for %s", state)
return check

View File

@@ -0,0 +1,235 @@
"""
Support for manual alarms controllable via MQTT.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.manual_mqtt/
"""
import asyncio
import datetime
import logging
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
import homeassistant.util.dt as dt_util
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, CONF_PLATFORM,
CONF_NAME, CONF_CODE, CONF_PENDING_TIME, CONF_TRIGGER_TIME,
CONF_DISARM_AFTER_TRIGGER)
import homeassistant.components.mqtt as mqtt
from homeassistant.helpers.event import async_track_state_change
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import track_point_in_time
CONF_PAYLOAD_DISARM = 'payload_disarm'
CONF_PAYLOAD_ARM_HOME = 'payload_arm_home'
CONF_PAYLOAD_ARM_AWAY = 'payload_arm_away'
DEFAULT_ALARM_NAME = 'HA Alarm'
DEFAULT_PENDING_TIME = 60
DEFAULT_TRIGGER_TIME = 120
DEFAULT_DISARM_AFTER_TRIGGER = False
DEFAULT_ARM_AWAY = 'ARM_AWAY'
DEFAULT_ARM_HOME = 'ARM_HOME'
DEFAULT_DISARM = 'DISARM'
DEPENDENCIES = ['mqtt']
PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
vol.Required(CONF_PLATFORM): 'manual_mqtt',
vol.Optional(CONF_NAME, default=DEFAULT_ALARM_NAME): cv.string,
vol.Optional(CONF_CODE): cv.string,
vol.Optional(CONF_PENDING_TIME, default=DEFAULT_PENDING_TIME):
vol.All(vol.Coerce(int), vol.Range(min=0)),
vol.Optional(CONF_TRIGGER_TIME, default=DEFAULT_TRIGGER_TIME):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Optional(CONF_DISARM_AFTER_TRIGGER,
default=DEFAULT_DISARM_AFTER_TRIGGER): cv.boolean,
vol.Required(mqtt.CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Required(mqtt.CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_PAYLOAD_ARM_AWAY, default=DEFAULT_ARM_AWAY): cv.string,
vol.Optional(CONF_PAYLOAD_ARM_HOME, default=DEFAULT_ARM_HOME): cv.string,
vol.Optional(CONF_PAYLOAD_DISARM, default=DEFAULT_DISARM): cv.string,
})
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the manual MQTT alarm platform."""
add_devices([ManualMQTTAlarm(
hass,
config[CONF_NAME],
config.get(CONF_CODE),
config.get(CONF_PENDING_TIME, DEFAULT_PENDING_TIME),
config.get(CONF_TRIGGER_TIME, DEFAULT_TRIGGER_TIME),
config.get(CONF_DISARM_AFTER_TRIGGER, DEFAULT_DISARM_AFTER_TRIGGER),
config.get(mqtt.CONF_STATE_TOPIC),
config.get(mqtt.CONF_COMMAND_TOPIC),
config.get(mqtt.CONF_QOS),
config.get(CONF_PAYLOAD_DISARM),
config.get(CONF_PAYLOAD_ARM_HOME),
config.get(CONF_PAYLOAD_ARM_AWAY))])
class ManualMQTTAlarm(alarm.AlarmControlPanel):
"""
Representation of an alarm status.
When armed, will be pending for 'pending_time', after that armed.
When triggered, will be pending for 'trigger_time'. After that will be
triggered for 'trigger_time', after that we return to the previous state
or disarm if `disarm_after_trigger` is true.
"""
def __init__(self, hass, name, code, pending_time,
trigger_time, disarm_after_trigger,
state_topic, command_topic, qos,
payload_disarm, payload_arm_home, payload_arm_away):
"""Init the manual MQTT alarm panel."""
self._state = STATE_ALARM_DISARMED
self._hass = hass
self._name = name
self._code = str(code) if code else None
self._pending_time = datetime.timedelta(seconds=pending_time)
self._trigger_time = datetime.timedelta(seconds=trigger_time)
self._disarm_after_trigger = disarm_after_trigger
self._pre_trigger_state = self._state
self._state_ts = None
self._state_topic = state_topic
self._command_topic = command_topic
self._qos = qos
self._payload_disarm = payload_disarm
self._payload_arm_home = payload_arm_home
self._payload_arm_away = payload_arm_away
@property
def should_poll(self):
"""Return the polling state."""
return False
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def state(self):
"""Return the state of the device."""
if self._state in (STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY) and \
self._pending_time and self._state_ts + self._pending_time > \
dt_util.utcnow():
return STATE_ALARM_PENDING
if self._state == STATE_ALARM_TRIGGERED and self._trigger_time:
if self._state_ts + self._pending_time > dt_util.utcnow():
return STATE_ALARM_PENDING
elif (self._state_ts + self._pending_time +
self._trigger_time) < dt_util.utcnow():
if self._disarm_after_trigger:
return STATE_ALARM_DISARMED
return self._pre_trigger_state
return self._state
@property
def code_format(self):
"""One or more characters."""
return None if self._code is None else '.+'
def alarm_disarm(self, code=None):
"""Send disarm command."""
if not self._validate_code(code, STATE_ALARM_DISARMED):
return
self._state = STATE_ALARM_DISARMED
self._state_ts = dt_util.utcnow()
self.schedule_update_ha_state()
def alarm_arm_home(self, code=None):
"""Send arm home command."""
if not self._validate_code(code, STATE_ALARM_ARMED_HOME):
return
self._state = STATE_ALARM_ARMED_HOME
self._state_ts = dt_util.utcnow()
self.schedule_update_ha_state()
if self._pending_time:
track_point_in_time(
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
if not self._validate_code(code, STATE_ALARM_ARMED_AWAY):
return
self._state = STATE_ALARM_ARMED_AWAY
self._state_ts = dt_util.utcnow()
self.schedule_update_ha_state()
if self._pending_time:
track_point_in_time(
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time)
def alarm_trigger(self, code=None):
"""Send alarm trigger command. No code needed."""
self._pre_trigger_state = self._state
self._state = STATE_ALARM_TRIGGERED
self._state_ts = dt_util.utcnow()
self.schedule_update_ha_state()
if self._trigger_time:
track_point_in_time(
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time)
track_point_in_time(
self._hass, self.async_update_ha_state,
self._state_ts + self._pending_time + self._trigger_time)
def _validate_code(self, code, state):
"""Validate given code."""
check = self._code is None or code == self._code
if not check:
_LOGGER.warning("Invalid code given for %s", state)
return check
def async_added_to_hass(self):
"""Subscribe mqtt events.
This method must be run in the event loop and returns a coroutine.
"""
async_track_state_change(
self.hass, self.entity_id, self._async_state_changed_listener
)
@callback
def message_received(topic, payload, qos):
"""Run when new MQTT message has been received."""
if payload == self._payload_disarm:
self.async_alarm_disarm(self._code)
elif payload == self._payload_arm_home:
self.async_alarm_arm_home(self._code)
elif payload == self._payload_arm_away:
self.async_alarm_arm_away(self._code)
else:
_LOGGER.warning("Received unexpected payload: %s", payload)
return
return mqtt.async_subscribe(
self.hass, self._command_topic, message_received, self._qos)
@asyncio.coroutine
def _async_state_changed_listener(self, entity_id, old_state, new_state):
"""Publish state change to MQTT."""
mqtt.async_publish(self.hass, self._state_topic, new_state.state,
self._qos, True)

View File

@@ -45,7 +45,7 @@ PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup the MQTT platform."""
"""Set up the MQTT Alarm Control Panel platform."""
async_add_devices([MqttAlarm(
config.get(CONF_NAME),
config.get(CONF_STATE_TOPIC),
@@ -62,7 +62,7 @@ class MqttAlarm(alarm.AlarmControlPanel):
def __init__(self, name, state_topic, command_topic, qos, payload_disarm,
payload_arm_home, payload_arm_away, code):
"""Initalize the MQTT alarm panel."""
"""Init the MQTT Alarm Control Panel."""
self._state = STATE_UNKNOWN
self._name = name
self._state_topic = state_topic
@@ -80,11 +80,11 @@ class MqttAlarm(alarm.AlarmControlPanel):
"""
@callback
def message_received(topic, payload, qos):
"""A new MQTT message has been received."""
"""Run when new MQTT message has been received."""
if payload not in (STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_PENDING,
STATE_ALARM_TRIGGERED):
_LOGGER.warning('Received unexpected payload: %s', payload)
_LOGGER.warning("Received unexpected payload: %s", payload)
return
self._state = payload
self.hass.async_add_job(self.async_update_ha_state())

View File

@@ -32,7 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup nx584 platform."""
"""Set up the nx584 platform."""
name = config.get(CONF_NAME)
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
@@ -42,15 +42,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
try:
add_devices([NX584Alarm(hass, url, name)])
except requests.exceptions.ConnectionError as ex:
_LOGGER.error('Unable to connect to NX584: %s', str(ex))
_LOGGER.error("Unable to connect to NX584: %s", str(ex))
return False
class NX584Alarm(alarm.AlarmControlPanel):
"""Represents the NX584-based alarm panel."""
"""Representation of a NX584-based alarm panel."""
def __init__(self, hass, url, name):
"""Initalize the nx584 alarm panel."""
"""Init the nx584 alarm panel."""
from nx584 import client
self._hass = hass
self._name = name
@@ -69,7 +69,7 @@ class NX584Alarm(alarm.AlarmControlPanel):
@property
def code_format(self):
"""The characters if code is defined."""
"""Return che characters if code is defined."""
return '[0-9]{4}([0-9]{2})?'
@property
@@ -83,20 +83,19 @@ class NX584Alarm(alarm.AlarmControlPanel):
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',
_LOGGER.error("Unable to connect to %(host)s: %(reason)s",
dict(host=self._url, reason=ex))
self._state = STATE_UNKNOWN
zones = []
except IndexError:
_LOGGER.error('nx584 reports no partitions')
_LOGGER.error("nx584 reports no partitions")
self._state = STATE_UNKNOWN
zones = []
bypassed = False
for zone in zones:
if zone['bypassed']:
_LOGGER.debug('Zone %(zone)s is bypassed, '
'assuming HOME',
_LOGGER.debug("Zone %(zone)s is bypassed, assuming HOME",
dict(zone=zone['number']))
bypassed = True
break

View File

@@ -31,6 +31,17 @@ alarm_arm_away:
description: An optional code to arm away the alarm control panel with
example: 1234
alarm_arm_night:
description: Send the alarm the command for arm night
fields:
entity_id:
description: Name of alarm control panel to arm night
example: 'alarm_control_panel.downstairs'
code:
description: An optional code to arm night the alarm control panel with
example: 1234
alarm_trigger:
description: Send the alarm the command for trigger

View File

@@ -15,9 +15,8 @@ from homeassistant.const import (
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 = ['simplisafe-python==1.0.2']
REQUIREMENTS = ['simplisafe-python==1.0.5']
_LOGGER = logging.getLogger(__name__)
@@ -42,7 +41,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
persistent_notification = loader.get_component('persistent_notification')
simplisafe = SimpliSafeApiInterface()
status = simplisafe.set_credentials(username, password)
if status:
@@ -53,8 +51,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
else:
message = 'Failed to log into SimpliSafe. Check credentials.'
_LOGGER.error(message)
persistent_notification.create(
hass, message,
hass.components.persistent_notification.create(
message,
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
@@ -80,8 +78,7 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
"""Return the name of the device."""
if self._name is not None:
return self._name
else:
return 'Alarm {}'.format(self.simplisafe.location_id())
return 'Alarm {}'.format(self.simplisafe.location_id())
@property
def code_format(self):
@@ -92,11 +89,11 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
def state(self):
"""Return the state of the device."""
status = self.simplisafe.state()
if status == 'Off':
if status == 'off':
state = STATE_ALARM_DISARMED
elif status == 'Home':
elif status == 'home':
state = STATE_ALARM_ARMED_HOME
elif status == 'Away':
elif status == 'away':
state = STATE_ALARM_ARMED_AWAY
else:
state = STATE_UNKNOWN
@@ -123,25 +120,25 @@ class SimpliSafeAlarm(alarm.AlarmControlPanel):
if not self._validate_code(code, 'disarming'):
return
self.simplisafe.set_state('off')
_LOGGER.info('SimpliSafe alarm disarming')
_LOGGER.info("SimpliSafe alarm disarming")
def alarm_arm_home(self, code=None):
"""Send arm home command."""
if not self._validate_code(code, 'arming home'):
return
self.simplisafe.set_state('home')
_LOGGER.info('SimpliSafe alarm arming home')
_LOGGER.info("SimpliSafe alarm arming home")
def alarm_arm_away(self, code=None):
"""Send arm away command."""
if not self._validate_code(code, 'arming away'):
return
self.simplisafe.set_state('away')
_LOGGER.info('SimpliSafe alarm arming away')
_LOGGER.info("SimpliSafe alarm arming away")
def _validate_code(self, code, state):
"""Validate given code."""
check = self._code is None or code == self._code
if not check:
_LOGGER.warning('Wrong code entered for %s', state)
_LOGGER.warning("Wrong code entered for %s", state)
return check

View File

@@ -0,0 +1,96 @@
"""
Support for Vanderbilt (formerly Siemens) SPC alarm systems.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.spc/
"""
import asyncio
import logging
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.spc import (
SpcWebGateway, ATTR_DISCOVER_AREAS, DATA_API, DATA_REGISTRY)
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_UNKNOWN)
_LOGGER = logging.getLogger(__name__)
SPC_AREA_MODE_TO_STATE = {'0': STATE_ALARM_DISARMED,
'1': STATE_ALARM_ARMED_HOME,
'3': STATE_ALARM_ARMED_AWAY}
def _get_alarm_state(spc_mode):
return SPC_AREA_MODE_TO_STATE.get(spc_mode, STATE_UNKNOWN)
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the SPC alarm control panel platform."""
if (discovery_info is None or
discovery_info[ATTR_DISCOVER_AREAS] is None):
return
entities = [SpcAlarm(hass=hass,
area_id=area['id'],
name=area['name'],
state=_get_alarm_state(area['mode']))
for area in discovery_info[ATTR_DISCOVER_AREAS]]
async_add_entities(entities)
class SpcAlarm(alarm.AlarmControlPanel):
"""Represents the SPC alarm panel."""
def __init__(self, hass, area_id, name, state):
"""Initialize the SPC alarm panel."""
self._hass = hass
self._area_id = area_id
self._name = name
self._state = state
self._api = hass.data[DATA_API]
hass.data[DATA_REGISTRY].register_alarm_device(area_id, self)
@asyncio.coroutine
def async_update_from_spc(self, state):
"""Update the alarm panel with a new state."""
self._state = state
yield from self.async_update_ha_state()
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def state(self):
"""Return the state of the device."""
return self._state
@asyncio.coroutine
def async_alarm_disarm(self, code=None):
"""Send disarm command."""
yield from self._api.send_area_command(
self._area_id, SpcWebGateway.AREA_COMMAND_UNSET)
@asyncio.coroutine
def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
yield from self._api.send_area_command(
self._area_id, SpcWebGateway.AREA_COMMAND_PART_SET)
@asyncio.coroutine
def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
yield from self._api.send_area_command(
self._area_id, SpcWebGateway.AREA_COMMAND_SET)

View File

@@ -1,17 +1,22 @@
"""Interfaces with TotalConnect alarm control panels."""
"""
Interfaces with TotalConnect alarm control panels.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.totalconnect/
"""
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
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_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_UNKNOWN,
CONF_NAME)
import homeassistant.helpers.config_validation as cv
STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED,
STATE_ALARM_ARMING, STATE_ALARM_DISARMING, STATE_UNKNOWN, CONF_NAME)
REQUIREMENTS = ['total_connect_client==0.7']
REQUIREMENTS = ['total_connect_client==0.11']
_LOGGER = logging.getLogger(__name__)
@@ -25,7 +30,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup a TotalConnect control panel."""
"""Set up a TotalConnect control panel."""
name = config.get(CONF_NAME)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
@@ -41,13 +46,13 @@ class TotalConnect(alarm.AlarmControlPanel):
"""Initialize the TotalConnect status."""
from total_connect_client import TotalConnectClient
_LOGGER.debug('Setting up TotalConnect...')
_LOGGER.debug("Setting up TotalConnect...")
self._name = name
self._username = username
self._password = password
self._state = STATE_UNKNOWN
self._client = TotalConnectClient.TotalConnectClient(username,
password)
self._client = TotalConnectClient.TotalConnectClient(
username, password)
@property
def name(self):
@@ -69,6 +74,12 @@ class TotalConnect(alarm.AlarmControlPanel):
state = STATE_ALARM_ARMED_HOME
elif status == self._client.ARMED_AWAY:
state = STATE_ALARM_ARMED_AWAY
elif status == self._client.ARMED_STAY_NIGHT:
state = STATE_ALARM_ARMED_NIGHT
elif status == self._client.ARMING:
state = STATE_ALARM_ARMING
elif status == self._client.DISARMING:
state = STATE_ALARM_DISARMING
else:
state = STATE_UNKNOWN
@@ -85,3 +96,7 @@ class TotalConnect(alarm.AlarmControlPanel):
def alarm_arm_away(self, code=None):
"""Send arm away command."""
self._client.arm_away()
def alarm_arm_night(self, code=None):
"""Send arm night command."""
self._client.arm_stay_night()

View File

@@ -5,6 +5,7 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.verisure/
"""
import logging
from time import sleep
import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.verisure import HUB as hub
@@ -17,23 +18,32 @@ _LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Verisure platform."""
"""Set up the Verisure platform."""
alarms = []
if int(hub.config.get(CONF_ALARM, 1)):
hub.update_alarms()
alarms.extend([
VerisureAlarm(value.id)
for value in hub.alarm_status.values()
])
hub.update_overview()
alarms.append(VerisureAlarm())
add_devices(alarms)
class VerisureAlarm(alarm.AlarmControlPanel):
"""Represent a Verisure alarm status."""
def set_arm_state(state, code=None):
"""Send set arm state command."""
transaction_id = hub.session.set_arm_state(code, state)[
'armStateChangeTransactionId']
_LOGGER.info('verisure set arm state %s', state)
transaction = {}
while 'result' not in transaction:
sleep(0.5)
transaction = hub.session.get_arm_state_transaction(transaction_id)
# pylint: disable=unexpected-keyword-arg
hub.update_overview(no_throttle=True)
def __init__(self, device_id):
class VerisureAlarm(alarm.AlarmControlPanel):
"""Representation of a Verisure alarm status."""
def __init__(self):
"""Initalize the Verisure alarm panel."""
self._id = device_id
self._state = STATE_UNKNOWN
self._digits = hub.config.get(CONF_CODE_DIGITS)
self._changed_by = None
@@ -41,58 +51,45 @@ class VerisureAlarm(alarm.AlarmControlPanel):
@property
def name(self):
"""Return the name of the device."""
return 'Alarm {}'.format(self._id)
return '{} alarm'.format(hub.session.installations[0]['alias'])
@property
def state(self):
"""Return the state of the device."""
return self._state
@property
def available(self):
"""Return True if entity is available."""
return hub.available
@property
def code_format(self):
"""The code format as regex."""
"""Return the code format as regex."""
return '^\\d{%s}$' % self._digits
@property
def changed_by(self):
"""Last change triggered by."""
"""Return the last change triggered by."""
return self._changed_by
def update(self):
"""Update alarm status."""
hub.update_alarms()
if hub.alarm_status[self._id].status == 'unarmed':
hub.update_overview()
status = hub.get_first("$.armState.statusType")
if status == 'DISARMED':
self._state = STATE_ALARM_DISARMED
elif hub.alarm_status[self._id].status == 'armedhome':
elif status == 'ARMED_HOME':
self._state = STATE_ALARM_ARMED_HOME
elif hub.alarm_status[self._id].status == 'armed':
elif status == 'ARMED_AWAY':
self._state = STATE_ALARM_ARMED_AWAY
elif hub.alarm_status[self._id].status != 'pending':
_LOGGER.error(
'Unknown alarm state %s',
hub.alarm_status[self._id].status)
self._changed_by = hub.alarm_status[self._id].name
elif status != 'PENDING':
_LOGGER.error('Unknown alarm state %s', status)
self._changed_by = hub.get_first("$.armState.name")
def alarm_disarm(self, code=None):
"""Send disarm command."""
hub.my_pages.alarm.set(code, 'DISARMED')
_LOGGER.info('verisure alarm disarming')
hub.my_pages.alarm.wait_while_pending()
set_arm_state('DISARMED', code)
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()
set_arm_state('ARMED_HOME', code)
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()
set_arm_state('ARMED_AWAY', code)

View File

@@ -4,6 +4,7 @@ Interfaces with Wink Cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.wink/
"""
import asyncio
import logging
import homeassistant.components.alarm_control_panel as alarm
@@ -16,11 +17,12 @@ 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."""
"""Set up the Wink platform."""
import pywink
for camera in pywink.get_cameras():
@@ -37,9 +39,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class WinkCameraDevice(WinkDevice, alarm.AlarmControlPanel):
"""Representation a Wink camera alarm."""
def __init__(self, wink, hass):
"""Initialize the Wink alarm."""
super().__init__(wink, hass)
@asyncio.coroutine
def async_added_to_hass(self):
"""Callback when entity is added to hass."""
self.hass.data[DOMAIN]['entities']['alarm_control_panel'].append(self)
@property
def state(self):

View File

@@ -8,15 +8,14 @@ import asyncio
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
import homeassistant.helpers.config_validation as cv
from homeassistant.core import callback
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.helpers.discovery import async_load_platform
from homeassistant.helpers.dispatcher import async_dispatcher_send
REQUIREMENTS = ['alarmdecoder==0.12.1.0']
REQUIREMENTS = ['alarmdecoder==0.12.3']
_LOGGER = logging.getLogger(__name__)
@@ -24,19 +23,16 @@ DOMAIN = 'alarmdecoder'
DATA_AD = 'alarmdecoder'
CONF_DEVICE = 'device'
CONF_DEVICE_TYPE = 'type'
CONF_DEVICE_HOST = 'host'
CONF_DEVICE_PORT = 'port'
CONF_DEVICE_PATH = 'path'
CONF_DEVICE_BAUD = 'baudrate'
CONF_ZONES = 'zones'
CONF_DEVICE_HOST = 'host'
CONF_DEVICE_PATH = 'path'
CONF_DEVICE_PORT = 'port'
CONF_DEVICE_TYPE = 'type'
CONF_PANEL_DISPLAY = 'panel_display'
CONF_ZONE_NAME = 'name'
CONF_ZONE_TYPE = 'type'
CONF_PANEL_DISPLAY = 'panel_display'
CONF_ZONES = 'zones'
DEFAULT_DEVICE_TYPE = 'socket'
DEFAULT_DEVICE_HOST = 'localhost'
@@ -87,7 +83,7 @@ CONFIG_SCHEMA = vol.Schema({
@asyncio.coroutine
def async_setup(hass, config):
"""Common setup for AlarmDecoder devices."""
"""Set up for the AlarmDecoder devices."""
from alarmdecoder import AlarmDecoder
from alarmdecoder.devices import (SocketDevice, SerialDevice, USBDevice)
@@ -106,28 +102,28 @@ def async_setup(hass, config):
sync_connect = asyncio.Future(loop=hass.loop)
def handle_open(device):
"""Callback for a successful connection."""
_LOGGER.info("Established a connection with the alarmdecoder.")
"""Handle the successful connection."""
_LOGGER.info("Established a connection with the alarmdecoder")
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder)
sync_connect.set_result(True)
@callback
def stop_alarmdecoder(event):
"""Callback to handle shutdown alarmdecoder."""
_LOGGER.debug("Shutting down alarmdecoder.")
"""Handle the shutdown of AlarmDecoder."""
_LOGGER.debug("Shutting down alarmdecoder")
controller.close()
@callback
def handle_message(sender, message):
"""Callback to handle message from alarmdecoder."""
"""Handle message from AlarmDecoder."""
async_dispatcher_send(hass, SIGNAL_PANEL_MESSAGE, message)
def zone_fault_callback(sender, zone):
"""Callback to handle zone fault from alarmdecoder."""
"""Handle zone fault from AlarmDecoder."""
async_dispatcher_send(hass, SIGNAL_ZONE_FAULT, zone)
def zone_restore_callback(sender, zone):
"""Callback to handle zone restore from alarmdecoder."""
"""Handle zone restore from AlarmDecoder."""
async_dispatcher_send(hass, SIGNAL_ZONE_RESTORE, zone)
controller = False
@@ -157,15 +153,16 @@ def async_setup(hass, config):
if not result:
return False
hass.async_add_job(async_load_platform(hass, 'alarm_control_panel', DOMAIN,
conf, config))
hass.async_add_job(
async_load_platform(hass, 'alarm_control_panel', DOMAIN, conf,
config))
if zones:
hass.async_add_job(async_load_platform(
hass, 'binary_sensor', DOMAIN, {CONF_ZONES: zones}, config))
if display:
hass.async_add_job(async_load_platform(hass, 'sensor', DOMAIN,
conf, config))
hass.async_add_job(async_load_platform(
hass, 'sensor', DOMAIN, conf, config))
return True

View File

@@ -25,6 +25,7 @@ _LOGGER = logging.getLogger(__name__)
DOMAIN = 'alert'
ENTITY_ID_FORMAT = DOMAIN + '.{}'
CONF_DONE_MESSAGE = 'done_message'
CONF_CAN_ACK = 'can_acknowledge'
CONF_NOTIFIERS = 'notifiers'
CONF_REPEAT = 'repeat'
@@ -35,6 +36,7 @@ DEFAULT_SKIP_FIRST = False
ALERT_SCHEMA = vol.Schema({
vol.Required(CONF_NAME): cv.string,
vol.Optional(CONF_DONE_MESSAGE, default=None): 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)]),
@@ -121,15 +123,15 @@ def async_setup(hass, config):
# 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])
alert[CONF_NAME], alert[CONF_DONE_MESSAGE],
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(
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
descriptions = descriptions.get(DOMAIN, {})
@@ -154,8 +156,8 @@ def async_setup(hass, config):
class Alert(ToggleEntity):
"""Representation of an alert."""
def __init__(self, hass, entity_id, name, watched_entity_id, state,
repeat, skip_first, notifiers, can_ack):
def __init__(self, hass, entity_id, name, done_message, watched_entity_id,
state, repeat, skip_first, notifiers, can_ack):
"""Initialize the alert."""
self.hass = hass
self._name = name
@@ -163,6 +165,7 @@ class Alert(ToggleEntity):
self._skip_first = skip_first
self._notifiers = notifiers
self._can_ack = can_ack
self._done_message = done_message
self._delay = [timedelta(minutes=val) for val in repeat]
self._next_delay = 0
@@ -170,6 +173,7 @@ class Alert(ToggleEntity):
self._firing = False
self._ack = False
self._cancel = None
self._send_done_message = False
self.entity_id = ENTITY_ID_FORMAT.format(entity_id)
event.async_track_state_change(
@@ -230,6 +234,8 @@ class Alert(ToggleEntity):
self._cancel()
self._ack = False
self._firing = False
if self._done_message and self._send_done_message:
yield from self._notify_done_message()
self.hass.async_add_job(self.async_update_ha_state)
@asyncio.coroutine
@@ -249,20 +255,30 @@ class Alert(ToggleEntity):
if not self._ack:
_LOGGER.info("Alerting: %s", self._name)
self._send_done_message = True
for target in self._notifiers:
yield from self.hass.services.async_call(
'notify', target, {'message': self._name})
yield from self._schedule_notify()
@asyncio.coroutine
def async_turn_on(self):
def _notify_done_message(self, *args):
"""Send notification of complete alert."""
_LOGGER.info("Alerting: %s", self._done_message)
self._send_done_message = False
for target in self._notifiers:
yield from self.hass.services.async_call(
'notify', target, {'message': self._done_message})
@asyncio.coroutine
def async_turn_on(self, **kwargs):
"""Async Unacknowledge alert."""
_LOGGER.debug("Reset Alert: %s", self._name)
self._ack = False
yield from self.async_update_ha_state()
@asyncio.coroutine
def async_turn_off(self):
def async_turn_off(self, **kwargs):
"""Async Acknowledge alert."""
_LOGGER.debug("Acknowledged Alert: %s", self._name)
self._ack = True

View File

@@ -15,9 +15,8 @@ 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
from homeassistant.helpers import intent, template, config_validation as cv
from homeassistant.components import http
_LOGGER = logging.getLogger(__name__)
@@ -36,7 +35,6 @@ CONF_TEXT = 'text'
CONF_FLASH_BRIEFINGS = 'flash_briefings'
CONF_UID = 'uid'
CONF_DATE = 'date'
CONF_TITLE = 'title'
CONF_AUDIO = 'audio'
CONF_TEXT = 'text'
@@ -62,6 +60,12 @@ class SpeechType(enum.Enum):
ssml = "SSML"
SPEECH_MAPPINGS = {
'plain': SpeechType.plaintext,
'ssml': SpeechType.ssml,
}
class CardType(enum.Enum):
"""The Alexa card types."""
@@ -71,24 +75,9 @@ class CardType(enum.Enum):
CONFIG_SCHEMA = vol.Schema({
DOMAIN: {
CONF_INTENTS: {
cv.string: {
vol.Optional(CONF_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_CARD): {
vol.Required(CONF_TYPE): cv.enum(CardType),
vol.Required(CONF_TITLE): cv.template,
vol.Required(CONF_CONTENT): cv.template,
},
vol.Optional(CONF_SPEECH): {
vol.Required(CONF_TYPE): cv.enum(SpeechType),
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,
@@ -99,40 +88,27 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
@asyncio.coroutine
def async_setup(hass, config):
"""Activate Alexa component."""
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(AlexaIntentsView)
hass.http.register_view(AlexaFlashBriefingView(hass, flash_briefings))
return True
class AlexaIntentsView(HomeAssistantView):
class AlexaIntentsView(http.HomeAssistantView):
"""Handle Alexa requests."""
url = INTENTS_API_ENDPOINT
name = 'api:alexa'
def __init__(self, hass, intents):
"""Initialize Alexa view."""
super().__init__()
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], "Alexa intent {}".format(name))
self.intents = intents
@asyncio.coroutine
def post(self, request):
"""Handle Alexa."""
hass = request.app['hass']
data = yield from request.json()
_LOGGER.debug('Received Alexa request: %s', data)
@@ -149,53 +125,61 @@ class AlexaIntentsView(HomeAssistantView):
if req_type == 'SessionEndedRequest':
return None
intent = req.get('intent')
response = AlexaResponse(request.app['hass'], intent)
alexa_intent_info = req.get('intent')
alexa_response = AlexaResponse(hass, alexa_intent_info)
if req_type == 'LaunchRequest':
response.add_speech(
SpeechType.plaintext,
"Hello, and welcome to the future. How may I help?")
return self.json(response)
if req_type != 'IntentRequest':
if req_type != 'IntentRequest' and req_type != 'LaunchRequest':
_LOGGER.warning('Received unsupported request: %s', req_type)
return self.json_message(
'Received unsupported request: {}'.format(req_type),
HTTP_BAD_REQUEST)
intent_name = intent['name']
config = self.intents.get(intent_name)
if req_type == 'LaunchRequest':
intent_name = data.get('session', {}) \
.get('application', {}) \
.get('applicationId')
else:
intent_name = alexa_intent_info['name']
if config is None:
try:
intent_response = yield from intent.async_handle(
hass, DOMAIN, intent_name,
{key: {'value': value} for key, value
in alexa_response.variables.items()})
except intent.UnknownIntent as err:
_LOGGER.warning('Received unknown intent %s', intent_name)
response.add_speech(
alexa_response.add_speech(
SpeechType.plaintext,
"This intent is not yet configured within Home Assistant.")
return self.json(response)
return self.json(alexa_response)
speech = config.get(CONF_SPEECH)
card = config.get(CONF_CARD)
action = config.get(CONF_ACTION)
except intent.InvalidSlotInfo as err:
_LOGGER.error('Received invalid slot data from Alexa: %s', err)
return self.json_message('Invalid slot data received',
HTTP_BAD_REQUEST)
except intent.IntentError:
_LOGGER.exception('Error handling request for %s', intent_name)
return self.json_message('Error handling intent', HTTP_BAD_REQUEST)
if action is not None:
yield from action.async_run(response.variables)
for intent_speech, alexa_speech in SPEECH_MAPPINGS.items():
if intent_speech in intent_response.speech:
alexa_response.add_speech(
alexa_speech,
intent_response.speech[intent_speech]['speech'])
break
# pylint: disable=unsubscriptable-object
if speech is not None:
response.add_speech(speech[CONF_TYPE], speech[CONF_TEXT])
if 'simple' in intent_response.card:
alexa_response.add_card(
CardType.simple, intent_response.card['simple']['title'],
intent_response.card['simple']['content'])
if card is not None:
response.add_card(card[CONF_TYPE], card[CONF_TITLE],
card[CONF_CONTENT])
return self.json(response)
return self.json(alexa_response)
class AlexaResponse(object):
"""Help generating the response for Alexa."""
def __init__(self, hass, intent=None):
def __init__(self, hass, intent_info):
"""Initialize the response."""
self.hass = hass
self.speech = None
@@ -204,8 +188,9 @@ class AlexaResponse(object):
self.session_attributes = {}
self.should_end_session = True
self.variables = {}
if intent is not None and 'slots' in intent:
for key, value in intent['slots'].items():
# Intent is None if request was a LaunchRequest or SessionEndedRequest
if intent_info is not None:
for key, value in intent_info.get('slots', {}).items():
if 'value' in value:
underscored_key = key.replace('.', '_')
self.variables[underscored_key] = value['value']
@@ -222,8 +207,8 @@ class AlexaResponse(object):
self.card = card
return
card["title"] = title.async_render(self.variables)
card["content"] = content.async_render(self.variables)
card["title"] = title
card["content"] = content
self.card = card
def add_speech(self, speech_type, text):
@@ -232,9 +217,6 @@ class AlexaResponse(object):
key = 'ssml' if speech_type == SpeechType.ssml else 'text'
if isinstance(text, template.Template):
text = text.async_render(self.variables)
self.speech = {
'type': speech_type.value,
key: text
@@ -275,7 +257,7 @@ class AlexaResponse(object):
}
class AlexaFlashBriefingView(HomeAssistantView):
class AlexaFlashBriefingView(http.HomeAssistantView):
"""Handle Alexa Flash Briefing skill requests."""
url = FLASH_BRIEFINGS_API_ENDPOINT
@@ -331,10 +313,7 @@ class AlexaFlashBriefingView(HomeAssistantView):
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)
output[ATTR_UPDATE_DATE] = datetime.now().strftime(DATE_FORMAT)
briefing.append(output)

View File

@@ -0,0 +1,147 @@
"""
This component provides basic support for Amcrest IP cameras.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/amcrest/
"""
import logging
from datetime import timedelta
import aiohttp
import voluptuous as vol
from requests.exceptions import HTTPError, ConnectTimeout
from homeassistant.const import (
CONF_NAME, CONF_HOST, CONF_PORT, CONF_USERNAME, CONF_PASSWORD,
CONF_SENSORS, CONF_SCAN_INTERVAL, HTTP_BASIC_AUTHENTICATION)
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['amcrest==1.2.1']
DEPENDENCIES = ['ffmpeg']
_LOGGER = logging.getLogger(__name__)
CONF_AUTHENTICATION = 'authentication'
CONF_RESOLUTION = 'resolution'
CONF_STREAM_SOURCE = 'stream_source'
CONF_FFMPEG_ARGUMENTS = 'ffmpeg_arguments'
DEFAULT_NAME = 'Amcrest Camera'
DEFAULT_PORT = 80
DEFAULT_RESOLUTION = 'high'
DEFAULT_STREAM_SOURCE = 'snapshot'
TIMEOUT = 10
DATA_AMCREST = 'amcrest'
DOMAIN = 'amcrest'
NOTIFICATION_ID = 'amcrest_notification'
NOTIFICATION_TITLE = 'Amcrest Camera Setup'
RESOLUTION_LIST = {
'high': 0,
'low': 1,
}
SCAN_INTERVAL = timedelta(seconds=10)
AUTHENTICATION_LIST = {
'basic': 'basic'
}
STREAM_SOURCE_LIST = {
'mjpeg': 0,
'snapshot': 1,
'rtsp': 2,
}
# Sensor types are defined like: Name, units, icon
SENSORS = {
'motion_detector': ['Motion Detected', None, 'mdi:run'],
'sdcard': ['SD Used', '%', 'mdi:sd'],
'ptz_preset': ['PTZ Preset', None, 'mdi:camera-iris'],
}
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.All(cv.ensure_list, [vol.Schema({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_AUTHENTICATION, default=HTTP_BASIC_AUTHENTICATION):
vol.All(vol.In(AUTHENTICATION_LIST)),
vol.Optional(CONF_RESOLUTION, default=DEFAULT_RESOLUTION):
vol.All(vol.In(RESOLUTION_LIST)),
vol.Optional(CONF_STREAM_SOURCE, default=DEFAULT_STREAM_SOURCE):
vol.All(vol.In(STREAM_SOURCE_LIST)),
vol.Optional(CONF_FFMPEG_ARGUMENTS): cv.string,
vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL):
cv.time_period,
vol.Optional(CONF_SENSORS, default=None):
vol.All(cv.ensure_list, [vol.In(SENSORS)]),
})])
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Set up the Amcrest IP Camera component."""
from amcrest import AmcrestCamera
amcrest_cams = config[DOMAIN]
for device in amcrest_cams:
camera = AmcrestCamera(device.get(CONF_HOST),
device.get(CONF_PORT),
device.get(CONF_USERNAME),
device.get(CONF_PASSWORD)).camera
try:
camera.current_time
except (ConnectTimeout, HTTPError) as ex:
_LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex))
hass.components.persistent_notification.create(
'Error: {}<br />'
'You will need to restart hass after fixing.'
''.format(ex),
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
ffmpeg_arguments = device.get(CONF_FFMPEG_ARGUMENTS)
name = device.get(CONF_NAME)
resolution = RESOLUTION_LIST[device.get(CONF_RESOLUTION)]
sensors = device.get(CONF_SENSORS)
stream_source = STREAM_SOURCE_LIST[device.get(CONF_STREAM_SOURCE)]
username = device.get(CONF_USERNAME)
password = device.get(CONF_PASSWORD)
# currently aiohttp only works with basic authentication
# only valid for mjpeg streaming
if username is not None and password is not None:
if device.get(CONF_AUTHENTICATION) == HTTP_BASIC_AUTHENTICATION:
authentication = aiohttp.BasicAuth(username, password)
else:
authentication = None
discovery.load_platform(
hass, 'camera', DOMAIN, {
'device': camera,
CONF_AUTHENTICATION: authentication,
CONF_FFMPEG_ARGUMENTS: ffmpeg_arguments,
CONF_NAME: name,
CONF_RESOLUTION: resolution,
CONF_STREAM_SOURCE: stream_source,
}, config)
if sensors:
discovery.load_platform(
hass, 'sensor', DOMAIN, {
'device': camera,
CONF_NAME: name,
CONF_SENSORS: sensors,
}, config)
return True

View File

@@ -13,7 +13,7 @@ from homeassistant.const import (CONF_HOST, CONF_PORT)
import homeassistant.helpers.config_validation as cv
from homeassistant.util import Throttle
REQUIREMENTS = ['apcaccess==0.0.4']
REQUIREMENTS = ['apcaccess==0.0.13']
_LOGGER = logging.getLogger(__name__)

View File

@@ -83,7 +83,7 @@ class APIEventStream(HomeAssistantView):
stop_obj = object()
to_write = asyncio.Queue(loop=hass.loop)
restrict = request.GET.get('restrict')
restrict = request.query.get('restrict')
if restrict:
restrict = restrict.split(',') + [EVENT_HOMEASSISTANT_STOP]
@@ -198,8 +198,7 @@ class APIEntityStateView(HomeAssistantView):
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)
return self.json_message('Entity not found', HTTP_NOT_FOUND)
@asyncio.coroutine
def post(self, request, entity_id):
@@ -213,7 +212,7 @@ class APIEntityStateView(HomeAssistantView):
new_state = data.get('state')
if not new_state:
if new_state is None:
return self.json_message('No state specified', HTTP_BAD_REQUEST)
attributes = data.get('attributes')
@@ -237,8 +236,7 @@ class APIEntityStateView(HomeAssistantView):
"""Remove entity."""
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)
return self.json_message('Entity not found', HTTP_NOT_FOUND)
class APIEventListenersView(HomeAssistantView):

View File

@@ -5,13 +5,12 @@ 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.helpers import intent, template
from homeassistant.components.http import HomeAssistantView
_LOGGER = logging.getLogger(__name__)
@@ -29,24 +28,14 @@ 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
}
}
}
DOMAIN: {}
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
@asyncio.coroutine
def async_setup(hass, config):
"""Activate API.AI component."""
intents = config[DOMAIN].get(CONF_INTENTS, {})
hass.http.register_view(ApiaiIntentsView(hass, intents))
hass.http.register_view(ApiaiIntentsView)
return True
@@ -57,24 +46,10 @@ class ApiaiIntentsView(HomeAssistantView):
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."""
hass = request.app['hass']
data = yield from request.json()
_LOGGER.debug("Received api.ai request: %s", data)
@@ -91,55 +66,41 @@ class ApiaiIntentsView(HomeAssistantView):
if action_incomplete:
return None
# use intent to no mix HASS actions with this parameter
intent = req.get('action')
action = req.get('action')
parameters = req.get('parameters')
# contexts = req.get('contexts')
response = ApiaiResponse(parameters)
apiai_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 == "":
if action == "":
_LOGGER.warning("Received intent with empty action")
response.add_speech(
apiai_response.add_speech(
"You have not defined an action in your api.ai intent.")
return self.json(response)
return self.json(apiai_response)
config = self.intents.get(intent)
try:
intent_response = yield from intent.async_handle(
hass, DOMAIN, action,
{key: {'value': value} for key, value
in parameters.items()})
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)
except intent.UnknownIntent as err:
_LOGGER.warning('Received unknown intent %s', action)
apiai_response.add_speech(
"This intent is not yet configured within Home Assistant.")
return self.json(apiai_response)
speech = config.get(CONF_SPEECH)
action = config.get(CONF_ACTION)
async_action = config.get(CONF_ASYNC_ACTION)
except intent.InvalidSlotInfo as err:
_LOGGER.error('Received invalid slot data: %s', err)
return self.json_message('Invalid slot data received',
HTTP_BAD_REQUEST)
except intent.IntentError:
_LOGGER.exception('Error handling request for %s', action)
return self.json_message('Error handling intent', HTTP_BAD_REQUEST)
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)
if 'plain' in intent_response.speech:
apiai_response.add_speech(
intent_response.speech['plain']['speech'])
# pylint: disable=unsubscriptable-object
if speech is not None:
response.add_speech(speech)
return self.json(response)
return self.json(apiai_response)
class ApiaiResponse(object):

View File

@@ -0,0 +1,253 @@
"""
Support for Apple TV.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/apple_tv/
"""
import os
import asyncio
import logging
import voluptuous as vol
from homeassistant.const import (CONF_HOST, CONF_NAME, ATTR_ENTITY_ID)
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers import discovery
from homeassistant.components.discovery import SERVICE_APPLE_TV
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyatv==0.3.4']
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'apple_tv'
SERVICE_SCAN = 'apple_tv_scan'
SERVICE_AUTHENTICATE = 'apple_tv_authenticate'
ATTR_ATV = 'atv'
ATTR_POWER = 'power'
CONF_LOGIN_ID = 'login_id'
CONF_START_OFF = 'start_off'
CONF_CREDENTIALS = 'credentials'
DEFAULT_NAME = 'Apple TV'
DATA_APPLE_TV = 'data_apple_tv'
DATA_ENTITIES = 'data_apple_tv_entities'
KEY_CONFIG = 'apple_tv_configuring'
NOTIFICATION_AUTH_ID = 'apple_tv_auth_notification'
NOTIFICATION_AUTH_TITLE = 'Apple TV Authentication'
NOTIFICATION_SCAN_ID = 'apple_tv_scan_notification'
NOTIFICATION_SCAN_TITLE = 'Apple TV Scan'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.All(cv.ensure_list, [vol.Schema({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_LOGIN_ID): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_CREDENTIALS, default=None): cv.string,
vol.Optional(CONF_START_OFF, default=False): cv.boolean
})])
}, extra=vol.ALLOW_EXTRA)
# Currently no attributes but it might change later
APPLE_TV_SCAN_SCHEMA = vol.Schema({})
APPLE_TV_AUTHENTICATE_SCHEMA = vol.Schema({
ATTR_ENTITY_ID: cv.entity_ids,
})
def request_configuration(hass, config, atv, credentials):
"""Request configuration steps from the user."""
configurator = hass.components.configurator
@asyncio.coroutine
def configuration_callback(callback_data):
"""Handle the submitted configuration."""
from pyatv import exceptions
pin = callback_data.get('pin')
try:
yield from atv.airplay.finish_authentication(pin)
hass.components.persistent_notification.async_create(
'Authentication succeeded!<br /><br />Add the following '
'to credentials: in your apple_tv configuration:<br /><br />'
'{0}'.format(credentials),
title=NOTIFICATION_AUTH_TITLE,
notification_id=NOTIFICATION_AUTH_ID)
except exceptions.DeviceAuthenticationError as ex:
hass.components.persistent_notification.async_create(
'Authentication failed! Did you enter correct PIN?<br /><br />'
'Details: {0}'.format(ex),
title=NOTIFICATION_AUTH_TITLE,
notification_id=NOTIFICATION_AUTH_ID)
hass.async_add_job(configurator.request_done, instance)
instance = configurator.request_config(
'Apple TV Authentication', configuration_callback,
description='Please enter PIN code shown on screen.',
submit_caption='Confirm',
fields=[{'id': 'pin', 'name': 'PIN Code', 'type': 'password'}]
)
@asyncio.coroutine
def scan_for_apple_tvs(hass):
"""Scan for devices and present a notification of the ones found."""
import pyatv
atvs = yield from pyatv.scan_for_apple_tvs(hass.loop, timeout=3)
devices = []
for atv in atvs:
login_id = atv.login_id
if login_id is None:
login_id = 'Home Sharing disabled'
devices.append('Name: {0}<br />Host: {1}<br />Login ID: {2}'.format(
atv.name, atv.address, login_id))
if not devices:
devices = ['No device(s) found']
hass.components.persistent_notification.async_create(
'The following devices were found:<br /><br />' +
'<br /><br />'.join(devices),
title=NOTIFICATION_SCAN_TITLE,
notification_id=NOTIFICATION_SCAN_ID)
@asyncio.coroutine
def async_setup(hass, config):
"""Set up the Apple TV component."""
if DATA_APPLE_TV not in hass.data:
hass.data[DATA_APPLE_TV] = {}
@asyncio.coroutine
def async_service_handler(service):
"""Handler for service calls."""
entity_ids = service.data.get(ATTR_ENTITY_ID)
if entity_ids:
devices = [device for device in hass.data[DATA_ENTITIES]
if device.entity_id in entity_ids]
else:
devices = hass.data[DATA_ENTITIES]
for device in devices:
atv = device.atv
if service.service == SERVICE_AUTHENTICATE:
credentials = yield from atv.airplay.generate_credentials()
yield from atv.airplay.load_credentials(credentials)
_LOGGER.debug('Generated new credentials: %s', credentials)
yield from atv.airplay.start_authentication()
hass.async_add_job(request_configuration,
hass, config, atv, credentials)
elif service.service == SERVICE_SCAN:
hass.async_add_job(scan_for_apple_tvs, hass)
@asyncio.coroutine
def atv_discovered(service, info):
"""Setup an Apple TV that was auto discovered."""
yield from _setup_atv(hass, {
CONF_NAME: info['name'],
CONF_HOST: info['host'],
CONF_LOGIN_ID: info['properties']['hG'],
CONF_START_OFF: False
})
discovery.async_listen(hass, SERVICE_APPLE_TV, atv_discovered)
tasks = [_setup_atv(hass, conf) for conf in config.get(DOMAIN, [])]
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_SCAN, async_service_handler,
descriptions.get(SERVICE_SCAN),
schema=APPLE_TV_SCAN_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_AUTHENTICATE, async_service_handler,
descriptions.get(SERVICE_AUTHENTICATE),
schema=APPLE_TV_AUTHENTICATE_SCHEMA)
return True
@asyncio.coroutine
def _setup_atv(hass, atv_config):
"""Setup an Apple TV."""
import pyatv
name = atv_config.get(CONF_NAME)
host = atv_config.get(CONF_HOST)
login_id = atv_config.get(CONF_LOGIN_ID)
start_off = atv_config.get(CONF_START_OFF)
credentials = atv_config.get(CONF_CREDENTIALS)
if host in hass.data[DATA_APPLE_TV]:
return
details = pyatv.AppleTVDevice(name, host, login_id)
session = async_get_clientsession(hass)
atv = pyatv.connect_to_apple_tv(details, hass.loop, session=session)
if credentials:
yield from atv.airplay.load_credentials(credentials)
power = AppleTVPowerManager(hass, atv, start_off)
hass.data[DATA_APPLE_TV][host] = {
ATTR_ATV: atv,
ATTR_POWER: power
}
hass.async_add_job(discovery.async_load_platform(
hass, 'media_player', DOMAIN, atv_config))
hass.async_add_job(discovery.async_load_platform(
hass, 'remote', DOMAIN, atv_config))
class AppleTVPowerManager:
"""Manager for global power management of an Apple TV.
An instance is used per device to share the same power state between
several platforms.
"""
def __init__(self, hass, atv, is_off):
"""Initialize power manager."""
self.hass = hass
self.atv = atv
self.listeners = []
self._is_on = not is_off
def init(self):
"""Initialize power management."""
if self._is_on:
self.atv.push_updater.start()
@property
def turned_on(self):
"""If device is on or off."""
return self._is_on
def set_power_on(self, value):
"""Change if a device is on or off."""
if value != self._is_on:
self._is_on = value
if not self._is_on:
self.atv.push_updater.stop()
else:
self.atv.push_updater.start()
for listener in self.listeners:
self.hass.async_add_job(listener.async_update_ha_state())

View File

@@ -0,0 +1,58 @@
"""
This component provides basic support for Netgear Arlo IP cameras.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/arlo/
"""
import logging
import voluptuous as vol
from requests.exceptions import HTTPError, ConnectTimeout
from homeassistant.helpers import config_validation as cv
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD
REQUIREMENTS = ['pyarlo==0.0.4']
_LOGGER = logging.getLogger(__name__)
CONF_ATTRIBUTION = "Data provided by arlo.netgear.com"
DATA_ARLO = 'data_arlo'
DEFAULT_BRAND = 'Netgear Arlo'
DOMAIN = 'arlo'
NOTIFICATION_ID = 'arlo_notification'
NOTIFICATION_TITLE = 'Arlo Camera Setup'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
}),
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Set up an Arlo component."""
conf = config[DOMAIN]
username = conf.get(CONF_USERNAME)
password = conf.get(CONF_PASSWORD)
try:
from pyarlo import PyArlo
arlo = PyArlo(username, password, preload=False)
if not arlo.is_connected:
return False
hass.data[DATA_ARLO] = arlo
except (ConnectTimeout, HTTPError) as ex:
_LOGGER.error("Unable to connect to Netgar Arlo: %s", str(ex))
hass.components.persistent_notification.create(
'Error: {}<br />'
'You will need to restart hass after fixing.'
''.format(ex),
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
return True

View File

@@ -0,0 +1,82 @@
"""Support for Asterisk Voicemail interface."""
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers import discovery
from homeassistant.const import (CONF_HOST,
CONF_PORT, CONF_PASSWORD)
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import (async_dispatcher_connect,
async_dispatcher_send)
REQUIREMENTS = ['asterisk_mbox==0.4.0']
SIGNAL_MESSAGE_UPDATE = 'asterisk_mbox.message_updated'
SIGNAL_MESSAGE_REQUEST = 'asterisk_mbox.message_request'
DOMAIN = 'asterisk_mbox'
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PORT): int,
vol.Required(CONF_PASSWORD): cv.string,
}),
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config):
"""Set up for the Asterisk Voicemail box."""
conf = config.get(DOMAIN)
host = conf.get(CONF_HOST)
port = conf.get(CONF_PORT)
password = conf.get(CONF_PASSWORD)
hass.data[DOMAIN] = AsteriskData(hass, host, port, password)
discovery.load_platform(hass, "mailbox", DOMAIN, {}, config)
return True
class AsteriskData(object):
"""Store Asterisk mailbox data."""
def __init__(self, hass, host, port, password):
"""Init the Asterisk data object."""
from asterisk_mbox import Client as asteriskClient
self.hass = hass
self.client = asteriskClient(host, port, password, self.handle_data)
self.messages = []
async_dispatcher_connect(
self.hass, SIGNAL_MESSAGE_REQUEST, self._request_messages)
@callback
def handle_data(self, command, msg):
"""Handle changes to the mailbox."""
from asterisk_mbox.commands import CMD_MESSAGE_LIST
if command == CMD_MESSAGE_LIST:
_LOGGER.info("AsteriskVM sent updated message list")
self.messages = sorted(msg,
key=lambda item: item['info']['origtime'],
reverse=True)
async_dispatcher_send(self.hass, SIGNAL_MESSAGE_UPDATE,
self.messages)
@callback
def _request_messages(self):
"""Handle changes to the mailbox."""
_LOGGER.info("Requesting message list")
self.client.messages()

View File

@@ -13,10 +13,11 @@ import voluptuous as vol
from homeassistant.setup import async_prepare_setup_platform
from homeassistant.core import CoreState
from homeassistant.loader import bind_hass
from homeassistant import config as conf_util
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_PLATFORM, STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF,
SERVICE_TOGGLE, SERVICE_RELOAD, EVENT_HOMEASSISTANT_START)
SERVICE_TOGGLE, SERVICE_RELOAD, EVENT_HOMEASSISTANT_START, CONF_ID)
from homeassistant.components import logbook
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import extract_domain_configs, script, condition
@@ -28,6 +29,7 @@ from homeassistant.util.dt import utcnow
import homeassistant.helpers.config_validation as cv
DOMAIN = 'automation'
DEPENDENCIES = ['group']
ENTITY_ID_FORMAT = DOMAIN + '.{}'
GROUP_NAME_ALL_AUTOMATIONS = 'all automations'
@@ -81,6 +83,8 @@ _TRIGGER_SCHEMA = vol.All(
_CONDITION_SCHEMA = vol.All(cv.ensure_list, [cv.CONDITION_SCHEMA])
PLATFORM_SCHEMA = vol.Schema({
# str on purpose
CONF_ID: str,
CONF_ALIAS: cv.string,
vol.Optional(CONF_INITIAL_STATE): cv.boolean,
vol.Optional(CONF_HIDE_ENTITY, default=DEFAULT_HIDE_ENTITY): cv.boolean,
@@ -101,6 +105,7 @@ TRIGGER_SERVICE_SCHEMA = vol.Schema({
RELOAD_SERVICE_SCHEMA = vol.Schema({})
@bind_hass
def is_on(hass, entity_id):
"""
Return true if specified automation entity_id is on.
@@ -110,48 +115,59 @@ def is_on(hass, entity_id):
return hass.states.is_state(entity_id, STATE_ON)
@bind_hass
def turn_on(hass, entity_id=None):
"""Turn on specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {}
hass.services.call(DOMAIN, SERVICE_TURN_ON, data)
@bind_hass
def turn_off(hass, entity_id=None):
"""Turn off specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {}
hass.services.call(DOMAIN, SERVICE_TURN_OFF, data)
@bind_hass
def toggle(hass, entity_id=None):
"""Toggle specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {}
hass.services.call(DOMAIN, SERVICE_TOGGLE, data)
@bind_hass
def trigger(hass, entity_id=None):
"""Trigger specified automation or all."""
data = {ATTR_ENTITY_ID: entity_id} if entity_id else {}
hass.services.call(DOMAIN, SERVICE_TRIGGER, data)
@bind_hass
def reload(hass):
"""Reload the automation from config."""
hass.services.call(DOMAIN, SERVICE_RELOAD)
@bind_hass
def async_reload(hass):
"""Reload the automation from config.
Returns a coroutine object.
"""
return hass.services.async_call(DOMAIN, SERVICE_RELOAD)
@asyncio.coroutine
def async_setup(hass, config):
"""Setup the automation."""
"""Set up the automation."""
component = EntityComponent(_LOGGER, DOMAIN, hass,
group_name=GROUP_NAME_ALL_AUTOMATIONS)
success = yield from _async_process_config(hass, config, component)
yield from _async_process_config(hass, config, component)
if not success:
return False
descriptions = yield from hass.loop.run_in_executor(
None, conf_util.load_yaml_config_file, os.path.join(
descriptions = yield from hass.async_add_job(
conf_util.load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
@@ -221,9 +237,10 @@ def async_setup(hass, config):
class AutomationEntity(ToggleEntity):
"""Entity to show status of entity."""
def __init__(self, name, async_attach_triggers, cond_func, async_action,
hidden, initial_state):
def __init__(self, automation_id, name, async_attach_triggers, cond_func,
async_action, hidden, initial_state):
"""Initialize an automation entity."""
self._id = automation_id
self._name = name
self._async_attach_triggers = async_attach_triggers
self._async_detach_triggers = None
@@ -346,6 +363,16 @@ class AutomationEntity(ToggleEntity):
self.async_trigger)
yield from self.async_update_ha_state()
@property
def device_state_attributes(self):
"""Return automation attributes."""
if self._id is None:
return None
return {
CONF_ID: self._id
}
@asyncio.coroutine
def _async_process_config(hass, config, component):
@@ -359,6 +386,7 @@ def _async_process_config(hass, config, component):
conf = config[config_key]
for list_no, config_block in enumerate(conf):
automation_id = config_block.get(CONF_ID)
name = config_block.get(CONF_ALIAS) or "{} {}".format(config_key,
list_no)
@@ -383,16 +411,14 @@ def _async_process_config(hass, config, component):
config_block.get(CONF_TRIGGER, []), name
)
entity = AutomationEntity(
name, async_attach_triggers, cond_func, action, hidden,
initial_state)
automation_id, name, async_attach_triggers, cond_func, action,
hidden, initial_state)
entities.append(entity)
if entities:
yield from component.async_add_entities(entities)
return len(entities) > 0
def _async_get_action(hass, config, name):
"""Return an action based on a configuration."""
@@ -400,7 +426,7 @@ def _async_get_action(hass, config, name):
@asyncio.coroutine
def action(entity_id, variables):
"""Action to be executed."""
"""Execute an action."""
_LOGGER.info('Executing %s', name)
logbook.async_log_entry(
hass, name, 'has been triggered', DOMAIN, entity_id)
@@ -430,7 +456,7 @@ def _async_process_if(hass, config, p_config):
@asyncio.coroutine
def _async_process_trigger(hass, config, trigger_configs, name, action):
"""Setup the triggers.
"""Set up the triggers.
This method is a coroutine.
"""

View File

@@ -9,12 +9,12 @@ import logging
import voluptuous as vol
from homeassistant.core import callback, CoreState
from homeassistant.const import CONF_PLATFORM, EVENT_HOMEASSISTANT_START
from homeassistant.core import callback
from homeassistant.const import CONF_PLATFORM
from homeassistant.helpers import config_validation as cv
CONF_EVENT_TYPE = "event_type"
CONF_EVENT_DATA = "event_data"
CONF_EVENT_TYPE = 'event_type'
CONF_EVENT_DATA = 'event_data'
_LOGGER = logging.getLogger(__name__)
@@ -31,19 +31,6 @@ def async_trigger(hass, config, action):
event_type = config.get(CONF_EVENT_TYPE)
event_data = config.get(CONF_EVENT_DATA)
if (event_type == EVENT_HOMEASSISTANT_START and
hass.state == CoreState.starting):
_LOGGER.warning('Deprecation: Automations should not listen to event '
"'homeassistant_start'. Use platform 'homeassistant' "
'instead. Feature will be removed in 0.45')
hass.async_run_job(action, {
'trigger': {
'platform': 'event',
'event': None,
},
})
return lambda: None
@callback
def handle_event(event):
"""Listen for events and calls the action when data matches."""

View File

@@ -31,7 +31,7 @@ def async_trigger(hass, config, action):
if event == EVENT_SHUTDOWN:
@callback
def hass_shutdown(event):
"""Called when Home Assistant is shutting down."""
"""Execute when Home Assistant is shutting down."""
hass.async_run_job(action, {
'trigger': {
'platform': 'homeassistant',

View File

@@ -14,11 +14,10 @@ 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"
CONF_FROM = "from"
CONF_TO = "to"
CONF_STATE = "state"
CONF_FOR = "for"
CONF_ENTITY_ID = 'entity_id'
CONF_FROM = 'from'
CONF_TO = 'to'
CONF_FOR = 'for'
TRIGGER_SCHEMA = vol.All(
vol.Schema({
@@ -27,11 +26,9 @@ TRIGGER_SCHEMA = vol.All(
# These are str on purpose. Want to catch YAML conversions
CONF_FROM: str,
CONF_TO: str,
CONF_STATE: str,
CONF_FOR: vol.All(cv.time_period, cv.positive_timedelta),
}),
vol.Any(cv.key_dependency(CONF_FOR, CONF_TO),
cv.key_dependency(CONF_FOR, CONF_STATE))
cv.key_dependency(CONF_FOR, CONF_TO),
)
@@ -40,10 +37,11 @@ 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
to_state = config.get(CONF_TO, MATCH_ALL)
time_delta = config.get(CONF_FOR)
async_remove_state_for_cancel = None
async_remove_state_for_listener = None
match_all = (from_state == MATCH_ALL and to_state == MATCH_ALL)
@callback
def clear_listener():
@@ -75,6 +73,11 @@ def async_trigger(hass, config, action):
}
})
# Ignore changes to state attributes if from/to is in use
if (not match_all and from_s is not None and to_s is not None and
from_s.last_changed == to_s.last_changed):
return
if time_delta is None:
call_action()
return

View File

@@ -16,8 +16,6 @@ from homeassistant.const import (
from homeassistant.helpers.event import async_track_sunrise, async_track_sunset
import homeassistant.helpers.config_validation as cv
DEPENDENCIES = ['sun']
_LOGGER = logging.getLogger(__name__)
TRIGGER_SCHEMA = vol.Schema({
@@ -44,8 +42,6 @@ def async_trigger(hass, config, action):
},
})
# Do something to call action
if event == SUN_EVENT_SUNRISE:
return async_track_sunrise(hass, call_action, offset)
else:
return async_track_sunset(hass, call_action, offset)
return async_track_sunset(hass, call_action, offset)

View File

@@ -10,32 +10,31 @@ import logging
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import CONF_AFTER, CONF_PLATFORM
from homeassistant.const import CONF_AT, CONF_PLATFORM
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.event import async_track_time_change
CONF_HOURS = "hours"
CONF_MINUTES = "minutes"
CONF_SECONDS = "seconds"
CONF_HOURS = 'hours'
CONF_MINUTES = 'minutes'
CONF_SECONDS = 'seconds'
_LOGGER = logging.getLogger(__name__)
TRIGGER_SCHEMA = vol.All(vol.Schema({
vol.Required(CONF_PLATFORM): 'time',
CONF_AFTER: cv.time,
CONF_AT: cv.time,
CONF_HOURS: vol.Any(vol.Coerce(int), vol.Coerce(str)),
CONF_MINUTES: vol.Any(vol.Coerce(int), vol.Coerce(str)),
CONF_SECONDS: vol.Any(vol.Coerce(int), vol.Coerce(str)),
}), cv.has_at_least_one_key(CONF_HOURS, CONF_MINUTES,
CONF_SECONDS, CONF_AFTER))
}), cv.has_at_least_one_key(CONF_HOURS, CONF_MINUTES, CONF_SECONDS, CONF_AT))
@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)
hours, minutes, seconds = after.hour, after.minute, after.second
if CONF_AT in config:
at_time = config.get(CONF_AT)
hours, minutes, seconds = at_time.hour, at_time.minute, at_time.second
else:
hours = config.get(CONF_HOURS)
minutes = config.get(CONF_MINUTES)

View File

@@ -14,8 +14,8 @@ from homeassistant.helpers.event import async_track_state_change
from homeassistant.helpers import (
condition, config_validation as cv, location)
EVENT_ENTER = "enter"
EVENT_LEAVE = "leave"
EVENT_ENTER = 'enter'
EVENT_LEAVE = 'leave'
DEFAULT_EVENT = EVENT_ENTER
TRIGGER_SCHEMA = vol.Schema({

View File

@@ -0,0 +1,371 @@
"""
Support for Axis devices.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/axis/
"""
import json
import logging
import os
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (ATTR_LOCATION, ATTR_TRIPPED,
CONF_HOST, CONF_INCLUDE, CONF_NAME,
CONF_PASSWORD, CONF_TRIGGER_TIME,
CONF_USERNAME, EVENT_HOMEASSISTANT_STOP)
from homeassistant.components.discovery import SERVICE_AXIS
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import discovery
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.entity import Entity
REQUIREMENTS = ['axis==8']
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'axis'
CONFIG_FILE = 'axis.conf'
AXIS_DEVICES = {}
EVENT_TYPES = ['motion', 'vmd3', 'pir', 'sound',
'daynight', 'tampering', 'input']
PLATFORMS = ['camera']
AXIS_INCLUDE = EVENT_TYPES + PLATFORMS
AXIS_DEFAULT_HOST = '192.168.0.90'
AXIS_DEFAULT_USERNAME = 'root'
AXIS_DEFAULT_PASSWORD = 'pass'
DEVICE_SCHEMA = vol.Schema({
vol.Required(CONF_INCLUDE):
vol.All(cv.ensure_list, [vol.In(AXIS_INCLUDE)]),
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_HOST, default=AXIS_DEFAULT_HOST): cv.string,
vol.Optional(CONF_USERNAME, default=AXIS_DEFAULT_USERNAME): cv.string,
vol.Optional(CONF_PASSWORD, default=AXIS_DEFAULT_PASSWORD): cv.string,
vol.Optional(CONF_TRIGGER_TIME, default=0): cv.positive_int,
vol.Optional(ATTR_LOCATION, default=''): cv.string,
})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: DEVICE_SCHEMA,
}),
}, extra=vol.ALLOW_EXTRA)
SERVICE_VAPIX_CALL = 'vapix_call'
SERVICE_VAPIX_CALL_RESPONSE = 'vapix_call_response'
SERVICE_CGI = 'cgi'
SERVICE_ACTION = 'action'
SERVICE_PARAM = 'param'
SERVICE_DEFAULT_CGI = 'param.cgi'
SERVICE_DEFAULT_ACTION = 'update'
SERVICE_SCHEMA = vol.Schema({
vol.Required(CONF_NAME): cv.string,
vol.Required(SERVICE_PARAM): cv.string,
vol.Optional(SERVICE_CGI, default=SERVICE_DEFAULT_CGI): cv.string,
vol.Optional(SERVICE_ACTION, default=SERVICE_DEFAULT_ACTION): cv.string,
})
def request_configuration(hass, name, host, serialnumber):
"""Request configuration steps from the user."""
configurator = hass.components.configurator
def configuration_callback(callback_data):
"""Called when config is submitted."""
if CONF_INCLUDE not in callback_data:
configurator.notify_errors(request_id,
"Functionality mandatory.")
return False
callback_data[CONF_INCLUDE] = callback_data[CONF_INCLUDE].split()
callback_data[CONF_HOST] = host
if CONF_NAME not in callback_data:
callback_data[CONF_NAME] = name
try:
config = DEVICE_SCHEMA(callback_data)
except vol.Invalid:
configurator.notify_errors(request_id,
"Bad input, please check spelling.")
return False
if setup_device(hass, config):
config_file = _read_config(hass)
config_file[serialnumber] = dict(config)
del config_file[serialnumber]['hass']
_write_config(hass, config_file)
configurator.request_done(request_id)
else:
configurator.notify_errors(request_id,
"Failed to register, please try again.")
return False
title = '{} ({})'.format(name, host)
request_id = configurator.request_config(
title, configuration_callback,
description='Functionality: ' + str(AXIS_INCLUDE),
entity_picture="/static/images/logo_axis.png",
link_name='Axis platform documentation',
link_url='https://home-assistant.io/components/axis/',
submit_caption="Confirm",
fields=[
{'id': CONF_NAME,
'name': "Device name",
'type': 'text'},
{'id': CONF_USERNAME,
'name': "User name",
'type': 'text'},
{'id': CONF_PASSWORD,
'name': 'Password',
'type': 'password'},
{'id': CONF_INCLUDE,
'name': "Device functionality (space separated list)",
'type': 'text'},
{'id': ATTR_LOCATION,
'name': "Physical location of device (optional)",
'type': 'text'},
{'id': CONF_TRIGGER_TIME,
'name': "Sensor update interval (optional)",
'type': 'number'},
]
)
def setup(hass, base_config):
"""Common setup for Axis devices."""
def _shutdown(call): # pylint: disable=unused-argument
"""Stop the metadatastream on shutdown."""
for serialnumber, device in AXIS_DEVICES.items():
_LOGGER.info("Stopping metadatastream for %s.", serialnumber)
device.stop_metadatastream()
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, _shutdown)
def axis_device_discovered(service, discovery_info):
"""Called when axis devices has been found."""
host = discovery_info[CONF_HOST]
name = discovery_info['hostname']
serialnumber = discovery_info['properties']['macaddress']
if serialnumber not in AXIS_DEVICES:
config_file = _read_config(hass)
if serialnumber in config_file:
# Device config saved to file
try:
config = DEVICE_SCHEMA(config_file[serialnumber])
config[CONF_HOST] = host
except vol.Invalid as err:
_LOGGER.error("Bad data from %s. %s", CONFIG_FILE, err)
return False
if not setup_device(hass, config):
_LOGGER.error("Couldn\'t set up %s", config[CONF_NAME])
else:
# New device, create configuration request for UI
request_configuration(hass, name, host, serialnumber)
else:
# Device already registered, but on a different IP
device = AXIS_DEVICES[serialnumber]
device.url = host
async_dispatcher_send(hass,
DOMAIN + '_' + device.name + '_new_ip',
host)
# Register discovery service
discovery.listen(hass, SERVICE_AXIS, axis_device_discovered)
if DOMAIN in base_config:
for device in base_config[DOMAIN]:
config = base_config[DOMAIN][device]
if CONF_NAME not in config:
config[CONF_NAME] = device
if not setup_device(hass, config):
_LOGGER.error("Couldn\'t set up %s", config[CONF_NAME])
# Services to communicate with device.
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
def vapix_service(call):
"""Service to send a message."""
for _, device in AXIS_DEVICES.items():
if device.name == call.data[CONF_NAME]:
response = device.do_request(call.data[SERVICE_CGI],
call.data[SERVICE_ACTION],
call.data[SERVICE_PARAM])
hass.bus.async_fire(SERVICE_VAPIX_CALL_RESPONSE, response)
return True
_LOGGER.info("Couldn\'t find device %s", call.data[CONF_NAME])
return False
# Register service with Home Assistant.
hass.services.register(DOMAIN,
SERVICE_VAPIX_CALL,
vapix_service,
descriptions[DOMAIN][SERVICE_VAPIX_CALL],
schema=SERVICE_SCHEMA)
return True
def setup_device(hass, config):
"""Set up device."""
from axis import AxisDevice
config['hass'] = hass
device = AxisDevice(config) # Initialize device
enable_metadatastream = False
if device.serial_number is None:
# If there is no serial number a connection could not be made
_LOGGER.error("Couldn\'t connect to %s", config[CONF_HOST])
return False
for component in config[CONF_INCLUDE]:
if component in EVENT_TYPES:
# Sensors are created by device calling event_initialized
# when receiving initialize messages on metadatastream
device.add_event_topic(convert(component, 'type', 'subscribe'))
if not enable_metadatastream:
enable_metadatastream = True
else:
discovery.load_platform(hass, component, DOMAIN, config)
if enable_metadatastream:
device.initialize_new_event = event_initialized
if not device.initiate_metadatastream():
hass.components.persistent_notification.create(
'Dependency missing for sensors, '
'please check documentation',
title=DOMAIN,
notification_id='axis_notification')
AXIS_DEVICES[device.serial_number] = device
return True
def _read_config(hass):
"""Read Axis config."""
path = hass.config.path(CONFIG_FILE)
if not os.path.isfile(path):
return {}
with open(path) as f_handle:
# Guard against empty file
return json.loads(f_handle.read() or '{}')
def _write_config(hass, config):
"""Write Axis config."""
data = json.dumps(config)
with open(hass.config.path(CONFIG_FILE), 'w', encoding='utf-8') as outfile:
outfile.write(data)
def event_initialized(event):
"""Register event initialized on metadatastream here."""
hass = event.device_config('hass')
discovery.load_platform(hass,
convert(event.topic, 'topic', 'platform'),
DOMAIN, {'axis_event': event})
class AxisDeviceEvent(Entity):
"""Representation of a Axis device event."""
def __init__(self, axis_event):
"""Initialize the event."""
self.axis_event = axis_event
self._event_class = convert(self.axis_event.topic, 'topic', 'class')
self._name = '{}_{}_{}'.format(self.axis_event.device_name,
convert(self.axis_event.topic,
'topic', 'type'),
self.axis_event.id)
self.axis_event.callback = self._update_callback
def _update_callback(self):
"""Update the sensor's state, if needed."""
self.update()
self.schedule_update_ha_state()
@property
def name(self):
"""Return the name of the event."""
return self._name
@property
def device_class(self):
"""Return the class of the event."""
return self._event_class
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def device_state_attributes(self):
"""Return the state attributes of the event."""
attr = {}
tripped = self.axis_event.is_tripped
attr[ATTR_TRIPPED] = 'True' if tripped else 'False'
location = self.axis_event.device_config(ATTR_LOCATION)
if location:
attr[ATTR_LOCATION] = location
return attr
def convert(item, from_key, to_key):
"""Translate between Axis and HASS syntax."""
for entry in REMAP:
if entry[from_key] == item:
return entry[to_key]
REMAP = [{'type': 'motion',
'class': 'motion',
'topic': 'tns1:VideoAnalytics/tnsaxis:MotionDetection',
'subscribe': 'onvif:VideoAnalytics/axis:MotionDetection',
'platform': 'binary_sensor'},
{'type': 'vmd3',
'class': 'motion',
'topic': 'tns1:RuleEngine/tnsaxis:VMD3/vmd3_video_1',
'subscribe': 'onvif:RuleEngine/axis:VMD3/vmd3_video_1',
'platform': 'binary_sensor'},
{'type': 'pir',
'class': 'motion',
'topic': 'tns1:Device/tnsaxis:Sensor/PIR',
'subscribe': 'onvif:Device/axis:Sensor/axis:PIR',
'platform': 'binary_sensor'},
{'type': 'sound',
'class': 'sound',
'topic': 'tns1:AudioSource/tnsaxis:TriggerLevel',
'subscribe': 'onvif:AudioSource/axis:TriggerLevel',
'platform': 'binary_sensor'},
{'type': 'daynight',
'class': 'light',
'topic': 'tns1:VideoSource/tnsaxis:DayNightVision',
'subscribe': 'onvif:VideoSource/axis:DayNightVision',
'platform': 'binary_sensor'},
{'type': 'tampering',
'class': 'safety',
'topic': 'tns1:VideoSource/tnsaxis:Tampering',
'subscribe': 'onvif:VideoSource/axis:Tampering',
'platform': 'binary_sensor'},
{'type': 'input',
'class': 'input',
'topic': 'tns1:Device/tnsaxis:IO/Port',
'subscribe': 'onvif:Device/axis:IO/Port',
'platform': 'binary_sensor'}, ]

View File

@@ -37,14 +37,14 @@ def setup(hass, config):
# noqa: F821
def setup_output(pin):
"""Setup a GPIO as output."""
"""Set up 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."""
"""Set up a GPIO as input."""
# pylint: disable=import-error,undefined-variable
import Adafruit_BBIO.GPIO as GPIO
GPIO.setup(pin, GPIO.IN, # noqa: F821

View File

@@ -14,7 +14,6 @@ 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 = timedelta(seconds=30)
@@ -57,7 +56,7 @@ class BinarySensorDevice(Entity):
@property
def is_on(self):
"""Return True if the binary sensor is on."""
"""Return true if the binary sensor is on."""
return None
@property
@@ -66,7 +65,6 @@ class BinarySensorDevice(Entity):
return STATE_ON if self.is_on else STATE_OFF
@property
@deprecated_substitute('sensor_class')
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return None

View File

@@ -0,0 +1,81 @@
"""
This component provides HA binary_sensor support for Abode Security System.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.abode/
"""
import logging
from homeassistant.components.abode import (CONF_ATTRIBUTION, DATA_ABODE)
from homeassistant.const import (ATTR_ATTRIBUTION)
from homeassistant.components.binary_sensor import (BinarySensorDevice)
DEPENDENCIES = ['abode']
_LOGGER = logging.getLogger(__name__)
# Sensor types: Name, device_class
SENSOR_TYPES = {
'Door Contact': 'opening',
'Motion Camera': 'motion',
}
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up a sensor for an Abode device."""
data = hass.data.get(DATA_ABODE)
sensors = []
for sensor in data.devices:
_LOGGER.debug('Sensor type %s', sensor.type)
if sensor.type in ['Door Contact', 'Motion Camera']:
sensors.append(AbodeBinarySensor(hass, data, sensor))
_LOGGER.debug('Adding %d sensors', len(sensors))
add_devices(sensors)
class AbodeBinarySensor(BinarySensorDevice):
"""A binary sensor implementation for Abode device."""
def __init__(self, hass, data, device):
"""Initialize a sensor for Abode device."""
super(AbodeBinarySensor, self).__init__()
self._device = device
@property
def should_poll(self):
"""Return the polling state."""
return True
@property
def name(self):
"""Return the name of the sensor."""
return "{0} {1}".format(self._device.type, self._device.name)
@property
def is_on(self):
"""Return True if the binary sensor is on."""
if self._device.type == 'Door Contact':
return self._device.status != 'Closed'
elif self._device.type == 'Motion Camera':
return self._device.get_value('motion_event') == '1'
@property
def device_class(self):
"""Return the class of the binary sensor."""
return SENSOR_TYPES.get(self._device.type)
@property
def device_state_attributes(self):
"""Return the state attributes."""
attrs = {}
attrs[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION
attrs['device_id'] = self._device.device_id
attrs['battery_low'] = self._device.battery_low
return attrs
def update(self):
"""Update the device state."""
self._device.refresh()

View File

@@ -11,7 +11,6 @@ from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.const import (STATE_ON, STATE_OFF, STATE_OPEN, STATE_CLOSED)
from homeassistant.components.alarmdecoder import (ZONE_SCHEMA,
CONF_ZONES,
CONF_ZONE_NAME,
@@ -27,7 +26,7 @@ _LOGGER = logging.getLogger(__name__)
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup AlarmDecoder binary sensor devices."""
"""Set up the AlarmDecoder binary sensor devices."""
configured_zones = discovery_info[CONF_ZONES]
devices = []
@@ -36,10 +35,8 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
device_config_data = ZONE_SCHEMA(configured_zones[zone_num])
zone_type = device_config_data[CONF_ZONE_TYPE]
zone_name = device_config_data[CONF_ZONE_NAME]
device = AlarmDecoderBinarySensor(hass,
zone_num,
zone_name,
zone_type)
device = AlarmDecoderBinarySensor(
hass, zone_num, zone_name, zone_type)
devices.append(device)
async_add_devices(devices)
@@ -58,7 +55,7 @@ class AlarmDecoderBinarySensor(BinarySensorDevice):
self._name = zone_name
self._type = zone_type
_LOGGER.debug('AlarmDecoderBinarySensor: Setup up zone: ' + zone_name)
_LOGGER.debug("Setup up zone: %s", self._name)
@asyncio.coroutine
def async_added_to_hass(self):
@@ -69,14 +66,6 @@ class AlarmDecoderBinarySensor(BinarySensorDevice):
async_dispatcher_connect(
self.hass, SIGNAL_ZONE_RESTORE, self._restore_callback)
@property
def state(self):
"""Return the state of the binary sensor."""
if self._type == 'opening':
return STATE_OPEN if self.is_on else STATE_CLOSED
return STATE_ON if self.is_on else STATE_OFF
@property
def name(self):
"""Return the name of the entity."""

View File

@@ -15,7 +15,7 @@ DEPENDENCIES = ['android_ip_webcam']
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup IP Webcam binary sensors."""
"""Set up the IP Webcam binary sensors."""
if discovery_info is None:
return
@@ -28,7 +28,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
class IPWebcamBinarySensor(AndroidIPCamEntity, BinarySensorDevice):
"""Represents an IP Webcam binary sensor."""
"""Representation of an IP Webcam binary sensor."""
def __init__(self, name, host, ipcam, sensor):
"""Initialize the binary sensor."""
@@ -47,7 +47,7 @@ class IPWebcamBinarySensor(AndroidIPCamEntity, BinarySensorDevice):
@property
def is_on(self):
"""True if the binary sensor is on."""
"""Return true if the binary sensor is on."""
return self._state
@asyncio.coroutine

View File

@@ -20,9 +20,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
})
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Setup an Online Status binary sensor."""
add_entities((OnlineStatus(config, apcupsd.DATA),))
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up an APCUPSd Online Status binary sensor."""
add_devices([OnlineStatus(config, apcupsd.DATA)], True)
class OnlineStatus(BinarySensorDevice):
@@ -33,7 +33,6 @@ class OnlineStatus(BinarySensorDevice):
self._config = config
self._data = data
self._state = None
self.update()
@property
def name(self):

View File

@@ -13,10 +13,9 @@ import voluptuous as vol
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA, DEVICE_CLASSES_SCHEMA)
from homeassistant.const import (
CONF_RESOURCE, CONF_PIN, CONF_NAME, CONF_SENSOR_CLASS, CONF_DEVICE_CLASS)
CONF_RESOURCE, CONF_PIN, CONF_NAME, 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__)
@@ -26,7 +25,6 @@ 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,
})
@@ -35,7 +33,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the aREST binary sensor."""
resource = config.get(CONF_RESOURCE)
pin = config.get(CONF_PIN)
device_class = get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
device_class = config.get(CONF_DEVICE_CLASS)
try:
response = requests.get(resource, timeout=10).json()
@@ -51,7 +49,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices([ArestBinarySensor(
arest, resource, config.get(CONF_NAME, response[CONF_NAME]),
device_class, pin)])
device_class, pin)], True)
class ArestBinarySensor(BinarySensorDevice):
@@ -64,12 +62,11 @@ class ArestBinarySensor(BinarySensorDevice):
self._name = name
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)
if request.status_code is not 200:
if request.status_code != 200:
_LOGGER.error("Can't set mode of %s", self._resource)
@property

View File

@@ -0,0 +1,68 @@
"""
Support for Axis binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.axis/
"""
import logging
from datetime import timedelta
from homeassistant.components.binary_sensor import (BinarySensorDevice)
from homeassistant.components.axis import (AxisDeviceEvent)
from homeassistant.const import (CONF_TRIGGER_TIME)
from homeassistant.helpers.event import track_point_in_utc_time
from homeassistant.util.dt import utcnow
DEPENDENCIES = ['axis']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Axis device event."""
add_devices([AxisBinarySensor(discovery_info['axis_event'], hass)], True)
class AxisBinarySensor(AxisDeviceEvent, BinarySensorDevice):
"""Representation of a binary Axis event."""
def __init__(self, axis_event, hass):
"""Initialize the binary sensor."""
self.hass = hass
self._state = False
self._delay = axis_event.device_config(CONF_TRIGGER_TIME)
self._timer = None
AxisDeviceEvent.__init__(self, axis_event)
@property
def is_on(self):
"""Return true if event is active."""
return self._state
def update(self):
"""Get the latest data and update the state."""
self._state = self.axis_event.is_tripped
def _update_callback(self):
"""Update the sensor's state, if needed."""
self.update()
if self._timer is not None:
self._timer()
self._timer = None
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 (%s sec) update.",
self._name, self._delay)
self.schedule_update_ha_state()
self._timer = None
self._timer = track_point_in_utc_time(
self.hass, _delay_update,
utcnow() + timedelta(seconds=self._delay))
else:
self.schedule_update_ha_state()

View File

@@ -42,7 +42,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Beaglebone Black GPIO devices."""
"""Set up the Beaglebone Black GPIO devices."""
pins = config.get(CONF_PINS)
binary_sensors = []
@@ -53,7 +53,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class BBBGPIOBinarySensor(BinarySensorDevice):
"""Represent a binary sensor that uses Beaglebone Black GPIO."""
"""Representation of a binary sensor that uses Beaglebone Black GPIO."""
def __init__(self, pin, params):
"""Initialize the Beaglebone Black binary sensor."""

View File

@@ -24,7 +24,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class BlinkCameraMotionSensor(BinarySensorDevice):
"""A representation of a Blink binary sensor."""
"""Representation of a Blink binary sensor."""
def __init__(self, name, data):
"""Initialize the sensor."""

View File

@@ -18,7 +18,6 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['bloomsky']
# These are the available sensors mapped to binary_sensor class
SENSOR_TYPES = {
'Rain': 'moisture',
'Night': None,
@@ -31,18 +30,19 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the available BloomSky weather binary sensors."""
"""Set up the available BloomSky weather binary sensors."""
bloomsky = get_component('bloomsky')
# Default needed in case of discovery
sensors = config.get(CONF_MONITORED_CONDITIONS, SENSOR_TYPES)
for device in bloomsky.BLOOMSKY.devices.values():
for variable in sensors:
add_devices([BloomSkySensor(bloomsky.BLOOMSKY, device, variable)])
add_devices(
[BloomSkySensor(bloomsky.BLOOMSKY, device, variable)], True)
class BloomSkySensor(BinarySensorDevice):
"""Represent a single binary sensor in a BloomSky device."""
"""Representation of a single binary sensor in a BloomSky device."""
def __init__(self, bs, device, sensor_name):
"""Initialize a BloomSky binary sensor."""
@@ -51,11 +51,11 @@ class BloomSkySensor(BinarySensorDevice):
self._sensor_name = sensor_name
self._name = '{} {}'.format(device['DeviceName'], sensor_name)
self._unique_id = 'bloomsky_binary_sensor {}'.format(self._name)
self.update()
self._state = None
@property
def name(self):
"""The name of the BloomSky device and this sensor."""
"""Return the name of the BloomSky device and this sensor."""
return self._name
@property

View File

@@ -4,19 +4,18 @@ 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/
"""
from datetime import timedelta
import logging
from datetime import timedelta
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import (
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_DEVICE_CLASS)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
CONF_COMMAND, CONF_DEVICE_CLASS)
_LOGGER = logging.getLogger(__name__)
@@ -31,7 +30,6 @@ PLATFORM_SCHEMA = 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): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
})
@@ -39,24 +37,24 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Command line Binary Sensor."""
"""Set up the Command line Binary Sensor."""
name = config.get(CONF_NAME)
command = config.get(CONF_COMMAND)
payload_off = config.get(CONF_PAYLOAD_OFF)
payload_on = config.get(CONF_PAYLOAD_ON)
device_class = get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
device_class = config.get(CONF_DEVICE_CLASS)
value_template = config.get(CONF_VALUE_TEMPLATE)
if value_template is not None:
value_template.hass = hass
data = CommandSensorData(command)
data = CommandSensorData(hass, command)
add_devices([CommandBinarySensor(
hass, data, name, device_class, payload_on, payload_off,
value_template)])
value_template)], True)
class CommandBinarySensor(BinarySensorDevice):
"""Represent a command line binary sensor."""
"""Representation of a command line binary sensor."""
def __init__(self, hass, data, name, device_class, payload_on,
payload_off, value_template):
@@ -69,7 +67,6 @@ class CommandBinarySensor(BinarySensorDevice):
self._payload_on = payload_on
self._payload_off = payload_off
self._value_template = value_template
self.update()
@property
def name(self):

View File

@@ -67,17 +67,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if zone['number'] not in exclude:
sensors.append(
Concord232ZoneSensor(
hass, client, zone, zone_types.get(zone['number'],
get_opening_type(zone)))
hass, client, zone, zone_types.get(
zone['number'], get_opening_type(zone))
)
)
add_devices(sensors)
return True
add_devices(sensors, True)
def get_opening_type(zone):
"""Helper function to try to guess sensor type from name."""
"""Return the result of the type guessing from name."""
if 'MOTION' in zone['name']:
return 'motion'
if 'KEY' in zone['name']:
@@ -99,7 +98,6 @@ class Concord232ZoneSensor(BinarySensorDevice):
self._zone = zone
self._number = zone['number']
self._zone_type = zone_type
self.update()
@property
def device_class(self):
@@ -123,13 +121,13 @@ class Concord232ZoneSensor(BinarySensorDevice):
return bool(self._zone['state'] == 'Normal')
def update(self):
""""Get updated stats from API."""
"""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'])
_LOGGER.debug("Updated from zone: %s", self._zone['name'])
if hasattr(self._client, 'zones'):
self._zone = next((x for x in self._client.zones

View File

@@ -8,7 +8,7 @@ from homeassistant.components.binary_sensor import BinarySensorDevice
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Demo binary sensor platform."""
"""Set up the Demo binary sensor platform."""
add_devices([
DemoBinarySensor('Basement Floor Wet', False, 'moisture'),
DemoBinarySensor('Movement Backyard', True, 'motion'),
@@ -16,7 +16,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class DemoBinarySensor(BinarySensorDevice):
"""A Demo binary sensor."""
"""representation of a Demo binary sensor."""
def __init__(self, name, state, device_class):
"""Initialize the demo sensor."""

View File

@@ -8,19 +8,18 @@ import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
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
ATTR_REGION, ATTR_VCPUS, DATA_DIGITAL_OCEAN)
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'Droplet'
DEFAULT_SENSOR_CLASS = 'motion'
DEFAULT_DEVICE_CLASS = 'moving'
DEPENDENCIES = ['digital_ocean']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@@ -30,19 +29,21 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Digital Ocean droplet sensor."""
digital_ocean = get_component('digital_ocean')
digital = hass.data.get(DATA_DIGITAL_OCEAN)
if not digital:
return False
droplets = config.get(CONF_DROPLETS)
dev = []
for droplet in droplets:
droplet_id = digital_ocean.DIGITAL_OCEAN.get_droplet_id(droplet)
droplet_id = digital.get_droplet_id(droplet)
if droplet_id is None:
_LOGGER.error("Droplet %s is not available", droplet)
return False
dev.append(DigitalOceanBinarySensor(
digital_ocean.DIGITAL_OCEAN, droplet_id))
dev.append(DigitalOceanBinarySensor(digital, droplet_id))
add_devices(dev)
add_devices(dev, True)
class DigitalOceanBinarySensor(BinarySensorDevice):
@@ -53,7 +54,7 @@ class DigitalOceanBinarySensor(BinarySensorDevice):
self._digital_ocean = do
self._droplet_id = droplet_id
self._state = None
self.update()
self.data = None
@property
def name(self):
@@ -68,7 +69,7 @@ class DigitalOceanBinarySensor(BinarySensorDevice):
@property
def device_class(self):
"""Return the class of this sensor."""
return DEFAULT_SENSOR_CLASS
return DEFAULT_DEVICE_CLASS
@property
def device_state_attributes(self):

View File

@@ -13,7 +13,7 @@ ECOBEE_CONFIG_FILE = 'ecobee.conf'
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Ecobee sensors."""
"""Set up the Ecobee sensors."""
if discovery_info is None:
return
data = ecobee.NETWORK
@@ -26,7 +26,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
dev.append(EcobeeBinarySensor(sensor['name'], index))
add_devices(dev)
add_devices(dev, True)
class EcobeeBinarySensor(BinarySensorDevice):
@@ -39,7 +39,6 @@ class EcobeeBinarySensor(BinarySensorDevice):
self.index = sensor_index
self._state = None
self._device_class = 'occupancy'
self.update()
@property
def name(self):

View File

@@ -0,0 +1,69 @@
"""
Support for Eight Sleep binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.eight_sleep/
"""
import logging
import asyncio
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.eight_sleep import (
DATA_EIGHT, EightSleepHeatEntity, CONF_BINARY_SENSORS, NAME_MAP)
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['eight_sleep']
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the eight sleep binary sensor."""
if discovery_info is None:
return
name = 'Eight'
sensors = discovery_info[CONF_BINARY_SENSORS]
eight = hass.data[DATA_EIGHT]
all_sensors = []
for sensor in sensors:
all_sensors.append(EightHeatSensor(name, eight, sensor))
async_add_devices(all_sensors, True)
class EightHeatSensor(EightSleepHeatEntity, BinarySensorDevice):
"""Representation of a Eight Sleep heat-based sensor."""
def __init__(self, name, eight, sensor):
"""Initialize the sensor."""
super().__init__(eight)
self._sensor = sensor
self._mapped_name = NAME_MAP.get(self._sensor, self._sensor)
self._name = '{} {}'.format(name, self._mapped_name)
self._state = None
self._side = self._sensor.split('_')[0]
self._userid = self._eight.fetch_userid(self._side)
self._usrobj = self._eight.users[self._userid]
_LOGGER.debug("Presence Sensor: %s, Side: %s, User: %s",
self._sensor, self._side, self._userid)
@property
def name(self):
"""Return the name of the sensor, if any."""
return self._name
@property
def is_on(self):
"""Return true if the binary sensor is on."""
return self._state
@asyncio.coroutine
def async_update(self):
"""Retrieve latest state."""
self._state = self._usrobj.bed_presence

View File

@@ -12,9 +12,8 @@ from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA, DEVICE_CLASSES_SCHEMA)
from homeassistant.components import enocean
from homeassistant.const import (
CONF_NAME, CONF_ID, CONF_SENSOR_CLASS, CONF_DEVICE_CLASS)
CONF_NAME, CONF_ID, CONF_DEVICE_CLASS)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
_LOGGER = logging.getLogger(__name__)
@@ -24,16 +23,15 @@ DEFAULT_NAME = 'EnOcean binary sensor'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
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): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Binary Sensor platform fo EnOcean."""
"""Set up the Binary Sensor platform for EnOcean."""
dev_id = config.get(CONF_ID)
devname = config.get(CONF_NAME)
device_class = get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
device_class = config.get(CONF_DEVICE_CLASS)
add_devices([EnOceanBinarySensor(dev_id, devname, device_class)])
@@ -44,7 +42,7 @@ class EnOceanBinarySensor(enocean.EnOceanDevice, BinarySensorDevice):
def __init__(self, dev_id, devname, device_class):
"""Initialize the EnOcean binary sensor."""
enocean.EnOceanDevice.__init__(self)
self.stype = "listener"
self.stype = 'listener'
self.dev_id = dev_id
self.which = -1
self.onoff = -1
@@ -53,7 +51,7 @@ class EnOceanBinarySensor(enocean.EnOceanDevice, BinarySensorDevice):
@property
def name(self):
"""The default name for the binary sensor."""
"""Return the default name for the binary sensor."""
return self.devname
@property
@@ -80,7 +78,13 @@ class EnOceanBinarySensor(enocean.EnOceanDevice, BinarySensorDevice):
elif value2 == 0x10:
self.which = 1
self.onoff = 1
self.hass.bus.fire('button_pressed', {"id": self.dev_id,
elif value2 == 0x37:
self.which = 10
self.onoff = 0
elif value2 == 0x15:
self.which = 10
self.onoff = 1
self.hass.bus.fire('button_pressed', {'id': self.dev_id,
'pushed': value,
'which': self.which,
'onoff': self.onoff})

View File

@@ -15,13 +15,14 @@ from homeassistant.components.envisalink import (
SIGNAL_ZONE_UPDATE)
from homeassistant.const import ATTR_LAST_TRIP_TIME
DEPENDENCIES = ['envisalink']
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['envisalink']
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup Envisalink binary sensor devices."""
"""Set up the Envisalink binary sensor devices."""
configured_zones = discovery_info['zones']
devices = []

View File

@@ -48,23 +48,21 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Create the binary sensor."""
"""Set up the FFmpeg binary moition 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)
async_add_devices([entity])
class FFmpegBinarySensor(FFmpegBase, BinarySensorDevice):
"""A binary sensor which use ffmpeg for noise detection."""
"""A binary sensor which use FFmpeg for noise detection."""
def __init__(self, config):
"""Constructor for binary sensor noise detection."""
"""Init for the binary sensor noise detection."""
super().__init__(config.get(CONF_INITIAL_STATE))
self._state = False
@@ -79,7 +77,7 @@ class FFmpegBinarySensor(FFmpegBase, BinarySensorDevice):
@property
def is_on(self):
"""True if the binary sensor is on."""
"""Return true if the binary sensor is on."""
return self._state
@property
@@ -89,10 +87,10 @@ class FFmpegBinarySensor(FFmpegBase, BinarySensorDevice):
class FFmpegMotion(FFmpegBinarySensor):
"""A binary sensor which use ffmpeg for noise detection."""
"""A binary sensor which use FFmpeg for noise detection."""
def __init__(self, hass, manager, config):
"""Initialize ffmpeg motion binary sensor."""
"""Initialize FFmpeg motion binary sensor."""
from haffmpeg import SensorMotion
super().__init__(config)
@@ -125,4 +123,4 @@ class FFmpegMotion(FFmpegBinarySensor):
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return "motion"
return 'motion'

View File

@@ -45,23 +45,21 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Create the binary sensor."""
"""Set up the FFmpeg noise 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)
async_add_devices([entity])
class FFmpegNoise(FFmpegBinarySensor):
"""A binary sensor which use ffmpeg for noise detection."""
"""A binary sensor which use FFmpeg for noise detection."""
def __init__(self, hass, manager, config):
"""Initialize ffmpeg noise binary sensor."""
"""Initialize FFmpeg noise binary sensor."""
from haffmpeg import SensorNoise
super().__init__(config)
@@ -77,14 +75,12 @@ class FFmpegNoise(FFmpegBinarySensor):
if entity_ids is not None and self.entity_id not in entity_ids:
return
# 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
yield from self.ffmpeg.open_sensor(
input_source=self._config.get(CONF_INPUT),
output_dest=self._config.get(CONF_OUTPUT),
@@ -94,4 +90,4 @@ class FFmpegNoise(FFmpegBinarySensor):
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
return "sound"
return 'sound'

View File

@@ -110,7 +110,7 @@ def start_scanning(config, add_entities, client):
def setup_button(hass, config, add_entities, client, address):
"""Setup single button device."""
"""Set up a 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)
@@ -199,11 +199,10 @@ class FlicButton(BinarySensorDevice):
"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
_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."""

View File

@@ -18,7 +18,7 @@ from homeassistant.const import (
CONF_SSL, EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START,
ATTR_LAST_TRIP_TIME, CONF_CUSTOMIZE)
REQUIREMENTS = ['pyhik==0.1.2']
REQUIREMENTS = ['pyhik==0.1.3']
_LOGGER = logging.getLogger(__name__)
CONF_IGNORED = 'ignored'
@@ -67,7 +67,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Setup Hikvision binary sensor devices."""
"""Set up the Hikvision binary sensor devices."""
name = config.get(CONF_NAME)
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
@@ -77,16 +77,16 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
customize = config.get(CONF_CUSTOMIZE)
if config.get(CONF_SSL):
protocol = "https"
protocol = 'https'
else:
protocol = "http"
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.')
_LOGGER.error("Hikvision event stream has no data, unable to setup")
return False
entities = []
@@ -104,7 +104,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
ignore = custom.get(CONF_IGNORED)
delay = custom.get(CONF_DELAY)
_LOGGER.debug('Entity: %s - %s, Options - Ignore: %s, Delay: %s',
_LOGGER.debug("Entity: %s - %s, Options - Ignore: %s, Delay: %s",
data.name, sensor_name, ignore, delay)
if not ignore:
entities.append(HikvisionBinarySensor(
@@ -126,8 +126,8 @@ class HikvisionData(object):
self._password = password
# Establish camera
self.camdata = HikCamera(self._url, self._port,
self._username, self._password)
self.camdata = HikCamera(
self._url, self._port, self._username, self._password)
if self._name is None:
self._name = self.camdata.get_name
@@ -251,7 +251,7 @@ class HikvisionBinarySensor(BinarySensorDevice):
# Set timer to wait until updating the state
def _delay_update(now):
"""Timer callback for sensor update."""
_LOGGER.debug('%s Called delayed (%ssec) update.',
_LOGGER.debug("%s Called delayed (%ssec) update",
self._name, self._delay)
self.schedule_update_ha_state()
self._timer = None

View File

@@ -1,5 +1,5 @@
"""
Support for Homematic binary sensors.
Support for HomeMatic binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.homematic/
@@ -14,28 +14,28 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['homematic']
SENSOR_TYPES_CLASS = {
"Remote": None,
"ShutterContact": "opening",
"MaxShutterContact": "opening",
"IPShutterContact": "opening",
"Smoke": "smoke",
"SmokeV2": "smoke",
"Motion": "motion",
"MotionV2": "motion",
"RemoteMotion": None,
"WeatherSensor": None,
"TiltSensor": None,
'Remote': None,
'ShutterContact': 'opening',
'MaxShutterContact': 'opening',
'IPShutterContact': 'opening',
'Smoke': 'smoke',
'SmokeV2': 'smoke',
'Motion': 'motion',
'MotionV2': 'motion',
'RemoteMotion': None,
'WeatherSensor': None,
'TiltSensor': None,
}
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Homematic binary sensor platform."""
"""Set up the HomeMatic binary sensor platform."""
if discovery_info is None:
return
devices = []
for config in discovery_info[ATTR_DISCOVER_DEVICES]:
new_device = HMBinarySensor(hass, config)
for conf in discovery_info[ATTR_DISCOVER_DEVICES]:
new_device = HMBinarySensor(hass, conf)
new_device.link_homematic()
devices.append(new_device)
@@ -43,7 +43,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
class HMBinarySensor(HMDevice, BinarySensorDevice):
"""Representation of a binary Homematic device."""
"""Representation of a binary HomeMatic device."""
@property
def is_on(self):
@@ -54,16 +54,14 @@ class HMBinarySensor(HMDevice, BinarySensorDevice):
@property
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"
"""Return the class of this sensor from DEVICE_CLASSES."""
# If state is MOTION (Only RemoteMotion working)
if self._state == 'MOTION':
return 'motion'
return SENSOR_TYPES_CLASS.get(self._hmdevice.__class__.__name__, None)
def _init_data_struct(self):
"""Generate a data struct (self._data) from the Homematic metadata."""
# add state to data struct
"""Generate the data dictionary (self._data) from metadata."""
# Add state to data struct
if self._state:
_LOGGER.debug("%s init datastruct with main node '%s'", self._name,
self._state)
self._data.update({self._state: STATE_UNKNOWN})

View File

@@ -67,7 +67,7 @@ class InsteonPLMBinarySensorDevice(BinarySensorDevice):
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)
_LOGGER.info("Sensor state for %s is %s", self._address, sensorstate)
return bool(sensorstate)
@property
@@ -83,5 +83,5 @@ class InsteonPLMBinarySensorDevice(BinarySensorDevice):
@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)
_LOGGER.info("Received update calback from PLM for %s", self._address)
self._hass.async_add_job(self.async_update_ha_state())

View File

@@ -64,7 +64,6 @@ class IssBinarySensor(BinarySensorDevice):
self._state = None
self._name = name
self._show_on_map = show
self.update()
@property
def name(self):

View File

@@ -12,7 +12,6 @@ import homeassistant.components.isy994 as isy
from homeassistant.const import STATE_ON, STATE_OFF
from homeassistant.helpers.typing import ConfigType
_LOGGER = logging.getLogger(__name__)
VALUE_TO_STATE = {
@@ -27,9 +26,9 @@ STATES = [STATE_OFF, STATE_ON, 'true', 'false']
# pylint: disable=unused-argument
def setup_platform(hass, config: ConfigType,
add_devices: Callable[[list], None], discovery_info=None):
"""Setup the ISY994 binary sensor platform."""
"""Set up the ISY994 binary sensor platform."""
if isy.ISY is None or not isy.ISY.connected:
_LOGGER.error('A connection has not been made to the ISY controller.')
_LOGGER.error("A connection has not been made to the ISY controller")
return False
devices = []

View File

@@ -11,7 +11,7 @@ DEPENDENCIES = ['knx']
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the KNX binary sensor platform."""
"""Set up the KNX binary sensor platform."""
add_devices([KNXSwitch(hass, KNXConfig(config))])

View File

@@ -4,7 +4,6 @@ Support for MAX! Window Shutter via MAX! Cube.
For more details about this platform, please refer to the documentation
https://home-assistant.io/components/maxcube/
"""
import logging
from homeassistant.components.binary_sensor import BinarySensorDevice
@@ -15,27 +14,24 @@ _LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Iterate through all MAX! Devices and add window shutters to HASS."""
"""Iterate through all MAX! Devices and add window shutters."""
cube = hass.data[MAXCUBE_HANDLE].cube
# List of devices
devices = []
for device in cube.devices:
# Create device name by concatenating room name + device name
name = "%s %s" % (cube.room_by_id(device.room_id).name, device.name)
name = "{} {}".format(
cube.room_by_id(device.room_id).name, device.name)
# Only add Window Shutters
if cube.is_windowshutter(device):
# add device to HASS
devices.append(MaxCubeShutter(hass, name, device.rf_address))
if len(devices) > 0:
if devices:
add_devices(devices)
class MaxCubeShutter(BinarySensorDevice):
"""MAX! Cube BinarySensor device."""
"""Representation of a MAX! Cube Binary Sensor device."""
def __init__(self, hass, name, rf_address):
"""Initialize MAX! Cube BinarySensorDevice."""
@@ -47,7 +43,7 @@ class MaxCubeShutter(BinarySensorDevice):
@property
def should_poll(self):
"""Polling is required."""
"""Return the polling state."""
return True
@property
@@ -68,9 +64,5 @@ class MaxCubeShutter(BinarySensorDevice):
def update(self):
"""Get latest data from MAX! Cube."""
self._cubehandle.update()
# Get the device we want to update
device = self._cubehandle.cube.device_by_rf(self._rf_address)
# Update our internal state
self._state = device.is_open

View File

@@ -8,7 +8,7 @@ import logging
import voluptuous as vol
import homeassistant.components.modbus as modbus
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_NAME, CONF_SLAVE
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.helpers import config_validation as cv
from homeassistant.components.sensor import PLATFORM_SCHEMA
@@ -16,9 +16,8 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['modbus']
CONF_COIL = "coil"
CONF_COILS = "coils"
CONF_SLAVE = "slave"
CONF_COIL = 'coil'
CONF_COILS = 'coils'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_COILS): [{
@@ -30,7 +29,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Modbus binary sensors."""
"""Set up the Modbus binary sensors."""
sensors = []
for coil in config.get(CONF_COILS):
sensors.append(ModbusCoilSensor(
@@ -50,6 +49,11 @@ class ModbusCoilSensor(BinarySensorDevice):
self._coil = int(coil)
self._value = None
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def is_on(self):
"""Return the state of the sensor."""
@@ -58,4 +62,10 @@ class ModbusCoilSensor(BinarySensorDevice):
def update(self):
"""Update the state of the sensor."""
result = modbus.HUB.read_coils(self._slave, self._coil, 1)
self._value = result.bits[0]
try:
self._value = result.bits[0]
except AttributeError:
_LOGGER.error(
'No response from modbus slave %s coil %s',
self._slave,
self._coil)

View File

@@ -15,10 +15,9 @@ from homeassistant.components.binary_sensor import (
BinarySensorDevice, DEVICE_CLASSES_SCHEMA)
from homeassistant.const import (
CONF_NAME, CONF_VALUE_TEMPLATE, CONF_PAYLOAD_ON, CONF_PAYLOAD_OFF,
CONF_SENSOR_CLASS, CONF_DEVICE_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__)
@@ -31,7 +30,6 @@ 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): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
@@ -49,7 +47,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
async_add_devices([MqttBinarySensor(
config.get(CONF_NAME),
config.get(CONF_STATE_TOPIC),
get_deprecated(config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS),
config.get(CONF_DEVICE_CLASS),
config.get(CONF_QOS),
config.get(CONF_PAYLOAD_ON),
config.get(CONF_PAYLOAD_OFF),
@@ -79,7 +77,7 @@ class MqttBinarySensor(BinarySensorDevice):
"""
@callback
def message_received(topic, payload, qos):
"""A new MQTT message has been received."""
"""Handle a new received MQTT message."""
if self._template is not None:
payload = self._template.async_render_with_possible_json_value(
payload)
@@ -95,7 +93,7 @@ class MqttBinarySensor(BinarySensorDevice):
@property
def should_poll(self):
"""No polling needed."""
"""Return the polling state."""
return False
@property

View File

@@ -4,62 +4,27 @@ Support for MySensors binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.mysensors/
"""
import logging
from homeassistant.components import mysensors
from homeassistant.components.binary_sensor import (DEVICE_CLASSES,
from homeassistant.components.binary_sensor import (DEVICE_CLASSES, DOMAIN,
BinarySensorDevice)
from homeassistant.const import STATE_ON
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = []
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the mysensors platform for sensors."""
# Only act if loaded via mysensors by discovery event.
# Otherwise gateway is not setup.
if discovery_info is None:
return
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
set_req = gateway.const.SetReq
map_sv_types = {
pres.S_DOOR: [set_req.V_TRIPPED],
pres.S_MOTION: [set_req.V_TRIPPED],
pres.S_SMOKE: [set_req.V_TRIPPED],
}
if float(gateway.protocol_version) >= 1.5:
map_sv_types.update({
pres.S_SPRINKLER: [set_req.V_TRIPPED],
pres.S_WATER_LEAK: [set_req.V_TRIPPED],
pres.S_SOUND: [set_req.V_TRIPPED],
pres.S_VIBRATION: [set_req.V_TRIPPED],
pres.S_MOISTURE: [set_req.V_TRIPPED],
})
devices = {}
gateway.platform_callbacks.append(mysensors.pf_callback_factory(
map_sv_types, devices, MySensorsBinarySensor, add_devices))
"""Setup the mysensors platform for binary sensors."""
mysensors.setup_mysensors_platform(
hass, DOMAIN, discovery_info, MySensorsBinarySensor,
add_devices=add_devices)
class MySensorsBinarySensor(
mysensors.MySensorsDeviceEntity, BinarySensorDevice):
mysensors.MySensorsEntity, BinarySensorDevice):
"""Represent the value of a MySensors Binary Sensor child node."""
@property
def is_on(self):
"""Return True if the binary sensor is on."""
if self.value_type in self._values:
return self._values[self.value_type] == STATE_ON
return False
return self._values.get(self.value_type) == STATE_ON
@property
def device_class(self):

View File

@@ -0,0 +1,95 @@
"""
Support for the myStrom buttons.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.mystrom/
"""
import asyncio
import logging
from homeassistant.components.binary_sensor import (BinarySensorDevice, DOMAIN)
from homeassistant.components.http import HomeAssistantView
from homeassistant.const import HTTP_UNPROCESSABLE_ENTITY
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['http']
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up myStrom Binary Sensor."""
hass.http.register_view(MyStromView(async_add_devices))
return True
class MyStromView(HomeAssistantView):
"""View to handle requests from myStrom buttons."""
url = '/api/mystrom'
name = 'api:mystrom'
def __init__(self, add_devices):
"""Initialize the myStrom URL endpoint."""
self.buttons = {}
self.add_devices = add_devices
@asyncio.coroutine
def get(self, request):
"""The GET request received from a myStrom button."""
res = yield from self._handle(request.app['hass'], request.query)
return res
@asyncio.coroutine
def _handle(self, hass, data):
"""Handle requests to the myStrom endpoint."""
button_action = list(data.keys())[0]
button_id = data[button_action]
entity_id = '{}.{}_{}'.format(DOMAIN, button_id, button_action)
if button_action not in ['single', 'double', 'long', 'touch']:
_LOGGER.error(
"Received unidentified message from myStrom button: %s", data)
return ("Received unidentified message: {}".format(data),
HTTP_UNPROCESSABLE_ENTITY)
if entity_id not in self.buttons:
_LOGGER.info("New myStrom button/action detected: %s/%s",
button_id, button_action)
self.buttons[entity_id] = MyStromBinarySensor(
'{}_{}'.format(button_id, button_action))
hass.async_add_job(self.add_devices, [self.buttons[entity_id]])
else:
new_state = True if self.buttons[entity_id].state == 'off' \
else False
self.buttons[entity_id].async_on_update(new_state)
class MyStromBinarySensor(BinarySensorDevice):
"""Representation of a myStrom button."""
def __init__(self, button_id):
"""Initialize the myStrom Binary sensor."""
self._button_id = button_id
self._state = None
@property
def name(self):
"""Return the name of the sensor."""
return self._button_id
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def is_on(self):
"""Return true if the binary sensor is on."""
return self._state
def async_on_update(self, value):
"""Receive an update."""
self._state = value
self.hass.async_add_job(self.async_update_ha_state())

View File

@@ -16,15 +16,18 @@ DEPENDENCIES = ['nest']
BINARY_TYPES = ['online']
CLIMATE_BINARY_TYPES = ['fan',
'is_using_emergency_heat',
'is_locked',
'has_leaf']
CLIMATE_BINARY_TYPES = [
'fan',
'is_using_emergency_heat',
'is_locked',
'has_leaf',
]
CAMERA_BINARY_TYPES = [
'motion_detected',
'sound_detected',
'person_detected']
'person_detected',
]
_BINARY_TYPES_DEPRECATED = [
'hvac_ac_state',
@@ -34,7 +37,8 @@ _BINARY_TYPES_DEPRECATED = [
'hvac_heat_x3_state',
'hvac_alt_heat_state',
'hvac_alt_heat_x2_state',
'hvac_emer_heat_state']
'hvac_emer_heat_state',
]
_VALID_BINARY_SENSOR_TYPES = BINARY_TYPES + CLIMATE_BINARY_TYPES \
+ CAMERA_BINARY_TYPES
@@ -43,7 +47,7 @@ _LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Nest binary sensors."""
"""Set up the Nest binary sensors."""
if discovery_info is None:
return
@@ -93,7 +97,7 @@ class NestBinarySensor(NestSensor, BinarySensorDevice):
@property
def is_on(self):
"""True if the binary sensor is on."""
"""Return true if the binary sensor is on."""
return self._state
def update(self):

View File

@@ -7,6 +7,7 @@ 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 (
@@ -16,10 +17,9 @@ 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__)
DEPENDENCIES = ['netatmo']
# These are the available sensors mapped to binary_sensor class
WELCOME_SENSOR_TYPES = {
@@ -34,8 +34,8 @@ PRESENCE_SENSOR_TYPES = {
"Outdoor vehicle": "motion"
}
TAG_SENSOR_TYPES = {
"Tag Vibration": 'vibration',
"Tag Open": 'opening'
"Tag Vibration": "vibration",
"Tag Open": "opening"
}
CONF_HOME = 'home'
@@ -44,35 +44,36 @@ CONF_WELCOME_SENSORS = 'welcome_sensors'
CONF_PRESENCE_SENSORS = 'presence_sensors'
CONF_TAG_SENSORS = 'tag_sensors'
DEFAULT_TIMEOUT = 15
DEFAULT_OFFSET = 90
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.Optional(CONF_HOME): cv.string,
vol.Optional(CONF_OFFSET, default=DEFAULT_OFFSET): cv.positive_int,
vol.Optional(CONF_PRESENCE_SENSORS, default=PRESENCE_SENSOR_TYPES):
vol.All(cv.ensure_list, [vol.In(PRESENCE_SENSOR_TYPES)]),
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
vol.Optional(CONF_WELCOME_SENSORS, default=WELCOME_SENSOR_TYPES):
vol.All(cv.ensure_list, [vol.In(WELCOME_SENSOR_TYPES)]),
})
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup access to Netatmo binary sensor."""
"""Set up the 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)
home = config.get(CONF_HOME)
timeout = config.get(CONF_TIMEOUT)
offset = config.get(CONF_OFFSET)
module_name = None
import lnetatmo
try:
data = CameraData(netatmo.NETATMO_AUTH, home)
if data.get_camera_names() == []:
if not data.get_camera_names():
return None
except lnetatmo.NoDevice:
return None
@@ -85,35 +86,31 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
for camera_name in data.get_camera_names():
camera_type = data.get_camera_type(camera=camera_name, home=home)
if camera_type == "NACamera":
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":
add_devices([NetatmoBinarySensor(
data, camera_name, module_name, home, timeout,
offset, camera_type, variable)], True)
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)])
add_devices([NetatmoBinarySensor(
data, camera_name, module_name, home, timeout, offset,
camera_type, variable)], True)
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)])
add_devices([NetatmoBinarySensor(
data, camera_name, module_name, home, timeout, offset,
camera_type, variable)], True)
class NetatmoBinarySensor(BinarySensorDevice):
@@ -121,7 +118,7 @@ class NetatmoBinarySensor(BinarySensorDevice):
def __init__(self, data, camera_name, module_name, home,
timeout, offset, camera_type, sensor):
"""Setup for access to the Netatmo camera events."""
"""Set up for access to the Netatmo camera events."""
self._data = data
self._camera_name = camera_name
self._module_name = module_name
@@ -129,23 +126,23 @@ class NetatmoBinarySensor(BinarySensorDevice):
self._timeout = timeout
self._offset = offset
if home:
self._name = home + ' / ' + camera_name
self._name = '{} / {}'.format(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)
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()
self._state = None
@property
def name(self):
"""The name of the Netatmo device and this sensor."""
"""Return the name of the Netatmo device and this sensor."""
return self._name
@property
@@ -156,12 +153,11 @@ class NetatmoBinarySensor(BinarySensorDevice):
@property
def device_class(self):
"""Return the class of this sensor, from DEVICE_CLASSES."""
if self._cameratype == "NACamera":
if self._cameratype == 'NACamera':
return WELCOME_SENSOR_TYPES.get(self._sensor_name)
elif self._cameratype == "NOC":
elif self._cameratype == 'NOC':
return PRESENCE_SENSOR_TYPES.get(self._sensor_name)
else:
return TAG_SENSOR_TYPES.get(self._sensor_name)
return TAG_SENSOR_TYPES.get(self._sensor_name)
@property
def is_on(self):
@@ -173,51 +169,44 @@ class NetatmoBinarySensor(BinarySensorDevice):
self._data.update()
self._data.update_event()
if self._cameratype == "NACamera":
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)
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":
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)
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)
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)
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)
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)
self._data.camera_data.moduleOpened(
self._home, self._module_name, self._camera_name)
else:
return None

View File

@@ -41,7 +41,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the NX584 binary sensor platform."""
"""Set up the NX584 binary sensor platform."""
from nx584 import client as nx584_client
host = config.get(CONF_HOST)
@@ -53,7 +53,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
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))
_LOGGER.error("Unable to connect to NX584: %s", str(ex))
return False
version = [int(v) for v in client.get_version().split('.')]

View File

@@ -9,18 +9,15 @@ import logging
import requests
import voluptuous as vol
from homeassistant.const import (
CONF_NAME, STATE_ON, STATE_OFF, CONF_MONITORED_CONDITIONS)
from homeassistant.const import CONF_NAME, CONF_MONITORED_CONDITIONS
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.loader import get_component
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['octoprint']
DOMAIN = "octoprint"
DEFAULT_NAME = 'OctoPrint'
SENSOR_TYPES = {
@@ -38,24 +35,20 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the available OctoPrint binary sensors."""
octoprint = get_component('octoprint')
"""Set up the available OctoPrint binary sensors."""
octoprint_api = hass.data[DOMAIN]["api"]
name = config.get(CONF_NAME)
monitored_conditions = config.get(CONF_MONITORED_CONDITIONS,
SENSOR_TYPES.keys())
monitored_conditions = config.get(
CONF_MONITORED_CONDITIONS, SENSOR_TYPES.keys())
devices = []
for octo_type in monitored_conditions:
new_sensor = OctoPrintBinarySensor(octoprint.OCTOPRINT,
octo_type,
SENSOR_TYPES[octo_type][2],
name,
SENSOR_TYPES[octo_type][3],
SENSOR_TYPES[octo_type][0],
SENSOR_TYPES[octo_type][1],
'flags')
new_sensor = OctoPrintBinarySensor(
octoprint_api, octo_type, SENSOR_TYPES[octo_type][2],
name, SENSOR_TYPES[octo_type][3], SENSOR_TYPES[octo_type][0],
SENSOR_TYPES[octo_type][1], 'flags')
devices.append(new_sensor)
add_devices(devices)
add_devices(devices, True)
class OctoPrintBinarySensor(BinarySensorDevice):
@@ -76,8 +69,6 @@ class OctoPrintBinarySensor(BinarySensorDevice):
self.api_endpoint = endpoint
self.api_group = group
self.api_tool = tool
# Set initial state
self.update()
_LOGGER.debug("Created OctoPrint binary sensor %r", self)
@property
@@ -85,18 +76,10 @@ class OctoPrintBinarySensor(BinarySensorDevice):
"""Return the name of the sensor."""
return self._name
@property
def state(self):
"""Return the state of the sensor."""
return self.is_on
@property
def is_on(self):
"""Return true if binary sensor is on."""
if self._state:
return STATE_ON
else:
return STATE_OFF
return bool(self._state)
@property
def device_class(self):
@@ -106,13 +89,9 @@ class OctoPrintBinarySensor(BinarySensorDevice):
def update(self):
"""Update state of sensor."""
try:
self._state = self.api.update(self.sensor_type,
self.api_endpoint,
self.api_group,
self.api_tool)
self._state = self.api.update(
self.sensor_type, self.api_endpoint, self.api_group,
self.api_tool)
except requests.exceptions.ConnectionError:
# Error calling the api, already logged in api.update()
return
if self._state is None:
_LOGGER.warning("Unable to locate value for %s", self.sensor_type)

View File

@@ -0,0 +1,189 @@
"""
Support for Pilight binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.pilight/
"""
import datetime
import logging
import voluptuous as vol
from homeassistant.components import pilight
from homeassistant.components.binary_sensor import (
PLATFORM_SCHEMA,
BinarySensorDevice,
)
from homeassistant.const import (
CONF_DISARM_AFTER_TRIGGER,
CONF_NAME,
CONF_PAYLOAD,
CONF_PAYLOAD_OFF,
CONF_PAYLOAD_ON
)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.event import track_point_in_time
from homeassistant.util import dt as dt_util
_LOGGER = logging.getLogger(__name__)
CONF_VARIABLE = 'variable'
CONF_RESET_DELAY_SEC = 'reset_delay_sec'
DEFAULT_NAME = 'Pilight Binary Sensor'
DEPENDENCIES = ['pilight']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_VARIABLE): cv.string,
vol.Required(CONF_PAYLOAD): vol.Schema(dict),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default='on'): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default='off'): cv.string,
vol.Optional(CONF_DISARM_AFTER_TRIGGER, default=False): cv.boolean,
vol.Optional(CONF_RESET_DELAY_SEC, default=30): cv.positive_int
})
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up Pilight Binary Sensor."""
disarm = config.get(CONF_DISARM_AFTER_TRIGGER)
if disarm:
add_devices([PilightTriggerSensor(
hass=hass,
name=config.get(CONF_NAME),
variable=config.get(CONF_VARIABLE),
payload=config.get(CONF_PAYLOAD),
on_value=config.get(CONF_PAYLOAD_ON),
off_value=config.get(CONF_PAYLOAD_OFF),
rst_dly_sec=config.get(CONF_RESET_DELAY_SEC),
)])
else:
add_devices([PilightBinarySensor(
hass=hass,
name=config.get(CONF_NAME),
variable=config.get(CONF_VARIABLE),
payload=config.get(CONF_PAYLOAD),
on_value=config.get(CONF_PAYLOAD_ON),
off_value=config.get(CONF_PAYLOAD_OFF),
)])
class PilightBinarySensor(BinarySensorDevice):
"""Representation of a binary sensor that can be updated using Pilight."""
def __init__(self, hass, name, variable, payload, on_value, off_value):
"""Initialize the sensor."""
self._state = False
self._hass = hass
self._name = name
self._variable = variable
self._payload = payload
self._on_value = on_value
self._off_value = off_value
hass.bus.listen(pilight.EVENT, self._handle_code)
@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._state
def _handle_code(self, call):
"""Handle received code by the pilight-daemon.
If the code matches the defined playload
of this sensor the sensor state is changed accordingly.
"""
# Check if received code matches defined playoad
# True if payload is contained in received code dict
payload_ok = True
for key in self._payload:
if key not in call.data:
payload_ok = False
continue
if self._payload[key] != call.data[key]:
payload_ok = False
# Read out variable if payload ok
if payload_ok:
if self._variable not in call.data:
return
value = call.data[self._variable]
self._state = (value == self._on_value)
self.schedule_update_ha_state()
class PilightTriggerSensor(BinarySensorDevice):
"""Representation of a binary sensor that can be updated using Pilight."""
def __init__(
self,
hass,
name,
variable,
payload,
on_value,
off_value,
rst_dly_sec=30):
"""Initialize the sensor."""
self._state = False
self._hass = hass
self._name = name
self._variable = variable
self._payload = payload
self._on_value = on_value
self._off_value = off_value
self._reset_delay_sec = rst_dly_sec
self._delay_after = None
self._hass = hass
hass.bus.listen(pilight.EVENT, self._handle_code)
@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._state
def _reset_state(self, call):
self._state = False
self._delay_after = None
self.schedule_update_ha_state()
def _handle_code(self, call):
"""Handle received code by the pilight-daemon.
If the code matches the defined playload
of this sensor the sensor state is changed accordingly.
"""
# Check if received code matches defined playoad
# True if payload is contained in received code dict
payload_ok = True
for key in self._payload:
if key not in call.data:
payload_ok = False
continue
if self._payload[key] != call.data[key]:
payload_ok = False
# Read out variable if payload ok
if payload_ok:
if self._variable not in call.data:
return
value = call.data[self._variable]
self._state = (value == self._on_value)
if self._delay_after is None:
self._delay_after = dt_util.utcnow() + datetime.timedelta(
seconds=self._reset_delay_sec)
track_point_in_time(
self._hass, self._reset_state,
self._delay_after)
self.schedule_update_ha_state()

View File

@@ -28,13 +28,19 @@ CONF_PING_COUNT = 'count'
DEFAULT_NAME = 'Ping Binary sensor'
DEFAULT_PING_COUNT = 5
DEFAULT_SENSOR_CLASS = 'connectivity'
DEFAULT_DEVICE_CLASS = 'connectivity'
SCAN_INTERVAL = timedelta(minutes=5)
PING_MATCHER = re.compile(
r'(?P<min>\d+.\d+)\/(?P<avg>\d+.\d+)\/(?P<max>\d+.\d+)\/(?P<mdev>\d+.\d+)')
PING_MATCHER_BUSYBOX = re.compile(
r'(?P<min>\d+.\d+)\/(?P<avg>\d+.\d+)\/(?P<max>\d+.\d+)')
WIN32_PING_MATCHER = re.compile(
r'(?P<min>\d+)ms.+(?P<max>\d+)ms.+(?P<avg>\d+)ms')
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
@@ -67,7 +73,7 @@ class PingBinarySensor(BinarySensorDevice):
@property
def device_class(self):
"""Return the class of this sensor."""
return DEFAULT_SENSOR_CLASS
return DEFAULT_DEVICE_CLASS
@property
def is_on(self):
@@ -102,7 +108,7 @@ class PingData(object):
if sys.platform == 'win32':
self._ping_cmd = [
'ping', '-n', str(self._count), '-w 1000', self._ip_address]
'ping', '-n', str(self._count), '-w', '1000', self._ip_address]
else:
self._ping_cmd = [
'ping', '-n', '-q', '-c', str(self._count), '-W1',
@@ -114,6 +120,23 @@ class PingData(object):
self._ping_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
try:
out = pinger.communicate()
_LOGGER.debug("Output is %s", str(out))
if sys.platform == 'win32':
match = WIN32_PING_MATCHER.search(str(out).split('\n')[-1])
rtt_min, rtt_avg, rtt_max = match.groups()
return {
'min': rtt_min,
'avg': rtt_avg,
'max': rtt_max,
'mdev': ''}
if 'max/' not in str(out):
match = PING_MATCHER_BUSYBOX.search(str(out).split('\n')[-1])
rtt_min, rtt_avg, rtt_max = match.groups()
return {
'min': rtt_min,
'avg': rtt_avg,
'max': rtt_max,
'mdev': ''}
match = PING_MATCHER.search(str(out).split('\n')[-1])
rtt_min, rtt_avg, rtt_max, rtt_mdev = match.groups()
return {

View File

@@ -0,0 +1,131 @@
"""
Configure a binary_sensor using a digital input from a raspihats board.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.raspihats/
"""
import logging
import voluptuous as vol
from homeassistant.const import (
CONF_NAME, CONF_DEVICE_CLASS, DEVICE_DEFAULT_NAME
)
import homeassistant.helpers.config_validation as cv
from homeassistant.components.binary_sensor import (
PLATFORM_SCHEMA, BinarySensorDevice
)
from homeassistant.components.raspihats import (
CONF_I2C_HATS, CONF_BOARD, CONF_ADDRESS, CONF_CHANNELS, CONF_INDEX,
CONF_INVERT_LOGIC, I2C_HAT_NAMES, I2C_HATS_MANAGER, I2CHatsException
)
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['raspihats']
DEFAULT_INVERT_LOGIC = False
DEFAULT_DEVICE_CLASS = None
_CHANNELS_SCHEMA = vol.Schema([{
vol.Required(CONF_INDEX): cv.positive_int,
vol.Required(CONF_NAME): cv.string,
vol.Optional(CONF_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean,
vol.Optional(CONF_DEVICE_CLASS, default=DEFAULT_DEVICE_CLASS): cv.string,
}])
_I2C_HATS_SCHEMA = vol.Schema([{
vol.Required(CONF_BOARD): vol.In(I2C_HAT_NAMES),
vol.Required(CONF_ADDRESS): vol.Coerce(int),
vol.Required(CONF_CHANNELS): _CHANNELS_SCHEMA
}])
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_I2C_HATS): _I2C_HATS_SCHEMA,
})
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the raspihats binary_sensor devices."""
I2CHatBinarySensor.I2C_HATS_MANAGER = hass.data[I2C_HATS_MANAGER]
binary_sensors = []
i2c_hat_configs = config.get(CONF_I2C_HATS)
for i2c_hat_config in i2c_hat_configs:
address = i2c_hat_config[CONF_ADDRESS]
board = i2c_hat_config[CONF_BOARD]
try:
I2CHatBinarySensor.I2C_HATS_MANAGER.register_board(board, address)
for channel_config in i2c_hat_config[CONF_CHANNELS]:
binary_sensors.append(
I2CHatBinarySensor(
address,
channel_config[CONF_INDEX],
channel_config[CONF_NAME],
channel_config[CONF_INVERT_LOGIC],
channel_config[CONF_DEVICE_CLASS]
)
)
except I2CHatsException as ex:
_LOGGER.error(
"Failed to register " + board + "I2CHat@" + hex(address) + " "
+ str(ex)
)
add_devices(binary_sensors)
class I2CHatBinarySensor(BinarySensorDevice):
"""Represents a binary sensor that uses a I2C-HAT digital input."""
I2C_HATS_MANAGER = None
def __init__(self, address, channel, name, invert_logic, device_class):
"""Initialize sensor."""
self._address = address
self._channel = channel
self._name = name or DEVICE_DEFAULT_NAME
self._invert_logic = invert_logic
self._device_class = device_class
self._state = self.I2C_HATS_MANAGER.read_di(
self._address,
self._channel
)
def online_callback():
"""Callback fired when board is online."""
self.schedule_update_ha_state()
self.I2C_HATS_MANAGER.register_online_callback(
self._address,
self._channel,
online_callback
)
def edge_callback(state):
"""Read digital input state."""
self._state = state
self.schedule_update_ha_state()
self.I2C_HATS_MANAGER.register_di_callback(
self._address,
self._channel,
edge_callback
)
@property
def device_class(self):
"""Return the class of this sensor."""
return self._device_class
@property
def name(self):
"""Return the name of this sensor."""
return self._name
@property
def should_poll(self):
"""Polling not needed for this sensor."""
return False
@property
def is_on(self):
"""Return the state of this sensor."""
return self._state != self._invert_logic

View File

@@ -14,11 +14,10 @@ from homeassistant.components.binary_sensor import (
from homeassistant.components.sensor.rest import RestData
from homeassistant.const import (
CONF_PAYLOAD, CONF_NAME, CONF_VALUE_TEMPLATE, CONF_METHOD, CONF_RESOURCE,
CONF_SENSOR_CLASS, CONF_VERIFY_SSL, CONF_USERNAME, CONF_PASSWORD,
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__)
@@ -35,7 +34,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
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): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_USERNAME): cv.string,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
@@ -44,7 +42,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the REST binary sensor."""
"""Set up the REST binary sensor."""
name = config.get(CONF_NAME)
resource = config.get(CONF_RESOURCE)
method = config.get(CONF_METHOD)
@@ -53,7 +51,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
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)
device_class = config.get(CONF_DEVICE_CLASS)
value_template = config.get(CONF_VALUE_TEMPLATE)
if value_template is not None:
value_template.hass = hass
@@ -74,7 +72,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
return False
add_devices([RestBinarySensor(
hass, rest, name, device_class, value_template)])
hass, rest, name, device_class, value_template)], True)
class RestBinarySensor(BinarySensorDevice):
@@ -89,7 +87,6 @@ class RestBinarySensor(BinarySensorDevice):
self._state = False
self._previous_data = None
self._value_template = value_template
self.update()
@property
def name(self):
@@ -107,6 +104,8 @@ class RestBinarySensor(BinarySensorDevice):
if self.rest.data is None:
return False
response = self.rest.data
if self._value_template is not None:
response = self._value_template.\
async_render_with_possible_json_value(self.rest.data, False)
@@ -114,8 +113,8 @@ class RestBinarySensor(BinarySensorDevice):
try:
return bool(int(response))
except ValueError:
return {"true": True, "on": True, "open": True,
"yes": True}.get(response.lower(), False)
return {'true': True, 'on': True, 'open': True,
'yes': True}.get(response.lower(), False)
def update(self):
"""Get the latest data from REST API and updates the state."""

View File

@@ -0,0 +1,232 @@
"""
Support for RFXtrx binary sensors.
Lighting4 devices (sensors based on PT2262 encoder) are supported and
tested. Other types may need some work.
"""
import logging
import voluptuous as vol
from homeassistant.components import rfxtrx
from homeassistant.util import slugify
from homeassistant.util import dt as dt_util
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import event as evt
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.rfxtrx import (
ATTR_AUTOMATIC_ADD, ATTR_NAME, ATTR_OFF_DELAY, ATTR_FIREEVENT,
ATTR_DATA_BITS, CONF_DEVICES
)
from homeassistant.const import (
CONF_DEVICE_CLASS, CONF_COMMAND_ON, CONF_COMMAND_OFF
)
DEPENDENCIES = ["rfxtrx"]
_LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA = vol.Schema({
vol.Required("platform"): rfxtrx.DOMAIN,
vol.Optional(CONF_DEVICES, default={}): vol.All(
dict, rfxtrx.valid_binary_sensor),
vol.Optional(ATTR_AUTOMATIC_ADD, default=False): cv.boolean,
}, extra=vol.ALLOW_EXTRA)
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Setup the Binary Sensor platform to rfxtrx."""
import RFXtrx as rfxtrxmod
sensors = []
for packet_id, entity in config['devices'].items():
event = rfxtrx.get_rfx_object(packet_id)
device_id = slugify(event.device.id_string.lower())
if device_id in rfxtrx.RFX_DEVICES:
continue
if entity[ATTR_DATA_BITS] is not None:
_LOGGER.info("Masked device id: %s",
rfxtrx.get_pt2262_deviceid(device_id,
entity[ATTR_DATA_BITS]))
_LOGGER.info("Add %s rfxtrx.binary_sensor (class %s)",
entity[ATTR_NAME], entity[CONF_DEVICE_CLASS])
device = RfxtrxBinarySensor(event, entity[ATTR_NAME],
entity[CONF_DEVICE_CLASS],
entity[ATTR_FIREEVENT],
entity[ATTR_OFF_DELAY],
entity[ATTR_DATA_BITS],
entity[CONF_COMMAND_ON],
entity[CONF_COMMAND_OFF])
device.hass = hass
device.is_lighting4 = (packet_id[2:4] == '13')
sensors.append(device)
rfxtrx.RFX_DEVICES[device_id] = device
add_devices_callback(sensors)
# pylint: disable=too-many-branches
def binary_sensor_update(event):
"""Callback for control updates from the RFXtrx gateway."""
if not isinstance(event, rfxtrxmod.ControlEvent):
return
device_id = slugify(event.device.id_string.lower())
if device_id in rfxtrx.RFX_DEVICES:
sensor = rfxtrx.RFX_DEVICES[device_id]
else:
sensor = rfxtrx.get_pt2262_device(device_id)
if sensor is None:
# Add the entity if not exists and automatic_add is True
if not config[ATTR_AUTOMATIC_ADD]:
return
poss_dev = rfxtrx.find_possible_pt2262_device(device_id)
if poss_dev is not None:
poss_id = slugify(poss_dev.event.device.id_string.lower())
_LOGGER.info("Found possible matching deviceid %s.",
poss_id)
pkt_id = "".join("{0:02x}".format(x) for x in event.data)
sensor = RfxtrxBinarySensor(event, pkt_id)
sensor.hass = hass
sensor.is_lighting4 = (pkt_id[2:4] == '13')
rfxtrx.RFX_DEVICES[device_id] = sensor
add_devices_callback([sensor])
_LOGGER.info("Added binary sensor %s "
"(Device_id: %s Class: %s Sub: %s)",
pkt_id,
slugify(event.device.id_string.lower()),
event.device.__class__.__name__,
event.device.subtype)
elif not isinstance(sensor, RfxtrxBinarySensor):
return
else:
_LOGGER.info("Binary sensor update "
"(Device_id: %s Class: %s Sub: %s)",
slugify(event.device.id_string.lower()),
event.device.__class__.__name__,
event.device.subtype)
if sensor.is_lighting4:
if sensor.data_bits is not None:
cmd = rfxtrx.get_pt2262_cmd(device_id, sensor.data_bits)
sensor.apply_cmd(int(cmd, 16))
else:
sensor.update_state(True)
else:
rfxtrx.apply_received_command(event)
if (sensor.is_on and sensor.off_delay is not None and
sensor.delay_listener is None):
def off_delay_listener(now):
"""Switch device off after a delay."""
sensor.delay_listener = None
sensor.update_state(False)
sensor.delay_listener = evt.track_point_in_time(
hass, off_delay_listener, dt_util.utcnow() + sensor.off_delay
)
# Subscribe to main rfxtrx events
if binary_sensor_update not in rfxtrx.RECEIVED_EVT_SUBSCRIBERS:
rfxtrx.RECEIVED_EVT_SUBSCRIBERS.append(binary_sensor_update)
# pylint: disable=too-many-instance-attributes,too-many-arguments
class RfxtrxBinarySensor(BinarySensorDevice):
"""An Rfxtrx binary sensor."""
def __init__(self, event, name, device_class=None,
should_fire=False, off_delay=None, data_bits=None,
cmd_on=None, cmd_off=None):
"""Initialize the sensor."""
self.event = event
self._name = name
self._should_fire_event = should_fire
self._device_class = device_class
self._off_delay = off_delay
self._state = False
self.is_lighting4 = False
self.delay_listener = None
self._data_bits = data_bits
self._cmd_on = cmd_on
self._cmd_off = cmd_off
if data_bits is not None:
self._masked_id = rfxtrx.get_pt2262_deviceid(
event.device.id_string.lower(),
data_bits)
def __str__(self):
"""Return the name of the sensor."""
return self._name
@property
def name(self):
"""Return the device name."""
return self._name
@property
def masked_id(self):
"""Return the masked device id (isolated address bits)."""
return self._masked_id
@property
def data_bits(self):
"""Return the number of data bits."""
return self._data_bits
@property
def cmd_on(self):
"""Return the value of the 'On' command."""
return self._cmd_on
@property
def cmd_off(self):
"""Return the value of the 'Off' command."""
return self._cmd_off
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def should_fire_event(self):
"""Return is the device must fire event."""
return self._should_fire_event
@property
def device_class(self):
"""Return the sensor class."""
return self._device_class
@property
def off_delay(self):
"""Return the off_delay attribute value."""
return self._off_delay
@property
def is_on(self):
"""Return true if the sensor state is True."""
return self._state
def apply_cmd(self, cmd):
"""Apply a command for updating the state."""
if cmd == self.cmd_on:
self.update_state(True)
elif cmd == self.cmd_off:
self.update_state(False)
def update_state(self, state):
"""Update the state of the device."""
self._state = state
self.schedule_update_ha_state()

View File

@@ -41,10 +41,10 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Raspberry PI GPIO devices."""
pull_mode = config.get('pull_mode', DEFAULT_PULL_MODE)
bouncetime = config.get('bouncetime', DEFAULT_BOUNCETIME)
invert_logic = config.get('invert_logic', DEFAULT_INVERT_LOGIC)
"""Set up the Raspberry PI GPIO devices."""
pull_mode = config.get(CONF_PULL_MODE)
bouncetime = config.get(CONF_BOUNCETIME)
invert_logic = config.get(CONF_INVERT_LOGIC)
binary_sensors = []
ports = config.get('ports')

View File

@@ -0,0 +1,93 @@
"""
Support for binary sensor using the PiFace Digital I/O module on a RPi.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.rpi_pfio/
"""
import logging
import voluptuous as vol
import homeassistant.components.rpi_pfio as rpi_pfio
from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.const import DEVICE_DEFAULT_NAME
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
ATTR_NAME = 'name'
ATTR_INVERT_LOGIC = 'invert_logic'
ATTR_SETTLE_TIME = 'settle_time'
CONF_PORTS = 'ports'
DEFAULT_INVERT_LOGIC = False
DEFAULT_SETTLE_TIME = 20
DEPENDENCIES = ['rpi_pfio']
PORT_SCHEMA = vol.Schema({
vol.Optional(ATTR_NAME, default=None): cv.string,
vol.Optional(ATTR_SETTLE_TIME, default=DEFAULT_SETTLE_TIME):
cv.positive_int,
vol.Optional(ATTR_INVERT_LOGIC, default=DEFAULT_INVERT_LOGIC): cv.boolean
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_PORTS, default={}): vol.Schema({
cv.positive_int: PORT_SCHEMA
})
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the PiFace Digital Input devices."""
binary_sensors = []
ports = config.get('ports')
for port, port_entity in ports.items():
name = port_entity[ATTR_NAME]
settle_time = port_entity[ATTR_SETTLE_TIME] / 1000
invert_logic = port_entity[ATTR_INVERT_LOGIC]
binary_sensors.append(RPiPFIOBinarySensor(
hass, port, name, settle_time, invert_logic))
add_devices(binary_sensors, True)
rpi_pfio.activate_listener(hass)
class RPiPFIOBinarySensor(BinarySensorDevice):
"""Represent a binary sensor that a PiFace Digital Input."""
def __init__(self, hass, port, name, settle_time, invert_logic):
"""Initialize the RPi binary sensor."""
self._port = port
self._name = name or DEVICE_DEFAULT_NAME
self._invert_logic = invert_logic
self._state = None
def read_pfio(port):
"""Read state from PFIO."""
self._state = rpi_pfio.read_input(self._port)
self.schedule_update_ha_state()
rpi_pfio.edge_detect(hass, self._port, read_pfio, settle_time)
@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
def update(self):
"""Update the PFIO state."""
self._state = rpi_pfio.read_input(self._port)

View File

@@ -11,7 +11,7 @@ DEPENDENCIES = ['sleepiq']
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the SleepIQ sensors."""
"""Set up the SleepIQ sensors."""
if discovery_info is None:
return

View File

@@ -0,0 +1,99 @@
"""
Support for Vanderbilt (formerly Siemens) SPC alarm systems.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.spc/
"""
import logging
import asyncio
from homeassistant.components.spc import (
ATTR_DISCOVER_DEVICES, DATA_REGISTRY)
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.const import (STATE_UNAVAILABLE, STATE_ON, STATE_OFF)
_LOGGER = logging.getLogger(__name__)
SPC_TYPE_TO_DEVICE_CLASS = {'0': 'motion',
'1': 'opening',
'3': 'smoke'}
SPC_INPUT_TO_SENSOR_STATE = {'0': STATE_OFF,
'1': STATE_ON}
def _get_device_class(spc_type):
return SPC_TYPE_TO_DEVICE_CLASS.get(spc_type, None)
def _get_sensor_state(spc_input):
return SPC_INPUT_TO_SENSOR_STATE.get(spc_input, STATE_UNAVAILABLE)
def _create_sensor(hass, zone):
return SpcBinarySensor(zone_id=zone['id'],
name=zone['zone_name'],
state=_get_sensor_state(zone['input']),
device_class=_get_device_class(zone['type']),
spc_registry=hass.data[DATA_REGISTRY])
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Initialize the platform."""
if (discovery_info is None or
discovery_info[ATTR_DISCOVER_DEVICES] is None):
return
async_add_entities(
_create_sensor(hass, zone)
for zone in discovery_info[ATTR_DISCOVER_DEVICES]
if _get_device_class(zone['type']))
class SpcBinarySensor(BinarySensorDevice):
"""Represents a sensor based on an SPC zone."""
def __init__(self, zone_id, name, state, device_class, spc_registry):
"""Initialize the sensor device."""
self._zone_id = zone_id
self._name = name
self._state = state
self._device_class = device_class
spc_registry.register_sensor_device(zone_id, self)
@asyncio.coroutine
def async_update_from_spc(self, state):
"""Update the state of the device."""
self._state = state
yield from self.async_update_ha_state()
@property
def name(self):
"""The name of the device."""
return self._name
@property
def is_on(self):
"""Whether the device is switched on."""
return self._state == STATE_ON
@property
def hidden(self) -> bool:
"""Whether the device is hidden by default."""
# these type of sensors are probably mainly used for automations
return True
@property
def should_poll(self):
"""No polling needed."""
return False
@property
def device_class(self):
"""The device class."""
return self._device_class

View File

@@ -0,0 +1,86 @@
"""
Support for Taps Affs.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.tapsaff/
"""
import logging
from datetime import timedelta
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)
REQUIREMENTS = ['tapsaff==0.1.3']
_LOGGER = logging.getLogger(__name__)
CONF_LOCATION = 'location'
DEFAULT_NAME = 'Taps Aff'
SCAN_INTERVAL = timedelta(minutes=30)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_LOCATION): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Taps Aff binary sensor."""
name = config.get(CONF_NAME)
location = config.get(CONF_LOCATION)
taps_aff_data = TapsAffData(location)
add_devices([TapsAffSensor(taps_aff_data, name)], True)
class TapsAffSensor(BinarySensorDevice):
"""Implementation of a Taps Aff binary sensor."""
def __init__(self, taps_aff_data, name):
"""Initialize the Taps Aff sensor."""
self.data = taps_aff_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 taps aff."""
return self.data.is_taps_aff
def update(self):
"""Get the latest data."""
self.data.update()
class TapsAffData(object):
"""Class for handling the data retrieval for pins."""
def __init__(self, location):
"""Initialize the sensor."""
from tapsaff import TapsAff
self._is_taps_aff = None
self.taps_aff = TapsAff(location)
@property
def is_taps_aff(self):
"""Return true if taps aff."""
return self._is_taps_aff
def update(self):
"""Get the latest data from the Taps Aff API and updates the states."""
try:
self._is_taps_aff = self.taps_aff.is_taps_aff
except RuntimeError:
_LOGGER.error("Update failed. Check configured location")

View File

@@ -27,5 +27,5 @@ class TcpBinarySensor(BinarySensorDevice, TcpSensor):
@property
def is_on(self):
"""True if the binary sensor is on."""
"""Return true if the binary sensor is on."""
return self._state == self._config[CONF_VALUE_ON]

View File

@@ -15,11 +15,9 @@ from homeassistant.components.binary_sensor import (
DEVICE_CLASSES_SCHEMA)
from homeassistant.const import (
ATTR_FRIENDLY_NAME, ATTR_ENTITY_ID, CONF_VALUE_TEMPLATE,
CONF_SENSOR_CLASS, CONF_SENSORS, CONF_DEVICE_CLASS,
EVENT_HOMEASSISTANT_START, STATE_ON)
CONF_SENSORS, CONF_DEVICE_CLASS, EVENT_HOMEASSISTANT_START, STATE_ON)
from homeassistant.exceptions import TemplateError
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.event import async_track_state_change
from homeassistant.helpers.restore_state import async_get_last_state
@@ -30,7 +28,6 @@ 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): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
@@ -41,7 +38,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup template binary sensors."""
"""Set up template binary sensors."""
sensors = []
for device, device_config in config[CONF_SENSORS].items():
@@ -49,23 +46,18 @@ def async_setup_platform(hass, config, async_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)
device_class = get_deprecated(
device_config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
device_class = device_config.get(CONF_DEVICE_CLASS)
if value_template is not None:
value_template.hass = hass
sensors.append(
BinarySensorTemplate(
hass,
device,
friendly_name,
device_class,
value_template,
hass, device, friendly_name, device_class, value_template,
entity_ids)
)
if not sensors:
_LOGGER.error('No sensors added')
_LOGGER.error("No sensors added")
return False
async_add_devices(sensors, True)
@@ -79,8 +71,8 @@ class BinarySensorTemplate(BinarySensorDevice):
value_template, entity_ids):
"""Initialize the Template binary sensor."""
self.hass = hass
self.entity_id = async_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._device_class = device_class
self._template = value_template
@@ -96,7 +88,7 @@ class BinarySensorTemplate(BinarySensorDevice):
@callback
def template_bsensor_state_listener(entity, old_state, new_state):
"""Called when the target device changes state."""
"""Handle the target device state changes."""
self.hass.async_add_job(self.async_update_ha_state(True))
@callback
@@ -139,8 +131,8 @@ class BinarySensorTemplate(BinarySensorDevice):
if ex.args and ex.args[0].startswith(
"UndefinedError: 'None' has no attribute"):
# Common during HA startup - so just a warning
_LOGGER.warning('Could not render template %s,'
' the state is unknown.', self._name)
_LOGGER.warning("Could not render template %s, "
"the state is unknown", self._name)
return
_LOGGER.error('Could not render template %s: %s', self._name, ex)
_LOGGER.error("Could not render template %s: %s", self._name, ex)
self._state = False

View File

@@ -13,10 +13,9 @@ 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,
CONF_NAME, CONF_ENTITY_ID, CONF_TYPE, STATE_UNKNOWN,
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__)
@@ -38,7 +37,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
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,
})
@@ -50,7 +48,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
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)
device_class = config.get(CONF_DEVICE_CLASS)
async_add_devices(
[ThresholdSensor(hass, entity_id, name, threshold, limit_type,
@@ -77,7 +75,7 @@ class ThresholdSensor(BinarySensorDevice):
# pylint: disable=invalid-name
def async_threshold_sensor_state_listener(
entity, old_state, new_state):
"""Called when the sensor changes state."""
"""Handle sensor state changes."""
if new_state.state == STATE_UNKNOWN:
return

View File

@@ -6,23 +6,17 @@ 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,
BinarySensorDevice, ENTITY_ID_FORMAT, PLATFORM_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
ATTR_FRIENDLY_NAME, ATTR_ENTITY_ID, CONF_DEVICE_CLASS, STATE_UNKNOWN)
from homeassistant.helpers.entity import generate_entity_id
from homeassistant.helpers.event import track_state_change
@@ -36,7 +30,6 @@ 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): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
})
@@ -47,26 +40,20 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the trend sensors."""
"""Set up the trend sensors."""
sensors = []
for device, device_config in config[CONF_SENSORS].items():
entity_id = device_config[ATTR_ENTITY_ID]
attribute = device_config.get(CONF_ATTRIBUTE)
friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device)
device_class = get_deprecated(
device_config, CONF_DEVICE_CLASS, CONF_SENSOR_CLASS)
device_class = device_config.get(CONF_DEVICE_CLASS)
invert = device_config[CONF_INVERT]
sensors.append(
SensorTrend(
hass,
device,
friendly_name,
entity_id,
attribute,
device_class,
invert)
hass, device, friendly_name, entity_id, attribute,
device_class, invert)
)
if not sensors:
_LOGGER.error("No sensors added")
@@ -82,8 +69,8 @@ class SensorTrend(BinarySensorDevice):
target_entity, attribute, device_class, invert):
"""Initialize the sensor."""
self._hass = hass
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id,
hass=hass)
self.entity_id = generate_entity_id(
ENTITY_ID_FORMAT, device_id, hass=hass)
self._name = friendly_name
self._target_entity = target_entity
self._attribute = attribute
@@ -95,7 +82,7 @@ class SensorTrend(BinarySensorDevice):
@callback
def trend_sensor_state_listener(entity, old_state, new_state):
"""Called when the target device changes state."""
"""Handle the target device state changes."""
self.from_state = old_state
self.to_state = new_state
hass.async_add_job(self.async_update_ha_state(True))

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