From fc9e564a2c42f7c6b357c0a53947f8b64d7a8d9b Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Fri, 20 Dec 2024 14:02:28 -0700 Subject: [PATCH] [mqtt.homeassistant] Fix components with an empty name (#17933) As opposed to null name. In either case, it's not usable, and we need to use our fallbacks. Signed-off-by: Cody Cutrer --- .../internal/component/AbstractComponent.java | 7 +- .../internal/component/ClimateTests.java | 77 ++++++++++++++++++- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java index 80fbb958a7d..1aef48287da 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java @@ -225,7 +225,7 @@ public abstract class AbstractComponent protected ComponentChannel.Builder buildChannel(String channelID, ComponentChannelType channelType, Value valueState, String label, ChannelStateUpdateListener channelStateUpdateListener) { - if (groupId == null) { + if (groupId == null && newStyleChannels) { channelID = componentId; } return new ComponentChannel.Builder(this, channelID, channelType.getChannelTypeUID(), valueState, label, @@ -304,12 +304,15 @@ public abstract class AbstractComponent */ public String getName() { String result = channelConfiguration.getName(); + if (result.isBlank()) { + result = null; + } Device device = channelConfiguration.getDevice(); if (result == null && device != null) { result = device.getName(); } - if (result == null) { + if (result == null || result.isBlank()) { result = haID.objectID; } return result; diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java index 44117740821..abed25174bc 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java @@ -38,6 +38,7 @@ import org.openhab.core.library.unit.Units; @NonNullByDefault public class ClimateTests extends AbstractComponentTests { public static final String CONFIG_TOPIC = "climate/0x847127fffe11dd6a_climate_zigbee2mqtt"; + public static final String TION_CONFIG_TOPIC = "climate/living-room-tion-3s/living-room-tion-3s"; @SuppressWarnings("null") @Test @@ -397,8 +398,82 @@ public class ClimateTests extends AbstractComponentTests { assertState(component, Climate.TARGET_HUMIDITY_CH_ID, new QuantityType<>(50, Units.PERCENT)); } + @SuppressWarnings("null") + @Test + public void testClimateWithEmptyName() { + var component = discoverComponent(configTopicToMqtt(TION_CONFIG_TOPIC), """ + { + "curr_temp_t": "living-room-tion-3s/climate/living-room-tion-3s/current_temperature/state", + "mode_cmd_t": "living-room-tion-3s/climate/living-room-tion-3s/mode/command", + "mode_stat_t": "living-room-tion-3s/climate/living-room-tion-3s/mode/state", + "modes": [ + "off", + "heat", + "fan_only", + "heat_cool" + ], + "temp_cmd_t": "living-room-tion-3s/climate/living-room-tion-3s/target_temperature/command", + "temp_stat_t": "living-room-tion-3s/climate/living-room-tion-3s/target_temperature/state", + "min_temp": 1, + "max_temp": 25, + "temp_step": 1, + "precision": 1, + "temp_unit": "C", + "min_hum": 30, + "max_hum": 99, + "act_t": "living-room-tion-3s/climate/living-room-tion-3s/action/state", + "fan_mode_cmd_t": "living-room-tion-3s/climate/living-room-tion-3s/fan_mode/command", + "fan_mode_stat_t": "living-room-tion-3s/climate/living-room-tion-3s/fan_mode/state", + "fan_modes": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "name": "", + "ic": "mdi:air-filter", + "avty_t": "living-room-tion-3s/status", + "uniq_id": "ESPclimateliving-room-tion-3s", + "dev": { + "ids": "f09e9e213ab0", + "name": "living-room-tion-3s", + "sw": "2024.8.0 (ESPHome 2024.11.3)", + "mdl": "tion", + "mf": "dentra", + "cns": [ + [ + "mac", + "f09e9e213ab0" + ] + ] + } + } + """); + + assertThat(component.channels.size(), is(5)); + assertThat(component.getName(), is("living-room-tion-3s")); + + assertChannel(component, Climate.ACTION_CH_ID, "living-room-tion-3s/climate/living-room-tion-3s/action/state", + "", "living-room-tion-3s", TextValue.class); + assertChannel(component, Climate.CURRENT_TEMPERATURE_CH_ID_DEPRECATED, + "living-room-tion-3s/climate/living-room-tion-3s/current_temperature/state", "", "living-room-tion-3s", + NumberValue.class); + assertChannel(component, Climate.FAN_MODE_CH_ID_DEPRECATED, + "living-room-tion-3s/climate/living-room-tion-3s/fan_mode/state", + "living-room-tion-3s/climate/living-room-tion-3s/fan_mode/command", "living-room-tion-3s", + TextValue.class); + assertChannel(component, Climate.MODE_CH_ID, "living-room-tion-3s/climate/living-room-tion-3s/mode/state", + "living-room-tion-3s/climate/living-room-tion-3s/mode/command", "living-room-tion-3s", TextValue.class); + assertChannel(component, Climate.TEMPERATURE_CH_ID, + "living-room-tion-3s/climate/living-room-tion-3s/target_temperature/state", + "living-room-tion-3s/climate/living-room-tion-3s/target_temperature/command", "living-room-tion-3s", + NumberValue.class); + } + @Override protected Set getConfigTopics() { - return Set.of(CONFIG_TOPIC); + return Set.of(CONFIG_TOPIC, TION_CONFIG_TOPIC); } }