Files
gunner47-GyverLamp/firmware/GyverLamp_v1.4/time.ino

172 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
IPAddress ntpServerIp = {0, 0, 0, 0};
static CHSV dawnColor = CHSV(0, 0, 0); // цвет "рассвета"
static CHSV dawnColorMinus1 = CHSV(0, 0, 0); // для большей плавности назначаем каждый новый цвет только 1/10 всех диодов; каждая следующая 1/10 часть будет "оставать" на 1 шаг
static CHSV dawnColorMinus2 = CHSV(0, 0, 0);
static CHSV dawnColorMinus3 = CHSV(0, 0, 0);
static CHSV dawnColorMinus4 = CHSV(0, 0, 0);
static CHSV dawnColorMinus5 = CHSV(0, 0, 0);
static uint8_t dawnCounter = 0; // счётчик первых 10 шагов будильника
void timeTick()
{
if (espMode == 1U)
{
if (timeTimer.isReady())
{
if (!timeSynched)
{
if (millis() - lastResolveTryMoment >= RESOLVE_INTERVAL || lastResolveTryMoment == 0)
{
resolveNtpServerAddress(ntpServerAddressResolved); // пытаемся получить IP адрес сервера времени (тест интернет подключения) до тех пор, пока время не будет успешно синхронизировано
lastResolveTryMoment = millis();
if (!ntpServerAddressResolved)
{
#ifdef GENERAL_DEBUG
LOG.println(F("Функции будильника отключены до восстановления подключения к интернету"));
#endif
}
}
if (!ntpServerAddressResolved)
{
return; // если нет интернет подключения, отключаем будильник до тех пор, пока оно не будет восстановлено
}
}
timeSynched = timeClient.update() || timeSynched; // если время хотя бы один раз было синхронизировано, продолжаем
if (!timeSynched) // если время не было синхронизиировано ни разу, отключаем будильник до тех пор, пока оно не будет синхронизировано
{
return;
}
time_t currentLocalTime = localTimeZone.toLocal(timeClient.getEpochTime());
uint8_t thisDay = dayOfWeek(currentLocalTime);
if (thisDay == 1) thisDay = 8; // в библиотеке Time воскресенье - это 1; приводим к диапазону [0..6], где воскресенье - это 6
thisDay -= 2;
thisTime = hour(currentLocalTime) * 60 + minute(currentLocalTime);
uint32_t thisFullTime = hour(currentLocalTime) * 3600 + minute(currentLocalTime) * 60 + second(currentLocalTime);
printTime(thisTime, false, ONflag); // проверка текущего времени и его вывод (если заказан и если текущее время соответстует заказанному расписанию вывода)
// проверка рассвета
if (alarms[thisDay].State && // день будильника
thisTime >= (uint16_t)constrain(alarms[thisDay].Time - pgm_read_byte(&dawnOffsets[dawnMode]), 0, (24 * 60)) && // позже начала
thisTime < (alarms[thisDay].Time + DAWN_TIMEOUT)) // раньше конца + минута
{
if (!manualOff) // будильник не был выключен вручную (из приложения или кнопкой)
{
// величина рассвета 0-255
int32_t dawnPosition = 255 * ((float)(thisFullTime - (alarms[thisDay].Time - pgm_read_byte(&dawnOffsets[dawnMode])) * 60) / (pgm_read_byte(&dawnOffsets[dawnMode]) * 60));
dawnPosition = constrain(dawnPosition, 0, 255);
dawnColorMinus5 = dawnCounter > 4 ? dawnColorMinus4 : dawnColorMinus5;
dawnColorMinus4 = dawnCounter > 3 ? dawnColorMinus3 : dawnColorMinus4;
dawnColorMinus3 = dawnCounter > 2 ? dawnColorMinus2 : dawnColorMinus3;
dawnColorMinus2 = dawnCounter > 1 ? dawnColorMinus1 : dawnColorMinus2;
dawnColorMinus1 = dawnCounter > 0 ? dawnColor : dawnColorMinus1;
dawnColor = CHSV(map(dawnPosition, 0, 255, 10, 35),
map(dawnPosition, 0, 255, 255, 170),
map(dawnPosition, 0, 255, 10, DAWN_BRIGHT));
dawnCounter++;
// fill_solid(leds, NUM_LEDS, dawnColor);
for (uint16_t i = 0U; i < NUM_LEDS; i++)
{
if (i % 6 == 0) leds[i] = dawnColor; // 1я 1/10 диодов: цвет текущего шага
if (i % 6 == 1) leds[i] = dawnColorMinus1; // 2я 1/10 диодов: -1 шаг
if (i % 6 == 2) leds[i] = dawnColorMinus2; // 3я 1/10 диодов: -2 шага
if (i % 6 == 3) leds[i] = dawnColorMinus3; // 3я 1/10 диодов: -3 шага
if (i % 6 == 4) leds[i] = dawnColorMinus4; // 3я 1/10 диодов: -4 шага
if (i % 6 == 5) leds[i] = dawnColorMinus5; // 3я 1/10 диодов: -5 шагов
}
FastLED.setBrightness(255);
delay(1);
FastLED.show();
dawnFlag = true;
}
#if defined(ALARM_PIN) && defined(ALARM_LEVEL) // установка сигнала в пин, управляющий будильником
if (thisTime == alarms[thisDay].Time) // установка, только в минуту, на которую заведён будильник
{
digitalWrite(ALARM_PIN, manualOff ? !ALARM_LEVEL : ALARM_LEVEL);// установка сигнала в зависимости от того, был ли отключен будильник вручную
}
#endif
}
else
{
// не время будильника (ещё не начался или закончился по времени)
if (dawnFlag)
{
dawnFlag = false;
FastLED.clear();
delay(2);
FastLED.show();
changePower(); // выключение матрицы или установка яркости текущего эффекта в засисимости от того, была ли включена лампа до срабатывания будильника
}
manualOff = false;
dawnColorMinus1 = CHSV(0, 0, 0);
dawnColorMinus2 = CHSV(0, 0, 0);
dawnColorMinus3 = CHSV(0, 0, 0);
dawnColorMinus4 = CHSV(0, 0, 0);
dawnColorMinus5 = CHSV(0, 0, 0);
dawnCounter = 0;
#if defined(ALARM_PIN) && defined(ALARM_LEVEL) // установка сигнала в пин, управляющий будильником
digitalWrite(ALARM_PIN, !ALARM_LEVEL);
#endif
}
}
}
}
void resolveNtpServerAddress(bool &ntpServerAddressResolved) // функция проверки подключения к интернету
{
if (ntpServerAddressResolved)
{
return;
}
WiFi.hostByName(NTP_ADDRESS, ntpServerIp, RESOLVE_TIMEOUT);
if (ntpServerIp[0] <= 0)
{
#ifdef GENERAL_DEBUG
if (ntpServerAddressResolved)
{
LOG.println(F("Подключение к интернету отсутствует"));
}
#endif
ntpServerAddressResolved = false;
}
else
{
#ifdef GENERAL_DEBUG
if (!ntpServerAddressResolved)
{
LOG.println(F("Подключение к интернету установлено"));
}
#endif
ntpServerAddressResolved = true;
}
}
void getFormattedTime(char *buf)
{
time_t currentLocalTime = localTimeZone.toLocal(timeClient.getEpochTime());
sprintf_P(buf, PSTR("%02u:%02u:%02u"), hour(currentLocalTime), minute(currentLocalTime), second(currentLocalTime));
}
#endif