Minor updates (#17436)

This commit is contained in:
Fabian Affolter 2018-10-14 17:11:39 +02:00 committed by Daniel Høyer Iversen
parent daf48a3b1f
commit 253e154a79

View file

@ -1,55 +1,54 @@
""" """
The Habitica API component. The Habitica API component.
For more details about this platform, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/habitica/ https://home-assistant.io/components/habitica/
""" """
import logging
from collections import namedtuple from collections import namedtuple
import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.const import \
CONF_NAME, CONF_URL, CONF_SENSORS, CONF_PATH, CONF_API_KEY from homeassistant.const import (
CONF_API_KEY, CONF_NAME, CONF_PATH, CONF_SENSORS, CONF_URL)
from homeassistant.helpers import config_validation as cv, discovery
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers import \
config_validation as cv, discovery
REQUIREMENTS = ['habitipy==0.2.0'] REQUIREMENTS = ['habitipy==0.2.0']
_LOGGER = logging.getLogger(__name__)
DOMAIN = "habitica"
CONF_API_USER = "api_user" _LOGGER = logging.getLogger(__name__)
CONF_API_USER = 'api_user'
DEFAULT_URL = 'https://habitica.com'
DOMAIN = 'habitica'
ST = SensorType = namedtuple('SensorType', [ ST = SensorType = namedtuple('SensorType', [
"name", "icon", "unit", "path" 'name', 'icon', 'unit', 'path'
]) ])
SENSORS_TYPES = { SENSORS_TYPES = {
'name': ST('Name', None, '', ["profile", "name"]), 'name': ST('Name', None, '', ['profile', 'name']),
'hp': ST('HP', 'mdi:heart', 'HP', ["stats", "hp"]), 'hp': ST('HP', 'mdi:heart', 'HP', ['stats', 'hp']),
'maxHealth': ST('max HP', 'mdi:heart', 'HP', ["stats", "maxHealth"]), 'maxHealth': ST('max HP', 'mdi:heart', 'HP', ['stats', 'maxHealth']),
'mp': ST('Mana', 'mdi:auto-fix', 'MP', ["stats", "mp"]), 'mp': ST('Mana', 'mdi:auto-fix', 'MP', ['stats', 'mp']),
'maxMP': ST('max Mana', 'mdi:auto-fix', 'MP', ["stats", "maxMP"]), 'maxMP': ST('max Mana', 'mdi:auto-fix', 'MP', ['stats', 'maxMP']),
'exp': ST('EXP', 'mdi:star', 'EXP', ["stats", "exp"]), 'exp': ST('EXP', 'mdi:star', 'EXP', ['stats', 'exp']),
'toNextLevel': ST( 'toNextLevel': ST(
'Next Lvl', 'mdi:star', 'EXP', ["stats", "toNextLevel"]), 'Next Lvl', 'mdi:star', 'EXP', ['stats', 'toNextLevel']),
'lvl': ST( 'lvl': ST(
'Lvl', 'mdi:arrow-up-bold-circle-outline', 'Lvl', ["stats", "lvl"]), 'Lvl', 'mdi:arrow-up-bold-circle-outline', 'Lvl', ['stats', 'lvl']),
'gp': ST('Gold', 'mdi:coin', 'Gold', ["stats", "gp"]), 'gp': ST('Gold', 'mdi:coin', 'Gold', ['stats', 'gp']),
'class': ST('Class', 'mdi:sword', '', ["stats", "class"]) 'class': ST('Class', 'mdi:sword', '', ['stats', 'class'])
} }
INSTANCE_SCHEMA = vol.Schema({ INSTANCE_SCHEMA = vol.Schema({
vol.Optional(CONF_URL, default='https://habitica.com'): cv.url, vol.Optional(CONF_URL, default=DEFAULT_URL): cv.url,
vol.Optional(CONF_NAME): cv.string, vol.Optional(CONF_NAME): cv.string,
vol.Required(CONF_API_USER): cv.string, vol.Required(CONF_API_USER): cv.string,
vol.Required(CONF_API_KEY): cv.string, vol.Required(CONF_API_KEY): cv.string,
vol.Optional(CONF_SENSORS, default=list(SENSORS_TYPES)): vol.Optional(CONF_SENSORS, default=list(SENSORS_TYPES)):
vol.All( vol.All(cv.ensure_list, vol.Unique(), [vol.In(list(SENSORS_TYPES))]),
cv.ensure_list,
vol.Unique(),
[vol.In(list(SENSORS_TYPES))])
}) })
has_unique_values = vol.Schema(vol.Unique()) # pylint: disable=invalid-name has_unique_values = vol.Schema(vol.Unique()) # pylint: disable=invalid-name
@ -57,7 +56,7 @@ has_unique_values = vol.Schema(vol.Unique()) # pylint: disable=invalid-name
def has_all_unique_users(value): def has_all_unique_users(value):
"""Validate that all `api_user`s are unique.""" """Validate that all API users are unique."""
api_users = [user[CONF_API_USER] for user in value] api_users = [user[CONF_API_USER] for user in value]
has_unique_values(api_users) has_unique_values(api_users)
return value return value
@ -75,9 +74,7 @@ def has_all_unique_users_names(value):
INSTANCE_LIST_SCHEMA = vol.All( INSTANCE_LIST_SCHEMA = vol.All(
cv.ensure_list, cv.ensure_list, has_all_unique_users, has_all_unique_users_names,
has_all_unique_users,
has_all_unique_users_names,
[INSTANCE_SCHEMA]) [INSTANCE_SCHEMA])
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
@ -87,23 +84,24 @@ CONFIG_SCHEMA = vol.Schema({
SERVICE_API_CALL = 'api_call' SERVICE_API_CALL = 'api_call'
ATTR_NAME = CONF_NAME ATTR_NAME = CONF_NAME
ATTR_PATH = CONF_PATH ATTR_PATH = CONF_PATH
ATTR_ARGS = "args" ATTR_ARGS = 'args'
EVENT_API_CALL_SUCCESS = "{0}_{1}_{2}".format( EVENT_API_CALL_SUCCESS = '{0}_{1}_{2}'.format(
DOMAIN, SERVICE_API_CALL, "success") DOMAIN, SERVICE_API_CALL, 'success')
SERVICE_API_CALL_SCHEMA = vol.Schema({ SERVICE_API_CALL_SCHEMA = vol.Schema({
vol.Required(ATTR_NAME): str, vol.Required(ATTR_NAME): str,
vol.Required(ATTR_PATH): vol.All(cv.ensure_list, [str]), vol.Required(ATTR_PATH): vol.All(cv.ensure_list, [str]),
vol.Optional(ATTR_ARGS): dict vol.Optional(ATTR_ARGS): dict,
}) })
async def async_setup(hass, config): async def async_setup(hass, config):
"""Set up the habitica service.""" """Set up the Habitica service."""
from habitipy.aio import HabitipyAsync
conf = config[DOMAIN] conf = config[DOMAIN]
data = hass.data[DOMAIN] = {} data = hass.data[DOMAIN] = {}
websession = async_get_clientsession(hass) websession = async_get_clientsession(hass)
from habitipy.aio import HabitipyAsync
class HAHabitipyAsync(HabitipyAsync): class HAHabitipyAsync(HabitipyAsync):
"""Closure API class to hold session.""" """Closure API class to hold session."""
@ -116,7 +114,7 @@ async def async_setup(hass, config):
username = instance[CONF_API_USER] username = instance[CONF_API_USER]
password = instance[CONF_API_KEY] password = instance[CONF_API_KEY]
name = instance.get(CONF_NAME) name = instance.get(CONF_NAME)
config_dict = {"url": url, "login": username, "password": password} config_dict = {'url': url, 'login': username, 'password': password}
api = HAHabitipyAsync(config_dict) api = HAHabitipyAsync(config_dict)
user = await api.user.get() user = await api.user.get()
if name is None: if name is None:
@ -125,34 +123,30 @@ async def async_setup(hass, config):
if CONF_SENSORS in instance: if CONF_SENSORS in instance:
hass.async_create_task( hass.async_create_task(
discovery.async_load_platform( discovery.async_load_platform(
hass, "sensor", DOMAIN, hass, 'sensor', DOMAIN,
{"name": name, "sensors": instance[CONF_SENSORS]}, {'name': name, 'sensors': instance[CONF_SENSORS]}, config))
config))
async def handle_api_call(call): async def handle_api_call(call):
name = call.data[ATTR_NAME] name = call.data[ATTR_NAME]
path = call.data[ATTR_PATH] path = call.data[ATTR_PATH]
api = hass.data[DOMAIN].get(name) api = hass.data[DOMAIN].get(name)
if api is None: if api is None:
_LOGGER.error( _LOGGER.error("API_CALL: User '%s' not configured", name)
"API_CALL: User '%s' not configured", name)
return return
try: try:
for element in path: for element in path:
api = api[element] api = api[element]
except KeyError: except KeyError:
_LOGGER.error( _LOGGER.error(
"API_CALL: Path %s is invalid" "API_CALL: Path %s is invalid for API on '{%s}' element",
" for api on '{%s}' element", path, element) path, element)
return return
kwargs = call.data.get(ATTR_ARGS, {}) kwargs = call.data.get(ATTR_ARGS, {})
data = await api(**kwargs) data = await api(**kwargs)
hass.bus.async_fire(EVENT_API_CALL_SUCCESS, { hass.bus.async_fire(
"name": name, "path": path, "data": data EVENT_API_CALL_SUCCESS, {'name': name, 'path': path, 'data': data})
})
hass.services.async_register( hass.services.async_register(
DOMAIN, SERVICE_API_CALL, DOMAIN, SERVICE_API_CALL, handle_api_call,
handle_api_call,
schema=SERVICE_API_CALL_SCHEMA) schema=SERVICE_API_CALL_SCHEMA)
return True return True