Merge branch 'dev' into refactor-media-player
Conflicts: homeassistant/components/frontend/version.py
This commit is contained in:
commit
8e50f50a48
9 changed files with 1593 additions and 1235 deletions
|
@ -36,6 +36,8 @@ omit =
|
|||
homeassistant/components/notify/nma.py
|
||||
homeassistant/components/notify/pushbullet.py
|
||||
homeassistant/components/notify/pushover.py
|
||||
homeassistant/components/notify/smtp.py
|
||||
homeassistant/components/notify/syslog.py
|
||||
homeassistant/components/notify/xmpp.py
|
||||
homeassistant/components/sensor/bitcoin.py
|
||||
homeassistant/components/sensor/mysensors.py
|
||||
|
|
|
@ -1,24 +1,41 @@
|
|||
# Adding support for a new device
|
||||
# Contributing to Home Assistant
|
||||
|
||||
Everybody is invited and welcome to contribute to Home Assistant. There is a lot to do...if you are not a developer perhaps you would like to help with the documentation on [home-assistant.io](https://home-assistant.io/)? If you are a developer and have devices in your home which aren't working with Home Assistant yet, why not spent a couple of hours and help to integrate them?
|
||||
|
||||
The process is straight-forward.
|
||||
|
||||
- Fork the Home Assistant [git repository](https://github.com/balloob/home-assistant).
|
||||
- Write the code for your device, notification service, sensor, or IoT thing.
|
||||
- Check it with ``pylint`` and ``flake8``.
|
||||
- Create a Pull Request against the [**dev**](https://github.com/balloob/home-assistant/tree/dev) branch of Home Assistant.
|
||||
|
||||
Still interested? Then you should read the next sections and get more details.
|
||||
|
||||
## Adding support for a new device
|
||||
|
||||
For help on building your component, please see the [developer documentation](https://home-assistant.io/developers/) on [home-assistant.io](https://home-assistant.io/).
|
||||
|
||||
After you finish adding support for your device:
|
||||
|
||||
- update the supported devices in README.md.
|
||||
- add any new dependencies to requirements.txt.
|
||||
- Make sure all your code passes Pylint, flake8 (PEP8 and some more) validation. To generate reports, run `pylint homeassistant > pylint.txt` and `flake8 homeassistant --exclude bower_components,external > flake8.txt`.
|
||||
- Update the supported devices in the `README.md` file.
|
||||
- Add any new dependencies to `requirements.txt`.
|
||||
- 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).
|
||||
- Make sure all your code passes Pylint and flake8 (PEP8 and some more) validation. To generate reports, run `pylint homeassistant > pylint.txt` and `flake8 homeassistant --exclude bower_components,external > flake8.txt`.
|
||||
- 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:
|
||||
|
||||
- update the file [`domain-icon.html`](https://github.com/balloob/home-assistant/blob/master/homeassistant/components/http/www_static/polymer/domain-icon.html) with an icon for your domain ([pick from this list](https://www.polymer-project.org/0.5/components/core-elements/demo.html#core-icon))
|
||||
- update the demo component with two states that it provides
|
||||
- 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
|
||||
|
||||
Since you've updated domain-icon.html, you've made changes to the frontend:
|
||||
Since you've updated `home-assistant-icons.html`, you've made changes to the frontend:
|
||||
|
||||
- run `build_frontend`. This will build a new version of the frontend. Make sure you add the changed files `frontend.py` and `frontend.html` to the commit.
|
||||
- Run `build_frontend`. This will build a new version of the frontend. Make sure you add the changed files `frontend.py` and `frontend.html` to the commit.
|
||||
|
||||
## Setting states
|
||||
### Setting states
|
||||
|
||||
It is the responsibility of the component to maintain the states of the devices in your domain. Each device should be a single state and, if possible, a group should be provided that tracks the combined state of the devices.
|
||||
|
||||
|
@ -31,9 +48,9 @@ A state can have several attributes that will help the frontend in displaying yo
|
|||
|
||||
These attributes are defined in [homeassistant.components](https://github.com/balloob/home-assistant/blob/master/homeassistant/components/__init__.py#L25).
|
||||
|
||||
## Proper Visibility Handling ##
|
||||
### Proper Visibility Handling
|
||||
|
||||
Generally, when creating a new entity for Home Assistant you will want it to be a class that inherits the [homeassistant.helpers.entity.Entity](https://github.com/balloob/home-assistant/blob/master/homeassistant/helpers/entity.py) Class. If this is done, visibility will be handled for you.
|
||||
Generally, when creating a new entity for Home Assistant you will want it to be a class that inherits the [homeassistant.helpers.entity.Entity](https://github.com/balloob/home-assistant/blob/master/homeassistant/helpers/entity.py) class. If this is done, visibility will be handled for you.
|
||||
You can set a suggestion for your entity's visibility by setting the hidden property by doing something similar to the following.
|
||||
|
||||
```python
|
||||
|
@ -44,12 +61,12 @@ This will SUGGEST that the active frontend hides the entity. This requires that
|
|||
|
||||
Remember: The suggestion set by your component's code will always be overwritten by user settings in the configuration.yaml file. This is why you may set hidden to be False, but the property may remain True (or vice-versa).
|
||||
|
||||
## Working on the frontend
|
||||
### Working on the frontend
|
||||
|
||||
The frontend is composed of Polymer web-components and compiled into the file `frontend.html`. During development you do not want to work with the compiled version but with the seperate files. To have Home Assistant serve the seperate files, set `development=1` for the http-component in your config.
|
||||
The frontend is composed of [Polymer](https://www.polymer-project.org) web-components and compiled into the file `frontend.html`. During development you do not want to work with the compiled version but with the seperate files. To have Home Assistant serve the seperate files, set `development=1` for the *http-component* in your config.
|
||||
|
||||
When you are done with development and ready to commit your changes, run `build_frontend`, set `development=0` in your config and validate that everything still works.
|
||||
|
||||
## Notes on PyLint and PEP8 validation
|
||||
### Notes on PyLint and PEP8 validation
|
||||
|
||||
In case a PyLint warning cannot be avoided, add a comment to disable the PyLint check for that line. This can be done using the format `# pylint: disable=YOUR-ERROR-NAME`. Example of an unavoidable PyLint warning is if you do not use the passed in datetime if you're listening for time change.
|
||||
|
|
|
@ -35,16 +35,16 @@ If you run into issues while using Home Assistant or during development of a com
|
|||
|
||||
## Installation instructions / Quick-start guide
|
||||
|
||||
Running Home Assistant requires that python 3.4 and the package requests are installed. Run the following code to install and start Home Assistant:
|
||||
Running Home Assistant requires that [Python](https://www.python.org/) 3.4 and the package [requests](http://docs.python-requests.org/en/latest/) are installed. Run the following code to install and start Home Assistant:
|
||||
|
||||
```python
|
||||
git clone --recursive https://github.com/balloob/home-assistant.git
|
||||
cd home-assistant
|
||||
pip3 install -r requirements.txt
|
||||
python3 -m pip install --user -r requirements.txt
|
||||
python3 -m homeassistant --open-ui
|
||||
```
|
||||
|
||||
The last command will start the Home Assistant server and launch its webinterface. By default Home Assistant looks for the configuration file `config/home-assistant.conf`. A standard configuration file will be written if none exists.
|
||||
The last command will start the Home Assistant server and launch its web interface. By default Home Assistant looks for the configuration file `config/home-assistant.conf`. A standard configuration file will be written if none exists.
|
||||
|
||||
If you are still exploring if you want to use Home Assistant in the first place, you can enable the demo mode by adding the `--demo-mode` argument to the last command.
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
""" DO NOT MODIFY. Auto-generated by build_frontend script """
|
||||
VERSION = "464ae07e4263837b88b3e5bda062eaed"
|
||||
VERSION = "17c8913244cf7359d3e107501e6ca373"
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -42,7 +42,11 @@
|
|||
},
|
||||
|
||||
cardTapped: function() {
|
||||
uiActions.showMoreInfoDialog(this.stateObj.entityId);
|
||||
// Debounce wrapper added as workaround for bug
|
||||
// https://github.com/PolymerElements/iron-overlay-behavior/issues/14
|
||||
this.debounce('show-more-info-dialog', function() {
|
||||
uiActions.showMoreInfoDialog(this.stateObj.entityId);
|
||||
}, 1);
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
|
File diff suppressed because one or more lines are too long
164
homeassistant/components/notify/smtp.py
Normal file
164
homeassistant/components/notify/smtp.py
Normal file
|
@ -0,0 +1,164 @@
|
|||
"""
|
||||
homeassistant.components.notify.mail
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Mail notification service.
|
||||
|
||||
Configuration:
|
||||
|
||||
To use the Mail notifier you will need to add something like the following
|
||||
to your config/configuration.yaml
|
||||
|
||||
notify:
|
||||
platform: mail
|
||||
server: MAIL_SERVER
|
||||
port: YOUR_SMTP_PORT
|
||||
sender: SENDER_EMAIL_ADDRESS
|
||||
starttls: 1 or 0
|
||||
username: YOUR_SMTP_USERNAME
|
||||
password: YOUR_SMTP_PASSWORD
|
||||
recipient: YOUR_RECIPIENT
|
||||
|
||||
Variables:
|
||||
|
||||
server
|
||||
*Required
|
||||
SMTP server which is used to end the notifications. For Google Mail, eg.
|
||||
smtp.gmail.com. Keep in mind that Google has some extra layers of protection
|
||||
which need special attention (Hint: 'Less secure apps').
|
||||
|
||||
port
|
||||
*Required
|
||||
The port that the SMTP server is using, eg. 587 for Google Mail and STARTTLS
|
||||
or 465/993 depending on your SMTP servers.
|
||||
|
||||
sender
|
||||
*Required
|
||||
E-Mail address of the sender.
|
||||
|
||||
starttls
|
||||
*Optional
|
||||
Enables STARTTLS, eg. 1 or 0.
|
||||
|
||||
username
|
||||
*Required
|
||||
Username for the SMTP account.
|
||||
|
||||
password
|
||||
*Required
|
||||
Password for the SMTP server that belongs to the given username. If the
|
||||
password contains a colon it need to be wrapped in apostrophes.
|
||||
|
||||
recipient
|
||||
*Required
|
||||
Recipient of the notification.
|
||||
"""
|
||||
import logging
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
from homeassistant.helpers import validate_config
|
||||
from homeassistant.components.notify import (
|
||||
DOMAIN, ATTR_TITLE, BaseNotificationService)
|
||||
|
||||
_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']},
|
||||
_LOGGER):
|
||||
return None
|
||||
|
||||
smtp_server = config[DOMAIN]['server']
|
||||
port = int(config[DOMAIN]['port'])
|
||||
username = config[DOMAIN]['username']
|
||||
password = config[DOMAIN]['password']
|
||||
|
||||
server = None
|
||||
try:
|
||||
server = smtplib.SMTP(smtp_server, port)
|
||||
server.ehlo()
|
||||
if int(config[DOMAIN]['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.")
|
||||
|
||||
return None
|
||||
|
||||
except smtplib.socket.gaierror:
|
||||
_LOGGER.exception(
|
||||
"SMTP server not found. "
|
||||
"Please check the IP address or hostname of your SMTP server.")
|
||||
|
||||
return None
|
||||
|
||||
except smtplib.SMTPAuthenticationError:
|
||||
_LOGGER.exception(
|
||||
"Login not possible. "
|
||||
"Please check your setting and/or your credentials.")
|
||||
|
||||
return None
|
||||
|
||||
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']
|
||||
)
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods, too-many-instance-attributes
|
||||
class MailNotificationService(BaseNotificationService):
|
||||
""" Implements notification service for E-Mail messages. """
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
def __init__(self, server, port, sender, starttls, username,
|
||||
password, recipient):
|
||||
self._server = server
|
||||
self._port = port
|
||||
self._sender = sender
|
||||
self.starttls = int(starttls)
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.recipient = recipient
|
||||
|
||||
self.mail = smtplib.SMTP(self._server, self._port)
|
||||
self.mail.ehlo_or_helo_if_needed()
|
||||
if self.starttls == 1:
|
||||
self.mail.starttls()
|
||||
self.mail.ehlo()
|
||||
|
||||
self.mail.login(self.username, self.password)
|
||||
|
||||
def send_message(self, message="", **kwargs):
|
||||
""" Send a message to a user. """
|
||||
|
||||
subject = kwargs.get(ATTR_TITLE)
|
||||
|
||||
msg = MIMEText(message)
|
||||
msg['Subject'] = subject
|
||||
msg['To'] = self.recipient
|
||||
msg['From'] = self._sender
|
||||
msg['X-Mailer'] = 'HomeAssistant'
|
||||
|
||||
self.mail.sendmail(self._sender, self.recipient, msg.as_string())
|
110
homeassistant/components/notify/syslog.py
Normal file
110
homeassistant/components/notify/syslog.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
"""
|
||||
homeassistant.components.notify.syslog
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Syslog notification service.
|
||||
|
||||
Configuration:
|
||||
|
||||
To use the Syslog notifier you will need to add something like the following
|
||||
to your config/configuration.yaml
|
||||
|
||||
notify:
|
||||
platform: syslog
|
||||
facility: SYSLOG_FACILITY
|
||||
option: SYSLOG_LOG_OPTION
|
||||
priority: SYSLOG_PRIORITY
|
||||
|
||||
Variables:
|
||||
|
||||
facility
|
||||
*Optional
|
||||
Facility according to RFC 3164 (http://tools.ietf.org/html/rfc3164). Default
|
||||
is 'syslog' if no value is given.
|
||||
|
||||
option
|
||||
*Option
|
||||
Log option. Default is 'pid' if no value is given.
|
||||
|
||||
priority
|
||||
*Optional
|
||||
Priority of the messages. Default is 'info' if no value is given.
|
||||
"""
|
||||
import logging
|
||||
import syslog
|
||||
|
||||
from homeassistant.helpers import validate_config
|
||||
from homeassistant.components.notify import (
|
||||
DOMAIN, ATTR_TITLE, BaseNotificationService)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
FACILITIES = {'kernel': syslog.LOG_KERN,
|
||||
'user': syslog.LOG_USER,
|
||||
'mail': syslog.LOG_MAIL,
|
||||
'daemon': syslog.LOG_DAEMON,
|
||||
'auth': syslog.LOG_KERN,
|
||||
'LPR': syslog.LOG_LPR,
|
||||
'news': syslog.LOG_NEWS,
|
||||
'uucp': syslog.LOG_UUCP,
|
||||
'cron': syslog.LOG_CRON,
|
||||
'syslog': syslog.LOG_SYSLOG,
|
||||
'local0': syslog.LOG_LOCAL0,
|
||||
'local1': syslog.LOG_LOCAL1,
|
||||
'local2': syslog.LOG_LOCAL2,
|
||||
'local3': syslog.LOG_LOCAL3,
|
||||
'local4': syslog.LOG_LOCAL4,
|
||||
'local5': syslog.LOG_LOCAL5,
|
||||
'local6': syslog.LOG_LOCAL6,
|
||||
'local7': syslog.LOG_LOCAL7}
|
||||
|
||||
OPTIONS = {'pid': syslog.LOG_PID,
|
||||
'cons': syslog.LOG_CONS,
|
||||
'ndelay': syslog.LOG_NDELAY,
|
||||
'nowait': syslog.LOG_NOWAIT,
|
||||
'perror': syslog.LOG_PERROR}
|
||||
|
||||
PRIORITIES = {5: syslog.LOG_EMERG,
|
||||
4: syslog.LOG_ALERT,
|
||||
3: syslog.LOG_CRIT,
|
||||
2: syslog.LOG_ERR,
|
||||
1: syslog.LOG_WARNING,
|
||||
0: syslog.LOG_NOTICE,
|
||||
-1: syslog.LOG_INFO,
|
||||
-2: syslog.LOG_DEBUG}
|
||||
|
||||
|
||||
def get_service(hass, config):
|
||||
""" Get the mail notification service. """
|
||||
|
||||
if not validate_config(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)
|
||||
|
||||
return SyslogNotificationService(_facility, _option, _priority)
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class SyslogNotificationService(BaseNotificationService):
|
||||
""" Implements syslog notification service. """
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
def __init__(self, facility, option, priority):
|
||||
self._facility = facility
|
||||
self._option = option
|
||||
self._priority = priority
|
||||
|
||||
def send_message(self, message="", **kwargs):
|
||||
""" Send a message to a user. """
|
||||
|
||||
title = kwargs.get(ATTR_TITLE)
|
||||
|
||||
syslog.openlog(title, self._option, self._facility)
|
||||
syslog.syslog(self._priority, message)
|
||||
syslog.closelog()
|
Loading…
Add table
Add a link
Reference in a new issue