#ifdef USE_NTP

#define RESOLVE_INTERVAL      (5UL * 60UL * 1000UL)                       // интервал проверки подключения к интеренету в миллисекундах (5 минут)
                                                                          // при старте ESP пытается получить точное время от сервера времени в интрнете
                                                                          // эта попытка длится RESOLVE_TIMEOUT
                                                                          // если при этом отсутствует подключение к интернету (но есть WiFi подключение),
                                                                          // модуль будет подвисать на RESOLVE_TIMEOUT каждое срабатывание таймера, т.е., 3 секунды
                                                                          // чтобы избежать этого, будем пытаться узнать состояние подключения 1 раз в RESOLVE_INTERVAL (5 минут)
                                                                          // попытки будут продолжаться до первой успешной синхронизации времени
                                                                          // до этого момента функции будильника работать не будут
                                                                          // интервал последующих синхронизаций времени определяён в NTP_INTERVAL (30 минут)
                                                                          // при ошибках повторной синхронизации времени функции будильника отключаться не будут
#define RESOLVE_TIMEOUT       (1500UL)                                    // таймаут ожидания подключения к интернету в миллисекундах (1,5 секунды)
uint64_t lastResolveTryMoment = 0UL;
bool timeSynched = false;
bool ntpServerAddressResolved = false;
IPAddress ntpServerIp = {0, 0, 0, 0};


void timeTick()
{
  if (ESP_MODE == 1)
  {
    if (timeTimer.isReady())
    {
      if (!timeSynched)
      {
        if (millis() - lastResolveTryMoment >= RESOLVE_INTERVAL || lastResolveTryMoment == 0)
        {
          resolveNtpServerAddress(ntpServerAddressResolved);              // пытаемся получить IP адрес сервера времени (тест интернет подключения) до тех пор, пока время не будет успешно синхронизировано
          lastResolveTryMoment = millis();
          if (!ntpServerAddressResolved)
          {
            #ifdef GENERAL_DEBUG
            Serial.println(F("Функции будильника отключены до восстановления подключения к интернету"));
            #endif
          }
        }
        if (!ntpServerAddressResolved)
        {
          return;                                                         // если нет интернет подключения, отключаем будильник до тех пор, пока оно не будет восстановлено
        }
      }

      timeSynched = timeSynched || timeClient.update();                   // если время хотя бы один раз было синхронизировано, продолжаем
      if (!timeSynched)                                                   // если время не было синхронизиировано ни разу, отключаем будильник до тех пор, пока оно не будет синхронизировано
      {
        return;
      }

      byte thisDay = timeClient.getDay();
      if (thisDay == 0) thisDay = 7;                                      // воскресенье это 0
      thisDay--;
      thisTime = timeClient.getHours() * 60 + timeClient.getMinutes();

      // проверка рассвета
      if (alarms[thisDay].State &&                                                            // день будильника
          thisTime >= (alarms[thisDay].Time - pgm_read_byte(&dawnOffsets[dawnMode])) &&       // позже начала
          thisTime < (alarms[thisDay].Time + DAWN_TIMEOUT))                                   // раньше конца + минута
      {
        if (!manualOff)                                                   // будильник не был выключен вручную (из приложения или кнопкой)
        {
          // величина рассвета 0-255
          int32_t dawnPosition = 255 * ((float)(thisTime - (alarms[thisDay].Time - pgm_read_byte(&dawnOffsets[dawnMode]))) / pgm_read_byte(&dawnOffsets[dawnMode]));
          dawnPosition = constrain(dawnPosition, 0, 255);
          CHSV dawnColor = CHSV(map(dawnPosition, 0, 255, 10, 35),
                                map(dawnPosition, 0, 255, 255, 170),
                                map(dawnPosition, 0, 255, 10, DAWN_BRIGHT));
          fill_solid(leds, NUM_LEDS, dawnColor);
          FastLED.setBrightness(255);
          delay(1);
          FastLED.show();
          dawnFlag = true;
        }
      }
      else
      {
        if (dawnFlag)
        {
          dawnFlag = false;
          manualOff = false;
          FastLED.clear();
          delay(2);
          FastLED.show();
          changePower();                                                  // выключение матрицы или установка яркости текущего эффекта в засисимости от того, была ли включена лампа до срабатывания будильника
        }
      }
    }
  }
}

void resolveNtpServerAddress(bool &ntpServerAddressResolved)              // функция проверки подключения к интернету
{
  if (ntpServerAddressResolved)
  {
    return;
  }

  WiFi.hostByName(NTP_ADDRESS, ntpServerIp, RESOLVE_TIMEOUT);
  if (ntpServerIp[0] <= 0)
  {
    #ifdef GENERAL_DEBUG
    if (ntpServerAddressResolved)
    {
      Serial.println(F("Подключение к интернету отсутствует"));
    }
    #endif

    ntpServerAddressResolved = false;
  }
  else
  {
    #ifdef GENERAL_DEBUG
    if (!ntpServerAddressResolved)
    {
      Serial.println(F("Подключение к интернету установлено"));
    }
    #endif

    ntpServerAddressResolved = true;
  }
}
#endif
