diff --git a/NaturalLight.cpp b/NaturalLight.cpp new file mode 100644 index 0000000..ad6968a --- /dev/null +++ b/NaturalLight.cpp @@ -0,0 +1,54 @@ +#include "NaturalLight.h" +#include +#include +#include +#include + +NaturalLight::NaturalLight(char *lat, char *lon, int timezoneOffset) { + _timezoneOffset = timezoneOffset; + sprintf(_url, SOLAR_EVENT_URL, lat, lon); +} + +String NaturalLight::getSolarEventJson() { + HTTPClient http; + http.begin(_url); + int httpCode = http.GET(); + String result = ""; + if (httpCode > 0) + result = http.getString(); + http.end(); + + return result; +} + +int NaturalLight::getEpoch(const char *str) { + struct tm time; + int year, month; + sscanf(str, "%d-%d-%dT%d:%d:%d+00:00", &year, &month, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec); + time.tm_year = year - 1900; + time.tm_mon = month - 1; + return mktime(&time); +} + +int NaturalLight::adjustForTimezone(int epoch) { + return epoch + _timezoneOffset; +} + +void NaturalLight::update() { + String json = getSolarEventJson(); + StaticJsonBuffer<1024> jsonBuffer; + JsonObject &root = jsonBuffer.parseObject(json); + + if (!root.success()) + return; + + const char *astronomicalTwilightBegin = root["results"]["astronomical_twilight_begin"]; + const char *sunrise = root["results"]["sunrise"]; + const char *sunset = root["results"]["sunset"]; + const char *astronomicalTwilightEnd = root["results"]["astronomical_twilight_end"]; + + _astronomicalTwilightBegin = adjustForTimezone(getEpoch(astronomicalTwilightBegin)); + _sunrise = adjustForTimezone(getEpoch(sunrise)); + _sunset = adjustForTimezone(getEpoch(sunset)); + _astronomicalTwilightEnd = adjustForTimezone(getEpoch(astronomicalTwilightEnd)); +} \ No newline at end of file diff --git a/NaturalLight.h b/NaturalLight.h new file mode 100644 index 0000000..149c142 --- /dev/null +++ b/NaturalLight.h @@ -0,0 +1,22 @@ +#ifndef _DAYLIGHT_h +#define _DAYLIGHT_h +#include + +#define SOLAR_EVENT_URL "http://api.sunrise-sunset.org/json?lat=%s&lng=%s&formatted=0" + +class NaturalLight { + int _astronomicalTwilightBegin, _sunrise, _sunset, _astronomicalTwilightEnd, _timezoneOffset; + char _url[80]; + String getSolarEventJson(); + int getEpoch(const char *str); + int adjustForTimezone(int epoch); + +public: + NaturalLight(char *lat, char *lon, int timezoneOffset); + void update(); + int getAstronomicalTwilightBegin() { return _astronomicalTwilightBegin; } + int getSunrise() { return _sunrise; } + int getSunset() { return _sunset; } + int getAstronomicalTwilightEnd() { return _astronomicalTwilightEnd; } +}; +#endif \ No newline at end of file diff --git a/monitor.ino b/monitor.ino index d0ad360..e711ed8 100644 --- a/monitor.ino +++ b/monitor.ino @@ -1,11 +1,10 @@ #include #include #include -#include -#include #include #include "sensors.h" +#include "NaturalLight.h" #define HOSTNAME "Fishtank" #define MQTT_SERVER "192.168.1.3" @@ -17,8 +16,10 @@ #define TEMPERATURE_TOPIC "/home/sensors/fishtank/temperature" #define TEMPERATURE_PIN D5 -#define SOLAR_EVENT_URL "http://api.sunrise-sunset.org/json?lat=20.548103&lng=96.916835&formatted=0" +#define LATITUDE "20.548103" +#define LONGITUDE "96.916835" #define TIMEZONE_OFFSET 27000 // 7.5 hours in seconds + #define NTP_POOL "uk.pool.ntp.org" #define HEAT_INDEX_MAX 241.0 // After 241 the pallet seems to go dim @@ -28,9 +29,9 @@ WiFiClient _wifiClient; PubSubClient _mqttClient = PubSubClient(MQTT_SERVER, 1883, mqttCallback, _wifiClient); Sensors _sensors = Sensors(TEMPERATURE_PIN, TEMPERATURE_TOPIC, PH_TOPIC, _mqttClient); +NaturalLight _naturalLight = NaturalLight(LATITUDE, LONGITUDE, TIMEZONE_OFFSET); CRGB _leds[LED_COUNT]; -int _lightsOnStartTime, _lightsOnEndTime, _lightsOffStartTime, _lightsOffEndTime; void waitForWiFi() { @@ -62,54 +63,6 @@ void reconnect() { waitForMQTT(); } -String getSolarEventJson(){ - waitForWiFi(); - - HTTPClient http; - http.begin(SOLAR_EVENT_URL); - int httpCode = http.GET(); - String result = ""; - if (httpCode > 0) - result = http.getString(); - http.end(); - - return result; -} - -int getEpoch(const char *str) { - struct tm time; - int year, month; - sscanf(str, "%d-%d-%dT%d:%d:%d+00:00", &year, &month, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec); - time.tm_year = year - 1900; - time.tm_mon = month - 1; - return mktime(&time); -} - -int adjustForTimezone(int epoch){ - return epoch + TIMEZONE_OFFSET; -} - -void parseEvents(){ - String json = getSolarEventJson(); - StaticJsonBuffer<1024> jsonBuffer; - JsonObject &root = jsonBuffer.parseObject(json); - - if (!root.success()) { - Serial.println("Could not parse json"); - return; - } - - const char *astronomicalTwilightBegin = root["results"]["astronomical_twilight_begin"]; - const char *sunrise = root["results"]["sunrise"]; - const char *sunset = root["results"]["sunset"]; - const char *astronomicalTwilightEnd = root["results"]["astronomical_twilight_end"]; - - _lightsOnStartTime = adjustForTimezone(getEpoch(astronomicalTwilightBegin)); - _lightsOnEndTime = adjustForTimezone(getEpoch(sunrise)); - _lightsOffStartTime = adjustForTimezone(getEpoch(sunset)); - _lightsOffEndTime = adjustForTimezone(getEpoch(astronomicalTwilightEnd)); -} - void setup() { Serial.begin(115200); @@ -122,7 +75,7 @@ void setup() { delay(2000); configTime(0, 0, NTP_POOL); - parseEvents(); + _naturalLight.update(); FastLED.addLeds(_leds, LED_COUNT).setCorrection(TypicalSMD5050).setTemperature(Tungsten40W); } @@ -136,7 +89,9 @@ float getIndexMultiplier(int now, int startTime, int endTime, bool swap){ float getHeatIndex() { time_t now = time(nullptr); - float indexMultiplier = now >= _lightsOffStartTime ? getIndexMultiplier(now, _lightsOffStartTime, _lightsOffEndTime, true) : getIndexMultiplier(now, _lightsOnStartTime, _lightsOnEndTime, false); + float indexMultiplier = now >= _naturalLight.getAstronomicalTwilightEnd() ? + getIndexMultiplier(now, _naturalLight.getSunset(), _naturalLight.getAstronomicalTwilightEnd(), true) : + getIndexMultiplier(now, _naturalLight.getAstronomicalTwilightBegin(), _naturalLight.getSunrise(), false); return HEAT_INDEX_MAX * indexMultiplier; } @@ -148,7 +103,7 @@ void doLighting() { } EVERY_N_SECONDS(10800){ - parseEvents(); + _naturalLight.update(); } } @@ -181,8 +136,6 @@ void loop() { void mqttCallback(char *topic, byte *payload, unsigned int length) { Serial.print("Got payload: "); for (int i = 0; i < length; i++) - { Serial.print((char)payload[i]); - } Serial.println(); } \ No newline at end of file