From 23284d6166ad03e1d0f42ecd403438da3d4c99db Mon Sep 17 00:00:00 2001 From: Lee Ballard Date: Wed, 25 Sep 2019 12:31:53 -0500 Subject: [PATCH] ballle98/AqualinkD#13: add time sync --- aq_programmer.c | 2 +- aqualinkd.c | 16 ++-- pda.c | 10 ++- pda_aq_programmer.c | 175 ++++++++++---------------------------------- pda_menu.c | 12 ++- 5 files changed, 65 insertions(+), 150 deletions(-) diff --git a/aq_programmer.c b/aq_programmer.c index ac6cd45c..0207da1f 100644 --- a/aq_programmer.c +++ b/aq_programmer.c @@ -2228,7 +2228,7 @@ bool send_cmd(unsigned char cmd) } } if (ret) { - LOG(PROG_LOG, LOG_INFO, "sent '0x%02hhx' to controller\n", _pgm_command); + LOG(PROG_LOG, LOG_INFO, "sent '0x%02hhx' to controller\n", cmd); } pthread_mutex_unlock(&_pgm_command_mutex); return ret; diff --git a/aqualinkd.c b/aqualinkd.c index 315bbb3f..398544e2 100644 --- a/aqualinkd.c +++ b/aqualinkd.c @@ -128,7 +128,7 @@ void processLEDstate() bool checkAqualinkTime() { - static time_t last_checked; + static time_t last_checked = 0; time_t now = time(0); // get time now int time_difference; struct tm aq_tm; @@ -156,9 +156,9 @@ bool checkAqualinkTime() // date is simply a day or week for PDA. localtime_r(&now, &aq_tm); int real_wday = aq_tm.tm_wday; // NSF Need to do this better, we could be off by 7 days - snprintf(datestr, DATE_STRING_LEN, "%s %s",_aqualink_data.date,_aqualink_data.time); + snprintf(datestr, DATE_STRING_LEN, "%.12s %.8s",_aqualink_data.date,_aqualink_data.time); - if (strptime(datestr, "%A %I:%M%p", &aq_tm) == NULL) { + if (strptime(datestr, "%a %I:%M%p", &aq_tm) == NULL) { LOG(AQUA_LOG,LOG_ERR, "Could not convert PDA RS time string '%s'", datestr); last_checked = (time_t)NULL; return true; @@ -197,23 +197,23 @@ bool checkAqualinkTime() aq_tm.tm_isdst = localtime(&now)->tm_isdst; // ( Might need to use -1) set daylight savings to same as system time aq_tm.tm_sec = 0; // Set seconds to time. Really messes up when we don't do this. - char buff[20]; + char buff[30]; LOG(AQUA_LOG,LOG_DEBUG, "Aqualinkd created time from : %s\n", datestr); - strftime(buff, 20, "%Y-%m-%d %H:%M:%S", &aq_tm); + strftime(buff, 30, "%Y-%m-%d %H:%M:%S %a", &aq_tm); LOG(AQUA_LOG,LOG_DEBUG, "Aqualinkd created time : %s\n", buff); aqualink_time = mktime(&aq_tm); - strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&aqualink_time)); + strftime(buff, 30, "%Y-%m-%d %H:%M:%S", localtime(&aqualink_time)); LOG(AQUA_LOG,LOG_DEBUG, "Aqualinkd converted time : %s\n", buff); - strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&now)); + strftime(buff, 30, "%Y-%m-%d %H:%M:%S", localtime(&now)); LOG(AQUA_LOG,LOG_DEBUG, "System time : %s\n", buff); time_difference = (int)difftime(now, aqualink_time); - strftime(buff, 20, "%m/%d/%y %I:%M %p", localtime(&now)); + strftime(buff, 30, "%m/%d/%y %I:%M %p", localtime(&now)); LOG(AQUA_LOG,LOG_INFO, "Aqualink time '%s' is off system time '%s' by %d seconds...\n", datestr, buff, time_difference); if (abs(time_difference) < ACCEPTABLE_TIME_DIFF) diff --git a/pda.c b/pda.c index 17dd2cd1..d66c7a0d 100644 --- a/pda.c +++ b/pda.c @@ -307,18 +307,20 @@ void process_pda_packet_msg_long_time(const char *msg) // message " SAT 8:46AM " // " SAT 10:29AM" // " SAT 4:23PM " + // " SUN 2:36PM" // printf("TIME = '%.*s'\n",AQ_MSGLEN,msg ); // printf("TIME = '%c'\n",msg[AQ_MSGLEN-1] ); + if (msg[AQ_MSGLEN - 1] == ' ') { - strncpy(_aqualink_data->time, msg + 9, 6); + snprintf(_aqualink_data->time, sizeof(_aqualink_data->time), "%.6s", msg + 9); } else { - strncpy(_aqualink_data->time, msg + 9, 7); + snprintf(_aqualink_data->time, sizeof(_aqualink_data->time), "%.7s", msg + 9); } - strncpy(_aqualink_data->date, msg + 5, 3); - + snprintf(_aqualink_data->date, sizeof(_aqualink_data->date), "%.3s", msg + 5); + if (checkAqualinkTime() != true) { LOG(AQRS_LOG,LOG_NOTICE, "RS time is NOT accurate '%s %s', re-setting on controller!\n", _aqualink_data->time, _aqualink_data->date); diff --git a/pda_aq_programmer.c b/pda_aq_programmer.c index 87186de9..cb528f5a 100644 --- a/pda_aq_programmer.c +++ b/pda_aq_programmer.c @@ -15,13 +15,14 @@ * https://github.com/sfeakes/aqualinkd */ +#define _GNU_SOURCE 1 // for strcasestr & strptime #include #include #include #include #include #include - +#include #include "aqualink.h" #include "utils.h" @@ -35,7 +36,6 @@ #ifdef AQ_DEBUG - #include #include "timespec_subtract.h" #endif @@ -939,21 +939,17 @@ bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aq_data, int v bool set_PDA_aqualink_time(struct aqualinkdata *aq_data) { if (! goto_pda_menu(aq_data, PM_SET_TIME)) { - LOG(PDA_LOG,LOG_ERR, "Error finding freeze protect setpoints menu\n"); + LOG(PDA_LOG,LOG_ERR, "Error finding set time menu\n"); return false; } - - //struct tm *tm; - //time_t now; - //static char result[30]; - //localtime_r(&now, &tm); - //LOG(PDA_LOG,LOG_DEBUG, "set_PDA_aqualink_time %s\n", asctime_r(&tm,result)); - - time_t now = time(0); // get time now - struct tm *tm = localtime(&now); - LOG(PDA_LOG, LOG_DEBUG, "Setting time to %d/%d/%d %d:%d\n", tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900, tm->tm_hour + 1 - tm->tm_isdst, tm->tm_min); - LOG(PDA_LOG, LOG_DEBUG, "Setting time to %s\n", asctime(tm)); - + struct tm tm; + struct tm panel_tm; + time_t now; + char result[30]; + + time(&now); // get time now + localtime_r(&now, &tm); + LOG(PDA_LOG,LOG_DEBUG, "set_PDA_aqualink_time to %s", asctime_r(&tm,result)); /* Debug: PDA: PDA Menu Line 0 = Set Time Debug: PDA: PDA Menu Line 1 = @@ -967,132 +963,41 @@ Debug: PDA: PDA Menu Line 8 = Press SELECT Debug: PDA: PDA Menu Line 9 = to continue. */ - // Crap way to do this, we should use highlight chars, but I don't have enough debug/packet data - // info to code that at present. So just pull from lines. - - - waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHTCHARS,5); - - //int cbuf = 0; - char *line = pda_m_hlight(); - - - // This is a dam mess. Needs to be cleaned up. - - // Basic check for date line. - if (line[4] == '/') { - line = pda_m_hlight(); - // We should use the CMD_PDA_HIGHLIGHTCHARS to check we are on month - - if (! set_PDA_numeric_field_value(aq_data, tm->tm_mon+1, atoi(&line[2]), NULL, 1)) { - LOG(PDA_LOG,LOG_ERR, "Error failed to set month\n"); - } - // No Need to send select, since set_PDA_numeric_field_value does that. - longwaitfor_queue2empty(); - - waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHTCHARS,5); - - //line = pda_m_hlight(); The hlight line jumps down then back up, or we wait for two CMD_PDA_HIGHLIGHTCHARS - if (! set_PDA_numeric_field_value(aq_data, tm->tm_mday, atoi(&line[5]), NULL, 1)) { - LOG(PDA_LOG,LOG_ERR, "Error failed to set day\n"); - } - longwaitfor_queue2empty(); - //send_cmd(KEY_PDA_SELECT); - waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHTCHARS,5); - //line = pda_m_hlight(); - - int year=tm->tm_year - 100; // tm_year is a number relative to 1900. so 100 is 2000 - LOG(PDA_LOG,LOG_DEBUG, "tm year=%d year=%d\n",tm->tm_year,year); - if (! set_PDA_numeric_field_value(aq_data, year, atoi(&line[8]), NULL, 1)) { - LOG(PDA_LOG,LOG_ERR, "Error failed to set year\n"); - } - longwaitfor_queue2empty(); - //send_cmd(KEY_PDA_SELECT); - waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHTCHARS,5); - - //waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHTCHARS,5); - - int cnt=0; - - while ( pda_m_hlightindex() != 3 && line[11] != 'M' ) { - delay(50); - waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,CMD_PDA_CLEAR,1); - line = pda_m_hlight(); - if (cnt++ >= 30) { - LOG(PDA_LOG,LOG_ERR, "Error failed to get to time within date time menu\n"); - break; - } - } - line = pda_m_hlight(); - - int index = 4; - if (line[index] == ' ') // Their is no leading 0 on hour - index++; - - int hour = (tm->tm_hour+1) - tm->tm_isdst; - if (hour > 12) { - hour=hour-12; - // Still need to to AM PM check. - if (line[10] == 'A') { - // Need to change AM/PM - for (int i = 1; i > 12; i++) { - send_cmd(KEY_PDA_DOWN); // Just send 12 down. Can come back and to this better - } - } - } else { - if (line[10] == 'P') { - // Need to change PM/AM - for (int i = 1; i > 12; i++) { - send_cmd(KEY_PDA_DOWN); // Just send 12 down. Can come back and to this better - } - } - } - - if (! set_PDA_numeric_field_value(aq_data, hour, atoi(&line[index]), NULL, 1)) { - LOG(PDA_LOG,LOG_ERR, "Error failed to set hour\n"); - } - - longwaitfor_queue2empty(); - - // See if we have AM / PM correct. - - //send_cmd(KEY_PDA_SELECT); - waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHTCHARS,5); - - if (! set_PDA_numeric_field_value(aq_data, tm->tm_min+1, atoi(&line[7]), NULL, 1)) { - LOG(PDA_LOG,LOG_ERR, "Error failed to set minute\n"); - } - - longwaitfor_queue2empty(); - send_cmd(KEY_PDA_SELECT); - send_cmd(KEY_PDA_BACK); - send_cmd(KEY_PDA_BACK); - - } else { - LOG(PDA_LOG,LOG_ERR, "Error set time failed\n"); - send_cmd(KEY_PDA_BACK); - send_cmd(KEY_PDA_BACK); - return true; + if (strptime(pda_m_line(2), "%t%D %a", &panel_tm) == NULL) { + LOG(PDA_LOG,LOG_ERR, "set_PDA_aqualink_time read date (%.*s) failed\n", + AQ_MSGLEN, pda_m_line(2)); + return false; } + if (strptime(pda_m_line(3), "%t%I:%M %p", &panel_tm) == NULL) { + LOG(PDA_LOG,LOG_ERR, "set_PDA_aqualink_time read time (%.*s) failed\n", + AQ_MSGLEN, pda_m_line(3)); + return false; + } + panel_tm.tm_isdst = tm.tm_isdst; + panel_tm.tm_sec = 0; -/* - if (! set_PDA_numeric_field_value(aq_data, tm.tm_mon, aq_data->tm.tm_mon, NULL, 1)) { + LOG(PDA_LOG,LOG_DEBUG, "set_PDA_aqualink_time panel time %s", + asctime_r(&panel_tm,result)); + + // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x02|0x02|0x03|0x01|0x8c|0x10|0x03| + if (! set_PDA_numeric_field_value(aq_data, tm.tm_mon, panel_tm.tm_mon, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set month\n"); - } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_mday, aq_data->tm.tm_mday, NULL, 1)) { + // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x02|0x05|0x06|0x01|0x92|0x10|0x03| + } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_mday, panel_tm.tm_mday, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set day\n"); - } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_year, aq_data->tm.tm_year, NULL, 1)) { + // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x02|0x08|0x09|0x01|0x98|0x10|0x03| + } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_year, panel_tm.tm_year, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set year\n"); - } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_hour, aq_data->tm.tm_hour, NULL, 1)) { + // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x03|0x04|0x05|0x01|0x91|0x10|0x03| + } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_hour, panel_tm.tm_hour, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set hour\n"); - } else { - time(&now); // update time - localtime_r(&now, &tm); - if (! set_PDA_numeric_field_value(aq_data, tm.tm_min, aq_data->tm.tm_min, NULL, 1)) { - LOG(PDA_LOG,LOG_ERR, "Error failed to set min\n"); - } - waitForPDAnextMenu(aq_data); + // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x03|0x07|0x08|0x01|0x97|0x10|0x03| + } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_min, panel_tm.tm_min, NULL, 1)) { + LOG(PDA_LOG,LOG_ERR, "Error failed to set min\n"); } -*/ + + waitForPDAnextMenu(aq_data); + return true; } @@ -1379,4 +1284,4 @@ IntelliFlo® VS. The SCALE setting is fixed to RPM for the Jandy ePumpTM DC, Jandy ePumpTM AC, and IntelliFlo® VS. The SCALE setting is fixed to GPM for the IntelliFlo® VF There are eight (8) default speed presets for each variable speed pump. -*/ \ No newline at end of file +*/ diff --git a/pda_menu.c b/pda_menu.c index 89357de8..42254a17 100644 --- a/pda_menu.c +++ b/pda_menu.c @@ -242,6 +242,14 @@ bool process_pda_menu_packet(unsigned char* packet, int length) if (getLogLevel(PDA_LOG) >= LOG_DEBUG){print_menu();} break; case CMD_PDA_HIGHLIGHTCHARS: + // pkt[4] = line, pkt[5] = startchar, pkt[6] = endchar, pkt[7] = clr/inv + // highlight characters 10 to 15 on line 3 (from FREEZE PROTECT menu) + // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x03|0x0a|0x0f|0x01|0xa1|0x10|0x03| + // clear hlight chars 2 to 9 on line 2 and line 3 then hlight char 2 to 3 on line 3 + // (from SET TIME menu) + // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x02|0x02|0x09|0x00|0x91|0x10|0x03| + // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x03|0x02|0x09|0x00|0x92|0x10|0x03| + // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x02|0x02|0x03|0x01|0x8c|0x10|0x03| if (packet[4] <= PDA_LINES) { _hlightindex = packet[4]; _hlightcharindexstart = packet[5]; @@ -254,7 +262,7 @@ bool process_pda_menu_packet(unsigned char* packet, int length) if (getLogLevel(PDA_LOG) >= LOG_DEBUG){print_menu();} break; case CMD_PDA_SHIFTLINES: - /// press up from top - shift menu down by 1 + // press up from top - shift menu down by 1 // PDA Shif | HEX: 0x10|0x02|0x62|0x0f|0x01|0x08|0x01|0x8d|0x10|0x03| // press down from bottom - shift menu up by 1 // PDA Shif | HEX: 0x10|0x02|0x62|0x0f|0x01|0x08|0xff|0x8b|0x10|0x03| @@ -356,4 +364,4 @@ bool NEW_process_pda_menu_packet_NEW(unsigned char* packet, int length) return rtn; } -#endif \ No newline at end of file +#endif