Displaying current exchange rates using OpenExchangeRates

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.

sensor:
  platform: currency
  api_key: [API_KEY]
  base: USD
  quote: EUR

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
1 Like

See the updated sensor here https://github.com/arsaboo/HASS/tree/master/custom-components/OpenExchangeRates

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.

1000 requests per month… I wonder who would make so many requests per day…? Not that I would watch an increase or decrease at home all day…

Trust me…if you are really serious about currency trades…you can blow that 1000 up in a day :slight_smile:

Did you check your API key? Try entering https://openexchangerates.org/api/latest.json?app_id=your_api_key_here in a browser to see if your key is valid.

If I do that I get the correct response -

{
“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,

"ZAR": 15.14544,
"ZMK": 5253.075255,
"ZMW": 10.938713,
"ZWL": 322.387247

}
}

So the API key is valid.

What do you have in your config? Also, you can try the other sensor using currencylayer.

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.”
}

So that explains why I’m getting an error.

Ahh…that makes sense. May be currencylayer is the way to go. Thanks for pointing it out…I will update the instructions accordingly.

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.”
}
}

:frowning:

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.

No need for this, seems something is coming for fixer.io. Dont even need API keys

If you’re really serious about currency trades, you’re probably not spending a lot of time dicking around with your open source home automation setup :wink: