2017-12-30 20:12:01 +00:00
# ifndef AQUALINK_H_
# define AQUALINK_H_
# include <pthread.h>
2018-07-29 14:31:35 +00:00
# include <stdbool.h>
2023-05-14 21:35:13 +00:00
# include <stdint.h>
2017-12-30 20:12:01 +00:00
# include "aq_serial.h"
# include "aq_programmer.h"
2025-01-28 23:45:53 +00:00
# include "sensors.h"
2023-05-14 21:35:13 +00:00
//#include "aq_panel.h" // Moved to later in file to overcome circular dependancy. (crappy I know)
2017-12-30 20:12:01 +00:00
2023-06-04 21:17:48 +00:00
# define SIGRESTART SIGUSR1
# ifdef AQ_NO_THREAD_NETSERVICE
# define DEFAULT_POLL_SPEED -1
# define DEFAULT_POLL_SPEED_NON_THREADDED 2
# endif
2020-07-19 16:20:18 +00:00
2024-09-03 23:43:26 +00:00
# define CLIGHT_PANEL_FIX // Overcome bug in some jandy panels where color light status of on is not in LED status
2017-12-30 20:12:01 +00:00
# define TIME_CHECK_INTERVAL 3600
2023-05-16 16:17:42 +00:00
//#define TIME_CHECK_INTERVAL 100 // DEBUG ONLY
2017-12-30 20:12:01 +00:00
# define ACCEPTABLE_TIME_DIFF 120
2019-10-13 15:07:14 +00:00
// Use these settings to test time
//#define TIME_CHECK_INTERVAL 100
//#define ACCEPTABLE_TIME_DIFF 10
2023-06-04 21:17:48 +00:00
# define MAX_ZERO_READ_BEFORE_RECONNECT_NONBLOCKING 100000 // 10k normally
# define MAX_ZERO_READ_BEFORE_RECONNECT_BLOCKING (25 / (SERIAL_BLOCKING_TIME / 10) ) // Want this to be 25 seconds, so it's depdand on how long the serial blocking is
// Time in ms to delay between read requests in non blocking serial port. Have to set something to stop CPU spiking.
# define NONBLOCKING_SERIAL_DELAY 2
2017-12-30 20:12:01 +00:00
2023-05-14 21:35:13 +00:00
// The below will change state of devices before that are actually set on the control panel, this helps
// with duplicate messages that come in quick succession that can catch the state before it happens.
2024-06-14 22:11:57 +00:00
//#define PRESTATE_ONOFF
2023-05-14 21:35:13 +00:00
# define PRESTATE_SWG_SETPOINT
//#define PRESTATE_HEATER_SETPOINT // This one is not implimented yet
2020-07-26 19:28:58 +00:00
void intHandler ( int dummy ) ;
2023-05-14 21:35:13 +00:00
# ifdef AQ_PDA
bool checkAqualinkTime ( ) ; // Only need to externalise this for PDA
# endif
2023-06-23 20:16:30 +00:00
// There are cases where SWG will read 80% in allbutton and 0% in onetouch/aqualinktouch, this will compile that in or out
2020-07-26 19:28:58 +00:00
//#define READ_SWG_FROM_EXTENDED_ID
2020-06-20 16:09:54 +00:00
//#define TOTAL_BUTTONS 12
2020-07-18 16:37:19 +00:00
/*
2020-06-20 16:09:54 +00:00
# ifndef AQ_RS16
# define TOTAL_BUTTONS 12
# else
# define TOTAL_BUTTONS 20
# define RS16_VBUTTONS_START 13 // RS16 panel has 4 buttons with no LED's, so list them for manual matching to RS messages
# define RS16_VBUTTONS_END 16 // RS16 panel has 4 buttons with no LED's, so list them for manual matching to RS messages
# endif
2020-07-18 16:37:19 +00:00
*/
2017-12-30 20:12:01 +00:00
# define TEMP_UNKNOWN -999
2023-05-14 21:35:13 +00:00
# define TEMP_REFRESH -998
2018-09-23 21:54:15 +00:00
//#define UNKNOWN TEMP_UNKNOWN
2017-12-30 20:12:01 +00:00
# define DATE_STRING_LEN 30
2019-06-08 19:34:47 +00:00
# define MAX_PUMPS 4
2020-06-06 16:36:04 +00:00
# define MAX_LIGHTS 4
2025-01-28 23:45:53 +00:00
# define MAX_SENSORS 4
2019-05-31 23:08:45 +00:00
2024-09-06 23:32:20 +00:00
bool isVirtualButtonEnabled ( ) ;
2024-09-13 22:44:48 +00:00
# define PUMP_RPM_MAX 3450
# define PUMP_RPM_MIN 600
# define PUMP_GPM_MAX 130
# define PUMP_GPM_MIN 15
2017-12-30 20:12:01 +00:00
enum {
FAHRENHEIT ,
CELSIUS ,
UNKNOWN
} ;
typedef struct aqualinkkey
{
//int number;
//aqledstate *state;
aqled * led ;
char * label ;
char * name ;
2020-07-18 16:37:19 +00:00
//#ifdef AQ_PDA
// char *pda_label;
//#endif
2017-12-30 20:12:01 +00:00
unsigned char code ;
2024-09-03 23:43:26 +00:00
unsigned char rssd_code ;
2017-12-30 20:12:01 +00:00
int dz_idx ;
2020-08-28 19:12:38 +00:00
uint8_t special_mask ;
2024-10-12 22:37:26 +00:00
void * special_mask_ptr ;
2017-12-30 20:12:01 +00:00
} aqkey ;
2023-05-14 21:35:13 +00:00
// special_mask for above aqualinkkey structure.
2020-08-28 19:12:38 +00:00
# define VS_PUMP (1 << 0)
# define PROGRAM_LIGHT (1 << 1)
2023-05-16 16:17:42 +00:00
# define TIMER_ACTIVE (1 << 2)
2024-08-25 23:31:58 +00:00
//#define DIMMER_LIGHT (1 << 3) // NOT USED (Use PROGRAM_LIGHT or type LC_DIMMER)
2024-09-06 23:32:20 +00:00
# define VIRTUAL_BUTTON (1 << 4)
2017-12-30 20:12:01 +00:00
//typedef struct ProgramThread ProgramThread; // Definition is later
struct programmingthread {
pthread_t * thread_id ;
pthread_mutex_t thread_mutex ;
pthread_cond_t thread_cond ;
program_type ptype ;
//void *thread_args;
} ;
2023-05-14 21:35:13 +00:00
2017-12-30 20:12:01 +00:00
typedef enum action_type {
NO_ACTION = - 1 ,
POOL_HTR_SETOINT ,
SPA_HTR_SETOINT ,
FREEZE_SETPOINT ,
2019-10-13 15:07:14 +00:00
SWG_SETPOINT ,
2020-06-01 00:35:17 +00:00
SWG_BOOST ,
2020-07-18 16:37:19 +00:00
PUMP_RPM ,
2020-08-28 19:12:38 +00:00
PUMP_VSPROGRAM ,
POOL_HTR_INCREMENT , // Setpoint add value (can be negative)
2023-05-14 21:35:13 +00:00
SPA_HTR_INCREMENT , // Setpoint add value
ON_OFF ,
TIMER ,
LIGHT_MODE ,
2024-10-12 22:37:26 +00:00
LIGHT_BRIGHTNESS ,
2023-05-14 21:35:13 +00:00
DATE_TIME
2017-12-30 20:12:01 +00:00
} action_type ;
struct action {
action_type type ;
time_t requested ;
int value ;
2020-06-01 00:35:17 +00:00
int id ; // Only used for Pumps at the moment.
2017-12-30 20:12:01 +00:00
//char value[10];
} ;
2020-06-01 00:35:17 +00:00
// Moved to aq_programmer to stop circular dependancy
/*
typedef enum pump_type {
PT_UNKNOWN = - 1 ,
EPUMP ,
VSPUMP ,
VFPUMP
} pump_type ;
*/
2024-04-19 19:06:00 +00:00
/*
typedef enum simulator_type {
SIM_NONE ,
SIM_ALLB ,
SIM_ONET ,
SIM_PDA ,
SIM_IAQT
} simulator_type ;
*/
2024-06-18 23:53:05 +00:00
//#define PUMP_PRIMING -1
//#define PUMP_OFFLINE -2
//#define PUMP_ERROR -3
2020-07-18 16:37:19 +00:00
# define PUMP_OFF_RPM 0
# define PUMP_OFF_GPM PUMP_OFF_RPM
# define PUMP_OFF_WAT PUMP_OFF_RPM
2024-06-18 23:53:05 +00:00
// FUTURE VSP STATUS, keep panel status and RS485 status seperate
typedef enum panel_vsp_status
{
PS_OK = 0 , // Start at 0 to match actual status from RS, but go down from their.
PS_OFF = - 1 ,
PS_PRIMING = - 2 ,
PS_OFFLINE = - 3 ,
PS_ERROR = - 4
} panel_vsp_status ;
2024-08-31 23:01:12 +00:00
# define PUMP_NAME_LENGTH 30
2024-06-18 23:53:05 +00:00
2019-05-31 23:08:45 +00:00
typedef struct pumpd
{
int rpm ;
2020-06-01 00:35:17 +00:00
int gpm ;
2019-06-07 22:54:20 +00:00
int watts ;
2024-09-13 22:44:48 +00:00
int maxSpeed ; // Max rpm or gpm depending on pump
int minSpeed ;
2019-06-07 22:54:20 +00:00
unsigned char pumpID ;
2020-06-01 00:35:17 +00:00
int pumpIndex ;
2024-08-31 23:01:12 +00:00
char pumpName [ PUMP_NAME_LENGTH ] ;
//char *pumpName;
2020-06-01 00:35:17 +00:00
pump_type pumpType ;
2019-06-08 19:34:47 +00:00
//int buttonID;
2020-06-06 16:36:04 +00:00
protocolType prclType ;
2019-06-08 19:34:47 +00:00
aqkey * button ;
2020-06-01 00:35:17 +00:00
//bool updated;
2024-06-10 22:27:01 +00:00
// Other VSP values read directly from RS485
int mode ; // 0 local control, 1 remote control
//int driveState; // Haven't figured out what this is yet
int status ;
2024-06-18 23:53:05 +00:00
panel_vsp_status pStatus ; // FUTURE VSP STATUS,
2024-06-10 22:27:01 +00:00
int pressureCurve ;
2019-05-31 23:08:45 +00:00
} pump_detail ;
2020-06-06 16:36:04 +00:00
// color light modes (Aqualink program, Jandy, Jandy LED, SAm/SAL, Color Logic, Intellibrite)
typedef enum clight_type {
LC_PROGRAMABLE = 0 ,
LC_JANDY ,
LC_JANDYLED ,
LC_SAL ,
LC_CLOGIG ,
2023-05-16 22:27:45 +00:00
LC_INTELLIB ,
2024-09-03 23:43:26 +00:00
LC_HAYWCL ,
LC_SPARE_1 ,
LC_SPARE_2 ,
LC_SPARE_3 ,
2024-10-12 22:37:26 +00:00
LC_DIMMER , // use 0, 25, 50, 100
LC_DIMMER2 , // use range 0 to 100
2023-05-16 22:27:45 +00:00
NUMBER_LIGHT_COLOR_TYPES // This is used to size and count so add more prior to this
2020-06-06 16:36:04 +00:00
} clight_type ;
2023-05-14 21:35:13 +00:00
typedef enum {
NET_MQTT = 0 ,
NET_API ,
NET_WS ,
2024-06-10 22:27:01 +00:00
NET_DZMQTT ,
2024-12-03 23:53:23 +00:00
NET_TIMER , // Timer or Scheduler (eg poweron/freezeprotect check)
2024-10-12 22:37:26 +00:00
UNACTION_TIMER
2024-06-10 22:27:01 +00:00
} request_source ;
2023-05-14 21:35:13 +00:00
2020-06-06 16:36:04 +00:00
typedef struct clightd
{
clight_type lightType ;
aqkey * button ;
2024-08-25 23:31:58 +00:00
int currentValue ;
2024-11-10 21:06:29 +00:00
int lastValue ; // Used for AqualinkD self programming
2024-09-03 23:43:26 +00:00
aqledstate RSSDstate ; // state from rs serial adapter
2020-06-06 16:36:04 +00:00
} clight_detail ;
2023-05-14 21:35:13 +00:00
# include "aq_panel.h"
2017-12-30 20:12:01 +00:00
struct aqualinkdata
{
2019-06-27 22:18:44 +00:00
char version [ AQ_MSGLEN * 2 ] ;
2023-06-23 20:16:30 +00:00
char revision [ AQ_MSGLEN ] ;
2017-12-30 20:12:01 +00:00
char date [ AQ_MSGLEN ] ;
char time [ AQ_MSGLEN ] ;
2020-08-29 21:35:03 +00:00
char last_message [ AQ_MSGLONGLEN + 1 ] ; // Last ascii message from panel - allbutton (or PDA) protocol
char last_display_message [ AQ_MSGLONGLEN + 1 ] ; // Last message to display in web UI
2024-05-22 23:57:33 +00:00
bool is_display_message_programming ;
2017-12-30 20:12:01 +00:00
aqled aqualinkleds [ TOTAL_LEDS ] ;
aqkey aqbuttons [ TOTAL_BUTTONS ] ;
2020-07-18 16:37:19 +00:00
unsigned short total_buttons ;
2024-09-06 23:32:20 +00:00
unsigned short virtual_button_start ;
2017-12-30 20:12:01 +00:00
int air_temp ;
int pool_temp ;
int spa_temp ;
int temp_units ;
2020-07-18 16:37:19 +00:00
//bool single_device; // Pool or Spa only, not Pool & Spa (Thermostat setpoints are different)
2017-12-30 20:12:01 +00:00
int battery ;
int frz_protect_set_point ;
int pool_htr_set_point ;
int spa_htr_set_point ;
2018-02-19 00:55:50 +00:00
int swg_percent ;
int swg_ppm ;
2020-07-18 16:37:19 +00:00
unsigned char ar_swg_device_status ; // Actual state
2024-05-22 23:57:33 +00:00
unsigned char heater_err_status ;
2020-07-18 16:37:19 +00:00
aqledstate swg_led_state ; // Display state for UI's
2019-03-01 15:22:03 +00:00
aqledstate service_mode_state ;
2018-09-14 20:43:14 +00:00
aqledstate frz_protect_state ;
2020-06-01 00:35:17 +00:00
int num_pumps ;
2019-05-31 23:08:45 +00:00
pump_detail pumps [ MAX_PUMPS ] ;
2020-06-06 16:36:04 +00:00
int num_lights ;
clight_detail lights [ MAX_LIGHTS ] ;
2019-10-13 15:07:14 +00:00
bool boost ;
char boost_msg [ 10 ] ;
2024-05-22 23:57:33 +00:00
int boost_duration ; // need to remove boost message and use this
2020-06-06 16:36:04 +00:00
float ph ;
int orp ;
2020-07-18 16:37:19 +00:00
// Below this line is not state related. (Future just do a mem compare for change)
//aqkey *orderedbuttons[TOTAL_BUTTONS]; // Future to reduce RS4,6,8,12,16 & spa buttons
//unsigned short total_ordered_buttons;
2020-08-28 19:12:38 +00:00
unsigned char last_packet_type ;
2020-07-18 16:37:19 +00:00
int swg_delayed_percent ;
2024-04-19 19:06:00 +00:00
//bool simulate_panel; // NSF remove in future
unsigned char simulator_packet [ AQ_MAXPKTLEN + 1 ] ;
bool simulator_packet_updated ;
int simulator_packet_length ;
//bool simulator_active; // should be redundant with other two
unsigned char simulator_id ;
//simulator_type simulator_active;
emulation_type simulator_active ;
2023-06-04 21:17:48 +00:00
bool aqManagerActive ;
2020-07-18 16:37:19 +00:00
int open_websockets ;
struct programmingthread active_thread ;
struct action unactioned ;
unsigned char raw_status [ AQ_PSTLEN ] ;
// Multiple threads update this value.
volatile bool updated ;
2023-06-24 00:38:59 +00:00
char self [ AQ_MSGLEN * 2 ] ;
2023-06-23 20:16:30 +00:00
2025-01-28 23:45:53 +00:00
int num_sensors ;
external_sensor sensors [ MAX_SENSORS ] ;
2023-06-23 20:16:30 +00:00
# ifdef AQ_MANAGER
2023-06-20 03:23:22 +00:00
volatile bool run_slogger ;
2024-08-25 23:31:58 +00:00
int slogger_packets ;
bool slogger_debug ;
char slogger_ids [ 20 ] ;
2023-06-23 20:16:30 +00:00
# endif
2020-07-18 16:37:19 +00:00
# ifdef AQ_RS16
int rs16_vbutton_start ;
int rs16_vbutton_end ;
# endif
# ifdef AQ_PDA
int pool_heater_index ;
int spa_heater_index ;
int solar_heater_index ;
# endif
// Timing for DEBUG
2019-06-27 22:18:44 +00:00
# ifdef AQ_DEBUG
2019-01-28 18:50:14 +00:00
struct timespec last_active_time ;
struct timespec start_active_time ;
2019-06-27 22:18:44 +00:00
# endif
2024-09-03 23:43:26 +00:00
// Overcome color light bug, by reconnecting allbutton panel.
//bool reconnectAllButton;
2017-12-30 20:12:01 +00:00
} ;
2018-06-06 00:18:44 +00:00
# endif