fishtankmonitor/Lighting.cpp

81 lines
No EOL
2.3 KiB
C++

#include "Lighting.h"
#include <FastLED.h>
#define MAX_HEAT_INDEX 240.0
Lighting::Lighting(int ledCount, NaturalLight* naturalLight, Weather* weather, float cloudCoverLimit) {
_ledCount = ledCount;
_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;
}
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++) {
FastLED.showColor(CRGB::White);
delay(random8(10, 20));
FastLED.showColor(colour);
delay(random8(40, 80));
}
_nextLightningFlash = millis() + (random8(1, 60) * 1000);
}
fill_solid(_leds, _ledCount, colour);
FastLED.show();
}
_lastHeatIndex = heatIndex;
_lastBrightness = brightness;
}
void Lighting::updateWhite(){
float brightness = (_heatIndex - 0.5) / 0.5;
if (brightness<0)
brightness = 0;
analogWrite(_whitePin, 1024 * brightness);
}
void Lighting::update(int now) {
_heatIndex = getHeatIndex(now);
_brightness = getBrightness();
updateRGB(now);
updateWhite();
}