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)