[mqtt.homeassistant] VETO updates to read only channels (#15937)

I.e. Button, Scene, and Binary Sensors.

Also ensure we set up the CommandDescription, since some value types mights use it.

Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
Cody Cutrer 2023-11-25 04:27:05 -07:00 committed by GitHub
parent a13fd80bfe
commit 935415aa6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 11 deletions

View File

@ -33,12 +33,14 @@ import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.binding.builder.ChannelBuilder;
import org.openhab.core.thing.type.AutoUpdatePolicy;
import org.openhab.core.thing.type.ChannelDefinition;
import org.openhab.core.thing.type.ChannelDefinitionBuilder;
import org.openhab.core.thing.type.ChannelType;
import org.openhab.core.thing.type.ChannelTypeBuilder;
import org.openhab.core.thing.type.ChannelTypeUID;
import org.openhab.core.types.Command;
import org.openhab.core.types.CommandDescription;
import org.openhab.core.types.StateDescriptionFragment;
/**
@ -130,6 +132,7 @@ public class ComponentChannel {
private boolean retain;
private boolean trigger;
private boolean isAdvanced;
private @Nullable AutoUpdatePolicy autoUpdatePolicy;
private @Nullable Integer qos;
private @Nullable Predicate<Command> commandFilter;
@ -203,6 +206,11 @@ public class ComponentChannel {
return this;
}
public Builder withAutoUpdatePolicy(@Nullable AutoUpdatePolicy autoUpdatePolicy) {
this.autoUpdatePolicy = autoUpdatePolicy;
return this;
}
public Builder commandFilter(@Nullable Predicate<Command> commandFilter) {
this.commandFilter = commandFilter;
return this;
@ -237,23 +245,26 @@ public class ComponentChannel {
isAdvanced = true;
}
ChannelTypeBuilder typeBuilder;
if (this.trigger) {
type = ChannelTypeBuilder.trigger(channelTypeUID, label)
.withConfigDescriptionURI(URI.create(MqttBindingConstants.CONFIG_HA_CHANNEL))
.isAdvanced(isAdvanced).build();
typeBuilder = ChannelTypeBuilder.trigger(channelTypeUID, label);
} else {
StateDescriptionFragment description = valueState.createStateDescription(commandTopic == null).build();
type = ChannelTypeBuilder.state(channelTypeUID, label, channelState.getItemType())
.withConfigDescriptionURI(URI.create(MqttBindingConstants.CONFIG_HA_CHANNEL))
.withStateDescriptionFragment(description).isAdvanced(isAdvanced).build();
StateDescriptionFragment stateDescription = valueState.createStateDescription(commandTopic == null)
.build();
CommandDescription commandDescription = valueState.createCommandDescription().build();
typeBuilder = ChannelTypeBuilder.state(channelTypeUID, label, channelState.getItemType())
.withStateDescriptionFragment(stateDescription).withCommandDescription(commandDescription);
}
type = typeBuilder.withConfigDescriptionURI(URI.create(MqttBindingConstants.CONFIG_HA_CHANNEL))
.isAdvanced(isAdvanced).build();
Configuration configuration = new Configuration();
configuration.put("config", component.getChannelConfigurationJson());
component.getHaID().toConfig(configuration);
channel = ChannelBuilder.create(channelUID, channelState.getItemType()).withType(channelTypeUID)
.withKind(type.getKind()).withLabel(label).withConfiguration(configuration).build();
.withKind(type.getKind()).withLabel(label).withConfiguration(configuration)
.withAutoUpdatePolicy(autoUpdatePolicy).build();
ComponentChannel result = new ComponentChannel(channelUID, channelState, channel, type, channelTypeUID,
channelStateUpdateListener);

View File

@ -22,6 +22,7 @@ import org.openhab.binding.mqtt.generic.values.Value;
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
import org.openhab.binding.mqtt.homeassistant.internal.listener.ExpireUpdateStateListener;
import org.openhab.binding.mqtt.homeassistant.internal.listener.OffDelayUpdateStateListener;
import org.openhab.core.thing.type.AutoUpdatePolicy;
import com.google.gson.annotations.SerializedName;
@ -72,7 +73,8 @@ public class BinarySensor extends AbstractComponent<BinarySensor.ChannelConfigur
OnOffValue value = new OnOffValue(channelConfiguration.payloadOn, channelConfiguration.payloadOff);
buildChannel(SENSOR_CHANNEL_ID, value, "value", getListener(componentConfiguration, value))
.stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate()).build();
.stateTopic(channelConfiguration.stateTopic, channelConfiguration.getValueTemplate())
.withAutoUpdatePolicy(AutoUpdatePolicy.VETO).build();
}
private ChannelStateUpdateListener getListener(ComponentFactory.ComponentConfiguration componentConfiguration,

View File

@ -16,6 +16,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.mqtt.generic.values.TextValue;
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
import org.openhab.core.thing.type.AutoUpdatePolicy;
import com.google.gson.annotations.SerializedName;
@ -53,6 +54,6 @@ public class Button extends AbstractComponent<Button.ChannelConfiguration> {
buildChannel(BUTTON_CHANNEL_ID, value, getName(), componentConfiguration.getUpdateListener())
.commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(),
channelConfiguration.getQos())
.build();
.withAutoUpdatePolicy(AutoUpdatePolicy.VETO).build();
}
}

View File

@ -16,6 +16,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.mqtt.generic.values.TextValue;
import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration;
import org.openhab.core.thing.type.AutoUpdatePolicy;
import com.google.gson.annotations.SerializedName;
@ -51,6 +52,6 @@ public class Scene extends AbstractComponent<Scene.ChannelConfiguration> {
buildChannel(SCENE_CHANNEL_ID, value, getName(), componentConfiguration.getUpdateListener())
.commandTopic(channelConfiguration.commandTopic, channelConfiguration.isRetain(),
channelConfiguration.getQos())
.build();
.withAutoUpdatePolicy(AutoUpdatePolicy.VETO).build();
}
}

View File

@ -16,12 +16,14 @@ import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.Objects;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
import org.openhab.binding.mqtt.generic.values.TextValue;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.type.AutoUpdatePolicy;
/**
* Tests for {@link Button}
@ -57,6 +59,8 @@ public class ButtonTests extends AbstractComponentTests {
assertChannel(component, Button.BUTTON_CHANNEL_ID, "", "esphome/single-car-gdo/button/restart/command",
"Restart", TextValue.class);
assertThat(Objects.requireNonNull(component.getChannel(Button.BUTTON_CHANNEL_ID)).getChannel()
.getAutoUpdatePolicy(), is(AutoUpdatePolicy.VETO));
assertThrows(IllegalArgumentException.class,
() -> component.getChannel(Button.BUTTON_CHANNEL_ID).getState().publishValue(new StringType("ON")));