<?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, 04 Sep 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[New device and state class selectors]]></title>
            <link>https://developers.home-assistant.io/blog/2026/09/04/device-and-state-class-selectors</link>
            <guid>https://developers.home-assistant.io/blog/2026/09/04/device-and-state-class-selectors</guid>
            <pubDate>Fri, 04 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[New selectors are available to choose a device class or sensor state class.]]></description>
            <content:encoded><![CDATA[<p>New <a href="https://www.home-assistant.io/docs/blueprint/selectors/" target="_blank" rel="noopener noreferrer" class="">selectors</a> are available to choose a device class or sensor state class.</p>
<p>These selectors can be used in config flows and blueprints when requesting a device or state class from the user.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="device-class-selector">Device class selector<a href="https://developers.home-assistant.io/blog/2026/09/04/device-and-state-class-selectors#device-class-selector" class="hash-link" aria-label="Direct link to Device class selector" title="Direct link to Device class selector" translate="no">​</a></h2>
<p>The new <code>DeviceClassSelector</code> is available for selecting device classes in config flows and blueprints. It supports device classes for the following platforms:</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">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">BINARY_SENSOR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> BinarySensorDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">BUTTON</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ButtonDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">COVER</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> CoverDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">EVENT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> EventDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">HUMIDIFIER</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> HumidifierDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">INFRARED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> InfraredDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">MEDIA_PLAYER</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> MediaPlayerDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">NUMBER</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> NumberDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">SENSOR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> SensorDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">SWITCH</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> SwitchDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">UPDATE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> UpdateDeviceClass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">VALVE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ValveDeviceClass</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="device-class-selector-examples">Device class selector examples<a href="https://developers.home-assistant.io/blog/2026/09/04/device-and-state-class-selectors#device-class-selector-examples" class="hash-link" aria-label="Direct link to Device class selector examples" title="Direct link to Device class selector examples" translate="no">​</a></h3>
<p>Example of a device class selector that returns a single device class:</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">vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Schema</span><span class="token punctuation" style="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">        vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Optional</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">CONF_DEVICE_CLASS</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"> DeviceClassSelector</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            DeviceClassSelectorConfig</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">domain</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">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">        </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>Example of a device class selector that returns multiple device classes as a list:</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">vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Schema</span><span class="token punctuation" style="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">        vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Optional</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">CONF_DEVICE_CLASS</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"> DeviceClassSelector</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            DeviceClassSelectorConfig</span><span class="token punctuation" style="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">Platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">BINARY_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">                multiple</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><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"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="sensor-state-class-selector">Sensor state class selector<a href="https://developers.home-assistant.io/blog/2026/09/04/device-and-state-class-selectors#sensor-state-class-selector" class="hash-link" aria-label="Direct link to Sensor state class selector" title="Direct link to Sensor state class selector" translate="no">​</a></h2>
<p>The new <code>StateClassSelector</code> is available for selecting sensor state classes in config flows and blueprints.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="sensor-state-class-selector-examples">Sensor state class selector examples<a href="https://developers.home-assistant.io/blog/2026/09/04/device-and-state-class-selectors#sensor-state-class-selector-examples" class="hash-link" aria-label="Direct link to Sensor state class selector examples" title="Direct link to Sensor state class selector examples" translate="no">​</a></h3>
<p>Example of a sensor state class selector that returns a single state class:</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">vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Schema</span><span class="token punctuation" style="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">        vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Optional</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">CONF_STATE_CLASS</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"> StateClassSelector</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><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>Example of a sensor state class selector that returns a single state class with only a filtered subset of available state classes:</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">vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Schema</span><span class="token punctuation" style="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">        vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Optional</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">CONF_STATE_CLASS</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"> StateClassSelector</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            StateClassSelectorConfig</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                state_classes</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">                    SensorStateClass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">MEASUREMENT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                    SensorStateClass</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">TOTAL_INCREASING</span><span class="token punctuation" style="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">        </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>Example of a state class selector that returns multiple state classes as a list:</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">vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Schema</span><span class="token punctuation" style="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">        vol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Optional</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">CONF_STATE_CLASS</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"> StateClassSelector</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            StateClassSelectorConfig</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">multiple</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 punctuation" style="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"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="migrating-existing-device-and-state-class-selectors">Migrating existing device and state class selectors<a href="https://developers.home-assistant.io/blog/2026/09/04/device-and-state-class-selectors#migrating-existing-device-and-state-class-selectors" class="hash-link" aria-label="Direct link to Migrating existing device and state class selectors" title="Direct link to Migrating existing device and state class selectors" translate="no">​</a></h2>
<p>Unlike using a generic <code>SelectSelector</code>, the <code>DeviceClassSelector</code> allows the frontend to automatically translate device classes into user-friendly names.</p>
<p>Existing implementations that select a device or state class using <code>SelectSelector</code> should be migrated to use <code>DeviceClassSelector</code> or <code>StateClassSelector</code>. After migration, any stale translations related to the old selector values should be removed.</p>
<p>The <a href="https://www.home-assistant.io/docs/blueprint/selectors/" target="_blank" rel="noopener noreferrer" class="">Selectors</a> documentation has been updated to include the new selectors.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deprecating modbus.get_hub in favor of async_get_unit]]></title>
            <link>https://developers.home-assistant.io/blog/2026/09/02/modbus-get-hub-deprecation</link>
            <guid>https://developers.home-assistant.io/blog/2026/09/02/modbus-get-hub-deprecation</guid>
            <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[As of Home Assistant Core 2026.10, modbus.get_hub is deprecated. It will be removed in Home Assistant Core 2027.10. Custom integrations that call it get a warning in the log until then, and stop working after that.]]></description>
            <content:encoded><![CDATA[<p>As of Home Assistant Core 2026.10, <code>modbus.get_hub</code> is deprecated. It will be removed in Home Assistant Core 2027.10. Custom integrations that call it get a warning in the log until then, and stop working after that.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://developers.home-assistant.io/blog/2026/09/02/modbus-get-hub-deprecation#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></h2>
<p><code>get_hub</code> attaches an integration to a Modbus hub the user configured in YAML, under a name the integration has to be told. The user has to set up the hub by hand before the integration can work, and two integrations that need the same bus cannot share it.</p>
<p>In July we announced our plan to <a class="" href="https://developers.home-assistant.io/blog/2026/07/05/modernizing-modbus">modernize Modbus in Home Assistant</a>. Home Assistant Core 2026.9 delivered the first piece: <code>async_get_unit</code>. An integration collects the connection details in its own config flow, the same as any other integration, and asks the Modbus integration for a unit on them. Integrations that ask with equal details share one connection. Nothing is configured in YAML and nothing extra is persisted.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-to-do">What to do<a href="https://developers.home-assistant.io/blog/2026/09/02/modbus-get-hub-deprecation#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>Replace the call to <code>get_hub</code> with a call to <code>async_get_unit</code>:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">from</span><span class="token plain"> 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">modbus </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> async_get_unit</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"> modbus_connection </span><span class="token keyword" style="font-style:italic">import</span><span class="token plain"> ModbusTcpParams</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">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_entry</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"> entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> MyConfigEntry</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)">"""Set up my device from a config entry."""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    unit </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> async_get_unit</span><span class="token punctuation" style="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">        entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        ModbusTcpParams</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">host</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">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">CONF_HOST</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"> port</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">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">CONF_PORT</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">        entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">CONF_UNIT_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">    </span><span class="token punctuation" style="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"> MyDevice</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">unit</span><span class="token punctuation" style="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 not a one-to-one swap. Your config flow has to collect the connection details required by the transport, for example host and port, besides unit ID, that the user used to write in the YAML hub, and the device-specific communication should move into a library built on <a href="https://home-assistant-libs.github.io/modbus-connection/" target="_blank" rel="noopener noreferrer" class=""><code>modbus-connection</code></a>. The <a class="" href="https://developers.home-assistant.io/docs/modbus/introduction">Modbus developer documentation</a> describes both, with example code and a reference device library.</p>
<p>More details can be found in the <a href="https://github.com/home-assistant/core/pull/179933" target="_blank" rel="noopener noreferrer" class="">core PR</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Configurator integration is now deprecated]]></title>
            <link>https://developers.home-assistant.io/blog/2026/08/31/deprecate-configurator</link>
            <guid>https://developers.home-assistant.io/blog/2026/08/31/deprecate-configurator</guid>
            <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The Configurator integration has been deprecated and will be removed in Home Assistant 2027.10. The integration was originally created to provide a web-based configuration interface for Home Assistant, but it is no longer recommended for use. No core integrations use the Configurator integration anymore, and it is not recommended for custom integrations either.]]></description>
            <content:encoded><![CDATA[<p>The Configurator integration has been deprecated and will be removed in Home Assistant 2027.10. The integration was originally created to provide a web-based configuration interface for Home Assistant, but it is no longer recommended for use. No core integrations use the Configurator integration anymore, and it is not recommended for custom integrations either.</p>
<p>The modern way to configure integrations in Home Assistant is via config flows and config entries. <a href="https://developers.home-assistant.io/docs/core/integration/config_flow" target="_blank" rel="noopener noreferrer" class="">Config flows</a> provide a user-friendly interface for setting up and configuring integrations, while config entries allow for easy management of integration settings.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[More device registry deprecations, new helpers and validation]]></title>
            <link>https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes</link>
            <guid>https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes</guid>
            <pubDate>Mon, 24 Aug 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/08/24/device-registry-follow-up-changes#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>This is a follow-up to <a class="" href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry">Devices are restricted to a single config entry and at most one subentry</a>, and covers additional device registry deprecations, a few new helper methods, and some stricter validation that landed after that post.</p>
<p><strong>Most custom integrations won't be affected by this set of changes.</strong> Read on if your integration sets <code>via_device</code> or <code>default_manufacturer</code> / <code>default_model</code> / <code>default_name</code> in <code>DeviceInfo</code>, looks devices up in the registry, reads the registry's <code>devices</code>, <code>deleted_devices</code> or <code>child_devices</code> containers, calls <code>async_update_device</code> directly, or attaches a device to an entity that has no config entry or unique id.</p>
<p>Unless noted otherwise, deprecated functionality logs a warning at runtime and remains supported until Home Assistant Core 2027.8. As before, deprecations which are only relevant to core and core integrations are enforced more strictly there: those callers raise immediately, while custom integrations keep getting a warning until the removal version.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="via_device-follow-ups"><code>via_device</code> follow-ups<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#via_device-follow-ups" class="hash-link" aria-label="Direct link to via_device-follow-ups" title="Direct link to via_device-follow-ups" translate="no">​</a></h2>
<p>The previous post deprecated <code>DeviceInfo["via_device"]</code> and <code>DeviceRegistry.async_get_or_create(via_device=...)</code> in favor of <code>via_device_id</code>, because identifiers are only unique per config entry and no longer point at a single device. A few related changes build on that.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="looking-up-a-via-device-id-async_get_device_id_by_identifier">Looking up a via device id: <code>async_get_device_id_by_identifier()</code><a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#looking-up-a-via-device-id-async_get_device_id_by_identifier" class="hash-link" aria-label="Direct link to looking-up-a-via-device-id-async_get_device_id_by_identifier" title="Direct link to looking-up-a-via-device-id-async_get_device_id_by_identifier" translate="no">​</a></h3>
<p>To set <code>via_device_id</code> you need the device id of the via device. The new helper <code>homeassistant.helpers.device_registry.async_get_device_id_by_identifier()</code> looks it up, scoped to the config entry that owns the via device:</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 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_get_device_id_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">    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"> identifier</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)">tuple</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 builtin" style="color:rgb(130, 170, 255)">str</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 punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> 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 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 builtin" style="color:rgb(130, 170, 255)">str</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><br></div></code></pre></div></div>
<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">via_device_id</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">dr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_get_device_id_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">    hass</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">DOMAIN</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> hub_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"> 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><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 lookup is unambiguous because identifiers are unique within a config entry. It raises <code>ValueError</code> if no matching device exists, so only call it once the via device has been created. When your integration creates the via device itself, skip the lookup and read <code>.id</code> from the <code>DeviceEntry</code> that <code>async_get_or_create</code> returned for it.</p>
<p>This helper was added in core <a href="https://github.com/home-assistant/core/pull/177494" target="_blank" rel="noopener noreferrer" class="">PR #177494</a>, which also migrated a number of integrations from <code>via_device</code> to <code>via_device_id</code> as examples.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="via_device-removed-from-the-deviceinfo-type-and-attr_via_device-deprecated"><code>via_device</code> removed from the <code>DeviceInfo</code> type, and <code>ATTR_VIA_DEVICE</code> deprecated<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#via_device-removed-from-the-deviceinfo-type-and-attr_via_device-deprecated" class="hash-link" aria-label="Direct link to via_device-removed-from-the-deviceinfo-type-and-attr_via_device-deprecated" title="Direct link to via_device-removed-from-the-deviceinfo-type-and-attr_via_device-deprecated" translate="no">​</a></h3>
<p>Two typing-level follow-ups from core <a href="https://github.com/home-assistant/core/pull/178465" target="_blank" rel="noopener noreferrer" class="">PR #178465</a>:</p>
<ul>
<li class=""><code>via_device</code> has been removed from the <code>DeviceInfo</code> <code>TypedDict</code>. A <code>DeviceInfo</code> literal that still sets <code>via_device</code> is now a typing error; use <code>via_device_id</code>.</li>
<li class="">The constant <code>homeassistant.const.ATTR_VIA_DEVICE</code> is deprecated. Importing it logs a warning; use the string <code>"via_device_id"</code> instead. It is removed in Home Assistant Core 2027.8.</li>
</ul>
<p>The same PR also escalates the enforcement of the deprecations announced in the previous post — <code>DeviceRegistry.async_get_device()</code>, passing <code>via_device</code> to <code>async_get_or_create()</code>, and the <code>add_config_entry_id</code> / <code>add_config_subentry_id</code> / <code>remove_config_entry_id</code> / <code>remove_config_subentry_id</code> parameters of <code>async_update_device()</code>. Core and core integrations now raise <code>RuntimeError</code> when calling these, while custom integrations continue to log a warning until Home Assistant Core 2027.8.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-device-cant-be-its-own-via-device">A device can't be its own via device<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#a-device-cant-be-its-own-via-device" class="hash-link" aria-label="Direct link to A device can't be its own via device" title="Direct link to A device can't be its own via device" translate="no">​</a></h3>
<p>A device may no longer set itself as its own via device (core <a href="https://github.com/home-assistant/core/pull/178194" target="_blank" rel="noopener noreferrer" class="">PR #178194</a>):</p>
<ul>
<li class="">Passing <code>via_device_id</code> equal to the device's own id to <code>async_get_or_create()</code> or <code>async_update_device()</code> raises <code>HomeAssistantError</code>.</li>
<li class="">Passing the deprecated <code>via_device</code> referencing the device itself is ignored and logged now, and will raise from Home Assistant Core 2027.8.</li>
</ul>
<p>The device registry storage is bumped to version 3.3 (introduced in Home Assistant Core 2026.8), which clears any existing <code>via_device_id</code> self-references on load. Integrations which previously worked around this by clearing the self-reference themselves can drop that code.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="async_update_device-merge_connections-and-merge_identifiers-deprecated"><code>async_update_device()</code>: <code>merge_connections</code> and <code>merge_identifiers</code> deprecated<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#async_update_device-merge_connections-and-merge_identifiers-deprecated" class="hash-link" aria-label="Direct link to async_update_device-merge_connections-and-merge_identifiers-deprecated" title="Direct link to async_update_device-merge_connections-and-merge_identifiers-deprecated" translate="no">​</a></h2>
<p>Passing <code>merge_connections</code> or <code>merge_identifiers</code> to <code>DeviceRegistry.async_update_device()</code> is deprecated in core <a href="https://github.com/home-assistant/core/pull/178888" target="_blank" rel="noopener noreferrer" class="">PR #178888</a>. These parameters only add to the device's existing connections or identifiers; compute the full desired set yourself and pass it as <code>new_connections</code> or <code>new_identifiers</code> instead.</p>
<p>Core and core integrations raise <code>RuntimeError</code> when passing the merge parameters; custom integrations log a warning until Home Assistant Core 2027.9 (note this removal is one release later than the others).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="finding-a-devices-config-entry-for-a-domain-async_get_device_and_config_entry_for_domain">Finding a device's config entry for a domain: <code>async_get_device_and_config_entry_for_domain()</code><a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#finding-a-devices-config-entry-for-a-domain-async_get_device_and_config_entry_for_domain" class="hash-link" aria-label="Direct link to finding-a-devices-config-entry-for-a-domain-async_get_device_and_config_entry_for_domain" title="Direct link to finding-a-devices-config-entry-for-a-domain-async_get_device_and_config_entry_for_domain" translate="no">​</a></h2>
<p>A common pattern was to fetch a device and loop over its <code>config_entries</code> to find the config entry belonging to a given integration. Since <code>DeviceEntry.config_entries</code> is deprecated, core <a href="https://github.com/home-assistant/core/pull/178991" target="_blank" rel="noopener noreferrer" class="">PR #178991</a> adds a helper that does this directly:</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 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_get_device_and_config_entry_for_domain</span><span class="token punctuation" style="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"> 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 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 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"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</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 builtin" style="color:rgb(130, 170, 255)">tuple</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">DeviceEntry </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"> ConfigEntry </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 punctuation" style="color:rgb(199, 146, 234)">:</span><br></div></code></pre></div></div>
<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</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> config_entry </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> dr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_get_device_and_config_entry_for_domain</span><span class="token punctuation" style="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"> device_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> domain</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">DOMAIN</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>It returns <code>(None, None)</code> for an unknown or child-device id, and <code>(device, None)</code> when a main device exists but no config entry of <code>domain</code> owns it. For a pre-migration composite id it returns a matching split device and its config entry, or the restored composite device and <code>None</code> when no split matches. The helper does not check whether the config entry is loaded, so keep your own <code>ConfigEntryState.LOADED</code> check if you need one.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-devices-deleted_devices-and-child_devices-containers-are-protected">The <code>devices</code>, <code>deleted_devices</code> and <code>child_devices</code> containers are protected<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#the-devices-deleted_devices-and-child_devices-containers-are-protected" class="hash-link" aria-label="Direct link to the-devices-deleted_devices-and-child_devices-containers-are-protected" title="Direct link to the-devices-deleted_devices-and-child_devices-containers-are-protected" translate="no">​</a></h2>
<p>The <code>DeviceRegistry.devices</code>, <code>DeviceRegistry.deleted_devices</code> and <code>DeviceRegistry.child_devices</code> attributes used to be dictionaries keyed by device id, and integrations sometimes read them directly — <code>registry.devices.get(device_id)</code>, <code>registry.devices.values()</code>, or <code>device_id in registry.devices</code>. The backing containers are now protected, and the public attributes are narrowed to what an integration legitimately needs.</p>
<p><code>devices</code> (core <a href="https://github.com/home-assistant/core/pull/179578" target="_blank" rel="noopener noreferrer" class="">PR #179578</a>) is now a read-only collection of the registered devices. Iterating it yields the <code>DeviceEntry</code> values directly, and <code>len()</code> and value membership (<code>device_entry in registry.devices</code>) work as expected. Using it as a mapping — subscription, <code>.get()</code>, <code>.values()</code>, <code>.keys()</code>, or membership by device id (<code>device_id in registry.devices</code>) — is deprecated. The mapping surface keeps working as a backwards compatibility shim: core and core integrations raise <code>RuntimeError</code>, while custom integrations only log a warning. It is removed in Home Assistant Core 2027.9.</p>
<p>In practice, iterate with <code>for device in registry.devices</code> instead of <code>registry.devices.values()</code>, and look a device up by id with <code>registry.async_get(device_id)</code> instead of <code>registry.devices.get(device_id)</code>.</p>
<p><code>child_devices</code> (core <a href="https://github.com/home-assistant/core/pull/179713" target="_blank" rel="noopener noreferrer" class="">PR #179713</a>) is now a read-only collection of the child devices. It follows the container protocol — you can iterate it (it yields the child device entries), take its <code>len()</code>, and test value membership — and offers no dictionary-style access at all: there is no <code>.get()</code> or <code>.values()</code> and no lookup by device id. There is no backwards compatibility shim.</p>
<p><code>deleted_devices</code> (core <a href="https://github.com/home-assistant/core/pull/179720" target="_blank" rel="noopener noreferrer" class="">PR #179720</a>) is an internal implementation detail of the device registry, and the whole attribute is now deprecated — there is no supported public use. Accessing it in any way is deprecated: core and core integrations raise <code>RuntimeError</code>, while custom integrations only log a warning. It is removed in Home Assistant Core 2027.9.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="testing-what-kind-of-device-an-id-refers-to">Testing what kind of device an id refers to<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#testing-what-kind-of-device-an-id-refers-to" class="hash-link" aria-label="Direct link to Testing what kind of device an id refers to" title="Direct link to Testing what kind of device an id refers to" translate="no">​</a></h3>
<p>With direct container access going away, <code>DeviceRegistry.async_get</code> gains an <code>include_composite_devices</code> parameter to test what an id refers to (core <a href="https://github.com/home-assistant/core/pull/179594" target="_blank" rel="noopener noreferrer" class="">PR #179594</a>). With <code>include_composite_devices=False</code>, a pre-migration composite device id resolves to <code>None</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">is_composite </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">    registry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">device_id</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">is</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">not</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</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">and</span><span class="token plain"> registry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">async_get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">device_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> include_composite_devices</span><span class="token operator" style="color:rgb(137, 221, 255)">=</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><span class="token keyword" style="font-style:italic">is</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</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 complements the existing <code>include_child_devices</code> and <code>include_main_devices</code> parameters, which similarly resolve — or exclude — child and main devices. <code>DeviceRegistry.async_is_composite_device_id</code>, introduced in the previous post, is now redundant and deprecated in the same PR; use <code>async_get</code> with <code>include_composite_devices=False</code> instead. It keeps working — core and core integrations raise <code>RuntimeError</code>, while custom integrations only log a warning — until Home Assistant Core 2027.9.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="attaching-a-device-to-an-entity-requires-a-config-entry-and-a-unique-id">Attaching a device to an entity requires a config entry and a unique id<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#attaching-a-device-to-an-entity-requires-a-config-entry-and-a-unique-id" class="hash-link" aria-label="Direct link to Attaching a device to an entity requires a config entry and a unique id" title="Direct link to Attaching a device to an entity requires a config entry and a unique id" translate="no">​</a></h2>
<p>An entity may only attach a device if it has a unique id and belongs to a config entry. Attempting to attach a device from an entity without a config entry, or without a unique id, is now caught in <code>entity_platform</code> (core <a href="https://github.com/home-assistant/core/pull/177459" target="_blank" rel="noopener noreferrer" class="">PR #177459</a>): the device link is dropped and a warning is logged. This is only a warning for now, and will raise from Home Assistant Core 2027.8.</p>
<p>Note that the device link is already dropped today, even though the raise only lands in 2027.8 — an affected entity ends up with no device until it is given a unique id and a config entry.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="device-info-types-are-removed">Device info types are removed<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#device-info-types-are-removed" class="hash-link" aria-label="Direct link to Device info types are removed" title="Direct link to Device info types are removed" translate="no">​</a></h2>
<p>The device registry used to classify each <code>DeviceInfo</code> as one of a fixed set of "device info types" (link, primary, secondary) based on which keys it contained. This existed to guess the primary integration for a device shared across several config entries, which is obsolete now that a device is owned by a single config entry. The classification is removed and replaced by lighter validation in core <a href="https://github.com/home-assistant/core/pull/179397" target="_blank" rel="noopener noreferrer" class="">PR #179397</a>, with the following developer-visible consequences:</p>
<ul>
<li class=""><code>DeviceInfo</code> shapes that previously didn't match any type are now accepted. The old error <em>"device info needs to either describe a device, link to existing device or provide extra information"</em> is gone; a <code>DeviceInfo</code> still needs at least one of <code>identifiers</code> or <code>connections</code>.</li>
<li class="">Passing both a field and its <code>default_</code> counterpart — for example both <code>name</code> and <code>default_name</code>, or <code>model</code> and <code>default_model</code> — now raises <code>DeviceInfoError</code>.</li>
<li class="">When a new device is created without a name, it now defaults to the config entry title for <strong>all</strong> device infos, not just those that were previously classified as primary. This can change the composed name of entities on devices that previously had no name.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="default_manufacturer-default_model-and-default_name-are-deprecated"><code>default_manufacturer</code>, <code>default_model</code> and <code>default_name</code> are deprecated<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#default_manufacturer-default_model-and-default_name-are-deprecated" class="hash-link" aria-label="Direct link to default_manufacturer-default_model-and-default_name-are-deprecated" title="Direct link to default_manufacturer-default_model-and-default_name-are-deprecated" translate="no">​</a></h2>
<p>The <code>default_manufacturer</code>, <code>default_model</code> and <code>default_name</code> members of <code>DeviceInfo</code> are deprecated in core <a href="https://github.com/home-assistant/core/pull/179549" target="_blank" rel="noopener noreferrer" class="">PR #179549</a>. Pass the plain <code>manufacturer</code>, <code>model</code> and <code>name</code> fields instead.</p>
<p>These <code>default_</code> fields let an integration that wasn't considered the primary one for a shared device suggest a name, manufacturer or model without overwriting the value set by the primary integration. A device now belongs to a single config entry, so there is no longer a primary integration to defer to, and the plain fields can be set directly.</p>
<p>The three fields have been removed from the <code>DeviceInfo</code> type, so setting them is a typing error, and passing any of them to <code>async_get_or_create</code> logs a warning. As with the other device registry deprecations, core and core integrations raise <code>RuntimeError</code>, while custom integrations keep working with a warning until Home Assistant Core 2027.9.</p>
<p>Entities which set these fields — device trackers, for example, set <code>default_name</code> — should pass the non-default variant 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 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">DeviceInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    connections</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">CONNECTION_NETWORK_MAC</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> mac</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">    default_name</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string-interpolation string" style="color:rgb(195, 232, 141)">f"Device </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">mac</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(195, 232, 141)">"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="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">DeviceInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    connections</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">CONNECTION_NETWORK_MAC</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> mac</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">    name</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string-interpolation string" style="color:rgb(195, 232, 141)">f"Device </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">mac</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(195, 232, 141)">"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="passing-created_at-or-modified_at-to-async_get_or_create-is-deprecated">Passing <code>created_at</code> or <code>modified_at</code> to <code>async_get_or_create</code> is deprecated<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#passing-created_at-or-modified_at-to-async_get_or_create-is-deprecated" class="hash-link" aria-label="Direct link to passing-created_at-or-modified_at-to-async_get_or_create-is-deprecated" title="Direct link to passing-created_at-or-modified_at-to-async_get_or_create-is-deprecated" translate="no">​</a></h2>
<p><code>created_at</code> and <code>modified_at</code> are managed by the device registry itself, and passing them to <code>DeviceRegistry.async_get_or_create</code> never had any effect — the values were ignored. Passing either is now deprecated in core <a href="https://github.com/home-assistant/core/pull/179998" target="_blank" rel="noopener noreferrer" class="">PR #179998</a>: core and core integrations raise <code>RuntimeError</code>, while custom integrations only log a warning, until Home Assistant Core 2027.9. Simply drop the arguments.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="more-examples">More examples<a href="https://developers.home-assistant.io/blog/2026/08/24/device-registry-follow-up-changes#more-examples" class="hash-link" aria-label="Direct link to More examples" title="Direct link to More examples" translate="no">​</a></h2>
<p>The changes above land alongside a large number of per-integration adaptations — migrating to <code>via_device_id</code>, using the new lookup helpers, and removing device self-references — which can serve as further examples. Search the core repository for pull requests referencing these APIs if you need a concrete migration to follow.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Device registry WebSocket API changes]]></title>
            <link>https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes</link>
            <guid>https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes</guid>
            <pubDate>Wed, 19 Aug 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/08/19/device-registry-websocket-api-changes#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h2>
<p>This post describes changes to the device registry <strong>WebSocket API</strong> — the commands and device serialization consumed by the frontend, custom cards, and other WebSocket clients. They stem from two changes to the device registry:</p>
<ul>
<li class=""><strong>Restricting each device to a single config entry</strong> (Home Assistant Core 2026.8). The Python API side of this change is described in the companion post <a class="" href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry">Devices are restricted to a single config entry and at most one subentry</a>.</li>
<li class=""><strong>Introducing <a href="https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes#child-devices-in-the-device-list" class="">child devices</a></strong> (Home Assistant Core 2026.9, <a href="https://github.com/home-assistant/architecture/discussions/1414" target="_blank" rel="noopener noreferrer" class="">architecture proposal #1414</a>).</li>
</ul>
<p>Most clients only read devices through <code>config/device_registry/list</code>, and the new device fields are additive, so no changes are required to keep working — but clients that iterate the device list should be ready to encounter child devices, which are serialized differently. Clients that remove devices, or that inspect a device's config entries, should read on.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-device-fields-config_entry_id-and-config_subentry_id">New device fields: <code>config_entry_id</code> and <code>config_subentry_id</code><a href="https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes#new-device-fields-config_entry_id-and-config_subentry_id" class="hash-link" aria-label="Direct link to new-device-fields-config_entry_id-and-config_subentry_id" title="Direct link to new-device-fields-config_entry_id-and-config_subentry_id" translate="no">​</a></h2>
<p>Every device returned by <code>config/device_registry/list</code>, and every device in an <code>EVENT_DEVICE_REGISTRY_UPDATED</code> payload, now carries two new fields:</p>
<ul>
<li class=""><code>config_entry_id</code> — the id of the single config entry the device belongs to.</li>
<li class=""><code>config_subentry_id</code> — the id of the single config subentry the device belongs to, or <code>null</code>.</li>
</ul>
<p>They replace the previous fields, which modelled a device that could span several config entries and subentries:</p>
<ul>
<li class=""><code>config_entries</code> — a list of config entry ids.</li>
<li class=""><code>config_entries_subentries</code> — a map of config entry id to a list of subentry ids.</li>
<li class=""><code>primary_config_entry</code> — the id of the device's primary config entry.</li>
</ul>
<p>The old fields are <strong>kept for backwards compatibility and are deprecated</strong>; they are scheduled for removal in Home Assistant Core 2027.8. During the deprecation period they are derived from the new values: a device reports <code>config_entries</code> as the single-element list <code>[config_entry_id]</code>, <code>config_entries_subentries</code> as <code>{config_entry_id: [config_subentry_id]}</code>, and <code>primary_config_entry</code> equal to <code>config_entry_id</code>.</p>
<p>Update your client to read <code>config_entry_id</code> and <code>config_subentry_id</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="child-devices-in-the-device-list">Child devices in the device list<a href="https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes#child-devices-in-the-device-list" class="hash-link" aria-label="Direct link to Child devices in the device list" title="Direct link to Child devices in the device list" translate="no">​</a></h2>
<p>Home Assistant Core 2026.9 introduces <strong>child devices</strong> (<a href="https://github.com/home-assistant/architecture/discussions/1414" target="_blank" rel="noopener noreferrer" class="">architecture proposal #1414</a>, core <a href="https://github.com/home-assistant/core/pull/178666" target="_blank" rel="noopener noreferrer" class="">PR #178666</a>). A child device is a lightweight logical part of a parent device: it has no hardware or firmware metadata of its own, and it references its parent through a <code>parent_device_id</code>. The parent must be registered by the same config entry and belong to the same config subentry.</p>
<p><code>config/device_registry/list</code> now returns child devices alongside regular devices, so its result is a mix of two kinds of entry. A child device is serialized with a smaller set of fields:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "id": "child1234",</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "parent_device_id": "abcd1234",</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "config_entry_id": "wxyz5678",</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "config_subentry_id": null,</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "area_id": null,</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "name": "Left channel",</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "name_by_user": null,</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "labels": [],</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "identifiers": [["demo", "left"]],</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "disabled_by": null,</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "created_at": 1723987200.0,</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "modified_at": 1723987200.0</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>Compared to a regular device, a child device has <strong>no</strong> <code>connections</code>, <code>via_device_id</code>, <code>configuration_url</code>, <code>entry_type</code>, <code>manufacturer</code>, <code>model</code>, <code>model_id</code>, <code>hw_version</code>, <code>sw_version</code>, <code>serial_number</code>, <code>primary_config_entry</code>, <code>config_entries</code>, or <code>config_entries_subentries</code>. Clients that read the device list must not assume every entry carries these fields.</p>
<p>The reliable way to tell the two apart is the <code>parent_device_id</code> field: it is present and non-null only on child devices. A regular device carries <code>via_device_id</code> instead.</p>
<p>A child device with no <code>area_id</code> of its own inherits its parent's area, so a client resolving a child device's area should fall back to the parent device when the child's <code>area_id</code> is <code>null</code>.</p>
<p>Two related commands also understand child devices:</p>
<ul>
<li class=""><code>config/device_registry/update</code> accepts a child device id — setting <code>area_id</code>, <code>disabled_by</code>, <code>labels</code>, or <code>name_by_user</code> — and returns the updated child device in the reduced serialization shown above.</li>
<li class=""><code>config/device_registry/list_linked_devices</code> always returns an empty <code>linked_devices</code> list for a child device, since a child shares its parent's per-config-entry identifier namespace and is never linked to devices of other config entries.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-command-configdevice_registryremove">New command: <code>config/device_registry/remove</code><a href="https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes#new-command-configdevice_registryremove" class="hash-link" aria-label="Direct link to new-command-configdevice_registryremove" title="Direct link to new-command-configdevice_registryremove" translate="no">​</a></h2>
<p>A new WebSocket command removes a device by id:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "type": "config/device_registry/remove",</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "device_id": "abcd1234"</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>Because a device now belongs to exactly one config entry, removing it from that config entry removes the device. The command requires admin, and it rejects a <a href="https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes#composite-devices" class="">composite device id</a> with the error <code>Cannot remove a composite device</code>.</p>
<p>It replaces <code>config/device_registry/remove_config_entry</code>, which took both a <code>device_id</code> and a <code>config_entry_id</code>:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "type": "config/device_registry/remove_config_entry",</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "config_entry_id": "wxyz5678",</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "device_id": "abcd1234"</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>That command still works but is <strong>deprecated</strong>: it logs a warning and will be removed in Home Assistant Core 2027.9. Its <code>config_entry_id</code> parameter is now only used to check that it matches the device's config entry — a mismatch fails with <code>Config entry not in device</code> — and the device is removed regardless of which config entry was passed. Update clients to call <code>config/device_registry/remove</code> and drop the <code>config_entry_id</code>.</p>
<p>Implemented in core <a href="https://github.com/home-assistant/core/pull/178319" target="_blank" rel="noopener noreferrer" class="">PR #178319</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-command-configdevice_registrylist_linked_devices">New command: <code>config/device_registry/list_linked_devices</code><a href="https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes#new-command-configdevice_registrylist_linked_devices" class="hash-link" aria-label="Direct link to new-command-configdevice_registrylist_linked_devices" title="Direct link to new-command-configdevice_registrylist_linked_devices" translate="no">​</a></h2>
<p>Because connections and identifiers are now unique per config entry, a physical device supported by several integrations is represented by one device per config entry instead of a single shared device. This command returns the other devices that share a connection or identifier with a given device — the sibling devices representing the same physical hardware under different config entries:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "type": "config/device_registry/list_linked_devices",</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "device_id": "abcd1234"</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>Result:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "linked_devices": ["ef567890", "12ab34cd"]</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>The queried device itself is excluded from the result. This lets a client, for example, link from a device page to the other devices that represent the same hardware. Implemented in core <a href="https://github.com/home-assistant/core/pull/177449" target="_blank" rel="noopener noreferrer" class="">PR #177449</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="composite-devices">New command: <code>config/device_registry/list_composite_splits</code><a href="https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes#composite-devices" class="hash-link" aria-label="Direct link to composite-devices" title="Direct link to composite-devices" translate="no">​</a></h2>
<p>When the device registry is loaded, each pre-migration device that spanned several config entries is split into one device per config entry, and the original ("composite") device id no longer refers to a registered device. Composite device ids are still referenced by automations, scripts, dashboards, and target pickers, so this command maps every composite device id to the devices it was split into:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "type": "config/device_registry/list_composite_splits"</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>Result:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  "old_composite_id": {</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    "split_ids": ["ef567890", "12ab34cd"],</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    "primary_id": "ef567890"</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  }</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>For each composite device id, <code>split_ids</code> lists the replacement device ids and <code>primary_id</code> is the split that inherited the composite's former primary config entry, or <code>null</code>. Use it to resolve a stored composite device id to a current device — for example, to keep a device picker working when the stored id is a composite id. Implemented in core <a href="https://github.com/home-assistant/core/pull/176693" target="_blank" rel="noopener noreferrer" class="">PR #176693</a>.</p>
<p>The <a class="" href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#backwards-compatibility">Backwards compatibility</a> section of the companion post describes the rest of the deprecation-period behavior, such as actions targeting a composite device id trickling down to the split devices.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="device-registry-events">Device registry events<a href="https://developers.home-assistant.io/blog/2026/08/19/device-registry-websocket-api-changes#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>Clients that subscribe to <code>device_registry_updated</code> events (<code>EVENT_DEVICE_REGISTRY_UPDATED</code>) see two changes, mirroring the Python API:</p>
<ul>
<li class="">The <code>changes</code> map 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="">A device now belongs to a single config entry, so it can no longer lose one config entry while remaining for another. A device losing its config entry is now a <code>remove</code> event rather than an <code>update</code>.</li>
</ul>
<p>See <a class="" href="https://developers.home-assistant.io/blog/2026/07/21/device-registry-single-config-entry#device-registry-events">Device registry events</a> in the companion post for details.</p>]]></content:encoded>
        </item>
        <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[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 modbus 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.]]></description>
            <content:encoded><![CDATA[<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 <code>modbus</code> integration solves this by handing out units over connections it shares. A device integration collects its own connection details in its own config flow, the same as any other integration, and asks <code>modbus</code> for a unit on them. Two integrations that ask with equal details get units over one connection, so their requests serialize behind it instead of contending for the bus.</p>
<p>The shared connection is not configured or persisted separately. It exists only while an integration holds a unit, and it closes when the last consumer's config entry unloads. That keeps the user experience where it belongs — you set up your heat pump, not a bus — while still giving the bus a single owner. The <a class="" href="https://developers.home-assistant.io/docs/modbus/introduction">Modbus developer documentation</a> covers how to ask for a unit, 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</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>
    </channel>
</rss>