mirror of
https://github.com/home-assistant/home-assistant.io.git
synced 2025-07-24 09:46:59 +00:00
Add development 101 section
This commit is contained in:
parent
00a5dee7fb
commit
94957caacb
@ -23,6 +23,16 @@
|
||||
<li>{% active_link /developers/development_validation/ Validation %}</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
{% active_link /developers/development_101/ Development 101 %}
|
||||
<ul>
|
||||
<li>{% active_link /developers/development_hass_object/ Hass object %}</li>
|
||||
<li>{% active_link /developers/development_events/ Events %}</li>
|
||||
<li>{% active_link /developers/development_states/ States %}</li>
|
||||
<li>{% active_link /developers/development_services/ Services %}</li>
|
||||
<li>{% active_link /developers/development_config/ Config %}</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
{% active_link /developers/add_new_platform/ Support a new device (as a platform) %}
|
||||
<ul>
|
||||
|
@ -11,7 +11,7 @@ footer: true
|
||||
|
||||
Home Assistant allows components and platforms to specify their dependencies and requirements using the variables `DEPENDENCIES` and `REQUIREMENTS`. Both are lists that contain strings.
|
||||
|
||||
## Dependencies
|
||||
## {% linkable_title Dependencies %}
|
||||
|
||||
Dependencies are other Home Assistant components that should be setup before the platform is loaded. An example is the MQTT sensor component, which requires an active connection to an MQTT broker. If Home Assistant is unable to load and setup the MQTT component, it will not setup the MQTT sensor component.
|
||||
|
||||
@ -19,7 +19,7 @@ Dependencies are other Home Assistant components that should be setup before the
|
||||
DEPENDENCIES = ['mqtt']
|
||||
```
|
||||
|
||||
## Requirements
|
||||
## {% linkable_title Requirements %}
|
||||
|
||||
Requirements are Python libraries that you would normally install using `pip` for your component. Home Assistant will try to install the requirements into the `deps` subdirectory of the Home Assistant configuration directory (`.home-assistant` by default) or verify it is already installed at startup. If that fails, the component will fail to load.
|
||||
|
||||
|
@ -1,36 +0,0 @@
|
||||
---
|
||||
layout: page
|
||||
title: "Initializing your components"
|
||||
description: "Instructions how to handle initialization of your component."
|
||||
date: 2016-04-16 13:32
|
||||
sidebar: true
|
||||
comments: false
|
||||
sharing: true
|
||||
footer: true
|
||||
---
|
||||
|
||||
After loading, the bootstrapper will call `setup(hass, config)` method on the component to initialize it.
|
||||
|
||||
### {% linkable_title hass: the Home Assistant instance %}
|
||||
|
||||
The Home Assistant instance contains four objects to help you interact with the system.
|
||||
|
||||
| Object | Description |
|
||||
| ------ | ----------- |
|
||||
| `hass.config` | This is the core configuration of Home Assistant exposing location, temperature preferences and config directory path. [Details](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/core.py#L687)
|
||||
| `hass.states` | This is the StateMachine. It allows you to set states and track when they are changed. [See available methods](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/core.py#L434). |
|
||||
| `hass.bus` | This is the EventBus. It allows you to trigger and listen for events.<br>[See available methods](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/core.py#L229). |
|
||||
| `hass.services` | This is the ServiceRegistry. It allows you to register services.<br>[See available methods](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/core.py#L568). |
|
||||
|
||||
### {% linkable_title config: User given configuration. %}
|
||||
|
||||
The `config` parameter is a dictionary containing the user supplied configuration. The keys of the dictionary are the component names and the value is another dictionary with the component configuration.
|
||||
|
||||
If your configuration file contains the following lines:
|
||||
|
||||
```yaml
|
||||
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`.
|
38
source/developers/development_101.markdown
Normal file
38
source/developers/development_101.markdown
Normal file
@ -0,0 +1,38 @@
|
||||
---
|
||||
layout: page
|
||||
title: "Development 101"
|
||||
description: "Introduction to the basics of Home Assistant."
|
||||
date: 2017-05-13 05:40:00 +0000
|
||||
sidebar: true
|
||||
comments: false
|
||||
sharing: true
|
||||
footer: true
|
||||
---
|
||||
|
||||
The goal of development 101 is to get you familiar with the basics of developing for Home Assistant. Before we start, please make sure you familiarize yourself with the [architecture].
|
||||
|
||||
To get our code running inside Home Assistant we're going to create a custom component. The first step is to locate your config folder. You can find the path to your config folder by opening the Home Assistant frontend, click on the <img src='/images/screenshots/developer-tool-about-icon.png' alt='service developer tool icon' class="no-shadow" height="38" />. It's the path after the text "Path to configuration.yaml".
|
||||
|
||||
Inside your configuration directory create a new folder called `custom_components`. It might be that one already exists, that's fine too. This is the folder that Home Assistant will look at when looking for custom code.
|
||||
|
||||
<p class='note'>
|
||||
The Home Assistant API has two variants: a synchronous and an asynchronous version (asyncio). This development course will focus on the synchronous version.
|
||||
</p>
|
||||
|
||||
To verify that everything is working correctly, let's create a small Hello World component. To do so, create a file called `hello_world.py` in your custom components folder. Copy paste the following content to it:
|
||||
|
||||
```python
|
||||
# The domain of your component. Equal to the filename of your component.
|
||||
DOMAIN = "hello_world"
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""Setup the hello_world component."""
|
||||
# States are in the format DOMAIN.OBJECT_ID.
|
||||
hass.states.set('hello_world.Hello_World', 'Works!')
|
||||
|
||||
# Return boolean to indicate that initialization was successfully.
|
||||
return True
|
||||
```
|
||||
|
||||
[architecture]: /developers/architecture/
|
35
source/developers/development_config.markdown
Normal file
35
source/developers/development_config.markdown
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
layout: page
|
||||
title: "Using Config"
|
||||
description: "Introduction to the Config object in Home Assistant."
|
||||
date: 2017-05-13 05:40:00 +0000
|
||||
sidebar: true
|
||||
comments: false
|
||||
sharing: true
|
||||
footer: true
|
||||
---
|
||||
|
||||
Based on where you are in the code, `config` can mean various things.
|
||||
|
||||
### {% linkable_title On the hass object %}
|
||||
|
||||
On the hass object is an instance of the Config class. The Config class contains the users preferred units, the path to the config directory and which components are loaded. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.Config)
|
||||
|
||||
### {% linkable_title Config passed into component setup %}
|
||||
|
||||
The `config` parameter passed to a component setup is a dictionary containing all of the user supplied configuration. The keys of the dictionary are the component names and the value is another dictionary with the component configuration.
|
||||
|
||||
The object will have already been validated using your `CONFIG_SCHEMA` or `PLATFORM_SCHEMA` if available. If you have defined a `PLATFORM_SCHEMA`, all references to your component (ie `light 2:` etc) will have been changed to be accessible as a list under `config[DOMAIN]`.
|
||||
|
||||
If your configuration file contains the following lines:
|
||||
|
||||
```yaml
|
||||
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`.
|
||||
|
||||
### {% linkable_title Passed into platform setup %}
|
||||
|
||||
The `config` parameter passed to a platform setup function is only the config for that specific platform.
|
61
source/developers/development_events.markdown
Normal file
61
source/developers/development_events.markdown
Normal file
@ -0,0 +1,61 @@
|
||||
---
|
||||
layout: page
|
||||
title: "Using Events"
|
||||
description: "Introduction to using events in Home Assistant."
|
||||
date: 2017-05-13 05:40:00 +0000
|
||||
sidebar: true
|
||||
comments: false
|
||||
sharing: true
|
||||
footer: true
|
||||
---
|
||||
|
||||
The core of Home Assistant is driven by events. That means that if you want to respond to something happening, you'll have to respond to events. Most of the times you won't interact directly with the event system but use one of the [event listener helpers][helpers].
|
||||
|
||||
The event system is very flexible. There are no limitations on the event type, as long as it's a string. Each event can contain data. The data is a dictionary that can contain any data as long as it's JSON serializable. This means that you can use number, string, dictionary and list.
|
||||
|
||||
[List of events that Home Assistant fires.][object]
|
||||
|
||||
### {% linkable_title Firing events %}
|
||||
|
||||
To fire an event, you have to interact with the event bus. The event bus is available on the Home Assistant instance as `hass.bus`.
|
||||
|
||||
Example component that will fire an event when loaded.
|
||||
|
||||
```python
|
||||
DOMAIN = 'hello_event'
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up is called when Home Assistant is loading our component."""
|
||||
|
||||
# Fire event my_cool_event with event data answer=42
|
||||
hass.bus.fire('my_cool_event', {
|
||||
'answer': 42
|
||||
})
|
||||
```
|
||||
|
||||
### {% linkable_title Listening to events %}
|
||||
|
||||
Most of the times you'll not be firing events but instead listen to events. For example, the state change of an entity is broadcasted as an event.
|
||||
|
||||
```python
|
||||
DOMAIN = 'hello_event'
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up is called when Home Assistant is loading our component."""
|
||||
count = 0
|
||||
|
||||
# Listener to handle fired events
|
||||
def handle_event(event):
|
||||
count += 1
|
||||
print('Total events received:', count)
|
||||
|
||||
# Listen for when my_cool_event is fired
|
||||
hass.bus.listen('my_cool_event', handle_event)
|
||||
```
|
||||
|
||||
#### {% linkable_title Helpers %}
|
||||
|
||||
Home Assistant comes with a lot of bundled helpers to listen to specific types of event. There are helpers to track a point in time, to track a time interval, a state change or the sun set. [See available methods.][helpers]
|
||||
|
||||
[helpers]: https://dev-docs.home-assistant.io/en/master/api/helpers.html#module-homeassistant.helpers.event
|
||||
[object]: /docs/configuration/events/
|
37
source/developers/development_hass_object.markdown
Normal file
37
source/developers/development_hass_object.markdown
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
layout: page
|
||||
title: "Hass object"
|
||||
description: "Introduction to developing with the hass object."
|
||||
date: 2016-04-16 13:32
|
||||
sidebar: true
|
||||
comments: false
|
||||
sharing: true
|
||||
footer: true
|
||||
---
|
||||
|
||||
While developing Home Assistant you will see a variable that is everywhere: `hass`. This is the Home Assistant instance that will give you access to all the various parts of the system.
|
||||
|
||||
### {% linkable_title The `hass` object %}
|
||||
|
||||
The Home Assistant instance contains four objects to help you interact with the system.
|
||||
|
||||
| Object | Description |
|
||||
| ------ | ----------- |
|
||||
| `hass` | This is the instance of Home Assistant. Allows starting, stopping and enqueing new jobs. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.HomeAssistant)
|
||||
| `hass.config` | This is the core configuration of Home Assistant exposing location, temperature preferences and config directory path. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.Config)
|
||||
| `hass.states` | This is the StateMachine. It allows you to set states and track when they are changed. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.StateMachine). |
|
||||
| `hass.bus` | This is the EventBus. It allows you to trigger and listen for events. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.EventBus). |
|
||||
| `hass.services` | This is the ServiceRegistry. It allows you to register services. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.ServiceRegistry). |
|
||||
|
||||
### {% linkable_title Where to find `hass` %}
|
||||
|
||||
Depending on what you're writing, there are different ways the `hass` object is made available.
|
||||
|
||||
**Component**<br>
|
||||
Passed into `setup(hass, config)` or `async_setup(hass, config)`.
|
||||
|
||||
**Platform**<br>
|
||||
Passed into `setup_platform(hass, config, add_devices, discovery_info=None)` or `async_setup_platform(hass, config, async_add_devices, discovery_info=None)`.
|
||||
|
||||
**Entity**<br>
|
||||
Available as `self.hass` once the entity has been added via the `add_devices` callback inside a platform.
|
@ -1,13 +1,12 @@
|
||||
---
|
||||
layout: page
|
||||
title: "Basic Service Example"
|
||||
description: ""
|
||||
date: 2016-02-07 12:13
|
||||
title: "Using Services"
|
||||
description: "Introduction to services in Home Assistant."
|
||||
date: 2017-05-13 05:40:00 +0000
|
||||
sidebar: true
|
||||
comments: false
|
||||
sharing: true
|
||||
footer: true
|
||||
ha_category: Custom Python Component Examples
|
||||
---
|
||||
|
||||
This is a simple "hello world" example to show the basics of registering a service. To use this example, create the file `<config dir>/custom_components/hello_service.py` and copy the below example code.
|
@ -1,20 +1,25 @@
|
||||
---
|
||||
layout: page
|
||||
title: "Basic State Setting Example"
|
||||
description: ""
|
||||
date: 2016-02-07 12:13
|
||||
title: "Using States"
|
||||
description: "Introduction to states in Home Assistant."
|
||||
date: 2017-05-13 05:40:00 +0000
|
||||
sidebar: true
|
||||
comments: false
|
||||
sharing: true
|
||||
footer: true
|
||||
ha_category: Custom Python Component Examples
|
||||
---
|
||||
|
||||
This is a simple tutorial/example on how to write a component for [Home Assistant](https://home-assistant.io/). We will work on a component called "hello_state" to begin with. The purpose of this component is to display a given text in the frontend.
|
||||
Home Assistant keeps track of the states of entities in a state machine. The state machine has very few requirements:
|
||||
|
||||
The setup of a development environment is described in the [Developers section](/developers/#starting-development) of the documentation.
|
||||
- Each state is related to an entitiy identified by an entity id. This id is made up of a domain and an object id. For example `light.kitchen_ceiling`. You can make up any combination of domain and object id, even overwriting existing states.
|
||||
- Each state has a primary attribute that describes the state of the entity. In the case of a light this could be for example "on" and "off". You can store anything you want in the state, as long as it's a string (will be converted if it's not).
|
||||
- You can store more information about an entity by setting attributes. Attributes is a dictionary that can contain any data that you want. The only requirement is that it's JSON serializable, so you're limited to numbers, strings, dictionaries and lists.
|
||||
|
||||
## {% linkable_title Component %}
|
||||
[Description of the state object.](/docs/configuration/state_object/)
|
||||
|
||||
### {% linkable_title Using states in your component %}
|
||||
|
||||
This is a simple tutorial/example on how to create and set states. We will do our work in a component called "hello_state". The purpose of this component is to display a given text in the frontend.
|
||||
|
||||
To get started, create the file `<config dir>/custom_components/hello_state.py` and copy the below example code.
|
||||
|
||||
@ -32,17 +37,17 @@ _LOGGER = logging.getLogger(__name__)
|
||||
DOMAIN = 'hello_state'
|
||||
DEPENDENCIES = []
|
||||
|
||||
def setup(hass, config=None):
|
||||
def setup(hass, config):
|
||||
"""Setup the Hello State component. """
|
||||
_LOGGER.info("The 'hello state' component is ready!")
|
||||
|
||||
return True
|
||||
```
|
||||
|
||||
1. In the file header we decided to add some details: A short description and the link to the documentation.
|
||||
1. In the file header we decided to add some details: A short description and the link to the documentation.
|
||||
2. We want to do some logging. This means that we import the Python logging module and create an alias.
|
||||
3. The component name is equal to the domain name.
|
||||
4. At the moment this component has no dependencies. For detail check [dependencies](/developers/creating_components/#dependencies) section.
|
||||
4. At the moment this component has no dependencies. For detail check [dependencies](/developers/component_deps_and_reqs/#dependencies) section.
|
||||
5. The `setup` function will take care of the initialization of our component.
|
||||
The component will only write a log message. Keep in mind for later that you have several options for the severity:
|
||||
|
||||
@ -66,9 +71,7 @@ After a start or a restart of Home Assistant the component will create an entry
|
||||
16-03-12 14:16:42 INFO (MainThread) [custom_components.hello_state] The 'hello state' component is ready!
|
||||
```
|
||||
|
||||
The next step is the introduction of configuration options. Most configuration details are coming out of the `configuration.yaml` file. To do that we need to update the `def setup()` method to accept configuration information and access the configuration variable in the `setup` method.
|
||||
|
||||
More details about this topic can be found in the [User given configuration](/developers/creating_components/#config-user-given-configuration) section.
|
||||
The next step is the introduction of configuration options. A user can pass configuration options to our component via `configuration.yaml`. To use them we'll use the passed in `config` variable to our `setup` method.
|
||||
|
||||
```python
|
||||
import logging
|
||||
@ -92,26 +95,28 @@ def setup(hass, config):
|
||||
return True
|
||||
```
|
||||
|
||||
To add the latest feature of our component, update the entry in your `configuration.yaml` file.
|
||||
To use the latest feature of our component, update the entry in your `configuration.yaml` file.
|
||||
|
||||
```yaml
|
||||
hello_state:
|
||||
text: 'Hello, World!'
|
||||
```
|
||||
|
||||
Thanks to `DEFAULT_TEXT` variable the component will launch even if no `text:` field is used in the `configuration.yaml` file. Quite often there are variables which are required. It's important to check if all mandatory configuration variables are provided. If not, the setup should fail. We will use `voluptuous` as a helper to achive this. The next listing shows the essential parts.
|
||||
Thanks to `DEFAULT_TEXT` variable the component will launch even if no `text:` field is used in the `configuration.yaml` file. Quite often there are variables which are required. It's important to check if all mandatory configuration variables are provided. If not, the setup should fail. We will use `voluptuous` as a helper to achieve this. The next listing shows the essential parts.
|
||||
|
||||
```python
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
[...]
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_TEXT): cv.string,
|
||||
})
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
vol.Required(CONF_TEXT): cv.string,
|
||||
})
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
```
|
||||
|
||||
If `text:` is missing, there will be a warning in the log file.
|
||||
Now, when `text:` is missing from the config, Home Assistant will alert the user and not setup your component.
|
||||
|
||||
After a start or a restart of Home Assistant the component will be visible in the frontend if the `configuration.yaml` file is up-to-date.
|
||||
|
||||
@ -120,4 +125,3 @@ After a start or a restart of Home Assistant the component will be visible in th
|
||||
</p>
|
||||
|
||||
To get your component included in the Home Assistant releases, follow the steps described in the [Submitting improvements](https://home-assistant.io/developers/#submitting-improvements) section. Basically you only need to move your component in the `homeassistant/component/` directory of your fork and create a Pull Request.
|
||||
|
Loading…
x
Reference in New Issue
Block a user