-
-
Notifications
You must be signed in to change notification settings - Fork 428
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
[UoM] Add currency handling #3503
Conversation
bundles/org.openhab.core/src/main/java/org/openhab/core/internal/i18n/I18nProviderImpl.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.core/src/test/java/org/openhab/core/library/unit/CurrencyUnitTest.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.core/src/main/java/org/openhab/core/library/unit/CurrencyUnit.java
Outdated
Show resolved
Hide resolved
Can't set status; build succeeded. |
Maybe we should make three parameters for the The problem is that especially the symbols are not necessarily unique, so it may be difficult to determine the correct currency if there is something like Edit: I think we can omit the name and use the |
Yes, the unique key should definitely be the currency code. The symbol is probably subject to some kind of localization, since it can be placed before or after the amount, for example "$ 15" in the US, and "15 €" in Europe. And the currency name (if included) should support I18N (e.g. "den danske krone" in Danish or "Danish krone" in English). On top of that, this could be formatted also as the sub unit (1/100) "øre", e.g. "1 krone og 25 øre", although this would usually be written "1,25 kr.". Just listing everything I can think of now. 🙂 But again, the most important start is to use the ISO currency code. |
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.
Small note on naming. CurrencyProvider
suggest that it is something to declare currencies while it seems to provide also exchange rate. The scale factor might also be a bit unfortunate term, cause it might imply a more static nature than it actually is.
bundles/org.openhab.core/src/main/java/org/openhab/core/library/unit/CurrencyProvider.java
Outdated
Show resolved
Hide resolved
bef2173
to
0036306
Compare
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.
Some minor comments (I know it's still a draft).
I plan to refactor openhab/openhab-addons#14376 quickly to use this when finished and merged.
...org.openhab.core/src/main/java/org/openhab/core/internal/library/unit/CurrencyConverter.java
Outdated
Show resolved
Hide resolved
...s/org.openhab.core/src/main/java/org/openhab/core/internal/library/unit/CurrencyService.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.core/src/main/java/org/openhab/core/library/dimension/Currency.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.core/src/test/java/org/openhab/core/library/unit/CurrencyUnitTest.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.core/src/main/java/org/openhab/core/library/unit/CurrencyUnit.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.core/src/main/resources/OH-INF/config/i18n.xml
Outdated
Show resolved
Hide resolved
|
||
@Test | ||
public void testPriceCalculation() { | ||
QuantityType<?> unitPrice = new QuantityType<>("0.25 €/kWh"); |
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.
Shouldn't this only work for "0.25 EUR/kWh", since the symbol is ambiguous and we're using the currency code as key?
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.
The CurrencyProvider
has to take care that the symbol is unique. For the system provider there is only one currency, so there can't be ambiguity. For (future) extensions, the provider has to make sure that e.g. Kr
or $
is only used for one currency and either not set a symbol for other currencies or prefix them (like AUS$
).
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.
Hmm, it's quite possible (even likely) I don't fully understand it yet. Let's say you have two currencies:
- Currency code: NOK, symbol: kr
- Currency code: SEK, symbol: kr
I then receive an energy price in NOK, e.g. 1 NOK/kWh, and would like that converted (through an exchange rate service) to SEK. How would I then define that quantity, if not like new QuantityType<>("1 NOK/kWh")
? I imagined that symbols would only be used for something like state patterns, i.e. only for display purposes.
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.
You can always user the currency code. The CurrencyProvider
has to make sure that aliases (symbols) are unique, so it can only use kr
for one currency.
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.
OK. Perhaps a test for currency code could be added as well, e.g. "0.25 EUR/kWh" or "1.75 DKK/kWh" (to pick a currency having an ambiguous symbol)?
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.
There should be no ambiguous symbol within a given set of currencies. This has to be ensured by the CurrencyProvider
. How should I test that this is the case?
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.
I didn't mean to test that, only to ensure coverage for using a currency code rather than currency symbol. So simply the same testcase but using for example "EUR" instead of "€".
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.
Submitting review to publish comment made after unrelated minor code comments.
...s/org.openhab.core/src/main/java/org/openhab/core/internal/library/unit/CurrencyService.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.core/src/main/java/org/openhab/core/library/unit/CurrencyProvider.java
Outdated
Show resolved
Hide resolved
|
||
@Test | ||
public void testPriceCalculation() { | ||
QuantityType<?> unitPrice = new QuantityType<>("0.25 €/kWh"); |
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.
Hmm, it's quite possible (even likely) I don't fully understand it yet. Let's say you have two currencies:
- Currency code: NOK, symbol: kr
- Currency code: SEK, symbol: kr
I then receive an energy price in NOK, e.g. 1 NOK/kWh, and would like that converted (through an exchange rate service) to SEK. How would I then define that quantity, if not like new QuantityType<>("1 NOK/kWh")
? I imagined that symbols would only be used for something like state patterns, i.e. only for display purposes.
The The system provider (which is part of the |
83e4e4e
to
461a17e
Compare
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.
Two minor comments.
...s/org.openhab.core/src/main/java/org/openhab/core/internal/library/unit/CurrencyService.java
Outdated
Show resolved
Hide resolved
bundles/org.openhab.core/src/main/java/org/openhab/core/library/unit/CurrencyProvider.java
Show resolved
Hide resolved
@openhab/core-maintainers - any chance to have this PR reviewed? 🙂 |
I can have a look at it asap. |
Awesome, thanks! 👍
From reading the code I don't see any issues. But I have to admit that I scratched only the surface and tried to ask a few questions from my somewhat limited understanding of this area (I read only the new code, not the current code). Everything else I'm leaving for core maintainers, I'm just a passer-by with some interest in the topic. 😄 I did not yet get my hands dirty with it, i.e. tried to build the core project, implement currency support in Energi Data Service and/or implement a currency provider. Only then would I probably really understand what is being offered here. 🙂 I am eager to try it out though, and the concept looks promising.
Correct, but that's only a slight difference of opinion and should not prevent a merge. Since currency symbols like "kr." or "$" are ambiguous I don't see the benefit of using them for anything other than display/formatting purposes. Currency codes like DKK are ISO standard and unambiguous. |
Until I can try this out, maybe let me run through an example to verify if my understanding is correct. New channel type definition: <channel-type id="spot-price">
<item-type>Number:EnergyPrice</item-type>
<label>Spot Price</label>
<description>Spot price.</description>
<category>Price</category>
<state readOnly="true" pattern="%.9f %unit%"></state>
</channel-type> I would assume the channel can be updated like this: updateState(CHANNEL_SPOT_PRICE, new QuantityType<>(spotPrice + " DKK/kWh"); (here I'm not sure if it can be provided as value and unit separately, but that's a minor thing) For the Is that correct? If I now change either base unit configuration to "EUR" or item metadata unit to "EUR/kWh", I'm not sure what would then be displayed, since I don't have any If I implement a currency exchange converter (i.e. a Last, in a JavaScript rule I would now assume I could do something like this: var spotPrice = items.SpotPrice.quantityState; // Unit is "EUR/kWh"
var consumption = Quantity("2 kWh");
var totalPrice = consumption.multiply(spotPrice);
console.log("Total price: " + totalPrice);
console.log("Total price in US dollars: " + totalPrice.toUnit("USD")); and I would see this logged:
@J-N-K - can you confirm or correct my assumptions here? @kaikreuzer - to me this would seem logical and correct, so if confirmed, I'm very happy with the result. If not, let's figure out where I'm wrong and synchronize. |
In relation to this, I'm now wondering how to override/configure display unit. Let's say channel
I assume I can trigger a currency conversion for display purposes:
But what if I wanted to not only trigger a currency conversion, but also currency symbol display?
(note: symbol for DKK is "kr." with dot... for SEK and NOK it would be just "kr" without dot) This could be ambiguous, so what would actually happen - is it possible at all? I agree that unit symbol is often preferable for display purposes. |
See also #3597 (comment). |
Signed-off-by: Jan N. Klug <[email protected]>
Signed-off-by: Jan N. Klug <[email protected]>
Signed-off-by: Jan N. Klug <[email protected]>
Signed-off-by: Jan N. Klug <[email protected]>
a57b979
to
1861d50
Compare
Thanks for rebasing, @J-N-K. I have now built (I'm wondering if this should be part of regional settings rather than a separate unit settings - do you expect more unit settings since you put it separately?) Created an item: label: Currency Item
type: Number:Currency
category: price
groupNames: []
groupType: None
function: null
tags: [] And first tests: openhab> openhab:update CurrencyItem "100 kr."
Update has been sent successfully.
openhab> openhab:update CurrencyItem "200 DKK"
Error: State '200 DKK' is not valid for item 'CurrencyItem'
Valid data types are: ( DecimalType QuantityType UnDefType )
openhab> openhab:update CurrencyItem "300 $"
Error: State '300 $' is not valid for item 'CurrencyItem'
Valid data types are: ( DecimalType QuantityType UnDefType )
openhab> openhab:update CurrencyItem "400 €"
Error: State '400 €' is not valid for item 'CurrencyItem'
Valid data types are: ( DecimalType QuantityType UnDefType )
openhab> openhab:update CurrencyItem "500 kr"
Error: State '500 kr' is not valid for item 'CurrencyItem'
Valid data types are: ( DecimalType QuantityType UnDefType ) Besides not being able to use currency code for the update, I think it behaves as I would expect. I assume the error when trying unit symbols $, € and kr. is because I have configured DKK indirectly through openhab> openhab:update CurrencyItem "200 kr"
Error: State '200 kr' is not valid for item 'CurrencyItem'
Valid data types are: ( DecimalType QuantityType UnDefType )
openhab> openhab:update CurrencyItem "200 SEK"
Update has been sent successfully. So when using the Also, is it expected that the state value is kept, but the unit is changed, when another currency is configured? Unit metadata doesn't seem to have much impact: When eventually adding a new |
This is correct, but for display/formatting purposes you would want SEK and NOK both use "kr" as a symbol - and if only one of both is allowed to use it, that would be a problem, wouldn't it? |
Indeed. Perhaps my misconception is that I somehow assumed that display/formatting could have an asymmetric relation to "real" unit, so that both SEK/NOK would be displayed as "kr" but still maintain their currency code for all other matters. But of course this wouldn't work the other way, so for example a sitemap After running the tests in my previous post I'm still a bit confused about the roles of If it's possible for a binding to publish SEK, and for a user to use a currency exchange service (through a |
If a Both, What is the state here? Any change request or can this be merged? |
From my perspective, here's a shortened summary of concerns from my testing session:
|
|
Thank you for your detailed answer, @J-N-K. That removes my last doubts. Regarding the settings page, this can always be reworked later without breaking anything. I just wondered why a new page was introduced when we can already configure the measurement system in regional settings. If by any chance this PR would be ready for a merge soon, I should be able to implement currency support in Energy Data Service binding for 4.1. Currency exchange probably not. 😄 |
@kaikreuzer - gentle ping. 🙂 |
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.
Thank you. 😄 I'll give it a go, I have a few hours left. Any chance of a full build now so that a PR in addons will build successfully? |
I have triggered a core build, once it's done I'll trigger an add-ons build and a distro-build. |
Thanks! Meanwhile I started looking into the implementation. Is it correct that a state update for kr./kWh can/should now be done like this? BigDecimal price = new BigDecimal("1");
updateState("price", new QuantityType<EnergyPrice>(price + " DKK/kWh")); |
I had already triggered a core build and all is available with https://ci.openhab.org/job/openHAB-Core/1310/. |
With the addons build I am waiting for openhab/openhab-addons#16060 to succeed first. |
This pull request has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/using-the-new-currency-units-of-measurement-in-4-1/152338/22 |
Closes #3408
Related to #3478
This enables currency handling for UoM. You can define prices (e.g.
0.336 €/kWh
) and do calculations based on that like any other unit.Currently you can define a "system currency" (e.g.
€
, defaults zu@
if not set at all) which is then available as any other unit. It is also possible to define aCurrencyProvider
which adds additional currencies and their exchange rates (relative to the system currency). Switching between different currency providers is not yet implemented.