2020-03-25 09:00:55 +01:00
|
|
|
#include "wled.h"
|
2020-03-31 02:38:08 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* LED methods
|
|
|
|
*/
|
2019-12-03 14:15:12 +01:00
|
|
|
void setValuesFromMainSeg()
|
|
|
|
{
|
|
|
|
WS2812FX::Segment& seg = strip.getSegment(strip.getMainSegmentId());
|
|
|
|
colorFromUint32(seg.colors[0]);
|
|
|
|
colorFromUint32(seg.colors[1], true);
|
|
|
|
effectCurrent = seg.mode;
|
|
|
|
effectSpeed = seg.speed;
|
|
|
|
effectIntensity = seg.intensity;
|
|
|
|
effectPalette = seg.palette;
|
|
|
|
}
|
2016-12-31 00:38:51 +01:00
|
|
|
|
2019-12-13 01:23:07 +01:00
|
|
|
|
|
|
|
void resetTimebase()
|
|
|
|
{
|
|
|
|
strip.timebase = 0 - millis();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-11-22 00:09:30 +01:00
|
|
|
void toggleOnOff()
|
|
|
|
{
|
|
|
|
if (bri == 0)
|
|
|
|
{
|
|
|
|
bri = briLast;
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
briLast = bri;
|
|
|
|
bri = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-24 11:52:23 +01:00
|
|
|
|
2020-10-29 01:23:04 +01:00
|
|
|
//scales the brightness with the briMultiplier factor
|
|
|
|
byte scaledBri(byte in)
|
|
|
|
{
|
|
|
|
uint32_t d = in*briMultiplier;
|
|
|
|
uint32_t val = d/100;
|
|
|
|
if (val > 255) val = 255;
|
|
|
|
return (byte)val;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-11-19 19:39:17 +01:00
|
|
|
void setAllLeds() {
|
2020-02-09 19:10:29 +01:00
|
|
|
if (!realtimeMode || !arlsForceMaxBri)
|
2017-02-01 19:25:36 +01:00
|
|
|
{
|
2020-10-29 01:23:04 +01:00
|
|
|
strip.setBrightness(scaledBri(briT));
|
2017-02-01 19:25:36 +01:00
|
|
|
}
|
2020-02-20 00:45:09 +01:00
|
|
|
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY)
|
2018-05-31 19:26:16 +02:00
|
|
|
{
|
2019-02-05 21:53:39 +01:00
|
|
|
colorRGBtoRGBW(colT);
|
|
|
|
colorRGBtoRGBW(colSecT);
|
2018-05-31 19:26:16 +02:00
|
|
|
}
|
2019-06-20 14:40:12 +02:00
|
|
|
strip.setColor(0, colT[0], colT[1], colT[2], colT[3]);
|
|
|
|
strip.setColor(1, colSecT[0], colSecT[1], colSecT[2], colSecT[3]);
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|
|
|
|
|
2018-11-24 11:52:23 +01:00
|
|
|
|
2020-03-25 09:00:55 +01:00
|
|
|
void setLedsStandard(bool justColors)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2019-02-05 21:53:39 +01:00
|
|
|
for (byte i=0; i<4; i++)
|
2018-05-10 19:55:58 +02:00
|
|
|
{
|
|
|
|
colOld[i] = col[i];
|
|
|
|
colT[i] = col[i];
|
|
|
|
colSecOld[i] = colSec[i];
|
|
|
|
colSecT[i] = colSec[i];
|
|
|
|
}
|
2020-02-09 10:35:32 +01:00
|
|
|
if (justColors) return;
|
2018-03-14 13:16:28 +01:00
|
|
|
briOld = bri;
|
|
|
|
briT = bri;
|
2016-11-19 19:39:17 +01:00
|
|
|
setAllLeds();
|
|
|
|
}
|
|
|
|
|
2018-11-24 11:52:23 +01:00
|
|
|
|
2017-11-28 16:04:11 +01:00
|
|
|
bool colorChanged()
|
|
|
|
{
|
2019-02-05 21:53:39 +01:00
|
|
|
for (byte i=0; i<4; i++)
|
2017-11-28 16:04:11 +01:00
|
|
|
{
|
2018-03-14 13:16:28 +01:00
|
|
|
if (col[i] != colIT[i]) return true;
|
|
|
|
if (colSec[i] != colSecIT[i]) return true;
|
2017-11-28 16:04:11 +01:00
|
|
|
}
|
2018-03-14 13:16:28 +01:00
|
|
|
if (bri != briIT) return true;
|
2017-11-28 16:04:11 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-24 11:52:23 +01:00
|
|
|
|
2016-11-19 19:39:17 +01:00
|
|
|
void colorUpdated(int callMode)
|
|
|
|
{
|
2018-11-24 11:52:23 +01:00
|
|
|
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
|
2019-01-09 22:52:42 +01:00
|
|
|
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
|
2020-02-22 16:17:32 +01:00
|
|
|
if (callMode != NOTIFIER_CALL_MODE_INIT &&
|
|
|
|
callMode != NOTIFIER_CALL_MODE_DIRECT_CHANGE &&
|
|
|
|
callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments
|
2020-12-14 23:32:57 +01:00
|
|
|
|
|
|
|
bool someSel = false;
|
|
|
|
|
|
|
|
if (callMode == NOTIFIER_CALL_MODE_NOTIFICATION) {
|
|
|
|
someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
|
|
|
}
|
2019-12-02 12:41:35 +01:00
|
|
|
|
2020-12-14 23:32:57 +01:00
|
|
|
//Notifier: apply received FX to selected segments only if actually receiving FX
|
|
|
|
if (someSel) strip.applyToAllSelected = receiveNotificationEffects;
|
|
|
|
|
2018-11-24 11:52:23 +01:00
|
|
|
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
|
2020-02-24 17:25:40 +01:00
|
|
|
bool colChanged = colorChanged();
|
|
|
|
|
2020-12-14 23:32:57 +01:00
|
|
|
//Notifier: apply received color to selected segments only if actually receiving color
|
|
|
|
if (someSel) strip.applyToAllSelected = receiveNotificationColor;
|
|
|
|
|
2020-02-24 17:25:40 +01:00
|
|
|
if (fxChanged || colChanged)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2020-02-24 17:25:40 +01:00
|
|
|
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
|
|
|
|
if (isPreset) {isPreset = false;}
|
|
|
|
else {currentPreset = -1;}
|
|
|
|
|
|
|
|
notify(callMode);
|
|
|
|
|
|
|
|
//set flag to update blynk and mqtt
|
2020-12-10 16:27:23 +01:00
|
|
|
interfaceUpdateCallMode = callMode;
|
2020-02-24 17:25:40 +01:00
|
|
|
} else {
|
2020-02-22 16:17:32 +01:00
|
|
|
if (nightlightActive && !nightlightActiveOld &&
|
|
|
|
callMode != NOTIFIER_CALL_MODE_NOTIFICATION &&
|
|
|
|
callMode != NOTIFIER_CALL_MODE_NO_NOTIFY)
|
2018-11-22 00:09:30 +01:00
|
|
|
{
|
2020-02-22 16:17:32 +01:00
|
|
|
notify(NOTIFIER_CALL_MODE_NIGHTLIGHT);
|
|
|
|
interfaceUpdateCallMode = NOTIFIER_CALL_MODE_NIGHTLIGHT;
|
2019-04-14 19:31:25 +02:00
|
|
|
}
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|
2020-02-24 17:25:40 +01:00
|
|
|
|
|
|
|
if (!colChanged) return; //following code is for e.g. initiating transitions
|
|
|
|
|
2020-06-22 12:30:31 +02:00
|
|
|
if (callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightActive && (nightlightMode == NL_MODE_FADE || nightlightMode == NL_MODE_COLORFADE))
|
2017-04-26 14:04:53 +02:00
|
|
|
{
|
2018-03-14 13:16:28 +01:00
|
|
|
briNlT = bri;
|
2017-04-26 14:04:53 +02:00
|
|
|
nightlightDelayMs -= (millis() - nightlightStartTime);
|
|
|
|
nightlightStartTime = millis();
|
|
|
|
}
|
2019-02-05 21:53:39 +01:00
|
|
|
for (byte i=0; i<4; i++)
|
|
|
|
{
|
|
|
|
colIT[i] = col[i];
|
|
|
|
colSecIT[i] = colSec[i];
|
|
|
|
}
|
2020-02-09 10:35:32 +01:00
|
|
|
if (briT == 0)
|
|
|
|
{
|
2020-02-22 16:17:32 +01:00
|
|
|
setLedsStandard(true); //do not color transition if starting from off
|
|
|
|
if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning
|
2020-02-09 10:35:32 +01:00
|
|
|
}
|
|
|
|
|
2018-03-14 13:16:28 +01:00
|
|
|
briIT = bri;
|
|
|
|
if (bri > 0) briLast = bri;
|
2020-06-22 12:30:31 +02:00
|
|
|
|
|
|
|
//deactivate nightlight if target brightness is reached
|
2020-10-02 12:30:17 +02:00
|
|
|
if (bri == nightlightTargetBri && callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightMode != NL_MODE_SUN) nightlightActive = false;
|
2018-10-04 16:50:12 +02:00
|
|
|
|
2018-09-04 15:51:38 +02:00
|
|
|
if (fadeTransition)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2018-03-15 13:03:50 +01:00
|
|
|
//set correct delay if not using notification delay
|
2020-02-22 16:17:32 +01:00
|
|
|
if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay;
|
2019-10-29 02:21:23 +01:00
|
|
|
jsonTransitionOnce = false;
|
2018-10-04 16:50:12 +02:00
|
|
|
if (transitionDelayTemp == 0) {setLedsStandard(); strip.trigger(); return;}
|
2018-03-15 13:03:50 +01:00
|
|
|
|
2017-10-28 23:40:06 +02:00
|
|
|
if (transitionActive)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2019-02-05 21:53:39 +01:00
|
|
|
for (byte i=0; i<4; i++)
|
|
|
|
{
|
|
|
|
colOld[i] = colT[i];
|
|
|
|
colSecOld[i] = colSecT[i];
|
|
|
|
}
|
2018-03-14 13:16:28 +01:00
|
|
|
briOld = briT;
|
|
|
|
tperLast = 0;
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|
2018-09-06 02:05:56 +02:00
|
|
|
strip.setTransitionMode(true);
|
2016-11-19 19:39:17 +01:00
|
|
|
transitionActive = true;
|
|
|
|
transitionStartTime = millis();
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
setLedsStandard();
|
2017-11-19 15:31:17 +01:00
|
|
|
strip.trigger();
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|
2018-10-04 16:50:12 +02:00
|
|
|
}
|
|
|
|
|
2018-11-24 11:52:23 +01:00
|
|
|
|
2018-10-04 16:50:12 +02:00
|
|
|
void updateInterfaces(uint8_t callMode)
|
|
|
|
{
|
2020-06-26 17:28:35 +02:00
|
|
|
sendDataWs();
|
2019-03-01 17:10:42 +01:00
|
|
|
#ifndef WLED_DISABLE_ALEXA
|
2020-02-22 16:17:32 +01:00
|
|
|
if (espalexaDevice != nullptr && callMode != NOTIFIER_CALL_MODE_ALEXA) {
|
2019-03-01 17:10:42 +01:00
|
|
|
espalexaDevice->setValue(bri);
|
|
|
|
espalexaDevice->setColor(col[0], col[1], col[2]);
|
|
|
|
}
|
|
|
|
#endif
|
2020-02-22 16:17:32 +01:00
|
|
|
if (callMode != NOTIFIER_CALL_MODE_BLYNK &&
|
|
|
|
callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) updateBlynk();
|
2019-10-20 17:38:25 +02:00
|
|
|
doPublishMqtt = true;
|
2018-10-04 16:50:12 +02:00
|
|
|
lastInterfaceUpdate = millis();
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|
|
|
|
|
2018-11-24 11:52:23 +01:00
|
|
|
|
2016-11-19 19:39:17 +01:00
|
|
|
void handleTransitions()
|
|
|
|
{
|
2018-10-04 16:50:12 +02:00
|
|
|
//handle still pending interface update
|
|
|
|
if (interfaceUpdateCallMode && millis() - lastInterfaceUpdate > 2000)
|
|
|
|
{
|
|
|
|
updateInterfaces(interfaceUpdateCallMode);
|
|
|
|
interfaceUpdateCallMode = 0; //disable
|
|
|
|
}
|
2019-10-20 17:38:25 +02:00
|
|
|
if (doPublishMqtt) publishMqtt();
|
2018-10-04 16:50:12 +02:00
|
|
|
|
2018-03-15 13:03:50 +01:00
|
|
|
if (transitionActive && transitionDelayTemp > 0)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2018-03-15 13:03:50 +01:00
|
|
|
float tper = (millis() - transitionStartTime)/(float)transitionDelayTemp;
|
2016-11-19 19:39:17 +01:00
|
|
|
if (tper >= 1.0)
|
|
|
|
{
|
2018-09-06 02:05:56 +02:00
|
|
|
strip.setTransitionMode(false);
|
2016-11-19 19:39:17 +01:00
|
|
|
transitionActive = false;
|
2018-03-14 13:16:28 +01:00
|
|
|
tperLast = 0;
|
2016-11-19 19:39:17 +01:00
|
|
|
setLedsStandard();
|
|
|
|
return;
|
|
|
|
}
|
2019-02-05 19:40:24 +01:00
|
|
|
if (tper - tperLast < 0.004) return;
|
2018-03-14 13:16:28 +01:00
|
|
|
tperLast = tper;
|
2019-02-05 21:53:39 +01:00
|
|
|
for (byte i=0; i<4; i++)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2019-02-05 19:40:24 +01:00
|
|
|
colT[i] = colOld[i]+((col[i] - colOld[i])*tper);
|
|
|
|
colSecT[i] = colSecOld[i]+((colSec[i] - colSecOld[i])*tper);
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|
2019-02-05 19:40:24 +01:00
|
|
|
briT = briOld +((bri - briOld )*tper);
|
|
|
|
|
|
|
|
setAllLeds();
|
2016-11-27 16:45:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-24 11:52:23 +01:00
|
|
|
|
2016-11-27 16:45:54 +01:00
|
|
|
void handleNightlight()
|
|
|
|
{
|
|
|
|
if (nightlightActive)
|
|
|
|
{
|
2018-03-14 13:16:28 +01:00
|
|
|
if (!nightlightActiveOld) //init
|
2016-11-27 16:45:54 +01:00
|
|
|
{
|
2016-12-11 20:11:14 +01:00
|
|
|
nightlightStartTime = millis();
|
2016-11-27 16:45:54 +01:00
|
|
|
nightlightDelayMs = (int)(nightlightDelayMins*60000);
|
2018-03-14 13:16:28 +01:00
|
|
|
nightlightActiveOld = true;
|
|
|
|
briNlT = bri;
|
2020-09-10 11:01:05 +02:00
|
|
|
for (byte i=0; i<4; i++) colNlT[i] = col[i]; // remember starting color
|
2020-06-22 12:30:31 +02:00
|
|
|
if (nightlightMode == NL_MODE_SUN)
|
|
|
|
{
|
|
|
|
//save current
|
|
|
|
colNlT[0] = effectCurrent;
|
|
|
|
colNlT[1] = effectSpeed;
|
|
|
|
colNlT[2] = effectPalette;
|
|
|
|
|
2020-09-10 11:01:05 +02:00
|
|
|
strip.setMode(strip.getMainSegmentId(), FX_MODE_STATIC); //make sure seg runtime is reset if left in sunrise mode
|
2020-06-22 12:30:31 +02:00
|
|
|
effectCurrent = FX_MODE_SUNRISE;
|
|
|
|
effectSpeed = nightlightDelayMins;
|
|
|
|
effectPalette = 0;
|
|
|
|
if (effectSpeed > 60) effectSpeed = 60; //currently limited to 60 minutes
|
|
|
|
if (bri) effectSpeed += 60; //sunset if currently on
|
|
|
|
briNlT = !bri; //true == sunrise, false == sunset
|
|
|
|
if (!bri) bri = briLast;
|
|
|
|
colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY);
|
|
|
|
}
|
2016-11-27 16:45:54 +01:00
|
|
|
}
|
|
|
|
float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs);
|
2020-06-22 12:30:31 +02:00
|
|
|
if (nightlightMode == NL_MODE_FADE || nightlightMode == NL_MODE_COLORFADE)
|
2017-04-26 14:04:53 +02:00
|
|
|
{
|
2018-11-09 17:00:36 +01:00
|
|
|
bri = briNlT + ((nightlightTargetBri - briNlT)*nper);
|
2020-06-22 12:30:31 +02:00
|
|
|
if (nightlightMode == NL_MODE_COLORFADE) // color fading only is enabled with "NF=2"
|
2020-01-08 12:00:25 +01:00
|
|
|
{
|
2020-02-24 17:27:59 +01:00
|
|
|
for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color
|
2020-01-08 12:00:25 +01:00
|
|
|
}
|
2020-02-22 16:17:32 +01:00
|
|
|
colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY);
|
2017-04-26 14:04:53 +02:00
|
|
|
}
|
2020-06-22 12:30:31 +02:00
|
|
|
if (nper >= 1) //nightlight duration over
|
2016-11-27 16:45:54 +01:00
|
|
|
{
|
|
|
|
nightlightActive = false;
|
2020-06-22 12:30:31 +02:00
|
|
|
if (nightlightMode == NL_MODE_SET)
|
2016-12-11 20:11:14 +01:00
|
|
|
{
|
2018-02-20 22:29:48 +01:00
|
|
|
bri = nightlightTargetBri;
|
2020-02-22 16:17:32 +01:00
|
|
|
colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY);
|
2016-12-11 20:11:14 +01:00
|
|
|
}
|
2018-03-14 13:16:28 +01:00
|
|
|
if (bri == 0) briLast = briNlT;
|
2020-06-22 12:30:31 +02:00
|
|
|
if (nightlightMode == NL_MODE_SUN)
|
|
|
|
{
|
|
|
|
if (!briNlT) { //turn off if sunset
|
|
|
|
effectCurrent = colNlT[0];
|
|
|
|
effectSpeed = colNlT[1];
|
|
|
|
effectPalette = colNlT[2];
|
|
|
|
toggleOnOff();
|
|
|
|
setLedsStandard();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
updateBlynk();
|
|
|
|
if (macroNl > 0)
|
2020-11-06 22:12:48 +01:00
|
|
|
applyPreset(macroNl);
|
2020-06-22 12:30:31 +02:00
|
|
|
nightlightActiveOld = false;
|
2016-11-27 16:45:54 +01:00
|
|
|
}
|
2018-03-14 13:16:28 +01:00
|
|
|
} else if (nightlightActiveOld) //early de-init
|
2016-11-27 16:45:54 +01:00
|
|
|
{
|
2020-06-22 12:30:31 +02:00
|
|
|
if (nightlightMode == NL_MODE_SUN) { //restore previous effect
|
|
|
|
effectCurrent = colNlT[0];
|
|
|
|
effectSpeed = colNlT[1];
|
|
|
|
effectPalette = colNlT[2];
|
|
|
|
colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY);
|
|
|
|
}
|
2018-03-14 13:16:28 +01:00
|
|
|
nightlightActiveOld = false;
|
2016-11-27 16:45:54 +01:00
|
|
|
}
|
2018-04-11 23:50:35 +02:00
|
|
|
|
|
|
|
//also handle preset cycle here
|
2020-05-18 16:36:31 +02:00
|
|
|
if (presetCyclingEnabled && (millis() - presetCycledTime > (100*presetCycleTime)))
|
2018-04-11 23:50:35 +02:00
|
|
|
{
|
2020-08-30 23:31:58 +02:00
|
|
|
presetCycledTime = millis();
|
|
|
|
if (bri == 0 || nightlightActive) return;
|
|
|
|
|
|
|
|
if (presetCycCurr < presetCycleMin || presetCycCurr > presetCycleMax) presetCycCurr = presetCycleMin;
|
2020-12-10 16:27:23 +01:00
|
|
|
applyPreset(presetCycCurr); //this handles colorUpdated() for us
|
2020-08-30 23:31:58 +02:00
|
|
|
presetCycCurr++;
|
2020-11-23 00:58:58 +01:00
|
|
|
if (presetCycCurr > 250) presetCycCurr = 1;
|
2020-12-10 16:27:23 +01:00
|
|
|
interfaceUpdateCallMode = 0; //disable updates to MQTT and Blynk
|
2018-04-11 23:50:35 +02:00
|
|
|
}
|
2016-11-27 16:45:54 +01:00
|
|
|
}
|
2020-08-25 17:23:17 +02:00
|
|
|
|
|
|
|
//utility for FastLED to use our custom timer
|
|
|
|
uint32_t get_millisecond_timer()
|
|
|
|
{
|
|
|
|
return strip.now;
|
|
|
|
}
|