2019-07-19 19:13:21 +00:00
/*
* Copyright ( c ) 2017 Shaun Feakes - All rights reserved
*
* You may use redistribute and / or modify this code under the terms of
* the GNU General Public License version 2 as published by the
* Free Software Foundation . For the terms of this license ,
* see < http : //www.gnu.org/licenses/>.
*
* You are free to use this software under the terms of the GNU General
* Public License , but WITHOUT ANY WARRANTY ; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details .
*
* https : //github.com/sfeakes/aqualinkd
*/
2019-05-25 16:52:36 +00:00
# include <stdio.h>
# include <stdarg.h>
# include <stdlib.h>
# include <pthread.h>
# include <unistd.h>
# include <string.h>
# include "aqualink.h"
# include "utils.h"
# include "aq_programmer.h"
# include "aq_serial.h"
# include "pda.h"
# include "pda_menu.h"
# include "pda_aq_programmer.h"
# include "init_buttons.h"
2019-06-27 22:18:44 +00:00
# ifdef AQ_DEBUG
# include <time.h>
# include "timespec_subtract.h"
# endif
2019-05-25 16:52:36 +00:00
bool waitForPDAMessageHighlight ( struct aqualinkdata * aq_data , int highlighIndex , int numMessageReceived ) ;
bool waitForPDAMessageType ( struct aqualinkdata * aq_data , unsigned char mtype , int numMessageReceived ) ;
2019-06-27 22:18:44 +00:00
bool waitForPDAMessageTypes ( struct aqualinkdata * aq_data , unsigned char mtype1 , unsigned char mtype2 , int numMessageReceived ) ;
2019-07-01 14:16:00 +00:00
bool waitForPDAMessageTypesOrMenu ( struct aqualinkdata * aq_data , unsigned char mtype1 , unsigned char mtype2 , int numMessageReceived , char * text , int line ) ;
2019-05-25 16:52:36 +00:00
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 ) ;
bool loopover_devices ( struct aqualinkdata * aq_data ) ;
bool find_pda_menu_item ( struct aqualinkdata * aq_data , char * menuText , int charlimit ) ;
bool select_pda_menu_item ( struct aqualinkdata * aq_data , char * menuText , bool waitForNextMenu ) ;
static pda_type _PDA_Type ;
2019-06-27 22:18:44 +00:00
/*
// 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 ;
}
}
*/
2019-05-25 16:52:36 +00:00
bool wait_pda_selected_item ( struct aqualinkdata * aq_data )
{
2019-06-27 22:45:55 +00:00
int i = 0 ;
while ( pda_m_hlightindex ( ) = = - 1 & & i < 5 ) {
2019-05-25 16:52:36 +00:00
waitForPDAMessageType ( aq_data , CMD_PDA_HIGHLIGHT , 10 ) ;
2019-06-27 22:45:55 +00:00
i + + ;
2019-05-25 16:52:36 +00:00
}
if ( pda_m_hlightindex ( ) = = - 1 )
return false ;
else
return true ;
}
bool waitForPDAnextMenu ( struct aqualinkdata * aq_data ) {
waitForPDAMessageType ( aq_data , CMD_PDA_CLEAR , 10 ) ;
2019-06-27 22:18:44 +00:00
return waitForPDAMessageTypes ( aq_data , CMD_PDA_HIGHLIGHT , CMD_PDA_HIGHLIGHTCHARS , 15 ) ;
2019-05-25 16:52:36 +00:00
}
bool loopover_devices ( struct aqualinkdata * aq_data ) {
int i ;
2019-08-09 03:21:09 +00:00
int index = - 1 ;
2019-05-25 16:52:36 +00:00
if ( ! goto_pda_menu ( aq_data , PM_EQUIPTMENT_CONTROL ) ) {
2019-08-09 03:21:09 +00:00
logMessage ( LOG_ERR , " loopover_devices :- can't goto PM_EQUIPTMENT_CONTROL menu \n " ) ;
2019-05-25 16:52:36 +00:00
//cleanAndTerminateThread(threadCtrl);
return false ;
}
// Should look for message "ALL OFF", that's end of device list.
2019-08-09 03:21:09 +00:00
for ( i = 0 ; i < 18 & & ( index = pda_find_m_index ( " ALL OFF " ) ) = = - 1 ; i + + ) {
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_DOWN ) ;
2019-08-09 03:21:09 +00:00
// Wait for highlight change or shift and update of current line
waitForPDAMessageTypes ( aq_data , CMD_PDA_HIGHLIGHT , CMD_MSG_LONG , 8 ) ;
}
if ( index = = - 1 ) {
logMessage ( LOG_ERR , " loopover_devices :- can't find ALL OFF \n " ) ;
return false ;
2019-05-25 16:52:36 +00:00
}
return true ;
}
/*
if charlimit is set , use case insensitive match and limit chars .
*/
bool find_pda_menu_item ( struct aqualinkdata * aq_data , char * menuText , int charlimit ) {
int i = pda_m_hlightindex ( ) ;
2019-06-21 19:59:50 +00:00
int min_index = - 1 ;
int max_index = - 1 ;
int cnt = 0 ;
2019-05-25 16:52:36 +00:00
2019-07-01 14:16:00 +00:00
logMessage ( LOG_DEBUG , " PDA Device programmer looking for menu text '%s' \n " , menuText ) ;
int index = ( charlimit = = 0 ) ? pda_find_m_index ( menuText ) : pda_find_m_index_case ( menuText , charlimit ) ;
2019-05-25 16:52:36 +00:00
if ( index < 0 ) { // No menu, is there a page down. "PDA Line 9 = ^^ MORE __"
2019-06-05 16:41:38 +00:00
if ( strncasecmp ( pda_m_line ( 9 ) , " ^^ MORE " , 10 ) = = 0 ) {
2019-05-25 16:52:36 +00:00
int j ;
for ( j = 0 ; j < 20 ; j + + ) {
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_DOWN ) ;
2019-05-25 16:52:36 +00:00
//delay(500);
//wait_for_empty_cmd_buffer();
2019-08-09 03:21:09 +00:00
waitForPDAMessageTypes ( aq_data , CMD_PDA_HIGHLIGHT , CMD_MSG_LONG , 8 ) ;
2019-05-25 16:52:36 +00:00
//waitForMessage(aq_data, NULL, 1);
index = ( charlimit = = 0 ) ? pda_find_m_index ( menuText ) : pda_find_m_index_case ( menuText , charlimit ) ;
if ( index > = 0 ) {
i = pda_m_hlightindex ( ) ;
break ;
}
}
if ( index < 0 ) {
logMessage ( LOG_ERR , " PDA Device programmer couldn't find menu item on any page '%s' \n " , menuText ) ;
return false ;
}
} else {
2019-08-09 03:21:09 +00:00
logMessage ( LOG_ERR , " PDA Device programmer couldn't find menu item '%s' in menu %d index %d \n " ,
menuText , pda_m_type ( ) , index ) ;
2019-05-25 16:52:36 +00:00
return false ;
}
}
2019-06-21 19:59:50 +00:00
if ( strncasecmp ( pda_m_line ( 9 ) , " ^^ MORE " , 10 ) ! = 0 ) {
if ( pda_m_type ( ) = = PM_HOME ) {
min_index = 4 ;
max_index = 9 ;
} else if ( pda_m_type ( ) = = PM_EQUIPTMENT_CONTROL ) {
min_index = 1 ;
max_index = 9 ;
} else if ( pda_m_type ( ) = = PM_MAIN ) {
// Line 0 = MAIN MENU
// Line 1 =
// Line 2 = HELP >
// Line 3 = PROGRAM >
// Line 4 = SET TEMP >
// Line 5 = SET TIME >
// Line 6 = PDA OPTIONS >
// Line 7 = SYSTEM SETUP >
// Line 8 =
// Line 9 =
// Line 0 = MAIN MENU
// Line 1 = HELP >
// Line 2 = PROGRAM >
// Line 3 = SET TEMP >
// Line 4 = SET TIME >
// Line 5 = SET AquaPure >
// Line 6 = PDA OPTIONS >
// Line 7 = SYSTEM SETUP >
// Line 8 =
// Line 9 = BOOST
// "SET AquaPure" and "BOOST" are only present when filter pump is running
if ( strncasecmp ( pda_m_line ( 9 ) , " BOOST " , 16 ) = = 0 ) {
min_index = 1 ;
max_index = 8 ; // to account for 8 missing
if ( index = = 9 ) { // looking for boost
index = 8 ;
}
} else {
min_index = 2 ;
max_index = 7 ;
}
}
}
logMessage ( LOG_DEBUG , " find_pda_menu_item i=%d idx=%d min=%d max=%d \n " ,
i , index , min_index , max_index ) ;
2019-05-25 16:52:36 +00:00
if ( i < index ) {
2019-06-21 19:59:50 +00:00
if ( ( min_index ! = - 1 ) & & ( ( index - i ) > ( i - min_index + max_index - index + 1 ) ) ) {
cnt = i - min_index + max_index - index + 1 ;
for ( i = 0 ; i < cnt ; i + + ) {
send_cmd ( KEY_PDA_UP ) ;
}
} else {
for ( i = pda_m_hlightindex ( ) ; i < index ; i + + ) {
send_cmd ( KEY_PDA_DOWN ) ;
}
2019-05-25 16:52:36 +00:00
}
} else if ( i > index ) {
2019-06-21 19:59:50 +00:00
if ( ( min_index ! = - 1 ) & & ( ( i - index ) > ( index - min_index + max_index - i + 1 ) ) ) {
cnt = i - min_index + max_index - index + 1 ;
for ( i = 0 ; i < cnt ; i + + ) {
send_cmd ( KEY_PDA_UP ) ;
}
} else {
for ( i = pda_m_hlightindex ( ) ; i > index ; i - - ) {
send_cmd ( KEY_PDA_UP ) ;
}
2019-05-25 16:52:36 +00:00
}
}
return waitForPDAMessageHighlight ( aq_data , index , 10 ) ;
}
bool select_pda_menu_item ( struct aqualinkdata * aq_data , char * menuText , bool waitForNextMenu ) {
if ( find_pda_menu_item ( aq_data , menuText , 0 ) ) {
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_SELECT ) ;
2019-05-25 16:52:36 +00:00
logMessage ( LOG_DEBUG , " PDA Device programmer selected menu item '%s' \n " , menuText ) ;
if ( waitForNextMenu )
waitForPDAnextMenu ( aq_data ) ;
return true ;
}
2019-08-09 03:21:09 +00:00
logMessage ( LOG_ERR , " PDA Device programmer couldn't select menu item '%s' menu %d \n " , menuText , pda_m_type ( ) ) ;
2019-05-25 16:52:36 +00:00
return false ;
}
2019-06-21 19:59:50 +00:00
// for reference see H0572300 - AquaLink PDA I/O Manual
// https://www.jandy.com/-/media/zodiac/global/downloads/h/h0572300.pdf
// and H0574200 - AquaPalm Wireless Handheld Remote Installation and Operation Manual
// https://www.jandy.com/-/media/zodiac/global/downloads/h/h0574200.pdf
// and 6594 - AquaLink RS Control Panel Installation Manual
// https://www.jandy.com/-/media/zodiac/global/downloads/0748-91071/6594.pdf
2019-05-25 16:52:36 +00:00
bool goto_pda_menu ( struct aqualinkdata * aq_data , pda_menu_type menu ) {
2019-06-21 19:59:50 +00:00
bool ret = true ;
2019-05-25 16:52:36 +00:00
logMessage ( LOG_DEBUG , " PDA Device programmer request for menu %d \n " , menu ) ;
2019-06-21 19:59:50 +00:00
if ( pda_m_type ( ) = = PM_FW_VERSION ) {
logMessage ( LOG_DEBUG , " goto_pda_menu at FW version menu \n " ) ;
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_BACK ) ;
2019-06-21 19:59:50 +00:00
if ( ! waitForPDAnextMenu ( aq_data ) ) {
logMessage ( LOG_ERR , " PDA Device programmer wait for next menu failed " ) ;
}
} else if ( pda_m_type ( ) = = PM_BUILDING_HOME ) {
logMessage ( LOG_DEBUG , " goto_pda_menu building home menu \n " ) ;
2019-05-25 16:52:36 +00:00
waitForPDAMessageType ( aq_data , CMD_PDA_HIGHLIGHT , 15 ) ;
}
2019-06-27 22:18:44 +00:00
2019-05-25 16:52:36 +00:00
2019-06-21 19:59:50 +00:00
while ( ret & & ( pda_m_type ( ) ! = menu ) ) {
switch ( menu ) {
2019-08-09 03:21:09 +00:00
case PM_HOME :
send_cmd ( KEY_PDA_BACK ) ;
ret = waitForPDAnextMenu ( aq_data ) ;
break ;
2019-06-21 19:59:50 +00:00
case PM_EQUIPTMENT_CONTROL :
if ( pda_m_type ( ) = = PM_HOME ) {
ret = select_pda_menu_item ( aq_data , " EQUIPMENT ON/OFF " , true ) ;
} else {
send_cmd ( KEY_PDA_BACK ) ;
ret = waitForPDAnextMenu ( aq_data ) ;
}
break ;
case PM_PALM_OPTIONS :
if ( pda_m_type ( ) = = PM_HOME ) {
ret = select_pda_menu_item ( aq_data , " MENU " , true ) ;
} else if ( pda_m_type ( ) = = PM_MAIN ) {
ret = select_pda_menu_item ( aq_data , " PALM OPTIONS " , true ) ;
} else {
send_cmd ( KEY_PDA_BACK ) ;
ret = waitForPDAnextMenu ( aq_data ) ;
}
break ;
case PM_AUX_LABEL :
if ( _PDA_Type = = PDA ) {
if ( pda_m_type ( ) = = PM_HOME ) {
ret = select_pda_menu_item ( aq_data , " MENU " , true ) ;
} else if ( pda_m_type ( ) = = PM_MAIN ) {
ret = select_pda_menu_item ( aq_data , " SYSTEM SETUP " , true ) ;
} else if ( pda_m_type ( ) = = PM_SYSTEM_SETUP ) {
ret = select_pda_menu_item ( aq_data , " LABEL AUX " , true ) ;
} else {
send_cmd ( KEY_PDA_BACK ) ;
ret = waitForPDAnextMenu ( aq_data ) ;
}
} else {
logMessage ( LOG_ERR , " PDA in AquaPlalm mode, there is no SYSTEM SETUP / LABEL AUX menu \n " ) ;
}
break ;
case PM_SYSTEM_SETUP :
if ( _PDA_Type = = PDA ) {
if ( pda_m_type ( ) = = PM_HOME ) {
ret = select_pda_menu_item ( aq_data , " MENU " , true ) ;
} else if ( pda_m_type ( ) = = PM_MAIN ) {
ret = select_pda_menu_item ( aq_data , " SYSTEM SETUP " , true ) ;
} else {
send_cmd ( KEY_PDA_BACK ) ;
ret = waitForPDAnextMenu ( aq_data ) ;
}
} else {
logMessage ( LOG_ERR , " PDA in AquaPlalm mode, there is no SYSTEM SETUP menu \n " ) ;
}
break ;
case PM_FREEZE_PROTECT :
if ( _PDA_Type = = PDA ) {
if ( pda_m_type ( ) = = PM_HOME ) {
ret = select_pda_menu_item ( aq_data , " MENU " , true ) ;
} else if ( pda_m_type ( ) = = PM_MAIN ) {
ret = select_pda_menu_item ( aq_data , " SYSTEM SETUP " , true ) ;
} else if ( pda_m_type ( ) = = PM_SYSTEM_SETUP ) {
ret = select_pda_menu_item ( aq_data , " FREEZE PROTECT " , true ) ;
} else {
send_cmd ( KEY_PDA_BACK ) ;
ret = waitForPDAnextMenu ( aq_data ) ;
}
} else {
logMessage ( LOG_ERR , " PDA in AquaPlalm mode, there is no SYSTEM SETUP / FREEZE PROTECT menu \n " ) ;
}
break ;
case PM_AQUAPURE :
if ( pda_m_type ( ) = = PM_HOME ) {
ret = select_pda_menu_item ( aq_data , " MENU " , true ) ;
} else if ( pda_m_type ( ) = = PM_MAIN ) {
ret = select_pda_menu_item ( aq_data , " SET AquaPure " , true ) ;
} else {
send_cmd ( KEY_PDA_BACK ) ;
ret = waitForPDAnextMenu ( aq_data ) ;
}
break ;
case PM_SET_TEMP :
if ( pda_m_type ( ) = = PM_HOME ) {
ret = select_pda_menu_item ( aq_data , " MENU " , true ) ;
} else if ( pda_m_type ( ) = = PM_MAIN ) {
ret = select_pda_menu_item ( aq_data , " SET TEMP " , true ) ;
// Depending on control panel config, may get an extra menu asking to press any key
// waitForPDAMessageType(aq_data,CMD_PDA_CLEAR,10);
// waitForPDAMessageTypesOrMenu(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,20,"press ANY key",8);
} else {
send_cmd ( KEY_PDA_BACK ) ;
ret = waitForPDAnextMenu ( aq_data ) ;
}
break ;
case PM_SET_TIME :
if ( pda_m_type ( ) = = PM_HOME ) {
ret = select_pda_menu_item ( aq_data , " MENU " , true ) ;
} else if ( pda_m_type ( ) = = PM_MAIN ) {
ret = select_pda_menu_item ( aq_data , " SET TIME " , true ) ;
} else {
send_cmd ( KEY_PDA_BACK ) ;
ret = waitForPDAnextMenu ( aq_data ) ;
}
break ;
default :
logMessage ( LOG_ERR , " PDA Device programmer didn't understand requested menu \n " ) ;
return false ;
break ;
}
logMessage ( LOG_DEBUG , " PDA Device programmer request for menu %d, current %d \n " ,
menu , pda_m_type ( ) ) ;
2019-05-25 16:52:36 +00:00
}
if ( pda_m_type ( ) ! = menu ) {
2019-08-09 03:21:09 +00:00
logMessage ( LOG_ERR , " PDA Device programmer didn't find a requested menu %d, current %d \n " ,
menu , pda_m_type ( ) ) ;
2019-07-01 14:16:00 +00:00
return false ;
2019-05-25 16:52:36 +00:00
}
return true ;
}
void * set_aqualink_PDA_device_on_off ( void * ptr )
{
struct programmingThreadCtrl * threadCtrl ;
threadCtrl = ( struct programmingThreadCtrl * ) ptr ;
struct aqualinkdata * aq_data = threadCtrl - > aq_data ;
//int i=0;
//int found;
char device_name [ 15 ] ;
2019-01-28 18:50:14 +00:00
waitForSingleThreadOrTerminate ( threadCtrl , AQ_PDA_DEVICE_ON_OFF ) ;
2019-05-25 16:52:36 +00:00
char * buf = ( char * ) threadCtrl - > thread_args ;
2019-06-05 16:41:38 +00:00
unsigned int device = atoi ( & buf [ 0 ] ) ;
unsigned int state = atoi ( & buf [ 5 ] ) ;
2019-05-25 16:52:36 +00:00
2019-06-05 16:41:38 +00:00
if ( device > TOTAL_BUTTONS ) {
2019-05-25 16:52:36 +00:00
logMessage ( LOG_ERR , " PDA Device On/Off :- bad device number '%d' \n " , device ) ;
cleanAndTerminateThread ( threadCtrl ) ;
return ptr ;
}
logMessage ( LOG_INFO , " PDA Device On/Off, device '%s', state %d \n " , aq_data - > aqbuttons [ device ] . pda_label , state ) ;
if ( ! goto_pda_menu ( aq_data , PM_EQUIPTMENT_CONTROL ) ) {
2019-08-09 03:21:09 +00:00
logMessage ( LOG_ERR , " PDA Device On/Off :- can't find EQUIPTMENT CONTROL menu \n " ) ;
2019-05-25 16:52:36 +00:00
cleanAndTerminateThread ( threadCtrl ) ;
return ptr ;
}
2019-07-01 14:16:00 +00:00
// If single config (Spa OR pool) rather than (Spa AND pool) heater is TEMP1 and TEMP2
if ( aq_data - > single_device = = TRUE & & device = = POOL_HEAT_INDEX ) { // rename Heater and Spa
sprintf ( device_name , " %-13s \n " , " TEMP1 " ) ;
} else if ( aq_data - > single_device = = TRUE & & device = = SPA_HEAT_INDEX ) { // rename Heater and Spa
sprintf ( device_name , " %-13s \n " , " TEMP2 " ) ;
} else {
//Pad name with spaces so something like "SPA" doesn't match "SPA BLOWER"
sprintf ( device_name , " %-13s \n " , aq_data - > aqbuttons [ device ] . pda_label ) ;
}
2019-05-25 16:52:36 +00:00
if ( find_pda_menu_item ( aq_data , device_name , 13 ) ) {
if ( aq_data - > aqbuttons [ device ] . led - > state ! = state ) {
//printf("*** Select State ***\n");
logMessage ( LOG_INFO , " PDA Device On/Off, found device '%s', changing state \n " , aq_data - > aqbuttons [ device ] . pda_label , state ) ;
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_SELECT ) ;
2019-05-25 16:52:36 +00:00
while ( get_aq_cmd_length ( ) > 0 ) { delay ( 500 ) ; }
2019-06-21 19:59:50 +00:00
// If you are turning on a heater there will be a sub menu to set temp
if ( ( state = = ON ) & & ( ( device = = POOL_HEAT_INDEX ) | | ( device = = SPA_HEAT_INDEX ) ) ) {
if ( ! waitForPDAnextMenu ( aq_data ) ) {
logMessage ( LOG_ERR , " PDA Device On/Off: %s on - waitForPDAnextMenu \n " ,
aq_data - > aqbuttons [ device ] . pda_label ) ;
} else {
send_cmd ( KEY_PDA_SELECT ) ;
while ( get_aq_cmd_length ( ) > 0 ) { delay ( 500 ) ; }
if ( ! waitForPDAMessageType ( aq_data , CMD_PDA_HIGHLIGHT , 20 ) ) {
logMessage ( LOG_ERR , " PDA Device On/Off: %s on - wait for CMD_PDA_HIGHLIGHT \n " ,
aq_data - > aqbuttons [ device ] . pda_label ) ;
}
}
} else { // not turning on heater wait for line update
// worst case spa when pool is running
if ( ! waitForPDAMessageType ( aq_data , CMD_MSG_LONG , 2 ) ) {
logMessage ( LOG_ERR , " PDA Device On/Off: %s on - wait for CMD_MSG_LONG \n " ,
aq_data - > aqbuttons [ device ] . pda_label ) ;
}
}
2019-05-25 16:52:36 +00:00
} else {
logMessage ( LOG_INFO , " PDA Device On/Off, found device '%s', not changing state, is same \n " , aq_data - > aqbuttons [ device ] . pda_label , state ) ;
}
} else {
logMessage ( LOG_ERR , " PDA Device On/Off, device '%s' not found \n " , aq_data - > aqbuttons [ device ] . pda_label ) ;
}
cleanAndTerminateThread ( threadCtrl ) ;
// just stop compiler error, ptr is not valid as it's just been freed
return ptr ;
}
void * get_aqualink_PDA_device_status ( void * ptr )
{
struct programmingThreadCtrl * threadCtrl ;
threadCtrl = ( struct programmingThreadCtrl * ) ptr ;
struct aqualinkdata * aq_data = threadCtrl - > aq_data ;
//int i;
waitForSingleThreadOrTerminate ( threadCtrl , AQ_PDA_DEVICE_STATUS ) ;
2019-06-21 19:59:50 +00:00
goto_pda_menu ( aq_data , PM_HOME ) ;
2019-05-25 16:52:36 +00:00
if ( ! loopover_devices ( aq_data ) ) {
logMessage ( LOG_ERR , " PDA Device Status :- failed \n " ) ;
}
cleanAndTerminateThread ( threadCtrl ) ;
// just stop compiler error, ptr is not valid as it's just been freed
return ptr ;
}
void * set_aqualink_PDA_init ( void * ptr )
{
struct programmingThreadCtrl * threadCtrl ;
threadCtrl = ( struct programmingThreadCtrl * ) ptr ;
struct aqualinkdata * aq_data = threadCtrl - > aq_data ;
//int i=0;
waitForSingleThreadOrTerminate ( threadCtrl , AQ_PDA_INIT ) ;
//int val = atoi((char*)threadCtrl->thread_args);
//logMessage(LOG_DEBUG, "PDA Init\n", val);
logMessage ( LOG_DEBUG , " PDA Init \n " ) ;
if ( pda_m_type ( ) = = PM_FW_VERSION ) {
// check pda_m_line(1) to "AquaPalm"
if ( strstr ( pda_m_line ( 1 ) , " AquaPalm " ) ! = NULL ) {
_PDA_Type = AQUAPALM ;
} else {
_PDA_Type = PDA ;
}
2019-06-27 22:18:44 +00:00
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 ) ) ;
2019-06-29 14:52:41 +00:00
//printf("****** Version '%s' ********\n",aq_data->version);
2019-06-21 19:59:50 +00:00
logMessage ( LOG_DEBUG , " PDA type=%d, version=%s \n " , _PDA_Type , aq_data - > version ) ;
// don't wait for version menu to time out press back to get to home menu faster
send_cmd ( KEY_PDA_BACK ) ;
if ( ! waitForPDAnextMenu ( aq_data ) ) {
logMessage ( LOG_ERR , " PDA Init :- wait for next menu failed " ) ;
}
}
else {
logMessage ( LOG_ERR , " PDA Init :- should be called when on FW VERSION menu. \n " ) ;
2019-05-25 16:52:36 +00:00
}
2019-07-14 14:39:15 +00:00
/*
2019-05-25 16:52:36 +00:00
// Get status of all devices
if ( ! loopover_devices ( aq_data ) ) {
logMessage ( LOG_ERR , " PDA Init :- can't find menu \n " ) ;
}
2019-07-14 14:39:15 +00:00
*/
2019-05-25 16:52:36 +00:00
// Get heater setpoints
if ( ! get_PDA_aqualink_pool_spa_heater_temps ( aq_data ) ) {
logMessage ( LOG_ERR , " PDA Init :- Error getting heater setpoints \n " ) ;
}
// Get freeze protect setpoint, AquaPalm doesn't have freeze protect in menu.
if ( _PDA_Type ! = AQUAPALM & & ! get_PDA_freeze_protect_temp ( aq_data ) ) {
logMessage ( LOG_ERR , " PDA Init :- Error getting freeze setpoints \n " ) ;
}
2019-08-09 03:21:09 +00:00
// shift line test
// goto_pda_menu(aq_data,PM_SYSTEM_SETUP);
// select_pda_menu_item(aq_data, "SERVICE INFO", true);
2019-05-25 16:52:36 +00:00
pda_reset_sleep ( ) ;
cleanAndTerminateThread ( threadCtrl ) ;
// just stop compiler error, ptr is not valid as it's just been freed
return ptr ;
}
void * set_aqualink_PDA_wakeinit ( void * ptr )
{
struct programmingThreadCtrl * threadCtrl ;
threadCtrl = ( struct programmingThreadCtrl * ) ptr ;
struct aqualinkdata * aq_data = threadCtrl - > aq_data ;
//int i=0;
// At this point, we should probably just exit if there is a thread already going as
// it means the wake was called due to changing a device.
2019-01-28 18:50:14 +00:00
waitForSingleThreadOrTerminate ( threadCtrl , AQ_PDA_WAKE_INIT ) ;
2019-05-25 16:52:36 +00:00
logMessage ( LOG_DEBUG , " PDA Wake Init \n " ) ;
// Get status of all devices
if ( ! loopover_devices ( aq_data ) ) {
logMessage ( LOG_ERR , " PDA Init :- can't find menu \n " ) ;
}
cleanAndTerminateThread ( threadCtrl ) ;
// just stop compiler error, ptr is not valid as it's just been freed
return ptr ;
}
bool get_PDA_freeze_protect_temp ( struct aqualinkdata * aq_data ) {
if ( _PDA_Type = = PDA ) {
if ( ! goto_pda_menu ( aq_data , PM_FREEZE_PROTECT ) ) {
return false ;
}
2019-08-05 17:50:26 +00:00
/* select the freeze protect temp to see which devices are enabled by freeze
protect */
send_cmd ( KEY_PDA_SELECT ) ;
return waitForPDAnextMenu ( aq_data ) ;
2019-05-25 16:52:36 +00:00
} else {
logMessage ( LOG_INFO , " In PDA AquaPalm mode, freezepoints not supported \n " ) ;
return false ;
}
}
bool get_PDA_aqualink_pool_spa_heater_temps ( struct aqualinkdata * aq_data ) {
// Get heater setpoints
if ( ! goto_pda_menu ( aq_data , PM_SET_TEMP ) ) {
return false ;
}
return true ;
}
bool waitForPDAMessageHighlight ( struct aqualinkdata * aq_data , int highlighIndex , int numMessageReceived )
{
logMessage ( LOG_DEBUG , " waitForPDAMessageHighlight index %d \n " , highlighIndex ) ;
if ( pda_m_hlightindex ( ) = = highlighIndex ) return true ;
int i = 0 ;
pthread_mutex_lock ( & aq_data - > active_thread . thread_mutex ) ;
while ( + + i < = numMessageReceived )
{
logMessage ( LOG_DEBUG , " waitForPDAMessageHighlight last = 0x%02hhx : index %d : (%d of %d) \n " , aq_data - > last_packet_type , pda_m_hlightindex ( ) , i , numMessageReceived ) ;
if ( aq_data - > last_packet_type = = CMD_PDA_HIGHLIGHT & & pda_m_hlightindex ( ) = = highlighIndex ) break ;
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 ( pda_m_hlightindex ( ) ! = highlighIndex ) {
//logMessage(LOG_ERR, "Could not select MENU of Aqualink control panel\n");
logMessage ( LOG_DEBUG , " waitForPDAMessageHighlight: did not receive index '%d' \n " , highlighIndex ) ;
return false ;
} else
logMessage ( LOG_DEBUG , " waitForPDAMessageHighlight: received index '%d' \n " , highlighIndex ) ;
return true ;
}
bool waitForPDAMessageType ( struct aqualinkdata * aq_data , unsigned char mtype , int numMessageReceived )
{
logMessage ( LOG_DEBUG , " waitForPDAMessageType 0x%02hhx \n " , mtype ) ;
int i = 0 ;
pthread_mutex_lock ( & aq_data - > active_thread . thread_mutex ) ;
while ( + + i < = numMessageReceived )
{
logMessage ( LOG_DEBUG , " waitForPDAMessageType 0x%02hhx, last message type was 0x%02hhx (%d of %d) \n " , mtype , aq_data - > last_packet_type , i , numMessageReceived ) ;
if ( aq_data - > last_packet_type = = mtype ) break ;
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 ! = mtype ) {
//logMessage(LOG_ERR, "Could not select MENU of Aqualink control panel\n");
logMessage ( LOG_DEBUG , " waitForPDAMessageType: did not receive 0x%02hhx \n " , mtype ) ;
return false ;
} else
logMessage ( LOG_DEBUG , " waitForPDAMessageType: received 0x%02hhx \n " , mtype ) ;
return true ;
}
2019-07-01 14:16:00 +00:00
// Wait for Message, hit return on particular menu.
bool waitForPDAMessageTypesOrMenu ( struct aqualinkdata * aq_data , unsigned char mtype1 , unsigned char mtype2 , int numMessageReceived , char * text , int line )
2019-06-27 22:18:44 +00:00
{
logMessage ( LOG_DEBUG , " waitForPDAMessageTypes 0x%02hhx or 0x%02hhx \n " , mtype1 , mtype2 ) ;
int i = 0 ;
2019-07-01 14:16:00 +00:00
bool gotmenu = false ;
2019-06-27 22:18:44 +00:00
pthread_mutex_lock ( & aq_data - > active_thread . thread_mutex ) ;
while ( + + i < = numMessageReceived )
{
2019-07-01 14:16:00 +00:00
if ( gotmenu = = false & & line > 0 & & text ! = NULL ) {
if ( stristr ( pda_m_line ( line ) , text ) ! = NULL ) {
send_cmd ( KEY_PDA_SELECT ) ;
gotmenu = true ;
logMessage ( LOG_DEBUG , " waitForPDAMessageTypesOrMenu saw '%s' and line %d \n " , text , line ) ;
}
}
2019-06-27 22:18:44 +00:00
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_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");
2019-07-01 14:16:00 +00:00
logMessage ( LOG_ERR , " waitForPDAMessageTypes: did not receive 0x%02hhx or 0x%02hhx \n " , mtype1 , mtype2 ) ;
2019-06-27 22:18:44 +00:00
return false ;
} else
logMessage ( LOG_DEBUG , " waitForPDAMessageTypes: received 0x%02hhx \n " , aq_data - > last_packet_type ) ;
return true ;
}
2019-07-01 14:16:00 +00:00
bool waitForPDAMessageTypes ( struct aqualinkdata * aq_data , unsigned char mtype1 , unsigned char mtype2 , int numMessageReceived )
{
return waitForPDAMessageTypesOrMenu ( aq_data , mtype1 , mtype2 , numMessageReceived , NULL , 0 ) ;
}
2019-05-25 16:52:36 +00:00
bool set_PDA_numeric_field_value ( struct aqualinkdata * aq_data , int val , int * cur_val , char * select_label , int step ) {
2019-06-27 22:45:55 +00:00
int i = 0 ;
2019-05-25 16:52:36 +00:00
2019-08-05 17:50:26 +00:00
if ( val = = * cur_val ) {
logMessage ( LOG_INFO , " PDA %s value : already at %d \n " , select_label , val ) ;
return true ;
}
if ( select_label ! = NULL ) {
// :TODO: Should probably change below to call find_pda_menu_item(), rather than doing it here
// If we lease this, need to limit on the number of loops
2019-08-09 03:21:09 +00:00
while ( strncasecmp ( pda_m_hlight ( ) , select_label , strlen ( select_label ) ) ! = 0 ) {
2019-08-05 17:50:26 +00:00
send_cmd ( KEY_PDA_DOWN ) ;
delay ( 500 ) ; // Last message probably was CMD_PDA_HIGHLIGHT, so wait before checking.
waitForPDAMessageType ( aq_data , CMD_PDA_HIGHLIGHT , 2 ) ;
if ( i > 10 ) {
logMessage ( LOG_ERR , " PDA numeric selector could not find string '%s' \n " , select_label ) ;
return false ;
}
i + + ;
2019-06-27 22:45:55 +00:00
}
2019-08-05 17:50:26 +00:00
send_cmd ( KEY_PDA_SELECT ) ;
2019-05-25 16:52:36 +00:00
}
if ( val < * cur_val ) {
logMessage ( LOG_DEBUG , " PDA %s value : lower from %d to %d \n " , select_label , * cur_val , val ) ;
for ( i = * cur_val ; i > val ; i = i - step ) {
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_DOWN ) ;
2019-05-25 16:52:36 +00:00
}
} else if ( val > * cur_val ) {
logMessage ( LOG_DEBUG , " PDA %s value : raise from %d to %d \n " , select_label , * cur_val , val ) ;
for ( i = * cur_val ; i < val ; i = i + step ) {
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_UP ) ;
2019-05-25 16:52:36 +00:00
}
} else {
logMessage ( LOG_INFO , " PDA %s value : already at %d \n " , select_label , val ) ;
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_BACK ) ;
2019-05-25 16:52:36 +00:00
return true ;
}
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_SELECT ) ;
2019-05-25 16:52:36 +00:00
logMessage ( LOG_DEBUG , " PDA %s value : set to %d \n " , select_label , * cur_val ) ;
return true ;
}
bool set_PDA_aqualink_SWG_setpoint ( struct aqualinkdata * aq_data , int val ) {
if ( ! goto_pda_menu ( aq_data , PM_AQUAPURE ) ) {
2019-07-01 14:16:00 +00:00
logMessage ( LOG_ERR , " Error finding SWG setpoints menu \n " ) ;
2019-05-25 16:52:36 +00:00
}
if ( aq_data - > aqbuttons [ SPA_INDEX ] . led - > state ! = OFF )
2019-07-01 14:16:00 +00:00
return set_PDA_numeric_field_value ( aq_data , val , & aq_data - > swg_percent , " SET SPA " , 5 ) ;
2019-05-25 16:52:36 +00:00
else
2019-07-01 14:16:00 +00:00
return set_PDA_numeric_field_value ( aq_data , val , & aq_data - > swg_percent , " SET POOL " , 5 ) ;
2019-05-25 16:52:36 +00:00
2019-07-01 14:16:00 +00:00
//return true;
2019-05-25 16:52:36 +00:00
}
bool set_PDA_aqualink_heater_setpoint ( struct aqualinkdata * aq_data , int val , bool isPool ) {
char label [ 10 ] ;
int * cur_val ;
2019-06-27 22:18:44 +00:00
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 ;
}
2019-05-25 16:52:36 +00:00
} else {
2019-06-27 22:18:44 +00:00
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 ;
}
2019-05-25 16:52:36 +00:00
}
if ( val = = * cur_val ) {
logMessage ( LOG_INFO , " PDA %s setpoint : temp already %d \n " , label , val ) ;
2019-06-05 16:41:38 +00:00
send_cmd ( KEY_PDA_BACK ) ;
2019-05-25 16:52:36 +00:00
return true ;
}
if ( ! goto_pda_menu ( aq_data , PM_SET_TEMP ) ) {
2019-07-01 14:16:00 +00:00
logMessage ( LOG_ERR , " Error finding heater setpoints menu \n " ) ;
return false ;
2019-05-25 16:52:36 +00:00
}
set_PDA_numeric_field_value ( aq_data , val , cur_val , label , 1 ) ;
return true ;
}
bool set_PDA_aqualink_freezeprotect_setpoint ( struct aqualinkdata * aq_data , int val ) {
2019-08-05 17:50:26 +00:00
if ( _PDA_Type ! = PDA ) {
logMessage ( LOG_INFO , " In PDA AquaPalm mode, freezepoints not supported \n " ) ;
return false ;
} else if ( ! goto_pda_menu ( aq_data , PM_FREEZE_PROTECT ) ) {
2019-07-01 14:16:00 +00:00
logMessage ( LOG_ERR , " Error finding freeze protect setpoints menu \n " ) ;
return false ;
2019-08-05 17:50:26 +00:00
} else if ( ! set_PDA_numeric_field_value ( aq_data , val , & aq_data - > frz_protect_set_point , NULL , 1 ) ) {
logMessage ( LOG_ERR , " Error failed to set freeze protect temp value \n " ) ;
return false ;
} else {
return waitForPDAnextMenu ( aq_data ) ;
2019-05-25 16:52:36 +00:00
}
}
2019-07-14 14:39:15 +00:00
// Test ine this.
bool get_PDA_aqualink_aux_labels ( struct aqualinkdata * aq_data ) {
# ifdef BETA_PDA_AUTOLABEL
int i = 0 ;
char label [ 10 ] ;
logMessage ( LOG_INFO , " Finding PDA labels, (BETA ONLY) \n " ) ;
if ( ! goto_pda_menu ( aq_data , PM_AUX_LABEL ) ) {
logMessage ( LOG_ERR , " Error finding aux label menu \n " ) ;
return false ;
}
for ( i = 1 ; i < 8 ; i + + ) {
sprintf ( label , " AUX%d " , i ) ;
select_pda_menu_item ( aq_data , label , true ) ;
send_cmd ( KEY_PDA_BACK ) ;
waitForPDAnextMenu ( aq_data ) ;
}
// Read first page of devices and make some assumptions.
# endif
return true ;
}
2019-05-25 16:52:36 +00:00
/*
bool waitForPDAMessage ( struct aqualinkdata * aq_data , int numMessageReceived , unsigned char packettype )
{
logMessage ( LOG_DEBUG , " waitForPDAMessage %s %d \n " , message , numMessageReceived ) ;
int i = 0 ;
pthread_mutex_init ( & aq_data - > active_thread . thread_mutex , NULL ) ;
pthread_mutex_lock ( & aq_data - > active_thread . thread_mutex ) ;
char * msgS ;
char * ptr ;
if ( message ! = NULL ) {
if ( message [ 0 ] = = ' ^ ' )
msgS = & message [ 1 ] ;
else
msgS = message ;
}
while ( + + i < = numMessageReceived )
{
if ( message ! = NULL )
logMessage ( LOG_DEBUG , " Programming mode: loop %d of %d looking for '%s' received message '%s' \n " , i , numMessageReceived , message , aq_data - > last_message ) ;
else
logMessage ( LOG_DEBUG , " Programming mode: loop %d of %d waiting for next message, received '%s' \n " , i , numMessageReceived , aq_data - > last_message ) ;
if ( message ! = NULL ) {
ptr = stristr ( aq_data - > last_message , msgS ) ;
if ( ptr ! = NULL ) { // match
logMessage ( LOG_DEBUG , " Programming mode: String MATCH \n " ) ;
if ( msgS = = message ) // match & don't care if first char
break ;
else if ( ptr = = aq_data - > last_message ) // match & do care if first char
break ;
}
}
//logMessage(LOG_DEBUG, "Programming mode: looking for '%s' received message '%s'\n",message,aq_data->last_message);
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 ) ;
//logMessage(LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message);
}
pthread_mutex_unlock ( & aq_data - > active_thread . thread_mutex ) ;
if ( message ! = NULL & & ptr = = NULL ) {
//logMessage(LOG_ERR, "Could not select MENU of Aqualink control panel\n");
logMessage ( LOG_DEBUG , " Programming mode: did not find '%s' \n " , message ) ;
return false ;
} else if ( message ! = NULL )
logMessage ( LOG_DEBUG , " Programming mode: found message '%s' in '%s' \n " , message , aq_data - > last_message ) ;
return true ;
}
*/
/*
Link to two different menu ' s used in PDA
http : //www.poolequipmentpriceslashers.com.au/wp-content/uploads/2012/11/Jandy-Aqualink-RS-PDA-Wireless-Pool-Controller_manual.pdf
https : //www.jandy.com/-/media/zodiac/global/downloads/h/h0574200.pdf
*/
/*
List of how menu ' s display
PDA Line 0 =
PDA Line 1 = AquaPalm
PDA Line 2 =
PDA Line 3 = Firmware Version
PDA Line 4 =
PDA Line 5 = REV MMM
PDA Line 6 =
PDA Line 7 =
PDA Line 8 =
PDA Line 9 =
2019-06-05 16:41:38 +00:00
PDA Line 0 =
PDA Line 1 = AquaPalm
PDA Line 2 =
PDA Line 3 = Firmware Version
PDA Line 4 =
PDA Line 5 = REV T
PDA Line 6 =
PDA Line 7 =
PDA Line 8 =
PDA Line 9 =
2019-06-27 22:18:44 +00:00
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 * * * * * * * * *
2019-05-25 16:52:36 +00:00
* * * * * * * * * * * * * * * * * Think this is startup different rev * * * * * * * * * * * * *
2019-06-27 22:18:44 +00:00
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
2019-05-25 16:52:36 +00:00
PDA Line 0 =
PDA Line 1 = AIR POOL
PDA Line 2 =
PDA Line 3 =
PDA Line 4 = POOL MODE ON
PDA Line 5 = POOL HEATER OFF
PDA Line 6 = SPA MODE OFF
PDA Line 7 = SPA HEATER OFF
PDA Line 8 = MENU
PDA Line 9 = EQUIPMENT ON / OFF
PDA Line 0 = MAIN MENU
PDA Line 1 =
PDA Line 2 = SET TEMP >
PDA Line 3 = SET TIME >
PDA Line 4 = SET AquaPure >
PDA Line 5 = PALM OPTIONS >
PDA Line 6 =
PDA Line 7 = BOOST POOL
PDA Line 8 =
PDA Line 9 =
* * * * * * * * * * * * * * * * OPTION 2 FOR THIS MENU * * * * * * * * * * * * * * * * * * * *
PDA Line 0 = MAIN MENU
PDA Line 1 =
PDA Line 2 = HELP >
PDA Line 3 = PROGRAM >
PDA Line 4 = SET TEMP >
PDA Line 5 = SET TIME >
PDA Line 6 = PDA OPTIONS >
PDA Line 7 = SYSTEM SETUP >
PDA Line 8 =
PDA Line 9 = BOOST
* * * * * * * * * * Guess at SYSTEM SETUP Menu ( not on Rev MMM or before ) * * * * * * * * * * * *
// PDA Line 0 = SYSTEM SETUP
// PDA Line 1 = LABEL AUX >
// PDA Line 2 = FREEZE PROTECT >
// PDA Line 3 = AIR TEMP >
// PDA Line 4 = DEGREES C/F >
// PDA Line 5 = TEMP CALIBRATE >
// PDA Line 6 = SOLAR PRIORITY >
// PDA Line 7 = PUMP LOCKOUT >
// PDA Line 8 = ASSIGN JVAs >
// PDA Line 9 = ^^ MORE __
// PDA Line 5 = COLOR LIGHTS >
// PDA Line 6 = SPA SWITCH >
// PDA Line 7 = SERVICE INFO >
// PDA Line 8 = CLEAR MEMORY >
PDA Line 0 = PALM OPTIONS
PDA Line 1 =
PDA Line 2 =
PDA Line 3 = SET AUTO - OFF >
PDA Line 4 = BACKLIGHT >
PDA Line 5 = ASSIGN HOTKEYS >
PDA Line 6 =
PDA Line 7 = Choose setting
PDA Line 8 = and press SELECT
PDA Line 9 =
PDA Line 0 = SET AquaPure
PDA Line 1 =
PDA Line 2 =
PDA Line 3 = SET POOL TO : 45 %
PDA Line 4 = SET SPA TO : 0 %
PDA Line 5 =
PDA Line 6 =
PDA Line 7 = Highlight an
PDA Line 8 = item and press
PDA Line 9 = SELECT
PDA Line 0 = SET TIME
PDA Line 1 =
PDA Line 2 = 05 / 22 / 19 WED
PDA Line 3 = 10 : 53 AM
PDA Line 4 =
PDA Line 5 =
PDA Line 6 = Use ARROW KEYS
PDA Line 7 = to set value .
PDA Line 8 = Press SELECT
PDA Line 9 = to continue .
PDA Line 0 = SET TEMP
PDA Line 1 =
PDA Line 2 = POOL HEAT 70 ` F
PDA Line 3 = SPA HEAT 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
2019-06-27 22:18:44 +00:00
* * * * * * * 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
2019-05-25 16:52:36 +00:00
PDA Line 0 = EQUIPMENT
PDA Line 1 = FILTER PUMP ON
PDA Line 2 = SPA OFF
PDA Line 3 = POOL HEAT OFF
PDA Line 4 = SPA HEAT OFF
PDA Line 5 = CLEANER ON
PDA Line 6 = WATERFALL OFF
PDA Line 7 = AIR BLOWER OFF
PDA Line 8 = LIGHT OFF
PDA Line 9 = ^ ^ MORE __
PDA Line 0 = EQUIPMENT
PDA Line 1 = WATERFALL OFF
PDA Line 2 = AIR BLOWER OFF
PDA Line 3 = LIGHT OFF
PDA Line 4 = AUX5 OFF
PDA Line 5 = EXTRA AUX OFF
PDA Line 6 = SPA MODE OFF
PDA Line 7 = CLEAN MODE OFF
PDA Line 8 = ALL OFF
PDA Line 9 =
2019-06-27 23:07:28 +00:00
// This is from a single device setup (pool OR spa not pool AND spa)
PDA Menu Line 0 = EQUIPMENT
PDA Menu Line 1 =
PDA Menu Line 2 = FILTER PUMP ON
PDA Menu Line 3 = TEMP1 OFF
PDA Menu Line 4 = TEMP2 OFF
PDA Menu Line 5 = AUX1 OFF
PDA Menu Line 6 = Pool Light ON
PDA Menu Line 7 = AUX3 OFF
PDA Menu Line 8 = EXTRA AUX OFF
PDA Menu Line 9 = ALL OFF
2019-06-05 16:41:38 +00:00
PDA Line 0 = Equipment Status
PDA Line 1 =
PDA Line 2 = Intelliflo VS 1
PDA Line 3 = RPM : 1700
PDA Line 4 = Watts : 367
PDA Line 5 =
PDA Line 6 =
PDA Line 7 =
PDA Line 8 =
PDA Line 9 =
PDA Line 0 = Equipment Status
PDA Line 1 =
PDA Line 2 = AquaPure 20 %
PDA Line 3 = Salt 4000 PPM
PDA Line 4 =
PDA Line 5 =
PDA Line 6 =
PDA Line 7 =
PDA Line 8 =
PDA Line 9 =
2019-06-07 21:31:06 +00:00
VSP Motes .
four types of variable speed pumps ,
Jandy ePumpTM DC ,
Jandy ePumpTM AC ,
IntelliFlo ® 1 VF ,
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 .
2019-06-27 22:18:44 +00:00
*/