fishtankmonitor/Lighting.cpp

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();
}