mirror of
https://github.com/home-assistant/developers.home-assistant.git
synced 2025-07-16 05:46:30 +00:00
Add docs for native app integration (#149)
* Add docs for native app integration * Update docs/app_integration_setup.md Co-Authored-By: balloob <paulus@home-assistant.io> * Update docs/app_integration_setup.md Co-Authored-By: balloob <paulus@home-assistant.io> * Update docs/app_integration_setup.md Co-Authored-By: balloob <paulus@home-assistant.io> * Update app_integration_sending_data.md * Address comments
This commit is contained in:
parent
e9b92fec46
commit
5f4d549954
10
docs/app_integration_index.md
Normal file
10
docs/app_integration_index.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "Native App Integration"
|
||||
sidebar_label: "Introduction"
|
||||
---
|
||||
|
||||
This guide describes how to build a native Home Assistant app that communicates with Home Assistant and offers a seamless integration. Below is a list of the things that we will discuss in this guide.
|
||||
|
||||
- Allow the user to establish a connection and authenticate with their own Home Assistant instance.
|
||||
- Send location and device info back to Home Assistant.
|
||||
- A view to control the house via an authenticated webview.
|
57
docs/app_integration_sending_data.md
Normal file
57
docs/app_integration_sending_data.md
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
title: "Sending data home"
|
||||
---
|
||||
|
||||
There are different APIs that your app can use to send data back or communicate with Home Assistant.
|
||||
|
||||
## Short note on instance URLs
|
||||
|
||||
Some users have configured Home Assistant to be available outside of their home network using a dynamic DNS service. There are some routers that don't support hairpinning / NAT loopback: a device sending data from inside the routers network, via the externally configured DNS service, to Home Asisstant, which also resides inside the local network.
|
||||
|
||||
To work around this, the app will need to record which WiFi is the home network, and use a direct connection when connected to the home WiFi network.
|
||||
|
||||
## Webhooks
|
||||
|
||||
Any component in Home Assistant can register webhook endpoints. The webhook endpoints contain a randomized URL-segment which are bound to just a single update handler. Because of this, the call requires no authentication, making calls have little overhead.
|
||||
|
||||
Webhooks are ideal for sending quick updates, like location or battery, from your app to Home Assistant.
|
||||
|
||||
Webhooks are available on the local instance on `/api/webhook/<webhook id>`, which requires a direct connection. If the Home Assistant instance is configured to use Home Assistant Cloud, it is possible to get a cloud url for the webhook. This url is accessible from anywhere on the internet.
|
||||
|
||||
To register a webhook in your component:
|
||||
|
||||
```python
|
||||
async def handle_webhook(hass, webhook_id, request):
|
||||
"""Handle webhook callback."""
|
||||
body = await request.json()
|
||||
# Do something with the data
|
||||
|
||||
|
||||
webhook_id = hass.components.webhook.async_generate_id()
|
||||
|
||||
hass.components.webhook.async_register(
|
||||
DOMAIN, 'Name of the webhook', webhook_id, handle_webhook)
|
||||
|
||||
print(
|
||||
"Webhook available on:",
|
||||
hass.components.webhook.async_generate_url(webhook_id)
|
||||
)
|
||||
```
|
||||
|
||||
## Websocket API
|
||||
|
||||
With a websocket connection you will be able to stream updates from Home Assistant and control most of the things inside Home Assistant. This API is perfect if you want to show a realtime view of the house and allow the user to interact with it.
|
||||
|
||||
Websocket API requires authentication via an access token and a direct connection with the instance.
|
||||
|
||||
- [Websocket API Docs](external_api_websocket)
|
||||
- [Making authenticated requests](auth_api#making-authenticated-requests)
|
||||
|
||||
## Rest API
|
||||
|
||||
With the Rest API you are able to query the state of the house and call services. Your component is also able to register new HTTP views to offer other Rest API endpoints.
|
||||
|
||||
Rest API requires authentication via an access token and a direct connection with the instance.
|
||||
|
||||
- [Rest API Docs](external_api_rest)
|
||||
- [Making authenticated requests](auth_api#making-authenticated-requests)
|
38
docs/app_integration_setup.md
Normal file
38
docs/app_integration_setup.md
Normal file
@ -0,0 +1,38 @@
|
||||
---
|
||||
title: "Connecting to an instance"
|
||||
---
|
||||
|
||||
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. 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.
|
||||
|
||||
## Registering the device
|
||||
|
||||
Once you have tokens to authenticate as a user, it's time to register the app with the app component in Home Assistant. Each native app will need to build their own support layer for their app. The setup of your component will need to use a config flow so that it is configurable via the user interface and can access advanced Home Assistant features like the device registry.
|
||||
|
||||
Let's take as an example that we're building an iOS application and that it is supported by the `ios` component in Home Assistant. If the component is loaded, it will register a new API endpoint on `/api/ios/register` (requiring authentication). The app can post to this endpoint to register the users' device with Home Assistant. Example payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"device_type": "iPhone 6",
|
||||
"firmware": "zxcx"
|
||||
}
|
||||
```
|
||||
|
||||
The endpoint will register the device with Home Assistant:
|
||||
|
||||
- Generate a unique webhook endpoint that the app can use to send data back to Home Assistant.
|
||||
- Use the storage helper to store data.
|
||||
- Register the iOS device with the [device registry](device_registry_index).
|
||||
- Make the device available as a notification target.
|
||||
|
||||
> The following section is not implemented yet.
|
||||
|
||||
If the app receives a 404 HTTP status code when trying to register the device, it means the `ios` component is not loaded. In this case, the app can load the `ios` component by posting to `/api/config_entry_discovery`. This will trigger the `http_discovery` step of the config flow for the `ios` component and it will be loaded. The app can now retry the device registration.
|
||||
|
||||
[zeroconf component]: https://www.home-assistant.io/components/zeroconf
|
||||
[OAuth2 with Home Assistant]: auth_api
|
9
docs/app_integration_webview.md
Normal file
9
docs/app_integration_webview.md
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
title: "Authenticated Webview"
|
||||
---
|
||||
|
||||
Your application already asked the user to authenticate. This means that your app should not ask the user to authenticate again when they open the Home Assistant UI.
|
||||
|
||||
To make this possible, the Home Assistant UI supports [external authentication](frontend_external_auth). This allows your app to provide hooks so that the frontend will ask your app for access tokens.
|
||||
|
||||
Note that this feature requires a direct connection to the instance.
|
@ -5,6 +5,19 @@
|
||||
"previous": "Previous",
|
||||
"tagline": "All you need to start developing for Home Assistant",
|
||||
"docs": {
|
||||
"app_integration_index": {
|
||||
"title": "Native App Integration",
|
||||
"sidebar_label": "Introduction"
|
||||
},
|
||||
"app_integration_sending_data": {
|
||||
"title": "Sending data home"
|
||||
},
|
||||
"app_integration_setup": {
|
||||
"title": "Connecting to an instance"
|
||||
},
|
||||
"app_integration_webview": {
|
||||
"title": "Authenticated Webview"
|
||||
},
|
||||
"architecture_components": {
|
||||
"title": "Components Architecture",
|
||||
"sidebar_label": "Components"
|
||||
@ -937,6 +950,56 @@
|
||||
},
|
||||
"version-0.81.0-hassio_addon_config": {
|
||||
"title": "Add-On Configuration"
|
||||
},
|
||||
"version-0.82.0-architecture_hassio": {
|
||||
"title": "Hass.io Architecture",
|
||||
"sidebar_label": "Hass.io"
|
||||
},
|
||||
"version-0.82.0-asyncio_working_with_async": {
|
||||
"title": "Working with Async"
|
||||
},
|
||||
"version-0.82.0-auth_permissions": {
|
||||
"title": "Permissions"
|
||||
},
|
||||
"version-0.82.0-config_entries_index": {
|
||||
"title": "Config Entries",
|
||||
"sidebar_label": "Introduction"
|
||||
},
|
||||
"version-0.82.0-creating_component_code_review": {
|
||||
"title": "Checklist for creating a component"
|
||||
},
|
||||
"version-0.82.0-creating_component_deps_and_reqs": {
|
||||
"title": "Requirements & Dependencies"
|
||||
},
|
||||
"version-0.82.0-creating_component_generic_discovery": {
|
||||
"title": "Generic Platform Discovery"
|
||||
},
|
||||
"version-0.82.0-development_checklist": {
|
||||
"title": "Development Checklist"
|
||||
},
|
||||
"version-0.82.0-development_guidelines": {
|
||||
"title": "Style guidelines"
|
||||
},
|
||||
"version-0.82.0-development_validation": {
|
||||
"title": "Validate the input"
|
||||
},
|
||||
"version-0.82.0-documentation_index": {
|
||||
"title": "Documentation"
|
||||
},
|
||||
"version-0.82.0-entity_registry_index": {
|
||||
"title": "Entity Registry",
|
||||
"sidebar_label": "Introduction"
|
||||
},
|
||||
"version-0.82.0-entity_sensor": {
|
||||
"title": "Sensor Entity",
|
||||
"sidebar_label": "Sensor"
|
||||
},
|
||||
"version-0.82.0-hassio_addon_config": {
|
||||
"title": "Add-On Configuration"
|
||||
},
|
||||
"version-0.82.0-hassio_addon_index": {
|
||||
"title": "Developing an add-on",
|
||||
"sidebar_label": "Introduction"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
@ -968,6 +1031,7 @@
|
||||
"Internationalization": "Internationalization",
|
||||
"Documentation": "Documentation",
|
||||
"Intents": "Intents",
|
||||
"Native App Integration": "Native App Integration",
|
||||
"asyncio": "asyncio",
|
||||
"Hass.io": "Hass.io",
|
||||
"Hass.io Add-Ons": "Hass.io Add-Ons",
|
||||
|
@ -133,6 +133,12 @@
|
||||
"intent_conversation",
|
||||
"intent_builtin"
|
||||
],
|
||||
"Native App Integration": [
|
||||
"app_integration_index",
|
||||
"app_integration_setup",
|
||||
"app_integration_sending_data",
|
||||
"app_integration_webview"
|
||||
],
|
||||
"asyncio": [
|
||||
"asyncio_index",
|
||||
"asyncio_101",
|
||||
|
Loading…
x
Reference in New Issue
Block a user