core/homeassistant/components/steam_online/sensor.py

119 lines
3.5 KiB
Python
Raw Normal View History

"""Sensor for Steam account status."""
2017-03-02 14:58:35 +00:00
import logging
2016-09-04 02:21:59 +00:00
import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA
2016-02-20 23:08:18 +00:00
from homeassistant.helpers.entity import Entity
2016-02-24 06:41:24 +00:00
from homeassistant.const import CONF_API_KEY
2016-09-04 02:21:59 +00:00
import homeassistant.helpers.config_validation as cv
2017-03-02 14:58:35 +00:00
_LOGGER = logging.getLogger(__name__)
2016-09-04 02:21:59 +00:00
CONF_ACCOUNTS = 'accounts'
2016-02-20 23:08:18 +00:00
ICON = 'mdi:steam'
Proper Steam game names and small fixes (#11182) * Use constant for offline state * Use constant for no game name * Rename trade and play constant their proper names Trade and Play are not the correct names for the states. For instance Play might be seens as the user is actually is playing, which is not correct as there is no such state is returned from the Steam API. Just having "trade" does not say much about what is happening and might be misintepreted that the user is currently trading, which is not correct either. We instead use the names from the underlying library for naming the states [1] [1] https://github.com/Lagg/steamodd/blob/2e518ad84f3afce631d5d7eca3af0f85b5330b5b/steam/user.py#L109 * Get the proper game name if no extra info is given from the api The third `current_game` parameter that was used before hold extra information about the game that is being played. This might contain the game name, it might also be empty. The correct way to get the game name is to fetch it from the API depending on the game id that might be returned in the `current_game` attribute if the user is playing a game. To not break existing implementations we keep the functionality to first go with the extra information and only then fetch the proper game name. * Refactor getting game name to its own function This cleans up the code and removed "ugly" else statements from the sensor and makes the game fetching easier to read. * Let state constant values be lower snake case * Return None instead of 'None' when no current game exists * Initialize steam app list only once to benefit form caching * Return None as state attributes if no current game is present
2017-12-21 03:32:33 +00:00
STATE_OFFLINE = 'offline'
STATE_ONLINE = 'online'
STATE_BUSY = 'busy'
STATE_AWAY = 'away'
STATE_SNOOZE = 'snooze'
STATE_LOOKING_TO_TRADE = 'looking_to_trade'
STATE_LOOKING_TO_PLAY = 'looking_to_play'
2017-03-10 03:55:18 +00:00
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_API_KEY): cv.string,
vol.Required(CONF_ACCOUNTS, default=[]):
vol.All(cv.ensure_list, [cv.string]),
})
2016-02-20 23:08:18 +00:00
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Steam platform."""
2016-02-20 23:08:18 +00:00
import steam as steamod
steamod.api.key.set(config.get(CONF_API_KEY))
Proper Steam game names and small fixes (#11182) * Use constant for offline state * Use constant for no game name * Rename trade and play constant their proper names Trade and Play are not the correct names for the states. For instance Play might be seens as the user is actually is playing, which is not correct as there is no such state is returned from the Steam API. Just having "trade" does not say much about what is happening and might be misintepreted that the user is currently trading, which is not correct either. We instead use the names from the underlying library for naming the states [1] [1] https://github.com/Lagg/steamodd/blob/2e518ad84f3afce631d5d7eca3af0f85b5330b5b/steam/user.py#L109 * Get the proper game name if no extra info is given from the api The third `current_game` parameter that was used before hold extra information about the game that is being played. This might contain the game name, it might also be empty. The correct way to get the game name is to fetch it from the API depending on the game id that might be returned in the `current_game` attribute if the user is playing a game. To not break existing implementations we keep the functionality to first go with the extra information and only then fetch the proper game name. * Refactor getting game name to its own function This cleans up the code and removed "ugly" else statements from the sensor and makes the game fetching easier to read. * Let state constant values be lower snake case * Return None instead of 'None' when no current game exists * Initialize steam app list only once to benefit form caching * Return None as state attributes if no current game is present
2017-12-21 03:32:33 +00:00
# Initialize steammods app list before creating sensors
# to benefit from internal caching of the list.
steam_app_list = steamod.apps.app_list()
add_entities(
2016-02-20 23:08:18 +00:00
[SteamSensor(account,
Proper Steam game names and small fixes (#11182) * Use constant for offline state * Use constant for no game name * Rename trade and play constant their proper names Trade and Play are not the correct names for the states. For instance Play might be seens as the user is actually is playing, which is not correct as there is no such state is returned from the Steam API. Just having "trade" does not say much about what is happening and might be misintepreted that the user is currently trading, which is not correct either. We instead use the names from the underlying library for naming the states [1] [1] https://github.com/Lagg/steamodd/blob/2e518ad84f3afce631d5d7eca3af0f85b5330b5b/steam/user.py#L109 * Get the proper game name if no extra info is given from the api The third `current_game` parameter that was used before hold extra information about the game that is being played. This might contain the game name, it might also be empty. The correct way to get the game name is to fetch it from the API depending on the game id that might be returned in the `current_game` attribute if the user is playing a game. To not break existing implementations we keep the functionality to first go with the extra information and only then fetch the proper game name. * Refactor getting game name to its own function This cleans up the code and removed "ugly" else statements from the sensor and makes the game fetching easier to read. * Let state constant values be lower snake case * Return None instead of 'None' when no current game exists * Initialize steam app list only once to benefit form caching * Return None as state attributes if no current game is present
2017-12-21 03:32:33 +00:00
steamod,
steam_app_list)
for account in config.get(CONF_ACCOUNTS)], True)
2016-02-20 23:08:18 +00:00
class SteamSensor(Entity):
2016-02-24 09:47:35 +00:00
"""A class for the Steam account."""
2016-03-08 15:46:34 +00:00
Proper Steam game names and small fixes (#11182) * Use constant for offline state * Use constant for no game name * Rename trade and play constant their proper names Trade and Play are not the correct names for the states. For instance Play might be seens as the user is actually is playing, which is not correct as there is no such state is returned from the Steam API. Just having "trade" does not say much about what is happening and might be misintepreted that the user is currently trading, which is not correct either. We instead use the names from the underlying library for naming the states [1] [1] https://github.com/Lagg/steamodd/blob/2e518ad84f3afce631d5d7eca3af0f85b5330b5b/steam/user.py#L109 * Get the proper game name if no extra info is given from the api The third `current_game` parameter that was used before hold extra information about the game that is being played. This might contain the game name, it might also be empty. The correct way to get the game name is to fetch it from the API depending on the game id that might be returned in the `current_game` attribute if the user is playing a game. To not break existing implementations we keep the functionality to first go with the extra information and only then fetch the proper game name. * Refactor getting game name to its own function This cleans up the code and removed "ugly" else statements from the sensor and makes the game fetching easier to read. * Let state constant values be lower snake case * Return None instead of 'None' when no current game exists * Initialize steam app list only once to benefit form caching * Return None as state attributes if no current game is present
2017-12-21 03:32:33 +00:00
def __init__(self, account, steamod, steam_app_list):
2016-03-08 15:46:34 +00:00
"""Initialize the sensor."""
2016-02-20 23:08:18 +00:00
self._steamod = steamod
Proper Steam game names and small fixes (#11182) * Use constant for offline state * Use constant for no game name * Rename trade and play constant their proper names Trade and Play are not the correct names for the states. For instance Play might be seens as the user is actually is playing, which is not correct as there is no such state is returned from the Steam API. Just having "trade" does not say much about what is happening and might be misintepreted that the user is currently trading, which is not correct either. We instead use the names from the underlying library for naming the states [1] [1] https://github.com/Lagg/steamodd/blob/2e518ad84f3afce631d5d7eca3af0f85b5330b5b/steam/user.py#L109 * Get the proper game name if no extra info is given from the api The third `current_game` parameter that was used before hold extra information about the game that is being played. This might contain the game name, it might also be empty. The correct way to get the game name is to fetch it from the API depending on the game id that might be returned in the `current_game` attribute if the user is playing a game. To not break existing implementations we keep the functionality to first go with the extra information and only then fetch the proper game name. * Refactor getting game name to its own function This cleans up the code and removed "ugly" else statements from the sensor and makes the game fetching easier to read. * Let state constant values be lower snake case * Return None instead of 'None' when no current game exists * Initialize steam app list only once to benefit form caching * Return None as state attributes if no current game is present
2017-12-21 03:32:33 +00:00
self._steam_app_list = steam_app_list
2016-02-20 23:08:18 +00:00
self._account = account
self._profile = None
self._game = self._state = self._name = self._avatar = None
2016-02-20 23:08:18 +00:00
@property
def name(self):
2016-02-24 09:47:35 +00:00
"""Return the name of the sensor."""
2017-03-02 14:58:35 +00:00
return self._name
2016-02-20 23:08:18 +00:00
@property
def entity_id(self):
2016-02-24 09:47:35 +00:00
"""Return the entity ID."""
2016-02-20 23:08:18 +00:00
return 'sensor.steam_{}'.format(self._account)
@property
def state(self):
2016-02-24 09:47:35 +00:00
"""Return the state of the sensor."""
2016-02-23 18:01:50 +00:00
return self._state
2016-02-20 23:08:18 +00:00
def update(self):
2016-02-24 09:47:35 +00:00
"""Update device state."""
2017-03-02 14:58:35 +00:00
try:
self._profile = self._steamod.user.profile(self._account)
Proper Steam game names and small fixes (#11182) * Use constant for offline state * Use constant for no game name * Rename trade and play constant their proper names Trade and Play are not the correct names for the states. For instance Play might be seens as the user is actually is playing, which is not correct as there is no such state is returned from the Steam API. Just having "trade" does not say much about what is happening and might be misintepreted that the user is currently trading, which is not correct either. We instead use the names from the underlying library for naming the states [1] [1] https://github.com/Lagg/steamodd/blob/2e518ad84f3afce631d5d7eca3af0f85b5330b5b/steam/user.py#L109 * Get the proper game name if no extra info is given from the api The third `current_game` parameter that was used before hold extra information about the game that is being played. This might contain the game name, it might also be empty. The correct way to get the game name is to fetch it from the API depending on the game id that might be returned in the `current_game` attribute if the user is playing a game. To not break existing implementations we keep the functionality to first go with the extra information and only then fetch the proper game name. * Refactor getting game name to its own function This cleans up the code and removed "ugly" else statements from the sensor and makes the game fetching easier to read. * Let state constant values be lower snake case * Return None instead of 'None' when no current game exists * Initialize steam app list only once to benefit form caching * Return None as state attributes if no current game is present
2017-12-21 03:32:33 +00:00
self._game = self._get_current_game()
2017-03-02 14:58:35 +00:00
self._state = {
2017-03-10 03:55:18 +00:00
1: STATE_ONLINE,
2: STATE_BUSY,
3: STATE_AWAY,
4: STATE_SNOOZE,
Proper Steam game names and small fixes (#11182) * Use constant for offline state * Use constant for no game name * Rename trade and play constant their proper names Trade and Play are not the correct names for the states. For instance Play might be seens as the user is actually is playing, which is not correct as there is no such state is returned from the Steam API. Just having "trade" does not say much about what is happening and might be misintepreted that the user is currently trading, which is not correct either. We instead use the names from the underlying library for naming the states [1] [1] https://github.com/Lagg/steamodd/blob/2e518ad84f3afce631d5d7eca3af0f85b5330b5b/steam/user.py#L109 * Get the proper game name if no extra info is given from the api The third `current_game` parameter that was used before hold extra information about the game that is being played. This might contain the game name, it might also be empty. The correct way to get the game name is to fetch it from the API depending on the game id that might be returned in the `current_game` attribute if the user is playing a game. To not break existing implementations we keep the functionality to first go with the extra information and only then fetch the proper game name. * Refactor getting game name to its own function This cleans up the code and removed "ugly" else statements from the sensor and makes the game fetching easier to read. * Let state constant values be lower snake case * Return None instead of 'None' when no current game exists * Initialize steam app list only once to benefit form caching * Return None as state attributes if no current game is present
2017-12-21 03:32:33 +00:00
5: STATE_LOOKING_TO_TRADE,
6: STATE_LOOKING_TO_PLAY,
}.get(self._profile.status, STATE_OFFLINE)
2017-03-02 14:58:35 +00:00
self._name = self._profile.persona
self._avatar = self._profile.avatar_medium
except self._steamod.api.HTTPTimeoutError as error:
_LOGGER.warning(error)
self._game = self._state = self._name = self._avatar = None
2016-02-20 23:08:18 +00:00
Proper Steam game names and small fixes (#11182) * Use constant for offline state * Use constant for no game name * Rename trade and play constant their proper names Trade and Play are not the correct names for the states. For instance Play might be seens as the user is actually is playing, which is not correct as there is no such state is returned from the Steam API. Just having "trade" does not say much about what is happening and might be misintepreted that the user is currently trading, which is not correct either. We instead use the names from the underlying library for naming the states [1] [1] https://github.com/Lagg/steamodd/blob/2e518ad84f3afce631d5d7eca3af0f85b5330b5b/steam/user.py#L109 * Get the proper game name if no extra info is given from the api The third `current_game` parameter that was used before hold extra information about the game that is being played. This might contain the game name, it might also be empty. The correct way to get the game name is to fetch it from the API depending on the game id that might be returned in the `current_game` attribute if the user is playing a game. To not break existing implementations we keep the functionality to first go with the extra information and only then fetch the proper game name. * Refactor getting game name to its own function This cleans up the code and removed "ugly" else statements from the sensor and makes the game fetching easier to read. * Let state constant values be lower snake case * Return None instead of 'None' when no current game exists * Initialize steam app list only once to benefit form caching * Return None as state attributes if no current game is present
2017-12-21 03:32:33 +00:00
def _get_current_game(self):
game_id = self._profile.current_game[0]
game_extra_info = self._profile.current_game[2]
if game_extra_info:
return game_extra_info
if game_id and game_id in self._steam_app_list:
# The app list always returns a tuple
# with the game id and the game name
return self._steam_app_list[game_id][1]
return None
@property
def device_state_attributes(self):
2016-03-08 15:46:34 +00:00
"""Return the state attributes."""
Proper Steam game names and small fixes (#11182) * Use constant for offline state * Use constant for no game name * Rename trade and play constant their proper names Trade and Play are not the correct names for the states. For instance Play might be seens as the user is actually is playing, which is not correct as there is no such state is returned from the Steam API. Just having "trade" does not say much about what is happening and might be misintepreted that the user is currently trading, which is not correct either. We instead use the names from the underlying library for naming the states [1] [1] https://github.com/Lagg/steamodd/blob/2e518ad84f3afce631d5d7eca3af0f85b5330b5b/steam/user.py#L109 * Get the proper game name if no extra info is given from the api The third `current_game` parameter that was used before hold extra information about the game that is being played. This might contain the game name, it might also be empty. The correct way to get the game name is to fetch it from the API depending on the game id that might be returned in the `current_game` attribute if the user is playing a game. To not break existing implementations we keep the functionality to first go with the extra information and only then fetch the proper game name. * Refactor getting game name to its own function This cleans up the code and removed "ugly" else statements from the sensor and makes the game fetching easier to read. * Let state constant values be lower snake case * Return None instead of 'None' when no current game exists * Initialize steam app list only once to benefit form caching * Return None as state attributes if no current game is present
2017-12-21 03:32:33 +00:00
return {'game': self._game} if self._game else None
2016-02-20 23:08:18 +00:00
@property
2016-02-24 06:41:24 +00:00
def entity_picture(self):
"""Avatar of the account."""
2017-03-02 14:58:35 +00:00
return self._avatar
2016-02-20 23:08:18 +00:00
@property
def icon(self):
2016-02-24 09:47:35 +00:00
"""Return the icon to use in the frontend."""
2016-02-20 23:08:18 +00:00
return ICON