mirror of
https://github.com/home-assistant/developers.home-assistant.git
synced 2025-07-09 10:26:30 +00:00
Add mobile app docs (#193)
This commit is contained in:
parent
1d5d20d178
commit
1e695768fa
@ -7,4 +7,5 @@ This guide describes how to build a native Home Assistant app that communicates
|
||||
|
||||
- Allow the user to establish a connection and authenticate with their own Home Assistant instance.
|
||||
- Send location and device info back to Home Assistant.
|
||||
- Call services, fire events and render templates.
|
||||
- A view to control the house via an authenticated webview.
|
||||
|
@ -2,7 +2,9 @@
|
||||
title: "Sending data home"
|
||||
---
|
||||
|
||||
There are different APIs that your app can use to send data back or communicate with Home Assistant.
|
||||
Once you have registered your app with the mobile app component, you can start interacting with Home Assistant via the provided webhook information.
|
||||
|
||||
The first step is to turn the returned webhook ID into a full URL: `<instance_url>/api/webhook/<webhook_id>`. This will be the only url that we will need for all our interactions. The webhook endpoint will not require authenticated requests.
|
||||
|
||||
## Short note on instance URLs
|
||||
|
||||
@ -10,48 +12,133 @@ Some users have configured Home Assistant to be available outside of their home
|
||||
|
||||
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
|
||||
## Interaction basics
|
||||
|
||||
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.
|
||||
All interaction will be done by making HTTP POST requests to the webhook url. These requests do not need to contain authentication.
|
||||
|
||||
Webhooks are ideal for sending quick updates, like location or battery, from your app to Home Assistant.
|
||||
The payload format depends on the type of interaction, but it all shares a common base:
|
||||
|
||||
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)
|
||||
)
|
||||
```json5
|
||||
{
|
||||
"type": "<type of message>",
|
||||
// other info
|
||||
}
|
||||
```
|
||||
|
||||
## Websocket API
|
||||
If you received a `secret` during registration, you will need to encrypt your message and wrap it in an encrypted message:
|
||||
|
||||
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.
|
||||
```json5
|
||||
{
|
||||
"type": "encrypted",
|
||||
"data": "<encrypted message>"
|
||||
}
|
||||
```
|
||||
|
||||
Websocket API requires authentication via an access token and a direct connection with the instance.
|
||||
## Update device location
|
||||
|
||||
- [Websocket API Docs](external_api_websocket)
|
||||
- [Making authenticated requests](auth_api#making-authenticated-requests)
|
||||
This message will inform Home Assistant of new location information.
|
||||
|
||||
## Rest API
|
||||
```json
|
||||
{
|
||||
"type": "update_location",
|
||||
"gps": [12.34, 56.78],
|
||||
"gps_accuracy": 120,
|
||||
"battery": 45,
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
| Key | Type | Description
|
||||
| --- | ---- | -----------
|
||||
| `gps` | latlong | Current location as latitude and longitude.
|
||||
| `gps_accuracy` | int | GPS accurracy in meters.
|
||||
| `battery` | int | Percentage of battery the device has left.
|
||||
|
||||
Rest API requires authentication via an access token and a direct connection with the instance.
|
||||
## Call a service
|
||||
|
||||
- [Rest API Docs](external_api_rest)
|
||||
- [Making authenticated requests](auth_api#making-authenticated-requests)
|
||||
Call a service in Home Assistant.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "call_service",
|
||||
"domain": "light",
|
||||
"service": "turn_on",
|
||||
"service_data": {
|
||||
"entity_id": "light.kitchen"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Key | Type | Description
|
||||
| --- | ---- | -----------
|
||||
| `domain` | string | The domain of the service
|
||||
| `service` | string | The service namae
|
||||
| `service_data` | dict | The data to send to the service
|
||||
|
||||
## Fire an event
|
||||
|
||||
Fire an event in Home Assistant.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "fire_event",
|
||||
"event_type": "my_custom_event",
|
||||
"event_data": {
|
||||
"something": 50
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Key | Type | Description
|
||||
| --- | ---- | -----------
|
||||
| `event_type` | string | Type of the event to fire
|
||||
| `event_data` | string | Date of the event to fire
|
||||
|
||||
## Render templates
|
||||
|
||||
> This API is very likely to change in an upcoming release. Support to render multiple templates at once will be added.
|
||||
|
||||
Renders a template and returns the result.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "render_template",
|
||||
"template": "Hello {{ name }}, you are {{ states('person.paulus') }}.",
|
||||
"variables": {
|
||||
"name": "Paulus"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Key | Type | Description
|
||||
| --- | ---- | -----------
|
||||
| `template` | string | The template to render
|
||||
| `variables` | Dict | The extra template variables to include.
|
||||
|
||||
## Update registration
|
||||
|
||||
Update your app registration. Use this if the app version changed or any of the other values.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "update_registration",
|
||||
"app_data": {
|
||||
"push_notification_key": "abcd"
|
||||
},
|
||||
"app_version": "2.0.0",
|
||||
"device_name": "Robbies iPhone",
|
||||
"manufacturer": "Apple, Inc.",
|
||||
"model": "iPhone XR",
|
||||
"os_version": "23.02",
|
||||
}
|
||||
```
|
||||
|
||||
All keys are optional.
|
||||
|
||||
| Key | Type | Description
|
||||
| --- | --- | --
|
||||
| `app_version` | string | Version of the mobile app.
|
||||
| `device_name` | string | Name of the device running the app.
|
||||
| `manufacturer` | string | The manufacturer of the device running the app.
|
||||
| `model` | string | The model of the device running the app.
|
||||
| `os_version` | string | The OS version of the device running the app.
|
||||
| `app_data` | Dict | App data can be used if the app has a supporting component that extends mobile_app functionality.
|
||||
|
@ -6,33 +6,77 @@ When a user first opens the app, they will need to connect to their local instan
|
||||
|
||||
## 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.
|
||||
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.
|
||||
|
||||
## 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.
|
||||
> This is an experimental feature. We expect to evolve the API in the upcoming releases.
|
||||
|
||||
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:
|
||||
_This requires Home Assistant 0.89 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. You can do so by making an authenticated POST request to `/api/mobile_app/devices`. [More info on making authenticated requests.](auth_api.md#making-authenticated-requests)
|
||||
|
||||
If you get a 404 when making this request, it means the user does not have the mobile_app component enabled. Prompt the user to enable the `mobile_app` component. The mobile_app component is set up as part of the default Home Assistant configuration.
|
||||
|
||||
Example payload to send to the registration endpoint:
|
||||
|
||||
```json
|
||||
{
|
||||
"device_type": "iPhone 6",
|
||||
"firmware": "zxcx"
|
||||
"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",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The endpoint will register the device with Home Assistant:
|
||||
| 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.
|
||||
|
||||
- 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.
|
||||
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. Store this information.
|
||||
|
||||
> The following section is not implemented yet.
|
||||
```json
|
||||
{
|
||||
"webhook_id": "abcdefgh",
|
||||
"secret": "qwerty"
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
| Key | Type | Description
|
||||
| --- | ---- | -----------
|
||||
| `webhook_id` | string | The webhook ID that can be used to send data back.
|
||||
| `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.
|
||||
|
||||
[zeroconf component]: https://www.home-assistant.io/components/zeroconf
|
||||
[OAuth2 with Home Assistant]: auth_api
|
||||
|
||||
## Encryption
|
||||
|
||||
The mobile app component supports encryption to make sure all communication between the app and Home Assistant is encrypted. The encryption is powered by [libsodium](https://libsodium.gitbook.io). Example to encrypt the message using libsodium on Python:
|
||||
|
||||
```python
|
||||
from nacl.secret import SecretBox
|
||||
from nacl.encoding import Base64Encoder
|
||||
|
||||
data = SecretBox(key).encrypt(
|
||||
payload,
|
||||
encoder=Base64Encoder
|
||||
).decode("utf-8")
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user