-
-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sentence): Add support for custom responses in the sentence node
- Loading branch information
Showing
20 changed files
with
469 additions
and
50 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,125 @@ | ||
# Sentence | ||
|
||
The Sentence node triggers when the Home Assistant [Assist](https://www.home-assistant.io/voice_control/) feature matches a sentence from a voice assistant using the default [conversation agent](https://www.home-assistant.io/integrations/conversation/). This node is used for voice control integrations, allowing specific voice commands to trigger automations within Node-RED. | ||
The **Sentence** node is triggered when the Home Assistant [Assist](https://www.home-assistant.io/voice_control/) feature matches a sentence from a voice assistant using the default [conversation agent](https://www.home-assistant.io/integrations/conversation/). This node enables voice control integrations, allowing specific voice commands to trigger automations within Node-RED. | ||
|
||
Sentences are allowed to use some basic template syntax. Check Home Assistant [documentation](https://www.home-assistant.io/docs/automation/trigger/#sentence-trigger) for more information. | ||
Sentences support basic template syntax. Refer to the Home Assistant [documentation](https://www.home-assistant.io/docs/automation/trigger/#sentence-trigger) for more details. | ||
|
||
::: warning | ||
_Needs [Custom Integration](https://github.com/zachowj/hass-node-red) installed | ||
in Home Assistant for this node to function_ | ||
This node requires the [Custom Integration](https://github.com/zachowj/hass-node-red) to be installed in Home Assistant. | ||
::: | ||
|
||
## Configuration | ||
## Configuration Options | ||
|
||
### Mode | ||
|
||
- **Type**: `string` | ||
- **Options**: | ||
- `trigger` | ||
- `response` | ||
|
||
Defines the node’s function. | ||
If set to **trigger**, the node activates when a sentence is matched. | ||
If set to **response**, the node sends a dynamic response back to Home Assistant. | ||
|
||
### Sentences | ||
|
||
- Type: `string` | ||
- **Type**: `string` | ||
|
||
A list of sentences to match. Supports basic template syntax. For more details, see the Home Assistant [documentation](https://www.home-assistant.io/docs/automation/trigger/#sentence-trigger). | ||
|
||
### Response Type | ||
|
||
- **Type**: `string` | ||
- **Options**: | ||
- `dynamic` | ||
- `fixed` | ||
|
||
Specifies the type of response sent to Home Assistant: | ||
|
||
- **Fixed**: The same response is sent for all matched sentences. | ||
- **Dynamic**: The response is determined by the node set to response mode. | ||
|
||
### Response | ||
|
||
- **Type**: `string` | ||
|
||
The message sent to Home Assistant when a sentence is matched. This option is used only if the **Response Type** is set to `fixed`. | ||
|
||
### Fallback Response | ||
|
||
- **Type**: `string` | ||
|
||
The message sent to Home Assistant when a timeout occurs. This is used when the **Response Type** is set to `dynamic`. | ||
|
||
### Response Timeout | ||
|
||
- **Type**: `number` | ||
|
||
Specifies the time in milliseconds to wait for a response before sending the **Fallback Response**. This option is used only when the **Response Type** is set to `dynamic`. | ||
|
||
A list of sentences to match. Sentences are allowed to use some basic template syntax. Check Home Assistant [documentation](https://www.home-assistant.io/docs/automation/trigger/#sentence-trigger) for more information. | ||
### Expose As | ||
|
||
### Expose as | ||
- **Type**: `string` | ||
|
||
- Type: `string` | ||
Select an entity to create a switch in Home Assistant. Turning the switch on or off will enable or disable this node in Node-RED. | ||
|
||
When an entity is selected a switch entity will be created in Home Assistant. Turning on and off this switch will disable/enable the nodes in Node-RED. | ||
## Inputs | ||
|
||
All properties must be provided in `msg.payload`. | ||
|
||
Example input: | ||
|
||
```json | ||
{ | ||
"response": "The light is now on" | ||
} | ||
``` | ||
|
||
### Response | ||
|
||
- **Type**: `string` | ||
|
||
The response sent to Home Assistant when a sentence is matched. This is used only when the **Response Type** is set to `dynamic`. | ||
|
||
## Outputs | ||
|
||
Value types: | ||
|
||
- `trigger id`: sentence that triggered the flow | ||
- `config`: config properties of the node | ||
- `trigger id`: The sentence that triggered the flow. | ||
- `config`: The node's configuration properties. | ||
|
||
## Examples | ||
|
||
<InfoPanelOnly> | ||
|
||
[link](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/sentence.html#examples) | ||
For detailed usage examples, see the [Examples](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/sentence.html#examples) section. | ||
|
||
</InfoPanelOnly> | ||
|
||
<DocsOnly> | ||
|
||
### Basic Usage | ||
|
||
![screenshot](./images/sentence_01.png) | ||
|
||
@[code](@examples/node/sentence/sentence_usage.json) | ||
|
||
### Dynamic Response Examples | ||
|
||
#### Example 1: Count Lights On and Off | ||
|
||
This example shows how to use the Sentence node to provide a dynamic response based on the number of lights that are on or off in the house. It also turns on any lights that were off. | ||
|
||
![screenshot](./images/sentence_dynamic_example_01.png) | ||
|
||
@[code](@examples/node/sentence/sentence_dynamic_response_01.json) | ||
|
||
#### Example 2: Check Garage Sensor | ||
|
||
This example checks the status of a binary sensor to determine whether the car is in the garage. If the car is present, a response is sent confirming its location. If the car is not present, the response states that the car is not in the garage. | ||
|
||
![screenshot](./images/sentence_dynamic_example_02.png) | ||
|
||
@[code](@examples/node/sentence/sentence_dynamic_response_02.json) | ||
|
||
</DocsOnly> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[{"id":"5b44e487c5795df9","type":"ha-get-entities","z":"01b6599a0739a237","name":"lights off count","server":"","version":1,"rules":[{"condition":"state_object","property":"entity_id","logic":"starts_with","value":"light.","valueType":"str"},{"condition":"state_object","property":"state","logic":"is","value":"off","valueType":"str"}],"outputType":"array","outputEmptyResults":true,"outputLocationType":"msg","outputLocation":"lightsOff","outputResultsCount":1,"x":312,"y":800,"wires":[["99c90d5fd17832c9","7c588d1510201532"]]},{"id":"99c90d5fd17832c9","type":"ha-get-entities","z":"01b6599a0739a237","name":"lights on count","server":"","version":1,"rules":[{"condition":"state_object","property":"entity_id","logic":"starts_with","value":"light.","valueType":"str"},{"condition":"state_object","property":"state","logic":"is","value":"on","valueType":"str"}],"outputType":"count","outputEmptyResults":false,"outputLocationType":"msg","outputLocation":"lightsOnCount","outputResultsCount":1,"x":504,"y":800,"wires":[["f6e701c97c731979"]]},{"id":"09cb88520209e712","type":"inject","z":"01b6599a0739a237","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":132,"y":752,"wires":[["0b2ef68df13c5b94"]]},{"id":"0b2ef68df13c5b94","type":"api-call-service","z":"01b6599a0739a237","name":"","server":"","version":7,"debugenabled":false,"action":"conversation.process","floorId":[],"areaId":[],"deviceId":[],"entityId":[],"labelId":[],"data":"{\"text\": \"let there be light\"}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"results"}],"queue":"none","blockInputOverrides":true,"domain":"conversation","service":"process","x":332,"y":752,"wires":[["edfa883350eca925"]]},{"id":"edfa883350eca925","type":"debug","z":"01b6599a0739a237","name":"output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload.response.speech.plain.speech","targetType":"msg","statusVal":"","statusType":"auto","x":686,"y":752,"wires":[]},{"id":"b389cf7e343fc938","type":"api-call-service","z":"01b6599a0739a237","name":"","server":"","version":7,"debugenabled":false,"action":"light.turn_on","floorId":[],"areaId":[],"deviceId":[],"entityId":[],"labelId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","blockInputOverrides":true,"domain":"light","service":"turn_on","x":890,"y":848,"wires":[[]]},{"id":"28191039a0c43c00","type":"change","z":"01b6599a0739a237","name":"build entity list","rules":[{"t":"set","p":"payload","pt":"msg","to":"{ \"target\": { \"entity_id\": lightsOff.entity_id}}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":848,"wires":[["b389cf7e343fc938"]]},{"id":"794a0664ef0e9ab0","type":"ha-sentence","z":"01b6599a0739a237","name":"let there be light","server":"5d205f70b1e41e9f","version":2,"inputs":0,"outputs":1,"exposeAsEntityConfig":"","mode":"trigger","sentences":["let there be light"],"response":"Something took to long","responseType":"jsonata","triggerResponseType":"dynamic","responseTimeout":1000,"outputProperties":[{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"payload","propertyType":"msg","value":"","valueType":"triggerId"}],"x":128,"y":800,"wires":[["5b44e487c5795df9"]]},{"id":"f6e701c97c731979","type":"ha-sentence","z":"01b6599a0739a237","name":"","server":"5d205f70b1e41e9f","version":2,"inputs":1,"outputs":1,"exposeAsEntityConfig":"","mode":"response","sentences":[],"response":"lightsOnCount & \" lights were already on turning on \" & $count(lightsOffCount) & \" lights that were off\"\t","responseType":"jsonata","triggerResponseType":"fixed","responseTimeout":1000,"outputProperties":[],"x":692,"y":800,"wires":[[]]},{"id":"7c588d1510201532","type":"switch","z":"01b6599a0739a237","name":"any lights off?","property":"lightsOff.length","propertyType":"msg","rules":[{"t":"gt","v":"0","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":506,"y":848,"wires":[["28191039a0c43c00"]]}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[{"id":"d140cd86c26cbbe5","type":"inject","z":"01b6599a0739a237","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":204,"y":960,"wires":[["c18458aa0fda5201"]]},{"id":"c18458aa0fda5201","type":"api-call-service","z":"01b6599a0739a237","name":"is the car in the garage","server":"","version":7,"debugenabled":false,"action":"conversation.process","floorId":[],"areaId":[],"deviceId":[],"entityId":[],"labelId":[],"data":"{\"text\": \"is the car in the garage\"}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"results"}],"queue":"none","blockInputOverrides":true,"domain":"conversation","service":"process","x":462,"y":960,"wires":[["080f0fda9ce2ebc9"]]},{"id":"080f0fda9ce2ebc9","type":"debug","z":"01b6599a0739a237","name":"output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload.response.speech.plain.speech","targetType":"msg","statusVal":"","statusType":"auto","x":674,"y":960,"wires":[]},{"id":"aac0b36dca0c47b4","type":"ha-sentence","z":"01b6599a0739a237","name":"is the car in the garage","server":"5d205f70b1e41e9f","version":2,"inputs":0,"outputs":1,"exposeAsEntityConfig":"","mode":"trigger","sentences":["is the car in the garage"],"response":"Something took to long","responseType":"jsonata","triggerResponseType":"dynamic","responseTimeout":1000,"outputProperties":[{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"payload","propertyType":"msg","value":"","valueType":"triggerId"}],"x":220,"y":1008,"wires":[["6a2a0e27afac616e"]]},{"id":"2dd86795094ba553","type":"ha-sentence","z":"01b6599a0739a237","name":"","server":"5d205f70b1e41e9f","version":2,"inputs":1,"outputs":1,"exposeAsEntityConfig":"","mode":"response","sentences":[],"response":"payload","responseType":"msg","triggerResponseType":"fixed","responseTimeout":1000,"outputProperties":[],"x":940,"y":1008,"wires":[[]]},{"id":"6a2a0e27afac616e","type":"api-current-state","z":"01b6599a0739a237","name":"","server":"","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.car_in_garage","state_type":"str","blockInputOverrides":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":522,"y":1008,"wires":[["fa724a7fe743faaa"],["30171db069e062f0"]]},{"id":"fa724a7fe743faaa","type":"change","z":"01b6599a0739a237","name":"yes","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"response\": \"Yes the car is in the garage\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":770,"y":1008,"wires":[["2dd86795094ba553"]]},{"id":"30171db069e062f0","type":"change","z":"01b6599a0739a237","name":"no","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"response\": \"No the car is not in the garage\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":772,"y":1056,"wires":[["2dd86795094ba553"]]},{"id":"b4d9680db1056a02","type":"inject","z":"01b6599a0739a237","name":"set car in garage","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":224,"y":1056,"wires":[["0c940aece619684d"]]},{"id":"0c940aece619684d","type":"ha-binary-sensor","z":"01b6599a0739a237","name":"","entityConfig":"c9ce588e6f25ce5d","version":0,"state":"payload","stateType":"msg","attributes":[],"inputOverride":"allow","outputProperties":[],"x":496,"y":1056,"wires":[[]]},{"id":"763df26767e56a92","type":"inject","z":"01b6599a0739a237","name":"remove car from garage","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":254,"y":1104,"wires":[["0c940aece619684d"]]},{"id":"c9ce588e6f25ce5d","type":"ha-entity-config","server":"5d205f70b1e41e9f","deviceConfig":"","name":"car in garage","version":"6","entityType":"binary_sensor","haConfig":[{"property":"name","value":"car in garage"},{"property":"icon","value":""},{"property":"entity_picture","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":""}],"resend":true,"debugEnabled":false}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
[{"id":"2f10cb78ab2f486f","type":"debug","z":"39a6dba4b503e011","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"msg","x":382,"y":384,"wires":[]},{"id":"5c563c29d19f4aab","type":"ha-sentence","z":"39a6dba4b503e011","name":"","server":"bf5874816710d0c7","version":0,"outputs":1,"sentences":["[it's ]party time","happy (new year|birthday)","hello world"],"outputProperties":[{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"payload","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"sentences","propertyType":"msg","value":"sentences","valueType":"config"}],"x":176,"y":384,"wires":[["2f10cb78ab2f486f"]]},{"id":"4868b36e0e57db4f","type":"api-call-service","z":"39a6dba4b503e011","name":"process sentence","server":"","version":5,"debugenabled":false,"domain":"conversation","service":"process","areaId":[],"deviceId":[],"entityId":[],"data":" {\"text\": payload}\t","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":422,"y":336,"wires":[[]]},{"id":"0bd711e6ab321cf9","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"happy new year","payloadType":"str","x":200,"y":336,"wires":[["4868b36e0e57db4f"]]},{"id":"7b19f1bcd79bf7ea","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"happy birthday","payloadType":"str","x":204,"y":288,"wires":[["4868b36e0e57db4f"]]},{"id":"fdec3314ea56130d","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"party time","payloadType":"str","x":184,"y":240,"wires":[["4868b36e0e57db4f"]]},{"id":"92aa9c7e046ebba3","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"it's party time","payloadType":"str","x":198,"y":192,"wires":[["4868b36e0e57db4f"]]},{"id":"4c1ecc1396d9eddf","type":"inject","z":"39a6dba4b503e011","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"hello world","payloadType":"str","x":188,"y":144,"wires":[["4868b36e0e57db4f"]]}] | ||
[{"id":"2f10cb78ab2f486f","type":"debug","z":"01b6599a0739a237","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"msg","x":418,"y":1136,"wires":[]},{"id":"5c563c29d19f4aab","type":"ha-sentence","z":"01b6599a0739a237","name":"","server":"5d205f70b1e41e9f","version":2,"inputs":0,"outputs":1,"exposeAsEntityConfig":"","mode":"trigger","sentences":["[it's ]party time","happy (new year|birthday)","hello world"],"response":"","responseType":"fixed","responseTimeout":1000,"outputProperties":[{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"payload","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"sentences","propertyType":"msg","value":"sentences","valueType":"config"}],"x":212,"y":1136,"wires":[["2f10cb78ab2f486f"]]},{"id":"4868b36e0e57db4f","type":"api-call-service","z":"01b6599a0739a237","name":"process sentence","server":"","version":7,"debugenabled":false,"action":"conversation.process","floorId":[],"areaId":[],"deviceId":[],"entityId":[],"labelId":[],"data":" {\"text\": payload}\t","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","blockInputOverrides":false,"domain":"conversation","service":"process","x":458,"y":1088,"wires":[[]]},{"id":"0bd711e6ab321cf9","type":"inject","z":"01b6599a0739a237","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"happy new year","payloadType":"str","x":236,"y":1088,"wires":[["4868b36e0e57db4f"]]},{"id":"7b19f1bcd79bf7ea","type":"inject","z":"01b6599a0739a237","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"happy birthday","payloadType":"str","x":240,"y":1040,"wires":[["4868b36e0e57db4f"]]},{"id":"fdec3314ea56130d","type":"inject","z":"01b6599a0739a237","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"party time","payloadType":"str","x":220,"y":992,"wires":[["4868b36e0e57db4f"]]},{"id":"92aa9c7e046ebba3","type":"inject","z":"01b6599a0739a237","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"it's party time","payloadType":"str","x":234,"y":944,"wires":[["4868b36e0e57db4f"]]},{"id":"4c1ecc1396d9eddf","type":"inject","z":"01b6599a0739a237","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"hello world","payloadType":"str","x":224,"y":896,"wires":[["4868b36e0e57db4f"]]}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.