text: """
  Support for Google Geocode sensors.
  
  For more details about this platform, please refer to the documentation at
  https://github.com/michaelmcarthur/GoogleGeocode-HASS
  
  Written By Michael McArthur
  https://github.com/michaelmcarthur/GoogleGeocode-HASS
  
  """
  from datetime import datetime
  from datetime import timedelta 
  import logging
  import json
  import requests
  from requests import get
  
  import voluptuous as vol
  
  from homeassistant.components.sensor import PLATFORM_SCHEMA
  from homeassistant.const import (
      CONF_API_KEY, CONF_NAME, CONF_SCAN_INTERVAL, ATTR_ATTRIBUTION, ATTR_LATITUDE, ATTR_LONGITUDE)
  import homeassistant.helpers.location as location
  from homeassistant.util import Throttle
  from homeassistant.helpers.entity import Entity
  import homeassistant.helpers.config_validation as cv
  
  _LOGGER = logging.getLogger(__name__)
  
  CONF_ORIGIN = 'origin'
  CONF_OPTIONS = 'options'
  CONF_DISPLAY_ZONE = 'display_zone'
  CONF_ATTRIBUTION = "Data provided by maps.google.com"
  
  ATTR_STREET_NUMBER = 'Street Number'
  ATTR_STREET = 'Street'
  ATTR_CITY = 'City'
  ATTR_POSTAL_TOWN = 'Postal Town'
  ATTR_POSTAL_CODE = 'Postal Code'
  ATTR_REGION = 'State'
  ATTR_COUNTRY = 'Country'
  ATTR_COUNTY = 'County'
  ATTR_FORMATTED_ADDRESS = 'Formatted Address'
  
  DEFAULT_NAME = 'Google Geocode'
  DEFAULT_OPTION = 'street, city'
  DEFAULT_DISPLAY_ZONE = 'display'
  DEFAULT_KEY = 'no key'
  current = '0,0'
  zone_check = 'a'
  SCAN_INTERVAL = timedelta(seconds=60)
  
  PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
      vol.Required(CONF_ORIGIN): cv.string,
      vol.Optional(CONF_API_KEY, default=DEFAULT_KEY): cv.string,
      vol.Optional(CONF_OPTIONS, default=DEFAULT_OPTION): cv.string,
      vol.Optional(CONF_DISPLAY_ZONE, default=DEFAULT_DISPLAY_ZONE): cv.string,
      vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
      vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL):
          cv.time_period,
  })
  
  TRACKABLE_DOMAINS = ['device_tracker', 'sensor']
  
  def setup_platform(hass, config, add_devices, discovery_info=None):
      """Setup the sensor platform."""
      name = config.get(CONF_NAME)
      api_key = config.get(CONF_API_KEY)
      origin = config.get(CONF_ORIGIN)
      options = config.get(CONF_OPTIONS)
      display_zone = config.get(CONF_DISPLAY_ZONE)
  
      add_devices([GoogleGeocode(hass, origin, name, api_key, options, display_zone)])
  
  
  class GoogleGeocode(Entity):
      """Representation of a Google Geocode Sensor."""
  
      def __init__(self, hass, origin, name, api_key, options, display_zone):
          """Initialize the sensor."""
          self._hass = hass
          self._name = name
          self._api_key = api_key
          self._options = options.lower()
          self._display_zone = display_zone.lower()
          self._state = "Awaiting Update"
  
          self._street_number = None
          self._street = None
          self._city = None
          self._postal_town = None
          self._postal_code = None
          self._city = None
          self._region = None
          self._country = None
          self._county = None
          self._formatted_address = None
          self._zone_check_current = None
  
          # Check if origin is a trackable entity
          if origin.split('.', 1)[0] in TRACKABLE_DOMAINS:
              self._origin_entity_id = origin
          else:
              self._origin = origin
  
      @property
      def name(self):
          """Return the name of the sensor."""
          return self._name
  
      @property
      def state(self):
          """Return the state of the sensor."""
          return self._state
  
      @property
      def device_state_attributes(self):
          """Return the state attributes."""
          return{
              ATTR_STREET_NUMBER: self._street_number,
              ATTR_STREET: self._street,
              ATTR_CITY: self._city,
              ATTR_POSTAL_TOWN: self._postal_town,
              ATTR_POSTAL_CODE: self._postal_code,
              ATTR_REGION: self._region,
              ATTR_COUNTRY: self._country,
              ATTR_COUNTY: self._county,
              ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
              ATTR_FORMATTED_ADDRESS: self._formatted_address,
          }
  
      @Throttle(SCAN_INTERVAL)
      def update(self):
          """Get the latest data and updates the states."""
  
          if hasattr(self, '_origin_entity_id'):
              self._origin = self._get_location_from_entity(
                  self._origin_entity_id
              )
  
          """Update if location has changed."""
  
          global current
          global zone_check_count
          global zone_check
          global user_display
          zone_check = self.hass.states.get(self._origin_entity_id).state
          zone_check_count = 2
  
          if zone_check == self._zone_check_current:
              zone_check_count = 1
          if zone_check == 'not_home':
              zone_check_count = 2
          if zone_check_count == 1:
              pass
          elif self._origin == None:
              pass
          elif current == self._origin:
              pass
          else:
              _LOGGER.info("google request sent")
              self._zone_check_current = self.hass.states.get(self._origin_entity_id).state
              zone_check_count = 2
              lat = self._origin
              current = lat
              self._reset_attributes()
              if self._api_key == 'no key':
                  url = "https://maps.google.com/maps/api/geocode/json?latlng=" + lat
              else:
                  url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + lat + "&key=" + self._api_key
              response = get(url)
              json_input = response.text
              decoded = json.loads(json_input)
              street_number = ''
              street = 'Unnamed Road'
              alt_street = 'Unnamed Road'
              city = ''
              postal_town = ''
              formatted_address = ''
              state = ''
              county = ''
              country = ''
              
              for result in decoded["results"]:
                  for component in result["address_components"]:
                      if 'street_number' in component["types"]:
                          street_number = component["long_name"]
                          self._street_number = street_number
                      if 'route' in component["types"]:
                          street = component["long_name"]
                          self._street = street
                      if 'sublocality_level_1' in component["types"]:
                          alt_street = component["long_name"]
                      if 'postal_town' in component["types"]:
                          postal_town = component["long_name"]
                          self._postal_town = postal_town
                      if 'locality' in component["types"]:
                          city = component["long_name"]
                          self._city = city
                      if 'administrative_area_level_1' in component["types"]:
                          state = component["long_name"]
                          self._region = state
                      if 'administrative_area_level_2' in component["types"]:
                          county = component["long_name"]
                          self._county = county
                      if 'country' in component["types"]:
                          country = component["long_name"]
                          self._country = country
                      if 'postal_code' in component["types"]:
                          postal_code = component["long_name"]
                          self._postal_code = postal_code
  
              if 'formatted_address' in decoded['results'][0]:
                  formatted_address = decoded['results'][0]['formatted_address']
                  self._formatted_address = formatted_address
                  
              if 'error_message' in decoded:
                  self._state = decoded['error_message']
                  _LOGGER.error("You have exceded your daily requests plase create an api key.")
              elif self._display_zone == 'hide' or zone_check == "not_home":
                  if street == 'Unnamed Road':
                      street = alt_street
                      self._street = alt_street
                  if city == '':
                      city = postal_town
                      if city == '':
                          city = county
  
                  display_options = self._options
                  user_display = []
  
                  if "street_number" in display_options:
                      user_display.append(street_number)
                  if "street" in display_options:
                      user_display.append(street)
                  if "city" in display_options:
                      self._append_to_user_display(city)
                  if "county" in display_options:
                      self._append_to_user_display(county)
                  if "state" in display_options:
                      self._append_to_user_display(state)
                  if "postal_code" in display_options:
                      self._append_to_user_display(postal_code)
                  if "country" in display_options:
                      self._append_to_user_display(country)
                  if "formatted_address" in display_options:
                      self._append_to_user_display(formatted_address)
                          
                  user_display = ', '.join(  x for x in user_display )
                  
                  if user_display == '':
                      user_display = street
                  self._state = user_display
              else:
                  self._state = zone_check[0].upper() + zone_check[1:]
  
      def _get_location_from_entity(self, entity_id):
          """Get the origin from the entity state or attributes."""
          entity = self._hass.states.get(entity_id)
  
          if entity is None:
              _LOGGER.error("Unable to find entity %s", entity_id)
              return None
  
          # Check if the entity has origin attributes
          if location.has_location(entity):
              return self._get_location_from_attributes(entity)
  
          # When everything fails just return nothing
          return None
  
      def _reset_attributes(self):
          """Resets attributes."""
          self._street = None
          self._street_number = None
          self._city = None
          self._postal_town = None
          self._postal_code = None
          self._region = None
          self._country = None
          self._county = None
          self._formatted_address = None
  
      def _append_to_user_display(self, append_check):
          """Appends attribute to state if false."""
          if append_check == "":
              pass
          else:
              user_display.append(append_check)
  
      @staticmethod
      def _get_location_from_attributes(entity):
          """Get the lat/long string from an entities attributes."""
          attr = entity.attributes
          return "%s,%s" % (attr.get(ATTR_LATITUDE), attr.get(ATTR_LONGITUDE))
  