-
-
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
GroupItem uses GroupItem's system unit #4563
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
@mherwege for info.. |
This comment was marked as outdated.
This comment was marked as outdated.
...b.core/src/main/java/org/openhab/core/library/types/QuantityTypeArithmeticGroupFunction.java
Show resolved
Hide resolved
@mherwege while testing this, I discovered that the JUnit assertion test values are physically WRONG. e.g. the sum of 23.54 °C plus 89 °C plus 122.41 °C is absolutely NOT 234.95 °C .. rather it is 781.24 °C .. this assumes that the three absolute Kelvin values must be summed. => So this really provokes the question about what we are really trying to achieve here? Do we want a) just the sum of three numbers, or b) the sum of three physical temperatures?
|
Look at the PR I already linked several times. This is on purpose. The second and third arguments are interpreted ad differential values, not absolute values. And that’s what makes sense, as most would expect that adding 20 °C to 20 °C gives 40°C. And with the way it is done, it does. It also works for Fahrenheit, which is not the same scale as Kelvin or Celsius. This problem is only there if the 0 point of the respective units is not the same. |
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
Ok. Got it. I just committed support for the following..
|
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
...b.core/src/main/java/org/openhab/core/library/types/QuantityTypeArithmeticGroupFunction.java
Outdated
Show resolved
Hide resolved
...b.core/src/main/java/org/openhab/core/library/types/QuantityTypeArithmeticGroupFunction.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.core/src/test/java/org/openhab/core/internal/i18n/TestKelvinProvider.java
Outdated
Show resolved
Hide resolved
...re/src/test/java/org/openhab/core/library/types/QuantityTypeArithmeticGroupFunctionTest.java
Outdated
Show resolved
Hide resolved
...re/src/test/java/org/openhab/core/library/types/QuantityTypeArithmeticGroupFunctionTest.java
Show resolved
Hide resolved
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
What about the following approach: Create a new method in openhab-core/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/QuantityType.java Line 585 in ce37425
It should be something like:
You then call this method instead of This will then be different from when you simply do the calculation in a rule, because there only the first argument is treated as ABSOLUTE. But I don't think this kind of logic applies in groups anyhow. |
@mherwege please calm down. As you say add is a relative function. It is based on the zero point offset of the initial unit. So in the case of Celsius it is a relative add. And in the case of Kelvin (and most other zero based units) the add function is at the same time both relative and absolute. So..
|
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
Absolutely true, but my worry is the different results depending on the unit used. And that is not logical. QuantityType calculations are meant to give the same result, whatever the unit. And of course that cannot be true for invertible units, which is a special case. And that's what we try to solve that by converting to the group item base unit to make the result at least predictable. But if it breaks the rule of having the same result within the same dimension, whatever the unit, that is not acceptable. And the rule is broken because of the conversion to the base unit. Add now does not do a relative add anymore, whatever the unit. |
Honestly, I am pretty calm on this. I am just trying to achieve the best possible result. That's why I keep on questioning things. If we don't do that now, I know we hit issues at some point in time and we will have to find other workarounds again. |
We just need to add the following text to the readme and JavaDoc; then everything clear :) The
See. Perfectly logical. :)
|
This is not what the current add method in QuantityType does. Within the group arithmetic functions, because you first convert all arguments to the base unit, you get (assuming base unit is K): |
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
Are you sure? I would expect a result of 40 °C ??? |
Indeed, 40 °C I will correct the post. |
See the following unit tests. They all produce IMHO the correct results. Or do you expect them to produce others??. |
@andrewfg So, I ran the simulations and here is a little table. The original unit of the inputs are on top, but the values in the cells are already recalculated to the target unit. These correspond to the tests with some extensions.
My first question is the difference in outcome between 6a and 6b (is the same as 1). In the current propsal, the base unit determines the way the sum is calculated. Before, the first element in the group did determine it. I would argue that even made the whole summing quantity types in groups unpredictable, but that is another story. At least now it is predictable. To that end, I also created a scenario 3b where the base unit is °C and there is a mirek input. So the sum would be off when you try to visualize this with e.g. a Kelvin state description pattern. This is another case you would have when the °C default is not changed. I am just not so sure anymore it is the right thing to do to use group base item unit as the reference unit. It does make the result dependent on that unit setting. And so far the unit never really had an impact on any calculation we did. If someone changes the unit of an item, it has a broader impact than just this calculation. It will also impact persistence. That's why it got introduced in the first place. So if you change this to make the group sum calculation work, it impacts that as well. That's why I was somewhat advocating to always use the value against an absolute reference (hence the addAbsolute proposal). In that case base unit will not have an impact anymore. The solution here is also loosly related to how to treat it for the state filter profiles. There is no natural base unit there. Summing in absolute units would avoid that problem there as well. I don't want to be the final decision maker on this. I am not a maintainer, so won't be the final judge. I can live with your proposed solution as long as it is properly documented. |
Thanks for the analysis. AFAICT this issue only affects the SUM calculation. The MIN MAX AVG and MEDIAN functions anyway produce the same results. @mherwege can you please confirm re MEDIAN? For SUM I think we have three possible ways forward:
*) on the case of SUMREL the relative base would be the zero point of the GroupItem's Unit, rather than the Unit of the "first" item in the Group members set. |
Indeed, the challenge is only with SUM. Following wiki is an interesting read: https://github.com/unitsofmeasurement/unit-api/wiki/Arithmetic-rules-for-Difference-versus-Absolute-quantities This is actually the reference for all Quantity calculations and how they should be treated. I quote:
The QuantityType.add method treats the second argument in the add as a INCREMENTAL, and the first argument as ABSOLUTE. So it results in: If we step back for a moment, what would summing temperatures in a group really be used for? Honestly, I can't think of cases where it makes sense. Average or median, min or max I believe make a lot of sense. I am not sure summing temperatures in a group does to be honest. And unless someone finds an example where it does make sense, I would stick to the golden rule, which is convert everything to system unit before calculating. This avoids the extra complexity of adding (documenting, explaining, maintaining) another version of SUM, just for the temperature case, where I see little relevance. So my vote goes to doing the calculations in system unit and not creating an extra flavor of SUM. |
@mherwege I am good with your proposal above. But I thought it was you who was insisting that the calculations must be relative (20 C + 30 C = 50 C) so I am a little surprised that you seem to have changed your mind. ?? |
Yes, and I was turning in circles on this. I have advocated the opposite in some of my messages as well. My appologies for that. My itch came from the fact that I went the extra mile to make rules work with first argument absolute and second argument differential (relative). And that's reflected in the add method. The moment the conversion is done beforehand, you actually make them relative to a new base, not the first argument anymore, as the conversion is always converting absolule values, not differential values. And then you treat the first argument as absolute and the second (converted) argument as relative again in the add method. I actually think an extra javadoc on the add method explaining this, stating that the first argument is treated as absolute and the second argument as differential would be appropriate. Do you mind putting that in? You are touching the same classes. Also, this would anyhow be a breaking change. Currently the outcome depends on the unit of the first item in the group that is considered. I don't think that is fixed. With the current change, it becomes deterministic, whatever solution is chosen. It really doesn't matter if the current JUnit test still pass in that sense, as they are deterministic in that the first element in the group is fixed, and you fixed the tests by making the base unit the same as the unit of the first element in the list. |
I will do that. |
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
@mherwege I made a commit just now that should hopefully reflect our final agreement. |
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
...b.core/src/main/java/org/openhab/core/library/types/QuantityTypeArithmeticGroupFunction.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
...b.core/src/main/java/org/openhab/core/library/types/QuantityTypeArithmeticGroupFunction.java
Outdated
Show resolved
Hide resolved
...b.core/src/main/java/org/openhab/core/library/types/QuantityTypeArithmeticGroupFunction.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
@mherwege thanks for approving the PR. Unfortunately I had to revert your proposal from |
Depends on openhab/openhab-core#4563 Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
Fixes #4562
Requires #4561
Previously the calculations over a GroupItem's set of member Items were based on the Unit of the first member in the set. There are two problems: a) the order of the set is not fixed, and b) the Unit of the first member Item is also not definitive to the Unit of the expected result. Therefore these calculations could produce variable and unexpected results.
This PR normalises the calculations over the group's set of member Item so that all calculations are based on the Unit of the GroupItem's base Item.
Furthermore this PR allows conversion between non- inverted and inverted Units so invertible conversions (e.g. Kelvin <=> Mirek) are supported.
Signed-off-by: Andrew Fiddian-Green software@whitebear.ch