DS_CAP_TIMERS_SOLAR - denis-stepanov/esp-ds-system GitHub Wiki

DS_CAP_TIMERS_SOLAR — Support for Timer on Solar Events

Description

This capability adds support for timers based on solar events — sunrise or sunset. Because timing of these events changes every day, it is not easy to make a timer event for them. This type of timer offers standard timer interface for such events.

The timer is implemented as a variant of an absolute timer, hence, it requires that a notion of time is enabled in controller.

The following methods, complementary to the generic timer methods, are available:

TimerSolar::TimerSolar(const String action = "undefined", const timer_type_t type = TIMER_SUNRISE,
  const int8_t offset = 0, const uint8_t dow = TIMER_DOW_ANY, const bool armed = true,
  const bool recurrent = true, const bool transient = false, const int id = -1);  // Constructor
int8_t TimerSolar::getOffset() const;                  // Return offset in minutes from event
void TimerSolar::setOffset(const int8_t offset );      // Set offset in minutes from event
void TimerSolar::adjust();                             // Recalculate alignment to solar times

One can also compare solar timers among themselves and with a struct tm value containing absolute time.

Timer type can be one of TIMER_SUNRISE (default) or TIMER_SUNSET. offset defines optional offset in minutes within one hour from the solar event (e.g., "5 minutes before sunset"). Methods getOffset() and setOffset() allow changing the offset at run-time. If timer is modified at run-time, a function adjust() should be called. It should also be called if system time jumps significantly (e.g., another date is set, which will affect effective times of solar events). The library will automatically recalculate solar events every night at 3:30 am, or as soon as 24 hours from the previous calculation have elapsed.

The rest of the timer methods are the same as for an absolute timer.

Solar event time calculation is assured by an external library, Dusk2Dawn. This is a mathematical calculation based on controller's geographical location; no external database is consulted. Accuracy of calculation is pretty decent and differs from an actual sunrise or sunset by no more than few minutes. In order to enable calculation, the following information must be provided in MySystem.h:

#define DS_TIMEZONE TZ_Europe_Paris       // Controller timezone
#define DS_LATITUDE 48.85863              // Controller latitude (in decimal notation)
#define DS_LONGITUDE 2.29443              // Controller longitude (in decimal notation)

If these are not defined, the library will issue a warning and default time zone to UTC and geographical location to Greenwich. You can obtain your coordinates from any navigation software, such as Google Maps. It is not required to specify your precise location — one comma after a digit (meaning a few kilometers precision) is enough for the library to work correctly. For details of time zone definition refer to time capability.

Even though time resolution of an absolute timer is one second, time resolution of a solar timer is one minute. This is linked to a relatively low accuracy needed in defining of solar events. The getSecond() method of a solar timer would typically return 0.

Since a solar timer is also an absolute timer, its registration and processing is made in the same way; consult the absolute timer page for more details.

When solar timer capability is enabled, the following additional ds::System methods are made available:

uint16_t System::getSunrise();       // Return sunrise time (in minutes from midnight)
uint16_t System::getSunset();        // Return sunset time (in minutes from midnight)

Requires

Cooperates With

  • DS_CAP_SYS_LOG — if syslog is enabled, timer firing event, as well as time recalculation event, will be logged;
  • DS_CAP_APP_LOG — if application log is enabled, timer firing event will be logged;
  • DS_CAP_WEB_TIMERS — if timer configuration by user is enabled, solar timers will be offered as an option;
  • DS_CAP_WEBSERVER — if web server is enabled, calculated sunrise and sunset times, as well as controller coordinates, will be displayed in its System Information page.

Conflicts With

None.

Usage

MySystem.h:

#define DS_CAP_SYS_TIME     // Enable system time
#define DS_CAP_TIMERS_SOLAR // Enable timers from solar events

#define DS_TIMEZONE TZ_Europe_Paris       // My timezone
#define DS_LATITUDE 48.85863              // My latitude
#define DS_LONGITUDE 2.29443              // My longitude

#include "System.h"         // System global definitions

sketch.ino:

#include "MySystem.h"

using namespace ds;

// Timer handler
void myTimerHandler(const TimerAbsolute* timer) {
  if (timer->getAction() == "lamp on") {

    // Turn the lamp on here ...
  }
}
void (*System::timerHandler)(const TimerAbsolute*) = myTimerHandler;  // Install the handler

void setup() {

  // Turn on the lamp every day five minutes before sunset
  System::timers.push_front(new TimerSolar("lamp on", TIMER_SUNSET, -5));  
}

void loop() {
  System::update();
}

Mandatory Calls

System::begin() Not required
System::update() Required

Examples

Bugs

  • Timer calculation might not work properly if solar event is happening shortly past midnight. Since it is something unlikely in real life, no specific fix is currently planned.
  • The library has no means to check consistency between specified time zone and geographical coordinates. If they are in disagreement (e.g., a Paris time zone specified for Greenwich location), the timer will fire at a wrong time.

Availability

Version 1.1 or later.

Solar times and coordinates display on web server's "System Information" page is available from version 1.2.

See Also

⚠️ **GitHub.com Fallback** ⚠️