From c97ab456f22dca6a69e3775cc1353dbf3957389a Mon Sep 17 00:00:00 2001 From: "Alfie \"Azelphur\" Day" Date: Tue, 19 May 2015 00:27:09 +0100 Subject: [PATCH 01/13] Add basic support for LimitlessLED --- .../components/light/limitlessled.py | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 homeassistant/components/light/limitlessled.py diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py new file mode 100644 index 00000000000..53411d319d7 --- /dev/null +++ b/homeassistant/components/light/limitlessled.py @@ -0,0 +1,102 @@ +""" +homeassistant.components.light.limitlessled +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Support for LimitlessLED bulbs, also known as... + +EasyBulb +AppLight +AppLamp +MiLight +LEDme +dekolight +iLight + +""" +import random +import logging + +from homeassistant.helpers.entity import ToggleEntity +from homeassistant.const import STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME +from homeassistant.components.light import ATTR_BRIGHTNESS + +_LOGGER = logging.getLogger(__name__) + + +def setup_platform(hass, config, add_devices_callback, discovery_info=None): + try: + import ledcontroller + except ImportError: + _LOGGER.exception("Error while importing dependency ledcontroller.") + return + + led = ledcontroller.LedController(config['host']) + + lights = [] + for i in range(1, 5): + if 'group_%d_name' % (i) in config: + lights.append( + LimitlessLED( + led, + i, + config['group_%d_name' % (i)], + STATE_OFF + ) + ) + + add_devices_callback(lights) + + +class LimitlessLED(ToggleEntity): + def __init__(self, led, group, name, state, brightness=180): + self.led = led + self.group = group + + # LimitlessLEDs don't report state, we have track it ourselves. + self.led.off(self.group) + + self._name = name or DEVICE_DEFAULT_NAME + self._state = state + self._brightness = brightness + + @property + def should_poll(self): + """ No polling needed for a demo light. """ + return False + + @property + def name(self): + """ Returns the name of the device if any. """ + return self._name + + @property + def state(self): + """ Returns the name of the device if any. """ + return self._state + + @property + def state_attributes(self): + """ Returns optional state attributes. """ + if self.is_on: + return { + ATTR_BRIGHTNESS: self._brightness, + } + + @property + def is_on(self): + """ True if device is on. """ + return self._state == STATE_ON + + def turn_on(self, **kwargs): + """ Turn the device on. """ + self._state = STATE_ON + + if ATTR_BRIGHTNESS in kwargs: + self._brightness = kwargs[ATTR_BRIGHTNESS] + + self.led.set_brightness(self._brightness, self.group) + + def turn_off(self, **kwargs): + """ Turn the device off. """ + self._state = STATE_OFF + self.led.off(self.group) From 5b1c372fdf4b62b463089b78ac9e88037924a7db Mon Sep 17 00:00:00 2001 From: "Alfie \"Azelphur\" Day" Date: Tue, 19 May 2015 01:55:37 +0100 Subject: [PATCH 02/13] Add configuration.yaml example in the header --- homeassistant/components/light/limitlessled.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index 53411d319d7..3525d0a20c8 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -12,6 +12,14 @@ LEDme dekolight iLight +light: + platform: limitlessled + host: 192.168.1.10 + group_1_name: Living Room + group_2_name: Bedroom + group_3_name: Office + group_4_name: Kitchen + """ import random import logging From 6132ed1967ff4c02b2ee6eba930a4a1fc95ba553 Mon Sep 17 00:00:00 2001 From: "Alfie \"Azelphur\" Day" Date: Tue, 19 May 2015 01:58:16 +0100 Subject: [PATCH 03/13] Add ledcontroller to requirements.txt --- requirements.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/requirements.txt b/requirements.txt index 8bc2c4616ee..63e3f3d5022 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,6 +14,9 @@ pyephem>=3.7 # lights.hue phue>=0.8 +# lights.limitlessled +ledcontroller>=1.0.7 + # media_player.cast pychromecast>=0.5 From 0e9dc61805c64516415f620edfdabec10f6b9481 Mon Sep 17 00:00:00 2001 From: "Alfie \"Azelphur\" Day" Date: Tue, 19 May 2015 02:09:34 +0100 Subject: [PATCH 04/13] Fix some code styling violations --- homeassistant/components/light/limitlessled.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index 3525d0a20c8..ba9ac9b3a05 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -21,7 +21,6 @@ light: group_4_name: Kitchen """ -import random import logging from homeassistant.helpers.entity import ToggleEntity @@ -32,6 +31,7 @@ _LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_devices_callback, discovery_info=None): + """ Gets the LimitlessLED lights. """ try: import ledcontroller except ImportError: @@ -56,6 +56,8 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): class LimitlessLED(ToggleEntity): + """ Represents a LimitlessLED light """ + def __init__(self, led, group, name, state, brightness=180): self.led = led self.group = group From f52412df41b6a9047e21e350ea0c3b17a52f9da3 Mon Sep 17 00:00:00 2001 From: "Alfie \"Azelphur\" Day" Date: Tue, 19 May 2015 02:31:30 +0100 Subject: [PATCH 05/13] More pylint fixes --- homeassistant/components/light/limitlessled.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index ba9ac9b3a05..36492d4d10f 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -47,8 +47,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): LimitlessLED( led, i, - config['group_%d_name' % (i)], - STATE_OFF + config['group_%d_name' % (i)] ) ) @@ -58,7 +57,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): class LimitlessLED(ToggleEntity): """ Represents a LimitlessLED light """ - def __init__(self, led, group, name, state, brightness=180): + def __init__(self, led, group, name): self.led = led self.group = group @@ -66,7 +65,7 @@ class LimitlessLED(ToggleEntity): self.led.off(self.group) self._name = name or DEVICE_DEFAULT_NAME - self._state = state + self._state = STATE_OFF self._brightness = brightness @property From 2b444b0a28af29b55708166944c94c2095acc541 Mon Sep 17 00:00:00 2001 From: "Alfie \"Azelphur\" Day" Date: Tue, 19 May 2015 02:33:37 +0100 Subject: [PATCH 06/13] And fix the part where I'm being stupid --- homeassistant/components/light/limitlessled.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index 36492d4d10f..deb98e2428e 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -66,7 +66,7 @@ class LimitlessLED(ToggleEntity): self._name = name or DEVICE_DEFAULT_NAME self._state = STATE_OFF - self._brightness = brightness + self._brightness = 100 @property def should_poll(self): From 827fd4d070f4218468b2591399781901f46d60e4 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 15 May 2015 15:19:49 +0200 Subject: [PATCH 07/13] add bitcoin sensor --- homeassistant/components/sensor/bitcoin.py | 232 +++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 homeassistant/components/sensor/bitcoin.py diff --git a/homeassistant/components/sensor/bitcoin.py b/homeassistant/components/sensor/bitcoin.py new file mode 100644 index 00000000000..8394744504c --- /dev/null +++ b/homeassistant/components/sensor/bitcoin.py @@ -0,0 +1,232 @@ +""" +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: + - type: 'exchangerate' + - type: 'trade_volume_btc' + - type: 'miners_revenue_usd' + - type: 'btc_mined' + - type: 'trade_volume_usd' + - type: 'difficulty' + - type: 'minutes_between_blocks' + - type: 'number_of_transactions' + - type: 'hash_rate' + - type: 'timestamp' + - type: 'mined_blocks' + - type: 'blocks_size' + - type: 'total_fees_btc' + - type: 'total_btc_sent' + - type: 'estimated_btc_sent' + - type: 'total_btc' + - type: 'total_blocks' + - type: 'next_retarget' + - type: 'estimated_transaction_volume_usd' + - type: 'miners_revenue_btc' + - type: '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.: + +type +*Required +The variable you wish to display, see the configuration example above for a +list of all available variables. +""" +import logging +from blockchain import statistics, exchangerates + +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'] +} + + +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 e: + _LOGGER.error(e) + wallet = None + + dev = [] + if wallet is not None and password: + dev.append(BitcoinSensor('wallet', currency, wallet)) + + for variable in config['display_options']: + if variable['type'] not in OPTION_TYPES: + _LOGGER.error('Option type: "%s" does not exist', variable['type']) + else: + dev.append(BitcoinSensor(variable['type'], 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 + def update(self): + """ Gets the latest data and updates the states. """ + + 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) From 022f6608b92972da43e460714fb3e3805e6b0b84 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 15 May 2015 15:20:20 +0200 Subject: [PATCH 08/13] add blockchain as requirement --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index 63e3f3d5022..86605af82c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -56,3 +56,5 @@ pyowm>=2.2.0 # XMPP Bindings (notify.xmpp) sleekxmpp>=1.3.1 +# Blockchain (sensor.bitcoin) +blockchain>=1.1.2 From 4bed8647acebe03d6fb2198438ded01b0f0e9c18 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 15 May 2015 15:21:53 +0200 Subject: [PATCH 09/13] add bitcoin sensor --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index d97befce096..4029b48d47c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -36,6 +36,7 @@ omit = homeassistant/components/notify/pushbullet.py homeassistant/components/notify/pushover.py homeassistant/components/notify/xmpp.py + homeassistant/components/sensor/bitcoin.py homeassistant/components/sensor/mysensors.py homeassistant/components/sensor/openweathermap.py homeassistant/components/sensor/sabnzbd.py From 61148d8215f8ea1ad95226eb8661b3df3f38e72e Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 16 May 2015 01:11:25 +0200 Subject: [PATCH 10/13] add throttle, rename variable, fix pylint issues --- homeassistant/components/sensor/bitcoin.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sensor/bitcoin.py b/homeassistant/components/sensor/bitcoin.py index 8394744504c..ec5589f19cd 100644 --- a/homeassistant/components/sensor/bitcoin.py +++ b/homeassistant/components/sensor/bitcoin.py @@ -70,8 +70,9 @@ The variable you wish to display, see the configuration example above for a list of all available variables. """ import logging -from blockchain import statistics, exchangerates +from datetime import timedelta +from homeassistant.util import Throttle from homeassistant.helpers.entity import Entity @@ -101,6 +102,9 @@ OPTION_TYPES = { '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. """ @@ -128,8 +132,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): try: wallet.get_balance() - except exceptions.APIException as e: - _LOGGER.error(e) + except exceptions.APIException as error: + _LOGGER.error(error) wallet = None dev = [] @@ -174,8 +178,10 @@ class BitcoinSensor(Entity): 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() From 397336e03cc07369679e5a1c07c56959cd981f55 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 17 May 2015 00:36:32 +0200 Subject: [PATCH 11/13] switch to list for options --- homeassistant/components/sensor/bitcoin.py | 58 ++++++++++------------ 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/homeassistant/components/sensor/bitcoin.py b/homeassistant/components/sensor/bitcoin.py index ec5589f19cd..3b9030055c7 100644 --- a/homeassistant/components/sensor/bitcoin.py +++ b/homeassistant/components/sensor/bitcoin.py @@ -20,28 +20,27 @@ sensor: password: YOUR_ACCOUNT_PASSWORD currency: YOUR CURRENCY display_options: - - type: 'exchangerate' - - type: 'trade_volume_btc' - - type: 'miners_revenue_usd' - - type: 'btc_mined' - - type: 'trade_volume_usd' - - type: 'difficulty' - - type: 'minutes_between_blocks' - - type: 'number_of_transactions' - - type: 'hash_rate' - - type: 'timestamp' - - type: 'mined_blocks' - - type: 'blocks_size' - - type: 'total_fees_btc' - - type: 'total_btc_sent' - - type: 'estimated_btc_sent' - - type: 'total_btc' - - type: 'total_blocks' - - type: 'next_retarget' - - type: 'estimated_transaction_volume_usd' - - type: 'miners_revenue_btc' - - type: 'market_price_usd' - + - 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: @@ -62,12 +61,8 @@ display_options *Required An array specifying the variables to display. -These are the variables for the display_options array.: - -type -*Required -The variable you wish to display, see the configuration example above for a -list of all available variables. +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 @@ -141,10 +136,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): dev.append(BitcoinSensor('wallet', currency, wallet)) for variable in config['display_options']: - if variable['type'] not in OPTION_TYPES: - _LOGGER.error('Option type: "%s" does not exist', variable['type']) + if variable not in OPTION_TYPES: + _LOGGER.error('Option type: "%s" does not exist', variable) else: - dev.append(BitcoinSensor(variable['type'], currency)) + print("############ ", variable) + dev.append(BitcoinSensor(variable, currency)) add_devices(dev) From 9392f9b5125969f167bbc01d5c905f8ca7c330a6 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 18 May 2015 23:38:46 +0200 Subject: [PATCH 12/13] use throttle as balloob suggested --- homeassistant/components/sensor/bitcoin.py | 33 ++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/sensor/bitcoin.py b/homeassistant/components/sensor/bitcoin.py index 3b9030055c7..5cb207e4ad5 100644 --- a/homeassistant/components/sensor/bitcoin.py +++ b/homeassistant/components/sensor/bitcoin.py @@ -58,7 +58,7 @@ currency The currency to exchange to. Eg. CHF, USD, EUR,etc. display_options -*Required +*Optional An array specifying the variables to display. These are the variables for the display_options array. See the configuration @@ -67,6 +67,8 @@ example above for a list of all available variables. import logging from datetime import timedelta +from blockchain import statistics, exchangerates + from homeassistant.util import Throttle from homeassistant.helpers.entity import Entity @@ -98,7 +100,7 @@ OPTION_TYPES = { } # Return cached results if last scan was less then this time ago -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=120) +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) def setup_platform(hass, config, add_devices, discovery_info=None): @@ -131,16 +133,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None): _LOGGER.error(error) wallet = None + data = BitcoinData() dev = [] if wallet is not None and password: - dev.append(BitcoinSensor('wallet', currency, wallet)) + dev.append(BitcoinSensor(data, '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)) + dev.append(BitcoinSensor(data, variable, currency)) add_devices(dev) @@ -149,8 +151,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class BitcoinSensor(Entity): """ Implements a Bitcoin sensor. """ - def __init__(self, option_type, currency, wallet=''): - + def __init__(self, data, option_type, currency, wallet=''): + self.data = data self._name = OPTION_TYPES[option_type][0] self._unit_of_measurement = OPTION_TYPES[option_type][1] self._currency = currency @@ -174,13 +176,12 @@ class BitcoinSensor(Entity): 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() + self.data.update() + stats = self.data.stats + ticker = self.data.ticker # pylint: disable=no-member if self.type == 'wallet' and self._wallet is not None: @@ -232,3 +233,13 @@ class BitcoinSensor(Entity): 0.00000001) elif self.type == 'market_price_usd': self._state = '{0:.2f}'.format(stats.market_price_usd) + +class BitcoinData(object): + def __init__(self): + self.stats = None + self.ticker = None + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + self.stats = statistics.get() + self.ticker = exchangerates.get_ticker() From 2d1b934a1c2f1630ce8c167e7bcb6466841fa7bc Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Wed, 20 May 2015 18:27:43 +0200 Subject: [PATCH 13/13] minor updates --- homeassistant/components/sensor/bitcoin.py | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/sensor/bitcoin.py b/homeassistant/components/sensor/bitcoin.py index 5cb207e4ad5..8d174981900 100644 --- a/homeassistant/components/sensor/bitcoin.py +++ b/homeassistant/components/sensor/bitcoin.py @@ -11,8 +11,8 @@ 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 +To use the Bitcoin sensor you will need to add something like the following +to your config/configuration.yaml sensor: platform: bitcoin @@ -45,17 +45,17 @@ sensor: Variables: wallet -*Required +*Optional This is your wallet identifier from https://blockchain.info to access the online wallet. password -*Required +*Optional Password your your online wallet. currency -*Required -The currency to exchange to. Eg. CHF, USD, EUR,etc. +*Optional +The currency to exchange to, eg. CHF, USD, EUR,etc. Default is USD. display_options *Optional @@ -67,8 +67,6 @@ example above for a list of all available variables. import logging from datetime import timedelta -from blockchain import statistics, exchangerates - from homeassistant.util import Throttle from homeassistant.helpers.entity import Entity @@ -100,7 +98,7 @@ OPTION_TYPES = { } # Return cached results if last scan was less then this time ago -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=120) def setup_platform(hass, config, add_devices, discovery_info=None): @@ -135,7 +133,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): data = BitcoinData() dev = [] - if wallet is not None and password: + if wallet is not None and password is not None: dev.append(BitcoinSensor(data, 'wallet', currency, wallet)) for variable in config['display_options']: @@ -234,12 +232,19 @@ class BitcoinSensor(Entity): elif self.type == 'market_price_usd': self._state = '{0:.2f}'.format(stats.market_price_usd) + class BitcoinData(object): + """ Gets the latest data and updates the states. """ + def __init__(self): self.stats = None self.ticker = None @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): + """ Gets the latest data from blockchain.info. """ + + from blockchain import statistics, exchangerates + self.stats = statistics.get() self.ticker = exchangerates.get_ticker()