Skip to content

Commit

Permalink
V0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
sfeakes committed Oct 13, 2019
1 parent a77dfc6 commit 23c0280
Show file tree
Hide file tree
Showing 23 changed files with 1,658 additions and 42 deletions.
22 changes: 18 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ LIBS := -lpthread -lm

# debug of not
#DBG = -g -O0 -fsanitize=address -static-libasan
#DBG = -g
DBG = -g
#DBG = -D TESTING
DBG =
#DBG =

# define any compile-time flags
#CFLAGS = -Wall -g -lpthread -lwiringPi -lm -I.
Expand All @@ -30,19 +30,28 @@ INCLUDES = -I./ -I./GPIO_Pi -I./minIni
# define the C source files
#SRCS = aqualinkd.c utils.c config.c aq_serial.c init_buttons.c aq_programmer.c net_services.c json_messages.c mongoose.c

.SUFFIXES: .o_test

#SL_SRC = serial_logger.c aq_serial.c utils.c
#AL_SRC = aquapure_logger.c aq_serial.c utils.c
SRCS = aquapure.c ap_net_services.c SWG_device.c aq_serial.c utils.c mongoose.c json_messages.c config.c packetLogger.c GPIO_device.c ./GPIO_Pi/GPIO_Pi.c ./minIni/minIni.c
SRCS = aquapure.c ap_net_services.c SWG_device.c aq_serial.c utils.c mongoose.c json_messages.c config.c \
packetLogger.c GPIO_device.c ./GPIO_Pi/GPIO_Pi.c ./minIni/minIni.c
#SRCS = aq_serial.c utils.c mongoose.c json_messages.c config.c aquapured/ap_net_services.c aquapured/ap_config.c aquapured/aquapure.c
TEST_D_SRC = aquapure.c aq_serial.c

OBJS = $(SRCS:.c=.o)

TEST_SRC := $(filter-out $(TEST_D_SRC), $(SRCS))
TEST_OBJS = $(TEST_SRC:.c=.o)
TEST_D_OBJS = $(TEST_D_SRC:.c=.o_test)

#SL_OBJS = $(SL_SRC:.c=.o)
#AL_OBJS = $(AL_SRC:.c=.o)
#AP_OBJS = $(AP_SRC:.c=.o)

# define the executable file
MAIN = ./release/aquapured
TEST = ./release/aquapured_test

#SLOG = ./release/serial_logger
#AQUAPURELOG = ./release/aquapure_logger
Expand All @@ -54,6 +63,8 @@ all: $(MAIN)
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)

test: $(TEST_OBJS) $(TEST_D_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(TEST) $(TEST_OBJS) $(TEST_D_OBJS) $(LFLAGS) $(LIBS)

# this is a suffix replacement rule for building .o's from .c's
# it uses automatic variables $<: the name of the prerequisite of
Expand All @@ -62,8 +73,11 @@ $(MAIN): $(OBJS)
.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

.c.o_test:
$(CC) $(CFLAGS) $(INCLUDES) -D TESTING -c $< -o $@

clean:
$(RM) *.o *~ $(MAIN) $(MAIN_U)
$(RM) *.o *~ *.o_test $(MAIN) $(MAIN_U) $(TEST)

depend: $(SRCS)
makedepend $(INCLUDES) $^
Expand Down
51 changes: 36 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,44 @@
linux daemon to control Aquapure SWG without the need for a pool control panel.

## Note
This is an old fork of AqualinkD, simply to test at the moment, not ment to be consumable.
This is still in beta mode.

To be considered ALPHA release at present.
After downloading
Please edit `./release/aquapured.conf` and change configuration to your setup.

run
```
sudo ./release/aquapured -d -c ./release/aquapured.conf
```
To run
```sudo ./release/aquapured -d -c ./release/aquapured.conf```

You should see bunch of messages then
```
Debug: Sent Probe | HEX: 0x10|0x02|0x50|0x00|0x62|0x10|0x03|
```
### Currently supported
SWG using Jandy protocol (this is most SWG, including Pentair).
MQTT, Web API, Web Sockets and Basic Web UI
Use of GPIO to control relays to turn on/off other pool equiptment.
Homekit integration with homekit-aqualinkd

### Web API
http://ip/?command=status (return JSON status)
http://ip/?command=swg_percent&value=50 (Set SWG Percent to 50)
http://ip/?command=swg&value=on (Set SWG on or off)
http://ip/?command=GPIO_13&value=on (Set GPIO 13 on or off)

### MQTT
#### Status posted. 0=off 1=on,
aquapured/SWG 0
aquapured/SWG/Percent 30
aquapured/SWG/fullstatus 254
aquapured/SWG/PPM 3100
aquapured/SWG/enabled 0
aquapured/SWG/Boost 0
aquapured/GPIO_13 0
aquapured/GPIO_19 0
aquapured/GPIO_18 0
aquapured/GPIO_16 0

#### Make requests over MQTT
Add /set to topic and messages are 0=off, 1=on or number between 1 and 100 for percent.
aquapured/SWG/set
aquapured/SWG/Percent/set
aquapured/SWG/Boost/set
aquapured/GPIO_13/set

If you see an ACK after the probe, then we are in buisness. If not, and the RS485 port is setup correctly, then not much can be done.
```
To 0x50 of type Probe | HEX: 0x10|0x02|0x50|0x00|0x62|0x10|0x03|
From 0x50 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|

```
28 changes: 27 additions & 1 deletion SWG_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>


#include "SWG_device.h"
#include "utils.h"
#include "aq_serial.h"
#include "aqualink.h"
#include "aq_mqtt.h"

#define CACHE_FILE "/tmp/aquapure.cache"
#define CMD_NONE 0xFF
Expand All @@ -29,7 +31,11 @@ double timval_diff(struct timeval time1, struct timeval time2) {
return(result);

}

void set_display_message(char *msg)
{
snprintf(_apdata_.display_message, DISMSGLEN, msg);
}
// END --- NSF MOVE THIS TO UTILS OR SOMEWHERE

void debugStatusPrint();

Expand Down Expand Up @@ -295,6 +301,26 @@ void set_swg_on(bool val) {
_apdata_.changed = true;
}

bool action_boost_request(char *value)
{

if (value != NULL) {
if (strcmp(value, "on") == 0 ) {
set_swg_boost(true);
} else if (strcmp(value, "off") == 0 ) {
set_swg_boost(false);
} else if ( atoi(value) == MQTT_ON ) {
set_swg_boost(true);
} else if ( atoi(value) == MQTT_OFF ) {
set_swg_boost(false);
}
}

// Force update even if value wasn't changed to re-set UI's.
_apdata_.changed = true;
return true;
}


void write_swg_cache() {
FILE *fp;
Expand Down
4 changes: 4 additions & 0 deletions SWG_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
const extern struct apdata _apdata_;
#endif

#define DISMSGLEN 30

// connected, receiving ACK
// status, status from RS485 (on & generating are same status)
Expand All @@ -27,6 +28,7 @@ struct apdata
bool connected;
char *cache_file;
bool changed;
char display_message[DISMSGLEN+1]; // Need to move this to a generic data, not device data
};


Expand All @@ -39,8 +41,10 @@ void set_swg_req_percent(char *sval, bool f2c);
void set_swg_percent(int percent);
void set_swg_boost(bool val);
void set_swg_on(bool val);
bool action_boost_request(char *value);

void write_swg_cache();
void read_swg_cache();
void set_display_message(char *msg);

#endif
100 changes: 89 additions & 11 deletions ap_net_services.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static void signal_handler(int sig_num) {
s_signal_received = sig_num;
}

void send_mqtt(struct mg_connection *nc, char *toppic, char *message) {
void send_mqtt(struct mg_connection *nc, const char *toppic, char *message) {
static uint16_t msg_id = 0;

if (toppic == NULL)
Expand Down Expand Up @@ -122,6 +122,19 @@ void send_mqtt_float_msg(struct mg_connection *nc, char *dev_name, float value)
send_mqtt(nc, mqtt_pub_topic, msg);
}

void send_domoticz_mqtt_status_message(struct mg_connection *nc, int idx, int value, char *svalue) {
if (idx <= 0)
return;

char mqtt_msg[JSON_MQTT_MSG_SIZE];
build_dz_mqtt_status_message_JSON(mqtt_msg, JSON_MQTT_MSG_SIZE, idx, value, svalue);

send_mqtt(nc, _apconfig_.mqtt_dz_pub_topic, mqtt_msg);
}




void check_net_services(struct mg_mgr *mgr) {

if (_mqtt_status == mqttstopped)
Expand Down Expand Up @@ -209,10 +222,79 @@ void mqtt_broadcast_aquapurestate(struct mg_connection *nc) {
send_mqtt_float_msg(nc, SWG_PPM_F_TOPIC, roundf(degFtoC(_apdata_.PPM)));
}

send_mqtt_int_msg(nc, SWG_TOPIC, ((_apdata_.connected && (_apdata_.Percent > 0))?2:0) );
//send_mqtt_int_msg(nc, SWG_TOPIC, ((_apdata_.connected && (_apdata_.Percent > 0))?2:0) );
send_mqtt_int_msg(nc, SWG_ENABELED_TOPIC, (_apdata_.connected?2:0));
send_mqtt_int_msg(nc, SWG_EXTENDED_TOPIC, (int)_apdata_.status);
send_mqtt_int_msg(nc, SWG_BOOST_TOPIC, _apdata_.boost);

//if (_apconfig_.dzidx_swg_status > 0 && strlen(_apconfig_.mqtt_dz_pub_topic) > 0){
switch (_apdata_.status) {
// Level = (0=gray, 1=green, 2=yellow, 3=orange, 4=red)
case SWG_STATUS_ON:
set_display_message( "AquaPure ON");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 1, "GENERATING CHLORINE");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_ON);
break;
case SWG_STATUS_NO_FLOW:
set_display_message( "AquaPure No Flow");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 2, "NO FLOW");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_OFF);
break;
case SWG_STATUS_LOW_SALT:
set_display_message( "AquaPure Low Salt");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 2, "LOW SALT");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_ON);
break;
case SWG_STATUS_HI_SALT:
set_display_message( "AquaPure High Salt");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 3, "HIGH SALT");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_ON);
break;
case SWG_STATUS_HIGH_CURRENT:
set_display_message( "AquaPure High Current");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 4, "HIGH CURRENT");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_ON);
break;
case SWG_STATUS_TURNING_OFF:
set_display_message( "AquaPure Turning Off");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 0, "TURNING OFF");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_OFF);
break;
case SWG_STATUS_CLEAN_CELL:
set_display_message( "AquaPure Clean Cell");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 2, "CLEAN CELL");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_ON);
break;
case SWG_STATUS_LOW_VOLTS:
set_display_message( "AquaPure Low Voltage");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 3, "LOW VOLTAGE");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_ON);
break;
case SWG_STATUS_LOW_TEMP:
set_display_message( "AquaPure Water Temp Low");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 2, "WATER TEMP LOW");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_OFF);
break;
case SWG_STATUS_CHECK_PCB:
set_display_message( "AquaPure Check PCB");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 4, "CHECK PCB");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_OFF);
break;
case SWG_STATUS_OFF: // THIS IS OUR OFF STATUS, NOT AQUAPURE
set_display_message( "AquaPure OFF");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 0, "OFF");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_OFF);
break;
case SWG_STATUS_OFFLINE:
set_display_message( "AquaPure OFFLINE");
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 4, "OFFLINE");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_OFF);
break;
default:
send_domoticz_mqtt_status_message(nc, _apconfig_.dzidx_swg_status_msg, 4, "Unknown");
send_mqtt_int_msg(nc, SWG_TOPIC, SWG_ON);
break;
}
/*
if (_apdata_.status != _apdata_.last_status_published) {
Expand Down Expand Up @@ -470,25 +552,21 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message

if (strcmp(request.first.value, "GET_DEVICES") == 0) {
//char message[JSON_LABEL_SIZE*10];
//build_device_JSON(_aqualink_data, _aqualink_config->light_programming_button_pool, _aqualink_config->light_programming_button_spa, message, JSON_LABEL_SIZE*10, false);
//build_device_JSON(_aqualink_data, _apconfig_.light_programming_button_pool, _apconfig_.light_programming_button_spa, message, JSON_LABEL_SIZE*10, false);
build_device_JSON(&_apdata_, &_gpiodata_, data, JSON_STATUS_SIZE, false);
//logMessage(LOG_DEBUG, "-->%s<--", data);
ws_send(nc, data);
} else if (strcmp(request.first.key, "command") == 0) {
if (strcmp(request.first.value, SWG_TOPIC) == 0) {
if (strcmp(request.first.value, SWG_BOOST_TOPIC) == 0) {
printf("***** BOOST ****\n");
action_boost_request(request.second.value);
} else if (strcmp(request.first.value, SWG_TOPIC) == 0) {
//printf("Turn SWG on/off NOT IMPLIMENTED YET!\n");
//_apdata_.changed = true;
if (strcmp(request.second.value, "on") == 0)
set_swg_on(true);
else
set_swg_on(false);
} else if (strcmp(request.first.value, SWG_BOOST_TOPIC) == 0) {
//printf("Boost on/off NOT IMPLIMENTED YET!\n");
//_apdata_.changed = true;
if (strcmp(request.second.value, "on") == 0)
set_swg_boost(true);
else
set_swg_boost(false);
} else if (strncmp(request.first.value, GPIO_TOPIC, 4) == 0) {
action_gpio_request(request.first.value, request.second.value);
}
Expand Down
Binary file modified aq_serial.o
Binary file not shown.
2 changes: 1 addition & 1 deletion aqualink.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct aqualinkdata
char date[AQ_MSGLEN];
char time[AQ_MSGLEN];
//char datestr[DATE_STRING_LEN];
char last_message[AQ_MSGLONGLEN+1]; // NSF just temp for PDA crap
char display_message[AQ_MSGLONGLEN+1];
//char *last_message; // Be careful using this, can get core dumps.
//char *display_message;
unsigned char raw_status[AQ_PSTLEN];
Expand Down
4 changes: 4 additions & 0 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ void readCfg (char *cfgFile)
ini_gets("AQUACONTROLD", "MQTT_PASSWD", NULL, _apconfig_.mqtt_passwd, sizearray(_apconfig_.mqtt_passwd), cfgFile);
ini_gets("AQUACONTROLD", "MQTT_TOPIC", DEFAULT_MQTT_AQ_TP,_apconfig_.mqtt_topic, sizearray(_apconfig_.mqtt_topic), cfgFile);

ini_gets("AQUACONTROLD", "MQTT_DZ_PUB_TOPIC", NULL,_apconfig_.mqtt_dz_pub_topic, sizearray(_apconfig_.mqtt_dz_pub_topic), cfgFile);
ini_gets("AQUACONTROLD", "MQTT_DZ_SUB_TOPIC", NULL,_apconfig_.mqtt_dz_sub_topic, sizearray(_apconfig_.mqtt_dz_sub_topic), cfgFile);
_apconfig_.dzidx_swg_status_msg = ini_getl("AQUACONTROLD", "DZIDX_SWG_STATUS_ALERT_SENSOR", 0, cfgFile);


read_gpio_config(cfgFile);

Expand Down
4 changes: 3 additions & 1 deletion config.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ struct apconfig
char mqtt_dz_pub_topic[50];
char mqtt_ID[MQTT_ID_LEN];

int dzidx_swg_status_msg;

//char *version;
//char *name;
//char *serial_port;
Expand All @@ -58,7 +60,7 @@ struct apconfig
//char *mqtt_user;
//char *mqtt_passwd;
//char mqtt_ID[MQTT_ID_LEN+1];
char last_display_message[AQ_MSGLONGLEN+1];
//char last_display_message[AQ_MSGLONGLEN+1];
//int dzidx_air_temp;
//int dzidx_pool_water_temp;
//int dzidx_spa_water_temp;
Expand Down
Binary file modified config.o
Binary file not shown.
Loading

0 comments on commit 23c0280

Please sign in to comment.