Home Assistant Integration¶
This guide covers two ways to connect Prism with Home Assistant:
- Embed Prism as an iframe panel in the HA sidebar
- Pull Prism data into HA sensors via REST API
1. Embedding Prism as an HA Panel¶
Allow iframe embedding¶
By default, Prism blocks iframe embedding for security. To allow Home Assistant to embed it, set the ALLOWED_FRAME_ANCESTORS environment variable in your .env:
env
ALLOWED_FRAME_ANCESTORS=http://homeassistant.local:8123
Multiple origins (comma-separated):
env
ALLOWED_FRAME_ANCESTORS=http://homeassistant.local:8123, https://ha.example.com
Restart the Prism container after changing:
bash
docker-compose restart app
Add the panel in HA¶
In your Home Assistant configuration.yaml:
yaml
panel_iframe:
prism:
title: "Family Dashboard"
url: "http://prism.local:3000"
icon: mdi:view-dashboard
Restart Home Assistant. Prism will appear in the sidebar.
To show a specific dashboard (e.g. the kitchen layout):
yaml
url: "http://prism.local:3000/d/kitchen"
2. Creating an API Token¶
API tokens let Home Assistant query Prism's REST API without PIN-based login.
- Open Prism Settings (gear icon)
- Go to Security
- Under API Tokens, enter a name (e.g. "Home Assistant")
- Choose a scope: Voice API only (the default and recommended; sufficient for the Voice API and the read-only REST sensors below) or Full access (legacy) if you also need to drive write endpoints directly
- Click Generate Token
- Copy the token immediately (it's only shown once)
- Store it in your HA
secrets.yaml:
```yaml
secrets.yaml¶
prism_token: "paste-your-64-char-token-here" ```
Token scopes¶
Tokens carry a scope chosen when you generate them:
- Voice API only (default, recommended): reaches the Voice API (
/api/v1/voice/*) and the read-only REST sensors in Section 3. This is all most HA setups need. - Full access (legacy): every endpoint, including writes and admin routes. Only pick this if an automation calls a write endpoint directly instead of going through the Voice API.
The read sensors below (calendar, chores, shopping, meals) work with a Voice API only token. They are read-only GETs. Write actions (adding a shopping item, completing a chore) are exposed through the Voice API endpoints (see Section 5), which a voice-scoped token can also reach.
- Tokens never expire but can be revoked from Settings at any time
- Each request updates the token's "Last used" timestamp
3. REST Sensor Examples¶
Use HA's REST sensor to pull data from Prism.
Upcoming calendar events¶
yaml
sensor:
- platform: rest
name: "Prism Next Event"
resource: "http://prism.local:3000/api/events?limit=1"
headers:
Authorization: !secret prism_bearer
value_template: "{{ value_json.events[0].title if value_json.events else 'None' }}"
json_attributes_path: "$.events[0]"
json_attributes:
- startTime
- endTime
- location
scan_interval: 300
In secrets.yaml:
yaml
prism_bearer: "Bearer paste-your-64-char-token-here"
Pending chores count¶
yaml
sensor:
- platform: rest
name: "Prism Pending Chores"
resource: "http://prism.local:3000/api/chores"
headers:
Authorization: !secret prism_bearer
value_template: >
{{ value_json.chores | selectattr('enabled', 'true') | list | length }}
scan_interval: 600
Shopping list item count¶
{% raw %}
yaml
sensor:
- platform: rest
name: "Prism Shopping Items"
resource: "http://prism.local:3000/api/shopping-lists?includeItems=true"
headers:
Authorization: !secret prism_bearer
value_template: >
{% set total = 0 %}
{% for list in value_json.lists %}
{% set total = total + (list.items | rejectattr('checked', 'true') | list | length) %}
{% endfor %}
{{ total }}
scan_interval: 600
Today's meals¶
{% raw %}
yaml
sensor:
- platform: rest
name: "Prism Dinner Tonight"
resource: "http://prism.local:3000/api/meals?weekOf={{ now().strftime('%Y-%m-%d') }}"
headers:
Authorization: !secret prism_bearer
value_template: >
{% set today = now().strftime('%A') | lower %}
{% set dinner = value_json.meals | selectattr('dayOfWeek', 'equalto', today) | selectattr('mealType', 'equalto', 'dinner') | list %}
{{ dinner[0].name if dinner else 'Not planned' }}
scan_interval: 3600
4. Automation Examples¶
Announce dinner on smart speaker¶
yaml
automation:
- alias: "Announce tonight's dinner at 4pm"
trigger:
- platform: time
at: "16:00:00"
action:
- service: tts.speak
target:
entity_id: media_player.kitchen_speaker
data:
message: >
Tonight's dinner is {{ states('sensor.prism_dinner_tonight') }}.
Notify when shopping list grows¶
yaml
automation:
- alias: "Notify when shopping list has 10+ items"
trigger:
- platform: numeric_state
entity_id: sensor.prism_shopping_items
above: 10
action:
- service: notify.mobile_app
data:
title: "Shopping List"
message: "You have {{ states('sensor.prism_shopping_items') }} items on the shopping list."
5. Voice API (recommended surface)¶
Prism ships a purpose-built Voice API under /api/v1/voice/* that is the supported integration surface for Home Assistant and voice assistants. Each endpoint returns a ready-to-speak spoken field alongside structured data, so you don't have to assemble sentences from raw fields in Jinja templates. A Voice API only scoped token (the default) is all these endpoints need.
Available endpoints include:
GET /api/v1/voice/calendar/todayand/calendar/upcoming: today's and upcoming eventsGET /api/v1/voice/chores/today: chores due todayGET /api/v1/voice/tasks/today: tasks due todayGET /api/v1/voice/meals/today: today's planned mealsGET /api/v1/voice/weather/today: today's weatherGET /api/v1/voice/birthdays/upcoming: upcoming birthdaysGET /api/v1/voice/bus/status: bus tracking statusGET /api/v1/voice/family: family membersGET /api/v1/voice/message/recentandPOST /api/v1/voice/message/post: read/post messagesPOST /api/v1/voice/shopping/add: add a shopping itemPOST /api/v1/voice/chore/complete: mark a chore complete
Example REST sensor using the spoken response:
yaml
sensor:
- platform: rest
name: "Prism Meals Today"
resource: "http://prism.local:3000/api/v1/voice/meals/today"
headers:
Authorization: !secret prism_bearer
value_template: "{{ value_json.spoken }}"
scan_interval: 3600
Because the write endpoints (shopping/add, chore/complete) are part of the Voice API, a Voice API only token can drive them too. You do not need a Full access token for these.
See docs/voice-api.md for the full endpoint reference, request/response shapes, and more examples.
Troubleshooting¶
"Authentication required" error
- Make sure the Authorization header includes Bearer (with a space) before the token
- Verify the token hasn't been revoked in Settings → Security → API Tokens
iframe shows blank/refuses to connect
- Check ALLOWED_FRAME_ANCESTORS is set in .env and the container was restarted
- Verify the URL matches exactly (including port)
Sensors show "unknown"
- Check the Prism container is running: docker ps
- Test the endpoint manually: curl -H "Authorization: Bearer YOUR_TOKEN" http://prism.local:3000/api/chores
- Check HA logs for connection errors