<?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>Fri, 31 Jul 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[Frontend component updates in 2026.8]]></title>
            <link>https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8</link>
            <guid>https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8</guid>
            <pubDate>Fri, 31 Jul 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/07/31/frontend-component-updates-2026.8#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-split-panel">ha-split-panel<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#ha-split-panel" class="hash-link" aria-label="Direct link to ha-split-panel" title="Direct link to ha-split-panel" translate="no">​</a></h3>
<p>We added <code>ha-split-panel</code>, a Home Assistant wrapper around the Web Awesome split panel component.</p>
<p>Use it when a Home Assistant page, dialog, or tool needs a resizable two-pane layout. Custom card authors can use Home Assistant frontend components, but internal Home Assistant UI APIs may change.</p>
<div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag" style="color:rgb(255, 85, 114)">ha-split-panel</span><span class="token tag" style="color:rgb(255, 85, 114)"> </span><span class="token tag attr-name" style="color:rgb(255, 203, 107)">position</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(199, 146, 234)">=</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag attr-value" style="color:rgb(255, 85, 114)">40</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag" style="color:rgb(255, 85, 114)"> </span><span class="token tag attr-name" style="color:rgb(255, 203, 107)">snap</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(199, 146, 234)">=</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag attr-value" style="color:rgb(255, 85, 114)">50%</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag" style="color:rgb(255, 85, 114)">div</span><span class="token tag" style="color:rgb(255, 85, 114)"> </span><span class="token tag attr-name" style="color:rgb(255, 203, 107)">slot</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(199, 146, 234)">=</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag attr-value" style="color:rgb(255, 85, 114)">start</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain">Editor</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;/</span><span class="token tag" style="color:rgb(255, 85, 114)">div</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag" style="color:rgb(255, 85, 114)">div</span><span class="token tag" style="color:rgb(255, 85, 114)"> </span><span class="token tag attr-name" style="color:rgb(255, 203, 107)">slot</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(199, 146, 234)">=</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag attr-value" style="color:rgb(255, 85, 114)">end</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain">Preview</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;/</span><span class="token tag" style="color:rgb(255, 85, 114)">div</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;/</span><span class="token tag" style="color:rgb(255, 85, 114)">ha-split-panel</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</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-split-panel-divider-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-split-panel-divider-hit-area</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-split-panel-min</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-split-panel-max</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-split-panel-grip-display</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ha-tile-info-updates">ha-tile-info updates<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#ha-tile-info-updates" class="hash-link" aria-label="Direct link to ha-tile-info updates" title="Direct link to ha-tile-info updates" translate="no">​</a></h3>
<p><code>ha-tile-info</code> gained more layout controls for custom cards and tile-like surfaces.</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-tile-info-gap</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-tile-info-min-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-tile-info-primary-min-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-tile-info-primary-line-clamp</span><br></div></code></pre></div></div>
<p>Use <code>--ha-tile-info-primary-line-clamp</code> when the primary text should wrap to more than one line, and use the min-height tokens to keep rows aligned when some tiles have secondary text and others do not.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="form-and-selector-updates">Form and selector updates<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#form-and-selector-updates" class="hash-link" aria-label="Direct link to Form and selector updates" title="Direct link to Form and selector updates" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="conditional-ha-form-fields">Conditional ha-form fields<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#conditional-ha-form-fields" class="hash-link" aria-label="Direct link to Conditional ha-form fields" title="Direct link to Conditional ha-form fields" translate="no">​</a></h3>
<p><code>ha-form</code> schemas now support conditional field visibility with <code>visible</code>.</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 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">    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)">"advanced"</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">    selector</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><span class="token builtin" style="color:rgb(130, 170, 255)">boolean</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 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 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><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    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)">"advanced_name"</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">    visible</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"> field</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)">"advanced"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> value</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">    selector</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"> text</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 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 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>Supported operators are:</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 string" style="color:rgb(195, 232, 141)">"eq"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token string" style="color:rgb(195, 232, 141)">"not_eq"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token string" style="color:rgb(195, 232, 141)">"in"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token string" style="color:rgb(195, 232, 141)">"not_in"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token string" style="color:rgb(195, 232, 141)">"exists"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token string" style="color:rgb(195, 232, 141)">"not_exists"</span><br></div></code></pre></div></div>
<p>You can also combine conditions with <code>and</code>, <code>or</code>, and <code>not</code>.</p>
<p>Hidden fields are not rendered and are skipped during validation, so use <code>visible</code> instead of custom frontend-only hiding logic when a form field depends on another value.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="selector-additions">Selector additions<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#selector-additions" class="hash-link" aria-label="Direct link to Selector additions" title="Direct link to Selector additions" translate="no">​</a></h3>
<p>The text selector now supports HTML pattern validation:</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 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">  text</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">    pattern</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-z0-9_]+"</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">    validation_message</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)">"Use lowercase letters, numbers, and underscores"</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 punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>This works for both single-value and multiple-value text selectors.</p>
<p>Entity selectors can now filter by properties of the entity's device:</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 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 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">    filter</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">      domain</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)">"sensor"</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">      device</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">        manufacturer</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)">"Home Assistant"</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">        model</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)">"Connect ZBT-1"</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 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 punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>A new <code>ui_clock_date_format</code> selector was also added for the clock card date format editor.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="lovelace-updates">Lovelace updates<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#lovelace-updates" class="hash-link" aria-label="Direct link to Lovelace updates" title="Direct link to Lovelace updates" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="state_color-is-moving-to-color">state_color is moving to color<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#state_color-is-moving-to-color" class="hash-link" aria-label="Direct link to state_color is moving to color" title="Direct link to state_color is moving to color" translate="no">​</a></h3>
<p>The <code>entities</code> and <code>glance</code> cards now support <code>color</code> as the replacement for <code>state_color</code>.</p>
<p>Before:</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 key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> entities</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token key atrule">state_color</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" 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"></span><span class="token key atrule">entities</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"> light.kitchen</span><br></div></code></pre></div></div>
<p>After:</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 key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> entities</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token key atrule">color</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> state</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token key atrule">entities</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"> light.kitchen</span><br></div></code></pre></div></div>
<p>Use <code>color: state</code> for the old <code>state_color: true</code> behavior, and <code>color: none</code> for <code>state_color: false</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="custom-panels-and-apps">Custom panels and apps<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#custom-panels-and-apps" class="hash-link" aria-label="Direct link to Custom panels and apps" title="Direct link to Custom panels and apps" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="safe-area-handling">Safe-area handling<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#safe-area-handling" class="hash-link" aria-label="Direct link to Safe-area handling" title="Direct link to Safe-area handling" translate="no">​</a></h3>
<p>Custom panels and add-on app iframes now get safe-area padding by default, so content stays clear of notches, status bars, and home indicators.</p>
<p>Custom panels that already handle safe areas themselves can opt out:</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 key atrule">panel_custom</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 key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">panel</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token key atrule">module_url</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> /local/my</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">panel.js</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token key atrule">handle_safe_area</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><br></div></code></pre></div></div>
<p>For iframe-based custom panels, Home Assistant forwards the resolved safe-area values into the iframe document as CSS variables:</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)">--safe-area-inset-top</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)">--safe-area-inset-right</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)">--safe-area-inset-bottom</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)">--safe-area-inset-left</span><br></div></code></pre></div></div>
<p>Add-on app iframes can also opt into managing the safe area themselves when subscribing to Home Assistant properties:</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">parent</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)">postMessage</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 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)">"home-assistant/subscribe-properties"</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">handleSafeArea</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 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 string" style="color:rgb(195, 232, 141)">"*"</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>
<p>The properties message then includes <code>safeAreaInsets</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="context-and-editor-infrastructure">Context and editor infrastructure<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#context-and-editor-infrastructure" class="hash-link" aria-label="Direct link to Context and editor infrastructure" title="Direct link to Context and editor infrastructure" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="global-dirty-state">Global dirty state<a href="https://developers.home-assistant.io/blog/2026/07/31/frontend-component-updates-2026.8#global-dirty-state" class="hash-link" aria-label="Direct link to Global dirty state" title="Direct link to Global dirty state" translate="no">​</a></h3>
<p><code>DirtyStateProviderMixin</code> now also publishes a global dirty state.</p>
<p>When any connected dirty-state provider has unsaved changes, <code>window.isDirtyState</code> is set and Home Assistant fires a <code>dirty-state-changed</code> event.</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 plain">window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">addEventListener</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"dirty-state-changed"</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">ev</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 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 builtin" style="color:rgb(130, 170, 255)">console</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">log</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">ev</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">detail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">isDirty</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><br></div></code></pre></div></div>
<p>This is useful for shared infrastructure that needs to avoid disrupting active editors or dialogs with unsaved changes.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Standard event types for button event entities]]></title>
            <link>https://developers.home-assistant.io/blog/2026/07/22/button-standard-event-types</link>
            <guid>https://developers.home-assistant.io/blog/2026/07/22/button-standard-event-types</guid>
            <pubDate>Wed, 22 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Button event entities now have a set of standard event types, provided by the new ButtonEventType enum. Integrations that use EventDeviceClass.BUTTON should use these types instead of custom strings whenever the interaction maps to one of them.]]></description>
            <content:encoded><![CDATA[<p>Button event entities now have a set of standard event types, provided by the new <code>ButtonEventType</code> enum. Integrations that use <code>EventDeviceClass.BUTTON</code> should use these types instead of custom strings whenever the interaction maps to one of them.</p>
<p>See the <a href="https://github.com/home-assistant/architecture/discussions/1377" 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/07/22/button-standard-event-types#why" class="hash-link" aria-label="Direct link to Why" title="Direct link to Why" translate="no">​</a></h2>
<p>Previously, each integration picked its own strings for button interactions — <code>single</code>, <code>click</code>, <code>hold</code>, <code>double_press</code>, and so on. This inconsistency made it impossible to build generic button automations that work across integrations, and prevented the frontend from offering meaningful trigger suggestions.</p>
<p>The new <code>ButtonEventType</code> standard event types solve this by giving every button integration a shared vocabulary for the common interactions.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-event-types">The event types<a href="https://developers.home-assistant.io/blog/2026/07/22/button-standard-event-types#the-event-types" class="hash-link" aria-label="Direct link to The event types" title="Direct link to The event types" translate="no">​</a></h2>
<p><code>ButtonEventType</code> defines six standard event types:</p>
<ul>
<li class=""><code>ButtonEventType.PRESS_START</code>: the button was pressed down.</li>
<li class=""><code>ButtonEventType.PRESS_END</code>: the button was released after a brief press (the standard "click").</li>
<li class=""><code>ButtonEventType.LONG_PRESS_START</code>: the button was held past a duration threshold.</li>
<li class=""><code>ButtonEventType.LONG_PRESS_END</code>: the button was released after a long hold.</li>
<li class=""><code>ButtonEventType.MULTI_PRESS_ONGOING</code>: an intermediate press in a multi-press sequence was detected.</li>
<li class=""><code>ButtonEventType.MULTI_PRESS_END</code>: a multi-press sequence completed.</li>
</ul>
<p>The <code>MULTI_PRESS_ONGOING</code> and <code>MULTI_PRESS_END</code> events include a <code>multi_press_count</code> attribute in their event data (the <code>ATTR_MULTI_PRESS_COUNT</code> constant) with the number of presses.</p>
<p><strong>None of these are mandatory.</strong> Unlike the doorbell <code>ring</code> event, there is no required type here. Each integration maps only the interactions its hardware can actually produce, and lists just those in <code>event_types</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-to-do">What to do<a href="https://developers.home-assistant.io/blog/2026/07/22/button-standard-event-types#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>ButtonEventType</code> from <code>homeassistant.components.event</code> and include the types your device supports in the entity's <code>event_types</code>. Fire them as the interactions happen:</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"> </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">    ATTR_MULTI_PRESS_COUNT</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">    ButtonEventType</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">    EventDeviceClass</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">    EventEntity</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" 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)">MyButtonEvent</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">BUTTON</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"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        ButtonEventType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PRESS_END</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">        ButtonEventType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">LONG_PRESS_END</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">        ButtonEventType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">MULTI_PRESS_END</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 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_multi_press</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"> count</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 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 a completed multi-press sequence."""</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"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            ButtonEventType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">MULTI_PRESS_END</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">ATTR_MULTI_PRESS_COUNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> count</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><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="single-event-devices">Single-event devices<a href="https://developers.home-assistant.io/blog/2026/07/22/button-standard-event-types#single-event-devices" class="hash-link" aria-label="Direct link to Single-event devices" title="Direct link to Single-event devices" translate="no">​</a></h3>
<p>If a device only emits a single event per interaction, with no separate press and release, map it to the matching <code>_end</code> type (<code>PRESS_END</code> for short presses, <code>LONG_PRESS_END</code> for holds, and so on). This keeps the "button was pressed" trigger consistent across devices without synthesizing events the hardware never sends.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="no-migration-required">No migration required<a href="https://developers.home-assistant.io/blog/2026/07/22/button-standard-event-types#no-migration-required" class="hash-link" aria-label="Direct link to No migration required" title="Direct link to No migration required" translate="no">​</a></h2>
<p>This change only adds the shared constants; nothing is deprecated and no integration is forced to migrate. Custom event types are still allowed alongside the standard ones. Adopt <code>ButtonEventType</code> when it fits your device.</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[Devices are restricted to a single config entry and at most one subentry]]></title>
            <link>https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry</link>
            <guid>https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry</guid>
            <pubDate>Tue, 21 Jul 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/07/21/device-registry-single-config-entry#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>A device is now owned by a single config entry, and by a single (or no) config subentry. Devices are no longer merged across integrations: a physical device supported by several integrations is now represented by one device per config entry instead of a single shared device.</p>
<p>Devices which were previously tied to multiple config entries are split into one device per config entry when the device registry is loaded. The entity registry is updated so entities point to the correct device.</p>
<p><strong>Most integrations don't interact directly with the device registry and don't need any changes.</strong> Integrations which interact with it directly need to handle the deprecations listed below.</p>
<p>This is implemented in core <a href="https://github.com/home-assistant/core/pull/175785" target="_blank" rel="noopener noreferrer" class="">PR #175785</a>, the rationale is described in architecture proposal <a href="https://github.com/home-assistant/architecture/discussions/1226" target="_blank" rel="noopener noreferrer" class="">home-assistant/architecture#1226</a>. The changes land in Home Assistant Core 2026.8.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></h2>
<p>Until now, a physical device supported by several integrations has been merged into a single, shared device. This was achieved by identifying devices by connections and identifiers which are globally unique, so that for example a device tracker and a native integration referring to the same MAC address end up on the same device.</p>
<p>This causes a few problems:</p>
<ul>
<li class="">There's no single source of truth for device information such as name or model; conflicting values are discarded instead of preserved.</li>
<li class="">Users get a confusing experience where a device page contains a hodgepodge of entities from multiple integrations.</li>
<li class="">There are long-standing bugs where modifying the connections and identifiers of a device causes multiple devices to end up with the same connections, violating the original design of the device registry.</li>
</ul>
<p>The new behavior is achieved by making identifiers and connections unique per config entry instead of globally unique.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecations">Deprecations<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#deprecations" class="hash-link" aria-label="Direct link to Deprecations" title="Direct link to Deprecations" translate="no">​</a></h2>
<p>Using the deprecated functionality below logs a warning at runtime. Unless noted otherwise, deprecated functionality remains supported until Home Assistant Core 2027.8.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deviceentryconfig_entries"><code>DeviceEntry.config_entries</code><a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#deviceentryconfig_entries" class="hash-link" aria-label="Direct link to deviceentryconfig_entries" title="Direct link to deviceentryconfig_entries" translate="no">​</a></h3>
<p>Deprecated, use <code>DeviceEntry.config_entry_id</code> instead. The property is kept as a compatibility shim which returns a set with the device's single config entry.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deviceentryconfig_entries_subentries"><code>DeviceEntry.config_entries_subentries</code><a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#deviceentryconfig_entries_subentries" class="hash-link" aria-label="Direct link to deviceentryconfig_entries_subentries" title="Direct link to deviceentryconfig_entries_subentries" translate="no">​</a></h3>
<p>Deprecated, use <code>DeviceEntry.config_entry_id</code> and <code>DeviceEntry.config_subentry_id</code> instead. The property is kept as a compatibility shim.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deviceentryprimary_config_entry"><code>DeviceEntry.primary_config_entry</code><a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#deviceentryprimary_config_entry" class="hash-link" aria-label="Direct link to deviceentryprimary_config_entry" title="Direct link to deviceentryprimary_config_entry" translate="no">​</a></h3>
<p>Deprecated, use <code>DeviceEntry.config_entry_id</code> instead. A device now belongs to a single config entry, which is its primary config entry.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="reading-config-entries-of-a-composite-device">Reading config entries of a composite device<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#reading-config-entries-of-a-composite-device" class="hash-link" aria-label="Direct link to Reading config entries of a composite device" title="Direct link to Reading config entries of a composite device" translate="no">​</a></h3>
<p><code>DeviceEntry.config_entries</code>, <code>DeviceEntry.config_entries_subentries</code> and <code>DeviceEntry.primary_config_entry</code> are only deprecated for ordinary devices, which belong to a single config entry. They are not deprecated when interacting with a synthesized composite device, the read-only device the backwards compatibility resolution returns for a pre-migration composite device id (see <a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#backwards-compatibility" class="">Backwards compatibility</a>). Such a device spans several config entries, which <code>config_entry_id</code> and <code>config_subentry_id</code> can't represent, so these three properties, which report the union across the split devices, remain the way to read that information.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deviceinfovia_device-and-deviceregistryasync_get_or_createvia_device"><code>DeviceInfo["via_device"]</code> and <code>DeviceRegistry.async_get_or_create(via_device=...)</code><a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#deviceinfovia_device-and-deviceregistryasync_get_or_createvia_device" class="hash-link" aria-label="Direct link to deviceinfovia_device-and-deviceregistryasync_get_or_createvia_device" title="Direct link to deviceinfovia_device-and-deviceregistryasync_get_or_createvia_device" translate="no">​</a></h3>
<p>Deprecated, use <code>via_device_id</code> instead. Because identifiers are only unique per config entry, an identifier pair no longer unambiguously points at a single device, which is why <code>via_device</code> is deprecated.</p>
<p>Passing both <code>via_device</code> and <code>via_device_id</code> raises <code>HomeAssistantError</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deviceregistryasync_update_device-config-entry-parameters"><code>DeviceRegistry.async_update_device()</code> config entry parameters<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#deviceregistryasync_update_device-config-entry-parameters" class="hash-link" aria-label="Direct link to deviceregistryasync_update_device-config-entry-parameters" title="Direct link to deviceregistryasync_update_device-config-entry-parameters" translate="no">​</a></h3>
<p>The <code>add_config_entry_id</code>, <code>add_config_subentry_id</code>, <code>remove_config_entry_id</code> and <code>remove_config_subentry_id</code> parameters are all deprecated. A device belongs to a single config entry and subentry, so adding and removing config entries is no longer meaningful; a device is instead moved or removed.</p>
<p>To move a device to another config entry or subentry, pass the new <code>new_config_entry_id</code> and <code>new_config_subentry_id</code> parameters:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py 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">device_registry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_update_device</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">    device</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token builtin" style="color:rgb(130, 170, 255)">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">    new_config_entry_id</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">config_entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">entry_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">    new_config_subentry_id</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">subentry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">subentry_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"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Moving a device with the old parameters took the integration several <code>async_update_device</code> calls, adding the device to the new config entry and subentry and then removing it from the old ones, with a separate case for a device that only changed subentry within the same config entry. The single call shown above replaces all of that. In addition, the device registry now clears a <code>CONFIG_ENTRY</code> disable when a device is moved to an enabled config entry, so the integration no longer has to carry the <code>disabled_by</code> flag across the move by hand.</p>
<p>Relatedly, <code>async_update_device</code> now validates the <code>disabled_by</code> flag against the owning config entry's disabled state. Setting <code>disabled_by=None</code> for a device on a disabled config entry, or <code>disabled_by=DeviceEntryDisabler.CONFIG_ENTRY</code> for a device on an enabled config entry, is inconsistent; such a value is ignored and logged now, and will raise from Home Assistant Core 2027.8.</p>
<p>Core integrations have been updated as examples: <code>openai_conversation</code> in <a href="https://github.com/home-assistant/core/pull/176662" target="_blank" rel="noopener noreferrer" class="">PR #176662</a>, <code>scrape</code> in <a href="https://github.com/home-assistant/core/pull/176663" target="_blank" rel="noopener noreferrer" class="">PR #176663</a>, <code>waqi</code> in <a href="https://github.com/home-assistant/core/pull/176664" target="_blank" rel="noopener noreferrer" class="">PR #176664</a> and <code>wolflink</code> in <a href="https://github.com/home-assistant/core/pull/176665" target="_blank" rel="noopener noreferrer" class="">PR #176665</a>.</p>
<p>To remove a device, call <code>DeviceRegistry.async_remove_device()</code>:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py 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">device_registry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_remove_device</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 builtin" style="color:rgb(130, 170, 255)">id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Core integrations have been updated to remove devices this way in PRs <a href="https://github.com/home-assistant/core/pull/176669" target="_blank" rel="noopener noreferrer" class="">#176669</a>, <a href="https://github.com/home-assistant/core/pull/176671" target="_blank" rel="noopener noreferrer" class="">#176671</a>, <a href="https://github.com/home-assistant/core/pull/176672" target="_blank" rel="noopener noreferrer" class="">#176672</a> and <a href="https://github.com/home-assistant/core/pull/176673" target="_blank" rel="noopener noreferrer" class="">#176673</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deviceregistryasync_get_device"><code>DeviceRegistry.async_get_device()</code><a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#deviceregistryasync_get_device" class="hash-link" aria-label="Direct link to deviceregistryasync_get_device" title="Direct link to deviceregistryasync_get_device" translate="no">​</a></h3>
<p>Deprecated. Identifiers and connections are only unique per config entry, so a lookup by identifiers or connections can by design match more than one device, and what <code>async_get_device</code> returns is therefore ambiguous.</p>
<p>When the owning config entry is known, look the device up scoped to that config entry with the new methods <code>DeviceRegistry.async_get_device_by_identifier()</code> or <code>DeviceRegistry.async_get_device_by_connection()</code>. Each takes a single identifier or connection tuple plus the config entry id, so the lookup can no longer be ambiguous:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py 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"># Before</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">device </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> device_registry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_get_device</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">identifiers</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 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"> serial_number</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 comment" style="color:rgb(105, 112, 152);font-style:italic"># After</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">device </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> device_registry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_get_device_by_identifier</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">DOMAIN</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> serial_number</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"> entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">entry_id</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>Inside an entity, prefer <code>self.device_entry</code> over a registry lookup. If you genuinely need every device matching a key, possibly across config entries, use <code>DeviceRegistry.async_get_devices()</code>, which returns a list.</p>
<p>Core integrations are migrated to the new methods, <code>heos</code> in core <a href="https://github.com/home-assistant/core/pull/176932" target="_blank" rel="noopener noreferrer" class="">PR #176932</a> is an example.</p>
<p>During the deprecation period, <code>async_get_device</code> resolves an ambiguous lookup as described in <a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#backwards-compatibility" class="">Backwards compatibility</a> below. Note that this backwards-compatible resolution only happens through the <code>DeviceRegistry</code> lookup methods such as <code>async_get()</code> and <code>async_get_device()</code>; interacting with the <code>devices</code> container directly, for example <code>DeviceRegistry.devices.get(device_id)</code>, does not synthesize a composite device.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="adding-a-helper-config-entry-to-another-integrations-device">Adding a helper config entry to another integration's device<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#adding-a-helper-config-entry-to-another-integrations-device" class="hash-link" aria-label="Direct link to Adding a helper config entry to another integration's device" title="Direct link to Adding a helper config entry to another integration's device" translate="no">​</a></h3>
<p>Helper integrations must not add their config entry to the source entity's device or to a user-selected device, they should link their entities to the device instead. This is a direct consequence of the change described here: a device now belongs to a single config entry, so a helper config entry can no longer be added to a device owned by another integration.</p>
<p>This was announced last year in <a class="" href="https://developers.home-assistant.io/blog/2025/07/18/updated-pattern-for-helpers-linking-to-devices">Updated guidelines for helper integrations linking to other integration's device</a>, and stops working in Home Assistant Core 2026.8.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="helpersdeviceasync_device_info_to_link_from_entity-and-async_device_info_to_link_from_device_id"><code>helpers.device.async_device_info_to_link_from_entity()</code> and <code>async_device_info_to_link_from_device_id()</code><a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#helpersdeviceasync_device_info_to_link_from_entity-and-async_device_info_to_link_from_device_id" class="hash-link" aria-label="Direct link to helpersdeviceasync_device_info_to_link_from_entity-and-async_device_info_to_link_from_device_id" title="Direct link to helpersdeviceasync_device_info_to_link_from_entity-and-async_device_info_to_link_from_device_id" translate="no">​</a></h3>
<p>Both helpers now always return <code>None</code>.</p>
<p>They returned a <code>DeviceInfo</code> carrying another device's identifiers and connections, which implicitly added the caller's config entry to that device. A device with a single config entry can't represent that, it would silently fork a duplicate device instead.</p>
<p>Link the helper entity to the device by setting <code>self.device_entry</code> in the entity's constructor instead:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py 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">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">device_entry </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> async_entity_id_to_device</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"> source_entity_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>The helpers are removed in Home Assistant Core 2027.8.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="helpershelper_integrationasync_handle_source_entity_changesadd_helper_config_entry_to_device"><code>helpers.helper_integration.async_handle_source_entity_changes(add_helper_config_entry_to_device=...)</code><a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#helpershelper_integrationasync_handle_source_entity_changesadd_helper_config_entry_to_device" class="hash-link" aria-label="Direct link to helpershelper_integrationasync_handle_source_entity_changesadd_helper_config_entry_to_device" title="Direct link to helpershelper_integrationasync_handle_source_entity_changesadd_helper_config_entry_to_device" translate="no">​</a></h3>
<p>The parameter no longer has any effect and should be removed from the call.</p>
<p>When the source entity moves to another device, <code>async_handle_source_entity_changes</code> now only updates the helper entity to link to the new device, it no longer removes the helper config entry from the old device and adds it to the new one.</p>
<p>Passing the parameter is accepted until Home Assistant Core 2027.8, and logs a warning.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cleaning-up-helper-devices">Cleaning up helper devices<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#cleaning-up-helper-devices" class="hash-link" aria-label="Direct link to Cleaning up helper devices" title="Direct link to Cleaning up helper devices" translate="no">​</a></h3>
<p>The helper used to clean up a helper integration's devices from a config entry migration step has been renamed from <code>async_remove_helper_config_entry_from_source_device</code> to <code>homeassistant.helpers.helper_integration.async_remove_helper_devices</code> in core <a href="https://github.com/home-assistant/core/pull/176714" target="_blank" rel="noopener noreferrer" class="">PR #176714</a>. The old name is kept as a deprecated alias which keeps working until Home Assistant Core 2027.8. The new signature is:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py 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)">async_remove_helper_devices</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">    </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">    helper_config_entry_id</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">    source_device_id</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 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">    remove_all_devices</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">    keep_device_ids</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Collection</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</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><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 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><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="helpersdeviceasync_remove_stale_devices_links_keep_entity_device-and-async_remove_stale_devices_links_keep_current_device"><code>helpers.device.async_remove_stale_devices_links_keep_entity_device()</code> and <code>async_remove_stale_devices_links_keep_current_device()</code><a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#helpersdeviceasync_remove_stale_devices_links_keep_entity_device-and-async_remove_stale_devices_links_keep_current_device" class="hash-link" aria-label="Direct link to helpersdeviceasync_remove_stale_devices_links_keep_entity_device-and-async_remove_stale_devices_links_keep_current_device" title="Direct link to helpersdeviceasync_remove_stale_devices_links_keep_entity_device-and-async_remove_stale_devices_links_keep_current_device" translate="no">​</a></h3>
<p>Both are now no-ops. Call <code>async_remove_helper_devices</code> with <code>remove_all_devices=True</code> from the helper's <code>async_setup_entry</code> instead:</p>
<div class="language-py codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-py 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">async_remove_helper_devices</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">    helper_config_entry_id</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">entry_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">    source_device_id</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">CONF_DEVICE_ID</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">    remove_all_devices</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token boolean" style="color:rgb(255, 88, 116)">True</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 <code>template</code> helper has been migrated as an example in core <a href="https://github.com/home-assistant/core/pull/176900" target="_blank" rel="noopener noreferrer" class="">PR #176900</a>. The functions are removed in Home Assistant Core 2027.8.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="devices-can-only-have-a-single-config-subentry">Devices can only have a single config subentry<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#devices-can-only-have-a-single-config-subentry" class="hash-link" aria-label="Direct link to Devices can only have a single config subentry" title="Direct link to Devices can only have a single config subentry" translate="no">​</a></h2>
<p>A device can no longer be tied to more than one config subentry. This is a breaking change without a backwards compatibility shim; integrations which attach several subentries to the same device must create one device per subentry.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="example-telegram_bot">Example: <code>telegram_bot</code><a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#example-telegram_bot" class="hash-link" aria-label="Direct link to example-telegram_bot" title="Direct link to example-telegram_bot" translate="no">​</a></h3>
<p>The <code>telegram_bot</code> integration has been adjusted for this in core <a href="https://github.com/home-assistant/core/pull/176606" target="_blank" rel="noopener noreferrer" class="">PR #176606</a>, which can be used as an example.</p>
<p>It previously had a single bot device shared by every chat, with each chat's subentry attached to that same device. It now creates an individual device per chat, linked to the bot device as a via device. A config entry migration moves each chat's notify entity onto its own device and strips the chat subentries from the bot device, leaving the bot device with no subentry.</p>
<p>Note that the PR was written before <code>via_device_id</code> was added, new code should use <code>via_device_id</code> instead of <code>via_device</code>.</p>
<p>When <a href="https://github.com/home-assistant/architecture/discussions/1414" target="_blank" rel="noopener noreferrer" class="">child devices</a> are introduced, integrations which model this with a via device should migrate to child devices instead.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="linking-an-entity-to-a-split-device">Linking an entity to a split device<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#linking-an-entity-to-a-split-device" class="hash-link" aria-label="Direct link to Linking an entity to a split device" title="Direct link to Linking an entity to a split device" translate="no">​</a></h2>
<p>A pre-migration composite device id no longer refers to a real device. Attempting to link an entity to such an id, by passing it to <code>EntityRegistry.async_get_or_create(device_id=...)</code> or <code>EntityRegistry.async_update_entity(device_id=...)</code>, is ignored with a logged warning rather than applied. A new entity is then created with no device, and an existing entity keeps its current device. Passing a genuinely non-existent device id still raises <code>ValueError</code> as before.</p>
<p>Entities whose stored device is a composite device with no split owned by the entity's config entry are detached from the device when the registry is loaded; the owning integration is expected to re-link them.</p>
<p>Link entities to one of the split devices instead, looking it up with <code>async_get_device_by_identifier</code> or <code>async_get_device_by_connection</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="device-registry-events">Device registry events<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#device-registry-events" class="hash-link" aria-label="Direct link to Device registry events" title="Direct link to Device registry events" translate="no">​</a></h2>
<p>Splitting a pre-migration composite device happens when the registry is loaded from storage, before any listeners run, so it emits no <code>EVENT_DEVICE_REGISTRY_UPDATED</code> events; devices are already split at startup.</p>
<p>Two things change for integrations which subscribe to <code>EVENT_DEVICE_REGISTRY_UPDATED</code>, or use <code>async_track_device_registry_updated_event</code>, and inspect the payload:</p>
<ul>
<li class="">The <code>changes</code> dict of an <code>update</code> event reports a device move with the keys <code>config_entry_id</code> and <code>config_subentry_id</code>, replacing the previous <code>config_entries</code> and <code>config_entries_subentries</code>.</li>
<li class="">Updating or removing a pre-migration composite device id forwards the operation to each split device, so one event is fired per split device rather than a single event for the composite id.</li>
</ul>
<p>A device now belongs to a single config entry, so it can no longer lose one config entry while staying around for another. Integrations which previously watched <code>update</code> events for a change to the <code>config_entries</code> or <code>config_entries_subentries</code> keys, typically to detect their config entry being removed from a device shared with another integration, probably only need to handle <code>remove</code> events now: a device losing its config entry means the device is removed.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="backwards-compatibility">Backwards compatibility<a href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#backwards-compatibility" class="hash-link" aria-label="Direct link to Backwards compatibility" title="Direct link to Backwards compatibility" translate="no">​</a></h2>
<p>Splitting devices changes assumptions which custom integrations may rely on, and device ids which are stored in automations and scripts no longer exist as devices. To soften that, the device registry makes a best-effort attempt to keep unmodified custom integrations working, by resolving a pre-migration composite device id to the devices it was split into.</p>
<p>This is best-effort, not a guarantee. The shims can't cover every way a custom integration interacts with the device registry, and an operation which is ambiguous across the split devices can't be applied at all. An AI-assisted analysis of 462 custom integrations interacting directly with the device registry suggests at least 90% are expected to work unaffected, which also means some will not. Please migrate your integration to the new API rather than relying on these shims; they are removed in Home Assistant Core 2027.8.</p>
<p>During the deprecation period:</p>
<ul>
<li class=""><code>DeviceRegistry.async_get()</code> synthesizes a read-only restored composite device when passed the id of a pre-migration composite device. Its identifiers, connections and config entries are the union of the split devices'. The synthesis only happens in <code>async_get()</code>; interacting with the <code>devices</code> container directly, for example <code>DeviceRegistry.devices.get(device_id)</code>, does not synthesize a composite and returns <code>None</code> for a pre-migration composite device id.</li>
<li class=""><code>DeviceRegistry.async_get_device()</code> resolves a lookup by identifiers or connections matching several config entries to a single device when possible, preferring the device whose config entry domain matches the looked-up identifier. If the remaining matches are the splits of one pre-migration composite device, a read-only composite spanning them is returned. For independent devices sharing an identifier or connection, a device owned by the calling integration is preferred, falling back to the first match.</li>
<li class=""><code>DeviceRegistry.async_update_device()</code> and <code>DeviceRegistry.async_remove_device()</code> forward the call to each of the split devices. Arguments which rewrite a device's identity or move it are ambiguous across the split devices; they are ignored and reported to the offending integration.</li>
<li class="">Entity registry <code>get_entries_for_device_id()</code> and <code>async_entries_for_device()</code> expand a pre-migration composite device id to the entities of the devices it was split into.</li>
<li class="">Actions targeting a pre-migration composite device id trickle down to the split devices.</li>
<li class="">User customizations (area, floor, labels, name) are kept when a device is split.</li>
</ul>
<p>A new method <code>DeviceRegistry.async_get_devices_for_composite_device_id()</code> returns the devices a pre-migration composite device was split into. <code>DeviceRegistry.async_is_composite_device_id()</code> returns whether a device id is a pre-migration composite device id, that is, an id which was split into one device per config entry and no longer refers to a registered device.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing the Open Home Foundation AI Policy]]></title>
            <link>https://developers.home-assistant.io/blog/2026/07/20/ai-policy</link>
            <guid>https://developers.home-assistant.io/blog/2026/07/20/ai-policy</guid>
            <pubDate>Mon, 20 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[AI-assisted development has become part of daily reality for many contributors, and for us as maintainers too. That can be a good thing unreviewed AI output submitted as a contribution costs maintainers real time, and maintainer time is the scarcest resource an open source project has.]]></description>
            <content:encoded><![CDATA[<p>AI-assisted development has become part of daily reality for many contributors, and for us as maintainers too. That can be a good thing: AI tools help people write code, improve their English, and find their way in an unfamiliar codebase. It also has a downside: unreviewed AI output submitted as a contribution costs maintainers real time, and maintainer time is the scarcest resource an open source project has.</p>
<p>Today, we are publishing the <a class="" href="https://developers.home-assistant.io/docs/ai_policy">Open Home Foundation AI Policy</a>. It applies to all Open Home Foundation projects, including every repository in the <code>home-assistant</code> and <code>home-assistant-libs</code> GitHub organizations.</p>
<p>The policy boils down to a few points:</p>
<ul>
<li class="">AI tools are welcome as an aid. You remain responsible for everything you submit.</li>
<li class="">Autonomous agents are not allowed to contribute. Pull requests and issues that were created autonomously will be closed.</li>
<li class="">You must understand and be able to explain every change you submit, in your own words. This includes answering questions from maintainers yourself, not having an AI do it for you.</li>
<li class="">Using AI to improve the grammar or clarity of text you have written yourself is fine. For non-native English speakers this is genuinely useful, and we appreciate the effort.</li>
</ul>
<p>We are rolling the policy out to every repository in both organizations. Each repository gets an <code>AI_POLICY.md</code> file in its root, and existing contributing guidelines and <code>AGENTS.md</code> files gain a reference to it, so both humans and their AI tools know what we expect.</p>
<p>Read the full policy in the <a class="" href="https://developers.home-assistant.io/docs/ai_policy">developer documentation</a>. If a contribution does not follow it, it will be closed. If you believe that happened to yours in error, reach out to a maintainer and we will sort it out.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modernizing Modbus in Home Assistant]]></title>
            <link>https://developers.home-assistant.io/blog/2026/07/05/modernizing-modbus</link>
            <guid>https://developers.home-assistant.io/blog/2026/07/05/modernizing-modbus</guid>
            <pubDate>Sun, 05 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[We are re-evaluating the Home Assistant side of the approach described in this post. The foundation is unchanged: everything will still be built around the modbus-connection PyPI package, and device libraries built on it remain the right investment. What we are rethinking is how connections surface inside Home Assistant itself, where we want to focus on being able to produce a better user experience. If you are working on a device integration, hold off on wiring it up to the modbus_connection integration described below — we will share the updated approach here soon.]]></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>Update — July 16, 2026</div><div class="admonitionContent_BuS1"><p>We are re-evaluating the Home Assistant side of the approach described in this post. The foundation is unchanged: everything will still be built around the <a href="https://home-assistant-libs.github.io/modbus-connection/" target="_blank" rel="noopener noreferrer" class=""><code>modbus-connection</code></a> PyPI package, and device libraries built on it remain the right investment. What we are rethinking is how connections surface inside Home Assistant itself, where we want to focus on being able to produce a better user experience. If you are working on a device integration, hold off on wiring it up to the <code>modbus_connection</code> integration described below — we will share the updated approach here soon.</p></div></div>
<p>Modbus is everywhere in the modern home: solar inverters, energy meters, heat pumps, and all kinds of industrial equipment that has found its way indoors. Home Assistant has long supported these devices through the YAML-based <code>modbus</code> integration, where users hand-write register maps in their configuration. That integration is not going anywhere, and existing setups keep working. But hand-writing register maps puts the burden of understanding a device's protocol on every user, and it does not fit the config-flow, UI-first direction the rest of Home Assistant has taken.</p>
<p>So we are adding a new way to use Modbus: an integration-based approach, where a device integration owns the device-specific knowledge and the user simply picks their device in the UI, the same as any other integration.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="sharing-a-connection">Sharing a connection<a href="https://developers.home-assistant.io/blog/2026/07/05/modernizing-modbus#sharing-a-connection" class="hash-link" aria-label="Direct link to Sharing a connection" title="Direct link to Sharing a connection" translate="no">​</a></h2>
<p>A Modbus connection is a single, exclusive resource: only one party can talk on the bus at a time. A serial (RS-485) bus, or a TCP-to-serial gateway, can carry many devices at once, sometimes from different manufacturers. If two integrations each open their own connection to the same bus, they fight over it, and historically Home Assistant did not support sharing a bus between integrations at all.</p>
<p>The new <a href="https://github.com/home-assistant/core/tree/dev/homeassistant/components/modbus_connection" target="_blank" rel="noopener noreferrer" class=""><code>modbus_connection</code></a> integration solves this by making a connection something device integrations route through rather than own. The user sets up a connection once in the UI, and <code>modbus_connection</code> keeps it open and manages its lifecycle, including reconnecting after a drop. Device integrations then borrow what they need from that shared connection instead of managing their own. We have revamped the <a class="" href="https://developers.home-assistant.io/docs/modbus/introduction">Modbus developer documentation</a> to cover how that works, with example code.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-standalone-library">A standalone library<a href="https://developers.home-assistant.io/blog/2026/07/05/modernizing-modbus#a-standalone-library" class="hash-link" aria-label="Direct link to A standalone library" title="Direct link to A standalone library" translate="no">​</a></h2>
<p>The connection abstraction underneath <code>modbus_connection</code> lives in <a href="https://home-assistant-libs.github.io/modbus-connection/" target="_blank" rel="noopener noreferrer" class=""><code>modbus-connection</code></a>, a new library we designed for this purpose and published on PyPI. It is not bound to Home Assistant and can be used standalone in any Python project. It presents a common, backend-neutral interface, so device library authors write against one API regardless of the underlying Modbus implementation, and it ships a device-modelling framework and a <code>pytest</code> plugin to make building and testing a device library straightforward.</p>
<p>This keeps concerns where they belong. A device library is a normal PyPI package that knows how to talk to a specific device, and a consuming integration in Home Assistant wires that library up to a shared connection and exposes entities. Both can be developed and tested independently.</p>
<p>For more background, see our <a href="https://gist.github.com/balloob/b9fa91ba1a0914a9787f8f6ceb637b83" target="_blank" rel="noopener noreferrer" class="">research</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="lets-get-building">Let's get building<a href="https://developers.home-assistant.io/blog/2026/07/05/modernizing-modbus#lets-get-building" class="hash-link" aria-label="Direct link to Let's get building" title="Direct link to Let's get building" translate="no">​</a></h2>
<p>With these new building blocks in place, it is now possible to turn a collection of YAML configuration for Modbus into manufacturer-specific integrations that people can set up via the UI. If you're (interested in) working on this, stop by the <a href="https://discord.com/channels/330944238910963714/1347329854495916044" target="_blank" rel="noopener noreferrer" class="">#modbus channel on the Home Assistant Discord</a> and we'll be happy to help.</p>
<p>If you're using an AI agent, you can give it the following prompt:</p>
<blockquote>
<p>I want to create a new integration for Home Assistant using the new Modbus Connection integration as documented here: <a href="https://developers.home-assistant.io/docs/modbus/introduction" target="_blank" rel="noopener noreferrer" class="">https://developers.home-assistant.io/docs/modbus/introduction</a></p>
<p>The YAML we want to turn into a device library can be found here: <em>TODO INSERT LOCATION OF MODBUS YAML!</em></p>
<p>The deliverables of this task are going to be 3 folders:</p>
<ul>
<li class="">
<p>Start by creating a device library based on the YAML. Follow <a href="https://github.com/Tom-Bom-badil/trovis-modbus/" target="_blank" rel="noopener noreferrer" class="">https://github.com/Tom-Bom-badil/trovis-modbus/</a> as an exact example, including how to use component models, all GitHub Actions, helper scripts and README. This library is meant as a standalone device library and should not mention Home Assistant. Look at the source of modbus_connection to figure out all supported fields.</p>
</li>
<li class="">
<p>Create an integration that can be contributed to Home Assistant core that follows this example: <a href="https://github.com/home-assistant/core/tree/trovis557x-integration/homeassistant/components/trovis557x" target="_blank" rel="noopener noreferrer" class="">https://github.com/home-assistant/core/tree/trovis557x-integration/homeassistant/components/trovis557x</a></p>
</li>
<li class="">
<p>Create a custom integration version where the device library is vendorized so it is ready to be tested by the community via HACS. Follow this template <a href="https://github.com/ludeeus/integration_blueprint" target="_blank" rel="noopener noreferrer" class="">https://github.com/ludeeus/integration_blueprint</a></p>
</li>
</ul>
</blockquote>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Media sources can now be searched]]></title>
            <link>https://developers.home-assistant.io/blog/2026/07/03/media-source-search</link>
            <guid>https://developers.home-assistant.io/blog/2026/07/03/media-source-search</guid>
            <pubDate>Fri, 03 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Media sources can now implement search. By adding an asyncsearchmedia method to your MediaSource, users can search through your media directly from the media browser.]]></description>
            <content:encoded><![CDATA[<p>Media sources can now implement search. By adding an <code>async_search_media</code> method to your <code>MediaSource</code>, users can search through your media directly from the media browser.</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">media_player </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> SearchMedia</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> SearchMediaQuery</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_search_media</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"> item</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> MediaSourceItem</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> query</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> SearchMediaQuery</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"> SearchMedia</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)">"""Search media."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    results </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 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"># list of BrowseMediaSource items</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"> SearchMedia</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">result</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">results</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>To tell the media browser which items can be searched, set the <code>can_search</code> flag to <code>True</code> on the <code>BrowseMediaSource</code> items you return while browsing (typically directories). Other integrations can trigger a search through the new <code>media_source.async_search_media</code> helper.</p>
<p>For more info, see <a class="" href="https://developers.home-assistant.io/docs/core/platform/media_source#searching-media">the updated documentation.</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deprecation of the home_assistant_start flag of async_initialize_triggers]]></title>
            <link>https://developers.home-assistant.io/blog/2026/06/30/async-initialize-triggers-home-assistant-start-deprecated</link>
            <guid>https://developers.home-assistant.io/blog/2026/06/30/async-initialize-triggers-home-assistant-start-deprecated</guid>
            <pubDate>Tue, 30 Jun 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The dedicated homeassistantstart flag of asyncinitializetriggers is deprecated and will be removed in Home Assistant Core 2027.8. During the deprecation period the parameter no longer has any effect.]]></description>
            <content:encoded><![CDATA[<p>The dedicated <code>home_assistant_start</code> flag of <code>async_initialize_triggers</code> is deprecated and will be removed in Home Assistant Core 2027.8. During the deprecation period the parameter no longer has any effect.</p>
<p>The flag existed because the <code>homeassistant</code> start trigger was a pseudo trigger: instead of acting like a real trigger, it relied on the caller of the trigger API passing <code>home_assistant_start=True</code> so that <code>async_initialize_triggers</code> would fire the trigger during startup.</p>
<p>The start trigger has been rewritten to work as a real trigger, so the flag is no longer needed. Callers of <code>async_initialize_triggers</code> should simply stop passing <code>home_assistant_start</code>.</p>
<p>To make the new implementation possible, the rewrite adds <code>HomeAssistant.async_add_startup_job</code>, which registers a job to be called after all listeners to <code>EVENT_HOMEASSISTANT_START</code> have executed, but before <code>EVENT_HOMEASSISTANT_STARTED</code> is fired. This mirrors the approach already used for the homeassistant shutdown trigger, and avoids adding yet another core state and event to the already complex relationship between core states and events.</p>
<p>For more details, see <a href="https://github.com/home-assistant/core/pull/175160" target="_blank" rel="noopener noreferrer" class="">core PR 175160</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing new unit enumerators]]></title>
            <link>https://developers.home-assistant.io/blog/2026/06/30/new-unit-enumerators</link>
            <guid>https://developers.home-assistant.io/blog/2026/06/30/new-unit-enumerators</guid>
            <pubDate>Tue, 30 Jun 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[As of Home Assistant Core 2026.7, the following unit constants are deprecated and replaced]]></description>
            <content:encoded><![CDATA[<p>As of Home Assistant Core 2026.7, the following unit constants are deprecated and replaced
by a corresponding enum:</p>
<ul>
<li class=""><code>UnitOfDensity</code> enumerator replaces mass over volume <code>CONCENTRATION_***</code> constants
(<code>"g/m³"</code>, <code>"mg/m³"</code>, <code>"μg/m³"</code>, <code>"μg/ft³"</code>)</li>
<li class=""><code>UnitOfRatio</code> enumerator replaces unit-less ratio <code>CONCENTRATION_***</code> constants
(<code>"ppm"</code>, <code>"ppb"</code>)</li>
</ul>
<p><code>CONCENTRATION_PARTS_PER_CUBIC_METER</code> was only used by a single integration and is deprecated
without a replacement unit.</p>
<p>Please note that the use of <code>PERCENTAGE</code> constant is also deprecated when used as a unit of
measurement, even if the constant itself is not deprecated.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Frontend component updates in 2026.7]]></title>
            <link>https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7</link>
            <guid>https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7</guid>
            <pubDate>Tue, 23 Jun 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/06/23/frontend-component-updates-2026.7#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="component-sizes-use-web-awesome-names">Component sizes use Web Awesome names<a href="https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7#component-sizes-use-web-awesome-names" class="hash-link" aria-label="Direct link to Component sizes use Web Awesome names" title="Direct link to Component sizes use Web Awesome names" translate="no">​</a></h3>
<p><code>ha-button</code>, <code>ha-button-toggle-group</code>, and <code>ha-slider</code> now use the short Web Awesome size names.</p>
<p>For <code>ha-button</code>, use:</p>
<div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag" style="color:rgb(255, 85, 114)">ha-button</span><span class="token tag" style="color:rgb(255, 85, 114)"> </span><span class="token tag attr-name" style="color:rgb(255, 203, 107)">size</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(199, 146, 234)">=</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag attr-value" style="color:rgb(255, 85, 114)">s</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain">Save</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;/</span><span class="token tag" style="color:rgb(255, 85, 114)">ha-button</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><br></div></code></pre></div></div>
<p>Supported values are <code>xs</code>, <code>s</code>, <code>m</code>, <code>l</code>, and <code>xl</code>.</p>
<p>For <code>ha-button-toggle-group</code>, use <code>s</code> or <code>m</code>:</p>
<div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag" style="color:rgb(255, 85, 114)">ha-button-toggle-group</span><span class="token tag" style="color:rgb(255, 85, 114)"> </span><span class="token tag attr-name" style="color:rgb(255, 203, 107)">size</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(199, 146, 234)">=</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag attr-value" style="color:rgb(255, 85, 114)">s</span><span class="token tag attr-value punctuation" style="color:rgb(199, 146, 234)">"</span><span class="token tag" style="color:rgb(255, 85, 114)"> </span><span class="token tag attr-name" style="color:rgb(255, 203, 107)">.buttons</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(199, 146, 234)">=</span><span class="token tag attr-value" style="color:rgb(255, 85, 114)">${buttons}</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;/</span><span class="token tag" style="color:rgb(255, 85, 114)">ha-button-toggle-group</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><br></div></code></pre></div></div>
<p><code>ha-slider</code> uses <code>s</code> or <code>m</code>.</p>
<p>If your custom card or editor still uses <code>small</code>, <code>medium</code>, or <code>large</code> on these components, migrate them to short values like <code>s</code>, <code>m</code>, or <code>l</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="virtualized-lists">Virtualized lists<a href="https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7#virtualized-lists" class="hash-link" aria-label="Direct link to Virtualized lists" title="Direct link to Virtualized lists" translate="no">​</a></h3>
<p>We added two list components for large data sets:</p>
<ul>
<li class=""><code>ha-list-virtualized</code></li>
<li class=""><code>ha-list-selectable-virtualized</code></li>
</ul>
<p>Use these when a picker or dialog can render enough rows to affect scrolling or initial render time. The virtualized list renders only the visible rows while keeping the roving-tabindex keyboard navigation from <code>ha-list-base</code>.</p>
<p>Rows expose accessibility metadata with <code>aria-setsize</code> and <code>aria-posinset</code>, so assistive technologies still get the full list position even though only part of the list is in the DOM.</p>
<p>For selectable lists, render <code>ha-list-item-option</code> rows.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="context-and-editor-infrastructure">Context and editor infrastructure<a href="https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7#context-and-editor-infrastructure" class="hash-link" aria-label="Direct link to Context and editor infrastructure" title="Direct link to Context and editor infrastructure" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="dirty-state-tracking">Dirty state tracking<a href="https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7#dirty-state-tracking" class="hash-link" aria-label="Direct link to Dirty state tracking" title="Direct link to Dirty state tracking" translate="no">​</a></h3>
<p>Dialogs and editors now have shared dirty-state infrastructure:</p>
<ul>
<li class=""><code>DirtyStateProviderMixin</code></li>
<li class=""><code>dirtyStateContext</code></li>
<li class=""><code>isDirtyState</code></li>
<li class=""><code>isEffectiveDirtyState</code></li>
</ul>
<p>Use <code>DirtyStateProviderMixin</code> for new dialogs or editors that need to block scrim close, enable Save only after edits, or coordinate dirty state with child components.</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">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">MyDialog</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">DirtyStateProviderMixin</span><span class="token class-name operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token class-name" style="color:rgb(255, 203, 107)">MyState</span><span class="token class-name operator" style="color:rgb(137, 221, 255)">&gt;</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">LitElement</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">public</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">openDialog</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><br></div><div class="token-line" style="color:#bfc7d5"><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 function" style="color:rgb(130, 170, 255)">_initDirtyTracking</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"> 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)">"shallow"</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 keyword" style="font-style:italic">this</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">_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 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">private</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">_stateChanged</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">state</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> MyState</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">this</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">_updateDirtyState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">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 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><code>isDirtyState</code> is the raw comparison and is usually right for enabling Save. <code>isEffectiveDirtyState</code> can ignore equivalent config output, for example when an editor normalizes an explicit default back to the same effective config.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-context">Related context<a href="https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7#related-context" class="hash-link" aria-label="Direct link to Related context" title="Direct link to Related context" translate="no">​</a></h3>
<p>Pages and editors can now publish related context for nearby pickers:</p>
<ul>
<li class=""><code>relatedContext</code></li>
<li class=""><code>fireRelatedContext</code></li>
<li class=""><code>fireEntityRelatedContext</code></li>
</ul>
<p>When a card editor, badge editor, automation trace page, or similar surface knows the current entity, device, or area, it can provide that context. Entity pickers and add-element searches can then prioritize related entities, devices, and areas.</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 function" style="color:rgb(130, 170, 255)">fireEntityRelatedContext</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 string" style="color:rgb(195, 232, 141)">"light.kitchen"</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>Clear the context with <code>undefined</code> when the editor no longer has a related item.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="narrow-viewport-context">Narrow viewport context<a href="https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7#narrow-viewport-context" class="hash-link" aria-label="Direct link to Narrow viewport context" title="Direct link to Narrow viewport context" translate="no">​</a></h3>
<p><code>narrowViewportContext</code> exposes whether the main Home Assistant viewport is in the narrow layout.</p>
<p>Components that only need narrow-layout state can consume this context instead of receiving <code>narrow</code> through several layers of properties.</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)">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"> narrowViewportContext</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"> _narrow</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"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">boolean</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="lovelace-updates">Lovelace updates<a href="https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7#lovelace-updates" class="hash-link" aria-label="Direct link to Lovelace updates" title="Direct link to Lovelace updates" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="strategy-regeneration-control">Strategy regeneration control<a href="https://developers.home-assistant.io/blog/2026/06/23/frontend-component-updates-2026.7#strategy-regeneration-control" class="hash-link" aria-label="Direct link to Strategy regeneration control" title="Direct link to Strategy regeneration control" translate="no">​</a></h3>
<p>Lovelace strategies can now avoid unnecessary regeneration.</p>
<p>Strategies may declare <code>registryDependencies</code> to use the default reference-change check for only the registries they depend on:</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">static</span><span class="token plain"> registryDependencies </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)">"entities"</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)">"areas"</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">as</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>For custom logic, implement <code>shouldRegenerate()</code>:</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">static</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">shouldRegenerate</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"> oldHomeAssistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> newHomeAssistant</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"> oldHomeAssistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">entities </span><span class="token operator" style="color:rgb(137, 221, 255)">!==</span><span class="token plain"> newHomeAssistant</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">entities</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>If neither is provided, strategies keep the previous default behavior and regenerate on changes to entities, devices, areas, or floors.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Changes to device tracker entity models]]></title>
            <link>https://developers.home-assistant.io/blog/2026/06/15/device-tracker-changes</link>
            <guid>https://developers.home-assistant.io/blog/2026/06/15/device-tracker-changes</guid>
            <pubDate>Mon, 15 Jun 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/06/15/device-tracker-changes#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>There have been multiple recent changes to the device tracker entity model:</p>
<ul>
<li class="">The <code>battery_level</code> property has been deprecated</li>
<li class="">The <code>location_name</code> property of <code>TrackerEntity</code> has been deprecated</li>
<li class="">A new entity base class <code>BaseScannerEntity</code> has been introduced</li>
<li class="">Users can associate scanners with other zones than the home zone</li>
<li class=""><code>TrackerEntity</code> has a new property <code>in_zones</code></li>
<li class=""><code>BaseScannerEntity</code> and <code>ScannerEntity</code> have a new state attribute <code>in_zones</code></li>
<li class="">A new capability attribute <code>tracking_type</code> has been introduced</li>
<li class="">Zones are now calculated by size, then distance to center when calculating the state of <code>TrackerEntity</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="details">Details<a href="https://developers.home-assistant.io/blog/2026/06/15/device-tracker-changes#details" class="hash-link" aria-label="Direct link to Details" title="Direct link to Details" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecation-of-battery_level">Deprecation of <code>battery_level</code><a href="https://developers.home-assistant.io/blog/2026/06/15/device-tracker-changes#deprecation-of-battery_level" class="hash-link" aria-label="Direct link to deprecation-of-battery_level" title="Direct link to deprecation-of-battery_level" translate="no">​</a></h3>
<p>The <code>battery_level</code> property has been deprecated in all device tracker base classes, and will stop working in Home Assistant Core 2027.7. Integrations should communicate battery level via a battery sensor instead.</p>
<p>More details can be found in  <a href="https://github.com/home-assistant/architecture/discussions/627" target="_blank" rel="noopener noreferrer" class="">architecture proposal #627</a></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecation-of-location_name">Deprecation of <code>location_name</code><a href="https://developers.home-assistant.io/blog/2026/06/15/device-tracker-changes#deprecation-of-location_name" class="hash-link" aria-label="Direct link to deprecation-of-location_name" title="Direct link to deprecation-of-location_name" translate="no">​</a></h3>
<p>The <code>location_name</code> property of <code>TrackerEntity</code> has been deprecated, and will stop working in Home Assistant Core 2027.7.</p>
<p>Integrations with device trackers which do not know or do not want to report the exact coordinates and today use <code>location_name</code> to report the name of a zone should instead report a list of zone entity IDs through the <code>in_zones</code> property.
Device trackers which use <code>location_name</code> to give extra context can instead do that via a separate sensor or an extra state attribute.</p>
<p>More details can be found in  <a href="https://github.com/home-assistant/architecture/discussions/1387" target="_blank" rel="noopener noreferrer" class="">architecture proposal #1387</a></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction-of-the-basescannerentity-base-class">Introduction of the <code>BaseScannerEntity</code> base class<a href="https://developers.home-assistant.io/blog/2026/06/15/device-tracker-changes#introduction-of-the-basescannerentity-base-class" class="hash-link" aria-label="Direct link to introduction-of-the-basescannerentity-base-class" title="Direct link to introduction-of-the-basescannerentity-base-class" translate="no">​</a></h3>
<p>The <a class="" href="https://developers.home-assistant.io/docs/core/entity/device-tracker#basescannerentity"><code>BaseScannerEntity</code></a> class should be used by integrations which have scanners which do not track connection to a WLAN or other local network, for example scanners which track connection to a BLE beacon.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="users-can-associate-basescannerentity-and-scannerentity-with-any-zone">Users can associate <code>BaseScannerEntity</code> and <code>ScannerEntity</code> with any zone<a href="https://developers.home-assistant.io/blog/2026/06/15/device-tracker-changes#users-can-associate-basescannerentity-and-scannerentity-with-any-zone" class="hash-link" aria-label="Direct link to users-can-associate-basescannerentity-and-scannerentity-with-any-zone" title="Direct link to users-can-associate-basescannerentity-and-scannerentity-with-any-zone" translate="no">​</a></h3>
<p><code>BaseScannerEntity</code> and <code>ScannerEntity</code> store the associated zone as an entity registry option. The base class will set the state of the entity to the name of the associated zone when connected, and the <code>in_zones</code> state attribute to all zones which contain the associated zone.</p>
<p>More details can be found in  <a href="https://github.com/home-assistant/architecture/discussions/1389" target="_blank" rel="noopener noreferrer" class="">architecture proposal #1389</a></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction-of-the-in_zones-state-attribute">Introduction of the <code>in_zones</code> state attribute<a href="https://developers.home-assistant.io/blog/2026/06/15/device-tracker-changes#introduction-of-the-in_zones-state-attribute" class="hash-link" aria-label="Direct link to introduction-of-the-in_zones-state-attribute" title="Direct link to introduction-of-the-in_zones-state-attribute" translate="no">​</a></h3>
<p>A new state attribute <code>in_zones</code> is present in the state of device tracker entities. The state attribute is automatically calculated by <code>BaseScannerEntity</code> and <code>ScannerEntity</code>. <code>TrackerEntity</code> will derive the <code>in_zones</code> state attribute from the <a href="https://developers.home-assistant.io/docs/core/entity/device-tracker#properties-2" target="_blank" rel="noopener noreferrer" class=""><code>in_zones</code> property</a> if not <code>None</code>, if it is <code>None</code> it will be calculated from the reported location.</p>
<p>The <code>in_zones</code> state attribute is a list of zone entity IDs sorted by size, with the smallest zone first, then by distance to center.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction-of-the-tracking_type-capability-attribute">Introduction of the <code>tracking_type</code> capability attribute<a href="https://developers.home-assistant.io/blog/2026/06/15/device-tracker-changes#introduction-of-the-tracking_type-capability-attribute" class="hash-link" aria-label="Direct link to introduction-of-the-tracking_type-capability-attribute" title="Direct link to introduction-of-the-tracking_type-capability-attribute" translate="no">​</a></h3>
<p>A new capability attribute <code>tracking_type</code> is present in the state of device tracker entities. The state attribute is set to <code>connection</code> by <code>BaseScannerEntity</code> and <code>ScannerEntity</code> and to <code>location</code> by <code>TrackerEntity</code>. Integrations should not override this behavior.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Custom card suggestions in the card picker]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/27/custom-card-suggestions</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/27/custom-card-suggestions</guid>
            <pubDate>Wed, 27 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[As of Home Assistant 2026.6, custom cards can show up as suggestions in the card picker. When a user selects an entity, custom cards that opt in are listed under a Community section, below the built-in suggestions.]]></description>
            <content:encoded><![CDATA[<p>As of Home Assistant 2026.6, custom cards can show up as suggestions in the card picker. When a user selects an entity, custom cards that opt in are listed under a <strong>Community</strong> section, below the built-in suggestions.</p>
<p>To opt in, add a <code>getEntitySuggestion</code> function to your <code>window.customCards</code> entry. It receives the <code>hass</code> object and the selected entity id, and returns a suggestion (or <code>null</code> if the entity is not supported):</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">customCards</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-card"</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 Card"</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)">getEntitySuggestion</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 parameter">hass</span><span class="token parameter punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token parameter"> entityId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:rgb(137, 221, 255)">=&gt;</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 control-flow" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">entityId</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)">split</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"."</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)">0</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 string" style="color:rgb(195, 232, 141)">"light"</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 control-flow" style="font-style:italic">return</span><span class="token plain"> </span><span class="token keyword null nil" style="font-style:italic">null</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 control-flow" 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 plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">      </span><span class="token literal-property property">config</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><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)">"custom:my-card"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token literal-property property">entity</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> entityId </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 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><br></div></code></pre></div></div>
<p>You can also return an array of suggestions to offer several variants, each with its own <code>label</code>.</p>
<p>Only suggest your card when it makes sense for the entity. Check the domain, device class, or supported features with the <code>hass</code> object, and return <code>null</code> otherwise. Suggesting your card for every entity makes the picker noisy.</p>
<p>See the <a class="" href="https://developers.home-assistant.io/docs/frontend/custom-ui/custom-card#suggesting-your-card-for-an-entity">custom card documentation</a> for the full reference.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Frontend component updates in 2026.6]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/27/frontend-component-updates-2026.6</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/27/frontend-component-updates-2026.6</guid>
            <pubDate>Wed, 27 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/27/frontend-component-updates-2026.6#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-radio-updates">ha-radio updates<a href="https://developers.home-assistant.io/blog/2026/05/27/frontend-component-updates-2026.6#ha-radio-updates" class="hash-link" aria-label="Direct link to ha-radio updates" title="Direct link to ha-radio updates" translate="no">​</a></h3>
<p><code>ha-radio</code> was removed from our codebase, we use the webawesome based <code>ha-radio-group</code> with <code>ha-radio-option</code> now. No need for a <code>ha-formfield</code> around a <code>ha-radio</code> anymore and you can use the new CSS properties to customize the radio group and options.</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-radio-group-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-radio-group-required-marker-offset</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 variable" style="color:rgb(191, 199, 213)">--ha-radio-option-active-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-radio-option-heigh</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-radio-option-toggle-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-radio-option-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-radio-option-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-radio-option-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-radio-option-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-radio-option-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-radio-option-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-radio-option-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-radio-option-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-radio-option-control-margin</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ha-drawer-updates">ha-drawer updates<a href="https://developers.home-assistant.io/blog/2026/05/27/frontend-component-updates-2026.6#ha-drawer-updates" class="hash-link" aria-label="Direct link to ha-drawer updates" title="Direct link to ha-drawer updates" translate="no">​</a></h3>
<p><code>ha-drawer</code> was updated to use the webawesome drawer component. The API is mostly the same it just uses now <code>--ha-sidebar-width</code> instead of <code>--mdc-drawer-width</code></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="top-bar">top bar<a href="https://developers.home-assistant.io/blog/2026/05/27/frontend-component-updates-2026.6#top-bar" class="hash-link" aria-label="Direct link to top bar" title="Direct link to top bar" translate="no">​</a></h3>
<ul>
<li class=""><code>ha-top-app-bar</code> was removed entirely.</li>
<li class=""><code>ha-top-app-bar-fixed</code> was migrated from MWC to plain Lit.</li>
<li class=""><code>ha-two-pane-top-app-bar-fixed</code> was rewritten to extend the new implementation instead of Material base code.</li>
<li class=""><code>ha-header-bar</code> was rewritten from a Material top-app-bar styled wrapper to a native Lit component.</li>
</ul>
<p>The <code>--ha-top-app-bar-width</code> token replaces <code>--mdc-top-app-bar-width</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-decorators">New decorators<a href="https://developers.home-assistant.io/blog/2026/05/27/frontend-component-updates-2026.6#new-decorators" class="hash-link" aria-label="Direct link to New decorators" title="Direct link to New decorators" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="consumelocalize">@consumeLocalize<a href="https://developers.home-assistant.io/blog/2026/05/27/frontend-component-updates-2026.6#consumelocalize" class="hash-link" aria-label="Direct link to @consumeLocalize" title="Direct link to @consumeLocalize" translate="no">​</a></h3>
<p>Following up on the <a class="" href="https://developers.home-assistant.io/blog/2026/05/04/frontend-context-groups-decorators">context entry decorators</a> introduced last release, we added a shortcut for the most common single-field read off <code>internationalizationContext</code>: the <code>localize</code> function.</p>
<p>Before:</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"> internationalizationContext</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 operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">HomeAssistantInternationalization</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> LocalizeFunc</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</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 punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> localize </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)">=&gt;</span><span class="token plain"> localize</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"> _localize</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"> LocalizeFunc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>After:</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)">consumeLocalize</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"> _localize</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"> LocalizeFunc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Use <code>@consumeLocalize()</code> whenever a component only needs the <code>localize</code> function. For other single-field reads off <code>internationalizationContext</code> (e.g. <code>locale</code>, <code>language</code>), keep using <code>@consume</code> + <code>@transform</code>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deprecation of advanced mode in data entry flow]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/26/advanced-mode-config-flow-deprecation</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/26/advanced-mode-config-flow-deprecation</guid>
            <pubDate>Tue, 26 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/26/advanced-mode-config-flow-deprecation#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>User profile <a href="https://github.com/OpenHomeFoundation/roadmap/issues/54" target="_blank" rel="noopener noreferrer" class="">advanced mode is going away</a>, which means integrations can no longer check if advanced mode is enabled or not in data entry flows.</p>
<p>Integrations authors need to update integrations to use an alternative user friendly way to present additional options in the UI, for example group additional options in a section.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="flowhandlershow_advanced_options"><code>FlowHandler.show_advanced_options</code><a href="https://developers.home-assistant.io/blog/2026/05/26/advanced-mode-config-flow-deprecation#flowhandlershow_advanced_options" class="hash-link" aria-label="Direct link to flowhandlershow_advanced_options" title="Direct link to flowhandlershow_advanced_options" translate="no">​</a></h3>
<p>The <code>FlowHandler.show_advanced_options</code> property has been deprecated and will be removed with the release of Home Assistant Core 2027.6. During the deprecation period, <code>FlowHandler.show_advanced_options</code> unconditionally returns <code>True</code> to not make options gated by this flag inaccessible to users.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="flowhandlercontextshow_advanced_options"><code>FlowHandler.context['show_advanced_options']</code><a href="https://developers.home-assistant.io/blog/2026/05/26/advanced-mode-config-flow-deprecation#flowhandlercontextshow_advanced_options" class="hash-link" aria-label="Direct link to flowhandlercontextshow_advanced_options" title="Direct link to flowhandlercontextshow_advanced_options" translate="no">​</a></h3>
<p>There is no longer a <code>show_advanced_options</code> key in <code>FlowHandler.context</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://developers.home-assistant.io/blog/2026/05/26/advanced-mode-config-flow-deprecation#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></h2>
<p>The Advanced mode toggle in the user profile is a single binary switch that gates a collection of unrelated features across Home Assistant, from app (add-on) visibility (Terminal &amp; SSH) to configuration options and UI elements, and we've been working on removing it during the past year.</p>
<p>For a more in-depth explanation, see <a href="https://github.com/OpenHomeFoundation/roadmap/issues/54" target="_blank" rel="noopener noreferrer" class="">roadmap issue #54</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[BrowseMediaSource: domain is now required]]></title>
            <link>https://developers.home-assistant.io/blog/2026/05/20/browse-media-source-root-class</link>
            <guid>https://developers.home-assistant.io/blog/2026/05/20/browse-media-source-root-class</guid>
            <pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The BrowseMediaSource class in the media_source integration has been tightened up. The domain parameter is now a required str instead of str | None, and the special "list every media source" root node has moved to its own class, RootBrowseMediaSource.]]></description>
            <content:encoded><![CDATA[<p>The <code>BrowseMediaSource</code> class in the <code>media_source</code> integration has been tightened up. The <code>domain</code> parameter is now a required <code>str</code> instead of <code>str | None</code>, and the special "list every media source" root node has moved to its own class, <code>RootBrowseMediaSource</code>.</p>
<p>Previously, <code>domain</code> was optional only to represent one edge case: the top-level node returned when browsing <code>media-source://</code> with no specific source selected. That made the type hint misleading for the 99% case — every actual media source has a domain — and added a <code>None</code> branch that consumers had to think about. Splitting the root into its own class removes that branch.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-changed">What changed<a href="https://developers.home-assistant.io/blog/2026/05/20/browse-media-source-root-class#what-changed" class="hash-link" aria-label="Direct link to What changed" title="Direct link to What changed" translate="no">​</a></h2>
<ul>
<li class=""><code>BrowseMediaSource.__init__</code> now requires <code>domain: str</code>.</li>
<li class="">A new <code>RootBrowseMediaSource</code> class represents the root browse node listing all available media sources. It hardcodes <code>domain=None</code> and <code>identifier=None</code> and uses <code>media-source://</code> as its content ID.</li>
<li class=""><code>media_source.async_browse_media()</code> and <code>MediaSourceItem.async_browse()</code> now return <code>BrowseMediaSource | RootBrowseMediaSource</code>.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="impact-on-custom-integrations">Impact on custom integrations<a href="https://developers.home-assistant.io/blog/2026/05/20/browse-media-source-root-class#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>
<p>Most integrations don't need any changes. If you implement a <code>media_source.py</code> platform, you were already passing your own <code>domain</code> to <code>BrowseMediaSource</code> — that keeps working.</p>
<p>You only need to act if:</p>
<ul>
<li class="">
<p><strong>You pass <code>domain=None</code> to <code>BrowseMediaSource</code>.</strong> This is no longer allowed. Set your integration domain instead.</p>
</li>
<li class="">
<p><strong>You call <code>media_source.async_browse_media()</code> and annotate the result.</strong> Update the type hint to <code>BrowseMediaSource | RootBrowseMediaSource</code>, or narrow with <code>isinstance()</code> before using domain-specific attributes:</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">media_source </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">    BrowseMediaSource</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_browse_media</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">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"> async_browse_media</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"> media_content_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"></span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">isinstance</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">result</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> BrowseMediaSource</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 comment" style="color:rgb(105, 112, 152);font-style:italic"># result.domain is guaranteed to be a str here</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>
</li>
</ul>
<p>See the updated <a class="" href="https://developers.home-assistant.io/docs/core/platform/media_source">media source platform documentation</a> for the full reference.</p>]]></content:encoded>
        </item>
        <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>
    </channel>
</rss>