Add Kraken delay after first update to avoid limit (#55736)

* Add delay after first update to avoid limit

* Apply suggestions
This commit is contained in:
Kevin Stillhammer 2021-09-30 13:23:46 +02:00 committed by GitHub
parent ef4b6d7bdf
commit dd52ec78c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 120 additions and 33 deletions

View File

@ -127,7 +127,7 @@ class KrakenData:
self._config_entry, options=options
)
await self._async_refresh_tradable_asset_pairs()
# Wait 1 second to avoid triggering the CallRateLimiter
# Wait 1 second to avoid triggering the KrakenAPI CallRateLimiter
await asyncio.sleep(CALL_RATE_LIMIT_SLEEP)
self.coordinator = DataUpdateCoordinator(
self._hass,
@ -139,6 +139,8 @@ class KrakenData:
),
)
await self.coordinator.async_config_entry_first_refresh()
# Wait 1 second to avoid triggering the KrakenAPI CallRateLimiter
await asyncio.sleep(CALL_RATE_LIMIT_SLEEP)
def _get_websocket_name_asset_pairs(self) -> str:
return ",".join(wsname for wsname in self.tradable_asset_pairs.values())

View File

@ -129,12 +129,14 @@ class KrakenSensor(CoordinatorEntity[Optional[KrakenResponse]], SensorEntity):
super()._handle_coordinator_update()
def _update_internal_state(self) -> None:
if not self.coordinator.data:
return
try:
self._attr_native_value = self.entity_description.value_fn(
self.coordinator, self.tracked_asset_pair_wsname # type: ignore[arg-type]
)
self._received_data_at_least_once = True # Received data at least one time.
except TypeError:
self._received_data_at_least_once = True
except KeyError:
if self._received_data_at_least_once:
if self._available:
_LOGGER.warning(

View File

@ -7,6 +7,12 @@ TRADEABLE_ASSET_PAIR_RESPONSE = pandas.DataFrame(
index=["ADAXBT", "ADAETH", "XBTEUR", "XXBTZGBP", "XXBTZUSD", "XXBTZJPY"],
)
MISSING_PAIR_TRADEABLE_ASSET_PAIR_RESPONSE = pandas.DataFrame(
{"wsname": ["ADA/XBT", "ADA/ETH", "XBT/EUR", "XBT/GBP", "XBT/JPY"]},
columns=["wsname"],
index=["ADAXBT", "ADAETH", "XBTEUR", "XXBTZGBP", "XXBTZJPY"],
)
TICKER_INFORMATION_RESPONSE = pandas.DataFrame(
{
"a": [
@ -78,3 +84,67 @@ TICKER_INFORMATION_RESPONSE = pandas.DataFrame(
columns=["a", "b", "c", "h", "l", "o", "p", "t", "v"],
index=["ADAXBT", "ADAETH", "XBTEUR", "XXBTZGBP", "XXBTZUSD", "XXBTZJPY"],
)
MISSING_PAIR_TICKER_INFORMATION_RESPONSE = pandas.DataFrame(
{
"a": [
[0.000349400, 15949, 15949.000],
[0.000349400, 15949, 15949.000],
[0.000349400, 15949, 15949.000],
[0.000349400, 15949, 15949.000],
[0.000349400, 15949, 15949.000],
],
"b": [
[0.000348400, 20792, 20792.000],
[0.000348400, 20792, 20792.000],
[0.000348400, 20792, 20792.000],
[0.000348400, 20792, 20792.000],
[0.000348400, 20792, 20792.000],
],
"c": [
[0.000347800, 2809.36384377],
[0.000347800, 2809.36384377],
[0.000347800, 2809.36384377],
[0.000347800, 2809.36384377],
[0.000347800, 2809.36384377],
],
"h": [
[0.000351600, 0.000352100],
[0.000351600, 0.000352100],
[0.000351600, 0.000352100],
[0.000351600, 0.000352100],
[0.000351600, 0.000352100],
],
"l": [
[0.000344600, 0.000344600],
[0.000344600, 0.000344600],
[0.000344600, 0.000344600],
[0.000344600, 0.000344600],
[0.000344600, 0.000344600],
],
"o": [
0.000351300,
0.000351300,
0.000351300,
0.000351300,
0.000351300,
],
"p": [
[0.000348573, 0.000344881],
[0.000348573, 0.000344881],
[0.000348573, 0.000344881],
[0.000348573, 0.000344881],
[0.000348573, 0.000344881],
],
"t": [[82, 128], [82, 128], [82, 128], [82, 128], [82, 128]],
"v": [
[146300.24906838, 253478.04715403],
[146300.24906838, 253478.04715403],
[146300.24906838, 253478.04715403],
[146300.24906838, 253478.04715403],
[146300.24906838, 253478.04715403],
],
},
columns=["a", "b", "c", "h", "l", "o", "p", "t", "v"],
index=["ADAXBT", "ADAETH", "XBTEUR", "XXBTZGBP", "XXBTZJPY"],
)

View File

@ -13,7 +13,12 @@ from homeassistant.components.kraken.const import (
from homeassistant.const import CONF_SCAN_INTERVAL, EVENT_HOMEASSISTANT_START
import homeassistant.util.dt as dt_util
from .const import TICKER_INFORMATION_RESPONSE, TRADEABLE_ASSET_PAIR_RESPONSE
from .const import (
MISSING_PAIR_TICKER_INFORMATION_RESPONSE,
MISSING_PAIR_TRADEABLE_ASSET_PAIR_RESPONSE,
TICKER_INFORMATION_RESPONSE,
TRADEABLE_ASSET_PAIR_RESPONSE,
)
from tests.common import MockConfigEntry, async_fire_time_changed
@ -230,38 +235,46 @@ async def test_missing_pair_marks_sensor_unavailable(hass):
with patch("homeassistant.util.dt.utcnow", return_value=utcnow), patch(
"pykrakenapi.KrakenAPI.get_tradable_asset_pairs",
return_value=TRADEABLE_ASSET_PAIR_RESPONSE,
):
with patch(
"pykrakenapi.KrakenAPI.get_ticker_information",
return_value=TICKER_INFORMATION_RESPONSE,
):
entry = MockConfigEntry(
domain=DOMAIN,
options={
CONF_SCAN_INTERVAL: DEFAULT_SCAN_INTERVAL,
CONF_TRACKED_ASSET_PAIRS: [DEFAULT_TRACKED_ASSET_PAIR],
},
)
entry.add_to_hass(hass)
) as tradeable_asset_pairs_mock, patch(
"pykrakenapi.KrakenAPI.get_ticker_information",
return_value=TICKER_INFORMATION_RESPONSE,
) as ticket_information_mock:
entry = MockConfigEntry(
domain=DOMAIN,
options={
CONF_SCAN_INTERVAL: DEFAULT_SCAN_INTERVAL,
CONF_TRACKED_ASSET_PAIRS: [DEFAULT_TRACKED_ASSET_PAIR],
},
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
await hass.async_block_till_done()
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
await hass.async_block_till_done()
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
await hass.async_block_till_done()
sensor = hass.states.get("sensor.xbt_usd_ask")
assert sensor.state == "0.0003494"
sensor = hass.states.get("sensor.xbt_usd_ask")
assert sensor.state == "0.0003494"
with patch(
"pykrakenapi.KrakenAPI.get_ticker_information",
side_effect=KrakenAPIError("EQuery:Unknown asset pair"),
):
async_fire_time_changed(
hass, utcnow + timedelta(seconds=DEFAULT_SCAN_INTERVAL * 2)
)
await hass.async_block_till_done()
tradeable_asset_pairs_mock.return_value = (
MISSING_PAIR_TRADEABLE_ASSET_PAIR_RESPONSE
)
ticket_information_mock.side_effect = KrakenAPIError(
"EQuery:Unknown asset pair"
)
async_fire_time_changed(
hass, utcnow + timedelta(seconds=DEFAULT_SCAN_INTERVAL * 2)
)
await hass.async_block_till_done()
sensor = hass.states.get("sensor.xbt_usd_ask")
assert sensor.state == "unavailable"
ticket_information_mock.side_effect = None
ticket_information_mock.return_value = MISSING_PAIR_TICKER_INFORMATION_RESPONSE
async_fire_time_changed(
hass, utcnow + timedelta(seconds=DEFAULT_SCAN_INTERVAL * 2)
)
await hass.async_block_till_done()
sensor = hass.states.get("sensor.xbt_usd_ask")
assert sensor.state == "unavailable"