SprinklerD/sd_cron.c

336 lines
11 KiB
C
Raw Normal View History

2018-06-16 21:52:48 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
#include <errno.h>
#include "sd_cron.h"
#include "utils.h"
#include "config.h"
#define DELAY24H_SEC 86400
2018-08-11 19:28:18 +00:00
bool setTodayChanceOfRain(int percent)
{
logMessage(LOG_DEBUG, "Set today's chance of rain = %d\n",percent);
if (percent <= 100 && percent >= 0) {
2024-12-14 14:17:00 +00:00
//_sdconfig_.eventToUpdateHappened = true;
setEventRainProbability;
2018-08-11 19:28:18 +00:00
_sdconfig_.todayRainChance = percent;
2018-12-01 13:12:33 +00:00
if (_sdconfig_.precipChanceDelay > 0 && _sdconfig_.todayRainChance >= _sdconfig_.precipChanceDelay) {
//enable_delay24h(true);
2024-12-14 14:17:00 +00:00
reset_delay24h_time(0); // will add 24hours or turn on and set delay to 24hours
} else {
enable_delay24h(false); // Turn off rain delay
2018-12-01 13:12:33 +00:00
}
2018-08-11 19:28:18 +00:00
return true;
}
return false;
}
bool setTodayRainTotal(float rain)
{
2024-12-14 14:17:00 +00:00
if (_sdconfig_.todayRainTotal == rain && rain != 0)
2018-08-20 23:52:36 +00:00
return true;
2024-12-14 14:17:00 +00:00
_sdconfig_.todayRainTotal = rain;
//_sdconfig_.eventToUpdateHappened = true;
setEventRainTotal;
2018-08-20 23:52:36 +00:00
2018-08-11 19:28:18 +00:00
logMessage(LOG_DEBUG, "Today's rain total = %f\n",_sdconfig_.todayRainTotal);
2018-08-20 23:52:36 +00:00
time_t now;
time(&now);
2018-08-11 19:28:18 +00:00
if (_sdconfig_.precipInchDelay2day > 0 && _sdconfig_.todayRainTotal >= _sdconfig_.precipInchDelay2day) {
reset_delay24h_time(now + (DELAY24H_SEC * 2) ); // today + 2 days in seconds
} else if (_sdconfig_.precipInchDelay1day > 0 && _sdconfig_.todayRainTotal >= _sdconfig_.precipInchDelay1day) {
2018-08-20 23:52:36 +00:00
//enable_delay24h(true);
reset_delay24h_time(now + DELAY24H_SEC);
2018-08-11 19:28:18 +00:00
}
return true;
}
2018-06-16 21:52:48 +00:00
bool check_delay24h()
{
2018-06-18 18:54:17 +00:00
if (_sdconfig_.delay24h_time > 0) {
2018-06-16 21:52:48 +00:00
time_t now;
time(&now);
2018-06-18 18:54:17 +00:00
if (difftime(now, _sdconfig_.delay24h_time) > 0) { // 24hours in seconds
2018-06-16 21:52:48 +00:00
enable_delay24h(false);
return true;
}
}
return false;
}
2018-06-22 17:58:28 +00:00
void enable_calendar(bool state)
2018-06-18 18:54:17 +00:00
{
2018-06-22 17:58:28 +00:00
if (_sdconfig_.calendar != state) {
2024-12-14 14:17:00 +00:00
//_sdconfig_.eventToUpdateHappened = true;
setEventStatus;
2018-06-22 17:58:28 +00:00
_sdconfig_.calendar = state;
2018-06-18 18:54:17 +00:00
logMessage(LOG_NOTICE, "Turning %s calendar\n",state==true?"on":"off");
} else {
logMessage(LOG_NOTICE, "Ignore request to turn %s calendar\n",state==true?"on":"off");
}
}
2018-06-16 21:52:48 +00:00
void enable_delay24h(bool state)
{
2018-06-18 18:54:17 +00:00
if (_sdconfig_.delay24h != state) {
2024-12-14 14:17:00 +00:00
//_sdconfig_.eventToUpdateHappened = true;
setEventStatus;
2018-06-18 18:54:17 +00:00
_sdconfig_.delay24h = state;
if (state) {
time(&_sdconfig_.delay24h_time);
_sdconfig_.delay24h_time = _sdconfig_.delay24h_time + DELAY24H_SEC;
logMessage(LOG_NOTICE, "Turning on rain Delay\n");
2018-08-11 19:28:18 +00:00
zc_rain_delay_enabeled();
2018-06-18 18:54:17 +00:00
} else {
_sdconfig_.delay24h_time = 0;
logMessage(LOG_NOTICE, "Turning off rain Delay\n");
}
2018-07-07 22:36:47 +00:00
write_cache();
2018-06-16 21:52:48 +00:00
} else {
2018-06-18 18:54:17 +00:00
logMessage(LOG_NOTICE, "Ignore request to turn %s rain Delay\n",state==true?"on":"off");
2018-06-16 21:52:48 +00:00
}
}
2018-06-22 17:58:28 +00:00
void reset_delay24h_time(unsigned long dtime)
2018-06-21 14:58:45 +00:00
{
if (_sdconfig_.delay24h != true) {
2024-12-14 14:17:00 +00:00
//_sdconfig_.eventToUpdateHappened = true;
setEventStatus;
2018-06-21 14:58:45 +00:00
}
2018-06-22 17:58:28 +00:00
time_t now;
time(&now);
2018-12-01 13:12:33 +00:00
//logMessage(LOG_NOTICE, "Reset rain Delay request %d now %d\n", dtime, now);
2018-06-22 17:58:28 +00:00
if (dtime > now) {
_sdconfig_.delay24h = true;
_sdconfig_.delay24h_time = dtime;
2018-12-01 13:12:33 +00:00
logMessage(LOG_NOTICE, "Reset rain Delay custom time %s\n", ctime(&_sdconfig_.delay24h_time));
2018-08-11 19:28:18 +00:00
zc_rain_delay_enabeled();
2018-06-22 17:58:28 +00:00
} else {
_sdconfig_.delay24h = true;
time(&_sdconfig_.delay24h_time);
_sdconfig_.delay24h_time = _sdconfig_.delay24h_time + DELAY24H_SEC;
2018-12-01 13:12:33 +00:00
logMessage(LOG_NOTICE, "Reset rain Delay to %s\n", ctime(&_sdconfig_.delay24h_time));
2018-08-11 19:28:18 +00:00
zc_rain_delay_enabeled();
2018-06-22 17:58:28 +00:00
}
2018-07-07 22:36:47 +00:00
write_cache();
2018-06-21 14:58:45 +00:00
}
2018-06-16 21:52:48 +00:00
void check_cron() {
2018-06-18 18:54:17 +00:00
if (_sdconfig_.cron_update > 0) {
2018-06-16 21:52:48 +00:00
logMessage(LOG_DEBUG, "Checking if CRON needs to be updated\n");
time_t now;
time(&now);
2018-06-18 18:54:17 +00:00
if (difftime(now, _sdconfig_.cron_update) > TIMEDIFF_CRON_UPDATE) {
2018-06-16 21:52:48 +00:00
logMessage(LOG_INFO, "Updating CRON\n");
write_cron();
2018-06-18 18:54:17 +00:00
_sdconfig_.cron_update = 0;
2018-06-16 21:52:48 +00:00
}
}
}
void write_cron() {
FILE *fp;
int min;
int hour;
int day;
int zone;
2024-12-14 14:17:00 +00:00
int rb4i;
2018-06-16 21:52:48 +00:00
bool fs = remount_root_ro(false);
fp = fopen(CRON_FILE, "w");
if (fp == NULL) {
logMessage(LOG_ERR, "Open file failed '%s'\n", CRON_FILE);
remount_root_ro(true);
//fprintf(stdout, "Open file failed 'sprinkler.cron'\n");
return;
}
2018-06-17 12:40:39 +00:00
fprintf(fp, "#***** AUTO GENERATED DO NOT EDIT *****\n");
2018-06-16 21:52:48 +00:00
for (day=0; day <= 6; day++) {
2018-06-18 18:54:17 +00:00
if (_sdconfig_.cron[day].hour >= 0 && _sdconfig_.cron[day].minute >= 0) {
//length += sprintf(buffer+length, ", \"d%d-starttime\" : \"%.2d:%.2d\" ",day,_sdconfig_.cron[day].hour,_sdconfig_.cron[day].minute);
min = _sdconfig_.cron[day].minute;
hour = _sdconfig_.cron[day].hour;
2021-02-14 16:34:26 +00:00
for (zone=0; zone < _sdconfig_.zones; zone ++) {
2018-06-18 18:54:17 +00:00
if (_sdconfig_.cron[day].zruntimes[zone] > 0) {
2019-07-21 20:17:24 +00:00
fprintf(fp, "%d %d * * %d root /usr/bin/curl -s -o /dev/null 'localhost:%s?type=cron&zone=%d&runtime=%d&state=on'\n",min,hour,day,_sdconfig_.socket_port,zone+1,_sdconfig_.cron[day].zruntimes[zone]);
//fprintf(fp, "%d %d * * %d root /usr/bin/curl -s -o /dev/null 'localhost?type=cron&zone=%d&runtime=%d&state=on'\n",min,hour,day,zone+1,_sdconfig_.cron[day].zruntimes[zone]);
2018-06-18 18:54:17 +00:00
min = min + _sdconfig_.cron[day].zruntimes[zone];
2018-06-16 21:52:48 +00:00
// NSF Check if to incrument hour.
if (min >= 60) {
min = min-60;
hour = hour+1;
}
if (hour >= 24) {
logMessage(LOG_ERR, "DON'T SUPPORT ZONES RUNTIMES GOING INTO NEXT DAY\n");
break;
}
}
}
}
2024-12-14 14:17:00 +00:00
for (rb4i=0; rb4i<_sdconfig_.runBeforeCmds; rb4i++) {
if (_sdconfig_.cron[day].minute < _sdconfig_.runBeforeCmd[rb4i].mins) {
fprintf(fp, "%d %d * * %d root %s\n",
(60 - (_sdconfig_.runBeforeCmd[rb4i].mins - _sdconfig_.cron[day].minute)),
(_sdconfig_.cron[day].hour - 1),
day,
_sdconfig_.runBeforeCmd[rb4i].command);
} else {
fprintf(fp, "%d %d * * %d root %s\n",
(_sdconfig_.cron[day].minute - _sdconfig_.runBeforeCmd[rb4i].mins),
_sdconfig_.cron[day].hour,
day,
_sdconfig_.runBeforeCmd[rb4i].command);
}
}
2018-06-16 21:52:48 +00:00
}
2024-12-14 14:17:00 +00:00
2019-07-21 20:17:24 +00:00
fprintf(fp, "0 0 * * * root /usr/bin/curl -s -o /dev/null 'localhost:%s?type=sensor&sensor=chanceofrain&value=0'\n",_sdconfig_.socket_port);
fprintf(fp, "0 0 * * * root /usr/bin/curl -s -o /dev/null 'localhost:%s?type=sensor&sensor=raintotal&value=0'\n",_sdconfig_.socket_port);
2018-06-17 12:40:39 +00:00
fprintf(fp, "#***** AUTO GENERATED DO NOT EDIT *****\n");
2018-06-16 21:52:48 +00:00
fclose(fp);
remount_root_ro(fs);
}
void read_cron() {
FILE *fp;
//int i;
char *line = NULL;
int rc;
int hour;
int minute;
int day;
int zone;
int runtime;
size_t len = 0;
ssize_t read_size;
regex_t regexCompiled;
//char regexString="([0-9]*) ([0-9]*) \* \* ([0-9]*) .*zone&z([0-9]*).*runtime=([0-9]*).*";
//char *regexString="([0-9]{1,2}) ([0-9]{1,2}) \\* \\* ([0-9]{1,2}) .*zone&z([0-9]{1,2}).*runtime=([0-9]{1,2}).*";
//char *regexString="([0-9]*)\\s([0-9]*)\\s.*\\s([0-9]*)\\s.*zone&z([0-9]*).*runtime=([0-9]*).*$";
//char *regexString="([0-9]*)\\s([0-9]*)\\s.*\\s([0-9]*)\\s.*zone&z([0-9]*).*runtime=([0-9]*).$";
char *regexString="([0-9]{1,2})\\s([0-9]{1,2})\\s.*\\s([0-9]{1,2})\\s.*zone=([0-9]{1,2}).*runtime=([0-9]{1,2}).*$";
size_t maxGroups = 7;
regmatch_t groupArray[maxGroups];
//static char buf[100];
// reset cron config
for (day=0; day <= 6; day++) {
2018-06-18 18:54:17 +00:00
_sdconfig_.cron[day].hour = -1;
_sdconfig_.cron[day].minute = -1;
2024-12-14 14:17:00 +00:00
for (zone=0; zone < _sdconfig_.zones; zone ++) {
2018-06-18 18:54:17 +00:00
_sdconfig_.cron[day].zruntimes[zone] = 0;
2018-06-16 21:52:48 +00:00
}
}
if (0 != (rc = regcomp(&regexCompiled, regexString, REG_EXTENDED))) {
//printf("regcomp() failed, returning nonzero (%d)\n", rc);
logMessage(LOG_ERR, "regcomp() failed, returning nonzero (%d)\n", rc);
return;
//exit(EXIT_FAILURE);
}
fp = fopen(CRON_FILE, "r");
if (fp == NULL) {
logMessage(LOG_ERR, "Open file failed '%s'\n", CRON_FILE);
//fprintf(stdout, "Open file failed 'sprinkler.cron'\n");
return;
}
while ((read_size = getline(&line, &len, fp)) != -1) {
//printf("Read from cron:-\n %s", line);
//lc++;
//rc = regexec(&regexCompiled, line, maxGroups, groupArray, 0);
if (0 == (rc = regexec(&regexCompiled, line, maxGroups, groupArray, REG_EXTENDED))) {
// Group 1 is minute
// Group 2 is hour
// Group 3 is day of week
// Group 4 is zone
// Group 5 is runtime
if (groupArray[2].rm_so == (size_t)-1) {
logMessage(LOG_ERR, "No matching information from cron file\n");
} else {
minute = str2int((line + groupArray[1].rm_so), (groupArray[1].rm_eo - groupArray[1].rm_so));
hour = str2int((line + groupArray[2].rm_so), (groupArray[2].rm_eo - groupArray[2].rm_so));
day = str2int((line + groupArray[3].rm_so), (groupArray[3].rm_eo - groupArray[3].rm_so));
zone = str2int((line + groupArray[4].rm_so), (groupArray[4].rm_eo - groupArray[4].rm_so));
runtime = str2int((line + groupArray[5].rm_so), (groupArray[5].rm_eo - groupArray[5].rm_so));
logMessage(LOG_DEBUG, "Read from cron Day %d | Time %d:%d | Zone %d | Runtime %d\n",day,hour,minute,zone,runtime);
2018-06-18 18:54:17 +00:00
if (day < 7 && zone <= _sdconfig_.zones) {
if (_sdconfig_.cron[day].hour == -1) { // Only get the first starttime
_sdconfig_.cron[day].hour = hour;
_sdconfig_.cron[day].minute = minute;
2018-06-16 21:52:48 +00:00
}
2018-06-18 18:54:17 +00:00
_sdconfig_.cron[day].zruntimes[zone-1] = runtime;
2018-06-16 21:52:48 +00:00
}
}
} else {
logMessage(LOG_DEBUG, "regexp no match (%d)\n", rc);
}
}
/*
for (day=0; day <= 6; day++) {
2018-06-18 18:54:17 +00:00
logMessage(LOG_DEBUG, "DAY %d Start time %d:%d\n",day,_sdconfig_.cron[day].hour,_sdconfig_.cron[day].minute);
for (zone=0; zone < _sdconfig_.zones; zone ++) {
logMessage(LOG_DEBUG, "DAY %d zone %d runtime %d\n",day,zone+1,_sdconfig_.cron[day].zruntimes[zone]);
2018-06-16 21:52:48 +00:00
}
}
*/
fclose(fp);
}
/*
void write_cache(struct arconfig *ar_prms) {
FILE *fp;
fp = fopen(ar_prms->cache_file, "w");
if (fp == NULL) {
logMessage(LOG_ERR, "Open file failed '%s'\n", ar_prms->cache_file);
return;
}
fprintf(fp, "%d\n", ar_prms->Percent);
fprintf(fp, "%d\n", ar_prms->PPM);
fclose(fp);
}
void read_cache(struct arconfig *ar_prms) {
FILE *fp;
int i;
fp = fopen(ar_prms->cache_file, "r");
if (fp == NULL) {
logMessage(LOG_ERR, "Open file failed '%s'\n", ar_prms->cache_file);
return;
}
fscanf (fp, "%d", &i);
logMessage(LOG_DEBUG, "Read Percent '%d' from cache\n", i);
if (i > -1 && i< 102)
ar_prms->Percent = i;
fscanf (fp, "%d", &i);
logMessage(LOG_DEBUG, "Read PPM '%d' from cache\n", i);
if (i > -1 && i< 5000)
ar_prms->PPM = i;
fclose (fp);
}
2018-06-18 18:54:17 +00:00
*/