-
-
Notifications
You must be signed in to change notification settings - Fork 429
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
Fix QuantityType toInvertibleUnit method #4561
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Andrew Fiddian-Green <[email protected]>
Signed-off-by: Andrew Fiddian-Green <[email protected]>
Signed-off-by: Andrew Fiddian-Green <[email protected]>
The code looks perfectly fine to me and is needed to make sure the proper conversion is done. I am wondering if this conversion to system unit always applies for reciprocal units. I only found one example where it doesn’t, but it is esoteric and I would’t expect it to be of any use in our context: So in conclusion, if we were to have dioptre as a unit for reciprocal length in the system, the change you make would also fix it for this, always converting to meter before inverting. But I cannot be 100% sure something else pops up in the future. In these cases, there is no easy rule anymore, because you would have to convert to a specific unit different from the system unit before inverting. |
@mherwege I did a trawl through the addons and found about 40 cases using toInvertibleUnit; most of them are color temperature cases; and as far as I can tell the others are calling toInvertibleUnit where in fact toUnit would work; in those latter cases the target is generally a non inverted unit, so the method code falls through to toUnit anyway. I added a unit test to check that fall through use case too. |
Apropos Dioptre and Kaiser -- AFAICT these units are not defined in OH so any potential problem with Kaiser is perhaps moot?? Apropos actual usages of So how would you like to proceed? My proposal is as follows..
@mherwege => WDYT? |
@andrewfg Your proposal makes sense. But I still have a very uncomfortable feeling about using invertible units in general. I would prefer to try to eliminate the use wherever there is no real reason to use it, combined with your proposal here. Here is an example in core where invertible units may lead to very strange results: Line 99 in 15eb5cc
The method calculates the average over a group of items (average group function). Imagine you have color temperature items in there in Kelvin and others in Mired. Depending on the unit of the group item, the result will be very different. We should never allow to use toInvertibleUnit when there is any calculation involved, or it can go badly wrong. So the example above I actually consider a bug. Imagine you do this with Ohm and Siemens. Adding resistance is when you have resistors in serie. Adding conductivity is when you have resistors in parallel. Mixing them, you cannot calculate at all. You would actually have to provide the unit for the calculation as an argument to be able to have a predictable result. In all, I am OK with your solution, but I also want to make it very clear there are strong limitations to the use of in invertible units. And that should probably also be made clear in the javadoc. I would very much like to understand the few cases where invertible units are used for pure temperature and time. Is it necessary in these cases? And be careful with the transform profiles. Any calculation is a potential problem. |
Indeed, it is. And I don’t think Kaiser will ever be defined. I also stated these units are likely not relevant. But that was not my point. If we code logic now, and someone at some point needs a unit that would create this kind of problem, nobody will remember. We would be building exception on top of exception. |
@mherwege all your points duly noted.
|
Indeed. And as mentioned above, it applies to ALL calculations based on sets of items with mixed units. So to be clear this is not really an issue with |
That is not correct, as the calculation functions will be done on the absolute scale since #3792. So there is no unpredictability. Looking at the code of the arithmetic group functions, it looks like items of another dimension than the first are excluded from the sum. So depending on the unit of the first item, you will have a different set of items used in the function if there are invertible units in it. It would probably be better to use the unit of the group base item, instead of the unit of the first item, and then allow the reciprocal unit in the calculation after conversion to the base unit. I notice in the history the use of toInvertibleUnit in that method has explicitly been added to cope with color temperature, but in my view it does not work at all at this time (and that is from reading code, not testing). Also it is not used in all methods, only a few. |
The General comment: this calculation use case looks to be similar to the calculation use case that you cite in OH Core, so we should try to follow similar logic in resolving any potential issues. The good news: for the case of The bad news: I am beginning to think that there may be bigger issues in other cases that calculate over sets of QuantityType. I think it is not just a question of |
Yes. That solution also works for invertible units since the target unit is always determined. |
Signed-off-by: Andrew Fiddian-Green <[email protected]>
I don’t think it is any different from the other methods from that perspective, only it was added later. EDIT: Actually, it is fine in this case. The median method converts to the base unit of the item for all values and finds the median value using a statistics function I actually wrote myself. It adds the base unit at the end in the result again. So this is fine, except the previous remark: reciprocal unit are not of the same dimension, so not considered at all, even if they are intended to be considered in the code. |
Ok. Shall I close the issue? Or would you prefer to open a PR that replaces |
Signed-off-by: Andrew Fiddian-Green <[email protected]>
Keep it for now. I am not sure what the best solution is though. I will comment in the issue. |
Resolves openhab/openhab-addons#18118
Fix for the QuantityType toInvertibleUnit method
Signed-off-by: Andrew Fiddian-Green [email protected]