diff --git a/homeassistant/components/broadlink/light.py b/homeassistant/components/broadlink/light.py index c4dd48b7dc0..d42e2b76b99 100644 --- a/homeassistant/components/broadlink/light.py +++ b/homeassistant/components/broadlink/light.py @@ -44,10 +44,11 @@ async def async_setup_entry( class BroadlinkLight(BroadlinkEntity, LightEntity): """Representation of a Broadlink light.""" + _attr_has_entity_name = True + def __init__(self, device): """Initialize the light.""" super().__init__(device) - self._attr_name = f"{device.name} Light" self._attr_unique_id = device.unique_id self._attr_supported_color_modes = set() diff --git a/homeassistant/components/broadlink/remote.py b/homeassistant/components/broadlink/remote.py index da72f4fcb06..4bbb3fe1513 100644 --- a/homeassistant/components/broadlink/remote.py +++ b/homeassistant/components/broadlink/remote.py @@ -106,6 +106,8 @@ async def async_setup_entry( class BroadlinkRemote(BroadlinkEntity, RemoteEntity, RestoreEntity): """Representation of a Broadlink remote.""" + _attr_has_entity_name = True + def __init__(self, device, codes, flags): """Initialize the remote.""" super().__init__(device) @@ -116,7 +118,6 @@ class BroadlinkRemote(BroadlinkEntity, RemoteEntity, RestoreEntity): self._flags = defaultdict(int) self._lock = asyncio.Lock() - self._attr_name = f"{device.name} Remote" self._attr_is_on = True self._attr_supported_features = ( RemoteEntityFeature.LEARN_COMMAND | RemoteEntityFeature.DELETE_COMMAND diff --git a/homeassistant/components/broadlink/sensor.py b/homeassistant/components/broadlink/sensor.py index f908391893f..4d362482e64 100644 --- a/homeassistant/components/broadlink/sensor.py +++ b/homeassistant/components/broadlink/sensor.py @@ -32,7 +32,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( ), SensorEntityDescription( key="air_quality", - name="Air Quality", + name="Air quality", ), SensorEntityDescription( key="humidity", @@ -113,12 +113,13 @@ async def async_setup_entry( class BroadlinkSensor(BroadlinkEntity, SensorEntity): """Representation of a Broadlink sensor.""" + _attr_has_entity_name = True + def __init__(self, device, description: SensorEntityDescription): """Initialize the sensor.""" super().__init__(device) self.entity_description = description - self._attr_name = f"{device.name} {description.name}" self._attr_native_value = self._coordinator.data[description.key] self._attr_unique_id = f"{device.unique_id}-{description.key}" diff --git a/homeassistant/components/broadlink/switch.py b/homeassistant/components/broadlink/switch.py index 229949b7ee2..009536a9adb 100644 --- a/homeassistant/components/broadlink/switch.py +++ b/homeassistant/components/broadlink/switch.py @@ -145,7 +145,6 @@ class BroadlinkSwitch(BroadlinkEntity, SwitchEntity, RestoreEntity, ABC): super().__init__(device) self._command_on = command_on self._command_off = command_off - self._attr_name = f"{device.name} Switch" async def async_added_to_hass(self) -> None: """Call when the switch is added to hass.""" @@ -198,6 +197,8 @@ class BroadlinkRMSwitch(BroadlinkSwitch): class BroadlinkSP1Switch(BroadlinkSwitch): """Representation of a Broadlink SP1 switch.""" + _attr_has_entity_name = True + def __init__(self, device): """Initialize the switch.""" super().__init__(device, 1, 0) @@ -219,6 +220,7 @@ class BroadlinkSP2Switch(BroadlinkSP1Switch): """Representation of a Broadlink SP2 switch.""" _attr_assumed_state = False + _attr_has_entity_name = True def __init__(self, device, *args, **kwargs): """Initialize the switch.""" @@ -234,13 +236,14 @@ class BroadlinkMP1Slot(BroadlinkSwitch): """Representation of a Broadlink MP1 slot.""" _attr_assumed_state = False + _attr_has_entity_name = True def __init__(self, device, slot): """Initialize the switch.""" super().__init__(device, 1, 0) self._slot = slot self._attr_is_on = self._coordinator.data[f"s{slot}"] - self._attr_name = f"{device.name} S{slot}" + self._attr_name = f"S{slot}" self._attr_unique_id = f"{device.unique_id}-s{slot}" def _update_state(self, data): @@ -263,6 +266,7 @@ class BroadlinkBG1Slot(BroadlinkSwitch): """Representation of a Broadlink BG1 slot.""" _attr_assumed_state = False + _attr_has_entity_name = True def __init__(self, device, slot): """Initialize the switch.""" @@ -270,7 +274,7 @@ class BroadlinkBG1Slot(BroadlinkSwitch): self._slot = slot self._attr_is_on = self._coordinator.data[f"pwr{slot}"] - self._attr_name = f"{device.name} S{slot}" + self._attr_name = f"S{slot}" self._attr_device_class = SwitchDeviceClass.OUTLET self._attr_unique_id = f"{device.unique_id}-s{slot}" diff --git a/tests/components/broadlink/__init__.py b/tests/components/broadlink/__init__.py index ce7e79bdff6..8cdb4f478a3 100644 --- a/tests/components/broadlink/__init__.py +++ b/tests/components/broadlink/__init__.py @@ -78,6 +78,16 @@ BROADLINK_DEVICES = { 57, 5, ), + "Gaming room": ( + "192.168.0.65", + "34ea34b61d2d", + "MP1-1K4S", + "Broadlink", + "MP1", + 0x4EB5, + 57, + 5, + ), } diff --git a/tests/components/broadlink/test_device.py b/tests/components/broadlink/test_device.py index 5430af9e311..c50494a9b84 100644 --- a/tests/components/broadlink/test_device.py +++ b/tests/components/broadlink/test_device.py @@ -6,6 +6,7 @@ import broadlink.exceptions as blke from homeassistant.components.broadlink.const import DOMAIN from homeassistant.components.broadlink.device import get_domains from homeassistant.config_entries import ConfigEntryState +from homeassistant.const import ATTR_FRIENDLY_NAME from homeassistant.helpers.entity_registry import async_entries_for_device from . import get_device @@ -266,7 +267,11 @@ async def test_device_setup_registry(hass): assert device_entry.sw_version == device.fwversion for entry in async_entries_for_device(entity_registry, device_entry.id): - assert entry.original_name.startswith(device.name) + assert ( + hass.states.get(entry.entity_id) + .attributes[ATTR_FRIENDLY_NAME] + .startswith(device.name) + ) async def test_device_unload_works(hass): @@ -345,4 +350,8 @@ async def test_device_update_listener(hass): ) assert device_entry.name == "New Name" for entry in async_entries_for_device(entity_registry, device_entry.id): - assert entry.original_name.startswith("New Name") + assert ( + hass.states.get(entry.entity_id) + .attributes[ATTR_FRIENDLY_NAME] + .startswith("New Name") + ) diff --git a/tests/components/broadlink/test_remote.py b/tests/components/broadlink/test_remote.py index a3b291efd00..d4fd9cd75b4 100644 --- a/tests/components/broadlink/test_remote.py +++ b/tests/components/broadlink/test_remote.py @@ -9,7 +9,7 @@ from homeassistant.components.remote import ( SERVICE_TURN_OFF, SERVICE_TURN_ON, ) -from homeassistant.const import STATE_OFF, STATE_ON, Platform +from homeassistant.const import ATTR_FRIENDLY_NAME, STATE_OFF, STATE_ON, Platform from homeassistant.helpers.entity_registry import async_entries_for_device from . import get_device @@ -39,7 +39,10 @@ async def test_remote_setup_works(hass): assert len(remotes) == 1 remote = remotes[0] - assert remote.original_name == f"{device.name} Remote" + assert ( + hass.states.get(remote.entity_id).attributes[ATTR_FRIENDLY_NAME] + == device.name + ) assert hass.states.get(remote.entity_id).state == STATE_ON assert mock_setup.api.auth.call_count == 1 diff --git a/tests/components/broadlink/test_sensors.py b/tests/components/broadlink/test_sensors.py index b5a49fdae15..13190883ef0 100644 --- a/tests/components/broadlink/test_sensors.py +++ b/tests/components/broadlink/test_sensors.py @@ -3,7 +3,7 @@ from datetime import timedelta from homeassistant.components.broadlink.const import DOMAIN from homeassistant.components.broadlink.updater import BroadlinkSP4UpdateManager -from homeassistant.const import Platform +from homeassistant.const import ATTR_FRIENDLY_NAME, Platform from homeassistant.helpers.entity_component import async_update_entity from homeassistant.helpers.entity_registry import async_entries_for_device from homeassistant.util import dt @@ -39,13 +39,16 @@ async def test_a1_sensor_setup(hass): assert len(sensors) == 5 sensors_and_states = { - (sensor.original_name, hass.states.get(sensor.entity_id).state) + ( + hass.states.get(sensor.entity_id).attributes[ATTR_FRIENDLY_NAME], + hass.states.get(sensor.entity_id).state, + ) for sensor in sensors } assert sensors_and_states == { (f"{device.name} Temperature", "27.4"), (f"{device.name} Humidity", "59.3"), - (f"{device.name} Air Quality", "3"), + (f"{device.name} Air quality", "3"), (f"{device.name} Light", "2"), (f"{device.name} Noise", "1"), } @@ -86,13 +89,16 @@ async def test_a1_sensor_update(hass): assert mock_setup.api.check_sensors_raw.call_count == 2 sensors_and_states = { - (sensor.original_name, hass.states.get(sensor.entity_id).state) + ( + hass.states.get(sensor.entity_id).attributes[ATTR_FRIENDLY_NAME], + hass.states.get(sensor.entity_id).state, + ) for sensor in sensors } assert sensors_and_states == { (f"{device.name} Temperature", "22.5"), (f"{device.name} Humidity", "47.4"), - (f"{device.name} Air Quality", "2"), + (f"{device.name} Air quality", "2"), (f"{device.name} Light", "3"), (f"{device.name} Noise", "2"), } @@ -118,7 +124,10 @@ async def test_rm_pro_sensor_setup(hass): assert len(sensors) == 1 sensors_and_states = { - (sensor.original_name, hass.states.get(sensor.entity_id).state) + ( + hass.states.get(sensor.entity_id).attributes[ATTR_FRIENDLY_NAME], + hass.states.get(sensor.entity_id).state, + ) for sensor in sensors } assert sensors_and_states == {(f"{device.name} Temperature", "18.2")} @@ -147,7 +156,10 @@ async def test_rm_pro_sensor_update(hass): assert mock_setup.api.check_sensors.call_count == 2 sensors_and_states = { - (sensor.original_name, hass.states.get(sensor.entity_id).state) + ( + hass.states.get(sensor.entity_id).attributes[ATTR_FRIENDLY_NAME], + hass.states.get(sensor.entity_id).state, + ) for sensor in sensors } assert sensors_and_states == {(f"{device.name} Temperature", "25.8")} @@ -179,7 +191,10 @@ async def test_rm_pro_filter_crazy_temperature(hass): assert mock_setup.api.check_sensors.call_count == 2 sensors_and_states = { - (sensor.original_name, hass.states.get(sensor.entity_id).state) + ( + hass.states.get(sensor.entity_id).attributes[ATTR_FRIENDLY_NAME], + hass.states.get(sensor.entity_id).state, + ) for sensor in sensors } assert sensors_and_states == {(f"{device.name} Temperature", "22.9")} @@ -225,7 +240,10 @@ async def test_rm4_pro_hts2_sensor_setup(hass): assert len(sensors) == 2 sensors_and_states = { - (sensor.original_name, hass.states.get(sensor.entity_id).state) + ( + hass.states.get(sensor.entity_id).attributes[ATTR_FRIENDLY_NAME], + hass.states.get(sensor.entity_id).state, + ) for sensor in sensors } assert sensors_and_states == { @@ -257,7 +275,10 @@ async def test_rm4_pro_hts2_sensor_update(hass): assert mock_setup.api.check_sensors.call_count == 2 sensors_and_states = { - (sensor.original_name, hass.states.get(sensor.entity_id).state) + ( + hass.states.get(sensor.entity_id).attributes[ATTR_FRIENDLY_NAME], + hass.states.get(sensor.entity_id).state, + ) for sensor in sensors } assert sensors_and_states == { @@ -316,7 +337,10 @@ async def test_scb1e_sensor_setup(hass): assert len(sensors) == 5 sensors_and_states = { - (sensor.original_name, hass.states.get(sensor.entity_id).state) + ( + hass.states.get(sensor.entity_id).attributes[ATTR_FRIENDLY_NAME], + hass.states.get(sensor.entity_id).state, + ) for sensor in sensors } assert sensors_and_states == { @@ -378,7 +402,10 @@ async def test_scb1e_sensor_update(hass): assert mock_setup.api.get_state.call_count == 2 sensors_and_states = { - (sensor.original_name, hass.states.get(sensor.entity_id).state) + ( + hass.states.get(sensor.entity_id).attributes[ATTR_FRIENDLY_NAME], + hass.states.get(sensor.entity_id).state, + ) for sensor in sensors } assert sensors_and_states == { diff --git a/tests/components/broadlink/test_switch.py b/tests/components/broadlink/test_switch.py new file mode 100644 index 00000000000..9a7fc7e1ec9 --- /dev/null +++ b/tests/components/broadlink/test_switch.py @@ -0,0 +1,126 @@ +"""Tests for Broadlink switches.""" +from homeassistant.components.broadlink.const import DOMAIN +from homeassistant.components.switch import ( + DOMAIN as SWITCH_DOMAIN, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, +) +from homeassistant.const import ATTR_FRIENDLY_NAME, STATE_OFF, STATE_ON, Platform +from homeassistant.helpers.entity_registry import async_entries_for_device + +from . import get_device + +from tests.common import mock_device_registry, mock_registry + + +async def test_switch_setup_works(hass): + """Test a successful setup with a switch.""" + device = get_device("Dining room") + device_registry = mock_device_registry(hass) + entity_registry = mock_registry(hass) + mock_setup = await device.setup_entry(hass) + + device_entry = device_registry.async_get_device( + {(DOMAIN, mock_setup.entry.unique_id)} + ) + entries = async_entries_for_device(entity_registry, device_entry.id) + switches = [entry for entry in entries if entry.domain == Platform.SWITCH] + assert len(switches) == 1 + + switch = switches[0] + assert ( + hass.states.get(switch.entity_id).attributes[ATTR_FRIENDLY_NAME] == device.name + ) + assert hass.states.get(switch.entity_id).state == STATE_OFF + assert mock_setup.api.auth.call_count == 1 + + +async def test_switch_turn_off_turn_on(hass): + """Test send turn on and off for a switch.""" + device = get_device("Dining room") + device_registry = mock_device_registry(hass) + entity_registry = mock_registry(hass) + mock_setup = await device.setup_entry(hass) + + device_entry = device_registry.async_get_device( + {(DOMAIN, mock_setup.entry.unique_id)} + ) + entries = async_entries_for_device(entity_registry, device_entry.id) + switches = [entry for entry in entries if entry.domain == Platform.SWITCH] + assert len(switches) == 1 + + switch = switches[0] + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {"entity_id": switch.entity_id}, + blocking=True, + ) + assert hass.states.get(switch.entity_id).state == STATE_OFF + + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {"entity_id": switch.entity_id}, + blocking=True, + ) + assert hass.states.get(switch.entity_id).state == STATE_ON + + assert mock_setup.api.auth.call_count == 1 + + +async def test_slots_switch_setup_works(hass): + """Test a successful setup with a switch with slots.""" + device = get_device("Gaming room") + device_registry = mock_device_registry(hass) + entity_registry = mock_registry(hass) + mock_setup = await device.setup_entry(hass) + + device_entry = device_registry.async_get_device( + {(DOMAIN, mock_setup.entry.unique_id)} + ) + entries = async_entries_for_device(entity_registry, device_entry.id) + switches = [entry for entry in entries if entry.domain == Platform.SWITCH] + assert len(switches) == 4 + + for slot, switch in enumerate(switches): + assert ( + hass.states.get(switch.entity_id).attributes[ATTR_FRIENDLY_NAME] + == f"{device.name} S{slot+1}" + ) + assert hass.states.get(switch.entity_id).state == STATE_OFF + assert mock_setup.api.auth.call_count == 1 + + +async def test_slots_switch_turn_off_turn_on(hass): + """Test send turn on and off for a switch with slots.""" + device = get_device("Gaming room") + device_registry = mock_device_registry(hass) + entity_registry = mock_registry(hass) + mock_setup = await device.setup_entry(hass) + + device_entry = device_registry.async_get_device( + {(DOMAIN, mock_setup.entry.unique_id)} + ) + entries = async_entries_for_device(entity_registry, device_entry.id) + switches = [entry for entry in entries if entry.domain == Platform.SWITCH] + assert len(switches) == 4 + + for switch in switches: + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {"entity_id": switch.entity_id}, + blocking=True, + ) + assert hass.states.get(switch.entity_id).state == STATE_OFF + + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {"entity_id": switch.entity_id}, + blocking=True, + ) + assert hass.states.get(switch.entity_id).state == STATE_ON + + assert mock_setup.api.auth.call_count == 1