text: """Linky Atome."""
  from datetime import timedelta
  import logging
  
  # Import AtomeClient to connect to server
  from pykeyatome.client import AtomeClient
  import voluptuous as vol
  
  from homeassistant.components.sensor import (
      PLATFORM_SCHEMA,
      SensorDeviceClass,
      SensorEntity,
      SensorStateClass,
  )
  from homeassistant.const import (
      CONF_NAME,
      CONF_PASSWORD,
      CONF_USERNAME,
      ENERGY_KILO_WATT_HOUR,
      POWER_WATT,
  )
  import homeassistant.helpers.config_validation as cv
  from homeassistant.util import Throttle
  
  _LOGGER = logging.getLogger(__name__)
  
  DEFAULT_NAME = "atome"
  
  LIVE_SCAN_INTERVAL = timedelta(seconds=30)
  DAILY_SCAN_INTERVAL = timedelta(seconds=150)
  WEEKLY_SCAN_INTERVAL = timedelta(hours=1)
  MONTHLY_SCAN_INTERVAL = timedelta(hours=1)
  YEARLY_SCAN_INTERVAL = timedelta(days=1)
  
  LIVE_NAME = "Atome Live Power"
  DAILY_NAME = "Atome Daily"
  WEEKLY_NAME = "Atome Weekly"
  MONTHLY_NAME = "Atome Monthly"
  YEARLY_NAME = "Atome Yearly"
  
  LIVE_TYPE = "live"
  DAILY_TYPE = "day"
  WEEKLY_TYPE = "week"
  MONTHLY_TYPE = "month"
  YEARLY_TYPE = "year"
  
  PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
      {
          vol.Required(CONF_USERNAME): cv.string,
          vol.Required(CONF_PASSWORD): cv.string,
          vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
      }
  )
  
  
  def setup_platform(hass, config, add_entities, discovery_info=None):
      """Set up the Atome sensor."""
      username = config[CONF_USERNAME]
      password = config[CONF_PASSWORD]
  
      atome_client = AtomeClient(username, password)
      if not atome_client.login():
          _LOGGER.error("No login available for atome server")
          return
  
      data = AtomeData(atome_client)
  
      sensors = []
      sensors.append(AtomeSensor(data, LIVE_NAME, LIVE_TYPE))
      sensors.append(AtomeSensor(data, DAILY_NAME, DAILY_TYPE))
      sensors.append(AtomeSensor(data, WEEKLY_NAME, WEEKLY_TYPE))
      sensors.append(AtomeSensor(data, MONTHLY_NAME, MONTHLY_TYPE))
      sensors.append(AtomeSensor(data, YEARLY_NAME, YEARLY_TYPE))
  
      add_entities(sensors, True)
  
  
  class AtomeData:
      """Stores data retrieved from Neurio sensor."""
  
      def __init__(self, client: AtomeClient) -> None:
          """Initialize the data."""
          self.atome_client = client
          self._live_power = None
          self._subscribed_power = None
          self._is_connected = None
          self._day_usage = None
          self._day_price = None
          self._week_usage = None
          self._week_price = None
          self._month_usage = None
          self._month_price = None
          self._year_usage = None
          self._year_price = None
  
      @property
      def live_power(self):
          """Return latest active power value."""
          return self._live_power
  
      @property
      def subscribed_power(self):
          """Return latest active power value."""
          return self._subscribed_power
  
      @property
      def is_connected(self):
          """Return latest active power value."""
          return self._is_connected
  
      def _retrieve_live(self):
          values = self.atome_client.get_live()
          if (
              values is not None
              and values.get("last")
              and values.get("subscribed")
              and (values.get("isConnected") is not None)
          ):
              self._live_power = values["last"]
              self._subscribed_power = values["subscribed"]
              self._is_connected = values["isConnected"]
              _LOGGER.debug(
                  "Updating Atome live data. Got: %d, isConnected: %s, subscribed: %d",
                  self._live_power,
                  self._is_connected,
                  self._subscribed_power,
              )
              return True
  
          _LOGGER.error("Live Data : Missing last value in values: %s", values)
          return False
  
      @Throttle(LIVE_SCAN_INTERVAL)
      def update_live_usage(self):
          """Return current power value."""
          if not self._retrieve_live():
              _LOGGER.debug("Perform Reconnect during live request")
              self.atome_client.login()
              self._retrieve_live()
  
      def _retrieve_period_usage(self, period_type):
          """Return current daily/weekly/monthly/yearly power usage."""
          values = self.atome_client.get_consumption(period_type)
          if values is not None and values.get("total") and values.get("price"):
              period_usage = values["total"] / 1000
              period_price = values["price"]
              _LOGGER.debug("Updating Atome %s data. Got: %d", period_type, period_usage)
              return True, period_usage, period_price
  
          _LOGGER.error("%s : Missing last value in values: %s", period_type, values)
          return False, None, None
  
      def _retrieve_period_usage_with_retry(self, period_type):
          """Return current daily/weekly/monthly/yearly power usage with one retry."""
          (
              retrieve_success,
              period_usage,
              period_price,
          ) = self._retrieve_period_usage(period_type)
          if not retrieve_success:
              _LOGGER.debug("Perform Reconnect during %s", period_type)
              self.atome_client.login()
              (
                  retrieve_success,
                  period_usage,
                  period_price,
              ) = self._retrieve_period_usage(period_type)
          return (period_usage, period_price)
  
      @property
      def day_usage(self):
          """Return latest daily usage value."""
          return self._day_usage
  
      @property
      def day_price(self):
          """Return latest daily usage value."""
          return self._day_price
  
      @Throttle(DAILY_SCAN_INTERVAL)
      def update_day_usage(self):
          """Return current daily power usage."""
          (
              self._day_usage,
              self._day_price,
          ) = self._retrieve_period_usage_with_retry(DAILY_TYPE)
  
      @property
      def week_usage(self):
          """Return latest weekly usage value."""
          return self._week_usage
  
      @property
      def week_price(self):
          """Return latest weekly usage value."""
          return self._week_price
  
      @Throttle(WEEKLY_SCAN_INTERVAL)
      def update_week_usage(self):
          """Return current weekly power usage."""
          (
              self._week_usage,
              self._week_price,
          ) = self._retrieve_period_usage_with_retry(WEEKLY_TYPE)
  
      @property
      def month_usage(self):
          """Return latest monthly usage value."""
          return self._month_usage
  
      @property
      def month_price(self):
          """Return latest monthly usage value."""
          return self._month_price
  
      @Throttle(MONTHLY_SCAN_INTERVAL)
      def update_month_usage(self):
          """Return current monthly power usage."""
          (
              self._month_usage,
              self._month_price,
          ) = self._retrieve_period_usage_with_retry(MONTHLY_TYPE)
  
      @property
      def year_usage(self):
          """Return latest yearly usage value."""
          return self._year_usage
  
      @property
      def year_price(self):
          """Return latest yearly usage value."""
          return self._year_price
  
      @Throttle(YEARLY_SCAN_INTERVAL)
      def update_year_usage(self):
          """Return current yearly power usage."""
          (
              self._year_usage,
              self._year_price,
          ) = self._retrieve_period_usage_with_retry(YEARLY_TYPE)
  
  
  class AtomeSensor(SensorEntity):
      """Representation of a sensor entity for Atome."""
  
      def __init__(self, data, name, sensor_type):
          """Initialize the sensor."""
          self._attr_name = name
          self._data = data
  
          self._sensor_type = sensor_type
  
          if sensor_type == LIVE_TYPE:
              self._attr_device_class = SensorDeviceClass.POWER
              self._attr_native_unit_of_measurement = POWER_WATT
              self._attr_state_class = SensorStateClass.MEASUREMENT
          else:
              self._attr_device_class = SensorDeviceClass.ENERGY
              self._attr_native_unit_of_measurement = ENERGY_KILO_WATT_HOUR
              self._attr_state_class = SensorStateClass.TOTAL_INCREASING
  
      def update(self):
          """Update device state."""
          update_function = getattr(self._data, f"update_{self._sensor_type}_usage")
          update_function()
  
          if self._sensor_type == LIVE_TYPE:
              self._attr_native_value = self._data.live_power
              self._attr_extra_state_attributes = {
                  "subscribed_power": self._data.subscribed_power,
                  "is_connected": self._data.is_connected,
              }
          else:
              self._attr_native_value = getattr(self._data, f"{self._sensor_type}_usage")
              self._attr_extra_state_attributes = {
                  "price": getattr(self._data, f"{self._sensor_type}_price")
              }
  