Ready for first release

This commit is contained in:
Paulus Schoutsen 2014-12-21 14:40:18 -08:00
parent 775045fc86
commit 86bb2df430
10 changed files with 438 additions and 79 deletions

View File

@ -1,3 +1,8 @@
To test changes to home-assistant.io locally, run `rake preview` and navigate to [http://127.0.0.1:4000](http://127.0.0.1:4000).
Deploying is done using `rake deploy`.
## What is Octopress?
Octopress is [Jekyll](https://github.com/mojombo/jekyll) blogging at its finest.

View File

@ -17,6 +17,19 @@
margin-top: -18px;
}
article.post, article.page {
table, img {
border-radius: 3px;
box-shadow: rgba(0,0,0,0.06) 0 0 10px;
}
table {
background-color: white;
}
}
.note {
background: #e7f2fa;
padding: 12px;
@ -30,8 +43,8 @@
}
.title {
border-top-left-radius: 0.4em;
border-top-right-radius: 0.4em;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
font-weight: bold;
display: block;
color: #fff;
@ -45,4 +58,16 @@
.content {
margin-bottom: 0;
}
&.warning {
background-color: #E5EABB;
.title {
background-color: rgb(187, 185, 13);;
}
.title::before {
content: "\f071";
}
}
}

View File

@ -1,7 +1,8 @@
<ul class="menu pull-right">
<li><a href="{{ root_url }}/getting-started/">Getting started</a></li>
<li><a href="{{ root_url }}/architecture/">Architecture</a></li>
<li><a href="{{ root_url }}/contributing/">Contributing</a></li>
<li><a href="{{ root_url }}/developers/">Developers</a></li>
<li><a href="{{ root_url }}/api/">API</a></li>
<li><a href="{{ root_url }}/blog/">Blog</a></li>
<li><a href="https://groups.google.com/forum/#!forum/home-assistant-dev">Need help?</a></li>
</ul>

196
source/api/index.markdown Normal file
View File

@ -0,0 +1,196 @@
---
layout: page
title: "Rest API"
date: 2014-12-21 13:27
sidebar: false
comments: true
sharing: true
footer: true
---
Home Assistent runs a webserver accessible on port 8123.
* http://127.0.0.1:8123/ is an interface to control Home Assistant.
* http://localhost:8123/api/ is a Rest API.
In the package [`homeassistant.remote`](https://github.com/balloob/home-assistant/blob/master/homeassistant/remote.py) a Python API on top of the HTTP API can be found.
The API accepts and returns only JSON encoded objects. All API calls have to be accompanied by the header `X-HA-Access: YOUR_PASSWORD` (as specified in your `home-assistant.conf`).
<div class='note'><p class='title'>Note</p><p class='content'>
You can append <code>?api_password=YOUR_PASSWORD</code> to any url to log in automatically.
</p></div>
Successful calls will return status code 200 or 201. Other status codes that can return are:
- 400 (Bad Request)
- 401 (Unauthorized)
- 404 (Not Found)
- 405 (Method not allowed)
The api supports the following actions:
**/api - GET**<br>
Returns message if API is up and running.
```json
{
"message": "API running."
}
```
**/api/events - GET**<br>
Returns an array of event objects. Each event object contain event name and listener count.
```json
[
{
"event": "state_changed",
"listener_count": 5
},
{
"event": "time_changed",
"listener_count": 2
}
]
```
**/api/services - GET**<br>
Returns an array of service objects. Each object contains the domain and which services it contains.
```json
[
{
"domain": "browser",
"services": [
"browse_url"
]
},
{
"domain": "keyboard",
"services": [
"volume_up",
"volume_down"
]
}
]
```
**/api/states - GET**<br>
Returns an array of state objects. Each state has the following attributes: entity_id, state, last_changed and attributes.
```json
[
{
"attributes": {
"next_rising": "07:04:15 29-10-2013",
"next_setting": "18:00:31 29-10-2013"
},
"entity_id": "sun.sun",
"last_changed": "23:24:33 28-10-2013",
"state": "below_horizon"
},
{
"attributes": {},
"entity_id": "process.Dropbox",
"last_changed": "23:24:33 28-10-2013",
"state": "on"
}
]
```
**/api/states/&lt;entity_id>** - GET<br>
Returns a state object for specified entity_id. Returns 404 if not found.
```json
{
"attributes": {
"next_rising": "07:04:15 29-10-2013",
"next_setting": "18:00:31 29-10-2013"
},
"entity_id": "sun.sun",
"last_changed": "23:24:33 28-10-2013",
"state": "below_horizon"
}
```
**/api/states/&lt;entity_id>** - POST<br>
Updates or creates the current state of an entity.
Return code is 200 if the entity existed, 201 if the state of a new entity was set. A location header will be returned with the url of the new resource. The response body will contain a JSON encoded State object.<br>
<br>
parameter: state - string<br>
optional parameter: attributes - JSON object
```json
{
"attributes": {
"next_rising": "07:04:15 29-10-2013",
"next_setting": "18:00:31 29-10-2013"
},
"entity_id": "weather.sun",
"last_changed": "23:24:33 28-10-2013",
"state": "below_horizon"
}
```
**/api/events/&lt;event_type>** - POST<br>
Fires an event with event_type<br>
optional body: JSON encoded object that represents event_data
```json
{
"message": "Event download_file fired."
}
```
**/api/services/&lt;domain>/&lt;service>** - POST<br>
Calls a service within a specific domain. Will return when the service has been executed or 10 seconds has past, whichever comes first.<br>
optional body: JSON encoded object that represents service_data
Returns a list of states that have changed since the start of this service call.
```json
[
{
"attributes": {
"next_rising": "07:04:15 29-10-2013",
"next_setting": "18:00:31 29-10-2013"
},
"entity_id": "sun.sun",
"last_changed": "23:24:33 28-10-2013",
"state": "below_horizon"
},
{
"attributes": {},
"entity_id": "process.Dropbox",
"last_changed": "23:24:33 28-10-2013",
"state": "on"
}
]
```
**/api/event_forwarding** - POST<br>
Setup event forwarding to another Home Assistant instance.<br>
parameter: host - string<br>
parameter: api_password - string<br>
optional parameter: port - int<br>
```json
{
"message": "Event forwarding setup."
}
```
**/api/event_forwarding** - DELETE<br>
Cancel event forwarding to another Home Assistant instance.<br>
parameter: host - string<br>
optional parameter: port - int<br>
If your client does not support DELETE HTTP requests you can add an optional attribute _METHOD and set its value to DELETE.
```json
{
"message": "Event forwarding cancelled."
}
```

View File

@ -8,23 +8,25 @@ sharing: true
footer: true
---
<img src='{{ root_url }}/images/ha_architecture.png' style='background-color: white'/>
<a href='{{ root_url }}/images/ha_architecture.png'>
<img src='{{ root_url }}/images/ha_architecture.png' style='border: 0; box-shadow: none;'/>
</a>
The core of Home Assistant exists of the following parts.
The <b>Event Bus</b> facilitates the firing and listening of events. This is the beating heart of Home Assistant.
The **Event Bus** facilitates the firing and listening of events. This is the beating heart of Home Assistant.
The <b>State Machine</b> keeps track of the states of things. Fires a state_changed event when a state has been changed.
The **State Machine** keeps track of the states of things. Fires a state_changed event when a state has been changed.
The <b>Service Registry</b> listens on the event bus for call_service events and allows other code to register services.
The **Service Registry** listens on the event bus for call_service events and allows other code to register services.
The <b>Timer</b> will send every 10 seconds a time_changed event on the event bus.
The **Timer** will send every 10 seconds a time_changed event on the event bus.
Take for example the device_tracker component. This component is responsible for keeping track which devices are home. It checks which devices are home every time a time_changed event is fired on the event bus. It will then update the state machine with the information for each device.
This setup allows us to create simple yet powerful logic for controlling your home:
In the event that the state of device 'Paulus Nexus 5' changes to the 'Home' state:
In the event that device 'Paulus Nexus 5' changes to the 'Home' state:
If the sun has set and the lights are not on:
Turn on the lights
@ -37,3 +39,29 @@ This setup allows us to create simple yet powerful logic for controlling your ho
Turn on the lights
By using the Bus as a central communication hub between components it is easy to replace components or add functionality. If you would want to change the way devices are detected you only have to write a component that updates the device states in the State Machine.
## Multiple connected instances
Home Assistant supports running multiple synchronzied instances using a master-slave model. Slaves forward all local events fired and states set to the master instance which will then replicate it to each slave.
Because each slave maintains its own ServiceRegistry it is possible to have multiple slaves respond to one service call.
<a href='{{ root_url }}/images/architecture-remote.png'>
<img src='{{ root_url }}/images/architecture-remote.png' style='border: 0; box-shadow: none;' />
</a>
A slave instance can be started with the following code and has the same support for components as a master-instance.
```python
import homeassistant.remote as remote
import homeassistant.components.http as http
remote_api = remote.API("remote_host_or_ip", "remote_api_password")
hass = remote.HomeAssistant(remote_api)
http.setup(hass, "my_local_api_password")
hass.start()
hass.block_till_stopped()
```

View File

@ -0,0 +1,104 @@
---
layout: page
title: "Components"
date: 2014-12-21 13:35
sidebar: false
comments: true
sharing: true
footer: true
---
### sun
Tracks the state of the sun and when the next sun rising and setting will occur.
Depends on: config variables common/latitude and common/longitude
* Maintains state of `weather.sun` including attributes `next_rising` and `next_setting`
### device_tracker
Keeps track of which devices are currently home.
* Sets the state per device and maintains a combined state called `all_devices`.
* Keeps track of known devices in the file `config/known_devices.csv`.
Supported platforms:
* `netgear` for Netgear routers that support their SOAP API
* `luci` for routers running OpenWRT
* `tomato` for routers running Tomato
* `nmap` for using nmap to scan IP ranges on the network
### light
Keeps track which lights are turned on and can control the lights. It has [4 built-in light profiles](https://github.com/balloob/home-assistant/blob/master/homeassistant/components/light/light_profiles.csv) which you're able to extend by putting a light_profiles.csv file in your config dir.
* Maintains a state per light and a combined state `all_light`.
* Registers services `light/turn_on` and `light/turn_off` to control the lights.
Optional service data:
- `entity_id` - only act on specified lights. Else targets all.
- `transition_seconds` - seconds to take to switch to new state.
- `profile` - which light profile to use.
- `xy_color` - two comma seperated floats that represent the color in XY
- `rgb_color` - three comma seperated integers that represent the color in RGB
- `brightness` - integer between 0 and 255 for how bright the color should be
- `flash` - tell light to flash, can be either value `short` or `long`
Supported platforms:
* `hue` for Philips Hue
### switch
Keeps track which switches are in the network, their state and allows you to control them.
* Maintains a state per switch and a combined state `all_switches`.
* Registers services `switch/turn_on` and `switch/turn_off` to control switches.
Optional service data:
- `entity_id` - only act on specific switch. Else targets all.
Supported platforms:
* `wemo` for Belkin WeMo switches
* `tellstick` for Tellstick switches
### device_sun_light_trigger
Turns lights on or off using a light control component based on state of the sun and devices that are home.
Depends on: light control, track_sun, device_tracker
* Turns lights off when all devices leave home.
* Turns lights on when a device is home while sun is setting.
* Turns lights on when a device gets home after sun set.
### chromecast
Registers 7 services to control playback on a Chromecast: `turn_off`, `volume_up`, `volume_down`, `media_play_pause`, `media_play`, `media_pause`, `media_next_track`.
Registers three services to start playing YouTube video's on the ChromeCast.
Service `chromecast/play_youtube_video` starts playing the specified video on the YouTube app on the ChromeCast. Specify video using `video` in service_data.
Service `chromecast/start_fireplace` will start a YouTube movie simulating a fireplace and the `chromecast/start_epic_sax` service will start playing Epic Sax Guy 10h version.
### keyboard
Registers services that will simulate key presses on the keyboard. It currently offers the following Buttons as a Service (BaaS): `keyboard/volume_up`, `keyboard/volume_down` and `keyboard/media_play_pause`
This actor depends on: PyUserInput
### downloader
Registers service `downloader/download_file` that will download files. File to download is specified in the `url` field in the service data.
### browser
Registers service `browser/browse_url` that opens `url` as specified in event_data in the system default browser.
### tellstick_sensor
Shows the values of that sensors that is connected to your Tellstick.
### simple_alarm
Will provide simple alarm functionality. Will flash a light shortly if a known device comes home. Will flash the lights red if the lights turn on while no one is home.
Depends on device_tracker, light.
Config options:
known_light: entity id of the light/light group to target to flash when a known device comes home
unknown_light: entity if of the light/light group to target when a light is turned on while no one is at home.

View File

@ -1,66 +0,0 @@
---
layout: page
title: "contributing"
date: 2014-12-18 22:57
sidebar: false
comments: true
sharing: true
footer: true
---
You've probably came here beacuse you noticed that your favorite device is not supported and want to add it.
First step is to decide under which component the device has to reside. Each component is responsible for a specific domain within Home Assistant. An example is the switch component, which is responsible for interaction with different types of switches. The switch component consists of the following files:
**homeassistant/components/switch/\_\_init\_\_.py**<br />
Contains the Switch component code.
**homeassistant/components/switch/wemo.py**<br />
Contains the code to interact with WeMo switches. Called if platform=wemo in switch config.
**homeassistant/components/switch/tellstick.py**
Contains the code to interact with Tellstick switches. Called if platform=tellstick in switch config.
If a component exists, your job is easy. Have a look at how the component works with other platforms and create a similar file for the platform that you would like to add. If you cannot find a suitable component, you'll have to add it yourself. When writing a component try to structure it after the Switch component to maximize reusability.
Communication between Home Assistant and devices should happen via third-party libraries that implement the device API. This will make sure the platform support code stays as small as possible.
For help on building your component, please see the See the documentation on [further customizing Home Assistant](https://github.com/balloob/home-assistant#further-customizing-home-assistant).
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`.
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/components/core-icons/demo.html))
- 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:
- 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
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.
A state can have several attributes that will help the frontend in displaying your state:
- `friendly_name`: this name will be used as the name of the device
- `entity_picture`: this picture will be shown instead of the domain icon
- `unit_of_measurement`: this will be appended to the state in the interface
These attributes are defined in [homeassistant.components](https://github.com/balloob/home-assistant/blob/master/homeassistant/components/__init__.py#L25).
## 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.
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
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.

View File

@ -0,0 +1,66 @@
---
layout: page
title: "Developers"
date: 2014-12-21 13:32
sidebar: false
comments: true
sharing: true
footer: true
---
Home Assistant can be extended by components. Components can listen for- or trigger events and offer services. Components are written in Python and can do all the goodness that Python has to offer.
Home Assistant offers [built-in components]({{site_root}}/components/) but it is easy to built your own. An example component can be found in [`/config/custom_components/example.py`](https://github.com/balloob/home-assistant/blob/master/config/custom_components/example.py).
<div class='note'><p class='title'>Note</p><p class='content'>
Home Assistant will use the directory that contains your config file as the directory that holds your customizations. By default this is the <code>config</code> folder in your current work directory. You can use a different folder by running Home Assistant with the --config argument <code>python3 homeassistant --config /YOUR/CONFIG/PATH/</code>.
</p></div>
A component will be loaded on start if a section (ie. `[light]`) for it exists in the config file. A component can also be loaded if another component is loaded that depends on it. When loading a component Home Assistant will check the following paths:
* <code>&lt;config directory>/custom_components/&lt;component name></code>
* <code>homeassistant/components/&lt;component name></code> (built-in components)
Once loaded, a component will only be setup if all dependencies can be loaded and are able to setup. Keep an eye on the logs to see if loading and setup of your component went well.
<div class='note warning'><p class='title'>Warning</p><p class='content'>
*Warning:* You can override a built-in component by offering a component with the same name in your custom_components folder. This is not recommended and may lead to unexpected behavior!
</p></div>
Each component is responsible for a specific domain within Home Assistant. An example is the switch component, which is responsible for interaction with different types of switches. The switch component consists of the following files in `homeassistant/components/switch/`:
| File | Description |
| ---- | ----------- |
| \_\_init\_\_.py | Contains the Switch component code.|
| wemo.py | WeMo platform support. Included if in config `platform=wemo`. |
| tellstick.py | Tellstick platform support. Included if in config `platform=tellstick`. |
If a component exists, your job is easy. Have a look at how the component works with other platforms and create a similar file for the platform that you would like to add. If you cannot find a suitable component, you'll have to add it yourself. When writing a component try to structure it after the Switch component to maximize reusability.
Communication between Home Assistant and devices should happen via third-party libraries that implement the device API. This will make sure the platform support code stays as small as possible.
After a component is loaded the bootstrapper will call its setup method `setup(hass, config)`:
| Parameter | Description |
| --------- | ----------- |
| <code>hass</code> | The Home Assistant object. Call its methods to track time, register services or listen for events: [Overview of available methods.](https://github.com/balloob/home-assistant/blob/master/homeassistant/__init__.py#L38) |
| <code>config</code> | A dict containing the configuration. The keys of the config-dict are component names and the value is another dict with configuration attributes. |
### Guidance on using the Home Assistant object
The Home Assistant object contains three objects to help you interact with the system.
| Object | Description |
| ------ | ----------- |
| <code>hass.states</code> | This is the StateMachine. The StateMachine allows you to see which states are available and set/test states for specified entities. [See available methods](https://github.com/balloob/home-assistant/blob/master/homeassistant/__init__.py#L473). |
| <code>hass.events</code> | This is the EventBus. The EventBus allows you to listen and trigger events. [See available methods](https://github.com/balloob/home-assistant/blob/master/homeassistant/__init__.py#L308). |
| <code>hass.services</code> | This is the ServiceRegistry. The ServiceRegistry allows you to register services. [See available methods](https://github.com/balloob/home-assistant/blob/master/homeassistant/__init__.py#L589). |
### Example on using the configuration parameter
If your configuration file containes the following lines:
```
[example]
host=paulusschoutsen.nl
```
Then in the setup-method of your component you will be able to refer to `config['example']['host']` to get the value `paulusschoutsen.nl`.

View File

@ -26,10 +26,10 @@ If you're using Docker, you can use
docker run -d --name="home-assistant" -v /path/to/homeassistant/config:/config -v /etc/localtime:/etc/localtime:ro -p 8123:8123 balloob/home-assistant
```
After you got the demo mode running it is time to enable some real components and get started. An example configuration file has been provided in [/config/home-assistant.conf.example](https://github.com/balloob/home-assistant/blob/master/config/home-assistant.conf.example).
After you got the demo mode running it is time to enable some [components]({{site_root}}/components/) and get started. An example configuration file has been provided in [`/config/home-assistant.conf.example`](https://github.com/balloob/home-assistant/blob/master/config/home-assistant.conf.example).
<div class='note'><p class='title'>Note</p><p class='content'>
You can append `?api_password=YOUR_PASSWORD` to the url of the web interface to log in automatically.
You can append <code>?api_password=YOUR_PASSWORD</code> to any url to log in automatically.
</p></div>
<div class='note'><p class='title'>Note</p><p class='content'>
@ -72,7 +72,7 @@ Tomato requires an extra config variable called `http_id`. The value can be obta
Before the Luci scanner can be used you have to install the luci RPC package on OpenWRT: `opkg install luci-mod-rpc`.
</p></div>
Once tracking, the `device_tracker` component will maintain a file in your config dir called `known_devices.csv`. Edit this file to adjust which devices have to be tracked.
Once tracking, the `device_tracker` component will maintain a file in your config dir called `known_devices.csv`. Edit this file to adjust which devices have to be tracked. Here you can also setup a url for each device to be used as the entity picture.
As an alternative to the router-based device tracking, it is possible to directly scan the network for devices by using nmap. The IP addresses to scan can be specified in any format that nmap understands, including the network-prefix notation (`192.168.1.1/24`) and the range notation (`192.168.1.1-255`).
@ -80,4 +80,4 @@ As an alternative to the router-based device tracking, it is possible to directl
[device_tracker]
platform=nmap_tracker
hosts=192.168.1.1/24
```
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB