From bb385155451ff95ce0d70a0bff42e36cd61a73fb Mon Sep 17 00:00:00 2001 From: Baldnerd Date: Tue, 11 Nov 2025 19:42:18 -0500 Subject: [PATCH] Console dashboard improvements. --- installer | 139 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 113 insertions(+), 26 deletions(-) diff --git a/installer b/installer index abccd79..d0af155 100755 --- a/installer +++ b/installer @@ -893,68 +893,103 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { EOF # --------------------------------------------------------------------------- -echo "System Dashboard" +echo "Console Dashboard" # --------------------------------------------------------------------------- cat > /usr/local/sbin/btc-console-dashboard <<'EOF' #!/bin/bash -# Console dashboard for Bitcoin Solo Miner +# Text/ANSI dashboard for Bitcoin Solo Miner (non-blocking, with system stats) BITCOIN_CLI="/usr/local/bin/bitcoin-cli" BITCOIN_CONF="/etc/bitcoin/bitcoin.conf" -DATADIR="/var/lib/bitcoind" +BTC_DIR="/var/lib/bitcoind" # colors RED="\033[31m" GRN="\033[32m" YEL="\033[33m" -BLU="\033[34m" CYN="\033[36m" BOLD="\033[1m" RST="\033[0m" +CONSEC_FAILS=0 +MAX_FAILS=3 +LAST_INFO="" + get_ip() { ip -4 addr show scope global 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1 } +make_bar() { + local pct="$1" + local width="$2" + [ -z "$pct" ] && pct=0 + pct=$(printf "%.1f" "$pct") + # clamp + if (( $(echo "$pct < 0" | bc -l 2>/dev/null || echo 0) )); then pct=0; fi + if (( $(echo "$pct > 100" | bc -l 2>/dev/null || echo 0) )); then pct=100; fi + local filled=$(printf "%.0f" "$(echo "$pct / 100 * $width" | bc -l)") + local empty=$((width - filled)) + printf "[" + for ((i=0; i/dev/null || true tput cup 0 0; echo -e "${BOLD}Bitcoin Node for Solo Miners${RST}" tput cup 1 0; echo -e "A Linux Appliance by Robbie Ferguson" - tput cup 2 0; printf '%*s' "$(tput cols)" '' | tr ' ' '─' + tput cup 2 0; printf '%*s' "$(tput cols)" '' | tr ' ' '-' } -draw_dynamic() { - # args: time ip web status progress services workers +draw_loading() { + tput cup 3 0; echo -e "${YEL}Loading node status…${RST}\033[K" +} + +draw_dashboard() { + # args: + # 1 now 2 ip 3 web 4 status 5 bar 6 progress 7 services 8 cpu 9 mem 10 disk 11 workers local now="$1" local ip="$2" local web="$3" local status="$4" - local progress="$5" - local services="$6" - local workers="$7" + local bar="$5" + local progress="$6" + local services="$7" + local cpu="$8" + local mem="$9" + local disk="${10}" + local workers="${11}" - # line 3 was the bar, so start at 3/4 tput cup 3 0; echo -e "Time: ${CYN}${now}${RST}\033[K" tput cup 4 0; echo -e "IP: ${CYN}${ip}${RST}\033[K" tput cup 5 0; echo -e "Web: ${CYN}${web}${RST}\033[K" - tput cup 6 0; printf '%*s' "$(tput cols)" '' | tr ' ' '─' + tput cup 6 0; printf '%*s' "$(tput cols)" '' | tr ' ' '-' tput cup 7 0; echo -e "${status}\033[K" - tput cup 8 0; echo -e "${progress}\033[K" - tput cup 9 0; echo -e "${services}\033[K" + tput cup 8 0; echo -e "${bar}\033[K" + tput cup 9 0; echo -e "${progress}\033[K" + tput cup 10 0; echo -e "${services}\033[K" - tput cup 10 0; printf '%*s' "$(tput cols)" '' | tr ' ' '─' - tput cup 11 0; echo -e "Workers:\033[K" - tput cup 12 2; echo -e "${workers}\033[K" + tput cup 11 0; printf '%*s' "$(tput cols)" '' | tr ' ' '-' + tput cup 12 0; echo -e "CPU load: ${cpu}\033[K" + tput cup 13 0; echo -e "Memory: ${mem}\033[K" + tput cup 14 0; echo -e "Disk (${BTC_DIR}): ${disk}\033[K" - tput cup 14 0; echo -e "(Appliance console view. Use the web UI for full details.)\033[K" + tput cup 16 0; echo -e "Workers:\033[K" + tput cup 17 2; echo -e "${workers}\033[K" + + tput cup 19 0; echo -e "(Appliance console view — use the web UI for full details.)\033[K" } draw_header +draw_loading + +FIRST_DONE=0 while true; do - # 1) COLLECT DATA FIRST + # -------- collect data (non-blocking) -------- NOW=$(date '+%Y-%m-%d %H:%M') IPADDR=$(get_ip) @@ -966,18 +1001,69 @@ while true; do STATUS_LINE="" PROGRESS_LINE="" + BAR_LINE="[--------------] 0.0%" SERVICES_LINE="Bitcoin: ${BTC_STATE} CKPool: ${CKP_STATE}" WORKERS_LINE="No workers detected (point your ASICs at this node)" - # try to get blockchain info - INFO=$($BITCOIN_CLI -conf="$BITCOIN_CONF" getblockchaininfo 2>/dev/null) + # cpu load + if [ -r /proc/loadavg ]; then + read -r L1 L5 L15 _ < /proc/loadavg + CPU_LINE="${L1} ${L5} ${L15}" + else + CPU_LINE="n/a" + fi + + # memory + if [ -r /proc/meminfo ]; then + MEM_TOTAL=$(awk '/MemTotal:/{print $2}' /proc/meminfo) + MEM_AVAIL=$(awk '/MemAvailable:/{print $2}' /proc/meminfo) + if [ -n "$MEM_TOTAL" ] && [ -n "$MEM_AVAIL" ]; then + MEM_USED=$((MEM_TOTAL - MEM_AVAIL)) + MEM_PCT=$((MEM_USED * 100 / MEM_TOTAL)) + MEM_LINE="$(printf "%dMiB / %dMiB (%d%% used)" "$((MEM_USED/1024))" "$((MEM_TOTAL/1024))" "$MEM_PCT")" + else + MEM_LINE="n/a" + fi + else + MEM_LINE="n/a" + fi + + # disk + if df -h "$BTC_DIR" >/dev/null 2>&1; then + read -r _ SIZE USED AVAIL USEP MNT <<< "$(df -h "$BTC_DIR" | awk 'NR==2{print $1,$2,$3,$4,$5,$6}')" + DISK_LINE="${AVAIL} free of ${SIZE} (${USEP} used)" + else + DISK_LINE="n/a" + fi + + # bitcoin-cli, but don't let it hang + INFO=$(timeout 15 "$BITCOIN_CLI" -conf="$BITCOIN_CONF" getblockchaininfo 2>/dev/null) + + if [ -z "$INFO" ]; then + # failed this round + CONSEC_FAILS=$((CONSEC_FAILS + 1)) + # if we have an older good value, reuse it + if [ -n "$LAST_INFO" ]; then + INFO="$LAST_INFO" + fi + else + # success – store and reset fail counter + LAST_INFO="$INFO" + CONSEC_FAILS=0 + fi if [ "$BTC_STATE" != "active" ]; then STATUS_LINE="${RED}❌ Bitcoin service is not running.${RST}" elif [ -z "$INFO" ]; then - STATUS_LINE="${RED}❌ bitcoin-cli did not respond.${RST}" + if [ $CONSEC_FAILS -ge $MAX_FAILS ]; then + STATUS_LINE="${RED}❌ bitcoin-cli has not responded for several checks.${RST}" + BAR_LINE="[--------------] 0.0%" + PROGRESS_LINE="" + else + # transient hiccup — keep showing last good data, or at least don't scream + STATUS_LINE="${YEL}⚠ Waiting for Bitcoin Core…${RST}" + fi else - # we have info; parse it if command -v jq >/dev/null 2>&1; then IBD=$(echo "$INFO" | jq -r '.initialblockdownload') BLOCKS=$(echo "$INFO" | jq -r '.blocks') @@ -992,7 +1078,6 @@ while true; do fi if [ "$IBD" = "true" ]; then - # still syncing if [ "$(echo "$PROG_PCT < 0.1" | bc -l 2>/dev/null || echo 0)" = "1" ]; then STATUS_LINE="${YEL}⚠ Bitcoin Core is starting up and loading blockchain data…${RST}" else @@ -1003,14 +1088,16 @@ while true; do fi PROGRESS_LINE="Blocks: ${BLOCKS} / ${HEADERS} $( [ "$PRUNED" = "true" ] && echo '(pruned)' )" + BAR_LINE=$(make_bar "$PROG_PCT" 30) else STATUS_LINE="${CYN}ℹ Bitcoin Core is active (install jq for more detail).${RST}" fi fi - # 2) NOW DRAW (single block) - draw_dynamic "$NOW" "$IPADDR" "$WEB" "$STATUS_LINE" "$PROGRESS_LINE" "$SERVICES_LINE" "$WORKERS_LINE" + # -------- draw -------- + draw_dashboard "$NOW" "$IPADDR" "$WEB" "$STATUS_LINE" "$BAR_LINE" "$PROGRESS_LINE" "$SERVICES_LINE" "$CPU_LINE" "$MEM_LINE" "$DISK_LINE" "$WORKERS_LINE" + FIRST_DONE=1 sleep 5 done EOF