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(®exCompiled, 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(®exCompiled, line, maxGroups, groupArray, 0);
|
|
|
|
if (0 == (rc = regexec(®exCompiled, 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
|
|
|
*/
|