This may be useful to some of you. I created a sensor to display the current exchange rate. This is my first Python experience, so it may not be the cleanest code (and I certainly welcome feedback), but it gets the job done.
First, signup at OpenExchageRates and get your API. The free account allows 1000 requests per month.
Place currency.py with the following contents in the /custom_components/sensor/ directory (you may need to create it) wherever your hass config file lies. Restart hass.
For some reason, I was not able to get the quote currency from the config and so had to hard code it. You need to change the symbol EUR to the the desired currency (list of supported currencies).
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
from homeassistant.const import CONF_API_KEY
import requests
import logging
from datetime import timedelta
_RESOURCE = 'https://openexchangerates.org/api/latest.json'
_LOGGER = logging.getLogger(__name__)
# Return cached results if last scan was less then this time ago.
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=75)
CONF_BASE = 'base'
CONF_QUOTE = 'quote'
CONF_NAME = 'name'
def setup_platform(hass, config, add_devices, discovery_info=None):
rest = CurrencyData(_RESOURCE, config.get(CONF_API_KEY),config.get(CONF_BASE),config.get(CONF_QUOTE))
add_devices([CurrencySensor(rest)])
class CurrencySensor(Entity):
def __init__(self, rest):
self.rest = rest
self.update()
self.currency = self.rest.data
@property
def name(self):
return 'Exchange Rates'
@property
def state(self):
# Change 'EUR' to the desired currency.
return round(self.currency['EUR'],2)
@property
def device_state_attributes(self):
return self.currency
def update(self):
"""Update current conditions"""
self.rest.update()
class CurrencyData(object):
def __init__(self, resource, api_key, base, quote):
self._resource = resource
self._api_key = api_key
self._base = base
self._quote = quote
self.data = dict()
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Get the latest data from openexchangerates"""
try:
result = requests.get(self._resource + '?base=' + self._base + '&app_id=' + self._api_key)
self.data = result.json()['rates']
_LOGGER.debug("Exchange Rates updated")
except requests.exceptions.ConnectionError:
_LOGGER.error("No route to host/endpoint: %s", self._resource)
self.data = None
I like the premise, however I’m having some trouble getting it to work as it always fails with a KeyError “rates” no matter if I use the old or new code. Any ideas, I’m using python 3.5 btw.
{
“disclaimer”: “Exchange rates provided for informational purposes only and do not constitute financial advice of any kind. Although every attempt is made to ensure quality, no guarantees are made of accuracy, validity, availability, or fitness for any purpose. All usage subject to acceptance of Terms: Terms & Conditions Of Website Use - Open Exchange Rates”,
“license”: “Data sourced from various providers; resale prohibited; no warranties given of any kind. All usage subject to License Agreement: License Information - Open Exchange Rates”,
“timestamp”: 1466344824,
“base”: “USD”,
“rates”: {
“AED”: 3.67308,
“AFN”: 69.405001,
“ALL”: 122.4899,
“AMD”: 477.479996,
“ANG”: 1.788825,
I think the problem is something to do with the base “USD” variable, as if I put anything other than USD in it it fails with a ‘rates’ error at line 58. So it will work for a base of USD but not anything else and it seems to be the same with all three versions.
I just called openexchangerates from the browser while changing the base rate to GBP and this what I got back …
{
“error”: true,
“status”: 403,
“message”: “not_allowed”,
“description”: “Changing the API base currency is available for Developer, Enterprise and Unlimited plan clients. Please upgrade, or contact [email protected] with any questions.”
}
You get the same with currencylayer if you change the base/source to say GBP…
{
“success”:false,
“error”:{
“code”:105,
“info”:“Access Restricted - Your current Subscription Plan does not support Source Currency Switching.”
}
}
Well…I guess, one can build a complicated logic to translate one currency to other using USD as a base currency. But I wish these services were not so US-centric.