text: """
  Support for UK Met Office weather service.
  
  For more details about this platform, please refer to the documentation at
  https://home-assistant.io/components/sensor.metoffice/
  """
  import logging
  from datetime import timedelta
  
  import voluptuous as vol
  
  from homeassistant.components.sensor import PLATFORM_SCHEMA
  from homeassistant.const import (
      CONF_MONITORED_CONDITIONS, TEMP_CELSIUS, STATE_UNKNOWN, CONF_NAME,
      ATTR_ATTRIBUTION, CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE)
  from homeassistant.helpers.entity import Entity
  from homeassistant.util import Throttle
  import homeassistant.helpers.config_validation as cv
  
  _LOGGER = logging.getLogger(__name__)
  
  REQUIREMENTS = ['datapoint==0.4.3']
  
  CONF_ATTRIBUTION = "Data provided by the Met Office"
  
  CONDITION_CLASSES = {
      'cloudy': ['7', '8'],
      'fog': ['5', '6'],
      'hail': ['19', '20', '21'],
      'lightning': ['30'],
      'lightning-rainy': ['28', '29'],
      'partlycloudy': ['2', '3'],
      'pouring': ['13', '14', '15'],
      'rainy': ['9', '10', '11', '12'],
      'snowy': ['22', '23', '24', '25', '26', '27'],
      'snowy-rainy': ['16', '17', '18'],
      'sunny': ['0', '1'],
      'windy': [],
      'windy-variant': [],
      'exceptional': [],
  }
  
  SCAN_INTERVAL = timedelta(minutes=35)
  
  # Sensor types are defined like: Name, units
  SENSOR_TYPES = {
      'name': ['Station Name', None],
      'weather': ['Weather', None],
      'temperature': ['Temperature', TEMP_CELSIUS],
      'feels_like_temperature': ['Feels Like Temperature', TEMP_CELSIUS],
      'wind_speed': ['Wind Speed', 'm/s'],
      'wind_direction': ['Wind Direction', None],
      'wind_gust': ['Wind Gust', 'm/s'],
      'visibility': ['Visibility', 'km'],
      'uv': ['UV', None],
      'precipitation': ['Probability of Precipitation', '%'],
      'humidity': ['Humidity', '%']
  }
  
  PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
      vol.Optional(CONF_NAME, default=None): cv.string,
      vol.Required(CONF_API_KEY): cv.string,
      vol.Required(CONF_MONITORED_CONDITIONS, default=[]):
          vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
  })
  
  
  def setup_platform(hass, config, add_devices, discovery_info=None):
      """Set up the Metoffice sensor platform."""
      import datapoint as dp
      datapoint = dp.connection(api_key=config.get(CONF_API_KEY))
  
      latitude = config.get(CONF_LATITUDE, hass.config.latitude)
      longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
  
      if None in (latitude, longitude):
          _LOGGER.error("Latitude or longitude not set in Home Assistant config")
          return False
  
      try:
          site = datapoint.get_nearest_site(latitude=latitude,
                                            longitude=longitude)
      except dp.exceptions.APIException as err:
          _LOGGER.error("Received error from Met Office Datapoint: %s", err)
          return False
  
      if not site:
          _LOGGER.error("Unable to get nearest Met Office forecast site")
          return False
  
      # Get data
      data = MetOfficeCurrentData(hass, datapoint, site)
      try:
          data.update()
      except (ValueError, dp.exceptions.APIException) as err:
          _LOGGER.error("Received error from Met Office Datapoint: %s", err)
          return False
  
      # Add
      add_devices([MetOfficeCurrentSensor(site, data, variable)
                   for variable in config[CONF_MONITORED_CONDITIONS]])
      return True
  
  
  class MetOfficeCurrentSensor(Entity):
      """Implementation of a Met Office current sensor."""
  
      def __init__(self, site, data, condition):
          """Initialize the sensor."""
          self.site = site
          self.data = data
          self._condition = condition
  
      @property
      def name(self):
          """Return the name of the sensor."""
          return 'Met Office {}'.format(SENSOR_TYPES[self._condition][0])
  
      @property
      def state(self):
          """Return the state of the sensor."""
          if self._condition in self.data.data.__dict__.keys():
              variable = getattr(self.data.data, self._condition)
              if self._condition == "weather":
                  return [k for k, v in CONDITION_CLASSES.items() if
                          self.data.data.weather.value in v][0]
              else:
                  return variable.value
          else:
              return STATE_UNKNOWN
  
      @property
      def unit_of_measurement(self):
          """Return the unit of measurement."""
          return SENSOR_TYPES[self._condition][1]
  
      @property
      def device_state_attributes(self):
          """Return the state attributes of the device."""
          attr = {}
          attr['Sensor Id'] = self._condition
          attr['Site Id'] = self.site.id
          attr['Site Name'] = self.site.name
          attr['Last Update'] = self.data.data.date
          attr[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION
          return attr
  
      def update(self):
          """Update current conditions."""
          self.data.update()
  
  
  class MetOfficeCurrentData(object):
      """Get data from Datapoint."""
  
      def __init__(self, hass, datapoint, site):
          """Initialize the data object."""
          self._hass = hass
          self._datapoint = datapoint
          self._site = site
          self.data = None
  
      @Throttle(SCAN_INTERVAL)
      def update(self):
          """Get the latest data from Datapoint."""
          import datapoint as dp
  
          try:
              forecast = self._datapoint.get_forecast_for_site(
                  self._site.id, "3hourly")
              self.data = forecast.now()
          except (ValueError, dp.exceptions.APIException) as err:
              _LOGGER.error("Check Met Office %s", err.args)
              self.data = None
              raise
  