1st commit

This commit is contained in:
2025-10-05 15:41:11 +02:00
commit 2f8f75dfa1
8 changed files with 251 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.tmp

20
LICENSE Normal file
View File

@@ -0,0 +1,20 @@
MIT License
Copyright (c) 2025 > Djeex
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

82
README.MD Normal file
View File

@@ -0,0 +1,82 @@
# HotDisk
A lightweight Linux tool that monitors **SATA HDD temperatures**, sends **Discord notifications**, and safely shuts down the system if disks overheat.
> [!NOTE]
>_HotDisk focuses on SATA disks (NVMe ignored). The repo contains installer scripts, systemd integration, and log rotation setup._
> _Github repo is a mirror of https://git.djeex.fr/Djeex/hotdisk. You'll find full package, history and release note there._
## 📌 Table of Contents
- [✨ Features](#-features)
- [📜 Script Installation (Debian/Ubuntu)](#-script-installation-debianubuntu)
- [⚙️ Configuration Variables](#-configuration-variables)
- [🐞 Common issues](#-common-issues)
- [❓ How it works](#-how-it-works)
- [🧑‍💻 Contributors](#-contributors)
## ✨ Features
- Monitors SATA disk temperatures using SMART (`smartctl`).
- Configurable maximum temperature threshold.
- Counts consecutive minutes above or below threshold before notifications or shutdown.
- Sends Discord notifications when disks exceed or drop below the threshold.
- Sends pre-shutdown warning before executing system shutdown.
- Configurable logging with automatic log rotation.
- Runs as a **systemd service + timer** for continuous monitoring.
## 📜 Script Installation (Debian/Ubuntu)
**Requirements**
- `bash`, `smartmontools`, `curl`, `lsblk` (Debian/Ubuntu default)
- `systemd` & `sudo`
**Quick Install with Curl**
```bash
curl -fsSL https://git.djeex.fr/Djeex/hotdisk/raw/branch/main/sh/hotdisk_curl_install.sh | bash
```
The installer will:
- Prompt for configuration: max temperature, cooldown, Discord webhook, log file, logrotate settings.
- Check and install missing dependencies.
- Generate logrotate configuration.
- Install and enable systemd service + timer.
- Run HotDisk immediately for testing.
**Check Logs**
```bash
tail -f /var/log/hdd_temp_monitor.log
```
## ⚙️ Configuration Variables
| Variable | Description | Default Value |
|-----------------------|-----------------------------------------------------------------|-----------------------------------------------|
| `MAX_TEMP` | Maximum allowed temperature (°C) before starting shutdown count | `60` |
| `HOT_DURATION` | Consecutive minutes above `MAX_TEMP` before shutdown | `5` |
| `COOL_DURATION` | Consecutive minutes below `MAX_TEMP` required to reset counter | `5` |
| `LOG_FILE` | Path to the main log file | `/var/log/hdd_temp_monitor.log` |
| `LOG_ROTATE_COUNT` | Number of log files to keep | `7` |
| `LOG_ROTATE_PERIOD` | Rotation period for logs (`daily` or `weekly`) | `daily` |
| `DISCORD_WEBHOOK` | Discord webhook URL for notifications | _Required_ |
Configuration is stored in `/etc/hdd_temp_monitor.conf` and is created by the installer.
## 🐞 Common issues
- `smartctl` may fail if SATA disks do not support SMART.
- Incorrect Discord webhook URL: double-check for typos.
- Installer requires `sudo` privileges for shutdown, log creation, and systemd services.
## ❓ How it works
1. The script reads SMART temperature for all SATA disks every minute.
2. Counts consecutive minutes above/below threshold.
3. Sends Discord notifications if threshold exceeded or cooled.
4. Initiates system shutdown if temperature exceeds limit for configured duration.
5. Logs all temperatures and counter states, rotates logs automatically.

1
VERSION Normal file
View File

@@ -0,0 +1 @@
0.1.0

46
sh/hotdisk.sh Normal file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
# HotDisk: Monitor SATA disk temperature and notify via Discord
CONF_FILE="/etc/hdd_temp_monitor.conf"
STATE_FILE="/tmp/hdd_temp_state.txt"
source "$CONF_FILE"
DISKS=$(lsblk -dno NAME,TYPE | awk '$2=="disk"{print $1}' | grep -v '^nvme')
if [ ! -f "$STATE_FILE" ]; then touch "$STATE_FILE"; fi
declare -A HOT_COUNTERS
declare -A COOL_COUNTERS
while read -r line; do
disk=$(echo "$line" | cut -d= -f1)
val=$(echo "$line" | cut -d= -f2)
HOT_COUNTERS[$disk]=$val
done < "$STATE_FILE"
for disk in $DISKS; do
temp=$(smartctl -A /dev/$disk | awk '/Temperature_Celsius/ {print $10; exit}')
[ -z "$temp" ] && continue
hot=${HOT_COUNTERS[$disk]:-0}
cool=${COOL_COUNTERS[$disk]:-0}
if [ "$temp" -ge "$MAX_TEMP" ]; then
hot=$((hot+1))
cool=0
curl -s -X POST -H "Content-Type: application/json" -d "{\"content\":\"🔥 Warning: $disk is above $MAX_TEMP°C for $hot minute(s)\"}" "$DISCORD_WEBHOOK"
if [ "$hot" -ge "$HOT_DURATION" ]; then
curl -s -X POST -H "Content-Type: application/json" -d "{\"content\":\"⚠️ Critical: $disk has been above $MAX_TEMP°C for $HOT_DURATION minutes. Shutting down...\"}" "$DISCORD_WEBHOOK"
sleep 5
shutdown -h now
fi
else
if [ "$hot" -gt 0 ]; then
cool=$((cool+1))
curl -s -X POST -H "Content-Type: application/json" -d "{\"content\":\"❄️ Notice: $disk is under $MAX_TEMP°C for $cool minute(s)\"}" "$DISCORD_WEBHOOK"
if [ "$cool" -ge "$COOL_DURATION" ]; then
hot=0
cool=0
fi
fi
fi
HOT_COUNTERS[$disk]=$hot
COOL_COUNTERS[$disk]=$cool
echo "$(date '+%Y-%m-%d %H:%M:%S') $disk $temp°C" >> "$LOG_FILE"
done
> "$STATE_FILE"
for disk in "${!HOT_COUNTERS[@]}"; do
echo "$disk=${HOT_COUNTERS[$disk]}" >> "$STATE_FILE"
done

View File

@@ -0,0 +1,11 @@
#!/bin/bash
BASE_URL="https://git.djeex.fr/Djeex/hotdisk/raw/branch/main/sh"
SCRIPTS=("hotdisk.sh" "hotdisk_logger.sh" "install_hotdisk.sh")
sudo apt update
sudo apt install -y smartmontools curl
sudo mkdir -p /usr/local/bin
for script in "${SCRIPTS[@]}"; do
sudo curl -fsSL "$BASE_URL/$script" -o "/usr/local/bin/$script"
sudo chmod +x "/usr/local/bin/$script"
done
sudo /usr/local/bin/install_hotdisk.sh

15
sh/hotdisk_logger.sh Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
CONF_FILE="/etc/hdd_temp_monitor.conf"
source "$CONF_FILE"
LOGROTATE_FILE="/etc/logrotate.d/hotdisk"
sudo tee "$LOGROTATE_FILE" > /dev/null <<EOF
$LOG_FILE {
$LOG_ROTATE_PERIOD
rotate $LOG_ROTATE_COUNT
compress
missingok
notifempty
copytruncate
}
EOF
echo "Logrotate configuration generated at $LOGROTATE_FILE"

75
sh/install_hotdisk.sh Normal file
View File

@@ -0,0 +1,75 @@
#!/bin/bash
CONFIG_FILE=/etc/hdd_temp_monitor.conf
SERVICE_FILE=/etc/systemd/system/hotdisk.service
TIMER_FILE=/etc/systemd/system/hotdisk.timer
echo "=== HotDisk Installation ==="
DEPENDENCIES=(bash smartctl curl lsblk awk date tee sudo systemctl)
MISSING=()
for cmd in "${DEPENDENCIES[@]}"; do
if ! command -v "$cmd" >/dev/null 2>&1; then MISSING+=("$cmd"); fi
done
if [ ${#MISSING[@]} -ne 0 ]; then
echo "❌ Missing dependencies:"
for cmd in "${MISSING[@]}"; do echo " - $cmd"; done
echo "Install missing packages: sudo apt update && sudo apt install smartmontools curl"
exit 1
fi
echo "✅ All dependencies are installed."
read -p "Maximum temperature (°C) before shutdown [60]: " MAX_TEMP
MAX_TEMP=${MAX_TEMP:-60}
read -p "Consecutive minutes above MAX_TEMP before shutdown [5]: " HOT_DURATION
HOT_DURATION=${HOT_DURATION:-5}
read -p "Consecutive minutes below MAX_TEMP to reset counter [5]: " COOL_DURATION
COOL_DURATION=${COOL_DURATION:-5}
read -p "Log file path [/var/log/hdd_temp_monitor.log]: " LOG_FILE
LOG_FILE=${LOG_FILE:-/var/log/hdd_temp_monitor.log}
read -p "Logrotate: number of files to keep [7]: " LOG_ROTATE_COUNT
LOG_ROTATE_COUNT=${LOG_ROTATE_COUNT:-7}
read -p "Logrotate: rotation period (daily/weekly) [daily]: " LOG_ROTATE_PERIOD
LOG_ROTATE_PERIOD=${LOG_ROTATE_PERIOD:-daily}
echo "Paste your Discord Webhook URL here."
read -p "Discord Webhook URL: " DISCORD_WEBHOOK
[ -z "$DISCORD_WEBHOOK" ] && { echo "Discord Webhook cannot be empty"; exit 1; }
echo ""
echo "Please confirm:"
echo "MAX_TEMP=$MAX_TEMP"
echo "HOT_DURATION=$HOT_DURATION"
echo "COOL_DURATION=$COOL_DURATION"
echo "LOG_FILE=$LOG_FILE"
echo "LOG_ROTATE_COUNT=$LOG_ROTATE_COUNT"
echo "LOG_ROTATE_PERIOD=$LOG_ROTATE_PERIOD"
echo "DISCORD_WEBHOOK=$DISCORD_WEBHOOK"
read -p "Is this correct? (y/n): " CONFIRM
[[ ! "$CONFIRM" =~ ^[Yy]$ ]] && { echo "Aborted"; exit 1; }
sudo tee "$CONFIG_FILE" > /dev/null <<EOF
MAX_TEMP=$MAX_TEMP
HOT_DURATION=$HOT_DURATION
COOL_DURATION=$COOL_DURATION
LOG_FILE=$LOG_FILE
LOG_ROTATE_COUNT=$LOG_ROTATE_COUNT
LOG_ROTATE_PERIOD=$LOG_ROTATE_PERIOD
DISCORD_WEBHOOK=$DISCORD_WEBHOOK
EOF
sudo chmod +x /usr/local/bin/sh/hotdisk.sh /usr/local/bin/sh/hotdisk_logger.sh
sudo /usr/local/bin/sh/hotdisk_logger.sh
sudo tee "$SERVICE_FILE" > /dev/null <<EOF
[Unit]
Description=HotDisk SATA Temperature Check
[Service]
Type=oneshot
ExecStart=/usr/local/bin/sh/hotdisk.sh
EOF
sudo tee "$TIMER_FILE" > /dev/null <<EOF
[Unit]
Description=Run HotDisk temperature check every minute
[Timer]
OnBootSec=1min
OnUnitActiveSec=1min
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now hotdisk.timer
sudo /usr/local/bin/sh/hotdisk.sh
echo "✅ HotDisk installation complete!"