<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Home Assistant Developer Docs Blog</title>
        <link>https://developers.home-assistant.io/blog</link>
        <description>Home Assistant Developer Docs Blog</description>
        <lastBuildDate>Wed, 13 May 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Changes to the condition and script APIs]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/13/condition-script-api-changes</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/13/condition-script-api-changes</guid>
            <pubDate>Wed, 13 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Summary]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="summary">Summary<a href="https://developers.home-assistant.io/blog/2026/05/13/condition-script-api-changes#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>The condition and script APIs have been changed.</p>
<p>Conditions are now instances of condition classes, which are evaluated by calling the <code>async_check</code> method and discarded by calling the <code>async_unload</code> method. Also, conditions may optionally implement an <code>_async_setup</code> or <code>_async_unload</code> method. Note that users of conditions don't need to call the condition's <code>async_setup</code> method.</p>
<p>During a deprecation period, which ends with the release of Home Assistant Core 2027.1, it's possible to use the condition object as a callable.</p>
<p>Scripts also have an <code>async_unload</code> method which must be called when the script is no longer needed.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="impact-on-custom-integrations">Impact on custom integrations<a href="https://developers.home-assistant.io/blog/2026/05/13/condition-script-api-changes#impact-on-custom-integrations" class="hash-link" aria-label="Direct link to Impact on custom integrations" title="Direct link to Impact on custom integrations" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="custom-integrations-which-create-conditions-or-scripts">Custom integrations which create conditions or scripts<a href="https://developers.home-assistant.io/blog/2026/05/13/condition-script-api-changes#custom-integrations-which-create-conditions-or-scripts" class="hash-link" aria-label="Direct link to Custom integrations which create conditions or scripts" title="Direct link to Custom integrations which create conditions or scripts" translate="no">​</a></h3>
<p>Custom integrations which create condition objects should evaluate them by calling the <code>async_check</code> method and call the <code>async_unload</code> method when the condition is no longer needed.</p>
<p>Example:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">helpers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">condition </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    async_condition_from_config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    async_validate_condition_config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Validate condition config</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">validated_config </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> async_validate_condition_config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Create a condition</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">condition </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> async_condition_from_config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> validated_config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Evaluate the condition</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">result </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> condition</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_check</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Discard the condition</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">condition</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_unload</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Custom integrations which create scripts should call the <code>async_unload</code> method when the script is no longer needed.</p>
<p>Example:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">helpers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">script </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Script</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    async_validate_actions_config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Validate script config</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">validated_config </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> async_validate_actions_config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Create a script</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">script </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> Script</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> validated_config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Execute the script</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">result </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Discard the script</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_unload</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="custom-integrations-which-provide-a-condition-platform">Custom integrations which provide a condition platform<a href="https://developers.home-assistant.io/blog/2026/05/13/condition-script-api-changes#custom-integrations-which-provide-a-condition-platform" class="hash-link" aria-label="Direct link to Custom integrations which provide a condition platform" title="Direct link to Custom integrations which provide a condition platform" translate="no">​</a></h3>
<p>Integrations which provide a condition platform don't need to change, but may implement <code>_async_setup</code> and <code>_async_unload</code> method if the platform needs to perform async initialization or do tear down.</p>
<p>Example:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">core </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> HomeAssistant</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">helpers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">condition </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Condition</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    ConditionCheckParams</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    ConditionConfig</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">helpers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">typing </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> ConfigType</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">CustomCondition</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">Condition</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""A custom condition."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token decorator annotation punctuation" style="color:rgb(199, 146, 234)">@classmethod</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">async_validate_config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        cls</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> HomeAssistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ConfigType</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> ConfigType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Validate config."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">__init__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> HomeAssistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ConditionConfig</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Initialize condition."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token builtin" style="color:rgb(130, 170, 255)">super</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">__init__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">_async_setup</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Set up the condition checker."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">_async_unload</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Clean up any resources held by the checker."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">_async_check</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">**</span><span class="token plain">kwargs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Unpack</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">ConditionCheckParams</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">bool</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Check the condition."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><br></div></code></pre></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Format entity names in custom cards]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/11/format-entity-name-helper</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/11/format-entity-name-helper</guid>
            <pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[As of Home Assistant 2026.4, the hass object exposes a formatEntityName helper. It is the same function used by the built-in cards (tile card, entity rows, ...) to compute the display name of an entity from its registry context (entity, device, area, floor). Custom cards can use it to produce names that stay consistent with the rest of the dashboard.]]></description>
            <content:encoded><![CDATA[<p>As of Home Assistant 2026.4, the <code>hass</code> object exposes a <code>formatEntityName</code> helper. It is the same function used by the built-in cards (tile card, entity rows, ...) to compute the display name of an entity from its registry context (entity, device, area, floor). Custom cards can use it to produce names that stay consistent with the rest of the dashboard.</p>
<p>Given a temperature sensor named <code>Temperature</code> on a device named <code>Thermostat</code>:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> stateObj </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token property-access">states</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(195, 232, 141)">"sensor.living_room_thermostat_temperature"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token method function property-access" style="color:rgb(130, 170, 255)">formatEntityName</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  stateObj</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token literal-property property">type</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"device"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token literal-property property">type</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"entity"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token literal-property property">separator</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">" · "</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// "Thermostat · Temperature"</span><br></div></code></pre></div></div>
<p>The frontend also ships an <code>entity_name</code> selector. If your card uses the <a class="" href="https://developers.home-assistant.io/docs/frontend/custom-ui/custom-card#using-the-built-in-form-editor">built-in form editor</a>, you can offer users the same name picker the built-in cards use — accepting either a free-form string or a composition of registry items.</p>
<p>Take a look at the updated <a class="" href="https://developers.home-assistant.io/docs/frontend/data#hassformatentitynamestateobj-name-options">data documentation</a> for the full reference and more examples.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[MQTT publish API changes]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/11/mqtt-publish-api-changes</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/11/mqtt-publish-api-changes</guid>
            <pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[In the future, the MQTT publish API will require explicit values for qos and retain. Passing None for either argument will no longer be supported.]]></description>
            <content:encoded><![CDATA[<p>In the future, the MQTT publish API will require explicit values for <code>qos</code> and <code>retain</code>. Passing <code>None</code> for either argument will no longer be supported.
Custom integrations should update their code to accept the defaults, or pass valid typed arguments.
The fallbacks of <code>None</code> to a valid value for <code>qos</code> and <code>retain</code> will stop working with HA Core 2027.6.</p>
<p>The new API signatures are:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">publish</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> HomeAssistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    topic</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    payload</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> PublishPayloadType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    qos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">int</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    retain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">bool</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">False</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    encoding</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> DEFAULT_ENCODING</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Publish message to a MQTT topic."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">create_task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">async_publish</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> topic</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> payload</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> qos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> retain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> encoding</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>and</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">async_publish</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> HomeAssistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    topic</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    payload</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> PublishPayloadType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    qos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">int</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    retain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">bool</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">False</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    encoding</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> DEFAULT_ENCODING</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Publish message to a MQTT topic."""</span><br></div></code></pre></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[MQTT publish API supports message expiry interval]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/11/mqtt-publish-api-message-expiry-interval</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/11/mqtt-publish-api-message-expiry-interval</guid>
            <pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The MQTT publish API now supports setting a message expiry interval.]]></description>
            <content:encoded><![CDATA[<p>The MQTT publish API now supports setting a message expiry interval.
Previously, retained messages were stored by the broker until they were replaced or explicitly cleared. With a <code>message_expiry_interval</code> set (in seconds), a published message — including a retained one — will automatically expire after the specified interval.
This option is only supported when using MQTT protocol version 5; it is ignored when using earlier protocol versions.</p>
<p>The new API signatures are:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">publish</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> HomeAssistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    topic</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    payload</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> PublishPayloadType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    qos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">int</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    retain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">bool</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">False</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    encoding</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> DEFAULT_ENCODING</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    message_expiry_interval</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">int</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Publish message to a MQTT topic."""</span><br></div></code></pre></div></div>
<p>and</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">async_publish</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> HomeAssistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    topic</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    payload</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> PublishPayloadType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    qos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">int</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    retain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">bool</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">False</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    encoding</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> DEFAULT_ENCODING</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    message_expiry_interval</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">int</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Publish message to a MQTT topic."""</span><br></div></code></pre></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deprecating config entry listener with reloading methods in config flow]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/07/config-entry-listener-together-with-reloading-methods</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/07/config-entry-listener-together-with-reloading-methods</guid>
            <pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[As of Home Assistant Core 2026.6, using a config entry listener together with any reloading methods in a config flow is deprecated and will result in an error from 2026.12.]]></description>
            <content:encoded><![CDATA[<p>As of Home Assistant Core 2026.6, using a config entry listener together with any reloading methods in a config flow is deprecated and will result in an error from 2026.12.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://developers.home-assistant.io/blog/2026/05/07/config-entry-listener-together-with-reloading-methods#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></h2>
<p>Using a config entry listener together with any reloading methods in a config flow can cause the integration to reload twice and/or create a race condition.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="possible-solutions">Possible solutions<a href="https://developers.home-assistant.io/blog/2026/05/07/config-entry-listener-together-with-reloading-methods#possible-solutions" class="hash-link" aria-label="Direct link to Possible solutions" title="Direct link to Possible solutions" translate="no">​</a></h2>
<ul>
<li class="">Remove the config entry listener and rely only on the reloading methods in your config flow.</li>
<li class="">Use <code>async_update_and_abort()</code> instead of <code>async_update_reload_and_abort()</code>.</li>
<li class="">Set <code>reload_on_update=False</code> when calling <code>_abort_if_unique_id_configured()</code>.</li>
</ul>
<p>More details can be found in the <a href="https://github.com/home-assistant/core/pull/169198" target="_blank" rel="noopener noreferrer" class="">core PR</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Frontend component updates in 2026.5]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5</guid>
            <pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Component updates]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="component-updates">Component updates<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#component-updates" class="hash-link" aria-label="Direct link to Component updates" title="Direct link to Component updates" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ha-progress-bar">ha-progress-bar<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#ha-progress-bar" class="hash-link" aria-label="Direct link to ha-progress-bar" title="Direct link to ha-progress-bar" translate="no">​</a></h3>
<p>A new component replaces <code>mwc-progress-bar</code> in our codebase and is fully themeable. Check out this <a href="https://github.com/home-assistant/frontend/pull/51489" target="_blank" rel="noopener noreferrer" class="">PR</a> for a fully custom progress bar.</p>
<p>New component specific tokens:</p>
<div class="language-css codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-css codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token variable" style="color:rgb(191, 199, 213)">--ha-progress-bar-indicator-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-progress-bar-indicator-background</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-progress-bar-track-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-progress-bar-track-height</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-progress-bar-border-radius</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-progress-bar-animation-duration</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-progress-bar-indicator-highlight-image</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-progress-bar-indicator-highlight-width</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-progress-bar-indicator-highlight-height</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ha-switch">ha-switch<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#ha-switch" class="hash-link" aria-label="Direct link to ha-switch" title="Direct link to ha-switch" translate="no">​</a></h3>
<p><code>ha-switch</code> was migrated to webawesome. It now has many CSS properties to make customization easier. We also removed some tokens from the old switch:</p>
<p>Removed tokens:</p>
<div class="language-css codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-css codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token variable" style="color:rgb(191, 199, 213)">--switch-unchecked-button-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--switch-unchecked-track-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--switch-unchecked-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--switch-checked-button-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--switch-checked-track-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--switch-checked-color</span><br></div></code></pre></div></div>
<p>New component specific tokens:</p>
<div class="language-css codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-css codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-size</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-thumb-size</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-width</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-background-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-thumb-background-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-background-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-thumb-background-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-checked-background-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-checked-thumb-background-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-checked-background-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-checked-thumb-background-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-border-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-thumb-border-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-thumb-border-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-checked-border-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-checked-thumb-border-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-checked-border-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-checked-thumb-border-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-thumb-box-shadow</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-disabled-opacity</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-required-marker</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-switch-required-marker-offset</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ha-checkbox">ha-checkbox<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#ha-checkbox" class="hash-link" aria-label="Direct link to ha-checkbox" title="Direct link to ha-checkbox" translate="no">​</a></h3>
<p><code>ha-checkbox</code> was also migrated to webawesome and got new CSS properties. You can no longer use MDC tokens for it, but we added a set of tokens to customize the new checkbox.</p>
<p>New component specific tokens:</p>
<div class="language-css codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-css codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-size</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-border-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-border-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-background-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-background-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-checked-background-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-checked-background-color-hover</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-checked-icon-color</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-checked-icon-scale</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-border-radius</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-border-width</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-required-marker</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-checkbox-required-marker-offset</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ha-textarea">ha-textarea<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#ha-textarea" class="hash-link" aria-label="Direct link to ha-textarea" title="Direct link to ha-textarea" translate="no">​</a></h3>
<p><code>ha-textarea</code> was migrated to webawesome and got new CSS properties. You can no longer use MDC tokens for it, but we added a set of tokens to customize the new textarea.</p>
<p>The API changed slightly. To make your textarea grow in size, set the <code>resize</code> prop to <code>auto</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ha-adaptive-popover">ha-adaptive-popover<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#ha-adaptive-popover" class="hash-link" aria-label="Direct link to ha-adaptive-popover" title="Direct link to ha-adaptive-popover" translate="no">​</a></h3>
<p>You might already know the (fairly new) <code>ha-adaptive-dialog</code> component. It combines a dialog and bottom sheet by showing a dialog on desktop and a bottom sheet on mobile.
We added <code>ha-adaptive-popover</code> as the popover counterpart to the adaptive dialog. It shows a popover on desktop and a bottom sheet on mobile. It is based on <code>ha-adaptive-dialog</code> and is currently used in the tile card date picker feature.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="removed-ha-fab">Removed ha-fab<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#removed-ha-fab" class="hash-link" aria-label="Direct link to Removed ha-fab" title="Direct link to Removed ha-fab" translate="no">​</a></h3>
<p><code>ha-fab</code> was removed, we use just a normal <code>ha-button</code> now, since the position styling was always done from the parent component.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="style-updates">Style updates<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#style-updates" class="hash-link" aria-label="Direct link to Style updates" title="Direct link to Style updates" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="box-shadow-tokens">Box shadow tokens<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#box-shadow-tokens" class="hash-link" aria-label="Direct link to Box shadow tokens" title="Direct link to Box shadow tokens" translate="no">​</a></h3>
<p>We added new global box shadow tokens: <code>--ha-box-shadow-s</code>, <code>--ha-box-shadow-m</code>, <code>--ha-box-shadow-l</code></p>
<p>But we also removed the old box shadow tokens:</p>
<div class="language-css codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-css codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-shadow-light</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-shadow-dark</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-shadow-offset-x-</span><span class="token plain">...</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-shadow-blur-</span><span class="token plain">...</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-shadow-spread-</span><span class="token plain">..</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="surface-colors">Surface colors<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-component-updates-2026.5#surface-colors" class="hash-link" aria-label="Direct link to Surface colors" title="Direct link to Surface colors" translate="no">​</a></h3>
<p>In the next release we plan to change the way we handle surface background colors. The tokens are introduced now but are just used for ha-tooltip.</p>
<p>New tokens:</p>
<div class="language-css codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-css codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-surface-default</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-surface-low</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-surface-lower</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-surface-default-inverted</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-surface-low-inverted</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-surface-lower-inverted</span><br></div></code></pre></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Frontend context groups, new context decorators and deprecated contexts]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/04/frontend-context-groups-decorators</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/04/frontend-context-groups-decorators</guid>
            <pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Last release we introduced the lazy context and we wanted to use hass context and lazy context more in favor of passing the hass object.]]></description>
            <content:encoded><![CDATA[<p>Last release we introduced the lazy context and we wanted to use hass context and lazy context more in favor of passing the hass object.
We found that small tasks often required subscribing to many contexts, so we grouped Hass contexts into logical groups.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="context-groups">Context groups<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-context-groups-decorators#context-groups" class="hash-link" aria-label="Direct link to Context groups" title="Direct link to Context groups" translate="no">​</a></h2>
<p>Following context groups have been added:</p>
<ul>
<li class="">registriesContext: contains all registries (device, entity, area, etc)</li>
<li class="">internationalizationContext: contains all internationalization related data (locale, localize, etc)</li>
<li class="">apiContext: contains all API related methods (callService, callWS, etc)</li>
<li class="">connectionContext: contains all connection related data (connection, connected, hassUrl, etc)</li>
<li class="">uiContext: contains all UI related data (themes, panels, dockedSidebar, etc)</li>
<li class="">configContext: contains all config related data (auth, config, user, etc)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="consume-context-entry-decorators">Consume context entry decorators<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-context-groups-decorators#consume-context-entry-decorators" class="hash-link" aria-label="Direct link to Consume context entry decorators" title="Direct link to Consume context entry decorators" translate="no">​</a></h2>
<p>In the last <a class="" href="https://developers.home-assistant.io/blog/2026/03/25/frontend-lazy-context">blogpost</a> I showed how to use context with <code>@transform</code>. <code>@transform</code> is powerful, but sometimes you only need a single context entry and do not want to define a transform function.
To support that, we added decorators that consume a single context entry directly.
You pass an array that defines where the entity ID comes from (usually a config property), and the decorator consumes the correct context and maps the entity ID to the correct registry entry.
It also watches the defined path and updates the entry when needed.</p>
<p>New decorators:</p>
<ul>
<li class="">@consumeEntityState</li>
<li class="">@consumeEntityStates</li>
<li class="">@consumeEntityRegistryEntry</li>
</ul>
<p>sample usage:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token decorator at operator" style="color:rgb(137, 221, 255)">@</span><span class="token decorator function" style="color:rgb(130, 170, 255)">state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token decorator at operator" style="color:rgb(137, 221, 255)">@</span><span class="token decorator function" style="color:rgb(130, 170, 255)">consumeEntityRegistryEntry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> entityIdPath</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(195, 232, 141)">"_config"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"entity"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">_entity</span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> EntityRegistryDisplayEntry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>We may add more of these decorators in the future, e.g. for areas, devices, etc.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecate-contexts">Deprecate contexts<a href="https://developers.home-assistant.io/blog/2026/05/04/frontend-context-groups-decorators#deprecate-contexts" class="hash-link" aria-label="Direct link to Deprecate contexts" title="Direct link to Deprecate contexts" translate="no">​</a></h2>
<p>These contexts are still available, but they can be removed in a future release. Use the new context groups instead.</p>
<ul>
<li class="">connectionSingleContext</li>
<li class="">localizeContext</li>
<li class="">localeContext</li>
<li class="">configSingleContext</li>
<li class="">themesContext</li>
<li class="">selectedThemeContext</li>
<li class="">userContext</li>
<li class="">userDataContext</li>
<li class="">panelsContext</li>
<li class="">authContext</li>
</ul>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Serious about serial: migrating from pyserial to serialx]]></title>
            <link>https://developers.home-assistant.io/blog/2026/04/27/pyserial-to-serialx</link>
            <guid>https://developers.home-assistant.io/blog/2026/04/27/pyserial-to-serialx</guid>
            <pubDate>Mon, 27 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Existing integrations and libraries communicating with serial ports should migrate from pyserial, pyserial-asyncio, and pyserial-asyncio-fast to serialx. This new library features native asyncio support on all platforms and will allow your integrations and libraries to take advantage of ESPHome serial proxies in Home Assistant, and includes critical fixes for asyncio event loop stability.]]></description>
            <content:encoded><![CDATA[<p>Existing integrations and libraries communicating with serial ports should migrate from <code>pyserial</code>, <code>pyserial-asyncio</code>, and <code>pyserial-asyncio-fast</code> to <a href="https://github.com/puddly/serialx" target="_blank" rel="noopener noreferrer" class=""><code>serialx</code></a>. This new library features native asyncio support on all platforms and will allow your integrations and libraries to take advantage of <a href="https://esphome.io/components/serial_proxy/" target="_blank" rel="noopener noreferrer" class="">ESPHome serial proxies</a> in Home Assistant, and includes critical fixes for asyncio event loop stability.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://developers.home-assistant.io/blog/2026/04/27/pyserial-to-serialx#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></h2>
<p><code>pyserial</code> has been the de facto serial library in Python for many years and has broad support for all popular platforms. Its API, however, predates asyncio in Python and is sync-only. The <code>pyserial-asyncio</code> package was eventually released to bridge <code>pyserial</code> with asyncio. Unfortunately, <code>pyserial-asyncio</code> development never reached 1.0 stability or cross-platform support, and neither <code>pyserial</code> nor <code>pyserial-asyncio</code> have had PyPI releases in almost five years. We forked <code>pyserial-asyncio</code> and released <a href="https://developers.home-assistant.io/blog/2026/01/05/pyserial-asyncio-fast/" target="_blank" rel="noopener noreferrer" class=""><code>pyserial-asyncio-fast</code></a> to fix outstanding issues affecting Core event loop stability.</p>
<p>We developed <code>serialx</code> from the ground up as a modern Python serial library with native sync and async APIs. It is import-compatible with the <code>serial</code>, <code>serial_asyncio</code>, and <code>serial_asyncio_fast</code> modules and allows existing packages to migrate with very minimal changes, if any.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="migration">Migration<a href="https://developers.home-assistant.io/blog/2026/04/27/pyserial-to-serialx#migration" class="hash-link" aria-label="Direct link to Migration" title="Direct link to Migration" translate="no">​</a></h2>
<p>The <code>serialx</code> documentation has <a href="https://puddly.github.io/serialx/how-to/pyserial-migration.html" target="_blank" rel="noopener noreferrer" class="">an extensive migration guide</a> that goes into more detail.</p>
<p>Most packages just need to replace <code>pyserial</code>, <code>pyserial-asyncio</code>, and <code>pyserial-asyncio-fast</code> with <code>serialx</code> in their <code>setup.py</code> or <code>pyproject.toml</code> file and update exception handling to replace broad catching of <code>SerialException</code> with more granular error handling (such as <code>OSError</code> and <code>TimeoutError</code>).</p>
<p>Packages directly constructing a sync <code>serial.Serial()</code> object should migrate to using the <code>serialx.serial_for_url()</code> helper to ensure automatic compatibility with all supported protocols.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="prompt-for-your-agent">Prompt for your agent<a href="https://developers.home-assistant.io/blog/2026/04/27/pyserial-to-serialx#prompt-for-your-agent" class="hash-link" aria-label="Direct link to Prompt for your agent" title="Direct link to Prompt for your agent" translate="no">​</a></h3>
<p>The migration itself is mechanical, paste the following instructions into your agent of choice:</p>
<blockquote>
<p>Migrate my code from pyserial, pyserial-asyncio, and pyserial-asyncio-fast to serialx using
<a href="https://raw.githubusercontent.com/puddly/serialx/refs/heads/dev/docs/how-to/pyserial-migration.md" target="_blank" rel="noopener noreferrer" class="">https://raw.githubusercontent.com/puddly/serialx/refs/heads/dev/docs/how-to/pyserial-migration.md</a></p>
</blockquote>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[New radio frequency entity platform for RF device integrations]]></title>
            <link>https://developers.home-assistant.io/blog/2026/04/24/radio-frequency-entity-platform</link>
            <guid>https://developers.home-assistant.io/blog/2026/04/24/radio-frequency-entity-platform</guid>
            <pubDate>Fri, 24 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Home Assistant now has a radio_frequency entity platform that decouples RF transceiver hardware from the devices it controls. Instead of each device integration talking directly to specific RF hardware, transmitter integrations (like esphome) expose RadioFrequencyTransmitterEntity instances, and device integrations send commands through them via helper functions.]]></description>
            <content:encoded><![CDATA[<p>Home Assistant now has a <code>radio_frequency</code> entity platform that decouples RF transceiver hardware from the devices it controls. Instead of each device integration talking directly to specific RF hardware, transmitter integrations (like <code>esphome</code>) expose <code>RadioFrequencyTransmitterEntity</code> instances, and device integrations send commands through them via helper functions.</p>
<p>This mirrors the <a class="" href="https://developers.home-assistant.io/blog/2026/03/30/infrared-entity-platform"><code>infrared</code> entity platform</a> and was approved in <a href="https://github.com/home-assistant/architecture/discussions/1365" target="_blank" rel="noopener noreferrer" class="">architecture discussion #1365</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="architecture">Architecture<a href="https://developers.home-assistant.io/blog/2026/04/24/radio-frequency-entity-platform#architecture" class="hash-link" aria-label="Direct link to Architecture" title="Direct link to Architecture" translate="no">​</a></h2>
<p>The <code>radio_frequency</code> domain sits between two types of integrations:</p>
<ul>
<li class=""><strong>Transmitter integrations</strong> (ESPHome, Broadlink, …) implement the <code>RadioFrequencyTransmitterEntity</code> base class to provide hardware-specific RF transmission.</li>
<li class=""><strong>Consumer integrations</strong> (garage door openers, RF remotes, wireless switches, …) use helper functions to send device-specific RF commands through available transmitters.</li>
</ul>
<p>Users select which transmitter to use during the consumer integration's config flow, filtered by the frequency the device operates on.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="implementing-a-transmitter-integration">Implementing a transmitter integration<a href="https://developers.home-assistant.io/blog/2026/04/24/radio-frequency-entity-platform#implementing-a-transmitter-integration" class="hash-link" aria-label="Direct link to Implementing a transmitter integration" title="Direct link to Implementing a transmitter integration" translate="no">​</a></h2>
<p>Transmitter integrations provide the <code>radio_frequency</code> platform by subclassing <code>RadioFrequencyTransmitterEntity</code>, declaring their <code>supported_frequency_ranges</code>, and implementing <code>async_send_command</code>:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> rf_protocols </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> RadioFrequencyCommand</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">radio_frequency </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> RadioFrequencyTransmitterEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">MyRadioFrequencyTransmitterEntity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">RadioFrequencyTransmitterEntity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""My RF transmitter."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token decorator annotation punctuation" style="color:rgb(199, 146, 234)">@property</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">supported_frequency_ranges</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">list</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token builtin" style="color:rgb(130, 170, 255)">tuple</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token builtin" style="color:rgb(130, 170, 255)">int</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">int</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Return the list of (min_hz, max_hz) ranges this hardware can transmit on."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">300_000_000</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">348_000_000</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">433_050_000</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">434_790_000</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">async_send_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> RadioFrequencyCommand</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Send an RF command."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_device</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">transmit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            frequency</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">frequency</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            modulation</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">modulation</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            timings</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">get_raw_timings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>The base class tracks the timestamp of the last sent command as the entity state, so transmitter integrations only need to handle the actual transmission.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="building-a-consumer-integration">Building a consumer integration<a href="https://developers.home-assistant.io/blog/2026/04/24/radio-frequency-entity-platform#building-a-consumer-integration" class="hash-link" aria-label="Direct link to Building a consumer integration" title="Direct link to Building a consumer integration" translate="no">​</a></h2>
<p>Consumer integrations control RF devices by sending commands through a transmitter entity. They don't interact with RF hardware directly. The snippets below are adapted from the <a href="https://github.com/home-assistant/core/pull/168450" target="_blank" rel="noopener noreferrer" class=""><code>honeywell_string_lights</code></a> integration, which uses the platform to drive a Honeywell String Lights set.</p>
<p><strong>1. Declare the dependency</strong> in <code>manifest.json</code>:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "dependencies": ["radio_frequency"]</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p><strong>2. Load the device's commands</strong> from the <a href="https://github.com/home-assistant-libs/rf-protocols" target="_blank" rel="noopener noreferrer" class=""><code>rf-protocols</code></a> library:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> rf_protocols </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> get_codes</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">COMMANDS </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> get_codes</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"honeywell/string_lights"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Each loaded command exposes the frequency and modulation the device uses, which the config flow needs to filter transmitters.</p>
<p><strong>3. Let the user pick a transmitter</strong> in the config flow, using a sample command to filter by the frequency and modulation the device requires:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> rf_protocols </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> RadioFrequencyCommand</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">radio_frequency </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> async_get_transmitters</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">exceptions </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> HomeAssistantError</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">sample_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> RadioFrequencyCommand </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_add_executor_job</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    COMMANDS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">load_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"turn_on"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">try</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    transmitters </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> async_get_transmitters</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> sample_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">frequency</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> sample_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">modulation</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">except</span><span class="token plain"> HomeAssistantError</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_abort</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">reason</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"no_transmitters"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">not</span><span class="token plain"> transmitters</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_abort</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">reason</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"no_compatible_transmitters"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Only <code>ModulationType.OOK</code> (on-off keying) is supported right now; later releases can add other modulation types.</p>
<p><strong>4. Send RF commands</strong> using the helper function and the stored transmitter entity ID:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">radio_frequency </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> async_send_command</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">async_turn_on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">**</span><span class="token plain">kwargs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Any</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Turn on the light."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    command </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_add_executor_job</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        COMMANDS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">load_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"turn_on"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> async_send_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_transmitter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_attr_is_on </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">True</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_write_ha_state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="rf-protocols-and-codes">RF protocols and codes<a href="https://developers.home-assistant.io/blog/2026/04/24/radio-frequency-entity-platform#rf-protocols-and-codes" class="hash-link" aria-label="Direct link to RF protocols and codes" title="Direct link to RF protocols and codes" translate="no">​</a></h2>
<p>RF protocol encoders and device code sets live outside Home Assistant in the <a href="https://github.com/home-assistant-libs/rf-protocols" target="_blank" rel="noopener noreferrer" class=""><code>rf-protocols</code></a> library. Common protocols and well-known device codes should be contributed there. For niche or proprietary protocols, a separate third-party library can also be used.</p>
<p>For full details, see the <a class="" href="https://developers.home-assistant.io/docs/core/entity/radio-frequency">radio frequency entity documentation</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Registering custom dashboard strategies]]></title>
            <link>https://developers.home-assistant.io/blog/2026/04/21/registering-custom-dashboard-strategies</link>
            <guid>https://developers.home-assistant.io/blog/2026/04/21/registering-custom-dashboard-strategies</guid>
            <pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[As of Home Assistant 2026.5, you can now register custom dashboard strategies, just as you can with custom cards, making them easier to discover and add using the new dashboard dialog under the Community dashboards section.]]></description>
            <content:encoded><![CDATA[<p>As of Home Assistant 2026.5, you can now register custom dashboard strategies, just as you can with <a class="" href="https://developers.home-assistant.io/docs/frontend/custom-ui/custom-card">custom cards</a>, making them easier to discover and add using the <strong>new dashboard</strong> dialog under the <strong>Community dashboards</strong> section.</p>
<p>Previously, you had to send users to create a blank dashboard, edit in YAML mode, and paste in your custom strategy. Now you can register a friendly name, description, and documentation.</p>
<p>To register your strategy, call <code>window.customStrategies.push()</code> with an object containing the following keys:</p>
<ul>
<li class=""><code>type</code>: The strategy type without the <code>custom:</code> prefix, for example <code>"my-demo"</code>.</li>
<li class=""><code>strategyType</code>: Set to <code>"dashboard"</code> to register a dashboard strategy.</li>
<li class=""><code>name</code>: The friendly name of the strategy.</li>
<li class=""><code>description</code> (<code>optional</code>): A short description of the strategy.</li>
<li class=""><code>documentationURL</code> (<code>optional</code>): A URL to the documentation for the strategy. This is not shown in the strategy UI yet but may in the future.</li>
</ul>
<p>Example:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token dom variable" style="color:rgb(191, 199, 213)">window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token property-access">customStrategies</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:rgb(191, 199, 213)">window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token property-access">customStrategies</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">||</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token dom variable" style="color:rgb(191, 199, 213)">window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token property-access">customStrategies</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token method function property-access" style="color:rgb(130, 170, 255)">push</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token literal-property property">type</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"my-demo"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token literal-property property">strategyType</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"dashboard"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token literal-property property">name</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"My demo dashboard"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token literal-property property">description</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"A starter dashboard generated from JavaScript."</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token literal-property property">documentationURL</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"https://example.com/my-demo-dashboard"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>This metadata is separate from the custom element itself. Your strategy still needs to be registered with a tag like <code>ll-strategy-dashboard-my-demo</code>, and users still need the resource loaded before Home Assistant can discover it. You can use HACS for this as other resources can be added, like custom cards.</p>
<p>Take a look at the updated <a class="" href="https://developers.home-assistant.io/docs/frontend/custom-ui/custom-strategy">custom strategies</a> documentation with example code and further details.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deprecation of legacy device tracker platform API]]></title>
            <link>https://developers.home-assistant.io/blog/2026/04/20/legacy-device-tracker-deprecation</link>
            <guid>https://developers.home-assistant.io/blog/2026/04/20/legacy-device-tracker-deprecation</guid>
            <pubDate>Mon, 20 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Summary]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="summary">Summary<a href="https://developers.home-assistant.io/blog/2026/04/20/legacy-device-tracker-deprecation#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>The legacy (non-config-entry) device tracker platform API is deprecated and will be removed in the Home Assistant 2027.5 release.
By the end of the 12-month deprecation period, all remaining legacy device tracker platforms will be removed from the core repository, and custom integrations implementing the legacy API will stop working.</p>
<p>Integrations authors need to update integrations to implement the <a href="https://developers.home-assistant.io/docs/core/entity/device-tracker" target="_blank" rel="noopener noreferrer" class="">modern device tracker platform API</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://developers.home-assistant.io/blog/2026/04/20/legacy-device-tracker-deprecation#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></h2>
<p>Config entry device trackers were introduced in May 2019, which means integration authors have had 8 years to migrate integrations when support is removed in May 2027.</p>
<p>As of today (April 2026) most widely used core device tracker integrations have already been migrated.</p>
<p>Note that the most popular integration that has not yet been migrated, xiaomi_miio, has a wide mix of functionality including other things than device tracker.</p>
<p>The proposal to deprecate the legacy device tracker API was approved in <a href="https://github.com/home-assistant/architecture/discussions/1375" target="_blank" rel="noopener noreferrer" class="">architecture proposal 1375</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="list-of-core-integrations-sorted-by-reported-use">List of core integrations, sorted by reported use<a href="https://developers.home-assistant.io/blog/2026/04/20/legacy-device-tracker-deprecation#list-of-core-integrations-sorted-by-reported-use" class="hash-link" aria-label="Direct link to List of core integrations, sorted by reported use" title="Direct link to List of core integrations, sorted by reported use" translate="no">​</a></h3>
<p>The list was generated from <a href="https://analytics.home-assistant.io/" target="_blank" rel="noopener noreferrer" class="">https://analytics.home-assistant.io/</a> in March 2026</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Integration                    Installations  API      Type               Details</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">----------------------------------------------------------------------------------------------------</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">mobile_app                           415,204  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">mqtt                                 233,161  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">zha                                  126,903  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">ibeacon                               89,099  modern   unknown            BaseTrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">fritz                                 42,934  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">ping                                  33,439  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">unifi                                 33,136  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">xiaomi_miio                           12,866  legacy   scanner            async_scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">nmap_tracker                           7,397  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">icloud                                 5,772  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">freebox                                5,312  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">asuswrt                                4,686  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">tile                                   4,212  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">renault                                3,646  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">private_ble_device                     3,231  modern   unknown            BaseTrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">keenetic_ndms2                         3,080  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">owntracks                              3,022  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">snmp                                   2,923  legacy   scanner            async_scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">devolo_home_network                    2,910  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">tesla_fleet                            2,798  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">netgear                                2,782  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">mikrotik                               2,761  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">tplink_omada                           2,708  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">starlink                               2,250  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">tractive                               2,144  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">volvo                                  2,077  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">husqvarna_automower                    1,924  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">tessie                                 1,562  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bluetooth_le_tracker                   1,011  legacy</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">traccar_server                           978  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">huawei_lte                               827  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">gpslogger                                813  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">teslemetry                               720  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">traccar                                  609  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">luci                                     590  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">subaru                                   502  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">mysensors                                474  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">starline                                 460  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">geofency                                 443  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">google_maps                              389  legacy</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">locative                                 378  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">opnsense                                 355  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">fing                                     266  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">ruckus_unleashed                         232  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">synology_srm                             193  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">unifi_direct                             190  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">mqtt_json                                182  legacy</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">vodafone_station                         166  modern   scanner            ScannerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">xiaomi                                   143  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">demo                                     141  legacy</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">ubus                                     111  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bt_smarthub                               95  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">aprs                                      93  legacy</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">nrgkick                                   81  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">ddwrt                                     79  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">fressnapf_tracker                         74  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">linksys_smart                             69  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">fortios                                   53  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">swisscom                                  51  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">tomato                                    45  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">quantum_gateway                           42  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">aruba                                     24  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">meraki                                    24  legacy</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">sky_hub                                   22  legacy   scanner            async_scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">ituran                                    19  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">cisco_ios                                 10  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">upc_connect                               10  legacy   scanner            async_scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">cisco_mobility_express                     6  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">arris_tg2492lg                             2  legacy   scanner            async_scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bbox                                       1  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">actiontec                                  0  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">autoskope                                  0  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bt_home_hub_5                              0  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">cppm_tracker                               0  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">fleetgo                                    0  legacy</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">hitron_coda                                0  legacy   scanner            scan_devices</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">lojack                                     0  modern   tracker            TrackerEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">thomson                                    0  legacy   scanner            scan_devices</span><br></div></code></pre></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Standard event type for doorbell event entities]]></title>
            <link>https://developers.home-assistant.io/blog/2026/04/15/doorbell-standard-event-type</link>
            <guid>https://developers.home-assistant.io/blog/2026/04/15/doorbell-standard-event-type</guid>
            <pubDate>Wed, 15 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Doorbell event entities now have a standard ring event type. Integrations that use EventDeviceClass.DOORBELL must include DoorbellEventType.RING in their event_types list.]]></description>
            <content:encoded><![CDATA[<p>Doorbell event entities now have a standard <code>ring</code> event type. Integrations that use <code>EventDeviceClass.DOORBELL</code> must include <code>DoorbellEventType.RING</code> in their <code>event_types</code> list.</p>
<p>See the <a href="https://github.com/home-assistant/architecture/discussions/1363" target="_blank" rel="noopener noreferrer" class="">architecture discussion</a> for the full background.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why">Why<a href="https://developers.home-assistant.io/blog/2026/04/15/doorbell-standard-event-type#why" class="hash-link" aria-label="Direct link to Why" title="Direct link to Why" translate="no">​</a></h2>
<p>Previously, each integration used its own string for the "doorbell was pressed" event — <code>ding</code>, <code>ring</code>, <code>doorbell_chime</code>, <code>single_press</code>, etc. This inconsistency made it impossible to build generic doorbell automations that work across all integrations.</p>
<p>The new <code>DoorbellEventType.RING</code> standard event type solves this by ensuring every doorbell integration fires a common <code>ring</code> event when the doorbell is pressed.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-to-do">What to do<a href="https://developers.home-assistant.io/blog/2026/04/15/doorbell-standard-event-type#what-to-do" class="hash-link" aria-label="Direct link to What to do" title="Direct link to What to do" translate="no">​</a></h2>
<p>Import <code>DoorbellEventType</code> from <code>homeassistant.components.event</code> and include <code>DoorbellEventType.RING</code> in your doorbell entity's <code>event_types</code>. Fire it whenever the doorbell is pressed:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">event </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> DoorbellEventType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> EventDeviceClass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> EventEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">MyDoorbellEvent</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">EventEntity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    _attr_device_class </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> EventDeviceClass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">DOORBELL</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    _attr_event_types </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">DoorbellEventType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">RING</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token decorator annotation punctuation" style="color:rgb(199, 146, 234)">@callback</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">_async_handle_event</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Handle the doorbell press event."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_trigger_event</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DoorbellEventType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">RING</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_write_ha_state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Additional custom event types (e.g., <code>double_press</code>, <code>long_press</code>) are still allowed alongside the standard <code>ring</code> type.</p>
<p>Doorbell entities that do not include <code>DoorbellEventType.RING</code> will log a deprecation warning and will <strong>stop working in Home Assistant 2027.4</strong>.</p>
<p>For full details, see the <a class="" href="https://developers.home-assistant.io/docs/core/entity/event">event entity documentation</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Entity IDs with mismatched domains are deprecated]]></title>
            <link>https://developers.home-assistant.io/blog/2026/04/07/entity-id-mismatched-domain-deprecated</link>
            <guid>https://developers.home-assistant.io/blog/2026/04/07/entity-id-mismatched-domain-deprecated</guid>
            <pubDate>Tue, 07 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Integrations that set entity_id directly on an entity will now be validated]]></description>
            <content:encoded><![CDATA[<p>Integrations that set <code>entity_id</code> directly on an entity will now be validated
to ensure the domain portion matches the platform's domain. For example,
a <code>light</code> entity must use <code>light.my_light</code>, not <code>cover.my_light</code>.</p>
<p>Setting an entity ID with the wrong domain will log a deprecation warning
and will <strong>stop working in Home Assistant 2027.5</strong>.</p>
<p>In most cases, integrations should not set <code>entity_id</code> at all — Home Assistant
will generate it automatically.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Migrating app builds to Docker BuildKit]]></title>
            <link>https://developers.home-assistant.io/blog/2026/04/02/builder-migration</link>
            <guid>https://developers.home-assistant.io/blog/2026/04/02/builder-migration</guid>
            <pubDate>Thu, 02 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The legacy home-assistant/builder container and the old home-assistant/builder GitHub Action have been retired. We recommend migrating all GitHub workflows and Dockerfiles for apps (formerly add-ons) as described in this post.]]></description>
            <content:encoded><![CDATA[<p>The legacy <code>home-assistant/builder</code> container and the old <code>home-assistant/builder</code> GitHub Action have been retired. We recommend migrating all GitHub workflows and Dockerfiles for apps (formerly add-ons) as described in this post.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-changed-and-why">What changed and why<a href="https://developers.home-assistant.io/blog/2026/04/02/builder-migration#what-changed-and-why" class="hash-link" aria-label="Direct link to What changed and why" title="Direct link to What changed and why" translate="no">​</a></h2>
<p>The old builder ran every architecture build inside a single privileged Docker-in-Docker container using QEMU emulation. This was slow, required elevated privileges, and those who were already familiar with Docker needed to learn how to use the custom Home Assistant's builder container. The old builder also had unnecessary maintenance overhead. Today, what the builder does can be fully replaced with Docker BuildKit, which is natively supported on GitHub Actions runners and has built-in multi-arch support with QEMU emulation if needed.</p>
<p>For your CI, the replacement is a set of focused <a href="https://github.com/home-assistant/builder" target="_blank" rel="noopener noreferrer" class="">composite GitHub Actions</a> that delegate building to the runner's native Docker with Docker BuildKit. Outside the CI, the migration means that your <code>Dockerfile</code> is now the single source of truth for building your app image, and you can use <code>docker build</code> directly to build and test your app locally without needing to use the builder container.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="migration-process">Migration process<a href="https://developers.home-assistant.io/blog/2026/04/02/builder-migration#migration-process" class="hash-link" aria-label="Direct link to Migration process" title="Direct link to Migration process" translate="no">​</a></h2>
<p>The migration has two parts: updating your Dockerfiles and updating your GitHub Actions workflows.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="update-dockerfiles">Update Dockerfiles<a href="https://developers.home-assistant.io/blog/2026/04/02/builder-migration#update-dockerfiles" class="hash-link" aria-label="Direct link to Update Dockerfiles" title="Direct link to Update Dockerfiles" translate="no">​</a></h3>
<p>The new build workflow doesn't use <code>build.yaml</code> anymore. Move the content into your <code>Dockerfile</code> as follows:</p>
<ul>
<li class="">
<p><strong><code>build_from</code></strong> - replace the <code>build_from</code> key in <code>build.yaml</code> with a <code>FROM</code> statement in your <code>Dockerfile</code>:</p>
<div class="language-dockerfile codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">FROM ghcr.io/home-assistant/base:latest</span><br></div></code></pre></div></div>
<p>As the base images are now published as multi-platform manifests, there is usually no need to define per-arch base images anymore. The <code>build-image</code> action still supplies <code>BUILD_ARCH</code> as a build argument though, so you can use that in your <code>Dockerfile</code> if you need to use it in the template for the base image name.</p>
</li>
<li class="">
<p><strong><code>labels</code></strong> - move any custom Docker labels directly into your <code>Dockerfile</code> with a <code>LABEL</code> statement:</p>
<div class="language-dockerfile codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">LABEL \</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    org.opencontainers.image.title="Your awesome app" \</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    org.opencontainers.image.description="Description of your app." \</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    org.opencontainers.image.source="https://github.com/your/repo" \</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    org.opencontainers.image.licenses="Apache License 2.0"</span><br></div></code></pre></div></div>
<p>If you are creating a custom workflow, note that the legacy builder used to add the <code>io.hass.type</code>, <code>io.hass.name</code>, <code>io.hass.description</code>, and <code>io.hass.url</code> labels automatically. The new actions do not infer these values, so add them explicitly via the <code>labels</code> input of the <code>build-image</code> (or similar) action.</p>
</li>
<li class="">
<p><strong><code>args</code></strong> - move custom build arguments into your <code>Dockerfile</code> as <code>ARG</code> definitions with default values:</p>
<div class="language-dockerfile codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">ARG MY_BUILD_ARG="default-value"</span><br></div></code></pre></div></div>
<p>Default values in <code>ARG</code> replace what was previously supplied via <code>build.yaml</code>'s <code>args</code> dictionary. They can still be overridden at build time with <code>--build-arg</code> if needed.</p>
</li>
</ul>
<p>With the content of <code>build.yaml</code> migrated, you can delete the file from your repository.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="update-github-actions-workflows">Update GitHub Actions workflows<a href="https://developers.home-assistant.io/blog/2026/04/02/builder-migration#update-github-actions-workflows" class="hash-link" aria-label="Direct link to Update GitHub Actions workflows" title="Direct link to Update GitHub Actions workflows" translate="no">​</a></h3>
<p>Remove any workflow steps using <code>home-assistant/builder@master</code> and replace them with the new composite actions. See the <a href="https://github.com/home-assistant/apps-example/blob/main/.github/workflows/builder.yaml" target="_blank" rel="noopener noreferrer" class="">example workflow</a> in our example app repository for a complete working example. Alternatively, use the <a href="https://github.com/home-assistant/builder?tab=readme-ov-file#example-workflow" target="_blank" rel="noopener noreferrer" class="">individual actions</a> in a more custom workflow as needed.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="image-naming">Image naming<a href="https://developers.home-assistant.io/blog/2026/04/02/builder-migration#image-naming" class="hash-link" aria-label="Direct link to Image naming" title="Direct link to Image naming" translate="no">​</a></h3>
<p>The preferred way to reference a published app image is now the <strong>generic (multi-arch) name</strong> without an architecture prefix:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># config.yaml</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"ghcr.io/my-org/my-app"</span><br></div></code></pre></div></div>
<p>The <code>{arch}</code> placeholder (e.g. <code>ghcr.io/my-org/{arch}-my-app</code>) is still supported as a compatibility fallback, but it's encouraged to use the generic name and let the manifest handle the platform resolution.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="local-builds">Local builds<a href="https://developers.home-assistant.io/blog/2026/04/02/builder-migration#local-builds" class="hash-link" aria-label="Direct link to Local builds" title="Direct link to Local builds" translate="no">​</a></h3>
<p>After updating your <code>Dockerfile</code>, you can use <code>docker build</code> to build the app image directly - you can refer to <a class="" href="https://developers.home-assistant.io/docs/apps/testing">Local app testing</a> for more details.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="apps-built-locally-by-supervisor">Apps built locally by Supervisor<a href="https://developers.home-assistant.io/blog/2026/04/02/builder-migration#apps-built-locally-by-supervisor" class="hash-link" aria-label="Direct link to Apps built locally by Supervisor" title="Direct link to Apps built locally by Supervisor" translate="no">​</a></h2>
<p>For backward compatibility, Supervisor still reads <code>build.yaml</code> file if it's present and populates the image build arguments with values read from this file. This will produce warnings and eventually be removed in the future, so it's recommended to migrate to the new Dockerfile-based approach as described above.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[New infrared entity platform for IR device integrations]]></title>
            <link>https://developers.home-assistant.io/blog/2026/03/30/infrared-entity-platform</link>
            <guid>https://developers.home-assistant.io/blog/2026/03/30/infrared-entity-platform</guid>
            <pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Home Assistant now has an infrared entity platform that decouples IR emitter hardware from the devices they control. Instead of each device integration talking directly to specific IR hardware, emitter integrations (like esphome) expose InfraredEntity instances, and device integrations (like lg_infrared) send commands through them via helper functions.]]></description>
            <content:encoded><![CDATA[<p>Home Assistant now has an <code>infrared</code> entity platform that decouples IR emitter hardware from the devices they control. Instead of each device integration talking directly to specific IR hardware, emitter integrations (like <code>esphome</code>) expose <code>InfraredEntity</code> instances, and device integrations (like <code>lg_infrared</code>) send commands through them via helper functions.</p>
<p>See the <a href="https://github.com/home-assistant/architecture/discussions/1316" target="_blank" rel="noopener noreferrer" class="">architecture discussion</a> for the full background.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="architecture">Architecture<a href="https://developers.home-assistant.io/blog/2026/03/30/infrared-entity-platform#architecture" class="hash-link" aria-label="Direct link to Architecture" title="Direct link to Architecture" translate="no">​</a></h2>
<p>The infrared domain sits between two types of integrations:</p>
<ul>
<li class=""><strong>Emitter integrations</strong> (ESPHome, Broadlink, …) implement the <code>InfraredEntity</code> base class to provide hardware-specific IR transmission.</li>
<li class=""><strong>Consumer integrations</strong> (LG, Samsung, Daikin, …) use helper functions to send device-specific IR commands through available emitters.</li>
</ul>
<p>Users select which emitter to use during the consumer integration's config flow.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="implementing-an-emitter-integration">Implementing an emitter integration<a href="https://developers.home-assistant.io/blog/2026/03/30/infrared-entity-platform#implementing-an-emitter-integration" class="hash-link" aria-label="Direct link to Implementing an emitter integration" title="Direct link to Implementing an emitter integration" translate="no">​</a></h2>
<p>Emitter integrations provide the <code>infrared</code> platform by subclassing <code>InfraredEntity</code> and implementing <code>async_send_command</code>. The command's <code>get_raw_timings()</code> method returns protocol-agnostic timing data that the hardware can transmit:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">infrared </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> InfraredCommand</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> InfraredEntity</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">MyInfraredEntity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">InfraredEntity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""My IR transmitter."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">async_send_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> InfraredCommand</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Send an IR command."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        timings </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            interval</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> timing </span><span class="token keyword" style="font-style:italic">in</span><span class="token plain"> command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">get_raw_timings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> interval </span><span class="token keyword" style="font-style:italic">in</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">timing</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">high_us</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain">timing</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">low_us</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_device</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">transmit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            carrier_frequency</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">modulation</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            timings</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">timings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>The raw protocol-agnostic timings should be converted to the specific format required by the hardware.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="building-a-consumer-integration">Building a consumer integration<a href="https://developers.home-assistant.io/blog/2026/03/30/infrared-entity-platform#building-a-consumer-integration" class="hash-link" aria-label="Direct link to Building a consumer integration" title="Direct link to Building a consumer integration" translate="no">​</a></h2>
<p>Consumer integrations control IR devices by sending commands through an emitter entity. They don't interact with IR hardware directly.</p>
<p><strong>1. Declare the dependency</strong> in <code>manifest.json</code>:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "dependencies": ["infrared"]</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p><strong>2. Let the user pick an emitter</strong> in the config flow:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">components </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> infrared</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">emitters </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> infrared</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_get_emitters</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">not</span><span class="token plain"> emitters</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_abort</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">reason</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"no_emitters"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p><strong>3. Send IR commands</strong> using the helper function and the <a href="https://github.com/home-assistant-libs/infrared-protocols" target="_blank" rel="noopener noreferrer" class=""><code>infrared-protocols</code></a> library:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> infrared_protocols</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">codes</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">lg</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">tv </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> LGTVCode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> make_lg_tv_command</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> homeassistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">components </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> infrared</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> infrared</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_send_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    hass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_infrared_entity_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    make_lg_tv_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">LGTVCode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">VOLUME_UP</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    context</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ir-protocols-and-codes">IR protocols and codes<a href="https://developers.home-assistant.io/blog/2026/03/30/infrared-entity-platform#ir-protocols-and-codes" class="hash-link" aria-label="Direct link to IR protocols and codes" title="Direct link to IR protocols and codes" translate="no">​</a></h2>
<p>IR protocol encoders and device code sets live outside Home Assistant in the <a href="https://github.com/home-assistant-libs/infrared-protocols" target="_blank" rel="noopener noreferrer" class=""><code>infrared-protocols</code></a> library. Common protocols (NEC, Samsung, etc.) and well-known device codes should be contributed there. For niche or proprietary protocols, a separate third-party library can also be used.</p>
<p>For full details, see the <a class="" href="https://developers.home-assistant.io/docs/core/entity/infrared">infrared entity documentation</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Frontend component updates 2026.4]]></title>
            <link>https://developers.home-assistant.io/blog/2026/03/25/frontend-component-updates-2026.4</link>
            <guid>https://developers.home-assistant.io/blog/2026/03/25/frontend-component-updates-2026.4</guid>
            <pubDate>Wed, 25 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[We do not officially support or encourage custom card developers to use our built in components. This component APIs can always change and you should build your card as independent component.]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p>We do not officially support or encourage custom card developers to use our built in components. This component APIs can always change and you should build your card as independent component.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ha-input">ha-input<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-component-updates-2026.4#ha-input" class="hash-link" aria-label="Direct link to ha-input" title="Direct link to ha-input" translate="no">​</a></h2>
<p>We keep migrating our Material Design based components to Web Awesome based. This time we migrated the input components, which leads to an API change but the look and feel stays the same for now.</p>
<ul>
<li class=""><code>ha-input</code> is the successor of <code>ha-textfield</code>
<ul>
<li class=""><code>ha-textfield</code> API stays but the component is migrated to use <code>ha-input</code> internally and will be removed in 2026.5</li>
<li class="">Also replaces <code>ha-outlined-text-field</code></li>
</ul>
</li>
<li class=""><code>ha-input-search</code> replaces <code>search-input</code> and <code>search-input-outlined</code></li>
<li class=""><code>ha-input-multi</code> replaces <code>ha-multi-textfield</code></li>
<li class=""><code>ha-input-copy</code> replaces <code>copy-textfield</code></li>
</ul>
<p>This component also introduces new semantic theme variables for form backgrounds:</p>
<div class="language-css codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-css codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-form-background</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">var</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-neutral-95</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-form-background-hover</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">var</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-neutral-90</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-form-background-disabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">var</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">--ha-color-neutral-80</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="date-picker">Date picker<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-component-updates-2026.4#date-picker" class="hash-link" aria-label="Direct link to Date picker" title="Direct link to Date picker" translate="no">​</a></h2>
<p>We finally removed the Vue 2 dependency by replacing the date and date range picker with <a href="https://wicky.nillia.ms/cally/" target="_blank" rel="noopener noreferrer" class="">Cally</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Frontend new way of dialogs]]></title>
            <link>https://developers.home-assistant.io/blog/2026/03/25/frontend-dialogs</link>
            <guid>https://developers.home-assistant.io/blog/2026/03/25/frontend-dialogs</guid>
            <pubDate>Wed, 25 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The Problem]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-problem">The Problem<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-dialogs#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Each dialog managed by the dialog manager was only opened once and stayed in the DOM for the lifetime of the application. This causes:</p>
<ul>
<li class=""><strong>More memory usage</strong>: Dialogs accumulate in the DOM even when not visible</li>
<li class=""><strong>More bugs because of missing state reset</strong>: Dialog state persists between opens, leading to stale data or unexpected behavior</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-solution-dialogmixin">The Solution: DialogMixin<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-dialogs#the-solution-dialogmixin" class="hash-link" aria-label="Direct link to The Solution: DialogMixin" title="Direct link to The Solution: DialogMixin" translate="no">​</a></h2>
<p>We implemented a new way of handling dialogs using <code>DialogMixin</code>. With this approach:</p>
<ul>
<li class=""><strong>Dialogs are created when opened and destroyed when closed</strong>: No need to manually reset the state of the dialog when it is closed</li>
<li class=""><strong>Closed events are automatically handled</strong>: The dialog mixin takes care of cleanup</li>
<li class=""><strong>Subscribe mixin can now be used in dialogs</strong>: Since dialogs are properly destroyed, subscriptions are cleaned up automatically</li>
<li class=""><strong>Use normal Lit lifecycle methods</strong>: Use <code>connectedCallback</code> to initialize when the dialog is opened instead of relying on the <code>showDialog</code> method</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="example">Example<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-dialogs#example" class="hash-link" aria-label="Direct link to Example" title="Direct link to Example" translate="no">​</a></h2>
<p>Check out <code>ha-dialog-date-picker</code> for a reference implementation. <code>DialogMixin</code> adds dialog params to <code>this.params</code> if available.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Frontend lazy context]]></title>
            <link>https://developers.home-assistant.io/blog/2026/03/25/frontend-lazy-context</link>
            <guid>https://developers.home-assistant.io/blog/2026/03/25/frontend-lazy-context</guid>
            <pubDate>Wed, 25 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[What is a context?]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-a-context">What is a context?<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-lazy-context#what-is-a-context" class="hash-link" aria-label="Direct link to What is a context?" title="Direct link to What is a context?" translate="no">​</a></h2>
<p>In the Home Assistant frontend, a <a href="https://lit.dev/docs/data/context/" target="_blank" rel="noopener noreferrer" class="">Context</a> is a way to share data across the component tree without explicitly passing it through every level as a property. Instead of threading the <code>hass</code> object down through multiple layers of components, you can provide specific pieces of data via context and consume them only where needed.</p>
<p>The key benefits of using context over passing the entire <code>hass</code> object are:</p>
<ul>
<li class=""><strong>Easier usage</strong>: Components can directly consume the data they need without requiring parent components to pass it down. This reduces prop drilling and makes components more self-contained and reusable.</li>
<li class=""><strong>Reducing unnecessary component re-renders</strong>: When a component receives <code>hass</code> as a property, any change to <code>hass</code> triggers a re-render of that component and all its children—even if the component only cares about a small subset of the data. By using context to provide only the specific data a component needs, you ensure that components only re-render when their actual dependencies change, leading to better performance and a more responsive UI.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introducing-lazycontext">Introducing LazyContext<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-lazy-context#introducing-lazycontext" class="hash-link" aria-label="Direct link to Introducing LazyContext" title="Direct link to Introducing LazyContext" translate="no">​</a></h2>
<p>We've introduced a new <code>LazyContext</code> pattern that should replace the traditional subscription-based approach and the usage of the <code>SubscribeMixin</code>. Previously, components would subscribe to data sources and manage subscription lifecycles manually, often leading to boilerplate code and potential memory leaks if subscriptions weren't properly cleaned up.</p>
<p><code>LazyContext</code> simplifies this by:</p>
<ul>
<li class=""><strong>Lazy loading</strong>: Data is only fetched when a component actually consumes the context</li>
<li class=""><strong>Automatic cleanup</strong>: Subscriptions are managed automatically</li>
<li class=""><strong>Shared state</strong>: Multiple components consuming the same context share a single subscription</li>
<li class=""><strong>Optimized re-renders</strong>: Only components that consume the context re-render when data changes</li>
</ul>
<p>This approach centralizes data-fetching logic and makes it easier to reason about when and how data flows through your application.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="examples">Examples<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-lazy-context#examples" class="hash-link" aria-label="Direct link to Examples" title="Direct link to Examples" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="defining-a-lazycontext">Defining a LazyContext<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-lazy-context#defining-a-lazycontext" class="hash-link" aria-label="Direct link to Defining a LazyContext" title="Direct link to Defining a LazyContext" translate="no">​</a></h3>
<p>To define a lazy context, use <code>LazyContextProvider</code> and provide a fetch function:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">new</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">LazyContextProvider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">this</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  context</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> labelsContext</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token function-variable function" style="color:rgb(130, 170, 255)">subscribeFn</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">connection</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> setValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">subscribeLabelRegistry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">connection</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> setValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="consuming-a-context-with-lit">Consuming a context with lit<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-lazy-context#consuming-a-context-with-lit" class="hash-link" aria-label="Direct link to Consuming a context with lit" title="Direct link to Consuming a context with lit" translate="no">​</a></h3>
<p>To consume a context in a component, use the <code>@consume</code> decorator:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token decorator at operator" style="color:rgb(137, 221, 255)">@</span><span class="token decorator function" style="color:rgb(130, 170, 255)">state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token decorator at operator" style="color:rgb(137, 221, 255)">@</span><span class="token decorator function" style="color:rgb(130, 170, 255)">consume</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> context</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> labelsContext</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> subscribe</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token plain"> _labels</span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> LabelRegistryEntry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Check out the updated custom card example to use it in vanilla JS: <a class="" href="https://developers.home-assistant.io/docs/frontend/custom-ui/custom-card#defining-your-card">Custom card example</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-transform-for-derived-data">Using @transform for derived Data<a href="https://developers.home-assistant.io/blog/2026/03/25/frontend-lazy-context#using-transform-for-derived-data" class="hash-link" aria-label="Direct link to Using @transform for derived Data" title="Direct link to Using @transform for derived Data" translate="no">​</a></h3>
<p><em>Only available within the home-assistant frontend codebase</em></p>
<p>The <code>@transform</code> decorator allows you to derive data from a context value, ensuring your component only re-renders when the transformed value actually changes.</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token decorator at operator" style="color:rgb(137, 221, 255)">@</span><span class="token decorator function" style="color:rgb(130, 170, 255)">state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token decorator at operator" style="color:rgb(137, 221, 255)">@</span><span class="token decorator function" style="color:rgb(130, 170, 255)">consume</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> context</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> statesContext</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> subscribe</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token decorator at operator" style="color:rgb(137, 221, 255)">@</span><span class="token decorator function" style="color:rgb(130, 170, 255)">transform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token function-variable function" style="color:rgb(130, 170, 255)">transformer</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">function</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">this</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> HuiButtonCard</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> entityStates</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> HassEntities</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">this</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_config</span><span class="token operator" style="color:rgb(137, 221, 255)">?.</span><span class="token plain">entity </span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token plain"> entityStates</span><span class="token operator" style="color:rgb(137, 221, 255)">?.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token keyword" style="font-style:italic">this</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_config</span><span class="token operator" style="color:rgb(137, 221, 255)">?.</span><span class="token plain">entity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">undefined</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  watch</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(195, 232, 141)">"_config"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token plain"> _stateObj</span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> HassEntity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>With <code>@transform</code>, even if the full states object updates, your component will only re-render if the transformed result (<code>_stateObj</code>) actually changes. The <code>watch</code> option allows you to specify additional properties that should trigger re-evaluation of the transformer function—in this case, when <code>_config</code> changes, the transformer runs again to extract the correct entity state.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Backup agents can now report upload progress]]></title>
            <link>https://developers.home-assistant.io/blog/2026/03/11/backup-upload-progress</link>
            <guid>https://developers.home-assistant.io/blog/2026/03/11/backup-upload-progress</guid>
            <pubDate>Wed, 11 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The BackupAgent.asyncuploadbackup method now receives a new on_progress callback parameter. Backup agents can call this callback periodically during upload to report the number of bytes uploaded so far:]]></description>
            <content:encoded><![CDATA[<p>The <code>BackupAgent.async_upload_backup</code> method now receives a new <code>on_progress</code> callback parameter. Backup agents can call this callback periodically during upload to report the number of bytes uploaded so far:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">ExampleBackupAgent</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">BackupAgent</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">async_upload_backup</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        open_stream</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Callable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Coroutine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">Any</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Any</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> AsyncIterator</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token builtin" style="color:rgb(130, 170, 255)">bytes</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        backup</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> AgentBackup</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        on_progress</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> OnProgressCallback</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">**</span><span class="token plain">kwargs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Any</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(195, 232, 141)">"""Upload a backup."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        bytes_uploaded </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> chunk </span><span class="token keyword" style="font-style:italic">in</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> open_stream</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">await</span><span class="token plain"> do_upload</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">chunk</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            bytes_uploaded </span><span class="token operator" style="color:rgb(137, 221, 255)">+=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">len</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">chunk</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            on_progress</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bytes_uploaded</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">bytes_uploaded</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><br></div></code></pre></div></div>
<p>The backup manager uses these progress reports to fire <code>UploadBackupEvent</code> events, enabling the frontend to display real-time upload progress to the user.</p>
<p>Check the <a class="" href="https://developers.home-assistant.io/docs/core/platform/backup#backup-agents">backup agent documentation</a> for more details.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Custom integrations can now ship their own brand images]]></title>
            <link>https://developers.home-assistant.io/blog/2026/02/24/brands-proxy-api</link>
            <guid>https://developers.home-assistant.io/blog/2026/02/24/brands-proxy-api</guid>
            <pubDate>Tue, 24 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Starting with Home Assistant 2026.3, custom integrations can include their own brand images (icons and logos) directly in the integration directory. No more submitting to a separate repository — just drop your images in a brand/ folder and they show up in the UI.]]></description>
            <content:encoded><![CDATA[<p>Starting with Home Assistant 2026.3, custom integrations can include their own brand images (icons and logos) directly in the integration directory. No more submitting to a separate repository — just drop your images in a <code>brand/</code> folder and they show up in the UI.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="local-brand-images-for-custom-integrations">Local brand images for custom integrations<a href="https://developers.home-assistant.io/blog/2026/02/24/brands-proxy-api#local-brand-images-for-custom-integrations" class="hash-link" aria-label="Direct link to Local brand images for custom integrations" title="Direct link to Local brand images for custom integrations" translate="no">​</a></h2>
<p>Add a <code>brand/</code> directory to your custom integration with your icon and logo files:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">custom_components/my_integration/</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── __init__.py</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── manifest.json</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">└── brand/</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    ├── icon.png</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    └── logo.png</span><br></div></code></pre></div></div>
<p>The following image filenames are supported:</p>
<ul>
<li class=""><code>icon.png</code> / <code>dark_icon.png</code></li>
<li class=""><code>logo.png</code> / <code>dark_logo.png</code></li>
<li class=""><code>icon@2x.png</code> / <code>dark_icon@2x.png</code></li>
<li class=""><code>logo@2x.png</code> / <code>dark_logo@2x.png</code></li>
</ul>
<p>Local brand images automatically take priority over images from the brands CDN. That's it — no extra configuration needed.</p>
<p>For more details, see the <a class="" href="https://developers.home-assistant.io/docs/creating_integration_file_structure#local-brand-images-for-custom-integrations">integration file structure documentation</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="brand-images-now-served-through-a-local-api">Brand images now served through a local API<a href="https://developers.home-assistant.io/blog/2026/02/24/brands-proxy-api#brand-images-now-served-through-a-local-api" class="hash-link" aria-label="Direct link to Brand images now served through a local API" title="Direct link to Brand images now served through a local API" translate="no">​</a></h2>
<p>To make local brand images possible, all brand images are now served through the Home Assistant local API instead of being fetched directly from the CDN by the browser.</p>
<p>A new <code>brands</code> system integration proxies brand images through two endpoints:</p>
<ul>
<li class=""><code>/api/brands/integration/{domain}/{image}</code> — Integration icons and logos</li>
<li class=""><code>/api/brands/hardware/{category}/{image}</code> — Hardware images</li>
</ul>
<p>Images are cached locally on disk and served with a stale-while-revalidate strategy, so they remain available during internet outages.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="impact-on-the-frontend">Impact on the frontend<a href="https://developers.home-assistant.io/blog/2026/02/24/brands-proxy-api#impact-on-the-frontend" class="hash-link" aria-label="Direct link to Impact on the frontend" title="Direct link to Impact on the frontend" translate="no">​</a></h3>
<p>The <code>brandsUrl()</code> and <code>hardwareBrandsUrl()</code> helpers in <code>src/util/brands-url.ts</code> now return local API paths instead of CDN URLs. If your custom card or panel uses these helpers, no changes are needed.</p>
<p>If you are constructing brand image URLs manually, update them:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// Old</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> url </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(195, 232, 141)">`</span><span class="token template-string string" style="color:rgb(195, 232, 141)">https://brands.home-assistant.io/_/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token template-string interpolation">domain</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token template-string string" style="color:rgb(195, 232, 141)">/icon.png</span><span class="token template-string template-punctuation string" style="color:rgb(195, 232, 141)">`</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// New</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> brandsUrl </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"../util/brands-url"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> url </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">brandsUrl</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> domain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> type</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"icon"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>These endpoints require authentication. The <code>brandsUrl()</code> helper handles this automatically by appending an access token. If you construct URLs manually, obtain a token via the <code>brands/access_token</code> WebSocket command and append it as a <code>token</code> query parameter.</p>]]></content:encoded>
        </item>
    </channel>
</rss>