197 lines
5.0 KiB
C
197 lines
5.0 KiB
C
WiFiUDP ntpUDP;
|
|
|
|
uint32_t lastTimeTriggerChecked = 0;
|
|
TimeTrigger* lastTimeTrigger = nullptr;
|
|
TimeTrigger* activeTimeTrigger = nullptr;
|
|
|
|
|
|
void initMotionPins()
|
|
{
|
|
if (!motionTriggerSettings->enabled())
|
|
return;
|
|
|
|
for (uint8_t i = 0; i < motionTriggerSettings->triggerCount(); i++)
|
|
{
|
|
MotionTrigger* trigger = motionTriggerSettings->trigger(i);
|
|
if (trigger->enabled)
|
|
pinMode(trigger->pin, INPUT);
|
|
}
|
|
}
|
|
|
|
|
|
void updateNTPClient()
|
|
{
|
|
if (ntpClient == nullptr && WiFi.status() == WL_CONNECTED &&
|
|
systemSettings->ntpServer() != nullptr && systemSettings->ntpInterval() > 0)
|
|
{
|
|
_dln("NTP :: initializing NTP client");
|
|
|
|
ntpClient = new NTPClient(ntpUDP, systemSettings->ntpServer(), 0, systemSettings->ntpInterval() * 60 * 1000);
|
|
ntpClient->begin();
|
|
}
|
|
|
|
|
|
if (ntpClient != nullptr)
|
|
ntpClient->update();
|
|
}
|
|
|
|
|
|
void updateTimeTrigger()
|
|
{
|
|
if (ntpClient == nullptr || !timeTriggerSettings->enabled())
|
|
{
|
|
activeTimeTrigger = nullptr;
|
|
return;
|
|
}
|
|
|
|
if (timeTriggerSettingsChanged)
|
|
{
|
|
// Time trigger settings changed, activeTimeTrigger pointer is considered
|
|
// invalid, force recheck
|
|
timeTriggerSettingsChanged = false;
|
|
}
|
|
else if (currentTime - lastTimeTriggerChecked < 10000)
|
|
return;
|
|
|
|
|
|
lastTimeTriggerChecked = currentTime;
|
|
_dln("Triggers:: updating time trigger");
|
|
|
|
uint32_t epochTime = ntpClient->getEpochTime();
|
|
if (epochTime == 0)
|
|
{
|
|
activeTimeTrigger = nullptr;
|
|
_dln("Triggers:: time not synchronised yet");
|
|
return;
|
|
}
|
|
|
|
// TODO apply timezone offset
|
|
|
|
tmElements_t time;
|
|
breakTime(epochTime, time);
|
|
|
|
activeTimeTrigger = timeTriggerSettings->getActiveTrigger(time);
|
|
|
|
#ifdef SerialDebug
|
|
_d("Triggers:: active time trigger: ");
|
|
if (activeTimeTrigger != nullptr)
|
|
_dln(activeTimeTrigger->time);
|
|
else
|
|
_dln("null");
|
|
#endif
|
|
}
|
|
|
|
|
|
uint32_t activeMotionStart = 0;
|
|
uint16_t activeMotionBrightness = 0;
|
|
MotionDirection activeMotionDirection = Nondirectional;
|
|
bool lastMotion = false;
|
|
|
|
|
|
void updateMotionTrigger()
|
|
{
|
|
if (!motionTriggerSettings->enabled() || !motionTriggerSettings->triggerCount())
|
|
{
|
|
activeMotionStart = 0;
|
|
return;
|
|
}
|
|
|
|
for (uint8_t i = 0; i < motionTriggerSettings->triggerCount(); i++)
|
|
{
|
|
MotionTrigger* trigger = motionTriggerSettings->trigger(i);
|
|
|
|
if (trigger->enabled && digitalRead(trigger->pin) == HIGH)
|
|
{
|
|
if (activeMotionStart == 0)
|
|
{
|
|
activeMotionDirection = trigger->direction;
|
|
activeMotionBrightness = trigger->brightness;
|
|
}
|
|
|
|
activeMotionStart = currentTime;
|
|
}
|
|
}
|
|
|
|
if (currentTime - activeMotionStart >= motionTriggerSettings->delay())
|
|
activeMotionStart = 0;
|
|
}
|
|
|
|
|
|
void checkTriggers()
|
|
{
|
|
if (!timeTriggerSettings->enabled() && activeTimeTrigger == nullptr &&
|
|
!motionTriggerSettings->enabled() && activeMotionStart == 0)
|
|
return;
|
|
|
|
updateTimeTrigger();
|
|
updateMotionTrigger();
|
|
|
|
bool inTimeTrigger = timeTriggerSettings->enabled() &&
|
|
activeTimeTrigger != nullptr &&
|
|
activeTimeTrigger->brightness;
|
|
bool timeTriggerChanged = activeTimeTrigger != lastTimeTrigger;
|
|
lastTimeTrigger = activeTimeTrigger;
|
|
|
|
bool inMotionTrigger = (activeMotionStart > 0) && (!inTimeTrigger || motionTriggerSettings->enabledDuringTimeTrigger());
|
|
bool motionChanged = (activeMotionStart > 0) != lastMotion;
|
|
lastMotion = (activeMotionStart > 0);
|
|
|
|
|
|
if (!motionChanged && !timeTriggerChanged)
|
|
return;
|
|
|
|
|
|
if (motionChanged)
|
|
{
|
|
if (inMotionTrigger)
|
|
{
|
|
_dln("Triggers :: start motion trigger");
|
|
|
|
if (activeMotionDirection == Nondirectional || motionTriggerSettings->transitionTime() == 0)
|
|
{
|
|
stairs->setAll(activeMotionBrightness, motionTriggerSettings->transitionTime(), 0);
|
|
}
|
|
else
|
|
{
|
|
// Start sweep
|
|
uint8_t stepsCount = stepsSettings->count();
|
|
uint16_t offsetIncrement = stepsCount > 0 ? (motionTriggerSettings->transitionTime() / stepsCount) * 1.5 : 0;
|
|
uint16_t offset = activeMotionDirection == TopDown ? 0 : (stepsCount - 1) * offsetIncrement;
|
|
|
|
for (uint8_t step = 0; step < stepsCount; step++)
|
|
{
|
|
stairs->set(step, activeMotionBrightness, motionTriggerSettings->transitionTime(), offset);
|
|
|
|
if (activeMotionDirection == TopDown)
|
|
offset += offsetIncrement;
|
|
else
|
|
offset -= offsetIncrement;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (inTimeTrigger)
|
|
{
|
|
_dln("Triggers :: motion stopped, falling back to time trigger");
|
|
|
|
// Fall back to time trigger value
|
|
stairs->setAll(activeTimeTrigger->brightness, motionTriggerSettings->transitionTime(), 0);
|
|
}
|
|
else
|
|
{
|
|
_dln("Triggers :: motion stopped, turning off");
|
|
|
|
// No more motion, no active time trigger, turn off
|
|
stairs->setAll(0, motionTriggerSettings->transitionTime(), 0);
|
|
}
|
|
}
|
|
}
|
|
else if (timeTriggerChanged && !inMotionTrigger)
|
|
{
|
|
_dln("Triggers :: time trigger changed");
|
|
|
|
// Set to time trigger value
|
|
stairs->setAll(activeTimeTrigger->brightness, timeTriggerSettings->transitionTime(), 0);
|
|
}
|
|
} |