mirror of https://github.com/sfeakes/AqualinkD.git
parent
796bb3e2b0
commit
82367eb42c
7
Makefile
7
Makefile
|
@ -13,7 +13,8 @@ AQ_RS16 = true
|
|||
AQ_PDA = true
|
||||
AQ_ONETOUCH = true
|
||||
AQ_IAQTOUCH = true
|
||||
AQ_MANAGER =false
|
||||
AQ_MANAGER =true
|
||||
AQ_RS_EXTRA_OPTS = false
|
||||
#AQ_MEMCMP = true // Not implimented correctly yet.
|
||||
|
||||
# Turn off threadded net services
|
||||
|
@ -74,7 +75,7 @@ endif
|
|||
# Main source files
|
||||
SRCS = aqualinkd.c utils.c config.c aq_serial.c aq_panel.c aq_programmer.c net_services.c json_messages.c rs_msg_utils.c\
|
||||
devices_jandy.c packetLogger.c devices_pentair.c color_lights.c serialadapter.c aq_timer.c aq_scheduler.c web_config.c\
|
||||
serial_logger.c mongoose.c
|
||||
serial_logger.c mongoose.c timespec_subtract.c
|
||||
|
||||
|
||||
AQ_FLAGS =
|
||||
|
@ -128,7 +129,7 @@ DBG_CFLAGS = $(DBGFLAGS) $(AQ_FLAGS) $(MGFLAGS)
|
|||
|
||||
# Other sources.
|
||||
DBG_SRC = $(SRCS) debug_timer.c
|
||||
SL_SRC = serial_logger.c aq_serial.c utils.c packetLogger.c rs_msg_utils.c
|
||||
SL_SRC = serial_logger.c aq_serial.c utils.c packetLogger.c rs_msg_utils.c timespec_subtract.c
|
||||
|
||||
# Build durectories
|
||||
OBJ_DIR := ./build
|
||||
|
|
12
README.md
12
README.md
|
@ -79,6 +79,18 @@ Designed to mimic AqualinkRS6 All Button keypad and (like the keypad) is used to
|
|||
* Add set time to OneTouch protocol.
|
||||
* Publish AqualinkD Management console. (Configure, Restart, run serial_logger) within AqualinkD.
|
||||
|
||||
# Update in Release 2.3.3
|
||||
* Introduced Aqualink Manager UI http://aqualink.ip/aqmanager.html
|
||||
* [AqualinkD Manager](#AQManager)
|
||||
* Moved logging into systemd/journal (journalctl) from syslog
|
||||
* [AqualinkD Log](#Log)
|
||||
* Updated to scheduler
|
||||
* [AqualinkD Scheduler](#Scheduler)
|
||||
* Introduced RS485 frame delay / timer.
|
||||
* Improve PDA panels reliability (PDA pannels are slower than RS panels)
|
||||
* Potentially fixed Pentair VSP / SWG problems since Pentair VSP use a different protocol, this will allow a timed delay for the VSP to post a status messages. Seems to only effect RS485 bus when both a Pentair VSP and Jandy SWG are present.
|
||||
* Add ```rs485_frame_delay = 4``` to /etc/aqualinkd.conf, 4 is number of milliseconds between frames, 0 will turn off ie no pause.
|
||||
|
||||
# Update in Release 2.3.2
|
||||
* Added support for VSP on panel versions REV 0.1 & 0.2
|
||||
* Can change heater sliver min/max values in web UI. `./web/config.js`
|
||||
|
|
|
@ -133,6 +133,7 @@ int save_schedules_js(char* inBuf, int inSize, char* outBuf, int outSize)
|
|||
int i;
|
||||
bool inarray = false;
|
||||
aqs_cron cline;
|
||||
bool fileexists = false;
|
||||
|
||||
if ( !_aqconfig_.enable_scheduler) {
|
||||
LOG(SCHD_LOG,LOG_WARNING, "Schedules are disabled\n");
|
||||
|
@ -143,6 +144,8 @@ int save_schedules_js(char* inBuf, int inSize, char* outBuf, int outSize)
|
|||
LOG(SCHD_LOG,LOG_NOTICE, "Saving Schedule:\n");
|
||||
|
||||
bool fs = remount_root_ro(false);
|
||||
if (access(CRON_FILE, F_OK) == 0)
|
||||
fileexists = true;
|
||||
fp = fopen(CRON_FILE, "w");
|
||||
if (fp == NULL) {
|
||||
LOG(SCHD_LOG,LOG_ERR, "Open file failed '%s'\n", CRON_FILE);
|
||||
|
@ -177,6 +180,11 @@ int save_schedules_js(char* inBuf, int inSize, char* outBuf, int outSize)
|
|||
fprintf(fp, "#***** AUTO GENERATED DO NOT EDIT *****\n");
|
||||
fclose(fp);
|
||||
|
||||
// if we created file, change the permisions
|
||||
if (!fileexists)
|
||||
if ( chmod(CRON_FILE, S_IRUSR | S_IWUSR ) < 0 )
|
||||
LOG(SCHD_LOG,LOG_ERR, "Could not change permitions on cron file %s, scheduling may not work\n",CRON_FILE);
|
||||
|
||||
remount_root_ro(fs);
|
||||
|
||||
return length;
|
||||
|
@ -225,7 +233,7 @@ int build_schedules_js(char* buffer, int size)
|
|||
|
||||
fp = fopen(CRON_FILE, "r");
|
||||
if (fp == NULL) {
|
||||
LOG(SCHD_LOG,LOG_ERR, "Open file failed '%s'\n", CRON_FILE);
|
||||
LOG(SCHD_LOG,LOG_WARNING, "Open file failed '%s'\n", CRON_FILE);
|
||||
length += sprintf(buffer+length,"\"message\": \"Error reading schedules\"}");
|
||||
return length;
|
||||
}
|
||||
|
@ -282,4 +290,4 @@ int build_schedules_js(char* buffer, int size)
|
|||
regfree(®exCompiled);
|
||||
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
|
48
aq_serial.c
48
aq_serial.c
|
@ -30,6 +30,7 @@
|
|||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include "packetLogger.h"
|
||||
#include "timespec_subtract.h"
|
||||
|
||||
/*
|
||||
Notes for serial usb speed
|
||||
|
@ -52,6 +53,8 @@ int _blocking_fds = -1;
|
|||
|
||||
static struct termios _oldtio;
|
||||
|
||||
static struct timespec last_serial_read_time;
|
||||
|
||||
void send_packet(int fd, unsigned char *packet, int length);
|
||||
//unsigned char getProtocolType(unsigned char* packet);
|
||||
|
||||
|
@ -339,18 +342,24 @@ int init_serial_port(const char* tty)
|
|||
return init_readahead_serial_port(_aqconfig_.serial_port);
|
||||
else
|
||||
return init_serial_port(_aqconfig_.serial_port);
|
||||
#else
|
||||
#elif AQ_RS_EXTRA_OPTS
|
||||
if (_aqconfig_.readahead_b4_write)
|
||||
return init_readahead_serial_port(_aqconfig_.serial_port);
|
||||
else
|
||||
return init_blocking_serial_port(_aqconfig_.serial_port);
|
||||
#else
|
||||
return init_blocking_serial_port(_aqconfig_.serial_port);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
int init_readahead_serial_port(const char* tty)
|
||||
{
|
||||
return _init_serial_port(tty, false, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
int init_blocking_serial_port(const char* tty)
|
||||
{
|
||||
_blocking_fds = _init_serial_port(tty, true, false);
|
||||
|
@ -414,6 +423,8 @@ int unlock_port(int fd)
|
|||
//#define OLD_SERIAL_INIT
|
||||
#ifndef OLD_SERIAL_INIT
|
||||
|
||||
|
||||
// Unless AQ_RS_EXTRA_OPTS is defined, blocking will always be true
|
||||
int _init_serial_port(const char* tty, bool blocking, bool readahead)
|
||||
{
|
||||
//B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400
|
||||
|
@ -726,6 +737,28 @@ void send_packet(int fd, unsigned char *packet, int length)
|
|||
{
|
||||
#endif
|
||||
|
||||
struct timespec elapsed_time;
|
||||
struct timespec now;
|
||||
|
||||
if (_aqconfig_.frame_delay > 0) {
|
||||
struct timespec min_frame_wait_time = {0, 4000000}; // 4 milliseconds
|
||||
struct timespec frame_wait_time;
|
||||
struct timespec remainder_time;
|
||||
|
||||
min_frame_wait_time.tv_sec = 0;
|
||||
min_frame_wait_time.tv_nsec = _aqconfig_.frame_delay * 1000000;
|
||||
|
||||
do {
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
timespec_subtract(&elapsed_time, &now, &last_serial_read_time);
|
||||
if (timespec_subtract(&frame_wait_time, &min_frame_wait_time, &elapsed_time)) {
|
||||
break;
|
||||
}
|
||||
} while (nanosleep(&frame_wait_time, &remainder_time) != 0);
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
|
||||
if (_blocking_mode) {
|
||||
//int nwrite = write(fd, packet, length);
|
||||
//LOG(RSSD_LOG,LOG_DEBUG, "Serial write %d bytes of %d\n",nwrite,length);
|
||||
|
@ -734,13 +767,14 @@ void send_packet(int fd, unsigned char *packet, int length)
|
|||
if (nwrite != length)
|
||||
LOG(RSSD_LOG, LOG_ERR, "write to serial port failed\n");
|
||||
} else {
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
if (_aqconfig_.readahead_b4_write) {
|
||||
if (cleanOutSerial(fd, false) != 0x00) {
|
||||
LOG(RSSD_LOG, LOG_ERR, "ERROR on RS485, AqualinkD was too slow in replying to message! (please check for performance issues)\n");
|
||||
cleanOutSerial(fd, true);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
int nwrite, i;
|
||||
for (i = 0; i < length; i += nwrite) {
|
||||
nwrite = write(fd, packet + i, length - i);
|
||||
|
@ -783,6 +817,13 @@ void send_packet(int fd, unsigned char *packet, int length)
|
|||
}*/
|
||||
|
||||
tcdrain(fd); // Make sure buffer has been sent.
|
||||
//if (_aqconfig_.frame_delay > 0) {
|
||||
timespec_subtract(&elapsed_time, &now, &last_serial_read_time);
|
||||
LOG(RSSD_LOG, LOG_DEBUG, "Time from recv to %s send is %ld.%09ld sec\n",
|
||||
(_blocking_mode?"blocking":"non-blocking"), elapsed_time.tv_sec,
|
||||
elapsed_time.tv_nsec);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
void _send_ack(int fd, unsigned char ack_type, unsigned char command)
|
||||
|
@ -1032,6 +1073,9 @@ int get_packet(int fd, unsigned char* packet)
|
|||
return AQSERR_2SMALL;
|
||||
}
|
||||
|
||||
//if (_aqconfig_.frame_delay > 0) {
|
||||
clock_gettime(CLOCK_REALTIME, &last_serial_read_time);
|
||||
//}
|
||||
LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Serial read %d bytes\n",index);
|
||||
if (_aqconfig_.log_protocol_packets || getLogLevel(RSSD_LOG) >= LOG_DEBUG_SERIAL)
|
||||
logPacketRead(packet, index);
|
||||
|
|
53
aqualinkd.c
53
aqualinkd.c
|
@ -1316,14 +1316,19 @@ int startup(char *self, char *cfgFile)
|
|||
if (READ_RSDEV_SWG && _aqconfig_.swg_zero_ignore != DEFAULT_SWG_ZERO_IGNORE_COUNT)
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Ignore SWG 0 msg count = %d\n", _aqconfig_.swg_zero_ignore);
|
||||
|
||||
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
if (_aqconfig_.readahead_b4_write == true)
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Serial Read Ahead Write = %s\n", bool2text(_aqconfig_.readahead_b4_write));
|
||||
if (_aqconfig_.prioritize_ack == true)
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Serial Prioritize Ack = %s\n", bool2text(_aqconfig_.prioritize_ack));
|
||||
#endif
|
||||
|
||||
if (_aqconfig_.ftdi_low_latency == true)
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Serial FTDI low latency = %s\n", bool2text(_aqconfig_.ftdi_low_latency));
|
||||
|
||||
if (_aqconfig_.prioritize_ack == true)
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Serial Prioritize Ack = %s\n", bool2text(_aqconfig_.prioritize_ack));
|
||||
if (_aqconfig_.frame_delay > 0)
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "RS485 Frame delay = %dms\n", _aqconfig_.frame_delay);
|
||||
|
||||
#ifdef AQ_NO_THREAD_NETSERVICE
|
||||
if (_aqconfig_.thread_netservices)
|
||||
|
@ -1335,7 +1340,9 @@ int startup(char *self, char *cfgFile)
|
|||
}
|
||||
if (_aqconfig_.rs_poll_speed != DEFAULT_POLL_SPEED)
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "RS Poll Speed = %d\n", _aqconfig_.rs_poll_speed);
|
||||
#endif
|
||||
|
||||
#if defined AQ_RS_EXTRA_OPTS && defined AQ_NO_THREAD_NETSERVICE
|
||||
if (_aqconfig_.rs_poll_speed < 0 && _aqconfig_.readahead_b4_write) {
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Serial Read Ahead Write is not valid when using Negative RS Poll Speed, turning Serial Read Ahead Write off\n");
|
||||
_aqconfig_.readahead_b4_write = false;
|
||||
|
@ -1628,9 +1635,10 @@ void main_loop()
|
|||
i=0;
|
||||
|
||||
// Turn off read ahead while dealing with probes
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
bool read_ahead = _aqconfig_.readahead_b4_write;
|
||||
_aqconfig_.readahead_b4_write = false;
|
||||
|
||||
#endif
|
||||
// Loop until we get the probe messages, that means we didn;t start too soon after last shutdown.
|
||||
while ( (got_probe == false || got_probe_rssa == false || got_probe_extended == false ) && _keepRunning == true)
|
||||
{
|
||||
|
@ -1742,8 +1750,9 @@ void main_loop()
|
|||
*/
|
||||
|
||||
//int max_blank_read = 0;
|
||||
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
_aqconfig_.readahead_b4_write = read_ahead;
|
||||
#endif
|
||||
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Starting communication with Control Panel\n");
|
||||
|
||||
|
@ -1840,32 +1849,38 @@ void main_loop()
|
|||
LOG(AQUA_LOG,LOG_DEBUG, "RS received packet of type %s length %d\n", get_packet_type(packet_buffer, packet_length), packet_length);
|
||||
logPacketRead(packet_buffer, packet_length);
|
||||
}
|
||||
|
||||
if (!_aqconfig_.prioritize_ack) {
|
||||
_aqualink_data.updated = process_packet(packet_buffer, packet_length);
|
||||
} else {
|
||||
// If we did not process the packet, above we need to record it for the caculate_ack_packet call.
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
// If we did not process the packet, above we need to record it for the caculate_ack_packet call.
|
||||
// Should find a better place to put this, but since prioritize_ack is expermental it's ok for now.
|
||||
// NSF We shouldn;t need to do the same for rssa / onetouch / iaqtouch and probably rssaadapter since they don;t queue commands & programming commands.
|
||||
if (_aqconfig_.prioritize_ack) {
|
||||
_aqualink_data.last_packet_type = packet_buffer[PKT_CMD];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
_aqualink_data.updated = process_packet(packet_buffer, packet_length);
|
||||
|
||||
#ifdef AQ_PDA
|
||||
if (isPDA_PANEL)
|
||||
caculate_ack_packet(rs_fd, packet_buffer, AQUAPDA);
|
||||
else
|
||||
#endif
|
||||
caculate_ack_packet(rs_fd, packet_buffer, ALLBUTTON);
|
||||
|
||||
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
if (_aqconfig_.prioritize_ack)
|
||||
_aqualink_data.updated = process_packet(packet_buffer, packet_length);
|
||||
|
||||
#endif
|
||||
DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AllButton Emulation Processed packet in");
|
||||
}
|
||||
else if (packet_length > 0 && isRSSA_ENABLED && packet_buffer[PKT_DEST] == _aqconfig_.rssa_device_id && getProtocolType(packet_buffer) == JANDY) {
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
if (_aqconfig_.prioritize_ack) {
|
||||
caculate_ack_packet(rs_fd, packet_buffer, RSSADAPTER);
|
||||
_aqualink_data.updated = process_rssadapter_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_aqualink_data.updated = process_rssadapter_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, RSSADAPTER);
|
||||
}
|
||||
|
@ -1873,11 +1888,15 @@ void main_loop()
|
|||
}
|
||||
#ifdef AQ_ONETOUCH
|
||||
else if (packet_length > 0 && isONET_ENABLED && packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id && getProtocolType(packet_buffer) == JANDY) {
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
if (_aqconfig_.prioritize_ack) {
|
||||
set_onetouch_lastmsg(packet_buffer[PKT_CMD]);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, ONETOUCH);
|
||||
_aqualink_data.updated = process_onetouch_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_aqualink_data.updated = process_onetouch_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, ONETOUCH);
|
||||
}
|
||||
|
@ -1886,11 +1905,15 @@ void main_loop()
|
|||
#endif
|
||||
#ifdef AQ_IAQTOUCH
|
||||
else if (packet_length > 0 && isIAQT_ENABLED && packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id && getProtocolType(packet_buffer) == JANDY) {
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
if (_aqconfig_.prioritize_ack) {
|
||||
set_iaqtouch_lastmsg(packet_buffer[PKT_CMD]);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, IAQTOUCH);
|
||||
_aqualink_data.updated = process_iaqtouch_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_aqualink_data.updated = process_iaqtouch_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, IAQTOUCH);
|
||||
}
|
||||
|
|
17
config.c
17
config.c
|
@ -138,8 +138,12 @@ void init_parameters (struct aqconfig * parms)
|
|||
|
||||
parms->sync_panel_time = true;
|
||||
|
||||
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
// Default parameters for threading and USB blocking
|
||||
parms->readahead_b4_write = false;
|
||||
parms->prioritize_ack = false;
|
||||
#endif
|
||||
|
||||
#ifdef AQ_NO_THREAD_NETSERVICE
|
||||
parms->rs_poll_speed = DEFAULT_POLL_SPEED;
|
||||
|
@ -148,7 +152,7 @@ void init_parameters (struct aqconfig * parms)
|
|||
|
||||
parms->enable_scheduler = true;
|
||||
parms->ftdi_low_latency = true;
|
||||
parms->prioritize_ack = false;
|
||||
parms->frame_delay = 0;
|
||||
|
||||
generate_mqtt_id(parms->mqtt_ID, MQTT_ID_LEN);
|
||||
}
|
||||
|
@ -585,9 +589,14 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
|||
} else if (strncasecmp (param, "display_warnings_in_web", 23) == 0) {
|
||||
_aqconfig_.display_warnings_web = text2bool(value);
|
||||
rtn=true;
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
} else if (strncasecmp (param, "serial_readahead_b4_write", 25) == 0) {
|
||||
_aqconfig_.readahead_b4_write = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "prioritize_ack", 14) == 0) {
|
||||
_aqconfig_.prioritize_ack = text2bool(value);
|
||||
rtn=true;
|
||||
#endif
|
||||
} else if (strncasecmp (param, "mqtt_timed_update", 17) == 0) {
|
||||
_aqconfig_.mqtt_timed_update = text2bool(value);
|
||||
rtn=true;
|
||||
|
@ -612,10 +621,10 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
|||
} else if (strncasecmp (param, "ftdi_low_latency", 16) == 0) {
|
||||
_aqconfig_.ftdi_low_latency = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "prioritize_ack", 14) == 0) {
|
||||
_aqconfig_.prioritize_ack = text2bool(value);
|
||||
} else if (strncasecmp (param, "rs485_frame_delay", 17) == 0) {
|
||||
_aqconfig_.frame_delay = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
}
|
||||
}
|
||||
else if (strncasecmp(param, "button_", 7) == 0) {
|
||||
// Check we have inichalized panel information, if not use any settings we may have
|
||||
if (_aqconfig_.paneltype_mask == 0)
|
||||
|
|
5
config.h
5
config.h
|
@ -85,12 +85,15 @@ struct aqconfig
|
|||
bool log_raw_bytes; // Read as bytes
|
||||
unsigned char RSSD_LOG_filter;
|
||||
//bool log_raw_RS_bytes;
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
bool readahead_b4_write;
|
||||
bool prioritize_ack;
|
||||
#endif
|
||||
bool mqtt_timed_update;
|
||||
bool sync_panel_time;
|
||||
bool enable_scheduler;
|
||||
bool ftdi_low_latency;
|
||||
bool prioritize_ack;
|
||||
int frame_delay;
|
||||
#ifdef AQ_NO_THREAD_NETSERVICE
|
||||
int rs_poll_speed; // Need to remove
|
||||
bool thread_netservices; // Need to remove
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <string.h>
|
||||
#include "debug_timer.h"
|
||||
#include "utils.h"
|
||||
//#include "timespec_subtract.h"
|
||||
#include "timespec_subtract.h"
|
||||
|
||||
#define NUM_DEBUG_TIMERS 10
|
||||
|
||||
|
@ -68,52 +68,8 @@ void stop_aqd_timer(int timeid, int16_t from, char *message)
|
|||
clear_aqd_timer(timeid);
|
||||
}
|
||||
|
||||
/* Copyright (c) 1991, 1999 Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/* Based on https://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html
|
||||
Subtract the struct timespec values X and Y,
|
||||
storing the result in RESULT.
|
||||
Return 1 if the difference is negative, otherwise 0. */
|
||||
|
||||
//#include <string.h>
|
||||
//#include "timespec_subtract.h"
|
||||
|
||||
int timespec_subtract (struct timespec *result, const struct timespec *x,
|
||||
const struct timespec *y)
|
||||
{
|
||||
struct timespec tmp;
|
||||
|
||||
memcpy (&tmp, y, sizeof(struct timespec));
|
||||
/* Perform the carry for the later subtraction by updating y. */
|
||||
if (x->tv_nsec < tmp.tv_nsec)
|
||||
{
|
||||
int nsec = (tmp.tv_nsec - x->tv_nsec) / 1000000000 + 1;
|
||||
tmp.tv_nsec -= 1000000000 * nsec;
|
||||
tmp.tv_sec += nsec;
|
||||
}
|
||||
if (x->tv_nsec - tmp.tv_nsec > 1000000000)
|
||||
{
|
||||
int nsec = (x->tv_nsec - tmp.tv_nsec) / 1000000000;
|
||||
tmp.tv_nsec += 1000000000 * nsec;
|
||||
tmp.tv_sec -= nsec;
|
||||
}
|
||||
|
||||
/* Compute the time remaining to wait.
|
||||
tv_nsec is certainly positive. */
|
||||
result->tv_sec = x->tv_sec - tmp.tv_sec;
|
||||
result->tv_nsec = x->tv_nsec - tmp.tv_nsec;
|
||||
|
||||
/* Return 1 if result is negative. */
|
||||
return x->tv_sec < tmp.tv_sec;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
#ifndef DEBUG_TIMER_H_
|
||||
#define DEBUG_TIMER_H_
|
||||
|
||||
int timespec_subtract (struct timespec *result, const struct timespec *x, const struct timespec *y);
|
||||
|
||||
#ifdef AQ_TM_DEBUG
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
void init_aqd_timer();
|
||||
int timespec_subtract (struct timespec *result, const struct timespec *x, const struct timespec *y);
|
||||
//int timespec_subtract (struct timespec *result, const struct timespec *x, const struct timespec *y);
|
||||
void stop_aqd_timer(int timeid, int16_t from, char *message);
|
||||
void start_aqd_timer(int *timeid);
|
||||
void clear_aqd_timer(int timeid);
|
||||
|
|
Binary file not shown.
|
@ -134,6 +134,7 @@ report_zero_pool_temp = no
|
|||
# Not documented. These are experimental. Will change how RS485 / Serial works, Only use if asked to for problem solving purposes.
|
||||
#serial_readahead_b4_write = yes
|
||||
#prioritize_ack = yes
|
||||
rs485_frame_delay = 4
|
||||
|
||||
# Get rid of the startup warning message about no low latency. BETTER option is to buy a better adapter.
|
||||
#ftdi_low_latency = no
|
||||
|
|
|
@ -50,6 +50,7 @@ log_level=INFO
|
|||
#debug_log_mask = 4096
|
||||
|
||||
display_warnings_in_web = yes
|
||||
rs485_frame_delay = 4
|
||||
|
||||
# The socket port that the daemon listens to
|
||||
# If you change this from 80, remember to update aqualink.service.avahi
|
||||
|
|
Binary file not shown.
|
@ -364,7 +364,9 @@ int main(int argc, char *argv[]) {
|
|||
bool errorMonitor = false;
|
||||
|
||||
// aq_serial.c uses the following
|
||||
#ifdef AQ_RS_EXTRA_OPTS
|
||||
_aqconfig_.readahead_b4_write = false;
|
||||
#endif
|
||||
_aqconfig_.log_protocol_packets = false;
|
||||
_aqconfig_.log_raw_bytes = false;
|
||||
_aqconfig_.ftdi_low_latency = true;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
#define AQUALINKD_NAME "Aqualink Daemon"
|
||||
#define AQUALINKD_VERSION "2.3.2"
|
||||
#define AQUALINKD_VERSION "2.3.3"
|
||||
|
|
160
web/debug.html
160
web/debug.html
|
@ -1,160 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang='en'>
|
||||
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=windows-1252'>
|
||||
<title>AqualinkD DEBUG</title>
|
||||
<meta name='viewport' content='width=device-width'>
|
||||
<meta name='mobile-web-app-capable' content='yes'>
|
||||
<meta name='apple-mobile-web-app-capable' content='yes'>
|
||||
<meta name='apple-mobile-web-app-status-bar-style' content='black'>
|
||||
<link href='aqualinkd.png' rel='apple-touch-icon'>
|
||||
<link href='aqualinkd.png' rel='icon'>
|
||||
</head>
|
||||
<style>
|
||||
/*
|
||||
******************************************************************************
|
||||
Button style taken from https://github.com/ubuwaits/css3-buttons */
|
||||
button::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
button.blue-pill {
|
||||
background-color: #a5b8da;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #a5b8da), color-stop(100%, #7089b3));
|
||||
background-image: -webkit-linear-gradient(top, #a5b8da, #7089b3);
|
||||
background-image: -moz-linear-gradient(top, #a5b8da, #7089b3);
|
||||
background-image: -ms-linear-gradient(top, #a5b8da, #7089b3);
|
||||
background-image: -o-linear-gradient(top, #a5b8da, #7089b3);
|
||||
background-image: linear-gradient(top, #a5b8da, #7089b3);
|
||||
border-top: 1px solid #758fba;
|
||||
border-right: 1px solid #6c84ab;
|
||||
border-bottom: 1px solid #5c6f91;
|
||||
border-left: 1px solid #6c84ab;
|
||||
border-radius: 18px;
|
||||
-webkit-box-shadow: inset 0 1px 0 0 #aec3e5;
|
||||
box-shadow: inset 0 1px 0 0 #aec3e5;
|
||||
color: #fff;
|
||||
font: bold 11px/1 "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
|
||||
padding: 8px 0;
|
||||
text-align: center;
|
||||
text-shadow: 0 -1px 1px #64799e;
|
||||
text-transform: uppercase;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
button.blue-pill:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var _poller;
|
||||
|
||||
function action(element) {
|
||||
var query;
|
||||
|
||||
if (element.id == "start") {
|
||||
document.getElementById('messages').innerHTML = "Debug Starting!"
|
||||
} else if (element.id == "serialstart") {
|
||||
document.getElementById('messages').innerHTML = "Serial Debug Starting!"
|
||||
} else if (element.id == "stop") {
|
||||
document.getElementById('messages').innerHTML = "Debug Stopping!"
|
||||
} else if (element.id == "clean") {
|
||||
document.getElementById('messages').innerHTML = "Cleaning Debug File!"
|
||||
} else if (element.id == "download") {
|
||||
//window.location = location.href + '?command=debug&value=download';
|
||||
window.location = '/api/debug/download';
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
var http = new XMLHttpRequest();
|
||||
//http.open('GET', location.href + '?command=debug&value='+element.id);
|
||||
http.open('GET', '/api/debug/'+element.id);
|
||||
http.send(null);
|
||||
|
||||
setTimeout(function () {
|
||||
forceupdate();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function forceupdate() {
|
||||
clearTimeout(_poller);
|
||||
update();
|
||||
}
|
||||
|
||||
function update() {
|
||||
var http = new XMLHttpRequest();
|
||||
if (http) {
|
||||
http.onreadystatechange = function () {
|
||||
if (http.readyState === 4) {
|
||||
if (http.status == 200 && http.status < 300) {
|
||||
var data = JSON.parse(http.responseText);
|
||||
//console.log(data.iLevel + " : " + data.sLevel);
|
||||
if ( data.iLevel >= 7 ) {
|
||||
document.getElementById('start').disabled = true;
|
||||
document.getElementById('serialstart').disabled = true;
|
||||
document.getElementById('stop').disabled = false;
|
||||
if ( data.iLevel >= 8 )
|
||||
document.getElementById('messages').innerHTML = "Serial debug Running!"
|
||||
else
|
||||
document.getElementById('messages').innerHTML = "Debug Running!"
|
||||
} else if ( data.iLevel < 7 ) {
|
||||
document.getElementById('start').disabled = false;
|
||||
document.getElementById('serialstart').disabled = false;
|
||||
document.getElementById('stop').disabled = true;
|
||||
document.getElementById('messages').innerHTML = "Not debugging, Log level = "+data.sLevel;
|
||||
}
|
||||
if (data.logReady == "true") {
|
||||
document.getElementById('download').disabled = false;
|
||||
if (document.getElementById('stop').disabled == true) {
|
||||
document.getElementById('clean').disabled = false;
|
||||
} else {
|
||||
document.getElementById('clean').disabled = true;
|
||||
}
|
||||
} else {
|
||||
document.getElementById('download').disabled = true;
|
||||
document.getElementById('clean').disabled = true;
|
||||
}
|
||||
}
|
||||
else if (http.status >= 400 || http.status == 0) {
|
||||
document.getElementById('messages').innerHTML = 'Error connecting to AqualinkD';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//http.open('GET', location.href + '?command=debug&value=status');
|
||||
http.open('GET', '/api/debug/status');
|
||||
http.send(null);
|
||||
_poller = setTimeout(update, 5000);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<body onload="update();">
|
||||
<table cellpadding="10" border="0" align="center">
|
||||
<tr><td colspan="3" align="center">
|
||||
<div id="messages"> </div>
|
||||
</td></tr>
|
||||
<tr><td align="center">
|
||||
<button class="blue-pill" id="start" type="button" onclick='action(this);'>Start Debug</button>
|
||||
</td><td align="center">
|
||||
<button class="blue-pill" id="serialstart" type="button" onclick='action(this);'>Start Serial Debug</button>
|
||||
</td><td align="center">
|
||||
<button class="blue-pill" id="stop" type="button" onclick='action(this);'>Stop Debug</button>
|
||||
</td></tr>
|
||||
<tr><td colspan="3" align="center">
|
||||
<table cellpadding="10" border="0" align="center">
|
||||
<tr><td>
|
||||
<button class="blue-pill" id="download" type="button" onclick='action(this);'>Download Debug File</button>
|
||||
</td><td>
|
||||
<button class="blue-pill" id="clean" type="button" onclick='action(this);'>Clean Debug File</button>
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
aqmanager.html
|
Loading…
Reference in New Issue