Compare commits

..

207 Commits
0.7.7 ... 0.8

Author SHA1 Message Date
Paulus Schoutsen
8e44ed0090 Merge pull request #617 from balloob/dev
0.8.0.rc1
2015-11-16 00:03:20 -08:00
Paulus Schoutsen
5fb6076f6e Version bump to 0.8.0 2015-11-16 00:03:00 -08:00
Fabian Affolter
4ea6def1bd Update docstrings and link to docs 2015-11-16 07:53:31 +01:00
Paulus Schoutsen
314185ffb8 Merge pull request #629 from rmkraus/dev
Adding updater to default list of components
2015-11-15 17:30:15 -08:00
Ryan Kraus
8aafb89a64 Merge remote-tracking branch 'balloob/dev' into dev 2015-11-15 20:04:21 -05:00
Ryan Kraus
d01ed9788f Added updater to set of default components 2015-11-15 20:03:45 -05:00
Paulus Schoutsen
b4e2f4f0be Merge pull request #625 from balloob/enhancement_pushbullet
Enhancement: targeted notifications in pushbullet
2015-11-15 16:41:18 -08:00
Tom Duijf
f4d8325084 Pushbullet; code cleanup & better errors on config typos 2015-11-16 00:29:04 +00:00
Tom Duijf
cc5dec3c59 Processed feedback from PR comments 2015-11-15 23:46:16 +00:00
Ryan Kraus
ec5a93a0fd Merge remote-tracking branch 'balloob/dev' into dev 2015-11-15 18:16:49 -05:00
Paulus Schoutsen
aabda1b7b0 Merge pull request #628 from rmkraus/dev
Small tweaks to daemon management.
2015-11-15 14:46:58 -08:00
Tom Duijf
aee4411cfb <type>.<name> split only on first separator 2015-11-15 22:44:51 +00:00
Ryan Kraus
135eb0a0ac Fixed hass daemon management
1) Changed signal to exit hass to SIGTERM
2) Updated initd script to send SIGTERM
3) Updated systemd script to never send SIGKILL.
2015-11-15 17:43:38 -05:00
Ryan Kraus
01daac066a Merge remote-tracking branch 'balloob/dev' into dev 2015-11-15 17:37:57 -05:00
Ryan Kraus
5d96ca133d Merge pull request #627 from rmkraus/update_notify
Updater component
2015-11-15 17:36:55 -05:00
Ryan Kraus
3cda1aacff Fixed typo in updater entity attributes.
Left some quotes in there. My bad.
2015-11-15 17:34:06 -05:00
Ryan Kraus
243130c133 Using ATTR_FRIENDLY_NAME in updater component. 2015-11-15 17:32:05 -05:00
Paulus Schoutsen
0d74b628b0 Merge pull request #623 from balloob/lib-clean-on-upgrade
Lib clean on upgrade
2015-11-15 14:30:51 -08:00
Ryan Kraus
c314101dde Updater suggestions from Paulus
1) Moved error checking into get_newest_version function.
2) Fixed import formatting mistake.
2015-11-15 17:30:42 -05:00
Paulus Schoutsen
0f68dc6b7b Add tests for version upgrade 2015-11-15 14:28:50 -08:00
Ryan Kraus
919c20a263 Implemented suggestions from Paulus for updater
1) Better Error handling when making PyPI requests.
2) More efficient event scheduling.
3) ENTITY_ID in constant
3) friendly_name from constant
2015-11-15 17:23:56 -05:00
Ryan Kraus
9b5385c565 Merge remote-tracking branch 'balloob/dev' into update_notify
Conflicts:
	homeassistant/components/frontend/version.py
	homeassistant/components/frontend/www_static/frontend.html
2015-11-15 17:00:35 -05:00
Ryan Kraus
7dacf01baa Updating fronted to latest version. 2015-11-15 16:56:33 -05:00
Tom Duijf
9b4650afd4 Added comments 2015-11-15 20:49:42 +00:00
Tom Duijf
0b0fd2490d Pushbullet; styling, requirements, example 2015-11-15 19:14:10 +00:00
Tom Duijf
3a85bebbf6 pushbullet; styling and minor fixed before PR 2015-11-15 18:57:16 +00:00
Paulus Schoutsen
18f1de10a5 Merge pull request #624 from leoc/feature-zwave-meter-sensor
Add Zwave `meter` command class
2015-11-15 10:16:57 -08:00
Paulus Schoutsen
869d6df65e Merge pull request #618 from nkgilley/camera-fix
add exception handling to generic camera requests function.
2015-11-15 10:02:20 -08:00
Tom Duijf
0a586bd919 Initial commit of pushbullet enhancement 2015-11-15 17:50:36 +00:00
Fabian Affolter
a98b1b0ebc Update link to docs 2015-11-15 18:50:06 +01:00
Paulus Schoutsen
511028612c Merge pull request #593 from leoc/feature-zwave-switches
Implement zwave switches
2015-11-15 09:30:06 -08:00
Paulus Schoutsen
e3efce5ded Merge pull request #622 from happyleavesaoc/s20
s20 switch support
2015-11-15 09:28:40 -08:00
Arthur Andersen
340ee171b5 [Zwave] Add zwave polling interval configuration 2015-11-15 17:50:14 +01:00
Arthur Andersen
773da3f755 [Zwave] Add Meter command class 2015-11-15 17:50:11 +01:00
happyleaves
12bdc39274 don't update state in turn_on/off 2015-11-15 08:59:18 -05:00
Paulus Schoutsen
700b7ba591 Remove unused import in notify 2015-11-15 02:20:35 -08:00
Paulus Schoutsen
295f27d259 Only delete lib dir in config upgrade if exists 2015-11-15 02:16:52 -08:00
Ryan Kraus
4463b69245 Added friendly name to updater component. 2015-11-15 05:15:36 -05:00
Paulus Schoutsen
71e4283a2e Remove lib directory in version upgrade 2015-11-15 02:05:46 -08:00
Paulus Schoutsen
6135b87b1d Log error if unable to install package 2015-11-15 02:05:13 -08:00
Paulus Schoutsen
04bb7ed58f Have Notify platform install platform dependencies 2015-11-15 02:04:57 -08:00
Ryan Kraus
dfa9880176 Created updater component 2015-11-15 05:00:24 -05:00
Paulus Schoutsen
88f3a5a50a Update to new version frontend 2015-11-15 00:51:12 -08:00
Paulus Schoutsen
e2c530b85d Script: new attribute if can cancel 2015-11-14 15:38:07 -08:00
Arthur Andersen
56c5d345a4 [Zwave] Update HA state on value change 2015-11-14 23:14:08 +01:00
happyleaves
86b9ae9566 addressed comments 2015-11-14 16:14:25 -05:00
Nolan Gilley
df264f2ec0 remove unnecessary else 2015-11-14 15:49:39 -05:00
happyleaves
aabcad59d8 rename platform to orvibo 2015-11-14 15:05:22 -05:00
happyleaves
70fef3c5b5 fixed names 2015-11-14 14:25:53 -05:00
happyleaves
57ec58e255 fixed requirements 2015-11-14 14:19:47 -05:00
happyleaves
cf8e23adbc s20 switch support 2015-11-14 14:14:02 -05:00
Paulus Schoutsen
eabf9087f3 Merge pull request #621 from fabaff/cleanup-glances
Glances sensor cleanup
2015-11-14 10:51:57 -08:00
Nolan Gilley
9acb341b96 remove break 2015-11-14 10:51:07 -05:00
Fabian Affolter
5275ca9ce7 Fix typo 2015-11-14 15:25:52 +01:00
Fabian Affolter
646618a25e Improve error messages, use constants, and fix docstrings 2015-11-14 15:23:20 +01:00
Paulus Schoutsen
bc48e4f98e Merge pull request #619 from nkgilley/mqtt-light-color-fix
Remove rgb color if it's not an rgb bulb.
2015-11-14 00:51:18 -08:00
Nolan Gilley
776324807e last PR was dumb. this fix is better. 2015-11-13 14:58:49 -05:00
Nolan Gilley
d68a4b52f1 Remove rgb color if it's not an rgb bulb. 2015-11-13 14:32:47 -05:00
Nolan Gilley
85e0db6ade add exception handling to generic camera requests function. 2015-11-13 13:55:22 -05:00
Fabian Affolter
d993f4014e Add link to docs 2015-11-13 08:29:54 +01:00
Paulus Schoutsen
7ebda9c3c6 Fix MQTT light test 2015-11-12 23:08:26 -08:00
Paulus Schoutsen
16e948d032 Merge branch 'pr/552' into dev 2015-11-12 23:04:05 -08:00
Paulus Schoutsen
41d0f95d9a Move core light test to correct dir 2015-11-12 23:03:56 -08:00
Paulus Schoutsen
bfaaf39e9e Merge pull request #613 from Xorso/squeezebox_fix
Fixing bug when connecting to squeezebox and it is a float
2015-11-12 22:45:03 -08:00
Paulus Schoutsen
16904452b8 Merge pull request #614 from persandstrom/asuswrt_not_loading
ASUSWRT more logging and more robust
2015-11-12 11:43:49 -08:00
Per Sandström
158d9e27ff more robust and more logging 2015-11-12 20:10:25 +01:00
Fabian Affolter
b652dd47cd Update file header and docstrings 2015-11-12 18:04:48 +01:00
Daren Lord
2812fae721 Fixing bug when connecting to squeezebox and it is a float 2015-11-11 16:21:42 -07:00
Tom Duijf
6da88108fe Merge pull request #612 from balloob/dt_snmp_fix
Fix memory issue in SNMP device tracker
2015-11-11 23:30:43 +01:00
Tom Duijf
5503c12cfd Fixes memory consumption issue 2015-11-11 21:54:33 +00:00
hexxter
329d63ac11 next online unittest test ;) 2015-11-11 20:52:41 +01:00
hexxter
698e30bd2b more self.hass.pool.block_till_done() 2015-11-11 20:40:21 +01:00
hexxter
90063ea7f8 check the default value only checkable local. I removed it. 2015-11-11 12:44:59 +01:00
hexxter
0c52b143ae now saved 2015-11-11 12:38:10 +01:00
hexxter
8f12b997f8 more unittests 2015-11-11 12:32:24 +01:00
Arthur Andersen
877926cfee [Zwave] Fix docstring 2015-11-11 10:24:00 +01:00
Arthur Andersen
19649390d3 [Zwave] Add binary switch component 2015-11-11 10:24:00 +01:00
Paulus Schoutsen
50d19bb1b4 Merge pull request #592 from leoc/feature-zwave-lights
Implement zwave light support
2015-11-11 00:11:51 -08:00
Arthur Andersen
665436cd91 [Zwave] Use threading.Timer for value refresh delay 2015-11-10 19:59:45 +01:00
Paulus Schoutsen
1a3410119e Merge pull request #606 from fabaff/pushetta
Pushetta notification platform
2015-11-10 09:27:16 -08:00
Fabian Affolter
bf2bcb6dcf Use _LOGGER.error instead of _LOGGER.exception 2015-11-10 18:20:10 +01:00
Fabian Affolter
8371b08676 Add pushetta notify platform 2015-11-10 14:17:28 +01:00
Fabian Affolter
e8a0d54fdd Add pushetta 2015-11-10 14:17:28 +01:00
Fabian Affolter
f4a82c6f6b Add pushetta 2015-11-10 14:17:28 +01:00
Paulus Schoutsen
963c4bb70e Update frontend with new card style 2015-11-10 00:56:56 -08:00
Paulus Schoutsen
ec2e0cc77d Compile new version frontend 2015-11-10 00:27:41 -08:00
Paulus Schoutsen
0c0ccb361d Merge branch 'dev-tool-info' into dev 2015-11-10 00:25:33 -08:00
Paulus Schoutsen
994fc32f25 Upgrade frontend with about page 2015-11-10 00:25:19 -08:00
Paulus Schoutsen
d68263d5c4 Another LimitlessLED color fix 2015-11-09 21:55:49 -08:00
Paulus Schoutsen
27b001df2b Add dev info to frontend urls 2015-11-09 21:48:36 -08:00
Paulus Schoutsen
dafc0ced6b Update limitlessled with lists for colors 2015-11-09 16:55:10 -08:00
Paulus Schoutsen
3ec2555c66 Merge pull request #601 from balloob/package-install-global
Check global installed packages
2015-11-09 12:45:51 -08:00
Fabian Affolter
bfa8e58879 Update link to docs (Jekyll 3 update) 2015-11-09 18:33:11 +01:00
Paulus Schoutsen
2d9a785c18 Merge pull request #600 from balloob/cleanup-notify
Clean up notifiy component
2015-11-09 07:32:13 -08:00
Fabian Affolter
97f9f8aa49 Update link to docs (Jekyll 3 update) 2015-11-09 13:12:18 +01:00
Fabian Affolter
64d5ca4da0 Add link to docs and update some docstrings 2015-11-09 08:25:46 +01:00
Paulus Schoutsen
4fb301b7a9 Check global installed packages 2015-11-08 22:55:22 -08:00
Paulus Schoutsen
fda65a4934 Update coveragerc 2015-11-08 22:33:43 -08:00
Paulus Schoutsen
98b4c27211 Style fixes 2015-11-08 22:21:02 -08:00
Paulus Schoutsen
3b3f5fe6fe Clean up notifiy component 2015-11-08 22:15:34 -08:00
Paulus Schoutsen
1c9c5ce1bd Merge pull request #599 from ryanturner/dev
Initial implementation of mjpeg camera
2015-11-08 22:13:49 -08:00
Ryan Turner
a36b315927 Fixed indentations hopefully 2015-11-09 00:11:11 -06:00
Ryan Turner
f3352546c6 More lint fixes 2015-11-09 00:00:31 -06:00
Ryan Turner
3a6aa8f3d1 Fixed line length issues to make lint happy. Still bummed that I decreased test coverage :( 2015-11-08 23:51:01 -06:00
Ryan Turner
dfa81b0117 Changed camera.mjpeg to use Response and Closing; cleaned up a number of code-clarity issues near that 2015-11-08 23:41:21 -06:00
Paulus Schoutsen
3947691347 Style fixes + rename honeywell 2015-11-08 20:56:11 -08:00
Ryan Turner
8541fdb112 Fixed style issue related to failing build 2015-11-08 22:26:27 -06:00
Ryan Turner
e078ab53ca Initial implementation of mjpeg camera 2015-11-08 22:15:06 -06:00
Paulus Schoutsen
0665af7f0f Merge branch 'pr/579' into dev
Conflicts:
	requirements_all.txt
2015-11-08 20:10:30 -08:00
Paulus Schoutsen
6dfb8f5737 Merge pull request #591 from balloob/error-log
Expose API to view error log
2015-11-08 20:06:56 -08:00
Paulus Schoutsen
1be2be0886 Merge pull request #590 from balloob/light-rgb
Light: base color now in RGB instead of XY
2015-11-08 20:06:49 -08:00
Paulus Schoutsen
3a095f53a8 Merge pull request #596 from badele/dev
Minor change for logger component
2015-11-08 19:57:58 -08:00
Paulus Schoutsen
ffce252a12 Merge pull request #598 from SEJeff/update-foscam-snapshot
Make a single request to get the foscam camera image
2015-11-08 19:57:21 -08:00
Paulus Schoutsen
7f4c13c382 Upgrade Wink version to v0.1.1 2015-11-08 19:41:22 -08:00
Jeff Schroeder
0f292e8fa6 Remove unused import for re 2015-11-08 20:37:29 -06:00
badele
e63d0c51e0 Change log severity 2015-11-08 19:02:51 +01:00
badele
ebaecdb9d6 Fix flake & pylint 2015-11-08 11:29:56 +01:00
badele
fd50693ca7 Minor change to documentation for logger component 2015-11-08 11:26:36 +01:00
badele
ebc95aca51 Add log info in the rfxtrx component 2015-11-08 11:15:03 +01:00
Jeff Schroeder
137cadb59c Make a single request to get the foscam camera image
This uses the `snapPicture2` command, which is documented in their
cgi sdk to return raw jpeg data instead of html containing the image
2015-11-07 20:18:46 -06:00
Arthur Andersen
84f81480bb [Zwave] Add light zwave component 2015-11-07 15:58:28 +01:00
Arthur Andersen
5565e418f8 [Zwave] Add type and genre to value filter 2015-11-07 15:57:46 +01:00
Arthur Andersen
5b4fc4f346 [Zwave] Add check for missing discovery_service 2015-11-07 15:57:28 +01:00
Paulus Schoutsen
e4c3d47dbf Expose API to view error log 2015-11-07 01:44:02 -08:00
Paulus Schoutsen
95320f39b3 Light: base color now in RGB instead of XY 2015-11-07 01:25:33 -08:00
Paulus Schoutsen
0c97280479 Merge pull request #587 from badele/logfilter
Add logger filter feature
2015-11-06 21:59:56 -08:00
Paulus Schoutsen
3e339c7304 Update vincenty version in setup.py 2015-11-06 21:58:18 -08:00
badele
6f06f48ac6 Ensure the component is loaded first 2015-11-06 22:57:03 +01:00
badele
aeacbad4a0 Fix pull request from balloob comments 2015-11-06 22:51:33 +01:00
sander
f60f3fa4a2 Removed unused self._sensorid. 2015-11-06 08:37:22 +01:00
sander
e49dc94d4b slightly better update method. 2015-11-05 09:58:35 +01:00
sander
26a6438e93 learning the alphabet ;-) 2015-11-05 09:37:05 +01:00
Paulus Schoutsen
cae71a73a1 Update frontend 2015-11-05 00:03:01 -08:00
Paulus Schoutsen
df7f6e1235 Remove alarm sensor from demo platform 2015-11-04 23:53:22 -08:00
badele
a31f7d2816 Fix flake & pylint 2015-11-04 22:08:15 +01:00
badele
c52c982510 Add logger feature 2015-11-04 21:30:02 +01:00
sander
ea06d946e6 modified .converagerc and requirements_all.txt 2015-11-04 21:15:56 +01:00
Paulus Schoutsen
bd798b8c55 Merge pull request #582 from balloob/mdi-icons
Icons for everyone!
2015-11-04 09:08:34 -08:00
Paulus Schoutsen
ac7456b73b Merge pull request #577 from happyleavesaoc/limitlessled_additions
LimitlessLED effects
2015-11-04 09:02:43 -08:00
Fabian Affolter
d69b08ecf5 Update with comments from PR 579 2015-11-03 11:46:03 +01:00
Paulus Schoutsen
be6dd20236 Update frontend with new icons 2015-11-03 00:20:59 -08:00
Paulus Schoutsen
4d069323f4 Add icon support to entity 2015-11-03 00:20:48 -08:00
Paulus Schoutsen
77f4fc8c22 Frontend: Add materialdesignicons 2015-11-03 00:20:20 -08:00
Paulus Schoutsen
72b4212b19 Demo uses device tracker demo platform 2015-11-03 00:19:28 -08:00
Fabian Affolter
5fce381b89 Remove empty point 2015-11-03 08:50:27 +01:00
happyleaves
7b968f6a6b re-fix conditionals 2015-11-02 18:11:58 -05:00
happyleaves
4d958c6d18 style fix 2015-11-02 18:08:17 -05:00
happyleaves
566712023d consolidate conditionals 2015-11-02 18:08:17 -05:00
happyleaves
3cd89f8474 add disco, white effects 2015-11-02 18:08:17 -05:00
Fabian Affolter
218a05356a Add docstrings 2015-11-02 21:00:53 +01:00
hexxter
186f68cce3 not working mqtt light unittest 2015-11-02 20:16:36 +01:00
hexxter
168eb8e5a2 mqtt light test is working more test should be written 2015-11-02 17:02:34 +01:00
Paulus Schoutsen
c6b5a04312 Allow more static files to be fingerprinted 2015-11-02 00:03:53 -08:00
Paulus Schoutsen
728cd8bb5e Upgrade Vincenty to latest version 2015-11-02 00:03:53 -08:00
Stefan Jonasson
d873ab0262 Merge pull request #569 from stefan-jonasson/dev
Fix for Philio Zwave devices which don't send an off event.
2015-11-02 08:15:57 +01:00
Daniel Høyer Iversen
0ff6a460c2 Update rfxtrx.py 2015-11-01 14:20:11 +01:00
Daniel Høyer Iversen
77539a5b89 revert prev commit 2015-11-01 12:51:09 +01:00
Daniel Høyer Iversen
92b05389f2 Update rfxtrx.py 2015-11-01 12:41:21 +01:00
Daniel Høyer Iversen
82aec895a0 Minor bug in rfxtrx 2015-11-01 12:40:41 +01:00
Stefan Jonasson
ec732becfc Fixed the get_config_value method when the zwave node was changed while reading it. 2015-10-31 23:34:19 +01:00
Stefan Jonasson
c4261ae2e0 Z-Wave workaround - Added a default value if we did not get any config value. 2015-10-31 23:03:40 +01:00
Stefan Jonasson
cae8932b18 Z-Wave workaround - Connected to the timeout to the configured node value "9. Turn Off Light Time" 2015-10-31 21:23:33 +01:00
sander
efacd66bec linting and flakeing.. 2015-10-31 20:35:23 +01:00
hexxter
31826ab263 redesigned mqtt light an first steps with the unittest system 2015-10-31 19:26:03 +01:00
Paulus Schoutsen
6bb95f5c9b Merge pull request #560 from pavoni/add-vera-dimmer
Add vera dimmer
2015-10-30 21:47:02 -07:00
Paulus Schoutsen
46761d827f Merge pull request #570 from nkgilley/actiontec-fix
Actiontec device_tracker bugfix and removed home_interval
2015-10-30 21:18:28 -07:00
Paulus Schoutsen
288db9a57f Merge pull request #559 from balloob/light_ct_color
Color temperature support for light component and hue platform
2015-10-30 19:11:24 -07:00
Tom Duijf
b76471c4b3 :( .. pyliny 2015-10-30 19:15:38 +00:00
Tom Duijf
194c6343ac Minor corrections to light and light/demo 2015-10-30 19:01:42 +00:00
Stefan Jonasson
2ad647bb09 Style fixes 2015-10-30 15:30:08 +01:00
Stefan Jonasson
a56173676e Fixed the workaround match logic 2015-10-30 15:28:06 +01:00
Nolan Gilley
e961dd5f95 increase valid for time to 60 since I was having some issues. removed deprecated lines. 2015-10-30 07:00:35 -04:00
pavoni
0269be5813 Update pyvera version 2015-10-30 09:39:30 +00:00
pavoni
031d5ce255 Fix style issues, update pyvera version. 2015-10-30 09:37:16 +00:00
sander
85bb828149 changed requirements to the latest evohome version. 2015-10-29 21:17:10 +01:00
Paulus Schoutsen
c7a0b5800c Update links in introduction component 2015-10-29 00:23:05 -07:00
Tom Duijf
f456d2ff23 styling fix 2015-10-28 23:16:25 +00:00
Tom Duijf
6bad702db4 Renamed to color_temp, removed capabilities (not needed afterall) 2015-10-28 23:12:16 +00:00
Nolan Gilley
bcb2451752 fix pylint warning 2015-10-28 17:47:13 -04:00
Nolan Gilley
8eeca94517 removed home_interval option since it was added to the main device_tracker component 2015-10-28 17:43:41 -04:00
Nolan Gilley
3b37a7b737 bugfix for actiontec device tracker 2015-10-28 17:20:15 -04:00
Stefan Jonasson
d578bf3494 Removed extra pylint hint from a previous merge 2015-10-28 22:17:17 +01:00
Stefan Jonasson
8cb046a4a9 Merge remote-tracking branch 'origin/dev' into dev 2015-10-28 22:16:00 +01:00
Stefan Jonasson
30de5af445 Fix for Philio Zwave devices which don't send an off event. 2015-10-28 22:08:50 +01:00
Stefan Jonasson
f74a6ed4c9 Merge remote-tracking branch 'origin/dev' into dev
Conflicts:
	homeassistant/components/script.py
	homeassistant/helpers/entity_component.py
2015-10-28 21:43:46 +01:00
Stefan Jonasson
f3500542dd Added pylint hint 2015-10-28 21:42:42 +01:00
Paulus Schoutsen
2eb65c8eb8 Version bump to 0.8.0.dev0 2015-10-28 12:45:57 -07:00
Stefan Jonasson
10c95b4352 Added pylint hint 2015-10-28 20:17:17 +01:00
Stefan Jonasson
48bfc98acb Fixed entity name 2015-10-28 19:52:09 +01:00
Stefan Jonasson
de027609d8 Fixed entity_id for the script component. Alias now does not override the entity_id
Fixed issue: #561
2015-10-28 12:27:58 +01:00
pavoni
6ef0d089ea Add VeraLight class based on VeraSwitch - add dimmer support 2015-10-27 23:18:46 +00:00
Tom Duijf
805aecd6f9 pylint & flake cleanup 2015-10-27 22:49:45 +00:00
Tom Duijf
e4d33bc6d4 Included ct_color in code coverage 2015-10-27 22:45:35 +00:00
Tom Duijf
e25503bc4a Hue device capabilities. Color temperature support for light component and hue platform 2015-10-27 22:34:49 +00:00
root
4fcd27e905 light/mqtt to .coveragerc 2015-10-27 16:52:43 +01:00
root
0128357024 Merge remote-tracking branch 'upstream/dev' into dev 2015-10-27 07:52:04 +01:00
root
c5f8095f53 Merge remote-tracking branch 'upstream/master' into dev 2015-10-27 07:51:21 +01:00
root
b66e4f1e15 two different demo lights on without RGB and one with RGB support.
and code cleanup more pylint aligned
2015-10-26 15:05:01 +01:00
pavoni
49f4d92c62 Add dimmer as switch 2015-10-26 10:51:23 +00:00
root
a8c2cc4c33 rework for flake8 errors done 2015-10-25 23:38:24 +01:00
root
538f8545f7 fix a bug after the pylint rework 2015-10-25 23:04:43 +01:00
root
7cfce94dfb pylint rework for light/mqtt 2015-10-25 22:58:07 +01:00
root
469d0619ba mqtt light component 2015-10-25 21:48:01 +01:00
sander
863955e1bd got the basics working 2015-10-21 21:48:21 +02:00
sander
f376061e23 Revert "had to change to let this work on windows."
This reverts commit 6c106a87f1.
2015-10-21 19:00:23 +02:00
sander
076b3db5e8 first try 2015-10-21 19:00:15 +02:00
sander
6c106a87f1 had to change to let this work on windows. 2015-10-15 15:02:09 +02:00
188 changed files with 3152 additions and 1764 deletions

View File

@@ -36,10 +36,12 @@ omit =
homeassistant/components/device_tracker/aruba.py
homeassistant/components/device_tracker/asuswrt.py
homeassistant/components/device_tracker/ddwrt.py
homeassistant/components/device_tracker/geofancy.py
homeassistant/components/device_tracker/luci.py
homeassistant/components/device_tracker/ubus.py
homeassistant/components/device_tracker/netgear.py
homeassistant/components/device_tracker/nmap_tracker.py
homeassistant/components/device_tracker/owntracks.py
homeassistant/components/device_tracker/thomson.py
homeassistant/components/device_tracker/tomato.py
homeassistant/components/device_tracker/tplink.py
@@ -48,6 +50,7 @@ omit =
homeassistant/components/downloader.py
homeassistant/components/keyboard.py
homeassistant/components/light/hue.py
homeassistant/components/light/mqtt.py
homeassistant/components/light/limitlessled.py
homeassistant/components/light/blinksticklight.py
homeassistant/components/light/hyperion.py
@@ -64,6 +67,7 @@ omit =
homeassistant/components/notify/instapush.py
homeassistant/components/notify/nma.py
homeassistant/components/notify/pushbullet.py
homeassistant/components/notify/pushetta.py
homeassistant/components/notify/pushover.py
homeassistant/components/notify/slack.py
homeassistant/components/notify/smtp.py
@@ -80,6 +84,7 @@ omit =
homeassistant/components/sensor/glances.py
homeassistant/components/sensor/mysensors.py
homeassistant/components/sensor/openweathermap.py
homeassistant/components/switch/orvibo.py
homeassistant/components/sensor/rest.py
homeassistant/components/sensor/rpi_gpio.py
homeassistant/components/sensor/sabnzbd.py
@@ -97,6 +102,7 @@ omit =
homeassistant/components/switch/rpi_gpio.py
homeassistant/components/switch/transmission.py
homeassistant/components/switch/wemo.py
homeassistant/components/thermostat/honeywell.py
homeassistant/components/thermostat/nest.py
homeassistant/components/thermostat/radiotherm.py

View File

@@ -17,19 +17,19 @@ For help on building your component, please see the [developer documentation](ht
After you finish adding support for your device:
- Update the supported devices in the `README.md` file.
- Add any new dependencies to `requirements_all.txt`. There is no ordering right now, so just add it to the end.
- Update the `.coveragerc` file.
- Provide some documentation for [home-assistant.io](https://home-assistant.io/). The documentation is handled in a separate [git repository](https://github.com/balloob/home-assistant.io). It's OK to add a docstring with configuration details to the file header.
- Add a link to the website of your device/service/component in the "examples" listing of the `README.md` file.
- Add any new dependencies to `requirements_all.txt` if needed. There is no ordering right now, so just add it to the end of the file.
- Update the `.coveragerc` file to exclude your platform if there are no tests available.
- Provide some documentation for [home-assistant.io](https://home-assistant.io/). It's OK to just add a docstring with configuration details (sample entry for `configuration.yaml` file and alike) to the file header as a start. Visit the [website documentation](https://home-assistant.io/developers/website/) for further information on contributing to [home-assistant.io](https://github.com/balloob/home-assistant.io).
- Make sure all your code passes ``pylint`` and ``flake8`` (PEP8 and some more) validation. To check your repository, run `./script/lint`.
- Create a Pull Request against the [**dev**](https://github.com/balloob/home-assistant/tree/dev) branch of Home Assistant.
- Check for comments and suggestions on your Pull Request and keep an eye on the [Travis output](https://travis-ci.org/balloob/home-assistant/).
If you've added a component:
If you add a platform for an existing component, there is usually no need for updating the frontend. Only if you've added a new component that should show up in the frontend, there are more steps needed:
- Update the file [`home-assistant-icons.html`](https://github.com/balloob/home-assistant/blob/master/homeassistant/components/frontend/www_static/polymer/resources/home-assistant-icons.html) with an icon for your domain ([pick one from this list](https://www.polymer-project.org/1.0/components/core-elements/demo.html#core-icon)).
- Update the demo component with two states that it provides
- Add your component to home-assistant.conf.example
- Update the demo component with two states that it provides.
- Add your component to `home-assistant.conf.example`.
Since you've updated `home-assistant-icons.html`, you've made changes to the frontend:

View File

@@ -17,8 +17,7 @@ Check out [the website](https://home-assistant.io) for [a demo][demo], installat
Examples of devices it can interface it:
* Monitoring connected devices to a wireless router: [OpenWrt](https://openwrt.org/), [Tomato](http://www.polarcloud.com/tomato), [Netgear](http://netgear.com), [DD-WRT](http://www.dd-wrt.com/site/index), [TPLink](http://www.tp-link.us/), [ASUSWRT](http://event.asus.com/2013/nw/ASUSWRT/) and any SNMP capable Linksys WAP/WRT
*
* [Philips Hue](http://meethue.com) lights, [WeMo](http://www.belkin.com/us/Products/home-automation/c/wemo-home-automation/) switches, [Edimax](http://www.edimax.com/) switches, [Efergy](https://efergy.com) energy monitoring, RFXtrx sensors, and [Tellstick](http://www.telldus.se/products/tellstick) devices and sensors
* [Philips Hue](http://meethue.com) lights, [WeMo](http://www.belkin.com/us/Products/home-automation/c/wemo-home-automation/) switches, [Edimax](http://www.edimax.com/) switches, [Efergy](https://efergy.com) energy monitoring, and [Tellstick](http://www.telldus.se/products/tellstick) devices and sensors
* [Google Chromecasts](http://www.google.com/intl/en/chrome/devices/chromecast), [Music Player Daemon](http://www.musicpd.org/), [Logitech Squeezebox](https://en.wikipedia.org/wiki/Squeezebox_%28network_music_player%29), [Plex](https://plex.tv/), [Kodi (XBMC)](http://kodi.tv/), iTunes (by way of [itunes-api](https://github.com/maddox/itunes-api)), and Amazon Fire TV (by way of [python-firetv](https://github.com/happyleavesaoc/python-firetv))
* Support for [ISY994](https://www.universal-devices.com/residential/isy994i-series/) (Insteon and X10 devices), [Z-Wave](http://www.z-wave.com/), [Nest Thermostats](https://nest.com/), [RFXtrx](http://www.rfxcom.com/), [Arduino](https://www.arduino.cc/), [Raspberry Pi](https://www.raspberrypi.org/), and [Modbus](http://www.modbus.org/)
* Interaction with [IFTTT](https://ifttt.com/)

View File

@@ -9,11 +9,12 @@ After bootstrapping you can add your own components or
start by calling homeassistant.start_home_assistant(bus)
"""
import os
import sys
from collections import defaultdict
import logging
import logging.handlers
from collections import defaultdict
import os
import shutil
import sys
import homeassistant.core as core
import homeassistant.util.dt as date_util
@@ -25,7 +26,7 @@ import homeassistant.components as core_components
import homeassistant.components.group as group
from homeassistant.helpers.entity import Entity
from homeassistant.const import (
EVENT_COMPONENT_LOADED, CONF_LATITUDE, CONF_LONGITUDE,
__version__, EVENT_COMPONENT_LOADED, CONF_LATITUDE, CONF_LONGITUDE,
CONF_TEMPERATURE_UNIT, CONF_NAME, CONF_TIME_ZONE, CONF_CUSTOMIZE,
TEMP_CELCIUS, TEMP_FAHRENHEIT)
@@ -34,6 +35,7 @@ _LOGGER = logging.getLogger(__name__)
ATTR_COMPONENT = 'component'
PLATFORM_FORMAT = '{}.{}'
ERROR_LOG_FILENAME = 'home-assistant.log'
def setup_component(hass, domain, config=None):
@@ -167,6 +169,7 @@ def from_config_dict(config, hass=None, config_dir=None, enable_log=True,
hass.config.config_dir = config_dir
mount_local_lib_path(config_dir)
process_ha_config_upgrade(hass)
process_ha_core_config(hass, config.get(core.DOMAIN, {}))
if enable_log:
@@ -252,7 +255,7 @@ def enable_logging(hass, verbose=False, daemon=False, log_rotate_days=None):
"Colorlog package not found, console coloring disabled")
# Log errors to a file if we have write access to file or config dir
err_log_path = hass.config.path('home-assistant.log')
err_log_path = hass.config.path(ERROR_LOG_FILENAME)
err_path_exists = os.path.isfile(err_log_path)
# Check if we can write to the error log if it exists or that
@@ -280,6 +283,31 @@ def enable_logging(hass, verbose=False, daemon=False, log_rotate_days=None):
'Unable to setup error log %s (access denied)', err_log_path)
def process_ha_config_upgrade(hass):
""" Upgrade config if necessary. """
version_path = hass.config.path('.HA_VERSION')
try:
with open(version_path, 'rt') as inp:
conf_version = inp.readline().strip()
except FileNotFoundError:
# Last version to not have this file
conf_version = '0.7.7'
if conf_version == __version__:
return
_LOGGER.info('Upgrading config directory from %s to %s', conf_version,
__version__)
lib_path = hass.config.path('lib')
if os.path.isdir(lib_path):
shutil.rmtree(lib_path)
with open(version_path, 'wt') as outp:
outp.write(__version__)
def process_ha_core_config(hass, config):
""" Processes the [homeassistant] section from the config. """
hac = hass.config

View File

@@ -1,7 +1,6 @@
"""
homeassistant.components
~~~~~~~~~~~~~~~~~~~~~~~~
This package contains components that can be plugged into Home Assistant.
Component design guidelines:
@@ -12,7 +11,6 @@ Each component that tracks states should create state entity names in the
format "<DOMAIN>.<OBJECT_ID>".
Each component should publish services only under its own domain.
"""
import itertools as it
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.alarm_control_panel.manual
Support for manual alarms.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.manual.html
https://home-assistant.io/components/alarm_control_panel.manual/
"""
import logging
import datetime

View File

@@ -4,7 +4,7 @@ homeassistant.components.alarm_control_panel.mqtt
This platform enables the possibility to control a MQTT alarm.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.mqtt.html
https://home-assistant.io/components/alarm_control_panel.mqtt/
"""
import logging
import homeassistant.components.mqtt as mqtt

View File

@@ -2,6 +2,9 @@
homeassistant.components.alarm_control_panel.verisure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Interfaces with Verisure alarm control panel.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/verisure/
"""
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.api
Provides a Rest API for Home Assistant.
For more details about the RESTful API, please refer to the documentation at
https://home-assistant.io/developers/api.html
https://home-assistant.io/developers/api/
"""
import re
import logging
@@ -14,13 +14,14 @@ import json
import homeassistant.core as ha
from homeassistant.helpers.state import TrackStates
import homeassistant.remote as rem
from homeassistant.bootstrap import ERROR_LOG_FILENAME
from homeassistant.const import (
URL_API, URL_API_STATES, URL_API_EVENTS, URL_API_SERVICES, URL_API_STREAM,
URL_API_EVENT_FORWARD, URL_API_STATES_ENTITY, URL_API_COMPONENTS,
URL_API_CONFIG, URL_API_BOOTSTRAP,
URL_API_CONFIG, URL_API_BOOTSTRAP, URL_API_ERROR_LOG,
EVENT_TIME_CHANGED, EVENT_HOMEASSISTANT_STOP, MATCH_ALL,
HTTP_OK, HTTP_CREATED, HTTP_BAD_REQUEST, HTTP_NOT_FOUND,
HTTP_UNPROCESSABLE_ENTITY)
HTTP_UNPROCESSABLE_ENTITY, CONTENT_TYPE_TEXT_PLAIN)
DOMAIN = 'api'
@@ -89,6 +90,9 @@ def setup(hass, config):
hass.http.register_path(
'GET', URL_API_COMPONENTS, _handle_get_api_components)
hass.http.register_path('GET', URL_API_ERROR_LOG,
_handle_get_api_error_log)
return True
@@ -341,6 +345,13 @@ def _handle_get_api_components(handler, path_match, data):
handler.write_json(handler.server.hass.config.components)
def _handle_get_api_error_log(handler, path_match, data):
""" Returns the logged errors for this session. """
error_path = handler.server.hass.config.path(ERROR_LOG_FILENAME)
with open(error_path, 'rb') as error_log:
handler.write_file_pointer(CONTENT_TYPE_TEXT_PLAIN, error_log)
def _services_json(hass):
""" Generate services data to JSONify. """
return [{"domain": key, "services": value}

View File

@@ -5,7 +5,7 @@ Arduino component that connects to a directly attached Arduino board which
runs with the Firmata firmware.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/arduino.html
https://home-assistant.io/components/arduino/
"""
import logging

View File

@@ -1,8 +1,10 @@
"""
homeassistant.components.automation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allows to setup simple automation rules via the config file.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/automation/
"""
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.automation.event
Offers event listening automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation.html#event-trigger
at https://home-assistant.io/components/automation/#event-trigger
"""
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.automation.mqtt
Offers MQTT listening automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation.html#mqtt-trigger
at https://home-assistant.io/components/automation/#mqtt-trigger
"""
import logging

View File

@@ -1,10 +1,10 @@
"""
homeassistant.components.automation.numeric_state
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Offers numeric state listening automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation.html#numeric-state-trigger
at https://home-assistant.io/components/automation/#numeric-state-trigger
"""
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.automation.state
Offers state listening automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation.html#state-trigger
at https://home-assistant.io/components/automation/#state-trigger
"""
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.automation.sun
Offers sun based automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation.html#sun-trigger
at https://home-assistant.io/components/automation/#sun-trigger
"""
import logging
from datetime import timedelta

View File

@@ -4,7 +4,7 @@ homeassistant.components.automation.time
Offers time listening automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation.html#time-trigger
at https://home-assistant.io/components/automation/#time-trigger
"""
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.automation.zone
Offers zone automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation.html#zone-trigger
at https://home-assistant.io/components/automation/#zone-trigger
"""
import logging

View File

@@ -1,8 +1,10 @@
"""
homeassistant.components.browser
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Provides functionality to launch a webbrowser on the host machine.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/browser/
"""
DOMAIN = "browser"

View File

@@ -4,24 +4,8 @@ homeassistant.components.camera
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Component to interface with various cameras.
The following features are supported:
- Returning recorded camera images and streams
- Proxying image requests via HA for external access
- Converting a still image url into a live video stream
Upcoming features
- Recording
- Snapshot
- Motion Detection Recording(for supported cameras)
- Automatic Configuration(for supported cameras)
- Creation of child entities for supported functions
- Collating motion event images passed via FTP into time based events
- A service for calling camera functions
- Camera movement(panning)
- Zoom
- Light/Nightvision toggling
- Support for more devices
- Expanded documentation
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/camera/
"""
import requests
import logging
@@ -103,7 +87,10 @@ def setup(hass, config):
if camera:
response = camera.camera_image()
handler.wfile.write(response)
if response is not None:
handler.wfile.write(response)
else:
handler.send_response(HTTP_NOT_FOUND)
else:
handler.send_response(HTTP_NOT_FOUND)
@@ -145,7 +132,8 @@ def setup(hass, config):
while True:
img_bytes = camera.camera_image()
if img_bytes is None:
continue
headers_str = '\r\n'.join((
'Content-length: {}'.format(len(img_bytes)),
'Content-type: image/jpeg',

View File

@@ -4,14 +4,13 @@ homeassistant.components.camera.foscam
This component provides basic support for Foscam IP cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.foscam.html
https://home-assistant.io/components/camera.foscam/
"""
import logging
from homeassistant.helpers import validate_config
from homeassistant.components.camera import DOMAIN
from homeassistant.components.camera import Camera
import requests
import re
_LOGGER = logging.getLogger(__name__)
@@ -40,7 +39,7 @@ class FoscamCamera(Camera):
self._username = device_info.get('username')
self._password = device_info.get('password')
self._snap_picture_url = self._base_url \
+ 'cgi-bin/CGIProxy.fcgi?cmd=snapPicture&usr=' \
+ 'cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=' \
+ self._username + '&pwd=' + self._password
self._name = device_info.get('name', 'Foscam Camera')
@@ -50,17 +49,9 @@ class FoscamCamera(Camera):
def camera_image(self):
""" Return a still image reponse from the camera. """
# send the request to snap a picture
# Send the request to snap a picture and return raw jpg data
response = requests.get(self._snap_picture_url)
# parse the response to find the image file name
pattern = re.compile('src="[.][.]/(.*[.]jpg)"')
filename = pattern.search(response.content.decode("utf-8")).group(1)
# send request for the image
response = requests.get(self._base_url + filename)
return response.content
@property

View File

@@ -4,7 +4,7 @@ homeassistant.components.camera.generic
Support for IP Cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.generic.html
https://home-assistant.io/components/camera.generic/
"""
import logging
from requests.auth import HTTPBasicAuth
@@ -42,11 +42,19 @@ class GenericCamera(Camera):
def camera_image(self):
""" Return a still image reponse from the camera. """
if self._username and self._password:
response = requests.get(
self._still_image_url,
auth=HTTPBasicAuth(self._username, self._password))
try:
response = requests.get(
self._still_image_url,
auth=HTTPBasicAuth(self._username, self._password))
except requests.exceptions.RequestException as error:
_LOGGER.error('Error getting camera image: %s', error)
return None
else:
response = requests.get(self._still_image_url)
try:
response = requests.get(self._still_image_url)
except requests.exceptions.RequestException as error:
_LOGGER.error('Error getting camera image: %s', error)
return None
return response.content

View File

@@ -0,0 +1,71 @@
"""
homeassistant.components.camera.mjpeg
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for IP Cameras.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/camera.mjpeg/
"""
import logging
from requests.auth import HTTPBasicAuth
from homeassistant.helpers import validate_config
from homeassistant.components.camera import DOMAIN
from homeassistant.components.camera import Camera
import requests
from contextlib import closing
_LOGGER = logging.getLogger(__name__)
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Adds a mjpeg IP Camera. """
if not validate_config({DOMAIN: config}, {DOMAIN: ['mjpeg_url']},
_LOGGER):
return None
add_devices_callback([MjpegCamera(config)])
# pylint: disable=too-many-instance-attributes
class MjpegCamera(Camera):
"""
A generic implementation of an IP camera that is reachable over a URL.
"""
def __init__(self, device_info):
super().__init__()
self._name = device_info.get('name', 'Mjpeg Camera')
self._username = device_info.get('username')
self._password = device_info.get('password')
self._mjpeg_url = device_info['mjpeg_url']
def camera_image(self):
""" Return a still image response from the camera. """
def process_response(response):
""" Take in a response object, return the jpg from it. """
data = b''
for chunk in response.iter_content(1024):
data += chunk
jpg_start = data.find(b'\xff\xd8')
jpg_end = data.find(b'\xff\xd9')
if jpg_start != -1 and jpg_end != -1:
jpg = data[jpg_start:jpg_end + 2]
return jpg
if self._username and self._password:
with closing(requests.get(self._mjpeg_url,
auth=HTTPBasicAuth(self._username,
self._password),
stream=True)) as response:
return process_response(response)
else:
with closing(requests.get(self._mjpeg_url,
stream=True)) as response:
return process_response(response)
@property
def name(self):
""" Return the name of this device. """
return self._name

View File

@@ -4,7 +4,7 @@ homeassistant.components.conversation
Provides functionality to have conversations with Home Assistant.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/conversation.html
https://home-assistant.io/components/conversation/
"""
import logging
import re

View File

@@ -10,14 +10,15 @@ import homeassistant.core as ha
import homeassistant.bootstrap as bootstrap
import homeassistant.loader as loader
from homeassistant.const import (
CONF_PLATFORM, ATTR_ENTITY_PICTURE, ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME)
CONF_PLATFORM, ATTR_ENTITY_ID)
DOMAIN = "demo"
DEPENDENCIES = ['introduction', 'conversation']
DEPENDENCIES = ['conversation', 'introduction', 'zone']
COMPONENTS_WITH_DEMO_PLATFORM = [
'switch', 'light', 'sensor', 'thermostat', 'media_player', 'notify']
'device_tracker', 'light', 'media_player', 'notify', 'switch', 'sensor',
'thermostat']
def setup(hass, config):
@@ -110,25 +111,6 @@ def setup(hass, config):
}},
]})
# Setup fake device tracker
hass.states.set("device_tracker.paulus", "home",
{ATTR_ENTITY_PICTURE:
"http://graph.facebook.com/297400035/picture",
ATTR_FRIENDLY_NAME: 'Paulus'})
hass.states.set("device_tracker.anne_therese", "not_home",
{ATTR_FRIENDLY_NAME: 'Anne Therese',
'latitude': hass.config.latitude + 0.002,
'longitude': hass.config.longitude + 0.002})
hass.states.set("group.all_devices", "home",
{
"auto": True,
ATTR_ENTITY_ID: [
"device_tracker.paulus",
"device_tracker.anne_therese"
]
})
# Setup configurator
configurator_ids = []

View File

@@ -1,9 +1,11 @@
"""
homeassistant.components.device_sun_light_trigger
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Provides functionality to turn on lights based on the state of the sun and
devices.
Provides functionality to turn on lights based on
the state of the sun and devices.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/device_sun_light_trigger/
"""
import logging
from datetime import timedelta

View File

@@ -1,25 +1,10 @@
"""
homeassistant.components.device_tracker
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Provides functionality to keep track of devices.
device_tracker:
platform: netgear
# Optional
# How many seconds to wait after not seeing device to consider it not home
consider_home: 180
# Seconds between each scan
interval_seconds: 12
# New found devices auto found
track_new_devices: yes
# Maximum distance from home we consider people home
range_home: 100
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/device_tracker/
"""
# pylint: disable=too-many-instance-attributes, too-many-arguments
# pylint: disable=too-many-locals

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports scanning an Actiontec MI424WR
(Verizon FIOS) router for device presence.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.actiontec.html
https://home-assistant.io/components/device_tracker.actiontec/
"""
import logging
from datetime import timedelta
@@ -17,20 +17,19 @@ import telnetlib
import homeassistant.util.dt as dt_util
from homeassistant.const import CONF_HOST, CONF_USERNAME, CONF_PASSWORD
from homeassistant.helpers import validate_config
from homeassistant.util import Throttle, convert
from homeassistant.util import Throttle
from homeassistant.components.device_tracker import DOMAIN
# Return cached results if last scan was less then this time ago
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5)
# Interval in minutes to exclude devices from a scan while they are home
CONF_HOME_INTERVAL = "home_interval"
_LOGGER = logging.getLogger(__name__)
_LEASES_REGEX = re.compile(
r'(?P<ip>([0-9]{1,3}[\.]){3}[0-9]{1,3})' +
r'\smac:\s(?P<mac>([0-9a-f]{2}[:-]){5}([0-9a-f]{2}))')
r'\smac:\s(?P<mac>([0-9a-f]{2}[:-]){5}([0-9a-f]{2}))' +
r'\svalid\sfor:\s(?P<timevalid>(-?\d+))' +
r'\ssec')
# pylint: disable=unused-argument
@@ -40,9 +39,7 @@ def get_scanner(hass, config):
{DOMAIN: [CONF_HOST, CONF_USERNAME, CONF_PASSWORD]},
_LOGGER):
return None
scanner = ActiontecDeviceScanner(config[DOMAIN])
return scanner if scanner.success_init else None
Device = namedtuple("Device", ["mac", "ip", "last_update"])
@@ -58,19 +55,11 @@ class ActiontecDeviceScanner(object):
self.host = config[CONF_HOST]
self.username = config[CONF_USERNAME]
self.password = config[CONF_PASSWORD]
minutes = convert(config.get(CONF_HOME_INTERVAL), int, 0)
self.home_interval = timedelta(minutes=minutes)
self.lock = threading.Lock()
self.last_results = []
# Test the router is accessible
data = self.get_actiontec_data()
self.success_init = data is not None
_LOGGER.info("actiontec scanner initialized")
if self.home_interval:
_LOGGER.info("home_interval set to: %s", self.home_interval)
def scan_devices(self):
"""
@@ -100,27 +89,13 @@ class ActiontecDeviceScanner(object):
return False
with self.lock:
exclude_targets = set()
exclude_target_list = []
now = dt_util.now()
if self.home_interval:
for host in self.last_results:
if host.last_update + self.home_interval > now:
exclude_targets.add(host)
if len(exclude_targets) > 0:
exclude_target_list = [t.ip for t in exclude_targets]
actiontec_data = self.get_actiontec_data()
if not actiontec_data:
return False
self.last_results = []
for client in exclude_target_list:
if client in actiontec_data:
actiontec_data.pop(client)
for name, data in actiontec_data.items():
device = Device(data['mac'], name, now)
self.last_results.append(device)
self.last_results.extend(exclude_targets)
self.last_results = [Device(data['mac'], name, now)
for name, data in actiontec_data.items()
if data['timevalid'] > -60]
_LOGGER.info("actiontec scan successful")
return True
@@ -153,6 +128,7 @@ class ActiontecDeviceScanner(object):
if match is not None:
devices[match.group('ip')] = {
'ip': match.group('ip'),
'mac': match.group('mac').upper()
'mac': match.group('mac').upper(),
'timevalid': int(match.group('timevalid'))
}
return devices

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports scanning a Aruba Access Point for device
presence.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.aruba.html
https://home-assistant.io/components/device_tracker.aruba/
"""
import logging
from datetime import timedelta

View File

@@ -4,32 +4,8 @@ homeassistant.components.device_tracker.asuswrt
Device tracker platform that supports scanning a ASUSWRT router for device
presence.
This device tracker needs telnet to be enabled on the router.
Configuration:
To use the ASUSWRT tracker you will need to add something like the following
to your configuration.yaml file.
device_tracker:
platform: asuswrt
host: YOUR_ROUTER_IP
username: YOUR_ADMIN_USERNAME
password: YOUR_ADMIN_PASSWORD
Variables:
host
*Required
The IP address of your router, e.g. 192.168.1.1.
username
*Required
The username of an user with administrative privileges, usually 'admin'.
password
*Required
The password for your given admin account.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.asuswrt/
"""
import logging
from datetime import timedelta
@@ -158,13 +134,16 @@ class AsusWrtDeviceScanner(object):
for lease in leases_result:
match = _LEASES_REGEX.search(lease.decode('utf-8'))
if not match:
_LOGGER.warning("Could not parse lease row: %s", lease)
continue
# For leases where the client doesn't set a hostname, ensure
# it is blank and not '*', which breaks the entity_id down
# the line
if match:
host = match.group('host')
if host == '*':
host = ''
host = match.group('host')
if host == '*':
host = ''
devices[match.group('ip')] = {
'host': host,
@@ -175,6 +154,9 @@ class AsusWrtDeviceScanner(object):
for neighbor in neighbors:
match = _IP_NEIGH_REGEX.search(neighbor.decode('utf-8'))
if match and match.group('ip') in devices:
if not match:
_LOGGER.warning("Could not parse neighbor row: %s", neighbor)
continue
if match.group('ip') in devices:
devices[match.group('ip')]['status'] = match.group('status')
return devices

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports scanning a DD-WRT router for device
presence.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.ddwrt.html
https://home-assistant.io/components/device_tracker.ddwrt/
"""
import logging
from datetime import timedelta

View File

@@ -1,7 +1,6 @@
"""
homeassistant.components.device_tracker.demo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Demo platform for the device tracker.
device_tracker:

View File

@@ -4,9 +4,8 @@ homeassistant.components.device_tracker.geofancy
Geofancy platform for the device tracker.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.geofancy.html
https://home-assistant.io/components/device_tracker.geofancy/
"""
from homeassistant.const import (
HTTP_UNPROCESSABLE_ENTITY, HTTP_INTERNAL_SERVER_ERROR)

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports scanning a OpenWRT router for device
presence.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.luci.html
https://home-assistant.io/components/device_tracker.luci/
"""
import logging
import json

View File

@@ -4,7 +4,7 @@ homeassistant.components.device_tracker.mqtt
MQTT platform for the device tracker.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.mqtt.html
https://home-assistant.io/components/device_tracker.mqtt/
"""
import logging
from homeassistant import util

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports scanning a Netgear router for device
presence.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.netgear.html
https://home-assistant.io/components/device_tracker.netgear/
"""
import logging
from datetime import timedelta

View File

@@ -4,7 +4,7 @@ homeassistant.components.device_tracker.nmap
Device tracker platform that supports scanning a network with nmap.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.nmap_scanner.html
https://home-assistant.io/components/device_tracker.nmap_scanner/
"""
import logging
from datetime import timedelta

View File

@@ -4,7 +4,7 @@ homeassistant.components.device_tracker.owntracks
OwnTracks platform for the device tracker.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.owntracks.html
https://home-assistant.io/components/device_tracker.owntracks/
"""
import json
import logging

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports fetching WiFi associations
through SNMP.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.snmp.html
https://home-assistant.io/components/device_tracker.snmp/
"""
import logging
from datetime import timedelta
@@ -45,9 +45,12 @@ class SnmpScanner(object):
This class queries any SNMP capable Acces Point for connected devices.
"""
def __init__(self, config):
self.host = config[CONF_HOST]
self.community = config[CONF_COMMUNITY]
self.baseoid = config[CONF_BASEOID]
from pysnmp.entity.rfc3413.oneliner import cmdgen
self.snmp = cmdgen.CommandGenerator()
self.host = cmdgen.UdpTransportTarget((config[CONF_HOST], 161))
self.community = cmdgen.CommunityData(config[CONF_COMMUNITY])
self.baseoid = cmdgen.MibVariable(config[CONF_BASEOID])
self.lock = threading.Lock()
@@ -91,16 +94,11 @@ class SnmpScanner(object):
def get_snmp_data(self):
""" Fetch mac addresses from WAP via SNMP. """
from pysnmp.entity.rfc3413.oneliner import cmdgen
devices = []
snmp = cmdgen.CommandGenerator()
errindication, errstatus, errindex, restable = snmp.nextCmd(
cmdgen.CommunityData(self.community),
cmdgen.UdpTransportTarget((self.host, 161)),
cmdgen.MibVariable(self.baseoid)
)
errindication, errstatus, errindex, restable = self.snmp.nextCmd(
self.community, self.host, self.baseoid)
if errindication:
_LOGGER.error("SNMPLIB error: %s", errindication)

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports scanning a THOMSON router for device
presence.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.thomson.html
https://home-assistant.io/components/device_tracker.thomson/
"""
import logging
from datetime import timedelta

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports scanning a Tomato router for device
presence.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.tomato.html
https://home-assistant.io/components/device_tracker.tomato/
"""
import logging
import json

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports scanning a TP-Link router for device
presence.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.tplink.html
https://home-assistant.io/components/device_tracker.tplink/
"""
import base64
import logging

View File

@@ -5,7 +5,7 @@ Device tracker platform that supports scanning a OpenWRT router for device
presence.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.ubus.html
https://home-assistant.io/components/device_tracker.ubus/
"""
import logging
import json

View File

@@ -1,7 +1,6 @@
"""
homeassistant.components.discovery
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Starts a service to scan in intervals for new devices.
Will emit EVENT_PLATFORM_DISCOVERED whenever a new service has been discovered.

View File

@@ -4,7 +4,7 @@ homeassistant.components.downloader
Provides functionality to download files.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/downloader.html
https://home-assistant.io/components/downloader/
"""
import os
import logging

View File

@@ -8,7 +8,7 @@ import re
import os
import logging
from . import version
from . import version, mdi_version
import homeassistant.util as util
from homeassistant.const import URL_ROOT, HTTP_OK
from homeassistant.config import get_default_config_dir
@@ -22,9 +22,11 @@ _LOGGER = logging.getLogger(__name__)
FRONTEND_URLS = [
URL_ROOT, '/logbook', '/history', '/map', '/devService', '/devState',
'/devEvent']
'/devEvent', '/devInfo']
STATES_URL = re.compile(r'/states(/([a-zA-Z\._\-0-9/]+)|)')
_FINGERPRINT = re.compile(r'^(\w+)-[a-z0-9]{32}\.(\w+)$', re.IGNORECASE)
def setup(hass, config):
""" Setup serving the frontend. """
@@ -72,6 +74,7 @@ def _handle_get_root(handler, path_match, data):
template_html = template_html.replace('{{ app_url }}', app_url)
template_html = template_html.replace('{{ auth }}', auth)
template_html = template_html.replace('{{ icons }}', mdi_version.VERSION)
handler.wfile.write(template_html.encode("UTF-8"))
@@ -80,9 +83,10 @@ def _handle_get_static(handler, path_match, data):
""" Returns a static file for the frontend. """
req_file = util.sanitize_path(path_match.group('file'))
# Strip md5 hash out of frontend filename
if re.match(r'^frontend-[A-Za-z0-9]{32}\.html$', req_file):
req_file = "frontend.html"
# Strip md5 hash out
fingerprinted = _FINGERPRINT.match(req_file)
if fingerprinted:
req_file = "{}.{}".format(*fingerprinted.groups())
path = os.path.join(os.path.dirname(__file__), 'www_static', req_file)

View File

@@ -46,6 +46,6 @@
</div>
<script src='/static/webcomponents-lite.min.js'></script>
<link rel='import' href='/static/{{ app_url }}' />
<home-assistant auth='{{ auth }}'></home-assistant>
<home-assistant auth='{{ auth }}' icons='{{ icons }}'></home-assistant>
</body>
</html>

View File

@@ -0,0 +1,2 @@
""" DO NOT MODIFY. Auto-generated by update_mdi script """
VERSION = "38EF63D0474411E4B3CF842B2B6CFE1B"

View File

@@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """
VERSION = "beb922c55bb26ea576581b453f6d7c04"
VERSION = "b75e3c9ebd3de2dae0912a89499127a9"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@ homeassistant.components.group
Provides functionality to group devices that can be turned on or off.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/group.html
https://home-assistant.io/components/group/
"""
import homeassistant.core as ha
from homeassistant.helpers import generate_entity_id

View File

@@ -4,7 +4,7 @@ homeassistant.components.history
Provide pre-made queries on top of the recorder component.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/history.html
https://home-assistant.io/components/history/
"""
import re
from datetime import timedelta

View File

@@ -4,7 +4,7 @@ homeassistant.components.http
This module provides an API and a HTTP interface for debug purposes.
For more details about the RESTful API, please refer to the documentation at
https://home-assistant.io/developers/api.html
https://home-assistant.io/developers/api/
"""
import json
import threading

View File

@@ -4,7 +4,7 @@ homeassistant.components.ifttt
This component enable you to trigger Maker IFTTT recipes.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/ifttt.html
https://home-assistant.io/components/ifttt/
"""
import logging
import requests

View File

@@ -4,7 +4,7 @@ homeassistant.components.introduction
Component that will help guide the user taking its first steps.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/introduction.html
https://home-assistant.io/components/introduction/
"""
import logging
@@ -26,13 +26,13 @@ def setup(hass, config=None):
Here are some resources to get started:
- Configuring Home Assistant:
https://home-assistant.io/getting-started/configuration.html
https://home-assistant.io/getting-started/configuration/
- Available components:
https://home-assistant.io/components/
- Troubleshooting your configuration:
https://home-assistant.io/getting-started/troubleshooting-configuration.html
https://home-assistant.io/getting-started/troubleshooting-configuration/
- Getting help:
https://home-assistant.io/help/

View File

@@ -5,7 +5,7 @@ Connects to an ISY-994 controller and loads relevant components to control its
devices. Also contains the base classes for ISY Sensors, Lights, and Switches.
For configuration details please visit the documentation for this component at
https://home-assistant.io/components/isy994.html
https://home-assistant.io/components/isy994/
"""
import logging
from urllib.parse import urlparse

View File

@@ -4,7 +4,7 @@ homeassistant.components.keyboard
Provides functionality to emulate keyboard presses on host machine.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/keyboard.html
https://home-assistant.io/components/keyboard/
"""
import logging

View File

@@ -1,58 +1,16 @@
"""
homeassistant.components.light
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Provides functionality to interact with lights.
It offers the following services:
TURN_OFF - Turns one or multiple lights off.
Supports following parameters:
- transition
Integer that represents the time the light should take to transition to
the new state.
- entity_id
String or list of strings that point at entity_ids of lights.
TURN_ON - Turns one or multiple lights on and change attributes.
Supports following parameters:
- transition
Integer that represents the time the light should take to transition to
the new state.
- entity_id
String or list of strings that point at entity_ids of lights.
- profile
String with the name of one of the built-in profiles (relax, energize,
concentrate, reading) or one of the custom profiles defined in
light_profiles.csv in the current working directory.
Light profiles define a xy color and a brightness.
If a profile is given and a brightness or xy color then the profile values
will be overwritten.
- xy_color
A list containing two floats representing the xy color you want the light
to be.
- rgb_color
A list containing three integers representing the xy color you want the
light to be.
- brightness
Integer between 0 and 255 representing how bright you want the light to be.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/light/
"""
import logging
import os
import csv
from homeassistant.components import group, discovery, wink, isy994
from homeassistant.components import group, discovery, wink, isy994, zwave
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, ATTR_ENTITY_ID)
@@ -77,6 +35,7 @@ ATTR_TRANSITION = "transition"
# lists holding color values
ATTR_RGB_COLOR = "rgb_color"
ATTR_XY_COLOR = "xy_color"
ATTR_COLOR_TEMP = "color_temp"
# int with value 0 .. 255 representing brightness of the light
ATTR_BRIGHTNESS = "brightness"
@@ -92,6 +51,7 @@ FLASH_LONG = "long"
# Apply an effect to the light, can be EFFECT_COLORLOOP
ATTR_EFFECT = "effect"
EFFECT_COLORLOOP = "colorloop"
EFFECT_WHITE = "white"
LIGHT_PROFILES_FILE = "light_profiles.csv"
@@ -100,11 +60,14 @@ DISCOVERY_PLATFORMS = {
wink.DISCOVER_LIGHTS: 'wink',
isy994.DISCOVER_LIGHTS: 'isy994',
discovery.SERVICE_HUE: 'hue',
zwave.DISCOVER_LIGHTS: 'zwave',
}
PROP_TO_ATTR = {
'brightness': ATTR_BRIGHTNESS,
'color_xy': ATTR_XY_COLOR,
'color_temp': ATTR_COLOR_TEMP,
'rgb_color': ATTR_RGB_COLOR,
'xy_color': ATTR_XY_COLOR,
}
_LOGGER = logging.getLogger(__name__)
@@ -119,8 +82,8 @@ def is_on(hass, entity_id=None):
# pylint: disable=too-many-arguments
def turn_on(hass, entity_id=None, transition=None, brightness=None,
rgb_color=None, xy_color=None, profile=None, flash=None,
effect=None):
rgb_color=None, xy_color=None, color_temp=None, profile=None,
flash=None, effect=None):
""" Turns all or specified light on. """
data = {
key: value for key, value in [
@@ -130,6 +93,7 @@ def turn_on(hass, entity_id=None, transition=None, brightness=None,
(ATTR_BRIGHTNESS, brightness),
(ATTR_RGB_COLOR, rgb_color),
(ATTR_XY_COLOR, xy_color),
(ATTR_COLOR_TEMP, color_temp),
(ATTR_FLASH, flash),
(ATTR_EFFECT, effect),
] if value is not None
@@ -150,7 +114,7 @@ def turn_off(hass, entity_id=None, transition=None):
hass.services.call(DOMAIN, SERVICE_TURN_OFF, data)
# pylint: disable=too-many-branches, too-many-locals
# pylint: disable=too-many-branches, too-many-locals, too-many-statements
def setup(hass, config):
""" Exposes light control via statemachine and services. """
@@ -240,6 +204,15 @@ def setup(hass, config):
# ValueError if value could not be converted to float
pass
if ATTR_COLOR_TEMP in dat:
# color_temp should be an int of mirads value
colortemp = dat.get(ATTR_COLOR_TEMP)
# Without this check, a ctcolor with value '99' would work
# These values are based on Philips Hue, may need ajustment later
if isinstance(colortemp, int) and 154 <= colortemp <= 500:
params[ATTR_COLOR_TEMP] = colortemp
if ATTR_RGB_COLOR in dat:
try:
# rgb_color should be a list containing 3 ints
@@ -247,26 +220,17 @@ def setup(hass, config):
if len(rgb_color) == 3:
params[ATTR_RGB_COLOR] = [int(val) for val in rgb_color]
params[ATTR_XY_COLOR] = \
color_util.color_RGB_to_xy(int(rgb_color[0]),
int(rgb_color[1]),
int(rgb_color[2]))
except (TypeError, ValueError):
# TypeError if rgb_color is not iterable
# ValueError if not all values can be converted to int
pass
if ATTR_FLASH in dat:
if dat[ATTR_FLASH] == FLASH_SHORT:
params[ATTR_FLASH] = FLASH_SHORT
if dat.get(ATTR_FLASH) in (FLASH_SHORT, FLASH_LONG):
params[ATTR_FLASH] = dat[ATTR_FLASH]
elif dat[ATTR_FLASH] == FLASH_LONG:
params[ATTR_FLASH] = FLASH_LONG
if ATTR_EFFECT in dat:
if dat[ATTR_EFFECT] == EFFECT_COLORLOOP:
params[ATTR_EFFECT] = EFFECT_COLORLOOP
if dat.get(ATTR_EFFECT) in (EFFECT_COLORLOOP, EFFECT_WHITE):
params[ATTR_EFFECT] = dat[ATTR_EFFECT]
for light in target_lights:
light.turn_on(**params)
@@ -297,10 +261,20 @@ class Light(ToggleEntity):
return None
@property
def color_xy(self):
def xy_color(self):
""" XY color value [float, float]. """
return None
@property
def rgb_color(self):
""" RGB color value [int, int, int] """
return None
@property
def color_temp(self):
""" CT color value in mirads. """
return None
@property
def device_state_attributes(self):
""" Returns device specific state attributes. """
@@ -317,6 +291,12 @@ class Light(ToggleEntity):
if value:
data[attr] = value
if ATTR_RGB_COLOR not in data and ATTR_XY_COLOR in data and \
ATTR_BRIGHTNESS in data:
data[ATTR_RGB_COLOR] = color_util.color_xy_brightness_to_RGB(
data[ATTR_XY_COLOR][0], data[ATTR_XY_COLOR][1],
data[ATTR_BRIGHTNESS])
device_attr = self.device_state_attributes
if device_attr is not None:

View File

@@ -4,7 +4,7 @@ homeassistant.components.light.blinksticklight
Support for Blinkstick lights.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.blinksticklight.html
https://home-assistant.io/components/light.blinksticklight/
"""
import logging

View File

@@ -1,37 +1,40 @@
"""
homeassistant.components.light.demo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Demo platform that implements lights.
"""
import random
from homeassistant.components.light import (
Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR)
Light, ATTR_BRIGHTNESS, ATTR_RGB_COLOR, ATTR_COLOR_TEMP)
LIGHT_COLORS = [
[0.368, 0.180],
[0.460, 0.470],
[237, 224, 33],
[255, 63, 111],
]
LIGHT_TEMPS = [240, 380]
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Find and return demo lights. """
add_devices_callback([
DemoLight("Bed Light", False),
DemoLight("Ceiling Lights", True, LIGHT_COLORS[0]),
DemoLight("Kitchen Lights", True, LIGHT_COLORS[1])
DemoLight("Ceiling Lights", True, LIGHT_COLORS[0], LIGHT_TEMPS[1]),
DemoLight("Kitchen Lights", True, LIGHT_COLORS[1], LIGHT_TEMPS[0])
])
class DemoLight(Light):
""" Provides a demo switch. """
def __init__(self, name, state, xy=None, brightness=180):
# pylint: disable=too-many-arguments
def __init__(self, name, state, rgb=None, ct=None, brightness=180):
self._name = name
self._state = state
self._xy = xy or random.choice(LIGHT_COLORS)
self._rgb = rgb or random.choice(LIGHT_COLORS)
self._ct = ct or random.choice(LIGHT_TEMPS)
self._brightness = brightness
@property
@@ -50,9 +53,14 @@ class DemoLight(Light):
return self._brightness
@property
def color_xy(self):
""" XY color value. """
return self._xy
def rgb_color(self):
""" rgb color value. """
return self._rgb
@property
def color_temp(self):
""" CT color temperature. """
return self._ct
@property
def is_on(self):
@@ -63,8 +71,11 @@ class DemoLight(Light):
""" Turn the device on. """
self._state = True
if ATTR_XY_COLOR in kwargs:
self._xy = kwargs[ATTR_XY_COLOR]
if ATTR_RGB_COLOR in kwargs:
self._rgb = kwargs[ATTR_RGB_COLOR]
if ATTR_COLOR_TEMP in kwargs:
self._ct = kwargs[ATTR_COLOR_TEMP]
if ATTR_BRIGHTNESS in kwargs:
self._brightness = kwargs[ATTR_BRIGHTNESS]

View File

@@ -3,20 +3,24 @@ homeassistant.components.light.hue
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for Hue lights.
https://home-assistant.io/components/light.hue.html
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.hue/
"""
import json
import logging
import os
import socket
from datetime import timedelta
from urllib.parse import urlparse
from homeassistant.loader import get_component
import homeassistant.util as util
import homeassistant.util.color as color_util
from homeassistant.const import CONF_HOST, DEVICE_DEFAULT_NAME
from homeassistant.components.light import (
Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_TRANSITION,
ATTR_FLASH, FLASH_LONG, FLASH_SHORT, ATTR_EFFECT,
EFFECT_COLORLOOP)
Light, ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_COLOR_TEMP,
ATTR_TRANSITION, ATTR_FLASH, FLASH_LONG, FLASH_SHORT,
ATTR_EFFECT, EFFECT_COLORLOOP, ATTR_RGB_COLOR)
REQUIREMENTS = ['phue==0.8']
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
@@ -30,21 +34,37 @@ _CONFIGURING = {}
_LOGGER = logging.getLogger(__name__)
def _find_host_from_config(hass):
""" Attempt to detect host based on existing configuration. """
path = hass.config.path(PHUE_CONFIG_FILE)
if not os.path.isfile(path):
return None
try:
with open(path) as inp:
return next(json.loads(''.join(inp)).keys().__iter__())
except (ValueError, AttributeError, StopIteration):
# ValueError if can't parse as JSON
# AttributeError if JSON value is not a dict
# StopIteration if no keys
return None
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Gets the Hue lights. """
try:
# pylint: disable=unused-variable
import phue # noqa
except ImportError:
_LOGGER.exception("Error while importing dependency phue.")
return
if discovery_info is not None:
host = urlparse(discovery_info[1]).hostname
else:
host = config.get(CONF_HOST, None)
if host is None:
host = _find_host_from_config(hass)
if host is None:
_LOGGER.error('No host found in configuration')
return False
# Only act if we are not already configuring this host
if host in _CONFIGURING:
return
@@ -125,6 +145,7 @@ def request_configuration(host, hass, add_devices_callback):
return
# pylint: disable=unused-argument
def hue_configuration_callback(data):
""" Actions to do when our configuration callback is called. """
setup_bridge(host, hass, add_devices_callback)
@@ -164,10 +185,15 @@ class HueLight(Light):
return self.info['state']['bri']
@property
def color_xy(self):
def xy_color(self):
""" XY color value. """
return self.info['state'].get('xy')
@property
def color_temp(self):
""" CT color value. """
return self.info['state'].get('ct')
@property
def is_on(self):
""" True if device is on. """
@@ -189,6 +215,12 @@ class HueLight(Light):
if ATTR_XY_COLOR in kwargs:
command['xy'] = kwargs[ATTR_XY_COLOR]
elif ATTR_RGB_COLOR in kwargs:
command['xy'] = color_util.color_RGB_to_xy(
*(int(val) for val in kwargs[ATTR_RGB_COLOR]))
if ATTR_COLOR_TEMP in kwargs:
command['ct'] = kwargs[ATTR_COLOR_TEMP]
flash = kwargs.get(ATTR_FLASH)

View File

@@ -3,7 +3,8 @@ homeassistant.components.light.hyperion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for Hyperion remotes.
https://home-assistant.io/components/light.hyperion.html
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.hyperion/
"""
import logging
import socket

View File

@@ -2,6 +2,9 @@
homeassistant.components.light.isy994
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for ISY994 lights.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/isy994/
"""
import logging

View File

@@ -1,29 +1,52 @@
"""
homeassistant.components.light.limitlessled
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for LimitlessLED bulbs.
Support for LimitlessLED bulbs, also known as...
- EasyBulb
- AppLight
- AppLamp
- MiLight
- LEDme
- dekolight
- iLight
https://home-assistant.io/components/light.limitlessled.html
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.limitlessled/
"""
import logging
from homeassistant.const import DEVICE_DEFAULT_NAME
from homeassistant.components.light import (Light, ATTR_BRIGHTNESS,
ATTR_XY_COLOR)
from homeassistant.util.color import color_RGB_to_xy
ATTR_RGB_COLOR, ATTR_EFFECT,
EFFECT_COLORLOOP, EFFECT_WHITE)
_LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['ledcontroller==1.1.0']
COLOR_TABLE = {
'white': [0xFF, 0xFF, 0xFF],
'violet': [0xEE, 0x82, 0xEE],
'royal_blue': [0x41, 0x69, 0xE1],
'baby_blue': [0x87, 0xCE, 0xFA],
'aqua': [0x00, 0xFF, 0xFF],
'royal_mint': [0x7F, 0xFF, 0xD4],
'seafoam_green': [0x2E, 0x8B, 0x57],
'green': [0x00, 0x80, 0x00],
'lime_green': [0x32, 0xCD, 0x32],
'yellow': [0xFF, 0xFF, 0x00],
'yellow_orange': [0xDA, 0xA5, 0x20],
'orange': [0xFF, 0xA5, 0x00],
'red': [0xFF, 0x00, 0x00],
'pink': [0xFF, 0xC0, 0xCB],
'fusia': [0xFF, 0x00, 0xFF],
'lilac': [0xDA, 0x70, 0xD6],
'lavendar': [0xE6, 0xE6, 0xFA],
}
def _distance_squared(rgb1, rgb2):
""" Return sum of squared distances of each color part. """
return sum((val1-val2)**2 for val1, val2 in zip(rgb1, rgb2))
def _rgb_to_led_color(rgb_color):
""" Convert an RGB color to the closest color string and color. """
return sorted((_distance_squared(rgb_color, color), name)
for name, color in COLOR_TABLE.items())[0][1]
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Gets the LimitlessLED lights. """
@@ -105,49 +128,15 @@ class RGBWLimitlessLED(LimitlessLED):
super().__init__(pool, controller_id, group, name, 'rgbw')
self._brightness = 100
self._xy_color = color_RGB_to_xy(255, 255, 255)
# Build a color table that maps an RGB color to a color string
# recognized by LedController's set_color method
self._color_table = [(color_RGB_to_xy(*x[0]), x[1]) for x in [
((0xFF, 0xFF, 0xFF), 'white'),
((0xEE, 0x82, 0xEE), 'violet'),
((0x41, 0x69, 0xE1), 'royal_blue'),
((0x87, 0xCE, 0xFA), 'baby_blue'),
((0x00, 0xFF, 0xFF), 'aqua'),
((0x7F, 0xFF, 0xD4), 'royal_mint'),
((0x2E, 0x8B, 0x57), 'seafoam_green'),
((0x00, 0x80, 0x00), 'green'),
((0x32, 0xCD, 0x32), 'lime_green'),
((0xFF, 0xFF, 0x00), 'yellow'),
((0xDA, 0xA5, 0x20), 'yellow_orange'),
((0xFF, 0xA5, 0x00), 'orange'),
((0xFF, 0x00, 0x00), 'red'),
((0xFF, 0xC0, 0xCB), 'pink'),
((0xFF, 0x00, 0xFF), 'fusia'),
((0xDA, 0x70, 0xD6), 'lilac'),
((0xE6, 0xE6, 0xFA), 'lavendar'),
]]
self._led_color = 'white'
@property
def brightness(self):
return self._brightness
@property
def color_xy(self):
return self._xy_color
def _xy_to_led_color(self, xy_color):
""" Convert an XY color to the closest LedController color string. """
def abs_dist_squared(p_0, p_1):
""" Returns the absolute value of the squared distance """
return abs((p_0[0] - p_1[0])**2 + (p_0[1] - p_1[1])**2)
candidates = [(abs_dist_squared(xy_color, x[0]), x[1]) for x in
self._color_table]
# First candidate in the sorted list is closest to desired color:
return sorted(candidates)[0][1]
def rgb_color(self):
return COLOR_TABLE[self._led_color]
def turn_on(self, **kwargs):
""" Turn the device on. """
@@ -156,13 +145,23 @@ class RGBWLimitlessLED(LimitlessLED):
if ATTR_BRIGHTNESS in kwargs:
self._brightness = kwargs[ATTR_BRIGHTNESS]
if ATTR_XY_COLOR in kwargs:
self._xy_color = kwargs[ATTR_XY_COLOR]
if ATTR_RGB_COLOR in kwargs:
self._led_color = _rgb_to_led_color(kwargs[ATTR_RGB_COLOR])
self.pool.execute(self.controller_id, "set_color",
self._xy_to_led_color(self._xy_color), self.group)
effect = kwargs.get(ATTR_EFFECT)
if effect == EFFECT_COLORLOOP:
self.pool.execute(self.controller_id, "disco", self.group)
elif effect == EFFECT_WHITE:
self.pool.execute(self.controller_id, "white", self.group)
else:
self.pool.execute(self.controller_id, "set_color",
self._led_color, self.group)
# Brightness can be set independently of color
self.pool.execute(self.controller_id, "set_brightness",
self._brightness / 255.0, self.group)
self.update_ha_state()

View File

@@ -0,0 +1,184 @@
"""
homeassistant.components.light.mqtt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allows to configure a MQTT light.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.mqtt/
"""
import logging
import homeassistant.util.color as color_util
import homeassistant.components.mqtt as mqtt
from homeassistant.components.light import (Light,
ATTR_BRIGHTNESS, ATTR_RGB_COLOR)
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "MQTT Light"
DEFAULT_QOS = 0
DEFAULT_PAYLOAD_ON = "on"
DEFAULT_PAYLOAD_OFF = "off"
DEFAULT_RGB_PATTERN = "%d,%d,%d"
DEFAULT_OPTIMISTIC = False
DEPENDENCIES = ['mqtt']
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Add MQTT Light. """
if config.get('command_topic') is None:
_LOGGER.error("Missing required variable: command_topic")
return False
add_devices_callback([MqttLight(
hass,
config.get('name', DEFAULT_NAME),
{"state_topic": config.get('state_topic'),
"command_topic": config.get('command_topic'),
"brightness_state_topic": config.get('brightness_state_topic'),
"brightness_command_topic":
config.get('brightness_command_topic'),
"rgb_state_topic": config.get('rgb_state_topic'),
"rgb_command_topic": config.get('rgb_command_topic')},
config.get('rgb', None),
config.get('qos', DEFAULT_QOS),
{"on": config.get('payload_on', DEFAULT_PAYLOAD_ON),
"off": config.get('payload_off', DEFAULT_PAYLOAD_OFF)},
config.get('brightness'),
config.get('optimistic', DEFAULT_OPTIMISTIC))])
# pylint: disable=too-many-instance-attributes
class MqttLight(Light):
""" Provides a MQTT light. """
# pylint: disable=too-many-arguments
def __init__(self, hass, name,
topic,
rgb, qos,
payload,
brightness, optimistic):
self._hass = hass
self._name = name
self._topic = topic
self._rgb = rgb
self._qos = qos
self._payload = payload
self._brightness = brightness
self._optimistic = optimistic
self._state = False
self._xy = None
def message_received(topic, payload, qos):
""" A new MQTT message has been received. """
if payload == self._payload["on"]:
self._state = True
elif payload == self._payload["off"]:
self._state = False
self.update_ha_state()
if self._topic["state_topic"] is None:
# force optimistic mode
self._optimistic = True
else:
# Subscribe the state_topic
mqtt.subscribe(self._hass, self._topic["state_topic"],
message_received, self._qos)
def brightness_received(topic, payload, qos):
""" A new MQTT message for the brightness has been received. """
self._brightness = int(payload)
self.update_ha_state()
def rgb_received(topic, payload, qos):
""" A new MQTT message has been received. """
self._rgb = [int(val) for val in payload.split(',')]
self._xy = color_util.color_RGB_to_xy(int(self._rgb[0]),
int(self._rgb[1]),
int(self._rgb[2]))
self.update_ha_state()
if self._topic["brightness_state_topic"] is not None:
mqtt.subscribe(self._hass, self._topic["brightness_state_topic"],
brightness_received, self._qos)
self._brightness = 255
else:
self._brightness = None
if self._topic["rgb_state_topic"] is not None:
mqtt.subscribe(self._hass, self._topic["rgb_state_topic"],
rgb_received, self._qos)
self._xy = [0, 0]
else:
self._xy = None
@property
def brightness(self):
""" Brightness of this light between 0..255. """
return self._brightness
@property
def rgb_color(self):
""" RGB color value. """
return self._rgb
@property
def color_xy(self):
""" RGB color value. """
return self._xy
@property
def should_poll(self):
""" No polling needed for a MQTT light. """
return False
@property
def name(self):
""" Returns the name of the device if any. """
return self._name
@property
def is_on(self):
""" True if device is on. """
return self._state
def turn_on(self, **kwargs):
""" Turn the device on. """
if ATTR_RGB_COLOR in kwargs and \
self._topic["rgb_command_topic"] is not None:
self._rgb = kwargs[ATTR_RGB_COLOR]
rgb = DEFAULT_RGB_PATTERN % tuple(self._rgb)
mqtt.publish(self._hass, self._topic["rgb_command_topic"],
rgb, self._qos)
if ATTR_BRIGHTNESS in kwargs and \
self._topic["brightness_command_topic"] is not None:
self._brightness = kwargs[ATTR_BRIGHTNESS]
mqtt.publish(self._hass, self._topic["brightness_command_topic"],
self._brightness, self._qos)
mqtt.publish(self._hass, self._topic["command_topic"],
self._payload["on"], self._qos)
if self._optimistic:
# optimistically assume that switch has changed state
self._state = True
self.update_ha_state()
def turn_off(self, **kwargs):
""" Turn the device off. """
mqtt.publish(self._hass, self._topic["command_topic"],
self._payload["off"], self._qos)
if self._optimistic:
# optimistically assume that switch has changed state
self._state = False
self.update_ha_state()

View File

@@ -4,7 +4,7 @@ homeassistant.components.light.rfxtrx
Support for RFXtrx lights.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.rfxtrx.html
https://home-assistant.io/components/light.rfxtrx/
"""
import logging
import homeassistant.components.rfxtrx as rfxtrx
@@ -59,6 +59,11 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
# Check if entity exists or previously added automatically
if entity_id in rfxtrx.RFX_DEVICES:
_LOGGER.debug(
"EntityID: %s light_update. Command: %s",
entity_id,
event.values['Command']
)
if event.values['Command'] == 'On'\
or event.values['Command'] == 'Off':
if event.values['Command'] == 'On':

View File

@@ -20,6 +20,10 @@ turn_on:
description: Color for the light in XY-format
example: '[0.52, 0.43]'
color_temp:
description: Color temperature for the light in mireds (154-500)
example: '250'
brightness:
description: Number between 0..255 indicating brightness
example: 120

View File

@@ -4,7 +4,7 @@ homeassistant.components.light.tellstick
Support for Tellstick lights.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.tellstick.html
https://home-assistant.io/components/light.tellstick/
"""
import logging
# pylint: disable=no-name-in-module, import-error

View File

@@ -4,15 +4,19 @@ homeassistant.components.light.vera
Support for Vera lights.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.vera.html
https://home-assistant.io/components/light.vera/
"""
import logging
import time
from requests.exceptions import RequestException
from homeassistant.components.switch.vera import VeraSwitch
REQUIREMENTS = ['https://github.com/balloob/home-assistant-vera-api/archive/'
'a8f823066ead6c7da6fb5e7abaf16fef62e63364.zip'
'#python-vera==0.1']
from homeassistant.components.light import ATTR_BRIGHTNESS
REQUIREMENTS = ['https://github.com/pavoni/home-assistant-vera-api/archive/'
'efdba4e63d58a30bc9b36d9e01e69858af9130b8.zip'
'#python-vera==0.1.1']
_LOGGER = logging.getLogger(__name__)
@@ -35,7 +39,10 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
controller = veraApi.VeraController(base_url)
devices = []
try:
devices = controller.get_devices(['Switch', 'On/Off Switch'])
devices = controller.get_devices([
'Switch',
'On/Off Switch',
'Dimmable Switch'])
except RequestException:
# There was a network related error connecting to the vera controller
_LOGGER.exception("Error communicating with Vera API")
@@ -47,6 +54,28 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
exclude = extra_data.get('exclude', False)
if exclude is not True:
lights.append(VeraSwitch(device, extra_data))
lights.append(VeraLight(device, extra_data))
add_devices_callback(lights)
class VeraLight(VeraSwitch):
""" Represents a Vera Light, including dimmable. """
@property
def state_attributes(self):
attr = super().state_attributes or {}
if self.vera_device.is_dimmable:
attr[ATTR_BRIGHTNESS] = self.vera_device.get_brightness()
return attr
def turn_on(self, **kwargs):
if ATTR_BRIGHTNESS in kwargs and self.vera_device.is_dimmable:
self.vera_device.set_brightness(kwargs[ATTR_BRIGHTNESS])
else:
self.vera_device.switch_on()
self.last_command_send = time.time()
self.is_on_status = True

View File

@@ -4,7 +4,7 @@ homeassistant.components.light.wink
Support for Wink lights.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.wink.html
https://home-assistant.io/components/light.wink/
"""
import logging
@@ -13,8 +13,8 @@ from homeassistant.components.wink import WinkToggleDevice
from homeassistant.const import CONF_ACCESS_TOKEN
REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/'
'c2b700e8ca866159566ecf5e644d9c297f69f257.zip'
'#python-wink==0.1']
'9eb39eaba0717922815e673ad1114c685839d890.zip'
'#python-wink==0.1.1']
def setup_platform(hass, config, add_devices_callback, discovery_info=None):

View File

@@ -0,0 +1,126 @@
"""
homeassistant.components.light.zwave
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for Z-Wave lights.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.zwave/
"""
# pylint: disable=import-error
from openzwave.network import ZWaveNetwork
from pydispatch import dispatcher
import homeassistant.components.zwave as zwave
from homeassistant.const import STATE_ON, STATE_OFF
from homeassistant.components.light import (Light, ATTR_BRIGHTNESS)
from threading import Timer
def setup_platform(hass, config, add_devices, discovery_info=None):
""" Find and add Z-Wave lights. """
if discovery_info is None:
return
node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]]
value = node.values[discovery_info[zwave.ATTR_VALUE_ID]]
if value.command_class != zwave.COMMAND_CLASS_SWITCH_MULTILEVEL:
return
if value.type != zwave.TYPE_BYTE:
return
if value.genre != zwave.GENRE_USER:
return
value.set_change_verified(False)
add_devices([ZwaveDimmer(value)])
def brightness_state(value):
"""
Returns the brightness and state according to the current data of given
value.
"""
if value.data > 0:
return (value.data / 99) * 255, STATE_ON
else:
return 255, STATE_OFF
class ZwaveDimmer(Light):
""" Provides a Z-Wave dimmer. """
# pylint: disable=too-many-arguments
def __init__(self, value):
self._value = value
self._node = value.node
self._brightness, self._state = brightness_state(value)
# Used for value change event handling
self._refreshing = False
self._timer = None
dispatcher.connect(
self._value_changed, ZWaveNetwork.SIGNAL_VALUE_CHANGED)
def _value_changed(self, value):
""" Called when a value has changed on the network. """
if self._value.value_id != value.value_id:
return
if self._refreshing:
self._refreshing = False
self._brightness, self._state = brightness_state(value)
else:
def _refresh_value():
"""Used timer callback for delayed value refresh."""
self._refreshing = True
self._value.refresh()
if self._timer is not None and self._timer.isAlive():
self._timer.cancel()
self._timer = Timer(2, _refresh_value)
self._timer.start()
self.update_ha_state()
@property
def should_poll(self):
""" No polling needed for a light. """
return False
@property
def name(self):
""" Returns the name of the device if any. """
name = self._node.name or "{}".format(self._node.product_name)
return "{}".format(name or self._value.label)
@property
def brightness(self):
""" Brightness of this light between 0..255. """
return self._brightness
@property
def is_on(self):
""" True if device is on. """
return self._state == STATE_ON
def turn_on(self, **kwargs):
""" Turn the device on. """
if ATTR_BRIGHTNESS in kwargs:
self._brightness = kwargs[ATTR_BRIGHTNESS]
# Zwave multilevel switches use a range of [0, 99] to control
# brightness.
brightness = (self._brightness / 255) * 99
if self._node.set_dimmer(self._value.value_id, brightness):
self._state = STATE_ON
def turn_off(self, **kwargs):
""" Turn the device off. """
if self._node.set_dimmer(self._value.value_id, 0):
self._state = STATE_OFF

View File

@@ -4,7 +4,7 @@ homeassistant.components.logbook
Parses events and generates a human log.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/logbook.html
https://home-assistant.io/components/logbook/
"""
from datetime import timedelta
from itertools import groupby

View File

@@ -0,0 +1,84 @@
"""
homeassistant.components.logger
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Component that will help set the level of logging for components.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/logger/
"""
import logging
from collections import OrderedDict
DOMAIN = 'logger'
DEPENDENCIES = []
LOGSEVERITY = {
'CRITICAL': 50,
'FATAL': 50,
'ERROR': 40,
'WARNING': 30,
'WARN': 30,
'INFO': 20,
'DEBUG': 10,
'NOTSET': 0
}
LOGGER_DEFAULT = 'default'
LOGGER_LOGS = 'logs'
class HomeAssistantLogFilter(logging.Filter):
""" A log filter. """
# pylint: disable=no-init,too-few-public-methods
def __init__(self, logfilter):
super().__init__()
self.logfilter = logfilter
def filter(self, record):
# Log with filtered severity
if LOGGER_LOGS in self.logfilter:
for filtername in self.logfilter[LOGGER_LOGS]:
logseverity = self.logfilter[LOGGER_LOGS][filtername]
if record.name.startswith(filtername):
return record.levelno >= logseverity
# Log with default severity
default = self.logfilter[LOGGER_DEFAULT]
return record.levelno >= default
def setup(hass, config=None):
""" Setup the logger component. """
logfilter = dict()
# Set default log severity
logfilter[LOGGER_DEFAULT] = LOGSEVERITY['DEBUG']
if LOGGER_DEFAULT in config.get(DOMAIN):
logfilter[LOGGER_DEFAULT] = LOGSEVERITY[
config.get(DOMAIN)[LOGGER_DEFAULT].upper()
]
# Compute log severity for components
if LOGGER_LOGS in config.get(DOMAIN):
for key, value in config.get(DOMAIN)[LOGGER_LOGS].items():
config.get(DOMAIN)[LOGGER_LOGS][key] = LOGSEVERITY[value.upper()]
logs = OrderedDict(
sorted(
config.get(DOMAIN)[LOGGER_LOGS].items(),
key=lambda t: len(t[0]),
reverse=True
)
)
logfilter[LOGGER_LOGS] = logs
# Set log filter for all log handler
for handler in logging.root.handlers:
handler.addFilter(HomeAssistantLogFilter(logfilter))
return True

View File

@@ -1,8 +1,10 @@
"""
homeassistant.components.media_player
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Component to interface with various media players.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/media_player/
"""
import logging
import os

View File

@@ -4,7 +4,7 @@ homeassistant.components.media_player.chromecast
Provides functionality to interact with Cast devices on the network.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.cast.html
https://home-assistant.io/components/media_player.cast/
"""
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.media_player.denon
Provides an interface to Denon Network Receivers.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.denon.html
https://home-assistant.io/components/media_player.denon/
"""
import telnetlib
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.media_player.firetv
Provides functionality to interact with FireTV devices.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.firetv.html
https://home-assistant.io/components/media_player.firetv/
"""
import logging
import requests

View File

@@ -4,7 +4,7 @@ homeassistant.components.media_player.itunes
Provides an interface to iTunes API.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.itunes.html
https://home-assistant.io/components/media_player.itunes/
"""
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.media_player.kodi
Provides an interface to the XBMC/Kodi JSON-RPC API
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.kodi.html
https://home-assistant.io/components/media_player.kodi/
"""
import urllib
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.media_player.mpd
Provides functionality to interact with a Music Player Daemon.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.mpd.html
https://home-assistant.io/components/media_player.mpd/
"""
import logging
import socket

View File

@@ -4,7 +4,7 @@ homeassistant.components.media_player.plex
Provides an interface to the Plex API.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.plex.html
https://home-assistant.io/components/media_player.plex/
"""
import os
import json

View File

@@ -4,7 +4,7 @@ homeassistant.components.media_player.sonos
Provides an interface to Sonos players (via SoCo)
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.sonos.html
https://home-assistant.io/components/media_player.sonos/
"""
import logging
import datetime

View File

@@ -4,7 +4,7 @@ homeassistant.components.media_player.squeezebox
Provides an interface to the Logitech SqueezeBox API
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.squeezebox.html
https://home-assistant.io/components/media_player.squeezebox/
"""
import logging
import telnetlib
@@ -173,7 +173,7 @@ class SqueezeBoxDevice(MediaPlayerDevice):
def volume_level(self):
""" Volume level of the media player (0..1). """
if 'mixer volume' in self._status:
return int(self._status['mixer volume']) / 100.0
return int(float(self._status['mixer volume'])) / 100.0
@property
def is_volume_muted(self):

View File

@@ -4,7 +4,7 @@ homeassistant.components.modbus
Modbus component, using pymodbus (python3 branch).
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/modbus.html
https://home-assistant.io/components/modbus/
"""
import logging

View File

@@ -4,7 +4,7 @@ homeassistant.components.mqtt
MQTT component, using paho-mqtt.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/mqtt.html
https://home-assistant.io/components/mqtt/
"""
import logging
import os

View File

@@ -1,15 +1,17 @@
"""
homeassistant.components.notify
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Provides functionality to notify people.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/notify/
"""
from functools import partial
import logging
import os
import homeassistant.bootstrap as bootstrap
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import get_component
from homeassistant.helpers import config_per_platform
from homeassistant.const import CONF_NAME
@@ -21,6 +23,9 @@ DEPENDENCIES = []
ATTR_TITLE = "title"
ATTR_TITLE_DEFAULT = "Home Assistant"
# Target of the notification (user, device, etc)
ATTR_TARGET = 'target'
# Text to notify user of
ATTR_MESSAGE = "message"
@@ -43,16 +48,15 @@ def setup(hass, config):
for platform, p_config in config_per_platform(config, DOMAIN, _LOGGER):
# get platform
notify_implementation = get_component(
'notify.{}'.format(platform))
notify_implementation = bootstrap.prepare_setup_platform(
hass, config, DOMAIN, platform)
if notify_implementation is None:
_LOGGER.error("Unknown notification service specified.")
continue
# create platform service
notify_service = notify_implementation.get_service(
hass, {DOMAIN: p_config})
notify_service = notify_implementation.get_service(hass, p_config)
if notify_service is None:
_LOGGER.error("Failed to initialize notification service %s",
@@ -68,8 +72,9 @@ def setup(hass, config):
return
title = call.data.get(ATTR_TITLE, ATTR_TITLE_DEFAULT)
target = call.data.get(ATTR_TARGET)
notify_service.send_message(message, title=title)
notify_service.send_message(message, title=title, target=target)
# register service
service_call_handler = partial(notify_message, notify_service)

View File

@@ -4,7 +4,7 @@ homeassistant.components.notify.file
File notification service.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.file.html
https://home-assistant.io/components/notify.file/
"""
import logging
import os
@@ -20,14 +20,14 @@ _LOGGER = logging.getLogger(__name__)
def get_service(hass, config):
""" Get the file notification service. """
if not validate_config(config,
if not validate_config({DOMAIN: config},
{DOMAIN: ['filename',
'timestamp']},
_LOGGER):
return None
filename = config[DOMAIN]['filename']
timestamp = config[DOMAIN]['timestamp']
filename = config['filename']
timestamp = config['timestamp']
return FileNotificationService(hass, filename, timestamp)

View File

@@ -4,11 +4,13 @@ homeassistant.components.notify.instapush
Instapush notification service.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.instapush.html
https://home-assistant.io/components/notify.instapush/
"""
import logging
import json
import requests
from homeassistant.helpers import validate_config
from homeassistant.components.notify import (
DOMAIN, ATTR_TITLE, BaseNotificationService)
@@ -21,7 +23,7 @@ _RESOURCE = 'https://api.instapush.im/v1/'
def get_service(hass, config):
""" Get the instapush notification service. """
if not validate_config(config,
if not validate_config({DOMAIN: config},
{DOMAIN: [CONF_API_KEY,
'app_secret',
'event',
@@ -29,52 +31,29 @@ def get_service(hass, config):
_LOGGER):
return None
headers = {'x-instapush-appid': config[CONF_API_KEY],
'x-instapush-appsecret': config['app_secret']}
try:
import requests
except ImportError:
_LOGGER.exception(
"Unable to import requests. "
"Did you maybe not install the 'Requests' package?")
response = requests.get(_RESOURCE + 'events/list',
headers=headers).json()
except ValueError:
_LOGGER.error('Unexpected answer from Instapush API.')
return None
# pylint: disable=unused-variable
try:
response = requests.get(_RESOURCE)
if 'error' in response:
_LOGGER.error(response['msg'])
return None
except requests.ConnectionError:
if len([app for app in response if app['title'] == config['event']]) == 0:
_LOGGER.error(
"Connection error "
"Please check if https://instapush.im is available.")
"No app match your given value. "
"Please create an app at https://instapush.im")
return None
instapush = requests.Session()
headers = {'x-instapush-appid': config[DOMAIN][CONF_API_KEY],
'x-instapush-appsecret': config[DOMAIN]['app_secret']}
response = instapush.get(_RESOURCE + 'events/list',
headers=headers)
try:
if response.json()['error']:
_LOGGER.error(response.json()['msg'])
# pylint: disable=bare-except
except:
try:
next(events for events in response.json()
if events['title'] == config[DOMAIN]['event'])
except StopIteration:
_LOGGER.error(
"No event match your given value. "
"Please create an event at https://instapush.im")
else:
return InstapushNotificationService(
config[DOMAIN].get(CONF_API_KEY),
config[DOMAIN]['app_secret'],
config[DOMAIN]['event'],
config[DOMAIN]['tracker']
)
return InstapushNotificationService(
config[CONF_API_KEY], config['app_secret'], config['event'],
config['tracker'])
# pylint: disable=too-few-public-methods
@@ -82,9 +61,6 @@ class InstapushNotificationService(BaseNotificationService):
""" Implements notification service for Instapush. """
def __init__(self, api_key, app_secret, event, tracker):
# pylint: disable=no-name-in-module, unused-variable
from requests import Session
self._api_key = api_key
self._app_secret = app_secret
self._event = event
@@ -94,8 +70,6 @@ class InstapushNotificationService(BaseNotificationService):
'x-instapush-appsecret': self._app_secret,
'Content-Type': 'application/json'}
self.instapush = Session()
def send_message(self, message="", **kwargs):
""" Send a message to a user. """
@@ -104,10 +78,8 @@ class InstapushNotificationService(BaseNotificationService):
data = {"event": self._event,
"trackers": {self._tracker: title + " : " + message}}
response = self.instapush.post(
_RESOURCE + 'post',
data=json.dumps(data),
headers=self._headers)
response = requests.post(_RESOURCE + 'post', data=json.dumps(data),
headers=self._headers)
if response.json()['status'] == 401:
_LOGGER.error(

View File

@@ -4,11 +4,13 @@ homeassistant.components.notify.nma
NMA (Notify My Android) notification service.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.nma.html
https://home-assistant.io/components/notify.nma/
"""
import logging
import xml.etree.ElementTree as ET
import requests
from homeassistant.helpers import validate_config
from homeassistant.components.notify import (
DOMAIN, ATTR_TITLE, BaseNotificationService)
@@ -21,31 +23,20 @@ _RESOURCE = 'https://www.notifymyandroid.com/publicapi/'
def get_service(hass, config):
""" Get the NMA notification service. """
if not validate_config(config,
if not validate_config({DOMAIN: config},
{DOMAIN: [CONF_API_KEY]},
_LOGGER):
return None
try:
# pylint: disable=unused-variable
from requests import Session
except ImportError:
_LOGGER.exception(
"Unable to import requests. "
"Did you maybe not install the 'Requests' package?")
return None
nma = Session()
response = nma.get(_RESOURCE + 'verify',
params={"apikey": config[DOMAIN][CONF_API_KEY]})
response = requests.get(_RESOURCE + 'verify',
params={"apikey": config[CONF_API_KEY]})
tree = ET.fromstring(response.content)
if tree[0].tag == 'error':
_LOGGER.error("Wrong API key supplied. %s", tree[0].text)
else:
return NmaNotificationService(config[DOMAIN][CONF_API_KEY])
return None
return NmaNotificationService(config[CONF_API_KEY])
# pylint: disable=too-few-public-methods
@@ -53,26 +44,20 @@ class NmaNotificationService(BaseNotificationService):
""" Implements notification service for NMA. """
def __init__(self, api_key):
# pylint: disable=no-name-in-module, unused-variable
from requests import Session
self._api_key = api_key
self._data = {"apikey": self._api_key}
self.nma = Session()
def send_message(self, message="", **kwargs):
""" Send a message to a user. """
title = kwargs.get(ATTR_TITLE)
data = {
"apikey": self._api_key,
"application": 'home-assistant',
"event": kwargs.get(ATTR_TITLE),
"description": message,
"priority": 0,
}
self._data['application'] = 'home-assistant'
self._data['event'] = title
self._data['description'] = message
self._data['priority'] = 0
response = self.nma.get(_RESOURCE + 'notify',
params=self._data)
response = requests.get(_RESOURCE + 'notify', params=data)
tree = ET.fromstring(response.content)
if tree[0].tag == 'error':

View File

@@ -4,59 +4,118 @@ homeassistant.components.notify.pushbullet
PushBullet platform for notify component.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.pushbullet.html
https://home-assistant.io/components/notify.pushbullet/
"""
import logging
from homeassistant.helpers import validate_config
from homeassistant.components.notify import (
DOMAIN, ATTR_TITLE, BaseNotificationService)
ATTR_TITLE, ATTR_TARGET, BaseNotificationService)
from homeassistant.const import CONF_API_KEY
_LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['pushbullet.py==0.7.1']
REQUIREMENTS = ['pushbullet.py==0.9.0']
# pylint: disable=unused-argument
def get_service(hass, config):
""" Get the PushBullet notification service. """
from pushbullet import PushBullet
from pushbullet import InvalidKeyError
if not validate_config(config,
{DOMAIN: [CONF_API_KEY]},
_LOGGER):
if CONF_API_KEY not in config:
_LOGGER.error("Unable to find config key '%s'", CONF_API_KEY)
return None
try:
# pylint: disable=unused-variable
from pushbullet import PushBullet, InvalidKeyError # noqa
except ImportError:
_LOGGER.exception(
"Unable to import pushbullet. "
"Did you maybe not install the 'pushbullet.py' package?")
return None
try:
return PushBulletNotificationService(config[DOMAIN][CONF_API_KEY])
pushbullet = PushBullet(config[CONF_API_KEY])
except InvalidKeyError:
_LOGGER.error(
"Wrong API key supplied. "
"Get it at https://www.pushbullet.com/account")
return None
return PushBulletNotificationService(pushbullet)
# pylint: disable=too-few-public-methods
class PushBulletNotificationService(BaseNotificationService):
""" Implements notification service for Pushbullet. """
def __init__(self, api_key):
from pushbullet import PushBullet
def __init__(self, pb):
self.pushbullet = pb
self.pbtargets = {}
self.refresh()
self.pushbullet = PushBullet(api_key)
def refresh(self):
'''
Refresh devices, contacts, channels, etc
def send_message(self, message="", **kwargs):
""" Send a message to a user. """
pbtargets stores all targets available from this pushbullet instance
into a dict. These are PB objects!. It sacrifices a bit of memory
for faster processing at send_message
'''
self.pushbullet.refresh()
self.pbtargets = {
'device':
{tgt.nickname: tgt for tgt in self.pushbullet.devices},
'contact':
{tgt.email: tgt for tgt in self.pushbullet.contacts},
'channel':
{tgt.channel_tag: tgt for tgt in self.pushbullet.channels},
}
def send_message(self, message=None, **kwargs):
"""
Send a message to a specified target.
If no target specified, a 'normal' push will be sent to all devices
linked to the PB account.
"""
targets = kwargs.get(ATTR_TARGET)
title = kwargs.get(ATTR_TITLE)
refreshed = False
self.pushbullet.push_note(title, message)
if not targets:
# Backward compatebility, notify all devices in own account
self.pushbullet.push_note(title, message)
_LOGGER.info('Sent notification to self')
return
# Make list if not so
if not isinstance(targets, list):
targets = [targets]
# Main loop, Process all targets specified
for target in targets:
# Allow for untargeted push, combined with other types
if target in ['device', 'device/']:
self.pushbullet.push_note(title, message)
_LOGGER.info('Sent notification to self')
continue
try:
ttype, tname = target.split('/', 1)
except ValueError:
_LOGGER.error('Invalid target syntax: %s', target)
continue
# Refresh if name not found. While awaiting periodic refresh
# solution in component, poor mans refresh ;)
if ttype not in self.pbtargets:
_LOGGER.error('Invalid target syntax: %s', target)
continue
if tname not in self.pbtargets[ttype] and not refreshed:
self.refresh()
refreshed = True
# Attempt push_note on a dict value. Keys are types & target
# name. Dict pbtargets has all *actual* targets.
try:
self.pbtargets[ttype][tname].push_note(title, message)
except KeyError:
_LOGGER.error('No such target: %s.%s', ttype, tname)
continue
except self.pushbullet.errors.PushError:
_LOGGER.error('Notify failed to: %s.%s', ttype, tname)
continue
_LOGGER.info('Sent notification to %s.%s', ttype, tname)

View File

@@ -0,0 +1,63 @@
"""
homeassistant.components.notify.pushetta
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Pushetta platform for notify component.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.pushetta/
"""
import logging
from homeassistant.helpers import validate_config
from homeassistant.components.notify import (
DOMAIN, ATTR_TITLE, BaseNotificationService)
from homeassistant.const import CONF_API_KEY
_LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['pushetta==1.0.15']
def get_service(hass, config):
""" Get the Pushetta notification service. """
from pushetta import Pushetta, exceptions
if not validate_config({DOMAIN: config},
{DOMAIN: [CONF_API_KEY, 'channel_name']},
_LOGGER):
return None
try:
pushetta = Pushetta(config[CONF_API_KEY])
pushetta.pushMessage(config['channel_name'], "Home Assistant started")
except exceptions.TokenValidationError:
_LOGGER.error("Please check your access token")
return None
except exceptions.ChannelNotFoundError:
_LOGGER.error("Channel '%s' not found", config['channel_name'])
return None
return PushettaNotificationService(config[CONF_API_KEY],
config['channel_name'])
# pylint: disable=too-few-public-methods
class PushettaNotificationService(BaseNotificationService):
""" Implements notification service for Pushetta. """
def __init__(self, api_key, channel_name):
from pushetta import Pushetta
self._api_key = api_key
self._channel_name = channel_name
self.pushetta = Pushetta(self._api_key)
def send_message(self, message="", **kwargs):
""" Send a message to a user. """
title = kwargs.get(ATTR_TITLE)
self.pushetta.pushMessage(self._channel_name,
"{} {}".format(title, message))

View File

@@ -4,7 +4,7 @@ homeassistant.components.notify.pushover
Pushover platform for notify component.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.pushover.html
https://home-assistant.io/components/notify.pushover/
"""
import logging
@@ -21,32 +21,21 @@ _LOGGER = logging.getLogger(__name__)
def get_service(hass, config):
""" Get the pushover notification service. """
if not validate_config(config,
if not validate_config({DOMAIN: config},
{DOMAIN: ['user_key', CONF_API_KEY]},
_LOGGER):
return None
try:
# pylint: disable=no-name-in-module, unused-variable
from pushover import InitError
except ImportError:
_LOGGER.exception(
"Unable to import pushover. "
"Did you maybe not install the 'python-pushover.py' package?")
return None
from pushover import InitError
try:
api_token = config[DOMAIN].get(CONF_API_KEY)
return PushoverNotificationService(
config[DOMAIN]['user_key'],
api_token)
return PushoverNotificationService(config['user_key'],
config[CONF_API_KEY])
except InitError:
_LOGGER.error(
"Wrong API key supplied. "
"Get it at https://pushover.net")
return None
# pylint: disable=too-few-public-methods
@@ -54,7 +43,6 @@ class PushoverNotificationService(BaseNotificationService):
""" Implements notification service for Pushover. """
def __init__(self, user_key, api_token):
# pylint: disable=no-name-in-module, unused-variable
from pushover import Client
self._user_key = user_key
self._api_token = api_token
@@ -63,11 +51,9 @@ class PushoverNotificationService(BaseNotificationService):
def send_message(self, message="", **kwargs):
""" Send a message to a user. """
# pylint: disable=no-name-in-module
from pushover import RequestError
title = kwargs.get(ATTR_TITLE)
try:
self.pushover.send_message(message, title=title)
self.pushover.send_message(message, title=kwargs.get(ATTR_TITLE))
except RequestError:
_LOGGER.exception("Could not send pushover notification")

View File

@@ -0,0 +1,15 @@
notify:
description: Send a notification
fields:
message:
description: Message body of the notification.
example: The garage door has been open for 10 minutes.
title:
description: Optional title for your notification.
example: 'Your Garage Door Friend'
target:
description: Target of the notification. Optional depending on the platform
example: platform specific

View File

@@ -4,13 +4,12 @@ homeassistant.components.notify.slack
Slack platform for notify component.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.slack.html
https://home-assistant.io/components/notify.slack/
"""
import logging
from homeassistant.helpers import validate_config
from homeassistant.components.notify import (
DOMAIN, BaseNotificationService)
from homeassistant.components.notify import DOMAIN, BaseNotificationService
from homeassistant.const import CONF_API_KEY
REQUIREMENTS = ['slacker==0.6.8']
@@ -20,34 +19,22 @@ _LOGGER = logging.getLogger(__name__)
# pylint: disable=unused-variable
def get_service(hass, config):
""" Get the slack notification service. """
import slacker
if not validate_config(config,
if not validate_config({DOMAIN: config},
{DOMAIN: ['default_channel', CONF_API_KEY]},
_LOGGER):
return None
try:
# pylint: disable=no-name-in-module, unused-variable
from slacker import Error as SlackError
except ImportError:
_LOGGER.exception(
"Unable to import slacker. "
"Did you maybe not install the 'slacker.py' package?")
return None
try:
api_token = config[DOMAIN].get(CONF_API_KEY)
return SlackNotificationService(
config[DOMAIN]['default_channel'],
api_token)
config['default_channel'],
config[CONF_API_KEY])
except SlackError as ex:
_LOGGER.error(
except slacker.Error:
_LOGGER.exception(
"Slack authentication failed")
_LOGGER.exception(ex)
return None
# pylint: disable=too-few-public-methods
@@ -56,6 +43,7 @@ class SlackNotificationService(BaseNotificationService):
def __init__(self, default_channel, api_token):
from slacker import Slacker
self._default_channel = default_channel
self._api_token = api_token
self.slack = Slacker(self._api_token)
@@ -63,11 +51,11 @@ class SlackNotificationService(BaseNotificationService):
def send_message(self, message="", **kwargs):
""" Send a message to a user. """
import slacker
from slacker import Error as SlackError
channel = kwargs.get('channel', self._default_channel)
try:
self.slack.chat.post_message(channel, message)
except SlackError as ex:
except slacker.Error:
_LOGGER.exception("Could not send slack notification")
_LOGGER.exception(ex)

View File

@@ -4,7 +4,7 @@ homeassistant.components.notify.smtp
Mail (SMTP) notification service.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.smtp.html
https://home-assistant.io/components/notify.smtp/
"""
import logging
import smtplib
@@ -20,35 +20,31 @@ _LOGGER = logging.getLogger(__name__)
def get_service(hass, config):
""" Get the mail notification service. """
if not validate_config(config,
{DOMAIN: ['server',
'port',
'sender',
'username',
'password',
'recipient']},
if not validate_config({DOMAIN: config},
{DOMAIN: ['server', 'port', 'sender', 'username',
'password', 'recipient']},
_LOGGER):
return None
smtp_server = config[DOMAIN]['server']
port = int(config[DOMAIN]['port'])
username = config[DOMAIN]['username']
password = config[DOMAIN]['password']
smtp_server = config['server']
port = int(config['port'])
username = config['username']
password = config['password']
starttls = int(config['starttls'])
server = None
try:
server = smtplib.SMTP(smtp_server, port)
server.ehlo()
if int(config[DOMAIN]['starttls']) == 1:
if starttls == 1:
server.starttls()
server.ehlo()
try:
server.login(username, password)
except (smtplib.SMTPException, smtplib.SMTPSenderRefused) as error:
_LOGGER.exception(error,
"Please check your settings.")
except (smtplib.SMTPException, smtplib.SMTPSenderRefused):
_LOGGER.exception("Please check your settings.")
return None
@@ -66,18 +62,13 @@ def get_service(hass, config):
return None
if server:
server.quit()
finally:
if server:
server.quit()
return MailNotificationService(
config[DOMAIN]['server'],
config[DOMAIN]['port'],
config[DOMAIN]['sender'],
config[DOMAIN]['starttls'],
config[DOMAIN]['username'],
config[DOMAIN]['password'],
config[DOMAIN]['recipient']
)
smtp_server, port, config['sender'], starttls, username, password,
config['recipient'])
# pylint: disable=too-few-public-methods, too-many-instance-attributes
@@ -90,7 +81,7 @@ class MailNotificationService(BaseNotificationService):
self._server = server
self._port = port
self._sender = sender
self.starttls = int(starttls)
self.starttls = starttls
self.username = username
self.password = password
self.recipient = recipient

View File

@@ -4,7 +4,7 @@ homeassistant.components.notify.syslog
Syslog notification service.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.syslog.html
https://home-assistant.io/components/notify.syslog/
"""
import logging
import syslog
@@ -52,16 +52,14 @@ PRIORITIES = {5: syslog.LOG_EMERG,
def get_service(hass, config):
""" Get the mail notification service. """
if not validate_config(config,
{DOMAIN: ['facility',
'option',
'priority']},
if not validate_config({DOMAIN: config},
{DOMAIN: ['facility', 'option', 'priority']},
_LOGGER):
return None
_facility = FACILITIES.get(config[DOMAIN]['facility'], 40)
_option = OPTIONS.get(config[DOMAIN]['option'], 10)
_priority = PRIORITIES.get(config[DOMAIN]['priority'], -1)
_facility = FACILITIES.get(config['facility'], 40)
_option = OPTIONS.get(config['option'], 10)
_priority = PRIORITIES.get(config['priority'], -1)
return SyslogNotificationService(_facility, _option, _priority)

View File

@@ -4,7 +4,7 @@ homeassistant.components.notify.telegram
Telegram platform for notify component.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/notify.telegram.html
https://home-assistant.io/components/notify.telegram/
"""
import logging
import urllib
@@ -16,35 +16,27 @@ from homeassistant.const import CONF_API_KEY
_LOGGER = logging.getLogger(__name__)
try:
import telegram
except ImportError:
_LOGGER.exception(
"Unable to import python-telegram-bot. "
"Did you maybe not install the 'python-telegram-bot' package?")
REQUIREMENTS = ['python-telegram-bot==2.8.7']
def get_service(hass, config):
""" Get the Telegram notification service. """
import telegram
if not validate_config(config,
if not validate_config({DOMAIN: config},
{DOMAIN: [CONF_API_KEY, 'chat_id']},
_LOGGER):
return None
try:
bot = telegram.Bot(token=config[DOMAIN][CONF_API_KEY])
bot = telegram.Bot(token=config[CONF_API_KEY])
username = bot.getMe()['username']
_LOGGER.info("Telegram bot is '%s'.", username)
except urllib.error.HTTPError:
_LOGGER.error("Please check your access token.")
return None
return TelegramNotificationService(
config[DOMAIN][CONF_API_KEY],
config[DOMAIN]['chat_id'])
return TelegramNotificationService(config[CONF_API_KEY], config['chat_id'])
# pylint: disable=too-few-public-methods
@@ -52,12 +44,15 @@ class TelegramNotificationService(BaseNotificationService):
""" Implements notification service for Telegram. """
def __init__(self, api_key, chat_id):
import telegram
self._api_key = api_key
self._chat_id = chat_id
self.bot = telegram.Bot(token=self._api_key)
def send_message(self, message="", **kwargs):
""" Send a message to a user. """
import telegram
title = kwargs.get(ATTR_TITLE)
@@ -65,4 +60,4 @@ class TelegramNotificationService(BaseNotificationService):
self.bot.sendMessage(chat_id=self._chat_id,
text=title + " " + message)
except telegram.error.TelegramError:
_LOGGER.error("Your chat id '%s' is not valid.", self._chat_id)
_LOGGER.exception("Error sending message.")

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