forked from sfeakes/AqualinkD
-
Notifications
You must be signed in to change notification settings - Fork 0
/
aq_serial.h
492 lines (412 loc) · 15.7 KB
/
aq_serial.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
#ifndef AQ_SERIAL_H_
#define AQ_SERIAL_H_
#include <termios.h>
#include <stdbool.h>
#define CONNECTION_ERROR "ERROR No connection to RS control panel"
// Protocol types
#define PCOL_JANDY 0xFF
#define PCOL_PENTAIR 0xFE
#define PCOL_UNKNOWN 0xFD
// packet offsets
#define PKT_DEST 2
#define PKT_CMD 3
#define PKT_DATA 4
#define PKT_STATUS_BYTES 5
#define DEV_MASTER 0x00
#define SWG_DEV_ID 0x50
#define IAQ_DEV_ID 0x33
/* Few Device ID's in decimal for quick checking
# Pentair pump ID's
# 0x60 to 0x6F (0x60, 0x61 0x62, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F)
# Jandy pump ID's
# 0x78, 0x79, 0x7A, 0x7B
*/
#define PENTAIR_DEC_PUMP_MIN 96
#define PENTAIR_DEC_PUMP_MAX 111
#define JANDY_DEC_PUMP_MIN 120
#define JANDY_DEC_PUMP_MAX 123
// PACKET DEFINES Jandy
#define NUL 0x00
#define DLE 0x10
#define STX 0x02
#define ETX 0x03
// Pentair packet headder (first 4 bytes)
#define PP1 0xFF
#define PP2 0x00
#define PP3 0xFF
#define PP4 0xA5
#define PEN_CMD_STATUS 0x07
#define PEN_PKT_FROM 6
#define PEN_PKT_DEST 5
#define PEN_PKT_CMD 7
#define PEN_HI_B_RPM 14
#define PEN_LO_B_RPM 15
#define PEN_HI_B_WAT 12
#define PEN_LO_B_WAT 13
// END Pentair
#define AQ_MINPKTLEN 5
//#define AQ_MAXPKTLEN 64
#define AQ_MAXPKTLEN 128 // Max 79 bytes so far, so 128 is a guess at the moment, just seen large packets from iAqualink
#define AQ_PSTLEN 5
#define AQ_MSGLEN 16
#define AQ_MSGLONGLEN 128
#define AQ_TADLEN 13
/* COMMANDS */
#define CMD_PROBE 0x00
#define CMD_ACK 0x01
#define CMD_STATUS 0x02
#define CMD_MSG 0x03
#define CMD_MSG_LONG 0x04
#define CMD_MSG_LOOP_ST 0x08
/* ACK RETURN COMMANDS */
/*
#define ACK_NORMAL 0x00
#define ACK_SCREEN_BUSY_SCROLL 0x01 // Seems to be busy displaying last message, but can cache next message,
#define ACK_SCREEN_BUSY_BLOCK 0x03 // Seems to be don't send me any more shit.
*/
// Some keypads use 0x00 some 0x80 (think it's something to do with version, but need to figure it out)
// But if you use 0x80 for ack then you get a start loop cycle CMD_MSG_LOOP_ST
#define ACK_NORMAL 0x80
#define ACK_SCREEN_BUSY_SCROLL 0x81 // Seems to be busy displaying last message, but can cache next message,
#define ACK_SCREEN_BUSY_BLOCK 0x83 // Seems to be don't send me any more shit.
// Remove this and fix all compile errors when get time.
#define ACK_SCREEN_BUSY ACK_SCREEN_BUSY_SCROLL
#define ACK_IAQ_TOUCH 0x00
#define ACK_PDA 0x40
#define ACK_ONETOUCH 0x80
#define ACK_ALLB_SIM 0x80 // Jandy's Allbutton simulator uses this and not ACK_NORMAL
#define ACK_ALLB_SIM_BUSY 0x81 // Jandy's Allbutton simulator uses this and not ACK_SCREEN_BUSY_SCROLL
/* ONE TOUCH KEYCODES */
#define KEY_ONET_UP 0x06
#define KEY_ONET_DOWN 0x05
#define KEY_ONET_SELECT 0x04
#define KEY_ONET_PAGE_UP 0x03 // Top
#define KEY_ONET_BACK 0x02 // Middle
#define KEY_ONET_PAGE_DN 0x01 // Bottom
#define KEY_ONET_SELECT_1 KEY_ONET_PAGE_UP
#define KEY_ONET_SELECT_2 KEY_ONET_BACK
#define KEY_ONET_SELECT_3 KEY_ONET_PAGE_DN
/* AquaRite commands */
#define CMD_GETID 0x14 // May be remote control control
#define CMD_PERCENT 0x11 // Set Percent
#define CMD_PPM 0x16 // Received PPM
/* PDA KEY CODES */ // Just plating at the moment
#define KEY_PDA_UP 0x06
#define KEY_PDA_DOWN 0x05
#define KEY_PDA_BACK 0x02
#define KEY_PDA_SELECT 0x04
//#define KEY_PDA_PGUP 0x01 // Think these are hot key #1
//#define KEY_PDA_PGDN 0x03 // Think these are hot key #2
/* KEY/BUTTON CODES */
#define KEY_PUMP 0x02
#define KEY_SPA 0x01
#define KEY_AUX1 0x05
#define KEY_AUX2 0x0a
#define KEY_AUX3 0x0f
#define KEY_AUX4 0x06
#define KEY_AUX5 0x0b
#define KEY_AUX6 0x10
#define KEY_AUX7 0x15
#define KEY_POOL_HTR 0x12
#define KEY_SPA_HTR 0x17
#define KEY_SOLAR_HTR 0x1c
#define KEY_MENU 0x09
#define KEY_CANCEL 0x0e
#define KEY_LEFT 0x13
#define KEY_RIGHT 0x18
#define KEY_HOLD 0x19
#define KEY_OVERRIDE 0x1e
#define KEY_ENTER 0x1d
#ifdef AQ_RS16
//RS 12 & 16 are different from Aux4 to Aux7
#define KEY_RS16_AUX4 0x14
#define KEY_RS16_AUX5 0x03
#define KEY_RS16_AUX6 0x07
#define KEY_RS16_AUX7 0x06
// RS 12 & 16 have extra buttons
#define KEY_AUXB1 0x0b
#define KEY_AUXB2 0x10
#define KEY_AUXB3 0x15
#define KEY_AUXB4 0x1a
#define KEY_AUXB5 0x04
#define KEY_AUXB6 0x08
#define KEY_AUXB7 0x0d
#define KEY_AUXB8 0x0c
// End diff in RS12
#endif
#define BTN_PUMP "Filter_Pump"
#define BTN_SPA "Spa_Mode"
#define BTN_AUX1 "Aux_1"
#define BTN_AUX2 "Aux_2"
#define BTN_AUX3 "Aux_3"
#define BTN_AUX4 "Aux_4"
#define BTN_AUX5 "Aux_5"
#define BTN_AUX6 "Aux_6"
#define BTN_AUX7 "Aux_7"
#define BTN_POOL_HTR "Pool_Heater"
#define BTN_SPA_HTR "Spa_Heater"
#define BTN_SOLAR_HTR "Solar_Heater"
#define BTN_TEMP1_HTR "Temp1_Heater"
#define BTN_TEMP2_HTR "Temp2_Heater"
#ifdef AQ_RS16
#define BTN_AUXB1 "Aux_B1"
#define BTN_AUXB2 "Aux_B2"
#define BTN_AUXB3 "Aux_B3"
#define BTN_AUXB4 "Aux_B4"
#define BTN_AUXB5 "Aux_B5"
#define BTN_AUXB6 "Aux_B6"
#define BTN_AUXB7 "Aux_B7"
#define BTN_AUXB8 "Aux_B8"
#endif
#define BTN_PDA_PUMP "FILTER PUMP"
#define BTN_PDA_SPA "SPA"
#define BTN_PDA_AUX1 "AUX1"
#define BTN_PDA_AUX2 "AUX2"
#define BTN_PDA_AUX3 "AUX3"
#define BTN_PDA_AUX4 "AUX4"
#define BTN_PDA_AUX5 "AUX5"
#define BTN_PDA_AUX6 "AUX6"
#define BTN_PDA_AUX7 "AUX7"
#define BTN_PDA_POOL_HTR "POOL HEAT"
#define BTN_PDA_SPA_HTR "SPA HEAT"
#define BTN_PDA_SOLAR_HTR "EXTRA AUX"
#define BUTTON_LABEL_LENGTH 20
#ifndef AQ_RS16
#define TOTAL_LEDS 20
#else
#define TOTAL_LEDS 24 // Only 20 exist in control panel, but need space for the extra buttons on RS16 panel
#endif
// Index starting at 1
#define POOL_HTR_LED_INDEX 15
#define SPA_HTR_LED_INDEX 17
#define SOLAR_HTR_LED_INDEX 19
#define LNG_MSG_SERVICE_ACTIVE "SERVICE MODE IS ACTIVE"
#define LNG_MSG_TIMEOUT_ACTIVE "TIMEOUT MODE IS ACTIVE"
#define LNG_MSG_POOL_TEMP_SET "POOL TEMP IS SET TO"
#define LNG_MSG_SPA_TEMP_SET "SPA TEMP IS SET TO"
#define LNG_MSG_FREEZE_PROTECTION_SET "FREEZE PROTECTION IS SET TO"
#define LNG_MSG_CLEANER_DELAY "CLEANER WILL TURN ON AFTER SAFETY DELAY"
#define LNG_MSG_BATTERY_LOW "BATTERY LOW"
//#define LNG_MSG_FREEZE_PROTECTION_ACTIVATED "FREEZE PROTECTION ACTIVATED"
#define LNG_MSG_FREEZE_PROTECTION_ACTIVATED "FREEZE PROTECTION IS ACTIVATED"
#define MSG_AIR_TEMP "AIR TEMP"
#define MSG_POOL_TEMP "POOL TEMP"
#define MSG_SPA_TEMP "SPA TEMP"
#define MSG_AIR_TEMP_LEN 8
#define MSG_POOL_TEMP_LEN 9
#define MSG_SPA_TEMP_LEN 8
// Will get water temp rather than pool in some cases. not sure if it's REV specific or device (ie no spa) specific yet
#define MSG_WATER_TEMP "WATER TEMP"
#define MSG_WATER_TEMP_LEN 10
#define LNG_MSG_WATER_TEMP1_SET "TEMP1 (HIGH TEMP) IS SET TO"
#define LNG_MSG_WATER_TEMP2_SET "TEMP2 (LOW TEMP) IS SET TO"
/*
// All Messages listed in the manual, This is obviously not complete, but it's everything Jandy has published
BATTERY IS LOW, BATTERY LOCATED AT THE POWER CENTER
CLEANER CANNOT BE TURNED ON WHILE SPA IS ON
CLEANER CANNOT BE TURNED ON WHILE SPILLOVER IS ON
FREEZE PROTECTION ACTIVATED
SENSOR OPENED
POOL HEATER ENABLED
PUMP WILL REMAIN ON WHILE SPILLOVER IS ON
PUMP WILL TURN OFF AFTER COOL DOWN CYCLE
PUMP WILL TURN ON AFTER DELAY
SERVICE MODE IS ACTIVE
SENSOR SHORTED
SPA WILL TURN OFF AFTER COOL DOWN CYCLE
TIMED AUX ON, WILL TURN OFF AFTER 30 MINUTES
TIMEOUT MODE IS ACTIVE
SPILLOVER IS DISABLED WHILE SPA IS ON
*/
#define MSG_SWG_PCT "AQUAPURE" // AquaPure 55%
#define MSG_SWG_PPM "SALT" // Salt 3000 PPM
#define MSG_SWG_PCT_LEN 8
#define MSG_SWG_PPM_LEN 4
#define MSG_SWG_NO_FLOW "Check AQUAPURE No Flow"
#define MSG_SWG_LOW_SALT "Check AQUAPURE Low Salt"
#define MSG_SWG_HIGH_SALT "Check AQUAPURE High Salt"
#define MSG_SWG_FAULT "Check AQUAPURE General Fault"
#define MSG_PMP_RPM "RPM:"
#define MSG_PMP_WAT "Watts:"
#define MSG_PMP_GPM "GPM:"
/* AQUAPURE SWG */
// These are madeup.
//#define SWG_STATUS_OFF 0xFF
//#define SWG_STATUS_OFFLINE 0xFE
//#define SWG_STATUS_UNKNOWN -128 // Idiot. unsigned char....Derr.
#define SWG_STATUS_OFF 0xFF // Documented this as off in API, so don't change.
#define SWG_STATUS_UNKNOWN 0xFE
// These are actual from RS485
#define SWG_STATUS_ON 0x00
#define SWG_STATUS_NO_FLOW 0x01 // no flow 0x01
#define SWG_STATUS_LOW_SALT 0x02 // low salt 0x02
//#define SWG_STATUS_VLOW_SALT 0x04 // very low salt 0x04
#define SWG_STATUS_HI_SALT 0x04 // high salt 0x04
#define SWG_STATUS_CLEAN_CELL 0x08 // clean cell 0x10
#define SWG_STATUS_TURNING_OFF 0x09 // turning off 0x09
#define SWG_STATUS_HIGH_CURRENT 0x10 // high current 0x08
#define SWG_STATUS_LOW_VOLTS 0x20 // low voltage 0x20
#define SWG_STATUS_LOW_TEMP 0x40 // low watertemp 0x40
#define SWG_STATUS_CHECK_PCB 0x80 // check PCB 0x80
#define CMD_PDA_0x04 0x04 // No idea, might be building menu
#define CMD_PDA_0x05 0x05 // No idea
#define CMD_PDA_0x1B 0x1b
#define CMD_PDA_HIGHLIGHT 0x08
#define CMD_PDA_CLEAR 0x09
#define CMD_PDA_SHIFTLINES 0x0F
#define CMD_PDA_HIGHLIGHTCHARS 0x10
// One Touch commands
//#define CMD_PDA_0x04 0x04 // No idea, might be building menu
/* iAqualink */
#define CMD_IAQ_PAGE_MSG 0x25
#define CMD_IAQ_TABLE_MSG 0x26 // ??? Some form of table populate
#define CMD_IAQ_PAGE_BUTTON 0x24
#define CMD_IAQ_PAGE_START 0x23 // Start a new menu // wait for 0x28 before sending anything
#define CMD_IAQ_PAGE_END 0x28 // Some kind a finished
#define CMD_IAQ_STARTUP 0x29 // Startup message
#define CMD_IAQ_POLL 0x30 // Poll message or ready to receive command
#define CMD_IAQ_CTRL_READY 0x31 // Get this when we can send big control command
#define CMD_IAQ_PAGE_CONTINUE 0x40 // Seems we get this on AUX device page when there is another page, keeps circuling through pages.
//#define CMD_IAQ_VSP_ERROR 0x2c // Error when setting speed too high
#define CMD_IAQ_MSG_LONG 0x2c // This this is display popup message. Next 2 bytes 0x00|0x01 = wait and then 0x00|0x00 clear
/*
#define CMD_IAQ_MSG_3 0x2d // Equiptment status message??
#define CMD_IAQ_0x31 0x31 // Some pump speed info
*/
#define ACK_CMD_READY_CTRL 0x80 // Send this before sending big control command
#define KEY_IAQTCH_HOME 0x01
#define KEY_IAQTCH_MENU 0x02
#define KEY_IAQTCH_ONETOUCH 0x03
#define KEY_IAQTCH_HELP 0x04
#define KEY_IAQTCH_BACK 0x05
#define KEY_IAQTCH_STATUS 0x06
#define KEY_IAQTCH_PREV_PAGE 0x20
#define KEY_IAQTCH_NEXT_PAGE 0x21
// PAGE1 (Horosontal keys) (These are duplicate so probable delete)
#define KEY_IAQTCH_HOMEP_KEY01 0x11
#define KEY_IAQTCH_HOMEP_KEY02 0x12
#define KEY_IAQTCH_HOMEP_KEY03 0x13
#define KEY_IAQTCH_HOMEP_KEY04 0x14
#define KEY_IAQTCH_HOMEP_KEY05 0x15
#define KEY_IAQTCH_HOMEP_KEY06 0x16
#define KEY_IAQTCH_HOMEP_KEY07 0x17
#define KEY_IAQTCH_HOMEP_KEY08 0x18 // Other Devices (may not be able to change)
// Numbering is colum then row.
#define KEY_IAQTCH_KEY01 0x11 // Column 1 row 1
#define KEY_IAQTCH_KEY02 0x12 // column 1 row 2
#define KEY_IAQTCH_KEY03 0x13 // column 1 row 3
#define KEY_IAQTCH_KEY04 0x14 // column 1 row 4
#define KEY_IAQTCH_KEY05 0x15 // column 1 row 5
#define KEY_IAQTCH_KEY06 0x16 // column 2 row 1
#define KEY_IAQTCH_KEY07 0x17 // column 2 row 2
#define KEY_IAQTCH_KEY08 0x18 // column 2 row 3
#define KEY_IAQTCH_KEY09 0x19 // column 2 row 4
#define KEY_IAQTCH_KEY10 0x1a // column 2 row 5
#define KEY_IAQTCH_KEY11 0x1b // column 3 row 1
#define KEY_IAQTCH_KEY12 0x1c // column 3 row 2
#define KEY_IAQTCH_KEY13 0x1d // column 3 row 3
#define KEY_IAQTCH_KEY14 0x1e // column 3 row 4
#define KEY_IAQTCH_KEY15 0x1f // column 3 row 5
#define IAQ_PAGE_HOME 0x01
#define IAQ_PAGE_STATUS 0x5b
#define IAQ_PAGE_STATUS2 0x2a // Something get this for Status rather than 0x5b
#define IAQ_PAGE_DEVICES 0x36
#define IAQ_PAGE_DEVICES2 0x35
#define IAQ_PAGE_SET_TEMP 0x39
#define IAQ_PAGE_MENU 0x0f
#define IAQ_PAGE_SET_VSP 0x1e
#define IAQ_PAGE_SET_TIME 0x4b
#define IAQ_PAGE_SET_DATE 0x4e
#define IAQ_PAGE_SET_SWG 0x30
#define IAQ_PAGE_SET_BOOST 0x1d
#define IAQ_PAGE_SET_QBOOST 0x3f
#define IAQ_PAGE_ONETOUCH 0x4d
#define IAQ_PAGE_COLOR_LIGHT 0x48
#define IAQ_PAGE_SYSTEM_SETUP 0x14
#define IAQ_PAGE_VSP_SETUP 0x2d
#define IAQ_PAGE_FREEZE_PROTECT 0x11
#define IAQ_PAGE_LABEL_AUX 0x32
//#define IAQ_PAGE_START_BOOST 0x3f
#define RSSA_DEV_STATUS 0x13
#define RSSA_DEV_READY 0x07 // Ready to receive change command
// For the moment, rest of RS_RA are in serialadapter.h
// Errors from get_packet
#define AQSERR_READ -1 // General fileIO read error
#define AQSERR_TIMEOUT -2 // Timeout
#define AQSERR_CHKSUM -3 // Checksum failed
#define AQSERR_2LARGE -4 // Buffer Overflow
#define AQSERR_2SMALL -5 // Not enough read
// At the moment just used for next ack
typedef enum {
DRS_NONE,
DRS_SWG,
DRS_EPUMP
} rsDeviceType;
typedef enum {
ON,
OFF,
FLASH,
ENABLE,
LED_S_UNKNOWN
} aqledstate;
typedef struct aqualinkled
{
//int number;
aqledstate state;
} aqled;
// Battery Status Identifiers
enum {
OK = 0,
LOW
};
typedef enum {
JANDY,
PENTAIR,
P_UNKNOWN
} protocolType;
int init_serial_port(const char* tty);
int init_blocking_serial_port(const char* tty);
int init_readahead_serial_port(const char* tty);
void close_serial_port(int file_descriptor);
void close_blocking_serial_port();
//#ifdef AQ_PDA
//void set_pda_mode(bool mode);
//bool pda_mode();
//#endif
int generate_checksum(unsigned char* packet, int length);
protocolType getProtocolType(unsigned char* packet);
bool check_jandy_checksum(unsigned char* packet, int length);
bool check_pentair_checksum(unsigned char* packet, int length);
void send_ack(int file_descriptor, unsigned char command);
void send_extended_ack(int fd, unsigned char ack_type, unsigned char command);
//void send_cmd(int file_descriptor, unsigned char cmd, unsigned char args);
int get_packet(int file_descriptor, unsigned char* packet);
int get_packet_lograw(int fd, unsigned char* packet);
//int get_packet_new(int fd, unsigned char* packet);
//int get_packet_new_lograw(int fd, unsigned char* packet);
//void close_serial_port(int file_descriptor, struct termios* oldtio);
//void process_status(void const * const ptr);
void process_status(unsigned char* ptr);
const char* get_packet_type(unsigned char* packet , int length);
/*
void set_onetouch_enabled(bool mode);
bool onetouch_enabled();
void set_iaqtouch_enabled(bool mode);
bool iaqtouch_enabled();
bool VSP_enabled();
void set_extended_device_id_programming(bool mode);
bool extended_device_id_programming();
*/
void send_jandy_command(int fd, unsigned char *packet_buffer, int size);
void send_pentair_command(int fd, unsigned char *packet_buffer, int size);
void send_command(int fd, unsigned char *packet_buffer, int size);
/*
#ifdef ONETOUCH
void set_onetouch_mode(bool mode);
bool onetouch_mode();
#endif
*/
//void send_test_cmd(int fd, unsigned char destination, unsigned char b1, unsigned char b2, unsigned char b3);
//void send_command(int fd, unsigned char destination, unsigned char b1, unsigned char b2, unsigned char b3);
//void send_messaged(int fd, unsigned char destination, char *message);
#endif // AQ_SERIAL_H_