mirror of https://github.com/sfeakes/AqualinkD.git
Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
|
6472e3ccd8 | |
|
d789fc2cfb | |
|
76f3adfcb9 | |
|
d23db569d0 | |
|
c04ec5ce01 | |
|
47c56ee5d4 | |
|
5fcbc2a2e9 | |
|
a410d31ad6 | |
|
4faa2e0db0 | |
|
a38a1c6e00 | |
|
1965a7460c | |
|
39a8ca5684 | |
|
411891fd88 |
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 =
|
||||
|
|
54
README.md
54
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).<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,22 @@ 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.3
|
||||
* 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)
|
||||
* Please use the following to upgrade
|
||||
* `curl -fsSL https://install.aqualinkd.com | sudo bash -s -- latest`
|
||||
* -or-
|
||||
* `curl -fsSL https://raw.githubusercontent.com/aqualinkd/AqualinkD/master/release/remote_install.sh | sudo bash -s -- latest`
|
||||
|
||||
# Updates in 2.6.1
|
||||
* Added External Sensors to Web UI & HomeKit.
|
||||
|
@ -123,7 +143,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 +215,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 +234,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 +295,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 +312,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 +458,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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,332 @@
|
|||
#!/bin/bash
|
||||
|
||||
#
|
||||
# run from curl or local will give different results.
|
||||
# curl -fsSL https://raw.githubusercontent.com/aqualinkd/AqualinkD/master/release/remote_install.sh | sudo bash -s -- latest
|
||||
# ./upgrade.sh latest
|
||||
#
|
||||
# To get good / bad exit code from both curl and bash, use below. It will exit current term so be careful.
|
||||
# curl -fsSL "https://raw.githubusercontent.com/aqualinkd/AqualinkD/master/release/remote_install.sh" | ( sudo bash && exit 0 ) || exit $?
|
||||
|
||||
REQUIRED_SPACE_MB=18 # Need 17MB, use 18
|
||||
|
||||
TRUE=0
|
||||
FALSE=1
|
||||
|
||||
REPO="https://api.github.com/repos/AqualinkD/AqualinkD"
|
||||
#REPO="https://api.github.com/repos/sfeakes/AqualinkD"
|
||||
|
||||
INSTALLED_BINARY="/usr/local/bin/aqualinkd"
|
||||
|
||||
# Can't use $0 since this script is usually piped into bash
|
||||
SELF="remote_install.sh"
|
||||
|
||||
REL_VERSION=""
|
||||
DEV_VERSION=""
|
||||
INSTALLED_VERSION=""
|
||||
|
||||
TEMP_INSTALL="/tmp/aqualinkd"
|
||||
OUTPUT="/tmp/aqualinkd_upgrade.log"
|
||||
|
||||
FROM_CURL=$FASE
|
||||
|
||||
# Remember not to use (check for terminal, as it may not exist when pipe to bash)
|
||||
# ie. if [ -t 0 ]; then
|
||||
|
||||
if command -v "systemd-cat" &>/dev/null; then SYSTEMD_LOG=$TRUE;fi
|
||||
|
||||
log()
|
||||
{
|
||||
echo "$*"
|
||||
if [[ $SYSTEMD_LOG -eq $TRUE ]]; then
|
||||
echo "Upgrade: $*" | systemd-cat -t aqualinkd -p info
|
||||
else
|
||||
logger -p local0.notice -t aqualinkd "Upgrade: $*"
|
||||
fi
|
||||
echo "$*" 2>/dev/null >> "$OUTPUT"
|
||||
}
|
||||
|
||||
logerr()
|
||||
{
|
||||
echo "Error: $*" >&2
|
||||
|
||||
if [[ $SYSTEMD_LOG -eq $TRUE ]]; then
|
||||
echo "Upgrade: $*" | systemd-cat -t aqualinkd -p err
|
||||
else
|
||||
logger -p local0.error -t aqualinkd "Upgrade: $*"
|
||||
fi
|
||||
|
||||
echo "ERROR: $*" 2>/dev/null >> "$OUTPUT"
|
||||
}
|
||||
|
||||
|
||||
function check_tool() {
|
||||
cmd=$1
|
||||
if ! command -v "$cmd" &>/dev/null
|
||||
then
|
||||
log "Command '$cmd' could not be found!"
|
||||
return "$FALSE"
|
||||
fi
|
||||
|
||||
return "$TRUE"
|
||||
}
|
||||
|
||||
function latest_release_version {
|
||||
REL_VERSION=$(curl -fsSL "$REPO/releases/latest" | grep -Po '"tag_name": "\K.*?(?=")')
|
||||
if [[ "$REL_VERSION" != "" ]]; then
|
||||
return "$TRUE"
|
||||
else
|
||||
return "$FALSE"
|
||||
fi
|
||||
}
|
||||
|
||||
function latest_development_version {
|
||||
#DEV_VERSION=$(curl --silent -L "https://raw.githubusercontent.com/sfeakes/AqualinkD/master/version.h" | grep AQUALINKD_VERSION | cut -d '"' -f 2)
|
||||
DEV_VERSION=$(curl -fsSL -H "Accept: application/vnd.github.raw" "$REPO/contents/source/version.h" | grep AQUALINKD_VERSION | cut -d '"' -f 2)
|
||||
if [[ "$DEV_VERSION" != "" ]]; then
|
||||
return "$TRUE"
|
||||
else
|
||||
return "$FALSE"
|
||||
fi
|
||||
}
|
||||
|
||||
function installed_version {
|
||||
if [ -f "$INSTALLED_BINARY" ]; then
|
||||
if check_tool strings &&
|
||||
check_tool grep &&
|
||||
check_tool awk &&
|
||||
check_tool tr; then
|
||||
INSTALLED_VERSION=$(strings "$INSTALLED_BINARY" | grep sw_version | awk -v RS="," -v FS=":" '/sw_version/{print $2;exit;}' | tr -d ' "' )
|
||||
log "Current installed version $INSTALLED_VERSION"
|
||||
fi
|
||||
else
|
||||
log "AqualinkD is not installed"
|
||||
fi
|
||||
|
||||
if [[ "$INSTALLED_VERSION" != "" ]]; then
|
||||
return "$TRUE"
|
||||
else
|
||||
return "$FALSE"
|
||||
fi
|
||||
}
|
||||
|
||||
function check_system_arch {
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
|
||||
case $ARCH in
|
||||
arm64 |\
|
||||
armhf)
|
||||
return "$TRUE"
|
||||
;;
|
||||
*)
|
||||
logerr "System arch is $ARCH, this is not supported by AqualinkD"
|
||||
return "$FALSE";
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
function check_can_upgrade {
|
||||
#version=$1
|
||||
output=""
|
||||
# Check we have needed commands.
|
||||
# curl, dpkg, systemctl
|
||||
if ! command -v curl &>/dev/null; then output+="Command 'curl' not found, please check it's installed and in path\n"; fi
|
||||
if ! command -v dpkg &>/dev/null; then output+="Command 'dpkg' not found, please check it's installed and in path\n"; fi
|
||||
if ! command -v systemctl &>/dev/null; then output+="Command 'systemctl' not found, please check it's installed and in path\n"; fi
|
||||
|
||||
# Check root is rw
|
||||
if mount | grep " / " | grep -q "(ro,"; then
|
||||
# check if can remount rw.
|
||||
if mount / -o remount,rw &>/dev/null; then
|
||||
# can mount RW.
|
||||
mount / -o remount,ro &>/dev/null
|
||||
else
|
||||
output+="Root filesystem is readonly & failed to remount read write, can't upgrade";
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check we can get the latest version
|
||||
if ! latest_release_version; then output+="Couldn't find latest version on github"; fi
|
||||
|
||||
# Check we can get the latest version
|
||||
if command -v dpkg &>/dev/null; then
|
||||
if ! check_system_arch; then output+="System Architecture not supported!"; fi
|
||||
fi
|
||||
|
||||
# Check free diskspace
|
||||
mkdir -p "$TEMP_INSTALL"
|
||||
free_space_mb=$(df -mP "$TEMP_INSTALL" 2>/dev/null | awk 'NR==2{print $4}' )
|
||||
|
||||
# Check if the df command was successful and if free_space_mb is a number
|
||||
if [ -z "$free_space_mb" ] || ! [[ "$free_space_mb" =~ ^[0-9]+$ ]]; then
|
||||
output+="Could not retrieve free space for directory: $TEMP_INSTALL"
|
||||
else
|
||||
if [ "$free_space_mb" -lt "$REQUIRED_SPACE_MB" ]; then
|
||||
output+="Not enough disk space on directory: $TEMP_INSTALL! (Required $REQUIRED_SPACE_MB MB)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$output" == "" ]] && [[ "$REL_VERSION" != "" ]]; then
|
||||
return "$TRUE"
|
||||
else [[ "$output" != "" ]]
|
||||
logerr "$output";
|
||||
return "$FALSE"
|
||||
fi
|
||||
|
||||
return "$TRUE"
|
||||
}
|
||||
|
||||
|
||||
function download_latest_release {
|
||||
mkdir -p "$TEMP_INSTALL"
|
||||
tar_url=$(curl -fsSL "$REPO/releases/latest" | grep -Po '"tarball_url": "\K.*?(?=")')
|
||||
if [[ "$tar_url" == "" ]]; then return "$FALSE"; fi
|
||||
|
||||
curl -fsSL "$tar_url" | tar xz --strip-components=1 --directory="$TEMP_INSTALL"
|
||||
if [ $? -ne 0 ]; then return "$FALSE"; fi
|
||||
|
||||
return "$TRUE";
|
||||
}
|
||||
|
||||
function download_latest_development {
|
||||
mkdir -p "$TEMP_INSTALL"
|
||||
tar_url="$REPO/tarball/master"
|
||||
curl -fsSL "$tar_url" | tar xz --strip-components=1 --directory="$TEMP_INSTALL"
|
||||
if [ $? -ne 0 ]; then return "$FALSE"; fi
|
||||
|
||||
return "$TRUE";
|
||||
}
|
||||
|
||||
function download_version {
|
||||
tar_url=$(curl -fsSL "$REPO/releases" | awk 'match($0,/.*"tarball_url": "(.*\/tarball\/.*)".*/)' | grep $1\" | awk -F '"' '{print $4}')
|
||||
if [[ ! -n "$tar_url" ]]; then
|
||||
return $"$FALSE"
|
||||
fi
|
||||
|
||||
mkdir -p "$TEMP_INSTALL"
|
||||
curl -fsSL "$tar_url" | tar xz --strip-components=1 --directory="$TEMP_INSTALL"
|
||||
if [ $? -ne 0 ]; then return "$FALSE"; fi
|
||||
|
||||
return "$TRUE";
|
||||
}
|
||||
|
||||
function get_all_versions {
|
||||
curl -fsSL "$REPO/releases" | awk 'match($0,/.*"tarball_url": "(.*\/tarball\/.*)".*/)' | awk -F '/' '{split($NF,a,"\""); print a[1]}'
|
||||
}
|
||||
|
||||
function run_install_script {
|
||||
if [ ! -f "$TEMP_INSTALL/release/install.sh" ]; then
|
||||
logerr "Can not find install script $TEMP_INSTALL/release/install.sh"
|
||||
return "$FALSE"
|
||||
fi
|
||||
|
||||
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"
|
||||
|
||||
#nohup "/nas/data/Development/Raspberry/AqualinkD/release/install.sh" >> "$OUTPUT" 2>&1 &
|
||||
#nohup "$TEMP_INSTALL/release/install.sh" >> "$OUTPUT" 2>&1 &
|
||||
}
|
||||
|
||||
function remove_install {
|
||||
curl -fsSL -H "Accept: application/vnd.github.raw+json" "$REPO/contents/install/install.sh" | sudo bash clean
|
||||
}
|
||||
|
||||
function cleanup {
|
||||
rm -rf "$TEMP_INSTALL"
|
||||
}
|
||||
|
||||
|
||||
####################################################
|
||||
#
|
||||
# Main
|
||||
#
|
||||
|
||||
|
||||
# See if we are called from curl ot local dir.
|
||||
# with curl no tty input and script name wil be blank.
|
||||
if ! tty > /dev/null 2>&1; then
|
||||
script=$(basename "$0")
|
||||
if [ "$script" == "bash" ] || [ "$script" == "" ]; then
|
||||
#echo "$(basename "$0") Script is likely running from curl"
|
||||
# We don't actualy use this, but may in the future to leave it here
|
||||
FROM_CURL=$TRUE
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
logerr "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#if [ ! -t 0 ]; then
|
||||
#Don't use log function here as we will cleanout the file if it exists.
|
||||
# Can't use $0 below as this script might be piped into bash from curl
|
||||
echo "$SELF - $(date) " 2>/dev/null > "$OUTPUT"
|
||||
#fi
|
||||
|
||||
if check_can_upgrade; then
|
||||
installed_version
|
||||
if [[ "$INSTALLED_VERSION" != "" ]]; then
|
||||
log "Current AqualinkD installation $INSTALLED_VERSION"
|
||||
log "System OK to upgrade AqualinkD to $REL_VERSION"
|
||||
else
|
||||
log "System OK to install AqualinkD $REL_VERSION"
|
||||
fi
|
||||
|
||||
#exit $TRUE;
|
||||
else
|
||||
logerr "Can not upgrade, Please fix error(s)!"
|
||||
exit $FALSE;
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
check|checkupgradable)
|
||||
# We have already done the check, and returned false at this point, so return true.
|
||||
exit $TRUE
|
||||
;;
|
||||
development)
|
||||
if ! latest_development_version; then logerr "getting development version";exit "$FALSE"; fi
|
||||
if ! download_latest_development; then logerr "downloading latest development";exit "$FALSE"; fi
|
||||
run_install_script "$REL_VERSION"
|
||||
cleanup
|
||||
;;
|
||||
# Add Delete / remove / clean.
|
||||
clean|delete|remove)
|
||||
if ! remove_install; then logerr "Removing install";exit "$FALSE"; fi
|
||||
log "Removed install"
|
||||
;;
|
||||
list|versions)
|
||||
get_all_versions
|
||||
;;
|
||||
v*)
|
||||
if ! download_version $1; then logerr "downloading version $1";exit "$FALSE"; fi
|
||||
run_install_script "$REL_VERSION"
|
||||
cleanup
|
||||
;;
|
||||
-h|help|h)
|
||||
echo "AqualinkD Installation script"
|
||||
echo "$SELF <- download and install latest AqualinkD version"
|
||||
echo "$SELF latest <- download and install latest AqualinkD version"
|
||||
echo "$SELF development <- download and install latest AqualinkD development version"
|
||||
echo "$SELF clean <- Remove AqualinkD"
|
||||
echo "$SELF list <- List available versions to install"
|
||||
echo "$SELF v1.0.0 <- install AqualinkD v1.0.0 (use list option to see available versions)"
|
||||
;;
|
||||
latest|*)
|
||||
if ! download_latest_release; then logerr "downloading latest"; exit "$FALSE"; fi
|
||||
run_install_script "$REL_VERSION"
|
||||
cleanup
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
exit
|
||||
|
||||
|
||||
# List all versions
|
||||
# curl -fsSL https://api.github.com/repos/sfeakes/aqualinkd/releases | awk 'match($0,/.*"html_url": "(.*\/releases\/tag\/.*)".*/)'
|
||||
# curl -fsSL "https://api.github.com/repos/sfeakes/AqualinkD/releases" | awk 'match($0,/.*"tarball_url": "(.*\/tarball\/.*)".*/)' | awk -F '"' '{print $4}'
|
|
@ -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
|
||||
|
||||
|
@ -1632,7 +1632,8 @@ void check_print_config (struct aqualinkdata *aqdata)
|
|||
break;
|
||||
}
|
||||
}
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Config error, couldn't find button `%s` from config option `%s`\n",_aqconfig_.sched_chk_booston_device,CFG_N_event_check_booston_device);
|
||||
if (i >= aqdata->total_buttons)
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Config error, couldn't find button `%s` from config option `%s`\n",_aqconfig_.sched_chk_booston_device,CFG_N_event_check_booston_device);
|
||||
} else {
|
||||
aqdata->boost_linked_device = AQ_UNKNOWN;
|
||||
}
|
||||
|
|
|
@ -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.3"
|
||||
|
|
|
@ -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'];
|
||||
}
|
||||
|
@ -1326,16 +1339,38 @@
|
|||
}
|
||||
|
||||
function setAqManagerOptions(data) {
|
||||
|
||||
/*
|
||||
read deamonized logging2file logfilename debugmasks[] loglevels[]
|
||||
if logfilename=NULL we can turn on/off logging to file.
|
||||
logging2file will tell us if it's currently on or off
|
||||
*/
|
||||
try{
|
||||
document.getElementById("aqualinkdversion").innerHTML = data['aqualinkd_version'];
|
||||
} catch (e){}
|
||||
|
||||
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 +1381,8 @@
|
|||
}, 10000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if (data['logfilename'] == "(null)")
|
||||
enabletoggle("logfile");
|
||||
|
@ -1517,7 +1554,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 +1581,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 +1624,16 @@
|
|||
var cmd = {};
|
||||
//cmd.uri = "rawcommand"
|
||||
switch (source.id) {
|
||||
case "upgrade":
|
||||
if (confirm("Are you sure you want to proceed upgrading AqualinkD?")) {
|
||||
console.log("Upgrading");
|
||||
update_log_message("***** AqualinkD upgrade in progress *****");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
cmd.uri = "upgrade"
|
||||
// NEED TO REGET aqmanager after restart.
|
||||
break;
|
||||
case "restart":
|
||||
cmd.uri = "restart"
|
||||
// NEED TO REGET aqmanager after restart.
|
||||
|
@ -1640,7 +1708,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