Version 2.6.4

pull/428/head v2.6.4
sfeakes 2025-05-04 14:24:41 -05:00
parent 6472e3ccd8
commit 48574ff73e
20 changed files with 626 additions and 53 deletions

293
Dockerfile.releaseBinaries2 Executable file
View File

@ -0,0 +1,293 @@
#####################################
#
# Build container to compile AqualnkD Release binaries (armhf and arm64)
#
# armhf is 32 bit armv6l (armhf) stretch and newer - work on all Pi's running 32bit (Pi1 to Pi4)
# arm64 is 64 bit aarch64 buster and newer - work on Pi3/Pi4/2w running 64bit os
#
# docker build -f Dockerfile.releaseBinaries2 -t aqualinkd-releasebin2 .
# For better debug logs use --progress=plain
# docker build --progress=plain -f Dockerfile.releaseBinaries2 -t aqualinkd-releasebin2 .
#
# docker run -it --mount type=bind,source=./build,target=/build aqualinkd-releasebin2 bash
#
# clean method
# docker system prune
# docker buildx prune <- just build env
#
# armhf =
# COLLECT_GCC=arm-linux-gnueabihf-gcc
# COLLECT_LTO_WRAPPER=/opt/cross-pi-gcc/libexec/gcc/arm-linux-gnueabihf/6.3.0/lto-wrapper
# Target: arm-linux-gnueabihf
# Configured with: ../gcc-6.3.0/configure --prefix=/opt/cross-pi-gcc --target=arm-linux-gnueabihf --enable-languages=c,c++,fortran --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-multilib --enable-linker-build-id
# Thread model: posix
# gcc version 6.3.0 (GCC)
# GLIBC version 2.24
#
# arm64 =
# COLLECT_GCC=aarch64-linux-gnu-gcc
# COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/aarch64-linux-gnu/8/lto-wrapper
# Target: aarch64-linux-gnu
# Configured with: ../src/configure -v --with-pkgversion='Debian 8.3.0-2' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --disable-libphobos --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --program-prefix=aarch64-linux-gnu- --includedir=/usr/aarch64-linux-gnu/include
# Thread model: posix
# gcc version 8.3.0 (Debian 8.3.0-2)
# GLIBC 2.28-10+deb10u3
#####################################
FROM debian:buster
# ############
# Get arm64 build environment.
#
RUN apt-get update && \
apt-get install -y \
build-essential \
libsystemd-dev \
gcc-aarch64-linux-gnu \
binutils-arm-linux-gnueabi \
file
RUN dpkg --add-architecture arm64
RUN apt-get update && \
apt-get install -y libsystemd-dev:arm64
# ############
# Get armhf build environment
# prebuilt armhf doesn't support hard float, (or something that causes it to fail on armhf machines)
#RUN apt-get install -y \
# gcc-arm-linux-gnueabihf \
# binutils-arm-linux-gnueabihf
#RUN dpkg --add-architecture armhf
#RUN apt-get update && \
# apt-get install -y libsystemd-dev:armhf
# So we need to build arnhf our selves. Since we are doing that, using debian/rasbian stretch versions of
# everthing for best compatibality
ENV GCC_VERSION gcc-6.3.0
ENV GLIBC_VERSION glibc-2.24
ENV BINUTILS_VERSION binutils-2.28
ARG DEBIAN_FRONTEND=noninteractive
# Install some tools and compilers + clean up
RUN apt-get update && \
#apt-get install -y rsync git wget gcc-6 g++-6 cmake gdb gdbserver bzip2 && \
apt-get install -y rsync git wget cmake gdb gdbserver bzip2 && \
apt-get clean autoclean && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
# Use GCC 6 as the default
#RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 999 \
# && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-6 999 \
# && update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-6 999 \
# && update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-6 999
# Add a user called `develop`
RUN useradd -ms /bin/bash develop
RUN echo "develop ALL=(ALL:ALL) ALL" >> /etc/sudoers
WORKDIR /home/develop
# Download and extract GCC
RUN wget https://ftp.gnu.org/gnu/gcc/${GCC_VERSION}/${GCC_VERSION}.tar.gz && \
tar xf ${GCC_VERSION}.tar.gz && \
rm ${GCC_VERSION}.tar.gz
# Download and extract LibC
RUN wget https://ftp.gnu.org/gnu/libc/${GLIBC_VERSION}.tar.bz2 && \
tar xjf ${GLIBC_VERSION}.tar.bz2 && \
rm ${GLIBC_VERSION}.tar.bz2
# Download and extract BinUtils
RUN wget https://ftp.gnu.org/gnu/binutils/${BINUTILS_VERSION}.tar.bz2 && \
tar xjf ${BINUTILS_VERSION}.tar.bz2 && \
rm ${BINUTILS_VERSION}.tar.bz2
# Download the GCC prerequisites
RUN cd ${GCC_VERSION} && contrib/download_prerequisites && rm *.tar.*
#RUN cd gcc-9.2.0 && contrib/download_prerequisites && rm *.tar.*
# Build BinUtils
RUN mkdir -p /opt/cross-pi-gcc
WORKDIR /home/develop/build-binutils
RUN ../${BINUTILS_VERSION}/configure \
--prefix=/opt/cross-pi-gcc --target=arm-linux-gnueabihf \
--with-arch=armv6 --with-fpu=vfp --with-float=hard \
--disable-multilib
RUN make -j$(nproc)
RUN make install
# Apply batch to GCC
# https://github.com/qca/open-ath9k-htc-firmware/issues/135
WORKDIR /home/develop
RUN sed -i '1474s/file ==/file[0] ==/' gcc-6.3.0/gcc/ubsan.c
# Build the first part of GCC
WORKDIR /home/develop/build-gcc
RUN ../${GCC_VERSION}/configure \
--prefix=/opt/cross-pi-gcc \
--target=arm-linux-gnueabihf \
--enable-languages=c,c++,fortran \
--with-arch=armv6 --with-fpu=vfp --with-float=hard \
--disable-multilib \
--enable-linker-build-id
RUN make -j$(nproc) 'LIMITS_H_TEST=true' all-gcc
RUN make install-gcc
ENV PATH=/opt/cross-pi-gcc/bin:${PATH}
# Install dependencies
RUN apt-get update && \
apt-get install -y gawk bison python3 && \
apt-get clean autoclean && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
# Download and install the Linux headers
WORKDIR /home/develop
# Should probably use below and change branch. Known to build with rpi-6.1.y or rpi-6.9.y rpi-6.12.y
#RUN git clone -b <branch> --depth=1 https://github.com/raspberrypi/linux
RUN git clone --depth=1 https://github.com/raspberrypi/linux
WORKDIR /home/develop/linux
ENV KERNEL=kernel7
RUN make ARCH=arm INSTALL_HDR_PATH=/opt/cross-pi-gcc/arm-linux-gnueabihf headers_install
# Build GLIBC
WORKDIR /home/develop/build-glibc
RUN ../${GLIBC_VERSION}/configure \
--prefix=/opt/cross-pi-gcc/arm-linux-gnueabihf \
--build=$MACHTYPE --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf \
--with-arch=armv6 --with-fpu=vfp --with-float=hard \
--with-headers=/opt/cross-pi-gcc/arm-linux-gnueabihf/include \
--disable-multilib libc_cv_forced_unwind=yes
RUN make install-bootstrap-headers=yes install-headers
RUN make -j8 csu/subdir_lib
RUN install csu/crt1.o csu/crti.o csu/crtn.o /opt/cross-pi-gcc/arm-linux-gnueabihf/lib
RUN arm-linux-gnueabihf-gcc -nostdlib -nostartfiles -shared -x c /dev/null \
-o /opt/cross-pi-gcc/arm-linux-gnueabihf/lib/libc.so
RUN touch /opt/cross-pi-gcc/arm-linux-gnueabihf/include/gnu/stubs.h
# Continue building GCC
WORKDIR /home/develop/build-gcc
RUN make -j$(nproc) all-target-libgcc
RUN make install-target-libgcc
# Finish building GLIBC
WORKDIR /home/develop/build-glibc
RUN make -j$(nproc)
RUN make install
# Finish building GCC
WORKDIR /home/develop/build-gcc
RUN make -j$(nproc)
RUN make install
# Download systemd and it's dependancys.
RUN mkdir -p /home/develop/packages
WORKDIR /home/develop/packages
####################
# Manually libsystemd-dev and all it's depandancys
# Commented out ones are what I really want, but couldn;t find.
#####RUN wget https://archive.debian.org/debian/pool/main/s/systemd/libsystemd-dev_232-25+deb9u14_armhf.deb
#RUN wget https://archive.debian.org/debian/pool/main/s/systemd/libsystemd-dev_232-25+deb9u12_armhf.deb
#####RUN wget https://archive.debian.org/debian/pool/main/s/systemd/libsystemd0_232-25+deb9u14_armhf.deb
#RUN wget https://archive.debian.org/debian/pool/main/s/systemd/libsystemd0_232-25+deb9u12_armhf.deb
#RUN wget https://archive.debian.org/debian/pool/main/g/glibc/libc6_2.24-11+deb9u4_armhf.deb
#RUN wget https://archive.debian.org/debian/pool/main/libg/libgpg-error/libgpg-error0_1.26-2_armhf.deb
#####RUN wget https://archive.debian.org/debian/pool/main/x/xz-utils/liblzma5_5.2.2-1.2+deb9u1_armhf.deb
#RUN wget https://archive.debian.org/debian/pool/main/x/xz-utils/liblzma5_5.2.2-1.2+b1_armhf.deb
#RUN wget https://archive.debian.org/debian/pool/main/libs/libselinux/libselinux1_2.6-3+b3_armhf.deb
#####RUN wget https://archive.debian.org/debian/pool/main/libg/libgcrypt20//libgcrypt20_1.7.6-2+deb9u4_armhf.deb
#RUN wget https://archive.debian.org/debian/pool/main/libg/libgcrypt20//libgcrypt20_1.7.6-2+deb9u3_armhf.deb
#####RUN wget https://archive.debian.org/debian/pool/main/l/lz4/liblz4-1_0.0~r131-2+deb9u1_armhf.deb
#RUN wget https://archive.debian.org/debian/pool/main/l/lz4/liblz4-1_0.0~r131-2+b1_armhf.deb
#####RUN wget https://archive.debian.org/debian/pool/main/p/pcre3/libpcre3_2%3a8.39-3_armhf.deb
#RUN wget https://archive.debian.org/debian/pool/main/p/pcre3/libpcre3_8.39-3_armhf.deb
#
# Now we have all packaged, let's unpack them.
#
# Install all packages into /opt/cross-pi-gcc/arm-linux-gnueabihf
#RUN for file in *; do dpkg-deb -x $file /opt/cross-pi-gcc/arm-linux-gnueabihf; done
#
####################
# Rather than manually, Let's do some modifications to apt and get that working (kinda)
# Get just enough for apt-get and dpk to run. apt-get doesn't actually work, just enough to download
ENV APT_ROOT=/opt/cross-pi-gcc/apt-armhf
RUN mkdir -p $APT_ROOT
#RUN APT_ROOT=/opt/cross-pi-gcc/apt-armhf; export APT_ROOT
RUN mkdir -p $APT_ROOT/etc/apt/sources.list.d/
RUN mkdir -p $APT_ROOT/var/lib/dpkg/updates/
RUN mkdir -p $APT_ROOT/var/lib/dpkg/info
RUN mkdir -p $APT_ROOT/var/cache/apt/archives/partial
RUN mkdir -p $APT_ROOT/var/log/apt/
#mkdir -p $APT_ROOT/usr/share/
RUN echo "deb http://archive.debian.org/debian/ stretch main contrib non-free" > $APT_ROOT/etc/apt/sources.list
RUN echo "deb http://archive.debian.org/debian/ stretch-proposed-updates main contrib non-free" >> $APT_ROOT/etc/apt/sources.list
RUN echo "deb http://archive.debian.org/debian-security stretch/updates main contrib non-free" >> $APT_ROOT/etc/apt/sources.list
RUN touch $APT_ROOT/var/lib/dpkg/status
RUN ln -s /etc/apt/trusted.gpg.d $APT_ROOT/etc/apt/
RUN ln -s /etc/apt/preferences.d $APT_ROOT/etc/apt/
RUN ln -s /etc/apt/auth.conf.d $APT_ROOT/etc/apt/
# needed for download
RUN dpkg --add-architecture armhf
# needed for install
RUN dpkg --root=$APT_ROOT --add-architecture armhf
RUN apt -o Dir=$APT_ROOT update
RUN apt -o Dir=$APT_ROOT download libsystemd-dev:armhf \
libsystemd0:armhf \
libc6:armhf \
libgcrypt20:armhf \
liblz4-1:armhf \
liblzma5:armhf \
libselinux1:armhf \
libpcre3:armhf \
libgpg-error0:armhf
############
# Now we have all packaged, let's unpack them.
# Install all packages into /opt/cross-pi-gcc/arm-linux-gnueabihf
# Could use `dpkg --root=$APT_ROOT --force-all -i` in below, but extract works without any warnings.
RUN for file in *; do dpkg -x $file /opt/cross-pi-gcc/arm-linux-gnueabihf; done
# the above will ge installed in /opt/cross-pi-gcc/arm-linux-gnueabihf/lib/arm-linux-gnueabihf,
# and we need them in /opt/cross-pi-gcc/arm-linux-gnueabihf/lib/, so make come links.
WORKDIR /opt/cross-pi-gcc/arm-linux-gnueabihf/lib
RUN for file in ./arm-linux-gnueabihf/*; do ln -s $file ./`basename $file` 2> /dev/null; done; exit 0
# liblz4.so.1 is installed in a different directory, so link that as well.
RUN ln -s /opt/cross-pi-gcc/arm-linux-gnueabihf/usr/lib/arm-linux-gnueabihf/liblz4.so.1 /opt/cross-pi-gcc/arm-linux-gnueabihf/lib/liblz4.so.1
ENV C_INCLUDE_PATH=/opt/cross-pi-gcc/arm-linux-gnueabihf/usr/include
ENV PATH=$PATH:/opt/cross-pi-gcc/bin:/opt/cross-pi-gcc/libexec/gcc/arm-linux-gnueabihf/6.3.0/
RUN mkdir /build
WORKDIR /build
# Add a user called `build` uid 1001 & gid 10000
# You chould change RB_UID & RB_GID to what works on your build setup
ENV RB_USER=build
ENV RB_UID=1001
ENV RB_GID=1000
RUN groupadd -g $RB_GID $RB_USER 2> /dev/null; exit 0
RUN useradd $RB_USER -u $RB_UID -g $RB_GID -m -s /bin/bash
RUN echo "$RB_USER ALL=(ALL:ALL) ALL" >> /etc/sudoers
USER $RB_USER

View File

@ -237,6 +237,10 @@ debugbinaries:
sudo docker run -it --mount type=bind,source=./,target=/build aqualinkd-releasebin make debugbuild
$(info Binaries for release have been built)
runindocker:
sudo docker run -it --mount type=bind,source=./,target=/build aqualinkd-releasebin make dockerbuildnrun
$(info Binaries for release have been built)
# 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)
@ -245,6 +249,11 @@ buildrelease: clean armhf arm64
quickbuild: armhf arm64
$(shell cd release && [ ! -f "./aqualinkd-armhf" ] && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./serial_logger-armhf ./serial_logger)
# This is run inside container Dockerfile.releaseBinariies (aqualinkd-releasebin)
dockerbuildnrun: ./release/aqualinkd
$(shell ./release/aqualinkd -d -c ./realease/aqualinkd.test.conf
debugbuild: CFLAGS = $(DFLAGS)
debugbuild: armhf arm64
$(shell cd release && [ ! -f "./aqualinkd-armhf" ] && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./serial_logger-armhf ./serial_logger)

View File

@ -126,6 +126,12 @@ NEED TO FIX FOR THIS RELEASE.
* Try an auto-update
* Update Mongoose
-->
# Updates in 2.6.4
* Fix docker crash where journal not configured correctly.
* Updates to config editor.
* Increased number of virtual buttons. (previous limitation only effected RS 16 panels).
* Changed to dimmable lights.
# Updates in 2.6.3
* AqualinkD can how self-update directly from github. use `Upgrade AqualinkD` button in Aqmanager
* New install and remote_install scripts.

View File

@ -17,6 +17,7 @@
#
# Clean the build env and start again
# docker buildx prune
# docker builder prune
#
#
# docker build -f ./Dockerfile.buildrelease .

View File

@ -6,11 +6,17 @@
# armhf is 32 bit armv6l (armhf) stretch and newer - work on all Pi's running 32bit (Pi1 to Pi4)
# arm64 is 64 bit aarch64 buster and newer - work on Pi3/Pi4/2w running 64bit os
#
# To build
# docker build -f Dockerfile.releaseBinaries -t aqualinkd-releasebin .
# For better debug logs use --progress=plain
# docker build --progress=plain -f Dockerfile.releaseBinaries -t aqualinkd-releasebin .
#
# To Run
# docker run -it --mount type=bind,source=./build,target=/build aqualinkd-releasebin bash
#
# clean method
# docker system prune
# docker buildx prune <- just build env
#
# armhf =
# COLLECT_GCC=arm-linux-gnueabihf-gcc
@ -142,6 +148,8 @@ RUN apt-get update && \
# Download and install the Linux headers
WORKDIR /home/develop
# Should probably use below and change branch. Known to build with rpi-6.1.y or rpi-6.9.y rpi-6.12.y
#RUN git clone -b <branch> --depth=1 https://github.com/raspberrypi/linux
RUN git clone --depth=1 https://github.com/raspberrypi/linux
WORKDIR /home/develop/linux
ENV KERNEL=kernel7

View File

@ -15,16 +15,16 @@ if [ $# -eq 0 ]
then
# Below is safer, but not supported on all platforms.
#VERSION=$(curl --silent "https://api.github.com/repos/sfeakes/AqualinkD/releases/latest" | grep -Po '"tag_name": "[^0-9|v|V]*\K.*?(?=")')
VERSION=$(curl --silent "https://api.github.com/repos/sfeakes/AqualinkD/releases/latest" | grep "tag_name" | awk -F'"' '$0=$4')
VERSION=$(curl --silent "https://api.github.com/repos/aqualinkd/AqualinkD/releases/latest" | grep "tag_name" | awk -F'"' '$0=$4')
LATEST_TAG="-t ${DOCKER_HUB_NAME}/${IMAGE}:latest"
else
VERSION=$1
fi
URL="https://github.com/sfeakes/AqualinkD/archive/refs/tags/"$VERSION".tar.gz"
URL2="https://github.com/sfeakes/AqualinkD/archive/refs/tags/v"$VERSION".tar.gz"
URL3="https://github.com/sfeakes/AqualinkD/archive/refs/tags/V"$VERSION".tar.gz"
#BURL="https://github.com/sfeakes/AqualinkD/archive/refs/heads/"$VERSION".tar.gz"
URL="https://github.com/aqualinkd/AqualinkD/archive/refs/tags/"$VERSION".tar.gz"
URL2="https://github.com/aqualinkd/AqualinkD/archive/refs/tags/v"$VERSION".tar.gz"
URL3="https://github.com/aqualinkd/AqualinkD/archive/refs/tags/V"$VERSION".tar.gz"
#BURL="https://github.com/aqualinkd/AqualinkD/archive/refs/heads/"$VERSION".tar.gz"
# Check version is accurate before running docker build
@ -46,7 +46,7 @@ fi
# Check we are building a version not already on docker hub
DOCKER_TAGS=$(wget -q -O - "https://hub.docker.com/v2/namespaces/sfeakes/repositories/aqualinkd/tags" | grep -o '"name": *"[^"]*' | grep -o '[^"]*$')
DOCKER_TAGS=$(wget -q -O - "https://hub.docker.com/v2/namespaces/aqualinkd/repositories/aqualinkd/tags" | grep -o '"name": *"[^"]*' | grep -o '[^"]*$')
if echo $DOCKER_TAGS | grep -q $VERSION; then
echo "AqualinkD version $VERSION already exists on docker.io, are you sure you want to overide"

Binary file not shown.

Binary file not shown.

View File

@ -27,18 +27,75 @@ SOURCEBIN=$BIN
LOG_SYSTEMD=1 # 1=false in bash, 0=true
REMOUNT_RO=1
TRUE=0
FALSE=1
_logfile="";
_frommake=$FALSE;
_ignorearch=$FALSE;
log()
{
echo "$*"
if [[ -n "$_logfile" ]]; then
echo "$*" >> "$_logfile"
fi
if [[ $LOG_SYSTEMD -eq 0 ]]; then
logger -p local0.notice -t aqualinkd "Upgrade: $*"
logger -p local0.notice -t aqualinkd.upgrade "Upgrade: $*"
# Below is same as above but will only wotrk on journald (leaving it here if we use that rater then file)
#echo $* | systemd-cat -t aqualinkd_upgrade -p info
#echo "$*" >> "$OUTPUT"
fi
}
printHelp()
{
echo "$0"
echo "ignorearch (don't check OS architecture, install what was made from Makefile)"
echo "--arch <arch> (install specific OS architecture - armhf | arm64)"
echo "--logfile <filename> (log to file)"
}
log "Called $0 with $*"
while [[ $# -gt 0 ]]; do
case "$1" in
--logfile)
shift
_logfile="$1"
;;
--arch | --forcearch)
shift
#_forcearch="$1"
if [[ -n "$1" ]]; then
_ignorearch=$TRUE
SOURCEBIN=$BIN-$1
else
log "--arch requires parameter eg. ( --arch armhf | --arch arm64 )"
fi
;;
from-make)
_frommake=$TRUE
;;
ignorearch)
_ignorearch=$TRUE
;;
help | -help | --help | -h)
printHelp
exit $TRUE;
;;
*)
echo "Unknown argument: $1"
printHelp;
exit $FALSE;
;;
esac
shift
done
if ! tty > /dev/null 2>&1 || [ "$1" = "syslog" ]; then
# No stdin, probably called from upgrade script
LOG_SYSTEMD=0 # Set logger to systemd
@ -63,7 +120,8 @@ fi
# Figure out what system we are on and set correct binary.
# If we have been called from make, this is a custom build and install, so ignore check.
if [ "$PARENT_COMMAND" != "make" ] && [ "$1" != "from-make" ] && [ "$1" != "ignorearch" ]; then
#if [ "$PARENT_COMMAND" != "make" ] && [ "$1" != "from-make" ] && [ "$1" != "ignorearch" ]; then
if [ "$PARENT_COMMAND" != "make" ] && [ "$_frommake" -eq $FALSE ] && [ "$_ignorearch" -eq $FALSE ]; then
# Use arch or uname -a to get above.
# dpkg --print-architecture

View File

@ -224,9 +224,11 @@ function run_install_script {
log "Installing AqualinkD $1"
# Can't run in background as it'll cleanup / delete files before install.
nohup "$TEMP_INSTALL/release/install.sh" >> "$OUTPUT" 2>&1
#source "/nas/data/Development/Raspberry/AqualinkD/release/install.sh" &>> "$OUTPUT"
temp_file=$(mktemp)
nohup "$TEMP_INSTALL/release/install.sh" "--logfile" "$temp_file" >> "$OUTPUT" 2>&1
cat $temp_file
rm $temp_file
#nohup "/nas/data/Development/Raspberry/AqualinkD/release/install.sh" >> "$OUTPUT" 2>&1 &
#nohup "$TEMP_INSTALL/release/install.sh" >> "$OUTPUT" 2>&1 &
}

Binary file not shown.

Binary file not shown.

View File

@ -680,6 +680,18 @@ bool setVirtualButtonAltLabel(aqkey *button, const char *label) {
return true;
}
int getPumpDefaultSpeed(pump_detail *pump, bool max)
{
if (pump == NULL)
return AQ_UNKNOWN;
if (max)
return pump->pumpType==VFPUMP?PUMP_GPM_MAX:PUMP_RPM_MAX;
else
return pump->pumpType==VFPUMP?PUMP_GPM_MIN:PUMP_RPM_MIN;
}
// So the 0-100% should be 600-3450 RPM and 15-130 GPM (ie 1% would = 600 & 0%=off)
// (value-600) / (3450-600) * 100
// (value) / 100 * (3450-600) + 600
@ -1254,9 +1266,9 @@ bool programDeviceValue(struct aqualinkdata *aqdata, action_type type, int value
}
void programDeviceLightBrightness(struct aqualinkdata *aqdata, int value, int button, bool expectMultiple)
void programDeviceLightBrightness(struct aqualinkdata *aqdata, int value, int deviceIndex, bool expectMultiple, request_source source)
{
clight_detail *light = getProgramableLight(aqdata, button);
clight_detail *light = getProgramableLight(aqdata, deviceIndex);
if (!isRSSA_ENABLED) {
LOG(PANL_LOG,LOG_ERR, "Light mode brightness is only supported with `rssa_device_id` set\n");
@ -1264,7 +1276,7 @@ void programDeviceLightBrightness(struct aqualinkdata *aqdata, int value, int bu
}
if (light == NULL) {
LOG(PANL_LOG,LOG_ERR, "Light mode control not configured for button %d\n",button);
LOG(PANL_LOG,LOG_ERR, "Light mode control not configured for button %d\n",deviceIndex);
return;
}
@ -1274,14 +1286,19 @@ void programDeviceLightBrightness(struct aqualinkdata *aqdata, int value, int bu
}
if (!expectMultiple) {
programDeviceLightMode(aqdata, value, button);
if (value <= 0) {
// Consider this a bad/malformed request to turn the light off.
panel_device_request(aqdata, ON_OFF, deviceIndex, 0, source);
} else {
programDeviceLightMode(aqdata, value, deviceIndex);
}
return;
}
time(&aqdata->unactioned.requested);
aqdata->unactioned.value = value;
aqdata->unactioned.type = LIGHT_MODE;
aqdata->unactioned.id = button;
aqdata->unactioned.id = deviceIndex;
return;
}
@ -1289,7 +1306,7 @@ void programDeviceLightBrightness(struct aqualinkdata *aqdata, int value, int bu
//void programDeviceLightMode(struct aqualinkdata *aqdata, char *value, int button)
//void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int deviceIndex)
{
#ifdef AQ_PDA
if (isPDA_PANEL && !isPDA_IAQT) {
@ -1308,10 +1325,10 @@ void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
}
}*/
clight_detail *light = getProgramableLight(aqdata, button);
clight_detail *light = getProgramableLight(aqdata, deviceIndex);
if (light == NULL) {
LOG(PANL_LOG,LOG_ERR, "Light mode control not configured for button %d\n",button);
LOG(PANL_LOG,LOG_ERR, "Light mode control not configured for button %d\n",deviceIndex);
return;
}
@ -1320,7 +1337,7 @@ void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
if (light->lightType == LC_PROGRAMABLE ) {
//sprintf(buf, "%-5s%-5d%-5d%-5d%.2f",value,
sprintf(buf, "%-5d%-5d%-5d%-5d%.2f",value,
button,
deviceIndex,
_aqconfig_.light_programming_initial_on,
_aqconfig_.light_programming_initial_off,
_aqconfig_.light_programming_mode );
@ -1368,12 +1385,12 @@ void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
set_aqualink_rssadapter_aux_extended_state(light->button, value);*/
} else {
//sprintf(buf, "%-5s%-5d%-5d",value, button, light->lightType);
sprintf(buf, "%-5d%-5d%-5d",value, button, light->lightType);
sprintf(buf, "%-5d%-5d%-5d",value, deviceIndex, light->lightType);
aq_programmer(AQ_SET_LIGHTCOLOR_MODE, buf, aqdata);
}
// Use function so can be called from programming thread if we decide to in future.
updateButtonLightProgram(aqdata, value, button);
updateButtonLightProgram(aqdata, value, deviceIndex);
}
/*
@ -1416,7 +1433,7 @@ bool panel_device_request(struct aqualinkdata *aqdata, action_type type, int dev
start_timer(aqdata, deviceIndex, value);
break;
case LIGHT_BRIGHTNESS:
programDeviceLightBrightness(aqdata, value, deviceIndex, (source==NET_MQTT?true:false));
programDeviceLightBrightness(aqdata, value, deviceIndex, (source==NET_MQTT?true:false), source);
break;
case LIGHT_MODE:
if (value <= 0) {

View File

@ -78,6 +78,7 @@ void addPanelIAQTouchInterface();
void addPanelRSserialAdapterInterface();
void changePanelToExtendedIDProgramming();
int getPumpDefaultSpeed(pump_detail *pump, bool max);
int getPumpSpeedAsPercent(pump_detail *pump);
int convertPumpPercentToSpeed(pump_detail *pump, int value); // This is probable only needed internally
@ -127,14 +128,13 @@ int PANEL_SIZE();
// If we need to increase virtual buttons, then increase below.
// NEED TO FIX, IF WE CHANGE TO ANOTHING OTHER THAN 0 CORE DUMP (we also had "panel_type = RS-16 Combo" in config)
// FIX IS PROBABLY MAKE SURE LEDS IS SAME OR MORE.
#define VIRTUAL_BUTTONS 0
#define VIRTUAL_BUTTONS 5 // This is the only parameter to change if we need more virtual buttons.
//#define TOTAL_BUTTONS 12+VIRTUAL_BUTTONS
#define TOTAL_BUTTONS 20+VIRTUAL_BUTTONS // Biggest jandy panel is 20 buttons (RS16)
#define TOTAL_LEDS TOTAL_BUTTONS+4 // Only 20 exist in control panel, but need space for the 4 extra buttons on RS16 panel, + every virtual button
#define TOTAL_BUTTONS 20+VIRTUAL_BUTTONS // Biggest jandy panel
// This needs to be called AFTER and as well as initButtons
void initButtons_RS16(struct aqualinkdata *aqdata);

View File

@ -292,8 +292,6 @@ DEV_UNKNOWN_MASK = 0xF8; // Unknown mask, used to reset values
#define BUTTON_LABEL_LENGTH 20
//#define TOTAL_LEDS 20
#define TOTAL_LEDS 24 // Only 20 exist in control panel, but need space for the extra buttons on RS16 panel
// Index starting at 1

View File

@ -927,7 +927,6 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
bool rtn = false;
char *tmpval;
//#ifdef CONFIG_DEV_TEST
//int val;
//char *sval;
@ -1120,7 +1119,7 @@ if (strlen(cleanwhitespace(value)) <= 0) {
} else if (strncasecmp(param, "light_program_", 14) == 0) {
int num = strtoul(param + 14, NULL, 10);
if ( num >= LIGHT_COLOR_OPTIONS ) {
if ( num >= LIGHT_COLOR_OPTIONS || num < 0 ) {
LOG(AQUA_LOG,LOG_ERR, "Config error, light_program_%d is out of range\n",num);
}
char *name = cleanalloc(value);
@ -1162,14 +1161,15 @@ if (strlen(cleanwhitespace(value)) <= 0) {
#endif
} else if (strncasecmp(param + 9, "_lightMode", 10) == 0) {
int type = strtoul(value, NULL, 10);
// See if light is existing button / light
if (isPLIGHT(aqdata->aqbuttons[num].special_mask)) {
((clight_detail *)aqdata->aqbuttons[num].special_mask_ptr)->lightType = type;
}
else if (aqdata->num_lights < MAX_LIGHTS)
{
if (type < LC_PROGRAMABLE || type > NUMBER_LIGHT_COLOR_TYPES) {
LOG(AQUA_LOG,LOG_ERR, "Config error, unknown light mode '%s'\n",type);
if (type < LC_PROGRAMABLE || type >= NUMBER_LIGHT_COLOR_TYPES) {
LOG(AQUA_LOG,LOG_ERR, "Config error, unknown light mode '%d' for '%s'\n",type,param);
} else {
aqdata->lights[aqdata->num_lights].button = &aqdata->aqbuttons[num];
aqdata->lights[aqdata->num_lights].lightType = type;
@ -1584,11 +1584,15 @@ void check_print_config (struct aqualinkdata *aqdata)
if (aqdata->chiller_button == NULL) {
LOG(AQUA_LOG,LOG_ERR, "Config error, `%s` is enabled, but no Virtual Button set for Heat Pump / Chiller! Creating vbutton.",CFG_N_force_chiller);
aqkey *button = getVirtualButton(aqdata, 0);
setVirtualButtonLabel(button, cleanalloc("Heat Pump"));// Need to malloc this so it can be freed
setVirtualButtonAltLabel(button, cleanalloc("Chiller"));// Need to malloc this so it can be freed
aqdata->chiller_button = button;
if (button != NULL) {
setVirtualButtonLabel(button, cleanalloc("Heat Pump"));// Need to malloc this so it can be freed
setVirtualButtonAltLabel(button, cleanalloc("Chiller"));// Need to malloc this so it can be freed
aqdata->chiller_button = button;
//aqdata->chiller_button->special_mask |= VIRTUAL_BUTTON_CHILLER;
setMASK(aqdata->chiller_button->special_mask, VIRTUAL_BUTTON_CHILLER);
setMASK(aqdata->chiller_button->special_mask, VIRTUAL_BUTTON_CHILLER);
} else {
LOG(AQUA_LOG,LOG_WARNING, "Error can't create Heat Pump / Chiller, total buttons=%d, config has %d already, ignoring!\n", TOTAL_BUTTONS, aqdata->total_buttons);
}
}
} else {
LOG(AQUA_LOG,LOG_ERR, "Config error, `%s` can only be enabled, if using an iAqualink Touch ID for `%s`, Turning off\n",CFG_N_force_chiller, CFG_N_extended_device_id );
@ -1637,6 +1641,18 @@ void check_print_config (struct aqualinkdata *aqdata)
} else {
aqdata->boost_linked_device = AQ_UNKNOWN;
}
// Check we have pump speed set
for (i=0; i < aqdata->num_pumps; i++) {
if (aqdata->pumps[i].maxSpeed <= 0) {
aqdata->pumps[i].maxSpeed = getPumpDefaultSpeed(&aqdata->pumps[i], true);
//aqdata.pumps[i].maxSpeed = (_aqualink_data.pumps[i].pumpType==VFPUMP?PUMP_GPM_MAX:PUMP_RPM_MAX);
}
if (aqdata->pumps[i].minSpeed <= 0) {
//aqdata.pumps[i].minSpeed = (_aqualink_data.pumps[i].pumpType==VFPUMP?PUMP_GPM_MIN:PUMP_RPM_MIN);
aqdata->pumps[i].minSpeed = getPumpDefaultSpeed(&aqdata->pumps[i], false);
}
}
/*
@ -2103,6 +2119,21 @@ bool writeCfg (struct aqualinkdata *aqdata)
if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpType != PT_UNKNOWN) {
fprintf(fp,"%s_pumpType=%s\n", prefix, pumpType2String(((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpType));
}
//if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->minSpeed != PT_UNKNOWN) {
if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->minSpeed != PT_UNKNOWN &&
((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->minSpeed != getPumpDefaultSpeed((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr, false) )
{
fprintf(fp,"%s_pumpMinSpeed=%d\n", prefix, ((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->minSpeed);
}
//if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->maxSpeed != PT_UNKNOWN) {
if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->maxSpeed != PT_UNKNOWN &&
((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->maxSpeed != getPumpDefaultSpeed((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr, true) )
{
fprintf(fp,"%s_pumpMaxSpeed=%d\n", prefix, ((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->maxSpeed);
}
} else if (isPLIGHT(aqdata->aqbuttons[i].special_mask)) {
//if (((clight_detail *)aqdata->aqbuttons[i].special_mask_ptr)->lightType > 0) {
fprintf(fp,"%s_lightMode=%d\n", prefix, ((clight_detail *)aqdata->aqbuttons[i].special_mask_ptr)->lightType);

View File

@ -35,6 +35,7 @@
#include "rs_msg_utils.h"
#include "color_lights.h"
#include "iaqualink.h"
#include "aq_panel.h"
//#define test_message "{\"type\": \"status\",\"version\": \"8157 REV MMM\",\"date\": \"09/01/16 THU\",\"time\": \"1:16 PM\",\"temp_units\": \"F\",\"air_temp\": \"96\",\"pool_temp\": \"86\",\"spa_temp\": \" \",\"battery\": \"ok\",\"pool_htr_set_pnt\": \"85\",\"spa_htr_set_pnt\": \"99\",\"freeze_protection\": \"off\",\"frz_protect_set_pnt\": \"0\",\"leds\": {\"pump\": \"on\",\"spa\": \"off\",\"aux1\": \"off\",\"aux2\": \"off\",\"aux3\": \"off\",\"aux4\": \"off\",\"aux5\": \"off\",\"aux6\": \"off\",\"aux7\": \"off\",\"pool_heater\": \"off\",\"spa_heater\": \"off\",\"solar_heater\": \"off\"}}"
//#define test_labels "{\"type\": \"aux_labels\",\"aux1_label\": \"Cleaner\",\"aux2_label\": \"Waterfall\",\"aux3_label\": \"Spa Blower\",\"aux4_label\": \"Pool Light\",\"aux5_label\": \"Spa Light\",\"aux6_label\": \"Unassigned\",\"aux7_label\": \"Unassigned\"}"
@ -1456,6 +1457,33 @@ int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_d
} else
length += result;
}
if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->minSpeed != PT_UNKNOWN &&
((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->minSpeed != getPumpDefaultSpeed((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr, false) )
{
sprintf(buf,"%s_pumpMinSpeed", prefix);
stringptr = pumpType2String(((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpType);
if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->minSpeed, CFG_INT, 0, NULL, 0) ) <= 0) {
LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length);
return length;
} else
length += result;
}
if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->maxSpeed != PT_UNKNOWN &&
((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->maxSpeed != getPumpDefaultSpeed((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr, true) )
{
sprintf(buf,"%s_pumpMaxSpeed", prefix);
stringptr = pumpType2String(((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpType);
if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->maxSpeed, CFG_INT, 0, NULL, 0) ) <= 0) {
LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length);
return length;
} else
length += result;
}
} else if (isPLIGHT(aq_data->aqbuttons[i].special_mask)) {
if (((clight_detail *)aq_data->aqbuttons[i].special_mask_ptr)->lightType > 0) {
sprintf(buf,"%s_lightMode", prefix);

View File

@ -180,7 +180,7 @@ void ws_send_logmsg(struct mg_connection *nc, char *msg) {
}
sd_journal *open_journal() {
sd_journal *journal;
sd_journal *journal; // should be static??????
char filter[51];
#ifndef AQ_CONTAINER
@ -192,14 +192,14 @@ sd_journal *open_journal() {
#endif
{
LOGSystemError(errno, NET_LOG, "Failed to open journal");
return journal;
return NULL;
}
snprintf(filter, 50, "SYSLOG_IDENTIFIER=%s",_aqualink_data->self );
if (sd_journal_add_match(journal, filter, 0) < 0)
{
LOGSystemError(errno, NET_LOG, "Failed to set journal syslog filter");
sd_journal_close(journal);
return journal;
return NULL;
}
/* Docker wll also have problem with this
// Daemon will change PID after printing startup message, so don't filter on current PID
@ -282,11 +282,13 @@ bool _broadcast_systemd_logmessages(bool aqMgrActive, bool reOpenStaleConnection
}
// aqManager is active
if (!active) {
if ( (journal = open_journal()) < 0) {
if ( (journal = open_journal()) == NULL) {
//printf("Open faied\n");
build_logmsg_JSON(msg, LOG_ERR, "Failed to open journal", WS_LOG_LENGTH,22);
ws_send_logmsg(_mgr.active_connections, msg);
return false;
}
//printf("Open good %d\n",journal);
if (sd_journal_seek_tail(journal) < 0) {
build_logmsg_JSON(msg, LOG_ERR, "Failed to seek to journal end", WS_LOG_LENGTH,29);
ws_send_logmsg(_mgr.active_connections, msg);
@ -373,7 +375,7 @@ bool write_systemd_logmessages_2file(char *fname, int lines)
LOG(NET_LOG, LOG_WARNING, "Failed to open tmp log file '%s'\n",fname);
return false;
}
if ( (journal = open_journal()) < 0) {
if ( (journal = open_journal()) == NULL) {
fclose (fp);
return false;
}
@ -2253,9 +2255,12 @@ bool _start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata) {
//volatile bool _broadcast = false; // This is redundent when most the fully threadded rather than option.
#define JOURNAL_FAIL_RETRY 5
void *net_services_thread( void *ptr )
{
struct aqualinkdata *aqdata = (struct aqualinkdata *) ptr;
int journald_fail = 0;
//struct mg_mgr mgr;
if (!_start_net_services(&_mgr, aqdata)) {
//LOG(NET_LOG,LOG_ERR, "Failed to start network services\n");
@ -2279,9 +2284,28 @@ void *net_services_thread( void *ptr )
aqdata->updated = false;
}
#ifdef AQ_MANAGER
// NSF, need to stop and disable after 5 tries, this just keeps looping.
// USe something like below to notify user
// build_logmsg_JSON(msg, LOG_ERR, "Failed to open journal, giving up!", WS_LOG_LENGTH,29);
// set global variable so _broadcast_systemd_logmessages() also doesn't keep erroring.
//if ( ! broadcast_systemd_logmessages(aqdata->aqManagerActive) && journald_fail < JOURNAL_FAIL_RETRY) {
if ( journald_fail < JOURNAL_FAIL_RETRY && ! broadcast_systemd_logmessages(aqdata->aqManagerActive) ) {
journald_fail++;
LOG(AQUA_LOG,LOG_ERR, "Couldn't open systemd journal log\n");
} else if (journald_fail == JOURNAL_FAIL_RETRY) {
char msg[WS_LOG_LENGTH];
build_logmsg_JSON(msg, LOG_ERR, "Giving up on journal, don't expect to see logs", WS_LOG_LENGTH,46);
ws_send_logmsg(_mgr.active_connections, msg);
journald_fail = JOURNAL_FAIL_RETRY+1;
}
// Reset failures when manager is not active.
if (!aqdata->aqManagerActive) {journald_fail=0;}
/*
if ( ! broadcast_systemd_logmessages(aqdata->aqManagerActive)) {
LOG(AQUA_LOG,LOG_ERR, "Couldn't open systemd journal log\n");
}
*/
#endif
if (aqdata->simulator_active != SIM_NONE && aqdata->simulator_packet_updated == true ) {
_broadcast_simulator_message(_mgr.active_connections);

View File

@ -4,4 +4,4 @@
#define AQUALINKD_SHORT_NAME "AqualinkD"
// Use Magor . Minor . Patch
#define AQUALINKD_VERSION "2.6.3"
#define AQUALINKD_VERSION "2.6.4"

View File

@ -311,6 +311,21 @@
opacity: 0.0;
}
.config_option_deletebutton {
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: 5px !important;
height: 18px !important;
}
/*
.helptxt {
@ -621,7 +636,7 @@
populateconfigtable(data);
}
function addConfigRow(hideLineSeperator, data, obj, row=-1) {
function addConfigRow(hideLineSeperator, data, obj, row=-1, deletable=false) {
const configtable = document.getElementById("config_table");
const newRow = configtable.insertRow(row);
@ -647,6 +662,14 @@
cell1.style.paddingLeft = "20px";
cell3.textContent = " ";
// Add DELETE button deletable
if (deletable) {
cell3.innerHTML = '<input type="button" class="config_option_deletebutton" id="delete" key="'+obj.toString()+'" value="X" onclick="deleteCfgOption(this);">';
}
if (data[obj]["valid values"] !== undefined) {
//console.log(data[obj]["valid values"]);
const input = document.createElement("select");
@ -731,8 +754,8 @@
// key = 1
//}
const buttonTypelist = ["pumpIndex", "pumpID", "pumpType", "pumpName", "lightMode"];
const virtButtonTypelist = ["pumpIndex", "pumpID", "pumpType", "pumpName", "onetouchID", "altLabel"];
const buttonTypelist = ["pumpIndex", "pumpID", "pumpType", "pumpName", "pumpMaxSpeed", "pumpMinSpeed", "lightMode"];
const virtButtonTypelist = ["pumpIndex", "pumpID", "pumpType", "pumpName", "pumpMaxSpeed", "pumpMinSpeed", "onetouchID", "altLabel"];
const configtable = document.getElementById("config_table");
const newRow = configtable.insertRow();
@ -831,7 +854,7 @@
return;
}
const virtButtonTypelist = ["pumpIndex", "pumpID", "pumpType", "pumpName", "onetouchID", "altLabel"];
const virtButtonTypelist = ["pumpIndex", "pumpID", "pumpType", "pumpName", "pumpMaxSpeed", "pumpMinSpeed", "onetouchID", "altLabel"];
const configtable = document.getElementById("config_table");
@ -919,6 +942,63 @@
console.log(event);
}
function deleteCfgOption(event) {
// Rebuild whole config table, or just delete single row.
// Rebuild table is better.
let rebuild = true;
//var id = event.srcElement.getAttribute('id');
var key = event.getAttribute('key');
let deleted = false;
//var value = event.srcElement.value;
//console.log(event.parentNode.parentNode);
//console.log("deleteCfgOption - "+key);
//console.log(_config[key]);
console.log(_config);
if (!rebuild) {
const configtable = document.getElementById("config_table");
for (let i = 0; i < configtable.rows.length; i++) {
//console.log(configtable.rows[i].cells[2]);
try{
if(configtable.rows[i].cells[2].childNodes[0].getAttribute('key') == key) {
//configtable.deleteRow(i);
deleted = true;
}
} catch (e){}
}
} else {
deleted=true;
}
//event.parentNode.parentNode.style.display = 'none';
if (deleted && key.startsWith("virtual_button") && key.endsWith("_label")) {
//console.log(key.slice(0, 17));
delete _config[key.slice(0, 17)];
// Delete the whole entity
} else if (deleted && key.startsWith("virtual_button")) {
delete _config[key.slice(0, 17)][key];
} else if (deleted && key.startsWith("button")) {
delete _config[key.slice(0, 9)][key];
//console.log(key.slice(0, 9));
} else if (deleted && key.startsWith("sensor")) {
//console.log(key.slice(0, 9));
delete _config[key.slice(0, 9)][key];
} else if (deleted && key.startsWith("light_program_")) {
//console.log(key.slice(0, 9));
delete _config[key];
}
if (rebuild) {
resetConfig(null);
}
console.log(_config);
}
function addSensorRow(num=0, row=-1){
if ( num == 0 ) {
if (_addedBlankSensor == true) {
@ -1011,7 +1091,6 @@
_addedBlankSensor = true;
}
function cfgAddButtonOption(event) {
var type = event.srcElement.value;
@ -1025,6 +1104,8 @@
case "pumpIndex":
case "lightMode":
case "onetouchID":
case "pumpMaxSpeed":
case "pumpMinSpeed":
js.type = "int";
break;
case "pumpID":
@ -1050,7 +1131,7 @@
for (let i = 0; i < configtable.rows.length; i++) {
if(configtable.rows[i].cells[0].getAttribute('button_key') !== null) {
if(configtable.rows[i].cells[0].getAttribute('button_key') == key) {
addConfigRow(true, _config[obj], key+"_"+type, i);
addConfigRow(true, _config[obj], key+"_"+type, i, true);
break;
}
}
@ -1209,7 +1290,20 @@
}
if (_config[obj].value !== undefined) {
addConfigRow(hideLineSeperator, _config, obj);
if (obj.toString().startsWith("light_program_") ) {
console.log(obj.toString());
num = parseInt(lastKey.match(/[0-9]+/));
num++;
console.log("check for light_program_"+String(num+1).padStart(2, '0'));
//console.log("check for light_program_"+num);
if ( !('light_program_'+String(num+1).padStart(2, '0') in _config)) {
addConfigRow(hideLineSeperator, _config, obj, -1, true);
} else {
addConfigRow(hideLineSeperator, _config, obj);
}
} else {
addConfigRow(hideLineSeperator, _config, obj);
}
} else if (obj.toString().startsWith("button_") || obj.toString().startsWith("virtual_button_") ) {
var hide=false;
for (var obj1 in _config[obj]) {
@ -1223,7 +1317,11 @@
cell1.style.borderTop = "1px solid black";
hide=true;
} else if (obj1.toString() != "advanced") {
addConfigRow(hide, _config[obj], obj1);
if ( obj1.toString().endsWith("_label") && !obj1.toString().startsWith("virtual_button")) {
addConfigRow(hide, _config[obj], obj1);
} else {
addConfigRow(hide, _config[obj], obj1, -1, true);
}
hide=true;
}
}
@ -1232,7 +1330,7 @@
var hide=false;
for (var obj1 in _config[obj]) {
if (obj1.toString() != "advanced") {
addConfigRow(hide, _config[obj], obj1);
addConfigRow(hide, _config[obj], obj1, -1, true);
hide=true;
}
}