Add option for exchange rate sensor precision to Coinbase (#68792)

* Add user option for precision to exchange rate sensors

* Add tests

* Add strings
This commit is contained in:
Tom Brien 2022-03-30 12:51:44 +01:00 committed by GitHub
parent 259b069dd9
commit bb7593351b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 13 deletions

View file

@ -18,6 +18,8 @@ from .const import (
API_TYPE_VAULT,
CONF_CURRENCIES,
CONF_EXCHANGE_BASE,
CONF_EXCHANGE_PRECISION,
CONF_EXCHANGE_PRECISION_DEFAULT,
CONF_EXCHANGE_RATES,
CONF_OPTIONS,
CONF_YAML_API_TOKEN,
@ -177,6 +179,9 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
default_currencies = self.config_entry.options.get(CONF_CURRENCIES, [])
default_exchange_rates = self.config_entry.options.get(CONF_EXCHANGE_RATES, [])
default_exchange_base = self.config_entry.options.get(CONF_EXCHANGE_BASE, "USD")
default_exchange_precision = self.config_entry.options.get(
CONF_EXCHANGE_PRECISION, CONF_EXCHANGE_PRECISION_DEFAULT
)
if user_input is not None:
# Pass back user selected options, even if bad
@ -189,6 +194,9 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
if CONF_EXCHANGE_RATES in user_input:
default_exchange_base = user_input[CONF_EXCHANGE_BASE]
if CONF_EXCHANGE_PRECISION in user_input:
default_exchange_precision = user_input[CONF_EXCHANGE_PRECISION]
try:
await validate_options(self.hass, self.config_entry, user_input)
except CurrencyUnavailable:
@ -217,6 +225,9 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
CONF_EXCHANGE_BASE,
default=default_exchange_base,
): vol.In(WALLETS),
vol.Optional(
CONF_EXCHANGE_PRECISION, default=default_exchange_precision
): int,
}
),
errors=errors,

View file

@ -3,6 +3,8 @@
CONF_CURRENCIES = "account_balance_currencies"
CONF_EXCHANGE_BASE = "exchange_base"
CONF_EXCHANGE_RATES = "exchange_rate_currencies"
CONF_EXCHANGE_PRECISION = "exchange_rate_precision"
CONF_EXCHANGE_PRECISION_DEFAULT = 2
CONF_OPTIONS = "options"
CONF_TITLE = "title"
DOMAIN = "coinbase"

View file

@ -22,6 +22,8 @@ from .const import (
API_RESOURCE_TYPE,
API_TYPE_VAULT,
CONF_CURRENCIES,
CONF_EXCHANGE_PRECISION,
CONF_EXCHANGE_PRECISION_DEFAULT,
CONF_EXCHANGE_RATES,
DOMAIN,
)
@ -66,6 +68,10 @@ async def async_setup_entry(
exchange_base_currency = instance.exchange_rates[API_ACCOUNT_CURRENCY]
exchange_precision = config_entry.options.get(
CONF_EXCHANGE_PRECISION, CONF_EXCHANGE_PRECISION_DEFAULT
)
for currency in desired_currencies:
if currency not in provided_currencies:
_LOGGER.warning(
@ -80,9 +86,7 @@ async def async_setup_entry(
for rate in config_entry.options[CONF_EXCHANGE_RATES]:
entities.append(
ExchangeRateSensor(
instance,
rate,
exchange_base_currency,
instance, rate, exchange_base_currency, exchange_precision
)
)
@ -178,14 +182,16 @@ class AccountSensor(SensorEntity):
class ExchangeRateSensor(SensorEntity):
"""Representation of a Coinbase.com sensor."""
def __init__(self, coinbase_data, exchange_currency, exchange_base):
def __init__(self, coinbase_data, exchange_currency, exchange_base, precision):
"""Initialize the sensor."""
self._coinbase_data = coinbase_data
self.currency = exchange_currency
self._name = f"{exchange_currency} Exchange Rate"
self._id = f"coinbase-{coinbase_data.user_id}-xe-{exchange_currency}"
self._precision = precision
self._state = round(
1 / float(self._coinbase_data.exchange_rates[API_RATES][self.currency]), 2
1 / float(self._coinbase_data.exchange_rates[API_RATES][self.currency]),
self._precision,
)
self._unit_of_measurement = exchange_base
self._attr_state_class = SensorStateClass.MEASUREMENT
@ -231,5 +237,6 @@ class ExchangeRateSensor(SensorEntity):
"""Get the latest state of the sensor."""
self._coinbase_data.update()
self._state = round(
1 / float(self._coinbase_data.exchange_rates.rates[self.currency]), 2
1 / float(self._coinbase_data.exchange_rates.rates[self.currency]),
self._precision,
)

View file

@ -28,7 +28,8 @@
"data": {
"account_balance_currencies": "Wallet balances to report.",
"exchange_rate_currencies": "Exchange rates to report.",
"exchange_base": "Base currency for exchange rate sensors."
"exchange_base": "Base currency for exchange rate sensors.",
"exchnage_rate_precision": "Number of decimal places for exchange rates."
}
}
},

View file

@ -14,9 +14,7 @@
"user": {
"data": {
"api_key": "API Key",
"api_token": "API Secret",
"currencies": "Account Balance Currencies",
"exchange_rates": "Exchange Rates"
"api_token": "API Secret"
},
"description": "Please enter the details of your API key as provided by Coinbase.",
"title": "Coinbase API Key Details"
@ -26,9 +24,7 @@
"options": {
"error": {
"currency_unavailable": "One or more of the requested currency balances is not provided by your Coinbase API.",
"currency_unavaliable": "One or more of the requested currency balances is not provided by your Coinbase API.",
"exchange_rate_unavailable": "One or more of the requested exchange rates is not provided by Coinbase.",
"exchange_rate_unavaliable": "One or more of the requested exchange rates is not provided by Coinbase.",
"unknown": "Unexpected error"
},
"step": {
@ -36,7 +32,8 @@
"data": {
"account_balance_currencies": "Wallet balances to report.",
"exchange_base": "Base currency for exchange rate sensors.",
"exchange_rate_currencies": "Exchange rates to report."
"exchange_rate_currencies": "Exchange rates to report.",
"exchnage_rate_precision": "Number of decimal places for exchange rates."
},
"description": "Adjust Coinbase Options"
}

View file

@ -8,6 +8,7 @@ from requests.models import Response
from homeassistant import config_entries
from homeassistant.components.coinbase.const import (
CONF_CURRENCIES,
CONF_EXCHANGE_PRECISION,
CONF_EXCHANGE_RATES,
CONF_YAML_API_TOKEN,
DOMAIN,
@ -211,6 +212,7 @@ async def test_option_form(hass):
user_input={
CONF_CURRENCIES: [GOOD_CURRENCY],
CONF_EXCHANGE_RATES: [GOOD_EXCHANGE_RATE],
CONF_EXCHANGE_PRECISION: 5,
},
)
assert result2["type"] == "create_entry"
@ -237,6 +239,7 @@ async def test_form_bad_account_currency(hass):
user_input={
CONF_CURRENCIES: [BAD_CURRENCY],
CONF_EXCHANGE_RATES: [],
CONF_EXCHANGE_PRECISION: 5,
},
)
@ -263,6 +266,7 @@ async def test_form_bad_exchange_rate(hass):
user_input={
CONF_CURRENCIES: [],
CONF_EXCHANGE_RATES: [BAD_EXCHANGE_RATE],
CONF_EXCHANGE_PRECISION: 5,
},
)
assert result2["type"] == "form"
@ -293,6 +297,7 @@ async def test_option_catch_all_exception(hass):
user_input={
CONF_CURRENCIES: [],
CONF_EXCHANGE_RATES: ["ETH"],
CONF_EXCHANGE_PRECISION: 5,
},
)