How to convert MQTT/JSON/Temperature value from Celsius to Fahrenheit

I am receiving a generic MQTT topic with a temperature in the payload in JSON format. The temperature in in Celsius but does not contain a unit. I would like for the Item to be displayed in Fahrenheit, but the Item is displayed in Celsius. With UoM it seems to me this should be straightforward but I’ve searched the forum and tried multiple things with out success. Can someone get me pointed in the right direction?

Payload:

{"battery":81,"humidity":0,"linkquality":136,"soil_moisture":0,"temperature":24.5}

Channel:

Type number : Temperature  "Temperature" 
			[stateTopic="zigbee/SoilMoistureSensor",
			transformationPattern="JSONPATH:$.temperature", unit="°C"]

Item:

Number:Temperature SoilTemperature    "Soil Temperature [%.1f °F]"
	{channel="mqtt:topic:MqttBroker:SoilMoistureSensor:Temperature"}

OH5.0 in Docker on a Synology NAS (Debian). Z-Wave-JS binding.

Thanks

Jim

Maybe you don’t need the “” around the degrees C? This is from the UI code of a generic MQTT thing -id: Nook_Temperature_n
channelTypeUID: mqtt:number
label: Nook Temperature
configuration:
stateTopic: zwave1/Sensors_-_37/sensor_multilevel/endpoint_0/Air_temperature
transformationPattern:

  • JSONPATH:$.value
    unit: °C
Number:Temperature SoilTemperature    "Soil Temperature [%.1f °F]"
	{channel="mqtt:topic:MqttBroker:SoilMoistureSensor:Temperature", unit="°F"}

Removing the quotes from the unit generates a warning in the log and ignores the file.

Configuration model 'MQTT.things' has errors, therefore ignoring it: [27,57]: no viable alternative at input '�' [27,58]: extraneous input 'C' expecting ']' 

@jimtng, I did a cut & past of your suggestion but it generates a warning in the log also.

Unit '�F' could not be parsed to a known unit. Keeping old unit '°F' for item 'SoilTemperature'.

image

FWIW, the code tab for the Thing is:

  - id: Temperature
    channelTypeUID: mqtt:number
    label: Temperature
    configuration:
      retained: false
      postCommand: false
      unit: �C
      formatBeforePublish: "%s"
      step: 1
      stateTopic: zigbee/SoilMoistureSensor
      transformationPattern:
        - JSONPATH:$.temperature

And the item Details Design tab shows:

Type: number

Dimension: Temperature (°F)

Unit: °F

And the Code tab contains

label: Soil Temperature
type: Number:Temperature
icon: ""
groupNames: []
tags: []

for what it is worth here is one of my mqtt for a temp sensor

  - id: temperature
    channelTypeUID: mqtt:number
    label: Temperature
    description: ""
    configuration:
      formatBeforePublish: '"%.3f"'
      stateTopic: zigbee2mqtt/0xa4c1386602fac81d/temperature
      unit: ' "°C"'
```
It correctly converts to Fahrenheit in my item

I typed from phone, the degree symbol is probably not right. Copy paste from the doc.

I tried using the degree symbol from another file that I had and also tried using 0176. Neither made any difference.

mine was copied straight out of code tab note the single quotes space and the double quote degree sign C then double quote then single quote does yours look same when viewing in code tab?

I kinda recall having to play around a bit to make it work correctly.

Mine doesn’t have the apostrophes, but when I try to add them it generates a warning in the log and doesn’t load the thing sfile.

Configuration model 'MQTT.things' has errors, therefore ignoring it: [27,57]: Character ' is neither a decimal digit number, decimal point, nor "e" notation exponential mark.

ok you are using a .things file I configured via UI maybe that is why mine has the single quotes then.

but I seem to recall the extra space was needed at least for mine to work

Without addressing the potential issue with degree symbol, you need to do the following:

  • set the unit property on the Channel to °C (also on my phone so that may not be the right degree symbol). I don’t think you need the quotes and extra space like in @justaoldman’s example
  • set the unit metadata on the Item to °Flike @jimtng showed above

Optionally set the state description metadata to display in °F too, but if you do the other two it will display as that by default anyway.

You must set the unit both places. On the channel to indicate what unit the value comes in as and on the Item to indicate what unit you actually want to use

Here’s the degree symbol you can copy paste °

Please copy paste your current config

I am quite sure @rlkoshak is correct but for mine at least I had to leave the item metadata as °C

and add %.2f °F to state description before it would trigger the UOM to change and display the converted value otherwise it show value in Celsius and added the Fahrenheit symbol to a Celsius value.

But this is also on 4.2.2 version so maybe that is all changed in later versions.

But when looking at it in the item list view it still shows in Celsius as soon as I open the item it is correct, and the values show correct when added to a widget or read from a script.

UOM is so fun… almost as much as getting TOD to behave!

I’m not sure where in the docs I can find the proper degree symbol. I copied one from the List of Units and verified that it is the same as what I have been using (x’B0’).

In the past I’ also needed to have a space before the degree symbol. I tried both with and without the space but that didn’t make any difference.

The thing that seems odd to me is the log message on the item that says

Unit ‘�F’ could not be parsed to a known unit. Keeping old unit ‘°F’ for item ‘SoilTemperature’. 

I looked at the degree symbol from the log message. Oddly, NotePad++ converted the one byte symbol to x’C2B0’. I tried using that for all of the symbols but it did not help. I’m going to post the entire things and items file (they’re short). Maybe someone can see something. (The temperature is at the end of each.)

Bridge mqtt:broker:MqttBroker [ 
       host="192.168.0.11", 
       port="1883", 
       secure=false,
       username="MqttUserid", password="<password>",
       clientID="OpenHab"]
	{
    Thing topic SoilMoistureSensor "Soil Moisture Sensor" [availabilityTopic="zigbee/SoilMoistureSensor/availability", 
	transformationPattern="JSONPATH:$.state", 
	payloadAvailable="online", 
	payloadNotAvailable="offline"] {
    Channels:
        Type string : LWT           "state"
			[stateTopic="zigbee/SoilMoistureSensor/availability",
			transformationPattern="JSONPATH:$.state"]
		Type number : BatteryLevel  "Battery Level" 
			[stateTopic="zigbee/SoilMoistureSensor",
			transformationPattern="JSONPATH:$.battery"]
		Type number : SoilMoisture  "Soil Moisture" 
			[stateTopic="zigbee/SoilMoistureSensor",
			transformationPattern="JSONPATH:$.soil_moisture"]
		Type number : LinkQuality  "Link Quality" 
			[stateTopic="zigbee/SoilMoistureSensor",
			transformationPattern="JSONPATH:$.linkquality"]
		Type string : Temperature  "Temperature" 
			[stateTopic="zigbee/SoilMoistureSensor",
			transformationPattern="JSONPATH:$.temperature", unit="°C", formatBeforePublish="%.1f"]
		}			
	}	
String SoilMoistureLWT  "Soil Moisture Status [%s]" 
	{channel="mqtt:topic:MqttBroker:SoilMoistureSensor:LWT"}
Number SoilMoisture     "Soil Moisture [%d]"
	{channel="mqtt:topic:MqttBroker:SoilMoistureSensor:SoilMoisture"} 
Number SoilBatteryLevel "Soil Battery Level [%d]"
	{channel="mqtt:topic:MqttBroker:SoilMoistureSensor:BatteryLevel"} 	
Number SoilLinkQuality  "Soil Link Quality [%d]"
	{channel="mqtt:topic:MqttBroker:SoilMoistureSensor:LinkQuality"}
Number:Temperature SoilTemperature    "Soil Temperature [%.1f °F]" 
	{channel="mqtt:topic:MqttBroker:SoilMoistureSensor:Temperature", unit=" °F"}

I very much appreciate everyone’s help with this.

Jim

There should be no spaces in

unit="°F"

That didn’t help. Still getting the “Unit ‘�F’ could not be parsed to a known unit. Keeping old unit ‘°F’ for item ‘SoilTemperature’” message in the log.

I think that I’m going to delete and recreate the container tomorrow.

Something must have been off, perhaps the way the unit was defined on the Thing. There’s be no point in the unit metadata otherwise.

Note that if you change the unit metadata on the Item, the unit won’t actually charge until the Item’s state changes. It’s not immediate nor is it applied retroactively. State description changes do apply immediately because that’s applied in the UI on demand.

That’s because the items list view does not apply the state description formatting. What you see there is the actual state of the item. Since the metadata is °C, that’s what you see. Charts will be in °C too. If you set the metadata to °F the Item’s actual state and charts will also be in °F.

I think the root of your problem is using ' "°C"' as the unit on the channel. That’s malformed and I bet the binding is simply delivering the number without a unit and when a plane number is received, the unit of the Item is assumed. So the channel says 20 and the Item becomes 20 °F instead being converted to 68 °F.

You do need a space when using units for the state description, but it’s between the value (e.g %.1f) and the unit. Everywhere else (i.e. the channel config and item metadata) do not add a leading space.

I didn’t realize that. This is a battery device which I believe is only updated every five minutes. In this case does the actual temperature value need to change or is it enough for a new JSON string to be received?