text: """Tests for the pvpc_hourly_pricing sensor component."""
  from datetime import datetime, timedelta
  import logging
  from unittest.mock import patch
  
  from openpeerpower.components.pvpc_hourly_pricing import ATTR_TARIFF, DOMAIN
  from openpeerpower.const import CONF_NAME
  from openpeerpower.core import ATTR_NOW, EVENT_TIME_CHANGED
  from openpeerpower.setup import async_setup_component
  from openpeerpower.util import dt as dt_util
  
  from .conftest import check_valid_state
  
  from tests.common import date_util
  from tests.test_util.aiohttp import AiohttpClientMocker
  
  
  async def _process_time_step(
      opp, mock_data, key_state=None, value=None, tariff="discrimination", delta_min=60
  ):
      state = opp.states.get("sensor.test_dst")
      check_valid_state(state, tariff=tariff, value=value, key_attr=key_state)
  
      mock_data["return_time"] += timedelta(minutes=delta_min)
      opp.bus.async_fire(EVENT_TIME_CHANGED, {ATTR_NOW: mock_data["return_time"]})
      await opp.async_block_till_done()
      return state
  
  
  async def test_sensor_availability(
      opp, caplog, legacy_patchable_time, pvpc_aioclient_mock: AiohttpClientMocker
  ):
      """Test sensor availability and handling of cloud access."""
      opp.config.time_zone = dt_util.get_time_zone("Europe/Madrid")
      config = {DOMAIN: [{CONF_NAME: "test_dst", ATTR_TARIFF: "discrimination"}]}
      mock_data = {"return_time": datetime(2019, 10, 27, 20, 0, 0, tzinfo=date_util.UTC)}
  
      def mock_now():
          return mock_data["return_time"]
  
      with patch("openpeerpower.util.dt.utcnow", new=mock_now):
          assert await async_setup_component(opp, DOMAIN, config)
          await opp.async_block_till_done()
          caplog.clear()
          assert pvpc_aioclient_mock.call_count == 2
  
          await _process_time_step(opp, mock_data, "price_21h", 0.13896)
          await _process_time_step(opp, mock_data, "price_22h", 0.06893)
          assert pvpc_aioclient_mock.call_count == 4
          await _process_time_step(opp, mock_data, "price_23h", 0.06935)
          assert pvpc_aioclient_mock.call_count == 5
  
          # sensor has no more prices, state is "unavailable" from now on
          await _process_time_step(opp, mock_data, value="unavailable")
          await _process_time_step(opp, mock_data, value="unavailable")
          num_errors = sum(
              1
              for x in caplog.records
              if x.levelno == logging.ERROR and "unknown job listener" not in x.msg
          )
          num_warnings = sum(1 for x in caplog.records if x.levelno == logging.WARNING)
          assert num_warnings == 1
          assert num_errors == 0
          assert pvpc_aioclient_mock.call_count == 9
  
          # check that it is silent until it becomes available again
          caplog.clear()
          with caplog.at_level(logging.WARNING):
              # silent mode
              for _ in range(21):
                  await _process_time_step(opp, mock_data, value="unavailable")
              assert pvpc_aioclient_mock.call_count == 30
              assert len(caplog.messages) == 0
  
              # warning about data access recovered
              await _process_time_step(opp, mock_data, value="unavailable")
              assert pvpc_aioclient_mock.call_count == 31
              assert len(caplog.messages) == 1
              assert caplog.records[0].levelno == logging.WARNING
  
              # working ok again
              await _process_time_step(opp, mock_data, "price_00h", value=0.06821)
              assert pvpc_aioclient_mock.call_count == 32
              await _process_time_step(opp, mock_data, "price_01h", value=0.06627)
              assert pvpc_aioclient_mock.call_count == 33
              assert len(caplog.messages) == 1
              assert caplog.records[0].levelno == logging.WARNING
  