Console dashboard improvements.

This commit is contained in:
2025-11-11 19:42:18 -05:00
parent c8052b8e01
commit bb38515545

139
installer
View File

@ -893,68 +893,103 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
EOF EOF
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
echo "System Dashboard" echo "Console Dashboard"
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
cat > /usr/local/sbin/btc-console-dashboard <<'EOF' cat > /usr/local/sbin/btc-console-dashboard <<'EOF'
#!/bin/bash #!/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_CLI="/usr/local/bin/bitcoin-cli"
BITCOIN_CONF="/etc/bitcoin/bitcoin.conf" BITCOIN_CONF="/etc/bitcoin/bitcoin.conf"
DATADIR="/var/lib/bitcoind" BTC_DIR="/var/lib/bitcoind"
# colors # colors
RED="\033[31m" RED="\033[31m"
GRN="\033[32m" GRN="\033[32m"
YEL="\033[33m" YEL="\033[33m"
BLU="\033[34m"
CYN="\033[36m" CYN="\033[36m"
BOLD="\033[1m" BOLD="\033[1m"
RST="\033[0m" RST="\033[0m"
CONSEC_FAILS=0
MAX_FAILS=3
LAST_INFO=""
get_ip() { get_ip() {
ip -4 addr show scope global 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1 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<filled; i++)); do printf "█"; done
for ((i=0; i<empty; i++)); do printf "-"; done
printf "] %s%%" "$pct"
}
draw_header() { draw_header() {
tput clear tput clear
tput civis 2>/dev/null || true tput civis 2>/dev/null || true
tput cup 0 0; echo -e "${BOLD}Bitcoin Node for Solo Miners${RST}" 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 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() { draw_loading() {
# args: time ip web status progress services workers 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 now="$1"
local ip="$2" local ip="$2"
local web="$3" local web="$3"
local status="$4" local status="$4"
local progress="$5" local bar="$5"
local services="$6" local progress="$6"
local workers="$7" 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 3 0; echo -e "Time: ${CYN}${now}${RST}\033[K"
tput cup 4 0; echo -e "IP: ${CYN}${ip}${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 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 7 0; echo -e "${status}\033[K"
tput cup 8 0; echo -e "${progress}\033[K" tput cup 8 0; echo -e "${bar}\033[K"
tput cup 9 0; echo -e "${services}\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; printf '%*s' "$(tput cols)" '' | tr ' ' '-'
tput cup 11 0; echo -e "Workers:\033[K" tput cup 12 0; echo -e "CPU load: ${cpu}\033[K"
tput cup 12 2; echo -e "${workers}\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_header
draw_loading
FIRST_DONE=0
while true; do while true; do
# 1) COLLECT DATA FIRST # -------- collect data (non-blocking) --------
NOW=$(date '+%Y-%m-%d %H:%M') NOW=$(date '+%Y-%m-%d %H:%M')
IPADDR=$(get_ip) IPADDR=$(get_ip)
@ -966,18 +1001,69 @@ while true; do
STATUS_LINE="" STATUS_LINE=""
PROGRESS_LINE="" PROGRESS_LINE=""
BAR_LINE="[--------------] 0.0%"
SERVICES_LINE="Bitcoin: ${BTC_STATE} CKPool: ${CKP_STATE}" SERVICES_LINE="Bitcoin: ${BTC_STATE} CKPool: ${CKP_STATE}"
WORKERS_LINE="No workers detected (point your ASICs at this node)" WORKERS_LINE="No workers detected (point your ASICs at this node)"
# try to get blockchain info # cpu load
INFO=$($BITCOIN_CLI -conf="$BITCOIN_CONF" getblockchaininfo 2>/dev/null) 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 if [ "$BTC_STATE" != "active" ]; then
STATUS_LINE="${RED}❌ Bitcoin service is not running.${RST}" STATUS_LINE="${RED}❌ Bitcoin service is not running.${RST}"
elif [ -z "$INFO" ]; then 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 else
# we have info; parse it
if command -v jq >/dev/null 2>&1; then if command -v jq >/dev/null 2>&1; then
IBD=$(echo "$INFO" | jq -r '.initialblockdownload') IBD=$(echo "$INFO" | jq -r '.initialblockdownload')
BLOCKS=$(echo "$INFO" | jq -r '.blocks') BLOCKS=$(echo "$INFO" | jq -r '.blocks')
@ -992,7 +1078,6 @@ while true; do
fi fi
if [ "$IBD" = "true" ]; then if [ "$IBD" = "true" ]; then
# still syncing
if [ "$(echo "$PROG_PCT < 0.1" | bc -l 2>/dev/null || echo 0)" = "1" ]; then 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}" STATUS_LINE="${YEL}⚠ Bitcoin Core is starting up and loading blockchain data…${RST}"
else else
@ -1003,14 +1088,16 @@ while true; do
fi fi
PROGRESS_LINE="Blocks: ${BLOCKS} / ${HEADERS} $( [ "$PRUNED" = "true" ] && echo '(pruned)' )" PROGRESS_LINE="Blocks: ${BLOCKS} / ${HEADERS} $( [ "$PRUNED" = "true" ] && echo '(pruned)' )"
BAR_LINE=$(make_bar "$PROG_PCT" 30)
else else
STATUS_LINE="${CYN} Bitcoin Core is active (install jq for more detail).${RST}" STATUS_LINE="${CYN} Bitcoin Core is active (install jq for more detail).${RST}"
fi fi
fi fi
# 2) NOW DRAW (single block) # -------- draw --------
draw_dynamic "$NOW" "$IPADDR" "$WEB" "$STATUS_LINE" "$PROGRESS_LINE" "$SERVICES_LINE" "$WORKERS_LINE" 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 sleep 5
done done
EOF EOF