diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/ComponentChannel.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/ComponentChannel.java index b016a6960e0bd..d63a304d5efc7 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/ComponentChannel.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/ComponentChannel.java @@ -224,7 +224,7 @@ public ComponentChannel build(boolean addToComponent) { ChannelType type; ChannelTypeUID channelTypeUID; - channelUID = new ChannelUID(component.getGroupUID(), channelID); + channelUID = component.buildChannelUID(channelID); channelTypeUID = new ChannelTypeUID(MqttBindingConstants.BINDING_ID, channelUID.getGroupId() + "_" + channelID); channelState = new HomeAssistantChannelState( 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 203218baa75ae..87625305d300b 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 @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.TreeMap; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledExecutorService; @@ -31,8 +32,10 @@ import org.openhab.binding.mqtt.homeassistant.internal.HaID; import org.openhab.binding.mqtt.homeassistant.internal.component.ComponentFactory.ComponentConfiguration; import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration; +import org.openhab.binding.mqtt.homeassistant.internal.config.dto.Device; import org.openhab.core.io.transport.mqtt.MqttBrokerConnection; import org.openhab.core.thing.ChannelGroupUID; +import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.type.ChannelDefinition; import org.openhab.core.thing.type.ChannelGroupDefinition; import org.openhab.core.thing.type.ChannelGroupType; @@ -54,8 +57,8 @@ public abstract class AbstractComponent // Component location fields private final ComponentConfiguration componentConfiguration; - protected final ChannelGroupTypeUID channelGroupTypeUID; - protected final ChannelGroupUID channelGroupUID; + protected final @Nullable ChannelGroupTypeUID channelGroupTypeUID; + protected final @Nullable ChannelGroupUID channelGroupUID; protected final HaID haID; // Channels and configuration @@ -83,10 +86,15 @@ public AbstractComponent(ComponentFactory.ComponentConfiguration componentConfig this.haID = componentConfiguration.getHaID(); - String groupId = this.haID.getGroupId(channelConfiguration.getUniqueId()); + if (channelConfiguration.getName() != null) { + String groupId = this.haID.getGroupId(channelConfiguration.getUniqueId()); - this.channelGroupTypeUID = new ChannelGroupTypeUID(MqttBindingConstants.BINDING_ID, groupId); - this.channelGroupUID = new ChannelGroupUID(componentConfiguration.getThingUID(), groupId); + this.channelGroupTypeUID = new ChannelGroupTypeUID(MqttBindingConstants.BINDING_ID, groupId); + this.channelGroupUID = new ChannelGroupUID(componentConfiguration.getThingUID(), groupId); + } else { + this.channelGroupTypeUID = null; + this.channelGroupUID = null; + } this.configSeen = false; @@ -142,7 +150,10 @@ public void setConfigSeen() { * @param channelTypeProvider The channel type provider */ public void addChannelTypes(MqttChannelTypeProvider channelTypeProvider) { - channelTypeProvider.setChannelGroupType(getGroupTypeUID(), getType()); + ChannelGroupTypeUID groupTypeUID = channelGroupTypeUID; + if (groupTypeUID != null) { + channelTypeProvider.setChannelGroupType(groupTypeUID, Objects.requireNonNull(getType())); + } channels.values().forEach(v -> v.addChannelTypes(channelTypeProvider)); } @@ -154,20 +165,31 @@ public void addChannelTypes(MqttChannelTypeProvider channelTypeProvider) { */ public void removeChannelTypes(MqttChannelTypeProvider channelTypeProvider) { channels.values().forEach(v -> v.removeChannelTypes(channelTypeProvider)); - channelTypeProvider.removeChannelGroupType(getGroupTypeUID()); + ChannelGroupTypeUID groupTypeUID = channelGroupTypeUID; + if (groupTypeUID != null) { + channelTypeProvider.removeChannelGroupType(groupTypeUID); + } + } + + public ChannelUID buildChannelUID(String channelID) { + final ChannelGroupUID groupUID = channelGroupUID; + if (groupUID != null) { + return new ChannelUID(groupUID, channelID); + } + return new ChannelUID(componentConfiguration.getThingUID(), channelID); } /** * Each HomeAssistant component corresponds to a Channel Group Type. */ - public ChannelGroupTypeUID getGroupTypeUID() { + public @Nullable ChannelGroupTypeUID getGroupTypeUID() { return channelGroupTypeUID; } /** * The unique id of this component. */ - public ChannelGroupUID getGroupUID() { + public @Nullable ChannelGroupUID getGroupUID() { return channelGroupUID; } @@ -175,7 +197,16 @@ public ChannelGroupUID getGroupUID() { * Component (Channel Group) name. */ public String getName() { - return channelConfiguration.getName(); + String result = channelConfiguration.getName(); + + Device device = channelConfiguration.getDevice(); + if (result == null && device != null) { + result = device.getName(); + } + if (result == null) { + result = haID.objectID; + } + return result; } /** @@ -207,11 +238,19 @@ public int getConfigHash() { /** * Return the channel group type. */ - public ChannelGroupType getType() { + public @Nullable ChannelGroupType getType() { + ChannelGroupTypeUID groupTypeUID = channelGroupTypeUID; + if (groupTypeUID == null) { + return null; + } final List channelDefinitions = channels.values().stream().map(ComponentChannel::type) .collect(Collectors.toList()); - return ChannelGroupTypeBuilder.instance(channelGroupTypeUID, getName()) - .withChannelDefinitions(channelDefinitions).build(); + return ChannelGroupTypeBuilder.instance(groupTypeUID, getName()).withChannelDefinitions(channelDefinitions) + .build(); + } + + public List getChannels() { + return channels.values().stream().map(ComponentChannel::type).collect(Collectors.toList()); } /** @@ -225,8 +264,12 @@ public void resetState() { /** * Return the channel group definition for this component. */ - public ChannelGroupDefinition getGroupDefinition() { - return new ChannelGroupDefinition(channelGroupUID.getId(), getGroupTypeUID(), getName(), null); + public @Nullable ChannelGroupDefinition getGroupDefinition() { + ChannelGroupTypeUID groupTypeUID = channelGroupTypeUID; + if (groupTypeUID == null) { + return null; + } + return new ChannelGroupDefinition(channelGroupUID.getId(), groupTypeUID, getName(), null); } public HaID getHaID() { diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AlarmControlPanel.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AlarmControlPanel.java index 8d213e7075cd8..5f60eec5fad53 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AlarmControlPanel.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AlarmControlPanel.java @@ -74,24 +74,23 @@ public AlarmControlPanel(ComponentFactory.ComponentConfiguration componentConfig final String[] stateEnum = { channelConfiguration.stateDisarmed, channelConfiguration.stateArmedHome, channelConfiguration.stateArmedAway, channelConfiguration.statePending, channelConfiguration.stateTriggered }; - buildChannel(STATE_CHANNEL_ID, new TextValue(stateEnum), channelConfiguration.getName(), - componentConfiguration.getUpdateListener()) + buildChannel(STATE_CHANNEL_ID, new TextValue(stateEnum), getName(), componentConfiguration.getUpdateListener()) .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())// .build(); String commandTopic = channelConfiguration.commandTopic; if (commandTopic != null) { buildChannel(SWITCH_DISARM_CHANNEL_ID, new TextValue(new String[] { channelConfiguration.payloadDisarm }), - channelConfiguration.getName(), componentConfiguration.getUpdateListener()) + getName(), componentConfiguration.getUpdateListener()) .commandTopic(commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos()).build(); buildChannel(SWITCH_ARM_HOME_CHANNEL_ID, - new TextValue(new String[] { channelConfiguration.payloadArmHome }), channelConfiguration.getName(), + new TextValue(new String[] { channelConfiguration.payloadArmHome }), getName(), componentConfiguration.getUpdateListener()) .commandTopic(commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos()).build(); buildChannel(SWITCH_ARM_AWAY_CHANNEL_ID, - new TextValue(new String[] { channelConfiguration.payloadArmAway }), channelConfiguration.getName(), + new TextValue(new String[] { channelConfiguration.payloadArmAway }), getName(), componentConfiguration.getUpdateListener()) .commandTopic(commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos()).build(); } diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Camera.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Camera.java index c66119ff53bdf..bcf12f36087f7 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Camera.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Camera.java @@ -43,7 +43,7 @@ public Camera(ComponentFactory.ComponentConfiguration componentConfiguration) { ImageValue value = new ImageValue(); - buildChannel(CAMERA_CHANNEL_ID, value, channelConfiguration.getName(), - componentConfiguration.getUpdateListener()).stateTopic(channelConfiguration.topic).build(); + buildChannel(CAMERA_CHANNEL_ID, value, getName(), componentConfiguration.getUpdateListener()) + .stateTopic(channelConfiguration.topic).build(); } } diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Climate.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Climate.java index a2ad15e81b64a..5e68b56689ade 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Climate.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Climate.java @@ -286,7 +286,7 @@ private ComponentChannel buildOptionalChannel(String channelId, Value valueState @Nullable String commandTopic, @Nullable String stateTemplate, @Nullable String stateTopic, @Nullable Predicate commandFilter) { if ((commandTopic != null && !commandTopic.isBlank()) || (stateTopic != null && !stateTopic.isBlank())) { - return buildChannel(channelId, valueState, channelConfiguration.getName(), channelStateUpdateListener) + return buildChannel(channelId, valueState, getName(), channelStateUpdateListener) .stateTopic(stateTopic, stateTemplate, channelConfiguration.getValueTemplate()) .commandTopic(commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos(), commandTemplate) diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Cover.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Cover.java index ecfa3a48c6919..8191f16c2ec6f 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Cover.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Cover.java @@ -56,8 +56,7 @@ public Cover(ComponentFactory.ComponentConfiguration componentConfiguration) { RollershutterValue value = new RollershutterValue(channelConfiguration.payloadOpen, channelConfiguration.payloadClose, channelConfiguration.payloadStop); - buildChannel(SWITCH_CHANNEL_ID, value, channelConfiguration.getName(), - componentConfiguration.getUpdateListener()) + buildChannel(SWITCH_CHANNEL_ID, value, getName(), componentConfiguration.getUpdateListener()) .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate()) .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos()) diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DefaultSchemaLight.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DefaultSchemaLight.java index 092b898a695f6..8b90631d3a93a 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DefaultSchemaLight.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DefaultSchemaLight.java @@ -281,7 +281,7 @@ public void updateChannelState(ChannelUID channel, State state) { colorValue.update(newOnState); } - listener.updateChannelState(new ChannelUID(getGroupUID(), COLOR_CHANNEL_ID), + listener.updateChannelState(buildChannelUID(COLOR_CHANNEL_ID), state.equals(OnOffType.ON) ? newOnState : HSBType.BLACK); } else if (brightnessChannel != null) { listener.updateChannelState(new ChannelUID(channel.getThingUID(), BRIGHTNESS_CHANNEL_ID), @@ -301,8 +301,7 @@ public void updateChannelState(ChannelUID channel, State state) { colorValue.update(new HSBType(DecimalType.ZERO, PercentType.ZERO, (PercentType) brightnessValue.getChannelState())); } - listener.updateChannelState(new ChannelUID(getGroupUID(), COLOR_CHANNEL_ID), - colorValue.getChannelState()); + listener.updateChannelState(buildChannelUID(COLOR_CHANNEL_ID), colorValue.getChannelState()); } else { listener.updateChannelState(channel, state); } @@ -330,13 +329,11 @@ public void updateChannelState(ChannelUID channel, State state) { HSBType xyColor = HSBType.fromXY(x, y); colorValue.update(new HSBType(xyColor.getHue(), xyColor.getSaturation(), brightness)); } - listener.updateChannelState(new ChannelUID(getGroupUID(), COLOR_CHANNEL_ID), - colorValue.getChannelState()); + listener.updateChannelState(buildChannelUID(COLOR_CHANNEL_ID), colorValue.getChannelState()); return; case RGB_CHANNEL_ID: colorValue.update((HSBType) state); - listener.updateChannelState(new ChannelUID(getGroupUID(), COLOR_CHANNEL_ID), - colorValue.getChannelState()); + listener.updateChannelState(buildChannelUID(COLOR_CHANNEL_ID), colorValue.getChannelState()); break; case RGBW_CHANNEL_ID: case RGBWW_CHANNEL_ID: diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DeviceTrigger.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DeviceTrigger.java index 657483fc538a7..e3c914bef2d9e 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DeviceTrigger.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/DeviceTrigger.java @@ -65,8 +65,7 @@ public DeviceTrigger(ComponentFactory.ComponentConfiguration componentConfigurat value = new TextValue(); } - buildChannel(channelConfiguration.type, value, channelConfiguration.getName(), - componentConfiguration.getUpdateListener()) + buildChannel(channelConfiguration.type, value, getName(), componentConfiguration.getUpdateListener()) .stateTopic(channelConfiguration.topic, channelConfiguration.getValueTemplate()).trigger(true).build(); } } diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Fan.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Fan.java index 49be4ee9238c6..7d056ed10ca38 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Fan.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Fan.java @@ -54,8 +54,7 @@ public Fan(ComponentFactory.ComponentConfiguration componentConfiguration) { super(componentConfiguration, ChannelConfiguration.class); OnOffValue value = new OnOffValue(channelConfiguration.payloadOn, channelConfiguration.payloadOff); - buildChannel(SWITCH_CHANNEL_ID, value, channelConfiguration.getName(), - componentConfiguration.getUpdateListener()) + buildChannel(SWITCH_CHANNEL_ID, value, getName(), componentConfiguration.getUpdateListener()) .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate()) .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos(), channelConfiguration.commandTemplate) diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/JSONSchemaLight.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/JSONSchemaLight.java index 01e8dcb9fe02b..12599b8f14fe4 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/JSONSchemaLight.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/JSONSchemaLight.java @@ -225,12 +225,11 @@ public void updateChannelState(ChannelUID channel, State state) { } if (hasColorChannel) { - listener.updateChannelState(new ChannelUID(getGroupUID(), COLOR_CHANNEL_ID), colorValue.getChannelState()); + listener.updateChannelState(buildChannelUID(COLOR_CHANNEL_ID), colorValue.getChannelState()); } else if (brightnessChannel != null) { - listener.updateChannelState(new ChannelUID(getGroupUID(), BRIGHTNESS_CHANNEL_ID), - brightnessValue.getChannelState()); + listener.updateChannelState(buildChannelUID(BRIGHTNESS_CHANNEL_ID), brightnessValue.getChannelState()); } else { - listener.updateChannelState(new ChannelUID(getGroupUID(), ON_OFF_CHANNEL_ID), onOffValue.getChannelState()); + listener.updateChannelState(buildChannelUID(ON_OFF_CHANNEL_ID), onOffValue.getChannelState()); } } } diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Lock.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Lock.java index b50974a412aa5..ccfab925c9b48 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Lock.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Lock.java @@ -58,8 +58,8 @@ public Lock(ComponentFactory.ComponentConfiguration componentConfiguration) { } buildChannel(SWITCH_CHANNEL_ID, - new OnOffValue(channelConfiguration.payloadLock, channelConfiguration.payloadUnlock), - channelConfiguration.getName(), componentConfiguration.getUpdateListener()) + new OnOffValue(channelConfiguration.payloadLock, channelConfiguration.payloadUnlock), getName(), + componentConfiguration.getUpdateListener()) .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate()) .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos()) diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Number.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Number.java index 947f46cc41a53..10519eb24312c 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Number.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Number.java @@ -82,8 +82,7 @@ public Number(ComponentFactory.ComponentConfiguration componentConfiguration) { NumberValue value = new NumberValue(channelConfiguration.min, channelConfiguration.max, channelConfiguration.step, UnitUtils.parseUnit(channelConfiguration.unitOfMeasurement)); - buildChannel(NUMBER_CHANNEL_ID, value, channelConfiguration.getName(), - componentConfiguration.getUpdateListener()) + buildChannel(NUMBER_CHANNEL_ID, value, getName(), componentConfiguration.getUpdateListener()) .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate()) .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos(), channelConfiguration.commandTemplate) diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Select.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Select.java index 9ead86ef8af4b..d49dfbf1a7172 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Select.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Select.java @@ -66,8 +66,7 @@ public Select(ComponentFactory.ComponentConfiguration componentConfiguration) { TextValue value = new TextValue(channelConfiguration.options); - buildChannel(SELECT_CHANNEL_ID, value, channelConfiguration.getName(), - componentConfiguration.getUpdateListener()) + buildChannel(SELECT_CHANNEL_ID, value, getName(), componentConfiguration.getUpdateListener()) .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate()) .commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos(), channelConfiguration.commandTemplate) diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Sensor.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Sensor.java index f9f8706b5b108..148a5b5e989ab 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Sensor.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Sensor.java @@ -88,8 +88,7 @@ public Sensor(ComponentFactory.ComponentConfiguration componentConfiguration) { boolean trigger = TRIGGER_ICONS.matcher(icon).matches(); - buildChannel(SENSOR_CHANNEL_ID, value, channelConfiguration.getName(), - getListener(componentConfiguration, value)) + buildChannel(SENSOR_CHANNEL_ID, value, getName(), getListener(componentConfiguration, value)) .stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())// .trigger(trigger).build(); } diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Vacuum.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Vacuum.java index 7fd9d6b901fb9..75de1517cf03d 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Vacuum.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Vacuum.java @@ -294,7 +294,7 @@ private ComponentChannel buildOptionalChannel(String channelId, Value valueState ChannelStateUpdateListener channelStateUpdateListener, @Nullable String commandTemplate, @Nullable String commandTopic, @Nullable String stateTemplate, @Nullable String stateTopic) { if ((commandTopic != null && !commandTopic.isBlank()) || (stateTopic != null && !stateTopic.isBlank())) { - return buildChannel(channelId, valueState, channelConfiguration.getName(), channelStateUpdateListener) + return buildChannel(channelId, valueState, getName(), channelStateUpdateListener) .stateTopic(stateTopic, stateTemplate, channelConfiguration.getValueTemplate()) .commandTopic(commandTopic, channelConfiguration.isRetain(), channelConfiguration.getQos(), commandTemplate) diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/config/dto/AbstractChannelConfiguration.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/config/dto/AbstractChannelConfiguration.java index ae64e5d2445da..dec22608edb28 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/config/dto/AbstractChannelConfiguration.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/config/dto/AbstractChannelConfiguration.java @@ -33,8 +33,9 @@ @NonNullByDefault public abstract class AbstractChannelConfiguration { public static final char PARENT_TOPIC_PLACEHOLDER = '~'; + private static final String DEFAULT_THING_NAME = "Home Assistant Device"; - protected String name; + protected @Nullable String name; protected String icon = ""; protected int qos; // defaults to 0 according to HA specification @@ -93,6 +94,9 @@ public String getThingName() { if (result == null) { result = name; } + if (result == null) { + result = DEFAULT_THING_NAME; + } return result; } @@ -127,7 +131,7 @@ public Map appendToProperties(Map properties) { return properties; } - public String getName() { + public @Nullable String getName() { return name; } diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandler.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandler.java index 14612c5f67924..99a14d4abd9c4 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandler.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandler.java @@ -18,6 +18,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -44,6 +45,7 @@ import org.openhab.binding.mqtt.homeassistant.internal.exception.ConfigurationException; import org.openhab.core.io.transport.mqtt.MqttBrokerConnection; import org.openhab.core.thing.Channel; +import org.openhab.core.thing.ChannelGroupUID; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingStatus; @@ -53,7 +55,6 @@ import org.openhab.core.thing.binding.builder.ThingBuilder; import org.openhab.core.thing.type.ChannelDefinition; import org.openhab.core.thing.type.ChannelGroupDefinition; -import org.openhab.core.thing.type.ChannelGroupType; import org.openhab.core.thing.type.ThingType; import org.openhab.core.thing.util.ThingHelper; import org.slf4j.Logger; @@ -93,7 +94,7 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler protected final DiscoverComponents discoverComponents; private final Gson gson; - protected final Map> haComponents = new HashMap<>(); + protected final Map<@Nullable String, AbstractComponent> haComponents = new HashMap<>(); protected HandlerConfiguration config = new HandlerConfiguration(); private Set discoveryHomeAssistantIDs = new HashSet<>(); @@ -137,10 +138,6 @@ public void initialize() { for (Channel channel : thing.getChannels()) { final String groupID = channel.getUID().getGroupId(); - if (groupID == null) { - logger.warn("Channel {} has no groupd ID", channel.getLabel()); - continue; - } // Already restored component? @Nullable AbstractComponent component = haComponents.get(groupID); @@ -160,7 +157,12 @@ public void initialize() { try { component = ComponentFactory.createComponent(thingUID, haID, channelConfigurationJSON, this, this, scheduler, gson, transformationServiceProvider); - haComponents.put(component.getGroupUID().getId(), component); + final ChannelGroupUID groupUID = component.getGroupUID(); + String id = null; + if (groupUID != null) { + id = groupUID.getId(); + } + haComponents.put(id, component); component.addChannelTypes(channelTypeProvider); } catch (ConfigurationException e) { logger.error("Cannot not restore component {}: {}", thing, e.getMessage()); @@ -228,9 +230,6 @@ protected void stop() { @Override public @Nullable ChannelState getChannelState(ChannelUID channelUID) { String groupID = channelUID.getGroupId(); - if (groupID == null) { - return null; - } AbstractComponent component; synchronized (haComponents) { // sync whenever discoverComponents is started component = haComponents.get(groupID); @@ -266,7 +265,12 @@ public void accept(List> discoveredComponentsList) { synchronized (haComponents) { // sync whenever discoverComponents is started for (AbstractComponent discovered : discoveredComponentsList) { - AbstractComponent known = haComponents.get(discovered.getGroupUID().getId()); + final ChannelGroupUID groupUID = discovered.getGroupUID(); + String id = null; + if (groupUID != null) { + id = groupUID.getId(); + } + AbstractComponent known = haComponents.get(id); // Is component already known? if (known != null) { if (discovered.getConfigHash() != known.getConfigHash()) { @@ -282,10 +286,10 @@ public void accept(List> discoveredComponentsList) { // Add channel and group types to the types registry discovered.addChannelTypes(channelTypeProvider); // Add component to the component map - haComponents.put(discovered.getGroupUID().getId(), discovered); + haComponents.put(id, discovered); // Start component / Subscribe to channel topics discovered.start(connection, scheduler, 0).exceptionally(e -> { - logger.warn("Failed to start component {}", discovered.getGroupUID(), e); + logger.warn("Failed to start component {}", discovered.getHaID(), e); return null; }); @@ -296,7 +300,7 @@ public void accept(List> discoveredComponentsList) { // We remove all conflicting old channels, they will be re-added below based on the new discovery logger.debug( "Received component {} with slightly different config. Making sure we re-create conflicting channels...", - discovered.getGroupUID()); + discovered.getHaID()); removeJustRediscoveredChannels(discoveredChannels); } @@ -346,9 +350,8 @@ private void updateThingType() { List channelDefs; synchronized (haComponents) { // sync whenever discoverComponents is started groupDefs = haComponents.values().stream().map(AbstractComponent::getGroupDefinition) - .collect(Collectors.toList()); - channelDefs = haComponents.values().stream().map(AbstractComponent::getType) - .map(ChannelGroupType::getChannelDefinitions).flatMap(List::stream) + .filter(Objects::nonNull).map(Objects::requireNonNull).collect(Collectors.toList()); + channelDefs = haComponents.values().stream().map(AbstractComponent::getChannels).flatMap(List::stream) .collect(Collectors.toList()); } ThingType thingType = channelTypeProvider.derive(typeID, MqttBindingConstants.HOMEASSISTANT_MQTT_THING) diff --git a/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/HomeAssistantMQTTImplementationTest.java b/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/HomeAssistantMQTTImplementationTest.java index 4bf6be8374ce3..c514b3159e4ee 100644 --- a/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/HomeAssistantMQTTImplementationTest.java +++ b/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/HomeAssistantMQTTImplementationTest.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; @@ -160,7 +161,8 @@ public void parseHATree() throws Exception { ComponentDiscovered cd = (haID, c) -> { haComponents.put(c.getGroupUID().getId(), c); c.addChannelTypes(channelTypeProvider); - channelTypeProvider.setChannelGroupType(c.getGroupTypeUID(), c.getType()); + channelTypeProvider.setChannelGroupType(Objects.requireNonNull(c.getGroupTypeUID()), + Objects.requireNonNull(c.getType())); latch.countDown(); };