Категории

Мониторинг состояния Raspberry Pi (температура, CPU, память, диск)

10.08.2025 17:14 | коды из категории: IOT умный дом

Мониторинг состояния Raspberry Pi в домашней автоматизации и самописном хомасистенте

про Мониторинг состояния Raspberry Pi (температура, CPU, память, диск)

Вот комплексное решение для мониторинга состояния Raspberry Pi (или Ubuntu) с интеграцией в PHP и MQTT.

Bash-скрипт для сбора данных (rpi_monitor.sh)

#!/bin/bash

# Конфигурация
MYSQL_USER="ваш_пользователь_mysql"
MYSQL_PASS="ваш_пароль_mysql"
MYSQL_DB="ваша_база_данных"
MQTT_TOPIC="homeassistant/rpi_monitor"
MQTT_HOST="localhost"

# Получаем данные о системе
# Температура CPU
CPU_TEMP=$(vcgencmd measure_temp | cut -d= -f2 | cut -d\' -f1)
[ -z "$CPU_TEMP" ] && CPU_TEMP=$(cat /sys/class/thermal/thermal_zone0/temp | awk '{print $1/1000}')

# Загрузка CPU
CPU_LOAD=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')

# Использование памяти
MEM_TOTAL=$(free -m | awk '/Mem:/ {print $2}')
MEM_USED=$(free -m | awk '/Mem:/ {print $3}')
MEM_PERCENT=$(free | awk '/Mem:/ {printf("%.1f"), $3/$2*100}')

# Использование диска
DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')

# Uptime системы
UPTIME=$(uptime -p)

# IP-адреса
IP_ADDRESSES=$(hostname -I | tr '\n' ' ')

# Формируем JSON для MQTT
JSON_DATA=$(jq -n \
  --arg cpu_temp "$CPU_TEMP" \
  --arg cpu_load "$CPU_LOAD" \
  --arg mem_total "$MEM_TOTAL" \
  --arg mem_used "$MEM_USED" \
  --arg mem_percent "$MEM_PERCENT" \
  --arg disk_usage "$DISK_USAGE" \
  --arg uptime "$UPTIME" \
  --arg ip_addresses "$IP_ADDRESSES" \
  '{
    "cpu_temp": $cpu_temp,
    "cpu_load": $cpu_load,
    "mem_total": $mem_total,
    "mem_used": $mem_used,
    "mem_percent": $mem_percent,
    "disk_usage": $disk_usage,
    "uptime": $uptime,
    "ip_addresses": $ip_addresses,
    "timestamp": now | todate
  }')

# Отправляем в MQTT
mosquitto_pub -h $MQTT_HOST -t $MQTT_TOPIC -m "$JSON_DATA"

# Записываем в MySQL
mysql -u $MYSQL_USER -p$MYSQL_PASS $MYSQL_DB <<EOF
INSERT INTO rpi_monitor (
  cpu_temp, cpu_load, mem_total, mem_used, mem_percent, 
  disk_usage, uptime, ip_addresses, timestamp
) VALUES (
  '$CPU_TEMP', '$CPU_LOAD', '$MEM_TOTAL', '$MEM_USED', '$MEM_PERCENT',
  '$DISK_USAGE', '$UPTIME', '$IP_ADDRESSES', NOW()
);
EOF

PHP-страница для отображения данных

<?php
// config.php
$db_host = 'localhost';
$db_user = 'ваш_пользователь_mysql';
$db_pass = 'ваш_пароль_mysql';
$db_name = 'ваша_база_данных';

// Подключение к БД
$conn = new mysqli($db_host, $db_user, $db_pass, $db_name);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// Получаем последние данные
$sql = "SELECT * FROM rpi_monitor ORDER BY timestamp DESC LIMIT 1";
$result = $conn->query($sql);
$rpi_data = $result->fetch_assoc();

// Закрываем соединение
$conn->close();
?>

<!DOCTYPE html>
<html>
<head>
    <title>Raspberry Pi Monitor</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            background-color: #f5f5f5;
        }
        .dashboard {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
        }
        .card {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .critical {
            color: #e74c3c;
            font-weight: bold;
        }
        .warning {
            color: #f39c12;
        }
        .ok {
            color: #2ecc71;
        }
        h1 {
            color: #2c3e50;
        }
        .progress-container {
            width: 100%;
            background-color: #e0e0e0;
            border-radius: 5px;
            margin: 10px 0;
        }
        .progress-bar {
            height: 20px;
            border-radius: 5px;
            background-color: #3498db;
            text-align: center;
            color: white;
            line-height: 20px;
        }
    </style>
</head>
<body>
    <h1>Raspberry Pi Monitoring</h1>
    <p>Last update: <?php echo htmlspecialchars($rpi_data['timestamp'] ?? 'Never'); ?></p>
    
    <div class="dashboard">
        <!-- CPU Card -->
        <div class="card">
            <h2>CPU</h2>
            <p>Temperature: 
                <span class="<?php 
                    $temp = $rpi_data['cpu_temp'] ?? 0;
                    if ($temp > 70) echo 'critical';
                    elseif ($temp > 60) echo 'warning';
                    else echo 'ok';
                ?>">
                <?php echo htmlspecialchars($temp); ?>°C
                </span>
            </p>
            <p>Load: <?php echo htmlspecialchars($rpi_data['cpu_load'] ?? 'N/A'); ?>%</p>
            <div class="progress-container">
                <div class="progress-bar" style="width: <?php echo min(100, $rpi_data['cpu_load'] ?? 0); ?>%">
                    <?php echo min(100, $rpi_data['cpu_load'] ?? 0); ?>%
                </div>
            </div>
        </div>
        
        <!-- Memory Card -->
        <div class="card">
            <h2>Memory</h2>
            <p>Used: <?php echo htmlspecialchars($rpi_data['mem_used'] ?? 'N/A'); ?>MB / 
                <?php echo htmlspecialchars($rpi_data['mem_total'] ?? 'N/A'); ?>MB</p>
            <p>Usage: <?php echo htmlspecialchars($rpi_data['mem_percent'] ?? 'N/A'); ?>%</p>
            <div class="progress-container">
                <div class="progress-bar" style="width: <?php echo min(100, $rpi_data['mem_percent'] ?? 0); ?>%">
                    <?php echo min(100, $rpi_data['mem_percent'] ?? 0); ?>%
                </div>
            </div>
        </div>
        
        <!-- Disk Card -->
        <div class="card">
            <h2>Disk</h2>
            <p>Usage: <?php echo htmlspecialchars($rpi_data['disk_usage'] ?? 'N/A'); ?>%</p>
            <div class="progress-container">
                <div class="progress-bar" style="width: <?php echo min(100, $rpi_data['disk_usage'] ?? 0); ?>%">
                    <?php echo min(100, $rpi_data['disk_usage'] ?? 0); ?>%
                </div>
            </div>
        </div>
        
        <!-- System Info Card -->
        <div class="card">
            <h2>System Info</h2>
            <p>Uptime: <?php echo htmlspecialchars($rpi_data['uptime'] ?? 'N/A'); ?></p>
            <p>IP Addresses: <?php echo htmlspecialchars($rpi_data['ip_addresses'] ?? 'N/A'); ?></p>
        </div>
    </div>
</body>
</html>

SQL для создания таблицы

CREATE TABLE rpi_monitor (
  id INT AUTO_INCREMENT PRIMARY KEY,
  cpu_temp DECIMAL(5,2),
  cpu_load DECIMAL(5,2),
  mem_total INT,
  mem_used INT,
  mem_percent DECIMAL(5,2),
  disk_usage INT,
  uptime VARCHAR(100),
  ip_addresses VARCHAR(255),
  timestamp DATETIME
);

Настройка cron
Добавьте в cron для регулярного выполнения (например, каждые 5 минут):

bash

(crontab -l ; echo "*/5 * * * * /путь/к/rpi_monitor.sh") | crontab -

Интеграция с Home Assistant через MQTT
Добавьте в configuration.yaml:

sensor:
  - platform: mqtt
    name: "RPI CPU Temperature"
    state_topic: "homeassistant/rpi_monitor"
    value_template: "{{ value_json.cpu_temp }}"
    unit_of_measurement: "°C"
    
  - platform: mqtt
    name: "RPI CPU Load"
    state_topic: "homeassistant/rpi_monitor"
    value_template: "{{ value_json.cpu_load }}"
    unit_of_measurement: "%"
    
  - platform: mqtt
    name: "RPI Memory Usage"
    state_topic: "homeassistant/rpi_monitor"
    value_template: "{{ value_json.mem_percent }}"
    unit_of_measurement: "%"
    
  - platform: mqtt
    name: "RPI Disk Usage"
    state_topic: "homeassistant/rpi_monitor"
    value_template: "{{ value_json.disk_usage }}"
    unit_of_measurement: "%"

В этой статье я расскажу, как реализовал комплексный мониторинг состояния Raspberry Pi, который является сердцем моей системы домашней автоматизации.

Какие параметры мы будем отслеживать?

Реализация мониторинга

1. Bash-скрипт для сбора данных

Основой системы является bash-скрипт, который собирает все необходимые метрики:

#!/bin/bash

# Температура CPU
CPU_TEMP=$(vcgencmd measure_temp | cut -d= -f2 | cut -d\' -f1)

# Загрузка CPU
CPU_LOAD=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')

# Использование памяти
MEM_TOTAL=$(free -m | awk '/Mem:/ {print $2}')
MEM_USED=$(free -m | awk '/Mem:/ {print $3}')

2. Визуализация данных

Для отображения данных я создал простую, но информативную PHP-страницу:

CPU

Temperature: 47.2°C

Load: 12%

Memory

Used: 450MB / 900MB

Usage: 50%

3. Интеграция с Home Assistant

Данные отправляются в MQTT и могут быть легко интегрированы в Home Assistant:

sensor:
  - platform: mqtt
    name: "RPI CPU Temperature"
    state_topic: "homeassistant/rpi_monitor"
    value_template: "{{ value_json.cpu_temp }}"
    unit_of_measurement: "°C"

Настройка автоматического выполнения

Скрипт настроен на выполнение каждые 5 минут через cron:

*/5 * * * * /путь/к/rpi_monitor.sh

Заключение

Реализованная система мониторинга позволяет:

В будущем планирую добавить мониторинг отдельных сервисов и автоматические действия при критических состояниях.


Для доступа к температуре без sudo добавьте пользователя в группу video:
sudo usermod -a -G video ваш_пользователь
Установите необходимые пакеты:
sudo apt install jq mosquitto-clients mysql-client
# Проверка критической температуры
if (( $(echo "$CPU_TEMP > 70" | bc -l) )); then
  # Отправить уведомление (например, через Telegram)
  /путь/к/send_alert.sh "CRITICAL: CPU temperature is $CPU_TEMP°C"
fi

Теги: #PHP #Ubuntu #server #MQTT #raspberry pi #мониторинг #bash #status

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

← Назад к списку

Важно: Блог-эксперимент

Блог только запустил, все статьи генерирую через нейросеть т.к. лень, возможны ошибки. Просто чтобы вы знали и не запускали ядерный реактор по моим статьям ))
Если у вас есть вопросы, или Нашли неточность? пишите в коментах — вместе поправим и сделаем статью более качественной. Я лично объясню нюансы из практики.

Посетителей сегодня: 0


кто я | книга | контакты без контактов

© Digital Specialist | Не являемся сотрудниками Google, Яндекса и NASA