Skip to content

Commit

Permalink
[mqtt] Treat incoming empty string as UNDEF for most types
Browse files Browse the repository at this point in the history
Signed-off-by: Cody Cutrer <[email protected]>
  • Loading branch information
ccutrer committed Nov 19, 2023
1 parent b4d7cf6 commit d17d712
Show file tree
Hide file tree
Showing 16 changed files with 126 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ public void addAvailabilityTopic(String availability_topic, String payload_avail
@Nullable TransformationServiceProvider transformationServiceProvider) {
availabilityStates.computeIfAbsent(availability_topic, topic -> {
Value value = new OnOffValue(payload_available, payload_not_available);
value.setUndefValue("");
ChannelGroupUID groupUID = new ChannelGroupUID(getThing().getUID(), "availability");
ChannelUID channelUID = new ChannelUID(groupUID, UIDUtils.encode(topic));
ChannelState state = new ChannelState(ChannelConfigBuilder.create().withStateTopic(topic).build(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class ChannelConfig {
/** If true, the state topic will not update a state, but trigger a channel instead. */
public boolean trigger = false;
public String unit = "";
public boolean emptyStringIsUndef = true;

public String transformationPattern = "";
public String transformationPatternOut = "";
Expand All @@ -57,6 +58,7 @@ public class ChannelConfig {
public @Nullable String stop;
public @Nullable String onState;
public @Nullable String offState;
public @Nullable String undefValue;

public int onBrightness = 10;
public String colorMode = ColorMode.HSB.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ public Command parseCommand(Command command) throws IllegalArgumentException {

@Override
public Type parseMessage(Command command) throws IllegalArgumentException {
if (command instanceof StringType && command.toString().equalsIgnoreCase(NAN)) {
if (command instanceof StringType
&& (command.toString().equalsIgnoreCase(NAN) || command.toString().equals(undefValue))) {
return UnDefType.UNDEF;
}
return parseCommand(command);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.openhab.core.library.types.StringType;
import org.openhab.core.library.types.UpDownType;
import org.openhab.core.types.Command;
import org.openhab.core.types.Type;
import org.openhab.core.types.UnDefType;

/**
* Implements a rollershutter value.
Expand Down Expand Up @@ -134,6 +136,9 @@ public Command parseCommand(Command command) throws IllegalArgumentException {

@Override
public Type parseMessage(Command command) throws IllegalArgumentException {
if (command instanceof StringType string && string.toString().equals(undefValue)) {
return UnDefType.UNDEF;
}
command = parseType(command, upStateString, downStateString);
if (inverted && command instanceof PercentType percentType) {
return new PercentType(100 - percentType.intValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.openhab.core.types.CommandOption;
import org.openhab.core.types.StateDescriptionFragmentBuilder;
import org.openhab.core.types.StateOption;
import org.openhab.core.types.Type;
import org.openhab.core.types.UnDefType;

/**
* Implements a text/string value. Allows to restrict the incoming value to a set of states.
Expand Down Expand Up @@ -91,7 +93,11 @@ public StringType parseCommand(Command command) throws IllegalArgumentException
}

@Override
public StringType parseMessage(Command command) throws IllegalArgumentException {
public Type parseMessage(Command command) throws IllegalArgumentException {
if (command instanceof StringType string && string.toString().equals(undefValue)) {
return UnDefType.UNDEF;
}

final Set<String> states = this.states;
String valueStr = command.toString();
if (states != null && !states.contains(valueStr)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.RawType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.types.Command;
import org.openhab.core.types.CommandDescriptionBuilder;
import org.openhab.core.types.State;
Expand Down Expand Up @@ -54,13 +55,18 @@
public abstract class Value {
protected State state = UnDefType.UNDEF;
protected final List<Class<? extends Command>> commandTypes;
protected @Nullable String undefValue = null;
private final String itemType;

protected Value(String itemType, List<Class<? extends Command>> commandTypes) {
this.itemType = itemType;
this.commandTypes = commandTypes;
}

public void setUndefValue(@Nullable String undefValue) {
this.undefValue = undefValue;
}

/**
* Return a list of supported command types. The order of the list is important.
* <p>
Expand Down Expand Up @@ -147,6 +153,9 @@ public void update(State newState) throws IllegalArgumentException {
* @exception IllegalArgumentException Thrown if for example a text is assigned to a number type.
*/
public Type parseMessage(Command command) throws IllegalArgumentException {
if (command instanceof StringType string && string.toString().equals(undefValue)) {
return UnDefType.UNDEF;
}
return parseCommand(command);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ public static Value createValueState(ChannelConfig config, String channelTypeID)
default:
throw new IllegalArgumentException("ChannelTypeUID not recognised: " + channelTypeID);
}

if (config.emptyStringIsUndef) {
value.setUndefValue("");
} else {
value.setUndefValue(config.undefValue);
}
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@
<default>false</default>
<advanced>true</advanced>
</parameter>
<parameter name="emptyStringIsUndef" type="boolean">
<label>Treat Empty String as UNDEF</label>
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
<default>true</default>
<advanced>true</advanced>
</parameter>

<parameter name="on" type="text">
<label>On/Open Value</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@
<default>false</default>
<advanced>true</advanced>
</parameter>
<parameter name="emptyStringIsUndef" type="boolean">
<label>Treat Empty String as UNDEF</label>
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
<default>true</default>
<advanced>true</advanced>
</parameter>



<parameter name="min" type="decimal">
<label>Absolute Minimum</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@
<default>false</default>
<advanced>true</advanced>
</parameter>
<parameter name="emptyStringIsUndef" type="boolean">
<label>Treat Empty String as UNDEF</label>
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
<default>true</default>
<advanced>true</advanced>
</parameter>

<parameter name="min" type="decimal">
<label>Absolute Minimum</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@
<default>false</default>
<advanced>true</advanced>
</parameter>
<parameter name="emptyStringIsUndef" type="boolean">
<label>Treat Empty String as UNDEF</label>
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
<default>true</default>
<advanced>true</advanced>
</parameter>

<parameter name="on" type="text">
<label>Up Command Value</label>
<description>A string (like "OPEN") that is sent when commanding the rollershutter to open. If not provided, 0 (or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@
<default>false</default>
<advanced>true</advanced>
</parameter>
<parameter name="undefValue" type="text">
<label>UNDEF Value</label>
<description>If the received MQTT value matches this, treat it as UNDEF instead of logging an error and ignoring it.</description>
<advanced>true</advanced>
</parameter>

<parameter name="allowedStates" type="text">
<label>Allowed States</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@
<default>false</default>
<advanced>true</advanced>
</parameter>
<parameter name="emptyStringIsUndef" type="boolean">
<label>Treat Empty String as UNDEF</label>
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
<default>true</default>
<advanced>true</advanced>
</parameter>

<parameter name="on" type="text">
<label>Custom On/Open Value</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ thing-type.config.mqtt.color_channel.colorMode.option.RGB = RGB (Red, Green, Blu
thing-type.config.mqtt.color_channel.colorMode.option.XYY = CIE xyY (x, y, Brightness)
thing-type.config.mqtt.color_channel.commandTopic.label = MQTT Command Topic
thing-type.config.mqtt.color_channel.commandTopic.description = An MQTT topic that this thing will send a command to. If not set, this will be a read-only switch.
thing-type.config.mqtt.color_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
thing-type.config.mqtt.color_channel.emptyStringIsUndef.description = If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.
thing-type.config.mqtt.color_channel.formatBeforePublish.label = Outgoing Value Format
thing-type.config.mqtt.color_channel.formatBeforePublish.description = Format a value before it is published to the MQTT broker. The default is to just pass the channel/item state. If you want to apply a prefix, say "MYCOLOR,", you would use "MYCOLOR,%s". If you want to adjust the precision of a number to for example 4 digits, you would use "%.4f".
thing-type.config.mqtt.color_channel.group.transformations.label = Transform Values
Expand Down Expand Up @@ -69,6 +71,8 @@ thing-type.config.mqtt.color_channel.transformationPatternOut.label = Outgoing V
thing-type.config.mqtt.color_channel.transformationPatternOut.description = Applies a transformation before publishing a MQTT topic value. Transformations are specialised in extracting a value, but some transformations like the MAP one could be useful.
thing-type.config.mqtt.dimmer_channel.commandTopic.label = MQTT Command Topic
thing-type.config.mqtt.dimmer_channel.commandTopic.description = An MQTT topic that this thing will send a command to. If not set, this will be a read-only switch.
thing-type.config.mqtt.dimmer_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
thing-type.config.mqtt.dimmer_channel.emptyStringIsUndef.description = If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.
thing-type.config.mqtt.dimmer_channel.formatBeforePublish.label = Outgoing Value Format
thing-type.config.mqtt.dimmer_channel.formatBeforePublish.description = Format a value before it is published to the MQTT broker. The default is to just pass the channel/item state. If you want to apply a prefix, say "MYCOLOR,", you would use "MYCOLOR,%s". If you want to adjust the precision of a number to for example 4 digits, you would use "%.4f".
thing-type.config.mqtt.dimmer_channel.group.transformations.label = Transform Values
Expand Down Expand Up @@ -100,6 +104,8 @@ thing-type.config.mqtt.dimmer_channel.transformationPatternOut.label = Outgoing
thing-type.config.mqtt.dimmer_channel.transformationPatternOut.description = Applies a transformation before publishing a MQTT topic value. Transformations are specialised in extracting a value, but some transformations like the MAP one could be useful.
thing-type.config.mqtt.number_channel.commandTopic.label = MQTT Command Topic
thing-type.config.mqtt.number_channel.commandTopic.description = An MQTT topic that this thing will send a command to. If not set, this will be a read-only switch.
thing-type.config.mqtt.number_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
thing-type.config.mqtt.number_channel.emptyStringIsUndef.description = If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.
thing-type.config.mqtt.number_channel.formatBeforePublish.label = Outgoing Value Format
thing-type.config.mqtt.number_channel.formatBeforePublish.description = Format a value before it is published to the MQTT broker. The default is to just pass the channel/item state. If you want to apply a prefix, say "MYCOLOR,", you would use "MYCOLOR,%s". If you want to adjust the precision of a number to for example 4 digits, you would use "%.4f".
thing-type.config.mqtt.number_channel.group.transformations.label = Transform Values
Expand Down Expand Up @@ -129,6 +135,8 @@ thing-type.config.mqtt.number_channel.unit.label = Unit Of Measurement
thing-type.config.mqtt.number_channel.unit.description = Unit of measurement (optional). The unit is used for representing the value in the GUI as well as for converting incoming values (like from '°F' to '°C'). Examples: "°C", "°F"
thing-type.config.mqtt.rollershutter_channel.commandTopic.label = MQTT Command Topic
thing-type.config.mqtt.rollershutter_channel.commandTopic.description = An MQTT topic that this thing will send a command to. If not set, this will be a read-only rollershutter.
thing-type.config.mqtt.rollershutter_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
thing-type.config.mqtt.rollershutter_channel.emptyStringIsUndef.description = If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.
thing-type.config.mqtt.rollershutter_channel.formatBeforePublish.label = Outgoing Value Format
thing-type.config.mqtt.rollershutter_channel.formatBeforePublish.description = Format a value before it is published to the MQTT broker. The default is to just pass the channel/item state. If you want to apply a prefix, say "MYCOLOR,", you would use "MYCOLOR,%s". If you want to adjust the precision of a number to for example 4 digits, you would use "%.4f".
thing-type.config.mqtt.rollershutter_channel.group.transformations.label = Transform Values
Expand Down Expand Up @@ -185,8 +193,12 @@ thing-type.config.mqtt.string_channel.transformationPattern.label = Incoming Val
thing-type.config.mqtt.string_channel.transformationPattern.description = Applies transformations to an incoming MQTT topic value. A transformation example for a received JSON would be "JSONPATH:$.device.status.temperature" for a json {device: {status: { temperature: 23.2 }}}. You can chain transformations by separating them with the intersection character ∩.
thing-type.config.mqtt.string_channel.transformationPatternOut.label = Outgoing Value Transformation
thing-type.config.mqtt.string_channel.transformationPatternOut.description = Applies a transformation before publishing a MQTT topic value. Transformations are specialised in extracting a value, but some transformations like the MAP one could be useful.
thing-type.config.mqtt.string_channel.undefValue.label = UNDEF Value
thing-type.config.mqtt.string_channel.undefValue.description = If the received MQTT value matches this, treat it as UNDEF instead of logging an error and ignoring it.
thing-type.config.mqtt.switch_channel.commandTopic.label = MQTT Command Topic
thing-type.config.mqtt.switch_channel.commandTopic.description = An MQTT topic that this thing will send a command to. If not set, this will be a read-only switch.
thing-type.config.mqtt.switch_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
thing-type.config.mqtt.switch_channel.emptyStringIsUndef.description = If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.
thing-type.config.mqtt.switch_channel.formatBeforePublish.label = Outgoing Value Format
thing-type.config.mqtt.switch_channel.formatBeforePublish.description = Format a value before it is published to the MQTT broker. The default is to just pass the channel/item state. If you want to apply a prefix, say "MYCOLOR,", you would use "MYCOLOR,%s". If you want to adjust the precision of a number to for example 4 digits, you would use "%.4f".
thing-type.config.mqtt.switch_channel.group.transformations.label = Transform Values
Expand Down
Loading

0 comments on commit d17d712

Please sign in to comment.