[SOLVED] String::format silently fails (maybe 2.5.0 M3 issue)

No, unfortunately not.

What about this:

	//var String test2 = String::format("%.1f °C", taupunkt_delta)
        var String test2 = "TEST"
        logInfo("TEST", test2)

This one does work. Output as expected.

Ok so now we are sure it’s that line causing problems
Delete it completely
Save the file
Type it in again (Not copy paste) there maybe some hidden stuff in it (Weird I know, it happens…)

I followed your directions but still no change. There must be something wrong with the float formatting because this here

logInfo(logName, "td=" + td + " | taupunkt_delta=" + taupunkt_delta)
var String test1 = String::format("%.1f °C", td)
logInfo(logName, "test1=" + test1)
var String test2 = String::format("%s", taupunkt_delta)
logInfo("TEST", "test2=" + test2)
var String test3 = String::format("%s", taupunkt_delta)
test3 = String::format("%.1f", taupunkt_delta)
logInfo("TEST", "test3=" + test3)

produces the following output (last logInfo not executed):

2019-09-15 12:34:30.009 [INFO ] [me.model.script.myrules.rules] - td=1.2345 | taupunkt_delta=0.2726788936991973
2019-09-15 12:34:30.013 [INFO ] [me.model.script.myrules.rules] - test1=1,2 °C
2019-09-15 12:34:30.018 [INFO ] [.eclipse.smarthome.model.script.TEST] - test2=0.2726788936991973

Very strange.

And if you remove the third one, does the second one still appear?

Possible clue about language formatting (decimal separator)


Yes, that could be an issue. But in a different rule something like this

Klima_Keller.sendCommand(String::format("T=%.1f °C | φ=%.0f%% | td=%.1f °C", t, h, d))
logMessage += String::format("=%.1f °C (T=%.1f °C, φ=%.0f %%)", d, t, h)

works without a flaw.

What happens if you use instead

val taupunkt_delta = Taupunkt_Differenz.state as Number

Rules are bit loose about typing. Either “should” work of course.

This makes no difference, too. The String::format part still fails. I wonder why there are no error messages in the logs. It is just as if the rule will be left at this very point.

Very odd

val taupunkt_delta = Taupunkt_Differenz.state as Number
val td=1.2345

should both result in Number objects, I think?
val Number td=1.2345

Don’t know, all very odd, trying to home in on what breaks it.

Yes, I think so, too.

Still no difference…

I also tried this here:

logInfo("TEST", "Taupunkt_Differenz=" + Taupunkt_Differenz)
logInfo("TEST", "taupunkt_delta=" + taupunkt_delta)
var Number td=1.2345
logInfo("TEST", "td=" + td + " | taupunkt_delta=" + taupunkt_delta)
var String test1 = String::format("%.1f °C", td)
logInfo("TEST", "test1=" + test1)
var String test2 = String::format("%s", taupunkt_delta)
logInfo("TEST", "test2=" + test2)
td = taupunkt_delta
logInfo("TEST", "before test3")
var String test3 = String::format("%.1f °C", td)
logInfo("TEST", "test3=" + test3)
var String test4 = String::format("%.1f °C", taupunkt_delta)
logInfo("TEST", "test4=" + test4)

The log now ends with test #3:

2019-09-15 13:40:42.278 [INFO ] [.eclipse.smarthome.model.script.TEST] - Taupunkt_Differenz=Taupunkt_Differenz (Type=NumberItem, State=0.7088823820515522, Label=Taupunktdifferenz Δtd, Category=humidity, Groups=[Weather, Temperature])
2019-09-15 13:40:42.293 [INFO ] [.eclipse.smarthome.model.script.TEST] - taupunkt_delta=0.7088823820515522
2019-09-15 13:40:42.303 [INFO ] [.eclipse.smarthome.model.script.TEST] - td=1.2345 | taupunkt_delta=0.7088823820515522
2019-09-15 13:40:42.311 [INFO ] [.eclipse.smarthome.model.script.TEST] - test1=1,2 °C
2019-09-15 13:40:42.319 [INFO ] [.eclipse.smarthome.model.script.TEST] - test2=0.7088823820515522
2019-09-15 13:40:42.326 [INFO ] [.eclipse.smarthome.model.script.TEST] - before test3

There must be something wrong with the taupunkt_deltavariable which the format statement does not like.

Longshot; try
td = taupunkt_delta + 1

1 Like

Yes! For whatever reason, this did the trick! Now this approach works:

val Number taupunkt_delta = Taupunkt_Differenz.state as DecimalType + 0 // needed to avoid non-working String::format
var String test = String::format("%.1f °C", taupunkt_delta)
logInfo("myrule.rules", "test=" + test) // now it works!

Many thanks to @rossko57 & @vzorglub for helping me solve it!

Nevertheless I wonder why this happens because it worked before and it is still working in other rules…

Now that’s weird behaviour…

I was worrying about the leading zero maybe followed by comma actually, amazed it works with + 0
Something to do with hidden baggage here. QuantityType issues shouldn’t be coming into play with a plain Number type Item, but it has that feel.

I had a play with this in OH2.4
The good news is an error message appears -
f != org.eclipse.smarthome.core.library.types.DecimalType

As we all probably expected, it’s to do with Java formatter not liking object type passed in.

But first, why did you not get the error message? Something odd about your install, like logging problems or locale, or is it a general OH2.5 issue?
Need an OH2.5 M3 user to try the following out please.

Okay, so a demo rule to show the issue

rule "format state"
   Item nm_test_temp changed
      // Item nm_test_state is defined: Number nm_test_temp "temp [%.1f °C]"
   val teststateA = (nm_test_temp.state as DecimalType).floatValue
   val teststateB = nm_test_temp.state as DecimalType
   logInfo("myrule.rules", "teststateA=" + teststateA.getClass)
   logInfo("myrule.rules", "teststateB=" + teststateB.getClass)
   var String test2 = String::format("%.1f °C", teststateA)
   logInfo("myrule.rules", "A formatted=" + test2)
   var String test3 = String::format("%.1f °C", teststateB)
   logInfo("myrule.rules", "B formatted=" + test3) // this line won't be reached!


2019-09-16 00:33:48.085 [INFO ] [.smarthome.model.script.myrule.rules] - teststateA=class java.lang.Float
2019-09-16 00:33:48.086 [INFO ] [.smarthome.model.script.myrule.rules] - teststateB=class org.eclipse.smarthome.core.library.types.DecimalType
2019-09-16 00:33:48.088 [INFO ] [.smarthome.model.script.myrule.rules] - A formatted=15.5 °C
2019-09-16 00:33:48.090 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'format state': f != org.eclipse.smarthome.core.library.types.DecimalType

So, a java float type (A) satisfies the java String formatter
An openHAB/Eclipse DecimalType does not.

I think the error message is a bit backwards ; at first it seems like it is expecting a org.eclipse.smarthome.core.library.types.DecimalType, but I think the closer meaning is that “f” (as in %.1f) is complaining that it cannot work with DecimalType.

Remembering that String::format is “raw java” and not openHAB-ified, this is perhaps not that surprising after all.

1 Like

Thank you, @rossko57, for your investigations!

I found out that applying this approach by @psyciknz that you mentioned also solved the issue:

// (1) not working original:
// val Number taupunkt_delta = Taupunkt_Differenz.state as DecimalType
// (2) this already satisfies String::format expression:
// val Number taupunkt_delta = Taupunkt_Differenz.state as DecimalType + 0
// (3) providing a floatValue works as well:
val Number taupunkt_delta = (Taupunkt_Differenz.state as DecimalType).floatValue
var String test = String::format("%.1f °C", taupunkt_delta) // fails for (1)
logInfo("myrule.rules", "test=" + test)

I would prefer (3) because MyItem.state as DecimalType + 0 looks quite odd in the code.

I have used my Taupunkt_Differenz item for your snippet. The log reads similar to yours

2019-09-16 06:42:37.715 [INFO ] [.smarthome.model.script.myrule.rules] - teststateA=class java.lang.Float
2019-09-16 06:42:37.721 [INFO ] [.smarthome.model.script.myrule.rules] - teststateB=class org.eclipse.smarthome.core.library.types.DecimalType
2019-09-16 06:42:37.728 [INFO ] [.smarthome.model.script.myrule.rules] - A formatted=2,6 °C
2019-09-16 06:42:37.733 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'format state': f != org.eclipse.smarthome.core.library.types.DecimalType

Now I am wondering why this error message does occur in your demo rule but not in my own code…

1 Like

I have no answer for that, but am reassured that 2.5M3 does produce the error message, and your locale settings don’t stop it either.