-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[mqtt] Faulty display of an linked item using Units of Measurement. #10338
Comments
This issue has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/mqtt-unit-of-measurement-faulty-behaviour/118946/17 |
This issue has been mentioned on openHAB Community. There might be relevant details there: |
The short version of the problem description is that the binding is posting just a number via the channel, and forgetting to append the given unit. |
Debatable if this is a bug or an enhancement. Looking at the code it seems that the unit is only honored for outgoing values (the command to the channel is converted to the unit in the channel config, so if you configure °C and send °F, the value is converted to °C and then send to the broker). The unit isn't considered for incoming values (i.e. values received from MQTT, they are always posted as DecimalType). IIRC it was delibaretly done that way because it would require a bigger refactoring to fully enable UoM in MQTT. |
In view of what you discribed the display of the "Degree value with the Fahrenheit sign" would be explained, but what about the initially displayed converted (Fahrenheit) value? |
No, that's explainable. What happens if you send a DecimalType is that the Item tries to determine the unit from the state description: So if the state description reports °F, the new value is set as °F. Before the first update the state description is probably not set (not sure about that) and the default unit (°C) is used, so the value set for the item is 16°C. .If you set the state desciption the display changes (correctly) to 60 °F. With the next update the state description is °F and the number 16 is send as 16 °F. |
I'm sorry but the actual code is above my humble java knowledge! |
I guess you could set something like
|
Yes, you did. In your original forum post,before applying pattern -
The binding did not supply °C, it was picked up by the framework as the system default unit appropriate for a Number:Temperature type Item, What does "default unit" mean? If you post a number with NO units (as the binding currently does) then it assumes you meant °C That's all working as designed - except for the binding not appending the unit you told it. I can't believe the MQTT channel unit parameter was only intended for outgoing. That's really pointless, as its easily done with a "format before sending" in any case. |
@Rossko57 Looking at the procedure I think the problem is between step 6 and 7. IMHO the " convert if necessary " should be applied. |
@Rossko57 No, it doesn't "only append" the unit. It converts the value of the item to that unit before sending. So if the item's state is 60.8 °F, the value is converted to 16°C before sending. @JueBag Step 6 is a final step, we never get to step 7. Values received from MQTT are send as To both of you: I fully agree that this is an unexpected behaviour and not clearly documented. And the correct solution would be to add the missing code. But as so said: that could be not full straight forward. |
Sure. But we're talking about incoming data here. In this case, numeric only. "We" the user/configurer knows that represents F or whatever, and wishes to add that info to the incoming data. In other words, add " °F" to the numeric to create a Quantity, ready for use updating a Number:Temperature Item. |
Fully agreed. The problem is that we would need to assign the correct „accepted item type“ dynamically depending on the selected unit, i.e. we would need to change the channel-type when configuration changes. That can be done but finding the correct dimension (like temperature, pressure) from the given unit is not trivial. Just posting a QuantityType will probably work but could end up with unsupported unit errors. |
I "see" that it not only appends the unit. For me the problem boils down to: In case of (1) the set of a State Description pattern does trigger a complete conversion to the desired unit. Looking at the linked code I'd say in case of (1) the state is recognized as a QunatityType ,in case of (2) it isn't. |
I believe this works fine in recent Modbus binding, with just a number type channel linked to Number:type of user's choice. The binding creates a Quantity from raw numeric data and user-designated "unit" parameter. I do not know if Modbus specifically allows all Number:xxx Item types as "accepted", or just takes advantage of lax policing when creating links. EDIT -duh, Opus has already linked his plain number type MQTT channel to a Number:Temperature Item, so I guess there is no practical problem here. |
I'm not sure what's troubling you here. Let's work through it. Next you come along and set Item option pattern "°F". Later. along comes the binding with another update, it's still just "16" The UI still uses the pattern, does the no-operation conversion °F to °F, and displays "16 °F" You might now come along and post "273 K" via the API. That's fine, it's a valid temperature. |
Thinks; if you want to prove a point here, you can make a state transformation on the MQTT channel that emulates what we'd like/expect the unit= parameter to do. Just a JS script that appends string " °F" to the raw data number (as string) |
Sometimes one doesn't see the wood because of all those trees! |
This issue has been mentioned on openHAB Community. There might be relevant details there: |
This issue has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/mqtt-binding-and-units-of-measurement/127026/3 |
I know I'm late to the party here but I just ran into exactly this problem. Based on what I'm seeing this isn't want is actually happening and it makes me wonder if there isn't some issue in openhab-core too. I'm receiving a number. I know this number is °C. I set "°C" as the unit in the Channel config. So far so good. I see in events.log that the Item is changing and using "°C". Now here is the tricky part. I want to see "°F" in the UIs so I edit the State Description Pattern to be "%.0f °F". What I'd expect to happen is that in the UI I now see the value converted to °F. And I in fact to see that. However, I also see that OH, on it's own and in response to adding the State Description Pattern also changed the state of the Item. At this point the Item is no longer storing "20 °C", it's actually storing "68 °F". This can be seen in the cart as well. (Sorry, I don't know how to make it smaller). That chart fragment starts at everything being °C. We start out at 18 °C. The Channel is configured to use °C for the units. Then I change only the State Description of the Item to use °F and you see the line spike up to 65ish and there was an Item changed event in the logs showing this as well. It's not just the way the Item is displayed that changed, the Item's state changed. The next value received from the device then gets applied to the Item. Despite the fact that the unit in the Channel is °C, it treats the value as if it were °F without doing any conversion at all. The cart drops to 18 °F which is clearly wrong. The next dip you see was me running an experiment. I changed the State Description Pattern to use °C. The Item then changed to around -6 °C which is the °C equivalent to 18 °F. Again, it's not just the way it displayed, the Item actually changed to this state based on events.log. Finally I removed the unit from the State Description Pattern and left it as °C in the Channel and things started to work, all be it as °C. Something is changing the state of the Items when the State Description Pattern is changed which doesn't seem like it should. State Description should change how it's displayed, it shouldn't change how it's stored, right? Also, the units that the binding should be providing (°C in this case) is ignored or overridden by the State Description Pattern. The only way I'm able to take in that raw °C number and convert it to a usable °F is to not use the unit parameter of the Channel config and instead use the following JS transform with a State Description of "%.0f °F".
Therefore I propose, at a minimum, the description of what the unit parameter on the Channel config does be changed to remove the implication that it can be used in any way to convert the incoming units to a different unit. And if someone agrees that there seems to be something outside of the MQTT binding also at play here I'll file an issue in core too. |
I don't think it works like that, Rich. Persistence is another story ... Store 20C, throw away unit and store 20. The glitch in your chart I think confirms convert-before-store theory. Retrieve data for charting, apply default F ... |
Here is the complete set of tests I've run thus far. I can't get the ItemChangeEvent to happen any more so that must have been an MQTT message triggered when not expected or something like that. But I think it does absolutely confirm that the MQTT Channel Config units property is being passed to the Item somehow. Thing config:
Item Config:Each Channel is linked to a System Config:Regional settings has Imperial checked which means the default units is °F Tests:Test 1: Send 18 to test/temp, review logs and Item states
Querying Persistence through the API shows:
Conclusion:The units from the binding has to be passed to OH and it has to be taking precedence over the system default. That's the only way You can see that the system default does apply when there are no units configured on the Thing's Channel with the NoUnits Item. However, the unit only appears in events.log, not in MainUI without a State Description Pattern. Test 2: With Items initialized to 18, change state description for all three Items to "%.0f °F"
MainUI now shows:
Persistence now shows:
So the value is converted somewhere and the converted value is what is stored in the DB. Interestingly I didn't see the I publish 19 to the topic.
Notice the interesting behavior for Conclusion:The units setting on the MQTT Channel is only used if there isn't a State Description, but it is in fact used at other times. But with the current behavior it is impossible to receive a value of one unit and convert it to another compatible set of units even for display. Test 3: Same as Test 2 except using %.0f °C and starting from the results of Test 2.
Persistence shows:
I publish 20 to the topic.
The same observations as above. The Item changes to the raw number with °C without any conversion. Test 4: Returning to no State Description
Persistence shows:
Publishing 21 results in
This is consistent with the other tests above. The number is never converted and the units used for the actual state of the Item is taken from Channel config or, when the Channel config doesn't have one defined the system default. Test 5: Set the state description for an non-MQTT sensorI don't have any temperature sensors that are reporting via any other binding except MQTT. I tried to find one I could play with. All the units my Things support are Dimensionless (which is less than useful in this particular case) or Time which only has the one unit so I can't try converting to another. This test will have to wait. Overall Conclusions
Because the State Description always takes precedence, it is impossible to receive a value as °C but see it and use it as °F using the built in UoM features, which we already know. One has to use a transformation to convert the incoming value to use the units you want. Persistence stores the value using the units defined in the State Description. |
This issue has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/mqtt-binding-and-units-of-measurement/127026/14 |
There is "something funny" going on here, like the channel passing a Number state (which happens to have unit text appended) instead of a Quantity state (which has the magical conversion properties). You can emulate that kind of behaviour in rules, I do not know if something similar can happen as channel updates. There might be further enlightment or confusion repeating the exercise with say |
This issue has been mentioned on openHAB Community. There might be relevant details there: |
This issue has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/convert-wh-to-kwh-divide-by-1000/130107/5 |
Setup
A device reports a temperature ( measured in °C) via mqtt as a plain number
16.0
.A channel is setup on that value using a JSONPATH transformation and a Unit of Measurement setting of
°C
.A linked Number:Temperature item would display
16,0 °C
.Expected Behavior
Using a State Description pattern on the item of
%.1f °F
the displayed value would be converted to Fahrenheit.60,8 °F
.Current Behavior
Initially the converted value is displayed correctly, however after the channel receives an update the displayed value changes back to the Degree value keeping the Fahrenheit sign
16,0 °F
.This change is correlating with this following events.log entry.
2021-03-14 14:00:32.259 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'TestTemperature' changed from 16.0 °C to 16.0 °F
Discussed on the forum
The text was updated successfully, but these errors were encountered: