[mqtt] Dynamically change accepted item-type for Number channels (#15114)
Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
parent
4fcff61a72
commit
ae146111c1
|
@ -20,6 +20,8 @@ import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.measure.Unit;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.mqtt.generic.AbstractMQTTThingHandler;
|
import org.openhab.binding.mqtt.generic.AbstractMQTTThingHandler;
|
||||||
|
@ -28,6 +30,7 @@ import org.openhab.binding.mqtt.generic.ChannelState;
|
||||||
import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
|
import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
|
||||||
import org.openhab.binding.mqtt.generic.MqttChannelStateDescriptionProvider;
|
import org.openhab.binding.mqtt.generic.MqttChannelStateDescriptionProvider;
|
||||||
import org.openhab.binding.mqtt.generic.TransformationServiceProvider;
|
import org.openhab.binding.mqtt.generic.TransformationServiceProvider;
|
||||||
|
import org.openhab.binding.mqtt.generic.internal.MqttBindingConstants;
|
||||||
import org.openhab.binding.mqtt.generic.utils.FutureCollector;
|
import org.openhab.binding.mqtt.generic.utils.FutureCollector;
|
||||||
import org.openhab.binding.mqtt.generic.values.Value;
|
import org.openhab.binding.mqtt.generic.values.Value;
|
||||||
import org.openhab.binding.mqtt.generic.values.ValueFactory;
|
import org.openhab.binding.mqtt.generic.values.ValueFactory;
|
||||||
|
@ -37,8 +40,12 @@ import org.openhab.core.thing.ChannelUID;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
import org.openhab.core.thing.ThingStatus;
|
import org.openhab.core.thing.ThingStatus;
|
||||||
import org.openhab.core.thing.ThingStatusDetail;
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||||
|
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||||
|
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
||||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||||
import org.openhab.core.types.StateDescription;
|
import org.openhab.core.types.StateDescription;
|
||||||
|
import org.openhab.core.types.util.UnitUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -136,6 +143,15 @@ public class GenericMQTTThingHandler extends AbstractMQTTThingHandler implements
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
initializeAvailabilityTopicsFromConfig();
|
initializeAvailabilityTopicsFromConfig();
|
||||||
|
|
||||||
|
ThingHandlerCallback callback = getCallback();
|
||||||
|
if (callback == null) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "Framework failure: callback must not be null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThingBuilder thingBuilder = editThing();
|
||||||
|
boolean modified = false;
|
||||||
|
|
||||||
List<ChannelUID> configErrors = new ArrayList<>();
|
List<ChannelUID> configErrors = new ArrayList<>();
|
||||||
for (Channel channel : thing.getChannels()) {
|
for (Channel channel : thing.getChannels()) {
|
||||||
final ChannelTypeUID channelTypeUID = channel.getChannelTypeUID();
|
final ChannelTypeUID channelTypeUID = channel.getChannelTypeUID();
|
||||||
|
@ -144,6 +160,31 @@ public class GenericMQTTThingHandler extends AbstractMQTTThingHandler implements
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final ChannelConfig channelConfig = channel.getConfiguration().as(ChannelConfig.class);
|
final ChannelConfig channelConfig = channel.getConfiguration().as(ChannelConfig.class);
|
||||||
|
|
||||||
|
if (channelTypeUID
|
||||||
|
.equals(new ChannelTypeUID(MqttBindingConstants.BINDING_ID, MqttBindingConstants.NUMBER))) {
|
||||||
|
Unit<?> unit = UnitUtils.parseUnit(channelConfig.unit);
|
||||||
|
String dimension = unit == null ? null : UnitUtils.getDimensionName(unit);
|
||||||
|
String expectedItemType = dimension == null ? "Number" : "Number:" + dimension; // unknown dimension ->
|
||||||
|
// Number
|
||||||
|
String actualItemType = channel.getAcceptedItemType();
|
||||||
|
if (!expectedItemType.equals(actualItemType)) {
|
||||||
|
ChannelBuilder channelBuilder = callback.createChannelBuilder(channel.getUID(), channelTypeUID)
|
||||||
|
.withAcceptedItemType(expectedItemType).withConfiguration(channel.getConfiguration());
|
||||||
|
String label = channel.getLabel();
|
||||||
|
if (label != null) {
|
||||||
|
channelBuilder.withLabel(label);
|
||||||
|
}
|
||||||
|
String description = channel.getDescription();
|
||||||
|
if (description != null) {
|
||||||
|
channelBuilder.withDescription(description);
|
||||||
|
}
|
||||||
|
thingBuilder.withoutChannel(channel.getUID());
|
||||||
|
thingBuilder.withChannel(channelBuilder.build());
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Value value = ValueFactory.createValueState(channelConfig, channelTypeUID.getId());
|
Value value = ValueFactory.createValueState(channelConfig, channelTypeUID.getId());
|
||||||
ChannelState channelState = createChannelState(channelConfig, channel.getUID(), value);
|
ChannelState channelState = createChannelState(channelConfig, channel.getUID(), value);
|
||||||
|
@ -159,6 +200,10 @@ public class GenericMQTTThingHandler extends AbstractMQTTThingHandler implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (modified) {
|
||||||
|
updateThing(thingBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
// If some channels could not start up, put the entire thing offline and display the channels
|
// If some channels could not start up, put the entire thing offline and display the channels
|
||||||
// in question to the user.
|
// in question to the user.
|
||||||
if (!configErrors.isEmpty()) {
|
if (!configErrors.isEmpty()) {
|
||||||
|
|
|
@ -70,16 +70,16 @@ public class ThingChannelConstants {
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
THING_CHANNEL_LIST.add(cb("mytext", "TextItemType", textConfiguration(), TEXT_CHANNEL));
|
THING_CHANNEL_LIST.add(cb("mytext", "String", textConfiguration(), TEXT_CHANNEL));
|
||||||
THING_CHANNEL_LIST.add(cb("onoff", "OnOffType", onoffConfiguration(), ON_OFF_CHANNEL));
|
THING_CHANNEL_LIST.add(cb("onoff", "Switch", onoffConfiguration(), ON_OFF_CHANNEL));
|
||||||
THING_CHANNEL_LIST.add(cb("num", "NumberType", numberConfiguration(), NUMBER_CHANNEL));
|
THING_CHANNEL_LIST.add(cb("num", "Number", numberConfiguration(), NUMBER_CHANNEL));
|
||||||
THING_CHANNEL_LIST.add(cb("percent", "NumberType", percentageConfiguration(), PERCENTAGE_CHANNEL));
|
THING_CHANNEL_LIST.add(cb("percent", "Number:Dimensionless", percentageConfiguration(), PERCENTAGE_CHANNEL));
|
||||||
|
|
||||||
|
THING_CHANNEL_LIST_WITH_JSON.add(cb("mytext", "String", textConfigurationWithJson(), TEXT_WITH_JSON_CHANNEL));
|
||||||
|
THING_CHANNEL_LIST_WITH_JSON.add(cb("onoff", "Switch", onoffConfiguration(), ON_OFF_CHANNEL));
|
||||||
|
THING_CHANNEL_LIST_WITH_JSON.add(cb("num", "Number", numberConfiguration(), NUMBER_CHANNEL));
|
||||||
THING_CHANNEL_LIST_WITH_JSON
|
THING_CHANNEL_LIST_WITH_JSON
|
||||||
.add(cb("mytext", "TextItemType", textConfigurationWithJson(), TEXT_WITH_JSON_CHANNEL));
|
.add(cb("percent", "Number:Dimensionless", percentageConfiguration(), PERCENTAGE_CHANNEL));
|
||||||
THING_CHANNEL_LIST_WITH_JSON.add(cb("onoff", "OnOffType", onoffConfiguration(), ON_OFF_CHANNEL));
|
|
||||||
THING_CHANNEL_LIST_WITH_JSON.add(cb("num", "NumberType", numberConfiguration(), NUMBER_CHANNEL));
|
|
||||||
THING_CHANNEL_LIST_WITH_JSON.add(cb("percent", "NumberType", percentageConfiguration(), PERCENTAGE_CHANNEL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Configuration textConfiguration() {
|
static Configuration textConfiguration() {
|
||||||
|
|
Loading…
Reference in New Issue