129 lines
5.9 KiB
Python
129 lines
5.9 KiB
Python
import rrdtool
|
||
import time
|
||
import requests
|
||
from dotenv import load_dotenv
|
||
import os
|
||
|
||
load_dotenv()
|
||
|
||
# Словарь с названиями устройств
|
||
device_names = {
|
||
"temp1": "ПБКТ-2 - Ш. 6 линия",
|
||
"temp2": "ПБКТ-3 - Ш. 1 линия"
|
||
}
|
||
|
||
def send_telegram(min_temp1, min_time1, max_temp1, max_time1, min_temp2, min_time2, max_temp2, max_time2):
|
||
token = os.getenv("TELEGRAM_TOKEN")
|
||
channel_id = os.getenv("TELEGRAM_CHANNEL_ID")
|
||
if not token or not channel_id:
|
||
raise ValueError("Telegram токен или ID канала не заданы в .env")
|
||
|
||
# Форматируем текст комментария
|
||
comment = (
|
||
f"{device_names['temp1']} - Min Temp: {min_temp1:.2f}°C at {min_time1}\n"
|
||
f"{device_names['temp1']} - Max Temp: {max_temp1:.2f}°C at {max_time1}\n"
|
||
f"{device_names['temp2']} - Min Temp: {min_temp2:.2f}°C at {min_time2}\n"
|
||
f"{device_names['temp2']} - Max Temp: {max_temp2:.2f}°C at {max_time2}"
|
||
)
|
||
|
||
url = f"https://api.telegram.org/bot{token}/sendPhoto"
|
||
with open('temperature_graph.png', 'rb') as file:
|
||
r = requests.post(url, data={
|
||
"chat_id": channel_id,
|
||
"caption": comment # Текст комментария
|
||
}, files={
|
||
"photo": file
|
||
})
|
||
print(r.text)
|
||
if r.status_code != 200:
|
||
raise Exception(f"Ошибка отправки в Telegram: {r.text}")
|
||
|
||
|
||
def get_extreme_timestamps(rrd_file: str, start_time: int, end_time: int, prefix: str):
|
||
# Извлекаем данные из RRD-файла
|
||
info = rrdtool.fetch(rrd_file, 'AVERAGE', '--start', str(start_time), '--end', str(end_time))
|
||
data = info[2] # Сырые данные
|
||
timestamps = range(info[0][0], info[0][1], info[0][2]) # Генерация временных меток
|
||
|
||
# Поиск минимального и максимального значений
|
||
min_temp, max_temp = float('inf'), float('-inf')
|
||
min_time, max_time = None, None
|
||
|
||
for idx, row in enumerate(data):
|
||
temp_low = row[0] if prefix == "temp1" else row[2] # Первое устройство - temp1, второе - temp2
|
||
temp_top = row[1] if prefix == "temp1" else row[3]
|
||
|
||
if temp_low is not None:
|
||
if temp_low < min_temp:
|
||
min_temp = temp_low
|
||
min_time = timestamps[idx]
|
||
if temp_top is not None:
|
||
if temp_top > max_temp:
|
||
max_temp = temp_top
|
||
max_time = timestamps[idx]
|
||
|
||
return min_temp, min_time, max_temp, max_time
|
||
|
||
|
||
def create_graph(rrd_file: str, output_file: str):
|
||
# Получаем текущее время
|
||
now = int(time.time())
|
||
start_time = now - 86400 # 24 часа назад
|
||
start_date = time.strftime("%d-%m-%Y", time.localtime(start_time))
|
||
end_date = time.strftime("%d-%m-%Y", time.localtime(now))
|
||
|
||
# Получаем минимальные и максимальные значения для обоих устройств
|
||
min_temp1, min_time1, max_temp1, max_time1 = get_extreme_timestamps(rrd_file, start_time, now, "temp1")
|
||
min_temp2, min_time2, max_temp2, max_time2 = get_extreme_timestamps(rrd_file, start_time, now, "temp2")
|
||
|
||
# Форматирование времени
|
||
min_time1_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(min_time1))
|
||
max_time1_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(max_time1))
|
||
min_time2_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(min_time2))
|
||
max_time2_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(max_time2))
|
||
|
||
# Вывод значений в терминал
|
||
print(f"{device_names['temp1']} - Min Temp: {min_temp1:.2f}°C at {min_time1_str}")
|
||
print(f"{device_names['temp1']} - Max Temp: {max_temp1:.2f}°C at {max_time1_str}")
|
||
print(f"{device_names['temp2']} - Min Temp: {min_temp2:.2f}°C at {min_time2_str}")
|
||
print(f"{device_names['temp2']} - Max Temp: {max_temp2:.2f}°C at {max_time2_str}")
|
||
|
||
try:
|
||
rrdtool.graph(
|
||
output_file,
|
||
"--start", str(start_time),
|
||
"--end", str(now),
|
||
"--title", f"Temperature from {start_date} to {end_date}",
|
||
"--vertical-label", "Temperature (°C)",
|
||
"--width", "800",
|
||
"--height", "400",
|
||
# Определение данных
|
||
"DEF:low_temp1={}:temp1_low:AVERAGE".format(rrd_file),
|
||
"DEF:high_temp1={}:temp1_top:AVERAGE".format(rrd_file),
|
||
"DEF:low_temp2={}:temp2_low:AVERAGE".format(rrd_file),
|
||
"DEF:high_temp2={}:temp2_top:AVERAGE".format(rrd_file),
|
||
# Линии графика
|
||
"LINE1:low_temp1#0000FF:{} - Low Temperature".format(device_names['temp1']),
|
||
"LINE2:high_temp1#FF0000:{} - Top Temperature".format(device_names['temp1']),
|
||
"LINE3:low_temp2#00FF00:{} - Low Temperature".format(device_names['temp2']),
|
||
"LINE4:high_temp2#FFA500:{} - Top Temperature".format(device_names['temp2']),
|
||
# Подписи
|
||
"COMMENT: \\n",
|
||
r"GPRINT:low_temp1:MIN:{} - Min Low Temp\: %2.2lf°C".format(device_names['temp1']),
|
||
"COMMENT: \\n",
|
||
r"GPRINT:high_temp1:MAX:{} - Max Top Temp\: %2.2lf°C".format(device_names['temp1']),
|
||
"COMMENT: \\n",
|
||
r"GPRINT:low_temp2:MIN:{} - Min Low Temp\: %2.2lf°C".format(device_names['temp2']),
|
||
"COMMENT: \\n",
|
||
r"GPRINT:high_temp2:MAX:{} - Max Top Temp\: %2.2lf°C".format(device_names['temp2'])
|
||
)
|
||
print(f"График успешно создан: {output_file}")
|
||
send_telegram(min_temp1, min_time1_str, max_temp1, max_time1_str, min_temp2, min_time2_str, max_temp2, max_time2_str)
|
||
except Exception as e:
|
||
print(f"Ошибка создания графика: {e}")
|
||
|
||
|
||
# Пример использования
|
||
rrd_file = "temperature_data.rrd"
|
||
output_file = "temperature_graph.png"
|
||
create_graph(rrd_file, output_file)
|