Skip to content

Commit f64cb0b

Browse files
authored
[MQTT] Fix state description (openhab#16866)
* fix state description Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
1 parent cc71808 commit f64cb0b

File tree

5 files changed

+49
-37
lines changed

5 files changed

+49
-37
lines changed

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

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.openhab.core.library.types.DateTimeType;
2222
import org.openhab.core.library.types.StringType;
2323
import org.openhab.core.types.Command;
24+
import org.openhab.core.types.StateDescriptionFragmentBuilder;
2425

2526
/**
2627
* Implements a datetime value.
@@ -50,4 +51,10 @@ public String getMQTTpublishValue(Command command, @Nullable String pattern) {
5051
}
5152
return String.format(formatPattern, ((DateTimeType) command).getZonedDateTime());
5253
}
54+
55+
@Override
56+
public StateDescriptionFragmentBuilder createStateDescription(boolean readOnly) {
57+
return StateDescriptionFragmentBuilder.create().withReadOnly(readOnly)
58+
.withPattern("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS");
59+
}
5360
}

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

+11-10
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.openhab.core.library.types.QuantityType;
2626
import org.openhab.core.library.types.StringType;
2727
import org.openhab.core.library.types.UpDownType;
28-
import org.openhab.core.library.unit.Units;
2928
import org.openhab.core.types.Command;
3029
import org.openhab.core.types.StateDescriptionFragmentBuilder;
3130
import org.openhab.core.types.Type;
@@ -53,16 +52,16 @@ public class NumberValue extends Value {
5352
private final @Nullable BigDecimal min;
5453
private final @Nullable BigDecimal max;
5554
private final BigDecimal step;
56-
private final Unit<?> unit;
55+
private final @Nullable Unit<?> unit;
5756

5857
public NumberValue(@Nullable BigDecimal min, @Nullable BigDecimal max, @Nullable BigDecimal step,
5958
@Nullable Unit<?> unit) {
60-
super(CoreItemFactory.NUMBER,
61-
List.of(QuantityType.class, IncreaseDecreaseType.class, UpDownType.class, StringType.class));
59+
super(CoreItemFactory.NUMBER, List.of(DecimalType.class, QuantityType.class, IncreaseDecreaseType.class,
60+
UpDownType.class, StringType.class));
6261
this.min = min;
6362
this.max = max;
6463
this.step = step == null ? BigDecimal.ONE : step;
65-
this.unit = unit != null ? unit : Units.ONE;
64+
this.unit = unit;
6665
}
6766

6867
protected boolean checkConditions(BigDecimal newValue) {
@@ -116,7 +115,8 @@ public Command parseCommand(Command command) throws IllegalArgumentException {
116115
}
117116
// items with units specified in the label in the UI but no unit on mqtt are stored as
118117
// DecimalType to avoid conversions (e.g. % expects 0-1 rather than 0-100)
119-
if (!Units.ONE.equals(unit)) {
118+
Unit<?> unit = this.unit;
119+
if (unit != null) {
120120
return new QuantityType<>(newValue, unit);
121121
} else {
122122
return new DecimalType(newValue);
@@ -147,7 +147,8 @@ private BigDecimal getOldValue() {
147147

148148
private BigDecimal getQuantityTypeAsDecimal(QuantityType<?> qType) {
149149
BigDecimal val = qType.toBigDecimal();
150-
if (!qType.getUnit().isCompatible(Units.ONE)) {
150+
Unit<?> unit = this.unit;
151+
if (unit != null) {
151152
QuantityType<?> convertedType = qType.toInvertibleUnit(unit);
152153
if (convertedType != null) {
153154
val = convertedType.toBigDecimal();
@@ -167,10 +168,10 @@ public StateDescriptionFragmentBuilder createStateDescription(boolean readOnly)
167168
if (min != null) {
168169
builder = builder.withMinimum(min);
169170
}
170-
if (!unit.equals(Units.ONE)) {
171-
builder.withPattern("%s " + unit);
171+
if (unit != null) {
172+
builder.withPattern("%.0f %unit%");
172173
} else {
173-
builder.withPattern("%s %unit%");
174+
builder.withPattern("%.0f");
174175
}
175176
return builder.withStep(step);
176177
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,6 @@ public String getMQTTpublishValue(Command command, @Nullable String pattern) {
152152
@Override
153153
public StateDescriptionFragmentBuilder createStateDescription(boolean readOnly) {
154154
return super.createStateDescription(readOnly).withMaximum(HUNDRED).withMinimum(BigDecimal.ZERO).withStep(step)
155-
.withPattern("%s %%");
155+
.withPattern("%.0f %%");
156156
}
157157
}

bundles/org.openhab.binding.mqtt.generic/src/test/java/org/openhab/binding/mqtt/generic/values/ValueTests.java

+29-25
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import org.openhab.core.library.unit.MetricPrefix;
3636
import org.openhab.core.library.unit.Units;
3737
import org.openhab.core.types.Command;
38-
import org.openhab.core.types.State;
3938
import org.openhab.core.types.TypeParser;
4039
import org.openhab.core.types.UnDefType;
4140

@@ -70,17 +69,17 @@ public void textStateUpdate() {
7069
@Test
7170
public void colorUpdate() {
7271
ColorValue v = new ColorValue(ColorMode.RGB, "fancyON", "fancyOFF", 77);
73-
v.update((State) v.parseCommand(p(v, "255,255,255")));
72+
v.update(v.parseCommand(p(v, "255,255,255")));
7473

75-
HSBType hsb = (HSBType) v.parseCommand(p(v, "OFF"));
74+
HSBType hsb = v.parseCommand(p(v, "OFF"));
7675
assertThat(hsb.getBrightness().intValue(), is(0));
7776
v.update(hsb);
78-
hsb = (HSBType) v.parseCommand(p(v, "ON"));
77+
hsb = v.parseCommand(p(v, "ON"));
7978
assertThat(hsb.getBrightness().intValue(), is(77));
8079

81-
hsb = (HSBType) v.parseCommand(p(v, "0"));
80+
hsb = v.parseCommand(p(v, "0"));
8281
assertThat(hsb.getBrightness().intValue(), is(0));
83-
hsb = (HSBType) v.parseCommand(p(v, "1"));
82+
hsb = v.parseCommand(p(v, "1"));
8483
assertThat(hsb.getBrightness().intValue(), is(1));
8584

8685
assertThat(v.parseMessage(new StringType("")), is(UnDefType.NULL));
@@ -218,8 +217,13 @@ public void numberPercentageUpdate() {
218217
assertThat(command, is(new QuantityType<>(20, Units.PERCENT)));
219218
assertThat(v.getMQTTpublishValue(command, null), is("20"));
220219

221-
// Test with command without units
222-
command = v.parseCommand(new QuantityType<>("20"));
220+
// Test with command with units.ONE
221+
command = v.parseCommand(new QuantityType<>("0.2"));
222+
assertThat(command, is(new QuantityType<>(20, Units.PERCENT)));
223+
assertThat(v.getMQTTpublishValue(command, null), is("20"));
224+
225+
// Test with command with DecimalType
226+
command = v.parseCommand(new DecimalType(20));
223227
assertThat(command, is(new QuantityType<>(20, Units.PERCENT)));
224228
assertThat(v.getMQTTpublishValue(command, null), is("20"));
225229
}
@@ -241,7 +245,7 @@ public void rollershutterUpdateWithStrings() {
241245

242246
// Test with exact percent
243247
Command command = new PercentType(27);
244-
assertThat(v.parseCommand((Command) command), is(command));
248+
assertThat(v.parseCommand(command), is(command));
245249
assertThat(v.getMQTTpublishValue(command, null), is("27"));
246250

247251
// Test formatting 0/100
@@ -272,7 +276,7 @@ public void rollershutterUpdateWithDiscreteCommandAndStateStrings() {
272276

273277
// Test with exact percent
274278
Command command = new PercentType(27);
275-
assertThat(v.parseCommand((Command) command), is(command));
279+
assertThat(v.parseCommand(command), is(command));
276280
assertThat(v.getMQTTpublishValue(command, null), is("27"));
277281

278282
// Test formatting 0/100
@@ -338,7 +342,7 @@ public void decimalCalc() {
338342
null, null);
339343
assertThat(v.parseCommand(new DecimalType(1.0)), is(PercentType.HUNDRED));
340344
assertThat(v.parseCommand(new DecimalType(0.1)), is(PercentType.ZERO));
341-
PercentType command = (PercentType) v.parseCommand(new DecimalType(0.2));
345+
PercentType command = v.parseCommand(new DecimalType(0.2));
342346
assertEquals(command.floatValue(), 11.11f, 0.01f);
343347
}
344348

@@ -348,26 +352,26 @@ public void increaseDecreaseCalc() {
348352
null, null);
349353

350354
// Normal operation.
351-
PercentType command = (PercentType) v.parseCommand(new DecimalType("6.0"));
355+
PercentType command = v.parseCommand(new DecimalType("6.0"));
352356
assertEquals(command.floatValue(), 50.0f, 0.01f);
353357
v.update(command);
354-
command = (PercentType) v.parseCommand(IncreaseDecreaseType.INCREASE);
358+
command = v.parseCommand(IncreaseDecreaseType.INCREASE);
355359
assertEquals(command.floatValue(), 55.0f, 0.01f);
356-
command = (PercentType) v.parseCommand(IncreaseDecreaseType.DECREASE);
360+
command = v.parseCommand(IncreaseDecreaseType.DECREASE);
357361
assertEquals(command.floatValue(), 45.0f, 0.01f);
358362

359363
// Lower limit.
360-
command = (PercentType) v.parseCommand(new DecimalType("1.1"));
364+
command = v.parseCommand(new DecimalType("1.1"));
361365
assertEquals(command.floatValue(), 1.0f, 0.01f);
362366
v.update(command);
363-
command = (PercentType) v.parseCommand(IncreaseDecreaseType.DECREASE);
367+
command = v.parseCommand(IncreaseDecreaseType.DECREASE);
364368
assertEquals(command.floatValue(), 0.0f, 0.01f);
365369

366370
// Upper limit.
367-
command = (PercentType) v.parseCommand(new DecimalType("10.8"));
371+
command = v.parseCommand(new DecimalType("10.8"));
368372
assertEquals(command.floatValue(), 98.0f, 0.01f);
369373
v.update(command);
370-
command = (PercentType) v.parseCommand(IncreaseDecreaseType.INCREASE);
374+
command = v.parseCommand(IncreaseDecreaseType.INCREASE);
371375
assertEquals(command.floatValue(), 100.0f, 0.01f);
372376
}
373377

@@ -377,26 +381,26 @@ public void upDownCalc() {
377381
null, null);
378382

379383
// Normal operation.
380-
PercentType command = (PercentType) v.parseCommand(new DecimalType("6.0"));
384+
PercentType command = v.parseCommand(new DecimalType("6.0"));
381385
assertEquals(command.floatValue(), 50.0f, 0.01f);
382386
v.update(command);
383-
command = (PercentType) v.parseCommand(UpDownType.UP);
387+
command = v.parseCommand(UpDownType.UP);
384388
assertEquals(command.floatValue(), 55.0f, 0.01f);
385-
command = (PercentType) v.parseCommand(UpDownType.DOWN);
389+
command = v.parseCommand(UpDownType.DOWN);
386390
assertEquals(command.floatValue(), 45.0f, 0.01f);
387391

388392
// Lower limit.
389-
command = (PercentType) v.parseCommand(new DecimalType("1.1"));
393+
command = v.parseCommand(new DecimalType("1.1"));
390394
assertEquals(command.floatValue(), 1.0f, 0.01f);
391395
v.update(command);
392-
command = (PercentType) v.parseCommand(UpDownType.DOWN);
396+
command = v.parseCommand(UpDownType.DOWN);
393397
assertEquals(command.floatValue(), 0.0f, 0.01f);
394398

395399
// Upper limit.
396-
command = (PercentType) v.parseCommand(new DecimalType("10.8"));
400+
command = v.parseCommand(new DecimalType("10.8"));
397401
assertEquals(command.floatValue(), 98.0f, 0.01f);
398402
v.update(command);
399-
command = (PercentType) v.parseCommand(UpDownType.UP);
403+
command = v.parseCommand(UpDownType.UP);
400404
assertEquals(command.floatValue(), 100.0f, 0.01f);
401405
}
402406

bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/SensorTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public void test() throws InterruptedException {
7777
publishMessage("zigbee2mqtt/sensor/state", "20");
7878
assertState(component, Sensor.SENSOR_CHANNEL_ID, new QuantityType<>(20, Units.WATT));
7979
assertThat(component.getChannel(Sensor.SENSOR_CHANNEL_ID).getState().getCache().createStateDescription(true)
80-
.build().getPattern(), is("%s W"));
80+
.build().getPattern(), is("%.0f %unit%"));
8181

8282
waitForAssert(() -> assertState(component, Sensor.SENSOR_CHANNEL_ID, UnDefType.UNDEF), 5000, 200);
8383

0 commit comments

Comments
 (0)