Defining a channel reporting PPM

I want to support a channel, which reports the Gas Concentration in PPM (parts per million)

I defined the channel as follows:

	<channel-type id="sensorPPM">
		<item-type>Number:Dimensionless</item-type>
		<label>@text/channel-type.shelly.sensorPPM.label</label>
		<description>@text/channel-type.shelly.sensorPPM.description</description>
		<category>Gas</category>
		<tags>
			<tag>Measurement</tag>
			<tag>Gas</tag>
		</tags>
		<state readOnly="true" pattern="%.0f %unit%">
		</state>
	</channel-type>

The channel is updated using Units.PARTS_PER_MILLION
as a result the value is displayed without a unit even %unit% is defined

Is Number:Dimensionless the correct itemType?

Yes, but you will need to post it a Quantity with units. So far as I know the pattern here would be “ppm” i.e. not “PPM”
I think it’s the part of your binding that is posting the value updates that needs attention, not the definition.

Number:Dimensionless will happily accept you posting numbers without units, but will assume you meant a ratio like 5-to-1

I already use a quantity update with Unit.xxx), as I do with Volt, kw/h etc.
Usually the framework inserts a proper unit for %unit%, but somehow something is wrong. Vallue shows up, but without unit

Number:Dimensionless types add an extra layer of murkiness to Quantity behaviour, because they are the exception that allows “no units given” to be treated as a valid unit - it is the usually invisible unit “ONE”, meaning ratio as in 5-to-1.

Examples to clarify -
postUpdate “20 °F” to a Number:Temperature type Item, and on most systems the Item state will become “6.666… °C”
Auto-conversion has kicked in - the system default temperature unit for metric OH users is °C, the post was auto-converted to default.
But
If the user modifies the Item with a display format pattern like [%d °F], the ‘conversion’ will be F-to-F and now the updated Item state will be “20 °F”. The system has used the user supplied display format to override the system default unit with a new Item-specific default unit.
Note that this is defined at the Item level, beyond the binding author’s control.

If we post just “20” with no units to the original Item, in the first case we’ll assume the system default and get “20 °C”
If we post just “20” with no units to the modified Item with pattern [%d °F] we’ll get “20 °F”.
Completely different temperatures, but that’s our fault for posting them without units. We must say what we mean i.e. provide units.

Number:Dimensionless is more complicated. You might have units %, ppm. dB, or ratio/ONE - where as mentioned the ONE is usually invisible when formatted. System default for this type is ONE.
I think then if we post “200” to an Item the system will assume you are posting “200 ONE” and be quite happy. but the visible “200” state is not mathematically 200ppm.
Having an Item format pattern like [%d %unit%] won’t affect that, no new default is designated.
I think then if we post “200 ppm” to an Item as above the system will apply auto-conversion to system default and you’ll end up with “0.00002” with an invisible ONE unit, or something like.

What you need is to designate this Item to have a default unit of ppm, using pattern like [%d ppm]
I think you can “suggest” with your XML definition but user changing it is beyond your control.

That would be the system default unit. It goes wrong where there is no system default unit - not al types have defaults.
And in this case it works, but the invisible ONE default is not what you expected.

To circle around, you were right to begin with - put ppm in your XML, not %unit%

So I used a pre-defined UPM (Units.PARTS_PER_MILLION), but it doesn’t derive the “ppm” from it’s definition in org.openhab.core.library.unit includes

 public static final Unit<Dimensionless> PARTS_PER_MILLION = addUnit( new TransformedUnit<>(ONE, MultiplyConverter.ofRational(BigInteger.ONE, BigInteger.valueOf(1000000))));

SimpleUnitFormat.getInstance().label(PARTS_PER_MILLION, "ppm");

I would like to avoid hard coding ppm in the format (pattern). It works with all other using, but ppm. Maybe there is a trick to help the framework formatting dimensionless?

The device reports ppm as Interner (0…65535). Does it means the framework devices this value by 1000000? So 135 will be saved as 0,000135? It’s hard to test, because I don’t have a Gas Alarm :slight_smile:

When I traced such issues back in 2020 for OH 3.0 I realized that %unit% thing is closely related to default measurements defined in openhab system of units. There are two and both miss most of cases. Look at the sources I18nProvider, maybe it will help.