Skip to content

Commit d17d712

Browse files
committed
[mqtt] Treat incoming empty string as UNDEF for most types
Signed-off-by: Cody Cutrer <[email protected]>
1 parent b4d7cf6 commit d17d712

File tree

16 files changed

+126
-2
lines changed

16 files changed

+126
-2
lines changed

bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/AbstractMQTTThingHandler.java

+1
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ public void addAvailabilityTopic(String availability_topic, String payload_avail
304304
@Nullable TransformationServiceProvider transformationServiceProvider) {
305305
availabilityStates.computeIfAbsent(availability_topic, topic -> {
306306
Value value = new OnOffValue(payload_available, payload_not_available);
307+
value.setUndefValue("");
307308
ChannelGroupUID groupUID = new ChannelGroupUID(getThing().getUID(), "availability");
308309
ChannelUID channelUID = new ChannelUID(groupUID, UIDUtils.encode(topic));
309310
ChannelState state = new ChannelState(ChannelConfigBuilder.create().withStateTopic(topic).build(),

bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/ChannelConfig.java

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class ChannelConfig {
4343
/** If true, the state topic will not update a state, but trigger a channel instead. */
4444
public boolean trigger = false;
4545
public String unit = "";
46+
public boolean emptyStringIsUndef = true;
4647

4748
public String transformationPattern = "";
4849
public String transformationPatternOut = "";
@@ -57,6 +58,7 @@ public class ChannelConfig {
5758
public @Nullable String stop;
5859
public @Nullable String onState;
5960
public @Nullable String offState;
61+
public @Nullable String undefValue;
6062

6163
public int onBrightness = 10;
6264
public String colorMode = ColorMode.HSB.toString();

bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/values/NumberValue.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ public Command parseCommand(Command command) throws IllegalArgumentException {
120120

121121
@Override
122122
public Type parseMessage(Command command) throws IllegalArgumentException {
123-
if (command instanceof StringType && command.toString().equalsIgnoreCase(NAN)) {
123+
if (command instanceof StringType
124+
&& (command.toString().equalsIgnoreCase(NAN) || command.toString().equals(undefValue))) {
124125
return UnDefType.UNDEF;
125126
}
126127
return parseCommand(command);

bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/values/RollershutterValue.java

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.openhab.core.library.types.StringType;
2323
import org.openhab.core.library.types.UpDownType;
2424
import org.openhab.core.types.Command;
25+
import org.openhab.core.types.Type;
26+
import org.openhab.core.types.UnDefType;
2527

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

135137
@Override
136138
public Type parseMessage(Command command) throws IllegalArgumentException {
139+
if (command instanceof StringType string && string.toString().equals(undefValue)) {
140+
return UnDefType.UNDEF;
141+
}
137142
command = parseType(command, upStateString, downStateString);
138143
if (inverted && command instanceof PercentType percentType) {
139144
return new PercentType(100 - percentType.intValue());

bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/values/TextValue.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.openhab.core.types.CommandOption;
2929
import org.openhab.core.types.StateDescriptionFragmentBuilder;
3030
import org.openhab.core.types.StateOption;
31+
import org.openhab.core.types.Type;
32+
import org.openhab.core.types.UnDefType;
3133

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

9395
@Override
94-
public StringType parseMessage(Command command) throws IllegalArgumentException {
96+
public Type parseMessage(Command command) throws IllegalArgumentException {
97+
if (command instanceof StringType string && string.toString().equals(undefValue)) {
98+
return UnDefType.UNDEF;
99+
}
100+
95101
final Set<String> states = this.states;
96102
String valueStr = command.toString();
97103
if (states != null && !states.contains(valueStr)) {

bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/values/Value.java

+9
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.openhab.core.library.types.DecimalType;
2424
import org.openhab.core.library.types.PercentType;
2525
import org.openhab.core.library.types.RawType;
26+
import org.openhab.core.library.types.StringType;
2627
import org.openhab.core.types.Command;
2728
import org.openhab.core.types.CommandDescriptionBuilder;
2829
import org.openhab.core.types.State;
@@ -54,13 +55,18 @@
5455
public abstract class Value {
5556
protected State state = UnDefType.UNDEF;
5657
protected final List<Class<? extends Command>> commandTypes;
58+
protected @Nullable String undefValue = null;
5759
private final String itemType;
5860

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

66+
public void setUndefValue(@Nullable String undefValue) {
67+
this.undefValue = undefValue;
68+
}
69+
6470
/**
6571
* Return a list of supported command types. The order of the list is important.
6672
* <p>
@@ -147,6 +153,9 @@ public void update(State newState) throws IllegalArgumentException {
147153
* @exception IllegalArgumentException Thrown if for example a text is assigned to a number type.
148154
*/
149155
public Type parseMessage(Command command) throws IllegalArgumentException {
156+
if (command instanceof StringType string && string.toString().equals(undefValue)) {
157+
return UnDefType.UNDEF;
158+
}
150159
return parseCommand(command);
151160
}
152161

bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/values/ValueFactory.java

+6
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ public static Value createValueState(ChannelConfig config, String channelTypeID)
8686
default:
8787
throw new IllegalArgumentException("ChannelTypeUID not recognised: " + channelTypeID);
8888
}
89+
90+
if (config.emptyStringIsUndef) {
91+
value.setUndefValue("");
92+
} else {
93+
value.setUndefValue(config.undefValue);
94+
}
8995
return value;
9096
}
9197
}

bundles/org.openhab.binding.mqtt.generic/src/main/resources/OH-INF/config/color-channel-config.xml

+6
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@
8989
<default>false</default>
9090
<advanced>true</advanced>
9191
</parameter>
92+
<parameter name="emptyStringIsUndef" type="boolean">
93+
<label>Treat Empty String as UNDEF</label>
94+
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
95+
<default>true</default>
96+
<advanced>true</advanced>
97+
</parameter>
9298

9399
<parameter name="on" type="text">
94100
<label>On/Open Value</label>

bundles/org.openhab.binding.mqtt.generic/src/main/resources/OH-INF/config/dimmer-channel-config.xml

+8
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@
7878
<default>false</default>
7979
<advanced>true</advanced>
8080
</parameter>
81+
<parameter name="emptyStringIsUndef" type="boolean">
82+
<label>Treat Empty String as UNDEF</label>
83+
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
84+
<default>true</default>
85+
<advanced>true</advanced>
86+
</parameter>
87+
88+
8189

8290
<parameter name="min" type="decimal">
8391
<label>Absolute Minimum</label>

bundles/org.openhab.binding.mqtt.generic/src/main/resources/OH-INF/config/number-channel-config.xml

+6
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@
7878
<default>false</default>
7979
<advanced>true</advanced>
8080
</parameter>
81+
<parameter name="emptyStringIsUndef" type="boolean">
82+
<label>Treat Empty String as UNDEF</label>
83+
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
84+
<default>true</default>
85+
<advanced>true</advanced>
86+
</parameter>
8187

8288
<parameter name="min" type="decimal">
8389
<label>Absolute Minimum</label>

bundles/org.openhab.binding.mqtt.generic/src/main/resources/OH-INF/config/rollershutter-channel-config.xml

+7
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@
7979
<default>false</default>
8080
<advanced>true</advanced>
8181
</parameter>
82+
<parameter name="emptyStringIsUndef" type="boolean">
83+
<label>Treat Empty String as UNDEF</label>
84+
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
85+
<default>true</default>
86+
<advanced>true</advanced>
87+
</parameter>
88+
8289
<parameter name="on" type="text">
8390
<label>Up Command Value</label>
8491
<description>A string (like "OPEN") that is sent when commanding the rollershutter to open. If not provided, 0 (or

bundles/org.openhab.binding.mqtt.generic/src/main/resources/OH-INF/config/string-channel-config.xml

+5
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@
7878
<default>false</default>
7979
<advanced>true</advanced>
8080
</parameter>
81+
<parameter name="undefValue" type="text">
82+
<label>UNDEF Value</label>
83+
<description>If the received MQTT value matches this, treat it as UNDEF instead of logging an error and ignoring it.</description>
84+
<advanced>true</advanced>
85+
</parameter>
8186

8287
<parameter name="allowedStates" type="text">
8388
<label>Allowed States</label>

bundles/org.openhab.binding.mqtt.generic/src/main/resources/OH-INF/config/switch-channel-config.xml

+6
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@
7878
<default>false</default>
7979
<advanced>true</advanced>
8080
</parameter>
81+
<parameter name="emptyStringIsUndef" type="boolean">
82+
<label>Treat Empty String as UNDEF</label>
83+
<description>If the received MQTT value is empty, treat it as UNDEF instead of logging an error and ignoring it.</description>
84+
<default>true</default>
85+
<advanced>true</advanced>
86+
</parameter>
8187

8288
<parameter name="on" type="text">
8389
<label>Custom On/Open Value</label>

bundles/org.openhab.binding.mqtt.generic/src/main/resources/OH-INF/i18n/mqtt.properties

+12
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ thing-type.config.mqtt.color_channel.colorMode.option.RGB = RGB (Red, Green, Blu
4242
thing-type.config.mqtt.color_channel.colorMode.option.XYY = CIE xyY (x, y, Brightness)
4343
thing-type.config.mqtt.color_channel.commandTopic.label = MQTT Command Topic
4444
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.
45+
thing-type.config.mqtt.color_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
46+
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.
4547
thing-type.config.mqtt.color_channel.formatBeforePublish.label = Outgoing Value Format
4648
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".
4749
thing-type.config.mqtt.color_channel.group.transformations.label = Transform Values
@@ -69,6 +71,8 @@ thing-type.config.mqtt.color_channel.transformationPatternOut.label = Outgoing V
6971
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.
7072
thing-type.config.mqtt.dimmer_channel.commandTopic.label = MQTT Command Topic
7173
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.
74+
thing-type.config.mqtt.dimmer_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
75+
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.
7276
thing-type.config.mqtt.dimmer_channel.formatBeforePublish.label = Outgoing Value Format
7377
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".
7478
thing-type.config.mqtt.dimmer_channel.group.transformations.label = Transform Values
@@ -100,6 +104,8 @@ thing-type.config.mqtt.dimmer_channel.transformationPatternOut.label = Outgoing
100104
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.
101105
thing-type.config.mqtt.number_channel.commandTopic.label = MQTT Command Topic
102106
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.
107+
thing-type.config.mqtt.number_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
108+
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.
103109
thing-type.config.mqtt.number_channel.formatBeforePublish.label = Outgoing Value Format
104110
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".
105111
thing-type.config.mqtt.number_channel.group.transformations.label = Transform Values
@@ -129,6 +135,8 @@ thing-type.config.mqtt.number_channel.unit.label = Unit Of Measurement
129135
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"
130136
thing-type.config.mqtt.rollershutter_channel.commandTopic.label = MQTT Command Topic
131137
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.
138+
thing-type.config.mqtt.rollershutter_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
139+
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.
132140
thing-type.config.mqtt.rollershutter_channel.formatBeforePublish.label = Outgoing Value Format
133141
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".
134142
thing-type.config.mqtt.rollershutter_channel.group.transformations.label = Transform Values
@@ -185,8 +193,12 @@ thing-type.config.mqtt.string_channel.transformationPattern.label = Incoming Val
185193
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 ∩.
186194
thing-type.config.mqtt.string_channel.transformationPatternOut.label = Outgoing Value Transformation
187195
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.
196+
thing-type.config.mqtt.string_channel.undefValue.label = UNDEF Value
197+
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.
188198
thing-type.config.mqtt.switch_channel.commandTopic.label = MQTT Command Topic
189199
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.
200+
thing-type.config.mqtt.switch_channel.emptyStringIsUndef.label = Treat Empty String as UNDEF
201+
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.
190202
thing-type.config.mqtt.switch_channel.formatBeforePublish.label = Outgoing Value Format
191203
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".
192204
thing-type.config.mqtt.switch_channel.group.transformations.label = Transform Values

0 commit comments

Comments
 (0)