Ultimate Free AI Voice Assist: Home Assistant Voice PE->HA->N8N->Groq

Background:
For reference my machine is a Dell Optiplex 9020 Micro with 16GB Ram, an i7-4785T (4 cores, 8 threads), an NVME SSD and a solid state drive, running proxmox. (This is not an ultra powerful machine)
My setup guide is documented here:
Google Coral USB + Frigate + PROXMOX - Third party integrations - Home Assistant Community

I recently ordered two “Home Assistant Voice PE” devices a while ago and finally found some time to get them set up. I installed the Wyoming protocol, fast-whisper and piper, and while it sort of worked,. The results were slow and unimpressive.
Meanwhile, I somehow stumbled onto a lot of videos of what people are creating with N8N, and it looked impressive.
If only there were some way to use N8N as the brains for home assistant voice assistant.
Is it possible? Yes! And it wasn’t that hard actually.
There may be other ways to achieve this,. and my setup isnt 100% local, but its mostly local and completely free.
The basic premise is to set up n8n to mirror the API specifications of ollama, and then use the ollama integration and point it at n8n.

Architecture:
My setup is as follows:

  • Proxmox running on Bare Metal (Optiplex 9020)
    • VM (Home Assistant Proxmox Install from here Alternative - Home Assistant )
    • LXC
      • Docker (with portainer installed)
        • Whisper
        • n8n
        • n8n-import
        • n8n-postgres-1
        • qdrant

Part 1 – Home Assistant Basic Setup:

  1. Do the basic setup for home assistant voice (I wont bother detailing this for now, you can find this elsewhere). Get to the point where your “Home Assistant Voice PE” is setup and you are able to talk to home assistant using the device.

Part 2 – Docker / Portainer Setup:
I had to fiddle with this a bit as Im not super experienced with docker and portainer. I just know enough to get by. Not that I don’t have this fully secured yet with HTTPS, so you should look into that once you are up and running. Or if/when I figure that out maybe I will post an update to this thread.

  1. You will need a custom DNS for this to work. Technically n8n will start without it, but a lot of the oauth providers wont let you use an IP address. Swap in your config instead of “your.domainnamehere.com”.
  2. Note that in the config below, the webhook is redirected to /api in order to simulate the ollama path setup. If you want to test it you will need to adjust the config and set “N8N_ENDPOINT_WEBHOOK_TEST” to api, instead of “N8N_ENDPOINT_WEBHOOK”.
  3. Create a folder in the LXC for your backups. I used “/home/n8n/backup”.
    Also create “/home/n8n/shared”. You will need to change these in the setup below if you opt to point somewhere different.
  4. Create a new “stack” that looks like this:
volumes:
  n8n_storage:
  postgres_storage:  
  qdrant_storage:

networks:
  demo:

x-n8n: &service-n8n
  image: n8nio/n8n:latest
  networks: ['demo']
  environment:
    - DB_TYPE=postgresdb
    - DB_POSTGRESDB_HOST=postgres
    - DB_POSTGRESDB_USER=${POSTGRES_USER}
    - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
    - N8N_DIAGNOSTICS_ENABLED=false
    - N8N_PERSONALIZATION_ENABLED=false
    - N8N_ENCRYPTION_KEY
    - N8N_USER_MANAGEMENT_JWT_SECRET
    - N8N_SECURE_COOKIE=false
    - N8N_ENDPOINT_WEBHOOK=api
    - N8N_ENDPOINT_WEBHOOK_TEST=apitest
    - N8N_HOST=your.domainnamehere.com
    - N8N_PORT=5678
    - N8N_PROTOCOL=http
    - WEBHOOK_URL=http://your.domainnamehere.com:5678/
   
    

services:
  postgres:
    image: postgres:16-alpine
    hostname: postgres
    networks: ['demo']
    restart: unless-stopped
    environment:
      - POSTGRES_USER
      - POSTGRES_PASSWORD
      - POSTGRES_DB
    volumes:
      - postgres_storage:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
      interval: 5s
      timeout: 5s
      retries: 10
      
  n8n-import:
    <<: *service-n8n
    hostname: n8n-import
    container_name: n8n-import
    entrypoint: /bin/sh
    command:
      - "-c"
      - "n8n import:credentials --separate --input=/backup/credentials && n8n import:workflow --separate --input=/backup/workflows"
    volumes:
      - ./n8n/backup:/backup
    depends_on:
      postgres:
        condition: service_healthy


  n8n:
    <<: *service-n8n
    hostname: n8n
    container_name: n8n
    restart: unless-stopped
    ports:
      - 5678:5678
    volumes:
      - n8n_storage:/home/node/.n8n
      - /home/n8n/backup:/backup
      - /home/n8n/shared:/data/shared
    depends_on:
      postgres:
        condition: service_healthy
      

  qdrant:
    image: qdrant/qdrant
    hostname: qdrant
    container_name: qdrant
    networks: ['demo']
    restart: unless-stopped
    ports:
      - 6333:6333
    volumes:
      - qdrant_storage:/qdrant/storage

  whisper:
    image: homeassistant/amd64-addon-whisper:latest
    container_name: whisper
    ports:
      - 10300:10300
    restart: unless-stopped
    volumes:
      - /home/whisper-data:/data
    entrypoint: python3
    command: -m wyoming_faster_whisper --uri tcp://0.0.0.0:10300 --model tiny-int8 --beam-size 1 --language pl --data-dir /data --download-dir /data

  1. Ensure you set the above “POSTGRES_DB” value to “n8n”. For some reason I couldn’t get it to work with any other DB name.
  2. Deploy the stack. The volumes should be created and hopefully everything starts.

Part 3 – Create the n8n “Ollama Proxy” workflow
Note that your portainer setup must have the N8N_ENDPOINT_WEBHOOK property set to “api” for this to work normally, or otherwise N8N_ENDPOINT_WEBHOOK_TESET must be set to “api” while you are testing (but not both at the same time obviously).
Create a workflow with 4 webhook triggers:

  • Get Version
    • HTTP Method: GET
    • Path: version
    • Respond: Immediately
    • Response Data: { “version”: “0.5.13” }
  • List Models
    • HTTP Method: GET
    • Path: tags
    • Respond: Immediately
    • Response Data:
{     "models": [         {             "name": "llama3.2:latest",             "model": "llama3.2:latest",             "modified_at": "2025-03-05T20:11:32.225032-08:00",             "size": 2019393189,             "digest": "a80c4f17acd55265feec403c7aef86be0c25983ab279d83f3bcd3abbcb5b8b72",             "details": {                 "parent_model": "",                 "format": "gguf",                 "family": "llama",                 "families": [                     "llama"                 ],                 "parameter_size": "3.2B",                 "quantization_level": "Q4_K_M"             }         },         {             "name": "deepseek-r1:latest",             "model": "deepseek-r1:latest",             "modified_at": "2025-03-03T17:26:50.7367646-08:00",             "size": 4683075271,             "digest": "0a8c266910232fd3291e71e5ba1e058cc5af9d411192cf88b6d30e92b6e73163",             "details": {                 "parent_model": "",                 "format": "gguf",                 "family": "qwen2",                 "families": [                     "qwen2"                 ],                 "parameter_size": "7.6B",                 "quantization_level": "Q4_K_M"             }         },         {             "name": "deepseek-r1:1.5b",             "model": "deepseek-r1:1.5b",             "modified_at": "2025-03-02T18:54:23.6412071-08:00",             "size": 1117322599,             "digest": "a42b25d8c10a841bd24724309898ae851466696a7d7f3a0a408b895538ccbc96",             "details": {                 "parent_model": "",                 "format": "gguf",                 "family": "qwen2",                 "families": [                     "qwen2"                 ],                 "parameter_size": "1.8B",                 "quantization_level": "Q4_K_M"             }         },         {             "name": "deepseek-r1:14b",             "model": "deepseek-r1:14b",             "modified_at": "2025-03-02T16:09:37.6128441-08:00",             "size": 8988112040,             "digest": "ea35dfe18182f635ee2b214ea30b7520fe1ada68da018f8b395b444b662d4f1a",             "details": {                 "parent_model": "",                 "format": "gguf",                 "family": "qwen2",                 "families": [                     "qwen2"                 ],                 "parameter_size": "14.8B",                 "quantization_level": "Q4_K_M"             }         }     ] }
  • Chat
    • HTTP Method: POST
    • Path: chat
    • Respond: Immediately
    • Response Data: “Hello World from n8n”

Part 4 – Free AI
If you have a good GPU behind your docker setup you can install an Ollama docker container,. And point n8n at that for your models,. I tried that and it did work, but it was pretty slow, so I started looking at AI pricing. I found that groq’s pricing seemed quite a bit cheaper than everything else, so I set up an account and found that they actually have a free tier with access to lots of decent models!

Part 5 – Point Home Assistant at N8N using the Ollama integration
Go back to home assistant, install the Ollama integration, and when you are prompted for an Ip address, point it at your n8n installation running (ex. 192.168.200.122:5678).
It will make calls to list the models available etc, and your n8n webhook workflow will respond, and trick home assistant into thinking it is talking to Ollama.

Part 6 – Point Home Assistant at faster-wisper
Go back to home assistant, add an instance of faster whisper and point it at your instance running in docker. I might be wrong on this part but I found despite running on the same underlying hardware, mine seemed to be much faster when running in the docker LXC rather than inside my home assistant VM. For TTS. Just use the google option as it works just fine.

Summary:
I only just set this up on Saturday but have been having a lot of fun with it so far.
I would be interested to know if anyone else has tried this, or if anyone else manages to get this going, and what they are able to build with home assistant and n8n.

3 Likes

Hey I actually found this when asking ChatGPT if I could setup the same exact thing. Any way you could share that as template from n8n? I’m having issues with Home assistant throwing “unexpected error during intent recognition”.

I was at least able to get Ollam to recognize N8N.

1 Like

I am currently trying to connect HA to n8n. I like this approach, but I have questions.

I am running HA on a NUC using the Voice Assistant pointed to a Llama model. I use a second PC for all the heavy lifting ( dual 4090 ) for the Llama models as well as running my docker containers. In these containers I run N8N, Piper, and Whisper. I have found this to be the fastest way to get responses.

My questions are:

Do you have the same functionality in HA to change the voice? The model that your using?

I love what you have done I have been messing with trying to get telegram to work, but then what is the point of using what I have made. I hope they make this an integration soon because the possibilities are endless. Again great job.

I am having the exact same issue. N8n is returning the json, but HA is giving me the unexpected intent error. How did you solve that?

I haven’t run into an “unexpected error during intent recognition”.
Are you trying to get the n8n API to return tools commands so that home assistant will turn lights on and off etc?

With some trial and error I was able to N8N to return tools commands to home assistant such that lights would turn on or off etc.

Here is a sample N8N “Respond to Webhook” body that will tell home assistant to turn off the kitchen lights:

{
    "model": "llama3.2",
    "created_at": "2025-03-12T02:42:49.823678882Z",
    "message": {
        "role": "assistant",
        "content": "Bro! {{ $json.output.replace(/['"*|\n]+/g, '')}}",
        "tool_calls": [
            {
                "function": {
                    "name": "HassTurnOff",
                    "arguments": {
                        "area": "",
                        "device_class": null,
                        "domain": null,
                        "floor": null,
                        "name": "Dining Room Pendants"
                    }
                }
            }
        ]
    },
    "done_reason": "stop",
    "done": true,
    "total_duration": 26621387245,
    "load_duration": 33544945,
    "prompt_eval_count": 254,
    "prompt_eval_duration": 16445000000,
    "eval_count": 44,
    "eval_duration": 10116000000
}

The above response did successfully result in home assistant turning off a ight called “Dining Room Pendants”.
However, I found that Home Assistant then makes an immediate call back to N8N for some reason, and I’m not quite sure why.
For that reason, I ended up adding an “If” activity with the following code, so that any API call wherein the last message was from home assistant (rather than an end-user) takes a separate route:

{{ $json.body.messages[$json.body.messages.length-1].role }}

And then that route responds with this:

{
    "model": "llama3.2",
    "created_at": "2025-03-12T02:42:49.823678882Z",
    "message": {
        "role": "assistant",
        "content": "Tool action completed"
    },
    "done_reason": "stop",
    "done": true,
    "total_duration": 26621387245,
    "load_duration": 33544945,
    "prompt_eval_count": 254,
    "prompt_eval_duration": 16445000000,
    "eval_count": 44,
    "eval_duration": 10116000000
}

All of that said,. I have ultimately decided not to try control home assistant using n8n responses.

I am having much more success (and fun) getting N8N to make calls to home assistant using the n8n home assistant integration.

Here is the current state of it. I have 1 main “CEO” agent that has 2 “Manager” agents that effectively report to him/her:

  • The “Event Manager” - responsible for all scheduled family events/appointments etc.
  • The “Home automation manager” - responsible for carrying out tasks against home assistant.

Its possible these “Managers” may also end up having their own direct reports, and I will have a whole organizational hierarchy of AIs… :stuck_out_tongue:

The “Home Automation Manager” is pretty basic so far… I haven’t had much time to play with this as of yet… But the below does work quite well for what it is.


I have uploaded my templates here in case they are any help to anyone wanting to get started:
n8n templates

One last thing I should mention is that I found the choice of AI model makes a huge difference. Its especially important to choose a model that has “tools” capabilities.
The models I am using right now via groq and having good success with are:

  • llama-3.3-70b-versatile
  • llama-3.3-70b-8192

I think you effectively have two choices:

  1. Return text to home assistant, and home assistant will then use whatever text-to-speech that you have configured for your assistant:

  2. Return an empty string, and make an API call to whatever TTS service you want, then make an API call to home assistant to get it to play the audio on a device.

I think approach 2 is probably unnecessary though.
I saw that networkchuck has found a way to use a local custom TTS and I think he just uses option 1 above:
Cloning my Voice Into an AI Assistant

Yes I have seen that video and have already gone down that road, and now my HA voice sounds like Florence Pugh. I just didn’t want to lose all that work. I am going to try running through your example and see what I can get. I don’t want to use n8n to control HA all of my automations are through Node Red. I want to talk to the assistant and have it read back an email or make a haircut appointment. Like this video: https://www.youtube.com/watch?v=k3mcttDLJB4&t=10s .

An example would be:
“Hey Jarvis tell Amie (n8n assistant) to cancel my appt with John and send him an email saying I cant make it”.

I just cant seem to connect HA to n8n, and if I use telegram well…then I am using telegram to talk to n8n and not HA.

I will look and try your process and get back to the thread. This weekend has just been busy.

First of all, the idea of faking an Ollama server is genius—thanks for that!

I’m encountering the same error as others:

“Unexpected error during intent recognition”

After troubleshooting for the last two hours, I’m pretty sure the Ollama fake might be missing something. When I check the Home Assistant logs, the error messages suggest:

“Something is wrong with your Ollama server.”

Since I’ve never worked with Ollama before, I’m not entirely sure what’s needed to fake it properly. Given that it works in your environment, I have a few questions:

  1. Are you still running an actual Ollama instance on the same Docker network?
  2. Could there be any dependencies or configurations missing in the fake setup?

I also checked your files for environment-specific settings (like the HassTurnOff intent for “Dining Room Pendants”) and managed to eliminate errors in n8n. However, the intent recognition error persists.

I’d really love to get this working—it’s an amazing project! Any help or insights would be greatly appreciated.

Thanks again for your hard work!

I found another github repository which did the same. I combined yours and his nodes an get it worked.
I upload one worklow for you guys so that you can use the marked nodes in your own workflows. Hope this helps you out!

{
  "name": "Fake Ollama Nodes",
  "nodes": [
    {
      "parameters": {
        "path": "dea91789-d01f-4984-bdc5-92bd3a23b401",
        "options": {
          "responseData": "{ “version”: “0.5.13” }"
        }
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -40,
        -240
      ],
      "id": "96d9b9c0-0d1c-4189-8900-72d74492646d",
      "name": "GET version",
      "webhookId": "dea91789-d01f-4984-bdc5-92bd3a23b401"
    },
    {
      "parameters": {
        "path": "debd2b1d-e5d8-4ca4-bc45-ea971204c55a",
        "options": {
          "responseData": "{     \"models\": [         {             \"name\": \"llama3.2:latest\",             \"model\": \"llama3.2:latest\",             \"modified_at\": \"2025-03-05T20:11:32.225032-08:00\",             \"size\": 2019393189,             \"digest\": \"a80c4f17acd55265feec403c7aef86be0c25983ab279d83f3bcd3abbcb5b8b72\",             \"details\": {                 \"parent_model\": \"\",                 \"format\": \"gguf\",                 \"family\": \"llama\",                 \"families\": [                     \"llama\"                 ],                 \"parameter_size\": \"3.2B\",                 \"quantization_level\": \"Q4_K_M\"             }         },         {             \"name\": \"deepseek-r1:latest\",             \"model\": \"deepseek-r1:latest\",             \"modified_at\": \"2025-03-03T17:26:50.7367646-08:00\",             \"size\": 4683075271,             \"digest\": \"0a8c266910232fd3291e71e5ba1e058cc5af9d411192cf88b6d30e92b6e73163\",             \"details\": {                 \"parent_model\": \"\",                 \"format\": \"gguf\",                 \"family\": \"qwen2\",                 \"families\": [                     \"qwen2\"                 ],                 \"parameter_size\": \"7.6B\",                 \"quantization_level\": \"Q4_K_M\"             }         },         {             \"name\": \"deepseek-r1:1.5b\",             \"model\": \"deepseek-r1:1.5b\",             \"modified_at\": \"2025-03-02T18:54:23.6412071-08:00\",             \"size\": 1117322599,             \"digest\": \"a42b25d8c10a841bd24724309898ae851466696a7d7f3a0a408b895538ccbc96\",             \"details\": {                 \"parent_model\": \"\",                 \"format\": \"gguf\",                 \"family\": \"qwen2\",                 \"families\": [                     \"qwen2\"                 ],                 \"parameter_size\": \"1.8B\",                 \"quantization_level\": \"Q4_K_M\"             }         },         {             \"name\": \"deepseek-r1:14b\",             \"model\": \"deepseek-r1:14b\",             \"modified_at\": \"2025-03-02T16:09:37.6128441-08:00\",             \"size\": 8988112040,             \"digest\": \"ea35dfe18182f635ee2b214ea30b7520fe1ada68da018f8b395b444b662d4f1a\",             \"details\": {                 \"parent_model\": \"\",                 \"format\": \"gguf\",                 \"family\": \"qwen2\",                 \"families\": [                     \"qwen2\"                 ],                 \"parameter_size\": \"14.8B\",                 \"quantization_level\": \"Q4_K_M\"             }         }     ] }"
        }
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        320,
        -240
      ],
      "id": "56040f9f-47ff-4133-ab72-ae4f36e3b454",
      "name": "List Models",
      "webhookId": "debd2b1d-e5d8-4ca4-bc45-ea971204c55a"
    },
    {
      "parameters": {
        "content": "## Ollama Integration Initialization\n",
        "height": 220,
        "width": 840
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -240,
        -300
      ],
      "id": "d7418986-3ffb-409c-a3d6-b57164159219",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "074967ba-308b-4623-8b26-a8cace260047",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -460,
        180
      ],
      "id": "7f0bb0f4-f20f-4017-adde-7df636add348",
      "name": "Chat",
      "webhookId": "074967ba-308b-4623-8b26-a8cace260047"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={\n  \"model\": \"llama3.2:latest\",\n  \"created_at\": \"{{ $now }}\",\n  \"message\": {\n    \"role\": \"assistant\",\n    \"content\": \"{{ $json.output }}\"\n  },\n  \"done\": true\n}\n",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        580,
        180
      ],
      "id": "cb0d285c-cb92-4c95-9b29-7ed311b459c2",
      "name": "Respond to Webhook",
      "alwaysOutputData": true,
      "executeOnce": true
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.body.messages[$json.body.messages.length - 1].content }}",
        "options": {
          "systemMessage": "You're a helpful assistant that helps the user control home assistant.\nHere is a list of entites\n\nLivingroom light \nlight.lv_1\n\nKitchen light \nlight.kitchen_light_switch\n\nBedroom Lights\nlight.bedroom_lights\n\nToday is {{ $now.format('cccc') }} the {{ $now.format('yyyy-MM-dd HH:mm') }}.\n"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.8,
      "position": [
        -140,
        180
      ],
      "id": "9221a496-1c3b-4569-bfbd-0e278e609ac0",
      "name": "AI Agent",
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [
        -300,
        500
      ],
      "id": "f1058247-120d-4d68-86a5-646d67dcf4f5",
      "name": "OpenAI Chat Model"
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Send an announcement to home assistant. ",
        "resource": "service",
        "operation": "call",
        "domain": "assist_satellite",
        "service": "announce",
        "serviceAttributes": {
          "attributes": [
            {
              "name": "entity_id",
              "value": "assist_satellite.assist_microphone"
            },
            {
              "name": "message",
              "value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Value', `This value is the announcement you with to make. `, 'string') }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.homeAssistantTool",
      "typeVersion": 1,
      "position": [
        220,
        500
      ],
      "id": "df3ce552-a759-4ad2-8726-77b89c570c42",
      "name": "Home Assistant Announce"
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Turns on one or more lgiths an dadjusts their properties, even when they are turned on already. ",
        "resource": "service",
        "operation": "call",
        "domain": "light",
        "service": "turn_on",
        "serviceAttributes": {
          "attributes": [
            {
              "name": "entity_id",
              "value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Value', ``, 'string') }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.homeAssistantTool",
      "typeVersion": 1,
      "position": [
        -40,
        500
      ],
      "id": "6c15bfae-76ce-417e-9f1d-690422841261",
      "name": "Home Assistant Light Turn on"
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Turns off one or more lights. ",
        "resource": "service",
        "operation": "call",
        "domain": "light",
        "service": "turn_off",
        "serviceAttributes": {
          "attributes": [
            {
              "name": "entity_id",
              "value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Value', ``, 'string') }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.homeAssistantTool",
      "typeVersion": 1,
      "position": [
        80,
        500
      ],
      "id": "2eeb5332-09f3-4ea5-b26d-34b021a30a99",
      "name": "Home Assistant Light Turn Off"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "cc0a5c98-73b2-4739-bb09-daf91ea7faee",
              "name": "output",
              "value": "={{ $json.output.replace(/\\n/g, \"\\\\n\").replace(/\"/g, '\\\\\"') }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        380,
        180
      ],
      "id": "b04c638d-d080-433c-ad56-bed70441b83b",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "content": "Chat Node",
        "height": 180,
        "width": 300
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        140
      ],
      "typeVersion": 1,
      "id": "4fe707f9-e410-458b-940d-a70226d85ac7",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "Response Node",
        "height": 200
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        540,
        140
      ],
      "typeVersion": 1,
      "id": "de884bd4-8542-4427-9194-d9316beb72a9",
      "name": "Sticky Note2"
    }
  ],
  "pinData": {},
  "connections": {
    "Chat": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Home Assistant Announce": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Home Assistant Light Turn on": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Home Assistant Light Turn Off": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "timezone": "Europe/Berlin",
    "callerPolicy": "workflowsFromSameOwner"
  },
  "versionId": "78f7bc06-36a7-40f5-89f1-d63757d78ae7",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "557ea45738eb3f9dd1951dbdd0f74e850f824f491664885d578300b5fd85ca70"
  },
  "id": "yVfGtXWIoVs4wLtP",
  "tags": []
}