This commit is contained in:
Fabian Affolter 2019-04-25 09:28:21 +02:00 committed by GitHub
parent 8db47da494
commit e1d2539e4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1788 additions and 0 deletions

View File

@ -0,0 +1,85 @@
---
title: Connecting to an instance
id: version-0.92.0-app_integration_setup
original_id: app_integration_setup
---
When a user first opens the app, they will need to connect to their local instance to authenticate and register the device.
## Authenticating the user
The local instance can be discovered if Home Assistant has the [zeroconf component] configured by searching for `_home-assistant._tcp.local.`. If not configured, the user will need to be asked for the local address of their instance.
When the address of the instance is known, the app will ask the user to authenticate via [OAuth2 with Home Assistant]. Home Assistant uses IndieAuth, which means that to be able to redirect to a url that triggers your app, you need to take some extra steps. Make sure to read the last paragraph of the "Clients" section thoroughly.
[zeroconf component]: https://www.home-assistant.io/components/zeroconf
[OAuth2 with Home Assistant]: auth_api.md
## Registering the device
_This requires Home Assistant 0.90 or later._
Home Assistant has a `mobile_app` component that allows applications to register themselves and interact with the instance. This is a generic component to handle most common mobile application tasks. This component is extendable with custom interactions if your app needs more types of interactions than are offered by this component.
Once you have tokens to authenticate as a user, it's time to register the app with the mobile app component in Home Assistant.
### Getting Ready
First, you must ensure that the `mobile_app` component is loaded. There are two ways to do this:
- You can publish a Zeroconf/Bonjour record `_hass-mobile-app._tcp.local.` to trigger the automatic load of the `mobile_app` component. You should wait at least 60 seconds after publishing the record before continuing.
- You can ask the user to add `mobile_app` to their configuration.yaml and restart Home Assistant. If the user already has `default_config` in their configuration, then `mobile_app` will have been already loaded.
You can confirm the `mobile_app` component has been loaded by checking the `components` array of the [`/api/config` REST API call](external_api_rest.md#get-api-config). If you continue to device registration and receive a 404 status code, then it most likely hasn't been loaded yet.
### Registering the device
To register the device, make an authenticated POST request to `/api/mobile_app/registrations`. [More info on making authenticated requests.](auth_api.md#making-authenticated-requests)
Example payload to send to the registration endpoint:
```json
{
"app_id": "awesome_home",
"app_name": "Awesome Home",
"app_version": "1.2.0",
"device_name": "Robbies iPhone",
"manufacturer": "Apple, Inc.",
"model": "iPhone X",
"os_version": "iOS 10.12",
"supports_encryption": true,
"app_data": {
"push_notification_key": "abcdef",
}
}
```
| Key | Required | Type | Description |
| --- | -------- | ---- | ----------- |
| `app_id` | V | string | A unique identifier for this app.
| `app_name` | V | string | Name of the mobile app.
| `app_version` | V | string | Version of the mobile app.
| `device_name` | V | string | Name of the device running the app.
| `manufacturer` | V | string | The manufacturer of the device running the app.
| `model` | V | string | The model of the device running the app.
| `os_version` | V | string | The OS version of the device running the app.
| `supports_encryption` | V | bool | If the app supports encryption. See also the [encryption section](#encryption).
| `app_data` | | Dict | App data can be used if the app has a supporting component that extends `mobile_app` functionality.
When you get a 200 response, the mobile app is registered with Home Assistant. The response is a JSON document and will contain the URLs on how to interact with the Home Assistant instance. You should permanently store this information.
```json
{
"cloudhook_url": "https://hooks.nabu.casa/randomlongstring123",
"remote_ui_url": "https://randomlongstring123.ui.nabu.casa",
"secret": "qwerty",
"webhook_id": "abcdefgh"
}
```
| Key | Type | Description
| --- | ---- | -----------
| `cloudhook_url` | string | The cloudhook URL provided by Home Assistant Cloud. Only will be provided if user is actively subscribed to Nabu Casa.
| `remote_ui_url` | string | The remote UI URL provided by Home Assistant Cloud. Only will be provided if user is actively subscribed to Nabu Casa.
| `secret` | string | The secret to use for encrypted communication. Will only be included if encryption is supported by both the app and the Home Assistant instance. [More info](app_integration_sending_data.md#implementing-encryption).
| `webhook_id` | string | The webhook ID that can be used to send data back.

View File

@ -0,0 +1,67 @@
---
title: Multi-factor Authentication Modules
id: version-0.92.0-auth_auth_module
original_id: auth_auth_module
---
Multi-factor Authentication Modules are used in conjunction with [Authentication Provider](auth_auth_provider.html) to provide a fully configurable authentication framework. Each MFA module may provide one multi-factor authentication function. User can enable multiple mfa modules, but can only select one module in login process.
## Defining an mfa auth module
> We currently only support built-in mfa auth modules. Support for custom auth modules might arrive in the future.
Multi-factor Auth modules are defined in `homeassistant/auth/mfa_modules/<name of module>.py`. The auth module will need to provide an implementation of the `MultiFactorAuthModule` class.
For an example of a fully implemented auth module, please see [insecure_example.py](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/auth/mfa_modules/insecure_example.py).
Multi-factor Auth modules shall extend the following methods of `MultiFactorAuthModule` class.
| method | Required | Description
| ------ | -------- | -----------
| `@property def input_schema(self)` | Yes | Return a schema defined the user input form.
| `async def async_setup_flow(self, user_id)` | Yes | Return a SetupFlow to handle the setup workflow.
| `async def async_setup_user(self, user_id, setup_data)` | Yes | Set up user for use this auth module.
| `async def async_depose_user(self, user_id)` | Yes | Remove user information from this auth module.
| `async def async_is_user_setup(self, user_id)` | Yes | Return whether user is set up.
| `async def async_validate(self, user_id, user_input)` | Yes | Given a user_id and user input, return validation result.
| `async def async_initialize_login_mfa_step(self, user_id)` | No | Will be called once before display the mfa step of login flow. This is not initialization for the MFA module but the mfa step in login flow.
## Setup Flow
Before user can use a multi-factor auth module, it has to be enabled or set up. All available modules will be listed in user profile page, user can enable the module he/she wants to use. A setup data entry flow will guide user finish the necessary steps.
Each MFA module need to implement a setup flow handler extends from `mfa_modules.SetupFlow` (if only one simple setup step need, `SetupFlow` can be used as well). For example for Google Authenticator (TOTP, Time-based One Time Password) module, the flow will need to be:
- Generate a secret and store it on instance of setup flow
- Return `async_show_form` with a QR code in the description (injected as base64 via `description_placeholders`)
- User scans code and enters a code to verify it scanned correctly and clock in synced
- TOTP module saved the secret along with user_id, module is enabled for user
## Workflow
![Multi Factor Authentication Workflow](/img/en/auth/mfa_workflow.png)
<!--
Source: https://drive.google.com/file/d/12_nANmOYnOdqM56BND01nPjJmGXe-M9a/view
-->
## Configuration example
```yaml
# configuration.xml
homeassistant:
auth_providers:
- type: homeassistant
- type: legacy_api_password
auth_mfa_modules:
- type: totp
- type: insecure_example
users: [{'user_id': 'a_32_bytes_length_user_id', 'pin': '123456'}]
```
In this example, user will first select from `homeassistant` or `legacy_api_password` auth provider. For `homeassistant` auth provider, user will first input username/password, if that user enabled both `totp` and `insecure_example`, then user need select one auth module, then input Google Authenticator code or input pin code base on the selection.
> insecure_example is only for demo purpose, please do not use it in production.
## Validation session
Not like auth provider, auth module use session to manage the validation. After auth provider validated, mfa module will create a validation session, include an experiation time and user_id from auth provider validate result. Mutli-factor auth module will not only verify the user input, but also verify the session is not expired. The validation session data is stored in your configuration directory.

View File

@ -0,0 +1,79 @@
---
title: Integration Manifest
sidebar_label: Manifest
id: version-0.92.0-creating_integration_manifest
original_id: creating_integration_manifest
---
Since 0.92.0, every integration has a manifest file to specify basic information about an integration. This file is stored as `manifest.json` in your integration directory. It is required to add such a file, including for custom components.
```json
{
"domain": "hue",
"name": "Philips Hue",
"documentation": "https://www.home-assistant.io/components/hue",
"dependencies": ["mqtt"],
"codeowners": ["@balloob"],
"requirements": ["aiohue==1.9.1"]
}
```
Or a minimal example that you can copy into your project:
```json
{
"domain": "your_domain_name",
"name": "Your Intgration",
"documentation": "https://www.example.com",
"dependencies": [],
"codeowners": [],
"requirements": []
}
```
## Domain
The domain is a short name consisting of characters and underscores. This domain has to be unique and cannot be changed. Example of the domain for the mobile app integration: `mobile_app`.
## Name
The name of the integration.
## Documentation
The website containing documentation on how to use your integration. If this integration is being submitted for inclusion in Home Assistant, it should be `https://www.home-assistant.io/components/<domain>`
## Dependencies
Dependencies are other Home Assistant integrations that you want Home Assistant to set up successfully prior to the integration being loaded. This can be necessary in case you want to offer functionality from that other integration, like using webhooks or an MQTT connection.
## Code Owners
GitHub usernames or team names of people that are responsible for this integration. You should add at least your GitHub username here, as well as anyone who helped you to write code that is being included.
## Requirements
Requirements are Python libraries or modules 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](https://www.home-assistant.io/docs/configuration/) if you are not using a `venv` or in something like `path/to/venv/lib/python3.6/site-packages` if you running in a virtual environment. This will make sure that all requirements are present at startup. If steps fail, like missing packages for the compilation of a module or other install errors, the component will fail to load.
Requirements is an array of strings. Each entry is a `pip` compatible string. For example, the media player Cast platform depends on the Python package PyChromecast v3.2.0: `["pychromecast==3.2.0"]`.
> Because of how Home Assistant installs requirements on demand, actual Python imports of your requirements should be done inside functions instead of at the root level of your Python files.
### Custom requirements during development & testing
During the development of a component, it can be useful to test against different versions of a requirement. This can be done in two steps, using `pychromecast` as an example:
```bash
pip install pychromecast==3.2.0 --target ~/.homeassistant/deps
hass --skip-pip
```
This will use the specified version, and prevent Home Assistant from trying to override it with what is specified in `requirements`.
If you need to make changes to a requirement to support your component, it's also possible to install a development version of the requirement using `pip install -e`:
```bash
git clone https://github.com/balloob/pychromecast.git
pip install -e ./pychromecast
hass --skip-pip
```

View File

@ -0,0 +1,23 @@
---
title: Integration Platforms
sidebar_label: Platforms
id: version-0.92.0-creating_platform_index
original_id: creating_platform_index
---
Home Assistant has various built-in integrations that abstract device types. There are [lights](entity_light.md), [switches](entity_switch.md), [covers](entity_cover.md), [climate devices](entity_climate.md), and [many more](entity_index.md). Your integration can hook into these integrations by creating a platform. You will need a platform for each integration that you are integrating with.
To create a platform, you will need to create a file with the domain name of the integration that you are building a platform for. So if you are building a light, you will add a new file `light.py` to your integration folder.
We have created two example integrations that should give you a look at how this works:
- [Example sensor platform](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_sensor/): hello world of platforms.
- [Example light platform](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_light/): showing best practices.
### Interfacing with devices
One Home Assistant rule is that the integration should never interface directly with devices. Instead, it should interact with a third-party Python 3 library. This way, Home Assistant can share code with the Python community and keep the project maintainable.
Once you have your Python library ready and published to PyPI, add it to the [manifest](creating_integration_manifest.md). It will now be time to implement the Entity base class that is provided by the integration that you are creating a platform for.
Find your integration at the [entity index](entity_index.md) to see what methods and properties are available to implement.

View File

@ -0,0 +1,44 @@
---
title: Submit your work
id: version-0.92.0-development_submitting
original_id: development_submitting
---
> Always base your Pull Requests of of the current **`dev`** branch, not `master`.
Submit your improvements, fixes, and new features to Home Assistant one at a time, using GitHub [Pull Requests](https://help.github.com/articles/using-pull-requests). Here are the steps:
1. From your fork's dev branch, create a new branch to hold your changes:
`git checkout -b some-feature`
2. Make your changes, create a [new platform](creating_platform_index.md), develop a [new component](creating_component_index.md), or fix [issues](https://github.com/home-assistant/home-assistant/issues).
3. [Test your changes](development_testing.md) and check for style violations.
4. If everything looks good according to these [musts](development_checklist.md), commit your changes:
`git add .`
`git commit -m "Add some-feature"`
* Write a meaningful commit message and not only `Update` or `Fix`.
* Use a capital letter to start with your commit message.
* Don't prefix your commit message with `[bla.bla]` or `platform:`.
* Consider adding tests to ensure that your code works.
5. Push your committed changes back to your fork on GitHub:
`git push origin HEAD`
6. Follow [these steps](https://help.github.com/articles/creating-a-pull-request/) to create your pull request.
* On GitHub, navigate to the main page of the Home Assistant repository.
* In the "Branch" menu, choose the branch that contains your commits (from your fork).
* To the right of the Branch menu, click **New pull request**.
* Use the base branch dropdown menu to select the branch you'd like to merge your changes into, then use the compare branch drop-down menu to choose the topic branch you made your changes in. Make sure the Home Assistant branch matches with your forked branch (`dev`) else you will propose ALL commits between branches.
* Type a title and complete the provided description for your pull request.
* Click **Create pull request**.
7. Check for comments and suggestions on your pull request and keep an eye on the [CI output](https://travis-ci.org/home-assistant/home-assistant/).

View File

@ -0,0 +1,233 @@
---
title: Climate Entity
sidebar_label: Climate
id: version-0.92.0-entity_climate
original_id: entity_climate
---
> A climate entity is a device that controls temperature, humidity, or fans, such as A/C systems and humidifiers. Derive entity platforms from [`homeassistant.components.climate.ClimateDevice`](https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/climate/__init__.py)
## Properties
> Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
| Name | Type | Default | Description
| ---- | ---- | ------- | -----------
| current_fan_mode | string | None | Returns the current fan mode.
| current_hold_mode | string | None | The current hold mode, e.g., home, away, temp.
| current_humidity | float | None | The current humidity.
| current_operation | string | None | The current operation (e.g. heat, cool, idle). Used to determine `state`.
| current_swing_mode | string | None | Returns the fan setting.
| current_temperature | float | None | The current temperature.
| fan_list | list | None | Returns the list of available fan modes.
| is_aux_heat_on | bool | None | Returns True if an auxiliary heater is on.
| is_away_mode_on | bool | None | Return true if away mode is on.
| is_on | bool | None | Returns True if device is on. Used to determine `state`.
| max_humidity | int | `DEFAULT_MAX_HUMIDITY` (value == 99) | Returns the maximum humidity.
| max_temp | int | `DEFAULT_MAX_TEMP` (value == 35) | Returns the maximum temperature.
| min_humidity | int | `DEFAULT_MIN_HUMIDITY` (value == 30) | Returns the minimum humidity.
| min_temp | int | `DEFAULT_MIN_TEMP` (value == 7) | Returns the minimum temperature.
| operation_list | list | None | List of available operation modes.
| precision | float | PRECISION_WHOLE | The precision of the temperature in the system: tenths for TEMP_CELSIUS, whole number otherwise.
| state | string | None | Returns the current state.
| state_attributes | dictionary | N/A | The optional state attributes: current temperature, minimum temperature, maximum temperature, and target temperature.
| supported_features | list | `NotImplementedError()` | Returns list of supported features.
| swing_list | list | None | Returns the list of available swing modes.
| target_humidity | float | None | The target humidity.
| target_temperature | float | None | The temperature currently set to be reached.
| target_temperature_high | float | None | The upper bound target temperature
| target_temperature_low | float | None | The lower bound target temperature
| target_temperature_step | float | None | The supported step of target temperature
| temperature_unit | string | `NotImplementedError` | The unit of temperature measurement for the system (e.g. Celsius).
### States
| Name | Description
| ---- | -----------
| STATE_HEAT | The device is set to heat.
| STATE_COOL | The device is set to cool.
| STATE_IDLE | The device is idle.
| STATE_AUTO | The device is set to auto.
| STATE_MANUAL | The device is set to manual.
| STATE_DRY | The device is set to dry.
| STATE_FAN_ONLY | The device is set to fan-only.
| STATE_ECO | The device is set to eco-mode.
### Supported features
Supported features constants are combined using the bitwise or (`|`) operator.
| Name | Description
| ---- | -----------
| SUPPORT_TARGET_TEMPERATURE | The device supports a target temperature.
| SUPPORT_TARGET_TEMPERATURE_HIGH | The device supports an upper bound target temperature.
| SUPPORT_TARGET_TEMPERATURE_LOW | The device supports a lower bound target temperature.
| SUPPORT_TARGET_HUMIDITY | The device supports a target humidity.
| SUPPORT_TARGET_HUMIDITY_HIGH | The device supports an upper bound target humidity.
| SUPPORT_TARGET_HUMIDITY_LOW | The device supports a lower bound target humidity.
| SUPPORT_FAN_MODE | The device supports fan modes.
| SUPPORT_OPERATION_MODE | The device supports operation modes.
| SUPPORT_HOLD_MODE | The device supports hold modes.
| SUPPORT_SWING_MODE | The device supports swing modes.
| SUPPORT_AWAY_MODE | The device supports away mode.
| SUPPORT_AUX_HEAT | The device supports auxiliary heaters.
| SUPPORT_ON_OFF | The device supports on/off states.
## Methods
### Set fan mode
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def set_fan_mode(self, fan_mode):
"""Set new target fan mode."""
async def async_set_fan_mode(self, fan_mode):
"""Set new target fan mode."""
```
### Set hold mode
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def set_hold_mode(self, hold_mode):
"""Set new target hold mode."""
async def async_set_hold_mode(self, hold_mode):
"""Set new target hold mode."""
```
### Set humidity
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def set_humidity(self, humidity):
"""Set new target humidity."""
async def async_set_humidity(self, humidity):
"""Set new target humidity."""
```
### Set operation mode
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def set_operation_mode(self, operation_mode):
"""Set new target operation mode."""
async def async_set_operation_mode(self, operation_mode):
"""Set new target operation mode."""
```
### Set swing mode
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def set_swing_mode(self, swing_mode):
"""Set new target swing operation."""
async def async_set_swing_mode(self, swing_mode):
"""Set new target swing operation."""
```
### Set temperature
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def set_temperature(self, **kwargs):
"""Set new target temperature."""
async def async_set_temperature(self, **kwargs):
"""Set new target temperature."""
```
### Turn auxiliary heater on
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def turn_aux_heat_on(self):
"""Turn auxiliary heater on."""
async def async_turn_aux_heat_on(self):
"""Turn auxiliary heater on."""
```
### Turn auxiliary heater off
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def turn_aux_heat_off(self):
"""Turn auxiliary heater off."""
async def async_turn_aux_heat_off(self):
"""Turn auxiliary heater off."""
```
### Turn away mode on
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def turn_away_mode_on(self):
"""Turn away mode on."""
async def async_turn_away_mode_on(self):
"""Turn away mode on."""
```
### Turn away mode off
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def turn_away_mode_off(self):
"""Turn away mode off."""
async def async_turn_away_mode_off(self):
"""Turn away mode off."""
```
### Turn the device on
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def turn_on(self):
"""Turn device on."""
async def async_turn_on(self):
"""Turn device on."""
```
### Turn the device off
```python
class MyClimateDevice(ClimateDevice):
# Implement one of these methods.
def turn_off(self):
"""Turn device off."""
async def async_turn_off(self):
"""Turn device off."""
```

View File

@ -0,0 +1,98 @@
---
title: Fan Entity
sidebar_label: Fan
id: version-0.92.0-entity_fan
original_id: entity_fan
---
A fan entity is a device that controls the different vetors of your fan susch as speed, direction and oscillation. Derive enitity platforms from ['homeassistant.components.fan.FanDevice'](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/fan/__init__.py).
## Properties
> Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
| Name | Type | Default | Description
| ---- | ---- | ------- | -----------
| current_direction | str | None | Return the current direction of the fan |
|is_on| boolean | None |Return true if the entity is on |
| speed | str | None | Return the current speed |
| speed_list | list | None| Get the list of available speeds |
| state_attributes | dict | None | Return optional state attributes |
| supported_features | int | None | Flag supported features |
## Supported Features
| Constant | Description |
|----------|--------------------------------------|
| 'SUPPORT_DIRECTION' | The fan supports changing the direction of it.
| 'SUPPORT_SET_SPEED' | The fan supports setting the speed.
| 'SUPPORT_OSCILLATE' | The fan supports oscillation.
## Methods
### Set direction
Only implement this method if the flag `SUPPORT_DIRECTION` is set.
```python
class FanEntity(ToggleEntity):
# Implement one of these methods.
def set_direction(self, direction: str) -> None:
"""Set the direction of the fan."""
async def async_set_direction(self, direction: str):
"""Set the direction of the fan."""
```
### Set speed
Only implement this method if the flag `SUPPORT_SET_SPEED` is set.
```python
class FanEntity(ToggleEntity):
# Implement one of these methods.
def set_speed(self, speed: str) -> None:
"""Set the speed of the fan."""
async def async_set_speed(self, speed: str):
"""Set the speed of the fan."""
```
### Turn on
```python
class FanEntity(ToggleEntity):
# Implement one of these methods.
def turn_on(self, speed: str = None, **kwargs) -> None:
"""Turn on the fan."""
async def async_turn_on(self, speed: str = None, **kwargs):
"""Turn on the fan."""
```
### Oscillate
Only implement this method if the flag `SUPPORT_OSCILLATE` is set.
```python
class FanEntity(ToggleEntity):
# Implement one of these methods.
def oscillate(self, oscillating: bool) -> None:
"""Oscillate the fan."""
def async_oscillate(self, oscillating: bool):
"""Oscillate the fan."""
```

View File

@ -0,0 +1,69 @@
---
title: Media Player Entity
sidebar_label: Media Player
id: version-0.92.0-entity_media_player
original_id: entity_media_player
---
> This entry is incomplete. Contribution welcome.
## Properties
> Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
| Name | Type | Default | Description
| ---- | ---- | ------- | -----------
| sound_mode | string | None | The current sound mode of the media player
| sound_mode_list | list | None | Dynamic list of available sound modes (set by platform, empty means sound mode not supported)
| source | string | None | The currently selected input source for the media player.
| source_list | list | None | The list of possible input sources for the media player. (This list should contain human readable names, suitible for frontend display)
| media_image_url | string | None | URL that represents the current image.
| media_image_remotely_accessible | boolean | False | Return `True` if property `media_image_url` is accessible outside of the home network.
## Methods
### Select sound mode
Optional. Switch the sound mode of the media player.
class MyMediaPlayer(MediaPlayerDevice):
# Implement one of these methods.
def select_sound_mode(self, sound_mode):
"""Switch the sound mode of the entity."""
def async_select_sound_mode(self, sound_mode):
"""Switch the sound mode of the entity."""
### Select source
Optional. Switch the selected input source for the media player.
class MyMediaPlayer(MediaPlayerDevice):
# Implement one of these methods.
def select_source(self, source):
"""Select input source."""
def async_select_source(self, source):
"""Select input source."""
### Mediatype
Required. Returns one of the defined constants from the below list that matches the mediatype
| CONST |
|-------|
|MEDIA_TYPE_MUSIC|
|MEDIA_TYPE_TVSHOW|
|MEDIA_TYPE_MOVIE|
|MEDIA_TYPE_VIDEO|
|MEDIA_TYPE_EPISODE|
|MEDIA_TYPE_CHANNEL|
|MEDIA_TYPE_PLAYLIST|
|MEDIA_TYPE_IMAGE|
|MEDIA_TYPE_URL|
|MEDIA_TYPE_GAME|
class MyMediaPlayer(MediaPlayerDevice):
# Implement the following method.
def media_content_type(self):
"""Content type of current playing media."""

View File

@ -0,0 +1,24 @@
---
title: Entity Registry
sidebar_label: Introduction
id: version-0.92.0-entity_registry_index
original_id: entity_registry_index
---
The entity registry is a registry where Home Assistant keeps track of entities. Any entity that is added to Home Assistant and has a unique ID will be registered in the registry.
Being registered has the advantage that the same entity will always get the same entity ID. It will also prevent other entities from using that entity ID.
A user is also able to override the name of an entity in the entity registry. When set, the name of the entity registry is used in favor of the name the device might give itself.
## Unique ID requirements
An entity is looked up in the registry based on a combination of the plaform type (e.g., `light`), and the integraion name (domain) (ie hue) and the unique ID of the entity. It is therefore very important that the unique ID is unique! It is also important that it is not possible for the user to change the unique ID, because that means it will lose all its settings related to it.
Good sources for a unique ID:
- Serial number of a device
- MAC address of a device
- latitude/longitude
If a device has a single serial but provides multiple entities, combine the serial with unique identifiers for the entities. For example, if a device measures both temperature and humidity, you can uniquely identify the entities using `{serial}-{sensor_type}`.

View File

@ -0,0 +1,436 @@
---
title: WebSocket API
id: version-0.92.0-external_api_websocket
original_id: external_api_websocket
---
Home Assistant contains a WebSocket API. This API can be used to stream information from a Home Assistant instance to any client that implements WebSockets. Implementations in different languages:
- [JavaScript](https://github.com/home-assistant/home-assistant-js-websocket) - powers the frontend
- [Python](https://raw.githubusercontent.com/home-assistant/home-assistant-dev-helper/master/ha-websocket-client.py) - CLI client using [`asyncws`](https://async-websockets.readthedocs.io/en/latest/)
- [JavaScript/HTML](https://raw.githubusercontent.com/home-assistant/home-assistant-dev-helper/master/ha-websocket.html) - WebSocket connection in your browser
Connect your websocket implementation to `ws://localhost:8123/api/websocket`. You will need a valid access token.
If you are not using the [`frontend`](https://www.home-assistant.io/components/frontend/) in your setup then you need to add the [`websocket_api` component](https://www.home-assistant.io/components/websocket_api/) to your `configuration.yaml` file to use the WebSocket API.
## Server states
1. Client connects.
1. Authentication phase starts.
- Server sends `auth_required` message.
- Client sends `auth` message.
- If `auth` message correct: go to 3.
- Server sends `auth_invalid`. Go to 6.
1. Send `auth_ok` message
1. Authentication phase ends.
1. Command phase starts.
1. Client can send commands.
1. Server can send results of previous commands.
1. Client or server disconnects session.
During the command phase, the client attaches a unique identifier to each message. The server will add this identifier to each message so that the client can link each message to its origin.
## Message format
Each API message is a JSON serialized object containing a `type` key. After the authentication phase messages also must contain an `id`, an integer that contains the number of interactions.
Example of an auth message:
```json
{
"type": "auth",
"access_token": "ABCDEFGHIJKLMNOPQ"
}
```
```json
{
"id": 5,
"type":"event",
"event":{
"data":{},
"event_type":"test_event",
"time_fired":"2016-11-26T01:37:24.265429+00:00",
"origin":"LOCAL"
}
}
```
## Authentication phase
When a client connects to the server, the server will test if the client is authenticated. Authentication will not be necessary if no api_password is set or if the user fulfills one of the other criteria for authentication (trusted network, password in url/header).
If no authentication is needed, the authentication phase will complete and the server will send an `auth_ok` message.
```json
{
"type": "auth_ok"
}
```
If authentication is necessary, the server sends out `auth_required`.
```json
{
"type": "auth_required"
}
```
This means that the next message from the client should be an auth message. You can authorize with an access token.
```json
{
"type": "auth",
"access_token": "ABCDEFGH"
}
```
For now, we also support authentication with an API password (legacy auth).
```json
{
"type": "auth",
"api_password": "supersecret"
}
```
If the client supplies valid authentication, the authentication phase will complete by the server sending the `auth_ok` message:
```json
{
"type": "auth_ok"
}
```
If the data is incorrect, the server will reply with `auth_invalid` message and disconnect the session.
```json
{
"type": "auth_invalid",
"message": "Invalid password"
}
```
## Command phase
During this phase the client can give commands to the server. The server will respond to each command with a `result` message indicating when the command is done and if it was successful.
```json
{
"id": 6,
"type": "result",
"success": true,
// Can contain extra result info
"result": null
}
```
## Subscribe to events
The command `subscribe_events` will subscribe your client to the event bus. You can either listen to all events or to a specific event type. If you want to listen to multiple event types, you will have to send multiple `subscribe_events` commands.
```json
{
"id": 18,
"type": "subscribe_events",
// Optional
"event_type": "state_changed"
}
```
The server will respond with a result message to indicate that the subscription is active.
```json
{
"id": 18,
"type": "result",
"success": true,
"result": null
}
```
For each event that matches, the server will send a message of type `event`. The `id` in the message will point at the original `id` of the `listen_event` command.
```json
{
"id": 18,
"type":"event",
"event":{
"data":{
"entity_id":"light.bed_light",
"new_state":{
"entity_id":"light.bed_light",
"last_changed":"2016-11-26T01:37:24.265390+00:00",
"state":"on",
"attributes":{
"rgb_color":[
254,
208,
0
],
"color_temp":380,
"supported_features":147,
"xy_color":[
0.5,
0.5
],
"brightness":180,
"white_value":200,
"friendly_name":"Bed Light"
},
"last_updated":"2016-11-26T01:37:24.265390+00:00"
},
"old_state":{
"entity_id":"light.bed_light",
"last_changed":"2016-11-26T01:37:10.466994+00:00",
"state":"off",
"attributes":{
"supported_features":147,
"friendly_name":"Bed Light"
},
"last_updated":"2016-11-26T01:37:10.466994+00:00"
}
},
"event_type":"state_changed",
"time_fired":"2016-11-26T01:37:24.265429+00:00",
"origin":"LOCAL"
}
}
```
### Unsubscribing from events
You can unsubscribe from previously created subscription events. Pass the id of the original subscription command as value to the subscription field.
```json
{
"id": 19,
"type": "unsubscribe_events",
"subscription": 18
}
```
The server will respond with a result message to indicate that unsubscribing was successful.
```json
{
"id": 19,
"type": "result",
"success": true,
"result": null
}
```
## Calling a service
This will call a service in Home Assistant. Right now there is no return value. The client can listen to `state_changed` events if it is interested in changed entities as a result of a service call.
```json
{
"id": 24,
"type": "call_service",
"domain": "light",
"service": "turn_on",
// Optional
"service_data": {
"entity_id": "light.kitchen"
}
}
```
The server will indicate with a message indicating that the service is done executing.
```json
{
"id": 24,
"type": "result",
"success": true,
"result": null
}
```
## Fetching states
This will get a dump of all the current states in Home Assistant.
```json
{
"id": 19,
"type": "get_states"
}
```
The server will respond with a result message containing the states.
```json
{
"id": 19,
"type": "result",
"success": true,
"result": [ ... ]
}
```
## Fetching config
This will get a dump of the current config in Home Assistant.
```json
{
"id": 19,
"type": "get_config"
}
```
The server will respond with a result message containing the config.
```json
{
"id": 19,
"type": "result",
"success": true,
"result": { ... }
}
```
## Fetching services
This will get a dump of the current services in Home Assistant.
```json
{
"id": 19,
"type": "get_services"
}
```
The server will respond with a result message containing the services.
```json
{
"id": 19,
"type": "result",
"success": true,
"result": { ... }
}
```
## Fetching panels
This will get a dump of the current registered panels in Home Assistant.
```json
{
"id": 19,
"type": "get_panels"
}
```
The server will respond with a result message containing the current registered panels.
```json
{
"id": 19,
"type": "result",
"success": true,
"result": [ ... ]
}
```
## Fetching camera thumbnails
_Introduced in Home Assistant 0.69._
Return a b64 encoded thumbnail of a camera entity.
```json
{
"id": 19,
"type": "camera_thumbnail"
}
```
The server will respond with a result message containing the thumbnail.
```json
{
"id": 19,
"type": "result",
"success": true,
"result": {
"content_type": "image/jpeg",
"content": "<base64 encoded image>"
}
}
```
## Fetching media player thumbnails
_Introduced in Home Assistant 0.69._
Fetch a base64 encoded thumbnail picture for a media player.
```json
{
"id": 19,
"type": "media_player_thumbnail",
"entity_id": "media_player.living_room"
}
```
The server will respond with the image encoded via base64.
```json
{
"id": 19,
"type": "result",
"success": true,
"result": {
"content_type": "image/jpeg",
"content": "<base64 encoded image>"
}
}
```
## Pings and Pongs
The API supports receiving a ping from the client and returning a pong. This serves as a heartbeat to ensure the connection is still alive:
```json
{
"id": 19,
"type": "ping"
}
```
The server must send a pong back as quickly as possible, if the connection is still active:
```json
{
"id": 19,
"type": "pong"
}
```
## Error handling
If an error occurs, the `success` key in the `result` message will be set to `false`. It will contain an `error` key containing an object with two keys: `code` and `message`.
| Code | Description |
| ----- | ------------ |
| 1 | A non-increasing identifier has been supplied.
| 2 | Received message is not in expected format (voluptuous validation error).
| 3 | Requested item cannot be found
```json
{
"id": 12,
"type":"result",
"success": false,
"error": {
"code": 2,
"message": "Message incorrectly formatted: expected str for dictionary value @ data['event_type']. Got 100"
}
}
```

View File

@ -0,0 +1,46 @@
---
title: Add-On Communication
id: version-0.92.0-hassio_addon_communication
original_id: hassio_addon_communication
---
There are different ways for communication between add-ons inside Hass.io.
## Network
We use an internal network that allows to communicate with every add-on, even to/from Home Assistant, by using its name or alias. Only the add-ons which run on the host network are a bit limited. These can talk with all internal add-ons by their name but all other add-on can't address these add-on by name - using an alias works for both!
Name/alias are used for communication inside Hass.io.
The name is generated using the following format: `{REPO}_{SLUG}`, e.g., `local_xy` or `3283fh_myaddon`. In this example, `{SLUG}` is defined in an add-ons `config.json`. You can use this name also as DNS name but you need replace the `_` with `-` to have a valid hostname. If an add-on is installed locally, `{REPO}` will be `local`. If the add-on is installed from a Github repository, `{REPO}` is a hashed identifier generated from the GitHub repository's URL (ex: https://github.com/xy/my_hassio_addons). See [here](https://github.com/home-assistant/hassio/blob/587047f9d648b8491dc8eef17dc6777f81938bfd/hassio/addons/utils.py#L17) to understand how this identifier is generated. Note that this identifier is required in certain service calls that use the [Hass.io add-on API][hassio-addon-api]. You can view the repository identifiers for all currently installed add-ons via a GET request to the hassio API `addons` endpoint.
Use `hassio` for communication with the internal API.
## Home Assistant
An add-on can talk to the [Home Assistant API][hass-api] using the internal proxy. That makes it very easy to communicate with the API without knowing the password, port or any other information of the Home Assistant instance. Use this URL: `http://hassio/homeassistant/api` and internal communication is redirected to the right place. The next stept is to add `homeassistant_api: true` to `config.json` and read the environment variable `HASSIO_TOKEN` and use this as Home-Assistant password.
There is also a proxy for the [Home Assistant Websocket API][hass-websocket]. It works like the API proxy above and requires `HASSIO_TOKEN` as password. Use this URL: `http://hassio/homeassistant/websocket`.
It is also possible to talk direct to the Home Assistant instance which is named `homeassistant` over the internal network. But you need to know the configuration that is used by the running instance.
We have severals services for Hass.io inside Home Assistant to run tasks. To send data over STDIN to an add-on use the `hassio.addon_stdin` service.
## Hass.io API
To enables calls to the [Hass.io API][hassio-api], add `hassio_api: true` to `config.json` and read the environment variable `HASSIO_TOKEN`. Now you can use the API over the URL: `http://hassio/`. Use the `HASSIO_TOKEN` with header `X-HASSIO-KEY`. It could be that you need also change the Hass.io API role like `hassio_role: default`.
Add-ons can call some API commands without need set `hassio_api: true`:
- `/homeassistant/api`
- `/homeassistant/api/stream`
- `/homeassistant/websocket`
- `/addons/self/*`
- `/services*`
- `/discovery*`
- `/info`
***Note:*** Fore Home Assistant API access requirements look above.
[hass-api]: https://www.home-assistant.io/developers/rest_api/
[hass-websocket]: https://www.home-assistant.io/developers/websocket_api/
[hassio-api]: https://github.com/home-assistant/hassio/blob/master/API.md
[hassio-addon-api]: https://github.com/home-assistant/hassio/blob/dev/API.md#restful-for-api-addons

View File

@ -0,0 +1,228 @@
---
title: Add-On Configuration
id: version-0.92.0-hassio_addon_config
original_id: hassio_addon_config
---
Each add-on is stored in a folder. The file structure looks like this:
```text
addon_name/
apparmor.txt
build.json
CHANGELOG.md
config.json
Dockerfile
icon.png
logo.png
README.md
run.sh
```
## Add-on script
As with every Docker container, you will need a script to run when the container is started. A user might run many add-ons, so it is encouraged to try to stick to Bash scripts if you're doing simple things.
All our Images have also [bashio][bashio] installed. It contains a set of commonly used operations and can be used to be included in add-ons to reduce code duplication across add-ons and therefore making it easier to develop and maintain add-ons.
When developing your script:
- `/data` is a volume for persistent storage.
- `/data/options.json` contains the user configuration. You can use bashio or `jq` inside your shell script to parse this data.
```bash
CONFIG_PATH=/data/options.json
TARGET="$(jq --raw-output '.target' $CONFIG_PATH)"
```
So if your `options` contain
```json
{ "target": "beer" }
```
then there will be a variable `TARGET` containing `beer` in the environment of your bash file afterwards.
[bashio]: https://github.com/hassio-addons/bashio
## Add-on Docker file
All add-ons are based on latest Alpine Linux. Hass.io will automatically substitute the right base image based on the machine architecture. Add `tzdata` if you need run in a different timezone. `tzdata` Is is already added to our base images.
```
ARG BUILD_FROM
FROM $BUILD_FROM
ENV LANG C.UTF-8
# Install requirements for add-on
RUN apk add --no-cache jq
# Copy data for add-on
COPY run.sh /
RUN chmod a+x /run.sh
CMD [ "/run.sh" ]
```
If you don't use local build on device or our build script, make sure that the Dockerfile have also a set of labels include:
```
LABEL io.hass.version="VERSION" io.hass.type="addon" io.hass.arch="armhf|aarch64|i386|amd64"
```
It is possible to use own base image with `build.json` or if you do not need support for automatic multi-arch building you can also use a simple docker `FROM`.
### Build Args
We support the following build arguments by default:
| ARG | Description |
|-----|-------------|
| BUILD_FROM | Hold image for dynamic builds or buildings over our systems.
| BUILD_VERSION | Add-on version (read from `config.json`).
| BUILD_ARCH | Hold current build arch inside.
## Add-on config
The config for an add-on is stored in `config.json`.
```json
{
"name": "xy",
"version": "1.2",
"slug": "folder",
"description": "long description",
"arch": ["amd64"],
"url": "website with more information about add-on (ie a forum thread for support)",
"startup": "application",
"boot": "auto",
"ports": {
"123/tcp": 123
},
"map": ["config:rw", "ssl"],
"options": {},
"schema": {},
"image": "repo/{arch}-my-custom-addon"
}
```
| Key | Type | Required | Description |
| --- | ---- | -------- | ----------- |
| name | string | yes | Name of the add-on
| version | string | yes | Version of the add-on
| slug | string | yes | Slug of the add-on
| description | string | yes | Description of the add-on
| arch | list | yes | List of supported arch: `armhf`, `armv7`, `aarch64`, `amd64`, `i386`.
| machine | list | no | Default it support any machine type. You can select that this add-on run only on specific machines.
| url | url | no | Homepage of the addon. Here you can explain the add-ons and options.
| startup | bool | yes | `initialize` will start addon on setup of Hass.io. `system` is for things like databases and not dependent on other things. `services` will start before Home Assistant, while `application` is started afterwards. Finally `once` is for applications that don't run as a daemon.
| webui | string | no | A URL for web interface of this add-on. Like `http://[HOST]:[PORT:2839]/dashboard`, the port needs the internal port, which will be replaced with the effective port. It is also possible to bind the proto part to a config options with: `[PROTO:option_name]://[HOST]:[PORT:2839]/dashboard` and he lookup if they is True and going to `https`.
| boot | string | yes | `auto` by system and manual or only `manual`
| ports | dict | no | Network ports to expose from the container. Format is `"container-port/type": host-port`.
| host_network | bool | no | If that is True, the add-on run on host network.
| host_ipc | bool | no | Default False. Allow to share the IPC namespace with others.
| host_dbus | bool | no | Default False. Map Host dbus service into add-on.
| host_pid | bool | no | Default False. Allow to run container on host PID namespace. Work only for not protected add-ons.
| devices | list | no | Device list to map into the add-on. Format is: `<path_on_host>:<path_in_container>:<cgroup_permissions>`. i.e. `/dev/ttyAMA0:/dev/ttyAMA0:rwm`
| auto_uart | bool | no | Default False. Auto mapping all UART/Serial device from host into add-on.
| homeassistant | string | no | Pin a minimun required Home Assistant version for such Add-on. Value is a version string like `0.91.2`.
| hassio_role | str | no | Default `default`. Role based access to Hass.io API. Available: `default`, `homeassistant`, `backup`, `manager`, `admin`.
| hassio_api | bool | no | This add-on can access to Hass.io REST API. It set the host alias `hassio`.
| homeassistant_api | bool | no | This add-on can access to Hass.io Home-Assistant REST API proxy. Use `http://hassio/homeassistant/api`.
| docker_api | bool | no | Allow read-oly access to docker API for add-on. Work only for not protected add-ons.
| privileged | list | no | Privilege for access to hardware/system. Available access: `NET_ADMIN`, `SYS_ADMIN`, `SYS_RAWIO`, `SYS_TIME`, `SYS_NICE`, `SYS_RESOURCE`, `SYS_PTRACE`, `SYS_MODULE`, `DAC_READ_SEARCH`.
| full_access | bool | no | Give full access to hardware like the privileged mode in docker. Work only for not protected add-ons.
| apparmor | bool/string | no | Enable or disable AppArmor support. If it is enable, you can also use custom profiles with the name of the profile.
| map | list | no | List of maps for additional Hass.io folders. Possible values: `config`, `ssl`, `addons`, `backup`, `share`. Defaults to `ro`, which you can change by adding `:rw` to the end of the name.
| environment | dict | no | A dict of environment variable to run add-on.
| audio | bool | no | Boolean. Mark this add-on to use internal an audio system. The ALSA configuration for this add-on will be mount automatic.
| gpio | bool | no | Boolean. If this is set to True, `/sys/class/gpio` will map into add-on for access to GPIO interface from kernel. Some library need also `/dev/mem` and `SYS_RAWIO` for read/write access to this device. On system with AppArmor enabled, you need disable AppArmor or better for security, provide you own profile for the add-on.
| devicetree | bool | no | Boolean. If this is set to True, `/device-tree` will map into add-on.
| kernel_modules | bool | no | Map host kernel modules and config into add-on (readonly).
| stdin | bool | no | Boolean. If that is enable, you can use the STDIN with Hass.io API.
| legacy | bool | no | Boolean. If the docker image have no hass.io labels, you can enable the legacy mode to use the config data.
| options | dict | yes | Default options value of the add-on
| schema | dict | yes | Schema for options value of the add-on. It can be `False` to disable schema validation and use custom options.
| image | string | no | For use with Docker Hub and other container registries.
| timeout | integer | no | Default 10 (second). The timeout to wait until the docker is done or will be killed.
| tmpfs | string | no | Mount a tmpfs file system in `/tmpfs`. Valide format for this option is : `size=XXXu,uid=N,rw`. Size is mandatory, valid units (`u`) are `k`, `m` and `g` and `XXX` has to be replaced by a number. `uid=N` (with `N` the uid number) and `rw` are optional.
| discovery | list | no | A list of services they this Add-on allow to provide for Home Assistant. Currently supported: `mqtt`
| services | list | no | A list of services they will be provided or consumed with this Add-on. Format is `service`:`function` and functions are: `provide` (this add-on can provide this service), `want` (this add-on can use this service) or `need` (this add-on need this service to work correctly).
| auth_api | bool | no | Allow access to Home Assistent user backend.
| ingress | bool | no | Enable the ingress feature for the Add-on
| ingress_port | integer | no | Default `8099`. For Add-ons they run on host network, you can use `0` and read the port later on API.
| ingress_entry | string | no | Modify the URL entry point from `/`.
| panel_icon | string | no | Default: mdi:puzzle. MDI icon for the menu panel integration.
| panel_title | string | no | Default add-on name, but can Modify with this options.
| panel_admin | bool | no | Default True. Make menu entry only available with admin privileged.
### Options / Schema
The `options` dictionary contains all available options and their default value. Set the default value to `null` if the value is required to be given by the user before the add-on can start, and it show it inside default values. Only nested arrays and dictionaries are supported with a deep of two size. If you want make an option optional, put `?` to the end of data type, otherwise it will be a required value.
```json
{
"message": "custom things",
"logins": [
{ "username": "beer", "password": "123456" },
{ "username": "cheep", "password": "654321" }
],
"random": ["haha", "hihi", "huhu", "hghg"],
"link": "http://example.com/",
"size": 15,
"count": 1.2
}
```
The `schema` looks like `options` but describes how we should validate the user input. For example:
```json
{
"message": "str",
"logins": [
{ "username": "str", "password": "str" }
],
"random": ["match(^\w*$)"],
"link": "url",
"size": "int(5,20)",
"count": "float",
"not_need": "str?"
}
```
We support:
- str
- bool
- int / int(min,) / int(,max) / int(min,max)
- float / float(min,) / float(,max) / float(min,max)
- email
- url
- port
- match(REGEX)
## Add-on extended build
Additional build options for an add-on is stored in `build.json`. This file will be read from our build systems.
You need this only, if you not use the default images or need additionals things.
```json
{
"build_from": {
"armhf": "mycustom/base-image:latest"
},
"squash": false,
"args": {
"my_build_arg": "xy"
}
}
```
| Key | Required | Description |
| --- | -------- | ----------- |
| build_from | no | A dictionary with the hardware architecture as the key and the base Docker image as value.
| squash | no | Default `False`. Be carfully with this option, you can not use the image for caching stuff after that!
| args | no | Allow to set additional Docker build arguments as a dictionary.
We provide a set of [Base-Images][hassio-base] which should cover a lot of needs. If you don't want use the Alpine based version or need a specific Image tag, feel free to pin this requirements for you build with `build_from` option.
[hassio-base]: https://github.com/home-assistant/hassio-base

View File

@ -0,0 +1,31 @@
---
title: Developing an add-on
sidebar_label: Introduction
id: version-0.92.0-hassio_addon_index
original_id: hassio_addon_index
---
Add-ons for Hass.io allow the user to extend the functionality around Home Assistant. This can be running an application that Home Assistant can integrate with (like an MQTT broker) or to share the configuration via Samba for easy editing from other computers. Add-ons can be configured via the Hass.io panel in Home Assistant.
Under the hood, add-ons are Docker images published in [Docker Hub](https://hub.docker.com/). Developers can create [GitHub](https://github.com) repositories that contain multiple references to add-ons for easy sharing with the community.
1. [Tutorial: Making your first add-on](hassio_addon_tutorial.md)
1. [Configuration](hassio_addon_config.md)
1. [Communication](hassio_addon_communication.md)
1. [Local Testing](hassio_addon_testing.md)
1. [Publishing](hassio_addon_publishing.md)
1. [Presentation](hassio_addon_presentation.md)
1. [Repositories](hassio_addon_repository.md)
1. [Security](hassio_addon_security.md)
Usefully links:
* [Hass.io Supervisor](https://github.com/home-assistant/hassio)
* [Hass.io Core Add-ons](https://github.com/home-assistant/hassio-addons)
* [Hass.io Build environment](https://github.com/home-assistant/hassio-build)
* [Hass.io base images](https://github.com/home-assistant/hassio-base)
* [Hass.io Builder](https://github.com/home-assistant/hassio-builder)
* [Hass.io community Add-ons](https://github.com/hassio-addons)
* [HassOS embedded Linux](https://github.com/home-assistant/hassos)
* [Home Assistant Dockerfile](https://github.com/home-assistant/hassio-homeassistant)

View File

@ -0,0 +1,64 @@
---
title: Presenting your add-on
id: version-0.92.0-hassio_addon_presentation
original_id: hassio_addon_presentation
---
If you decide to share your add-on to the public, paying attention to details is recommended. Of course, your add-on should have a proper name and description, but Hass.io also gives you some other tools to present your add-on even nicer.
## Adding documentation
Good documentation helps the consumer of your add-on to understand its usage, explains configuration options, points users in the right direction in the case they have questions or issues, and contains the license under which the add-on was published.
This file containing the documentation is usually referred to as the "README", which is generally published as the `README.md` file.
Take a look at other projects for inspiration. For example, see the `README.md` of the [Community Hass.io Add-ons: Homebridge](https://github.com/hassio-addons/addon-homebridge/blob/master/README.md) add-on.
In future versions of Hass.io, the `README.md` file will be displayed in the Home Assistant frontend.
## Add-on icon & logo
A picture is worth a thousand words. Therefore, your add-on can be improved by adding a proper image icon and logo. Those images are used when showing your add-on in the Home Assistant Hass.io panel and which will significantly improve the visual representation of your add-on.
Requirements for the logo of your add-on:
- The logo must be in the Portable Network Graphics format (`.png`).
- The filename must be `logo.png`.
- It is recommended to keep the logo size around 250x100px. You may choose to use a different size or aspect ratio as you seem fit for your add-on.
Requirements for the icon of your add-on:
- The icon must be in the Portable Network Graphics format (`.png`).
- The filename must be `icon.png`.
- The aspect ratio of the icon must be 1x1 (square).
- It is recommended to use an icon size of 128x128px.
## Keeping a changelog
It is likely you are going to release newer versions of your add-on in the future. In case that happens, the users of your add-on would see an upgrade notice and probably want to know what changes were made in the latest version.
A changelog is a file which contains a curated, chronologically ordered list of notable changes for each version of your add-on and is generally published as the `CHANGELOG.md` file.
If you are in need of a guide on keeping a changelog, we would recommend checking the [keep a changelog](http://keepachangelog.com) website. They have developed a standard that is used by many opensource projects around the world.
In future versions of Hass.io, the `CHANGELOG.md` file will be displayed in the Home Assistant frontend.
## AppArmor
You can use own security profile for you Add-on with AppArmor. Default it is enabled and use the Docker default profile. Put `apparmor.txt` file into your Add-on folder and it will load this file as primary profile. Use the config options to set the name of that profile.
## Ingress
Ingress allow users to access the add-on web interface via the Home Assistant UI. Authentication is handled by Home Assistant, so neither the user nor the add-on developer will need to care about the security or port forwarding. Users love this feature, however it is not every time simple to implement for the add-on developer.
To add Ingress support, follow the following steps:
- The add-on will need to provide the web interface on port `8099`. Make sure that the add-on accepts only connections from `172.30.32.2` on that port and that the connections are treated as authenticated.
- Update add-on configuration and set `ingress: true`. Here it is also possible to configure the Ingress port (default 8099).
- If you need to configure the application inside your add-on with the right path and port, query the add-on info API endpoint.
- If the application doesn't support relative paths or you can't set a base url, you can use nginx filter to replace the URL with correct path.
Ingress API gateway supports the following:
* HTTP/1.x
* Streaming content
* Websockets

View File

@ -0,0 +1,60 @@
---
title: Publishing your add-on
id: version-0.92.0-hassio_addon_publishing
original_id: hassio_addon_publishing
---
There are two different ways of publishing add-ons. One is to publish pre-build containers to Docker Hub and the other option is to have users build the containers locally on their Hass.io instance.
#### Pre-build containers
With pre-build containers, the developer is responsible for building the images for each architecture on their machine and push the results out to Docker Hub. This has a lot of advantages for the user. As a user it will only have to download the final container and be up and running once the download finishes. This makes the installation process fast and almost no chance of failure. This is the preferred method.
We have automated the process of building and publishing add-ons. See below for the instructions.
#### Locally build containers
Starting Hass.io 0.26, it is possible to distribute add-ons that will be built on the users machine. The advantage is that as a developer it is easy to test an idea and see if people are interested in your add-ons. This method includes installing and potentially compiling code. This means that installing such an add-on is slow and adds more wear and tear to users SD card/hard drive than the above mentioned pre-build solution. It also has a higher chance of failure if one of the dependencies of the container has changed or is no longer available.
Use this option when you are playing with add-ons and seeing if someone is interested in your work. Once you're an established repository, please migrate to pushing builds to Docker Hub as it greatly improves the user experience. In the future we will mark locally built add-ons in the add-on store to warn users.
## Build scripts to publish add-ons to Docker Hub
All add-ons are simple docker containers. Inside your add-on `config.json` you specify the Docker image that will be installed for your add-on:
```json
{
...
"image": "myhub/image-{arch}-addon-name",
...
}
```
You can use `{arch}` inside the image name to support multiple architectures with one (1) configuration file. It will be replaced with the architecture of the user when we load the image. If you use `Buildargs` you can use the `build.json` to overwrite our default args.
Hass.io assumes that the `master` branch of your add-on repository matches the latest tag on Docker Hub. When you're building a new version, it's suggested that you use another branch, ie `build` or do it with a PR on GitHub. After you push the add-on to [Docker Hub](https://hub.docker.com/), you can merge this branch to master.
## Custom Add-ons
You need a Docker Hub account to make your own add-ons. You can build your Docker images with the Docker `build` command or use our script that make it simple. Pull our [Builder Docker engine][builder] and run one of the following commands.
For a git repository:
```bash
$ docker run --rm --privileged -v \
~/.docker:/root/.docker homeassistant/amd64-builder \
--all -t addon-folder -r https://github.com/xy/addons \
-b branchname
```
For a local repository:
```bash
$ docker run --rm --privileged -v \
~/.docker:/root/.docker -v /my_addon:/data homeassistant/amd64-builder \
--all -t /data
```
> If you are developing on macOS and using Docker for Mac, you may encounter an error message similar to the following: <code>error creating aufs mount to /var/lib/docker/aufs/mnt/<SOME_ID>-init: invalid argument</code>. A proposed workaround is to add the following to the Advanced Daemon JSON configuration via Docker > Preferences > Daemon > Advanced: <code>"storage-driver" : "aufs"</code> or map the docker socket into container.
[builder]: https://github.com/home-assistant/hassio-builder

View File

@ -0,0 +1,43 @@
---
title: Add-on security
id: version-0.92.0-hassio_addon_security
original_id: hassio_addon_security
---
Hass.io rates every add-on based on the wanted rights. An add-on with a rating of 6 is very secure. If an add-on has a rating of 1, you shouldn't run this add-on unless you are 100% sure that you can trust the source.
## API Role
For access to Hass.io API you need define a role or you run in default mode. This is only required for Hass.io API not Home Assistant proxy. Any of the role have also the default API calls inheret for that are no settings are required.
### Available Roles
| Role | Description |
|------|-------------|
| default | Have access to all `info` calls |
| homeassistant | Can access to all Home Assistant API endpoints |
| backup | Can access to all snapshot API endpoints |
| manager | Is for Add-ons they run CLIs and need extended rights |
| admin | Have access to every API call. That is the only one they can disable/enable the Add-on protection mode |
## Protection
Default, all add-ons run in protection enabled mode. This mode prevents the add-on from getting any rights on the system. If an add-on requires more rights, you can disable this protection via the API add-on options for that add-on. But be carful, an add-on with disabled protection can destroy your system!
## Making a secure add-on
As a developer, follow the following best practices to make your add-on secure:
- Don't run on host network
- Create an AppArmor profile
- Map folders read only if you don't need write access
- If you need any API access, make sure you that you not grant to highest permission if you don't need it
## Use Home Assistant User backend
Instead to allow users to set new login credential in plain text config, use the Home Assistant [Auth backend][hassio-api-auth]. You can enable the access to API with `auth_api: true`. Now you are able to send the login credential to auth backend and validate it again Home Assistant.
We have some sample and helper around that system collected in a [GitHub repository][hassio-auth]. Feel free to copy past it or provide your usefully scripts.
[hassio-auth]: https://github.com/home-assistant/hassio-auth
[hassio-api-auth]: https://github.com/home-assistant/hassio/blob/dev/API.md#auth--sso-api

View File

@ -0,0 +1,34 @@
---
title: Local add-on testing
id: version-0.92.0-hassio_addon_testing
original_id: hassio_addon_testing
---
The fastest way to develop add-ons is by adding them to your local add-on repository. To access your local add-on repository, install either the [Samba add-on] or [SSH add-on].
Right now add-ons will work with images that are stored on Docker Hub (using `image` from add-on config). Without `image` inside local add-ons repository it to be built on the device.
The [Community Add-on][hassio-vagrant] repository create a vagrant based development system. This Vagrant virtual machine allows you to test and play with Hass.io and Home Assistant, and is a great environment for add-on developers
[Samba add-on]: https://www.home-assistant.io/addons/samba/
[SSH add-on]: https://www.home-assistant.io/addons/ssh/
[hassio-vagrant]: https://github.com/hassio-addons/hassio-vagrant
## Local build
You can build and try the addon on your developer machine also. Move all addon stuff into a temp folder. If you use `FROM $BUILD_FROM` you need set a base image with build args. Normally you can use follow base images:
- armhf: `homeassistant/armhf-base:latest`
- aarch64: `homeassistant/aarch64-base:latest`
- amd64: `homeassistant/amd64-base:latest`
- i386: `homeassistant/i386-base:latest`
Use `docker` to build the test addon: `docker build --build-arg BUILD_FROM="homeassistant/amd64-base:latest" -t local/my-test-addon .`
## Local run
Create a new folder for data and add a test _options.json_ file. After that you can run your add-on with: `docker run --rm -v /tmp/my_test_data:/data -p PORT_STUFF_IF_NEEDED local/my-test-addon`
## Logs
All stdout and stderr are redirected to the Docker logs. The logs can be fetched from the add-on page inside the Hass.io panel in Home Assistant.

View File

@ -0,0 +1,64 @@
---
title: Debugging Hass.io
id: version-0.92.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.
## SSH access to the host
### 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. 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

@ -0,0 +1,59 @@
---
title: Hass.io <> Home Assistant integration development
sidebar_label: HASS Integration development
id: version-0.92.0-hassio_hass
original_id: hassio_hass
---
These steps will help you connect your local Home Assistant to a remote Hass.io instance. You can then make changes locally to either the Hass.io component or the frontend and test it out against a real instance.
For this guide, we're going to assume that you have an Hass.io instance up and running. If you don't, you can use the generic installation method to install it inside a [virtual machine](https://github.com/home-assistant/hassio-build/tree/master/install#install-hassio).
## API Access
To develop for the frontend, we're going to need API access to the supervisor.
- Add our developer Add-on repository: https://github.com/home-assistant/hassio-addons-development
- Install the Add-on "Remote API proxy"
For some API commands you need explicit the Home Assistant API token, but 99% of the functionality work with `Remote API proxy`. This token change some times but you can read the current legal token on host system with:
```sh
$ docker inspect homeassistant | grep HASSIO_TOKEN
```
## Having Home Assistant connect to remote Hass.io
The connection with the supervisor is hidden inside the host and is only accessible from applications running on the host. So to make it accessible for our Home Assistant instance, we will need to route the connection to our computer running Home Assistant. We're going to do this by forwarding the API with "Remote API proxy" Add-on.
First, make sure Home Assistant will load the Hass.io component by adding `hassio:` to your `configuration.yaml` file. Next, we will need to tell Hass.io component how to connect to the remote Hass.io instance, we do this by setting the `HASSIO` and `HASSIO_TOKEN` environment variables when starting Home Assistant. Note that the `HASSIO` value is not the same as the one that we saw above and the `HASSIO_TOKEN` is available inside log output of "Remote API Add-on" (This change every restart of this Add-on!).
```bash
HASSIO=<IP OF HASS.IO>:80 HASSIO_TOKEN=<VALUE OF HASSIO_TOKEN> hass
```
Voila. Your local Home Assistant installation will now connect to a remote Hass.io instance.
## Frontend development
> This requires Home Assistant 0.71 or later.
We need a couple more steps to do frontend development. First, make sure you have a Home Assistant frontend development set up ([instructions](frontend_index.md)).
Update the Hass.io component configuration in your `configuration.yaml` to point at the frontend repository:
```yaml
# configuration.yaml
hassio:
development_repo: /home/paulus/dev/hass/home-assistant-polymer
```
To build a local version of the Hass.io panel, go to the frontend repository and run:
```bash
cd hassio
script/build_hassio
```
Now start Home Assistant as discussed in the previous section and it will now connect to the remote Hass.io but show your local frontend.
We're currently transitioning in how we're building the frontend so we don't have an incremental development mode just yet. For now, after making a local change, run `script/build_hassio` again.

View File

@ -1,4 +1,5 @@
[
"0.92.0",
"0.91.2",
"0.91.0",
"0.90.0",