From da7616e33be6db907c12595ff6c40a284229da46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 22:38:58 +0000 Subject: [PATCH 01/20] Bump the all-actions group with 2 updates Bumps the all-actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [softprops/action-gh-release](https://github.com/softprops/action-gh-release). Updates `actions/checkout` from 5.0.1 to 6.0.0 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5.0.1...v6.0.0) Updates `softprops/action-gh-release` from 2.4.2 to 2.5.0 - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/v2.4.2...v2.5.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: all-actions - dependency-name: softprops/action-gh-release dependency-version: 2.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/Create-NewReleases.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Create-NewReleases.yml b/.github/workflows/Create-NewReleases.yml index 7f869a8..ada7798 100644 --- a/.github/workflows/Create-NewReleases.yml +++ b/.github/workflows/Create-NewReleases.yml @@ -19,7 +19,7 @@ jobs: steps: # 1--- Check out master so we tag the exact merge commit - name: Checkout source code - uses: actions/checkout@v5.0.1 + uses: actions/checkout@v6.0.0 with: fetch-depth: 0 ref: 'master' @@ -97,7 +97,7 @@ jobs: # 7--- Publish a GitHub Release with auto-generated notes - name: Create Release with Automated Release Notes - uses: softprops/action-gh-release@v2.4.2 + uses: softprops/action-gh-release@v2.5.0 with: token: ${{ secrets.GITHUB_TOKEN }} tag_name: ${{ steps.nextver.outputs.tag }} From 5cfc3e7303af9625d8ac5aee8fac8f49a93021fd Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Tue, 2 Dec 2025 01:44:45 -0800 Subject: [PATCH 02/20] Fixed Message for Default Minutes Fixed message for default minutes to 5. Functionality is actually correct. This is just a message/cosmetic change. --- README.md | 4 ++-- connmon.sh | 6 +++--- connmonstats_www.asp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9ea4dd4..7672f58 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # connmon -## v3.0.9 -### Updated on 2025-Nov-27 +## v3.0.10 +### Updated on 2025-Dec-02 ## About connmon is an internet connection monitoring tool for AsusWRT Merlin with charts for daily, weekly and monthly summaries. diff --git a/connmon.sh b/connmon.sh index 4ddf390..ad6be93 100644 --- a/connmon.sh +++ b/connmon.sh @@ -11,7 +11,7 @@ ## Forked from https://github.com/jackyaz/connmon ## ## ## ############################################################## -# Last Modified: 2025-Nov-27 +# Last Modified: 2025-Dec-02 #------------------------------------------------------------- ############## Shellcheck directives ############# @@ -36,8 +36,8 @@ ### Start of script variables ### readonly SCRIPT_NAME="connmon" -readonly SCRIPT_VERSION="v3.0.9" -readonly SCRIPT_VERSTAG="25112700" +readonly SCRIPT_VERSION="v3.0.10" +readonly SCRIPT_VERSTAG="25120200" SCRIPT_BRANCH="develop" SCRIPT_REPO="https://raw.githubusercontent.com/AMTM-OSR/$SCRIPT_NAME/$SCRIPT_BRANCH" readonly SCRIPT_DIR="/jffs/addons/$SCRIPT_NAME.d" diff --git a/connmonstats_www.asp b/connmonstats_www.asp index 3ffa5a3..f05efc9 100644 --- a/connmonstats_www.asp +++ b/connmonstats_www.asp @@ -33,7 +33,7 @@ p{font-weight:bolder}thead.collapsible-jquery{color:#fff;padding:0;width:100%;bo @@ -1389,32 +1389,30 @@ function getCookie(e,t){if(null!==cookie.get("conn_"+e)){if("string"===t)return src="images/InternetScan.gif" /> - - Pushover API Token - - - - - - Pushover User Key - - - - + + Pushover User Key + + + + + + Pushover API Token + + + + List of devices to send Pushovers to
- - InfluxDB API Token
(v2.x only) - - - - + + InfluxDB API Token
(v2.x only) + + + +
 
Date: Mon, 8 Dec 2025 09:18:21 -0800 Subject: [PATCH 06/20] Code Improvements Added code to capture and display errors from the curl command sent when testing/sending notifications using the InfluxDB setup. --- README.md | 2 +- connmon.sh | 49 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a5191d1..187e801 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # connmon ## v3.0.10 -### Updated on 2025-Dec-07 +### Updated on 2025-Dec-08 ## About connmon is an internet connection monitoring tool for AsusWRT Merlin with charts for daily, weekly and monthly summaries. diff --git a/connmon.sh b/connmon.sh index aad7196..fd5668f 100644 --- a/connmon.sh +++ b/connmon.sh @@ -11,7 +11,7 @@ ## Forked from https://github.com/jackyaz/connmon ## ## ## ############################################################## -# Last Modified: 2025-Dec-07 +# Last Modified: 2025-Dec-08 #------------------------------------------------------------- ############## Shellcheck directives ############# @@ -37,7 +37,7 @@ ### Start of script variables ### readonly SCRIPT_NAME="connmon" readonly SCRIPT_VERSION="v3.0.10" -readonly SCRIPT_VERSTAG="25120718" +readonly SCRIPT_VERSTAG="25120808" SCRIPT_BRANCH="develop" SCRIPT_REPO="https://raw.githubusercontent.com/AMTM-OSR/$SCRIPT_NAME/$SCRIPT_BRANCH" readonly SCRIPT_DIR="/jffs/addons/$SCRIPT_NAME.d" @@ -117,6 +117,8 @@ readonly PassBGRNct="\e[30;102m" readonly WarnBYLWct="\e[30;103m" readonly WarnIMGNct="\e[45m" readonly WarnBMGNct="\e[30;105m" +isInteractive=false +[ -t 0 ] && ! tty | grep -qwi "NOT" && isInteractive=true ### End of output format variables ### @@ -3335,8 +3337,13 @@ SendHealthcheckPing() fi } +##----------------------------------------## +## Modified by Martinski W. [2025-Dec-08] ## +##----------------------------------------## SendToInfluxDB() { + local curlCode tempLogFile="/tmp/var/tmp/temp_${SCRIPT_NAME}.LOG" + TIMESTAMP="$1" PING="$2" JITTER="$3" @@ -3346,29 +3353,43 @@ SendToInfluxDB() NOTIFICATIONS_INFLUXDB_DB="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_DB)" NOTIFICATIONS_INFLUXDB_VERSION="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_VERSION)" NOTIFICATIONS_INFLUXDB_PROTO="http" - if [ "$NOTIFICATIONS_INFLUXDB_PORT" = "443" ]; then + if [ "$NOTIFICATIONS_INFLUXDB_PORT" = "443" ] + then NOTIFICATIONS_INFLUXDB_PROTO="https" fi - if [ "$NOTIFICATIONS_INFLUXDB_VERSION" = "1.8" ]; then + if [ "$NOTIFICATIONS_INFLUXDB_VERSION" = "1.8" ] + then INFLUX_AUTHHEADER="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_USERNAME):$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_PASSWORD)" - elif [ "$NOTIFICATIONS_INFLUXDB_VERSION" = "2.0" ]; then + elif [ "$NOTIFICATIONS_INFLUXDB_VERSION" = "2.0" ] + then INFLUX_AUTHHEADER="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_APITOKEN)" fi + date +'%Y-%b-%d %a %I:%M:%S %p %Z' > "$tempLogFile" - curl -fsL --retry 4 --retry-delay 5 --output /dev/null -XPOST "$NOTIFICATIONS_INFLUXDB_PROTO://$NOTIFICATIONS_INFLUXDB_HOST:$NOTIFICATIONS_INFLUXDB_PORT/api/v2/write?bucket=$NOTIFICATIONS_INFLUXDB_DB&precision=s" \ ---header "Authorization: Token $INFLUX_AUTHHEADER" --header "Accept-Encoding: gzip" \ ---data-raw "ping value=$PING $TIMESTAMP + curl -v --retry 4 --retry-delay 5 --output /dev/null \ + -XPOST "$NOTIFICATIONS_INFLUXDB_PROTO://$NOTIFICATIONS_INFLUXDB_HOST:$NOTIFICATIONS_INFLUXDB_PORT/api/v2/write?bucket=$NOTIFICATIONS_INFLUXDB_DB&precision=s" \ + --header "Authorization: Token $INFLUX_AUTHHEADER" --header "Accept-Encoding: gzip" \ + --data-raw "ping value=$PING $TIMESTAMP jitter value=$JITTER $TIMESTAMP -linequality value=$LINEQUAL $TIMESTAMP" +linequality value=$LINEQUAL $TIMESTAMP" >> "$tempLogFile" 2>&1 + curlCode="$?" - if [ $? -eq 0 ]; then - echo "" + if [ "$curlCode" -eq 0 ] + then + echo Print_Output false "Data sent to InfluxDB successfully" "$PASS" + rm -f "$tempLogFile" return 0 else - echo "" - Print_Output true "Data failed to send to InfluxDB" "$ERR" + echo + Print_Output true "Data failed to send to InfluxDB [Code: $curlCode]" "$ERR" + if "$isInteractive" + then + echo "-------------------------------------------------------" + cat "$tempLogFile" + echo "-------------------------------------------------------" + fi return 1 fi } @@ -4252,7 +4273,7 @@ Menu_InfluxDB() ;; cs) SendToInfluxDB "$(/bin/date +%s)" 30 15 90 - printf "\n" + echo PressEnter ;; e) From c840de06b741ab871506f2b2e860b2f77c1f0a7c Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Mon, 8 Dec 2025 11:11:06 -0800 Subject: [PATCH 07/20] Update connmon.sh Temporarily commented out line to delete temporary log file. --- connmon.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connmon.sh b/connmon.sh index fd5668f..2755dd2 100644 --- a/connmon.sh +++ b/connmon.sh @@ -37,7 +37,7 @@ ### Start of script variables ### readonly SCRIPT_NAME="connmon" readonly SCRIPT_VERSION="v3.0.10" -readonly SCRIPT_VERSTAG="25120808" +readonly SCRIPT_VERSTAG="25120811" SCRIPT_BRANCH="develop" SCRIPT_REPO="https://raw.githubusercontent.com/AMTM-OSR/$SCRIPT_NAME/$SCRIPT_BRANCH" readonly SCRIPT_DIR="/jffs/addons/$SCRIPT_NAME.d" @@ -3379,7 +3379,7 @@ linequality value=$LINEQUAL $TIMESTAMP" >> "$tempLogFile" 2>&1 then echo Print_Output false "Data sent to InfluxDB successfully" "$PASS" - rm -f "$tempLogFile" + ##TEMP-OFF## rm -f "$tempLogFile" ##TEMP-OFF## return 0 else echo From b78deba16d53ce5717b201d8d13ad73f174bdad5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 19:18:56 +0000 Subject: [PATCH 08/20] Bump actions/checkout from 6.0.0 to 6.0.1 in the all-actions group Bumps the all-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 6.0.0 to 6.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v6.0.0...v6.0.1) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/Create-NewReleases.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Create-NewReleases.yml b/.github/workflows/Create-NewReleases.yml index ada7798..4b78c3d 100644 --- a/.github/workflows/Create-NewReleases.yml +++ b/.github/workflows/Create-NewReleases.yml @@ -19,7 +19,7 @@ jobs: steps: # 1--- Check out master so we tag the exact merge commit - name: Checkout source code - uses: actions/checkout@v6.0.0 + uses: actions/checkout@v6.0.1 with: fetch-depth: 0 ref: 'master' From 3548c8149af4a383b73188357d729ea523fd1768 Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Tue, 9 Dec 2025 03:48:39 -0800 Subject: [PATCH 09/20] Code Improvements Modified calls to the curl command to capture and display errors when testing/sending notifications. --- README.md | 2 +- connmon.sh | 462 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 304 insertions(+), 160 deletions(-) diff --git a/README.md b/README.md index 187e801..be81e5b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # connmon ## v3.0.10 -### Updated on 2025-Dec-08 +### Updated on 2025-Dec-09 ## About connmon is an internet connection monitoring tool for AsusWRT Merlin with charts for daily, weekly and monthly summaries. diff --git a/connmon.sh b/connmon.sh index 2755dd2..41692a5 100644 --- a/connmon.sh +++ b/connmon.sh @@ -11,7 +11,7 @@ ## Forked from https://github.com/jackyaz/connmon ## ## ## ############################################################## -# Last Modified: 2025-Dec-08 +# Last Modified: 2025-Dec-09 #------------------------------------------------------------- ############## Shellcheck directives ############# @@ -37,7 +37,7 @@ ### Start of script variables ### readonly SCRIPT_NAME="connmon" readonly SCRIPT_VERSION="v3.0.10" -readonly SCRIPT_VERSTAG="25120811" +readonly SCRIPT_VERSTAG="25120900" SCRIPT_BRANCH="develop" SCRIPT_REPO="https://raw.githubusercontent.com/AMTM-OSR/$SCRIPT_NAME/$SCRIPT_BRANCH" readonly SCRIPT_DIR="/jffs/addons/$SCRIPT_NAME.d" @@ -68,6 +68,13 @@ readonly ENDIN_MenuAddOnsTag="/\*\*ENDIN:_AddOns_\*\*/" readonly branchxStr_TAG="[Branch: $SCRIPT_BRANCH]" readonly versionDev_TAG="${SCRIPT_VERSION}_${SCRIPT_VERSTAG}" readonly versionMod_TAG="$SCRIPT_VERSION on $ROUTER_MODEL" +readonly dateTimeLogFormat='%Y-%b-%d %a %I:%M:%S %p %Z' +readonly curlErr1RegExp="invalid|error" +readonly curlErr2RegExp="404: Not Found|400 Bad Request" +readonly curlErr3RegExp="$curlErr1RegExp|$curlErr2RegExp" +readonly curlOutLogFile="/tmp/var/tmp/temp_${SCRIPT_NAME}_curl_OUT.LOG" +readonly curlErrLogFile="/tmp/var/tmp/temp_${SCRIPT_NAME}_curl_ERR.LOG" +readonly tmpCurlSEPstr="-------------------------------------------------------" # For daily CRON job to trim database # readonly defTrimDB_Hour=3 @@ -2747,8 +2754,14 @@ Shortcut_Script() esac } +##----------------------------------------## +## Modified by Martinski W. [2025-Dec-08] ## +##----------------------------------------## PressEnter() { + if ! "$isInteractive" + then return 0 + fi while true do printf "Press key to continue..." @@ -2827,23 +2840,28 @@ Email_EmailAddress() EMAIL_ADDRESS="" while true do - printf "\\n${BOLD}Enter email address:${CLEARFORMAT} " + printf "\n${BOLD}Enter email address:${CLEARFORMAT} " read -r EMAIL_ADDRESS - if [ "$EMAIL_ADDRESS" = "e" ]; then + if [ "$EMAIL_ADDRESS" = "e" ] + then EMAIL_ADDRESS="" break - elif ! echo "$EMAIL_ADDRESS" | grep -qE "$EMAIL_REGEX"; then - printf "\\n${ERR}Please enter a valid email address${CLEARFORMAT}\\n" + elif ! echo "$EMAIL_ADDRESS" | grep -qE "$EMAIL_REGEX" + then + printf "\n${ERR}Please enter a valid email address${CLEARFORMAT}\n" else printf "${BOLD}${WARN}Is this correct? (y/n):${CLEARFORMAT} " read -r CONFIRM_INPUT case "$CONFIRM_INPUT" in y|Y) - if [ "$1" = "From" ]; then + if [ "$1" = "From" ] + then sed -i 's/^FROM_ADDRESS=.*$/FROM_ADDRESS="'"$EMAIL_ADDRESS"'"/' "$EMAIL_CONF" - elif [ "$1" = "To" ]; then + elif [ "$1" = "To" ] + then sed -i 's/^TO_ADDRESS=.*$/TO_ADDRESS="'"$EMAIL_ADDRESS"'"/' "$EMAIL_CONF" - elif [ "$1" = "Override" ]; then + elif [ "$1" = "Override" ] + then NOTIFICATIONS_EMAIL_LIST="$(Email_Recipients check),$EMAIL_ADDRESS" NOTIFICATIONS_EMAIL_LIST="$(echo "$NOTIFICATIONS_EMAIL_LIST" | sed 's/,,/,/g;s/,$//;s/^,//')" sed -i 's/^NOTIFICATIONS_EMAIL_LIST=.*$/NOTIFICATIONS_EMAIL_LIST='"$NOTIFICATIONS_EMAIL_LIST"'/' "$SCRIPT_CONF" @@ -2865,16 +2883,21 @@ Email_RouterName() do printf "\\n${BOLD}Enter friendly router name:${CLEARFORMAT} " read -r FRIENDLY_ROUTER_NAME - if [ "$FRIENDLY_ROUTER_NAME" = "e" ]; then + if [ "$FRIENDLY_ROUTER_NAME" = "e" ] + then FRIENDLY_ROUTER_NAME="" break - elif [ "$(printf "%s" "$FRIENDLY_ROUTER_NAME" | wc -m)" -lt 2 ] || [ "$(printf "%s" "$FRIENDLY_ROUTER_NAME" | wc -m)" -gt 16 ]; then + elif [ "$(printf "%s" "$FRIENDLY_ROUTER_NAME" | wc -m)" -lt 2 ] || [ "$(printf "%s" "$FRIENDLY_ROUTER_NAME" | wc -m)" -gt 16 ] + then printf "\\n${ERR}Router friendly name must be between 2 and 16 characters${CLEARFORMAT}\\n" - elif echo "$FRIENDLY_ROUTER_NAME" | grep -q "^-" || echo "$FRIENDLY_ROUTER_NAME" | grep -q "^_"; then + elif echo "$FRIENDLY_ROUTER_NAME" | grep -q "^-" || echo "$FRIENDLY_ROUTER_NAME" | grep -q "^_" + then printf "\\n${ERR}Router friendly name must not start with dash (-) or underscore (_)${CLEARFORMAT}\\n" - elif echo "$FRIENDLY_ROUTER_NAME" | grep -q "[-]$" || echo "$FRIENDLY_ROUTER_NAME" | grep -q "_$"; then + elif echo "$FRIENDLY_ROUTER_NAME" | grep -q "[-]$" || echo "$FRIENDLY_ROUTER_NAME" | grep -q "_$" + then printf "\\n${ERR}Router friendly name must not end with dash (-) or underscore (_)${CLEARFORMAT}\\n" - elif ! echo "$FRIENDLY_ROUTER_NAME" | grep -qE "^[a-zA-Z0-9_\-]*$"; then + elif ! echo "$FRIENDLY_ROUTER_NAME" | grep -qE "^[a-zA-Z0-9_\-]*$" + then printf "\\n${ERR}Router friendly name must not contain special characters other than dash (-) or underscore (_)${CLEARFORMAT}\\n" else printf "${BOLD}${WARN}Is this correct? (y/n):${CLEARFORMAT} " @@ -2892,15 +2915,19 @@ Email_RouterName() done } -Email_Server(){ +Email_Server() +{ SMTP="" - while true; do + while true + do printf "\\n${BOLD}Enter SMTP Server:${CLEARFORMAT} " read -r SMTP - if [ "$SMTP" = "e" ]; then + if [ "$SMTP" = "e" ] + then SMTP="" break - elif ! Validate_Domain "$SMTP"; then + elif ! Validate_Domain "$SMTP" + then printf "\\n${ERR}Domain cannot be resolved by nslookup, please ensure you enter a valid domain name${CLEARFORMAT}\\n" else printf "${BOLD}${WARN}Is this correct? (y/n):${CLEARFORMAT} " @@ -2918,8 +2945,10 @@ Email_Server(){ done } -Email_Protocol(){ - while true; do +Email_Protocol() +{ + while true + do printf "\\n${BOLD}Please choose the protocol for your email provider:${CLEARFORMAT}\\n" printf " 1. smtp\\n" printf " 2. smtps\\n\\n" @@ -2948,7 +2977,8 @@ Email_Protocol(){ Email_SSL() { SSL_FLAG="" - while true; do + while true + do printf "\\n${BOLD}Please choose the SSL security level:${CLEARFORMAT}\\n" printf " 1. Secure (recommended)\\n" printf " 2. Insecure (choose this if you see SSL errors)\\n\\n" @@ -2978,10 +3008,12 @@ Email_SSL() Email_Password() { PASSWORD="" - while true; do + while true + do printf "\\n${BOLD}Enter Password:${CLEARFORMAT} " read -r PASSWORD - if [ "$PASSWORD" = "e" ]; then + if [ "$PASSWORD" = "e" ] + then PASSWORD="" break else @@ -3005,7 +3037,8 @@ Email_Encrypt_Password() { PWENCFILE="$EMAIL_DIR/emailpw.enc" emailPwEnc="$(grep "emailPwEnc=" "$EMAIL_CONF" | cut -f2 -d"=" | sed 's/""//')" - if [ -f /usr/sbin/openssl11 ]; then + if [ -f /usr/sbin/openssl11 ] + then printf "$1" | /usr/sbin/openssl11 aes-256-cbc $emailPwEnc -out "$PWENCFILE" -pass pass:ditbabot,isoi else printf "$1" | /usr/sbin/openssl aes-256-cbc $emailPwEnc -out "$PWENCFILE" -pass pass:ditbabot,isoi @@ -3015,13 +3048,16 @@ Email_Encrypt_Password() Email_Decrypt_Password() { PWENCFILE="$EMAIL_DIR/emailpw.enc" - if /usr/sbin/openssl aes-256-cbc -d -in "$PWENCFILE" -pass pass:ditbabot,isoi >/dev/null 2>&1 ; then + if /usr/sbin/openssl aes-256-cbc -d -in "$PWENCFILE" -pass pass:ditbabot,isoi >/dev/null 2>&1 + then # old OpenSSL 1.0.x PASSWORD="$(/usr/sbin/openssl aes-256-cbc -d -in "$PWENCFILE" -pass pass:ditbabot,isoi 2>/dev/null)" - elif /usr/sbin/openssl aes-256-cbc -d -md md5 -in "$PWENCFILE" -pass pass:ditbabot,isoi >/dev/null 2>&1 ; then + elif /usr/sbin/openssl aes-256-cbc -d -md md5 -in "$PWENCFILE" -pass pass:ditbabot,isoi >/dev/null 2>&1 + then # new OpenSSL 1.1.x non-converted password PASSWORD="$(/usr/sbin/openssl aes-256-cbc -d -md md5 -in "$PWENCFILE" -pass pass:ditbabot,isoi 2>/dev/null)" - elif /usr/sbin/openssl aes-256-cbc $emailPwEnc -d -in "$PWENCFILE" -pass pass:ditbabot,isoi >/dev/null 2>&1 ; then + elif /usr/sbin/openssl aes-256-cbc $emailPwEnc -d -in "$PWENCFILE" -pass pass:ditbabot,isoi >/dev/null 2>&1 + then # new OpenSSL 1.1.x converted password with -pbkdf2 flag PASSWORD="$(/usr/sbin/openssl aes-256-cbc $emailPwEnc -d -in "$PWENCFILE" -pass pass:ditbabot,isoi 2>/dev/null)" fi @@ -3032,12 +3068,14 @@ Email_Recipients() { case "$1" in update) - while true; do + while true + do ScriptHeader printf "${BOLD}${UNDERLINE}Email Recipients Override List${CLEARFORMAT}\\n\\n" NOTIFICATIONS_EMAIL_LIST="$(Email_Recipients check)" - if [ "$NOTIFICATIONS_EMAIL_LIST" = "" ]; then + if [ "$NOTIFICATIONS_EMAIL_LIST" = "" ] + then NOTIFICATIONS_EMAIL_LIST="Generic To Address will be used" fi printf "Currently: ${SETTING}${NOTIFICATIONS_EMAIL_LIST}${CLEARFORMAT}\\n\\n" @@ -3105,97 +3143,101 @@ Encode_Text() } >> "$3" } +##----------------------------------------## +## Modified by Martinski W. [2025-Dec-08] ## +##----------------------------------------## SendEmail() { - if ! Email_ConfExists; then - return 1 - else - EMAILSUBJECT="$1" - EMAILCONTENTS="$2" - if [ -n "$3" ]; then - TO_ADDRESS="$3" - fi - if [ -z "$TO_ADDRESS" ]; then - Print_Output false "No email recipient specified" "$ERR" - return 1 - fi + if ! Email_ConfExists + then return 1 + fi - # html message to send # - { - echo "From: \"connmon\" <$FROM_ADDRESS>" - echo "To: \"$TO_ADDRESS\" <$TO_ADDRESS>" - echo "Subject: $EMAILSUBJECT" - echo "Date: $(/bin/date -R)" - echo "MIME-Version: 1.0" - echo "Content-Type: multipart/mixed; boundary=\"MULTIPART-MIXED-BOUNDARY\"" - echo "" - echo "--MULTIPART-MIXED-BOUNDARY" - echo "Content-Type: multipart/related; boundary=\"MULTIPART-RELATED-BOUNDARY\"" - echo "" - echo "--MULTIPART-RELATED-BOUNDARY" - echo "Content-Type: multipart/alternative; boundary=\"MULTIPART-ALTERNATIVE-BOUNDARY\"" - } > /tmp/mail.txt + local curlCode + EMAIL_SUBJECT="$1" + EMAIL_CONTENTS="$2" + if [ $# -gt 2 ] && [ -n "$3" ] + then + TO_ADDRESS="$3" + fi + if [ -z "$TO_ADDRESS" ] + then + Print_Output false "No email recipient specified" "$ERR" + return 1 + fi - #echo "

$2" > /tmp/message.html - echo "$EMAILCONTENTS" > /tmp/message.html + # html message to send # + { + echo "From: \"connmon\" <$FROM_ADDRESS>" + echo "To: \"$TO_ADDRESS\" <$TO_ADDRESS>" + echo "Subject: $EMAIL_SUBJECT" + echo "Date: $(/bin/date -R)" + echo "MIME-Version: 1.0" + echo "Content-Type: multipart/mixed; boundary=\"MULTIPART-MIXED-BOUNDARY\"" + echo "" + echo "--MULTIPART-MIXED-BOUNDARY" + echo "Content-Type: multipart/related; boundary=\"MULTIPART-RELATED-BOUNDARY\"" + echo "" + echo "--MULTIPART-RELATED-BOUNDARY" + echo "Content-Type: multipart/alternative; boundary=\"MULTIPART-ALTERNATIVE-BOUNDARY\"" + } > /tmp/mail.txt - echo "" >> /tmp/message.html + ##echo "

$2" > /tmp/message.html + echo "$EMAIL_CONTENTS" > /tmp/message.html - message_base64="$(openssl base64 -A < /tmp/message.html)" - rm -f /tmp/message.html + echo "" >> /tmp/message.html - { - echo "" - echo "--MULTIPART-ALTERNATIVE-BOUNDARY" - echo "Content-Type: text/html; charset=utf-8" - echo "Content-Transfer-Encoding: base64" - echo "" - echo "$message_base64" - echo "" - echo "--MULTIPART-ALTERNATIVE-BOUNDARY--" - echo "" - } >> /tmp/mail.txt + message_base64="$(openssl base64 -A < /tmp/message.html)" + rm -f /tmp/message.html - #image_base64="$(openssl base64 -A < "connmonlogo.png")" - #Encode_Image "connmonlogo.png" "$image_base64" /tmp/mail.txt + { + echo "" + echo "--MULTIPART-ALTERNATIVE-BOUNDARY" + echo "Content-Type: text/html; charset=utf-8" + echo "Content-Transfer-Encoding: base64" + echo "" + echo "$message_base64" + echo "" + echo "--MULTIPART-ALTERNATIVE-BOUNDARY--" + echo "" + } >> /tmp/mail.txt - #Encode_Text vnstat.txt "$(cat "$VNSTAT_OUTPUT_FILE")" /tmp/mail.txt + ##image_base64="$(openssl base64 -A < "connmonlogo.png")" + ##Encode_Image "connmonlogo.png" "$image_base64" /tmp/mail.txt + ##Encode_Text vnstat.txt "$(cat "$VNSTAT_OUTPUT_FILE")" /tmp/mail.txt - { - echo "--MULTIPART-RELATED-BOUNDARY--" - echo "" - echo "--MULTIPART-MIXED-BOUNDARY--" - } >> /tmp/mail.txt + { + echo "--MULTIPART-RELATED-BOUNDARY--" + echo "" + echo "--MULTIPART-MIXED-BOUNDARY--" + } >> /tmp/mail.txt - PASSWORD="$(Email_Decrypt_Password)" + PASSWORD="$(Email_Decrypt_Password)" - curl -s --show-error --url "$PROTOCOL://$SMTP:$PORT" \ - --mail-from "$FROM_ADDRESS" --mail-rcpt "$TO_ADDRESS" \ - --upload-file /tmp/mail.txt \ - --ssl-reqd \ - --user "$USERNAME:$PASSWORD" $SSL_FLAG + curl -s --show-error --url "${PROTOCOL}://${SMTP}:$PORT" \ + --mail-from "$FROM_ADDRESS" --mail-rcpt "$TO_ADDRESS" \ + --upload-file /tmp/mail.txt --user "${USERNAME}:$PASSWORD" \ + $SSL_FLAG --ssl-reqd --crlf + curlCode="$?" - if [ $? -eq 0 ]; then - echo "" - Print_Output false "Email sent successfully" "$PASS" - rm -f /tmp/mail.txt - PASSWORD="" - return 0 - else - echo "" - Print_Output true "Email failed to send" "$ERR" - rm -f /tmp/mail.txt - PASSWORD="" - return 1 - fi + "$isInteractive" && echo + if [ "$curlCode" -eq 0 ] + then + Print_Output false "Email sent successfully" "$PASS" + else + Print_Output true "Email failed to send [Code: $curlCode]" "$ERR" fi + + PASSWORD="" + rm -f /tmp/mail.txt + return "$curlCode" } Webhook_Targets() { case "$1" in update) - while true; do + while true + do ScriptHeader printf "${BOLD}${UNDERLINE}Discord Webhook List${CLEARFORMAT}\\n\\n" @@ -3231,34 +3273,64 @@ Webhook_Targets() esac } +##----------------------------------------## +## Modified by Martinski W. [2025-Dec-08] ## +##----------------------------------------## SendWebhook() { - WEBHOOKCONTENT="$1" - WEBHOOKTARGET="$2" - if [ -z "$WEBHOOKTARGET" ]; then + local curlCode + WEBHOOK_CONTENT="$1" + WEBHOOK_TARGET="$2" + if [ -z "$WEBHOOK_TARGET" ] + then Print_Output false "No Webhook URL specified" "$ERR" return 1 fi + printf '' > "$curlOutLogFile" + printf '' > "$curlErrLogFile" - curl -fsL --retry 4 --retry-delay 5 --output /dev/null -H "Content-Type: application/json" \ --d '{"username":"'"$SCRIPT_NAME"'","content":"'"$WEBHOOKCONTENT"'"}' "$WEBHOOKTARGET" + curl -vSL --retry 4 --retry-delay 5 --connect-timeout 60 -o "$curlOutLogFile" \ +-H "Content-Type: application/json" \ +-d '{"username":"'"$SCRIPT_NAME"'","content":"'"$WEBHOOK_CONTENT"'"}' "$WEBHOOK_TARGET" >> "$curlErrLogFile" 2>&1 + curlCode="$?" - if [ $? -eq 0 ]; then - echo "" + "$isInteractive" && echo + if [ "$curlCode" -eq 0 ] && \ + ! grep -qiE "$curlErr2RegExp" "$curlOutLogFile" && \ + ! grep -qiE "$curlErr2RegExp" "$curlErrLogFile" + then Print_Output false "Webhook sent successfully" "$PASS" - return 0 + ##OFF## rm -f "$curlOutLogFile" "$curlErrLogFile" ##OFF## else - echo "" - Print_Output true "Webhook failed to send" "$ERR" - return 1 + [ "$curlCode" -eq 0 ] && curlCode=999 + Print_Output true "Webhook failed to send [Code: $curlCode]" "$ERR" + if "$isInteractive" && \ + { [ -s "$curlOutLogFile" ] || [ -s "$curlErrLogFile" ] ; } + then + PressEnter ; echo + echo "$tmpCurlSEPstr" + if [ -s "$curlOutLogFile" ] && \ + grep -qiE "$curlErr3RegExp" "$curlOutLogFile" + then + cat "$curlOutLogFile" ; echo + echo "$tmpCurlSEPstr" + fi + if [ -s "$curlErrLogFile" ] + then + cat "$curlErrLogFile" ; echo + echo "$tmpCurlSEPstr" + fi + fi fi + return "$curlCode" } Pushover_Devices() { case "$1" in update) - while true; do + while true + do ScriptHeader printf "${BOLD}${UNDERLINE}Pushover Device List${CLEARFORMAT}\\n\\n" @@ -3294,47 +3366,108 @@ Pushover_Devices() esac } +##----------------------------------------## +## Modified by Martinski W. [2025-Dec-08] ## +##----------------------------------------## SendPushover() { - PUSHOVERCONTENT="$1" + local curlCode + PUSHOVER_MSG="$1" PUSHOVER_API="$(Conf_Parameters check NOTIFICATIONS_PUSHOVER_API)" PUSHOVER_USERKEY="$(Conf_Parameters check NOTIFICATIONS_PUSHOVER_USERKEY)" - if [ -z "$PUSHOVER_API" ] || [ -z "$PUSHOVER_USERKEY" ]; then + if [ -z "$PUSHOVER_API" ] || [ -z "$PUSHOVER_USERKEY" ] + then Print_Output false "No Pushover API or UserKey specified" "$ERR" return 1 fi + printf '' > "$curlOutLogFile" + printf '' > "$curlErrLogFile" - curl -fsL --retry 4 --retry-delay 5 --output /dev/null --form-string "token=$PUSHOVER_API" \ ---form-string "user=$PUSHOVER_USERKEY" --form-string "message=$PUSHOVERCONTENT" https://api.pushover.net/1/messages.json + curl -vSL --retry 4 --retry-delay 5 --connect-timeout 60 -o "$curlOutLogFile" \ +--form-string "token=$PUSHOVER_API" \ +--form-string "user=$PUSHOVER_USERKEY" \ +--form-string "message=$PUSHOVER_MSG" https://api.pushover.net/1/messages.json >> "$curlErrLogFile" 2>&1 + curlCode="$?" - if [ $? -eq 0 ]; then - echo "" + "$isInteractive" && echo + if [ "$curlCode" -eq 0 ] && \ + ! grep -qiE "$curlErr2RegExp" "$curlOutLogFile" && \ + ! grep -qiE "$curlErr2RegExp" "$curlErrLogFile" + then Print_Output false "Pushover sent successfully" "$PASS" - return 0 + ##OFF## rm -f "$curlOutLogFile" "$curlErrLogFile" ##OFF## else - echo "" - Print_Output true "Pushover failed to send" "$ERR" - return 1 + [ "$curlCode" -eq 0 ] && curlCode=999 + Print_Output true "Pushover failed to send [Code: $curlCode]" "$ERR" + if "$isInteractive" && \ + { [ -s "$curlOutLogFile" ] || [ -s "$curlErrLogFile" ] ; } + then + PressEnter ; echo + echo "$tmpCurlSEPstr" + if [ -s "$curlOutLogFile" ] && \ + grep -qiE "$curlErr3RegExp" "$curlOutLogFile" + then + cat "$curlOutLogFile" ; echo + echo "$tmpCurlSEPstr" + fi + if [ -s "$curlErrLogFile" ] + then + cat "$curlErrLogFile" ; echo + echo "$tmpCurlSEPstr" + fi + fi fi + return "$curlCode" } +##----------------------------------------## +## Modified by Martinski W. [2025-Dec-08] ## +##----------------------------------------## SendHealthcheckPing() { - NOTIFICATIONS_HEALTHCHECK_UUID="$(Conf_Parameters check NOTIFICATIONS_HEALTHCHECK_UUID)" - TESTFAIL="" - if [ "$1" = "Fail" ]; then - TESTFAIL="/fail" + local curlCode + HEALTHCHECK_UUID="$(Conf_Parameters check NOTIFICATIONS_HEALTHCHECK_UUID)" + TEST_FAIL="" + if [ "$1" = "Fail" ] + then + TEST_FAIL="/fail" fi - curl -fsL --retry 4 --retry-delay 5 --output /dev/null "https://hc-ping.com/${NOTIFICATIONS_HEALTHCHECK_UUID}${TESTFAIL}" - if [ $? -eq 0 ]; then - echo "" + printf '' > "$curlOutLogFile" + printf '' > "$curlErrLogFile" + + curl -vSL --retry 4 --retry-delay 5 --connect-timeout 60 -o "$curlOutLogFile" \ +"https://hc-ping.com/${HEALTHCHECK_UUID}$TEST_FAIL" >> "$curlErrLogFile" 2>&1 + curlCode="$?" + + "$isInteractive" && echo + if [ "$curlCode" -eq 0 ] && \ + ! grep -qiE "$curlErr2RegExp" "$curlOutLogFile" && \ + ! grep -qiE "$curlErr2RegExp" "$curlErrLogFile" + then Print_Output false "Healthcheck ping sent successfully" "$PASS" - return 0 + ##OFF## rm -f "$curlOutLogFile" "$curlErrLogFile" ##OFF## else - echo "" - Print_Output true "Healthcheck ping failed to send" "$ERR" - return 1 + [ "$curlCode" -eq 0 ] && curlCode=999 + Print_Output true "Healthcheck ping failed to send [Code: $curlCode]" "$ERR" + if "$isInteractive" && \ + { [ -s "$curlOutLogFile" ] || [ -s "$curlErrLogFile" ] ; } + then + PressEnter ; echo + echo "$tmpCurlSEPstr" + if [ -s "$curlOutLogFile" ] && \ + grep -qiE "$curlErr3RegExp" "$curlOutLogFile" + then + cat "$curlOutLogFile" ; echo + echo "$tmpCurlSEPstr" + fi + if [ -s "$curlErrLogFile" ] + then + cat "$curlErrLogFile" ; echo + echo "$tmpCurlSEPstr" + fi + fi fi + return "$curlCode" } ##----------------------------------------## @@ -3342,56 +3475,67 @@ SendHealthcheckPing() ##----------------------------------------## SendToInfluxDB() { - local curlCode tempLogFile="/tmp/var/tmp/temp_${SCRIPT_NAME}.LOG" - + local curlCode TIMESTAMP="$1" PING="$2" JITTER="$3" LINEQUAL="$4" - NOTIFICATIONS_INFLUXDB_HOST="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_HOST)" - NOTIFICATIONS_INFLUXDB_PORT="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_PORT)" - NOTIFICATIONS_INFLUXDB_DB="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_DB)" - NOTIFICATIONS_INFLUXDB_VERSION="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_VERSION)" - NOTIFICATIONS_INFLUXDB_PROTO="http" - if [ "$NOTIFICATIONS_INFLUXDB_PORT" = "443" ] - then - NOTIFICATIONS_INFLUXDB_PROTO="https" + INFLUXDB_DB="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_DB)" + INFLUXDB_HOST="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_HOST)" + INFLUXDB_PORT="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_PORT)" + INFLUXDB_VERSION="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_VERSION)" + INFLUXDB_PROTO="http" + if [ "$INFLUXDB_PORT" = "443" ] + then INFLUXDB_PROTO="https" fi - if [ "$NOTIFICATIONS_INFLUXDB_VERSION" = "1.8" ] + if [ "$INFLUXDB_VERSION" = "1.8" ] then INFLUX_AUTHHEADER="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_USERNAME):$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_PASSWORD)" - elif [ "$NOTIFICATIONS_INFLUXDB_VERSION" = "2.0" ] + elif [ "$INFLUXDB_VERSION" = "2.0" ] then INFLUX_AUTHHEADER="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_APITOKEN)" fi - date +'%Y-%b-%d %a %I:%M:%S %p %Z' > "$tempLogFile" + printf '' > "$curlOutLogFile" + printf '' > "$curlErrLogFile" - curl -v --retry 4 --retry-delay 5 --output /dev/null \ - -XPOST "$NOTIFICATIONS_INFLUXDB_PROTO://$NOTIFICATIONS_INFLUXDB_HOST:$NOTIFICATIONS_INFLUXDB_PORT/api/v2/write?bucket=$NOTIFICATIONS_INFLUXDB_DB&precision=s" \ + curl -vSL --retry 4 --retry-delay 5 --connect-timeout 60 -o "$curlOutLogFile" \ + "${INFLUXDB_PROTO}://${INFLUXDB_HOST}:${INFLUXDB_PORT}/api/v2/write?bucket=${INFLUXDB_DB}&precision=s" \ --header "Authorization: Token $INFLUX_AUTHHEADER" --header "Accept-Encoding: gzip" \ --data-raw "ping value=$PING $TIMESTAMP jitter value=$JITTER $TIMESTAMP -linequality value=$LINEQUAL $TIMESTAMP" >> "$tempLogFile" 2>&1 +linequality value=$LINEQUAL $TIMESTAMP" >> "$curlErrLogFile" 2>&1 curlCode="$?" - if [ "$curlCode" -eq 0 ] + "$isInteractive" && echo + if [ "$curlCode" -eq 0 ] && \ + ! grep -qiE "$curlErr2RegExp" "$curlOutLogFile" && \ + ! grep -qiE "$curlErr2RegExp" "$curlErrLogFile" then - echo Print_Output false "Data sent to InfluxDB successfully" "$PASS" - ##TEMP-OFF## rm -f "$tempLogFile" ##TEMP-OFF## - return 0 + ##OFF## rm -f "$curlOutLogFile" "$curlErrLogFile" ##OFF## else - echo + [ "$curlCode" -eq 0 ] && curlCode=999 Print_Output true "Data failed to send to InfluxDB [Code: $curlCode]" "$ERR" - if "$isInteractive" + if "$isInteractive" && \ + { [ -s "$curlOutLogFile" ] || [ -s "$curlErrLogFile" ] ; } then - echo "-------------------------------------------------------" - cat "$tempLogFile" - echo "-------------------------------------------------------" + PressEnter ; echo + echo "$tmpCurlSEPstr" + if [ -s "$curlOutLogFile" ] && \ + grep -qiE "$curlErr3RegExp" "$curlOutLogFile" + then + cat "$curlOutLogFile" ; echo + echo "$tmpCurlSEPstr" + fi + if [ -s "$curlErrLogFile" ] + then + cat "$curlErrLogFile" ; echo + echo "$tmpCurlSEPstr" + fi fi - return 1 fi + return "$curlCode" } ##----------------------------------------## From 174d38c5d7316719231f50c745495cfd86149b7a Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Tue, 9 Dec 2025 08:44:09 -0800 Subject: [PATCH 10/20] Code Improvements Modified API call to InfluxDB based on discovery and feedback from an SNBForum user (@scootertramp). --- connmon.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/connmon.sh b/connmon.sh index 41692a5..4022506 100644 --- a/connmon.sh +++ b/connmon.sh @@ -37,7 +37,7 @@ ### Start of script variables ### readonly SCRIPT_NAME="connmon" readonly SCRIPT_VERSION="v3.0.10" -readonly SCRIPT_VERSTAG="25120900" +readonly SCRIPT_VERSTAG="25120908" SCRIPT_BRANCH="develop" SCRIPT_REPO="https://raw.githubusercontent.com/AMTM-OSR/$SCRIPT_NAME/$SCRIPT_BRANCH" readonly SCRIPT_DIR="/jffs/addons/$SCRIPT_NAME.d" @@ -3471,7 +3471,7 @@ SendHealthcheckPing() } ##----------------------------------------## -## Modified by Martinski W. [2025-Dec-08] ## +## Modified by Martinski W. [2025-Dec-09] ## ##----------------------------------------## SendToInfluxDB() { @@ -3481,6 +3481,7 @@ SendToInfluxDB() JITTER="$3" LINEQUAL="$4" INFLUXDB_DB="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_DB)" + INFLUXDB_ORG=homenet ##Should it be a variable or a constant??## INFLUXDB_HOST="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_HOST)" INFLUXDB_PORT="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_PORT)" INFLUXDB_VERSION="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_VERSION)" @@ -3500,10 +3501,10 @@ SendToInfluxDB() printf '' > "$curlErrLogFile" curl -vSL --retry 4 --retry-delay 5 --connect-timeout 60 -o "$curlOutLogFile" \ - "${INFLUXDB_PROTO}://${INFLUXDB_HOST}:${INFLUXDB_PORT}/api/v2/write?bucket=${INFLUXDB_DB}&precision=s" \ + "${INFLUXDB_PROTO}://${INFLUXDB_HOST}:${INFLUXDB_PORT}/api/v2/write?org=${INFLUXDB_ORG}&bucket=${INFLUXDB_DB}&precision=s" \ --header "Authorization: Token $INFLUX_AUTHHEADER" --header "Accept-Encoding: gzip" \ - --data-raw "ping value=$PING $TIMESTAMP -jitter value=$JITTER $TIMESTAMP + --data-raw "ping value=$PING ${TIMESTAMP}, +jitter value=$JITTER ${TIMESTAMP}, linequality value=$LINEQUAL $TIMESTAMP" >> "$curlErrLogFile" 2>&1 curlCode="$?" From 2cac79f29e945b7a5947ab11030f2a6bb194756e Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Tue, 9 Dec 2025 13:13:31 -0800 Subject: [PATCH 11/20] New "InfluxDB Organization" Parameter Added new "InfluxDB Organization" parameter that's required to send InfluxDB notifications. --- connmon.sh | 61 ++++++++++++++++++++++++---------------- connmonstats_www.asp | 67 ++++++++++++++++++++++++-------------------- 2 files changed, 73 insertions(+), 55 deletions(-) diff --git a/connmon.sh b/connmon.sh index 4022506..cda7e4e 100644 --- a/connmon.sh +++ b/connmon.sh @@ -37,7 +37,7 @@ ### Start of script variables ### readonly SCRIPT_NAME="connmon" readonly SCRIPT_VERSION="v3.0.10" -readonly SCRIPT_VERSTAG="25120908" +readonly SCRIPT_VERSTAG="25120912" SCRIPT_BRANCH="develop" SCRIPT_REPO="https://raw.githubusercontent.com/AMTM-OSR/$SCRIPT_NAME/$SCRIPT_BRANCH" readonly SCRIPT_DIR="/jffs/addons/$SCRIPT_NAME.d" @@ -69,8 +69,8 @@ readonly branchxStr_TAG="[Branch: $SCRIPT_BRANCH]" readonly versionDev_TAG="${SCRIPT_VERSION}_${SCRIPT_VERSTAG}" readonly versionMod_TAG="$SCRIPT_VERSION on $ROUTER_MODEL" readonly dateTimeLogFormat='%Y-%b-%d %a %I:%M:%S %p %Z' -readonly curlErr1RegExp="invalid|error" -readonly curlErr2RegExp="404: Not Found|400 Bad Request" +readonly curlErr1RegExp="invalid|unauthorized|error" +readonly curlErr2RegExp="404: Not Found|400 Bad Request|401 Unauthorized" readonly curlErr3RegExp="$curlErr1RegExp|$curlErr2RegExp" readonly curlOutLogFile="/tmp/var/tmp/temp_${SCRIPT_NAME}_curl_OUT.LOG" readonly curlErrLogFile="/tmp/var/tmp/temp_${SCRIPT_NAME}_curl_ERR.LOG" @@ -662,7 +662,7 @@ _GetConfigParam_() } ##----------------------------------------## -## Modified by Martinski W. [2025-Nov-26] ## +## Modified by Martinski W. [2025-Dec-09] ## ##----------------------------------------## Conf_Exists() { @@ -760,6 +760,7 @@ Conf_Exists() echo "NOTIFICATIONS_INFLUXDB_HOST=" echo "NOTIFICATIONS_INFLUXDB_PORT=8086" echo "NOTIFICATIONS_INFLUXDB_DB=connmon" + echo "NOTIFICATIONS_INFLUXDB_ORG=homenet" echo "NOTIFICATIONS_INFLUXDB_VERSION=1.8" echo "NOTIFICATIONS_INFLUXDB_USERNAME=" echo "NOTIFICATIONS_INFLUXDB_PASSWORD=" @@ -772,6 +773,12 @@ Conf_Exists() [ -n "$sedNum" ] && sedNum="$((sedNum + 1))" && \ sed -i "$sedNum i NOTIFICATIONS_PINGTEST_FAILED=None" "$SCRIPT_CONF" fi + if ! grep -q "^NOTIFICATIONS_INFLUXDB_ORG=" "$SCRIPT_CONF" + then + sedNum="$(grep -n 'NOTIFICATIONS_INFLUXDB_DB=' "$SCRIPT_CONF" | cut -d':' -f1)" + [ -n "$sedNum" ] && sedNum="$((sedNum + 1))" && \ + sed -i "$sedNum i NOTIFICATIONS_INFLUXDB_ORG=homenet" "$SCRIPT_CONF" + fi return 0 else { @@ -808,6 +815,7 @@ Conf_Exists() echo "NOTIFICATIONS_INFLUXDB_HOST=" echo "NOTIFICATIONS_INFLUXDB_PORT=8086" echo "NOTIFICATIONS_INFLUXDB_DB=connmon" + echo "NOTIFICATIONS_INFLUXDB_ORG=homenet" echo "NOTIFICATIONS_INFLUXDB_VERSION=1.8" echo "NOTIFICATIONS_INFLUXDB_USERNAME=" echo "NOTIFICATIONS_INFLUXDB_PASSWORD=" @@ -3480,8 +3488,8 @@ SendToInfluxDB() PING="$2" JITTER="$3" LINEQUAL="$4" - INFLUXDB_DB="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_DB)" - INFLUXDB_ORG=homenet ##Should it be a variable or a constant??## + INFLUXDB_BID="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_DB)" + INFLUXDB_ORG="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_ORG)" INFLUXDB_HOST="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_HOST)" INFLUXDB_PORT="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_PORT)" INFLUXDB_VERSION="$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_VERSION)" @@ -3501,11 +3509,9 @@ SendToInfluxDB() printf '' > "$curlErrLogFile" curl -vSL --retry 4 --retry-delay 5 --connect-timeout 60 -o "$curlOutLogFile" \ - "${INFLUXDB_PROTO}://${INFLUXDB_HOST}:${INFLUXDB_PORT}/api/v2/write?org=${INFLUXDB_ORG}&bucket=${INFLUXDB_DB}&precision=s" \ + "${INFLUXDB_PROTO}://${INFLUXDB_HOST}:${INFLUXDB_PORT}/api/v2/write?org=${INFLUXDB_ORG}&bucket=${INFLUXDB_BID}&precision=s" \ --header "Authorization: Token $INFLUX_AUTHHEADER" --header "Accept-Encoding: gzip" \ - --data-raw "ping value=$PING ${TIMESTAMP}, -jitter value=$JITTER ${TIMESTAMP}, -linequality value=$LINEQUAL $TIMESTAMP" >> "$curlErrLogFile" 2>&1 + --data-raw "pingTest,ping=$PING ${TIMESTAMP},jitter=$JITTER ${TIMESTAMP},linequality=$LINEQUAL $TIMESTAMP" >> "$curlErrLogFile" 2>&1 curlCode="$?" "$isInteractive" && echo @@ -3560,7 +3566,7 @@ ToggleNotificationTypes() } ##----------------------------------------## -## Modified by Martinski W. [2025-Dec-07] ## +## Modified by Martinski W. [2025-Dec-09] ## ##----------------------------------------## Conf_Parameters() { @@ -3601,9 +3607,12 @@ Conf_Parameters() "InfluxDB Port") sed -i 's/^NOTIFICATIONS_INFLUXDB_PORT=.*$/NOTIFICATIONS_INFLUXDB_PORT='"$3"'/' "$SCRIPT_CONF" ;; - "InfluxDB Database") + "InfluxDB Database ID") sed -i 's/^NOTIFICATIONS_INFLUXDB_DB=.*$/NOTIFICATIONS_INFLUXDB_DB='"$3"'/' "$SCRIPT_CONF" ;; + "InfluxDB Organization") + sed -i 's/^NOTIFICATIONS_INFLUXDB_ORG=.*$/NOTIFICATIONS_INFLUXDB_ORG='"$3"'/' "$SCRIPT_CONF" + ;; "InfluxDB Version") sed -i 's/^NOTIFICATIONS_INFLUXDB_VERSION=.*$/NOTIFICATIONS_INFLUXDB_VERSION='"$3"'/' "$SCRIPT_CONF" ;; @@ -4354,7 +4363,7 @@ Menu_HealthcheckNotifications() } ##----------------------------------------## -## Modified by Martinski W. [2025-Dec-07] ## +## Modified by Martinski W. [2025-Dec-09] ## ##----------------------------------------## Menu_InfluxDB() { @@ -4370,11 +4379,12 @@ Menu_InfluxDB() printf " ${BOLD}${GRNct}${UNDERLINE}InfluxDB Configuration${CLRct}\n\n" printf "c1. Set InfluxDB Host\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_HOST)" printf "c2. Set InfluxDB Port\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_PORT)" - printf "c3. Set InfluxDB Database\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_DB)" - printf "c4. Set InfluxDB Version\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_VERSION)" - printf "c5. Set InfluxDB Username (v1.8+ only)\\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_USERNAME)" - printf "c6. Set InfluxDB Password (v1.8+ only)\n\n" - printf "c7. Set InfluxDB API Token (v2.x only)\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_APITOKEN)" + printf "c3. Set InfluxDB Database ID\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_DB)" + printf "c4. Set InfluxDB Organization\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_ORG)" + printf "c5. Set InfluxDB Version\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_VERSION)" + printf "c6. Set InfluxDB Username (v1.8+ only)\\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_USERNAME)" + printf "c7. Set InfluxDB Password (v1.8+ only)\n\n" + printf "c8. Set InfluxDB API Token (v2.x only)\n Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_APITOKEN)" printf "cs. Send test data to InfluxDB\n\n" printf " e. Go back\n\n" printf "${BOLD}##############################################################${CLEARFORMAT}\n" @@ -4398,22 +4408,25 @@ Menu_InfluxDB() Notification_Number "InfluxDB Port" ;; c3) - Notification_String "InfluxDB Database" + Notification_String "InfluxDB Database ID" ;; c4) + Notification_String "InfluxDB Organization" + ;; + c5) if [ "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_VERSION)" = "1.8" ]; then Conf_Parameters update "InfluxDB Version" "2.0" else Conf_Parameters update "InfluxDB Version" "1.8" fi ;; - c5) + c6) Notification_String "InfluxDB Username" ;; - c6) + c7) Notification_String "InfluxDB Password" ;; - c7) + c8) Notification_String "InfluxDB API Token" ;; cs) @@ -6195,7 +6208,7 @@ case "$1" in if Email_ConfExists then rm -f "$SCRIPT_WEB_DIR/password.htm" - sleep 3 + sleep 1 Email_Decrypt_Password > "$SCRIPT_WEB_DIR/password.htm" fi elif [ "$2" = "start" ] && [ "$3" = "${SCRIPT_NAME}deleteemailpassword" ] @@ -6204,7 +6217,7 @@ case "$1" in elif [ "$2" = "start" ] && [ "$3" = "${SCRIPT_NAME}customactionlist" ] then rm -f "$SCRIPT_STORAGE_DIR/.customactionlist" - sleep 3 + sleep 1 CustomAction_List silent elif [ "$2" = "start" ] && [ "$3" = "${SCRIPT_NAME}TestEmail" ] then diff --git a/connmonstats_www.asp b/connmonstats_www.asp index 4a9e580..2915fa7 100644 --- a/connmonstats_www.asp +++ b/connmonstats_www.asp @@ -33,7 +33,7 @@ p{font-weight:bolder}thead.collapsible-jquery{color:#fff;padding:0;width:100%;bo @@ -1060,7 +1060,7 @@ function getCookie(e,t){if(null!==cookie.get("conn_"+e)){if("string"===t)return id="table_connmonemailconfig">
- + @@ -1517,7 +1517,7 @@ function getCookie(e,t){if(null!==cookie.get("conn_"+e)){if("string"===t)return id="table_healthchecksioconfig"> - + @@ -1594,7 +1594,7 @@ function getCookie(e,t){if(null!==cookie.get("conn_"+e)){if("string"===t)return class="FormTable SettingsTable" id="table_influxdbconfig"> - + @@ -1676,15 +1676,15 @@ function getCookie(e,t){if(null!==cookie.get("conn_"+e)){if("string"===t)return data-lpignore="true" /> - + diff --git a/connmonstats_www.js b/connmonstats_www.js index e32423b..675ce88 100644 --- a/connmonstats_www.js +++ b/connmonstats_www.js @@ -1,5 +1,5 @@ /**----------------------------**/ -/** Last Modified: 2025-Dec-07 **/ +/** Last Modified: 2025-Dec-12 **/ /**----------------------------**/ iziToast.settings({ @@ -1123,7 +1123,7 @@ function parseLastXData(data) } /**----------------------------------------**/ -/** Modified by Martinski W. [2025-Nov-14] **/ +/** Modified by Martinski W. [2025-Dec-12] **/ /**----------------------------------------**/ $.fn.serializeObject = function() { @@ -1133,13 +1133,13 @@ $.fn.serializeObject = function() { if (o[this.name] !== undefined && this.name.indexOf('connmon') !== -1 && - this.name.indexOf('version') === -1 && this.name.indexOf('ipaddr') === -1 && this.name.indexOf('domain') === -1 && this.name.indexOf('schdays') === -1 && this.name.indexOf('pushover_list') === -1 && this.name.indexOf('pushover_list') === -1 && this.name.indexOf('webhook_list') === -1 && + this.name.indexOf('connmon_version_') === -1 && this.name !== 'connmon_notifications_pingtest' && this.name !== 'connmon_notifications_pingtest_failed' && this.name !== 'connmon_notifications_pingthreshold' && @@ -1152,13 +1152,13 @@ $.fn.serializeObject = function() o[this.name].push(this.value || ''); } else if (this.name.indexOf('connmon') !== -1 && - this.name.indexOf('version') === -1 && this.name.indexOf('ipaddr') === -1 && this.name.indexOf('domain') === -1 && this.name.indexOf('schdays') === -1 && this.name.indexOf('pushover_list') === -1 && this.name.indexOf('pushover_list') === -1 && this.name.indexOf('webhook_list') === -1 && + this.name.indexOf('connmon_version_') === -1 && this.name !== 'connmon_notifications_pingtest' && this.name !== 'connmon_notifications_pingtest_failed' && this.name !== 'connmon_notifications_pingthreshold' && @@ -1304,13 +1304,15 @@ $.fn.serializeObjectEmail = function() var o = customSettings; var a = this.serializeArray(); $.each(a, function () { - if (o[this.name] !== undefined && this.name.indexOf('email_') !== -1 && this.name.indexOf('show_pass') === -1) { + if (o[this.name] !== undefined && this.name.indexOf('email_') !== -1 && this.name.indexOf('show_pass') === -1) + { if (!o[this.name].push) { o[this.name] = [o[this.name]]; } o[this.name].push(this.value || ''); } - else if (this.name.indexOf('email_') !== -1 && this.name.indexOf('show_pass') === -1) { + else if (this.name.indexOf('email_') !== -1 && this.name.indexOf('show_pass') === -1) + { o[this.name] = this.value || ''; } }); @@ -1742,7 +1744,8 @@ function getEmailInfo() { }); } -function getChangelogFile() { +function getChangelogFile() +{ $.ajax({ url: '/ext/connmon/changelog.htm', dataType: 'text', @@ -1756,7 +1759,8 @@ function getChangelogFile() { }); } -function getVersionNumber(versiontype) { +function getVersionNumber(versiontype) +{ var versionprop; if (versiontype === 'local') { versionprop = customSettings.connmon_version_local; @@ -1773,7 +1777,8 @@ function getVersionNumber(versiontype) { } } -function getVersionChangelogFile() { +function getVersionChangelogFile() +{ $.ajax({ url: '/ext/connmon/detect_changelog.js', dataType: 'script', @@ -1789,7 +1794,8 @@ function getVersionChangelogFile() { }); } -function buildLastXTableNoData() { +function buildLastXTableNoData() +{ var tablehtml = '
Email notificationsEmail Notifications
Healthchecks.io monitoringHealthchecks.io Monitoring
InfluxDB exportingInfluxDB Exporting
InfluxDB Version - + - +
'; tablehtml += ''; tablehtml += '
'; @@ -2066,7 +2072,8 @@ function saveConfig(section) default: var disabledfields = $('#' + section).find('[disabled]'); disabledfields.prop('disabled', false); - document.getElementById('amng_custom').value = JSON.stringify($('#' + section).find('input,select,textarea').serializeObject()); + var updateSettings = JSON.stringify($('#' + section).find('input,select,textarea').serializeObject()); + document.getElementById('amng_custom').value = updateSettings; document.formScriptActions.action_script.value = 'start_addon_settings;start_connmonconfig'; document.formScriptActions.submit(); disabledfields.prop('disabled', true); From 86b8305e5e50a80014186bff6dfd716ccebc2023 Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Wed, 17 Dec 2025 00:07:33 -0800 Subject: [PATCH 18/20] Improvements for the top Main Menu Modified the CLI top Main Menu to separate some groups of options and settings into their own sub-menus. This is an effort to make the top Main Menu shorter, more manageable, more user-friendly, and to improve the user experience. --- README.md | 2 +- connmon.sh | 552 +++++++++++++++++++++++++++++++---------------------- 2 files changed, 327 insertions(+), 227 deletions(-) diff --git a/README.md b/README.md index 0552b47..5c95e10 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # connmon ## v3.0.10 -### Updated on 2025-Dec-12 +### Updated on 2025-Dec-16 ## About connmon is an internet connection monitoring tool for AsusWRT Merlin with charts for daily, weekly and monthly summaries. diff --git a/connmon.sh b/connmon.sh index e1ba37b..d239312 100644 --- a/connmon.sh +++ b/connmon.sh @@ -11,7 +11,7 @@ ## Forked from https://github.com/jackyaz/connmon ## ## ## ############################################################## -# Last Modified: 2025-Dec-12 +# Last Modified: 2025-Dec-16 #------------------------------------------------------------- ############## Shellcheck directives ############# @@ -37,7 +37,7 @@ ### Start of script variables ### readonly SCRIPT_NAME="connmon" readonly SCRIPT_VERSION="v3.0.10" -readonly SCRIPT_VERSTAG="25121222" +readonly SCRIPT_VERSTAG="25121620" SCRIPT_BRANCH="develop" SCRIPT_REPO="https://raw.githubusercontent.com/AMTM-OSR/$SCRIPT_NAME/$SCRIPT_BRANCH" readonly SCRIPT_DIR="/jffs/addons/$SCRIPT_NAME.d" @@ -106,9 +106,10 @@ readonly ERR="\\e[31m" readonly WARN="\\e[33m" readonly PASS="\\e[32m" readonly BOLD="\\e[1m" -readonly SETTING="${BOLD}\\e[36m" -readonly UNDERLINE="\\e[4m" -readonly CLEARFORMAT="\\e[0m" +readonly SETTING="${BOLD}\e[36m" +readonly UNDERLINE="\e[4m" +readonly CLEARFORMAT="\e[0m" +readonly BOLDUNDERLN="\e[1;4m" ##----------------------------------------## ## Modified by Martinski W. [2025-Feb-10] ## @@ -123,6 +124,7 @@ readonly PassBGRNct="\e[30;102m" readonly WarnBYLWct="\e[30;103m" readonly WarnIMGNct="\e[45m" readonly WarnBMGNct="\e[30;105m" +readonly menuSepStr="${BOLD}##############################################################${CLRct}" isInteractive=false [ -t 0 ] && ! tty | grep -qwi "NOT" && isInteractive=true @@ -835,7 +837,7 @@ Conf_Exists() } ##----------------------------------------## -## Modified by Martinski W. [2025-Jun-06] ## +## Modified by Martinski W. [2025-Dec-15] ## ##----------------------------------------## PingServer() { @@ -845,21 +847,21 @@ PingServer() while true do ScriptHeader - printf "\n${BOLD}Current ping destination: ${GRNct}%s${CLEARFORMAT}\n\n" "$(PingServer check)" + printf " ${BOLD}Current ping server destination: ${GRNct}%s${CLRct}\n\n" "$(PingServer check)" if "$exitOK" then PressEnter ; break fi - printf "1. Enter IP Address\n" - printf "2. Enter Domain Name\n" - printf "e. Return to Main Menu\n" - printf "\n${BOLD}Choose an option:${CLEARFORMAT} " + printf " ${GRNct}1${CLRct}. Enter IP Address\n" + printf " ${GRNct}2${CLRct}. Enter Domain Name\n" + printf " ${GRNct}e${CLRct}. Go back\n" + printf "\n${BOLD}Choose an option:${CLRct} " read -r pingoption case "$pingoption" in 1) while true do - printf "\n${BOLD}Please enter an IP address (e=Exit):${CLEARFORMAT} " + printf "\n${BOLD}Please enter an IP address (e=Exit):${CLRct} " read -r ipoption if [ "$ipoption" = "e" ] then @@ -874,7 +876,7 @@ PingServer() 2) while true do - printf "\n${BOLD}Please enter a domain name (e=Exit):${CLEARFORMAT} " + printf "\n${BOLD}Please enter a domain name (e=Exit):${CLRct} " read -r domainoption if [ "$domainoption" = "e" ] then @@ -889,7 +891,7 @@ PingServer() e) break ;; *) - printf "\n${BOLD}${ERR}Please choose a valid option.${CLEARFORMAT}\n\n" + printf "\n${BOLD}${ERR}Please choose a valid option.${CLRct}\n\n" PressEnter ;; esac @@ -916,8 +918,9 @@ PingDuration() while true do ScriptHeader - printf "${BOLD}Current number of seconds for ping tests: ${GRNct}${pingSecs}${CLRct}\n" - printf "\n${BOLD}Please enter the maximum number of seconds\nto run the ping tests [${MINvalue}-${MAXvalue}] (e=Exit):${CLEARFORMAT} " + printf " ${BOLD}Current number of seconds for ping tests: ${GRNct}${pingSecs}${CLRct}\n\n" + printf " ${BOLD}Please enter the maximum number of seconds\n" + printf " to run the ping tests [${GRNct}${MINvalue}-${MAXvalue}${CLRct}] (e=Exit):${CLRct} " read -r pingdur_choice if [ -z "$pingdur_choice" ] && \ echo "$pingSecs" | grep -qE "^([1-9][0-9])$" && \ @@ -931,11 +934,11 @@ PingDuration() break elif ! Validate_Number "$pingdur_choice" then - printf "\n${ERR}Please enter a valid number [${MINvalue}-${MAXvalue}].${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a valid number [${MINvalue}-${MAXvalue}].${CLRct}\n" PressEnter elif [ "$pingdur_choice" -lt "$MINvalue" ] || [ "$pingdur_choice" -gt "$MAXvalue" ] then - printf "\n${ERR}Please enter a number between ${MINvalue} and ${MAXvalue}.${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a number between ${MINvalue} and ${MAXvalue}.${CLRct}\n" PressEnter else pingSecs="$pingdur_choice" @@ -972,8 +975,9 @@ DaysToKeep() while true do ScriptHeader - printf "${BOLD}Current number of days to keep data: ${GRNct}${daysToKeep}${CLRct}\n\n" - printf "${BOLD}Please enter the maximum number of days\nto keep the data for [${MINvalue}-${MAXvalue}] (e=Exit):${CLEARFORMAT} " + printf " ${BOLD}Current number of days to keep data: ${GRNct}${daysToKeep}${CLRct}\n\n" + printf " ${BOLD}Please enter the maximum number of days\n" + printf " to keep the data for [${GRNct}${MINvalue}-${MAXvalue}${CLRct}] (e=Exit):${CLRct} " read -r daystokeep_choice if [ -z "$daystokeep_choice" ] && \ echo "$daysToKeep" | grep -qE "^([1-9][0-9]{1,2})$" && \ @@ -987,11 +991,11 @@ DaysToKeep() break elif ! Validate_Number "$daystokeep_choice" then - printf "\n${ERR}Please enter a valid number [${MINvalue}-${MAXvalue}].${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a valid number [${MINvalue}-${MAXvalue}].${CLRct}\n" PressEnter elif [ "$daystokeep_choice" -lt "$MINvalue" ] || [ "$daystokeep_choice" -gt "$MAXvalue" ] then - printf "\n${ERR}Please enter a number between ${MINvalue} and ${MAXvalue}.${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a number between ${MINvalue} and ${MAXvalue}.${CLRct}\n" PressEnter else daysToKeep="$daystokeep_choice" @@ -1028,8 +1032,9 @@ LastXResults() while true do ScriptHeader - printf "${BOLD}Current number of results to display: ${GRNct}${lastXResults}${CLRct}\n\n" - printf "${BOLD}Please enter the maximum number of results\nto display in the WebUI [${MINvalue}-${MAXvalue}] (e=Exit):${CLEARFORMAT} " + printf " ${BOLD}Current number of results to display: ${GRNct}${lastXResults}${CLRct}\n\n" + printf " ${BOLD}Please enter the maximum number of results\n" + printf " to display in the WebUI [${GRNct}${MINvalue}-${MAXvalue}${CLRct}] (e=Exit):${CLRct} " read -r lastx_choice if [ -z "$lastx_choice" ] && \ echo "$lastXResults" | grep -qE "^([1-9][0-9]{0,2})$" && \ @@ -1043,11 +1048,11 @@ LastXResults() break elif ! Validate_Number "$lastx_choice" then - printf "\n${ERR}Please enter a valid number [${MINvalue}-${MAXvalue}].${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a valid number [${MINvalue}-${MAXvalue}].${CLRct}\n" PressEnter elif [ "$lastx_choice" -lt "$MINvalue" ] || [ "$lastx_choice" -gt "$MAXvalue" ] then - printf "\n${ERR}Please enter a number between ${MINvalue} and ${MAXvalue}.${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a number between ${MINvalue} and ${MAXvalue}.${CLRct}\n" PressEnter else lastXResults="$lastx_choice" @@ -3525,7 +3530,7 @@ SendToInfluxDB() else routerID="$(echo "$ROUTER_MODEL" | sed 's/ /_/g')" fi - ## Variable ping test results are assigned to InfluxDB data "fields" ## + ## Variable ping test results are assigned to InfluxDB "data fields" ## dataTags="Router=${routerID},Source=${SCRIPT_NAME}" dataFields="Jitter=${JITTER},LineQuality=${LINEQUAL},PingAvrg=${PING},PingServer=\"${PING_TARGET}\"" @@ -4024,8 +4029,8 @@ Menu_EmailNotifications() printf " ${GRNct}c9${CLRct}. Set SMTP Protocol Currently: ${SETTING}%s${CLRct}\n" "$PROTOCOL" printf " ${GRNct}c10${CLRct}. Set SSL Requirement Currently: ${SETTING}%s${CLRct}\n\n" "$SSL_FlagStr" printf " ${GRNct}cs${CLRct}. Send a test email\n\n" - printf " ${GRNct}e${CLRct}. Go back\n\n" - printf "${BOLD}##############################################################${CLRct}\n\n" + printf " ${GRNct}e${CLRct}. Go back\n" + printf "\n${menuSepStr}\n\n" printf "Choose an option: " read -r emailmenu @@ -4122,8 +4127,8 @@ Menu_WebhookNotifications() printf " Current webhooks:\n" printf " ${SETTING}${notificationsWEBHOOK_LIST}${CLRct}\n\n" printf " ${GRNct}cs${CLRct}. Send a test webhook notification\n\n" - printf " ${GRNct}e${CLRct}. Go back\n\n" - printf "${BOLD}##############################################################${CLRct}\n\n" + printf " ${GRNct}e${CLRct}. Go back\n" + printf "\n${menuSepStr}\n\n" printf "Choose an option: " read -r webhookmenu @@ -4210,8 +4215,8 @@ Menu_PushoverNotifications() printf " ${GRNct}c3${CLRct}. Set list of Pushover devices for %s\n" "$SCRIPT_NAME" printf " Current devices: ${SETTING}${notificationsPUSHOVER_LIST}${CLRct}\n\n" printf " ${GRNct}cs${CLRct}. Send a test Pushover notification\n\n" - printf " ${GRNct}e${CLRct}. Go back\n\n" - printf "${BOLD}##############################################################${CLRct}\n\n" + printf " ${GRNct}e${CLRct}. Go back\n" + printf "\n${menuSepStr}\n\n" printf "Choose an option: " read -r pushoverOption @@ -4273,8 +4278,8 @@ CustomAction_Info() printf "${BOLD}opkg install python3 python3-pip && /opt/bin/python3 -m pip install --upgrade pip${CLRct}\n\n" printf "Apprise can then be leveraged at the command line as shown here:\n" printf "${BOLD}https://github.com/caronc/apprise#command-line${CLRct}\n\n" - printf " ${GRNct}e${CLRct}. Go back\n\n" - printf "${BOLD}##############################################################${CLRct}\n\n" + printf " ${GRNct}e${CLRct}. Go back\n" + printf "\n${menuSepStr}\n\n" fi { @@ -4445,8 +4450,8 @@ Menu_HealthcheckNotifications() printf " Cron schedule for Healthchecks.io configuration:\n" printf " ${HEALTHCHECK_CRON}${CLRct}\n\n" printf " ${GRNct}cs${CLRct}. Send a test Healthcheck notification\n\n" - printf " ${GRNct}e${CLRct}. Go back\n\n" - printf "${BOLD}##############################################################${CLRct}\n\n" + printf " ${GRNct}e${CLRct}. Go back\n" + printf "\n${menuSepStr}\n\n" printf "Choose an option: " read -r healthcheckOption @@ -4515,8 +4520,8 @@ Menu_InfluxDB() printf " ${GRNct}c9${CLRct}. Set InfluxDB API Token (v2.x only)\n" printf " Currently: ${SETTING}%s${CLRct}\n\n" "$(Conf_Parameters check NOTIFICATIONS_INFLUXDB_APITOKEN)" printf " ${GRNct}cs${CLRct}. Send test data to InfluxDB\n\n" - printf " ${GRNct}e${CLRct}. Go back\n\n" - printf "${BOLD}##############################################################${CLRct}\n\n" + printf " ${GRNct}e${CLRct}. Go back\n" + printf "\n${menuSepStr}\n\n" printf "Choose an option: " read -r influxdbOption @@ -4579,7 +4584,7 @@ Menu_InfluxDB() } ##----------------------------------------## -## Modified by Martinski W. [2025-Nov-14] ## +## Modified by Martinski W. [2025-Dec-15] ## ##----------------------------------------## Menu_Notifications() { @@ -4587,61 +4592,60 @@ Menu_Notifications() do ScriptHeader printf " ${BOLD}${GRNct}${UNDERLINE}Notification Types${CLRct}\n\n" - printf " 1. Ping test success\n" - printf " Current methods: ${SETTING}$(NotificationMethods check PingTestOK)${CLEARFORMAT}\n\n" - printf " 2. Ping test failure\n" - printf " Current methods: ${SETTING}$(NotificationMethods check PingTestFailed)${CLEARFORMAT}\n\n" - printf " 3. Ping threshold (values above this will trigger an alert)\n" - printf " Current threshold: ${SETTING}$(Conf_Parameters check NOTIFICATIONS_PINGTHRESHOLD_VALUE) ms${CLEARFORMAT}\n" - printf " Current methods: ${SETTING}$(NotificationMethods check PingThreshold)${CLEARFORMAT}\n\n" - printf " 4. Jitter threshold (values above this will trigger an alert)\n" - printf " Current threshold: ${SETTING}$(Conf_Parameters check NOTIFICATIONS_JITTERTHRESHOLD_VALUE) ms${CLEARFORMAT}\n" - printf " Current methods: ${SETTING}$(NotificationMethods check JitterThreshold)${CLEARFORMAT}\n\n" - printf " 5. Line Quality threshold (values below this will trigger an alert)\n" - printf " Current threshold: ${SETTING}$(Conf_Parameters check NOTIFICATIONS_LINEQUALITYTHRESHOLD_VALUE) %%${CLEARFORMAT}\n" - printf " Current methods: ${SETTING}$(NotificationMethods check LineQualityThreshold)${CLEARFORMAT}\n\n" - - printf "\n ${BOLD}${GRNct}${UNDERLINE}Notification Methods and Integrations${CLEARFORMAT}\n\n" + printf " ${GRNct}1${CLRct}. Ping test success\n" + printf " Current methods: ${SETTING}$(NotificationMethods check PingTestOK)${CLRct}\n\n" + printf " ${GRNct}2${CLRct}. Ping test failure\n" + printf " Current methods: ${SETTING}$(NotificationMethods check PingTestFailed)${CLRct}\n\n" + printf " ${GRNct}3${CLRct}. Ping threshold (values above this will trigger an alert)\n" + printf " Current threshold: ${SETTING}$(Conf_Parameters check NOTIFICATIONS_PINGTHRESHOLD_VALUE) ms${CLRct}\n" + printf " Current methods: ${SETTING}$(NotificationMethods check PingThreshold)${CLRct}\n\n" + printf " ${GRNct}4${CLRct}. Jitter threshold (values above this will trigger an alert)\n" + printf " Current threshold: ${SETTING}$(Conf_Parameters check NOTIFICATIONS_JITTERTHRESHOLD_VALUE) ms${CLRct}\n" + printf " Current methods: ${SETTING}$(NotificationMethods check JitterThreshold)${CLRct}\n\n" + printf " ${GRNct}5${CLRct}. Line Quality threshold (values below this will trigger an alert)\n" + printf " Current threshold: ${SETTING}$(Conf_Parameters check NOTIFICATIONS_LINEQUALITYTHRESHOLD_VALUE) %%${CLRct}\n" + printf " Current methods: ${SETTING}$(NotificationMethods check LineQualityThreshold)${CLRct}\n\n" + + printf "\n ${BOLD}${GRNct}${UNDERLINE}Notification Methods and Integrations${CLRct}\n\n" NOTIFICATION_SETTING="" if ToggleNotificationTypes check NOTIFICATIONS_EMAIL then NOTIFICATION_SETTING="${PASS}Enabled" else NOTIFICATION_SETTING="${ERR}Disabled" fi - printf " em. Email (shared with other addons/scripts e.g. Diversion)\n" - printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLEARFORMAT}\n\n" + printf " ${GRNct}em${CLRct}. Email (shared with other addons/scripts e.g. Diversion)\n" + printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLRct}\n\n" if ToggleNotificationTypes check NOTIFICATIONS_WEBHOOK then NOTIFICATION_SETTING="${PASS}Enabled" else NOTIFICATION_SETTING="${ERR}Disabled" fi - printf " wb. Discord webhook\n" - printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLEARFORMAT}\\n\\n" + printf " ${GRNct}wb${CLRct}. Discord webhook\n" + printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLRct}\n\n" if ToggleNotificationTypes check NOTIFICATIONS_PUSHOVER then NOTIFICATION_SETTING="${PASS}Enabled" else NOTIFICATION_SETTING="${ERR}Disabled" fi - printf " po. Pushover\n" - printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLEARFORMAT}\\n\\n" + printf " ${GRNct}po${CLRct}. Pushover\n" + printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLRct}\n\n" if ToggleNotificationTypes check NOTIFICATIONS_CUSTOM then NOTIFICATION_SETTING="${PASS}Enabled" else NOTIFICATION_SETTING="${ERR}Disabled" fi - printf " ca. Custom actions and user scripts\n" - printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLEARFORMAT}\\n\\n" + printf " ${GRNct}ca${CLRct}. Custom actions and user scripts\n" + printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLRct}\n\n" if ToggleNotificationTypes check NOTIFICATIONS_HEALTHCHECK then NOTIFICATION_SETTING="${PASS}Enabled" else NOTIFICATION_SETTING="${ERR}Disabled" fi - printf " hc. Healthchecks.io\n" - printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLEARFORMAT}\\n\\n" + printf " ${GRNct}hc${CLRct}. Healthchecks.io\n" + printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLRct}\n\n" if ToggleNotificationTypes check NOTIFICATIONS_INFLUXDB then NOTIFICATION_SETTING="${PASS}Enabled" else NOTIFICATION_SETTING="${ERR}Disabled" fi - printf " id. InfluxDB exporting\n" - printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLEARFORMAT}\\n\\n" - printf " e. Go back\n\n" - printf "${BOLD}##############################################################${CLEARFORMAT}\n" - printf "\n" + printf " ${GRNct}id${CLRct}. InfluxDB exporting\n" + printf " Currently: ${BOLD}${NOTIFICATION_SETTING}${CLRct}\n\n" + printf " ${GRNct}e${CLRct}. Go back\n" + printf "\n${menuSepStr}\n\n" printf "Choose an option: " read -r notificationsmenu @@ -4678,7 +4682,7 @@ Menu_Notifications() } ##----------------------------------------## -## Modified by Martinski W. [2025-Nov-14] ## +## Modified by Martinski W. [2025-Dec-15] ## ##----------------------------------------## NotificationMethods() { @@ -4687,7 +4691,7 @@ NotificationMethods() while true do ScriptHeader - printf " ${BOLD}${GRNct}${UNDERLINE}${2}${CLEARFORMAT}\n\n" + printf " ${BOLD}${GRNct}${UNDERLINE}${2}${CLRct}\n\n" if [ "$2" = "PingThreshold" ] || \ [ "$2" = "JitterThreshold" ] || \ [ "$2" = "LineQualityThreshold" ] @@ -4706,18 +4710,18 @@ NotificationMethods() UNIT="%%" ;; esac - printf "c1. Set threshold value - Currently: ${SETTING}$(Conf_Parameters check "$PARAMETERNAME") $UNIT${CLEARFORMAT}\n\n" + printf " ${GRNct}c1${CLRct}. Set threshold value - Currently: ${SETTING}$(Conf_Parameters check "$PARAMETERNAME") $UNIT${CLRct}\n\n" fi SETTINGNAME="" ; SETTINGVALUE="" - printf "Please choose the notification methods to enable\n" - printf "${BOLD}Currently enabled: ${SETTING}%s${CLEARFORMAT}\n\n" "$(NotificationMethods check "$2")" - printf " 1. Email\n" - printf " 2. Webhook\n" - printf " 3. Pushover\n" - printf " 4. Custom\n" - printf " 5. None\n\n" - printf " e. Go back\n\n" + printf " Please choose the notification methods to enable\n" + printf " ${BOLD}Currently enabled: ${SETTING}%s${CLRct}\n\n" "$(NotificationMethods check "$2")" + printf " ${GRNct}1${CLRct}. Email\n" + printf " ${GRNct}2${CLRct}. Webhook\n" + printf " ${GRNct}3${CLRct}. Pushover\n" + printf " ${GRNct}4${CLRct}. Custom\n" + printf " ${GRNct}5${CLRct}. None\n\n" + printf " ${GRNct}e${CLRct}. Go back\n\n" printf "Choose an option: " read -r methodsmenu case "$methodsmenu" in @@ -4955,81 +4959,52 @@ _CronScheduleHourMinsInfo_() } ##----------------------------------------## -## Modified by Martinski W. [2025-Nov-14] ## +## Modified by Martinski W. [2025-Dec-15] ## ##----------------------------------------## -MainMenu() +_HandleInvalidMenuOption_() { - local menuOption storageLocStr automaticModeStatus - local jffsFreeSpace jffsFreeSpaceStr jffsSpaceMsgTag + [ -n "$menuOption" ] && \ + printf "\n${REDct}INVALID input [$menuOption]${CLRct}" + printf "\nPlease choose a valid option.\n\n" +} - if [ "$(ExcludeFromQoS check)" = "true" ] - then EXCLUDEFROMQOS_MENU="excluded from" - else EXCLUDEFROMQOS_MENU="included in" - fi +##----------------------------------------## +## Modified by Martinski W. [2025-Dec-15] ## +##----------------------------------------## +_Menu_PingTestOptions_() +{ + local menuOption exitMenu=false + local OPTION_FOR_QOS TEST_SCHED_LINE TEST_SCHED_DAYS + local TEST_SCHED_MENU CRON_SCHED_DAYS CRON_SCHED_HOUR CRON_SCHED_MINS - if AutomaticMode check - then automaticModeStatus="${PassBGRNct} ENABLED ${CLRct}" - else automaticModeStatus="${CritIREDct} DISABLED ${CLRct}" + if [ "$(ExcludeFromQoS check)" = "true" ] + then OPTION_FOR_QOS="excluded from" + else OPTION_FOR_QOS="included in" fi - TEST_SCHEDULE="$(CronTestSchedule check)" - CRON_SCHED_DAYS="$(echo "$TEST_SCHEDULE" | cut -f1 -d'|')" - CRON_SCHED_HOUR="$(echo "$TEST_SCHEDULE" | cut -f2 -d'|')" - CRON_SCHED_MINS="$(echo "$TEST_SCHEDULE" | cut -f3 -d'|')" + TEST_SCHED_LINE="$(CronTestSchedule check)" + CRON_SCHED_DAYS="$(echo "$TEST_SCHED_LINE" | cut -f1 -d'|')" + CRON_SCHED_HOUR="$(echo "$TEST_SCHED_LINE" | cut -f2 -d'|')" + CRON_SCHED_MINS="$(echo "$TEST_SCHED_LINE" | cut -f3 -d'|')" if [ "$CRON_SCHED_DAYS" = "*" ] - then TEST_SCHEDULE_DAYS="Every day" - else TEST_SCHEDULE_DAYS="Days of Week: $CRON_SCHED_DAYS" - fi - TEST_SCHEDULE_MENU="$(_CronScheduleHourMinsInfo_ "$CRON_SCHED_HOUR" "$CRON_SCHED_MINS")" - - storageLocStr="$(ScriptStorageLocation check | tr 'a-z' 'A-Z')" - - _UpdateJFFS_FreeSpaceInfo_ - jffsFreeSpace="$(_Get_JFFS_Space_ FREE HRx | sed 's/%/%%/')" - if ! echo "$JFFS_LowFreeSpaceStatus" | grep -E "^WARNING[0-9]$" - then - jffsFreeSpaceStr="${SETTING}$jffsFreeSpace" - else - if [ "$storageLocStr" = "JFFS" ] - then jffsSpaceMsgTag="${CritBREDct} <<< WARNING! " - else jffsSpaceMsgTag="${WarnBMGNct} <<< NOTICE! " - fi - jffsFreeSpaceStr="${WarnBYLWct} $jffsFreeSpace ${CLRct} ${jffsSpaceMsgTag}${CLRct}" + then TEST_SCHED_DAYS="Every day" + else TEST_SCHED_DAYS="Days of Week: $CRON_SCHED_DAYS" fi + TEST_SCHED_MENU="$(_CronScheduleHourMinsInfo_ "$CRON_SCHED_HOUR" "$CRON_SCHED_MINS")" - printf " WebUI for %s is available at:\n ${SETTING}%s${CLEARFORMAT}\n\n" "$SCRIPT_NAME" "$(Get_WebUI_URL)" - - printf " 1. Check connection now\n" - printf " Database size: ${SETTING}%s${CLEARFORMAT}\n\n" "$(_GetFileSize_ "$CONNSTATS_DB" HRx)" - printf " 2. Set preferred ping server\n" - printf " Currently: ${SETTING}%s${CLEARFORMAT}\n\n" "$(PingServer check)" - printf " 3. Set ping test duration\n" - printf " Currently: ${SETTING}%s sec.${CLEARFORMAT}\n\n" "$(PingDuration check)" - printf " 4. Toggle automatic ping tests\n" - printf " Currently: ${automaticModeStatus}${CLEARFORMAT}\n\n" - printf " 5. Set schedule for automatic ping tests\n" - printf " Currently: ${SETTING}%s - %s${CLEARFORMAT}\n\n" "$TEST_SCHEDULE_MENU" "$TEST_SCHEDULE_DAYS" - printf " 6. Toggle time output mode\n" - printf " Currently: ${SETTING}%s${CLEARFORMAT} time values will be used for CSV exports\n\n" "$(OutputTimeMode check)" - printf " 7. Set number of ping test results to show in WebUI\n" - printf " Currently: ${SETTING}%s results will be shown${CLEARFORMAT}\n\n" "$(LastXResults check)" - printf " 8. Set number of days data to keep in database\n" - printf " Currently: ${SETTING}%s days data will be kept${CLEARFORMAT}\n\n" "$(DaysToKeep check)" - printf " s. Toggle storage location for stats and config\n" - printf " Current location: ${SETTING}%s${CLEARFORMAT}\n" "$storageLocStr" - printf " JFFS Available: ${jffsFreeSpaceStr}${CLEARFORMAT}\n\n" - printf " q. Toggle exclusion of %s ping tests from QoS\n" "$SCRIPT_NAME" - printf " Currently: %s ping tests are ${SETTING}%s${CLEARFORMAT} QoS\n\n" "$SCRIPT_NAME" "$EXCLUDEFROMQOS_MENU" - printf " n. Configure notifications and integrations for %s\n\n" "$SCRIPT_NAME" - printf " u. Check for updates\n" - printf " uf. Update %s with latest version (force update)\n\n" "$SCRIPT_NAME" - printf " cl. View changelog for %s (use q to exit)\n\n" "$SCRIPT_NAME" - printf " r. Reset %s database / delete all data\n\n" "$SCRIPT_NAME" - printf " e. Exit %s\n\n" "$SCRIPT_NAME" - printf " z. Uninstall %s\n" "$SCRIPT_NAME" - printf "\n" - printf "${BOLD}##############################################################${CLEARFORMAT}\n" - printf "\n" + ScriptHeader + printf " ${BOLDUNDERLN}${GRNct}Ping Test Options${CLRct}\n\n" + + printf " ${GRNct}1${CLRct}. Set preferred ping server\n" + printf " Currently: ${SETTING}%s${CLRct}\n\n" "$(PingServer check)" + printf " ${GRNct}2${CLRct}. Set ping test duration\n" + printf " Currently: ${SETTING}%s sec.${CLRct}\n\n" "$(PingDuration check)" + printf " ${GRNct}3${CLRct}. Set schedule for automatic ping tests\n" + printf " Currently: ${SETTING}%s - %s${CLRct}\n\n" "$TEST_SCHED_MENU" "$TEST_SCHED_DAYS" + printf " ${GRNct}q${CLRct}. Toggle exclusion of %s ping tests from QoS\n" "$SCRIPT_NAME" + printf " Currently: %s ping tests are ${SETTING}%s${CLRct} QoS\n\n" "$SCRIPT_NAME" "$OPTION_FOR_QOS" + printf " ${GRNct}e${CLRct}. Return to Main Menu\n" + printf "\n${menuSepStr}\n\n" while true do @@ -5038,58 +5013,107 @@ MainMenu() case "$menuOption" in 1) printf "\n" - if Check_Lock menu - then - Run_PingTest - Clear_Lock - fi - PressEnter + PingServer update break ;; 2) printf "\n" - PingServer update + PingDuration update && PressEnter break ;; 3) printf "\n" - PingDuration update && PressEnter + Menu_EditCronSchedule + PressEnter break ;; - 4) + q) printf "\n" - if Check_Lock menu + if [ "$(ExcludeFromQoS check)" = "true" ] then - if AutomaticMode check - then AutomaticMode disable - else AutomaticMode enable - fi - Clear_Lock - PressEnter + ExcludeFromQoS disable + elif [ "$(ExcludeFromQoS check)" = "false" ] + then + ExcludeFromQoS enable fi break ;; - 5) - printf "\n" - Menu_EditSchedule + e) exitMenu=true + break + ;; + *) + _HandleInvalidMenuOption_ PressEnter break ;; - 6) + esac + done + + "$exitMenu" && return 0 + _Menu_PingTestOptions_ +} + +##----------------------------------------## +## Modified by Martinski W. [2025-Dec-15] ## +##----------------------------------------## +_Menu_DatabaseOptions_() +{ + local menuOption exitMenu=false storageLocStr + local jffsFreeSpace jffsFreeSpaceStr jffsSpaceMsgTag + + storageLocStr="$(ScriptStorageLocation check | tr 'a-z' 'A-Z')" + + _UpdateJFFS_FreeSpaceInfo_ + jffsFreeSpace="$(_Get_JFFS_Space_ FREE HRx | sed 's/%/%%/')" + if ! echo "$JFFS_LowFreeSpaceStatus" | grep -E "^WARNING[0-9]$" + then + jffsFreeSpaceStr="${SETTING}$jffsFreeSpace" + else + if [ "$storageLocStr" = "JFFS" ] + then jffsSpaceMsgTag="${CritBREDct} <<< WARNING! " + else jffsSpaceMsgTag="${WarnBMGNct} <<< NOTICE! " + fi + jffsFreeSpaceStr="${WarnBYLWct} $jffsFreeSpace ${CLRct} ${jffsSpaceMsgTag}${CLRct}" + fi + + ScriptHeader + printf " ${BOLDUNDERLN}${GRNct}Database Options${CLRct}\n\n" + + printf " ${GRNct}1${CLRct}. Toggle time output mode\n" + printf " Currently: ${SETTING}%s${CLRct} time values will be used for CSV exports\n\n" "$(OutputTimeMode check)" + printf " ${GRNct}2${CLRct}. Set number of ping test database results to show in WebUI\n" + printf " Currently: ${SETTING}%s results will be shown${CLRct}\n\n" "$(LastXResults check)" + printf " ${GRNct}3${CLRct}. Set maximum number of days data to keep in database\n" + printf " Currently: ${SETTING}%s days data will be kept${CLRct}\n\n" "$(DaysToKeep check)" + printf " ${GRNct}s${CLRct}. Toggle storage location for database stats and config\n" + printf " Current location: ${SETTING}%s${CLRct}\n" "$storageLocStr" + printf " JFFS Available: ${jffsFreeSpaceStr}${CLRct}\n\n" + printf " ${GRNct}rs${CLRct}. Reset %s database / delete all data\n\n" "$SCRIPT_NAME" + printf " ${GRNct}e${CLRct}. Return to Main Menu\n" + printf "\n${menuSepStr}\n\n" + + while true + do + printf "Choose an option: " + read -r menuOption + case "$menuOption" in + 1) printf "\n" - if [ "$(OutputTimeMode check)" = "unix" ]; then + if [ "$(OutputTimeMode check)" = "unix" ] + then OutputTimeMode non-unix - elif [ "$(OutputTimeMode check)" = "non-unix" ]; then + elif [ "$(OutputTimeMode check)" = "non-unix" ] + then OutputTimeMode unix fi break ;; - 7) + 2) printf "\n" LastXResults update && PressEnter break ;; - 8) + 3) printf "\n" DaysToKeep update && PressEnter break @@ -5116,13 +5140,95 @@ MainMenu() fi break ;; - q) + rs) printf "\n" - if [ "$(ExcludeFromQoS check)" = "true" ]; then - ExcludeFromQoS disable - elif [ "$(ExcludeFromQoS check)" = "false" ]; then - ExcludeFromQoS enable + if Check_Lock menu + then + Menu_ResetDB + Clear_Lock + fi + PressEnter + break + ;; + e) exitMenu=true + break + ;; + *) + _HandleInvalidMenuOption_ + PressEnter + break + ;; + esac + done + + "$exitMenu" && return 0 + _Menu_DatabaseOptions_ +} + +##----------------------------------------## +## Modified by Martinski W. [2025-Dec-15] ## +##----------------------------------------## +MainMenu() +{ + local menuOption automaticModeStatus + + if AutomaticMode check + then automaticModeStatus="${PassBGRNct} ENABLED ${CLRct}" + else automaticModeStatus="${CritIREDct} DISABLED ${CLRct}" + fi + _UpdateJFFS_FreeSpaceInfo_ + + printf " WebUI for %s is available at:\n" "$SCRIPT_NAME" + printf " ${SETTING}%s${CLRct}\n\n" "$(Get_WebUI_URL)" + + printf " ${GRNct}1${CLRct}. Check connection now\n" + printf " Database size: ${SETTING}%s${CLRct}\n\n" "$(_GetFileSize_ "$CONNSTATS_DB" HRx)" + printf " ${GRNct}2${CLRct}. Toggle automatic ping tests\n" + printf " Currently: ${automaticModeStatus}${CLRct}\n\n" + printf " ${GRNct}3${CLRct}. Configure ping test options\n\n" + printf " ${GRNct}4${CLRct}. Configure database options\n\n" + printf " ${GRNct}n${CLRct}. Configure notifications and integrations for %s\n\n" "$SCRIPT_NAME" + printf " ${GRNct}u${CLRct}. Check for updates\n" + printf " ${GRNct}uf${CLRct}. Update %s with latest version (force update)\n\n" "$SCRIPT_NAME" + printf " ${GRNct}cl${CLRct}. View changelog for %s (use q to exit)\n\n" "$SCRIPT_NAME" + printf " ${GRNct}e${CLRct}. Exit %s\n\n" "$SCRIPT_NAME" + printf " ${GRNct}z${CLRct}. Uninstall %s\n" "$SCRIPT_NAME" + printf "\n${menuSepStr}\n\n" + + while true + do + printf "Choose an option: " + read -r menuOption + case "$menuOption" in + 1) + printf "\n" + if Check_Lock menu + then + Run_PingTest + Clear_Lock fi + PressEnter + break + ;; + 2) + printf "\n" + if Check_Lock menu + then + if AutomaticMode check + then AutomaticMode disable + else AutomaticMode enable + fi + Clear_Lock + PressEnter + fi + break + ;; + 3) + _Menu_PingTestOptions_ + break + ;; + 4) + _Menu_DatabaseOptions_ break ;; n) @@ -5132,7 +5238,8 @@ MainMenu() ;; u) printf "\n" - if Check_Lock menu; then + if Check_Lock menu + then Update_Version Clear_Lock fi @@ -5141,7 +5248,8 @@ MainMenu() ;; uf) printf "\n" - if Check_Lock menu; then + if Check_Lock menu + then Update_Version force Clear_Lock fi @@ -5152,24 +5260,15 @@ MainMenu() less "$SCRIPT_DIR/CHANGELOG.md" break ;; - r) - printf "\n" - if Check_Lock menu; then - Menu_ResetDB - Clear_Lock - fi - PressEnter - break - ;; e) ScriptHeader - printf "\n${BOLD}Thanks for using %s!${CLEARFORMAT}\n\n\n" "$SCRIPT_NAME" + printf "\n${BOLD}Thanks for using %s!${CLRct}\n\n\n" "$SCRIPT_NAME" exit 0 ;; z) while true do - printf "\n${BOLD}Are you sure you want to uninstall %s? (y/n)${CLEARFORMAT} " "$SCRIPT_NAME" + printf "\n${BOLD}Are you sure you want to uninstall %s? (y/n)${CLRct} " "$SCRIPT_NAME" read -r confirm case "$confirm" in y|Y) @@ -5183,9 +5282,7 @@ MainMenu() done ;; *) - [ -n "$menuOption" ] && \ - printf "\n${REDct}INVALID input [$menuOption]${CLEARFORMAT}" - printf "\nPlease choose a valid option.\n\n" + _HandleInvalidMenuOption_ PressEnter break ;; @@ -5589,7 +5686,7 @@ _ValidateCronMINS_() ##----------------------------------------## ## Modified by Martinski W. [2024-Dec-22] ## ##----------------------------------------## -Menu_EditSchedule() +Menu_EditCronSchedule() { local exitMenu testScheduleStr local cruDays cruHour cruMins formatType @@ -5652,10 +5749,11 @@ Menu_EditSchedule() while true do ScriptHeader - printf "${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n" - printf "\n${BOLD}Please enter the DAYS of the week when to run the ping tests.\n" - printf "[${GRNct}0-6${CLRct}], ${GRNct}0${CLRct}=Sunday, ${GRNct}6${CLRct}=Saturday, ${GRNct}*${CLRct}=Every day, or comma-separated days.${CLEARFORMAT}" - printf "\n\n${BOLD}Enter DAYS of the week (${GRNct}e${CLRct}=Exit)${CLEARFORMAT}: " + printf " ${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n\n" + printf " ${BOLD}Please enter the DAYS of the week when to run the ping tests.\n" + printf " [${GRNct}0-6${CLRct}], ${GRNct}0${CLRct}=Sunday, ${GRNct}6${CLRct}=Saturday," + printf " ${GRNct}*${CLRct}=Every day, or comma-separated days.${CLRct}" + printf "\n\n ${BOLD}Enter DAYS of the week (${GRNct}e${CLRct}=Exit)${CLRct}: " read -r day_choice if [ "$day_choice" = "e" ] @@ -5679,10 +5777,11 @@ Menu_EditSchedule() while true do ScriptHeader - printf "${BOLD}Please choose the method to specify the hour/minute(s)\nto run the ping tests:${CLEARFORMAT}\n\n" - printf " 1. Every X hours/minutes\n" - printf " 2. Custom\n" - printf " e. Exit to Main Menu\n\n" + printf " ${BOLD}Please choose the method to specify the hour/minute(s)\n" + printf " to run the ping tests:${CLRct}\n\n" + printf " ${GRNct}1${CLRct}. Every X hours/minutes\n" + printf " ${GRNct}2${CLRct}. Custom\n" + printf " ${GRNct}e${CLRct}. Go back\n\n" printf "Choose an option: " read -r formatChoice @@ -5690,7 +5789,7 @@ Menu_EditSchedule() 1) formatType="everyx" ; echo ; break ;; 2) formatType="custom" ; echo ; break ;; e) exitMenu=true ; break ;; - *) printf "\n${ERR}Please enter a valid choice [1-2]${CLEARFORMAT}\n" + *) printf "\n${ERR}Please enter a valid choice [1-2]${CLRct}\n" PressEnter ;; esac done @@ -5703,10 +5802,11 @@ Menu_EditSchedule() while true do ScriptHeader - printf "${BOLD}Please choose whether to specify every X hours or every X minutes\nto run the ping tests:${CLEARFORMAT}\n\n" - printf " 1. Hours\n" - printf " 2. Minutes\n" - printf " e. Exit to Main Menu\n\n" + printf " ${BOLD}Please choose whether to specify every X hours or every X minutes\n" + printf " to run the ping tests:${CLRct}\n\n" + printf " ${GRNct}1${CLRct}. Hours\n" + printf " ${GRNct}2${CLRct}. Minutes\n" + printf " ${GRNct}e${CLRct}. Go back\n\n" printf "Choose an option: " read -r formatChoice @@ -5714,7 +5814,7 @@ Menu_EditSchedule() 1) formatType="hours" ; echo ; break ;; 2) formatType="mins" ; echo ; break ;; e) exitMenu=true ; break ;; - *) printf "\n${ERR}Please enter a valid choice [1-2]${CLEARFORMAT}\n" + *) printf "\n${ERR}Please enter a valid choice [1-2]${CLRct}\n" PressEnter ;; esac done @@ -5729,9 +5829,9 @@ Menu_EditSchedule() while true do ScriptHeader - printf "${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n" - printf "\n${BOLD}Please enter how often in HOURS to run the ping tests.\n" - printf "Every X hours, where X is ${GRNct}1-24${CLRct}, (${GRNct}e${CLRct}=Exit)${CLEARFORMAT}: " + printf " ${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n\n" + printf " ${BOLD}Please enter how often in HOURS to run the ping tests.\n" + printf " Every X hours, where X is [${GRNct}1-24${CLRct}], (${GRNct}e${CLRct}=Exit)${CLRct}: " read -r hour_choice if [ "$hour_choice" = "e" ] @@ -5742,7 +5842,7 @@ Menu_EditSchedule() if _ValidateCronHOURS_ "$cruHour" -quiet || \ _ValidateCronFreqHOURS_ "$cruHour" -quiet then echo ; break ; fi - printf "\n${ERR}Please enter a number between 1 and 24${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a number between 1 and 24${CLRct}\n" PressEnter elif ! _ValidateCronFreqHOURS_ "$hour_choice" then @@ -5770,9 +5870,9 @@ Menu_EditSchedule() while true do ScriptHeader - printf "${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n" - printf "\n${BOLD}Please enter how often in MINUTES to run the ping tests.\n" - printf "Every X minutes, where X is ${GRNct}1-30${CLRct}, (${GRNct}e${CLRct}=Exit)${CLEARFORMAT}: " + printf " ${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n\n" + printf " ${BOLD}Please enter how often in MINUTES to run the ping tests.\n" + printf " Every X minutes, where X is [${GRNct}1-30${CLRct}], (${GRNct}e${CLRct}=Exit)${CLRct}: " read -r mins_choice if [ "$mins_choice" = "e" ] @@ -5783,7 +5883,7 @@ Menu_EditSchedule() if _ValidateCronMINS_ "$cruMins" -quiet || \ _ValidateCronFreqMINS_ "$cruMins" -quiet then echo ; break ; fi - printf "\n${ERR}Please enter a number between 1 and 30${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a number between 1 and 30${CLRct}\n" PressEnter elif ! _ValidateCronFreqMINS_ "$mins_choice" then @@ -5810,9 +5910,9 @@ Menu_EditSchedule() while true do ScriptHeader - printf "${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n" - printf "\n${BOLD}Please enter the HOURS when to run the ping tests.\n" - printf "[${GRNct}0-23${CLRct}], ${GRNct}*${CLRct}=Every hour, or comma-separated hours, (${GRNct}e${CLRct}=Exit)${CLEARFORMAT}: " + printf " ${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n\n" + printf " ${BOLD}Please enter the HOURS when to run the ping tests.\n" + printf " [${GRNct}0-23${CLRct}], ${GRNct}*${CLRct}=Every hour, or comma-separated hours, (${GRNct}e${CLRct}=Exit)${CLRct}: " read -r hour_choice if [ "$hour_choice" = "e" ] @@ -5823,7 +5923,7 @@ Menu_EditSchedule() if _ValidateCronHOURS_ "$cruHour" -quiet || \ _ValidateCronFreqHOURS_ "$cruHour" -quiet then echo ; break ; fi - printf "\n${ERR}Please enter a number between 0 and 23${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a number between 0 and 23${CLRct}\n" PressEnter else if _ValidateCronHOURS_ "$hour_choice" @@ -5875,9 +5975,9 @@ Menu_EditSchedule() while true do ScriptHeader - printf "${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n" - printf "\n${BOLD}Please enter the MINUTES when to run the ping tests.\n" - printf "[${GRNct}0-59${CLRct}], ${GRNct}*${CLRct}=Every minute, or comma-separated minutes, (${GRNct}e${CLRct}=Exit)${CLEARFORMAT}: " + printf " ${BOLD}Current schedule: ${GRNct}$(_GetScheduleHR_ "$cruHour" "$cruMins" "$cruDays")${CLRct}\n\n" + printf " ${BOLD}Please enter the MINUTES when to run the ping tests.\n" + printf " [${GRNct}0-59${CLRct}], ${GRNct}*${CLRct}=Every minute, or comma-separated minutes, (${GRNct}e${CLRct}=Exit)${CLRct}: " read -r mins_choice if [ "$mins_choice" = "e" ] @@ -5888,7 +5988,7 @@ Menu_EditSchedule() if _ValidateCronMINS_ "$cruMins" -quiet || \ _ValidateCronFreqMINS_ "$cruMins" -quiet then echo ; break ; fi - printf "\n${ERR}Please enter a number between 0 and 59${CLEARFORMAT}\n" + printf "\n${ERR}Please enter a number between 0 and 59${CLRct}\n" PressEnter else if _ValidateCronMINS_ "$mins_choice" @@ -5944,8 +6044,8 @@ Menu_EditSchedule() Menu_ResetDB() { printf "${BOLD}${WARN}WARNING: This will reset the %s database by deleting all database records.\n" "$SCRIPT_NAME" - printf "A backup of the database will be created if you change your mind.${CLEARFORMAT}\n" - printf "\n${BOLD}Do you want to continue? (y/n)${CLEARFORMAT} " + printf "A backup of the database will be created if you change your mind.${CLRct}\n" + printf "\n${BOLD}Do you want to continue? (y/n)${CLRct} " read -r confirm case "$confirm" in y|Y) @@ -5953,7 +6053,7 @@ Menu_ResetDB() Reset_DB ;; *) - printf "\n${BOLD}${WARN}Database reset cancelled${CLEARFORMAT}\n\n" + printf "\n${BOLD}${WARN}Database reset cancelled${CLRct}\n\n" ;; esac } From e734c3f5333553f759fadf1a4193bf8d12d0b881 Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Sat, 20 Dec 2025 23:49:05 -0800 Subject: [PATCH 19/20] Update README.md Updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c95e10..8e19742 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # connmon ## v3.0.10 -### Updated on 2025-Dec-16 +### Updated on 2025-Dec-20 ## About connmon is an internet connection monitoring tool for AsusWRT Merlin with charts for daily, weekly and monthly summaries. From 913ffff990e1cf58412725c30f273a5a81c8f17c Mon Sep 17 00:00:00 2001 From: Martinski4GitHub <119833648+Martinski4GitHub@users.noreply.github.com> Date: Sun, 21 Dec 2025 00:33:30 -0800 Subject: [PATCH 20/20] Update README.md Updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e19742..6c06ef3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # connmon ## v3.0.10 -### Updated on 2025-Dec-20 +### Updated on 2025-Dec-21 ## About connmon is an internet connection monitoring tool for AsusWRT Merlin with charts for daily, weekly and monthly summaries.