Support user-defined base currency for Coinbase exchange rate sensors (#52879)

This commit is contained in:
Tom Brien 2021-07-15 05:50:23 +01:00 committed by GitHub
parent f152369944
commit db97fd3d5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 17 deletions

View File

@ -20,6 +20,7 @@ from .const import (
API_ACCOUNT_ID, API_ACCOUNT_ID,
API_ACCOUNTS_DATA, API_ACCOUNTS_DATA,
CONF_CURRENCIES, CONF_CURRENCIES,
CONF_EXCHANGE_BASE,
CONF_EXCHANGE_RATES, CONF_EXCHANGE_RATES,
CONF_YAML_API_TOKEN, CONF_YAML_API_TOKEN,
DOMAIN, DOMAIN,
@ -67,9 +68,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Coinbase from a config entry.""" """Set up Coinbase from a config entry."""
instance = await hass.async_add_executor_job( instance = await hass.async_add_executor_job(create_and_update_instance, entry)
create_and_update_instance, entry.data[CONF_API_KEY], entry.data[CONF_API_TOKEN]
)
entry.async_on_unload(entry.add_update_listener(update_listener)) entry.async_on_unload(entry.add_update_listener(update_listener))
@ -91,10 +90,11 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
return unload_ok return unload_ok
def create_and_update_instance(api_key, api_token): def create_and_update_instance(entry: ConfigEntry) -> CoinbaseData:
"""Create and update a Coinbase Data instance.""" """Create and update a Coinbase Data instance."""
client = Client(api_key, api_token) client = Client(entry.data[CONF_API_KEY], entry.data[CONF_API_TOKEN])
instance = CoinbaseData(client) base_rate = entry.options.get(CONF_EXCHANGE_BASE, "USD")
instance = CoinbaseData(client, base_rate)
instance.update() instance.update()
return instance return instance
@ -139,11 +139,12 @@ def get_accounts(client):
class CoinbaseData: class CoinbaseData:
"""Get the latest data and update the states.""" """Get the latest data and update the states."""
def __init__(self, client): def __init__(self, client, exchange_base):
"""Init the coinbase data object.""" """Init the coinbase data object."""
self.client = client self.client = client
self.accounts = None self.accounts = None
self.exchange_base = exchange_base
self.exchange_rates = None self.exchange_rates = None
self.user_id = self.client.get_current_user()[API_ACCOUNT_ID] self.user_id = self.client.get_current_user()[API_ACCOUNT_ID]
@ -153,7 +154,9 @@ class CoinbaseData:
try: try:
self.accounts = get_accounts(self.client) self.accounts = get_accounts(self.client)
self.exchange_rates = self.client.get_exchange_rates() self.exchange_rates = self.client.get_exchange_rates(
currency=self.exchange_base
)
except AuthenticationError as coinbase_error: except AuthenticationError as coinbase_error:
_LOGGER.error( _LOGGER.error(
"Authentication error connecting to coinbase: %s", coinbase_error "Authentication error connecting to coinbase: %s", coinbase_error

View File

@ -15,6 +15,7 @@ from .const import (
API_ACCOUNT_CURRENCY, API_ACCOUNT_CURRENCY,
API_RATES, API_RATES,
CONF_CURRENCIES, CONF_CURRENCIES,
CONF_EXCHANGE_BASE,
CONF_EXCHANGE_RATES, CONF_EXCHANGE_RATES,
CONF_OPTIONS, CONF_OPTIONS,
CONF_YAML_API_TOKEN, CONF_YAML_API_TOKEN,
@ -156,6 +157,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
errors = {} errors = {}
default_currencies = self.config_entry.options.get(CONF_CURRENCIES, []) default_currencies = self.config_entry.options.get(CONF_CURRENCIES, [])
default_exchange_rates = self.config_entry.options.get(CONF_EXCHANGE_RATES, []) default_exchange_rates = self.config_entry.options.get(CONF_EXCHANGE_RATES, [])
default_exchange_base = self.config_entry.options.get(CONF_EXCHANGE_BASE, "USD")
if user_input is not None: if user_input is not None:
# Pass back user selected options, even if bad # Pass back user selected options, even if bad
@ -165,6 +167,9 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
if CONF_EXCHANGE_RATES in user_input: if CONF_EXCHANGE_RATES in user_input:
default_exchange_rates = user_input[CONF_EXCHANGE_RATES] default_exchange_rates = user_input[CONF_EXCHANGE_RATES]
if CONF_EXCHANGE_RATES in user_input:
default_exchange_base = user_input[CONF_EXCHANGE_BASE]
try: try:
await validate_options(self.hass, self.config_entry, user_input) await validate_options(self.hass, self.config_entry, user_input)
except CurrencyUnavaliable: except CurrencyUnavaliable:
@ -189,6 +194,10 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
CONF_EXCHANGE_RATES, CONF_EXCHANGE_RATES,
default=default_exchange_rates, default=default_exchange_rates,
): cv.multi_select(RATES), ): cv.multi_select(RATES),
vol.Optional(
CONF_EXCHANGE_BASE,
default=default_exchange_base,
): vol.In(WALLETS),
} }
), ),
errors=errors, errors=errors,

View File

@ -1,6 +1,7 @@
"""Constants used for Coinbase.""" """Constants used for Coinbase."""
CONF_CURRENCIES = "account_balance_currencies" CONF_CURRENCIES = "account_balance_currencies"
CONF_EXCHANGE_BASE = "exchange_base"
CONF_EXCHANGE_RATES = "exchange_rate_currencies" CONF_EXCHANGE_RATES = "exchange_rate_currencies"
CONF_OPTIONS = "options" CONF_OPTIONS = "options"
DOMAIN = "coinbase" DOMAIN = "coinbase"

View File

@ -49,7 +49,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
if CONF_CURRENCIES in config_entry.options: if CONF_CURRENCIES in config_entry.options:
desired_currencies = config_entry.options[CONF_CURRENCIES] desired_currencies = config_entry.options[CONF_CURRENCIES]
exchange_native_currency = instance.exchange_rates[API_ACCOUNT_CURRENCY] exchange_base_currency = instance.exchange_rates[API_ACCOUNT_CURRENCY]
for currency in desired_currencies: for currency in desired_currencies:
if currency not in provided_currencies: if currency not in provided_currencies:
@ -67,7 +67,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
ExchangeRateSensor( ExchangeRateSensor(
instance, instance,
rate, rate,
exchange_native_currency, exchange_base_currency,
) )
) )
@ -149,7 +149,7 @@ class AccountSensor(SensorEntity):
class ExchangeRateSensor(SensorEntity): class ExchangeRateSensor(SensorEntity):
"""Representation of a Coinbase.com sensor.""" """Representation of a Coinbase.com sensor."""
def __init__(self, coinbase_data, exchange_currency, native_currency): def __init__(self, coinbase_data, exchange_currency, exchange_base):
"""Initialize the sensor.""" """Initialize the sensor."""
self._coinbase_data = coinbase_data self._coinbase_data = coinbase_data
self.currency = exchange_currency self.currency = exchange_currency
@ -158,7 +158,7 @@ class ExchangeRateSensor(SensorEntity):
self._state = round( 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]), 2
) )
self._unit_of_measurement = native_currency self._unit_of_measurement = exchange_base
@property @property
def name(self): def name(self):

View File

@ -25,7 +25,8 @@
"description": "Adjust Coinbase Options", "description": "Adjust Coinbase Options",
"data": { "data": {
"account_balance_currencies": "Wallet balances to report.", "account_balance_currencies": "Wallet balances to report.",
"exchange_rate_currencies": "Exchange rates to report." "exchange_rate_currencies": "Exchange rates to report.",
"exchange_base": "Base currency for exchange rate sensors."
} }
} }
}, },

View File

@ -12,9 +12,7 @@
"user": { "user": {
"data": { "data": {
"api_key": "API Key", "api_key": "API Key",
"api_token": "API Secret", "api_token": "API Secret"
"currencies": "Account Balance Currencies",
"exchange_rates": "Exchange Rates"
}, },
"description": "Please enter the details of your API key as provided by Coinbase.", "description": "Please enter the details of your API key as provided by Coinbase.",
"title": "Coinbase API Key Details" "title": "Coinbase API Key Details"
@ -31,6 +29,7 @@
"init": { "init": {
"data": { "data": {
"account_balance_currencies": "Wallet balances to report.", "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."
}, },
"description": "Adjust Coinbase Options" "description": "Adjust Coinbase Options"