Add xbox live custom update interval (#26939)

* Add xbox_live custom update schedule

* Set a default update interval that is within the free limit. Consider
  number of users per api key when setting interval.

* Add codeowner

* Add callback decorator
This commit is contained in:
Martin Hjelmare 2019-09-27 08:02:58 +02:00 committed by GitHub
parent 77b7e4665b
commit 9f6fade236
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 39 deletions

View File

@ -318,6 +318,7 @@ homeassistant/components/wemo/* @sqldiablo
homeassistant/components/withings/* @vangorra homeassistant/components/withings/* @vangorra
homeassistant/components/worldclock/* @fabaff homeassistant/components/worldclock/* @fabaff
homeassistant/components/wwlln/* @bachya homeassistant/components/wwlln/* @bachya
homeassistant/components/xbox_live/* @MartinHjelmare
homeassistant/components/xfinity/* @cisasteelersfan homeassistant/components/xfinity/* @cisasteelersfan
homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi
homeassistant/components/xiaomi_miio/* @rytilahti @syssi homeassistant/components/xiaomi_miio/* @rytilahti @syssi

View File

@ -6,5 +6,7 @@
"xboxapi==0.1.1" "xboxapi==0.1.1"
], ],
"dependencies": [], "dependencies": [],
"codeowners": [] "codeowners": [
"@MartinHjelmare"
]
} }

View File

@ -1,12 +1,16 @@
"""Sensor for Xbox Live account status.""" """Sensor for Xbox Live account status."""
import logging import logging
from datetime import timedelta
import voluptuous as vol import voluptuous as vol
from xboxapi import xbox_api
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 CONF_API_KEY, STATE_UNKNOWN from homeassistant.const import CONF_API_KEY, CONF_SCAN_INTERVAL
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_track_time_interval
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -24,65 +28,76 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
def setup_platform(hass, config, add_entities, discovery_info=None): def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Xbox platform.""" """Set up the Xbox platform."""
from xboxapi import xbox_api api = xbox_api.XboxApi(config[CONF_API_KEY])
entities = []
api = xbox_api.XboxApi(config.get(CONF_API_KEY))
devices = []
# request personal profile to check api connection # request personal profile to check api connection
profile = api.get_profile() profile = api.get_profile()
if profile.get("error_code") is not None: if profile.get("error_code") is not None:
_LOGGER.error( _LOGGER.error(
"Can't setup XboxAPI connection. Check your account or " "Can't setup XboxAPI connection. Check your account or "
" api key on xboxapi.com. Code: %s Description: %s ", "api key on xboxapi.com. Code: %s Description: %s ",
profile.get("error_code", STATE_UNKNOWN), profile.get("error_code", "unknown"),
profile.get("error_message", STATE_UNKNOWN), profile.get("error_message", "unknown"),
) )
return return
for xuid in config.get(CONF_XUID): users = config[CONF_XUID]
new_device = XboxSensor(hass, api, xuid)
if new_device.success_init:
devices.append(new_device)
if devices: interval = timedelta(minutes=1 * len(users))
add_entities(devices, True) interval = config.get(CONF_SCAN_INTERVAL, interval)
for xuid in users:
gamercard = get_user_gamercard(api, xuid)
if gamercard is None:
continue
entities.append(XboxSensor(api, xuid, gamercard, interval))
if entities:
add_entities(entities, True)
def get_user_gamercard(api, xuid):
"""Get profile info."""
gamercard = api.get_user_gamercard(xuid)
_LOGGER.debug("User gamercard: %s", gamercard)
if gamercard.get("success", True) and gamercard.get("code") is None:
return gamercard
_LOGGER.error(
"Can't get user profile %s. Error Code: %s Description: %s",
xuid,
gamercard.get("code", "unknown"),
gamercard.get("description", "unknown"),
)
return None
class XboxSensor(Entity): class XboxSensor(Entity):
"""A class for the Xbox account.""" """A class for the Xbox account."""
def __init__(self, hass, api, xuid): def __init__(self, api, xuid, gamercard, interval):
"""Initialize the sensor.""" """Initialize the sensor."""
self._hass = hass
self._state = None self._state = None
self._presence = {} self._presence = []
self._xuid = xuid self._xuid = xuid
self._api = api self._api = api
self._gamertag = gamercard.get("gamertag")
# get profile info self._gamerscore = gamercard.get("gamerscore")
profile = self._api.get_user_gamercard(self._xuid) self._interval = interval
self._picture = gamercard.get("gamerpicSmallSslImagePath")
if profile.get("success", True) and profile.get("code") is None: self._tier = gamercard.get("tier")
self.success_init = True
self._gamertag = profile.get("gamertag")
self._gamerscore = profile.get("gamerscore")
self._picture = profile.get("gamerpicSmallSslImagePath")
self._tier = profile.get("tier")
else:
_LOGGER.error(
"Can't get user profile %s. " "Error Code: %s Description: %s",
self._xuid,
profile.get("code", STATE_UNKNOWN),
profile.get("description", STATE_UNKNOWN),
)
self.success_init = False
@property @property
def name(self): def name(self):
"""Return the name of the sensor.""" """Return the name of the sensor."""
return self._gamertag return self._gamertag
@property
def should_poll(self):
"""Return False as this entity has custom polling."""
return False
@property @property
def state(self): def state(self):
"""Return the state of the sensor.""" """Return the state of the sensor."""
@ -98,7 +113,7 @@ class XboxSensor(Entity):
for device in self._presence: for device in self._presence:
for title in device.get("titles"): for title in device.get("titles"):
attributes[ attributes[
"{} {}".format(device.get("type"), title.get("placement")) f'{device.get("type")} {title.get("placement")}'
] = title.get("name") ] = title.get("name")
return attributes return attributes
@ -113,8 +128,19 @@ class XboxSensor(Entity):
"""Return the icon to use in the frontend.""" """Return the icon to use in the frontend."""
return ICON return ICON
async def async_added_to_hass(self):
"""Start custom polling."""
@callback
def async_update(event_time=None):
"""Update the entity."""
self.async_schedule_update_ha_state(True)
async_track_time_interval(self.hass, async_update, self._interval)
def update(self): def update(self):
"""Update state data from Xbox API.""" """Update state data from Xbox API."""
presence = self._api.get_user_presence(self._xuid) presence = self._api.get_user_presence(self._xuid)
_LOGGER.debug("User presence: %s", presence)
self._state = presence.get("state") self._state = presence.get("state")
self._presence = presence.get("devices", {}) self._presence = presence.get("devices", [])