mirror of https://github.com/sfeakes/AqualinkD.git
1032 lines
35 KiB
C
1032 lines
35 KiB
C
/*
|
|
* 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
|
|
*/
|
|
|
|
#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 "allbutton_aq_programmer.h"
|
|
|
|
#ifdef AQ_PDA
|
|
#include "pda.h"
|
|
#include "pda_menu.h"
|
|
#include "pda_aq_programmer.h"
|
|
#endif
|
|
|
|
#include "aq_panel.h"
|
|
#include "onetouch_aq_programmer.h"
|
|
#include "iaqtouch_aq_programmer.h"
|
|
#include "serialadapter.h"
|
|
#include "color_lights.h"
|
|
#include "config.h"
|
|
#include "devices_jandy.h"
|
|
#include "iaqualink.h"
|
|
|
|
#ifdef AQ_DEBUG
|
|
#include <time.h>
|
|
#include "timespec_subtract.h"
|
|
#endif
|
|
|
|
void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data, bool allowOveride);
|
|
|
|
|
|
// Lookup table for programming function to protocal we will use for programming panel
|
|
// Should be one function per program_type enum.
|
|
/*
|
|
static void * (*_prog_functions[])(void *ptr) = {
|
|
*/
|
|
typedef void *(*func_ptr)(void *ptr);
|
|
|
|
const func_ptr _prog_functions[AQP_RSSADAPTER_MAX] = {
|
|
[AQ_GET_POOL_SPA_HEATER_TEMPS] = get_allbutton_pool_spa_heater_temps,
|
|
[AQ_GET_FREEZE_PROTECT_TEMP] = get_allbutton_freeze_protect_temp,
|
|
[AQ_SET_TIME] = set_allbutton_time,
|
|
[AQ_SET_POOL_HEATER_TEMP] = set_allbutton_pool_heater_temps,
|
|
[AQ_SET_SPA_HEATER_TEMP] = set_allbutton_spa_heater_temps,
|
|
[AQ_SET_FRZ_PROTECTION_TEMP] = set_allbutton_freeze_heater_temps,
|
|
[AQ_GET_DIAGNOSTICS_MODEL] = get_allbutton_diag_model,
|
|
[AQ_GET_PROGRAMS] = get_allbutton_programs,
|
|
[AQ_SET_LIGHTPROGRAM_MODE] = set_allbutton_light_programmode,
|
|
[AQ_SET_LIGHTCOLOR_MODE] = set_allbutton_light_colormode,
|
|
[AQ_SET_SWG_PERCENT] = set_allbutton_SWG,
|
|
[AQ_GET_AUX_LABELS] = get_allbutton_aux_labels,
|
|
[AQ_SET_BOOST] = set_allbutton_boost,
|
|
[AQ_SET_ONETOUCH_PUMP_RPM] = set_aqualink_onetouch_pump_rpm,
|
|
[AQ_GET_ONETOUCH_FREEZEPROTECT] = get_aqualink_onetouch_freezeprotect,
|
|
[AQ_GET_ONETOUCH_SETPOINTS] = get_aqualink_onetouch_setpoints,
|
|
[AQ_SET_ONETOUCH_TIME] = set_aqualink_onetouch_time,
|
|
[AQ_SET_ONETOUCH_BOOST] = set_aqualink_onetouch_boost,
|
|
[AQ_SET_ONETOUCH_SWG_PERCENT] = set_aqualink_onetouch_swg_percent,
|
|
[AQ_SET_ONETOUCH_POOL_HEATER_TEMP]= set_aqualink_onetouch_pool_heater_temp,
|
|
[AQ_SET_ONETOUCH_SPA_HEATER_TEMP] = set_aqualink_onetouch_spa_heater_temp,
|
|
[AQ_SET_ONETOUCH_FREEZEPROTECT] = set_aqualink_onetouch_freezeprotect,
|
|
[AQ_SET_IAQTOUCH_PUMP_RPM] = set_aqualink_iaqtouch_pump_rpm,
|
|
[AQ_GET_IAQTOUCH_VSP_ASSIGNMENT] = set_aqualink_iaqtouch_vsp_assignments,
|
|
[AQ_GET_IAQTOUCH_SETPOINTS] = get_aqualink_iaqtouch_setpoints,
|
|
[AQ_GET_IAQTOUCH_FREEZEPROTECT] = get_aqualink_iaqtouch_freezeprotect,
|
|
[AQ_GET_IAQTOUCH_AUX_LABELS] = get_aqualink_iaqtouch_aux_labels,
|
|
[AQ_SET_IAQTOUCH_SWG_PERCENT] = set_aqualink_iaqtouch_swg_percent,
|
|
[AQ_SET_IAQTOUCH_SWG_BOOST] = set_aqualink_iaqtouch_swg_boost,
|
|
[AQ_SET_IAQTOUCH_POOL_HEATER_TEMP]= set_aqualink_iaqtouch_pool_heater_temp,
|
|
[AQ_SET_IAQTOUCH_SPA_HEATER_TEMP] = set_aqualink_iaqtouch_spa_heater_temp,
|
|
[AQ_SET_IAQTOUCH_SET_TIME] = set_aqualink_iaqtouch_time,
|
|
[AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM] = set_aqualink_iaqtouch_pump_vs_program,
|
|
[AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE] = set_aqualink_iaqtouch_light_colormode,
|
|
[AQ_SET_IAQTOUCH_DEVICE_ON_OFF] = set_aqualink_iaqtouch_device_on_off,
|
|
//[AQ_SET_IAQTOUCH_ONETOUCH_ON_OFF] = set_aqualink_iaqtouch_onetouch_on_off, // Not finished and not needed
|
|
[AQ_PDA_INIT] = set_aqualink_PDA_init,
|
|
[AQ_PDA_WAKE_INIT] = set_aqualink_PDA_wakeinit,
|
|
[AQ_PDA_DEVICE_STATUS] = get_aqualink_PDA_device_status,
|
|
[AQ_PDA_DEVICE_ON_OFF] = set_aqualink_PDA_device_on_off,
|
|
[AQ_PDA_SET_BOOST] = set_PDA_aqualink_boost,
|
|
[AQ_PDA_SET_SWG_PERCENT] = set_PDA_aqualink_SWG_setpoint,
|
|
[AQ_PDA_GET_AUX_LABELS] = get_PDA_aqualink_aux_labels,
|
|
[AQ_PDA_SET_POOL_HEATER_TEMPS] = set_aqualink_PDA_pool_heater_temps,
|
|
[AQ_PDA_SET_SPA_HEATER_TEMPS] = set_aqualink_PDA_spa_heater_temps,
|
|
[AQ_PDA_SET_FREEZE_PROTECT_TEMP] = set_aqualink_PDA_freeze_protectsetpoint,
|
|
[AQ_PDA_SET_TIME] = set_PDA_aqualink_time,
|
|
//[AQ_PDA_GET_POOL_SPA_HEATER_TEMPS]= get_aqualink_PDA_pool_spa_heater_temps,
|
|
[AQ_PDA_GET_FREEZE_PROTECT_TEMP] = get_PDA_aqualink_pool_spa_heater_temps
|
|
/*
|
|
[AQ_PDA_SET_BOOST] = set_PDA_aqualink_boost
|
|
[AQ_PDA_SET_SWG_PERCENT] = set_PDA_aqualink_SWG_setpoint
|
|
[AQ_PDA_GET_AUX_LABELS] = get_PDA_aqualink_aux_labels
|
|
*/
|
|
|
|
};
|
|
|
|
|
|
int roundTo(int num, int denominator) {
|
|
return ((num + (denominator/2) ) / denominator )* denominator;
|
|
}
|
|
|
|
//(Intelliflo VF you set GPM, not RPM)
|
|
int RPM_check(pump_type type, int value, struct aqualinkdata *aqdata)
|
|
{
|
|
int rtn = value;
|
|
// RPM 3450 seems to be max
|
|
// RPM 600 min
|
|
// GPM 130 max
|
|
// GPM 15 min
|
|
if (type == VFPUMP) {
|
|
if (rtn > 130)
|
|
rtn = 130;
|
|
else if (rtn < 15)
|
|
rtn = 15;
|
|
else
|
|
rtn = roundTo(rtn, 5);
|
|
} else {
|
|
if (rtn > 3450)
|
|
rtn = 3450;
|
|
else if (rtn < 600)
|
|
rtn = 600;
|
|
else
|
|
rtn = roundTo(rtn, 5);
|
|
}
|
|
|
|
return rtn;
|
|
}
|
|
|
|
int setpoint_check(int type, int value, struct aqualinkdata *aqdata)
|
|
{
|
|
int rtn = value;
|
|
int max = 0;
|
|
int min = 0;
|
|
char *type_msg;
|
|
|
|
switch(type) {
|
|
case POOL_HTR_SETOINT:
|
|
type_msg = (isSINGLE_DEV_PANEL?"Temp1":"Pool");
|
|
if ( aqdata->temp_units == CELSIUS ) {
|
|
max = HEATER_MAX_C;
|
|
min = (isSINGLE_DEV_PANEL?HEATER_MIN_C+1:HEATER_MIN_C);
|
|
} else {
|
|
max = HEATER_MAX_F;
|
|
min = (isSINGLE_DEV_PANEL?HEATER_MIN_F+1:HEATER_MIN_F);
|
|
}
|
|
// if single device then TEMP1 & 2 (not pool & spa), TEMP1 must be set higher than TEMP2
|
|
if (isSINGLE_DEV_PANEL &&
|
|
aqdata->spa_htr_set_point != TEMP_UNKNOWN &&
|
|
min <= aqdata->spa_htr_set_point)
|
|
{
|
|
min = aqdata->spa_htr_set_point + 1;
|
|
}
|
|
break;
|
|
case SPA_HTR_SETOINT:
|
|
type_msg = (isSINGLE_DEV_PANEL?"Temp2":"Spa");
|
|
if ( aqdata->temp_units == CELSIUS ) {
|
|
max = (isSINGLE_DEV_PANEL?HEATER_MAX_C-1:HEATER_MAX_C);
|
|
min = HEATER_MIN_C;
|
|
} else {
|
|
max = (isSINGLE_DEV_PANEL?HEATER_MAX_F-1:HEATER_MAX_F);
|
|
min = HEATER_MIN_F;
|
|
}
|
|
// if single device then TEMP1 & 2 (not pool & spa), TEMP2 must be set lower than TEMP1
|
|
if (isSINGLE_DEV_PANEL &&
|
|
aqdata->pool_htr_set_point != TEMP_UNKNOWN &&
|
|
max >= aqdata->pool_htr_set_point)
|
|
{
|
|
max = aqdata->pool_htr_set_point - 1;
|
|
}
|
|
break;
|
|
case FREEZE_SETPOINT:
|
|
type_msg = "Freeze protect";
|
|
if ( aqdata->temp_units == CELSIUS ) {
|
|
max = FREEZE_PT_MAX_C;
|
|
min = FREEZE_PT_MIN_C;
|
|
} else {
|
|
max = FREEZE_PT_MAX_F;
|
|
min = FREEZE_PT_MIN_F;
|
|
}
|
|
break;
|
|
case SWG_SETPOINT:
|
|
type_msg = "Salt Water Generator";
|
|
max = SWG_PERCENT_MAX;
|
|
min = SWG_PERCENT_MIN;
|
|
break;
|
|
default:
|
|
type_msg = "Unknown";
|
|
break;
|
|
}
|
|
|
|
if (rtn > max)
|
|
rtn = max;
|
|
else if (rtn < min)
|
|
rtn = min;
|
|
|
|
// If SWG make sure it's 0,5,10,15,20......
|
|
if (type == SWG_SETPOINT) {
|
|
rtn = roundTo(rtn, 5);
|
|
}
|
|
|
|
if (rtn != value)
|
|
LOG(PROG_LOG, LOG_WARNING, "Setpoint of %d for %s is outside range, using %d\n",value,type_msg,rtn);
|
|
//else
|
|
// LOG(PROG_LOG, LOG_NOTICE, "Setting setpoint of %s to %d\n",type_msg,rtn);
|
|
|
|
return rtn;
|
|
}
|
|
|
|
/*
|
|
Figure out the fastest way in get all needed startup data depending on what protocols
|
|
are available and what's just called us
|
|
*/
|
|
void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_data)
|
|
{
|
|
LOG(PROG_LOG, LOG_INFO, "Initial setup call from %s with RSSA=%s ONETouch=%s IAQTouch=%s ExtendedProgramming=%s\n",
|
|
(source_type == ALLBUTTON)?"AllButton":((source_type == RSSADAPTER)?"RSSA":((source_type == ONETOUCH)?"OneTouch":((source_type == IAQTOUCH)?"IAQTouch":"PDA"))),
|
|
(isRSSA_ENABLED)?"enabled":"disabled",
|
|
(isONET_ENABLED)?"enabled":"disabled",
|
|
(isIAQT_ENABLED)?"enabled":"disabled",
|
|
(isEXTP_ENABLED)?"enabled":"disabled"
|
|
);
|
|
|
|
if (isRSSA_ENABLED && isEXTP_ENABLED == true) {
|
|
// serial adapter enabled and extended programming
|
|
if (source_type == RSSADAPTER) {
|
|
_aq_programmer(AQ_GET_RSSADAPTER_SETPOINTS, NULL, aq_data, false);
|
|
} else if (source_type == ONETOUCH && isEXTP_ENABLED) {
|
|
//_aq_programmer(AQ_GET_ONETOUCH_FREEZEPROTECT, NULL, aq_data, false); // Add back and remove below once tested and working
|
|
//_aq_programmer(AQ_GET_ONETOUCH_SETPOINTS, NULL, aq_data, false);
|
|
} else if (source_type == IAQTOUCH && isEXTP_ENABLED) {
|
|
//_aq_programmer(AQ_GET_IAQTOUCH_FREEZEPROTECT, NULL, aq_data, false); // Add back and remove below once tested and working
|
|
//_aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aq_data, false); // This get's freeze & heaters, we should just get freeze if isRSSA_ENABLED
|
|
} else if (source_type == ALLBUTTON) {
|
|
_aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aq_data, false); // This is still quicker that IAQ or ONE Touch protocols at the moment.
|
|
if (_aqconfig_.use_panel_aux_labels) {
|
|
_aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data, false);
|
|
}
|
|
}
|
|
} else if (isRSSA_ENABLED && isEXTP_ENABLED == false) {
|
|
// serial adapter enabled with no extended programming
|
|
if (source_type == RSSADAPTER) {
|
|
_aq_programmer(AQ_GET_RSSADAPTER_SETPOINTS, NULL, aq_data, false);
|
|
} else if (source_type == ALLBUTTON) {
|
|
_aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aq_data, false);
|
|
if (_aqconfig_.use_panel_aux_labels) {
|
|
_aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data, false);
|
|
}
|
|
}
|
|
} else if (!isRSSA_ENABLED && isEXTP_ENABLED && isONET_ENABLED) {
|
|
// One touch extended and no serial adapter
|
|
if (source_type == ONETOUCH) {
|
|
_aq_programmer(AQ_GET_ONETOUCH_SETPOINTS, NULL, aq_data, false);
|
|
} else if (source_type == ALLBUTTON) {
|
|
if (_aqconfig_.use_panel_aux_labels) {
|
|
_aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data, false);
|
|
}
|
|
}
|
|
} else if (!isRSSA_ENABLED && isEXTP_ENABLED && isIAQT_ENABLED) {
|
|
// IAQ touch extended and no serial adapter
|
|
if (source_type == IAQTOUCH) {
|
|
_aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aq_data, false);
|
|
} else if (source_type == ALLBUTTON) {
|
|
if (_aqconfig_.use_panel_aux_labels) {
|
|
_aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data, false);
|
|
}
|
|
}
|
|
#ifdef AQ_PDA
|
|
} else if ( isPDA_PANEL && source_type == AQUAPDA) {
|
|
aq_programmer(AQ_PDA_INIT, NULL, aq_data);
|
|
} else if ( isPDA_PANEL && source_type == IAQTOUCH) {
|
|
//aq_programmer(AQ_PDA_INIT, NULL, aq_data);
|
|
if (_aqconfig_.use_panel_aux_labels) {
|
|
aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data);
|
|
}
|
|
aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aq_data);
|
|
|
|
#endif
|
|
} else { // Must be all button only
|
|
aq_programmer(AQ_GET_POOL_SPA_HEATER_TEMPS, NULL, aq_data);
|
|
aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aq_data);
|
|
if (_aqconfig_.use_panel_aux_labels) {
|
|
aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool in_light_programming_mode(struct aqualinkdata *aq_data)
|
|
{
|
|
if ( ( aq_data->active_thread.thread_id != 0 ) &&
|
|
( aq_data->active_thread.ptype == AQ_SET_LIGHTPROGRAM_MODE ||
|
|
aq_data->active_thread.ptype == AQ_SET_LIGHTCOLOR_MODE ||
|
|
aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE)
|
|
) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool in_swg_programming_mode(struct aqualinkdata *aq_data)
|
|
{
|
|
if ( ( aq_data->active_thread.thread_id != 0 ) &&
|
|
( aq_data->active_thread.ptype == AQ_SET_ONETOUCH_SWG_PERCENT ||
|
|
aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_SWG_PERCENT ||
|
|
aq_data->active_thread.ptype == AQ_SET_SWG_PERCENT ||
|
|
aq_data->active_thread.ptype == AQ_SET_ONETOUCH_BOOST ||
|
|
aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_SWG_BOOST ||
|
|
aq_data->active_thread.ptype == AQ_SET_BOOST)
|
|
) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool in_ot_programming_mode(struct aqualinkdata *aq_data)
|
|
{
|
|
if ( aq_data->active_thread.thread_id != 0 &&
|
|
aq_data->active_thread.ptype >= AQP_ONETOUCH_MIN &&
|
|
aq_data->active_thread.ptype <= AQP_ONETOUCH_MAX) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool in_iaqt_programming_mode(struct aqualinkdata *aq_data)
|
|
{
|
|
if ( aq_data->active_thread.thread_id != 0 &&
|
|
aq_data->active_thread.ptype >= AQP_IAQTOUCH_MIN &&
|
|
aq_data->active_thread.ptype <= AQP_IAQTOUCH_MAX) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool in_allb_programming_mode(struct aqualinkdata *aq_data)
|
|
{
|
|
if ( aq_data->active_thread.thread_id != 0 &&
|
|
aq_data->active_thread.ptype >= AQP_ALLBUTTON_MIN &&
|
|
aq_data->active_thread.ptype <= AQP_ALLBUTTONL_MAX) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// May need to re-think. if we are in PDA mode and using IAQTOUCH should we
|
|
// return PAD or IAQTOUCH
|
|
emulation_type get_programming_mode(program_type type)
|
|
{
|
|
if (type >= AQP_ALLBUTTON_MIN &&
|
|
type <= AQP_ALLBUTTONL_MAX) {
|
|
return ALLBUTTON;
|
|
}
|
|
if (type >= AQP_IAQTOUCH_MIN &&
|
|
type <= AQP_IAQTOUCH_MAX) {
|
|
return IAQTOUCH;
|
|
}
|
|
if (type >= AQP_ONETOUCH_MIN &&
|
|
type <= AQP_ONETOUCH_MAX) {
|
|
return ONETOUCH;
|
|
}
|
|
if (type >= AQP_PDA_MIN &&
|
|
type <= AQP_PDA_MAX) {
|
|
return AQUAPDA;
|
|
}
|
|
return SIM_NONE;
|
|
}
|
|
|
|
emulation_type get_current_programming_mode(struct aqualinkdata *aq_data)
|
|
{
|
|
if ( !in_programming_mode(aq_data) ) {
|
|
return SIM_NONE;
|
|
}
|
|
|
|
return get_programming_mode(aq_data->active_thread.ptype);
|
|
}
|
|
|
|
|
|
bool in_programming_mode(struct aqualinkdata *aq_data)
|
|
{
|
|
if ( aq_data->active_thread.thread_id != 0 ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void kick_aq_program_thread(struct aqualinkdata *aq_data, emulation_type source_type)
|
|
{
|
|
if ( aq_data->active_thread.thread_id != 0 ) {
|
|
if ( (source_type == ONETOUCH) && in_ot_programming_mode(aq_data))
|
|
{
|
|
LOG(ONET_LOG, LOG_DEBUG, "Kicking OneTouch thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id);
|
|
pthread_cond_broadcast(&aq_data->active_thread.thread_cond);
|
|
}
|
|
else if (source_type == IAQTOUCH && in_iaqt_programming_mode(aq_data)) {
|
|
LOG(IAQT_LOG, LOG_DEBUG, "Kicking IAQ Touch thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id);
|
|
pthread_cond_broadcast(&aq_data->active_thread.thread_cond);
|
|
}
|
|
else if (source_type == ALLBUTTON && !in_ot_programming_mode(aq_data) && !in_iaqt_programming_mode(aq_data)) {
|
|
LOG(PROG_LOG, LOG_DEBUG, "Kicking RS Allbutton thread %d,%p message '%s'\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id,aq_data->last_message);
|
|
pthread_cond_broadcast(&aq_data->active_thread.thread_cond);
|
|
}
|
|
#ifdef AQ_PDA
|
|
else if (source_type == AQUAPDA && !in_ot_programming_mode(aq_data)) {
|
|
LOG(PDA_LOG, LOG_DEBUG, "Kicking PDA thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id);
|
|
pthread_cond_broadcast(&aq_data->active_thread.thread_cond);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data){
|
|
_aq_programmer(r_type, args, aq_data, true);
|
|
}
|
|
void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data, bool allowOveride)
|
|
{
|
|
struct programmingThreadCtrl *programmingthread = malloc(sizeof(struct programmingThreadCtrl));
|
|
|
|
program_type type = r_type;
|
|
|
|
// RS SerialAdapter is quickest for changing thermostat temps, so use that if enabeled.
|
|
// VSP RPM can only be changed with oneTouch or iAquatouch so check / use those
|
|
// VSP Program is only available with iAquatouch, so check / use that.
|
|
if (isRSSA_ENABLED && (r_type == AQ_SET_POOL_HEATER_TEMP || r_type == AQ_SET_SPA_HEATER_TEMP)) {
|
|
if (r_type == AQ_SET_POOL_HEATER_TEMP)
|
|
type = AQ_SET_RSSADAPTER_POOL_HEATER_TEMP;
|
|
else if (r_type == AQ_SET_SPA_HEATER_TEMP)
|
|
type = AQ_SET_RSSADAPTER_SPA_HEATER_TEMP;
|
|
} else if (r_type == AQ_SET_PUMP_RPM) {
|
|
if (isONET_ENABLED || isPDA_IAQT)
|
|
type = AQ_SET_ONETOUCH_PUMP_RPM;
|
|
else if (isIAQT_ENABLED)
|
|
type = AQ_SET_IAQTOUCH_PUMP_RPM;
|
|
else {
|
|
LOG(PROG_LOG, LOG_ERR, "Can only change pump RPM with an extended device id\n",type);
|
|
return;
|
|
}
|
|
} else if (r_type == AQ_SET_PUMP_VS_PROGRAM) {
|
|
if (isIAQT_ENABLED)
|
|
type = AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM;
|
|
else {
|
|
LOG(PROG_LOG, LOG_ERR, "Can only change pump VS Program with an iAqualink Touch device id\n",type);
|
|
return;
|
|
}
|
|
}
|
|
#ifdef AQ_ONETOUCH
|
|
// reset any types if to onetouch if available and if one touch is quicker
|
|
// At moment. onetouch is quicker for boost, and slower for heaters
|
|
else if (isONET_ENABLED && isEXTP_ENABLED) {
|
|
switch (r_type){
|
|
case AQ_GET_POOL_SPA_HEATER_TEMPS:
|
|
//case AQ_GET_FREEZE_PROTECT_TEMP:
|
|
type = AQ_GET_ONETOUCH_SETPOINTS;
|
|
break;
|
|
case AQ_SET_POOL_HEATER_TEMP:
|
|
type = AQ_SET_ONETOUCH_POOL_HEATER_TEMP;
|
|
break;
|
|
case AQ_SET_SPA_HEATER_TEMP:
|
|
type = AQ_SET_ONETOUCH_SPA_HEATER_TEMP;
|
|
break;
|
|
case AQ_SET_SWG_PERCENT:
|
|
type = AQ_SET_ONETOUCH_SWG_PERCENT;
|
|
break;
|
|
case AQ_SET_BOOST:
|
|
type = AQ_SET_ONETOUCH_BOOST;
|
|
break;
|
|
// NSF ONE TOUCH TIME IS NOT WORKING YET
|
|
//case AQ_SET_TIME:
|
|
// type = AQ_SET_ONETOUCH_TIME;
|
|
//break;
|
|
default:
|
|
type = r_type;
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef AQ_IAQTOUCH
|
|
else if ((isIAQT_ENABLED && isEXTP_ENABLED) || isPDA_IAQT) {
|
|
// IAQ Touch programming modes that should overite standard ones.
|
|
switch (r_type){
|
|
case AQ_GET_POOL_SPA_HEATER_TEMPS:
|
|
//case AQ_GET_FREEZE_PROTECT_TEMP:
|
|
type = AQ_GET_IAQTOUCH_SETPOINTS;
|
|
break;
|
|
case AQ_SET_SWG_PERCENT:
|
|
type = AQ_SET_IAQTOUCH_SWG_PERCENT;
|
|
break;
|
|
case AQ_SET_BOOST:
|
|
type = AQ_SET_IAQTOUCH_SWG_BOOST;
|
|
break;
|
|
case AQ_SET_POOL_HEATER_TEMP:
|
|
type = AQ_SET_IAQTOUCH_POOL_HEATER_TEMP;
|
|
break;
|
|
case AQ_SET_SPA_HEATER_TEMP:
|
|
type = AQ_SET_IAQTOUCH_SPA_HEATER_TEMP;
|
|
break;
|
|
case AQ_SET_TIME:
|
|
type = AQ_SET_IAQTOUCH_SET_TIME;
|
|
break;
|
|
case AQ_PDA_DEVICE_ON_OFF:
|
|
if (isPDA_IAQT) {
|
|
type = AQ_SET_IAQTOUCH_DEVICE_ON_OFF;
|
|
}
|
|
break;
|
|
// This isn;t going to work outside of PDA mode, if the labels are incorrect.
|
|
case AQ_SET_LIGHTCOLOR_MODE:
|
|
if (isPDA_IAQT) {
|
|
type = AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE;
|
|
}
|
|
break;
|
|
default:
|
|
type = r_type;
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef AQ_PDA
|
|
// Check we are doing something valid request
|
|
if (isPDA_PANEL && !isPDA_IAQT)
|
|
{
|
|
switch (r_type){
|
|
case AQ_SET_POOL_HEATER_TEMP:
|
|
type = AQ_PDA_SET_POOL_HEATER_TEMPS;
|
|
break;
|
|
case AQ_SET_SPA_HEATER_TEMP:
|
|
type = AQ_PDA_SET_SPA_HEATER_TEMPS;
|
|
break;
|
|
case AQ_SET_SWG_PERCENT:
|
|
type = AQ_PDA_SET_SWG_PERCENT;
|
|
break;
|
|
case AQ_PDA_DEVICE_ON_OFF:
|
|
break;
|
|
case AQ_GET_POOL_SPA_HEATER_TEMPS:
|
|
type = AQ_PDA_GET_POOL_SPA_HEATER_TEMPS;
|
|
break;
|
|
case AQ_GET_FREEZE_PROTECT_TEMP:
|
|
type = AQ_PDA_GET_FREEZE_PROTECT_TEMP;
|
|
break;
|
|
case AQ_SET_FRZ_PROTECTION_TEMP:
|
|
type = AQ_PDA_SET_FREEZE_PROTECT_TEMP;
|
|
break;
|
|
case AQ_SET_BOOST:
|
|
type = AQ_PDA_SET_BOOST;
|
|
break;
|
|
case AQ_SET_TIME:
|
|
type = AQ_PDA_SET_TIME;
|
|
break;
|
|
#ifdef BETA_PDA_AUTOLABEL
|
|
case AQ_GET_AUX_LABELS:
|
|
type = AQ_PDA_AUX_LABELS:
|
|
break;
|
|
#endif
|
|
default:
|
|
type = r_type;
|
|
break;
|
|
}
|
|
if (get_programming_mode(type) != AQUAPDA ) {
|
|
LOG(PROG_LOG, LOG_ERR, "Selected Programming mode '%s' '%d' not supported with PDA control panel\n",ptypeName(type),type);
|
|
return;
|
|
}
|
|
pda_reset_sleep();
|
|
}
|
|
else if (isPDA_PANEL && isPDA_IAQT)
|
|
{
|
|
if (isIAQL_ACTIVE) { // if we have iAqualink and AqualinkTouch active on PDA, use iAqualink for setpoints.
|
|
if (r_type == AQ_SET_POOL_HEATER_TEMP) {
|
|
type = AQ_SET_IAQLINK_POOL_HEATER_TEMP;
|
|
} else if (r_type == AQ_SET_SPA_HEATER_TEMP) {
|
|
type = AQ_SET_IAQLINK_SPA_HEATER_TEMP;
|
|
}
|
|
}
|
|
if ( get_programming_mode(type) != IAQTOUCH) {
|
|
LOG(PROG_LOG, LOG_ERR, "Selected Programming mode '%s' '%d' not supported with PDA control panel in iAqualinkTouch mode\n",ptypeName(type),type);
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (!allowOveride) {
|
|
// Reset anything back from changes above.
|
|
type = r_type;
|
|
}
|
|
|
|
|
|
LOG(PROG_LOG, LOG_NOTICE, "Starting programming thread '%s'\n",ptypeName(type));
|
|
|
|
programmingthread->aq_data = aq_data;
|
|
programmingthread->thread_id = 0;
|
|
//programmingthread->thread_args = args;
|
|
if (args != NULL /*&& type != AQ_SEND_CMD*/)
|
|
strncpy(programmingthread->thread_args, args, sizeof(programmingthread->thread_args)-1);
|
|
|
|
switch(type) {
|
|
case AQ_GET_RSSADAPTER_SETPOINTS:
|
|
get_aqualink_rssadapter_setpoints();
|
|
return; // No need to create this as thread.
|
|
break;
|
|
case AQ_SET_RSSADAPTER_POOL_HEATER_TEMP:
|
|
set_aqualink_rssadapter_pool_setpoint(args, aq_data);
|
|
return; // No need to create this as thread.
|
|
break;
|
|
case AQ_SET_RSSADAPTER_SPA_HEATER_TEMP:
|
|
set_aqualink_rssadapter_spa_setpoint(args, aq_data);
|
|
return; // No need to create this as thread.
|
|
break;
|
|
case AQ_ADD_RSSADAPTER_POOL_HEATER_TEMP:
|
|
increase_aqualink_rssadapter_pool_setpoint(args, aq_data);
|
|
return; // No need to create this as thread.
|
|
break;
|
|
case AQ_ADD_RSSADAPTER_SPA_HEATER_TEMP:
|
|
increase_aqualink_rssadapter_spa_setpoint(args, aq_data);
|
|
return; // No need to create this as thread.
|
|
break;
|
|
case AQ_SET_IAQLINK_POOL_HEATER_TEMP:
|
|
set_iaqualink_heater_setpoint(atoi(args), true);
|
|
return; // No need to create this as thread.
|
|
break;
|
|
case AQ_SET_IAQLINK_SPA_HEATER_TEMP:
|
|
set_iaqualink_heater_setpoint(atoi(args), false);
|
|
return; // No need to create this as thread.
|
|
break;
|
|
default:
|
|
// Should check that _prog_functions[type] is valid.
|
|
if( pthread_create( &programmingthread->thread_id , NULL , _prog_functions[type], (void*)programmingthread) < 0) {
|
|
LOG(PROG_LOG, LOG_ERR, "could not create thread\n");
|
|
return;
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
if ( programmingthread->thread_id != 0 ) {
|
|
//LOG(PROG_LOG, LOG_DEBUG, "********* DID pthread_detach %d\n",programmingthread->thread_id);
|
|
pthread_detach(programmingthread->thread_id);
|
|
} else {
|
|
//LOG(PROG_LOG, LOG_DEBUG, "********* DID NOT pthread_detach\n");
|
|
}
|
|
}
|
|
|
|
|
|
void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, program_type type)
|
|
{
|
|
//static int tries = 120;
|
|
int tries = 120;
|
|
static int waitTime = 1;
|
|
int i=0;
|
|
/*
|
|
i = 0;
|
|
while (get_aq_cmd_length() > 0 && ( i++ <= tries) ) {
|
|
LOG(PROG_LOG, LOG_DEBUG, "Thread %p (%s) sleeping, waiting command queue to empty\n", &threadCtrl->thread_id, ptypeName(type));
|
|
sleep(waitTime);
|
|
}
|
|
if (i >= tries) {
|
|
LOG(PROG_LOG, LOG_ERR, "Thread %p (%s) timeout waiting, ending\n",&threadCtrl->thread_id,ptypeName(type));
|
|
free(threadCtrl);
|
|
pthread_exit(0);
|
|
}
|
|
*/
|
|
while ( (threadCtrl->aq_data->active_thread.thread_id != 0) && ( i++ <= tries) ) {
|
|
//LOG(PROG_LOG, LOG_DEBUG, "Thread %d sleeping, waiting for thread %d to finish\n", threadCtrl->thread_id, threadCtrl->aq_data->active_thread.thread_id);
|
|
LOG(PROG_LOG, LOG_DEBUG, "Thread %p (%s) sleeping, waiting for thread %p (%s) to finish\n",
|
|
&threadCtrl->thread_id, ptypeName(type),
|
|
threadCtrl->aq_data->active_thread.thread_id, ptypeName(threadCtrl->aq_data->active_thread.ptype));
|
|
sleep(waitTime);
|
|
}
|
|
|
|
if (i >= tries) {
|
|
//LOG(PROG_LOG, LOG_ERR, "Thread %d timeout waiting, ending\n",threadCtrl->thread_id);
|
|
LOG(PROG_LOG, LOG_ERR, "Thread (%s) %p timeout waiting for thread (%s) %p to finish\n",
|
|
ptypeName(type), &threadCtrl->thread_id, ptypeName(threadCtrl->aq_data->active_thread.ptype),
|
|
threadCtrl->aq_data->active_thread.thread_id);
|
|
free(threadCtrl);
|
|
pthread_exit(0);
|
|
}
|
|
|
|
// Clear out any messages to the UI.
|
|
threadCtrl->aq_data->last_display_message[0] = '\0';
|
|
threadCtrl->aq_data->active_thread.thread_id = &threadCtrl->thread_id;
|
|
threadCtrl->aq_data->active_thread.ptype = type;
|
|
|
|
#ifdef AQ_DEBUG
|
|
clock_gettime(CLOCK_REALTIME, &threadCtrl->aq_data->start_active_time);
|
|
#endif
|
|
|
|
LOG(PROG_LOG, LOG_INFO, "Programming: %s, %d\n", ptypeName(threadCtrl->aq_data->active_thread.ptype), threadCtrl->aq_data->active_thread.ptype);
|
|
|
|
LOG(PROG_LOG, LOG_DEBUG, "Thread %d,%p is active (%s)\n",
|
|
threadCtrl->aq_data->active_thread.ptype,
|
|
threadCtrl->aq_data->active_thread.thread_id,
|
|
ptypeName(threadCtrl->aq_data->active_thread.ptype));
|
|
}
|
|
|
|
void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl)
|
|
{
|
|
//waitfor_queue2empty();
|
|
#ifndef AQ_DEBUG
|
|
LOG(PROG_LOG, LOG_DEBUG, "Thread %d,%p (%s) finished\n",threadCtrl->aq_data->active_thread.ptype, threadCtrl->thread_id,ptypeName(threadCtrl->aq_data->active_thread.ptype));
|
|
#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);
|
|
LOG(PROG_LOG, LOG_NOTICE, "Thread %d,%p (%s) finished in %d.%03ld sec\n",
|
|
threadCtrl->aq_data->active_thread.ptype,
|
|
threadCtrl->aq_data->active_thread.thread_id,
|
|
ptypeName(threadCtrl->aq_data->active_thread.ptype),
|
|
elapsed.tv_sec, elapsed.tv_nsec / 1000000L);
|
|
#endif
|
|
|
|
// Quick delay to allow for last message to be sent.
|
|
delay(500);
|
|
threadCtrl->aq_data->active_thread.thread_id = 0;
|
|
threadCtrl->aq_data->active_thread.ptype = AQP_NULL;
|
|
threadCtrl->thread_id = 0;
|
|
// Force update, change display message
|
|
threadCtrl->aq_data->updated = true;
|
|
free(threadCtrl);
|
|
pthread_exit(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
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 protect";
|
|
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_LIGHTPROGRAM_MODE:
|
|
return "Set light color (using AqualinkD)";
|
|
break;
|
|
case AQ_SET_LIGHTCOLOR_MODE:
|
|
return "Set light color (using Panel)";
|
|
break;
|
|
case AQ_SET_SWG_PERCENT:
|
|
return "Set SWG percent";
|
|
break;
|
|
case AQ_SET_BOOST:
|
|
return "SWG Boost";
|
|
break;
|
|
case AQ_SET_PUMP_RPM:
|
|
return "Set Pump RPM";
|
|
break;
|
|
case AQ_SET_PUMP_VS_PROGRAM:
|
|
return "Set Pump VS Program";
|
|
break;
|
|
case AQ_GET_AUX_LABELS:
|
|
return "Get AUX labels";
|
|
break;
|
|
case AQ_GET_RSSADAPTER_SETPOINTS:
|
|
return "Get SerialAdapter setpoints";
|
|
break;
|
|
case AQ_SET_RSSADAPTER_POOL_HEATER_TEMP:
|
|
return "Set SerialAdapter Pool heater setpoint";
|
|
break;
|
|
case AQ_SET_RSSADAPTER_SPA_HEATER_TEMP:
|
|
return "Set SerialAdapter Spa heater setpoint";
|
|
break;
|
|
#ifdef AQ_ONETOUCH
|
|
case AQ_SET_ONETOUCH_PUMP_RPM:
|
|
return "Set OneTouch Pump RPM";
|
|
break;
|
|
case AQ_SET_ONETOUCH_MACRO:
|
|
return "Set OneTouch Macro";
|
|
break;
|
|
case AQ_GET_ONETOUCH_SETPOINTS:
|
|
return "Get OneTouch setpoints";
|
|
break;
|
|
case AQ_GET_ONETOUCH_FREEZEPROTECT:
|
|
return "Get OneTouch freezeprotect";
|
|
break;
|
|
case AQ_SET_ONETOUCH_TIME:
|
|
return "Set OneTouch time";
|
|
break;
|
|
case AQ_SET_ONETOUCH_BOOST:
|
|
return "Set OneTouch Boost";
|
|
break;
|
|
case AQ_SET_ONETOUCH_SWG_PERCENT:
|
|
return "Set OneTouch SWG Percent";
|
|
break;
|
|
case AQ_SET_ONETOUCH_FREEZEPROTECT:
|
|
return "Set OneTouch Freezeprotect";
|
|
break;
|
|
case AQ_SET_ONETOUCH_POOL_HEATER_TEMP:
|
|
return "Set OneTouch Pool Heater Temp";
|
|
break;
|
|
case AQ_SET_ONETOUCH_SPA_HEATER_TEMP:
|
|
return "Set OneTouch Spa Heater Temp";
|
|
break;
|
|
#endif
|
|
#ifdef AQ_IAQTOUCH
|
|
case AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM:
|
|
return "Set AqualinkTouch Touch Pump VS Program";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_PUMP_RPM:
|
|
return "Set AqualinkTouch Touch Pump RPM";
|
|
break;
|
|
case AQ_GET_IAQTOUCH_VSP_ASSIGNMENT:
|
|
return "Get AqualinkTouch Touch Pump Assignment";
|
|
break;
|
|
case AQ_GET_IAQTOUCH_SETPOINTS:
|
|
return "Get AqualinkTouch Touch Setpoints";
|
|
break;
|
|
case AQ_GET_IAQTOUCH_FREEZEPROTECT:
|
|
return "Get AqualinkTouch Touch Freezeprotect";
|
|
break;
|
|
case AQ_GET_IAQTOUCH_AUX_LABELS:
|
|
return "Get AqualinkTouch AUX Labels";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_SWG_PERCENT:
|
|
return "Set AqualinkTouch SWG Percent";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_POOL_HEATER_TEMP:
|
|
return "Set AqualinkTouch Pool Heater";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_SET_TIME:
|
|
return "Set AqualinkTouch Set Time";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_DEVICE_ON_OFF:
|
|
return "Set AqualinkTouch Device On/Off";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_ONETOUCH_ON_OFF:
|
|
return "Set AqualinkTouch OneTouch On/Off";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE:
|
|
return "Set AqualinkTouch Light Color (using panel)";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_SWG_BOOST:
|
|
return "Set AqualinkTouch Boost";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_SPA_HEATER_TEMP:
|
|
return "Set AqualinkTouch Spa Heater";
|
|
break;
|
|
// These to same as above, but on the iAqualink protocol, not AqualinkTouch protocol
|
|
case AQ_SET_IAQLINK_POOL_HEATER_TEMP:
|
|
return "Set iAqualink Pool Heater";
|
|
break;
|
|
case AQ_SET_IAQLINK_SPA_HEATER_TEMP:
|
|
return "Set iAqualink Pool Heater";
|
|
break;
|
|
#endif
|
|
#ifdef AQ_PDA
|
|
case AQ_PDA_INIT:
|
|
return "Init PDA";
|
|
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_PDA_WAKE_INIT:
|
|
return "PDA init after wake";
|
|
break;
|
|
case AQ_PDA_SET_BOOST:
|
|
return "Set PDA SWG Boost";
|
|
break;
|
|
case AQ_PDA_SET_SWG_PERCENT:
|
|
return "Set PDA SWG Percent";
|
|
break;
|
|
case AQ_PDA_GET_AUX_LABELS:
|
|
return "Get PDA Lebels";
|
|
break;
|
|
case AQ_PDA_SET_POOL_HEATER_TEMPS:
|
|
return "Set PDA Pool Heater";
|
|
break;
|
|
case AQ_PDA_SET_SPA_HEATER_TEMPS:
|
|
return "Set PDA Spa Heater";
|
|
break;
|
|
case AQ_PDA_SET_FREEZE_PROTECT_TEMP:
|
|
return "Set PDA Freese protect";
|
|
break;
|
|
case AQ_PDA_SET_TIME:
|
|
return "Set PDA time";
|
|
break;
|
|
case AQ_PDA_GET_POOL_SPA_HEATER_TEMPS:
|
|
return "Get PDA heater setpoints";
|
|
break;
|
|
case AQ_PDA_GET_FREEZE_PROTECT_TEMP:
|
|
return "Get PDA freeze protect";
|
|
break;
|
|
#endif
|
|
case AQP_NULL:
|
|
default:
|
|
return "Unknown";
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Cleaner version of above for UI display purposes.
|
|
const char *programtypeDisplayName(program_type type)
|
|
{
|
|
switch (type) {
|
|
case AQ_GET_POOL_SPA_HEATER_TEMPS:
|
|
case AQ_GET_ONETOUCH_SETPOINTS:
|
|
case AQ_GET_FREEZE_PROTECT_TEMP:
|
|
case AQ_GET_IAQTOUCH_SETPOINTS:
|
|
case AQ_GET_RSSADAPTER_SETPOINTS:
|
|
case AQ_GET_ONETOUCH_FREEZEPROTECT:
|
|
case AQ_GET_IAQTOUCH_FREEZEPROTECT:
|
|
#ifdef AQ_PDA
|
|
case AQ_PDA_INIT:
|
|
#endif
|
|
return "Programming: retrieving setpoints";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_SET_TIME:
|
|
case AQ_SET_ONETOUCH_TIME:
|
|
case AQ_SET_TIME:
|
|
return "Programming: setting time";
|
|
break;
|
|
case AQ_SET_POOL_HEATER_TEMP:
|
|
case AQ_SET_ONETOUCH_POOL_HEATER_TEMP:
|
|
case AQ_SET_SPA_HEATER_TEMP:
|
|
case AQ_SET_ONETOUCH_SPA_HEATER_TEMP:
|
|
case AQ_SET_IAQTOUCH_SPA_HEATER_TEMP:
|
|
case AQ_SET_IAQTOUCH_POOL_HEATER_TEMP:
|
|
case AQ_SET_RSSADAPTER_POOL_HEATER_TEMP:
|
|
case AQ_SET_RSSADAPTER_SPA_HEATER_TEMP:
|
|
return "Programming: setting heater";
|
|
break;
|
|
case AQ_SET_FRZ_PROTECTION_TEMP:
|
|
case AQ_SET_ONETOUCH_FREEZEPROTECT:
|
|
return "Programming: setting Freeze protect";
|
|
break;
|
|
case AQ_GET_DIAGNOSTICS_MODEL:
|
|
return "Programming: retrieving diagnostics";
|
|
break;
|
|
case AQ_GET_PROGRAMS:
|
|
return "Programming: retrieving programs";
|
|
break;
|
|
case AQ_SET_LIGHTPROGRAM_MODE:
|
|
case AQ_SET_LIGHTCOLOR_MODE:
|
|
case AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE:
|
|
return "Programming: setting light color";
|
|
break;
|
|
case AQ_SET_SWG_PERCENT:
|
|
case AQ_SET_ONETOUCH_SWG_PERCENT:
|
|
case AQ_SET_IAQTOUCH_SWG_PERCENT:
|
|
return "Programming: setting SWG percent";
|
|
break;
|
|
case AQ_GET_AUX_LABELS:
|
|
case AQ_GET_IAQTOUCH_AUX_LABELS:
|
|
return "Programming: retrieving AUX labels";
|
|
break;
|
|
case AQ_SET_BOOST:
|
|
case AQ_SET_ONETOUCH_BOOST:
|
|
case AQ_SET_IAQTOUCH_SWG_BOOST:
|
|
return "Programming: setting SWG Boost";
|
|
break;
|
|
case AQ_SET_ONETOUCH_PUMP_RPM:
|
|
case AQ_SET_IAQTOUCH_PUMP_RPM:
|
|
case AQ_SET_PUMP_RPM:
|
|
case AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM:
|
|
case AQ_SET_PUMP_VS_PROGRAM:
|
|
return "Programming: setting Pump RPM";
|
|
break;
|
|
case AQ_SET_ONETOUCH_MACRO:
|
|
return "Programming: setting OneTouch Macro";
|
|
break;
|
|
case AQ_GET_IAQTOUCH_VSP_ASSIGNMENT:
|
|
return "Get Pump Assignment";
|
|
break;
|
|
case AQ_SET_IAQTOUCH_DEVICE_ON_OFF:
|
|
case AQ_SET_IAQTOUCH_ONETOUCH_ON_OFF:
|
|
return "Programming: setting device on/off";
|
|
break;
|
|
#ifdef AQ_PDA
|
|
case AQ_PDA_DEVICE_STATUS:
|
|
return "Programming: retrieving PDA Device status";
|
|
break;
|
|
case AQ_PDA_DEVICE_ON_OFF:
|
|
return "Programming: setting device on/off";
|
|
break;
|
|
case AQ_PDA_WAKE_INIT:
|
|
return "Programming: PDA wakeup";
|
|
break;
|
|
#endif
|
|
default:
|
|
return "Programming: please wait!";
|
|
break;
|
|
}
|
|
}
|