95 lines
No EOL
2.6 KiB
C++
95 lines
No EOL
2.6 KiB
C++
#include "Lighting.h"
|
|
#include <FastLED.h>
|
|
|
|
#define MAX_HEAT_INDEX 240.0
|
|
|
|
Lighting::Lighting(NaturalLight* naturalLight, Weather* weather, float cloudCoverLimit) {
|
|
_naturalLight = naturalLight;
|
|
_weather = weather;
|
|
_cloudCoverLimit = cloudCoverLimit;
|
|
|
|
CRGB leds = CRGB(_ledCount);
|
|
_leds = &leds;
|
|
}
|
|
|
|
float Lighting::getIndexMultiplier(int now, int startTime, int endTime, bool swap) {
|
|
float a = swap ? endTime - now : now - startTime;
|
|
float b = endTime - startTime;
|
|
return constrain(a / b, 0, 1);
|
|
}
|
|
|
|
float Lighting::getHeatIndex(int now) {
|
|
return now >= _naturalLight->getSunset()
|
|
? getIndexMultiplier(now, _naturalLight->getSunset(), _naturalLight->getAstronomicalTwilightEnd(), true)
|
|
: getIndexMultiplier(now, _naturalLight->getAstronomicalTwilightBegin(), _naturalLight->getSunrise(), false);
|
|
}
|
|
|
|
float Lighting::getPaletteHeatIndex(int now){
|
|
return MAX_HEAT_INDEX * getHeatIndex(now);
|
|
}
|
|
|
|
float Lighting::getBrightness() {
|
|
float cloudCover = (float)_weather->getCloudCover() / 100.0;
|
|
float multiplier = cloudCover * (_cloudCoverLimit / 100.0);
|
|
if (_weather->getCondition() == WeatherCondition::Other)
|
|
multiplier *= 2.0;
|
|
return 1 - multiplier;
|
|
}
|
|
|
|
float Lighting::getPaletteBrightness(){
|
|
return getBrightness() * 255.0;
|
|
}
|
|
|
|
int Lighting::byteToAnalogue(byte input){
|
|
float fraction = input / 255.0;
|
|
return fraction * 1024;
|
|
}
|
|
|
|
void Lighting::outputColour(CRGB colour){
|
|
if (_useStrip)
|
|
FastLED.showColor(colour);
|
|
|
|
if (_usePWM){
|
|
analogWrite(_rPin, byteToAnalogue(colour.r));
|
|
analogWrite(_gPin, byteToAnalogue(colour.g));
|
|
analogWrite(_bPin, byteToAnalogue(colour.b));
|
|
}
|
|
}
|
|
|
|
void Lighting::updateRGB(int now) {
|
|
byte heatIndex = getPaletteHeatIndex(now);
|
|
byte brightness = getPaletteBrightness();
|
|
if (heatIndex != _lastHeatIndex || brightness!=_lastBrightness) {
|
|
CRGB colour = ColorFromPalette(_sunrise, heatIndex, brightness, LINEARBLEND);
|
|
|
|
if (_weather->getCondition() == WeatherCondition::Thunder && millis() >= _nextLightningFlash) {
|
|
int flashes = random8(2, 8);
|
|
for (int i = 0; i < flashes; i++) {
|
|
outputColour(CRGB::White);
|
|
delay(random8(10, 20));
|
|
outputColour(colour);
|
|
delay(random8(40, 80));
|
|
}
|
|
_nextLightningFlash = millis() + (random8(1, 60) * 1000);
|
|
}
|
|
|
|
outputColour(colour);
|
|
}
|
|
_lastHeatIndex = heatIndex;
|
|
_lastBrightness = brightness;
|
|
}
|
|
|
|
void Lighting::updateWhite(){
|
|
float brightness = (_heatIndex - 0.5) / 0.5;
|
|
if (brightness<0)
|
|
brightness = 0;
|
|
analogWrite(_whitePin, PWMRANGE * brightness);
|
|
}
|
|
|
|
void Lighting::update(int now) {
|
|
_heatIndex = getHeatIndex(now);
|
|
_brightness = getBrightness();
|
|
|
|
updateRGB(now);
|
|
updateWhite();
|
|
} |