{"id":979,"date":"2025-01-06T07:02:56","date_gmt":"2025-01-06T07:02:56","guid":{"rendered":"https:\/\/mailitics.com\/index.php\/2025\/01\/06\/langchain-meets-home-assistant-unlock-the-power-of-generative-ai-in-your-smart-home-f318732d9d84\/"},"modified":"2025-01-06T07:02:56","modified_gmt":"2025-01-06T07:02:56","slug":"langchain-meets-home-assistant-unlock-the-power-of-generative-ai-in-your-smart-home-f318732d9d84","status":"publish","type":"post","link":"https:\/\/mailitics.com\/index.php\/2025\/01\/06\/langchain-meets-home-assistant-unlock-the-power-of-generative-ai-in-your-smart-home-f318732d9d84\/","title":{"rendered":"LangChain Meets Home Assistant: Unlock the Power of Generative AI in Your Smart Home"},"content":{"rendered":"<p>    LangChain Meets Home Assistant: Unlock the Power of Generative AI in Your Smart Home<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n    <!-- no image --><br \/>\n \t<BR><br \/>\n<BR><\/BR><\/p>\n<div>\n<h4>Learn how to create an agent that understands your home\u2019s context, learns your preferences, and interacts with you and your home to accomplish activities you find valuable.<\/h4>\n<figure><img decoding=\"async\" alt=\"\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1024\/0*FmWlPYUgsHV6Wo2G\"><figcaption>Photo by <a href=\"https:\/\/unsplash.com\/@omilaev?utm_source=medium&amp;utm_medium=referral\">Igor Omilaev<\/a> on\u00a0<a href=\"https:\/\/unsplash.com\/?utm_source=medium&amp;utm_medium=referral\">Unsplash<\/a><\/figcaption><\/figure>\n<h3>Introduction<\/h3>\n<p>This article describes the architecture and design of a <a href=\"https:\/\/www.home-assistant.io\/\">Home Assistant<\/a> (HA) integration called home-generative-agent. This project uses <a href=\"https:\/\/www.langchain.com\/\">LangChain<\/a> and <a href=\"https:\/\/www.langchain.com\/langgraph\">LangGraph<\/a> to create a <a href=\"https:\/\/arxiv.org\/abs\/2304.03442#\">generative AI agent<\/a> that interacts with and automates tasks within a HA smart home environment. The agent understands your home\u2019s context, learns your preferences, and interacts with you and your home to accomplish activities you find valuable. Key features include creating automations, analyzing images, and managing home states using various LLMs (Large Language Models). The architecture involves both cloud-based and edge-based models for optimal performance and cost-effectiveness. Installation instructions, configuration details, and information on the project\u2019s architecture and the different models used are included and can be found on the <a href=\"https:\/\/github.com\/goruck\/home-generative-agent\">home-generative-agent<\/a> GitHub. The project is open-source and welcomes contributions.<\/p>\n<p>These are some of the features currently supported:<\/p>\n<ul>\n<li>Create complex Home Assistant automations.<\/li>\n<li>Image scene analysis and understanding.<\/li>\n<li>Home state analysis of entities, devices, and\u00a0areas.<\/li>\n<li>Full agent control of allowed entities in the\u00a0home.<\/li>\n<li>Short- and long-term memory using semantic\u00a0search.<\/li>\n<li>Automatic summarization of home state to manage LLM context\u00a0length.<\/li>\n<\/ul>\n<p>This is my personal project and an example of what I call <a href=\"https:\/\/medium.com\/@lindo.st.angel\/learning-directed-hacking-89d366cbc884\"><em>learning-directed hacking<\/em><\/a>. The project is not affiliated with my work at Amazon nor am I associated with the organizations responsible for Home Assistant or LangChain\/LangGraph in any\u00a0way.<\/p>\n<h3>Important Considerations<\/h3>\n<p>Creating an agent to monitor and control your home can lead to unexpected actions and potentially put your home and yourself at risk due to LLM hallucinations and privacy concerns, especially when exposing home states and user information to cloud-based LLMs. I have made reasonable architectural and design choices to mitigate these risks, but they cannot be completely eliminated.<\/p>\n<p>One key early decision was to rely on a hybrid cloud-edge approach. This enables the use of the most sophisticated reasoning and planning models available, which should help reduce hallucinations. Simpler, more task-focused edge models are employed to further minimize LLM\u00a0errors.<\/p>\n<p>Another critical decision was to leverage LangChain\u2019s capabilities, which allow sensitive information to be hidden from LLM tools and provided only at runtime. For instance, tool logic may require using the ID of the user who made a request. However, such values should generally not be controlled by the LLM. Allowing the LLM to manipulate the user ID could pose security and privacy risks. To mitigate this, I utilized the <a href=\"https:\/\/python.langchain.com\/api_reference\/core\/tools\/langchain_core.tools.base.InjectedToolArg.html\"><em>InjectedToolArg<\/em><\/a> annotation.<\/p>\n<p>Additionally, using large cloud-based LLMs incurs significant cloud costs, and the edge hardware required to run LLM edge models can be expensive. The combined operational and installation costs are likely prohibitive for the average user at this time. An industry-wide effort to \u201cmake LLMs as cheap as CNNs\u201d is needed to bring home agents to the mass\u00a0market.<\/p>\n<p><strong><em>It is important to be aware of these risks and understand that, despite these mitigations, we are still in the early stages of this project and home agents in general. Significant work remains to make these agents truly useful and trustworthy assistants.<\/em><\/strong><\/p>\n<h3>Architecture and\u00a0Design<\/h3>\n<p>Below is a high-level view of the home-generative-agent architecture.<\/p>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/940\/1%2AXjehp4jA_Ptbu3_U391Adg.png?ssl=1\"><figcaption>Diagram by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<p>The general integration architecture follows the best practices as described in <a href=\"https:\/\/developers.home-assistant.io\/docs\/development_index\/\">Home Assistant Core<\/a> and is compliant with <a href=\"https:\/\/www.hacs.xyz\/\">Home Assistant Community Store<\/a> (HACS) publishing requirements.<\/p>\n<p>The agent is built using LangGraph and uses the HA <em>conversation<\/em> component to interact with the user. The agent uses the Home Assistant LLM API to fetch the state of the home and understand the HA native tools it has at its disposal. I implemented all other tools available to the agent using LangChain. The agent employs several LLMs, a large and very accurate primary model for high-level reasoning, smaller specialized helper models for camera image analysis, primary model context summarization, and embedding generation for long-term semantic search. The primary model is cloud-based, and the helper models are edge-based and run under the <a href=\"https:\/\/ollama.com\/\">Ollama<\/a> framework on a computer located in the\u00a0home.<\/p>\n<p>The models currently being used are summarized below.<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/platform.openai.com\/docs\/models#gpt-4o\">GPT-4o<\/a> | OpenAI Cloud | High-level reasoning and\u00a0planning<\/li>\n<li>\n<a href=\"https:\/\/ollama.com\/library\/llama3.2-vision\">llama-3.2-vision-11b<\/a> | Ollama Edge | Image scene\u00a0analysis<\/li>\n<li>\n<a href=\"https:\/\/ollama.com\/library\/llama3.2-vision\">llama-3.2-vision-11b<\/a> | Ollama Edge | Primary model context summarization<\/li>\n<li>\n<a href=\"https:\/\/ollama.com\/library\/mxbai-embed-large\">mxbai-embed-large<\/a> | Ollama Edge | Embedding generation for sematic\u00a0search<\/li>\n<\/ul>\n<h4>LangGraph-based Agent<\/h4>\n<p>LangGraph powers the conversation agent, enabling you to create stateful, multi-actor applications utilizing LLMs as quickly as possible. It extends LangChain\u2019s capabilities, introducing the ability to create and manage cyclical graphs essential for developing complex agent runtimes. A graph models the agent workflow, as seen in the image\u00a0below.<\/p>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/356\/1%2AUJDKU7QaYwzMwXOTlVVIew.png?ssl=1\"><figcaption>Diagram by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<p>The agent workflow has five nodes, each Python module modifying the agent\u2019s state, a shared data structure. The edges between the nodes represent the allowed transitions between them, with solid lines unconditional and dashed lines conditional. Nodes do the work, and edges tell what to do\u00a0next.<\/p>\n<p>The <em>__start__<\/em> and <em>__end__<\/em> nodes inform the graph where to start and stop. The <em>agent<\/em> node runs the primary LLM, and if it decides to use a tool, the <em>action<\/em> node runs the tool and then returns control to the <em>agent<\/em>. The <em>summarize_and_trim<\/em> node processes the LLM\u2019s context to manage growth while maintaining accuracy if <em>agent<\/em> has no tool to call and the number of messages meets the below-mentioned conditions.<\/p>\n<h4>LLM Context Management<\/h4>\n<p>You need to carefully manage the context length of LLMs to balance cost, accuracy, and latency and avoid triggering rate limits such as OpenAI\u2019s Tokens per Minute restriction. The system controls the context length of the primary model in two ways: it trims the messages in the context if they exceed a max parameter, and the context is summarized once the number of messages exceeds another parameter. These parameters are configurable in <em>const.py<\/em>; their description is\u00a0below.<\/p>\n<ul>\n<li>\n<em>CONTEXT_MAX_MESSAGES<\/em> | Messages to keep in context before deletion | Default =\u00a0100<\/li>\n<li>\n<em>CONTEXT_SUMMARIZE_THRESHOLD<\/em> | Messages in context before summary generation | Default =\u00a020<\/li>\n<\/ul>\n<p>The <em>summarize_and_trim<\/em> node in the graph will trim the messages only after content summarization. You can see the Python code associated with this node in the snippet\u00a0below.<\/p>\n<pre>async def _summarize_and_trim(<br>        state: State, config: RunnableConfig, *, store: BaseStore<br>    ) -&gt; dict[str, list[AnyMessage]]:<br>    \"\"\"Coroutine to summarize and trim message history.\"\"\"<br>    summary = state.get(\"summary\", \"\")<br><br>    if summary:<br>        summary_message = SUMMARY_PROMPT_TEMPLATE.format(summary=summary)<br>    else:<br>        summary_message = SUMMARY_INITIAL_PROMPT<br><br>    messages = (<br>        [SystemMessage(content=SUMMARY_SYSTEM_PROMPT)] +<br>        state[\"messages\"] +<br>        [HumanMessage(content=summary_message)]<br>    )<br><br>    model = config[\"configurable\"][\"vlm_model\"]<br>    options = config[\"configurable\"][\"options\"]<br>    model_with_config = model.with_config(<br>        config={<br>            \"model\": options.get(<br>                CONF_VLM,<br>                RECOMMENDED_VLM,<br>            ),<br>            \"temperature\": options.get(<br>                CONF_SUMMARIZATION_MODEL_TEMPERATURE,<br>                RECOMMENDED_SUMMARIZATION_MODEL_TEMPERATURE,<br>            ),<br>            \"top_p\": options.get(<br>                CONF_SUMMARIZATION_MODEL_TOP_P,<br>                RECOMMENDED_SUMMARIZATION_MODEL_TOP_P,<br>            ),<br>            \"num_predict\": VLM_NUM_PREDICT,<br>        }<br>    )<br><br>    LOGGER.debug(\"Summary messages: %s\", messages)<br>    response = await model_with_config.ainvoke(messages)<br><br>    # Trim message history to manage context window length.<br>    trimmed_messages = trim_messages(<br>        messages=state[\"messages\"],<br>        token_counter=len,<br>        max_tokens=CONTEXT_MAX_MESSAGES,<br>        strategy=\"last\",<br>        start_on=\"human\",<br>        include_system=True,<br>    )<br>    messages_to_remove = [m for m in state[\"messages\"] if m not in trimmed_messages]<br>    LOGGER.debug(\"Messages to remove: %s\", messages_to_remove)<br>    remove_messages = [RemoveMessage(id=m.id) for m in messages_to_remove]<br><br>    return {\"summary\": response.content, \"messages\": remove_messages}<\/pre>\n<h4>Latency<\/h4>\n<p>The latency between user requests or the agent taking timely action on the user\u2019s behalf is critical for you to consider in the design. I used several techniques to reduce latency, including using specialized, smaller helper LLMs running on the edge and facilitating primary model prompt caching by structuring the prompts to put static content, such as instructions and examples, upfront and variable content, such as user-specific information at the end. These techniques also reduce primary model usage costs considerably.<\/p>\n<p>You can see the typical latency performance below.<\/p>\n<ul>\n<li>HA intents (e.g., turn on a light) | &lt; 1\u00a0second<\/li>\n<li>Analyze camera image (initial request) | &lt; 3\u00a0seconds<\/li>\n<li>Add automation | &lt; 1\u00a0second<\/li>\n<li>Memory operations | &lt; 1\u00a0second<\/li>\n<\/ul>\n<h4>Tools<\/h4>\n<p>The agent can use HA tools as specified in the <a href=\"https:\/\/developers.home-assistant.io\/docs\/core\/llm\/\">LLM API<\/a> and other tools built in the LangChain framework as defined in <em>tools.py<\/em>. Additionally, you can extend the LLM API with tools of your own as well. The code gives the primary LLM the list of tools it can call, along with instructions on using them in its system message and in the docstring of the tool\u2019s Python function definition. You can see an example of docstring instructions in the code snippet below for the <em>get_and_analyze_camera_image<\/em> tool.<\/p>\n<pre>@tool(parse_docstring=False)<br>async def get_and_analyze_camera_image( # noqa: D417<br>        camera_name: str,<br>        detection_keywords: list[str] | None = None,<br>        *,<br>        # Hide these arguments from the model.<br>        config: Annotated[RunnableConfig, InjectedToolArg()],<br>    ) -&gt; str:<br>    \"\"\"<br>    Get a camera image and perform scene analysis on it.<br><br>    Args:<br>        camera_name: Name of the camera for scene analysis.<br>        detection_keywords: Specific objects to look for in image, if any.<br>            For example, If user says \"check the front porch camera for<br>            boxes and dogs\", detection_keywords would be [\"boxes\", \"dogs\"].<br><br>    \"\"\"<br>    hass = config[\"configurable\"][\"hass\"]<br>    vlm_model = config[\"configurable\"][\"vlm_model\"]<br>    options = config[\"configurable\"][\"options\"]<br>    image = await _get_camera_image(hass, camera_name)<br>    return await _analyze_image(vlm_model, options, image, detection_keywords)<\/pre>\n<p>If the agent decides to use a tool, the LangGraph node <em>action<\/em> is entered, and the node\u2019s code runs the tool. The node uses a simple error recovery mechanism that will ask the agent to try calling the tool again with corrected parameters in the event of making a mistake. The code snippet below shows the Python code associated with the <em>action<\/em>\u00a0node.<\/p>\n<pre>async def _call_tools(<br>        state: State, config: RunnableConfig, *, store: BaseStore<br>    ) -&gt; dict[str, list[ToolMessage]]:<br>    \"\"\"Coroutine to call Home Assistant or langchain LLM tools.\"\"\"<br>    # Tool calls will be the last message in state.<br>    tool_calls = state[\"messages\"][-1].tool_calls<br><br>    langchain_tools = config[\"configurable\"][\"langchain_tools\"]<br>    ha_llm_api = config[\"configurable\"][\"ha_llm_api\"]<br><br>    tool_responses: list[ToolMessage] = []<br>    for tool_call in tool_calls:<br>        tool_name = tool_call[\"name\"]<br>        tool_args = tool_call[\"args\"]<br><br>        LOGGER.debug(<br>            \"Tool call: %s(%s)\", tool_name, tool_args<br>        )<br><br>        def _handle_tool_error(err:str, name:str, tid:str) -&gt; ToolMessage:<br>            return ToolMessage(<br>                content=TOOL_CALL_ERROR_TEMPLATE.format(error=err),<br>                name=name,<br>                tool_call_id=tid,<br>                status=\"error\",<br>            )<br><br>        # A langchain tool was called.<br>        if tool_name in langchain_tools:<br>            lc_tool = langchain_tools[tool_name.lower()]<br><br>            # Provide hidden args to tool at runtime.<br>            tool_call_copy = copy.deepcopy(tool_call)<br>            tool_call_copy[\"args\"].update(<br>                {<br>                    \"store\": store,<br>                    \"config\": config,<br>                }<br>            )<br><br>            try:<br>                tool_response = await lc_tool.ainvoke(tool_call_copy)<br>            except (HomeAssistantError, ValidationError) as e:<br>                tool_response = _handle_tool_error(repr(e), tool_name, tool_call[\"id\"])<br>        # A Home Assistant tool was called.<br>        else:<br>            tool_input = llm.ToolInput(<br>                tool_name=tool_name,<br>                tool_args=tool_args,<br>            )<br><br>            try:<br>                response = await ha_llm_api.async_call_tool(tool_input)<br><br>                tool_response = ToolMessage(<br>                    content=json.dumps(response),<br>                    tool_call_id=tool_call[\"id\"],<br>                    name=tool_name,<br>                )<br>            except (HomeAssistantError, vol.Invalid) as e:<br>                tool_response = _handle_tool_error(repr(e), tool_name, tool_call[\"id\"])<br><br>        LOGGER.debug(\"Tool response: %s\", tool_response)<br>        tool_responses.append(tool_response)<br>    return {\"messages\": tool_responses}<\/pre>\n<p>The LLM API instructs the agent always to call tools using HA <a href=\"https:\/\/developers.home-assistant.io\/docs\/intent_builtin\">built-in intents<\/a> when controlling Home Assistant and to use the intents `HassTurnOn` to lock and `HassTurnOff` to unlock a lock. An intent describes a user\u2019s intention generated by user\u00a0actions.<\/p>\n<p>You can see the list of LangChain tools that the agent can use\u00a0below.<\/p>\n<ul>\n<li>\n<em>get_and_analyze_camera_image<\/em> | run scene analysis on the image from a\u00a0camera<\/li>\n<li>\n<em>upsert_memory<\/em> | add or update a\u00a0memory<\/li>\n<li>\n<em>add_automation<\/em> | create and register a HA automation<\/li>\n<li>\n<em>get_entity_history<\/em> | query HA database for entity\u00a0history<\/li>\n<\/ul>\n<h4>Hardware<\/h4>\n<p>I built the HA installation on a Raspberry Pi 5 with SSD storage, Zigbee, and LAN connectivity. I deployed the edge models under Ollama on an Ubuntu-based server with an AMD 64-bit 3.4 GHz CPU, Nvidia 3090 GPU, and 64 GB system RAM. The server is on the same LAN as the Raspberry Pi.<\/p>\n<h3>Results<\/h3>\n<p>I\u2019ve been using this project at home for a few weeks and have found it useful but frustrating in a few areas that I will be working on to address. Below is a list of pros and cons of my experience with the\u00a0agent.<\/p>\n<h4>Pros<\/h4>\n<ul>\n<li>The camera image scene analysis is very useful and flexible since you can query for almost anything and not have to worry having the right classifier as you would for a traditional ML approach.<\/li>\n<li>Automations are very easy to setup and can be quite complex. Its mind blowing how good the primary LLM is at generating HA-compliant YAML.<\/li>\n<li>Latency in most cases is quite acceptable.<\/li>\n<li>Its very easy to add additional LLM tools and graph states with LangChain and LangGraph.<\/li>\n<\/ul>\n<h4>Cons<\/h4>\n<ul>\n<li>The camera image analysis seems less accurate than traditional ML approaches. For example, detecting packages that are partially obscured is very difficult for the model to\u00a0handle.<\/li>\n<li>The primary model clould costs are high. Running a single package detector once every 30 mins costs about $2.50 per\u00a0day.<\/li>\n<li>Using structured model outputs for the helper LLMs, which would make downstream LLM processing easier, considerably reduces accuracy.<\/li>\n<li>The agent needs to be more proactive. Adding a planning step to the agent graph will hopefully address\u00a0this.<\/li>\n<\/ul>\n<h3>Example Use\u00a0Cases<\/h3>\n<p>Here are a few examples of what you can do with the home-generative-agent (HGA) integration as illustrated by screenshots of the Assist dialog taken by me during interactions with my HA installation.<\/p>\n<ul>\n<li>Create an Automation.<\/li>\n<\/ul>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/400\/1%2AqP8fNmqKJq4wABMCCAyOhg.png?ssl=1\"><figcaption>Image by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<ul>\n<li>Create an automation that runs periodically.<\/li>\n<\/ul>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/400\/1%2A7mxA0LVZJvRhlmsz3HvQBQ.png?ssl=1\"><figcaption>Image by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<p>The snippet below shows that the agent is fluent in YAML based on what it generated and registered as an HA automation.<\/p>\n<pre>alias: Check Litter Box Waste Drawer<br>triggers:<br>  - minutes: \/30<br>    trigger: time_pattern<br>conditions:<br>  - condition: numeric_state<br>    entity_id: sensor.litter_robot_4_waste_drawer<br>    above: 90<br>actions:<br>  - data:<br>      message: The Litter Box waste drawer is more than 90% full!<br>    action: notify.notify<\/pre>\n<ul>\n<li>Check a\u00a0camera.<\/li>\n<\/ul>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/400\/1%2AZxu-tsT9QkIwy6zGzF7_AA.png?ssl=1\"><figcaption>Image by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<ul>\n<li>Check multiple cameras (video by the\u00a0author).<\/li>\n<\/ul>\n<p><a href=\"https:\/\/github.com\/user-attachments\/assets\/230baae5-8702-4375-a3f0-ffa981ee66a3\">https:\/\/github.com\/user-attachments\/assets\/230baae5-8702-4375-a3f0-ffa981ee66a3<\/a><\/p>\n<ul>\n<li>Summarize the home state (video by the\u00a0author).<\/li>\n<\/ul>\n<p><a href=\"https:\/\/github.com\/user-attachments\/assets\/96f834a8-58cc-4bd9-a899-4604c1103a98\">https:\/\/github.com\/user-attachments\/assets\/96f834a8-58cc-4bd9-a899-4604c1103a98<\/a><\/p>\n<ul>\n<li>Long-term memory with semantic\u00a0search.<\/li>\n<\/ul>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/402\/1%2AAtCYRf5MUp_9_oEU5kYy0Q.png?ssl=1\"><\/figure>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/400\/1%2A88vfzObxYGatSDxfvAW4Zw.png?ssl=1\"><\/figure>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/403\/1%2Ahn3Yk6jkxq9IPr3DoYLrEw.png?ssl=1\"><figcaption>Images by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<p>You can see that the agent correctly generates the automation below.<\/p>\n<pre>alias: Prepare Home for Arrival<br>description: Turn on front porch light and unlock garage door lock at 7:30 PM<br>mode: single<br>triggers:<br> - at: \"19:30:00\"<br>    trigger: time<br>actions:<br>  - target:<br>      entity_id: light.front_porch_light<br>    action: light.turn_on<br>    data: {}<br>  - target:<br>      entity_id: lock.garage_door_lock<br>    action: lock.unlock<br>    data: {}<\/pre>\n<ul>\n<li>Check a camera for packages.<\/li>\n<\/ul>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/402\/1%2Arg3NMW1PTrRGRRf1lvcmqA.png?ssl=1\"><figcaption>Image by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<p>Below is the camera image the agent analyzed, you can see that two packages are\u00a0visible.<\/p>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/486\/1%2Ab6Hk2T0TiM32qpWcYHM-NQ.png?ssl=1\"><figcaption>Photo by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<ul>\n<li>Proactive notification of package delivery.<\/li>\n<\/ul>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/403\/1%2Albq7HT0FTHjF_8J3IrilVA.png?ssl=1\"><figcaption>Image by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<p>Below is an example notification from this automation if any boxes or packages are\u00a0visible.<\/p>\n<figure><img data-recalc-dims=\"1\" decoding=\"async\" alt=\"\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/457\/1%2AiHF_bKOlkuBACO_ohuLpFg.png?ssl=1\"><figcaption>Image by Lindo St.\u00a0Angel<\/figcaption><\/figure>\n<h3>Conclusions<\/h3>\n<p>The Home Generative Agent offers an intriguing way to make your Home Assistant setup more user-friendly and intuitive. By enabling natural language interactions and simplifying automation, it provides a practical and useful tool for everyday smart home\u00a0use.<\/p>\n<p>Using a home generative agent carries security, privacy and cost risks that need further mitigation and innovation before it can be truly useful for the mass\u00a0market.<\/p>\n<p>Whether you\u2019re new to Home Assistant or a seasoned user, this integration is a great way to enhance your system\u2019s capabilities and get familiar with using generative AI and agents at home. If you\u2019re interested in exploring its potential, visit the <a href=\"https:\/\/github.com\/goruck\/home-generative-agent\">Home Generative Agent GitHub page<\/a> and get started\u00a0today.<\/p>\n<h3>Appendix<\/h3>\n<h4>Installation<\/h4>\n<p>1. Using the tool of choice, open your HA configuration\u2019s directory (folder) (where you find <em>configuration.yaml<\/em>).<\/p>\n<p>2. If you do not have a `custom_components` directory (folder), you must create\u00a0it.<\/p>\n<p>3. In the <em>custom_components<\/em> directory (folder), create a new folder called <em>home_generative_agent<\/em>.<\/p>\n<p>4. Download <em>_all_<\/em> the files from the <em>custom_components\/home_generative_agent\/<\/em> directory (folder) in this repository.<\/p>\n<p>4. Place the files you downloaded in the new directory (folder) you\u00a0created.<\/p>\n<p>6. Restart Home Assistant<\/p>\n<p>7. In the HA UI, go to \u201cConfiguration\u201d -&gt; \u201cIntegrations\u201d click \u201c+,\u201d and search for \u201cHome Generative Agent\u201d<\/p>\n<p>8. Install all the Blueprints in the <em>blueprints<\/em> directory (folder).<\/p>\n<h4>Configuration<\/h4>\n<p>Configuration is done in the HA UI and via the parameters in <em>const.py<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/medium.com\/_\/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=f318732d9d84\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<hr>\n<p><a href=\"https:\/\/towardsdatascience.com\/langchain-meets-home-assistant-unlock-the-power-of-generative-ai-in-your-smart-home-f318732d9d84\">LangChain Meets Home Assistant: Unlock the Power of Generative AI in Your Smart Home<\/a> was originally published in <a href=\"https:\/\/towardsdatascience.com\/\">Towards Data Science<\/a> on Medium, where people are continuing the conversation by highlighting and responding to this story.<\/p>\n<\/div>\n<p> \t<BR><br \/>\n <BR><\/BR><br \/>\n    Lindo St. Angel<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n<a href=\"https:\/\/medium.com\/m\/global-identity-2?redirectUrl=https%3A%2F%2Ftowardsdatascience.com%2Flangchain-meets-home-assistant-unlock-the-power-of-generative-ai-in-your-smart-home-f318732d9d84\">Go to original source<\/a><br \/>\n \t<BR><br \/>\n <BR><\/BR><\/p>\n","protected":false},"excerpt":{"rendered":"<p>LangChain Meets Home Assistant: Unlock the Power of Generative AI in Your Smart Home Learn how to create an agent that understands your home\u2019s context, learns your preferences, and interacts with you and your home to accomplish activities you find valuable. Photo by Igor Omilaev on\u00a0Unsplash Introduction This article describes the architecture and design of [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[62,93,1119,978,447,1120],"tags":[448,30,163],"class_list":["post-979","post","type-post","status-publish","format-standard","hentry","category-aimldsaimlds","category-edge-computing","category-home-assistant","category-langchain","category-llm-agent","category-smart-home","tag-agent","tag-home","tag-your"],"_links":{"self":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/979"}],"collection":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/comments?post=979"}],"version-history":[{"count":0,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/979\/revisions"}],"wp:attachment":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/media?parent=979"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/categories?post=979"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/tags?post=979"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}