mirror of
https://github.com/home-assistant/home-assistant.io.git
synced 2025-07-23 17:27:19 +00:00
Merge branch 'current' into rc
This commit is contained in:
commit
a5dcedc160
@ -313,6 +313,7 @@ Supported abbreviations for device registry configuration:
|
|||||||
The following software has built-in support for MQTT discovery:
|
The following software has built-in support for MQTT discovery:
|
||||||
|
|
||||||
- [Arilux AL-LC0X LED controllers](https://github.com/smrtnt/Arilux_AL-LC0X)
|
- [Arilux AL-LC0X LED controllers](https://github.com/smrtnt/Arilux_AL-LC0X)
|
||||||
|
- [ebusd](https://github.com/john30/ebusd)
|
||||||
- [ecowitt2mqtt](https://github.com/bachya/ecowitt2mqtt)
|
- [ecowitt2mqtt](https://github.com/bachya/ecowitt2mqtt)
|
||||||
- [ESPHome](https://esphome.io)
|
- [ESPHome](https://esphome.io)
|
||||||
- [ESPurna](https://github.com/xoseperez/espurna)
|
- [ESPurna](https://github.com/xoseperez/espurna)
|
||||||
|
@ -388,6 +388,7 @@ The sunset/sunrise conditions do not work in locations inside the polar circles,
|
|||||||
In those cases it is advised to use conditions evaluating the solar elevation instead of the before/after sunset/sunrise conditions.
|
In those cases it is advised to use conditions evaluating the solar elevation instead of the before/after sunset/sunrise conditions.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
This is an example of 1 hour offset after sunset:
|
||||||
```yaml
|
```yaml
|
||||||
condition:
|
condition:
|
||||||
condition: sun
|
condition: sun
|
||||||
@ -395,7 +396,7 @@ condition:
|
|||||||
after_offset: "-01:00:00"
|
after_offset: "-01:00:00"
|
||||||
```
|
```
|
||||||
|
|
||||||
This is an example of 1 hour offset after sunset.
|
This is 'when dark' - equivalent to a state condition on `sun.sun` of `below_horizon`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
condition:
|
condition:
|
||||||
@ -404,7 +405,7 @@ condition:
|
|||||||
before: sunrise
|
before: sunrise
|
||||||
```
|
```
|
||||||
|
|
||||||
This is 'when dark' - equivalent to a state condition on `sun.sun` of `below_horizon`.
|
This is 'when light' - equivalent to a state condition on `sun.sun` of `above_horizon`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
condition:
|
condition:
|
||||||
@ -413,8 +414,6 @@ condition:
|
|||||||
before: sunset
|
before: sunset
|
||||||
```
|
```
|
||||||
|
|
||||||
This is 'when light' - equivalent to a state condition on `sun.sun` of `above_horizon`.
|
|
||||||
|
|
||||||
We cannot use both keys in this case as it will always be `false`.
|
We cannot use both keys in this case as it will always be `false`.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@ -429,7 +428,7 @@ condition:
|
|||||||
|
|
||||||
A visual timeline is provided below showing an example of when these conditions are true. In this chart, sunrise is at 6:00, and sunset is at 18:00 (6:00 PM). The green areas of the chart indicate when the specified conditions are true.
|
A visual timeline is provided below showing an example of when these conditions are true. In this chart, sunrise is at 6:00, and sunset is at 18:00 (6:00 PM). The green areas of the chart indicate when the specified conditions are true.
|
||||||
|
|
||||||
<img src='/images/docs/scripts/sun-conditions.svg' alt='Graphic showing an example of sun conditions' />
|

|
||||||
|
|
||||||
## Template condition
|
## Template condition
|
||||||
|
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
<p class='hero-buttons'>
|
<p class='hero-buttons'>
|
||||||
<a href='/getting-started/'>Get started</a>
|
<a href='/getting-started/'>Get started</a>
|
||||||
<a href='https://demo.home-assistant.io' target='_blank'>View demo</a>
|
<a href='https://demo.home-assistant.io' target='_blank'>View demo</a>
|
||||||
<a href='/integrations/'>Browse 1000+ integrations</a>
|
<a href='/integrations/'>Browse 1900+ integrations</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -207,11 +207,20 @@ _All these can be extended if your usage calls for more resources._
|
|||||||
- title: VirtualBox
|
- title: VirtualBox
|
||||||
content: |
|
content: |
|
||||||
1. Create a new virtual machine
|
1. Create a new virtual machine
|
||||||
2. Select Type “Linux” and Version “Other Linux (64-bit)”
|
2. Select Type “Linux” and Version “Linux 2.6 / 3.x / 4.x (64-bit)”
|
||||||
3. Select “Use an existing virtual hard disk file”, select the unzipped VDI file from above
|
3. Select “Use an existing virtual hard disk file”, select the unzipped VDI file from above
|
||||||
4. Edit the “Settings” of the VM and go “System” then “Motherboard” and select “Enable EFI”
|
4. Edit the “Settings” of the VM and go “System” then “Motherboard” and select “Enable EFI”
|
||||||
5. Then go to “Network” “Adapter 1” choose “Bridged Adapter” and choose your Network adapter
|
5. Then go to “Network” “Adapter 1” choose “Bridged Adapter” and choose your Network adapter
|
||||||
6. Then go to “Audio” and choose “Intel HD Audio” as Audio Controller.
|
6. Then go to “Audio” and choose “Intel HD Audio” as Audio Controller.
|
||||||
|
<div class="note info">
|
||||||
|
|
||||||
|
By default VirtualBox does not free up unused disk space. To automatically shrink the vdi disk image
|
||||||
|
the `discard` option must be enabled:
|
||||||
|
```bash
|
||||||
|
VBoxManage storageattach <VM name> --storagectl "SATA" --port 0 --device 0 --nonrotational on --discard on
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
- title: KVM
|
- title: KVM
|
||||||
content: |
|
content: |
|
||||||
|
@ -129,6 +129,10 @@ The `button.<your_vehicle>_find_vehicle` button requests the vehicle to update t
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
### Update the state / refresh from cloud
|
||||||
|
|
||||||
|
The `button.<vehicle_model>_refresh_from_cloud` button fetches the last state of the vehicles of all your accounts from the BMW server. This does *not* trigger an update from the vehicle; it gets the data from the BMW servers. So this service does *not* interact with your vehicles.
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
This software is not affiliated with or endorsed by BMW Group.
|
This software is not affiliated with or endorsed by BMW Group.
|
||||||
|
@ -28,7 +28,7 @@ download_dir:
|
|||||||
|
|
||||||
### Use the service
|
### Use the service
|
||||||
|
|
||||||
Go to the "Developer Tools", then to "Call Service", and choose `downloader/download_file` from the list of available services. Fill the "Service Data" field as shown in the example below and hit "CALL SERVICE".
|
Go to the "Developer Tools", then to "Services", and choose `downloader/download_file` from the list of available services. Fill the "Service Data" field as shown in the example below and hit "CALL SERVICE".
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{"url":"http://domain.tld/path/to/file"}
|
{"url":"http://domain.tld/path/to/file"}
|
||||||
@ -45,8 +45,8 @@ This will download the file from the given URL.
|
|||||||
|
|
||||||
### Download Status Events
|
### Download Status Events
|
||||||
|
|
||||||
When a download finished successfully, Home Assistant will emit a 'downloader_download_completed' event to the event bus which you can use to write automations against.
|
When a download finished successfully, Home Assistant will emit a `downloader_download_completed` event to the event bus which you can use to write automations against.
|
||||||
In case download failed another event 'downloader_download_failed' is emitted to indicate that the download did not complete successfully.
|
In case download failed another event `downloader_download_failed` is emitted to indicate that the download did not complete successfully.
|
||||||
|
|
||||||
Along with the event the following payload parameters are available:
|
Along with the event the following payload parameters are available:
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ For secure remote access, use a reverse proxy such as the {% my supervisor_addon
|
|||||||
|
|
||||||
1. Open the project you created in the [Actions on Google console](https://console.actions.google.com/).
|
1. Open the project you created in the [Actions on Google console](https://console.actions.google.com/).
|
||||||
2. Click `Develop` on the top of the page, then click `Actions` located in the hamburger menu on the top left.
|
2. Click `Develop` on the top of the page, then click `Actions` located in the hamburger menu on the top left.
|
||||||
3. Upload [this Javascript file](/assets/integrations/google_assistant/app.js) for both Node and Chrome by clicking the `Upload Javascript files` button.
|
3. Upload `app.js` from [here](https://github.com/NabuCasa/home-assistant-google-assistant-local-sdk/releases/latest) for both Node and Chrome by clicking the `Upload Javascript files` button.
|
||||||
4. Add device scan configuration:
|
4. Add device scan configuration:
|
||||||
1. Click `+ New scan config` if no configuration exists
|
1. Click `+ New scan config` if no configuration exists
|
||||||
2. Select `MDNS`
|
2. Select `MDNS`
|
||||||
|
@ -293,3 +293,18 @@ When a group contains entities from domains that have multiple `on` states or on
|
|||||||
It is possible to create a group that the system cannot calculate a group state. Groups with entities from unsupported domains will always have an unknown state.
|
It is possible to create a group that the system cannot calculate a group state. Groups with entities from unsupported domains will always have an unknown state.
|
||||||
|
|
||||||
These groups can still be in templates with the `expand()` directive, called using the `homeassistant.turn_on` and `homeassistant.turn_off` services, etc.
|
These groups can still be in templates with the `expand()` directive, called using the `homeassistant.turn_on` and `homeassistant.turn_off` services, etc.
|
||||||
|
|
||||||
|
### Services
|
||||||
|
|
||||||
|
This integration provides the following services to modify groups and a service to reload the configuration without restarting Home Assistant itself.
|
||||||
|
|
||||||
|
| Service | Data | Description |
|
||||||
|
| ------- | ---- | ----------- |
|
||||||
|
| `set` | `Object ID` | Group id and part of entity id.
|
||||||
|
| | `Name` | Name of the group.
|
||||||
|
| | `Icon` | Name of the icon for the group.
|
||||||
|
| | `Entities` | List of all members in the group. Not compatible with **delta**.
|
||||||
|
| | `Add Entities` | List of members that will change on group listening.
|
||||||
|
| | `All` | Enable this option if the group should only turn on when all entities are on.
|
||||||
|
| `remove` | `Object ID` | Group id and part of entity id.
|
||||||
|
| `reload` | `Object ID` | Group id and part of entity id.
|
||||||
|
@ -45,11 +45,11 @@ To obtain the `oauth_code` cookie value, follow the steps below:
|
|||||||
* In the cookie list, double click on the value for the `oauth_code` cookie to select it, and copy the value. This is the authorization code
|
* In the cookie list, double click on the value for the `oauth_code` cookie to select it, and copy the value. This is the authorization code
|
||||||
|
|
||||||
<div class='note'>
|
<div class='note'>
|
||||||
You can't write messages to yourself or get notifications in a group, if "you" write the message. The best way is to create a new Google Hangouts account for this integration.<br>
|
You can't write messages to yourself or get notifications in a group, if "you" write the message. The best way is to create a new Google Chat account for this integration.<br>
|
||||||
<br>
|
<br>
|
||||||
If you secured your account with 2-factor authentication: Only verification by app or SMS are supported. There is no support for verification by prompt on your phone.<br>
|
If you secured your account with 2-factor authentication: Only verification by app or SMS are supported. There is no support for verification by prompt on your phone.<br>
|
||||||
<br>
|
<br>
|
||||||
The manual authentication work-around is a result of unofficial support for using bots in hangouts from Google.
|
The manual authentication work-around is a result of unofficial support for using bots in Chat from Google.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
The authentication token will be generated and stored internally.
|
The authentication token will be generated and stored internally.
|
||||||
|
@ -19,7 +19,7 @@ templates.
|
|||||||
The preferred way to configure input datetime is via the user interface at **Configuration** -> **Helpers**. Click the add button and then choose the **Date and/or time** option.
|
The preferred way to configure input datetime is via the user interface at **Configuration** -> **Helpers**. Click the add button and then choose the **Date and/or time** option.
|
||||||
|
|
||||||
To be able to add **Helpers** via the user interface you should have `default_config:` in your `configuration.yaml`, it should already be there by default unless you removed it.
|
To be able to add **Helpers** via the user interface you should have `default_config:` in your `configuration.yaml`, it should already be there by default unless you removed it.
|
||||||
If you removed `default_config:` from you configuration, you must add `input_datetime:` to your `configuration.yaml` first, then you can use the UI.
|
If you removed `default_config:` from your configuration, you must add `input_datetime:` to your `configuration.yaml` first, then you can use the UI.
|
||||||
|
|
||||||
`input_datetime` can also be configured via YAML. To add three datetime inputs to your installation,
|
`input_datetime` can also be configured via YAML. To add three datetime inputs to your installation,
|
||||||
one with both date and time, and one with date or time each,
|
one with both date and time, and one with date or time each,
|
||||||
@ -87,7 +87,7 @@ automations and templates.
|
|||||||
|
|
||||||
### Restore State
|
### Restore State
|
||||||
|
|
||||||
If you set a valid value for `initial` this integration will start with the state set to that value. Otherwise, it will restore the state it had prior to Home Assistant stopping.
|
If you set a valid value for `initial`, this integration will start with the state set to that value. Otherwise, it will restore the state it had prior to Home Assistant stopping.
|
||||||
|
|
||||||
### Services
|
### Services
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ The `mqtt` light platform lets you control your MQTT enabled lights through one
|
|||||||
| RGBW Color | ✔ | ✔ | ✘ |
|
| RGBW Color | ✔ | ✔ | ✘ |
|
||||||
| RGBWW Color | ✔ | ✔ | ✘ |
|
| RGBWW Color | ✔ | ✔ | ✘ |
|
||||||
| Transitions | ✘ | ✔ | ✔ |
|
| Transitions | ✘ | ✔ | ✔ |
|
||||||
|
| White | ✔ | ✔ | ✘ |
|
||||||
| XY Color | ✔ | ✔ | ✘ |
|
| XY Color | ✔ | ✔ | ✘ |
|
||||||
|
|
||||||
|
|
||||||
@ -299,17 +300,49 @@ rgb_command_template:
|
|||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
rgb_command_topic:
|
rgb_command_topic:
|
||||||
description: "The MQTT topic to publish commands to change the light's RGB state. Please note that the color value sent by Home Assistant is normalized to full brightness if `brightness_command_topic` is set. Brightness information is in this case sent separately in the `brightness_command_topic`. This will cause a light that expects an absolute color value (including brightness) to flicker."
|
description: "The MQTT topic to publish commands to change the light's RGB state."
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
rgb_state_topic:
|
rgb_state_topic:
|
||||||
description: "The MQTT topic subscribed to receive RGB state updates. The expected payload is the RGB values separated by commas, for example, `255,0,127`. Please note that the color value received by Home Assistant is normalized to full brightness. Brightness information is received separately in the `brightness_state_topic`."
|
description: "The MQTT topic subscribed to receive RGB state updates. The expected payload is the RGB values separated by commas, for example, `255,0,127`."
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
rgb_value_template:
|
rgb_value_template:
|
||||||
description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the RGB value."
|
description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the RGB value."
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
rgbw_command_template:
|
||||||
|
description: "Defines a [template](/docs/configuration/templating/) to compose message which will be sent to `rgbw_command_topic`. Available variables: `red`, `green`, `blue` and `white`."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
rgbw_command_topic:
|
||||||
|
description: "The MQTT topic to publish commands to change the light's RGBW state."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
rgbw_state_topic:
|
||||||
|
description: "The MQTT topic subscribed to receive RGBW state updates. The expected payload is the RGBW values separated by commas, for example, `255,0,127,64`."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
rgbw_value_template:
|
||||||
|
description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the RGBW value."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
rgbww_command_template:
|
||||||
|
description: "Defines a [template](/docs/configuration/templating/) to compose message which will be sent to `rgbww_command_topic`. Available variables: `red`, `green`, `blue`, `cold_white` and `warm_white`."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
rgbww_command_topic:
|
||||||
|
description: "The MQTT topic to publish commands to change the light's RGBWW state."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
rgbww_state_topic:
|
||||||
|
description: "The MQTT topic subscribed to receive RGBWW state updates. The expected payload is the RGBWW values separated by commas, for example, `255,0,127,64,32`."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
rgbww_value_template:
|
||||||
|
description: "Defines a [template](/docs/configuration/templating/#processing-incoming-data) to extract the RGBWW value."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
schema:
|
schema:
|
||||||
description: The schema to use. Must be `default` or omitted to select the default schema.
|
description: The schema to use. Must be `default` or omitted to select the default schema.
|
||||||
required: false
|
required: false
|
||||||
|
@ -26,15 +26,27 @@ Additionally the following brands have been reported to also work with this inte
|
|||||||
- [Brel Home](https://www.brel-home.nl/)
|
- [Brel Home](https://www.brel-home.nl/)
|
||||||
- [3 Day Blinds](https://www.3dayblinds.com/)
|
- [3 Day Blinds](https://www.3dayblinds.com/)
|
||||||
- [Dooya](http://www.dooya.com/)
|
- [Dooya](http://www.dooya.com/)
|
||||||
|
- [Gaviota](https://www.gaviotagroup.com/en/)
|
||||||
|
- [Havana Shade](https://havanashade.com/)
|
||||||
- [Hurrican Shutters Wholesale](https://www.hurricaneshutterswholesale.com/)
|
- [Hurrican Shutters Wholesale](https://www.hurricaneshutterswholesale.com/)
|
||||||
|
- [Inspired Shades](https://www.inspired-shades.com/)
|
||||||
- [iSmartWindow](https://www.ismartwindow.co.nz/)
|
- [iSmartWindow](https://www.ismartwindow.co.nz/)
|
||||||
- [Martec](https://www.martec.co.nz/)
|
- [Martec](https://www.martec.co.nz/)
|
||||||
- [Motion Blinds](https://motionblinds.com/)
|
- [Motion Blinds](https://motionblinds.com/)
|
||||||
- [Raven Rock MRG](https://www.ravenrockmfg.com/)
|
- [Raven Rock MFG](https://www.ravenrockmfg.com/)
|
||||||
- [Smart Blinds](https://www.smartblinds.nl/)
|
- [Smart Blinds](https://www.smartblinds.nl/)
|
||||||
- [Smart Home](https://www.smart-home.hu)
|
- [Smart Home](https://www.smart-home.hu)
|
||||||
- [Uprise Smart Shades](http://uprisesmartshades.com)
|
- [Uprise Smart Shades](http://uprisesmartshades.com)
|
||||||
|
|
||||||
|
This integration allows for both directly controlling blinds that support wifi-connection and controlling Uni- and Bi-direction blinds that connect to a 433MHz WiFi bridge.
|
||||||
|
The following bridges are reported to work with this integration:
|
||||||
|
- CM-20 Motion Blinds bridge
|
||||||
|
- CMD-01 Motion Blinds mini-bridge
|
||||||
|
- DD7002B Connector bridge
|
||||||
|
- D1554 Connector mini-bridge
|
||||||
|
- DD7002B Brel-Home box
|
||||||
|
- D1554 Brel Home USB plug
|
||||||
|
|
||||||
{% include integrations/config_flow.md %}
|
{% include integrations/config_flow.md %}
|
||||||
|
|
||||||
## Retrieving the API Key
|
## Retrieving the API Key
|
||||||
@ -61,6 +73,9 @@ In the Brel Home app on Android go to the `me` page (home screen 4th tab), tap 5
|
|||||||
|
|
||||||
The official Bloc Blinds app doesn't seem to hand out the API key on Android, it does seem to provide the API key on the iOS version of the official Bloc Blinds app.
|
The official Bloc Blinds app doesn't seem to hand out the API key on Android, it does seem to provide the API key on the iOS version of the official Bloc Blinds app.
|
||||||
|
|
||||||
|
### Connector app
|
||||||
|
Click the about page of the connector app 5 times to get the key ([iOS app](https://apps.apple.com/us/app/connector/id1344058317), [Android app](https://play.google.com/store/apps/details?id=com.smarthome.app.connector)).
|
||||||
|
|
||||||
## Top Down Bottom Up (TDBU) blinds
|
## Top Down Bottom Up (TDBU) blinds
|
||||||
|
|
||||||
TDBU blinds consist of two bars controlled by two motors designated by Top and Bottom with fabric in between.
|
TDBU blinds consist of two bars controlled by two motors designated by Top and Bottom with fabric in between.
|
||||||
|
31
source/_posts/2022-04-30-creator-network-launched.markdown
Normal file
31
source/_posts/2022-04-30-creator-network-launched.markdown
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
title: "Introducing the Home Assistant Creator Network!"
|
||||||
|
description: "We are looking to invest into our community and support the effort being put in."
|
||||||
|
date: 2022-04-29 00:00:00
|
||||||
|
date_formatted: "April 29, 2022"
|
||||||
|
comments: true
|
||||||
|
author: "Zack Barett"
|
||||||
|
categories: Community
|
||||||
|
og_image: /images/blog/2022-04-30-creator-network/CreatorNetwork_social.jpg
|
||||||
|
---
|
||||||
|
|
||||||
|
Hey Everyone! Today we are announcing our new program called the Home Assistant Creator Network! We are super excited to
|
||||||
|
start talking closely with creators to ensure everyone has the best information possible. We are looking to invest in our
|
||||||
|
community and support the effort being put into keeping our users informed. This is a way for Home Assistant to reward these
|
||||||
|
creators that are positively engaging with our users.
|
||||||
|
|
||||||
|
<p class='img'>
|
||||||
|
<img class="no-shadow" src='/images/blog/2022-04-30-creator-network/Creators.jpg' alt='Creators in the network'>
|
||||||
|
First Members of the Creator Network!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## What is the Creator Network?
|
||||||
|
|
||||||
|
The creator network will be a group of creators that are active and engaged with our community with consistent content that
|
||||||
|
builds the archive for Home Assistant. These creators are creating content for YouTube, Twitter, Instagram, TikTok, etc.
|
||||||
|
with the goal of helping people use Home Assistant. This can be through tutorials, unbiased product reviews, creating cool stuff and more.
|
||||||
|
|
||||||
|
We are looking forward to growing this network to be a group of creators that work together with each other and the Home Assistant Developers.
|
||||||
|
One of the biggest ways we are doing that is monthly calls with the network to discuss releases and upcoming changes.
|
||||||
|
|
||||||
|
Visit the [Home Assistant Creators Network](https://partner.home-assistant.io/creators/) for more information and how to apply.
|
@ -1,193 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
/// <reference types="@google/local-home-sdk" />
|
|
||||||
/*
|
|
||||||
BASED ON: https://github.com/NabuCasa/home-assistant-google-assistant-local-sdk
|
|
||||||
Only removed the fart sound at the end.
|
|
||||||
For license information please check the repository.
|
|
||||||
*/
|
|
||||||
var App = smarthome.App;
|
|
||||||
var Constants = smarthome.Constants;
|
|
||||||
var DataFlow = smarthome.DataFlow;
|
|
||||||
var Execute = smarthome.Execute;
|
|
||||||
var Intents = smarthome.Intents;
|
|
||||||
var IntentFlow = smarthome.IntentFlow;
|
|
||||||
const findHassCustomDeviceDataByMdnsData = (requestId, devices, mdnsScanData) => {
|
|
||||||
let device;
|
|
||||||
device = devices.find((dev) => {
|
|
||||||
const customData = dev.customData;
|
|
||||||
return (customData &&
|
|
||||||
"webhookId" in customData &&
|
|
||||||
(!mdnsScanData.uuid || customData.uuid === mdnsScanData.uuid) &&
|
|
||||||
(!mdnsScanData.baseUrl || customData.baseUrl === mdnsScanData.baseUrl));
|
|
||||||
});
|
|
||||||
// backwards compatibility for HA < 0.109
|
|
||||||
if (!device) {
|
|
||||||
device = devices.find((dev) => dev.customData &&
|
|
||||||
"webhookId" in dev.customData);
|
|
||||||
}
|
|
||||||
if (!device) {
|
|
||||||
console.log(requestId, "Unable to find HASS connection info.", devices);
|
|
||||||
throw new IntentFlow.HandlerError(requestId, "invalidRequest", "Unable to find HASS connection info.");
|
|
||||||
}
|
|
||||||
return device.customData;
|
|
||||||
};
|
|
||||||
const findHassCustomDeviceDataByDeviceId = (requestId, devices, deviceId) => {
|
|
||||||
let device;
|
|
||||||
device = devices.find((dev) => {
|
|
||||||
const customData = dev.customData;
|
|
||||||
return (customData &&
|
|
||||||
"webhookId" in customData &&
|
|
||||||
customData.proxyDeviceId === deviceId);
|
|
||||||
});
|
|
||||||
if (!device) {
|
|
||||||
console.log(requestId, "Unable to find HASS connection info.", devices);
|
|
||||||
throw new IntentFlow.HandlerError(requestId, "invalidRequest", "Unable to find HASS connection info.");
|
|
||||||
}
|
|
||||||
return device.customData;
|
|
||||||
};
|
|
||||||
const createResponse = (request, payload) => ({
|
|
||||||
intent: request.inputs[0].intent,
|
|
||||||
requestId: request.requestId,
|
|
||||||
payload,
|
|
||||||
});
|
|
||||||
class UnknownInstance extends Error {
|
|
||||||
constructor(requestId) {
|
|
||||||
super();
|
|
||||||
this.requestId = requestId;
|
|
||||||
}
|
|
||||||
throwHandlerError() {
|
|
||||||
throw new IntentFlow.HandlerError(this.requestId, "invalidRequest", "Unknown Instance");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const forwardRequest = async (hassDeviceData, targetDeviceId, request) => {
|
|
||||||
const command = new DataFlow.HttpRequestData();
|
|
||||||
command.method = Constants.HttpOperation.POST;
|
|
||||||
command.requestId = request.requestId;
|
|
||||||
command.deviceId = targetDeviceId;
|
|
||||||
command.isSecure = hassDeviceData.httpSSL;
|
|
||||||
command.port = hassDeviceData.httpPort;
|
|
||||||
command.path = `/api/webhook/${hassDeviceData.webhookId}`;
|
|
||||||
command.data = JSON.stringify(request);
|
|
||||||
command.dataType = "application/json";
|
|
||||||
console.log(request.requestId, "Sending", command);
|
|
||||||
const deviceManager = await app.getDeviceManager();
|
|
||||||
let resp;
|
|
||||||
try {
|
|
||||||
resp = await new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => reject(-1), 10000);
|
|
||||||
deviceManager
|
|
||||||
.send(command)
|
|
||||||
.then((response) => resolve(response), reject);
|
|
||||||
});
|
|
||||||
// resp = (await deviceManager.send(command)) as HttpResponseData;
|
|
||||||
console.log(request.requestId, "Raw Response", resp);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.error(request.requestId, "Error making request", err);
|
|
||||||
throw new IntentFlow.HandlerError(request.requestId, "invalidRequest", err === -1 ? "Timeout" : err.message);
|
|
||||||
}
|
|
||||||
// Response if the webhook is not registered.
|
|
||||||
if (resp.httpResponse.statusCode === 200 && !resp.httpResponse.body) {
|
|
||||||
throw new UnknownInstance(request.requestId);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const response = JSON.parse(resp.httpResponse.body);
|
|
||||||
// Local SDK wants this.
|
|
||||||
response.intent = request.inputs[0].intent;
|
|
||||||
console.log(request.requestId, "Response", response);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.error(request.requestId, "Error parsing body", err);
|
|
||||||
throw new IntentFlow.HandlerError(request.requestId, "invalidRequest", err.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const identifyHandler = async (request) => {
|
|
||||||
console.log("IDENTIFY intent:", request);
|
|
||||||
const deviceToIdentify = request.inputs[0].payload.device;
|
|
||||||
if (!deviceToIdentify.mdnsScanData) {
|
|
||||||
console.error(request.requestId, "No usable mdns scan data");
|
|
||||||
return createResponse(request, {});
|
|
||||||
}
|
|
||||||
if (!deviceToIdentify.mdnsScanData.serviceName.endsWith("._home-assistant._tcp.local")) {
|
|
||||||
console.error(request.requestId, "Not Home Assistant type");
|
|
||||||
return createResponse(request, {});
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const hassCustomData = findHassCustomDeviceDataByMdnsData(request.requestId, request.devices, deviceToIdentify.mdnsScanData.txt);
|
|
||||||
return await forwardRequest(hassCustomData, "", request);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err instanceof UnknownInstance) {
|
|
||||||
return createResponse(request, {});
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const reachableDevicesHandler = async (request) => {
|
|
||||||
console.log("REACHABLE_DEVICES intent:", request);
|
|
||||||
const hassCustomData = findHassCustomDeviceDataByDeviceId(request.requestId, request.devices, request.inputs[0].payload.device.id);
|
|
||||||
try {
|
|
||||||
return forwardRequest(hassCustomData,
|
|
||||||
// Old code would sent it to the proxy ID: hassCustomData.proxyDeviceId
|
|
||||||
// But tutorial claims otherwise, but maybe it is not for hub devices??
|
|
||||||
// https://developers.google.com/assistant/smarthome/develop/local#implement_the_execute_handler
|
|
||||||
// Sending it to the device that has to receive the command as per the tutorial
|
|
||||||
request.inputs[0].payload.device.id, request);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err instanceof UnknownInstance) {
|
|
||||||
err.throwHandlerError();
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const executeHandler = async (request) => {
|
|
||||||
console.log("EXECUTE intent:", request);
|
|
||||||
const device = request.inputs[0].payload.commands[0].devices[0];
|
|
||||||
try {
|
|
||||||
return forwardRequest(device.customData, device.id, request);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err instanceof UnknownInstance) {
|
|
||||||
err.throwHandlerError();
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const queryHandler = async (request) => {
|
|
||||||
console.log("QUERY intent:", request);
|
|
||||||
const device = request.inputs[0].payload.devices[0];
|
|
||||||
try {
|
|
||||||
return await forwardRequest(device.customData, device.id, request);
|
|
||||||
} catch (err) {
|
|
||||||
if (err instanceof UnknownInstance) {
|
|
||||||
err.throwHandlerError();
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const app = new App("1.1.0");
|
|
||||||
app
|
|
||||||
.onIdentify(identifyHandler)
|
|
||||||
.onReachableDevices(reachableDevicesHandler)
|
|
||||||
.onExecute(executeHandler)
|
|
||||||
.onQuery(queryHandler)
|
|
||||||
// @ts-ignore
|
|
||||||
.onIndicate((req) => console.log("Indicate", req))
|
|
||||||
// @ts-ignore
|
|
||||||
.onParseNotification((req) => console.log("ParseNotification", req))
|
|
||||||
// @ts-ignore
|
|
||||||
.onProvision((req) => console.log("Provision", req))
|
|
||||||
// @ts-ignore
|
|
||||||
.onRegister((req) => console.log("Register", req))
|
|
||||||
// @ts-ignore
|
|
||||||
.onUnprovision((req) => console.log("Unprovision", req))
|
|
||||||
// @ts-ignore
|
|
||||||
.onUpdate((req) => console.log("Update", req))
|
|
||||||
.listen()
|
|
||||||
.then(() => {
|
|
||||||
console.log("Ready!");
|
|
||||||
})
|
|
||||||
.catch((e) => console.error(e));
|
|
@ -7,7 +7,7 @@ The onboarding process takes care of the initial setup for Home Assistant, such
|
|||||||
|
|
||||||
<div class='note'>
|
<div class='note'>
|
||||||
|
|
||||||
The steps below do not apply to Home Assistant Core installations, for those types of installations, [see here](/docs/configuration/).
|
The steps below do not apply to Home Assistant Core & Container installations, for those types of installations, [see here](/docs/configuration/).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -29,11 +29,8 @@ Have you found an issue in your Home Assistant installation? Please report it. R
|
|||||||
## Videos, talks, workshops and alike
|
## Videos, talks, workshops and alike
|
||||||
|
|
||||||
- [PyconFR 2018 - Faire de la domotique libriste avec Python](https://www.youtube.com/watch?v=Eu6umBJ51I4) (French) ([Slides](https://hackmd.io/p/BJTSyDkqm)) - October 2018
|
- [PyconFR 2018 - Faire de la domotique libriste avec Python](https://www.youtube.com/watch?v=Eu6umBJ51I4) (French) ([Slides](https://hackmd.io/p/BJTSyDkqm)) - October 2018
|
||||||
- [Build your own smart home with Home Assistant](https://zmonkey.org/blog/files/Home%20Assistant%202018%20v1.0.pdf) at [OpenWest](https://openwest.org) - June 2018
|
|
||||||
- [Automate your home with Home Assistant](https://www.youtube.com/watch?v=SSrgi4iHGbs) at [foss-north 2018](https://foss-north.se/2018/speakers-and-talks.html#jparadies) - March 2018
|
- [Automate your home with Home Assistant](https://www.youtube.com/watch?v=SSrgi4iHGbs) at [foss-north 2018](https://foss-north.se/2018/speakers-and-talks.html#jparadies) - March 2018
|
||||||
- [Home Assistant - Smart Home für Jedermann](https://www.youtube.com/watch?v=74oPCh0NS4Y) (German) at [Pi and More 2018](https://piandmore.de/de/conference/pam10-5/schedule/event/305) ([Slides](https://benleb.de/talks/pam105_homeassistant.pdf)) - February 2018
|
- [Home Assistant - Smart Home für Jedermann](https://www.youtube.com/watch?v=74oPCh0NS4Y) (German) at [Pi and More 2018](https://piandmore.de/de/conference/pam10-5/schedule/event/305) ([Slides](https://benleb.de/talks/pam105_homeassistant.pdf)) - February 2018
|
||||||
- [Home Assistant](https://github.com/home-assistant/home-assistant-assets/tree/master/english/2017-qecampX) at QECampX 2017 - October 2017
|
|
||||||
- [Open Source Heimautomation mit Home Assistant](https://github.com/home-assistant/home-assistant-assets/tree/master/german/2017-maker-faire-zurich) at [Mini Maker Faire Zurich 2017](https://www.makerfairezurich.ch/en/) - September 2017
|
|
||||||
- [Why we can't have the Internet of Nice Things: A home automation primer](https://www.openwest.org/custom/description.php?id=92) at [OpenWest 2017](https://www.openwest.org) - July 2017
|
- [Why we can't have the Internet of Nice Things: A home automation primer](https://www.openwest.org/custom/description.php?id=92) at [OpenWest 2017](https://www.openwest.org) - July 2017
|
||||||
- [Home Automation with Home Assistant](https://github.com/jjmontesl/talk-hass-pydaygalicia2017) at [PyDay Galicia 2017](https://pyday2017.python-vigo.es/gl/) - June 2017
|
- [Home Automation with Home Assistant](https://github.com/jjmontesl/talk-hass-pydaygalicia2017) at [PyDay Galicia 2017](https://pyday2017.python-vigo.es/gl/) - June 2017
|
||||||
- [Home Automation with Python](https://www.youtube.com/watch?v=KNFZSSCPUyM) at [GLT 2017](https://glt17.linuxtage.at) - April 2017
|
- [Home Automation with Python](https://www.youtube.com/watch?v=KNFZSSCPUyM) at [GLT 2017](https://glt17.linuxtage.at) - April 2017
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
BIN
source/images/blog/2022-04-30-creator-network/Creators.jpg
Normal file
BIN
source/images/blog/2022-04-30-creator-network/Creators.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
Loading…
x
Reference in New Issue
Block a user