2019-05-25 16:52:36 +00:00
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
# define _GNU_SOURCE 1 // for strcasestr & strptime
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
2023-05-14 21:35:13 +00:00
# include <ctype.h>
2019-05-25 16:52:36 +00:00
# include "aqualink.h"
2019-07-14 14:39:15 +00:00
2019-05-25 19:11:52 +00:00
# include "pda.h"
2019-05-25 16:52:36 +00:00
# include "pda_menu.h"
# include "utils.h"
2020-07-18 16:37:19 +00:00
# include "aq_panel.h"
# include "packetLogger.h"
# include "devices_jandy.h"
2023-05-21 15:03:27 +00:00
# include "rs_msg_utils.h"
2019-07-14 14:39:15 +00:00
2024-03-30 18:17:13 +00:00
// Used in equiptment_update_cycle() for additional items on EQUIPMENT STATUS
// TOTAL_BUTTONS is at most 20 so bits 21-31 should be available
# define PDA_BOOST_INDEX 21
# define PDA_FREEZE_PROTECT_INDEX 22
2019-05-25 16:52:36 +00:00
// static struct aqualinkdata _aqualink_data;
static struct aqualinkdata * _aqualink_data ;
static unsigned char _last_packet_type ;
static unsigned long _pda_loop_cnt = 0 ;
static bool _initWithRS = false ;
2019-06-27 22:18:44 +00:00
// Each RS message is around 0.25 seconds apart
2019-05-31 23:08:45 +00:00
2019-06-27 22:18:44 +00:00
# define PDA_SLEEP_FOR 120 // 30 seconds
# define PDA_WAKE_FOR 6 // ~1 seconds
2019-05-25 16:52:36 +00:00
2019-07-14 14:39:15 +00:00
2020-07-18 16:37:19 +00:00
2019-05-25 16:52:36 +00:00
void init_pda ( struct aqualinkdata * aqdata )
{
_aqualink_data = aqdata ;
2020-07-18 16:37:19 +00:00
//set_pda_mode(true);
2019-05-25 16:52:36 +00:00
}
2019-07-14 14:39:15 +00:00
2019-05-25 16:52:36 +00:00
2019-05-31 23:08:45 +00:00
bool pda_shouldSleep ( ) {
2020-07-18 16:37:19 +00:00
//LOG(PDA_LOG,LOG_DEBUG, "PDA loop count %d, will sleep at %d\n",_pda_loop_cnt,PDA_LOOP_COUNT);
2019-05-31 23:08:45 +00:00
if ( _pda_loop_cnt + + < PDA_WAKE_FOR ) {
return false ;
} else if ( _pda_loop_cnt > PDA_WAKE_FOR + PDA_SLEEP_FOR ) {
_pda_loop_cnt = 0 ;
return false ;
}
2019-05-25 16:52:36 +00:00
2019-05-31 23:08:45 +00:00
// NSF NEED TO CHECK ACTIVE THREADS.
if ( _aqualink_data - > active_thread . thread_id ! = 0 ) {
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " PDA can't sleep as thread %d,%p is active \n " ,
2019-01-28 18:50:14 +00:00
_aqualink_data - > active_thread . ptype ,
_aqualink_data - > active_thread . thread_id ) ;
2019-05-31 23:08:45 +00:00
_pda_loop_cnt = 0 ;
return false ;
}
// Last see if there are any open websockets. (don't sleep if the web UI is open)
if ( _aqualink_data - > open_websockets > 0 ) {
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " PDA can't sleep as websocket is active \n " ) ;
2019-05-31 23:08:45 +00:00
return false ;
}
return true ;
}
/*
2019-05-25 16:52:36 +00:00
bool pda_shouldSleep ( ) {
2020-07-18 16:37:19 +00:00
//LOG(PDA_LOG,LOG_DEBUG, "PDA loop count %d, will sleep at %d\n",_pda_loop_cnt,PDA_LOOP_COUNT);
2019-05-25 16:52:36 +00:00
if ( _pda_loop_cnt + + < PDA_LOOP_COUNT ) {
return false ;
} else if ( _pda_loop_cnt > PDA_LOOP_COUNT * 2 ) {
_pda_loop_cnt = 0 ;
return false ;
}
return true ;
}
2019-05-31 23:08:45 +00:00
*/
2019-05-25 16:52:36 +00:00
void pda_wake ( ) {
2019-05-25 19:11:52 +00:00
pda_reset_sleep ( ) ;
// Add and specic code to run when wake is called.
2019-05-25 16:52:36 +00:00
}
void pda_reset_sleep ( ) {
_pda_loop_cnt = 0 ;
}
unsigned char get_last_pda_packet_type ( )
{
return _last_packet_type ;
}
void set_pda_led ( struct aqualinkled * led , char state )
{
aqledstate old_state = led - > state ;
if ( state = = ' N ' )
{
led - > state = ON ;
}
else if ( state = = ' A ' )
{
led - > state = ENABLE ;
}
else if ( state = = ' * ' )
{
led - > state = FLASH ;
}
else
{
led - > state = OFF ;
}
if ( old_state ! = led - > state )
{
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " set_pda_led from %d to %d \n " , old_state , led - > state ) ;
2019-05-25 16:52:36 +00:00
}
}
2023-07-28 02:59:13 +00:00
// :TODO: Test what happens if there are more devices on than can fit on the status page
// :TODO: If web page is up PDA will not sleep therefore there is no wake and seeing
// the equipment page. Need to add support for determining filter pump on/off based on home
2023-05-14 21:35:13 +00:00
void equiptment_update_cycle ( int eqID ) {
// If you have a -1, it's a reset to clear / update information.
2023-07-28 02:59:13 +00:00
// TOTAL_BUTTONS is 20 so bits 21-31 available for BOOST, FREEZE PROTECT, etc.
2023-05-14 21:35:13 +00:00
int i ;
static uint32_t update_equiptment_bitmask = 0 ;
if ( eqID = = - 1 ) {
2023-07-28 02:59:13 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " Start new equipment cycle bitmask 0x%04x \n " ,
update_equiptment_bitmask ) ;
2023-05-14 21:35:13 +00:00
2023-05-30 23:14:04 +00:00
for ( i = 0 ; i < _aqualink_data - > total_buttons - 2 ; i + + ) { // total_buttons - 2 because we don't get heaters in this cycle
2023-07-28 02:59:13 +00:00
if ( ( update_equiptment_bitmask & ( 1 < < ( i ) ) ) ! = ( 1 < < ( i ) ) ) {
2023-05-14 21:35:13 +00:00
if ( _aqualink_data - > aqbuttons [ i ] . led - > state ! = OFF ) {
_aqualink_data - > aqbuttons [ i ] . led - > state = OFF ;
_aqualink_data - > updated = true ;
2022-05-31 22:04:32 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " Turn off equipment id %d %s not seen in last cycle \n " , i , _aqualink_data - > aqbuttons [ i ] . name ) ;
2023-05-14 21:35:13 +00:00
}
}
}
2023-07-28 02:59:13 +00:00
if ( ( _aqualink_data - > frz_protect_state = = ON ) & &
2024-03-30 18:17:13 +00:00
( ! ( update_equiptment_bitmask & ( 1 < < PDA_FREEZE_PROTECT_INDEX ) ) ) ) {
2023-07-28 02:59:13 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " Turn off freeze protect not seen in last cycle \n " ) ;
_aqualink_data - > frz_protect_state = ENABLE ;
}
if ( ( _aqualink_data - > boost ) & &
2024-03-30 18:17:13 +00:00
( ! ( update_equiptment_bitmask & ( 1 < < PDA_BOOST_INDEX ) ) ) ) {
2023-07-28 02:59:13 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " Turn off BOOST not seen in last cycle \n " ) ;
setSWGboost ( _aqualink_data , false ) ;
}
2023-05-14 21:35:13 +00:00
update_equiptment_bitmask = 0 ;
2023-07-28 02:59:13 +00:00
} else if ( ( eqID > = 0 ) & & ( eqID < 32 ) ) {
update_equiptment_bitmask | = ( 1 < < ( eqID ) ) ;
char * eqName = NULL ;
2023-08-31 15:41:01 +00:00
if ( eqID < TOTAL_BUTTONS ) {
2023-07-28 02:59:13 +00:00
eqName = _aqualink_data - > aqbuttons [ eqID ] . name ;
2024-03-30 18:17:13 +00:00
} else if ( eqID = = PDA_FREEZE_PROTECT_INDEX ) {
2023-07-28 02:59:13 +00:00
eqName = " FREEZE PROTECT " ;
2024-03-30 18:17:13 +00:00
} else if ( eqID = = PDA_BOOST_INDEX ) {
2023-07-28 02:59:13 +00:00
eqName = " BOOST " ;
} else {
eqName = " UNKNOWN " ;
}
LOG ( PDA_LOG , LOG_DEBUG , " Added equipment id %d %s to updated cycle bitmask 0x%04x \n " ,
eqID , eqName , update_equiptment_bitmask ) ;
2023-05-14 21:35:13 +00:00
} else {
2023-07-28 02:59:13 +00:00
LOG ( PDA_LOG , LOG_ERR , " equiptment_update_cycle(%d) - Invalid eqID \n " , eqID ) ;
2023-05-14 21:35:13 +00:00
}
}
2023-05-30 23:14:04 +00:00
2023-05-14 21:35:13 +00:00
2019-05-25 16:52:36 +00:00
void process_pda_packet_msg_long_temp ( const char * msg )
{
// 'AIR POOL'
// ' 86` 86` '
// 'AIR SPA '
// ' 86` 86` '
// 'AIR '
// ' 86` '
2019-06-27 22:18:44 +00:00
// 'AIR WATER' // In case of single device.
2023-05-14 21:35:13 +00:00
_aqualink_data - > temp_units = FAHRENHEIT ; // Force FAHRENHEIT
2019-05-25 16:52:36 +00:00
if ( stristr ( pda_m_line ( 1 ) , " AIR " ) ! = NULL )
_aqualink_data - > air_temp = atoi ( msg ) ;
if ( stristr ( pda_m_line ( 1 ) , " SPA " ) ! = NULL )
{
_aqualink_data - > spa_temp = atoi ( msg + 4 ) ;
_aqualink_data - > pool_temp = TEMP_UNKNOWN ;
}
else if ( stristr ( pda_m_line ( 1 ) , " POOL " ) ! = NULL )
{
_aqualink_data - > pool_temp = atoi ( msg + 7 ) ;
_aqualink_data - > spa_temp = TEMP_UNKNOWN ;
}
2019-06-27 22:18:44 +00:00
else if ( stristr ( pda_m_line ( 1 ) , " WATER " ) ! = NULL )
{
_aqualink_data - > pool_temp = atoi ( msg + 7 ) ;
_aqualink_data - > spa_temp = TEMP_UNKNOWN ;
}
2019-05-25 16:52:36 +00:00
else
{
_aqualink_data - > pool_temp = TEMP_UNKNOWN ;
_aqualink_data - > spa_temp = TEMP_UNKNOWN ;
}
// printf("Air Temp = %d | Water Temp = %d\n",atoi(msg),atoi(msg+7));
}
void process_pda_packet_msg_long_time ( const char * msg )
{
// message " SAT 8:46AM "
// " SAT 10:29AM"
// " SAT 4:23PM "
2019-09-25 17:31:53 +00:00
// " SUN 2:36PM"
2019-05-25 16:52:36 +00:00
// printf("TIME = '%.*s'\n",AQ_MSGLEN,msg );
// printf("TIME = '%c'\n",msg[AQ_MSGLEN-1] );
2019-09-25 17:31:53 +00:00
2019-05-25 16:52:36 +00:00
if ( msg [ AQ_MSGLEN - 1 ] = = ' ' )
{
2019-09-25 17:31:53 +00:00
snprintf ( _aqualink_data - > time , sizeof ( _aqualink_data - > time ) , " %.6s " , msg + 9 ) ;
2019-05-25 16:52:36 +00:00
}
else
{
2019-09-25 17:31:53 +00:00
snprintf ( _aqualink_data - > time , sizeof ( _aqualink_data - > time ) , " %.7s " , msg + 9 ) ;
2019-05-25 16:52:36 +00:00
}
2019-09-25 17:31:53 +00:00
snprintf ( _aqualink_data - > date , sizeof ( _aqualink_data - > date ) , " %.3s " , msg + 5 ) ;
2023-05-14 21:35:13 +00:00
if ( checkAqualinkTime ( ) ! = true )
{
LOG ( AQRS_LOG , LOG_NOTICE , " RS time is NOT accurate '%s %s', re-setting on controller! \n " , _aqualink_data - > time , _aqualink_data - > date ) ;
aq_programmer ( AQ_SET_TIME , NULL , _aqualink_data ) ;
2023-05-21 15:03:27 +00:00
}
2019-05-25 16:52:36 +00:00
}
void process_pda_packet_msg_long_equipment_control ( const char * msg )
{
// These are listed as "FILTER PUMP OFF"
int i ;
char labelBuff [ AQ_MSGLEN + 1 ] ;
strncpy ( labelBuff , msg , AQ_MSGLEN - 4 ) ;
labelBuff [ AQ_MSGLEN - 4 ] = 0 ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " *** Checking Equiptment '%s' \n " , labelBuff ) ;
2019-05-25 16:52:36 +00:00
2020-06-20 16:09:54 +00:00
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + )
2019-05-25 16:52:36 +00:00
{
2020-07-18 16:37:19 +00:00
if ( strcasecmp ( stripwhitespace ( labelBuff ) , _aqualink_data - > aqbuttons [ i ] . label ) = = 0 )
2019-05-25 16:52:36 +00:00
{
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " *** Found EQ CTL Status for %s = '%.*s' \n " , _aqualink_data - > aqbuttons [ i ] . label , AQ_MSGLEN , msg ) ;
2019-05-25 16:52:36 +00:00
set_pda_led ( _aqualink_data - > aqbuttons [ i ] . led , msg [ AQ_MSGLEN - 1 ] ) ;
2022-05-31 22:04:32 +00:00
// Force SWG off if pump is off.
if ( ( i = = 0 ) & & ( _aqualink_data - > aqbuttons [ 0 ] . led - > state = = OFF ) ) {
setSWGoff ( _aqualink_data ) ;
}
2019-05-25 16:52:36 +00:00
}
}
2019-06-27 23:07:28 +00:00
// NSF I think we need to check TEMP1 and TEMP2 and set Pool HEater and Spa heater directly, to support single device.
2020-07-18 16:37:19 +00:00
if ( isSINGLE_DEV_PANEL ) {
2019-06-27 23:07:28 +00:00
if ( strcasecmp ( stripwhitespace ( labelBuff ) , " TEMP1 " ) = = 0 )
2020-07-18 16:37:19 +00:00
set_pda_led ( _aqualink_data - > aqbuttons [ _aqualink_data - > pool_heater_index ] . led , msg [ AQ_MSGLEN - 1 ] ) ;
2019-06-27 23:07:28 +00:00
if ( strcasecmp ( stripwhitespace ( labelBuff ) , " TEMP2 " ) = = 0 )
2020-07-18 16:37:19 +00:00
set_pda_led ( _aqualink_data - > aqbuttons [ _aqualink_data - > spa_heater_index ] . led , msg [ AQ_MSGLEN - 1 ] ) ;
2019-06-27 23:07:28 +00:00
}
2019-05-25 16:52:36 +00:00
}
void process_pda_packet_msg_long_home ( const char * msg )
{
if ( stristr ( msg , " POOL MODE " ) ! = NULL )
{
// If pool mode is on the filter pump is on but if it is off the filter pump might be on if spa mode is on.
if ( msg [ AQ_MSGLEN - 1 ] = = ' N ' )
{
_aqualink_data - > aqbuttons [ PUMP_INDEX ] . led - > state = ON ;
}
else if ( msg [ AQ_MSGLEN - 1 ] = = ' * ' )
{
_aqualink_data - > aqbuttons [ PUMP_INDEX ] . led - > state = FLASH ;
}
}
else if ( stristr ( msg , " POOL HEATER " ) ! = NULL )
{
2020-07-18 16:37:19 +00:00
set_pda_led ( _aqualink_data - > aqbuttons [ _aqualink_data - > pool_heater_index ] . led , msg [ AQ_MSGLEN - 1 ] ) ;
2019-05-25 16:52:36 +00:00
}
else if ( stristr ( msg , " SPA MODE " ) ! = NULL )
{
// when SPA mode is on the filter may be on or pending
if ( msg [ AQ_MSGLEN - 1 ] = = ' N ' )
{
_aqualink_data - > aqbuttons [ PUMP_INDEX ] . led - > state = ON ;
_aqualink_data - > aqbuttons [ SPA_INDEX ] . led - > state = ON ;
}
else if ( msg [ AQ_MSGLEN - 1 ] = = ' * ' )
{
_aqualink_data - > aqbuttons [ PUMP_INDEX ] . led - > state = FLASH ;
_aqualink_data - > aqbuttons [ SPA_INDEX ] . led - > state = ON ;
}
else
{
_aqualink_data - > aqbuttons [ SPA_INDEX ] . led - > state = OFF ;
}
}
else if ( stristr ( msg , " SPA HEATER " ) ! = NULL )
{
2020-07-18 16:37:19 +00:00
set_pda_led ( _aqualink_data - > aqbuttons [ _aqualink_data - > spa_heater_index ] . led , msg [ AQ_MSGLEN - 1 ] ) ;
2019-05-25 16:52:36 +00:00
}
}
2019-06-27 22:18:44 +00:00
void setSingleDeviceMode ( )
{
2020-07-18 16:37:19 +00:00
if ( isSINGLE_DEV_PANEL ! = true )
2019-06-27 22:18:44 +00:00
{
2020-07-18 16:37:19 +00:00
changePanelToMode_Only ( ) ;
LOG ( AQRS_LOG , LOG_ERR , " AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config \n " ) ;
2019-06-27 22:18:44 +00:00
}
}
2023-05-21 15:03:27 +00:00
void process_pda_packet_msg_long_set_time ( const char * msg )
{
2023-05-30 23:14:04 +00:00
/*
2023-05-21 15:03:27 +00:00
// NOT Working at moment, also wrong format
LOG ( PDA_LOG , LOG_DEBUG , " process_pda_packet_msg_long_set_temp \n " ) ;
if ( msg [ 4 ] = = ' / ' & & msg [ 7 ] = = ' / ' ) {
//DATE
2023-05-30 23:14:04 +00:00
//rsm_strncpycut(_aqualink_data->date, msg, AQ_MSGLEN-1, AQ_MSGLEN-1);
strncpy ( _aqualink_data - > date , msg + 11 , 3 ) ;
2023-05-21 15:03:27 +00:00
} else if ( msg [ 6 ] = = ' : ' & & msg [ 11 ] = = ' M ' ) {
// TIME
2023-05-30 23:14:04 +00:00
//rsm_strncpycut(_aqualink_data->time, msg, AQ_MSGLEN-1, AQ_MSGLEN-1);
if ( msg [ 4 ] = = ' ' )
strncpy ( _aqualink_data - > time , msg + 5 , 6 ) ;
else
2023-05-21 15:03:27 +00:00
}
2023-05-30 23:14:04 +00:00
*/
2023-05-21 15:03:27 +00:00
}
2019-05-25 16:52:36 +00:00
void process_pda_packet_msg_long_set_temp ( const char * msg )
{
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " process_pda_packet_msg_long_set_temp \n " ) ;
2019-05-25 16:52:36 +00:00
if ( stristr ( msg , " POOL HEAT " ) ! = NULL )
{
_aqualink_data - > pool_htr_set_point = atoi ( msg + 10 ) ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " pool_htr_set_point = %d \n " , _aqualink_data - > pool_htr_set_point ) ;
2019-05-25 16:52:36 +00:00
}
else if ( stristr ( msg , " SPA HEAT " ) ! = NULL )
{
_aqualink_data - > spa_htr_set_point = atoi ( msg + 10 ) ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " spa_htr_set_point = %d \n " , _aqualink_data - > spa_htr_set_point ) ;
2019-05-25 16:52:36 +00:00
}
2019-06-27 22:18:44 +00:00
else if ( stristr ( msg , " TEMP1 " ) ! = NULL )
{
setSingleDeviceMode ( ) ;
_aqualink_data - > pool_htr_set_point = atoi ( msg + 10 ) ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " pool_htr_set_point = %d \n " , _aqualink_data - > pool_htr_set_point ) ;
2019-06-27 22:18:44 +00:00
}
else if ( stristr ( msg , " TEMP2 " ) ! = NULL )
{
setSingleDeviceMode ( ) ;
_aqualink_data - > spa_htr_set_point = atoi ( msg + 10 ) ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " spa_htr_set_point = %d \n " , _aqualink_data - > spa_htr_set_point ) ;
2019-06-27 22:18:44 +00:00
}
2019-05-25 16:52:36 +00:00
}
void process_pda_packet_msg_long_spa_heat ( const char * msg )
{
2019-06-05 16:41:38 +00:00
if ( strncasecmp ( msg , " ENABLED " , 16 ) = = 0 )
2019-05-25 16:52:36 +00:00
{
2020-07-18 16:37:19 +00:00
_aqualink_data - > aqbuttons [ _aqualink_data - > spa_heater_index ] . led - > state = ENABLE ;
2019-05-25 16:52:36 +00:00
}
2019-06-05 16:41:38 +00:00
else if ( strncasecmp ( msg , " SET TO " , 8 ) = = 0 )
2019-05-25 16:52:36 +00:00
{
_aqualink_data - > spa_htr_set_point = atoi ( msg + 8 ) ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " spa_htr_set_point = %d \n " , _aqualink_data - > spa_htr_set_point ) ;
2019-05-25 16:52:36 +00:00
}
}
void process_pda_packet_msg_long_pool_heat ( const char * msg )
{
2019-06-05 16:41:38 +00:00
if ( strncasecmp ( msg , " ENABLED " , 16 ) = = 0 )
2019-05-25 16:52:36 +00:00
{
2020-07-18 16:37:19 +00:00
_aqualink_data - > aqbuttons [ _aqualink_data - > pool_heater_index ] . led - > state = ENABLE ;
2019-05-25 16:52:36 +00:00
}
2019-06-05 16:41:38 +00:00
else if ( strncasecmp ( msg , " SET TO " , 8 ) = = 0 )
2019-05-25 16:52:36 +00:00
{
_aqualink_data - > pool_htr_set_point = atoi ( msg + 8 ) ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " pool_htr_set_point = %d \n " , _aqualink_data - > pool_htr_set_point ) ;
2019-05-25 16:52:36 +00:00
}
}
void process_pda_packet_msg_long_freeze_protect ( const char * msg )
{
2019-06-05 16:41:38 +00:00
if ( strncasecmp ( msg , " TEMP " , 10 ) = = 0 )
2019-05-25 16:52:36 +00:00
{
_aqualink_data - > frz_protect_set_point = atoi ( msg + 10 ) ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " frz_protect_set_point = %d \n " , _aqualink_data - > frz_protect_set_point ) ;
2019-05-25 16:52:36 +00:00
}
}
2022-05-31 22:04:32 +00:00
void process_pda_packet_msg_long_SWG ( int index , const char * msg )
2019-05-25 16:52:36 +00:00
{
2022-05-31 22:04:32 +00:00
char * ptr = NULL ;
// Single Setpoint
// PDA Line 0 = SET AquaPure
// PDA Line 1 =
// PDA Line 2 =
// PDA Line 3 = SET TO 100%
// PDA Line 0 = SET AquaPure
// PDA Line 1 =
// PDA Line 2 =
// PDA Line 3 = SET TO: 20%
// Dual Setpoint
// 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%
// Note: use pda_m_line(index) instead of msg because it is NULL terminated
if ( ( ptr = strcasestr ( pda_m_line ( index ) , " SET TO " ) ) ! = NULL ) {
setSWGpercent ( _aqualink_data , atoi ( ptr + 7 ) ) ;
LOG ( PDA_LOG , LOG_DEBUG , " swg_percent = %d \n " , _aqualink_data - > swg_percent ) ;
} else if ( ( ptr = strcasestr ( pda_m_line ( index ) , " SET SPA TO " ) ) ! = NULL ) {
if ( _aqualink_data - > aqbuttons [ SPA_INDEX ] . led - > state ! = OFF ) {
setSWGpercent ( _aqualink_data , atoi ( ptr + 11 ) ) ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " SPA swg_percent = %d \n " , _aqualink_data - > swg_percent ) ;
2019-05-25 16:52:36 +00:00
}
2022-05-31 22:04:32 +00:00
} else if ( ( ptr = strcasestr ( pda_m_line ( index ) , " SET POOL TO " ) ) ! = NULL ) {
if ( _aqualink_data - > aqbuttons [ SPA_INDEX ] . led - > state = = OFF ) {
setSWGpercent ( _aqualink_data , atoi ( ptr + 12 ) ) ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " POOL swg_percent = %d \n " , _aqualink_data - > swg_percent ) ;
2022-05-31 22:04:32 +00:00
}
} else if ( index = = 3 ) {
LOG ( PDA_LOG , LOG_ERR , " process msg SWG POOL idx %d unmatched %s \n " , index , pda_m_line ( index ) ) ;
2019-05-25 16:52:36 +00:00
}
}
void process_pda_packet_msg_long_unknown ( const char * msg )
{
int i ;
// Lets make a guess here and just see if there is an ON/OFF/ENA/*** at the end of the line
// When you turn on/off a piece of equiptment, a clear screen followed by single message is sent.
// So we are not in any PDA menu, try to catch that message here so we catch new device state ASAP.
if ( msg [ AQ_MSGLEN - 1 ] = = ' N ' | | msg [ AQ_MSGLEN - 1 ] = = ' F ' | | msg [ AQ_MSGLEN - 1 ] = = ' A ' | | msg [ AQ_MSGLEN - 1 ] = = ' * ' )
{
2020-06-20 16:09:54 +00:00
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + )
2019-05-25 16:52:36 +00:00
{
2020-07-18 16:37:19 +00:00
if ( stristr ( msg , _aqualink_data - > aqbuttons [ i ] . label ) ! = NULL )
2019-05-25 16:52:36 +00:00
{
2023-05-21 15:03:27 +00:00
//LOG(PDA_LOG,LOG_ERR," UNKNOWN Found Status for %s = '%.*s'\n", _aqualink_data->aqbuttons[i].label, AQ_MSGLEN, msg);
// This seems to keep everything off.
set_pda_led ( _aqualink_data - > aqbuttons [ i ] . led , msg [ AQ_MSGLEN - 1 ] ) ;
}
}
}
}
2023-05-30 23:14:04 +00:00
void pda_pump_update ( struct aqualinkdata * aq_data , int updated ) {
const int bitmask [ MAX_PUMPS ] = { 1 , 2 , 4 , 8 } ;
static unsigned char updates = ' \0 ' ;
int i ;
if ( updated = = - 1 ) {
for ( i = 0 ; i < MAX_PUMPS ; i + + ) {
if ( ( updates & bitmask [ i ] ) ! = bitmask [ i ] ) {
aq_data - > pumps [ i ] . rpm = PUMP_OFF_RPM ;
aq_data - > pumps [ i ] . gpm = PUMP_OFF_GPM ;
aq_data - > pumps [ i ] . watts = PUMP_OFF_WAT ;
}
}
updates = ' \0 ' ;
} else if ( updated > = 0 & & updated < MAX_PUMPS ) {
updates | = bitmask [ updated ] ;
}
}
2023-06-24 19:15:52 +00:00
/*
// Messages from different PDA versions.
PDA Menu Line 0 = Equipment Status
PDA Menu Line 1 =
PDA Menu Line 2 = Intelliflo VS 1
PDA Menu Line 3 = RPM : 1700
PDA Menu Line 4 = Watts : 367
- - - - - - - - - - - -
PDA Menu Line 2 = JANDY ePUMP 1
PDA Menu Line 3 = RPM : 2520
PDA Menu Line 4 = WATTS : 856
- - - - - - - - - - - -
PDA Menu Line 0 = EQUIPMENT STATUS
PDA Menu Line 1 =
PDA Menu Line 2 =
PDA Menu Line 3 = * * * PRIMING * * *
PDA Menu Line 4 = WATTS : 1303
- - - - - - - - - - - -
PDA Menu Line 4 = WATTS : 1298
- - - - - - - - - - - -
PDA Menu Line 0 = Equipment Status
PDA Menu Line 1 =
PDA Menu Line 2 = Intelliflo VS 1
PDA Menu Line 3 = ( Offline )
- - - - - - - - - -
PDA Menu Line 0 = EQUIPMENT STATUS
PDA Menu Line 1 =
PDA Menu Line 2 = JANDY ePUMP 1
PDA Menu Line 3 = RPM : 2520
PDA Menu Line 4 = WATTS : 809
- - - - - - - - - -
*/
// NSF This is now VERY similar to onetouch function get_pumpinfo_from_menu(), should thinmk about combining in future
void get_pda_pumpinfo_from_menu ( int menuLineIdx , int pump_number )
{
int rpm = 0 ;
int watts = 0 ;
int gpm = 0 ;
char * cidx = NULL ;
// valid controlpanel pump numbers are 1,2,3,4
if ( pump_number < 1 | | pump_number > MAX_PUMPS ) {
LOG ( PDA_LOG , LOG_WARNING , " Pump number %d for pump '%s' is invalid, ignoring! \n " , pump_number , pda_m_line ( menuLineIdx ) ) ;
return ;
}
if ( ( cidx = rsm_charafterstr ( pda_m_line ( menuLineIdx + 1 ) , " RPM " , AQ_MSGLEN ) ) ! = NULL ) {
rpm = rsm_atoi ( cidx ) ;
// Assuming Watts is always next line and GPM (if available) line after
if ( ( cidx = rsm_charafterstr ( pda_m_line ( menuLineIdx + 2 ) , " Watts " , AQ_MSGLEN ) ) ! = NULL ) {
watts = rsm_atoi ( cidx ) ;
2023-05-21 15:03:27 +00:00
}
2023-06-24 19:15:52 +00:00
if ( ( cidx = rsm_charafterstr ( pda_m_line ( menuLineIdx + 3 ) , " GPM " , AQ_MSGLEN ) ) ! = NULL ) {
gpm = rsm_atoi ( cidx ) ;
}
}
else if ( rsm_strcmp ( pda_m_line ( menuLineIdx + 1 ) , " *** Priming *** " ) = = 0 ) {
rpm = PUMP_PRIMING ;
}
else if ( rsm_strcmp ( pda_m_line ( menuLineIdx + 1 ) , " (Offline) " ) = = 0 ) {
rpm = PUMP_OFFLINE ;
}
else if ( rsm_strcmp ( pda_m_line ( menuLineIdx + 1 ) , " (Priming Error) " ) = = 0 ) {
rpm = PUMP_ERROR ;
}
2023-05-21 15:03:27 +00:00
2023-06-24 19:15:52 +00:00
if ( rpm = = 0 & & watts = = 0 & & rpm = = 0 ) {
// Didn't get any info, so return.
return ;
}
LOG ( PDA_LOG , LOG_DEBUG , " Found Pump information '%s', RPM %d, Watts %d, GPM %d \n " , pda_m_line ( menuLineIdx ) , rpm , watts , gpm ) ;
for ( int i = 0 ; i < _aqualink_data - > num_pumps ; i + + ) {
if ( _aqualink_data - > pumps [ i ] . pumpIndex = = pump_number ) {
LOG ( PDA_LOG , LOG_DEBUG , " Pump label: %s Index: %d, Number: %d, RPM: %d, Watts: %d, GPM: %d \n " , _aqualink_data - > pumps [ i ] . button - > name , i , pump_number , rpm , watts , gpm ) ;
pda_pump_update ( _aqualink_data , i ) ;
_aqualink_data - > pumps [ i ] . rpm = rpm ;
_aqualink_data - > pumps [ i ] . watts = watts ;
_aqualink_data - > pumps [ i ] . gpm = gpm ;
if ( _aqualink_data - > pumps [ i ] . pumpType = = PT_UNKNOWN ) {
if ( rsm_strcmp ( pda_m_line ( menuLineIdx ) , " Intelliflo VS " ) = = 0 )
_aqualink_data - > pumps [ i ] . pumpType = VSPUMP ;
else if ( rsm_strcmp ( pda_m_line ( menuLineIdx ) , " Intelliflo VF " ) = = 0 )
_aqualink_data - > pumps [ i ] . pumpType = VFPUMP ;
else if ( rsm_strcmp ( pda_m_line ( menuLineIdx ) , " Jandy ePUMP " ) = = 0 | |
rsm_strcmp ( pda_m_line ( menuLineIdx ) , " ePump AC " ) = = 0 )
_aqualink_data - > pumps [ i ] . pumpType = EPUMP ;
LOG ( PDA_LOG , LOG_DEBUG , " Pump index %d set PumpType to %d \n " , i , _aqualink_data - > pumps [ i ] . pumpType ) ;
2019-05-25 16:52:36 +00:00
}
2023-06-24 19:15:52 +00:00
return ;
}
}
LOG ( PDA_LOG , LOG_WARNING , " PDA Could not find config for Pump %s, Number %d, RPM %d, Watts %d, GPM %d \n " , pda_m_line ( menuLineIdx ) , pump_number , rpm , watts , gpm ) ;
}
void log_pump_information ( ) {
int i ;
char * cidx = NULL ;
for ( i = 0 ; i < PDA_LINES ; i + + )
{
if ( ( cidx = rsm_charafterstr ( pda_m_line ( i ) , " Intelliflo VS " , AQ_MSGLEN ) ) ! = NULL | |
( cidx = rsm_charafterstr ( pda_m_line ( i ) , " Intelliflo VF " , AQ_MSGLEN ) ) ! = NULL | |
( cidx = rsm_charafterstr ( pda_m_line ( i ) , " Jandy ePUMP " , AQ_MSGLEN ) ) ! = NULL | |
( cidx = rsm_charafterstr ( pda_m_line ( i ) , " ePump AC " , AQ_MSGLEN ) ) ! = NULL )
{
get_pda_pumpinfo_from_menu ( i , rsm_atoi ( cidx ) ) ;
2019-05-25 16:52:36 +00:00
}
2023-06-24 19:15:52 +00:00
/* // NSF This need to be used in the future and not process_pda_packet_msg_long_equiptment_status()
else if ( rsm_strcmp ( pda_m_line ( i ) , " AQUAPURE " ) = = 0 ) {
rtn = get_aquapureinfo_from_menu ( aq_data , i ) ;
} else if ( rsm_strcmp ( pda_m_line ( i ) , " Chemlink " ) = = 0 ) {
rtn = get_chemlinkinfo_from_menu ( aq_data , i ) ;
*/
2019-05-25 16:52:36 +00:00
}
}
2023-06-24 19:15:52 +00:00
2023-05-14 21:35:13 +00:00
void process_pda_packet_msg_long_equiptment_status ( const char * msg_line , int lineindex , bool reset )
{
2023-05-30 23:14:04 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " *** Pass Equiptment msg '%.16s' \n " , msg_line ) ;
2023-05-21 15:03:27 +00:00
if ( msg_line = = NULL ) {
2023-05-30 23:14:04 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " *** Pass Equiptment msg is NULL do nothing \n " ) ;
2023-05-21 15:03:27 +00:00
return ;
}
2023-05-14 21:35:13 +00:00
static char * index ;
int i ;
char * msg = ( char * ) msg_line ;
while ( isspace ( * msg ) ) msg + + ;
2023-05-21 15:03:27 +00:00
//strncpy(labelBuff, msg, AQ_MSGLEN);
2023-05-14 21:35:13 +00:00
// EQUIPMENT STATUS
//
// AquaPure 100%
// SALT 25500 PPM
// FILTER PUMP
// POOL HEAT
// SPA HEAT ENA
// EQUIPMENT STATUS
//
// FREEZE PROTECT
// AquaPure 100%
// SALT 25500 PPM
// CHECK AquaPure
// GENERAL FAULT
// FILTER PUMP
// CLEANER
//
2022-05-31 22:04:32 +00:00
// EQUIPMENT STATUS
//
// BOOST
// 23:59 REMAIN
// SALT 25500 PPM
// FILTER PUMP
2023-05-30 23:14:04 +00:00
// VSP Pumps are not read here, since they are over multiple lines.
2023-05-14 21:35:13 +00:00
// Check message for status of device
// Loop through all buttons and match the PDA text.
2023-05-21 15:03:27 +00:00
// Should probably use strncasestr
2023-06-23 20:16:30 +00:00
if ( ( index = rsm_strncasestr ( msg , " CHECK AquaPure " , AQ_MSGLEN ) ) ! = NULL )
2023-05-14 21:35:13 +00:00
{
LOG ( PDA_LOG , LOG_DEBUG , " CHECK AquaPure \n " ) ;
}
2023-06-23 20:16:30 +00:00
else if ( ( index = rsm_strncasestr ( msg , " FREEZE PROTECT " , AQ_MSGLEN ) ) ! = NULL )
2023-05-14 21:35:13 +00:00
{
_aqualink_data - > frz_protect_state = ON ;
2024-03-30 18:17:13 +00:00
equiptment_update_cycle ( PDA_FREEZE_PROTECT_INDEX ) ;
2023-05-21 15:03:27 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " Freeze Protect is on \n " ) ;
2023-05-14 21:35:13 +00:00
}
2022-05-31 22:04:32 +00:00
else if ( ( index = rsm_strncasestr ( msg , " BOOST " , AQ_MSGLEN ) ) ! = NULL )
{
setSWGboost ( _aqualink_data , true ) ;
2024-03-30 18:17:13 +00:00
equiptment_update_cycle ( PDA_BOOST_INDEX ) ;
2022-05-31 22:04:32 +00:00
}
else if ( ( _aqualink_data - > boost ) & & ( ( index = rsm_strncasestr ( msg , " REMAIN " , AQ_MSGLEN ) ) ! = NULL ) )
{
2024-03-30 20:33:37 +00:00
//snprintf(_aqualink_data->boost_msg, sizeof(_aqualink_data->boost_msg), "%s", msg+2);
//Message is ' 23:21 Remain', we only want time part
snprintf ( _aqualink_data - > boost_msg , 6 , " %s " , msg ) ;
2024-05-22 23:57:33 +00:00
_aqualink_data - > boost_duration = rsm_HHMM2min ( _aqualink_data - > boost_msg ) ;
2022-05-31 22:04:32 +00:00
}
2023-06-23 20:16:30 +00:00
else if ( ( index = rsm_strncasestr ( msg , MSG_SWG_PCT , AQ_MSGLEN ) ) ! = NULL )
2023-05-14 21:35:13 +00:00
{
changeSWGpercent ( _aqualink_data , atoi ( index + strlen ( MSG_SWG_PCT ) ) ) ;
//_aqualink_data->swg_percent = atoi(index + strlen(MSG_SWG_PCT));
//if (_aqualink_data->ar_swg_status == SWG_STATUS_OFF) {_aqualink_data->ar_swg_status = SWG_STATUS_ON;}
LOG ( PDA_LOG , LOG_DEBUG , " AquaPure = %d \n " , _aqualink_data - > swg_percent ) ;
}
2023-06-23 20:16:30 +00:00
else if ( ( index = rsm_strncasestr ( msg , MSG_SWG_PPM , AQ_MSGLEN ) ) ! = NULL )
2023-05-14 21:35:13 +00:00
{
_aqualink_data - > swg_ppm = atoi ( index + strlen ( MSG_SWG_PPM ) ) ;
//if (_aqualink_data->ar_swg_status == SWG_STATUS_OFF) {_aqualink_data->ar_swg_status = SWG_STATUS_ON;}
LOG ( PDA_LOG , LOG_DEBUG , " SALT = %d \n " , _aqualink_data - > swg_ppm ) ;
2023-05-30 23:14:04 +00:00
}
2023-05-21 15:03:27 +00:00
else if ( rsm_strncmp ( msg_line , " POOL HEAT ENA " , AQ_MSGLEN ) = = 0 )
2023-05-14 21:35:13 +00:00
{
_aqualink_data - > aqbuttons [ _aqualink_data - > pool_heater_index ] . led - > state = ENABLE ;
2023-05-21 15:03:27 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " Pool Hearter is enabled \n " ) ;
2023-05-30 23:14:04 +00:00
//equiptment_update_cycle(_aqualink_data->pool_heater_index);
2023-05-21 15:03:27 +00:00
}
else if ( rsm_strncmp ( msg_line , " SPA HEAT ENA " , AQ_MSGLEN ) = = 0 )
{
2023-05-14 21:35:13 +00:00
_aqualink_data - > aqbuttons [ _aqualink_data - > spa_heater_index ] . led - > state = ENABLE ;
2023-05-30 23:14:04 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " Spa Hearter is enabled \n " ) ;
//equiptment_update_cycle(_aqualink_data->spa_heater_index);
2023-05-21 15:03:27 +00:00
}
else
{
2023-05-14 21:35:13 +00:00
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + )
{
2023-05-21 15:03:27 +00:00
//LOG(PDA_LOG,LOG_DEBUG, "*** check msg '%s' against '%s'\n",labelBuff,_aqualink_data->aqbuttons[i].label);
2023-05-30 23:14:04 +00:00
//LOG(PDA_LOG,LOG_DEBUG, "*** check msg '%.*s' against '%s'\n",AQ_MSGLEN,msg_line,_aqualink_data->aqbuttons[i].label);
2023-05-21 15:03:27 +00:00
if ( rsm_strncmp ( msg_line , _aqualink_data - > aqbuttons [ i ] . label , AQ_MSGLEN - 1 ) = = 0 )
//if (rsm_strcmp(_aqualink_data->aqbuttons[i].label, labelBuff) == 0)
2023-05-14 21:35:13 +00:00
{
equiptment_update_cycle ( i ) ;
2023-05-21 15:03:27 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " Found Status for %s = '%.*s' \n " , _aqualink_data - > aqbuttons [ i ] . label , AQ_MSGLEN , msg_line ) ;
2023-05-14 21:35:13 +00:00
// It's on (or delayed) if it's listed here.
if ( _aqualink_data - > aqbuttons [ i ] . led - > state ! = FLASH )
{
_aqualink_data - > aqbuttons [ i ] . led - > state = ON ;
}
break ;
}
}
}
2023-05-21 15:03:27 +00:00
2023-05-14 21:35:13 +00:00
}
2019-07-14 14:39:15 +00:00
void process_pda_packet_msg_long_level_aux_device ( const char * msg )
{
# ifdef BETA_PDA_AUTOLABEL
int li = - 1 ;
char * str , * label ;
2020-06-01 00:35:17 +00:00
if ( ! _aqconfig_ - > use_panel_aux_labels )
2019-07-14 14:39:15 +00:00
return ;
// NSF Need to check config for use_panel_aux_labels value and ignore if not set
// Only care once we have the full menu, so check line
// PDA Line 0 = LABEL AUX1
// PDA Line 1 =
// PDA Line 2 = CURRENT LABEL
// PDA Line 3 = AUX1
if ( ( strlen ( pda_m_line ( 3 ) ) > 0 ) & &
( strncasecmp ( pda_m_line ( 2 ) , " CURRENT LABEL " , 16 ) = = 0 ) & &
( strncasecmp ( pda_m_line ( 0 ) , " LABEL AUX " , 12 ) = = 0 ) ) {
str = pda_m_line ( 0 ) ;
li = atoi ( & str [ 12 ] ) ; // 12 is a guess, need to check on real system
if ( li > 0 ) {
str = cleanwhitespace ( pda_m_line ( 3 ) ) ;
label = ( char * ) malloc ( strlen ( str ) + 1 ) ;
strcpy ( label , str ) ;
2020-07-18 16:37:19 +00:00
_aqualink_data - > aqbuttons [ li - 1 ] . label = label ;
2019-07-14 14:39:15 +00:00
} else {
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_ERR , " PDA couldn't get AUX? number \n " , pda_m_line ( 0 ) ) ;
2019-07-14 14:39:15 +00:00
}
}
# endif
}
2019-05-25 16:52:36 +00:00
void process_pda_freeze_protect_devices ( )
{
// PDA Line 0 = FREEZE PROTECT
// PDA Line 1 = DEVICES
// PDA Line 2 =
// PDA Line 3 = FILTER PUMP X
// PDA Line 4 = SPA
// PDA Line 5 = CLEANER X
// PDA Line 6 = POOL LIGHT
// PDA Line 7 = SPA LIGHT
// PDA Line 8 = EXTRA AUX
// PDA Line 9 =
int i ;
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " process_pda_freeze_protect_devices \n " ) ;
2019-05-25 16:52:36 +00:00
for ( i = 1 ; i < PDA_LINES ; i + + )
{
if ( pda_m_line ( i ) [ AQ_MSGLEN - 1 ] = = ' X ' )
{
2020-07-18 16:37:19 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " PDA freeze protect enabled by %s \n " , pda_m_line ( i ) ) ;
2019-05-25 16:52:36 +00:00
if ( _aqualink_data - > frz_protect_state = = OFF )
{
_aqualink_data - > frz_protect_state = ENABLE ;
break ;
}
}
}
}
bool process_pda_packet ( unsigned char * packet , int length )
{
bool rtn = true ;
2023-05-14 21:35:13 +00:00
//int i;
2019-05-25 16:52:36 +00:00
char * msg ;
2023-05-14 21:35:13 +00:00
int index = - 1 ;
2023-05-30 23:14:04 +00:00
static bool equiptment_update_loop = false ;
static bool read_equiptment_menu = false ;
2023-05-21 15:03:27 +00:00
2019-05-25 16:52:36 +00:00
2023-05-30 23:14:04 +00:00
process_pda_menu_packet ( packet , length , in_programming_mode ( _aqualink_data ) ) ;
2019-05-25 16:52:36 +00:00
switch ( packet [ PKT_CMD ] )
{
2023-05-30 23:14:04 +00:00
case CMD_ACK :
LOG ( PDA_LOG , LOG_DEBUG , " RS Received ACK length %d. \n " , length ) ;
2019-05-25 16:52:36 +00:00
break ;
2023-05-30 23:14:04 +00:00
case CMD_PDA_CLEAR :
read_equiptment_menu = false ; // Reset the have read menu flag, since this is new menu.
break ;
2023-05-14 21:35:13 +00:00
2023-05-30 23:14:04 +00:00
case CMD_STATUS :
_aqualink_data - > last_display_message [ 0 ] = ' \0 ' ;
if ( equiptment_update_loop = = false & & pda_m_type ( ) = = PM_EQUIPTMENT_STATUS )
2019-05-25 16:52:36 +00:00
{
2023-05-30 23:14:04 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " **** PDA Start new Equiptment loop **** \n " ) ;
equiptment_update_loop = true ;
// Need to process the equiptment full MENU here
2019-05-25 16:52:36 +00:00
}
2023-05-30 23:14:04 +00:00
else if ( read_equiptment_menu = = false & & equiptment_update_loop = = true & & pda_m_type ( ) = = PM_EQUIPTMENT_STATUS )
2019-05-25 16:52:36 +00:00
{
2023-05-30 23:14:04 +00:00
LOG ( PDA_LOG , LOG_DEBUG , " **** PDA read Equiptment page **** \n " ) ;
log_pump_information ( ) ;
read_equiptment_menu = true ;
2019-05-25 16:52:36 +00:00
}
2023-05-30 23:14:04 +00:00
else if ( equiptment_update_loop = = true & & pda_m_type ( ) ! = PM_EQUIPTMENT_STATUS )
{
LOG ( PDA_LOG , LOG_DEBUG , " **** PDA End Equiptment loop **** \n " ) ;
// Moved onto different MENU. Probably need to update any pump changes
equiptment_update_loop = false ;
// End of equiptment status chain of menus, reset any pump or equiptment that wasn't listed in menus as long as we are not in programming mode
if ( ! in_programming_mode ( _aqualink_data ) ) {
pda_pump_update ( _aqualink_data , - 1 ) ;
equiptment_update_cycle ( - 1 ) ;
2023-05-14 21:35:13 +00:00
}
2023-05-30 23:14:04 +00:00
}
else if ( _initWithRS = = false & & pda_m_type ( ) = = PM_FW_VERSION )
{
_initWithRS = true ;
LOG ( PDA_LOG , LOG_DEBUG , " **** PDA INIT **** \n " ) ;
//printf("**** PDA INIT PUT BACK IN ****\n");
queueGetProgramData ( AQUAPDA , _aqualink_data ) ;
2019-05-25 16:52:36 +00:00
}
break ;
2023-05-30 23:14:04 +00:00
case CMD_MSG_LONG :
msg = ( char * ) packet + PKT_DATA + 1 ;
index = packet [ PKT_DATA ] & 0xF ;
if ( packet [ PKT_DATA ] = = 0x82 )
{ // Air & Water temp is always this ID
process_pda_packet_msg_long_temp ( msg ) ;
}
else if ( packet [ PKT_DATA ] = = 0x40 )
{ // Time is always on this ID
process_pda_packet_msg_long_time ( msg ) ;
}
else
{
switch ( pda_m_type ( ) )
{
case PM_EQUIPTMENT_CONTROL :
process_pda_packet_msg_long_equipment_control ( msg ) ;
break ;
case PM_HOME :
case PM_BUILDING_HOME :
process_pda_packet_msg_long_home ( msg ) ;
break ;
case PM_EQUIPTMENT_STATUS :
2023-06-24 19:15:52 +00:00
// NSF In the future need to run over this like log_pump_information()
// So move into that function. This way you can get status of devices
// that span over multiple lines (like AQUAPURE).
// Plus tell if a device is not seen in loop, so can turn it off.
2023-05-30 23:14:04 +00:00
process_pda_packet_msg_long_equiptment_status ( msg , index , false ) ;
break ;
case PM_SET_TEMP :
process_pda_packet_msg_long_set_temp ( msg ) ;
break ;
case PM_SPA_HEAT :
process_pda_packet_msg_long_spa_heat ( msg ) ;
break ;
case PM_POOL_HEAT :
process_pda_packet_msg_long_pool_heat ( msg ) ;
break ;
case PM_FREEZE_PROTECT :
process_pda_packet_msg_long_freeze_protect ( msg ) ;
break ;
case PM_AQUAPURE :
2022-05-31 22:04:32 +00:00
process_pda_packet_msg_long_SWG ( index , msg ) ;
2023-05-30 23:14:04 +00:00
break ;
case PM_AUX_LABEL_DEVICE :
process_pda_packet_msg_long_level_aux_device ( msg ) ;
break ;
case PM_SET_TIME :
process_pda_packet_msg_long_set_time ( 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 ) ;
break ;
}
}
2019-05-25 16:52:36 +00:00
break ;
2023-05-30 23:14:04 +00:00
case CMD_PDA_0x1B :
LOG ( PDA_LOG , LOG_DEBUG , " **** CMD_PDA_0x1B **** \n " ) ;
2019-05-25 16:52:36 +00:00
// We get two of these on startup, one with 0x00 another with 0x01 at index 4. Just act on one.
// Think this is PDA finishd showing startup screen
2023-05-30 23:14:04 +00:00
if ( packet [ 4 ] = = 0x00 ) {
if ( _initWithRS = = false )
{
_initWithRS = true ;
LOG ( PDA_LOG , LOG_DEBUG , " **** PDA INIT **** \n " ) ;
2020-06-01 00:35:17 +00:00
//aq_programmer(AQ_PDA_INIT, NULL, _aqualink_data);
2023-05-30 23:14:04 +00:00
queueGetProgramData ( AQUAPDA , _aqualink_data ) ;
delay ( 50 ) ; // Make sure this one runs first.
2019-07-14 14:39:15 +00:00
# ifdef BETA_PDA_AUTOLABEL
2023-05-30 23:14:04 +00:00
if ( _aqconfig_ - > use_panel_aux_labels )
aq_programmer ( AQ_GET_AUX_LABELS , NULL , _aqualink_data ) ;
2019-07-14 14:39:15 +00:00
# endif
2023-05-30 23:14:04 +00:00
aq_programmer ( AQ_PDA_WAKE_INIT , NULL , _aqualink_data ) ;
} else {
LOG ( PDA_LOG , LOG_DEBUG , " **** PDA WAKE INIT **** \n " ) ;
aq_programmer ( AQ_PDA_WAKE_INIT , NULL , _aqualink_data ) ;
}
2019-05-25 16:52:36 +00:00
}
2023-05-30 23:14:04 +00:00
break ;
2019-05-25 16:52:36 +00:00
}
if ( packet [ PKT_CMD ] = = CMD_MSG_LONG | | packet [ PKT_CMD ] = = CMD_PDA_HIGHLIGHT | |
2019-06-27 22:18:44 +00:00
packet [ PKT_CMD ] = = CMD_PDA_SHIFTLINES | | packet [ PKT_CMD ] = = CMD_PDA_CLEAR | |
packet [ PKT_CMD ] = = CMD_PDA_HIGHLIGHTCHARS )
2019-05-25 16:52:36 +00:00
{
// We processed the next message, kick any threads waiting on the message.
2020-06-01 00:35:17 +00:00
kick_aq_program_thread ( _aqualink_data , AQUAPDA ) ;
2019-05-25 16:52:36 +00:00
}
2023-05-30 23:14:04 +00:00
// HERE AS A TEST. NEED TO FULLY TEST THIS IS GOES TO PROD.
else if ( packet [ PKT_CMD ] = = CMD_STATUS )
{
kick_aq_program_thread ( _aqualink_data , AQUAPDA ) ;
}
2020-07-18 16:37:19 +00:00
2019-05-25 16:52:36 +00:00
return rtn ;
2019-05-31 23:08:45 +00:00
}
2023-05-30 23:14:04 +00:00