text: """
  Support for Telldus Live.
  
  For more details about this component, please refer to the documentation at
  https://home-assistant.io/components/tellduslive/
  """
  import logging
  from datetime import timedelta
  
  import voluptuous as vol
  
  from homeassistant.helpers import discovery
  from homeassistant.util import Throttle
  import homeassistant.helpers.config_validation as cv
  
  DOMAIN = 'tellduslive'
  
  REQUIREMENTS = ['tellive-py==0.5.2']
  
  _LOGGER = logging.getLogger(__name__)
  
  CONF_PUBLIC_KEY = 'public_key'
  CONF_PRIVATE_KEY = 'private_key'
  CONF_TOKEN = 'token'
  CONF_TOKEN_SECRET = 'token_secret'
  
  MIN_TIME_BETWEEN_SWITCH_UPDATES = timedelta(minutes=1)
  MIN_TIME_BETWEEN_SENSOR_UPDATES = timedelta(minutes=5)
  
  NETWORK = None
  
  CONFIG_SCHEMA = vol.Schema({
      DOMAIN: vol.Schema({
          vol.Required(CONF_PUBLIC_KEY): cv.string,
          vol.Required(CONF_PRIVATE_KEY): cv.string,
          vol.Required(CONF_TOKEN): cv.string,
          vol.Required(CONF_TOKEN_SECRET): cv.string,
      }),
  }, extra=vol.ALLOW_EXTRA)
  
  
  def setup(hass, config):
      """Setup the Telldus Live component."""
      # fixme: aquire app key and provide authentication using username+password
  
      global NETWORK
      NETWORK = TelldusLiveData(hass, config)
  
      if not NETWORK.validate_session():
          _LOGGER.error(
              "Authentication Error: "
              "Please make sure you have configured your keys "
              "that can be aquired from https://api.telldus.com/keys/index")
          return False
  
      NETWORK.discover()
  
      return True
  
  
  @Throttle(MIN_TIME_BETWEEN_SWITCH_UPDATES)
  def request_switches():
      """Make request to online service."""
      _LOGGER.debug("Updating switches from Telldus Live")
      switches = NETWORK.request('devices/list')
      # Filter out any group of switches.
      if switches and 'device' in switches:
          return {switch["id"]: switch for switch in switches['device']
                  if switch["type"] == "device"}
      return None
  
  
  @Throttle(MIN_TIME_BETWEEN_SENSOR_UPDATES)
  def request_sensors():
      """Make request to online service."""
      _LOGGER.debug("Updating sensors from Telldus Live")
      units = NETWORK.request('sensors/list')
      # One unit can contain many sensors.
      if units and 'sensor' in units:
          return {unit['id']+sensor['name']: dict(unit, data=sensor)
                  for unit in units['sensor']
                  for sensor in unit['data']}
      return None
  
  
  class TelldusLiveData(object):
      """Get the latest data and update the states."""
  
      def __init__(self, hass, config):
          """Initialize the Tellus data object."""
          public_key = config[DOMAIN].get(CONF_PUBLIC_KEY)
          private_key = config[DOMAIN].get(CONF_PRIVATE_KEY)
          token = config[DOMAIN].get(CONF_TOKEN)
          token_secret = config[DOMAIN].get(CONF_TOKEN_SECRET)
  
          from tellive.client import LiveClient
  
          self._switches = {}
          self._sensors = {}
  
          self._hass = hass
          self._config = config
  
          self._client = LiveClient(
              public_key=public_key, private_key=private_key, access_token=token,
              access_secret=token_secret)
  
      def validate_session(self):
          """Make a dummy request to see if the session is valid."""
          response = self.request("user/profile")
          return response and 'email' in response
  
      def discover(self):
          """Update states, will trigger discover."""
          self.update_sensors()
          self.update_switches()
  
      def _discover(self, found_devices, component_name):
          """Send discovery event if component not yet discovered."""
          if not len(found_devices):
              return
  
          _LOGGER.info("discovered %d new %s devices",
                       len(found_devices), component_name)
  
          discovery.load_platform(self._hass, component_name, DOMAIN,
                                  found_devices, self._config)
  
      def request(self, what, **params):
          """Send a request to the Tellstick Live API."""
          from tellive.live import const
  
          supported_methods = const.TELLSTICK_TURNON \
              | const.TELLSTICK_TURNOFF \
              | const.TELLSTICK_TOGGLE \
  
          # Tellstick device methods not yet supported
          #   | const.TELLSTICK_BELL \
          #   | const.TELLSTICK_DIM \
          #   | const.TELLSTICK_LEARN \
          #   | const.TELLSTICK_EXECUTE \
          #   | const.TELLSTICK_UP \
          #   | const.TELLSTICK_DOWN \
          #   | const.TELLSTICK_STOP
  
          default_params = {'supportedMethods': supported_methods,
                            'includeValues': 1,
                            'includeScale': 1,
                            'includeIgnored': 0}
          params.update(default_params)
  
          # room for improvement: the telllive library doesn't seem to
          # re-use sessions, instead it opens a new session for each request
          # this needs to be fixed
  
          try:
              response = self._client.request(what, params)
              _LOGGER.debug("got response %s", response)
              return response
          except OSError as error:
              _LOGGER.error("failed to make request to Tellduslive servers: %s",
                            error)
              return None
  
      def update_devices(self, local_devices, remote_devices, component_name):
          """Update local device list and discover new devices."""
          if remote_devices is None:
              return local_devices
  
          remote_ids = remote_devices.keys()
          local_ids = local_devices.keys()
  
          added_devices = list(remote_ids - local_ids)
          self._discover(added_devices,
                         component_name)
  
          removed_devices = list(local_ids - remote_ids)
          remote_devices.update({id: dict(local_devices[id], offline=True)
                                 for id in removed_devices})
  
          return remote_devices
  
      def update_sensors(self):
          """Update local list of sensors."""
          self._sensors = self.update_devices(
              self._sensors, request_sensors(), 'sensor')
  
      def update_switches(self):
          """Update local list of switches."""
          self._switches = self.update_devices(
              self._switches, request_switches(), 'switch')
  
      def _check_request(self, what, **params):
          """Make request, check result if successful."""
          response = self.request(what, **params)
          return response and response.get('status') == 'success'
  
      def get_switch(self, switch_id):
          """Return the switch representation."""
          return self._switches[switch_id]
  
      def get_sensor(self, sensor_id):
          """Return the sensor representation."""
          return self._sensors[sensor_id]
  
      def turn_switch_on(self, switch_id):
          """Turn switch off."""
          if self._check_request('device/turnOn', id=switch_id):
              from tellive.live import const
              self.get_switch(switch_id)['state'] = const.TELLSTICK_TURNON
  
      def turn_switch_off(self, switch_id):
          """Turn switch on."""
          if self._check_request('device/turnOff', id=switch_id):
              from tellive.live import const
              self.get_switch(switch_id)['state'] = const.TELLSTICK_TURNOFF
  