From b74d0d9dbf404d9913ffdcf328150503c9930899 Mon Sep 17 00:00:00 2001 From: q00 Date: Sun, 1 Dec 2024 16:52:34 +0300 Subject: [PATCH] Gen graph and upload --- .gitignore | 1 + vodynoi/gen_graph.py | 90 ++++++++++++++++++++++++++-------- vodynoi/local_gen_graph.py | 41 ++++++++++++++++ vodynoi/temperature_graph.png | Bin 15845 -> 40845 bytes vodynoi/test.py | 82 +++++++++++++++++++++++++++++++ 5 files changed, 194 insertions(+), 20 deletions(-) create mode 100644 vodynoi/local_gen_graph.py create mode 100644 vodynoi/test.py diff --git a/.gitignore b/.gitignore index 26c9240..2433d40 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ share/ kaluga/lib64 */*.xlsx */*.rrd +*/*xlsx# diff --git a/vodynoi/gen_graph.py b/vodynoi/gen_graph.py index e3ad58f..cc14db8 100644 --- a/vodynoi/gen_graph.py +++ b/vodynoi/gen_graph.py @@ -3,18 +3,26 @@ import time import requests from dotenv import load_dotenv import os + load_dotenv() -def send_telegram(): +def send_telegram(min_temp, min_time, max_temp, max_time): 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"Min Temp: {min_temp:.2f}°C at {min_time}\n" + f"Max Temp: {max_temp:.2f}°C at {max_time}" + ) + 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 + "chat_id": channel_id, + "caption": comment # Текст комментария }, files={ "photo": file }) @@ -22,40 +30,82 @@ def send_telegram(): if r.status_code != 200: raise Exception(f"Ошибка отправки в Telegram: {r.text}") + +def get_extreme_timestamps(rrd_file: str, start_time: int, end_time: int): + # Извлекаем данные из 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_low_temp, max_high_temp = float('inf'), float('-inf') + min_low_time, max_high_time = None, None + + for idx, row in enumerate(data): + if row[0] is not None: # Проверяем, что данные не отсутствуют + if row[0] < min_low_temp: + min_low_temp = row[0] + min_low_time = timestamps[idx] + if row[1] is not None and row[1] > max_high_temp: + max_high_temp = row[1] + max_high_time = timestamps[idx] + + return min_low_temp, min_low_time, max_high_temp, max_high_time + + def create_graph(rrd_file: str, output_file: str): # Получаем текущее время now = int(time.time()) - # Время начала (24 часа назад) - start_time = now - 86400 # 86400 секунд = 1 день - - # Форматируем даты для заголовка + 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_low_temp, min_low_time, max_high_temp, max_high_time = get_extreme_timestamps(rrd_file, start_time, now) + + # Форматирование времени + min_low_time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(min_low_time)) + max_high_time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(max_high_time)) + + # Вывод значений в терминал + print(f"\033[32m{'Min Temp:':<20}\033[0m{min_low_temp:>10.2f}°C at {min_low_time_str}") + print(f"\033[31m{'Max Temp:':<20}\033[0m{max_high_temp:>10.2f}°C at {max_high_time_str}") + try: rrdtool.graph( output_file, - "--start", str(start_time), # Начало графика - "--end", str(now), # Конец графика + "--start", str(start_time), + "--end", str(now), + "--title", f"Temperature from {start_date} to {end_date}", "--vertical-label", "Temperature (°C)", - "--title", f"Temperature Readings from {start_date} to {end_date}", - "DEF:low_temp={}:temp_low:AVERAGE".format(rrd_file), # Средние значения нижней температуры - "DEF:high_temp={}:temp_high:AVERAGE".format(rrd_file), # Средние значения верхней температуры - "LINE1:low_temp#0000FF:Low Temperature", # Линия для нижней температуры (синий) - "LINE1:high_temp#FF0000:High Temperature", # Линия для верхней температуры (красный) + "--width", "800", + "--height", "400", + # Определение данных + "DEF:low_temp={}:temp_low:AVERAGE".format(rrd_file), + "DEF:high_temp={}:temp_high:AVERAGE".format(rrd_file), + # Линии графика + "LINE1:low_temp#0000FF:Low Temperature", + "LINE2:high_temp#FF0000:Top Temperature", + # Вертикальные линии для экстремумов + f"VRULE:{min_low_time}#00FF00:Min Temp Time", + f"VRULE:{max_high_time}#FF0000:Max Temp Time", + + # Подписи + "COMMENT: \\n", r"GPRINT:low_temp:MIN:Min Low Temp\: %2.2lf°C", - r"GPRINT:low_temp:MAX:Max Low Temp\: %2.2lf°C", - r"GPRINT:low_temp:AVERAGE:Avg Low Temp\: %2.2lf°C\n", - r"GPRINT:high_temp:MIN:Min High Temp\: %2.2lf°C", - r"GPRINT:high_temp:MAX:Max High Temp\: %2.2lf°C", - r"GPRINT:high_temp:AVERAGE:Avg High Temp\: %2.2lf°C\n", + "COMMENT: \\n", + r"GPRINT:high_temp:MAX:Max Top Temp\: %2.2lf°C", + "COMMENT: \\n", + r"GPRINT:low_temp:AVERAGE:Avg Low Temp\: %2.2lf°C", + "COMMENT: \\n", + r"GPRINT:high_temp:AVERAGE:Avg Top Temp\: %2.2lf°C" ) print(f"График успешно создан: {output_file}") - send_telegram() - + send_telegram(min_low_temp, min_low_time_str, max_high_temp, max_high_time_str) except Exception as e: print(f"Ошибка создания графика: {e}") + # Пример использования rrd_file = "temperature_data.rrd" output_file = "temperature_graph.png" diff --git a/vodynoi/local_gen_graph.py b/vodynoi/local_gen_graph.py new file mode 100644 index 0000000..3000e02 --- /dev/null +++ b/vodynoi/local_gen_graph.py @@ -0,0 +1,41 @@ +import rrdtool +import time +import requests +import os + + +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)) + + 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_temp={}:temp_low:AVERAGE".format(rrd_file), + "DEF:high_temp={}:temp_high:AVERAGE".format(rrd_file), + "LINE1:low_temp#0000FF:Low Temperature", + "LINE1:high_temp#FF0000:Top Temperature", + r"GPRINT:low_temp:MIN:Min Low Temp\: %2.2lf°C", + r"GPRINT:high_temp:MAX:Max Top Temp\: %2.2lf°C", + r"GPRINT:low_temp:AVERAGE:Avg Low Temp\: %2.2lf°C", + r"GPRINT:high_temp:AVERAGE:Avg Top Temp\: %2.2lf°C", + ) + print(f"График успешно создан: {output_file}") + except Exception as e: + print(f"Ошибка создания графика: {e}") + + except Exception as e: + print(f"Ошибка создания графика: {e}") +# Пример использования +rrd_file = "temperature_data.rrd" +output_file = "temperature_graph.png" +create_graph(rrd_file, output_file) diff --git a/vodynoi/temperature_graph.png b/vodynoi/temperature_graph.png index a6fa95a2b2baafb9e9d50a0eb4127494c2e048fb..e32e2fdb86490b00509c9369a3fa7405f1599789 100644 GIT binary patch literal 40845 zcmbq*1z45Y_BRINpn@QXl1fN}0n#7}QqnD@AR$P1tB90>bcb}KbfY4vq=dATz@elY zzV(7KI5YRo{XZY`jB{j^^PaueUTghgZ4W64p;MTIm}qEdr$mGWWYEx#JV8S{eDe5V z_|8XPURwCiF-AiUXd(jqayAiDk&X_sqkTIS@9Csegdcl~CIop% z9j19&Ivh`~0x*3~x z{6Ru4`h!2@@qB}h%J|lNU#XFokTjQ&Fe~SwF7k8eXI3xr_n(Yd36%6%kti?9H0L<{ z1nm$!7#i9uCURfl=sPQWzZ=2v6{f_)#CIp4j!_Y;0`Uq};2| z&PYfZ^V$5kr=_J;;j~3ZN9RX6lGDU{;+TuThzUD4sbuT)v8k>c-OA^usHmuDm#L-g z-zSQPclY!(aW8z1S5MoXDc)iUcj31mZc3w)wLOeB^bS7I)pu!G<;D8#bmVs{oE-1p zA9Tl|aM!DTalTXC-Y~Hw@z#aYg>%(JY(~8yPD??IDw)NoR13mr$K@_JQaioz=GV~< z^L6ne{^~Y^uG?E1UQw!c6A5pX?l@>`6kANR2$30@MELNok542;pFQ$N8^z2SL&=Y& zwhK{qsFeBnc}A7|2&eT4=F%TG@85sT?~I#A@Tez$dUK&^c4}&KDyPXWm2s_v8kN*V zjGM={U3&Lw2sPRT?++h7EF)i5+Fq*~w^(669#{1`?`#>DEp@0Em$5!=sx$n|y))d9V8=dv`tttFH-sq;W z1=pJw=M-+;s?0a+`M4m-yC%RB#N9G?W=Sac`SWAZO`ZMy<@YP$MS)RYaeNJ*$+sJ_ zvR|CH7or;*8{>BnIH(&VP5FTy&{rual;EK)BI_l`&uU`wDw$_;| zHs{~gkY3~UUd`!;4@_$$DFB;R{gOyAQ?&^GKu}N+b(GDALOze~6GpHaUd-j}DQ(|o zCG0qeUL{BCm~2evjK=2MeC2LbG#bS3a?EjauEud= zxv#)@U^1)1sa1rUiql)F*LuK_goFeFh=HDda-d>|XQg*|&Srbg$N6&PvZJXmleB`kN z8V+xZiq@(KG+5Zn`JF9n2VDum!oofb{($FSpDCI3CgW2-kDY42`TY5F`pm*u=bdf) z|MIWAJC6``Y)2*dWFKYOtkd#`JqMbwqFtAA-R{E^V)UzrFX&4wvH|IYE zGpbm@w-$Cj)0$6a6nIh}Id<|Kt9~1tg%=xfJ?d|4=7yd=ed@(jJpPic|8fxFW}l_G zghd3)h|UjNSz}{sWTDrWCfV-2L!0aQ0H67zkAx}YvK#BGb&^g)b2fxTM2Z=AEvxVq zdrfOdH0@1I=REQ0%hwu=u}C-vv!x3XYHEG(rfN)`{*t^R0@~Wz$kBjv_x$8}a?iY>o0PQO z!$d1WpJts_O5iU}LdrSAI*dW)(7d{e{GKXUHCv}4th)Mk@F!O5nO-D7;YX!pWH_!4 zy78@#$B}J*!w^_p8;hRpDacAsPtVKC%g8WX{V^z#WyvrGahIHxRWX(QNoLBYm_QbgCtG`dsHzGUGj+PE3SONMezVgmA|-4Mna`xqAkDnq=7 zVNX8%51o#5Wv7a0_vhGT+mLaqHLsB4o;fBaD(cNOQ^@PMUZ|Q0SxjENTGcOvDRGY<<>cg)U>|&zn3&k_@Tzc_dRmg% zr^0%+pVgqleL(UACZ@i=et>}jM9JX7T9o}vQA0SJ^Q`><5r-Ki4hgr-D|cAll@WhQ zEHd6rs2Ymc)OwE|;ZfkZogzvk`5eG`tOk;C)927@&a0JV>L%~eMK0$ z*dKj;18LE{@0JTJM7N~cIa__ctT|K4x-*Ztlc2iA$5Rr%#BG6W{Bh@1)e{3LwAN>< z(Rb#;W4>O6?3Pur9p>)MK6IQM^(Dz?egtwythlM^TN@cUIVgiIU0tE$?DZC&a4xG- zkZP0^WvAbkEDgb~QecGNsZJY9LU7J{Gk)ueSnph13#3VUIyzitFE1}x1jZ<$ks$Zb zYr2gQ9OgUQTe0dJAJ0e@sxpydx>XMOO+x;}S2^mu_DKWkJ&t(z_37tCM&BICU4|Xt zNCj&+t=0Nc?2I{Y3q86rik8wOJ*+=)f{y2ML(?cw

RfJik`BK`xtFN;r1b9 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≀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 literal 15845 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 max_high_temp: + max_high_temp = row[1] + max_high_time = timestamps[idx] + + return min_low_temp, min_low_time, max_high_temp, max_high_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_low_temp, min_low_time, max_high_temp, max_high_time = get_extreme_timestamps(rrd_file, start_time, now) + + # Форматирование времени для терминала + min_low_time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(min_low_time)) + max_high_time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(max_high_time)) + + # Вывод значений в терминал + print(f"\033[32m{'Min Temp:':<20}\033[0m{min_low_temp:>10.2f}°C at {min_low_time_str}") + print(f"\033[31m{'Max Temp:':<20}\033[0m{max_high_temp:>10.2f}°C at {max_high_time_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_temp={}:temp_low:AVERAGE".format(rrd_file), + "DEF:high_temp={}:temp_high:AVERAGE".format(rrd_file), + # Линии графика + "LINE1:low_temp#0000FF:Low Temperature", + "LINE2:high_temp#FF0000:Top Temperature", + # Вертикальные линии для экстремумов + f"VRULE:{min_low_time}#00FF00:Min Temp Time", + f"VRULE:{max_high_time}#FF0000:Max Temp Time", + + # Подписи + "COMMENT: \\n", + r"GPRINT:low_temp:MIN:Min Low Temp\: %2.2lf°C", + "COMMENT: \\n", + r"GPRINT:high_temp:MAX:Max Top Temp\: %2.2lf°C", + "COMMENT: \\n", + r"GPRINT:low_temp:AVERAGE:Avg Low Temp\: %2.2lf°C", + "COMMENT: \\n", + r"GPRINT:high_temp:AVERAGE:Avg Top Temp\: %2.2lf°C" + ) + print(f"График успешно создан: {output_file}") + except Exception as e: + print(f"Ошибка создания графика: {e}") + + +rrd_file = "temperature_data.rrd" +output_file = "temperature_graph.png" +create_graph(rrd_file, output_file)