mirror of
https://github.com/home-assistant/developers.home-assistant.git
synced 2025-07-07 17:36:29 +00:00
Add version 0.74.0
This commit is contained in:
parent
dfcbf9a891
commit
8503275f05
@ -0,0 +1,108 @@
|
||||
---
|
||||
title: Working with Async
|
||||
id: version-0.74.0-asyncio_working_with_async
|
||||
original_id: asyncio_working_with_async
|
||||
---
|
||||
|
||||
Although we have a backwards compatible API, using the async core directly will be a lot faster. Most core components have already been rewritten to leverage the async core. This includes the EntityComponent helper (foundation of light, switch, etc), scripts, groups and automation.
|
||||
|
||||
## Interacting with the core
|
||||
|
||||
[All methods in the Home Assistant core][dev-docs] are implemented in two flavors: an async version and a version to be called from other threads. The versions for other are merely wrappers that call the async version in a threadsafe manner.
|
||||
|
||||
So if you are making calls to the core (the hass object) from within a callback or coroutine, use the methods that start with async_. If you need to call an async_ function that is a coroutine, your task must also be a coroutine.
|
||||
|
||||
## Implementing an async component
|
||||
|
||||
To make a component async, implement an async_setup.
|
||||
|
||||
```python
|
||||
def setup(hass, config):
|
||||
# Setup your component outside of the event loop.
|
||||
```
|
||||
|
||||
Will turn into:
|
||||
|
||||
```python
|
||||
async def async_setup(hass, config):
|
||||
# Setup your component inside of the event loop.
|
||||
```
|
||||
|
||||
## Implementing an async platform
|
||||
|
||||
For platforms we support async setup. Instead of setup_platform you need to have a coroutine async_setup_platform.
|
||||
|
||||
```python
|
||||
setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
# Setup your platform outside of the event loop.
|
||||
```
|
||||
|
||||
Will turn into:
|
||||
|
||||
```python
|
||||
async def async_setup_platform(hass, config, async_add_entities,
|
||||
discovery_info=None):
|
||||
# Setup your platform inside of the event loop
|
||||
```
|
||||
|
||||
The only difference with the original parameters is that the `add_entities` function has been replaced by the async friendly callback `async_add_entities`.
|
||||
|
||||
## Implementing an async entity
|
||||
|
||||
You can make your entity async friendly by converting your update method to be async. This requires the dependency of your entities to also be async friendly!
|
||||
|
||||
```python
|
||||
class MyEntity(Entity):
|
||||
def update(self):
|
||||
"""Retrieve latest state."""
|
||||
self._state = fetch_state()
|
||||
```
|
||||
|
||||
Will turn into:
|
||||
|
||||
```python
|
||||
class MyEntity(Entity):
|
||||
async def async_update(self):
|
||||
"""Retrieve latest state."""
|
||||
self._state = await async_fetch_state()
|
||||
```
|
||||
|
||||
Make sure that all properties defined on your entity do not result in I/O being done. All data has to be fetched inside the update method and cached on the entity. This is because these properties are read from within the event loop and thus doing I/O will result in the core of Home Assistant waiting until your I/O is done.
|
||||
|
||||
## Calling async functions from threads
|
||||
|
||||
Sometimes it will happen that you’re in a thread and you want to call a function that is only available as async. Home Assistant includes a few async helper utilities to help with this.
|
||||
|
||||
In the following example, `say_hello` will schedule `async_say_hello` and block till the function has run and get the result back.
|
||||
|
||||
```python
|
||||
from homeassistant.util.async_ import run_callback_threadsafe
|
||||
|
||||
def say_hello(hass, target):
|
||||
return run_callback_threadsafe(
|
||||
hass.loop, async_say_hello, target).result()
|
||||
|
||||
async def async_say_hello(hass, target):
|
||||
return "Hello {}!".format(target)
|
||||
```
|
||||
|
||||
## Calling sync functions from async
|
||||
|
||||
If you are running inside an async context, it might sometimes be necessary to call a sync function. Do this like this:
|
||||
|
||||
```python
|
||||
# hub.update() is a sync function.
|
||||
result = await hass.async_add_executor_job(hub.update)
|
||||
```
|
||||
|
||||
## Starting independent task from async
|
||||
|
||||
If you want to spawn a task that will not block the current async context, you can choose to create it as a task on the event loop. It will then be executed in parallel.
|
||||
|
||||
```python
|
||||
hass.async_create_task(async_say_hello(hass, target))
|
||||
```
|
||||
|
||||
|
||||
[dev-docs]: https://dev-docs.home-assistant.io/en/master/api/core.html
|
||||
[dev-docs-async]: https://dev-docs.home-assistant.io/en/dev/api/util.html#module-homeassistant.util.async
|
89
website/versioned_docs/version-0.74.0/auth_api.md
Normal file
89
website/versioned_docs/version-0.74.0/auth_api.md
Normal file
@ -0,0 +1,89 @@
|
||||
---
|
||||
title: Authentication API
|
||||
sidebar_label: API
|
||||
id: version-0.74.0-auth_api
|
||||
original_id: auth_api
|
||||
---
|
||||
|
||||
> This is experimental. It is not persisted and is not yet intended for production.
|
||||
|
||||
This page will describe the steps required to fetch an access token for a user and how to refresh it. We follow the OAuth 2 specification.
|
||||
|
||||
## Requirements
|
||||
|
||||
A client needs to be created inside Home Assistant before a client can request users to authorize it or fetch a new access token. The only way currently to create a client is programmatically:
|
||||
|
||||
```python
|
||||
client = await hass.auth.async_get_or_create_client(
|
||||
'Example client',
|
||||
redirect_uris=['http://www.example.com/hass_callback']
|
||||
)
|
||||
print(client.id)
|
||||
```
|
||||
|
||||
## Authorize
|
||||
|
||||
[](https://www.websequencediagrams.com/?lz=dGl0bGUgQXV0aG9yaXphdGlvbiBGbG93CgpVc2VyIC0-IENsaWVudDogTG9nIGludG8gSG9tZSBBc3Npc3RhbnQKABoGIC0-IFVzZXI6AEMJZSB1cmwgAD4JACgOOiBHbyB0bwAeBWFuZCBhAC0ICgBQDgB1DACBFw5jb2RlAHELAE4RZXQgdG9rZW5zIGZvcgAoBgBBGlQAJQUK&s=qsd)
|
||||
|
||||
- The authorize url should contain `client_id`, `redirect_uri` and, if available, `client_secret` as query parameters. Example: `http://your-instance.com/auth/authorize?client_id=ABCDE&client_secret=QWERTY&redirect_uri=https%3A%2F%2Fexample.com%2Fhass_callback`
|
||||
- The user will navigate to this link, log into Home Assistant and authorize the client.
|
||||
- Once authorized, the user will be redirected back to the passed in redirect uri with the authorization code as part of the query parameters. Example: https://example.com/hass_callback?code=12345
|
||||
- This authorization code can be exchanged for tokens by sending it to the token endpoint (see next section).
|
||||
- As specified in the OAuth 2 specification, it is possible to pass an optional state string to the authorize url using the `state` query parameter. This string will be added as query parameter to the redirect url.
|
||||
|
||||
## Token
|
||||
|
||||
The token endpoint returns tokens given valid grants. This grant is either an authorization code retrieved from the authorize endpoint or a refresh token.
|
||||
|
||||
All interactions with this endpoint need to be HTTP POST requests to `http://your-instance.com/auth/token` with the request body encoded in `application/x-www-form-urlencoded`.
|
||||
|
||||
### Authorization code
|
||||
|
||||
Use the grant type `authorization_code` to retrieve the tokens after a user has successfully finished the authorize step. The request body is:
|
||||
|
||||
```
|
||||
grant_type=authorization_code&code=12345
|
||||
```
|
||||
|
||||
The return response will be an access and refresh token:
|
||||
|
||||
```json
|
||||
{
|
||||
"access_token": "ABCDEFGH",
|
||||
"expires_in": 1800,
|
||||
"refresh_token": "IJKLMNOPQRST",
|
||||
"token_type": "Bearer"
|
||||
}
|
||||
```
|
||||
|
||||
### Refresh token
|
||||
|
||||
Use the grant type `refresh_token` to retrieve an access token using a refresh token. The request body is:
|
||||
|
||||
```
|
||||
grant_type=refresh_token&refresh_token=QWERTY
|
||||
```
|
||||
|
||||
The return response will be an access token:
|
||||
|
||||
```json
|
||||
{
|
||||
"access_token": "ABCDEFGH",
|
||||
"expires_in": 1800,
|
||||
"token_type": "Bearer"
|
||||
}
|
||||
```
|
||||
|
||||
## Making authenticated requests
|
||||
|
||||
Once you have an access token, you can make authenticated requests to the Home Assistant APIs.
|
||||
|
||||
For the websocket connection, pass the access token in the [authentication message](https://developers.home-assistant.io/docs/en/external_api_websocket.html#authentication-phase).
|
||||
|
||||
For HTTP requests, pass the token type and access token as the authorization header:
|
||||
|
||||
```
|
||||
Authorization: Bearer ABCDEFGH
|
||||
```
|
||||
|
||||
If the access token is no longer valid, you will get a response with HTTP status code 401 unauthorized. This means that you will need to refresh the token. If the refresh token doesn't work, the tokens are no longer valid and the client should ask the user to authorize again.
|
45
website/versioned_docs/version-0.74.0/entity_media_player.md
Normal file
45
website/versioned_docs/version-0.74.0/entity_media_player.md
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
title: Media Player Entity
|
||||
sidebar_label: Media Player
|
||||
id: version-0.74.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)
|
||||
|
||||
|
||||
## 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."""
|
57
website/versioned_docs/version-0.74.0/entity_vacuum.md
Normal file
57
website/versioned_docs/version-0.74.0/entity_vacuum.md
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
title: Vacuum Entity
|
||||
sidebar_label: Vacuum
|
||||
id: version-0.74.0-entity_vacuum
|
||||
original_id: entity_vacuum
|
||||
---
|
||||
|
||||
## 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
|
||||
| ---- | ---- | ------- | -----------
|
||||
| name | string | **Required** | Name of the device.
|
||||
| state | string | **Required** | One of the states listed in the states section.
|
||||
| battery_level | int | `none` | Current battery level.
|
||||
| battery_icon | string | function | Battery icon to show in UI.
|
||||
| cleaning_mode | string | `none` | The current cleaning mode.
|
||||
| cleaning_mode_list | list | `NotImplementedError()`| List of avaliable fan speeds and cleaning modes.
|
||||
| error | string | **Required** with `STATE_ERROR` | An error message if the vacuum is in `STATE_ERROR`.
|
||||
|
||||
|
||||
## States
|
||||
| State | Description
|
||||
| ----- | -----------
|
||||
| `STATE_CLEANING` | The vacuum is currently cleaning.
|
||||
| `STATE_DOCKED` | The vacuum is currently docked, it is assumed that docked can also mean charging.
|
||||
| `STATE_PAUSED` | The vacuum was cleaning but was paused without returning to the dock.
|
||||
| `STATE_IDLE` | The vacuum is not paused, not docked and does not have any errors.
|
||||
| `STATE_RETURNING` | The vacuum is done cleaning and is currently returning to the dock, but not yet docked.
|
||||
| `STATE_ERROR` | The vacuum encountered an error while cleaning, the error can be specified as a property on the entity.
|
||||
|
||||
## Methods
|
||||
|
||||
### `turn_on` or `async_turn_on`
|
||||
Turn the vacuum on and start cleaning.
|
||||
|
||||
### `turn_off`or `async_turn_off`
|
||||
Turn the vacuum off stopping the cleaning and returning home.
|
||||
|
||||
### `return_to_base` or `async_return_to_base`
|
||||
Set the vacuum cleaner to return to the dock.
|
||||
|
||||
### `stop` or `async_stop`
|
||||
Stop the vacuum cleaner, do not return to base.
|
||||
|
||||
### `clean_spot` or `async_clean_spot`
|
||||
Perform a spot clean-up.
|
||||
|
||||
### `locate` or `async_locate`
|
||||
Locate the vacuum cleaner.
|
||||
|
||||
### `set_cleaning_mode` or `async_set_cleaning_mode`
|
||||
Set the cleaning mode.
|
||||
|
||||
### `send_command` or `async_send_command`
|
||||
Send a command to a vacuum cleaner.
|
180
website/versioned_docs/version-0.74.0/hassio_addon_tutorial.md
Normal file
180
website/versioned_docs/version-0.74.0/hassio_addon_tutorial.md
Normal file
@ -0,0 +1,180 @@
|
||||
---
|
||||
title: Tutorial: Making your first add-on
|
||||
id: version-0.74.0-hassio_addon_tutorial
|
||||
original_id: hassio_addon_tutorial
|
||||
---
|
||||
|
||||
So you've got Home Assistant going and you've been enjoying the built-in add-ons but you're missing this one application. Time to make your own add-on! In Hass.io 0.24 we introduced the option to have local add-ons be build on your device. This is great for developing new add-ons locally.
|
||||
|
||||
To get started with developing add-ons, we first need access to where Hass.io looks for local add-ons. For this you can use the Samba add-on or the SSH add-on.
|
||||
|
||||
For Samba, once you have enabled and started it, your Hass.io instance will show up in your local network tab and share a folder called "addons". This is the folder to store your custom add-ons.
|
||||
|
||||
If you are on macOS and the folder is not showing up automatically, go to Finder and press CMD+K then enter 'smb://hassio.local'
|
||||
|
||||

|
||||
|
||||
For SSH, you will have to install it. Before you can start it, you will have to have a private/public key pair and store your public key in the add-on config ([see docs for more info][ssh]). Once started, you can SSH to Hass.io and store your custom add-ons in "/addons".
|
||||
|
||||

|
||||
|
||||
Once you have located your add-on directory, it's time to get started!
|
||||
|
||||
[ssh]: https://www.home-assistant.io/addons/ssh/
|
||||
|
||||
## Step 1: The basics
|
||||
|
||||
- Create a new directory called `hello_world`
|
||||
- Inside that directory create three files.
|
||||
|
||||
`Dockerfile`:
|
||||
```
|
||||
ARG BUILD_FROM
|
||||
FROM $BUILD_FROM
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
|
||||
# Copy data for add-on
|
||||
COPY run.sh /
|
||||
RUN chmod a+x /run.sh
|
||||
|
||||
CMD [ "/run.sh" ]
|
||||
```
|
||||
|
||||
`config.json`:
|
||||
```json
|
||||
{
|
||||
"name": "Hello world",
|
||||
"version": "1",
|
||||
"slug": "hello_world",
|
||||
"description": "My first real add-on!",
|
||||
"startup": "before",
|
||||
"boot": "auto",
|
||||
"options": {},
|
||||
"schema": {}
|
||||
}
|
||||
```
|
||||
|
||||
`run.sh`:
|
||||
```bash
|
||||
echo Hello world!
|
||||
```
|
||||
Make sure your editor is using UNIX-like line breaks (LF), not Dos/Windows (CRLF).
|
||||
|
||||
## Step 2: Installing and testing your add-on
|
||||
|
||||
Now comes the fun part, time to open the Hass.io UI and install and run your add-on.
|
||||
|
||||
- Open the Home Assistant frontend
|
||||
- Go to the Hass.io panel
|
||||
- On the top right click the shopping basket to go to the add-on store.
|
||||
|
||||

|
||||
|
||||
- On the top right click the refresh button
|
||||
- You should now see a new card called "Local" that lists your add-on!
|
||||
|
||||

|
||||
|
||||
- Click on your add-on to go to the add-on details page.
|
||||
- Install your add-on
|
||||
- Start your add-on
|
||||
- Refresh the logs of your add-on, you should now see "Hello world!" in your logs.
|
||||
|
||||

|
||||
|
||||
### I don't see my add-on?!
|
||||
|
||||
Oops! You clicked refresh in the store and your add-on didn't show up. Or maybe you just updated an option, clicked refresh and saw your add-on disappear.
|
||||
|
||||
When this happens, it means that your `config.json` is invalid. It's either invalid JSON or one of the specified options is incorrect. To see what went wrong, go to the Hass.io panel and in the supervisor card click on "View logs". This should bring you to a page with the logs of the supervisor. Scroll to the bottom and you should be able to find the validation error.
|
||||
|
||||
Once you fixed the error, go to the add-on store and click refresh again.
|
||||
|
||||
## Step 3: Hosting a server
|
||||
|
||||
Until now we've been able to do some basic stuff, but it's not very useful yet. So let's take it one step further and host a server that we expose on a port. For this we're going to use the built-in HTTP server that comes with Python 3.
|
||||
|
||||
To do this, we will need to update our files as follows:
|
||||
|
||||
- `Dockerfile`: Install Python 3
|
||||
- `config.json`: Make the port from the container available on the host
|
||||
- `run.sh`: Run the Python 3 command to start the HTTP server
|
||||
|
||||
Add to your `Dockerfile` before `RUN`:
|
||||
|
||||
```
|
||||
# Install requirements for add-on
|
||||
RUN apk add --no-cache python3
|
||||
|
||||
# Python 3 HTTP Server serves the current working dir
|
||||
# So let's set it to our add-on persistent data directory.
|
||||
WORKDIR /data
|
||||
```
|
||||
|
||||
Add "ports" to `config.json`. This will make TCP on port 8000 inside the container available on the host on port 8000.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Hello world",
|
||||
"version": "0.2",
|
||||
"slug": "hello_world",
|
||||
"description": "My first real add-on!",
|
||||
"startup": "before",
|
||||
"boot": "auto",
|
||||
"options": {},
|
||||
"schema": {},
|
||||
"ports": {
|
||||
"8000/tcp": 8000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Update `run.sh` to start the Python 3 server:
|
||||
|
||||
```
|
||||
python3 -m http.server
|
||||
```
|
||||
|
||||
## Step 4: Installing the update
|
||||
|
||||
Since we updated the version number in our `config.json`, Home Assistant will show an update button when looking at the add-on details. You might have to refresh your browser or click the refresh button in the add-on store for it to show up. If you did not update the version number, you can also uninstall and install the add-on again. After installing the add-on again, make sure you start it.
|
||||
|
||||
Now navigate to [http://hassio.local:8000](http://hassio.local:8000) to see our server in action!
|
||||
|
||||

|
||||
|
||||
## Bonus: Working with add-on options
|
||||
|
||||
In the screenshot you've probably seen that our server only served up 1 file: `options.json`. This file contains the user configuration for this add-on. Because we specified an empty "config" and "schema" in our `config.json`, the file is currently empty.
|
||||
|
||||
Let's see if we can get some data into that file!
|
||||
|
||||
To do this, we need to specify the default options and a schema for the user to change the options.
|
||||
|
||||
Change the options and schema entries in your `config.json` with the following:
|
||||
|
||||
```json
|
||||
{
|
||||
…
|
||||
|
||||
"options": {
|
||||
"beer": true,
|
||||
"wine": true,
|
||||
"liquor": false,
|
||||
"name": "world",
|
||||
"year": 2017
|
||||
},
|
||||
"schema": {
|
||||
"beer": "bool",
|
||||
"wine": "bool",
|
||||
"liquor": "bool",
|
||||
"name": "str",
|
||||
"year": "int"
|
||||
},
|
||||
|
||||
…
|
||||
}
|
||||
```
|
||||
|
||||
Refresh the add-on store and re-install your add-on. You will now see the options available in the add-on config screen. When you now go back to our Python 3 server and download `options.json`, you'll see the options you set. [Example of how options.json can be used inside `run.sh`](https://github.com/home-assistant/hassio-addons/blob/master/mosquitto/run.sh#L4-L6)
|
@ -0,0 +1,13 @@
|
||||
---
|
||||
title: Internationalization
|
||||
id: version-0.74.0-internationalization_index
|
||||
original_id: internationalization_index
|
||||
---
|
||||
|
||||
The Home Assistant internationalization project includes preparing platforms and the frontend for localization, as well as the actual translation of localized strings.
|
||||
|
||||
Some components and platforms will have strings that need to be localized specifically for that platform. These strings are managed in the core [home-assistant](https://github.com/home-assistant/home-assistant) repository. The Home Assistant backend will serve strings to the clients based on the loaded components in the running instance.
|
||||
|
||||
There are also localizable strings that exist only on the frontend. These strings are managed in the [home-assistant-polymer](https://github.com/home-assistant/home-assistant-polymer) repository. These strings are stored with the frontend and don’t depend on the backend configuration.
|
||||
|
||||
Our strings are translated by the community using the online translation tool [Lokalise](https://lokalise.co/).
|
211
website/versioned_docs/version-0.74.0/lovelace_custom_card.md
Normal file
211
website/versioned_docs/version-0.74.0/lovelace_custom_card.md
Normal file
@ -0,0 +1,211 @@
|
||||
---
|
||||
title: Lovelace: Custom Cards
|
||||
id: version-0.74.0-lovelace_custom_card
|
||||
original_id: lovelace_custom_card
|
||||
---
|
||||
|
||||
[Lovelace](https://www.home-assistant.io/lovelace/) is our new approach to defining your user interface for Home Assistant. We offer a lot of built-in cards, but you're not just limited to the ones that we decided to include in the Lovelace UI. You can build and use your own!
|
||||
|
||||
## API
|
||||
|
||||
You define your custom card as a [custom element](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements). It's up to you to decide how to render your DOM inside your element. You can use Polymer, Angular, Preact or any other popular framework (except for React – [more info on React here](https://custom-elements-everywhere.com/#react)).
|
||||
|
||||
```js
|
||||
const element = document.createElement('some-custom-card');
|
||||
```
|
||||
|
||||
Home Assistant will call `setConfig(config)` when the configuration changes (rare). If you throw an exception if the configuration is invalid, Lovelace will render an error card to notify the user.
|
||||
|
||||
```js
|
||||
try {
|
||||
element.setConfig(config);
|
||||
} catch (err) {
|
||||
showErrorCard(err.message, config);
|
||||
}
|
||||
```
|
||||
|
||||
Home Assistant will set the `hass` property when the state of Home Assistant changes (frequent). Whenever the state changes, the component will have to update itself to represent the latest state.
|
||||
|
||||
```js
|
||||
element.hass = hass;
|
||||
```
|
||||
|
||||
Your card can define a `getCardSize` method that returns the size of your card as a number. A height of 1 is equivalent to 50 pixels. This will help Home Assistant distribute the cards evenly over the columns. A card size of `1` will be assumed if the method is not defined.
|
||||
|
||||
```js
|
||||
if ('getCardSize' in element) {
|
||||
return element.getCardSize();
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
```
|
||||
|
||||
## Defining your card
|
||||
|
||||
Create a new file in your Home Assistant config dir as `<config>/www/content-card-example.js` and put in the following contents:
|
||||
|
||||
```js
|
||||
class ContentCardExample extends HTMLElement {
|
||||
set hass(hass) {
|
||||
if (!this.content) {
|
||||
const card = document.createElement('ha-card');
|
||||
card.header = 'Example card';
|
||||
this.content = document.createElement('div');
|
||||
this.content.style.padding = '0 16px 16px';
|
||||
card.appendChild(this.content);
|
||||
this.appendChild(card);
|
||||
}
|
||||
|
||||
const entityId = this.config.entity;
|
||||
const state = hass.states[entityId];
|
||||
const stateStr = state ? state.state : 'unavailable';
|
||||
|
||||
this.content.innerHTML = `
|
||||
The state of ${entityId} is ${stateStr}!
|
||||
<br><br>
|
||||
<img src="http://via.placeholder.com/350x150">
|
||||
`;
|
||||
}
|
||||
|
||||
setConfig(config) {
|
||||
if (!config.entity) {
|
||||
throw new Error('You need to define an entity');
|
||||
}
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
// The height of your card. Home Assistant uses this to automatically
|
||||
// distribute all cards over the available columns.
|
||||
getCardSize() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('content-card-example', ContentCardExample);
|
||||
```
|
||||
|
||||
## Referencing your new card
|
||||
|
||||
In our example card we defined a card with the tag `content-card-example` (see last line), so our card type will be `custom:content-card-example`. And because you created the file in your `<config>/www` directory, it will be accessible in your browser via the url `/local/`.
|
||||
|
||||
```yaml
|
||||
# Example ui-lovelace.yaml
|
||||
resources:
|
||||
- url: /local/content-card-example.js
|
||||
type: js
|
||||
views:
|
||||
- name: Example
|
||||
cards:
|
||||
- type: "custom:content-card-example"
|
||||
entity: input_boolean.switch_tv
|
||||
```
|
||||
|
||||
## Advanced example
|
||||
|
||||
Resources to load in Lovelace can be imported as a JS script, an HTML import or as a JS module import. Below is an example of a custom card using JS modules that does all the fancy things.
|
||||
|
||||

|
||||
|
||||
Create a new file in your Home Assistant config dir as `<config>/www/wired-cards.js` and put in the following contents:
|
||||
|
||||
```js
|
||||
import 'https://unpkg.com/wired-card@0.6.5/wired-card.js?module';
|
||||
import 'https://unpkg.com/wired-toggle@0.6.5/wired-toggle.js?module';
|
||||
import {
|
||||
LitElement, html
|
||||
} from 'https://unpkg.com/@polymer/lit-element@^0.5.2/lit-element.js?module';
|
||||
|
||||
function loadCSS(url) {
|
||||
const link = document.createElement('link');
|
||||
link.type = 'text/css';
|
||||
link.rel = 'stylesheet';
|
||||
link.href = url;
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
|
||||
loadCSS('https://fonts.googleapis.com/css?family=Gloria+Hallelujah');
|
||||
|
||||
class WiredToggleCard extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
config: Object,
|
||||
}
|
||||
}
|
||||
|
||||
_render({ hass, config }) {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
font-family: 'Gloria Hallelujah', cursive;
|
||||
}
|
||||
wired-card {
|
||||
background-color: white;
|
||||
padding: 16px;
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
}
|
||||
.state {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
wired-toggle {
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
||||
<wired-card elevation="2">
|
||||
${config.entities.map(ent => hass.states[ent]).map((state) =>
|
||||
html`
|
||||
<div class='state'>
|
||||
${state.attributes.friendly_name}
|
||||
<wired-toggle
|
||||
checked="${state.state === 'on'}"
|
||||
on-change="${ev => this._toggle(state)}"
|
||||
></wired-toggle>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</wired-card>
|
||||
`;
|
||||
}
|
||||
|
||||
setConfig(config) {
|
||||
if (!config.entities) {
|
||||
throw new Error('You need to define entities');
|
||||
}
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
// The height of your card. Home Assistant uses this to automatically
|
||||
// distribute all cards over the available columns.
|
||||
getCardSize() {
|
||||
return this.config.entities.length + 1;
|
||||
}
|
||||
|
||||
_toggle(state) {
|
||||
this.hass.callService('homeassistant', 'toggle', {
|
||||
entity_id: state.entity_id
|
||||
});
|
||||
}
|
||||
}
|
||||
customElements.define('wired-toggle-card', WiredToggleCard);
|
||||
```
|
||||
|
||||
And for your configuration:
|
||||
|
||||
```yaml
|
||||
# Example ui-lovelace.yaml
|
||||
resources:
|
||||
- url: /local/wired-cards.js
|
||||
type: module
|
||||
views:
|
||||
- name: Example
|
||||
cards:
|
||||
- type: "custom:wired-toggle-card"
|
||||
entities:
|
||||
- input_boolean.switch_ac_kitchen
|
||||
- input_boolean.switch_ac_livingroom
|
||||
- input_boolean.switch_tv
|
||||
```
|
151
website/versioned_sidebars/version-0.74.0-sidebars.json
Normal file
151
website/versioned_sidebars/version-0.74.0-sidebars.json
Normal file
@ -0,0 +1,151 @@
|
||||
{
|
||||
"version-0.74.0-Architecture": {
|
||||
"Architecture": [
|
||||
"version-0.74.0-architecture_index",
|
||||
"version-0.74.0-architecture_components",
|
||||
"version-0.74.0-architecture_entities",
|
||||
"version-0.74.0-architecture_hassio"
|
||||
],
|
||||
"Entities": [
|
||||
"version-0.74.0-entity_index",
|
||||
"version-0.74.0-entity_alarm_control_panel",
|
||||
"version-0.74.0-entity_binary_sensor",
|
||||
"version-0.74.0-entity_climate",
|
||||
"version-0.74.0-entity_cover",
|
||||
"version-0.74.0-entity_fan",
|
||||
"version-0.74.0-entity_light",
|
||||
"version-0.74.0-entity_lock",
|
||||
"version-0.74.0-entity_media_player",
|
||||
"version-0.74.0-entity_remote",
|
||||
"version-0.74.0-entity_sensor",
|
||||
"version-0.74.0-entity_switch",
|
||||
"version-0.74.0-entity_vacuum",
|
||||
"version-0.74.0-entity_weather"
|
||||
],
|
||||
"Authentication": [
|
||||
"version-0.74.0-auth_index",
|
||||
"version-0.74.0-auth_api",
|
||||
"version-0.74.0-auth_auth_provider"
|
||||
],
|
||||
"Configuration.yaml": [
|
||||
"version-0.74.0-configuration_yaml_index"
|
||||
],
|
||||
"Config Entries": [
|
||||
"version-0.74.0-config_entries_index",
|
||||
"version-0.74.0-config_entries_config_flow_handler"
|
||||
],
|
||||
"Data Entry Flow": [
|
||||
"version-0.74.0-data_entry_flow_index"
|
||||
],
|
||||
"Entity Registry": [
|
||||
"version-0.74.0-entity_registry_index"
|
||||
]
|
||||
},
|
||||
"version-0.74.0-Extending Frontend": {
|
||||
"Frontend": [
|
||||
"version-0.74.0-frontend_index",
|
||||
"version-0.74.0-frontend_architecture",
|
||||
"version-0.74.0-frontend_development"
|
||||
],
|
||||
"Extending the frontend": [
|
||||
"version-0.74.0-frontend_add_card",
|
||||
"version-0.74.0-frontend_add_more_info",
|
||||
"version-0.74.0-frontend_add_websocket_api"
|
||||
],
|
||||
"Custom UI": [
|
||||
"version-0.74.0-lovelace_custom_card",
|
||||
"version-0.74.0-frontend_creating_custom_ui",
|
||||
"version-0.74.0-frontend_creating_custom_panels"
|
||||
]
|
||||
},
|
||||
"version-0.74.0-Extending HASS": {
|
||||
"Developing a feature": [
|
||||
"version-0.74.0-development_index",
|
||||
"version-0.74.0-development_environment",
|
||||
"version-0.74.0-development_submitting",
|
||||
"version-0.74.0-development_checklist",
|
||||
"version-0.74.0-development_guidelines",
|
||||
"version-0.74.0-development_testing",
|
||||
"version-0.74.0-development_catching_up",
|
||||
"version-0.74.0-development_validation",
|
||||
"version-0.74.0-development_typing"
|
||||
],
|
||||
"Development 101": [
|
||||
"version-0.74.0-dev_101_index",
|
||||
"version-0.74.0-dev_101_hass",
|
||||
"version-0.74.0-dev_101_events",
|
||||
"version-0.74.0-dev_101_states",
|
||||
"version-0.74.0-dev_101_services",
|
||||
"version-0.74.0-dev_101_config"
|
||||
],
|
||||
"Creating Platforms": [
|
||||
"version-0.74.0-creating_platform_index",
|
||||
"version-0.74.0-creating_platform_code_review",
|
||||
"version-0.74.0-creating_platform_example_light",
|
||||
"version-0.74.0-creating_platform_example_sensor"
|
||||
],
|
||||
"Creating Components": [
|
||||
"version-0.74.0-creating_component_index",
|
||||
"version-0.74.0-creating_component_code_review",
|
||||
"version-0.74.0-creating_component_deps_and_reqs",
|
||||
"version-0.74.0-creating_component_events",
|
||||
"version-0.74.0-creating_component_states",
|
||||
"version-0.74.0-creating_component_discovery",
|
||||
"version-0.74.0-creating_component_loading",
|
||||
"version-0.74.0-creating_component_generic_discovery"
|
||||
]
|
||||
},
|
||||
"version-0.74.0-Misc": {
|
||||
"Introduction": [
|
||||
"version-0.74.0-misc"
|
||||
],
|
||||
"External API": [
|
||||
"version-0.74.0-external_api_rest",
|
||||
"version-0.74.0-external_api_rest_python",
|
||||
"version-0.74.0-external_api_websocket",
|
||||
"version-0.74.0-external_api_server_sent_events"
|
||||
],
|
||||
"Internationalization": [
|
||||
"version-0.74.0-internationalization_index",
|
||||
"version-0.74.0-internationalization_backend_localization",
|
||||
"version-0.74.0-internationalization_custom_component_localization",
|
||||
"version-0.74.0-internationalization_translation"
|
||||
],
|
||||
"Documentation": [
|
||||
"version-0.74.0-documentation_index",
|
||||
"version-0.74.0-documentation_standards",
|
||||
"version-0.74.0-documentation_create_page"
|
||||
],
|
||||
"Intents": [
|
||||
"version-0.74.0-intent_index",
|
||||
"version-0.74.0-intent_firing",
|
||||
"version-0.74.0-intent_handling",
|
||||
"version-0.74.0-intent_conversation",
|
||||
"version-0.74.0-intent_builtin"
|
||||
],
|
||||
"asyncio": [
|
||||
"version-0.74.0-asyncio_index",
|
||||
"version-0.74.0-asyncio_101",
|
||||
"version-0.74.0-asyncio_categorizing_functions",
|
||||
"version-0.74.0-asyncio_working_with_async"
|
||||
],
|
||||
"Hass.io": [
|
||||
"version-0.74.0-hassio_debugging",
|
||||
"version-0.74.0-hassio_hass"
|
||||
],
|
||||
"Hass.io Add-Ons": [
|
||||
"version-0.74.0-hassio_addon_index",
|
||||
"version-0.74.0-hassio_addon_tutorial",
|
||||
"version-0.74.0-hassio_addon_config",
|
||||
"version-0.74.0-hassio_addon_communication",
|
||||
"version-0.74.0-hassio_addon_testing",
|
||||
"version-0.74.0-hassio_addon_publishing",
|
||||
"version-0.74.0-hassio_addon_presentation",
|
||||
"version-0.74.0-hassio_addon_repository"
|
||||
],
|
||||
"Maintainer docs": [
|
||||
"version-0.74.0-maintenance",
|
||||
"version-0.74.0-releasing"
|
||||
]
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
[
|
||||
"0.74.0",
|
||||
"0.73.0",
|
||||
"0.72"
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user