""" homeassistant.components.sensor.bitcoin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Bitcoin information service that uses blockchain.info and its online wallet. Configuration: You need to enable the API access for your online wallet to get the balance. To do that log in and move to 'Account Setting', choose 'IP Restrictions', and check 'Enable Api Access'. You will get an email message from blockchain.info where you must authorize the API access. To use the Bitcoin sensor you will need to add something like the following to your config/configuration.yaml sensor: platform: bitcoin wallet: 'YOUR WALLET_ID' password: YOUR_ACCOUNT_PASSWORD currency: YOUR CURRENCY display_options: - exchangerate - trade_volume_btc - miners_revenue_usd - btc_mined - trade_volume_usd - difficulty - minutes_between_blocks - number_of_transactions - hash_rate - timestamp - mined_blocks - blocks_size - total_fees_btc - total_btc_sent - estimated_btc_sent - total_btc - total_blocks - next_retarget - estimated_transaction_volume_usd - miners_revenue_btc - market_price_usd Variables: wallet *Required This is your wallet identifier from https://blockchain.info to access the online wallet. password *Required Password your your online wallet. currency *Required The currency to exchange to. Eg. CHF, USD, EUR,etc. display_options *Required An array specifying the variables to display. These are the variables for the display_options array. See the configuration example above for a list of all available variables. """ import logging from datetime import timedelta from homeassistant.util import Throttle from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) OPTION_TYPES = { 'wallet': ['Wallet balance', 'BTC'], 'exchangerate': ['Exchange rate (1 BTC)', ''], 'trade_volume_btc': ['Trade volume', 'BTC'], 'miners_revenue_usd': ['Miners revenue', 'USD'], 'btc_mined': ['Mined', 'BTC'], 'trade_volume_usd': ['Trade volume', 'USD'], 'difficulty': ['Difficulty', ''], 'minutes_between_blocks': ['Time between Blocks', 'min'], 'number_of_transactions': ['No. of Transactions', ''], 'hash_rate': ['Hash rate', 'PH/s'], 'timestamp': ['Timestamp', ''], 'mined_blocks': ['Minded Blocks', ''], 'blocks_size': ['Block size', ''], 'total_fees_btc': ['Total fees', 'BTC'], 'total_btc_sent': ['Total sent', 'BTC'], 'estimated_btc_sent': ['Estimated sent', 'BTC'], 'total_btc': ['Total', 'BTC'], 'total_blocks': ['Total Blocks', ''], 'next_retarget': ['Next retarget', ''], 'estimated_transaction_volume_usd': ['Est. Transaction volume', 'USD'], 'miners_revenue_btc': ['Miners revenue', 'BTC'], 'market_price_usd': ['Market price', 'USD'] } # Return cached results if last scan was less then this time ago MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=120) def setup_platform(hass, config, add_devices, discovery_info=None): """ Get the Bitcoin sensor. """ try: from blockchain.wallet import Wallet from blockchain import exchangerates, exceptions except ImportError: _LOGGER.exception( "Unable to import blockchain. " "Did you maybe not install the 'blockchain' package?") return None wallet_id = config.get('wallet', None) password = config.get('password', None) currency = config.get('currency', 'USD') if currency not in exchangerates.get_ticker(): _LOGGER.error('Currency "%s" is not available. Using "USD".', currency) currency = 'USD' wallet = Wallet(wallet_id, password) try: wallet.get_balance() except exceptions.APIException as error: _LOGGER.error(error) wallet = None dev = [] if wallet is not None and password: dev.append(BitcoinSensor('wallet', currency, wallet)) for variable in config['display_options']: if variable not in OPTION_TYPES: _LOGGER.error('Option type: "%s" does not exist', variable) else: print("############ ", variable) dev.append(BitcoinSensor(variable, currency)) add_devices(dev) # pylint: disable=too-few-public-methods class BitcoinSensor(Entity): """ Implements a Bitcoin sensor. """ def __init__(self, option_type, currency, wallet=''): self._name = OPTION_TYPES[option_type][0] self._unit_of_measurement = OPTION_TYPES[option_type][1] self._currency = currency self._wallet = wallet self.type = option_type self._state = None self.update() @property def name(self): """ Returns the name of the device. """ return self._name @property def state(self): """ Returns the state of the device. """ return self._state @property def unit_of_measurement(self): return self._unit_of_measurement # pylint: disable=too-many-branches @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): """ Gets the latest data and updates the states. """ from blockchain import statistics, exchangerates stats = statistics.get() ticker = exchangerates.get_ticker() # pylint: disable=no-member if self.type == 'wallet' and self._wallet is not None: self._state = '{0:.8f}'.format(self._wallet.get_balance() * 0.00000001) elif self.type == 'exchangerate': self._state = ticker[self._currency].p15min self._unit_of_measurement = self._currency elif self.type == 'trade_volume_btc': self._state = '{0:.1f}'.format(stats.trade_volume_btc) elif self.type == 'miners_revenue_usd': self._state = '{0:.0f}'.format(stats.miners_revenue_usd) elif self.type == 'btc_mined': self._state = '{}'.format(stats.btc_mined * 0.00000001) elif self.type == 'trade_volume_usd': self._state = '{0:.1f}'.format(stats.trade_volume_usd) elif self.type == 'difficulty': self._state = '{0:.0f}'.format(stats.difficulty) elif self.type == 'minutes_between_blocks': self._state = '{0:.2f}'.format(stats.minutes_between_blocks) elif self.type == 'number_of_transactions': self._state = '{}'.format(stats.number_of_transactions) elif self.type == 'hash_rate': self._state = '{0:.1f}'.format(stats.hash_rate * 0.000001) elif self.type == 'timestamp': self._state = stats.timestamp elif self.type == 'mined_blocks': self._state = '{}'.format(stats.mined_blocks) elif self.type == 'blocks_size': self._state = '{0:.1f}'.format(stats.blocks_size) elif self.type == 'total_fees_btc': self._state = '{0:.2f}'.format(stats.total_fees_btc * 0.00000001) elif self.type == 'total_btc_sent': self._state = '{0:.2f}'.format(stats.total_btc_sent * 0.00000001) elif self.type == 'estimated_btc_sent': self._state = '{0:.2f}'.format(stats.estimated_btc_sent * 0.00000001) elif self.type == 'total_btc': self._state = '{0:.2f}'.format(stats.total_btc * 0.00000001) elif self.type == 'total_blocks': self._state = '{0:.2f}'.format(stats.total_blocks) elif self.type == 'next_retarget': self._state = '{0:.2f}'.format(stats.next_retarget) elif self.type == 'estimated_transaction_volume_usd': self._state = '{0:.2f}'.format( stats.estimated_transaction_volume_usd) elif self.type == 'miners_revenue_btc': self._state = '{0:.1f}'.format(stats.miners_revenue_btc * 0.00000001) elif self.type == 'market_price_usd': self._state = '{0:.2f}'.format(stats.market_price_usd)