Skip to content

Commit

Permalink
Update 2.5.1 dev
Browse files Browse the repository at this point in the history
  • Loading branch information
sfeakes committed Dec 6, 2024
1 parent 3608f9f commit 765339a
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 31 deletions.
Binary file removed release/aqualinkd-amd64
Binary file not shown.
Binary file modified release/aqualinkd-arm64
Binary file not shown.
Binary file modified release/aqualinkd-armhf
Binary file not shown.
4 changes: 3 additions & 1 deletion release/aqualinkd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ enable_scheduler = yes

# Check if button_01 (usually Pump) is scheduled to run after an event that may have turned it off, and set it to run.
# Only for RS panels, Will not work for PDA panles.
# Example below is if pump is off due to power reset, freezeprotect/swg boots turned off between 6am and 11pm turn the pump on.
# Example below is if pump is off due to power reset, freezeprotect or swg boots is turned off between 6am and 11pm then turn the pump on.
# You can leave scheduler_check_pumpon_hour & scheduler_check_pumpoff_hour commented out and AqualinkD will try to find the hours from the actual schedule
# that's been set in scheduler. This only works if you have the same schedule for every day of the week.
#scheduler_check_pumpon_hour = 6
#scheduler_check_pumpoff_hour = 23
#scheduler_check_poweron = yes
Expand Down
Binary file removed release/serial_logger-amd64
Binary file not shown.
Binary file modified release/serial_logger-arm64
Binary file not shown.
Binary file modified release/serial_logger-armhf
Binary file not shown.
6 changes: 3 additions & 3 deletions source/allbutton.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
if ((msg_loop & MSG_FREEZE) != MSG_FREEZE) {
if (aq_data->frz_protect_state != default_frz_protect_state) {
LOG(ALLB_LOG,LOG_INFO, "Freeze protect turned off\n");
event_happened_set_device_state(FREEZE_PROTECT_OFF, aq_data);
event_happened_set_device_state(AQS_FRZ_PROTECT_OFF, aq_data);
// Add code to check Pump if to turn it on (was scheduled) ie time now is inbetween ON / OFF schedule
}
aq_data->frz_protect_state = default_frz_protect_state;
Expand Down Expand Up @@ -286,7 +286,7 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
if ((msg_loop & MSG_BOOST) != MSG_BOOST) {
if (aq_data->boost == true) {
LOG(ALLB_LOG,LOG_INFO, "Boost turned off\n");
event_happened_set_device_state(BOOST_OFF, aq_data);
event_happened_set_device_state(AQS_BOOST_OFF, aq_data);
// Add code to check Pump if to turn it on (was scheduled) ie time now is inbetween ON / OFF schedule
}
aq_data->boost = false;
Expand Down Expand Up @@ -515,7 +515,7 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
{
//LOG(ALLBUTTON,LOG_NOTICE, "Standard protocol initialization complete\n");
queueGetProgramData(ALLBUTTON, aq_data);
event_happened_set_device_state(POWER_ON, aq_data);
event_happened_set_device_state(AQS_POWER_ON, aq_data);
//queueGetExtendedProgramData(ALLBUTTON, aq_data, _aqconfig_.use_panel_aux_labels);
_initWithRS = true;
}
Expand Down
79 changes: 62 additions & 17 deletions source/aq_scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ int build_schedules_js(char* buffer, int size)

if ( !_aqconfig_.enable_scheduler) {
LOG(SCHD_LOG,LOG_WARNING, "Schedules are disabled\n");
length += sprintf(buffer, "{\"message\":\"Error Schedules disabled\"}");
if (size > 0)
length += sprintf(buffer, "{\"message\":\"Error Schedules disabled\"}");
return length;
}

Expand All @@ -220,22 +221,26 @@ int build_schedules_js(char* buffer, int size)
regmatch_t groupArray[maxGroups];
//static char buf[100];

length += sprintf(buffer+length,"{\"type\": \"schedules\",");
if (size > 0)
length += sprintf(buffer+length,"{\"type\": \"schedules\",");

if (0 != (rc = regcomp(&regexCompiled, regexString, REG_EXTENDED))) {
LOG(SCHD_LOG,LOG_ERR, "regcomp() failed, returning nonzero (%d)\n", rc);
length += sprintf(buffer+length,"\"message\": \"Error reading schedules\"}");
if (size > 0)
length += sprintf(buffer+length,"\"message\": \"Error reading schedules\"}");
return length;
}

fp = fopen(CRON_FILE, "r");
if (fp == NULL) {
LOG(SCHD_LOG,LOG_WARNING, "Open file failed '%s'\n", CRON_FILE);
length += sprintf(buffer+length,"\"message\": \"Error reading schedules\"}");
if (size > 0)
length += sprintf(buffer+length,"\"message\": \"Error reading schedules\"}");
return length;
}

length += sprintf(buffer+length,"\"schedules\": [ ");
if (size > 0)
length += sprintf(buffer+length,"\"schedules\": [ ");

while ((read_size = getline(&line, &len, fp)) != -1) {
//printf("Read from cron:-\n %s", line);
Expand Down Expand Up @@ -264,7 +269,8 @@ int build_schedules_js(char* buffer, int size)
sprintf(cline.url, "%.*s", (groupArray[9].rm_eo - groupArray[9].rm_so), (line + groupArray[9].rm_so));
sprintf(cline.value, "%.*s", (groupArray[10].rm_eo - groupArray[10].rm_so), (line + groupArray[10].rm_so));
LOG(SCHD_LOG,LOG_INFO, "Read from cron. Enabled:%d Min:%s Hour:%s DayM:%s Month:%s DayW:%s URL:%s Value:%s\n",cline.enabled,cline.minute,cline.hour,cline.daym,cline.month,cline.dayw,cline.url,cline.value);
length += sprintf(buffer+length, "{\"enabled\":\"%d\", \"min\":\"%s\",\"hour\":\"%s\",\"daym\":\"%s\",\"month\":\"%s\",\"dayw\":\"%s\",\"url\":\"%s\",\"value\":\"%s\"},",
if (size > 0) {
length += sprintf(buffer+length, "{\"enabled\":\"%d\", \"min\":\"%s\",\"hour\":\"%s\",\"daym\":\"%s\",\"month\":\"%s\",\"dayw\":\"%s\",\"url\":\"%s\",\"value\":\"%s\"},",
cline.enabled,
cline.minute,
cline.hour,
Expand All @@ -273,27 +279,63 @@ int build_schedules_js(char* buffer, int size)
cline.dayw,
cline.url,
cline.value);
}
//LOG(SCHD_LOG,LOG_DEBUG, "Read from cron Day %d | Time %d:%d | Zone %d | Runtime %d\n",day,hour,minute,zone,runtime);

// Test / get for pump start and end time
if (isAQS_USE_PUMP_TIME_FROM_CRON_ENABLED) {
// Could also check that dayw is *
if ( cline.enabled && strstr(cline.url, AQS_PUMP_URL ))
{
int value = strtoul(cline.value, NULL, 10);
int hour = strtoul(cline.hour, NULL, 10);
if (value == 0) {
if (hour > _aqconfig_.sched_chk_pumpoff_hour) // NSF this picks up the greatest offhour, (do we want the smallest???)
_aqconfig_.sched_chk_pumpoff_hour = hour;
} else if (value == 1){
if (hour < _aqconfig_.sched_chk_pumpon_hour || _aqconfig_.sched_chk_pumpon_hour == 0)
_aqconfig_.sched_chk_pumpon_hour = hour;
}
}
}
}
} else {
LOG(SCHD_LOG,LOG_DEBUG, "regexp no match (%d) %s\n", rc, line);
}
}

buffer[--length] = '\0';
length += sprintf(buffer+length,"]}\n");
if (size > 0) {
buffer[--length] = '\0';
length += sprintf(buffer+length,"]}\n");
}

fclose(fp);
regfree(&regexCompiled);

return length;
}

void get_cron_pump_times()
{
build_schedules_js(NULL, 0);
return;
}


bool event_happened_set_device_state(reset_event_type type, struct aqualinkdata *aq_data)
{
if (! isAQS_START_PUMP_EVENT_ENABLED) {
LOG(SCHD_LOG,LOG_DEBUG, "Event scheduler is not enabled\n");
return false;
}
// Check time is between hours.
bool scheduledOn = false;

if (isAQS_USE_PUMP_TIME_FROM_CRON_ENABLED) {
get_cron_pump_times();
LOG(SCHD_LOG,LOG_DEBUG, "Pump on times from scheduler are between hours %.2d & %.2d\n",_aqconfig_.sched_chk_pumpon_hour, _aqconfig_.sched_chk_pumpoff_hour);
}

time_t now = time(NULL);
struct tm *tm_struct = localtime(&now);

Expand All @@ -304,28 +346,31 @@ bool event_happened_set_device_state(reset_event_type type, struct aqualinkdata

// Check event type.
switch(type){
case POWER_ON:
if (scheduledOn && _aqconfig_.sched_chk_poweron && aq_data->aqbuttons[0].led->state == OFF) {
case AQS_POWER_ON:
if (scheduledOn && isAQS_POWER_ON_ENABED && aq_data->aqbuttons[0].led->state == OFF) {
LOG(SCHD_LOG,LOG_INFO, "Powered on, schedule is set for pump running and pump is off, turning pump on\n");
panel_device_request(aq_data, ON_OFF, 0, true, NET_TIMER);
} else {
LOG(SCHD_LOG,LOG_DEBUG, "Powered on, schedule is not set and/or pump is already on, leaving\n");
//LOG(SCHD_LOG,LOG_DEBUG, "Powered on, schedule is not set and/or pump is already on, leaving\n");
LOG(SCHD_LOG,LOG_DEBUG, "Powered on, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_POWER_ON_ENABED?"":"not "),(scheduledOn?"":" not"), (aq_data->aqbuttons[0].led->state ==OFF?"Off":"On"));
}
break;
case FREEZE_PROTECT_OFF:
if (scheduledOn && _aqconfig_.sched_chk_freezeprotectoff && aq_data->aqbuttons[0].led->state == OFF) {
case AQS_FRZ_PROTECT_OFF:
if (scheduledOn && isAQS_FRZ_PROTECT_OFF_ENABED && aq_data->aqbuttons[0].led->state == OFF) {
LOG(SCHD_LOG,LOG_INFO, "Freeze Protect off, schedule is set for pump running and pump is off, turning pump on\n");
panel_device_request(aq_data, ON_OFF, 0, true, NET_TIMER);
} else {
LOG(SCHD_LOG,LOG_DEBUG, "Freeze Protect off, schedule is not set and/or pump is already on, leaving\n");
//LOG(SCHD_LOG,LOG_DEBUG, "Freeze Protect off, schedule is not set and/or pump is already on, leaving\n");
LOG(SCHD_LOG,LOG_DEBUG, "Freeze Protect off, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_FRZ_PROTECT_OFF_ENABED?"":"not "),(scheduledOn?"":" not"), (aq_data->aqbuttons[0].led->state ==OFF?"Off":"On"));
}
break;
case BOOST_OFF:
if (scheduledOn && _aqconfig_.sched_chk_boostoff && aq_data->aqbuttons[0].led->state == OFF) {
case AQS_BOOST_OFF:
if (scheduledOn && isAQS_BOOST_OFF_ENABED && aq_data->aqbuttons[0].led->state == OFF) {
LOG(SCHD_LOG,LOG_INFO, "Boost off, schedule is set for pump running and pump is off, turning pump on\n");
panel_device_request(aq_data, ON_OFF, 0, true, NET_TIMER);
} else {
LOG(SCHD_LOG,LOG_DEBUG, "Boost off, schedule is not set and/or pump is already on, leaving\n");
//LOG(SCHD_LOG,LOG_DEBUG, "Boost off, schedule is not set and/or pump is already on, leaving\n");
LOG(SCHD_LOG,LOG_DEBUG, "Boost off, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_BOOST_OFF_ENABED?"":"not "),(scheduledOn?"":" not"), (aq_data->aqbuttons[0].led->state ==OFF?"Off":"On"));
}
break;
}
Expand Down
22 changes: 21 additions & 1 deletion source/aq_scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef AQ_SCHEDULER_H_
#define AQ_SCHEDULER_H_

#include "config.h"

#define CRON_FILE "/etc/cron.d/aqualinkd"
#define CURL "curl"
Expand All @@ -26,12 +27,31 @@ typedef struct aqs_cron
int build_schedules_js(char* buffer, int size);
int save_schedules_js(const char* inBuf, int inSize, char* outBuf, int outSize);


#define AQS_PUMP_URL BTN_PUMP "/set"

#define AQS_DONT_USE_CRON_PUMP_TIME (1 << 0)
typedef enum reset_event_type{
AQS_POWER_ON = (1 << 1),
AQS_FRZ_PROTECT_OFF = (1 << 2),
AQS_BOOST_OFF = (1 << 3)
} reset_event_type;

#define isAQS_START_PUMP_EVENT_ENABLED ( ((_aqconfig_.schedule_event_mask & AQS_POWER_ON) == AQS_POWER_ON) || \
((_aqconfig_.schedule_event_mask & AQS_FRZ_PROTECT_OFF) == AQS_FRZ_PROTECT_OFF) || \
((_aqconfig_.schedule_event_mask & AQS_BOOST_OFF) == AQS_BOOST_OFF) )

#define isAQS_USE_PUMP_TIME_FROM_CRON_ENABLED !((_aqconfig_.schedule_event_mask & AQS_DONT_USE_CRON_PUMP_TIME) == AQS_DONT_USE_CRON_PUMP_TIME)
#define isAQS_POWER_ON_ENABED ((_aqconfig_.schedule_event_mask & AQS_POWER_ON) == AQS_POWER_ON)
#define isAQS_FRZ_PROTECT_OFF_ENABED ((_aqconfig_.schedule_event_mask & AQS_FRZ_PROTECT_OFF) == AQS_FRZ_PROTECT_OFF)
#define isAQS_BOOST_OFF_ENABED ((_aqconfig_.schedule_event_mask & AQS_BOOST_OFF) == AQS_BOOST_OFF)
/*
typedef enum reset_event_type{
POWER_ON,
FREEZE_PROTECT_OFF,
BOOST_OFF
} reset_event_type;

*/
bool event_happened_set_device_state(reset_event_type type, struct aqualinkdata *aq_data);
//void read_schedules();
//void write_schedules();
Expand Down
22 changes: 16 additions & 6 deletions source/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "aqualink.h"
#include "iaqualink.h"
#include "color_lights.h"
#include "aq_scheduler.h"

#define MAXCFGLINE 256

Expand Down Expand Up @@ -156,9 +157,10 @@ void init_parameters (struct aqconfig * parms)

parms->enable_scheduler = true;

parms->sched_chk_poweron = false;
parms->sched_chk_freezeprotectoff = false;
parms->sched_chk_boostoff = false;
parms->schedule_event_mask = 0;
//parms->sched_chk_poweron = false;
//parms->sched_chk_freezeprotectoff = false;
//parms->sched_chk_boostoff = false;
parms->sched_chk_pumpon_hour = 0;
parms->sched_chk_pumpoff_hour = 0;

Expand Down Expand Up @@ -690,19 +692,27 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
_aqconfig_.enable_scheduler = text2bool(value);
rtn=true;
} else if (strncasecmp (param, "scheduler_check_poweron", 23) == 0) {
_aqconfig_.sched_chk_poweron = text2bool(value);
if (text2bool(value)) {
_aqconfig_.schedule_event_mask |= AQS_POWER_ON;
}
rtn=true;
} else if (strncasecmp (param, "scheduler_check_freezeprotectoff", 32) == 0) {
_aqconfig_.sched_chk_freezeprotectoff = text2bool(value);
if (text2bool(value)) {
_aqconfig_.schedule_event_mask |= AQS_FRZ_PROTECT_OFF;
}
rtn=true;
} else if (strncasecmp (param, "scheduler_check_boostoff", 24) == 0) {
_aqconfig_.sched_chk_boostoff = text2bool(value);
if (text2bool(value)) {
_aqconfig_.schedule_event_mask |= AQS_BOOST_OFF;
}
rtn=true;
} else if (strncasecmp (param, "scheduler_check_pumpon_hour", 27) == 0) {
_aqconfig_.sched_chk_pumpon_hour = strtoul(value, NULL, 10);
_aqconfig_.schedule_event_mask |= AQS_DONT_USE_CRON_PUMP_TIME;
rtn=true;
} else if (strncasecmp (param, "scheduler_check_pumpoff_hour", 28) == 0) {
_aqconfig_.sched_chk_pumpoff_hour = strtoul(value, NULL, 10);
_aqconfig_.schedule_event_mask |= AQS_DONT_USE_CRON_PUMP_TIME;
rtn=true;
} else if (strncasecmp (param, "ftdi_low_latency", 16) == 0) {
_aqconfig_.ftdi_low_latency = text2bool(value);
Expand Down
7 changes: 4 additions & 3 deletions source/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,10 @@ struct aqconfig
bool mqtt_timed_update;
bool sync_panel_time;
bool enable_scheduler;
bool sched_chk_poweron;
bool sched_chk_freezeprotectoff;
bool sched_chk_boostoff;
int16_t schedule_event_mask;
//bool sched_chk_poweron;
//bool sched_chk_freezeprotectoff;
//bool sched_chk_boostoff;
int sched_chk_pumpon_hour;
int sched_chk_pumpoff_hour;
bool ftdi_low_latency;
Expand Down

0 comments on commit 765339a

Please sign in to comment.