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

DS_CAP_WEB_TIMERS — Timer Configuration at Run-time

Description

This capability adds support for timers that can be configured by user via provided web interface. Supported timer types are all based on absolute time, hence, notion of time is required on controller. They include absolute timers (fire at specific time of a day), solar timers (fire at sunrise or sunset), and countdown timers (fire periodically).

The configuration page is served using /timers path. The figure below shows timers of each type offered for configuration.

Web Timers

Timers can be turned off at once with a global switch; each timer can be also turned off individually. For each timer one or more days of week could be selected. Deselecting all days of week effectively disables the timer. Because user-configured timers usually concern relatively slow events, timer accuracy made available for configuration is one minute.

Supported fields:

Field Description Default Value
std::forward_list System::timer_actions List of supported timer actions (empty)

Supported actions ("execute ...") must be pre-configured by programmer, and the installed timer handler must recognize these actions (see Usage below).

The list of actions is implemented as a forward list. To add an action to the list, use std::forward_list methods, such as System::timer_actions.push_front("lamp on"). If you want actions to be presented in the order of addition, call System::timer_actions.reverse() after filling the list.

Because of supported timer types, in addition to regular macros, programmer is required to specify additional information in MySystem.h: time zone for absolute timers and geographical location for solar timers.

If file system is enabled, timers' configuration is automatically saved on flash, so they survive cold restarts. File name is /ds/timers1.cfg, where 1 represents the current file format version.

Timer configuration page relies on a consequent piece of JavaScript coding (see Bugs below). To decrease memory consumption when serving such a page, the JavaScript is provided in compressed form. The compressor used is JavaScript Minifier. If you need to change the code for some reason, do not edit the compressed code, but rather turn to the master copy contained in timers.html and regenerate the code. A script js2cpp.py should be used to compress the JavaScript code, to be run as follows:

$ ./js2cpp.py timers.html

Requires

Cooperates With

  • DS_CAP_SYS_LOG — if syslog is enabled, timer reconfiguration action will be logged. Also, number of configured timers will be reported on boot
  • DS_CAP_APP_LOG — if application log is enabled, timer reconfiguration action will be logged
  • DS_CAP_SYS_FS — if file system is enabled, timer configuration will be saved on flash drive

Conflicts With

None.

Usage

MySystem.h:

#define DS_CAP_SYS_TIME          // Enable system time (needed for absolute timers)
#define DS_CAP_SYS_NETWORK       // Enable network (needed for web server)
#define DS_CAP_TIMERS_ABS        // Enable timers from absolute time
#define DS_CAP_TIMERS_SOLAR      // Enable timers from solar events
#define DS_CAP_TIMERS_COUNT_ABS  // Enable countdown timers via absolute time
#define DS_CAP_WEBSERVER         // Enable web server
#define DS_CAP_WEB_TIMERS        // Enable timer configuration via web
#define DS_CAP_SYS_FS            // Enable file system (where timer configuration is stored)

#define DS_TIMEZONE TZ_Europe_Paris       // My timezone
#define DS_LATITUDE 48.85863              // My latitude (needed for solar timers)
#define DS_LONGITUDE 2.29443              // My longitude (needed for solar timers)

#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
    // ...
  } // else ...
}
void (*System::timerHandler)(const TimerAbsolute*) = myTimerHandler;  // Install the handler

void setup() {
  System::begin();

  // Register some timer actions (used for action drop-down selector on the web)
  System::timer_actions.push_front("lamp on");
}

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

Mandatory Calls

System::begin() Required
System::update() Required

Examples

Bugs

  • Because the timer configuration page includes a large piece of a JavaScript code, its size is significantly larger (typically around 4 kiB) than what's provided by default by the web server capability (2 kiB). This is not an issue per se unless you are short on memory for sketch-specific reasons. The alternative would be to serve the JavaScript portion from flash drive, but this would complicate controller programming and introduce hard dependency on file system;
  • The configuration page resets all timers on "save", even if their configuration has not changed. This means that ongoing timer actions could experience jumps when configuration is updated;
  • It is possible to use Unicode icons in actions, but due to mixed JavaScript / C++ environment one needs to be careful when passing them around. In actions they should passed as escaped UTF-16 to reach JavaScript layer correctly, whereas in the handler they should be compared as UTF-8 strings. See Examples for details.

Availability

Version 1.1 or later.

See Also

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