From 1e2209c61816796539e161c3031b82c68f1f263a Mon Sep 17 00:00:00 2001 From: bkobus-bbx Date: Fri, 7 Aug 2026 13:36:18 +0200 Subject: [PATCH] Use product name as model and add hardware version for BleBox devices info (#178421) --- .../components/blebox/diagnostics.py | 1 + homeassistant/components/blebox/entity.py | 3 +- tests/components/blebox/conftest.py | 1 + .../blebox/snapshots/test_diagnostics.ambr | 2 ++ tests/components/blebox/test_binary_sensor.py | 4 +++ tests/components/blebox/test_button.py | 1 + tests/components/blebox/test_climate.py | 2 ++ tests/components/blebox/test_config_flow.py | 1 + tests/components/blebox/test_cover.py | 4 +++ tests/components/blebox/test_init.py | 35 +++++++++++++++++++ tests/components/blebox/test_light.py | 5 +++ tests/components/blebox/test_sensor.py | 6 ++++ tests/components/blebox/test_switch.py | 3 ++ tests/components/blebox/test_update.py | 1 + 14 files changed, 68 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/blebox/diagnostics.py b/homeassistant/components/blebox/diagnostics.py index bb9a0728dab5..d9fa6d497931 100644 --- a/homeassistant/components/blebox/diagnostics.py +++ b/homeassistant/components/blebox/diagnostics.py @@ -23,6 +23,7 @@ async def async_get_config_entry_diagnostics( "name": product.name, "type": product.type, "model": product.model, + "product": product.product, "unique_id": product.unique_id, "firmware_version": product.firmware_version, "hardware_version": product.hardware_version, diff --git a/homeassistant/components/blebox/entity.py b/homeassistant/components/blebox/entity.py index ccd5a565986b..9dfd6543e6ac 100644 --- a/homeassistant/components/blebox/entity.py +++ b/homeassistant/components/blebox/entity.py @@ -23,8 +23,9 @@ class BleBoxEntity[_FeatureT: Feature](CoordinatorEntity[BleBoxCoordinator]): self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, product.unique_id)}, manufacturer=product.brand, - model=product.model, + model=product.product, name=product.name, sw_version=product.firmware_version, + hw_version=product.hardware_version, configuration_url=f"http://{product.address}", ) diff --git a/tests/components/blebox/conftest.py b/tests/components/blebox/conftest.py index 39e599b95a8c..15cd93775c2a 100644 --- a/tests/components/blebox/conftest.py +++ b/tests/components/blebox/conftest.py @@ -53,6 +53,7 @@ def mock_feature(category, spec, set_spec: bool = True, **kwargs): type(feature_mock.product).name = PropertyMock(return_value="Some name") type(feature_mock.product).type = PropertyMock(return_value="some type") type(feature_mock.product).model = PropertyMock(return_value="some model") + type(feature_mock.product).product = PropertyMock(return_value="some product") type(feature_mock.product).brand = PropertyMock(return_value="BleBox") type(feature_mock.product).firmware_version = PropertyMock(return_value="1.23") type(feature_mock.product).hardware_version = PropertyMock(return_value="0.1") diff --git a/tests/components/blebox/snapshots/test_diagnostics.ambr b/tests/components/blebox/snapshots/test_diagnostics.ambr index 326885368ae9..fa702c9adb6e 100644 --- a/tests/components/blebox/snapshots/test_diagnostics.ambr +++ b/tests/components/blebox/snapshots/test_diagnostics.ambr @@ -11,6 +11,7 @@ }), 'model': 'some model', 'name': 'Some name', + 'product': 'some product', 'type': 'some type', 'unique_id': 'abcd0123ef5678', }), @@ -49,6 +50,7 @@ }), 'model': 'some model', 'name': 'Some name', + 'product': 'some product', 'type': 'some type', 'unique_id': 'abcd0123ef5678', }), diff --git a/tests/components/blebox/test_binary_sensor.py b/tests/components/blebox/test_binary_sensor.py index 1ba01a7ef02a..6b7103f0aa7d 100644 --- a/tests/components/blebox/test_binary_sensor.py +++ b/tests/components/blebox/test_binary_sensor.py @@ -28,6 +28,7 @@ def airsensor_fixture() -> tuple[AsyncMock, str]: product = feature.product type(product).name = PropertyMock(return_value="My rain sensor") type(product).model = PropertyMock(return_value="rainSensor") + type(product).product = PropertyMock(return_value="rainSensor") return feature, "binary_sensor.my_rain_sensor_moisture" @@ -45,6 +46,7 @@ def open_sensor_fixture() -> tuple[AsyncMock, str]: product = feature.product type(product).name = PropertyMock(return_value="My open sensor") type(product).model = PropertyMock(return_value="openSensor") + type(product).product = PropertyMock(return_value="openSensor") return feature, "binary_sensor.my_open_sensor_window" @@ -62,6 +64,7 @@ def inputsensor_fixture() -> tuple[AsyncMock, str]: product = feature.product type(product).name = PropertyMock(return_value="My input sensor") type(product).model = PropertyMock(return_value="inputSensorD") + type(product).product = PropertyMock(return_value="inputSensorD") return feature, "binary_sensor.my_input_sensor_input" @@ -134,6 +137,7 @@ async def test_binary_sensor_with_name(hass: HomeAssistant) -> None: product = feature.product type(product).name = PropertyMock(return_value="My rain sensor") type(product).model = PropertyMock(return_value="rainSensor") + type(product).product = PropertyMock(return_value="rainSensor") await async_setup_entity(hass, "binary_sensor.my_rain_sensor_front_yard") state = hass.states.get("binary_sensor.my_rain_sensor_front_yard") diff --git a/tests/components/blebox/test_button.py b/tests/components/blebox/test_button.py index 1a18de458b16..4e8fff9bb784 100644 --- a/tests/components/blebox/test_button.py +++ b/tests/components/blebox/test_button.py @@ -36,6 +36,7 @@ def tv_lift_box_fixture(caplog: pytest.LogCaptureFixture): product = feature.product type(product).name = PropertyMock(return_value="My tvLiftBox") type(product).model = PropertyMock(return_value="tvLiftBox") + type(product).product = PropertyMock(return_value="tvLiftBox") type(product)._query_string = PropertyMock(return_value="open_or_stop") return (feature, "button.my_tvliftbox") diff --git a/tests/components/blebox/test_climate.py b/tests/components/blebox/test_climate.py index 7d55d8447b09..6567abf4ecbf 100644 --- a/tests/components/blebox/test_climate.py +++ b/tests/components/blebox/test_climate.py @@ -55,6 +55,7 @@ def saunabox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My sauna") type(product).model = PropertyMock(return_value="saunaBox") + type(product).product = PropertyMock(return_value="saunaBox") return (feature, "climate.my_sauna") @@ -78,6 +79,7 @@ def thermobox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My thermo") type(product).model = PropertyMock(return_value="thermoBox") + type(product).product = PropertyMock(return_value="thermoBox") return (feature, "climate.my_thermo") diff --git a/tests/components/blebox/test_config_flow.py b/tests/components/blebox/test_config_flow.py index 85afe7b7c637..1c3e1e4bfc9a 100644 --- a/tests/components/blebox/test_config_flow.py +++ b/tests/components/blebox/test_config_flow.py @@ -64,6 +64,7 @@ def create_valid_feature_mock(path="homeassistant.components.blebox.Products"): type(product).name = PropertyMock(return_value="My gate controller") type(product).model = PropertyMock(return_value="gateController") + type(product).product = PropertyMock(return_value="gateController") type(product).type = PropertyMock(return_value="gateBox") type(product).brand = PropertyMock(return_value="BleBox") type(product).firmware_version = PropertyMock(return_value="1.23") diff --git a/tests/components/blebox/test_cover.py b/tests/components/blebox/test_cover.py index b057e178d56d..69b6b634c5e1 100644 --- a/tests/components/blebox/test_cover.py +++ b/tests/components/blebox/test_cover.py @@ -63,6 +63,7 @@ def shutterbox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My shutter") type(product).model = PropertyMock(return_value="shutterBox") + type(product).product = PropertyMock(return_value="shutterBox") return (feature, "cover.my_shutter") @@ -86,6 +87,7 @@ def gatebox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My gatebox") type(product).model = PropertyMock(return_value="gateBox") + type(product).product = PropertyMock(return_value="gateBox") return (feature, "cover.my_gatebox") @@ -109,6 +111,7 @@ def gate_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My gate controller") type(product).model = PropertyMock(return_value="gateController") + type(product).product = PropertyMock(return_value="gateController") return (feature, "cover.my_gate_controller") @@ -247,6 +250,7 @@ async def test_device_class_from_unified_cover_type( product = feature.product type(product).name = PropertyMock(return_value="My shutter") type(product).model = PropertyMock(return_value="shutterBox") + type(product).product = PropertyMock(return_value="shutterBox") entity_id = "cover.my_shutter" entry = await async_setup_entity(hass, entity_id) diff --git a/tests/components/blebox/test_init.py b/tests/components/blebox/test_init.py index cd8d0e8e4da1..757ccdd5317d 100644 --- a/tests/components/blebox/test_init.py +++ b/tests/components/blebox/test_init.py @@ -1,13 +1,19 @@ """BleBox devices setup tests.""" +from unittest.mock import PropertyMock + import blebox_uniapi +import blebox_uniapi.sensor import pytest from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr from .conftest import ( async_setup_config_entry, + async_setup_entity, + mock_feature, patch_product_identify, setup_product_mock, ) @@ -67,3 +73,32 @@ async def test_unload_config_entry( assert not hasattr(config_entry, "runtime_data") assert config_entry.state is ConfigEntryState.NOT_LOADED + + +async def test_device_registry_model_and_hw_version( + hass: HomeAssistant, device_registry: dr.DeviceRegistry +) -> None: + """Test device registry has correct model and hardware version.""" + feature_mock = mock_feature( + "sensors", + blebox_uniapi.sensor.Temperature, + unique_id="BleBox-multiSensor-1afe34e750b8-0.temperature", + full_name="multiSensor-0.temperature", + device_class="temperature", + unit="celsius", + current=None, + native_value=None, + index=None, + ) + type(feature_mock).name = PropertyMock(return_value=None) + type(feature_mock.product).name = PropertyMock(return_value="My test sensor") + type(feature_mock.product).model = PropertyMock(return_value="multiSensor") + type(feature_mock.product).product = PropertyMock(return_value="rainSensor") + type(feature_mock.product).hardware_version = PropertyMock(return_value="2.1") + + entry = await async_setup_entity(hass, "sensor.my_test_sensor_temperature") + + device = device_registry.async_get(entry.device_id) + + assert device.model == "rainSensor" + assert device.hw_version == "2.1" diff --git a/tests/components/blebox/test_light.py b/tests/components/blebox/test_light.py index 031f4bca861a..df3112bd1ca8 100644 --- a/tests/components/blebox/test_light.py +++ b/tests/components/blebox/test_light.py @@ -53,6 +53,7 @@ def dimmer_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My dimmer") type(product).model = PropertyMock(return_value="dimmerBox") + type(product).product = PropertyMock(return_value="dimmerBox") return (feature, "light.my_dimmer") @@ -175,6 +176,7 @@ def wlightboxs_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My wLightBoxS") type(product).model = PropertyMock(return_value="wLightBoxS") + type(product).product = PropertyMock(return_value="wLightBoxS") return (feature, "light.my_wlightboxs") @@ -260,6 +262,7 @@ def wlightbox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My wLightBox") type(product).model = PropertyMock(return_value="wLightBox") + type(product).product = PropertyMock(return_value="wLightBox") return (feature, "light.my_wlightbox") @@ -286,6 +289,7 @@ def wlightbox_ct_fixture() -> tuple[MagicMock, str]: product = feature.product type(product).name = PropertyMock(return_value="My wLightBox") type(product).model = PropertyMock(return_value="wLightBox") + type(product).product = PropertyMock(return_value="wLightBox") return feature, "light.my_wlightbox" @@ -571,6 +575,7 @@ async def test_multichannel_light_name( product = feature.product type(product).name = PropertyMock(return_value="My wLightBox") type(product).model = PropertyMock(return_value="wLightBox") + type(product).product = PropertyMock(return_value="wLightBox") await async_setup_entity(hass, entity_id) state = hass.states.get(entity_id) diff --git a/tests/components/blebox/test_sensor.py b/tests/components/blebox/test_sensor.py index 5a24da079bcf..9c003d60a789 100644 --- a/tests/components/blebox/test_sensor.py +++ b/tests/components/blebox/test_sensor.py @@ -48,6 +48,7 @@ def airsensor_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My air sensor") type(product).model = PropertyMock(return_value="airSensor") + type(product).product = PropertyMock(return_value="airSensor") return (feature, "sensor.my_air_sensor_pm1") @@ -69,6 +70,7 @@ def tempsensor_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My temperature sensor") type(product).model = PropertyMock(return_value="tempSensor") + type(product).product = PropertyMock(return_value="tempSensor") return (feature, "sensor.my_temperature_sensor_temperature") @@ -174,6 +176,7 @@ async def test_multi_sensor_single_has_no_channel_suffix( product = feature.product type(product).name = PropertyMock(return_value="My smart meter") type(product).model = PropertyMock(return_value="smartMeter") + type(product).product = PropertyMock(return_value="smartMeter") await async_setup_entity(hass, "sensor.my_smart_meter_voltage") state = hass.states.get("sensor.my_smart_meter_voltage") @@ -201,6 +204,7 @@ async def test_multi_sensor_multiple_have_channel_suffix( product = setup_product_mock("sensors", features) type(product).name = PropertyMock(return_value="My smart meter") type(product).model = PropertyMock(return_value="smartMeter") + type(product).product = PropertyMock(return_value="smartMeter") type(product).brand = PropertyMock(return_value="BleBox") type(product).firmware_version = PropertyMock(return_value="1.23") type(product).unique_id = PropertyMock(return_value="aabbcc112233") @@ -256,6 +260,7 @@ def open_status_sensor_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My open sensor") type(product).model = PropertyMock(return_value="openSensor") + type(product).product = PropertyMock(return_value="openSensor") return (feature, "sensor.my_open_sensor_open_status") @@ -326,6 +331,7 @@ def co2_definition_sensor_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My CO2 sensor") type(product).model = PropertyMock(return_value="co2Sensor") + type(product).product = PropertyMock(return_value="co2Sensor") return (feature, "sensor.my_co2_sensor_carbon_dioxide_level") diff --git a/tests/components/blebox/test_switch.py b/tests/components/blebox/test_switch.py index ccd66fad439e..503af5b88b4e 100644 --- a/tests/components/blebox/test_switch.py +++ b/tests/components/blebox/test_switch.py @@ -48,6 +48,7 @@ def switchbox_fixture(): product = feature.product type(product).name = PropertyMock(return_value="My switch box") type(product).model = PropertyMock(return_value="switchBox") + type(product).product = PropertyMock(return_value="switchBox") return (feature, "switch.my_switch_box") @@ -162,6 +163,7 @@ def switchbox_d_fixture(): type(product).name = PropertyMock(return_value="My relays") type(product).model = PropertyMock(return_value="switchBoxD") + type(product).product = PropertyMock(return_value="switchBoxD") type(product).brand = PropertyMock(return_value="BleBox") type(product).firmware_version = PropertyMock(return_value="1.23") type(product).unique_id = PropertyMock(return_value="abcd0123ef5678") @@ -333,6 +335,7 @@ async def test_switchbox_with_name(hass: HomeAssistant) -> None: product = feature.product type(product).name = PropertyMock(return_value="My switch box") type(product).model = PropertyMock(return_value="switchBoxD") + type(product).product = PropertyMock(return_value="switchBoxD") await async_setup_entity(hass, "switch.my_switch_box_garden_lights") state = hass.states.get("switch.my_switch_box_garden_lights") diff --git a/tests/components/blebox/test_update.py b/tests/components/blebox/test_update.py index 9f56b9112fb0..3f1b21aa7e23 100644 --- a/tests/components/blebox/test_update.py +++ b/tests/components/blebox/test_update.py @@ -48,6 +48,7 @@ def firmwareupdate_fixture() -> tuple[blebox_uniapi.update.Update, str]: product = feature.product type(product).name = PropertyMock(return_value="My airSensor") type(product).model = PropertyMock(return_value="airSensor") + type(product).product = PropertyMock(return_value="airSensor") return (feature, "update.my_airsensor_firmware")