mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 14:57:09 +00:00
Add configurable decimal rounding of display value for CoinMarketCap sensor and upgrade to 5.0.3 (#14437) (#14604)
This commit is contained in:
parent
143be49c66
commit
b4f8d52fb1
@ -13,64 +13,78 @@ import voluptuous as vol
|
|||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ATTRIBUTION, CONF_CURRENCY, CONF_DISPLAY_CURRENCY)
|
ATTR_ATTRIBUTION, CONF_DISPLAY_CURRENCY)
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
REQUIREMENTS = ['coinmarketcap==4.2.1']
|
REQUIREMENTS = ['coinmarketcap==5.0.3']
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ATTR_24H_VOLUME = '24h_volume'
|
ATTR_VOLUME_24H = 'volume_24h'
|
||||||
ATTR_AVAILABLE_SUPPLY = 'available_supply'
|
ATTR_AVAILABLE_SUPPLY = 'available_supply'
|
||||||
|
ATTR_CIRCULATING_SUPPLY = 'circulating_supply'
|
||||||
ATTR_MARKET_CAP = 'market_cap'
|
ATTR_MARKET_CAP = 'market_cap'
|
||||||
ATTR_PERCENT_CHANGE_24H = 'percent_change_24h'
|
ATTR_PERCENT_CHANGE_24H = 'percent_change_24h'
|
||||||
ATTR_PERCENT_CHANGE_7D = 'percent_change_7d'
|
ATTR_PERCENT_CHANGE_7D = 'percent_change_7d'
|
||||||
ATTR_PERCENT_CHANGE_1H = 'percent_change_1h'
|
ATTR_PERCENT_CHANGE_1H = 'percent_change_1h'
|
||||||
ATTR_PRICE = 'price'
|
ATTR_PRICE = 'price'
|
||||||
|
ATTR_RANK = 'rank'
|
||||||
ATTR_SYMBOL = 'symbol'
|
ATTR_SYMBOL = 'symbol'
|
||||||
ATTR_TOTAL_SUPPLY = 'total_supply'
|
ATTR_TOTAL_SUPPLY = 'total_supply'
|
||||||
|
|
||||||
CONF_ATTRIBUTION = "Data provided by CoinMarketCap"
|
CONF_ATTRIBUTION = "Data provided by CoinMarketCap"
|
||||||
|
CONF_CURRENCY_ID = 'currency_id'
|
||||||
|
CONF_DISPLAY_CURRENCY_DECIMALS = 'display_currency_decimals'
|
||||||
|
|
||||||
DEFAULT_CURRENCY = 'bitcoin'
|
DEFAULT_CURRENCY_ID = 1
|
||||||
DEFAULT_DISPLAY_CURRENCY = 'USD'
|
DEFAULT_DISPLAY_CURRENCY = 'USD'
|
||||||
|
DEFAULT_DISPLAY_CURRENCY_DECIMALS = 2
|
||||||
|
|
||||||
ICON = 'mdi:currency-usd'
|
ICON = 'mdi:currency-usd'
|
||||||
|
|
||||||
SCAN_INTERVAL = timedelta(minutes=15)
|
SCAN_INTERVAL = timedelta(minutes=15)
|
||||||
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
vol.Optional(CONF_CURRENCY, default=DEFAULT_CURRENCY): cv.string,
|
vol.Optional(CONF_CURRENCY_ID, default=DEFAULT_CURRENCY_ID):
|
||||||
|
cv.positive_int,
|
||||||
vol.Optional(CONF_DISPLAY_CURRENCY, default=DEFAULT_DISPLAY_CURRENCY):
|
vol.Optional(CONF_DISPLAY_CURRENCY, default=DEFAULT_DISPLAY_CURRENCY):
|
||||||
cv.string,
|
cv.string,
|
||||||
|
vol.Optional(CONF_DISPLAY_CURRENCY_DECIMALS,
|
||||||
|
default=DEFAULT_DISPLAY_CURRENCY_DECIMALS):
|
||||||
|
vol.All(vol.Coerce(int), vol.Range(min=1)),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
"""Set up the CoinMarketCap sensor."""
|
"""Set up the CoinMarketCap sensor."""
|
||||||
currency = config.get(CONF_CURRENCY)
|
currency_id = config.get(CONF_CURRENCY_ID)
|
||||||
display_currency = config.get(CONF_DISPLAY_CURRENCY).lower()
|
display_currency = config.get(CONF_DISPLAY_CURRENCY).upper()
|
||||||
|
display_currency_decimals = config.get(CONF_DISPLAY_CURRENCY_DECIMALS)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
CoinMarketCapData(currency, display_currency).update()
|
CoinMarketCapData(currency_id, display_currency).update()
|
||||||
except HTTPError:
|
except HTTPError:
|
||||||
_LOGGER.warning("Currency %s or display currency %s is not available. "
|
_LOGGER.warning("Currency ID %s or display currency %s "
|
||||||
"Using bitcoin and USD.", currency, display_currency)
|
"is not available. Using 1 (bitcoin) "
|
||||||
currency = DEFAULT_CURRENCY
|
"and USD.", currency_id, display_currency)
|
||||||
|
currency_id = DEFAULT_CURRENCY_ID
|
||||||
display_currency = DEFAULT_DISPLAY_CURRENCY
|
display_currency = DEFAULT_DISPLAY_CURRENCY
|
||||||
|
|
||||||
add_devices([CoinMarketCapSensor(
|
add_devices([CoinMarketCapSensor(
|
||||||
CoinMarketCapData(currency, display_currency))], True)
|
CoinMarketCapData(
|
||||||
|
currency_id, display_currency), display_currency_decimals)], True)
|
||||||
|
|
||||||
|
|
||||||
class CoinMarketCapSensor(Entity):
|
class CoinMarketCapSensor(Entity):
|
||||||
"""Representation of a CoinMarketCap sensor."""
|
"""Representation of a CoinMarketCap sensor."""
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data, display_currency_decimals):
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
self.data = data
|
self.data = data
|
||||||
|
self.display_currency_decimals = display_currency_decimals
|
||||||
self._ticker = None
|
self._ticker = None
|
||||||
self._unit_of_measurement = self.data.display_currency.upper()
|
self._unit_of_measurement = self.data.display_currency
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@ -80,8 +94,9 @@ class CoinMarketCapSensor(Entity):
|
|||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
return round(float(self._ticker.get(
|
return round(float(
|
||||||
'price_{}'.format(self.data.display_currency))), 2)
|
self._ticker.get('quotes').get(self.data.display_currency)
|
||||||
|
.get('price')), self.display_currency_decimals)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unit_of_measurement(self):
|
def unit_of_measurement(self):
|
||||||
@ -97,15 +112,24 @@ class CoinMarketCapSensor(Entity):
|
|||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
"""Return the state attributes of the sensor."""
|
"""Return the state attributes of the sensor."""
|
||||||
return {
|
return {
|
||||||
ATTR_24H_VOLUME: self._ticker.get(
|
ATTR_VOLUME_24H:
|
||||||
'24h_volume_{}'.format(self.data.display_currency)),
|
self._ticker.get('quotes').get(self.data.display_currency)
|
||||||
|
.get('volume_24h'),
|
||||||
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
|
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
|
||||||
ATTR_AVAILABLE_SUPPLY: self._ticker.get('available_supply'),
|
ATTR_CIRCULATING_SUPPLY: self._ticker.get('circulating_supply'),
|
||||||
ATTR_MARKET_CAP: self._ticker.get(
|
ATTR_MARKET_CAP:
|
||||||
'market_cap_{}'.format(self.data.display_currency)),
|
self._ticker.get('quotes').get(self.data.display_currency)
|
||||||
ATTR_PERCENT_CHANGE_24H: self._ticker.get('percent_change_24h'),
|
.get('market_cap'),
|
||||||
ATTR_PERCENT_CHANGE_7D: self._ticker.get('percent_change_7d'),
|
ATTR_PERCENT_CHANGE_24H:
|
||||||
ATTR_PERCENT_CHANGE_1H: self._ticker.get('percent_change_1h'),
|
self._ticker.get('quotes').get(self.data.display_currency)
|
||||||
|
.get('percent_change_24h'),
|
||||||
|
ATTR_PERCENT_CHANGE_7D:
|
||||||
|
self._ticker.get('quotes').get(self.data.display_currency)
|
||||||
|
.get('percent_change_7d'),
|
||||||
|
ATTR_PERCENT_CHANGE_1H:
|
||||||
|
self._ticker.get('quotes').get(self.data.display_currency)
|
||||||
|
.get('percent_change_1h'),
|
||||||
|
ATTR_RANK: self._ticker.get('rank'),
|
||||||
ATTR_SYMBOL: self._ticker.get('symbol'),
|
ATTR_SYMBOL: self._ticker.get('symbol'),
|
||||||
ATTR_TOTAL_SUPPLY: self._ticker.get('total_supply'),
|
ATTR_TOTAL_SUPPLY: self._ticker.get('total_supply'),
|
||||||
}
|
}
|
||||||
@ -113,20 +137,20 @@ class CoinMarketCapSensor(Entity):
|
|||||||
def update(self):
|
def update(self):
|
||||||
"""Get the latest data and updates the states."""
|
"""Get the latest data and updates the states."""
|
||||||
self.data.update()
|
self.data.update()
|
||||||
self._ticker = self.data.ticker[0]
|
self._ticker = self.data.ticker.get('data')
|
||||||
|
|
||||||
|
|
||||||
class CoinMarketCapData(object):
|
class CoinMarketCapData(object):
|
||||||
"""Get the latest data and update the states."""
|
"""Get the latest data and update the states."""
|
||||||
|
|
||||||
def __init__(self, currency, display_currency):
|
def __init__(self, currency_id, display_currency):
|
||||||
"""Initialize the data object."""
|
"""Initialize the data object."""
|
||||||
self.currency = currency
|
self.currency_id = currency_id
|
||||||
self.display_currency = display_currency
|
self.display_currency = display_currency
|
||||||
self.ticker = None
|
self.ticker = None
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Get the latest data from blockchain.info."""
|
"""Get the latest data from coinmarketcap.com."""
|
||||||
from coinmarketcap import Market
|
from coinmarketcap import Market
|
||||||
self.ticker = Market().ticker(
|
self.ticker = Market().ticker(
|
||||||
self.currency, limit=1, convert=self.display_currency)
|
self.currency_id, convert=self.display_currency)
|
||||||
|
@ -199,7 +199,7 @@ ciscosparkapi==0.4.2
|
|||||||
coinbase==2.1.0
|
coinbase==2.1.0
|
||||||
|
|
||||||
# homeassistant.components.sensor.coinmarketcap
|
# homeassistant.components.sensor.coinmarketcap
|
||||||
coinmarketcap==4.2.1
|
coinmarketcap==5.0.3
|
||||||
|
|
||||||
# homeassistant.scripts.check_config
|
# homeassistant.scripts.check_config
|
||||||
colorlog==3.1.4
|
colorlog==3.1.4
|
||||||
|
@ -44,7 +44,7 @@ apns2==0.3.0
|
|||||||
caldav==0.5.0
|
caldav==0.5.0
|
||||||
|
|
||||||
# homeassistant.components.sensor.coinmarketcap
|
# homeassistant.components.sensor.coinmarketcap
|
||||||
coinmarketcap==4.2.1
|
coinmarketcap==5.0.3
|
||||||
|
|
||||||
# homeassistant.components.device_tracker.upc_connect
|
# homeassistant.components.device_tracker.upc_connect
|
||||||
defusedxml==0.5.0
|
defusedxml==0.5.0
|
||||||
|
@ -11,8 +11,9 @@ from tests.common import (
|
|||||||
|
|
||||||
VALID_CONFIG = {
|
VALID_CONFIG = {
|
||||||
'platform': 'coinmarketcap',
|
'platform': 'coinmarketcap',
|
||||||
'currency': 'ethereum',
|
'currency_id': 1027,
|
||||||
'display_currency': 'EUR',
|
'display_currency': 'EUR',
|
||||||
|
'display_currency_decimals': 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -39,6 +40,6 @@ class TestCoinMarketCapSensor(unittest.TestCase):
|
|||||||
state = self.hass.states.get('sensor.ethereum')
|
state = self.hass.states.get('sensor.ethereum')
|
||||||
assert state is not None
|
assert state is not None
|
||||||
|
|
||||||
assert state.state == '240.47'
|
assert state.state == '493.455'
|
||||||
assert state.attributes.get('symbol') == 'ETH'
|
assert state.attributes.get('symbol') == 'ETH'
|
||||||
assert state.attributes.get('unit_of_measurement') == 'EUR'
|
assert state.attributes.get('unit_of_measurement') == 'EUR'
|
||||||
|
55
tests/fixtures/coinmarketcap.json
vendored
55
tests/fixtures/coinmarketcap.json
vendored
@ -1,21 +1,36 @@
|
|||||||
[
|
{
|
||||||
{
|
"cached": false,
|
||||||
"id": "ethereum",
|
"data": {
|
||||||
"name": "Ethereum",
|
"id": 1027,
|
||||||
"symbol": "ETH",
|
"name": "Ethereum",
|
||||||
"rank": "2",
|
"symbol": "ETH",
|
||||||
"price_usd": "282.423",
|
"website_slug": "ethereum",
|
||||||
"price_btc": "0.048844",
|
"rank": 2,
|
||||||
"24h_volume_usd": "407024000.0",
|
"circulating_supply": 99619842.0,
|
||||||
"market_cap_usd": "26908205315.0",
|
"total_supply": 99619842.0,
|
||||||
"available_supply": "95276253.0",
|
"max_supply": null,
|
||||||
"total_supply": "95276253.0",
|
"quotes": {
|
||||||
"percent_change_1h": "0.06",
|
"USD": {
|
||||||
"percent_change_24h": "-4.57",
|
"price": 577.019,
|
||||||
"percent_change_7d": "-16.39",
|
"volume_24h": 2839960000.0,
|
||||||
"last_updated": "1508776751",
|
"market_cap": 57482541899.0,
|
||||||
"price_eur": "240.473299695",
|
"percent_change_1h": -2.28,
|
||||||
"24h_volume_eur": "346566690.16",
|
"percent_change_24h": -14.88,
|
||||||
"market_cap_eur": "22911395039.0"
|
"percent_change_7d": -17.51
|
||||||
|
},
|
||||||
|
"EUR": {
|
||||||
|
"price": 493.454724572,
|
||||||
|
"volume_24h": 2428699712.48,
|
||||||
|
"market_cap": 49158380042.0,
|
||||||
|
"percent_change_1h": -2.28,
|
||||||
|
"percent_change_24h": -14.88,
|
||||||
|
"percent_change_7d": -17.51
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last_updated": 1527098658
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"timestamp": 1527098716,
|
||||||
|
"error": null
|
||||||
}
|
}
|
||||||
]
|
}
|
Loading…
x
Reference in New Issue
Block a user