diff --git a/homeassistant/components/rainbird/coordinator.py b/homeassistant/components/rainbird/coordinator.py index be8ccfa7ea7b..a4b4870b3cea 100644 --- a/homeassistant/components/rainbird/coordinator.py +++ b/homeassistant/components/rainbird/coordinator.py @@ -13,9 +13,10 @@ from pyrainbird.async_client import ( ) from pyrainbird.data import ModelAndVersion, Schedule +from homeassistant.const import CONF_MAC from homeassistant.core import HomeAssistant from homeassistant.helpers.debounce import Debouncer -from homeassistant.helpers.device_registry import DeviceInfo +from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DOMAIN, MANUFACTURER, TIMEOUT_SECONDS @@ -104,13 +105,18 @@ class RainbirdUpdateCoordinator(DataUpdateCoordinator[RainbirdDeviceState]): """Return information about the device.""" if self._unique_id is None: return None - return DeviceInfo( + device_info = DeviceInfo( name=self.device_name, identifiers={(DOMAIN, self._unique_id)}, manufacturer=MANUFACTURER, model=self._model_info.model_name, sw_version=f"{self._model_info.major}.{self._model_info.minor}", ) + # The unique id is the formatted MAC for current config entries, but was + # historically the serial number, so derive the connection from the MAC. + if mac_address := self.config_entry.data.get(CONF_MAC): + device_info["connections"] = {(CONNECTION_NETWORK_MAC, mac_address)} + return device_info async def _async_update_data(self) -> RainbirdDeviceState: """Fetch data from Rain Bird device.""" diff --git a/tests/components/rainbird/snapshots/test_init.ambr b/tests/components/rainbird/snapshots/test_init.ambr new file mode 100644 index 000000000000..594652e0c857 --- /dev/null +++ b/tests/components/rainbird/snapshots/test_init.ambr @@ -0,0 +1,36 @@ +# serializer version: 1 +# name: test_device_registry + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + tuple( + 'mac', + '4c:a1:61:00:11:22', + ), + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'rainbird', + '4c:a1:61:00:11:22', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'Rain Bird', + 'model': 'ESP-TM2', + 'model_id': None, + 'name': 'Rain Bird Controller', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '9.12', + 'via_device_id': None, + }) +# --- diff --git a/tests/components/rainbird/test_init.py b/tests/components/rainbird/test_init.py index 56f4fe32f7cd..a8df4bf188c0 100644 --- a/tests/components/rainbird/test_init.py +++ b/tests/components/rainbird/test_init.py @@ -2,12 +2,14 @@ from http import HTTPStatus from typing import Any +from unittest.mock import patch import pytest +from syrupy.assertion import SnapshotAssertion from homeassistant.components.rainbird.const import DOMAIN from homeassistant.config_entries import ConfigEntryState -from homeassistant.const import CONF_MAC +from homeassistant.const import CONF_MAC, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr, entity_registry as er @@ -42,6 +44,24 @@ async def test_init_success( assert config_entry.state is ConfigEntryState.NOT_LOADED +async def test_device_registry( + hass: HomeAssistant, + config_entry: MockConfigEntry, + device_registry: dr.DeviceRegistry, + snapshot: SnapshotAssertion, +) -> None: + """Test the controller device registry entry, including the network MAC connection.""" + # Load a platform so the controller device is registered. + with patch("homeassistant.components.rainbird.PLATFORMS", [Platform.SENSOR]): + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + device_entry = device_registry.async_get_device( + identifiers={(DOMAIN, MAC_ADDRESS_UNIQUE_ID)} + ) + assert device_entry == snapshot + + @pytest.mark.parametrize( ("config_entry_data", "responses", "config_entry_state", "config_flow_steps"), [