Yes. It should work @sayanova. I haven’t tested this extensively, but it works fine for most of my entities, like: calendar, weather and even some custom components like sensor.feedparser.
Omg. This is really simple and concise way to access attributes in entity.
I would love to put this in examples and README of the component.
Thank you very much for sharing the function!
Also, feel free to contribute not only to code but also to examples of prompts or functions.
I would like to collect useful functions like this, so everyone can access them whenever they need.
Is it possible to integrate the custom intent_scripts with Extended OpenAI Conversation?
When I try to use them I receive this response, “I’m sorry, but I don’t have any information on …”.
No, it directly calls service rather than calls service via intent. Could you explain more about your case? You should be able to do the same with supported functions.
Ah thanks for that bit of advice, I didn’t realize this would be possible with the functions. In hindsight that seems pretty obvious. I looked through the docs pretty extensively and I think I have a rough idea of what needs to be done, but I’m not entirely sure I have the technical ability to put it all together.
Use case: I would like to ask “has <my dog> been fed” and receive a response based on the state of a contact sensor. I created a template sensor which determines if he’s been fed, and use the automation below (not an intent script, I forgot I changed it to an automation as that worked better) which responds to tell me if he’s been fed and at what time.
trigger:
- platform: conversation
command:
- Has rudy been fed
- Is rudy fed
- rudy fed
- was rudy fed
- when was rudy fed
id: voiceAssistant
- service: tts.google_translate_say
action:
....
- service: tts.google_translate_say
data:
cache: false
entity_id: media_player.kitchen_entry
language: en-ie
message: >
{% set feedingTime = (as_timestamp(
states.binary_sensor.rudy_foody_contact.last_updated)
| timestamp_custom(' %H:%M', true | int)) -%} Yes,
Rudy had dinner at {{feedingTime}}
It looks like the easiest way to integrate this with EOC is call a service to trigger the automation, like this:
function:
type: native
name: execute_service
- service: automation.trigger
target:
entity_id: automation.rudy_foody
I’m confused on how to code the “spec”. How can I trigger this function to run when EOC hears one of the commands from my trigger?
I made search_music
function with Music Assistant service, ‘mass.search’. It provide spotify uri with Spotify provider, so you can use this function to play music.
- spec:
name: search_music
description: search for music.
parameters:
type: object
properties:
query:
type: string
description: search query
media_type:
type: array
optional: true
items:
type: string
enum: ["artist", "album", "playlist", "track", "radio"]
description: Types of media to search
artist:
type: string
optional: true
description: Specify this when you search from a specific artist
album:
type: string
optional: true
description: Specify this when you search from a specific album
required:
- query
function:
type: script
sequence:
- service: mass.search
data: >
{
"name": "{{ query }}",
{% if media_type is defined and media_type %}
"media_type": {{ media_type | tojson }},
{% else %}
"media_type": ["artist", "album", "playlist", "track", "radio"],
{% endif %}
{% if artist is defined and artist %}
"artist": "{{ artist }}",
{% endif %}
{% if album is defined and album %}
"album": "{{ album }}",
{% endif %}
"limit": 1
}
response_variable: _function_result
I made search_google function to make Assist more clever.
- spec:
name: search_google
description: Search Google using the Custom Search API.
parameters:
type: object
properties:
query:
type: string
description: The search query.
required:
- query
function:
type: rest
resource_template: "https://www.googleapis.com/customsearch/v1?key=[GOOGLE_API_KEY]&cx=[GOOGLE_PROGRAMMING_SEARCH_ENGINE]:omuauf_lfve&q={{ query }}&num=3"
value_template: >-
{% if value_json.items %}
```csv
title,link
{% for item in value_json.items %}
"{{ item.title | replace(',', ' ') }}","{{ item.link }}"
{% endfor %}
```
{% else %}
No results found,
{% endif %}
It makes you search google and retrieve top 3 search result as csv, title and link as column. Enjoy!
Understood!
Firstly, since you want to retrieve the state of entity, you don’t have to register any functions.
You can achieve it simply by exposing entity “binary_sensor.rudy_foody_contact”.
Then ask “has Rudy been fed”. There might be two cases.
1. gpt answers based on state of “binary_sensor.rudy_foody_contact” entity. (without feeding time)
2. gpt can’t find entity about rudy fed.
If #2 is the case, try to set aliases on “binary_sensor.rudy_foody_contact” like “rudy fed” and try again.
Secondly, if you want gpt to know “last_updated” of “binary_sensor.rudy_foody_contact” entity, you have to register one of two functions.
1. get_attributes
Since last_updated
property is in attributes, let gpt know current attributes of the entity.
- spec:
name: get_attributes
description: Get attributes of any home assistant entity
parameters:
type: object
properties:
entity_id:
type: string
description: entity_id
required:
- entity_id
function:
type: template
value_template: "{{states[entity_id]}}"
2. query_histories_from_db
If you want gpt to know the past history, add below function. Then you will be able to ask “when was rudy fed yesterday”
- spec:
name: query_histories_from_db
description: >-
Use this function to query histories from Home Assistant SQLite database.
Example:
Question: When did bedroom light turn on?
Answer: SELECT datetime(s.last_updated_ts, 'unixepoch', 'localtime') last_updated_ts FROM states s INNER JOIN states_meta sm ON s.metadata_id = sm.metadata_id INNER JOIN states old ON s.old_state_id = old.state_id WHERE sm.entity_id = 'light.bedroom' AND s.state = 'on' AND s.state != old.state ORDER BY s.last_updated_ts DESC LIMIT 1
Question: Was livingroom light on at 9 am?
Answer: SELECT datetime(s.last_updated_ts, 'unixepoch', 'localtime') last_updated, s.state FROM states s INNER JOIN states_meta sm ON s.metadata_id = sm.metadata_id INNER JOIN states old ON s.old_state_id = old.state_id WHERE sm.entity_id = 'switch.livingroom' AND s.state != old.state AND datetime(s.last_updated_ts, 'unixepoch', 'localtime') < '2023-11-17 08:00:00' ORDER BY s.last_updated_ts DESC LIMIT 1
parameters:
type: object
properties:
query:
type: string
description: A fully formed SQL query.
function:
type: sqlite
query: >-
{%- if is_exposed_entity_in_query(query) -%}
{{ query }}
{%- else -%}
{{ raise("entity_id should be exposed.") }}
{%- endif -%}
Yes, of course!
@jekalmin
It’s really special, exactly what I was missing…
I want to play music with a Squeezebox player (Logitech Media Server)
I want to be able to send a command to play an album I want,
Would appreciate help
Thanks
Hi,
if i right, i had to add this function in the openai parameters, below the execute_services function?
When i try this i get this error:
@stban1983 Have you installed Music Assistant (BETA) addon and hass Music Assistant integration, set music provider? I see mass.search not found.
ha no, i was thinking that it is working only with spotify integration.
I try to ask assist to play an artist but it doesn’t work. Should i need to install Music Assistant for that?
Yes, you need to. It use ‘mass.search’, which are provided by Music Assistant (BETA) integration. I choose to use this since Music Assistant can use various providers such as Youtube Music, Spotify, Tidal, Plex music etc.
Can anyone help me in making get_history
function that use rest api to get history from Home Assistant? I want to make this function for who don’t use sqlite as DB backend, but I’m having trouble make this function work.
- spec:
name: get_history
description: Retrieve historical data of specified entities in KST.
parameters:
type: object
properties:
timestamp:
type: string
optional: true
description: Start of the history period in YYYY-MM-DDThh:mm:ss format in KST. Defaults to 1 day before the time of the request.
filter_entity_id:
type: string
description: Comma-separated entity IDs to filter.
end_time:
type: string
optional: true
description: End of the history period in YYYY-MM-DDThh:mm:ss format in KST. Defaults to 1 day.
minimal_response:
type: boolean
optional: true
description: Return minimal response for faster processing.
no_attributes:
type: boolean
optional: true
description: Skip returning attributes for faster processing.
significant_changes_only:
type: boolean
optional: true
description: Return only significant state changes.
required:
- filter_entity_id
function:
type: rest
resource_template: >-
{% set base_url = 'http://homeassistant.local:8123/api/history/period' %}{% set timestamp_path = '/' + (timestamp | as_timestamp - 9 * 3600) | timestamp_custom('%Y-%m-%dT%H:%M:%S+09:00', False) if timestamp is defined else '' %}{% set query_string = 'filter_entity_id=' + filter_entity_id %}{% if end_time is defined %}{% set query_string = query_string + '&end_time=' + (end_time | as_timestamp - 9 * 3600) | timestamp_custom('%Y-%m-%dT%H:%M:%S+09:00', False) %}{% endif %}{% if minimal_response is defined and minimal_response %}{% set query_string = query_string + '&minimal_response' %}{% endif %}{% if no_attributes is defined and no_attributes %}{% set query_string = query_string + '&no_attributes' %}{% endif %}{% if significant_changes_only is defined and significant_changes_only %}{% set query_string = query_string + '&significant_changes_only' %}{% endif %}{{ base_url }}{{ timestamp_path }}?{{ query_string }}
headers:
Authorization: "[BEARER+TOKEN]"
content-type: "application/json"
value_template: >-
{% if value_json is defined %}
{{ value_json }}
{% else %}
"No data returned or invalid response"
{% endif %}
It might be pretty similar to what @sayanova shared above.
Since I haven’t setup Squeezebox player, I don’t have an example that actually works.
You can try to make it on your own or give me an example of service call syntax which plays an album, then I can give you a blueprint of how a function looks like.
I would be very happy if you could help me,
This is the service provided by him to play a specific album
ervice: squeezebox.call_method
data:
command: playlist
parameters:
- loadtracks
- album.titlesearch=<ALBUM NAME>
target:
entity_id: media_player.000000
Thank you
Ok i install Music Assistant, it works well, i can play spotify music through Music Assistant.
But if ask Openai, nothing happen:
LogBook is empty
Only Music Assistant media_player are exposed to Voice Assistant
@stban1983 You mean OpenAI says it will play music on specific media player but the result is not anything playing? I don’t speak French but I think your conversation dialog say so. Is it right?