Files
embemetrics/app.py
2025-10-26 17:24:37 +02:00

148 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import Flask, render_template
import psutil
import paramiko
import json
from collections import defaultdict
from datetime import datetime
from database import TemperatureDB
app = Flask(__name__)
CONFIG_FILE = "config.json"
db = TemperatureDB()
# Зберігаємо історію температур (останні 20 значень для кожного пристрою)
temperature_history = defaultdict(lambda: {'gpu': [], 'cpu': [], 'timestamps': []})
MAX_HISTORY = 20
def load_config(file_path):
"""Завантаження налаштувань з JSON файлу."""
try:
with open(file_path, "r") as file:
return json.load(file)
except Exception as e:
print(f"Помилка завантаження конфігурації: {e}")
return {"devices": []}
def get_remote_temperature(host, username, password):
"""Підключення до Raspberry Pi через SSH та отримання температури."""
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=host, username=username, password=password)
# Отримуємо hostname
stdin, stdout, stderr = client.exec_command("hostname")
hostname = stdout.read().decode().strip()
# Перевіряємо модель Raspberry Pi
stdin, stdout, stderr = client.exec_command("cat /proc/cpuinfo | grep Model")
model_info = stdout.read().decode().strip()
is_pi5 = "Raspberry Pi 5" in model_info
# Вибираємо правильну команду залежно від моделі
if is_pi5:
temp_command = "vcgencmd measure_temp"
stdin, stdout, stderr = client.exec_command(temp_command)
output = stdout.read().decode().strip()
temp_value = float(output.replace("temp=", "").replace("'C", ""))
# Отримуємо додаткову інформацію про процесор
stdin, stdout, stderr = client.exec_command("cat /sys/class/thermal/thermal_zone0/temp")
cpu_temp = float(stdout.read().decode().strip()) / 1000
client.close()
return {
'temp': temp_value,
'cpu_temp': cpu_temp,
'model': 'Raspberry Pi 5',
'status': 'OK',
'hostname': hostname
}
else:
client.close()
return {
'temp': None,
'cpu_temp': None,
'model': model_info if model_info else 'Unknown',
'status': 'Unsuported device',
'hostname': hostname
}
except Exception as e:
print(f"Помилка підключення до {host}: {e}")
return {
'temp': None,
'cpu_temp': None,
'model': 'Unknown',
'status': f'Error: {str(e)}',
'hostname': 'Unknown'
}
@app.route('/')
def index():
temperatures = []
current_time = datetime.now().strftime('%H:%M:%S')
# Очищення старих записів при кожному запиті
db.cleanup_old_records()
# Отримуємо віддалені температури
config = load_config(CONFIG_FILE)
for device in config.get("devices", []):
host = device.get("host")
username = device.get("username")
password = device.get("password")
if host and username and password:
temp_data = get_remote_temperature(host, username, password)
if temp_data['temp'] is not None:
# Отримуємо історію з бази даних
history = db.get_history(host)
temperatures.append({
'name': f"Raspberry Pi 5: {host}",
'value': round(temp_data['temp'], 1),
'cpu': round(temp_data['cpu_temp'], 1),
'status': temp_data['status'],
'hostname': temp_data['hostname'],
'history': history
})
else:
temperatures.append({
'name': f"Пристрій: {host}",
'value': f"Помилка: {temp_data['status']}",
'cpu': 'Н',
'status': 'Error',
'hostname': temp_data['hostname']
})
return render_template('index.html',
temperatures=temperatures,
current_time=current_time)
@app.route('/graphs')
def graphs():
devices = []
config = load_config(CONFIG_FILE)
for device in config.get("devices", []):
host = device.get("host")
username = device.get("username")
password = device.get("password")
if host and username and password:
# Отримуємо hostname
temp_data = get_remote_temperature(host, username, password)
history = db.get_history(host)
devices.append({
'host': host,
'hostname': temp_data['hostname'],
'history': history
})
return render_template('graphs.html', devices=devices)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8080)