Release 95"

This commit is contained in:
Paulus Schoutsen 2019-07-08 09:34:26 -07:00
parent 68c775459d
commit 2d257fd570
10 changed files with 961 additions and 0 deletions

View File

@ -1521,6 +1521,33 @@
}, },
"version-0.94.0/version-0.94.0-hassio_debugging": { "version-0.94.0/version-0.94.0-hassio_debugging": {
"title": "Debugging Hass.io" "title": "Debugging Hass.io"
},
"version-0.95.0/version-0.95.0-config_entries_config_flow_handler": {
"title": "Integration Configuration",
"sidebar_label": "Configuration"
},
"version-0.95.0/version-0.95.0-development_environment": {
"title": "Set up Development Environment"
},
"version-0.95.0/version-0.95.0-development_testing": {
"title": "Testing your code"
},
"version-0.95.0/version-0.95.0-device_registry_index": {
"title": "Device Registry",
"sidebar_label": "Introduction"
},
"version-0.95.0/version-0.95.0-documentation_standards": {
"title": "Standards"
},
"version-0.95.0/version-0.95.0-frontend_development": {
"title": "Frontend development",
"sidebar_label": "Development"
},
"version-0.95.0/version-0.95.0-hassio_addon_tutorial": {
"title": "Tutorial: Making your first add-on"
},
"version-0.95.0/version-0.95.0-hassio_debugging": {
"title": "Debugging Hass.io"
} }
}, },
"links": { "links": {

View File

@ -0,0 +1,143 @@
---
title: Integration Configuration
sidebar_label: Configuration
id: version-0.95.0-config_entries_config_flow_handler
original_id: config_entries_config_flow_handler
---
> This option is currently only available for built-in components.
Integrations can be set up via the user interface by adding support for a config config to create a config entry. Components that want to support config entries will need to define a Config Flow Handler. This handler will manage the creation of entries from user input, discovery or other sources (like Hass.io).
Config Flow Handlers control the data that is stored in a config entry. This means that there is no need to validate that the config is correct when Home Assistant starts up. It will also prevent breaking changes, because we will be able to migrate configuration entries to new formats if the version changes.
When instantiating the handler, Home Assistant will make sure to load all dependencies and install the requirements of the component.
## Updating the manifest
You need to update your integrations manifest to inform Home Assistant that your integration has a config flow. This is done by adding `config_flow: true` to your manifest ([docs](creating_integration_manifest.md#config-flow)).
## Defining your config flow
Config entries uses the [data flow entry framework](data_entry_flow_index.md) to define their config flows. The config flow needs to be defined in the file `config_flow.py` in your integration folder.
To define it, extend the ConfigFlow base class from the config entries module, and decorate it with the `HANDLERS.register` decorator:
```python
from homeassistant import config_entries
@config_entries.HANDLERS.register(DOMAIN)
class ExampleConfigFlow(config_entries.ConfigFlow):
```
## Defining steps
Your config flow will need to define steps of your configuration flow. The docs for [Data Entry Flow](data_entry_flow_index.md) describe the different return values of a step. Here is an example on how to define the `user` step.
```python
@config_entries.HANDLERS.register(DOMAIN)
class ExampleConfigFlow(data_entry_flow.FlowHandler):
async def async_step_user(self, info):
if info is not None:
# process info
return self.async_show_form(
step_id='init',
data_schema=vol.Schema({
vol.Required('password'): str
})
)
```
There are a few step names reserved for system use:
| Step name | Description |
| --------- | ----------- |
| `user` | Invoked when a user initiates a flow via the user interface.
| `zeroconf` | Invoked if your integration has been discovered via Zeroconf/mDNS as specified [using `zeroconf` in the manifest](creating_integration_manifest.md#zeroconf).
| `homekit` | Invoked if your integration has been discovered via HomeKit as specified [using `homekit` in the manifest](creating_integration_manifest.md#homekit).
| `ssdp` | Invoked if your integration has been discovered via SSDP/uPnP as specified [using `ssdp` in the manifest](creating_integration_manifest.md#ssdp).
| `discovery` | _DEPRECATED_ Invoked if your integration has been discovered by the discovery integration.
## Discovery steps
When an integration is discovered, their respective discovery step is invoked with the discovery information. The step will have to check the following things:
- Make sure there are no other instances of this config flow in progress of setting up the discovered device. This can happen if there are multiple ways of discovering that a device is on the network.
- Make sure that the device is not already set up.
- Invoking a discovery step should never result in a finished flow and a config entry. Always confirm with the user.
## Discoverable integrations that require no authentication
If your integration is discoverable without requiring any authentication, you'll be able to use the Discoverable Flow that is built-in. This flow offers the following features:
- Detect if devices/services can be discovered on the network before finishing the config flow.
- Support all manifest-based discovery protocols.
- Limit to only 1 config entry. It is up to the config entry to discover all available devices.
```python
"""Config flow for LIFX."""
from homeassistant.helpers import config_entry_flow
from homeassistant import config_entries
import aiolifx
from .const import DOMAIN
async def _async_has_devices(hass):
"""Return if there are devices that can be discovered."""
lifx_ip_addresses = await aiolifx.LifxScan(hass.loop).scan()
return len(lifx_ip_addresses) > 0
config_entry_flow.register_discovery_flow(
# Domain of your integration
DOMAIN,
# Title of the created config entry
'LIFX',
# async method that returns a boolean if devices/services are found
_async_has_devices,
# Connection class of the integration
config_entries.CONN_CLASS_LOCAL_POLL
)
```
## Translations
Translations for the config flow handlers are defined under the `config` key in the component translation file `strings.json`. Example of the Hue component:
```json
{
"config": {
"title": "Philips Hue Bridge",
"step": {
"init": {
"title": "Pick Hue bridge",
"data": {
"host": "Host"
}
},
"link": {
"title": "Link Hub",
"description": "Press the button on the bridge to register Philips Hue with Home Assistant.\n\n![Location of button on bridge](/static/images/config_philips_hue.jpg)"
}
},
"error": {
"register_failed": "Failed to register, please try again",
"linking": "Unknown linking error occurred."
},
"abort": {
"discover_timeout": "Unable to discover Hue bridges",
"no_bridges": "No Philips Hue bridges discovered",
"all_configured": "All Philips Hue bridges are already configured",
"unknown": "Unknown error occurred",
"cannot_connect": "Unable to connect to the bridge",
"already_configured": "Bridge is already configured"
}
}
}
```
When the translations are merged into Home Assistant, they will be automatically uploaded to [Lokalise](https://lokalise.co/) where the translation team will help to translate them in other languages. [More info on translating Home Assistant.](internationalization_translation.md)

View File

@ -0,0 +1,120 @@
---
title: Set up Development Environment
id: version-0.95.0-development_environment
original_id: development_environment
---
You'll need to set up a development environment if you want to develop a new feature or component for Home Assistant. Read on to learn how to set up.
## Preparing your environment
### Developing on Linux
Install the core dependencies.
```bash
$ sudo apt-get install python3-pip python3-dev python3-venv
```
In order to run `script/setup` below you will need some more dependencies.
```bash
$ sudo apt-get install autoconf libssl-dev libxml2-dev libxslt1-dev libjpeg-dev libffi-dev libudev-dev zlib1g-dev
$ sudo apt-get install -y libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev libavresample-dev libavfilter-dev
```
> Different distributions have different package installation mechanisms and sometimes packages names as well. For example CentOS would use: `sudo yum install epel-release && sudo yum install python36 python36-devel mysql-devel gcc`
Additional dependencies exist if you plan to perform Frontend Development, please read the [Frontend](frontend_index.md) section to learn more.
### Developing on Windows
Due to Home Assistant is mainly designed and developed on Linux distributions, on Windows 10 you can setup a [Linux subsystem](https://docs.microsoft.com/windows/wsl/install-win10).
Open Powershell as an Administrator and run
```bash
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```
From Windows Store install Ubuntu.
When the Linux subsystem is set up, perform install as for Linux.
```bash
$ sudo apt-get update
$ sudo apt-get install python3-pip python3-dev python3-venv
$ sudo apt-get install autoconf libssl-dev libxml2-dev libxslt1-dev libjpeg-dev libffi-dev libudev-dev zlib1g-dev
$ sudo apt-get install -y libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev libavresample-dev libavfilter-dev
```
Hint: Git is included in Linux subsytem.
When invoking your installation (see below), make sure to specify a folder for configuration which is accessible from Windows.
```bash
$ mkdir -p ../config
$ hass -c ../config
```
### Developing on macOS
Install [Homebrew](https://brew.sh/), then use that to install Python 3:
```bash
$ brew install python3 autoconf
```
Then install ffmpeg:
```bash
$ brew install ffmpeg
```
## Setup Local Repository
Visit the [Home Assistant repository](https://github.com/home-assistant/home-assistant) and click **Fork**.
Once forked, setup your local copy of the source using the commands:
```bash
$ git clone https://github.com/YOUR_GIT_USERNAME/home-assistant.git
$ cd home-assistant
$ git remote add upstream https://github.com/home-assistant/home-assistant.git
```
## Setting up virtual environment
To isolate your environment from the rest of the system, set up a [`venv`](https://docs.python.org/3/library/venv.html). Within the `home-assistant` directory, create and activate your virtual environment.
```bash
$ python3 -m venv venv
$ source venv/bin/activate
```
Install the requirements with a provided script named `setup`.
```bash
$ script/setup
```
Invoke your installation, adjusting the [configuration](https://www.home-assistant.io/docs/configuration/) if required.
```bash
$ hass
```
## Logging
By default logging in Home Assistant is tuned for operating in production (set to INFO by default, with some modules set to even less verbose logging levels).
You can use the [logger](https://www.home-assistant.io/components/logger/) component to adjust logging to DEBUG to see even more details about what is going on:
```yaml
logger:
default: info
logs:
homeassistant.core: debug
nest.nest: debug
asyncio: debug
homeassistant.components.cloud.iot: debug
```

View File

@ -0,0 +1,80 @@
---
title: Testing your code
id: version-0.95.0-development_testing
original_id: development_testing
---
As it states in the [Style guidelines section](development_guidelines.md) all code is checked to verify the following:
- All the unit tests pass
- All code passes the checks from the linting tools
Local testing is done using Tox, which has been installed as part of running `script/setup` in the [virtual environment](development_environment.md). To start the tests, activate the virtual environment and simply run the command:
```bash
$ tox
```
**Important:** Run `tox` before you create your pull request to avoid annoying fixes.
Running Tox will run unit tests against the locally available Pythons, as well as validate the code and document style using `pycodestyle`, `pydocstyle` and `pylint`. You can run tests on only one tox target -- just use `-e` to select an environment. For example, `tox -e lint` runs the linters only, and `tox -e py36` runs unit tests only on Python 3.6.
Tox uses virtual environments under the hood to create isolated testing environments. The tox virtual environments will get out-of-date when requirements change, causing test errors. Run `tox -r` to tell Tox to recreate the virtual environments.
macOS users may see an `Error creating virtualenv` when runnng `tox`. If this occurs, install the [tox-venv](https://pypi.org/project/tox-venv/) package using the command `pip install tox-venv` and try again.
### Adding new dependencies to test environment
If you are working on tests for a component or platform and you need the dependencies available inside the Tox environment, update the list inside `script/gen_requirements_all.py`. Then run the script and then run `tox -r` to recreate the virtual environments.
### Running single tests using Tox
You can pass arguments via Tox to py.test to be able to run single test suites or test files. Replace `py36` with the Python version that you use.
```bash
# Stop after the first test fails
$ tox -e py36 -- tests/test_core.py -x
# Run test with specified name
$ tox -e py36 -- tests/test_core.py -k test_split_entity_id
# Fail a test after it runs for 2 seconds
$ tox -e py36 -- tests/test_core.py --timeout 2
# Show the 10 slowest tests
$ tox -e py36 -- tests/test_core.py --duration=10
```
### Testing outside of Tox
Running tox will invoke the full test suite. Even if you specify which tox target to run, you still run all tests inside that target. That's not very convenient to quickly iterate on your code! To be able to run the specific test suites without Tox, you'll need to install the test dependencies into your Python environment:
```bash
$ pip3 install -r requirements_test_all.txt -c homeassistant/package_constraints.txt
```
Now that you have all test dependencies installed, you can run tests on individual files:
```bash
$ flake8 homeassistant/core.py
$ pylint homeassistant/core.py
$ pydocstyle homeassistant/core.py
$ py.test tests/test_core.py
```
You can also run linting tests against all changed files, as reported by `git diff upstream/dev... --diff-filter=d --name-only`, using the `lint` script:
```bash
$ script/lint
```
### Preventing Linter Errors
Save yourself the hassle of extra commits just to fix style errors by enabling the Flake8 git commit hook. Flake8 will check your code when you try to commit to the repository and block the commit if there are any style errors, which gives you a chance to fix them!
```bash
$ pip3 install flake8 flake8-docstrings
$ flake8 --install-hook=git
```
The `flake8-docstrings` extension will check docstrings according to [PEP257](https://www.python.org/dev/peps/pep-0257/) when running Flake8.
### Notes on PyLint and PEP8 validation
If you can't avoid a PyLint warning, add a comment to disable the PyLint check for that line with `# pylint: disable=YOUR-ERROR-NAME`. Example of an unavoidable one is if PyLint incorrectly reports that a certain object doesn't have a certain member.

View File

@ -0,0 +1,87 @@
---
title: Device Registry
sidebar_label: Introduction
id: version-0.95.0-device_registry_index
original_id: device_registry_index
---
The device registry is a registry where Home Assistant keeps track of devices. A device is represented in Home Assistant via one or more entities. For example, a battery-powered temperature and humidity sensor might expose entities for temperature, humidity and battery level.
<img
src='/img/en/device_registry/overview.png'
alt='Device registry overview'
/>
## What is a device?
A device in Home Assistant represents a physical device that has its own control unit. The control unit itself does not have to be smart, but it should be in control of what happens. For example, an Ecobee thermostat with 4 room sensors equals 5 devices in Home Assistant, one for the thermostat including all sensors inside it, and one for each sensor. Each device exists in a specific geographical area, and may have more than one input or output within that area.
If you connect a sensor to another device to read some of its data, it should still be represented as two different devices. The reason for this is that the sensor could be moved to read the data of another device.
A device that offers multiple endpoints, where parts of the device sense or output in different areas, should be split into separate devices and refer back to parent device with the `via_device` attribute. This allows the separate endpoints to be assigned to different areas in the building.
> Although not currently available, we could consider offering an option to users to merge devices.
## Device properties
| Attribute | Description |
| --------- | ----------- |
| id | Unique ID of device (generated by Home Assistant)
| name | Name of this device
| connections | A set of tuples of `(connection_type, connection identifier)`. Connection types are defined in the device registry module.
| identifiers | Set of identifiers. They identify the device in the outside world. An example is a serial number.
| manufacturer | The manufacturer of the device.
| model | The model of the device.
| config_entries | Config entries that are linked to this device.
| sw_version | The firmware version of the device.
| via_device | Identifier of a device that routes messages between this device and Home Assistant. Examples of such devices are hubs, or parent devices of a sub-device. This is used to show device topology in Home Assistant.
| area_id | The Area which the device is placed in.
## Defining devices
> Entity device info is only read if the entity is loaded via a [config entry](config_entries_index.md).
Each entity is able to define a device via the `device_info` property. This property is read when an entity is added to Home Assistant via a config entry. A device will be matched up with an existing device via supplied identifiers and connections, like serial numbers or MAC addresses.
```python
# Inside a platform
class HueLight(LightEntity):
@property
def device_info(self):
return {
'identifiers': {
# Serial numbers are unique identifiers within a specific domain
(hue.DOMAIN, self.unique_id)
},
'name': self.name,
'manufacturer': self.light.manufacturername,
'model': self.light.productname,
'sw_version': self.light.swversion,
'via_device': (hue.DOMAIN, self.api.bridgeid),
}
```
Components are also able to register devices in the case that there are no entities representing them. An example is a hub that communicates with the lights.
```python
# Inside a component
from homeassistant.helpers import device_registry as dr
device_registry = await dr.async_get_registry(hass)
device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
connections={
(dr.CONNECTION_NETWORK_MAC, config.mac)
},
identifiers={
(DOMAIN, config.bridgeid)
},
manufacturer='Signify',
name=config.name,
model=config.modelid,
sw_version=config.swversion,
)
```

View File

@ -0,0 +1,125 @@
---
title: Standards
id: version-0.95.0-documentation_standards
original_id: documentation_standards
---
To ensure that the documentation for Home Assistant is consistent and easy to follow for both novice and expert users, we ask that you follow a very strict set of standards for developing the documentation.
## General Documentation
* The language of the documentation should be American-English.
* Don't put two spaces after a period and avoid the "Oxford comma".
* There is no limit for the line length. You are allowed to write in a flowing text style. This will make it easier to use the GitHub online editor in the future.
* Be objective and not gender favoring, polarizing, race related or religion inconsiderate.
* The case of brand names, services, protocols, components and platforms must match its respective counterpart. e.g., "Z-Wave" **not** "Zwave", "Z-wave", "Z Wave" or "ZWave". Also, "Input Select" **not** "input select" or "Input select".
* Do not use ALL CAPITALS for emphasis - use italics instead.
## Component and Platform Pages
* The **Configuration Variables** section must use the `{% configuration %}` tag.
* Configuration variables must document the requirement status (`false` or `true`).
* Configuration variables must document the default value, if any.
* Configuration variables must document the accepted value types (see [Configuration variables details](documentation_create_page.md#configuration)).
* For configuration variables that accept multiple types, separate the types with a comma (i.e. `string, int`).
* Use YAML sequence syntax in the sample code if it is supported.
* All examples should be formatted to be included in `configuration.yaml` unless explicitly stated.
* Use capital letters and `_` to indicate that the value needs to be replaced. E.g., `api_key: YOUR_API_KEY` or `api_key: REPLACE_ME`.
* If you know that the API key or value contains [control characters](https://en.wikipedia.org/wiki/YAML#Syntax), e.g., `#`, `[`, `?`, etc., wrap it in quotes and add a note.
* Component and platform names should be a link to their respective documentation pages.
Example configuration block
```yaml
{% configuration %}
some_key:
description: This is a description of what this key is for.
required: false
type: string
default: Optional default value - leave out if there isn't one
{% endconfiguration %}
```
## Templates
* All examples containing Jinja2 templates should be wrapped **outside** of the code markdown with the `{% raw %}` tag.
* Do not use `states.switch.source.state` in templates. Instead use `states()` and `is_state()`.
* Use double quotes (`"`) for ([more information](#single-vs-double-quotation-marks)):
* `friendly_name`
* Single-line templates:
* `value_template`
* `level_template`
* `icon_template`
* Children of `data_template`
* Use single quotes (`'`) for ([more information](#single-vs-double-quotation-marks):
* Strings inside of templates:
* States
* Entity IDs
* `unit_of_measurement`
* No whitespace around pipe character (`|`) for Jinja2 filters.
* Single whitespace after Jinja2 opening delimiters ({% raw %}`{{`{% endraw %}).
* Single whitespace before Jinja2 closing delimiters ({% raw %}`}}`{% endraw %}).
* Do not quote values for:
* `device_class`
* `platform`
* `condition`
* `service`
## Renaming Pages
It can happen that a component or platform is renamed, in this case the documentation needs to be updated as well. If you rename a page, add `redirect_from:` to the file header and let it point to the old location/name of the page. Please consider to add details, like release number or old component/platform name, to the page in a [note](/developers/documentation/create_page/#html).
```text
---
...
redirect_from: /getting-started/android/
---
```
Adding a redirect also applies if you move content around in the [documentation](/docs/).
## Single vs. Double Quotation Marks
Use single quotes (`'`) for strings inside of a template. It is more obvious to escape a single quote when necessary (i.e. `name` is a possessive noun), because the single quotes that wrap the string are closer in position to the apostrophe inside the string. Use double quotes (`"`) outside of a template (unless it is a multi-line template, in which case outside quotes are not required).
### Examples
#### Double Quotes Outside, Single Quotes Inside (Valid)
```yaml
automation:
...
action:
- service: notify.notify
data_template:
message: "{% if trigger.to_state.name == 'Dale\'s Bedroom' %}Someone's in your base, killing your noobs!{% else %}It's just another door.{% endif %}"
```
#### Single Quotes Outside, Double Quotes Inside (Invalid)
```yaml
automation:
...
action:
- service: notify.notify
data_template:
message: '{% if trigger.to_state.name == "Dale's Bedroom" %}Someone's in your base, killing your noobs!{% else %}It's just another door.{% endif %}'
```
#### Multi-Line Template (Valid)
```yaml
automation:
...
action:
- service: notify.notify
data_template:
message: >-
{% if trigger.to_state.name == 'Dale\'s Bedroom' %}
Someone's in your base, killing your noobs!
{% else %}
It's just another door.
{% endif %}
```

View File

@ -0,0 +1,105 @@
---
title: Frontend development
sidebar_label: Development
id: version-0.95.0-frontend_development
original_id: frontend_development
---
The Home Assistant frontend is built using web components. For more background about our technology choices, [see this blog post](https://developers.home-assistant.io/blog/2019/05/22/internet-of-things-and-the-modern-web.html).
> Do not use development mode in production. Home Assistant uses aggressive caching to improve the mobile experience. This is disabled during development so that you do not have to restart the server in between changes.
## Setting up the environment
### Getting the code
First step is to fork the [home-assistant-polymer repository][hass-polymer] and add the upstream remote. You can place the forked repository anywhere on your system.
```bash
$ git clone git@github.com:YOUR_GIT_USERNAME/home-assistant-polymer.git
$ cd home-assistant-polymer
$ git remote add upstream https://github.com/home-assistant/home-assistant-polymer.git
```
### Configuring Home Assistant
You will need to have an instance of Home Assistant set up. See our guide on [setting up a development environment](https://developers.home-assistant.io/docs/en/development_environment.html).
Next step is to configure Home Assistant to use the development mode for the frontend. Do this by updating the frontend config in your `configuration.yaml` and set the path to the home-assistant-polymer repository that you cloned in the last step:
```yaml
frontend:
# Example absolute path: /home/paulus/dev/hass/home-assistant-polymer
development_repo: <absolute path to home-assistant-polymer repo>
```
### Installing Node.js
Node.js is required to build the frontend. The preferred method of installing node.js is with [nvm](https://github.com/creationix/nvm). Install nvm using the instructions in the [README](https://github.com/creationix/nvm#install-script), and install the correct node.js by running the following command:
```bash
$ nvm install
```
[Yarn](https://yarnpkg.com/en/) is used as the package manager for node modules. [Install yarn using the instructions here.](https://yarnpkg.com/en/docs/install)
Next, development dependencies need to be installed to bootstrap the frontend development environment. First activate the right Node version and then download all the dependencies:
```bash
$ nvm use
$ script/bootstrap
```
## Development
During development, you will need to run the development script to maintain a development build of the frontend that auto updates when you change any of the source files. To run this server, run:
```bash
$ nvm use
$ script/develop
```
Make sure you have cache disabled and correct settings to avoid stale content:
> Instructions are for Google Chrome
1. Disable cache by ticking the box in `Network` > `Disable cache`
<p class='img'>
<img src='/img/en/development/disable-cache.png' />
</p>
2. Enable Bypass for network in `Application` > `Service Workers` > `Bypass for network`
<p class='img'>
<img src='/img/en/development/bypass-for-network.png' />
</p>
## Creating pull requests
If you're planning on issuing a PR back to the Home Assistant codebase you need to fork the polymer project and add your fork as a remote to the Home Assistant Polymer repo.
```bash
$ git remote add fork <github URL to your fork>
```
When you've made your changes and are ready to push them change to the working directory for the polymer project and then push your changes
``` bash
$ git add -A
$ git commit -m "Added new feature X"
$ git push -u fork HEAD
```
## Building the Polymer frontend
If you're making changes to the way the frontend is packaged, it might be necessary to try out a new packaged build of the frontend in the main repository (instead of pointing it at the frontend repo). To do so, first build a production version of the frontend by running `script/build_frontend`.
To test it out inside Home assistant, run the following command from the main Home Assistant repository:
```bash
$ pip3 install -e /path/to/home-assistant-polymer/
$ hass --skip-pip
```
[hass-polymer]: https://github.com/home-assistant/home-assistant-polymer

View File

@ -0,0 +1,182 @@
---
title: Tutorial: Making your first add-on
id: version-0.95.0-hassio_addon_tutorial
original_id: hassio_addon_tutorial
---
So you've got Home Assistant going and you've been enjoying the built-in add-ons but you're missing this one application. Time to make your own add-on! In Hass.io 0.24 we introduced the option to have local add-ons be build on your device. This is great for developing new add-ons locally.
To get started with developing add-ons, we first need access to where Hass.io looks for local add-ons. For this you can use the Samba add-on or the SSH add-on.
For Samba, once you have enabled and started it, your Hass.io instance will show up in your local network tab and share a folder called "addons". This is the folder to store your custom add-ons.
If you are on macOS and the folder is not showing up automatically, go to Finder and press CMD+K then enter 'smb://hassio.local'
![Screenshot of Windows Explorer showing a folder on the Hass.io server](/img/en/hass.io/tutorial/samba.png)
For SSH, you will have to install it. Before you can start it, you will have to have a private/public key pair and store your public key in the add-on config ([see docs for more info][ssh]). Once started, you can SSH to Hass.io and store your custom add-ons in "/addons".
![Screenshot of Putty connected to Hass.io](/img/en/hass.io/tutorial/ssh.png)
Once you have located your add-on directory, it's time to get started!
[ssh]: https://www.home-assistant.io/addons/ssh/
## Step 1: The basics
- Create a new directory called `hello_world`
- Inside that directory create three files.
`Dockerfile`:
```
ARG BUILD_FROM
FROM $BUILD_FROM
ENV LANG C.UTF-8
# Copy data for add-on
COPY run.sh /
RUN chmod a+x /run.sh
CMD [ "/run.sh" ]
```
`config.json`:
```json
{
"name": "Hello world",
"version": "1",
"slug": "hello_world",
"description": "My first real add-on!",
"arch": ["armhf", "armv7", "aarch64", "amd64", "i386"],
"startup": "before",
"boot": "auto",
"options": {},
"schema": {}
}
```
`run.sh`:
```bash
echo Hello world!
```
Make sure your editor is using UNIX-like line breaks (LF), not Dos/Windows (CRLF).
## Step 2: Installing and testing your add-on
Now comes the fun part, time to open the Hass.io UI and install and run your add-on.
- Open the Home Assistant frontend
- Go to the Hass.io panel
- On the top right click the shopping basket to go to the add-on store.
![Screenshot of the Hass.io main panel](/img/en/hass.io/screenshots/main_panel_addon_store.png)
- On the top right click the refresh button
- You should now see a new card called "Local" that lists your add-on!
![Screenshot of the local repository card](/img/en/hass.io/screenshots/local_repository.png)
- Click on your add-on to go to the add-on details page.
- Install your add-on
- Start your add-on
- Refresh the logs of your add-on, you should now see "Hello world!" in your logs.
![Screenshot of the add-on logs](/img/en/hass.io/tutorial/addon_hello_world_logs.png)
### I don't see my add-on?!
Oops! You clicked refresh in the store and your add-on didn't show up. Or maybe you just updated an option, clicked refresh and saw your add-on disappear.
When this happens, it means that your `config.json` is invalid. It's either invalid JSON or one of the specified options is incorrect. To see what went wrong, go to the Hass.io panel and in the supervisor card click on "View logs". This should bring you to a page with the logs of the supervisor. Scroll to the bottom and you should be able to find the validation error.
Once you fixed the error, go to the add-on store and click refresh again.
## Step 3: Hosting a server
Until now we've been able to do some basic stuff, but it's not very useful yet. So let's take it one step further and host a server that we expose on a port. For this we're going to use the built-in HTTP server that comes with Python 3.
To do this, we will need to update our files as follows:
- `Dockerfile`: Install Python 3
- `config.json`: Make the port from the container available on the host
- `run.sh`: Run the Python 3 command to start the HTTP server
Add to your `Dockerfile` before `RUN`:
```
# Install requirements for add-on
RUN apk add --no-cache python3
# Python 3 HTTP Server serves the current working dir
# So let's set it to our add-on persistent data directory.
WORKDIR /data
```
Add "ports" to `config.json`. This will make TCP on port 8000 inside the container available on the host on port 8000.
```json
{
"name": "Hello world",
"version": "0.2",
"slug": "hello_world",
"description": "My first real add-on!",
"arch": ["armhf", "armv7", "aarch64", "amd64", "i386"],
"startup": "before",
"boot": "auto",
"options": {},
"schema": {},
"ports": {
"8000/tcp": 8000
}
}
```
Update `run.sh` to start the Python 3 server:
```
python3 -m http.server 8000
```
## Step 4: Installing the update
Since we updated the version number in our `config.json`, Home Assistant will show an update button when looking at the add-on details. You might have to refresh your browser or click the refresh button in the add-on store for it to show up. If you did not update the version number, you can also uninstall and install the add-on again. After installing the add-on again, make sure you start it.
Now navigate to [http://hassio.local:8000](http://hassio.local:8000) to see our server in action!
![Screenshot of the file index served by the add-on](/img/en/hass.io/tutorial/python3-http-server.png)
## Bonus: Working with add-on options
In the screenshot you've probably seen that our server only served up 1 file: `options.json`. This file contains the user configuration for this add-on. Because we specified an empty "config" and "schema" in our `config.json`, the file is currently empty.
Let's see if we can get some data into that file!
To do this, we need to specify the default options and a schema for the user to change the options.
Change the options and schema entries in your `config.json` with the following:
```json
{
"options": {
"beer": true,
"wine": true,
"liquor": false,
"name": "world",
"year": 2017
},
"schema": {
"beer": "bool",
"wine": "bool",
"liquor": "bool",
"name": "str",
"year": "int"
},
}
```
Refresh the add-on store and re-install your add-on. You will now see the options available in the add-on config screen. When you now go back to our Python 3 server and download `options.json`, you'll see the options you set. [Example of how options.json can be used inside `run.sh`](https://github.com/home-assistant/hassio-addons/blob/master/mosquitto/run.sh#L4-L6)

View File

@ -0,0 +1,91 @@
---
title: Debugging Hass.io
id: version-0.95.0-hassio_debugging
original_id: hassio_debugging
---
> This section is not for end users. End users should use the [SSH add-on] to SSH into Hass.io. This is for <b>developers</b> of Hass.io. Do not ask for support if you are using these options.
[SSH add-on]: https://www.home-assistant.io/addons/ssh/
The following debug tips and tricks are for developers who are running the Hass.io image and are working on the base image. If you use the generic Linux installer script, you should be able to access your host and logs as per your host.
## Debug Supervisor
Visual Studio Code config:
```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Hass.io remote debug",
"type": "python",
"request": "attach",
"port": 33333,
"host": "IP",
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/usr/src/hassio"
}
]
}
]
}
```
You need set the dev mode on supervisor and enable debug with options. You need also install the Remote debug Add-on from Developer Repository to expose the debug port to Host.
## SSH access to the host
> SSH access through the [SSH add-on] (which will give you SSH access through port 22) will not provide you with all the necessary privileges, and you will be asked for a username and password when typing the 'login' command. You need to follow the steps below, which will setup a separate SSH access through port 22222 with all necessary privileges.
### resinOS based Hass.io (deprecated)
Create an `authorized_keys` file containing your public key, and place it in the root of the boot partition of your SD card. See [Generating SSH Keys](#generating-ssh-keys) section below if you need help generating keys. Once the device is booted, you can access your device as root over SSH on port 22222.
### HassOS based Hass.io
Use a USB drive formatted with FAT, ext4, or NTFS and name it CONFIG (case sensitive). Create an `authorized_keys` file (no extension) containing your public key, and place it in the root of the USB drive. File needs to be ANSI encoded (not UTF-8) and must have Unix line ends (LF), not Windows (CR LF). See [Generating SSH Keys](#generating-ssh-keys) section below if you need help generating keys. From the UI, navigate to the hass.io system page and choose "Import from USB". You can now access your device as root over SSH on port 22222. Alternatively, the file will be imported from the USB when the hass.io device is rebooted.
> Make sure when you are copying the public key to the root of the USB drive that you rename the file correctly to `authorized_keys` with no `.pub` file extension.
You should then be able to SSH into your Hass.io device. On Mac/Linux, use:
```
ssh root@hassio.local -p 22222
```
You will initially be logged in to Hass.io CLI for HassOS where you can perform normal [CLI functions]. If you need access to the host system use the 'login' command. [Hass.io OS] is a hypervisor for Docker. See the [Hass.io Architecture] documentation for information regarding the Hass.io supervisor. The supervisor offers an API to manage the host and running the Docker containers. Home Assistant itself and all installed addon's run in separate Docker containers.
[CLI functions]: https://www.home-assistant.io/hassio/commandline/
[Hass.io OS]: https://github.com/home-assistant/hassos
[Hass.io Architecture]: https://developers.home-assistant.io/docs/en/architecture_hassio.html
## Checking the logs
```bash
# Logs from the supervisor service on the Host OS
journalctl -f -u hassos-supervisor.service
# Hass.io supervisor logs
docker logs hassos_supervisor
# Home Assistant logs
docker logs homeassistant
```
## Accessing the container bash
```bash
docker exec -it homeassistant /bin/bash
```
[windows-keys]: https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-putty-on-digitalocean-droplets-windows-users
### Generating SSH Keys
Windows instructions for how to generate and use private/public keys with Putty are [here][windows-keys]. Instead of the droplet instructions, add the public key as per above instructions.
Alternative instructions, for Mac, Windows and Linux can be found [here](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/#platform-mac).
Follow steps 1-4 under 'Generating a new SSH key' (The other sections are not applicable to Hass.io and can be ignored.)
Step 3 in the link above, shows the path to the private key file `id_rsa` for your chosen operating system. Your public key, `id_rsa.pub`, is saved in the same folder. Next, select all text from text box "Public key for pasting into the authorized_keys file" and save it to the root of your USB drive as `authorized_keys`.

View File

@ -1,4 +1,5 @@
[ [
"0.95.0",
"0.94.0", "0.94.0",
"0.93.0", "0.93.0",
"0.92.1", "0.92.1",