import tkinter as tk
from tkinter import ttk
import serial
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from collections import deque
import threading
import time

# Настройки COM-порта
COM_PORT = 'COM4'  # Замените на ваш COM-порт
BAUD_RATE = 9600

# Данные для графиков
temperature_data_hour = deque(maxlen=3600)  # Хранит данные за последний час
humidity_data_hour = deque(maxlen=3600)
temperature_data_day = deque(maxlen=86400)  # Хранит данные за сутки
humidity_data_day = deque(maxlen=86400)
time_data_hour = deque(maxlen=3600)
time_data_day = deque(maxlen=86400)

# Создание графического интерфейса
root = tk.Tk()
root.title("Данные с датчика BME280")

# Текущие данные
current_temperature = tk.StringVar()
current_humidity = tk.StringVar()


# Функция для получения данных из COM-порта
def read_serial():
    with serial.Serial(COM_PORT, BAUD_RATE, timeout=1) as ser:
        while True:
            line = ser.readline().decode('utf-8').strip()  # Чтение строки из порта
            if line:
                temperature, humidity = parse_data(line)  # Парсинг данных
                if temperature is not None and humidity is not None:
                    update_graphs(temperature, humidity)
            time.sleep(2)  # Задержка между чтениями


def parse_data(data):
    try:
        # Извлечение температуры и влажности из строки
        temp_str, hum_str = data.split(",")  # Получаем части строки
        temperature = float(temp_str.split(":")[1].strip().replace(" °C", ""))
        humidity = float(hum_str.split(":")[1].strip().replace(" %", ""))
        return temperature, humidity
    except (IndexError, ValueError) as e:
        print(f"Ошибка парсинга данных: {data} - {e}")
        return None, None  # Возвращаем None, если произошла ошибка


def update_graphs(temperature, humidity):
    # Обновление данных для часовых графиков
    temperature_data_hour.append(temperature)
    humidity_data_hour.append(humidity)
    time_data_hour.append(len(time_data_hour) * 2)  # Увеличиваем время на 2 секунды

    # Обновление данных для суточных графиков
    temperature_data_day.append(temperature)
    humidity_data_day.append(humidity)
    time_data_day.append(len(time_data_day) * 2)  # Увеличиваем время на 2 секунды

    # Обновление графиков
    ax1.clear()
    ax2.clear()
    ax3.clear()
    ax4.clear()

    ax1.plot(time_data_hour, temperature_data_hour, label='Температура (°C)', color='red')
    ax2.plot(time_data_hour, humidity_data_hour, label='Влажность (%)', color='blue')
    ax3.plot(time_data_day, temperature_data_day, label='Температура (°C)', color='orange')
    ax4.plot(time_data_day, humidity_data_day, label='Влажность (%)', color='green')

    ax1.set_title('Температура за последний час')
    ax1.set_xlabel('Время (с)')
    ax1.set_ylabel('Температура (°C)')
    ax1.legend()

    ax2.set_title('Влажность за последний час')
    ax2.set_xlabel('Время (с)')
    ax2.set_ylabel('Влажность (%)')
    ax2.legend()

    ax3.set_title('Температура за сутки')
    ax3.set_xlabel('Время (с)')
    ax3.set_ylabel('Температура (°C)')
    ax3.legend()

    ax4.set_title('Влажность за сутки')
    ax4.set_xlabel('Время (с)')
    ax4.set_ylabel('Влажность (%)')
    ax4.legend()

    # Обновление текущих данных
    current_temperature.set(f"Текущая температура: {temperature:.2f} °C")
    current_humidity.set(f"Текущая влажность: {humidity:.2f} %")

    canvas.draw()


frame = ttk.Frame(root)
frame.pack(padx=10, pady=10)

# Добавление текущих данных
current_frame = ttk.Frame(root)
current_frame.pack(pady=10)

current_temp_label = ttk.Label(current_frame, textvariable=current_temperature, font=("Helvetica", 14))
current_temp_label.pack()

current_hum_label = ttk.Label(current_frame, textvariable=current_humidity, font=("Helvetica", 14))
current_hum_label.pack()

# Создание графиков
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 8))
canvas = FigureCanvasTkAgg(fig, master=frame)
canvas.get_tk_widget().pack()

# Запуск потока для чтения данных из COM-порта
thread = threading.Thread(target=read_serial, daemon=True)
thread.start()

# Запуск главного цикла интерфейса
root.mainloop()


Как сделать красивый интерфейс с черным фоном?