mirror of https://github.com/sfeakes/AqualinkD.git
Version 3.0.0
parent
a5db4e0100
commit
59480ae97f
74
Makefile
74
Makefile
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Options
|
||||
#
|
||||
# make // standard build aqualinkd and serial_logger
|
||||
# make // standard build aqualinkd and rs485mon
|
||||
# make debug // Compule standard aqualinkd binary just with debugging
|
||||
# make aqdebug // Compile with extra aqualink debug information like timings
|
||||
# make slog // Serial logger
|
||||
|
|
@ -71,7 +71,7 @@ endif
|
|||
SRCS = aqualinkd.c utils.c config.c aq_serial.c aq_panel.c aq_programmer.c allbutton.c allbutton_aq_programmer.c net_services.c net_interface.c json_messages.c rs_msg_utils.c\
|
||||
onetouch.c onetouch_aq_programmer.c iaqtouch.c iaqtouch_aq_programmer.c iaqualink.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 mqtt_discovery.c simulator.c sensors.c aq_systemutils.c timespec_subtract.c auto_configure.c
|
||||
rs485mon.c mongoose.c mqtt_discovery.c simulator.c sensors.c aq_systemutils.c timespec_subtract.c auto_configure.c
|
||||
|
||||
|
||||
AQ_FLAGS =
|
||||
|
|
@ -90,8 +90,8 @@ ifeq ($(AQ_MANAGER), true)
|
|||
$(warning AQ_MANAGER requires threads, ignoring AQ_NO_THREAD_NETSERVICE)
|
||||
endif
|
||||
else
|
||||
# No need for serial_logger without aq_manager
|
||||
SRCS := $(filter-out serial_logger.c, $(SRCS))
|
||||
# No need for rs485mon without aq_manager
|
||||
SRCS := $(filter-out rs485mon.c, $(SRCS))
|
||||
# no threadded net service only valid without aq manager.
|
||||
ifeq ($(AQ_NO_THREAD_NETSERVICE), true)
|
||||
AQ_FLAGS := $(AQ_FLAGS) -D AQ_NO_THREAD_NETSERVICE
|
||||
|
|
@ -106,7 +106,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 timespec_subtract.c
|
||||
SL_SRC = rs485mon.c aq_serial.c utils.c packetLogger.c rs_msg_utils.c timespec_subtract.c
|
||||
|
||||
DD_SRC = dummy_device.c aq_serial.c utils.c packetLogger.c rs_msg_utils.c timespec_subtract.c
|
||||
DR_SRC = dummy_reader.c aq_serial.c utils.c packetLogger.c rs_msg_utils.c timespec_subtract.c
|
||||
|
|
@ -168,7 +168,7 @@ SL_OBJ_FILES_AMD64 := $(patsubst $(SRC_DIR)/%.c,$(SL_OBJ_DIR_AMD64)/%.o,$(SL_SRC
|
|||
|
||||
# define the executable file
|
||||
MAIN = ./release/aqualinkd
|
||||
SLOG = ./release/serial_logger
|
||||
RSMON = ./release/rs485mon
|
||||
DEBG = ./release/aqualinkd-debug
|
||||
DDEVICE = ./release/dummydevice
|
||||
DREADER = ./release/dummyreader
|
||||
|
|
@ -177,9 +177,9 @@ MAIN_ARM64 = ./release/aqualinkd-arm64
|
|||
MAIN_ARMHF = ./release/aqualinkd-armhf
|
||||
MAIN_AMD64 = ./release/aqualinkd-amd64
|
||||
|
||||
SLOG_ARM64 = ./release/serial_logger-arm64
|
||||
SLOG_ARMHF = ./release/serial_logger-armhf
|
||||
SLOG_AMD64 = ./release/serial_logger-amd64
|
||||
RSMON_ARM64 = ./release/rs485mon-arm64
|
||||
RSMON_ARMHF = ./release/rs485mon-armhf
|
||||
RSMON_AMD64 = ./release/rs485mon-amd64
|
||||
|
||||
#LOGR = ./release/log_reader
|
||||
#PLAY = ./release/aqualinkd-player
|
||||
|
|
@ -216,11 +216,11 @@ runindocker:
|
|||
|
||||
# This is run inside container Dockerfile.releaseBinariies (aqualinkd-releasebin)
|
||||
buildrelease: clean armhf arm64
|
||||
$(shell cd release && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./serial_logger-armhf ./serial_logger)
|
||||
$(shell cd release && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./rs485mon-armhf ./rs485mon)
|
||||
|
||||
# This is run inside container Dockerfile.releaseBinariies (aqualinkd-releasebin)
|
||||
quickbuild: armhf arm64
|
||||
$(shell cd release && [ ! -f "./aqualinkd-armhf" ] && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./serial_logger-armhf ./serial_logger)
|
||||
$(shell cd release && [ ! -f "./aqualinkd-armhf" ] && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./rs485mon-armhf ./rs485mon)
|
||||
|
||||
# This is run inside container Dockerfile.releaseBinariies (aqualinkd-releasebin)
|
||||
dockerbuildnrun: ./release/aqualinkd
|
||||
|
|
@ -229,16 +229,16 @@ dockerbuildnrun: ./release/aqualinkd
|
|||
|
||||
debugbuild: CFLAGS = $(DFLAGS)
|
||||
debugbuild: armhf arm64
|
||||
$(shell cd release && [ ! -f "./aqualinkd-armhf" ] && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./serial_logger-armhf ./serial_logger)
|
||||
$(shell cd release && [ ! -f "./aqualinkd-armhf" ] && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./rs485mon-armhf ./rs485mon)
|
||||
|
||||
|
||||
# Rules to pass to make.
|
||||
all: $(MAIN) $(SLOG)
|
||||
all: $(MAIN) $(RSMON)
|
||||
$(info $(MAIN) has been compiled)
|
||||
$(info $(SLOG) has been compiled)
|
||||
$(info $(RSMON) has been compiled)
|
||||
|
||||
slog: $(SLOG)
|
||||
$(info $(SLOG) has been compiled)
|
||||
slog: $(RSMON)
|
||||
$(info $(RSMON) has been compiled)
|
||||
|
||||
aqdebug: $(DEBG)
|
||||
$(info $(DEBG) has been compiled)
|
||||
|
|
@ -251,9 +251,9 @@ dummyreader: $(DREADER)
|
|||
|
||||
# Container, add container flag and compile
|
||||
container: CFLAGS := $(CFLAGS) -D AQ_CONTAINER
|
||||
container: $(MAIN) $(SLOG)
|
||||
container: $(MAIN) $(RSMON)
|
||||
$(info $(MAIN) has been compiled (** For Container use **))
|
||||
$(info $(SLOG) has been compiled (** For Container use **))
|
||||
$(info $(RSMON) has been compiled (** For Container use **))
|
||||
|
||||
container-arm64: CC := $(CC_ARM64)
|
||||
container-arm64: container
|
||||
|
|
@ -263,27 +263,27 @@ container-amd64: container
|
|||
|
||||
# armhf
|
||||
armhf: CC := $(CC_ARMHF)
|
||||
armhf: $(MAIN_ARMHF) $(SLOG_ARMHF)
|
||||
armhf: $(MAIN_ARMHF) $(RSMON_ARMHF)
|
||||
$(info $(MAIN_ARMHF) has been compiled)
|
||||
$(info $(SLOG_ARMHF) has been compiled)
|
||||
$(info $(RSMON_ARMHF) has been compiled)
|
||||
|
||||
# arm64
|
||||
arm64: CC := $(CC_ARM64)
|
||||
arm64: $(MAIN_ARM64) $(SLOG_ARM64)
|
||||
arm64: $(MAIN_ARM64) $(RSMON_ARM64)
|
||||
$(info $(MAIN_ARM64) has been compiled)
|
||||
$(info $(SLOG_ARM64) has been compiled)
|
||||
$(info $(RSMON_ARM64) has been compiled)
|
||||
|
||||
# amd64
|
||||
amd64: CC := $(CC_AMD64)
|
||||
amd64: $(MAIN_AMD64) $(SLOG_AMD64)
|
||||
amd64: $(MAIN_AMD64) $(RSMON_AMD64)
|
||||
$(info $(MAIN_AMD64) has been compiled)
|
||||
$(info $(SLOG_AMD64) has been compiled)
|
||||
$(info $(RSMON_AMD64) has been compiled)
|
||||
|
||||
#debug, Just change compile flags and call MAIN
|
||||
debug: CFLAGS = $(DFLAGS)
|
||||
debug: $(MAIN) $(SLOG)
|
||||
debug: $(MAIN) $(RSMON)
|
||||
$(info $(MAIN) has been compiled (** DEBUG **))
|
||||
$(info $(SLOG) has been compiled (** DEBUG **))
|
||||
$(info $(RSMON) has been compiled (** DEBUG **))
|
||||
|
||||
#install: $(MAIN)
|
||||
install:
|
||||
|
|
@ -340,27 +340,27 @@ $(MAIN_AMD64): $(OBJ_FILES_AMD64)
|
|||
$(DEBG): $(DBG_OBJ_FILES)
|
||||
$(CC) $(DBG_CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS)
|
||||
|
||||
$(SLOG): CFLAGS := $(CFLAGS) -D SERIAL_LOGGER
|
||||
$(SLOG): $(SL_OBJ_FILES)
|
||||
$(RSMON): CFLAGS := $(CFLAGS) -D RS485MON
|
||||
$(RSMON): $(SL_OBJ_FILES)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS)
|
||||
|
||||
$(SLOG_ARMHF): CFLAGS := $(CFLAGS) -D SERIAL_LOGGER
|
||||
$(SLOG_ARMHF): $(SL_OBJ_FILES_ARMHF)
|
||||
$(RSMON_ARMHF): CFLAGS := $(CFLAGS) -D RS485MON
|
||||
$(RSMON_ARMHF): $(SL_OBJ_FILES_ARMHF)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS)
|
||||
|
||||
$(SLOG_ARM64): CFLAGS := $(CFLAGS) -D SERIAL_LOGGER
|
||||
$(SLOG_ARM64): $(SL_OBJ_FILES_ARM64)
|
||||
$(RSMON_ARM64): CFLAGS := $(CFLAGS) -D RS485MON
|
||||
$(RSMON_ARM64): $(SL_OBJ_FILES_ARM64)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS)
|
||||
|
||||
$(SLOG_AMD64): CFLAGS := $(CFLAGS) -D SERIAL_LOGGER
|
||||
$(SLOG_AMD64): $(SL_OBJ_FILES_AMD64)
|
||||
$(RSMON_AMD64): CFLAGS := $(CFLAGS) -D RS485MON
|
||||
$(RSMON_AMD64): $(SL_OBJ_FILES_AMD64)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS)
|
||||
|
||||
$(DDEVICE): CFLAGS := $(CFLAGS) -D SERIAL_LOGGER -D DUMMY_DEVICE
|
||||
$(DDEVICE): CFLAGS := $(CFLAGS) -D RS485MON -D DUMMY_DEVICE
|
||||
$(DDEVICE): $(DD_OBJ_FILES)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS)
|
||||
|
||||
$(DREADER): CFLAGS := $(CFLAGS) -D SERIAL_LOGGER -D DUMMY_DEVICE -D DUMMY_READER
|
||||
$(DREADER): CFLAGS := $(CFLAGS) -D RS485MON -D DUMMY_DEVICE -D DUMMY_READER
|
||||
$(DREADER): $(DR_OBJ_FILES)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS)
|
||||
|
||||
|
|
@ -402,7 +402,7 @@ $(SL_OBJ_DIR_AMD64):
|
|||
|
||||
clean: clean-buildfiles
|
||||
$(RM) *.o *~ $(MAIN) $(MAIN_U) $(PLAY) $(PL_EXOBJ) $(DEBG) $(DDEVICE) $(DREADER)
|
||||
$(RM) $(wildcard *.o) $(wildcard *~) $(MAIN) $(MAIN_ARM64) $(MAIN_ARMHF) $(MAIN_AMD64) $(SLOG) $(DDEVICE) $(SLOG_ARM64) $(SLOG_ARMHF) $(SLOG_AMD64) $(MAIN_U) $(PLAY) $(PL_EXOBJ) $(LOGR) $(PLAY) $(DEBG)
|
||||
$(RM) $(wildcard *.o) $(wildcard *~) $(MAIN) $(MAIN_ARM64) $(MAIN_ARMHF) $(MAIN_AMD64) $(RSMON) $(DDEVICE) $(RSMON_ARM64) $(RSMON_ARMHF) $(RSMON_AMD64) $(MAIN_U) $(PLAY) $(PL_EXOBJ) $(LOGR) $(PLAY) $(DEBG)
|
||||
|
||||
clean-buildfiles:
|
||||
$(RM) $(wildcard *.o) $(wildcard *~) $(OBJ_FILES) $(DBG_OBJ_FILES) $(SL_OBJ_FILES) $(DD_OBJ_FILES) $(DR_OBJ_FILES) $(OBJ_FILES_ARMHF) $(OBJ_FILES_ARM64) $(OBJ_FILES_AMD64) $(SL_OBJ_FILES_ARMHF) $(SL_OBJ_FILES_ARM64) $(SL_OBJ_FILES_AMD64)
|
||||
|
|
|
|||
|
|
@ -179,8 +179,7 @@ AqualinkD will be moving over to github hosted runners for compiling, currently
|
|||
* Cleaned up exit & errors when running as daemon and docker.
|
||||
* Fixed issues with external sensors and homekit.
|
||||
* Added preliminary support for Jandy Infinite water color lights.
|
||||
- Need to finish off :-
|
||||
* HAT serial optimizations broke some USB serial adapters
|
||||
* Renamed serial_logger to rs485mon (more compliant with unix naming standards)
|
||||
|
||||
|
||||
# Updates in 2.6.11 (Sept 14 2025)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ LABEL org.opencontainers.image.version=$AQUALINKD_VERSION
|
|||
|
||||
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/aqualinkd /usr/local/bin/aqualinkd
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/serial_logger /usr/local/bin/serial_logger
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/rs485mon /usr/local/bin/rs485mon
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/web/ /var/www/aqualinkd/
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/aqualinkd.conf /etc/aqualinkd.conf
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ LABEL org.opencontainers.image.version=$AQUALINKD_VERSION
|
|||
EXPOSE 80/tcp
|
||||
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/aqualinkd /usr/local/bin/aqualinkd
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/serial_logger /usr/local/bin/serial_logger
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/rs485mon /usr/local/bin/rs485mon
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/web/ /var/www/aqualinkd/
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/aqualinkd.conf /etc/aqualinkd.conf
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -35,7 +35,7 @@ web_directory=/var/www/aqualinkd/
|
|||
# Also don't think setting a 12 when you have a 8 will give you 4 more accessories to control, it won't the
|
||||
# panel information is needed as different panels use different bits within the RS protocol for status and key
|
||||
# presses.
|
||||
# serial_logger will get the panel type string if you don't know it, below are examples.
|
||||
# rs485mon will get the panel type string if you don't know it, below are examples.
|
||||
# Must be in format `XX-N ????` (XX=RS or PD, N=Circuits, ????=Combo or Only or Dual)
|
||||
panel_type = RS-8 Combo
|
||||
#panel_type = PD-8 Combo
|
||||
|
|
@ -44,7 +44,7 @@ panel_type = RS-8 Combo
|
|||
#panel_type = RS-4 Combo
|
||||
#panel_type = RS-8 Only
|
||||
#
|
||||
# If serial_logger doesn't give you a type string in the format above, you can use the next options to set the specifics.
|
||||
# If rs485mon doesn't give you a type string in the format above, you can use the next options to set the specifics.
|
||||
#
|
||||
# panel_type_size = (6, 8, 10, 12, 14 or 16) (Number of supported accessories / buttons)
|
||||
# panel_type_combo = (yes or no) (combo panels support BOTH pool & spa)
|
||||
|
|
@ -62,7 +62,7 @@ panel_type = RS-8 Combo
|
|||
device_id=0xFF
|
||||
|
||||
|
||||
# The ID of Jandy SerialInterface device. These is only one usable ID, if serial_logger
|
||||
# The ID of Jandy SerialInterface device. These is only one usable ID, if rs485mon
|
||||
# picks up your panel supports this, uncomment, as it will speed up heater setpoints & RS16 panels.
|
||||
#rssa_device_id=0x48
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ PARENT_COMMAND=$(ps -o comm= $PPID 2>/dev/null)
|
|||
SERVICE="aqualinkd"
|
||||
|
||||
BIN="aqualinkd"
|
||||
RS485BIN="rs485mon"
|
||||
CFG="aqualinkd.conf"
|
||||
SRV="aqualinkd.service"
|
||||
DEF="aqualinkd"
|
||||
|
|
@ -22,7 +23,10 @@ DEFLocation="/etc/default"
|
|||
WEBLocation="/var/www/aqualinkd/"
|
||||
MDNSLocation="/etc/avahi/services/"
|
||||
|
||||
REQUIRED_GLIBC_VERSION="2.31"
|
||||
|
||||
SOURCEBIN=$BIN
|
||||
SOURCERS485BIN=$RS485BIN
|
||||
|
||||
LOG_SYSTEMD=1 # 1=false in bash, 0=true
|
||||
REMOUNT_RO=1
|
||||
|
|
@ -34,7 +38,10 @@ _logfile=""
|
|||
_frommake=$FALSE
|
||||
_ignorearch=$FALSE
|
||||
_nosystemd=$FALSE
|
||||
|
||||
_ignoreglibc=$FALSE
|
||||
_installrs485mon=$TRUE
|
||||
|
||||
|
||||
log()
|
||||
{
|
||||
|
|
@ -75,6 +82,7 @@ while [[ $# -gt 0 ]]; do
|
|||
if [[ -n "$1" ]]; then
|
||||
_ignorearch=$TRUE
|
||||
SOURCEBIN=$BIN-$1
|
||||
SOURCERS485BIN=$RS485BIN-$1
|
||||
else
|
||||
log "--arch requires parameter eg. ( --arch armhf | --arch arm64 )"
|
||||
fi
|
||||
|
|
@ -162,6 +170,7 @@ if [ "$PARENT_COMMAND" != "make" ] && [ "$_frommake" -eq $FALSE ] && [ "$_ignore
|
|||
# Need to check BINEXISTS
|
||||
if [ -f $BUILD/$SOURCEBIN$BINEXT ]; then
|
||||
SOURCEBIN=$BIN$BINEXT
|
||||
SOURCERS485BIN=$RS485BIN$BINEXT
|
||||
elif [ -f $BUILD/$SOURCEBIN ]; then
|
||||
# Not good
|
||||
log "Can't find correct aqualinkd binary for $ARCH, '$BUILD/$SOURCEBIN$BINEXT' using '$BUILD/$SOURCEBIN' ";
|
||||
|
|
@ -177,9 +186,10 @@ fi
|
|||
## New for V3.0 check GLIBC version.
|
||||
if [ "$_ignoreglibc" -eq $FALSE ]; then
|
||||
# Check glib-c version.
|
||||
REQUIRED_GLIBC_VERSION="2.31"
|
||||
REQUIRED_GLIBC_MAJOR=2
|
||||
REQUIRED_GLIBC_MINOR=31
|
||||
# Extract the part BEFORE the first dot
|
||||
REQUIRED_GLIBC_MAJOR="${REQUIRED_GLIBC_VERSION%.*}"
|
||||
# Extract the part AFTER the first dot
|
||||
REQUIRED_GLIBC_MINOR="${REQUIRED_GLIBC_VERSION#*.}"
|
||||
|
||||
CURRENT_GLIBC_VERSION_STRING=$(ldd --version 2>/dev/null | head -n 1 | awk '{print $NF}')
|
||||
|
||||
|
|
@ -219,6 +229,9 @@ if [ "$1" == "clean" ]; then
|
|||
if [ -f $BINLocation/$BIN ]; then
|
||||
rm -f $BINLocation/$BIN
|
||||
fi
|
||||
if [ -f $BINLocation/$RS485BIN ]; then
|
||||
rm -f $BINLocation/$RS485BIN
|
||||
fi
|
||||
if [ -f $SRVLocation/$SRV ]; then
|
||||
rm -f $SRVLocation/$SRV
|
||||
fi
|
||||
|
|
@ -275,8 +288,13 @@ fi
|
|||
# copy files to locations, but only copy cfg if it doesn;t already exist
|
||||
|
||||
cp $BUILD/$SOURCEBIN $BINLocation/$BIN
|
||||
|
||||
cp $BUILD/$SRV $SRVLocation/$SRV
|
||||
|
||||
if [ "$_installrs485mon" -eq $TRUE ]; then
|
||||
cp $BUILD/$SOURCERS485BIN $BINLocation/$RS485BIN
|
||||
fi
|
||||
|
||||
if [ -f $CFGLocation/$CFG ]; then
|
||||
log "AqualinkD config exists, did not copy new config, you may need to edit existing! $CFGLocation/$CFG"
|
||||
else
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
./rs485mon-armhf
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
./serial_logger-armhf
|
||||
|
|
@ -162,8 +162,8 @@ int save_schedules_js(const char* inBuf, int inSize, char* outBuf, int outSize)
|
|||
LOG(SCHD_LOG,LOG_DEBUG, "Write to cron Min:%s Hour:%s DayM:%s Month:%s DayW:%s URL:%s Value:%s\n",cline.minute,cline.hour,cline.daym,cline.month,cline.dayw,cline.url,cline.value);
|
||||
//LOG(SCHD_LOG,LOG_INFO, "%s%s %s %s %s %s curl -s -S --show-error -o /dev/null localhost:%s%s -d value=%s -X PUT\n",(cline.enabled?"":"#"),cline.minute, cline.hour, cline.daym, cline.month, cline.dayw, _aqconfig_.socket_port, cline.url, cline.value);
|
||||
//fprintf(fp, "%s%s %s %s %s %s root curl -s -S --show-error -o /dev/null localhost:%s%s -d value=%s -X PUT\n",(cline.enabled?"":"#"),cline.minute, cline.hour, cline.daym, cline.month, cline.dayw, _aqconfig_.socket_port, cline.url, cline.value);
|
||||
LOG(SCHD_LOG,LOG_INFO, "%s%s %s %s %s %s curl -s -S --show-error %s -o /dev/null %s%s -d value=%s -X PUT\n",(cline.enabled?"":"#"),cline.minute, cline.hour, cline.daym, cline.month, cline.dayw, (iface->isLocalurlTLS?"--insecure":""),(iface->localurl==NULL?_aqconfig_.listen_address:iface->localurl), cline.url, cline.value);
|
||||
fprintf(fp, "%s%s %s %s %s %s root curl -s -S --show-error %s -o /dev/null %s%s -d value=%s -X PUT\n",(cline.enabled?"":"#"),cline.minute, cline.hour, cline.daym, cline.month, cline.dayw, (iface->isLocalurlTLS?"--insecure":""),(iface->localurl==NULL?_aqconfig_.listen_address:iface->localurl), cline.url, cline.value);
|
||||
LOG(SCHD_LOG,LOG_INFO, "%s%s %s %s %s %s curl -s -S --show-error %s -o /dev/null %s%s -d value=%s -X PUT\n",(cline.enabled?"":"#"),cline.minute, cline.hour, cline.daym, cline.month, cline.dayw, (iface->isLocalurlTLS?"--insecure":""),(iface->localurl[0]=='\0'?_aqconfig_.listen_address:iface->localurl), cline.url, cline.value);
|
||||
fprintf(fp, "%s%s %s %s %s %s root curl -s -S --show-error %s -o /dev/null %s%s -d value=%s -X PUT\n",(cline.enabled?"":"#"),cline.minute, cline.hour, cline.daym, cline.month, cline.dayw, (iface->isLocalurlTLS?"--insecure":""),(iface->localurl[0]=='\0'?_aqconfig_.listen_address:iface->localurl), cline.url, cline.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -873,7 +873,7 @@ void send_packet(int fd, unsigned char *packet, int length)
|
|||
|
||||
tcdrain(fd); // Make sure buffer has been sent.
|
||||
//if (_aqconfig_.frame_delay > 0) {
|
||||
#ifndef SERIAL_LOGGER
|
||||
#ifndef RS485MON
|
||||
if (_aqconfig_.frame_delay > 0) {
|
||||
timespec_subtract(&elapsed_time, &now, &_last_serial_read_time);
|
||||
LOG(RSTM_LOG, LOG_DEBUG, "Time from recv to send is %.3f sec\n",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const char *getJandyDeviceName(emulation_type etype);
|
|||
|
||||
#define CONNECTION_ERROR "ERROR No connection to RS control panel"
|
||||
#ifdef AQ_MANAGER
|
||||
#define CONNECTION_RUNNING_SLOG "Running serial_logger, this will take some time"
|
||||
#define CONNECTION_RUNNING_SLOG "Running rs485mon, this will take some time"
|
||||
#endif
|
||||
|
||||
//#define SERIAL_BLOCKING_TIME 50 // (1 to 255) in 1/10th second so 1 = 0.1 sec, 255 = 25.5 sec
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
#include "auto_configure.h"
|
||||
|
||||
#ifdef AQ_MANAGER
|
||||
#include "serial_logger.h"
|
||||
#include "rs485mon.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1211,13 +1211,13 @@ void main_loop()
|
|||
|
||||
#ifdef AQ_MANAGER
|
||||
if (_aqualink_data.run_slogger) {
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Starting serial_logger, this will take some time!\n");
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Starting rs485mon, this will take some time!\n");
|
||||
broadcast_aqualinkstate_error(CONNECTION_RUNNING_SLOG);
|
||||
|
||||
if (_aqualink_data.slogger_debug)
|
||||
addDebugLogMask(SLOG_LOG);
|
||||
|
||||
serial_logger(rs_fd, _aqconfig_.serial_port, _aqualink_data.slogger_debug?LOG_DEBUG:getSystemLogLevel(), _aqualink_data.slogger_packets, _aqualink_data.slogger_ids);
|
||||
rs485mon(rs_fd, _aqconfig_.serial_port, _aqualink_data.slogger_debug?LOG_DEBUG:getSystemLogLevel(), _aqualink_data.slogger_packets, _aqualink_data.slogger_ids);
|
||||
_aqualink_data.run_slogger = false;
|
||||
|
||||
if (_aqualink_data.slogger_debug)
|
||||
|
|
|
|||
|
|
@ -475,6 +475,37 @@ int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size)
|
|||
return length;
|
||||
}
|
||||
|
||||
int build_color_lights_json(struct aqualinkdata *aqdata, char* buffer, int size)
|
||||
{
|
||||
memset(&buffer[0], 0, size);
|
||||
int length = 0;
|
||||
int i, j;
|
||||
|
||||
length += sprintf(buffer+length, "\"light_programs\": {");
|
||||
|
||||
if ( _color_light_options[0][1] == NULL || strcmp(_color_light_options[0][1], "1") == 0) {
|
||||
length += sprintf(buffer+length, "\"0\": [],");
|
||||
i=1;
|
||||
} else {
|
||||
i=0;
|
||||
}
|
||||
|
||||
for (; i < NUMBER_LIGHT_COLOR_TYPES; i++) {
|
||||
length += sprintf(buffer+length, "\"%d\": [", i);
|
||||
for (j=1; j < LIGHT_COLOR_OPTIONS; j++) { // Start a 1 since index 0 is blank
|
||||
if (_color_light_options[i][j] != NULL)
|
||||
length += sprintf(buffer+length, "\"%s%s\"%s", _color_light_options[i][j], (isShowMode(_color_light_options[i][j])?" - Show":""), (_color_light_options[i][j+1] != NULL)?",":"" );
|
||||
}
|
||||
//buffer[--length] = '\0';
|
||||
length += sprintf(buffer+length, "],");
|
||||
}
|
||||
|
||||
buffer[--length] = '\0';
|
||||
length += sprintf(buffer+length, "}");
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
int build_color_light_jsonarray(int index, char* buffer, int size)
|
||||
{
|
||||
memset(&buffer[0], 0, size);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ typedef enum clight_type {
|
|||
const char *get_currentlight_mode_name(clight_detail light, emulation_type protocol);
|
||||
const char *light_mode_name(clight_type type, int index, emulation_type protocol);
|
||||
int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size);
|
||||
int build_color_lights_json(struct aqualinkdata *aqdata, char* buffer, int size);
|
||||
int build_color_light_jsonarray(int index, char* buffer, int size);
|
||||
int dimmer_percent_to_mode_index(int value);
|
||||
int dimmer_mode_to_percent(int value);
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ char *generate_mqtt_id() {
|
|||
if (i < MQTT_ID_LEN) {
|
||||
ID[i++] = '_';
|
||||
const net_iface *info = get_first_valid_interface();
|
||||
if (info->rawmac != NULL)
|
||||
if (info->rawmac[0] != '\0')
|
||||
sprintf(&ID[i], "%.*s", (MQTT_ID_LEN-i), info->rawmac);
|
||||
else
|
||||
sprintf(&ID[i], "%.*d", (MQTT_ID_LEN-i), getpid());
|
||||
|
|
|
|||
|
|
@ -1142,7 +1142,7 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
return uActioned;
|
||||
*/
|
||||
} else if (strncmp(ri1, "seriallogger", 12) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
LOG(NET_LOG,LOG_NOTICE, "Received request to run serial_logger!\n");
|
||||
LOG(NET_LOG,LOG_NOTICE, "Received request to run rs485mon!\n");
|
||||
//LOG(NET_LOG,LOG_NOTICE, "Received request ri1=%s, ri2=%s, ri3=%s value=%f\n",ri1,ri2,ri3,value);
|
||||
_aqualink_data->slogger_packets = round(value);
|
||||
if (ri2 != NULL) {
|
||||
|
|
@ -1156,7 +1156,7 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
} else {
|
||||
_aqualink_data->slogger_debug = false;
|
||||
}
|
||||
//LOG(NET_LOG,LOG_NOTICE, "Received request to run serial_logger (%d,%s,%s)!\n",
|
||||
//LOG(NET_LOG,LOG_NOTICE, "Received request to run rs485mon (%d,%s,%s)!\n",
|
||||
// _aqualink_data->slogger_packets,
|
||||
// _aqualink_data->slogger_ids[0]!='\0'?_aqualink_data->slogger_ids:" ",
|
||||
// _aqualink_data->slogger_debug?"debug":"" );
|
||||
|
|
@ -1676,9 +1676,14 @@ void action_web_request(struct mg_connection *nc, struct mg_http_message *http_m
|
|||
{
|
||||
char message[JSON_BUFFER_SIZE];
|
||||
DEBUG_TIMER_START(&tid2);
|
||||
/*
|
||||
build_dynamic_webconfig_js(_aqualink_data, message, JSON_BUFFER_SIZE);
|
||||
DEBUG_TIMER_STOP(tid2, NET_LOG, "action_web_request() build_webconfig_js took");
|
||||
mg_http_reply(nc, 200, CONTENT_JS, message);
|
||||
*/
|
||||
build_dynamic_webconfig_json(_aqualink_data, message, JSON_BUFFER_SIZE);
|
||||
DEBUG_TIMER_STOP(tid2, NET_LOG, "action_web_request() build_webconfig_json took");
|
||||
mg_http_reply(nc, 200, CONTENT_JSON, message);
|
||||
}
|
||||
break;
|
||||
case uSchedules:
|
||||
|
|
@ -1823,6 +1828,15 @@ void action_websocket_request(struct mg_connection *nc, struct mg_ws_message *wm
|
|||
ws_send(nc, message);
|
||||
}
|
||||
break;
|
||||
case uDynamicconf:
|
||||
{
|
||||
char message[JSON_BUFFER_SIZE];
|
||||
DEBUG_TIMER_START(&tid2);
|
||||
build_dynamic_webconfig_json(_aqualink_data, message, JSON_BUFFER_SIZE);
|
||||
DEBUG_TIMER_STOP(tid2, NET_LOG, "action_web_request() build_webconfig_json took");
|
||||
ws_send(nc, message);
|
||||
}
|
||||
break;
|
||||
case uSimulator:
|
||||
{
|
||||
LOG(NET_LOG,LOG_DEBUG, "Request to start Simulator\n");
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "rs_devices.h"
|
||||
#include "serial_logger.h"
|
||||
#include "rs485mon.h"
|
||||
#include "aq_serial.h"
|
||||
#include "utils.h"
|
||||
#include "packetLogger.h"
|
||||
#include "rs_msg_utils.h"
|
||||
|
||||
#ifdef SERIAL_LOGGER
|
||||
#ifdef RS485MON
|
||||
// Make us look like config.c when we load config.h so we get globals.
|
||||
#define CONFIG_C
|
||||
#endif
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
#define PACKET_MAX 1200
|
||||
#define PROBE_CYCLES 2
|
||||
|
||||
#define VERSION "serial_logger V2.11"
|
||||
#define VERSION "rs485mon V2.12"
|
||||
|
||||
/*
|
||||
typedef enum used {
|
||||
|
|
@ -92,10 +92,10 @@ bool _playback_file = false;
|
|||
|
||||
int sl_timespec_subtract (struct timespec *result, const struct timespec *x, const struct timespec *y);
|
||||
|
||||
int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, bool panleProbe, bool rsSerialSpeedTest, bool errorMonitor, bool printAllIDs, bool timePackets);
|
||||
int _rs485mon(int rs_fd, char *port_name, int logPackets, int logLevel, bool panleProbe, bool rsSerialSpeedTest, bool errorMonitor, bool printAllIDs, bool timePackets);
|
||||
|
||||
|
||||
#ifdef SERIAL_LOGGER
|
||||
#ifdef RS485MON
|
||||
void broadcast_log(char *msg){
|
||||
// Do nothing, just for utils.c to work.
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ bool isAqualinkDStopping() {
|
|||
return !_keepRunning;
|
||||
}
|
||||
#else
|
||||
int serial_logger (int rs_fd, char *port_name, int logLevel, int slogger_packets, char *slogger_ids)
|
||||
int rs485mon (int rs_fd, char *port_name, int logLevel, int slogger_packets, char *slogger_ids)
|
||||
{
|
||||
int packets=PACKET_MAX;
|
||||
unsigned int n;
|
||||
|
|
@ -140,11 +140,11 @@ int serial_logger (int rs_fd, char *port_name, int logLevel, int slogger_packets
|
|||
}
|
||||
|
||||
if (slogger_packets > 0)
|
||||
LOG(SLOG_LOG, LOG_NOTICE, "Running serial logger with %d pakets, loglevel %s\n",packets,elevel2text(logLevel>=LOG_NOTICE?logLevel:LOG_NOTICE) );
|
||||
LOG(SLOG_LOG, LOG_NOTICE, "Running rs485mon with %d pakets, loglevel %s\n",packets,elevel2text(logLevel>=LOG_NOTICE?logLevel:LOG_NOTICE) );
|
||||
else
|
||||
LOG(SLOG_LOG, LOG_NOTICE, "Running serial logger (complete poll cycle), loglevel %s\n",elevel2text(logLevel>=LOG_NOTICE?logLevel:LOG_NOTICE) );
|
||||
LOG(SLOG_LOG, LOG_NOTICE, "Running rs485mon (complete poll cycle), loglevel %s\n",elevel2text(logLevel>=LOG_NOTICE?logLevel:LOG_NOTICE) );
|
||||
|
||||
return _serial_logger(rs_fd, port_name, packets, (logLevel>=LOG_NOTICE?logLevel:LOG_NOTICE), true, false, false, false, false);
|
||||
return _rs485mon(rs_fd, port_name, packets, (logLevel>=LOG_NOTICE?logLevel:LOG_NOTICE), true, false, false, false, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -529,7 +529,7 @@ bool filterMatch(unsigned char ID, unsigned char *packet_buffer, bool failNoFilt
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef SERIAL_LOGGER
|
||||
#ifdef RS485MON
|
||||
|
||||
void printHex(char *pk, int length)
|
||||
{
|
||||
|
|
@ -745,19 +745,19 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
startPacketLogger();
|
||||
|
||||
_serial_logger(rs_fd, argv[1], logPackets, logLevel, panleProbe, rsSerialSpeedTest, errorMonitor, printAllIDs, timePackets);
|
||||
_rs485mon(rs_fd, argv[1], logPackets, logLevel, panleProbe, rsSerialSpeedTest, errorMonitor, printAllIDs, timePackets);
|
||||
|
||||
stopPacketLogger();
|
||||
|
||||
close_serial_port(rs_fd);
|
||||
}
|
||||
|
||||
#endif // SERIAL_LOGGER
|
||||
#endif // RS485MON
|
||||
|
||||
|
||||
|
||||
|
||||
int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, bool panleProbe, bool rsSerialSpeedTest, bool errorMonitor, bool printAllIDs, bool timePackets) {
|
||||
int _rs485mon(int rs_fd, char *port_name, int logPackets, int logLevel, bool panleProbe, bool rsSerialSpeedTest, bool errorMonitor, bool printAllIDs, bool timePackets) {
|
||||
int packet_length;
|
||||
int last_packet_length = 0;
|
||||
unsigned char packet_buffer[AQ_MAXPKTLEN];
|
||||
|
|
@ -874,7 +874,7 @@ int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, boo
|
|||
}
|
||||
}
|
||||
//LOG(SLOG_LOG, LOG_DEBUG_SERIAL, "Received Packet for ID 0x%02hhx of type %s\n", packet_buffer[PKT_DEST], get_packet_type(packet_buffer, packet_length));
|
||||
#ifdef SERIAL_LOGGER
|
||||
#ifdef RS485MON
|
||||
if (logLevel > LOG_NOTICE)
|
||||
printPacket(lastID, packet_buffer, packet_length, timePackets?extra_message:NULL);
|
||||
#else
|
||||
|
|
@ -944,7 +944,7 @@ int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, boo
|
|||
|
||||
}
|
||||
|
||||
#ifndef SERIAL_LOGGER
|
||||
#ifndef RS485MON
|
||||
if(received_packets%100==0) {
|
||||
LOG(SLOG_LOG, LOG_NOTICE, "Read %d of %s%d packets\n", received_packets, probeCycle?"(max)":"" ,logPackets);
|
||||
}
|
||||
|
|
@ -961,7 +961,7 @@ int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, boo
|
|||
received_packets = 0;
|
||||
}
|
||||
} else if (logLevel < LOG_DEBUG) {
|
||||
#ifdef SERIAL_LOGGER
|
||||
#ifdef RS485MON
|
||||
advance_cursor();
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef RS485MON_H_
|
||||
#define RS485MON_H_
|
||||
|
||||
/*
|
||||
int logPackets = PACKET_MAX;
|
||||
int logLevel = LOG_NOTICE;
|
||||
bool panleProbe = true;
|
||||
bool rsSerialSpeedTest = false;
|
||||
//bool serialBlocking = true;
|
||||
bool errorMonitor = false;
|
||||
*/
|
||||
//int rs485mon(int rs_fd, char *port_name);
|
||||
//int rs485mon(int rs_fd, char *port_name, int logPackets, int logLevel, bool panleProbe, bool rsSerialSpeedTest, bool errorMonitor);
|
||||
|
||||
//int rs485mon (int rs_fd, char *port_name, int logLevel);
|
||||
int rs485mon (int rs_fd, char *port_name, int logLevel, int slogger_packets, char *slogger_ids);
|
||||
void getPanelInfo(int rs_fd, unsigned char *packet_buffer, int packet_length);
|
||||
|
||||
#endif // SERIAL_LOGGER_H_
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
#ifndef SERIAL_LOGGER_H_
|
||||
#define SERIAL_LOGGER_H_
|
||||
|
||||
/*
|
||||
int logPackets = PACKET_MAX;
|
||||
int logLevel = LOG_NOTICE;
|
||||
bool panleProbe = true;
|
||||
bool rsSerialSpeedTest = false;
|
||||
//bool serialBlocking = true;
|
||||
bool errorMonitor = false;
|
||||
*/
|
||||
//int serial_logger(int rs_fd, char *port_name);
|
||||
//int serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, bool panleProbe, bool rsSerialSpeedTest, bool errorMonitor);
|
||||
|
||||
//int serial_logger (int rs_fd, char *port_name, int logLevel);
|
||||
int serial_logger (int rs_fd, char *port_name, int logLevel, int slogger_packets, char *slogger_ids);
|
||||
void getPanelInfo(int rs_fd, unsigned char *packet_buffer, int packet_length);
|
||||
|
||||
#endif // SERIAL_LOGGER_H_
|
||||
|
|
@ -358,10 +358,10 @@ const char *logmask2name(logmask_t from)
|
|||
return "Simulator: ";
|
||||
break;
|
||||
case SLOG_LOG:
|
||||
return "Serial Log:";
|
||||
return "RS485mon: ";
|
||||
break;
|
||||
case IAQL_LOG:
|
||||
return "iAqualink2: ";
|
||||
return "iAqualink2:";
|
||||
break;
|
||||
case AQUA_LOG:
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -41,6 +41,20 @@ int build_dynamic_webconfig_js(struct aqualinkdata *aqdata, char* buffer, int si
|
|||
return length;
|
||||
}
|
||||
|
||||
int build_dynamic_webconfig_json(struct aqualinkdata *aqdata, char* buffer, int size)
|
||||
{
|
||||
memset(&buffer[0], 0, size);
|
||||
int length = 0;
|
||||
|
||||
length += sprintf(buffer+length, "{ \"type\": \"dynamicconfig\", \"enable_schedules\" : \"%s\",",(_aqconfig_.enable_scheduler)?"true":"false");
|
||||
|
||||
length += build_color_lights_json(aqdata, &buffer[length], size-length);
|
||||
|
||||
length += sprintf(buffer+length, "}");
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char* find_nth_char(const char* str, int character, int n) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
|
||||
int build_dynamic_webconfig_js(struct aqualinkdata *aqdata, char* buffer, int size);
|
||||
int build_dynamic_webconfig_json(struct aqualinkdata *aqdata, char* buffer, int size);
|
||||
int save_web_config_json(const char* inBuf, int inSize, char* outBuf, int outSize, struct aqualinkdata *aqdata);
|
||||
|
||||
|
||||
|
|
|
|||
4897
web/aqmanager.html
4897
web/aqmanager.html
File diff suppressed because it is too large
Load Diff
|
|
@ -271,7 +271,8 @@
|
|||
"tile_settings": {
|
||||
"turn_off_sensortiles": "true",
|
||||
"show_vsp_gpm": "true",
|
||||
"disable_off_icon_background": "true"
|
||||
"disable_off_icon_background": "true",
|
||||
"light_program_use_dropdown": "false"
|
||||
},
|
||||
"colors-dark-example": {
|
||||
"body_background": "#121212",
|
||||
|
|
|
|||
201
web/index.html
201
web/index.html
|
|
@ -4,15 +4,18 @@
|
|||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=windows-1252'>
|
||||
<title>AqualinkD</title>
|
||||
<meta name='viewport' content='width=device-width'>
|
||||
<!-- <meta name='viewport' content='width=device-width'> -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<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'>
|
||||
<!--<script src='config.js'></script>-->
|
||||
<!--<script src='?command=dynamic_config'></script>-->
|
||||
<script src='/api/dynamicconfig'></script>
|
||||
<!--<script src='/api/dynamicconfig'></script>-->
|
||||
<style>
|
||||
:root {
|
||||
--fonts: 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;
|
||||
|
|
@ -119,14 +122,14 @@
|
|||
.opaque {
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
filter: alpha(opacity=60);
|
||||
filter: opacity(60%);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.vopaque {
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
filter: alpha(opacity=40);
|
||||
filter: opacity(40%);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
|
|
@ -239,8 +242,8 @@
|
|||
|
||||
.hide {
|
||||
display: none;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0.0;
|
||||
filter: opacity(0%);
|
||||
}
|
||||
|
||||
.tile {
|
||||
|
|
@ -253,20 +256,20 @@
|
|||
padding: 5px;
|
||||
height: var(--tile-width);
|
||||
width: var(--tile-width);
|
||||
filter: alpha(opacity=90);
|
||||
filter: opacity(90%);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.on {
|
||||
background-color: var(--tile_on_background);
|
||||
color: var(--tile_on_text);
|
||||
filter: alpha(opacity=100);
|
||||
filter: opacity(100%);
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.flash {
|
||||
color: var(--tile_on_text);
|
||||
filter: alpha(opacity=100);
|
||||
filter: opacity(90%);
|
||||
opacity: 0.9;
|
||||
-webkit-animation-name: tile-flash;
|
||||
/* Safari 4.0 - 8.0 */
|
||||
|
|
@ -374,7 +377,7 @@
|
|||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: var(--tile_icon-height);
|
||||
filter: alpha(opacity=100);
|
||||
filter: opacity(100%);
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
|
|
@ -712,28 +715,28 @@
|
|||
|
||||
|
||||
.pane_close_button {
|
||||
font-size: 10px !important;
|
||||
font-weight: bold !important;
|
||||
font-size: 10px !important;
|
||||
font-weight: bold !important;
|
||||
/*color: var(--body_text);*/
|
||||
/*background-color: #7f8385 !important;*/
|
||||
border: none !important;
|
||||
color: rgb(0, 0, 0) !important;
|
||||
padding: 2px 2px !important;
|
||||
text-decoration: none !important;
|
||||
margin: 2px 2px 2px 2px !important;
|
||||
min-width: 18px !important;
|
||||
border-radius: 2px !important;
|
||||
height: 18px !important;
|
||||
border: none !important;
|
||||
color: rgb(0, 0, 0) !important;
|
||||
padding: 2px 2px !important;
|
||||
text-decoration: none !important;
|
||||
margin: 2px 2px 2px 2px !important;
|
||||
min-width: 18px !important;
|
||||
border-radius: 2px !important;
|
||||
height: 18px !important;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.pane_close_button_contaner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding-top: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.pane_close_button_contaner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding-top: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
/*
|
||||
.timedate {
|
||||
|
|
@ -745,6 +748,9 @@
|
|||
//'use strict';
|
||||
|
||||
var _config = {};
|
||||
var _dynamicconfig = {};
|
||||
|
||||
//'{"enable_schedules" : "false","light_programs": {"0":[], '
|
||||
|
||||
var _aq_display_tile_size = 'small';
|
||||
|
||||
|
|
@ -758,6 +764,7 @@
|
|||
var _scheduler_devices_json= [];
|
||||
var _tile_line_char_limit = 0;
|
||||
var _devices = [];
|
||||
var _enable_schedules = false;
|
||||
|
||||
var _switchOnUri;
|
||||
var _switchOffUri;
|
||||
|
|
@ -879,6 +886,10 @@
|
|||
if (! _config?.tile_settings?.link_spa_and_spa_heater) {
|
||||
_config.tile_settings.link_spa_and_spa_heater = "false";
|
||||
}
|
||||
|
||||
if (isConfigEnabled(_config?.tile_settings?.light_program_use_dropdown)) {
|
||||
_lightProgramDropdown = true;
|
||||
}
|
||||
}
|
||||
|
||||
function isConfigEnabled(value) {
|
||||
|
|
@ -921,7 +932,6 @@
|
|||
|
||||
setSizeSpecifics();
|
||||
populateLightProgram(-1);
|
||||
//populateLightProgram(0);
|
||||
document.getElementById('thermostat_options').classList.remove("hide");
|
||||
document.getElementById('swg_options').classList.remove("hide");
|
||||
document.getElementById('pswitch_options').classList.remove("hide");
|
||||
|
|
@ -971,6 +981,77 @@
|
|||
}
|
||||
|
||||
function populateLightProgram(type=0, current_mode="") {
|
||||
|
||||
var light_program={};
|
||||
|
||||
if (type != -1) {
|
||||
if ( typeof _dynamicconfig?.light_programs === 'undefined' || typeof _dynamicconfig?.light_programs[type] === 'undefined') {
|
||||
console.log("WARNING: blank Ignoring call to populateLightProgram(), type="+type);
|
||||
return;
|
||||
} else {
|
||||
light_program = _dynamicconfig.light_programs[type];
|
||||
}
|
||||
}
|
||||
|
||||
if (_lightProgramDropdown) {
|
||||
option = document.getElementById('pswitch_option_list');
|
||||
try {
|
||||
option.innerHTML = '<option value="0">Light Program</option>';
|
||||
fLen = light_program.length;
|
||||
for (i = 0; i < fLen; i++) {
|
||||
var opt = document.createElement('option');
|
||||
opt.value = i + 1;
|
||||
if (current_mode != "" && light_program[i].startsWith(current_mode)) {
|
||||
opt.selected = true;
|
||||
}
|
||||
opt.innerHTML = light_program[i];
|
||||
option.appendChild(opt);
|
||||
}
|
||||
} catch (e) {}
|
||||
} else {
|
||||
var tbody = document.getElementById('pswitch_table').getElementsByTagName('tbody')[0];
|
||||
if (type == -1) {
|
||||
// -1 is Just init, so create another row, just to delete later.
|
||||
row = tbody.insertRow(2);
|
||||
row.innerHTML = "<td align='center'>Solid Color</td><td align='center'>Light Show</td>";
|
||||
//light_program = _light_program[0]; // Use aqualinkd light modes to set size below
|
||||
light_program[0] = "blank";
|
||||
light_program[1] = "blank - show";
|
||||
}
|
||||
var html1 = '';
|
||||
var html2 = '';
|
||||
var fLen = light_program.length;
|
||||
var i;
|
||||
var selected = "";
|
||||
for (i = 0; i < fLen; i++) {
|
||||
selected = "";
|
||||
if (current_mode != "" && light_program[i].startsWith(current_mode)) {
|
||||
selected = "checked";
|
||||
}
|
||||
if (light_program[i].endsWith(" - Show"))
|
||||
html2 = html2 + "<div class='option_radiocontainer'><label><span class='radio'><input type='radio' name='light_program' value='" + (i+1) + "' "+selected+" onchange='updatePwsitchOptions(this, "+type+");'><span class='option_radio-value' aria-hidden='true'></span></span>" + light_program[i].substr(0, (light_program[i].length - 7)) + "</label></div>";
|
||||
else
|
||||
html1 = html1 + "<div class='option_radiocontainer'><label><span class='radio'><input type='radio' name='light_program' value='" + (i+1) + "' "+selected+" onchange='updatePwsitchOptions(this, "+type+");'><span class='option_radio-value' aria-hidden='true'></span></span>" + light_program[i] + "</label></div>";
|
||||
}
|
||||
var row;
|
||||
row = tbody.deleteRow(2);
|
||||
row = tbody.insertRow(2);
|
||||
if (type == 10) {
|
||||
row.innerHTML = "<td align='center'>Dimmer</td><td align='center'></td>";
|
||||
} else {
|
||||
row.innerHTML = "<td align='center'>Solid Color</td><td align='center'>Light Show</td>";
|
||||
}
|
||||
tbody.deleteRow(3);
|
||||
row = tbody.insertRow(3);
|
||||
row.innerHTML = "<td align='left' valign='top'>" + html1 + "</td><td align='left' valign='top'>" + html2 + "</td>";
|
||||
}
|
||||
}
|
||||
/*
|
||||
function populateLightProgram_old(type=0, current_mode="") {
|
||||
|
||||
console.log("WARNING: Ignoring call to populateLightProgram()");
|
||||
return;
|
||||
|
||||
var light_program = _light_program[type];
|
||||
|
||||
if (_lightProgramDropdown) {
|
||||
|
|
@ -1020,7 +1101,7 @@
|
|||
row.innerHTML = "<td align='left' valign='top'>" + html1 + "</td><td align='left' valign='top'>" + html2 + "</td>";
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// Simply loop over each key/value in color jason array and set that property adding -- to the beginning of key
|
||||
function setColors() {
|
||||
|
|
@ -1106,6 +1187,9 @@
|
|||
*/
|
||||
_tile_line_char_limit = getComputedStyle(document.documentElement).getPropertyValue('--tile_name-charlimit');
|
||||
|
||||
if (_lightProgramDropdown == false && h < 570) {
|
||||
_lightProgramDropdown = true;
|
||||
}
|
||||
|
||||
window.addEventListener("orientationchange", function() {
|
||||
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
|
||||
|
|
@ -1588,6 +1672,8 @@
|
|||
return -1;
|
||||
}
|
||||
|
||||
//function getTileS
|
||||
|
||||
function setThermostatTile(id, value, sp_value) {
|
||||
setTileValue(id, value);
|
||||
var tile;
|
||||
|
|
@ -1941,13 +2027,15 @@
|
|||
if (typeof object.type_ext !== 'undefined' && (object.type_ext == 'switch_program' || object.type_ext == 'light_dimmer')) {
|
||||
if (typeof object.Light_Type !== 'undefined') {
|
||||
document.getElementById(object.id).setAttribute('lighttype', object.Light_Type);
|
||||
|
||||
if (typeof object.Light_Program !== 'undefined') {
|
||||
var light_mode = parseInt(object.Light_Program);
|
||||
if ( object.Light_Type != "10" && object.type_ext != 'light_dimmer' ) {
|
||||
if ( object.Light_Type != "11" && object.type_ext != 'light_dimmer' ) {
|
||||
document.getElementById(object.id).setAttribute('spvalue', light_mode-1);
|
||||
//console.log("Light_Program spvalue = "+document.getElementById(object.id).getAttribute('spvalue'));
|
||||
} else if (object.Light_Type == "11") {
|
||||
document.getElementById(object.id).setAttribute('spvalue', light_mode);
|
||||
}
|
||||
} else {
|
||||
//console.log("Light_Program "+object.id+" object.Light_Program is null");
|
||||
}
|
||||
}
|
||||
// Other switch_program types (other than light_type) GO HERE
|
||||
|
|
@ -2404,8 +2492,10 @@
|
|||
var state = oswitch?.checked;
|
||||
if (type == 'switch_program') {
|
||||
var mode=false;
|
||||
|
||||
if (_lightProgramDropdown) {
|
||||
if (pswitch.selectedIndex > 0) {
|
||||
//console.log("check "+(getTileSPvalue(id)+1) +" against "+pswitch.selectedIndex);
|
||||
if (pswitch.selectedIndex > 0 && (getTileSPvalue(id)+1) != pswitch.selectedIndex) {
|
||||
send_light_mode(pswitch.selectedIndex, id, pswitch.options[pswitch.selectedIndex].text);
|
||||
mode=true;
|
||||
}
|
||||
|
|
@ -2415,6 +2505,7 @@
|
|||
for (x = 0; x < radio.length; x++) {
|
||||
if (radio[x].checked == true) {
|
||||
//console.log("Light Current= "+(getTileSPvalue(id)+1)+" - "+getTileOnText(id)+" Selected="+radio[x].value+" - "+document.getElementById('pswitch_option_switch_text_value').innerHTML);
|
||||
//console.log("check "+(getTileSPvalue(id)+1) +" against "+radio[x].value);
|
||||
if (getTileSPvalue(id)+1 != radio[x].value) {
|
||||
send_light_mode(radio[x].value, id, document.getElementById('pswitch_option_switch_text_value').innerHTML);
|
||||
}
|
||||
|
|
@ -2575,14 +2666,15 @@
|
|||
|
||||
var height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
//console.log("height = "+height+" - "+caller.id);
|
||||
//console.log("Height="+height+", computedwidth="+getComputedStyle(document.querySelector('.scheduler_pane')).width+", clientWidth="+document.documentElement.clientWidth+", innerWidth="+window.innerWidth);
|
||||
|
||||
if (typeof _enable_schedules === "undefined" || _enable_schedules != false)
|
||||
{
|
||||
if ( parseInt(getComputedStyle(document.querySelector('.scheduler_pane')).width) > Math.max(document.documentElement.clientWidth, window.innerWidth) ||
|
||||
height < 300 ) {
|
||||
//alert("Sorry, Scheduler won't fit on screen\nPlease use a different device");
|
||||
//if ( parseInt(getComputedStyle(document.querySelector('.scheduler_pane')).width) > Math.max(document.documentElement.clientWidth, window.innerWidth) || height < 300 ) {
|
||||
// Really bad check, but works. Should probably setup CSS variables for this.
|
||||
if ( Math.max(document.documentElement.clientWidth, window.innerWidth) < 600 || height < 300) {
|
||||
//alert("Sorry, Scheduler won't fit on screen\nPlease use a different device");
|
||||
displayMessage("Scheduler won't fit on screen", 3);
|
||||
//console.log("Height="+height+", computedwidth="+getComputedStyle(document.querySelector('.scheduler_pane')).width+", clientWidth="+document.documentElement.clientWidth+", innerWidth="+window.innerWidth);
|
||||
return;
|
||||
}
|
||||
import("./cronstrue.min.js");
|
||||
|
|
@ -2974,6 +3066,11 @@
|
|||
*
|
||||
*********************************************************************/
|
||||
|
||||
function update_dynamicconfig(data) {
|
||||
_dynamicconfig = data;
|
||||
_enable_schedules = isConfigEnabled(_dynamicconfig.enable_schedules);
|
||||
}
|
||||
|
||||
function update_status(data) {
|
||||
//console.log("Received Update Satus");
|
||||
_aqualink_data = data;
|
||||
|
|
@ -3083,30 +3180,35 @@
|
|||
// If aqualinkd programmed light, need to convert int to text index, if not value is text
|
||||
try {
|
||||
var light_type = document.getElementById(obj.toString()).getAttribute('lighttype');
|
||||
/*
|
||||
if (light_type == "0") {
|
||||
light_mode = parseInt(data.light_program_names[obj])-1;
|
||||
light_mode = data.light_program_names[obj];
|
||||
// For backward compatibility we could get a name here or number (number is is lights modes are in config.js vs aqualinkd.conf)
|
||||
//console.log("Light "+light_mode);
|
||||
if (! isNaN(light_mode)) {
|
||||
light_mode_name = _light_program[light_type][light_mode];
|
||||
//light_mode_name = _light_program[light_type][light_mode];
|
||||
light_mode_name = _dynamicconfig?.light_programs[light_type][light_mode];
|
||||
if (light_mode_name.endsWith(" - Show")) {
|
||||
light_mode_name = light_mode_name.slice(0, -7);
|
||||
}
|
||||
}
|
||||
} else if (/*light_type == 10 ||*/ light_type == 11) {
|
||||
} else*/ if (/*light_type == 10 ||*/ light_type == 11) {
|
||||
// Fo Dimmer Lights.
|
||||
light_mode = parseInt(light_mode_name);
|
||||
document.getElementById(obj.toString()).setAttribute('setpoint', light_mode);
|
||||
} else {
|
||||
light_mode = _light_program[light_type].findIndex(element => element.startsWith(light_mode_name))
|
||||
//light_mode = _light_program[light_type].findIndex(element => element.startsWith(light_mode_name));
|
||||
light_mode = _dynamicconfig?.light_programs[light_type].findIndex(element => element.startsWith(light_mode_name));
|
||||
|
||||
}
|
||||
} catch (e) { /*console.log(e);*/ }
|
||||
} catch (e) {}
|
||||
|
||||
if (light_mode_name != "-999%" && light_mode_name != "Off" && light_mode_name != "off")
|
||||
setTileOnText(obj.toString(),light_mode_name);
|
||||
|
||||
try {
|
||||
document.getElementById(obj.toString()).setAttribute('spvalue', light_mode);
|
||||
//console.log(obj.toString()+" set spvalue attribute to "+light_mode);
|
||||
//console.log("Light mode index "+light_mode+" - "+light_mode_name+" ----- "+_light_program[light_type][light_mode]);
|
||||
} catch (e) { /*console.log(e);*/ }
|
||||
|
||||
|
|
@ -3269,6 +3371,7 @@
|
|||
socket_di.onopen = function() {
|
||||
// success!
|
||||
get_devices();
|
||||
get_dynamicconfig();
|
||||
// Set recurring fetch every 1 minute
|
||||
if (!window.devicesInterval) {
|
||||
window.devicesInterval = setInterval(() => {get_devices();}, 60 * 1000);
|
||||
|
|
@ -3293,6 +3396,8 @@
|
|||
resetBackgroundSize();
|
||||
} else if (data.type == 'schedules') {
|
||||
cs_schedules(data);
|
||||
} else if (data.type == 'dynamicconfig') {
|
||||
update_dynamicconfig(data);
|
||||
}
|
||||
}
|
||||
socket_di.onclose = function() {
|
||||
|
|
@ -3324,6 +3429,13 @@
|
|||
socket_di.send(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
function get_dynamicconfig() {
|
||||
var msg = {
|
||||
uri: "dynamicconfig"
|
||||
};
|
||||
socket_di.send(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
function get_schedules() {
|
||||
var msg = {
|
||||
uri: "schedules"
|
||||
|
|
@ -3430,7 +3542,8 @@
|
|||
|
||||
function updatePwsitchOptions(source, light_type) {
|
||||
if (source.type == 'radio') {
|
||||
var modename = _light_program[light_type][source.value-1];
|
||||
//var modename = _light_program[light_type][source.value-1];
|
||||
var modename = _dynamicconfig?.light_programs[light_type][source.value-1];
|
||||
if (modename.endsWith(" - Show"))
|
||||
modename = modename.substr(0, (modename.length - 7));
|
||||
document.getElementById('pswitch_option_switch_text_value').innerHTML = modename;
|
||||
|
|
@ -3685,7 +3798,7 @@ function cs_synchronizeTableWidths() {
|
|||
<tr>
|
||||
<td colspan='2' align='center'>
|
||||
<select id='pswitch_option_list' class='options_selector'>
|
||||
<option value="0">Pool Light Program</option>
|
||||
<option value="0">Light Program</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
|||
Loading…
Reference in New Issue