pull/76/head
sfeakes 2019-06-27 17:18:44 -05:00
parent fda48cc459
commit a45807264f
17 changed files with 307 additions and 41 deletions

View File

@ -27,7 +27,14 @@ CFLAGS = $(GCCFLAGS) $(DBG) $(LIBS) -D MG_DISABLE_MD5 -D MG_DISABLE_HTTP_DIGEST_
# Add inputs and outputs from these tool invocations to the build variables
# define the C source files
SRCS = aqualinkd.c utils.c config.c aq_serial.c init_buttons.c aq_programmer.c net_services.c json_messages.c pda.c pda_menu.c pda_aq_programmer.c pentair_messages.c mongoose.c timespec_subtract.c
SRCS = aqualinkd.c utils.c config.c aq_serial.c init_buttons.c aq_programmer.c net_services.c json_messages.c pda.c pda_menu.c pda_aq_programmer.c pentair_messages.c mongoose.c
DBG_SRC = timespec_subtract.c
# If run with `make DEBUG=true` add debug files and pass parameter for compile
ifeq ($(DEBUG), true)
SRCS := $(SRCS) $(DBG_SRC)
CFLAGS := $(CFLAGS) -D AQ_DEBUG
endif
SL_SRC = serial_logger.c aq_serial.c utils.c
LR_SRC = log_reader.c aq_serial.c utils.c
@ -82,6 +89,7 @@ $(PLAY): $(PL_OBJS) $(PL_EXOBJ)
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
clean:
$(RM) *.o *~ $(MAIN) $(MAIN_U) $(PLAY) $(PL_EXOBJ)
$(RM) $(wildcard *.o) $(wildcard *~) $(MAIN) $(MAIN_U) $(PLAY) $(PL_EXOBJ)
depend: $(SRCS)

View File

@ -63,6 +63,8 @@ Designed to mimic AqualinkRS6 All Button keypad, and just like the keypad you ca
* http://aqualink.ip/simple.html <- (Simple opion if you don't like the above)
* http://aqualink.ip/simulator.html <- (RS8 All Button Control Panel simulator)
#<a name="release"></a>
## Update in Release 1.3.3a
* PDA fixes
## Update in Release 1.3.3
* AqualinkD will now automaticaly find a usable ID if not specifically configured.
* Support for reading (up to 4) Variable Speed Pump info & assigning per device. (Please see wiki for new config options).

View File

@ -20,7 +20,6 @@
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include "aqualink.h"
@ -31,7 +30,11 @@
#include "pda_menu.h"
#include "init_buttons.h"
#include "pda_aq_programmer.h"
#include "timespec_subtract.h"
#ifdef AQ_DEBUG
#include <time.h>
#include "timespec_subtract.h"
#endif
bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string);
bool select_menu_item(struct aqualinkdata *aq_data, char* item_string);
@ -388,6 +391,7 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr
}
while ( (threadCtrl->aq_data->active_thread.thread_id != 0) && ( i++ <= tries) ) {
//logMessage (LOG_DEBUG, "Thread %d sleeping, waiting for thread %d to finish\n", threadCtrl->thread_id, threadCtrl->aq_data->active_thread.thread_id);
logMessage (LOG_DEBUG, "Thread %d,%p sleeping, waiting for thread %d,%p to finish\n",
type, &threadCtrl->thread_id, threadCtrl->aq_data->active_thread.ptype,
threadCtrl->aq_data->active_thread.thread_id);
@ -395,6 +399,7 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr
}
if (i >= tries) {
//logMessage (LOG_ERR, "Thread %d timeout waiting, ending\n",threadCtrl->thread_id);
logMessage (LOG_ERR, "Thread %d,%p timeout waiting for thread %d,%p to finish\n",
type, &threadCtrl->thread_id, threadCtrl->aq_data->active_thread.ptype,
threadCtrl->aq_data->active_thread.thread_id);
@ -404,7 +409,12 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr
threadCtrl->aq_data->active_thread.thread_id = &threadCtrl->thread_id;
threadCtrl->aq_data->active_thread.ptype = type;
clock_gettime(CLOCK_REALTIME, &threadCtrl->aq_data->start_active_time);
#ifdef AQ_DEBUG
clock_gettime(CLOCK_REALTIME, &threadCtrl->aq_data->start_active_time);
#endif
//logMessage (LOG_DEBUG, "Thread %d is active\n", threadCtrl->aq_data->active_thread.thread_id);
logMessage (LOG_DEBUG, "Thread %d,%p is active\n",
threadCtrl->aq_data->active_thread.ptype,
threadCtrl->aq_data->active_thread.thread_id);
@ -412,16 +422,18 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr
void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl)
{
#ifndef AQ_DEBUG
logMessage(LOG_DEBUG, "Thread %d,%p finished\n",threadCtrl->aq_data->active_thread.ptype, threadCtrl->thread_id);
#else
struct timespec elapsed;
clock_gettime(CLOCK_REALTIME, &threadCtrl->aq_data->last_active_time);
timespec_subtract(&elapsed, &threadCtrl->aq_data->last_active_time, &threadCtrl->aq_data->start_active_time);
logMessage(LOG_DEBUG, "Thread %d,%p finished in %d.%03ld sec\n",
threadCtrl->aq_data->active_thread.ptype,
threadCtrl->aq_data->active_thread.thread_id,
elapsed.tv_sec, elapsed.tv_nsec / 1000000L);
// :TODO: This delay should not be needed
#endif
// Quick delay to allow for last message to be sent.
delay(500);
threadCtrl->aq_data->active_thread.thread_id = 0;
@ -1434,3 +1446,57 @@ bool waitForButtonState(struct aqualinkdata *aq_data, aqkey* button, aqledstate
return true;
}
const char *ptypeName(program_type type)
{
switch (type) {
case AQ_GET_POOL_SPA_HEATER_TEMPS:
return "Get Heater setpoints";
break;
case AQ_GET_FREEZE_PROTECT_TEMP:
return "Get Freeze proctect";
break;
case AQ_SET_TIME:
return "Set time";
break;
case AQ_SET_POOL_HEATER_TEMP:
return "Set Pool heater setpoint";
break;
case AQ_SET_SPA_HEATER_TEMP:
return "Set Spa heater setpoint";
break;
case AQ_SET_FRZ_PROTECTION_TEMP:
return "Set Freeze protect setpoint";
break;
case AQ_GET_DIAGNOSTICS_MODEL:
return "Get diagnostics";
break;
case AQ_GET_PROGRAMS:
return "Get programs";
break;
case AQ_SET_COLORMODE:
return "Set light color";
break;
case AQ_PDA_INIT:
return "Init PDA";
break;
case AQ_SET_SWG_PERCENT:
return "Set SWG percent";
break;
case AQ_PDA_DEVICE_STATUS:
return "Get PDA Device status";
break;
case AQ_PDA_DEVICE_ON_OFF:
return "Switch PDA device on/off";
break;
case AQ_GET_AUX_LABELS:
return "Get labels";
break;
case AQ_PDA_WAKE_INIT:
return "PDA init after wake";
break;
case AQP_NULL:
default:
return "Unknown";
break;
}
}

View File

@ -67,7 +67,7 @@ unsigned char pop_aq_cmd(struct aqualinkdata *aq_data);
int get_aq_cmd_length();
int setpoint_check(int type, int value, struct aqualinkdata *aqdata);
const char *ptypeName(program_type type);
// These shouldn't be here, but just for the PDA AQ PROGRAMMER
void send_cmd(unsigned char cmd);

View File

@ -79,7 +79,7 @@ typedef struct pumpd
struct aqualinkdata
{
//char crap[AQ_MSGLEN];
char version[AQ_MSGLEN];
char version[AQ_MSGLEN*2];
char date[AQ_MSGLEN];
char time[AQ_MSGLEN];
//char datestr[DATE_STRING_LEN];
@ -115,8 +115,10 @@ struct aqualinkdata
int open_websockets;
//bool last_msg_was_status;
//bool ar_swg_connected;
#ifdef AQ_DEBUG
struct timespec last_active_time;
struct timespec start_active_time;
#endif
};

View File

@ -39,8 +39,10 @@
#include "pda_menu.h"
#include "pda.h"
#include "pentair_messages.h"
#include "pda_aq_programmer.h"
#include "version.h"
//#define DEFAULT_CONFIG_FILE "./aqualinkd.conf"
static volatile bool _keepRunning = true;
@ -904,16 +906,16 @@ void logPacket(unsigned char *packet_buffer, int packet_length)
}
#define MAX_BLOCK_ACK 12
#define MAX_BUSY_ACK (50 + MAX_BLOCK_ACK)
void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer) {
static int delayAckCnt = 0;
if (!_aqualink_data.simulate_panel || _aqualink_data.active_thread.thread_id != 0) {
// if PDA mode, should we sleep? if not Can only send command to status message on PDA.
if (_config_parameters.pda_mode == true) {
//pda_programming_thread_check(&_aqualink_data);
if (_config_parameters.pda_sleep_mode && pda_shouldSleep()) {
logMessage(LOG_DEBUG, "PDA Aqualink daemon in sleep mode\n");
return;
@ -1108,6 +1110,7 @@ void main_loop()
send_ack(rs_fd, pop_aq_cmd(&_aqualink_data));
else
caculate_ack_packet(rs_fd, packet_buffer);
}/*
else if (_config_parameters.use_PDA_auxiliary && packet_length > 0 && packet_buffer[PKT_DEST] == 0x60 && _aqualink_data.aqbuttons[PUMP_INDEX].led->state != OFF)
{

44
pda.c
View File

@ -17,11 +17,10 @@ static unsigned char _last_packet_type;
static unsigned long _pda_loop_cnt = 0;
static bool _initWithRS = false;
// Each RS message is around 0.5 seconds apart, so 2 mins = 120 seconds = 240 polls
//#define PDA_LOOP_COUNT 240 // 2 mins in poll (sleep timer)
// Each RS message is around 0.25 seconds apart
#define PDA_SLEEP_FOR 60 // 30 seconds
#define PDA_WAKE_FOR 6 // 3 seconds
#define PDA_SLEEP_FOR 120 // 30 seconds
#define PDA_WAKE_FOR 6 // ~1 seconds
void init_pda(struct aqualinkdata *aqdata)
{
@ -215,6 +214,7 @@ void process_pda_packet_msg_long_temp(const char *msg)
// ' 86` 86` '
// 'AIR '
// ' 86` '
// 'AIR WATER' // In case of single device.
_aqualink_data->temp_units = FAHRENHEIT; // Force FAHRENHEIT
if (stristr(pda_m_line(1), "AIR") != NULL)
_aqualink_data->air_temp = atoi(msg);
@ -229,6 +229,11 @@ void process_pda_packet_msg_long_temp(const char *msg)
_aqualink_data->pool_temp = atoi(msg + 7);
_aqualink_data->spa_temp = TEMP_UNKNOWN;
}
else if (stristr(pda_m_line(1), "WATER") != NULL)
{
_aqualink_data->pool_temp = atoi(msg + 7);
_aqualink_data->spa_temp = TEMP_UNKNOWN;
}
else
{
_aqualink_data->pool_temp = TEMP_UNKNOWN;
@ -318,6 +323,15 @@ void process_pda_packet_msg_long_home(const char *msg)
}
}
void setSingleDeviceMode()
{
if (_aqualink_data->single_device != true)
{
_aqualink_data->single_device = true;
logMessage(LOG_NOTICE, "AqualinkD set to 'Pool OR Spa Only' mode\n");
}
}
void process_pda_packet_msg_long_set_temp(const char *msg)
{
logMessage(LOG_DEBUG, "process_pda_packet_msg_long_set_temp\n");
@ -332,6 +346,20 @@ void process_pda_packet_msg_long_set_temp(const char *msg)
_aqualink_data->spa_htr_set_point = atoi(msg + 10);
logMessage(LOG_DEBUG, "spa_htr_set_point = %d\n", _aqualink_data->spa_htr_set_point);
}
else if (stristr(msg, "TEMP1") != NULL)
{
setSingleDeviceMode();
_aqualink_data->pool_htr_set_point = atoi(msg + 10);
logMessage(LOG_DEBUG, "pool_htr_set_point = %d\n", _aqualink_data->pool_htr_set_point);
}
else if (stristr(msg, "TEMP2") != NULL)
{
setSingleDeviceMode();
_aqualink_data->spa_htr_set_point = atoi(msg + 10);
logMessage(LOG_DEBUG, "spa_htr_set_point = %d\n", _aqualink_data->spa_htr_set_point);
}
}
void process_pda_packet_msg_long_spa_heat(const char *msg)
@ -546,9 +574,12 @@ bool process_pda_packet(unsigned char *packet, int length)
case PM_FREEZE_PROTECT:
process_pda_packet_msg_long_freeze_protect(msg);
break;
case PM_AQUAPURE:
case PM_AQUAPURE:
process_pda_packet_msg_long_SWG(msg);
break;
//case PM_FW_VERSION:
// process_pda_packet_msg_long_FW_version(msg);
//break;
case PM_UNKNOWN:
default:
process_pda_packet_msg_long_unknown(msg);
@ -580,7 +611,8 @@ bool process_pda_packet(unsigned char *packet, int length)
}
if (packet[PKT_CMD] == CMD_MSG_LONG || packet[PKT_CMD] == CMD_PDA_HIGHLIGHT ||
packet[PKT_CMD] == CMD_PDA_SHIFTLINES || packet[PKT_CMD] == CMD_PDA_CLEAR)
packet[PKT_CMD] == CMD_PDA_SHIFTLINES || packet[PKT_CMD] == CMD_PDA_CLEAR ||
packet[PKT_CMD] == CMD_PDA_HIGHLIGHTCHARS)
{
// We processed the next message, kick any threads waiting on the message.
kick_aq_program_thread(_aqualink_data);

View File

@ -16,8 +16,15 @@
#include "init_buttons.h"
#ifdef AQ_DEBUG
#include <time.h>
#include "timespec_subtract.h"
#endif
bool waitForPDAMessageHighlight(struct aqualinkdata *aq_data, int highlighIndex, int numMessageReceived);
bool waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, int numMessageReceived);
bool waitForPDAMessageTypes(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived);
bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu);
bool wait_pda_selected_item(struct aqualinkdata *aq_data);
bool waitForPDAnextMenu(struct aqualinkdata *aq_data);
@ -27,6 +34,64 @@ bool select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool wai
static pda_type _PDA_Type;
/*
// Each RS message / call to this function is around 0.2 seconds apart
//#define MAX_ACK_FOR_THREAD 200 // ~40 seconds (Init takes 30)
#define MAX_ACK_FOR_THREAD 60 // ~12 seconds (testing, will stop every thread)
// *** DELETE THIS WHEN PDA IS OUT OF BETA ****
void pda_programming_thread_check(struct aqualinkdata *aq_data)
{
static pthread_t thread_id = 0;
static int ack_count = 0;
#ifdef AQ_DEBUG
static struct timespec start;
static struct timespec now;
struct timespec elapsed;
#endif
// Check for long lasting threads
if (aq_data->active_thread.thread_id != 0) {
if (thread_id != *aq_data->active_thread.thread_id) {
printf ("**************** LAST POINTER SET %ld , %p ****************************\n",thread_id,&thread_id);
thread_id = *aq_data->active_thread.thread_id;
#ifdef AQ_DEBUG
clock_gettime(CLOCK_REALTIME, &start);
#endif
printf ("**************** NEW POINTER SET %d, %ld %ld , %p %p ****************************\n",aq_data->active_thread.ptype,thread_id,*aq_data->active_thread.thread_id,&thread_id,aq_data->active_thread.thread_id);
ack_count = 0;
} else if (ack_count > MAX_ACK_FOR_THREAD) {
#ifdef AQ_DEBUG
clock_gettime(CLOCK_REALTIME, &now);
timespec_subtract(&elapsed, &now, &start);
logMessage(LOG_ERR, "Thread %d,%p FAILED to finished in reasonable time, %d.%03ld sec, killing it.\n",
aq_data->active_thread.ptype,
aq_data->active_thread.thread_id,
elapsed.tv_sec, elapsed.tv_nsec / 1000000L);
#else
logMessage(LOG_ERR, "Thread %d,%p FAILED to finished in reasonable time, killing it!\n", aq_data->active_thread.ptype, aq_data->active_thread.thread_id)
#endif
if (pthread_cancel(*aq_data->active_thread.thread_id) != 0)
logMessage(LOG_ERR, "Thread kill failed\n");
else {
}
aq_data->active_thread.thread_id = 0;
aq_data->active_thread.ptype = AQP_NULL;
ack_count = 0;
thread_id = 0;
} else {
ack_count++;
}
} else {
ack_count = 0;
thread_id = 0;
}
}
*/
bool wait_pda_selected_item(struct aqualinkdata *aq_data)
{
while (pda_m_hlightindex() == -1){
@ -41,7 +106,7 @@ bool wait_pda_selected_item(struct aqualinkdata *aq_data)
bool waitForPDAnextMenu(struct aqualinkdata *aq_data) {
waitForPDAMessageType(aq_data,CMD_PDA_CLEAR,10);
return waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,15);
return waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15);
}
bool loopover_devices(struct aqualinkdata *aq_data) {
@ -133,7 +198,7 @@ bool select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool wai
}
bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
//int i = 0;
int i = 0;
//char *menuText;
logMessage(LOG_DEBUG, "PDA Device programmer request for menu %d\n",menu);
@ -144,7 +209,8 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
delay(500);
}
while ( pda_m_type() != menu && pda_m_type() != PM_HOME ) {
// This needs a timeout.
while ( pda_m_type() != menu && pda_m_type() != PM_HOME) {
if (pda_m_type() != PM_BUILDING_HOME) {
send_cmd(KEY_PDA_BACK);
//logMessage(LOG_DEBUG, "******************PDA Device programmer selected back button\n",menu);
@ -152,10 +218,17 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
} else {
waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,15);
}
if (i > 4 ) {
logMessage(LOG_ERR, "PDA Device programmer request for menu %d failed! Couldn't get to HOME menu\n",menu);
return false;
}
i++;
//logMessage(LOG_DEBUG, "******************PDA Device programmer menu type %d\n",pda_m_type());
//if (!wait_for_empty_cmd_buffer() || i++ > 6)
// return false;
}
if (pda_m_type() == menu)
return true;
@ -253,7 +326,7 @@ void *set_aqualink_PDA_device_on_off( void *ptr )
}
//Pad name with spaces so something like "SPA" doesn't match "SPA BLOWER"
sprintf(device_name,"%-14s\n",aq_data->aqbuttons[device].pda_label);
sprintf(device_name,"%-13s\n",aq_data->aqbuttons[device].pda_label);
if ( find_pda_menu_item(aq_data, device_name, 13) ) {
if (aq_data->aqbuttons[device].led->state != state) {
//printf("*** Select State ***\n");
@ -322,9 +395,14 @@ void *set_aqualink_PDA_init( void *ptr )
} else {
_PDA_Type = PDA;
}
char *ptr = pda_m_line(5);
ptr[AQ_MSGLEN+1] = '\0';
strcpy(aq_data->version, stripwhitespace(ptr));
char *ptr1 = pda_m_line(1);
char *ptr2 = pda_m_line(5);
ptr1[AQ_MSGLEN+1] = '\0';
ptr2[AQ_MSGLEN+1] = '\0';
//strcpy(aq_data->version, stripwhitespace(ptr));
snprintf(aq_data->version, (AQ_MSGLEN*2)-1, "%s %s",stripwhitespace(ptr1),stripwhitespace(ptr2));
printf("****** Version '%s' ********\n",aq_data->version);
}
// Get status of all devices
@ -466,6 +544,36 @@ bool waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, in
return true;
}
bool waitForPDAMessageTypes(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived)
{
logMessage(LOG_DEBUG, "waitForPDAMessageTypes 0x%02hhx or 0x%02hhx\n",mtype1,mtype2);
int i=0;
pthread_mutex_init(&aq_data->active_thread.thread_mutex, NULL);
pthread_mutex_lock(&aq_data->active_thread.thread_mutex);
while( ++i <= numMessageReceived)
{
logMessage(LOG_DEBUG, "waitForPDAMessageTypes 0x%02hhx | 0x%02hhx, last message type was 0x%02hhx (%d of %d)\n",mtype1,mtype2,aq_data->last_packet_type,i,numMessageReceived);
if (aq_data->last_packet_type == mtype1 || aq_data->last_packet_type == mtype2) break;
pthread_cond_init(&aq_data->active_thread.thread_cond, NULL);
pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex);
}
pthread_mutex_unlock(&aq_data->active_thread.thread_mutex);
if (aq_data->last_packet_type != mtype1 && aq_data->last_packet_type != mtype2) {
//logMessage(LOG_ERR, "Could not select MENU of Aqualink control panel\n");
logMessage(LOG_DEBUG, "waitForPDAMessageTypes: did not receive 0x%02hhx or 0x%02hhx\n",mtype1,mtype2);
return false;
} else
logMessage(LOG_DEBUG, "waitForPDAMessageTypes: received 0x%02hhx\n",aq_data->last_packet_type);
return true;
}
bool set_PDA_numeric_field_value(struct aqualinkdata *aq_data, int val, int *cur_val, char *select_label, int step) {
int i;
@ -519,12 +627,22 @@ bool set_PDA_aqualink_heater_setpoint(struct aqualinkdata *aq_data, int val, boo
char label[10];
int *cur_val;
if (isPool) {
sprintf(label, "POOL HEAT");
cur_val = &aq_data->pool_htr_set_point;
if ( aq_data->single_device != true ) {
if (isPool) {
sprintf(label, "POOL HEAT");
cur_val = &aq_data->pool_htr_set_point;
} else {
sprintf(label, "SPA HEAT");
cur_val = &aq_data->spa_htr_set_point;
}
} else {
sprintf(label, "SPA HEAT");
cur_val = &aq_data->spa_htr_set_point;
if (isPool) {
sprintf(label, "TEMP1");
cur_val = &aq_data->pool_htr_set_point;
} else {
sprintf(label, "TEMP2");
cur_val = &aq_data->spa_htr_set_point;
}
}
if (val == *cur_val) {
@ -641,13 +759,25 @@ PDA Line 7 =
PDA Line 8 =
PDA Line 9 =
PDA Menu Line 0 =
PDA Menu Line 1 = PDA-P4 Only
PDA Menu Line 2 =
PDA Menu Line 3 = Firmware Version
PDA Menu Line 4 =
PDA Menu Line 5 = PDA: 7.1.0
PDA Menu Line 6 =
PDA Menu Line 7 =
PDA Menu Line 8 =
PDA Menu Line 9 =
************** The above have different menu to below rev/version *********
***************** Think this is startup different rev *************
Line 0 =
Line 1 = PDA-PS4 Combo
Line 2 =
Line 3 = Firmware Version
Line 4 =
Line 5 = PPD: PDA 1.2
PDA Menu Line 0 =
PDA Menu Line 1 = PDA-PS4 Combo
PDA Menu Line 2 =
PDA Menu Line 3 = Firmware Version
PDA Menu Line 4 =
PDA Menu Line 5 = PPD: PDA 1.2
PDA Line 0 =
PDA Line 1 = AIR POOL
@ -747,6 +877,21 @@ PDA Line 8 = item and press
PDA Line 9 = SELECT
******* GUSSING AT BELOW *******
when single mode (pool OR spa) not (pool AND spa) temps are different.
PDA Line 0 = SET TEMP
PDA Line 1 =
PDA Line 2 = TEMP1 70`F
PDA Line 3 = TEMP2 98`F
PDA Line 4 =
PDA Line 5 =
PDA Line 6 =
PDA Line 7 = Highlight an
PDA Line 8 = item and press
PDA Line 9 = SELECT
@ -807,4 +952,4 @@ The SCALE setting is fixed to RPM for the Jandy ePumpTM DC, Jandy ePumpTM AC, an
The SCALE setting is fixed to GPM for the IntelliFlo® VF
There are eight (8) default speed presets for each variable speed pump.
*/
*/

View File

@ -18,4 +18,6 @@ bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aq_data, int v
bool get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data);
bool get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data);
//void pda_programming_thread_check(struct aqualinkdata *aq_data);
#endif // AQ_PDA_PROGRAMMER_H_

View File

@ -96,7 +96,8 @@ pda_menu_type pda_m_type()
else if (strncasecmp(_menu[0]," MAIN MENU ", 16) == 0)
return PM_MAIN;
//else if ((_menu[0] == '\0' && _hlightindex == -1) || strncmp(_menu[4], "POOL MODE", 9) == 0 )// IF we are building the main menu this may be valid
else if (strncasecmp(_menu[4], "POOL MODE", 9) == 0 ) {
else if (strncasecmp(_menu[4], "POOL MODE", 9) == 0 || // Will not see POOL MODE if single device config (pool vs pool&spa)
strncasecmp(_menu[9], "EQUIPMENT ON/OFF", 16) == 0) {
if (pda_m_hlightindex() == -1)
return PM_BUILDING_HOME;
else
@ -120,7 +121,7 @@ pda_menu_type pda_m_type()
return PM_FREEZE_PROTECT_DEVICES;
else if (strncasecmp(_menu[3],"Firmware Version", 16) == 0 ||
strncasecmp(_menu[1]," AquaPalm", 12) == 0 ||
strncasecmp(_menu[1]," PDA-PS4 Combo", 14) == 0)
strncasecmp(_menu[1]," PDA-P", 6) == 0) // PDA-P4 Only -or- PDA-PS4 Combo
return PM_FW_VERSION;
return PM_UNKNOWN;

Binary file not shown.

Binary file not shown.

View File

@ -72,7 +72,6 @@ device_id=0x0a
# Put AqualinkD to sleep when in PDA mode after inactivity.
# If you have Jandy PDA then this MUST be set to yes as the controller can only support one PDA.
# If you don't have a Jandy PDA leave this at no as AqualinkD will be a lot quicker.
# Sleep timer is around 2 mins of inactivity, then wake after 2 mins of sleep.
#pda_sleep_mode = yes
# Read status information from other devices on the RS485 bus.

Binary file not shown.

View File

@ -27,7 +27,10 @@
#include <sys/stat.h>
#include <time.h>
#include <ctype.h>
#ifdef AD_DEBUG
#include <sys/time.h>
#endif
#ifndef _UTILS_C_
#define _UTILS_C_
@ -341,12 +344,16 @@ void logMessage(int msg_level, char *format, ...)
if (msg_level == LOG_ERR) {
fprintf(stderr, "%s", buffer);
} else {
#ifndef AD_DEBUG
printf("%s", buffer);
#else
struct timespec tspec;
struct tm localtm;
clock_gettime(CLOCK_REALTIME, &tspec);
char timeStr[TIMESTAMP_LENGTH];
strftime(timeStr, sizeof(timeStr), "%H:%M:%S", localtime_r(&tspec.tv_sec, &localtm));
printf("%s.%03ld %s", timeStr, tspec.tv_nsec / 1000000L, buffer);
#endif
}
}
}

View File

@ -1,6 +1,5 @@
#include <syslog.h>
#include <stdbool.h>
#include <time.h>
#ifndef UTILS_H_
#define UTILS_H_

View File

@ -1,4 +1,4 @@
#define AQUALINKD_NAME "Aqualink Daemon"
#define AQUALINKD_VERSION "1.3.3"
#define AQUALINKD_VERSION "1.3.3a"