text: """
  Support for interface with a Ziggo Mediabox XL.
  
  For more details about this platform, please refer to the documentation at
  https://home-assistant.io/components/media_player.ziggo_mediabox_xl/
  """
  import logging
  import socket
  
  import voluptuous as vol
  
  from homeassistant.components.media_player import (
      PLATFORM_SCHEMA, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PLAY,
      SUPPORT_PREVIOUS_TRACK, SUPPORT_SELECT_SOURCE, SUPPORT_TURN_OFF,
      SUPPORT_TURN_ON, MediaPlayerDevice)
  from homeassistant.const import (
      CONF_HOST, CONF_NAME, STATE_OFF, STATE_PAUSED, STATE_PLAYING)
  import homeassistant.helpers.config_validation as cv
  
  REQUIREMENTS = ['ziggo-mediabox-xl==1.1.0']
  
  _LOGGER = logging.getLogger(__name__)
  
  DATA_KNOWN_DEVICES = 'ziggo_mediabox_xl_known_devices'
  
  SUPPORT_ZIGGO = SUPPORT_TURN_ON | SUPPORT_TURN_OFF | \
      SUPPORT_NEXT_TRACK | SUPPORT_PAUSE | SUPPORT_PREVIOUS_TRACK | \
      SUPPORT_SELECT_SOURCE | SUPPORT_PLAY
  
  PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
      vol.Required(CONF_HOST): cv.string,
      vol.Optional(CONF_NAME): cv.string,
  })
  
  
  def setup_platform(hass, config, add_entities, discovery_info=None):
      """Set up the Ziggo Mediabox XL platform."""
      from ziggo_mediabox_xl import ZiggoMediaboxXL
  
      hass.data[DATA_KNOWN_DEVICES] = known_devices = set()
  
      # Is this a manual configuration?
      if config.get(CONF_HOST) is not None:
          host = config.get(CONF_HOST)
          name = config.get(CONF_NAME)
          manual_config = True
      elif discovery_info is not None:
          host = discovery_info.get('host')
          name = discovery_info.get('name')
          manual_config = False
      else:
          _LOGGER.error("Cannot determine device")
          return
  
      # Only add a device once, so discovered devices do not override manual
      # config.
      hosts = []
      connection_successful = False
      ip_addr = socket.gethostbyname(host)
      if ip_addr not in known_devices:
          try:
              # Mediabox instance with a timeout of 3 seconds.
              mediabox = ZiggoMediaboxXL(ip_addr, 3)
              # Check if a connection can be established to the device.
              if mediabox.test_connection():
                  connection_successful = True
              else:
                  if manual_config:
                      _LOGGER.info("Can't connect to %s", host)
                  else:
                      _LOGGER.error("Can't connect to %s", host)
              # When the device is in eco mode it's not connected to the network
              # so it needs to be added anyway if it's configured manually.
              if manual_config or connection_successful:
                  hosts.append(ZiggoMediaboxXLDevice(mediabox, host, name,
                                                     connection_successful))
                  known_devices.add(ip_addr)
          except socket.error as error:
              _LOGGER.error("Can't connect to %s: %s", host, error)
      else:
          _LOGGER.info("Ignoring duplicate Ziggo Mediabox XL %s", host)
      add_entities(hosts, True)
  
  
  class ZiggoMediaboxXLDevice(MediaPlayerDevice):
      """Representation of a Ziggo Mediabox XL Device."""
  
      def __init__(self, mediabox, host, name, available):
          """Initialize the device."""
          self._mediabox = mediabox
          self._host = host
          self._name = name
          self._available = available
          self._state = None
  
      def update(self):
          """Retrieve the state of the device."""
          try:
              if self._mediabox.test_connection():
                  if self._mediabox.turned_on():
                      if self._state != STATE_PAUSED:
                          self._state = STATE_PLAYING
                  else:
                      self._state = STATE_OFF
                  self._available = True
              else:
                  self._available = False
          except socket.error:
              _LOGGER.error("Couldn't fetch state from %s", self._host)
              self._available = False
  
      def send_keys(self, keys):
          """Send keys to the device and handle exceptions."""
          try:
              self._mediabox.send_keys(keys)
          except socket.error:
              _LOGGER.error("Couldn't send keys to %s", self._host)
  
      @property
      def name(self):
          """Return the name of the device."""
          return self._name
  
      @property
      def state(self):
          """Return the state of the device."""
          return self._state
  
      @property
      def available(self):
          """Return True if the device is available."""
          return self._available
  
      @property
      def source_list(self):
          """List of available sources (channels)."""
          return [self._mediabox.channels()[c]
                  for c in sorted(self._mediabox.channels().keys())]
  
      @property
      def supported_features(self):
          """Flag media player features that are supported."""
          return SUPPORT_ZIGGO
  
      def turn_on(self):
          """Turn the media player on."""
          self.send_keys(['POWER'])
  
      def turn_off(self):
          """Turn off media player."""
          self.send_keys(['POWER'])
  
      def media_play(self):
          """Send play command."""
          self.send_keys(['PLAY'])
          self._state = STATE_PLAYING
  
      def media_pause(self):
          """Send pause command."""
          self.send_keys(['PAUSE'])
          self._state = STATE_PAUSED
  
      def media_play_pause(self):
          """Simulate play pause media player."""
          self.send_keys(['PAUSE'])
          if self._state == STATE_PAUSED:
              self._state = STATE_PLAYING
          else:
              self._state = STATE_PAUSED
  
      def media_next_track(self):
          """Channel up."""
          self.send_keys(['CHAN_UP'])
          self._state = STATE_PLAYING
  
      def media_previous_track(self):
          """Channel down."""
          self.send_keys(['CHAN_DOWN'])
          self._state = STATE_PLAYING
  
      def select_source(self, source):
          """Select the channel."""
          if str(source).isdigit():
              digits = str(source)
          else:
              digits = next((
                  key for key, value in self._mediabox.channels().items()
                  if value == source), None)
          if digits is None:
              return
  
          self.send_keys(['NUM_{}'.format(digit) for digit in str(digits)])
          self._state = STATE_PLAYING
  