mirror of https://github.com/sfeakes/AqualinkD.git
Updates 2.6.2
parent
4faa2e0db0
commit
a410d31ad6
2
Makefile
2
Makefile
|
@ -84,7 +84,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 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 hassio.c simulator.c sensors.c aq_filesystem.c timespec_subtract.c
|
||||
serial_logger.c mongoose.c hassio.c simulator.c sensors.c aq_systemutils.c timespec_subtract.c
|
||||
|
||||
|
||||
AQ_FLAGS =
|
||||
|
|
50
README.md
50
README.md
|
@ -11,23 +11,29 @@ If you like this project, you can buy me a cup of coffee :)
|
|||
<br>
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SEGN9UNS38TXJ)
|
||||
|
||||
|
||||
## AqualinkD new home
|
||||
AqualinkD has grown over the years and now has multiple repositories for software / hardware. We are brining them all together under one organization. [AqualinkD home page (under construction)](https://www.aqualinkd.com) -or- [AqualinkD organization](https://github.com/aqualinkd/AqualinkD).<br>
|
||||
AqualinkD will always be open source and so will every associated repository. Nothing will change from that perspective. You will always be able to run this on cheap off the shelf hardware.
|
||||
|
||||
|
||||
## AqualinkD discussions
|
||||
|
||||
* Please use github Discussions for questions (Link at top of page).
|
||||
https://github.com/sfeakes/AqualinkD/discussions
|
||||
https://github.com/aqualinkd/AqualinkD/discussions
|
||||
* For Bugs, please use issues link on top of page. ( please add AqualinkD version to posts )
|
||||
https://github.com/sfeakes/AqualinkD/issues
|
||||
https://github.com/aqualinkd/AqualinkD/issues
|
||||
|
||||
## Please see Wiki for installation instructions
|
||||
https://github.com/sfeakes/AqualinkD/wiki
|
||||
https://github.com/aqualinkd/AqualinkD/wiki
|
||||
|
||||
<!--
|
||||
For information on Control panel versions and upgrading the chips.<br>
|
||||
https://github.com/sfeakes/AqualinkD/wiki/Upgrading-Jandy-Aqualink-PDA-to-RS-panel
|
||||
https://github.com/aqualinkd/AqualinkD/wiki/Upgrading-Jandy-Aqualink-PDA-to-RS-panel
|
||||
-->
|
||||
<!--
|
||||
Here's where I started to document what I know about the Jandy RS485 protocol.<br>
|
||||
https://github.com/sfeakes/AqualinkD/wiki/Jandy-Aqualink-RS485-protocol
|
||||
https://github.com/aqualinkd/AqualinkD/wiki/Jandy-Aqualink-RS485-protocol
|
||||
-->
|
||||
|
||||
## AqualinkD built in WEB Interface(s).
|
||||
|
@ -80,9 +86,11 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control
|
|||
* http://aqualink.ip/onetouch_sim.html <- (One Touch Simulator)
|
||||
* http://aqualink.ip/aquapda_sim.html <- (PDA simulator)
|
||||
#<a name="release"></a>
|
||||
|
||||
|
||||
# ToDo (future release)
|
||||
* Create iAqualink Touch Simulator
|
||||
* AuqlinkD to self configure. (Done for ID's, need to do for Panel type/size)
|
||||
* AqualinkD to self configure. (Done for ID's, need to do for Panel type/size)
|
||||
|
||||
|
||||
<!--
|
||||
|
@ -100,7 +108,7 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control
|
|||
-->
|
||||
|
||||
# Call for Help.
|
||||
* The only Jandy devices I have not decoded yet are LX heater & Chemical Feeder. If you have either of these devices and are willing to post some logs, please let me know, or post in the [Discussions area](https://github.com/sfeakes/AqualinkD/discussions)
|
||||
* The only Jandy devices I have not decoded yet are LX heater & Chemical Feeder. If you have either of these devices and are willing to post some logs, please let me know, or post in the [Discussions area](https://github.com/aqualinkd/AqualinkD/discussions)
|
||||
|
||||
|
||||
<!--
|
||||
|
@ -111,10 +119,18 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
* update documentation on how vbutton / vpump / pump_max & min / enable_iauqalink2
|
||||
* check rs serial adapter is active if light color mode 11 is used.
|
||||
|
||||
* Check SWG messages like "#1 TruClear", see log in this post https://github.com/sfeakes/AqualinkD/discussions/388
|
||||
* Check SWG messages like "#1 TruClear", see log in this post https://github.com/aqualinkd/AqualinkD/discussions/388
|
||||
|
||||
* Heat Pump / Chiller for OneTouch
|
||||
|
||||
* Try an auto-update
|
||||
* Update Mongoose
|
||||
-->
|
||||
# Updates in 2.6.2
|
||||
* AqualinkD can how self-update directly from github. use `Upgrade AqualinkD` button in Aqmanager
|
||||
* New install and remote_install scripts.
|
||||
* Changed MQTT posting frequency when Timers are enabled for better
|
||||
* Updates for new repo location. [AqualinkD organization](https://github.com/aqualinkd/AqualinkD)
|
||||
|
||||
# Updates in 2.6.1
|
||||
* Added External Sensors to Web UI & HomeKit.
|
||||
|
@ -123,7 +139,7 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
* Link device/virtual/onetouch button with SWG BOOST. (Allows you to set VSP RPM when in Boost mode)
|
||||
|
||||
# Updates in 2.6.0
|
||||
* Added configuration editor in aqmanager. [Wiki - AQManager](https://github.com/sfeakes/AqualinkD/wiki#AQManager)
|
||||
* Added configuration editor in aqmanager. [Wiki - AQManager](https://github.com/aqualinkd/AqualinkD/wiki#AQManager)
|
||||
* Can now self-configure on startup. set `device_id=0xFF`
|
||||
* Added scheduling of pump after events (Power On, Freeze Protect, Boost)
|
||||
* Fixed HA bug for thermostats not converting to °C when HA is set to display °C.
|
||||
|
@ -195,10 +211,10 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
|
||||
# Update in Release 2.3.5
|
||||
* Added Home Assistant integration through MQTT discover
|
||||
* Please read the Home Assistant section of the [Wiki - HASSIO](https://github.com/sfeakes/AqualinkD/wiki#HASSIO)
|
||||
* Please read the Home Assistant section of the [Wiki - HASSIO](https://github.com/aqualinkd/AqualinkD/wiki#HASSIO)
|
||||
* There are still some enhacments to come on this.
|
||||
* Included Docker into main releases
|
||||
* Please read Docker section of the [Wiki - Docker](https://github.com/sfeakes/AqualinkD/wiki#Docker)
|
||||
* Please read Docker section of the [Wiki - Docker](https://github.com/aqualinkd/AqualinkD/wiki#Docker)
|
||||
* Added support for reading extended information for Jandy JXi heaters.
|
||||
* Added Color Light to iAqualinkTouch protocol.
|
||||
* Fixed issue mqtt_timed_update (1~2 min rather than between 2 & 20 min)
|
||||
|
@ -214,11 +230,11 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
|
||||
# Update in Release 2.3.3
|
||||
* Introduced Aqualink Manager UI http://aqualink.ip/aqmanager.html
|
||||
* [AqualinkD Manager](https://github.com/sfeakes/AqualinkD/wiki#AQManager)
|
||||
* [AqualinkD Manager](https://github.com/aqualinkd/AqualinkD/wiki#AQManager)
|
||||
* Moved logging into systemd/journal (journalctl) from syslog
|
||||
* [AqualinkD Log](https://github.com/sfeakes/AqualinkD/wiki#Log)
|
||||
* [AqualinkD Log](https://github.com/aqualinkd/AqualinkD/wiki#Log)
|
||||
* Updated to scheduler
|
||||
* [AqualinkD Scheduler](https://github.com/sfeakes/AqualinkD/wiki#Scheduler)
|
||||
* [AqualinkD Scheduler](https://github.com/aqualinkd/AqualinkD/wiki#Scheduler)
|
||||
* Introduced RS485 frame delay / timer.
|
||||
* Improve PDA panels reliability (PDA pannels are slower than RS panels)
|
||||
* Potentially fixed Pentair VSP / SWG problems since Pentair VSP use a different protocol, this will allow a timed delay for the VSP to post a status messages. Seems to only effect RS485 bus when both a Pentair VSP and Jandy SWG are present.
|
||||
|
@ -275,7 +291,7 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
* Fixed RS-4 panel bug.
|
||||
* Fixed some AqualinkTouch programming issues.
|
||||
* Increased timeout for startup probe.
|
||||
* This release WILL require you to make aqualinkd.conf changes. <b>Make sure to read wiki section https://github.com/sfeakes/AqualinkD/wiki#Version_2</b>
|
||||
* This release WILL require you to make aqualinkd.conf changes. <b>Make sure to read wiki section https://github.com/aqualinkd/AqualinkD/wiki#Version_2</b>
|
||||
* Extensive work to reduce CPU cycles and unnesessary logic.
|
||||
* iAqualink Touch protocol supported for VSP & extended programming.
|
||||
* This protocol is a lot faster for programming, ID's are between 0x38 & 0x3B `extended_device_id`, use Serial_logger to find valid ID.
|
||||
|
@ -292,7 +308,7 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
* AqualinkD startup changed to fix some 'systemctl restart' issues.
|
||||
* More detailed API replys.
|
||||
# Update in Release 2.1.0
|
||||
* Big update, lots of core changes, <b>please read wiki section https://github.com/sfeakes/AqualinkD/wiki#Version_2</b>
|
||||
* Big update, lots of core changes, <b>please read wiki section https://github.com/aqualinkd/AqualinkD/wiki#Version_2</b>
|
||||
* Full Variable Speed Pump support. (Can read,set & change RPM,GPM)
|
||||
* Full support for all Colored Lights (even if Jandy Control Panel doesn't support them)
|
||||
* Chemlink pH & ORP now supported. (along with posting MQTT information)
|
||||
|
@ -438,7 +454,7 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
* Freeze protect, heater temperature and SWG set-points have been added to support for standard HTTP requests (MQTT & WS always had support).
|
||||
|
||||
# Please see Wiki for install instructions
|
||||
https://github.com/sfeakes/AqualinkD/wiki
|
||||
https://github.com/aqualinkd/AqualinkD/wiki
|
||||
|
||||
#
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ RUN mkdir /home/AqualinkD
|
|||
WORKDIR /home/AqualinkD
|
||||
|
||||
ARG AQUALINKD_VERSION
|
||||
RUN curl -sL "https://github.com/sfeakes/AqualinkD/archive/refs/tags/$AQUALINKD_VERSION.tar.gz" | tar xz --strip-components=1
|
||||
RUN curl -sL "https://github.com/aqualinkd/AqualinkD/archive/refs/tags/$AQUALINKD_VERSION.tar.gz" | tar xz --strip-components=1
|
||||
# Get latest release
|
||||
#RUN curl -sL $(curl -s https://api.github.com/repos/sfeakes/AqualinkD/releases/latest | grep "tarball_url" | cut -d'"' -f4) | tar xz --strip-components=1
|
||||
#RUN curl -sL $(curl -s https://api.github.com/repos/aqualinkd/AqualinkD/releases/latest | grep "tarball_url" | cut -d'"' -f4) | tar xz --strip-components=1
|
||||
|
||||
# Build aqualinkd
|
||||
RUN make clean && \
|
||||
|
@ -48,9 +48,9 @@ RUN sed -i '/EXTRA_OPTS=.-l./s/^#//g' /etc/default/cron
|
|||
# See: https://github.com/opencontainers/image-spec/blob/main/annotations.md
|
||||
|
||||
LABEL org.opencontainers.image.title="AqualinkD"
|
||||
LABEL org.opencontainers.image.url="https://hub.docker.com/repository/docker/sfeakes/aqualinkd/general"
|
||||
LABEL org.opencontainers.image.source="https://github.com/sfeakes/AqualinkD"
|
||||
LABEL org.opencontainers.image.documentation="https://github.com/sfeakes/AqualinkD"
|
||||
LABEL org.opencontainers.image.url="https://hub.docker.com/repository/docker/aqualinkd/aqualinkd/general"
|
||||
LABEL org.opencontainers.image.source="https://github.com/aqualinkd/AqualinkD"
|
||||
LABEL org.opencontainers.image.documentation="https://github.com/aqualinkd/AqualinkD"
|
||||
LABEL org.opencontainers.image.version=$AQUALINKD_VERSION
|
||||
|
||||
|
||||
|
@ -60,7 +60,7 @@ COPY --from=aqualinkd-build /home/AqualinkD/web/ /var/www/aqualinkd/
|
|||
COPY --from=aqualinkd-build /home/AqualinkD/release/aqualinkd.conf /etc/aqualinkd.conf
|
||||
|
||||
#COPY --from=aqualinkd-build /home/AqualinkD/docker/aqualinkd-docker.cmd /usr/local/bin/aqualinkd-docker
|
||||
RUN curl -s -o /usr/local/bin/aqualinkd-docker https://raw.githubusercontent.com/sfeakes/AqualinkD/master/docker/aqualinkd-docker.cmd && \
|
||||
RUN curl -s -o /usr/local/bin/aqualinkd-docker https://raw.githubusercontent.com/aqualinkd/AqualinkD/master/docker/aqualinkd-docker.cmd && \
|
||||
chmod +x /usr/local/bin/aqualinkd-docker
|
||||
|
||||
CMD ["sh", "-c", "/usr/local/bin/aqualinkd-docker"]
|
||||
|
|
|
@ -59,9 +59,9 @@ WORKDIR /home/AqualinkD
|
|||
|
||||
|
||||
ARG AQUALINKD_VERSION
|
||||
RUN curl -sL "https://github.com/sfeakes/AqualinkD/archive/refs/tags/$AQUALINKD_VERSION.tar.gz" | tar xz --strip-components=1
|
||||
RUN curl -sL "https://github.com/aqualinkd/AqualinkD/archive/refs/tags/$AQUALINKD_VERSION.tar.gz" | tar xz --strip-components=1
|
||||
# Get latest release
|
||||
#RUN curl -sL $(curl -s https://api.github.com/repos/sfeakes/AqualinkD/releases/latest | grep "tarball_url" | cut -d'"' -f4) | tar xz --strip-components=1
|
||||
#RUN curl -sL $(curl -s https://api.github.com/repos/aqualinkd/AqualinkD/releases/latest | grep "tarball_url" | cut -d'"' -f4) | tar xz --strip-components=1
|
||||
|
||||
|
||||
# Make AqualinkD
|
||||
|
@ -87,8 +87,8 @@ RUN sed -i '/EXTRA_OPTS=.-l./s/^#//g' /etc/default/cron
|
|||
|
||||
LABEL org.opencontainers.image.title="AqualinkD"
|
||||
LABEL org.opencontainers.image.url="https://hub.docker.com/repository/docker/sfeakes/aqualinkd/general"
|
||||
LABEL org.opencontainers.image.source="https://github.com/sfeakes/AqualinkD"
|
||||
LABEL org.opencontainers.image.documentation="https://github.com/sfeakes/AqualinkD"
|
||||
LABEL org.opencontainers.image.source="https://github.com/aqualinkd/AqualinkD"
|
||||
LABEL org.opencontainers.image.documentation="https://github.com/aqualinkd/AqualinkD"
|
||||
LABEL org.opencontainers.image.version=$AQUALINKD_VERSION
|
||||
|
||||
EXPOSE 80/tcp
|
||||
|
|
|
@ -2,7 +2,7 @@ services:
|
|||
aqualinkd:
|
||||
image: sfeakes/aqualinkd:latest
|
||||
#build:
|
||||
# context: https://github.com/sfeakes/AqualinkD.git#master:docker
|
||||
# context: https://github.com/aqualinkd/AqualinkD.git#master:docker
|
||||
# args:
|
||||
# AQUALINKD_VERSION: v2.3.6 # Make sure to change to correct version
|
||||
# tags:
|
||||
|
|
|
@ -10,6 +10,25 @@
|
|||
# curl --silent "https://raw.githubusercontent.com/sfeakes/AqualinkD/master/version.h" | grep AQUALINKD_VERSION | cut -d '"' -f 2
|
||||
#
|
||||
|
||||
echo "This script has been updated!"
|
||||
echo "Please use 'curl -fsSL https://raw.githubusercontent.com/aqualinkd/AqualinkD/master/release/remote_install.sh | sudo bash -s -- latest' to install AqualinkD"
|
||||
|
||||
while true; do
|
||||
read -p "Continue install with this script? (y/n): " response
|
||||
case $response in
|
||||
[yY] )
|
||||
echo "Continuing..."
|
||||
break
|
||||
;;
|
||||
[nN] )
|
||||
echo "Exiting..."
|
||||
exit 0
|
||||
;;
|
||||
* )
|
||||
echo "Invalid input. Please enter y or n."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
NAME="AqualinkD"
|
||||
SOURCE_LOCATION="/extras/aqua.sh"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# * See the GNU General Public License for more details.
|
||||
# *
|
||||
# * https://github.com/sfeakes/aqualinkd
|
||||
# * https://github.com/aqualinkd/aqualinkd
|
||||
# */
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# * See the GNU General Public License for more details.
|
||||
# *
|
||||
# * https://github.com/sfeakes/aqualinkd
|
||||
# * https://github.com/aqualinkd/aqualinkd
|
||||
# */
|
||||
|
||||
MAX_TEMP=78
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -24,14 +24,41 @@ MDNSLocation="/etc/avahi/services/"
|
|||
|
||||
SOURCEBIN=$BIN
|
||||
|
||||
LOG_SYSTEMD=1 # 1=false in bash, 0=true
|
||||
REMOUNT_RO=1
|
||||
|
||||
log()
|
||||
{
|
||||
echo "$*"
|
||||
|
||||
if [[ $LOG_SYSTEMD -eq 0 ]]; then
|
||||
logger -p local0.notice -t aqualinkd "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
|
||||
}
|
||||
|
||||
if ! tty > /dev/null 2>&1 || [ "$1" = "syslog" ]; then
|
||||
# No stdin, probably called from upgrade script
|
||||
LOG_SYSTEMD=0 # Set logger to systemd
|
||||
fi
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script must be run as root"
|
||||
log "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $(mount | grep " / " | grep "(ro,") ]]; then
|
||||
echo "Root filesystem is readonly, can't install"
|
||||
exit 1
|
||||
if mount / -o remount,rw &>/dev/null; then
|
||||
# can mount RW.
|
||||
#mount / -o remount,rw &>/dev/null
|
||||
log "Root filesystem is readonly, remounted RW"
|
||||
REMOUNT_RO=0;
|
||||
else
|
||||
log "Root filesystem is readonly, can't install"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Figure out what system we are on and set correct binary.
|
||||
|
@ -41,7 +68,7 @@ if [ "$PARENT_COMMAND" != "make" ] && [ "$1" != "from-make" ] && [ "$1" != "igno
|
|||
# dpkg --print-architecture
|
||||
|
||||
# Exit if we can't find systemctl
|
||||
command -v dpkg >/dev/null 2>&1 || { echo -e "Can't detect system architecture, Please check path to 'dpkg' or install manually.\n"\
|
||||
command -v dpkg >/dev/null 2>&1 || { log -e "Can't detect system architecture, Please check path to 'dpkg' or install manually.\n"\
|
||||
"Or run '$0 ignorearch'" >&2; exit 1; }
|
||||
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
|
@ -49,19 +76,19 @@ if [ "$PARENT_COMMAND" != "make" ] && [ "$1" != "from-make" ] && [ "$1" != "igno
|
|||
|
||||
case $ARCH in
|
||||
arm64)
|
||||
echo "Arch is $ARCH, Using 64bit AqualinkD"
|
||||
log "Arch is $ARCH, Using 64bit AqualinkD"
|
||||
BINEXT="-arm64"
|
||||
;;
|
||||
armhf)
|
||||
echo "Arch is $ARCH, Using 32bit AqualinkD"
|
||||
log "Arch is $ARCH, Using 32bit AqualinkD"
|
||||
BINEXT="-armhf"
|
||||
;;
|
||||
*)
|
||||
if [ -f $BUILD/$SOURCEBIN-$ARCH ]; then
|
||||
echo "Arch $ARCH is not officially supported, but we found a suitable binary"
|
||||
log "Arch $ARCH is not officially supported, but we found a suitable binary"
|
||||
BINEXT="-$ARCH"
|
||||
else
|
||||
echo "Arch $ARCH is unknown, Default to using 32bit HF AqualinkD, you may need to manually try ./release/aqualnkd_arm64"
|
||||
log "Arch $ARCH is unknown, Default to using 32bit HF AqualinkD, you may need to manually try ./release/aqualnkd_arm64"
|
||||
BINEXT=""
|
||||
fi
|
||||
;;
|
||||
|
@ -72,18 +99,18 @@ if [ "$PARENT_COMMAND" != "make" ] && [ "$1" != "from-make" ] && [ "$1" != "igno
|
|||
SOURCEBIN=$BIN$BINEXT
|
||||
elif [ -f $BUILD/$SOURCEBIN ]; then
|
||||
# Not good
|
||||
echo "Can't find correct aqualnkd binary for $ARCH, '$BUILD/$SOURCEBIN$BINEXT' using '$BUILD/$SOURCEBIN' ";
|
||||
log "Can't find correct aqualnkd binary for $ARCH, '$BUILD/$SOURCEBIN$BINEXT' using '$BUILD/$SOURCEBIN' ";
|
||||
fi
|
||||
fi
|
||||
|
||||
# Exit if we can't find binary
|
||||
if [ ! -f $BUILD/$SOURCEBIN ]; then
|
||||
echo "Can't find aqualnkd binary `$BUILD/$SOURCEBIN` ";
|
||||
log "Can't find aqualnkd binary `$BUILD/$SOURCEBIN` ";
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Exit if we can't find systemctl
|
||||
command -v systemctl >/dev/null 2>&1 || { echo "This script needs systemd's systemctl manager, Please check path or install manually" >&2; exit 1; }
|
||||
command -v systemctl >/dev/null 2>&1 || { log "This script needs systemd's systemctl manager, Please check path or install manually" >&2; exit 1; }
|
||||
|
||||
# stop service, hide any error, as the service may not be installed yet
|
||||
systemctl stop $SERVICE > /dev/null 2>&1
|
||||
|
@ -91,7 +118,7 @@ SERVICE_EXISTS=$(echo $?)
|
|||
|
||||
# Clean everything if requested.
|
||||
if [ "$1" == "clean" ]; then
|
||||
echo "Deleting install"
|
||||
log "Deleting install"
|
||||
systemctl disable $SERVICE > /dev/null 2>&1
|
||||
if [ -f $BINLocation/$BIN ]; then
|
||||
rm -f $BINLocation/$BIN
|
||||
|
@ -105,6 +132,9 @@ if [ "$1" == "clean" ]; then
|
|||
if [ -f $DEFLocation/$DEF ]; then
|
||||
rm -f $DEFLocation/$DEF
|
||||
fi
|
||||
if [ -f /etc/cron.d/aqualinkd ]; then
|
||||
rm -f /etc/cron.d/aqualinkd
|
||||
fi
|
||||
if [ -d $WEBLocation ]; then
|
||||
rm -rf $WEBLocation
|
||||
fi
|
||||
|
@ -115,17 +145,17 @@ fi
|
|||
|
||||
# Check cron.d options
|
||||
if [ ! -d "/etc/cron.d" ]; then
|
||||
echo "The version of Cron may not support chron.d, if so AqualinkD Scheduler will not work"
|
||||
echo "Please check before starting"
|
||||
log "The version of Cron may not support chron.d, if so AqualinkD Scheduler will not work"
|
||||
log "Please check before starting"
|
||||
else
|
||||
if [ -f "/etc/default/cron" ]; then
|
||||
CD=$(cat /etc/default/cron | grep -v ^# | grep "\-l")
|
||||
if [ -z "$CD" ]; then
|
||||
echo "Please enabled cron.d support, if not AqualinkD Scheduler will not work"
|
||||
echo "Edit /etc/default/cron and look for the -l option, usually in EXTRA_OPTS"
|
||||
log "Please enabled cron.d support, if not AqualinkD Scheduler will not work"
|
||||
log "Edit /etc/default/cron and look for the -l option, usually in EXTRA_OPTS"
|
||||
fi
|
||||
else
|
||||
echo "Please make sure the version if Cron supports chron.d, if not the AqualinkD Scheduler will not work"
|
||||
log "Please make sure the version if Cron supports chron.d, if not the AqualinkD Scheduler will not work"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -134,10 +164,12 @@ fi
|
|||
if [ -f "$WEBLocation/config.js" ]; then
|
||||
# Test is if has AUX_V1 in file AND "Spa" is in file (Spa_mode changed to Spa)
|
||||
# Version 2.6.0 added Chiller as well
|
||||
if ! grep -q 'Aux_V1' $WEBLocation/$file || ! grep -q '"Spa"' $WEBLocation/$file || ! grep -q '"Chiller"' $WEBLocation/$file; then
|
||||
if ! grep -q '"Aux_V1"' "$WEBLocation/config.js" ||
|
||||
! grep -q '"Spa"' "$WEBLocation/config.js" ||
|
||||
! grep -q '"Chiller"' "$WEBLocation/config.js"; then
|
||||
dateext=`date +%Y%m%d_%H_%M_%S`
|
||||
echo "AqualinkD web config is old, making copy to $WEBLocation/config.js.$dateext"
|
||||
echo "Please make changes to new version $WEBLocation/config.js"
|
||||
log "AqualinkD web config is old, making copy to $WEBLocation/config.js.$dateext"
|
||||
log "Please make changes to new version $WEBLocation/config.js"
|
||||
mv $WEBLocation/config.js $WEBLocation/config.js.$dateext
|
||||
fi
|
||||
fi
|
||||
|
@ -150,24 +182,25 @@ cp $BUILD/$SOURCEBIN $BINLocation/$BIN
|
|||
cp $BUILD/$SRV $SRVLocation/$SRV
|
||||
|
||||
if [ -f $CFGLocation/$CFG ]; then
|
||||
echo "AqualinkD config exists, did not copy new config, you may need to edit existing! $CFGLocation/$CFG"
|
||||
log "AqualinkD config exists, did not copy new config, you may need to edit existing! $CFGLocation/$CFG"
|
||||
else
|
||||
cp $BUILD/$CFG $CFGLocation/$CFG
|
||||
fi
|
||||
|
||||
if [ -f $DEFLocation/$DEF ]; then
|
||||
echo "AqualinkD defaults exists, did not copy new defaults to $DEFLocation/$DEF"
|
||||
log "AqualinkD defaults exists, did not copy new defaults to $DEFLocation/$DEF"
|
||||
else
|
||||
|
||||
cp $BUILD/$DEF.defaults $DEFLocation/$DEF
|
||||
fi
|
||||
|
||||
if [ -f $MDNSLocation/$MDNS ]; then
|
||||
echo "Avahi/mDNS defaults exists, did not copy new defaults to $MDNSLocation/$MDNS"
|
||||
log "Avahi/mDNS defaults exists, did not copy new defaults to $MDNSLocation/$MDNS"
|
||||
else
|
||||
if [ -d "$MDNSLocation" ]; then
|
||||
cp $BUILD/$MDNS.avahi $MDNSLocation/$MDNS
|
||||
else
|
||||
echo "Avahi/mDNS may not be installed, not copying $MDNSLocation/$MDNS"
|
||||
log "Avahi/mDNS may not be installed, not copying $MDNSLocation/$MDNS"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -176,20 +209,38 @@ if [ ! -d "$WEBLocation" ]; then
|
|||
fi
|
||||
|
||||
if [ -f "$WEBLocation/config.js" ]; then
|
||||
echo "AqualinkD web config exists, did not copy new config, you may need to edit existing $WEBLocation/config.js "
|
||||
rsync -avq --exclude='config.js' $BUILD/../web/* $WEBLocation
|
||||
log "AqualinkD web config exists, did not copy new config, you may need to edit existing $WEBLocation/config.js "
|
||||
if command -v "rsync" &>/dev/null; then
|
||||
rsync -avq --exclude='config.js' $BUILD/../web/* $WEBLocation
|
||||
else
|
||||
# This isn;t the right way to do it, but seems to work.
|
||||
shopt -s extglob
|
||||
`cp -r "$BUILD/../web/"!(*config.js) "$WEBLocation"`
|
||||
shopt -u extglob
|
||||
# Below should work, but doesn't.
|
||||
#shopt -s extglob
|
||||
#cp -r "$BUILD/../web/"!(*config.js) "$WEBLocation"
|
||||
#shopt -u extglob
|
||||
fi
|
||||
else
|
||||
cp -r $BUILD/../web/* $WEBLocation
|
||||
fi
|
||||
|
||||
# remount root ro
|
||||
if [[ $REMOUNT_RO -eq 0 ]]; then
|
||||
mount / -o remount,ro &>/dev/null
|
||||
fi
|
||||
|
||||
systemctl enable $SERVICE
|
||||
systemctl daemon-reload
|
||||
|
||||
if [ $SERVICE_EXISTS -eq 0 ]; then
|
||||
echo "Starting daemon $SERVICE"
|
||||
log "Starting daemon $SERVICE"
|
||||
systemctl start $SERVICE
|
||||
else
|
||||
echo "Please edit $CFGLocation/$CFG, then start AqualinkD service"
|
||||
log "Please edit $CFGLocation/$CFG, then start AqualinkD service with `sudo systemctl start aqualinkd`"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include "aqualink.h"
|
||||
#include "aq_scheduler.h"
|
||||
|
||||
bool remount_root_ro(bool readonly)
|
||||
{
|
||||
|
||||
#ifdef AQ_CONTAINER
|
||||
// In container this is pointless
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_INFO, "reMounting root RO\n");
|
||||
mount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct statvfs fsinfo;
|
||||
statvfs("/", &fsinfo);
|
||||
if ((fsinfo.f_flag & ST_RDONLY) == 0) // We are readwrite, ignore
|
||||
return false;
|
||||
|
||||
LOG(AQUA_LOG, LOG_INFO, "reMounting root RW\n");
|
||||
mount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *aq_open_file(char *filename, bool *ro_root, bool *created_file)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
*ro_root = remount_root_ro(false);
|
||||
|
||||
if (access(filename, F_OK) == 0)
|
||||
{
|
||||
*created_file = true;
|
||||
}
|
||||
|
||||
fp = fopen(filename, "w");
|
||||
if (fp == NULL)
|
||||
{
|
||||
remount_root_ro(*ro_root);
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
bool aq_close_file(FILE *file, bool ro_root)
|
||||
{
|
||||
if (file != NULL)
|
||||
fclose(file);
|
||||
|
||||
return remount_root_ro(ro_root);
|
||||
}
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
bool copy_file(const char *source_path, const char *destination_path) {
|
||||
|
||||
|
||||
bool ro_root = remount_root_ro(false);
|
||||
|
||||
FILE *source_file = fopen(source_path, "rb");
|
||||
if (source_file == NULL) {
|
||||
LOG(AQUA_LOG,LOG_ERR, "Error opening source file: %s\n",source_path);
|
||||
remount_root_ro(ro_root);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *destination_file = fopen(destination_path, "wb");
|
||||
if (destination_file == NULL) {
|
||||
LOG(AQUA_LOG,LOG_ERR, "Error opening source file: %s\n",destination_path);
|
||||
fclose(source_file);
|
||||
remount_root_ro(ro_root);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[BUFFER_SIZE];
|
||||
size_t bytes_read;
|
||||
|
||||
while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, source_file)) > 0) {
|
||||
if (fwrite(buffer, 1, bytes_read, destination_file) != bytes_read) {
|
||||
LOG(AQUA_LOG,LOG_ERR, "Error writing to destination file: %s\n",destination_path);
|
||||
fclose(source_file);
|
||||
fclose(destination_file);
|
||||
remount_root_ro(ro_root);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror(source_file)) {
|
||||
LOG(AQUA_LOG,LOG_ERR, "Error reading from source: %s\n",source_path);
|
||||
fclose(source_file);
|
||||
fclose(destination_file);
|
||||
remount_root_ro(ro_root);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(source_file);
|
||||
fclose(destination_file);
|
||||
remount_root_ro(ro_root);
|
||||
return true;
|
||||
}
|
|
@ -29,7 +29,7 @@
|
|||
#include "config.h"
|
||||
#include "aq_panel.h"
|
||||
//#include "utils.h"
|
||||
#include "aq_filesystem.h"
|
||||
#include "aq_systemutils.h"
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Shaun Feakes - All rights reserved
|
||||
*
|
||||
* You may use redistribute and/or modify this code under the terms of
|
||||
* the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation. For the terms of this license,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* You are free to use this software under the terms of the GNU General
|
||||
* Public License, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* https://github.com/sfeakes/aqualinkd
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "aqualink.h"
|
||||
#include "aq_scheduler.h"
|
||||
|
||||
bool remount_root_ro(bool readonly)
|
||||
{
|
||||
|
||||
#ifdef AQ_CONTAINER
|
||||
// In container this is pointless
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (readonly)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_INFO, "reMounting root RO\n");
|
||||
mount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct statvfs fsinfo;
|
||||
statvfs("/", &fsinfo);
|
||||
if ((fsinfo.f_flag & ST_RDONLY) == 0) // We are readwrite, ignore
|
||||
return false;
|
||||
|
||||
LOG(AQUA_LOG, LOG_INFO, "reMounting root RW\n");
|
||||
mount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *aq_open_file(char *filename, bool *ro_root, bool *created_file)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
*ro_root = remount_root_ro(false);
|
||||
|
||||
if (access(filename, F_OK) == 0)
|
||||
{
|
||||
*created_file = true;
|
||||
}
|
||||
|
||||
fp = fopen(filename, "w");
|
||||
if (fp == NULL)
|
||||
{
|
||||
remount_root_ro(*ro_root);
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
bool aq_close_file(FILE *file, bool ro_root)
|
||||
{
|
||||
if (file != NULL)
|
||||
fclose(file);
|
||||
|
||||
return remount_root_ro(ro_root);
|
||||
}
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
bool copy_file(const char *source_path, const char *destination_path)
|
||||
{
|
||||
|
||||
bool ro_root = remount_root_ro(false);
|
||||
|
||||
FILE *source_file = fopen(source_path, "rb");
|
||||
if (source_file == NULL)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_ERR, "Error opening source file: %s\n", source_path);
|
||||
remount_root_ro(ro_root);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *destination_file = fopen(destination_path, "wb");
|
||||
if (destination_file == NULL)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_ERR, "Error opening source file: %s\n", destination_path);
|
||||
fclose(source_file);
|
||||
remount_root_ro(ro_root);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[BUFFER_SIZE];
|
||||
size_t bytes_read;
|
||||
|
||||
while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, source_file)) > 0)
|
||||
{
|
||||
if (fwrite(buffer, 1, bytes_read, destination_file) != bytes_read)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_ERR, "Error writing to destination file: %s\n", destination_path);
|
||||
fclose(source_file);
|
||||
fclose(destination_file);
|
||||
remount_root_ro(ro_root);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror(source_file))
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_ERR, "Error reading from source: %s\n", source_path);
|
||||
fclose(source_file);
|
||||
fclose(destination_file);
|
||||
remount_root_ro(ro_root);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(source_file);
|
||||
fclose(destination_file);
|
||||
remount_root_ro(ro_root);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool run_aqualinkd_upgrade(bool onlycheck)
|
||||
{
|
||||
int pipe_curl_to_bash[2];
|
||||
pid_t pid_curl, pid_bash;
|
||||
//char *curl_args[] = {"curl", "-fsSl", "http://tiger/scratch/remote_install.sh", NULL};
|
||||
//char *curl_args[] = {"curl", "-fsSl", "-H", "Accept: application/vnd.github.raw", "https://api.github.com/repos/sfeakes/AqualinkD/contents/release/remote_install.sh", NULL};
|
||||
char *curl_args[] = {"curl", "-fsSl", "-H", "Accept: application/vnd.github.raw", "https://api.github.com/repos/AqualinkD/AqualinkD/contents/release/remote_install.sh", NULL};
|
||||
char *bash_args[] = {"bash", "-s", "--", "check", NULL};
|
||||
int status_curl, status_bash;
|
||||
|
||||
if (!onlycheck) {
|
||||
bash_args[3] = NULL;
|
||||
}
|
||||
|
||||
if (pipe(pipe_curl_to_bash) == -1)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, opening pipe");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fork for curl
|
||||
pid_curl = fork();
|
||||
if (pid_curl == -1)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, fork (curl)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pid_curl == 0)
|
||||
{ // Child process (curl)
|
||||
close(pipe_curl_to_bash[0]);
|
||||
dup2(pipe_curl_to_bash[1], STDOUT_FILENO);
|
||||
close(pipe_curl_to_bash[1]);
|
||||
execvp("curl", curl_args);
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, execvp (curl)");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fork for bash
|
||||
pid_bash = fork();
|
||||
if (pid_bash == -1)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, fork (bash)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pid_bash == 0)
|
||||
{ // Child process (bash)
|
||||
close(pipe_curl_to_bash[1]);
|
||||
dup2(pipe_curl_to_bash[0], STDIN_FILENO);
|
||||
close(pipe_curl_to_bash[0]);
|
||||
execvp("bash", bash_args);
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, execvp (bash)");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parent process
|
||||
close(pipe_curl_to_bash[0]);
|
||||
close(pipe_curl_to_bash[1]);
|
||||
|
||||
// Wait for curl and get its exit status
|
||||
if (waitpid(pid_curl, &status_curl, 0) == -1)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, waitpid (curl)");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for bash and get its exit status
|
||||
if (waitpid(pid_bash, &status_bash, 0) == -1)
|
||||
{
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, waitpid (bash)");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the exit status of curl
|
||||
if (WIFEXITED(status_curl))
|
||||
{
|
||||
//printf("curl exited with status: %d\n", WEXITSTATUS(status_curl));
|
||||
if (WEXITSTATUS(status_curl) != 0) {
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, curl exited with status: %d\n", WEXITSTATUS(status_curl));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (WIFSIGNALED(status_curl))
|
||||
{
|
||||
//printf("curl terminated by signal: %d\n", WTERMSIG(status_curl));
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, curl terminated by signal: %d\n", WTERMSIG(status_curl));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the exit status of bash
|
||||
if (WIFEXITED(status_bash))
|
||||
{
|
||||
//printf("bash exited with status: %d\n", WEXITSTATUS(status_bash));
|
||||
if (WEXITSTATUS(status_bash) != 0) {
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, bash exited with status: %d\n", WEXITSTATUS(status_bash));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (WIFSIGNALED(status_bash))
|
||||
{
|
||||
//printf("bash terminated by signal: %d\n", WTERMSIG(status_bash));
|
||||
LOG(AQUA_LOG, LOG_ERR,"Upgrade error, bash terminated by signal: %d\n", WTERMSIG(status_bash));
|
||||
return false;
|
||||
}
|
||||
|
||||
//printf("Command execution complete.\n");
|
||||
LOG(AQUA_LOG, LOG_NOTICE, "AqualinkD is upgrading!");
|
||||
return true;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
FILE *aq_open_file( char *filename, bool *ro_root, bool* created_file);
|
||||
bool aq_close_file(FILE *file, bool ro_root);
|
||||
bool copy_file(const char *source_path, const char *destination_path);
|
||||
|
||||
bool run_aqualinkd_upgrade(bool onlycheck);
|
||||
|
||||
|
||||
|
|
@ -14,7 +14,8 @@
|
|||
#define setMASK(bitmask, mask) (bitmask |= mask)
|
||||
#define removeMASK(bitmask, mask) (bitmask &= ~mask)
|
||||
|
||||
#define SIGRESTART SIGUSR1
|
||||
#define SIGRESTART SIGUSR1
|
||||
#define SIGRUPGRADE SIGUSR2
|
||||
|
||||
#ifdef AQ_NO_THREAD_NETSERVICE
|
||||
#define DEFAULT_POLL_SPEED -1
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "debug_timer.h"
|
||||
#include "aq_scheduler.h"
|
||||
#include "json_messages.h"
|
||||
#include "aq_systemutils.h"
|
||||
|
||||
#ifdef AQ_MANAGER
|
||||
#include "serial_logger.h"
|
||||
|
@ -102,11 +103,19 @@ bool isAqualinkDStopping() {
|
|||
|
||||
void intHandler(int sig_num)
|
||||
{
|
||||
if (sig_num == SIGRUPGRADE) {
|
||||
if (! run_aqualinkd_upgrade(false)) {
|
||||
LOG(AQUA_LOG,LOG_ERR, "AqualinkD upgrade failed!\n");
|
||||
}
|
||||
return; // Let the upgrade process terminate us.
|
||||
}
|
||||
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Stopping!\n");
|
||||
|
||||
_keepRunning = false;
|
||||
|
||||
if (sig_num == SIGRESTART) {
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Restarting AqualinkD!\n");
|
||||
// If we are deamonized, we need to use the system
|
||||
if (_aqconfig_.deamonize) {
|
||||
if(fork() == 0) {
|
||||
|
@ -502,6 +511,32 @@ int main(int argc, char *argv[])
|
|||
return startup(argv[0], cfgFile);
|
||||
}
|
||||
|
||||
void check_upgrade_log()
|
||||
{
|
||||
FILE *fp;
|
||||
size_t len = 0;
|
||||
ssize_t read_size;
|
||||
char *line = NULL;
|
||||
|
||||
fp = fopen("/tmp/aqualinkd_upgrade.log", "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
// No upgrade file
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "--- AqualinkD Upgrade log ----\n");
|
||||
while ((read_size = getline(&line, &len, fp)) != -1) {
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "%s", line);
|
||||
}
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "--- End AqualinkD Upgrade log ----\n");
|
||||
|
||||
free(line);
|
||||
fclose(fp);
|
||||
|
||||
remove("/tmp/aqualinkd_upgrade.log");
|
||||
// Need to delete the file here.
|
||||
}
|
||||
|
||||
|
||||
int startup(char *self, char *cfgFile)
|
||||
|
@ -539,6 +574,8 @@ int startup(char *self, char *cfgFile)
|
|||
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Starting %s v%s !\n", AQUALINKD_NAME, AQUALINKD_VERSION);
|
||||
|
||||
check_upgrade_log();
|
||||
|
||||
check_print_config(&_aqualink_data);
|
||||
|
||||
|
||||
|
@ -938,6 +975,7 @@ void main_loop()
|
|||
signal(SIGTERM, intHandler);
|
||||
signal(SIGQUIT, intHandler);
|
||||
signal(SIGRESTART, intHandler);
|
||||
signal(SIGRUPGRADE, intHandler);
|
||||
|
||||
if (!start_net_services(&_aqualink_data))
|
||||
{
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "aq_scheduler.h"
|
||||
#include "aq_panel.h"
|
||||
#include "rs_msg_utils.h"
|
||||
#include "aq_filesystem.h"
|
||||
#include "aq_systemutils.h"
|
||||
|
||||
#define MAXCFGLINE 256
|
||||
|
||||
|
|
|
@ -610,6 +610,8 @@ int build_aqualink_aqmanager_JSON(struct aqualinkdata *aqdata, char* buffer, int
|
|||
length += sprintf(buffer+length, ",\"config_editor\": \"yes\"");
|
||||
}
|
||||
|
||||
length += sprintf(buffer+length, ",\"aqualinkd_version\":\"%s\"",AQUALINKD_VERSION);
|
||||
|
||||
|
||||
/*
|
||||
length += sprintf(buffer+length, ",\"panel_type\":\"%s\"",getPanelString());
|
||||
|
@ -655,6 +657,7 @@ int build_aqualink_aqmanager_JSON(struct aqualinkdata *aqdata, char* buffer, int
|
|||
|
||||
return length;
|
||||
}
|
||||
|
||||
int build_aqualink_status_JSON(struct aqualinkdata *aqdata, char* buffer, int size)
|
||||
{
|
||||
//strncpy(buffer, test_message, strlen(test_message)+1);
|
||||
|
|
|
@ -691,6 +691,8 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
int i;
|
||||
const char *status;
|
||||
int pumpStatus;
|
||||
static struct timespec last_update_timestamp = {0, 0};
|
||||
|
||||
|
||||
// We get called about every second, so check time every MQTT_TIMED_UDATE / 2
|
||||
if (_aqconfig_.mqtt_timed_update) {
|
||||
|
@ -926,8 +928,18 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
//send_mqtt_timer_duration_msg(nc, _aqualink_data->aqbuttons[i].name, &_aqualink_data->aqbuttons[i]);
|
||||
// send_mqtt_timer_state_msg will call send_mqtt_timer_duration_msg so no need to do it here.
|
||||
// Have to use send_mqtt_timer_state_msg due to a timer being set on a device that's already on, (ir no state change so above code does't get hit)
|
||||
send_mqtt_timer_state_msg(nc, _aqualink_data->aqbuttons[i].name, &_aqualink_data->aqbuttons[i]);
|
||||
|
||||
struct timespec current_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
||||
|
||||
// Calculate the time difference in nanoseconds
|
||||
long long time_difference_ns = (current_time.tv_sec - last_update_timestamp.tv_sec) * 1000000000LL + (current_time.tv_nsec - last_update_timestamp.tv_nsec);
|
||||
|
||||
// Check if 10 seconds (10 * 10^9 nanoseconds) have passed
|
||||
if (time_difference_ns >= 10000000000LL || last_update_timestamp.tv_sec == 0) {
|
||||
send_mqtt_timer_state_msg(nc, _aqualink_data->aqbuttons[i].name, &_aqualink_data->aqbuttons[i]);
|
||||
last_update_timestamp = current_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1174,6 +1186,10 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
LOG(NET_LOG,LOG_NOTICE, "Received restart request!\n");
|
||||
raise(SIGRESTART);
|
||||
return uActioned;
|
||||
} else if (strncmp(ri1, "upgrade", 7) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
LOG(NET_LOG,LOG_NOTICE, "Received upgrade request!\n");
|
||||
raise(SIGRUPGRADE);
|
||||
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 ri1=%s, ri2=%s, ri3=%s value=%f\n",ri1,ri2,ri3,value);
|
||||
|
@ -1647,14 +1663,13 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
|
||||
// If we have a get request, pass it
|
||||
if (strncmp(http_msg->uri.p, "/api", 4 ) != 0) {
|
||||
if (strstr(http_msg->method.p, "GET") && http_msg->query_string.len > 0) {
|
||||
//LOG(NET_LOG,LOG_ERR, "WEB: Old API stanza requested, ignoring client request\n");
|
||||
log_http_request(LOG_ERR, "Old API stanza requested, ignoring request :", http_msg);
|
||||
} else {
|
||||
//if (strstr(http_msg->method.p, "GET") && http_msg->query_string.len > 0) {
|
||||
// log_http_request(LOG_ERR, "Old API stanza requested, ignoring request :", http_msg);
|
||||
//} else {
|
||||
DEBUG_TIMER_START(&tid);
|
||||
mg_serve_http(nc, http_msg, _http_server_opts);
|
||||
DEBUG_TIMER_STOP(tid, NET_LOG, "action_web_request() serve file took");
|
||||
}
|
||||
//}
|
||||
//} else if (strstr(http_msg->method.p, "PUT")) {
|
||||
} else {
|
||||
char buf[JSON_BUFFER_SIZE];
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
#define AQUALINKD_SHORT_NAME "AqualinkD"
|
||||
|
||||
// Use Magor . Minor . Patch
|
||||
#define AQUALINKD_VERSION "2.6.1"
|
||||
#define AQUALINKD_VERSION "2.6.2"
|
||||
|
|
|
@ -337,6 +337,9 @@
|
|||
|
||||
var _config = {};
|
||||
|
||||
const _urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
|
||||
// if loading confighelp.js failes, create a blank variable that it creates.
|
||||
if (typeof _confighelp === 'undefined') {
|
||||
var _confighelp = {};
|
||||
|
@ -1284,6 +1287,7 @@
|
|||
read panel_message, panel_type, version, aqualinkd_version
|
||||
|
||||
*/
|
||||
/*
|
||||
if (data['aqualinkd_version']) {
|
||||
document.getElementById("aqualinkdversion").innerHTML = data['aqualinkd_version'];
|
||||
if (data['aqualinkd_version'] == _latestVersionAvailable ) {
|
||||
|
@ -1291,7 +1295,16 @@
|
|||
} else {
|
||||
document.getElementById("latesversionavailable").classList.add("newversion");
|
||||
}
|
||||
}
|
||||
|
||||
//const upgrade = _urlParams.get('upgrade');
|
||||
//console.log("upgrade = "+upgrade);
|
||||
|
||||
if ( isNewerVersion(_latestVersionAvailable, data['aqualinkd_version'] ) || _urlParams.get('upgrade') != null) {
|
||||
enablebutton("upgrade");
|
||||
} else {
|
||||
disablebutton("upgrade");
|
||||
}
|
||||
}*/
|
||||
if (data['version']) {
|
||||
document.getElementById("panelversion").innerHTML = data['version'];
|
||||
}
|
||||
|
@ -1335,7 +1348,25 @@
|
|||
if (data['deamonized'] == 'off') {
|
||||
//console.log("deamonized=" + data['deamonized'] + " Need to rename Restart to Reload");
|
||||
disablebutton("restart");
|
||||
disablebutton("upgrade");
|
||||
} else {
|
||||
enablebutton("restart");
|
||||
if (data['aqualinkd_version']) {
|
||||
document.getElementById("aqualinkdversion").innerHTML = data['aqualinkd_version'];
|
||||
if (data['aqualinkd_version'] == _latestVersionAvailable ) {
|
||||
document.getElementById("latesversionavailable").classList.add("hidden");
|
||||
} else {
|
||||
document.getElementById("latesversionavailable").classList.add("newversion");
|
||||
}
|
||||
if ( isNewerVersion(_latestVersionAvailable, data['aqualinkd_version'] ) || _urlParams.get('upgrade') != null) {
|
||||
enablebutton("upgrade");
|
||||
} else {
|
||||
disablebutton("upgrade");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (data['config_editor'] == 'yes') {
|
||||
enablebutton("editconfig");
|
||||
} else {
|
||||
|
@ -1346,6 +1377,8 @@
|
|||
}, 10000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if (data['logfilename'] == "(null)")
|
||||
enabletoggle("logfile");
|
||||
|
@ -1517,7 +1550,25 @@
|
|||
socket_di.send(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
function isNewerVersion(version1, version2) {
|
||||
try{
|
||||
let [major1, minor1, patch1] = version1.split('.').map(Number => parseInt(Number, 10));
|
||||
let [major2, minor2, patch2] = version2.split('.').map(Number => parseInt(Number, 10));
|
||||
|
||||
if (patch1 === undefined) { patch1 = 0; }
|
||||
if (patch2 === undefined) { patch2 = 0; }
|
||||
|
||||
if (major1 > major2) return true;
|
||||
if (major1 < major2) return false;
|
||||
|
||||
if (minor1 > minor2) return true;
|
||||
if (minor1 < minor2) return false;
|
||||
|
||||
return patch1 > patch2;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
function reset() {
|
||||
socket_di.send("reset\n");
|
||||
|
@ -1526,9 +1577,12 @@
|
|||
function init() {
|
||||
// Resize log container
|
||||
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
console.log("Height="+h+" Setting to "+(h-290) );
|
||||
//console.log("Height="+h+" Setting to "+(h-290) );
|
||||
document.documentElement.style.setProperty('--logcontainer-height', (h-290)+'px');
|
||||
|
||||
disablebutton("restart");
|
||||
disablebutton("upgrade");
|
||||
|
||||
startWebsockets();
|
||||
getLatestVersion();
|
||||
}
|
||||
|
@ -1566,6 +1620,10 @@
|
|||
var cmd = {};
|
||||
//cmd.uri = "rawcommand"
|
||||
switch (source.id) {
|
||||
case "upgrade":
|
||||
cmd.uri = "upgrade"
|
||||
// NEED TO REGET aqmanager after restart.
|
||||
break;
|
||||
case "restart":
|
||||
cmd.uri = "restart"
|
||||
// NEED TO REGET aqmanager after restart.
|
||||
|
@ -1640,7 +1698,8 @@
|
|||
<td colspan="2" align="center"><label id="statusmsg" class="statusmsg">status</label></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" align="center"><input id="restart" type="button" onclick="send(this);" value="Restart AqualinkD"></td>
|
||||
<td colspan="1" align="center"><input id="restart" type="button" onclick="send(this);" value="Restart AqualinkD"></td>
|
||||
<td colspan="1" align="center"><input id="upgrade" type="button" onclick="send(this);" value="Upgrade AqualinkD"></td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr>
|
||||
|
|
|
@ -647,6 +647,32 @@
|
|||
showTileOptions(false);
|
||||
startWebsockets();
|
||||
resetBackgroundSize();
|
||||
|
||||
// Test for mobile-app mode
|
||||
|
||||
if (window.navigator.standalone === true || window.matchMedia('(display-mode: standalone)').matches) {
|
||||
//console.log("Running in standalone mode");
|
||||
//alert("Standalone");
|
||||
// in webapp mode, remove the aqmanager link
|
||||
try{
|
||||
document.getElementById('td_cog').classList.add("hide");
|
||||
} catch (e){}
|
||||
} else {
|
||||
//console.log("Not running in standalone mode");
|
||||
//alert("NOT Standalone");
|
||||
}
|
||||
|
||||
|
||||
// Test for iframe
|
||||
if (window.self !== window.top) {
|
||||
//console.log("The code is running inside an iframe.");
|
||||
// Change the link under the cog/hamburger icon
|
||||
ele = document.getElementById('cog_link');
|
||||
ele.setAttribute("href", "/");
|
||||
ele.setAttribute("target", "_parent");
|
||||
} else {
|
||||
//console.log("The code is not running inside an iframe.");
|
||||
}
|
||||
}
|
||||
|
||||
function populateLightProgram(type=0, current_mode="") {
|
||||
|
@ -2726,6 +2752,14 @@
|
|||
<div id="header" class="head" onclick="showBackground();">
|
||||
<table border='0' width='100%' cellpadding='0' cellspacing='0'>
|
||||
<tr>
|
||||
<td width="25px" align='left' id='td_cog' style="vertical-align:middle">
|
||||
<a id="cog_link" href="/aqmanager.html">
|
||||
<svg viewBox='0 0 10 8' width='18' height='18'>
|
||||
<path d='M1 1h8M1 4h 8M1 7h8' stroke='#FFF' stroke-width='1.2' stroke-linecap='round'/>
|
||||
</svg>
|
||||
</a>
|
||||
</td>
|
||||
</td>
|
||||
<td width="70px" align='left' id='td_name'><span class='title' id='name'
|
||||
onclick="showVersion(this);event.stopPropagation();">AqualinkD</span>
|
||||
</td>
|
||||
|
|
Loading…
Reference in New Issue