Display Decimal as Percent

So I’m trying to incorporate Plantlink into OpenHAB, using their API and I’ve run into a odd problem. The JSON output for a plant’s moisture level is in a decimal format like this: 0.23999999999999999

I feel like a noob asking, but how would I convert this to 23%?
Would a rule handle this conversion, or is it simply a formatting issue in my items file?

Thanks in advance.

Maybe use a transform in your binding if supported, like JS(topct.js).

transform/topct.js:

result = parseInt(input*100)

or

result = Math.round(input*100)

Thanks @watou but I’m wondering, could I use this in conjunction with JSONPATH? Any idea how I would format the binding string?

Here’s one of the entires, with my api key xxx’d out:

Number Plant0_Moisture_Test     "Plant 1 Moisture Test [%d %%]"         (Patio) { http="<[https://dashboard.myplantlink.com/api/v1/plants/XXXX{authorization=Basic XXXXXXXXXXXXXXXXXXXXXXXXX}:3600000:JSONPATH($..last_measurements.moisture[0])]" }

I tried this, but it threw an error:

Number Plant0_Moisture_Test     "Plant 1 Moisture Test [%d %%]"         (Patio) { http="<[https://dashboard.myplantlink.com/api/v1/plants/XXXX{authorization=Basic XXXXXXXXXXXXXXXXXXXXXXXXX}:3600000:JSONPATH($..last_measurements.moisture[0]:JS(topct.js))]" }

Got any ideas?

Ah! You just want it to display as a percentage? Then you can use a transform in the state placeholder, like this:

Number Plant0_Moisture_Test     "Plant 1 Moisture Test [JS(topct.js):%d %%]"         (Patio) { http="<[https://dashboard.myplantlink.com/api/v1/plants/XXXX{authorization=Basic XXXXXXXXXXXXXXXXXXXXXXXXX}:3600000:JSONPATH($..last_measurements.moisture[0])]" }

The item’s state will continue to be a fraction of 1, but it will be formatted via the transform to be a fraction of 100. See here.

1 Like

Thanks again @watou for the help!

I think the transform in the state placeholder would work for now, but is there a way to convert and store the item’s state as a percentage? In the long term I think a percentage would be a lot more useful, as I can build rules based on the percentage, and not have to worry about the decimal length or value. From what I’ve read in their documentation a value such as: 0.23999999999999999 would never be 1.xxxxx.

The JSONPATH transform used to extract the field from the JSON output does not provide additional transformation abilities, like multiplying the value by 100, and only one transform can be given to the HTTP binding (they can’t be chained together). And since you want the actual value transformed, not just how it appears in the UI, you would have to use a proxy item/rule.

You would want an item type that accepts DecimalType state updates (and PercentType is a subclass of DecimalType, so PercentType is a DecimalType). For example,

Number Plant0_Moisture_Percent "Plant 1 Moisture Percent [%.2f %%]"

then you want a rule that will update it when the decimal state changes:

import org.openhab.core.library.types.*   // only needed on openHAB 1.x

rule UpdatePercent
when
  Item Plant0_Moisture_Test changed
then
  val DecimalType pct = new DecimalType((Plant0_Moisture_Test.state as DecimalType) * 100)
  Plant0_Moisture_Percent.postUpdate(pct)
end

So I tried to display the value as a % using the JS above, and got the following error:

2016-07-10 13:13:39.474 [WARN ] [o.u.i.items.ItemUIRegistryImpl] - Exception while formatting value '0.40914484766799719' of item Plant0_Moisture_Percent with format 'JS(topct.js):%d %%': java.util.IllegalFormatConversionException: d != java.math.BigDecimal

Next I’ll try the proxy rule/item option. Would I need to have a separate rule for each item? I currently have 7 sensors (0-6), so would that be 7 rules?

Thanks for all the help!

%d is only for whole numbers. You would have to use a floating point format like %.2f instead. Then the exception you noted won’t occur.

The most direct solution for the proxy item/rule approach would require a separate rule for each conversion you want to do.

Sweet, thanks @watou that’s exactly what I wanted! The proxy item/rule works great. I’ll reproduce it 6 more times for the rest of my plants. Thanks for all the help!

Now I just need to figure out how to convert epoch time to a DateTime I understand…