1818)
1919from homeassistant .helpers import device_registry as dr
2020from homeassistant .helpers .aiohttp_client import async_get_clientsession
21- from homeassistant .helpers .device_registry import DeviceInfo
21+ from homeassistant .helpers .device_registry import CONNECTION_NETWORK_MAC , DeviceInfo
2222from homeassistant .helpers .typing import ConfigType
2323from homeassistant .helpers .update_coordinator import CoordinatorEntity
2424
2525from custom_components .bhyve .pybhyve .typings import BHyveDevice
2626
2727from .const import (
2828 CONF_DEVICES ,
29+ DEVICE_BRIDGE ,
2930 DOMAIN ,
3031 EVENT_PROGRAM_CHANGED ,
3132 LOGGER ,
@@ -103,6 +104,17 @@ async def async_update_callback(data: dict) -> None:
103104 programs = await client .timer_programs
104105 devices = filter_configured_devices (entry , all_devices )
105106
107+ # Build a mapping from device_gateway_topic to bridge device ID
108+ # so child devices can reference their bridge via via_device.
109+ # Bridges are always included by filter_configured_devices.
110+ gateway_to_bridge : dict [str , str ] = {}
111+ for device in devices :
112+ if device .get ("type" ) == DEVICE_BRIDGE :
113+ gateway_topic = device .get ("device_gateway_topic" )
114+ if gateway_topic :
115+ gateway_to_bridge [gateway_topic ] = device .get ("id" , "" )
116+ coordinator .gateway_to_bridge = gateway_to_bridge
117+
106118 hass .data .setdefault (DOMAIN , {})[entry .entry_id ] = {
107119 "client" : client ,
108120 "coordinator" : coordinator ,
@@ -146,9 +158,12 @@ async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
146158 # Get currently configured device IDs
147159 configured_ids = set (entry .options .get (CONF_DEVICES , []))
148160
149- # Find devices that were removed from configuration
150- all_device_ids = {str (d ["id" ]) for d in all_devices }
151- removed_device_ids = all_device_ids - configured_ids
161+ # Find leaf devices that were removed from configuration
162+ # (bridges are always included and not user-selectable)
163+ leaf_device_ids = {
164+ str (d ["id" ]) for d in all_devices if d .get ("type" ) != DEVICE_BRIDGE
165+ }
166+ removed_device_ids = leaf_device_ids - configured_ids
152167
153168 if removed_device_ids :
154169 # Remove devices from Home Assistant
@@ -183,8 +198,16 @@ def __init__(
183198 self ._mac_address = device .get ("mac_address" )
184199
185200 # Device info for grouping
186- self ._attr_device_info = DeviceInfo (
201+ connections : set [tuple [str , str ]] = set ()
202+ if self ._mac_address :
203+ # Format raw MAC (e.g. "4467552a366e") with colons
204+ raw = self ._mac_address .replace (":" , "" ).replace ("-" , "" ).lower ()
205+ formatted_mac = ":" .join (raw [i : i + 2 ] for i in range (0 , len (raw ), 2 ))
206+ connections .add ((CONNECTION_NETWORK_MAC , formatted_mac ))
207+
208+ device_info = DeviceInfo (
187209 identifiers = {(DOMAIN , self ._device_id )},
210+ connections = connections ,
188211 manufacturer = MANUFACTURER ,
189212 configuration_url = f"https://techsupport.orbitbhyve.com/dashboard/support/device/{ self ._device_id } " ,
190213 name = self ._device_name ,
@@ -193,6 +216,16 @@ def __init__(
193216 sw_version = device .get ("firmware_version" ),
194217 )
195218
219+ # Link non-bridge devices to their bridge via device_gateway_topic
220+ if self ._device_type != DEVICE_BRIDGE :
221+ gateway_topic = device .get ("device_gateway_topic" )
222+ gateway_to_bridge = getattr (coordinator , "gateway_to_bridge" , {})
223+ bridge_id = gateway_to_bridge .get (gateway_topic ) if gateway_topic else None
224+ if bridge_id :
225+ device_info ["via_device" ] = (DOMAIN , bridge_id )
226+
227+ self ._attr_device_info = device_info
228+
196229 LOGGER .debug (
197230 "Creating %s: %s - %s" ,
198231 self .__class__ .__name__ ,
0 commit comments