mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Add display currency setting to CoinMarketCap sensor (#10093)
* Add support for different display currencies in CoinMarkerCap sensor. * Add test for CoinMarketCap sensor. * Add test dependency to gen_requirements_all. * Fix review comments: use string formatting and less string case chanes.
This commit is contained in:
parent
2561efe45d
commit
c2ef22bd08
@ -465,7 +465,6 @@ omit =
|
||||
homeassistant/components/sensor/broadlink.py
|
||||
homeassistant/components/sensor/buienradar.py
|
||||
homeassistant/components/sensor/citybikes.py
|
||||
homeassistant/components/sensor/coinmarketcap.py
|
||||
homeassistant/components/sensor/cert_expiry.py
|
||||
homeassistant/components/sensor/comed_hourly_pricing.py
|
||||
homeassistant/components/sensor/cpuspeed.py
|
||||
|
@ -12,26 +12,28 @@ import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import ATTR_ATTRIBUTION, CONF_CURRENCY
|
||||
from homeassistant.const import (
|
||||
ATTR_ATTRIBUTION, CONF_CURRENCY, CONF_DISPLAY_CURRENCY)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
REQUIREMENTS = ['coinmarketcap==4.1.1']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_24H_VOLUME_USD = '24h_volume_usd'
|
||||
ATTR_24H_VOLUME = '24h_volume'
|
||||
ATTR_AVAILABLE_SUPPLY = 'available_supply'
|
||||
ATTR_MARKET_CAP = 'market_cap_usd'
|
||||
ATTR_MARKET_CAP = 'market_cap'
|
||||
ATTR_NAME = 'name'
|
||||
ATTR_PERCENT_CHANGE_24H = 'percent_change_24h'
|
||||
ATTR_PERCENT_CHANGE_7D = 'percent_change_7d'
|
||||
ATTR_PRICE = 'price_usd'
|
||||
ATTR_PRICE = 'price'
|
||||
ATTR_SYMBOL = 'symbol'
|
||||
ATTR_TOTAL_SUPPLY = 'total_supply'
|
||||
|
||||
CONF_ATTRIBUTION = "Data provided by CoinMarketCap"
|
||||
|
||||
DEFAULT_CURRENCY = 'bitcoin'
|
||||
DEFAULT_DISPLAY_CURRENCY = 'USD'
|
||||
|
||||
ICON = 'mdi:currency-usd'
|
||||
|
||||
@ -39,21 +41,26 @@ SCAN_INTERVAL = timedelta(minutes=15)
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_CURRENCY, default=DEFAULT_CURRENCY): cv.string,
|
||||
vol.Optional(CONF_DISPLAY_CURRENCY, default=DEFAULT_DISPLAY_CURRENCY):
|
||||
cv.string,
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the CoinMarketCap sensor."""
|
||||
currency = config.get(CONF_CURRENCY)
|
||||
display_currency = config.get(CONF_DISPLAY_CURRENCY).lower()
|
||||
|
||||
try:
|
||||
CoinMarketCapData(currency).update()
|
||||
CoinMarketCapData(currency, display_currency).update()
|
||||
except HTTPError:
|
||||
_LOGGER.warning("Currency %s is not available. Using bitcoin",
|
||||
currency)
|
||||
_LOGGER.warning("Currency %s or display currency %s is not available. "
|
||||
"Using bitcoin and USD.", currency, display_currency)
|
||||
currency = DEFAULT_CURRENCY
|
||||
display_currency = DEFAULT_DISPLAY_CURRENCY
|
||||
|
||||
add_devices([CoinMarketCapSensor(CoinMarketCapData(currency))], True)
|
||||
add_devices([CoinMarketCapSensor(
|
||||
CoinMarketCapData(currency, display_currency))], True)
|
||||
|
||||
|
||||
class CoinMarketCapSensor(Entity):
|
||||
@ -63,7 +70,7 @@ class CoinMarketCapSensor(Entity):
|
||||
"""Initialize the sensor."""
|
||||
self.data = data
|
||||
self._ticker = None
|
||||
self._unit_of_measurement = 'USD'
|
||||
self._unit_of_measurement = self.data.display_currency.upper()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@ -73,7 +80,8 @@ class CoinMarketCapSensor(Entity):
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return round(float(self._ticker.get('price_usd')), 2)
|
||||
return round(float(self._ticker.get(
|
||||
'price_{}'.format(self.data.display_currency))), 2)
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
@ -89,10 +97,12 @@ class CoinMarketCapSensor(Entity):
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes of the sensor."""
|
||||
return {
|
||||
ATTR_24H_VOLUME_USD: self._ticker.get('24h_volume_usd'),
|
||||
ATTR_24H_VOLUME: self._ticker.get(
|
||||
'24h_volume_{}'.format(self.data.display_currency)),
|
||||
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
|
||||
ATTR_AVAILABLE_SUPPLY: self._ticker.get('available_supply'),
|
||||
ATTR_MARKET_CAP: self._ticker.get('market_cap_usd'),
|
||||
ATTR_MARKET_CAP: self._ticker.get(
|
||||
'market_cap_{}'.format(self.data.display_currency)),
|
||||
ATTR_PERCENT_CHANGE_24H: self._ticker.get('percent_change_24h'),
|
||||
ATTR_PERCENT_CHANGE_7D: self._ticker.get('percent_change_7d'),
|
||||
ATTR_SYMBOL: self._ticker.get('symbol'),
|
||||
@ -108,12 +118,16 @@ class CoinMarketCapSensor(Entity):
|
||||
class CoinMarketCapData(object):
|
||||
"""Get the latest data and update the states."""
|
||||
|
||||
def __init__(self, currency):
|
||||
def __init__(self, currency, display_currency):
|
||||
"""Initialize the data object."""
|
||||
self.currency = currency
|
||||
self.display_currency = display_currency
|
||||
self.ticker = None
|
||||
|
||||
def update(self):
|
||||
"""Get the latest data from blockchain.info."""
|
||||
from coinmarketcap import Market
|
||||
self.ticker = Market().ticker(self.currency, limit=1)
|
||||
self.ticker = Market().ticker(
|
||||
self.currency,
|
||||
limit=1,
|
||||
convert=self.display_currency)
|
||||
|
@ -89,6 +89,7 @@ CONF_DEVICES = 'devices'
|
||||
CONF_DISARM_AFTER_TRIGGER = 'disarm_after_trigger'
|
||||
CONF_DISCOVERY = 'discovery'
|
||||
CONF_DISPLAY_OPTIONS = 'display_options'
|
||||
CONF_DISPLAY_CURRENCY = 'display_currency'
|
||||
CONF_DOMAIN = 'domain'
|
||||
CONF_DOMAINS = 'domains'
|
||||
CONF_EFFECT = 'effect'
|
||||
|
@ -36,6 +36,9 @@ aiohttp_cors==0.5.3
|
||||
# homeassistant.components.notify.apns
|
||||
apns2==0.1.1
|
||||
|
||||
# homeassistant.components.sensor.coinmarketcap
|
||||
coinmarketcap==4.1.1
|
||||
|
||||
# homeassistant.components.device_tracker.upc_connect
|
||||
defusedxml==0.5.0
|
||||
|
||||
|
@ -39,6 +39,7 @@ TEST_REQUIREMENTS = (
|
||||
'aioautomatic',
|
||||
'aiohttp_cors',
|
||||
'apns2',
|
||||
'coinmarketcap',
|
||||
'defusedxml',
|
||||
'dsmr_parser',
|
||||
'ephem',
|
||||
|
44
tests/components/sensor/test_coinmarketcap.py
Normal file
44
tests/components/sensor/test_coinmarketcap.py
Normal file
@ -0,0 +1,44 @@
|
||||
"""Tests for the CoinMarketCap sensor platform."""
|
||||
import json
|
||||
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import homeassistant.components.sensor as sensor
|
||||
from homeassistant.setup import setup_component
|
||||
from tests.common import (
|
||||
get_test_home_assistant, load_fixture, assert_setup_component)
|
||||
|
||||
VALID_CONFIG = {
|
||||
'platform': 'coinmarketcap',
|
||||
'currency': 'ethereum',
|
||||
'display_currency': 'EUR',
|
||||
}
|
||||
|
||||
|
||||
class TestCoinMarketCapSensor(unittest.TestCase):
|
||||
"""Test the CoinMarketCap sensor."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
self.config = VALID_CONFIG
|
||||
|
||||
def tearDown(self):
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
@patch('coinmarketcap.Market.ticker',
|
||||
return_value=json.loads(load_fixture('coinmarketcap.json')))
|
||||
def test_setup(self, mock_request):
|
||||
"""Test the setup with custom settings."""
|
||||
with assert_setup_component(1, sensor.DOMAIN):
|
||||
assert setup_component(self.hass, sensor.DOMAIN, {
|
||||
'sensor': VALID_CONFIG})
|
||||
|
||||
state = self.hass.states.get('sensor.ethereum')
|
||||
assert state is not None
|
||||
|
||||
assert state.state == '240.47'
|
||||
assert state.attributes.get('symbol') == 'ETH'
|
||||
assert state.attributes.get('unit_of_measurement') == 'EUR'
|
21
tests/fixtures/coinmarketcap.json
vendored
Normal file
21
tests/fixtures/coinmarketcap.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"id": "ethereum",
|
||||
"name": "Ethereum",
|
||||
"symbol": "ETH",
|
||||
"rank": "2",
|
||||
"price_usd": "282.423",
|
||||
"price_btc": "0.048844",
|
||||
"24h_volume_usd": "407024000.0",
|
||||
"market_cap_usd": "26908205315.0",
|
||||
"available_supply": "95276253.0",
|
||||
"total_supply": "95276253.0",
|
||||
"percent_change_1h": "0.06",
|
||||
"percent_change_24h": "-4.57",
|
||||
"percent_change_7d": "-16.39",
|
||||
"last_updated": "1508776751",
|
||||
"price_eur": "240.473299695",
|
||||
"24h_volume_eur": "346566690.16",
|
||||
"market_cap_eur": "22911395039.0"
|
||||
}
|
||||
]
|
Loading…
x
Reference in New Issue
Block a user