MeterLogger
Functions | Variables
cron.c File Reference
#include <esp8266.h>
#include <time.h>
#include "unix_time.h"
#include "ac/ac_out.h"
#include "cron/cron.h"
#include "config.h"
Include dependency graph for cron.c:

Go to the source code of this file.

Functions

ICACHE_FLASH_ATTR static void minute_timer_func (void *arg)
 
ICACHE_FLASH_ATTR void cron_init ()
 
ICACHE_FLASH_ATTR unsigned int add_cron_job_from_query (char *query)
 
ICACHE_FLASH_ATTR void clear_cron_jobs ()
 

Variables

static os_timer_t minute_timer
 
char sec_drift
 

Function Documentation

◆ add_cron_job_from_query()

ICACHE_FLASH_ATTR unsigned int add_cron_job_from_query ( char *  query)

Definition at line 226 of file cron.c.

References cfg_save_defered(), COMMAND_L, CRON_FIELD_L, cron_jobs_t::cron_job_list, syscfg_t::cron_jobs, CRON_JOBS_MAX, ICACHE_FLASH_ATTR, key, KEY_VALUE_L, memset, cron_jobs_t::n, NULL, os_printf, strncmp, strncpy, and sys_cfg.

226  {
227  char *str;
228  char *key, *value;
229  char key_value[KEY_VALUE_L];
230  char *context_query_string, *context_key_value;
231 
232  if (sys_cfg.cron_jobs.n <= CRON_JOBS_MAX - 1) { // if there are room for more cron jobs
233  // parse mqtt message for query string
235  str = strtok_r(query, "&", &context_query_string);
236  while (str != NULL) {
237  strncpy(key_value, str, KEY_VALUE_L);
238  key = strtok_r(key_value, "=", &context_key_value);
239  value = strtok_r(NULL, "=", &context_key_value);
240  if (strncmp(key, "minute", KEY_VALUE_L) == 0) {
242  }
243  else if (strncmp(key, "hour", KEY_VALUE_L) == 0) {
245  }
246  else if (strncmp(key, "day_of_month", KEY_VALUE_L) == 0) {
248  }
249  else if (strncmp(key, "month", KEY_VALUE_L) == 0) {
251  }
252  else if (strncmp(key, "day_of_week", KEY_VALUE_L) == 0) {
254  }
255  else if (strncmp(key, "command", COMMAND_L) == 0) {
257 #ifdef DEBUG
258  os_printf("job #%d added\n\r", sys_cfg.cron_jobs.n);
259 #endif
260  sys_cfg.cron_jobs.n++;
261  }
262 
263  str = strtok_r(NULL, "&", &context_query_string);
264  }
265  // save it to flash
267  }
268 
269  return sys_cfg.cron_jobs.n;
270 }
cron_jobs_t cron_jobs
Definition: config.h:63
#define memset(x, a, b)
Definition: platform.h:21
#define KEY_VALUE_L
Definition: cron.h:4
#define NULL
Definition: def.h:47
#define COMMAND_L
Definition: cron.h:5
#define os_printf
Definition: osapi.h:62
void ICACHE_FLASH_ATTR cfg_save_defered()
Definition: config.c:144
unsigned char n
Definition: cron.h:29
cron_job_list_t cron_job_list
Definition: cron.h:30
#define strncmp(a, b, c)
Definition: platform.h:18
#define CRON_FIELD_L
Definition: cron.h:8
#define strncpy(a, b, c)
Definition: platform.h:16
static const char key[]
Definition: config.h:42
syscfg_t sys_cfg
Definition: config.c:12
#define CRON_JOBS_MAX
Definition: cron.h:7
Here is the call graph for this function:

◆ clear_cron_jobs()

ICACHE_FLASH_ATTR void clear_cron_jobs ( )

Definition at line 273 of file cron.c.

References cfg_save_defered(), syscfg_t::cron_jobs, memset, os_printf, and sys_cfg.

273  {
274 #ifdef DEBUG
275  //debug_cron_jobs();
276 #endif
277  memset(&sys_cfg.cron_jobs, 0, sizeof(cron_job_t));
278 
279  // save it to flash
281 #ifdef DEBUG
282  os_printf("\n\rcleared all jobs\n\r");
283 #endif
284 }
cron_jobs_t cron_jobs
Definition: config.h:63
#define memset(x, a, b)
Definition: platform.h:21
#define os_printf
Definition: osapi.h:62
void ICACHE_FLASH_ATTR cfg_save_defered()
Definition: config.c:144
syscfg_t sys_cfg
Definition: config.c:12
Here is the call graph for this function:

◆ cron_init()

ICACHE_FLASH_ATTR void cron_init ( )

Definition at line 212 of file cron.c.

References syscfg_t::cron_jobs, ICACHE_FLASH_ATTR, minute_timer, minute_timer_func(), cron_jobs_t::n, NULL, os_printf, os_timer_arm, os_timer_disarm, os_timer_func_t, os_timer_setfn, and sys_cfg.

212  {
213  //memset(&sys_cfg.cron_jobs, 0, sizeof(cron_job_t));
214 
215  // check if there are any cron jobs to run every minute
218  os_timer_arm(&minute_timer, 60000, 1);
219 
220 #ifdef DEBUG
221  os_printf("\n\rcron jobs: %d\n\r", sys_cfg.cron_jobs.n);
222 #endif
223 }
cron_jobs_t cron_jobs
Definition: config.h:63
ICACHE_FLASH_ATTR static void minute_timer_func(void *arg)
Definition: cron.c:13
#define os_timer_disarm
Definition: osapi.h:51
#define NULL
Definition: def.h:47
#define os_timer_func_t
Definition: os_type.h:35
#define os_printf
Definition: osapi.h:62
#define os_timer_setfn
Definition: osapi.h:52
unsigned char n
Definition: cron.h:29
#define os_timer_arm(a, b, c)
Definition: osapi.h:50
static os_timer_t minute_timer
Definition: cron.c:9
syscfg_t sys_cfg
Definition: config.c:12
Here is the call graph for this function:

◆ minute_timer_func()

ICACHE_FLASH_ATTR static void minute_timer_func ( void *  arg)
static

Definition at line 13 of file cron.c.

References ac_off(), ac_test(), ac_thermo_close(), ac_thermo_open(), COMMAND_L, CRON_FIELD_L, cron_jobs_t::cron_job_list, syscfg_t::cron_jobs, get_unix_time(), ICACHE_FLASH_ATTR, minute_timer, cron_jobs_t::n, NULL, os_printf, os_timer_arm, os_timer_disarm, os_timer_func_t, os_timer_setfn, sec_drift, strncmp, and sys_cfg.

Referenced by cron_init().

13  {
14  struct tm *dt;
15  time_t unix_time;
16  unsigned char i;
17  unsigned char run_command;
18 
19  bool dst = false;
20  int previous_sunday;
21  int s;
22 
23  unix_time = get_unix_time() + (1 * 60 * 60); // UTC + 1
24  dt = gmtime(&unix_time);
25 
26  // compensate for daylight savings in Europe/Copenhagen
27  // thanx to Richard A Burton
28  // https://github.com/raburton/esp8266/blob/master/ntp/timezone.c
29  if (dt->tm_mon < 2 || dt->tm_mon > 9) {
30  // these months are completely out of DST
31  }
32  else if (dt->tm_mon > 2 && dt->tm_mon < 9) {
33  // these months are completely in DST
34  dst = true;
35  }
36  else {
37  // else we must be in one of the change months
38  // work out when the last sunday was (could be today)
39  previous_sunday = dt->tm_mday - dt->tm_wday;
40  if (dt->tm_mon == 2) { // march
41  // was last sunday (which could be today) the last sunday in march
42  if (previous_sunday >= 25) {
43  // are we actually on the last sunday today
44  if (dt->tm_wday == 0) {
45  // if so are we at/past 2am gmt
46  s = (dt->tm_hour * 3600) + (dt->tm_min * 60) + dt->tm_sec;
47  if (s >= 7200) {
48  dst = true;
49  }
50  } else {
51  dst = true;
52  }
53  }
54  }
55  else if (dt->tm_mon == 9) {
56  // was last sunday (which could be today) the last sunday in october
57  if (previous_sunday >= 25) {
58  // we have reached/passed it, so is it today?
59  if (dt->tm_wday == 0) {
60  // change day, so are we before 1am gmt (2am localtime)
61  s = (dt->tm_hour * 3600) + (dt->tm_min * 60) + dt->tm_sec;
62  if (s < 3600) {
63  dst = true;
64  }
65  }
66  }
67  else {
68  // not reached the last sunday yet
69  dst = true;
70  }
71  }
72  }
73 
74  if (dst) {
75  // add the dst hour
76  unix_time += (1 * 60 * 60);
77  // call gmtime on changed value
78  dt = gmtime(&unix_time);
79  // don't rely on isdst returned by mktime, it doesn't know about timezones and tends to reset this to 0
80  dt->tm_isdst = 1;
81 #ifdef DEBUG
82  os_printf("UTC+1 DST+1: ");
83 #endif
84  }
85  else {
86  dt->tm_isdst = 0;
87 #ifdef DEBUG
88  os_printf("UTC+1: ");
89 #endif
90  }
91 #ifdef DEBUG
92  os_printf("%02d:%02d:%02d %d.%d.%d\r\n", dt->tm_hour, dt->tm_min, dt->tm_sec, dt->tm_mday, dt->tm_mon + 1, dt->tm_year + 1900);
93 #endif
94 
95  // sync to ntp time
96  if (dt->tm_sec == 0) {
97  if (sec_drift) {
98  // we have run the timer with sec_drift interval, run it at normal interval again
101  os_timer_arm(&minute_timer, 60000, 1);
102  sec_drift = 0;
103 #ifdef DEBUG
104  //os_printf("normal\n\r");
105 #endif
106  }
107  }
108  else {
109  sec_drift = (60 - dt->tm_sec);
112  os_timer_arm(&minute_timer, (sec_drift * 1000), 0);
113 #ifdef DEBUG
114  //os_printf("adjusting by %d s\n\r", sec_drift);
115 #endif
116  }
117 
118  // check if any jobs should have run the last minute
119  for (i = 0; i < sys_cfg.cron_jobs.n; i++) {
120  run_command = 0;
121 #ifdef DEBUG
122  /*
123  os_printf("j: %u\t%s:%s\t%s\t %s\t%s\tc: %s\n\r",
124  i,
125  sys_cfg.cron_jobs.cron_job_list[i].hour,
126  sys_cfg.cron_jobs.cron_job_list[i].minute,
127  sys_cfg.cron_jobs.cron_job_list[i].day_of_month,
128  sys_cfg.cron_jobs.cron_job_list[i].month,
129  sys_cfg.cron_jobs.cron_job_list[i].day_of_week,
130  sys_cfg.cron_jobs.cron_job_list[i].command);
131  */
132 #endif
133  // check cron jobs hour value
134  if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].hour, "*", CRON_FIELD_L) == 0) {
135  run_command++;
136  }
137  else if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].hour, "", CRON_FIELD_L) == 0) {
138  run_command++;
139  }
140  else if (dt->tm_hour == atoi(sys_cfg.cron_jobs.cron_job_list[i].hour)) {
141  run_command++;
142  }
143 
144  // check cron jobs minute value
145  if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].minute, "*", CRON_FIELD_L) == 0) {
146  run_command++;
147  }
148  else if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].minute, "", CRON_FIELD_L) == 0) {
149  run_command++;
150  }
151  else if (dt->tm_min == atoi(sys_cfg.cron_jobs.cron_job_list[i].minute)) {
152  run_command++;
153  }
154 
155  // check cron jobs day_of_month value
156  if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].day_of_month, "*", CRON_FIELD_L) == 0) {
157  run_command++;
158  }
159  else if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].day_of_month, "", CRON_FIELD_L) == 0) {
160  run_command++;
161  }
162  else if (dt->tm_mday == atoi(sys_cfg.cron_jobs.cron_job_list[i].day_of_month)) {
163  run_command++;
164  }
165 
166  // check cron jobs month value
167  if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].month, "*", CRON_FIELD_L) == 0) {
168  run_command++;
169  }
170  else if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].month, "", CRON_FIELD_L) == 0) {
171  run_command++;
172  }
173  else if ((dt->tm_mon + 1) == atoi(sys_cfg.cron_jobs.cron_job_list[i].month)) {
174  run_command++;
175  }
176 
177  // check cron jobs day_of_week value
178  if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].day_of_week, "*", CRON_FIELD_L) == 0) {
179  run_command++;
180  }
181  else if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].day_of_week, "", CRON_FIELD_L) == 0) {
182  run_command++;
183  }
184  else if (dt->tm_wday == atoi(sys_cfg.cron_jobs.cron_job_list[i].day_of_week) % 7) { // (0 or 7 is Sun therefore % 7
185  run_command++;
186  }
187 
188  // we need to run the command
189  if (run_command == 5) {
190 #ifdef DEBUG
191  os_printf("run: %s\n\r", sys_cfg.cron_jobs.cron_job_list[i].command);
192 #endif
193  if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].command, "open", COMMAND_L) == 0) {
194  //ac_motor_valve_open();
195  ac_thermo_open();
196  }
197  else if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].command, "close", COMMAND_L) == 0) {
198  //ac_motor_valve_close();
199  ac_thermo_close();
200  }
201  else if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].command, "off", COMMAND_L) == 0) {
202  ac_off();
203  }
204  else if (strncmp(sys_cfg.cron_jobs.cron_job_list[i].command, "test", COMMAND_L) == 0) {
205  ac_test();
206  }
207  }
208  }
209 }
ICACHE_FLASH_ATTR void ac_thermo_close()
Definition: ac_out.c:203
cron_jobs_t cron_jobs
Definition: config.h:63
ICACHE_FLASH_ATTR uint32_t get_unix_time(void)
Definition: unix_time.c:55
ICACHE_FLASH_ATTR static void minute_timer_func(void *arg)
Definition: cron.c:13
#define os_timer_disarm
Definition: osapi.h:51
#define NULL
Definition: def.h:47
#define COMMAND_L
Definition: cron.h:5
#define os_timer_func_t
Definition: os_type.h:35
ICACHE_FLASH_ATTR void ac_thermo_open()
Definition: ac_out.c:173
ICACHE_FLASH_ATTR void ac_off()
Definition: ac_out.c:247
#define os_printf
Definition: osapi.h:62
#define os_timer_setfn
Definition: osapi.h:52
unsigned char n
Definition: cron.h:29
cron_job_list_t cron_job_list
Definition: cron.h:30
#define strncmp(a, b, c)
Definition: platform.h:18
#define CRON_FIELD_L
Definition: cron.h:8
#define os_timer_arm(a, b, c)
Definition: osapi.h:50
static os_timer_t minute_timer
Definition: cron.c:9
char sec_drift
Definition: cron.c:10
ICACHE_FLASH_ATTR void ac_test()
Definition: ac_out.c:115
syscfg_t sys_cfg
Definition: config.c:12
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ minute_timer

os_timer_t minute_timer
static

Definition at line 9 of file cron.c.

Referenced by cron_init(), and minute_timer_func().

◆ sec_drift

char sec_drift

Definition at line 10 of file cron.c.

Referenced by minute_timer_func().