Spaces:
Build error
Build error
from flask import Flask, request, jsonify, redirect, url_for, render_template | |
import os | |
import sqlite3 | |
from datetime import datetime | |
import pytz | |
import matplotlib.pyplot as plt | |
import io | |
import base64 | |
from dotenv import load_dotenv | |
import globs | |
from api_logic import api | |
import requests | |
import telegram | |
load_dotenv() | |
# Инициализация базы данных | |
def init_db(db_name): | |
conn = sqlite3.connect(db_name) | |
cursor = conn.cursor() | |
# Таблица с системными данными (твоя старая таблица) | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS system_data ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
date_time TEXT, | |
dey TEXT, | |
wek TEXT, | |
v_hid TEXT, | |
v_min TEXT, | |
ph TEXT, | |
ec TEXT, | |
tS TEXT, | |
tA TEXT, | |
hDm TEXT, | |
sVen TEXT, | |
onA TEXT, | |
onB TEXT, | |
onC TEXT, | |
nPh TEXT, | |
nEC TEXT, | |
nTa TEXT, | |
nLon TEXT, | |
nLoff TEXT | |
) | |
''') | |
# **Новая таблица для пользователей бота** | |
cursor.execute(''' | |
CREATE TABLE IF NOT EXISTS bot_users ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, -- Уникальный ID | |
chat_id INTEGER UNIQUE, -- Telegram ID пользователя | |
created_at TEXT -- Время добавления (ISO формат) | |
) | |
''') | |
conn.commit() | |
conn.close() | |
# Глобальные переменные | |
api_key_sys = os.getenv('api_key') # Берём значение API-ключа из .env | |
globs.dey = 0 | |
globs.wek = 0 | |
globs.v_hid = 0 | |
globs.v_min = 0 | |
globs.ph = 0 | |
globs.ec = 0 | |
globs.tS = 0 | |
globs.tA = 0 | |
globs.hDm = 0 | |
globs.sVen = 0 | |
globs.onA = 0 | |
globs.onB = 0 | |
globs.onC = 0 | |
globs.ph_eep = 0 | |
globs.ph_on_eep = 0 | |
globs.ec_eep = 0 | |
globs.ec_A_eep = 0 | |
globs.ec_B_eep = 0 | |
globs.ec_C_eep = 0 | |
globs.l_ON_h_eep = 0 | |
globs.l_ON_m_eep = 0 | |
globs.l_OFF_h_eep = 0 | |
globs.l_OFF_m_eep = 0 | |
globs.t_Voz_eep = 0 | |
# Создаем экземпляр Flask-приложения | |
app = Flask(__name__, template_folder="./") | |
app.config['DEBUG'] = True | |
# Инициализация бота | |
bot = telegram.Bot(token='7766407698:AAGZHEbUuiOri4_YzZ7hDPSD6U8MGMXXSnA') | |
# Асинхронная установка webhook | |
async def set_webhook(): | |
await bot.set_webhook(url='https://dmitrmakeev-flask-inference-api-g.hf.space/webhook') | |
def webhook(): | |
# Получаем обновление от Telegram | |
update = telegram.Update.de_json(request.get_json(force=True), bot) | |
# Извлекаем chat_id и текст сообщения | |
chat_id = update.message.chat.id | |
text = update.message.text | |
# Обрабатываем команду /start | |
if text == '/start': | |
bot.send_message(chat_id=chat_id, text="Привет! Я твой новый телеграм-бот.") | |
return 'ok' | |
# Функция сохранения в базу пользователей TG | |
def save_user(chat_id, db_name="your_database.db"): | |
conn = sqlite3.connect(db_name) | |
cursor = conn.cursor() | |
created_at = datetime.now().isoformat() # Форматируем дату | |
try: | |
cursor.execute("INSERT INTO bot_users (chat_id, created_at) VALUES (?, ?)", (chat_id, created_at)) | |
conn.commit() | |
except sqlite3.IntegrityError: | |
print(f"Пользователь {chat_id} уже есть в базе.") | |
conn.close() | |
# Функция сохранения в базу данных системы автоматизации гидропоники | |
def save_data_to_db(db_name, data): | |
try: | |
conn = sqlite3.connect(db_name) | |
cursor = conn.cursor() | |
# ✅ Устанавливаем московское время (UTC+3) | |
moscow_tz = pytz.timezone("Europe/Moscow") | |
current_time = datetime.now(moscow_tz).strftime('%Y-%m-%d %H:%M:%S') | |
# Вставляем данные в таблицу | |
cursor.execute(''' | |
INSERT INTO system_data ( | |
date_time, dey, wek, v_hid, v_min, ph, ec, tS, tA, hDm, sVen, onA, onB, onC, nPh, nEC, nTa, nLon, nLoff | |
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) | |
''', ( | |
current_time, # ✅ Дата и время по Москве | |
data['dey'], data['wek'], data['v_hid'], data['v_min'], data['ph'], data['ec'], | |
data['tS'], data['tA'], data['hDm'], data['sVen'], data['onA'], data['onB'], | |
data['onC'], data['nPh'], data['nEC'], data['nTa'], data['nLon'], data['nLoff'] | |
)) | |
conn.commit() | |
conn.close() | |
except Exception as e: | |
return jsonify({'status': 'error', 'message': str(e)}), 500 | |
# Маршрут сохранения в базу | |
def sav_db_api(): | |
# Инициализируем базу данных | |
init_db('system_data.db') | |
# Получаем данные из запроса | |
data = { | |
'dey': request.args.get('dey'), | |
'wek': request.args.get('wek'), | |
'v_hid': request.args.get('v_hid'), | |
'v_min': request.args.get('v_min'), | |
'ph': request.args.get('ph'), | |
'ec': request.args.get('ec'), | |
'tS': request.args.get('tS'), | |
'tA': request.args.get('tA'), | |
'hDm': request.args.get('hDm'), | |
'sVen': request.args.get('sVen'), | |
'onA': request.args.get('onA'), | |
'onB': request.args.get('onB'), | |
'onC': request.args.get('onC'), | |
'nPh': request.args.get('nPh'), | |
'nEC': request.args.get('nEC'), | |
'nTa': request.args.get('nTa'), | |
'nLon': request.args.get('nLon'), | |
'nLoff': request.args.get('nLoff') | |
} | |
# Проверяем, что все необходимые параметры переданы | |
required_params = ['dey', 'wek', 'v_hid', 'v_min', 'ph', 'ec', 'tS', 'tA', 'hDm', 'sVen', 'onA', 'onB', 'onC', 'nPh', 'nEC', 'nTa', 'nLon', 'nLoff'] | |
for param in required_params: | |
if data[param] is None: | |
return jsonify({'status': 'error', 'message': f'Отсутствует параметр: {param}'}), 400 | |
# Сохраняем данные в базу | |
save_data_to_db('system_data.db', data) | |
# Возвращаем ответ | |
return jsonify({'status': 'success', 'message': 'Save OK'}) | |
# Проверка входа на страницы | |
def check_api_key(): | |
api_sys_param = request.args.get('api_sys') # Получаем параметр из запроса | |
if api_sys_param == api_key_sys: | |
return jsonify({"status": "ok"}), 200 # ✅ Совпадает — отправляем "ok" | |
else: | |
return jsonify({"status": "error", "message": "Invalid API key"}), 403 # ❌ Ошибка 403 | |
# Тестовый запрос с установки | |
def test_server(): | |
api_key_param = request.args.get('api_sys') # Получаем параметр из запроса | |
err_ser = 1 if api_key_param == api_key_sys else 0 # Проверяем совпадение ключей | |
return jsonify(err_ser=err_ser) | |
def test_server_str(): | |
api_key_param = request.args.get('api_sys') | |
err_ser = "1" if api_key_param == api_key_sys else "0" | |
return err_ser # Возвращаем строку "1" или "0" | |
# Маршрут для вывода всех данных из таблицы | |
def get_all_data(): | |
try: | |
conn = sqlite3.connect('system_data.db') | |
cursor = conn.cursor() | |
# Выполняем запрос для получения всех данных из таблицы | |
cursor.execute('SELECT * FROM system_data') | |
rows = cursor.fetchall() | |
# Получаем названия столбцов | |
column_names = [description[0] for description in cursor.description] | |
# Преобразуем данные в формат JSON | |
data = [] | |
for row in rows: | |
data.append(dict(zip(column_names, row))) | |
conn.close() | |
# Возвращаем данные в формате JSON | |
return jsonify(data) | |
except Exception as e: | |
return jsonify({'status': 'error', 'message': str(e)}), 500 | |
# Удаление базы | |
def delete_db(): | |
try: | |
conn = sqlite3.connect("system_data.db") # Используем вашу БД | |
cursor = conn.cursor() | |
# ✅ Удаляем все записи из таблицы | |
cursor.execute("DELETE FROM system_data") | |
# ✅ Сбрасываем автоинкрементный счётчик ID (для SQLite) | |
cursor.execute("DELETE FROM sqlite_sequence WHERE name='system_data'") | |
conn.commit() | |
conn.close() | |
return jsonify({'status': 'ok', 'message': 'База данных успешно очищена'}) | |
except Exception as e: | |
return jsonify({'status': 'error', 'message': str(e)}), 500 | |
def plot_week(): | |
try: | |
# Получаем номер недели из параметров запроса | |
week_number = request.args.get('week', default=1, type=int) | |
week_number = max(1, min(30, week_number)) # Ограничиваем диапазон 1-30 | |
# Подключаемся к базе данных | |
conn = sqlite3.connect('system_data.db') | |
cursor = conn.cursor() | |
# Проверяем существование таблицы | |
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='system_data'") | |
table_exists = cursor.fetchone() | |
if not table_exists: | |
conn.close() | |
return render_template('plot_week.html', data=None, week_number=week_number, table_exists=False) | |
# Запрашиваем данные за выбранную неделю | |
cursor.execute(''' | |
SELECT date_time, dey, ph, ec, tS, tA, hDm, sVen, onA, onB, onC, v_hid, v_min | |
FROM system_data | |
WHERE wek = ? | |
ORDER BY date_time | |
''', (str(week_number),)) # Приводим week_number к строке, так как wek имеет тип TEXT | |
rows = cursor.fetchall() | |
conn.close() | |
# Если данных нет | |
if not rows: | |
return render_template('plot_week.html', data=None, week_number=week_number, table_exists=True) | |
# Формируем данные для JSON | |
data = { | |
'week': week_number, | |
'dates': [row[0] for row in rows], | |
'days_of_week': [int(row[1]) if row[1] else 0 for row in rows], # Преобразуем dey в int | |
'ph': [float(row[2]) if row[2] else 0.0 for row in rows], # pH | |
'ec': [float(row[3]) if row[3] else 0.0 for row in rows], # EC | |
'tS': [float(row[4]) if row[4] else 0.0 for row in rows], # Температура раствора | |
'tA': [float(row[5]) if row[5] else 0.0 for row in rows], # Температура воздуха | |
'hDm': [float(row[6]) if row[6] else 0.0 for row in rows], # Влажность воздуха | |
'sVen': [float(row[7]) if row[7] else 0.0 for row in rows], # Обороты вентилятора | |
'onA': [float(row[8]) if row[8] else 0.0 for row in rows], # Насос A | |
'onB': [float(row[9]) if row[9] else 0.0 for row in rows], # Насос B | |
'onC': [float(row[10]) if row[10] else 0.0 for row in rows], # Насос C | |
'sus': [f"{row[11]}:{row[12]}" if row[11] and row[12] else "0:0" for row in rows] # Объединяем v_hid и v_min | |
} | |
# Отправляем данные в HTML-шаблон | |
return render_template('plot_week.html', data=data, week_number=week_number, table_exists=True) | |
except Exception as e: | |
# Логируем ошибку в консоль для отладки | |
print(f"Ошибка: {str(e)}") | |
return render_template('plot_week.html', data=None, week_number=week_number, table_exists=True, message=f"Ошибка: {str(e)}") | |
def index(): | |
return flask.render_template('index.html') | |
def online(): | |
return render_template('online.html') | |
def table(): | |
return render_template('table.html') | |
def online_api(): | |
# Устанавливаем московское время (UTC+3) | |
moscow_tz = pytz.timezone("Europe/Moscow") | |
current_time = datetime.now(moscow_tz) | |
# Форматируем дату и время отдельно | |
date = current_time.strftime('%Y-%m-%d') # Например, "2025-03-23" | |
time = current_time.strftime('%H:%M:%S') # Например, "14:35:42" | |
return jsonify( | |
dey=globs.dey, | |
wek=globs.wek, | |
v_hid=globs.v_hid, | |
v_min=globs.v_min, | |
ph=globs.ph, | |
ec=globs.ec, | |
tS=globs.tS, | |
tA=globs.tA, | |
hDm=globs.hDm, | |
sVen=globs.sVen, | |
rFul=globs.rFul, | |
rLi=globs.rLi, | |
rWat=globs.rWat, | |
rRas=globs.rRas, | |
rPH=globs.rPH, | |
rEC=globs.rEC, | |
rSl=globs.rSl, | |
rLe=globs.rLe, | |
alW=globs.alW, | |
ec_A_eep=globs.ec_A_eep, | |
ec_B_eep=globs.ec_B_eep, | |
ec_C_eep=globs.ec_C_eep, | |
date=date, # Добавляем дату | |
time=time # Добавляем время | |
) | |
def settings(): | |
return render_template('settings.html') | |
def settings_api(): | |
return jsonify(ph_eep=globs.ph_eep, | |
ph_on_eep=globs.ph_on_eep, | |
ec_eep=globs.ec_eep, | |
ec_A_eep=globs.ec_A_eep, | |
ec_B_eep=globs.ec_B_eep, | |
ec_C_eep=globs.ec_C_eep, | |
l_ON_h_eep=globs.l_ON_h_eep, | |
l_ON_m_eep=globs.l_ON_m_eep, | |
l_OFF_h_eep=globs.l_OFF_h_eep, | |
l_OFF_m_eep=globs.l_OFF_m_eep, | |
t_Voz_eep=globs.t_Voz_eep | |
) | |
def set_pH_value(): | |
ph_value = request.args.get('value') | |
globs.ph_set = ph_value | |
globs.eep_set = 1 | |
return "pH value set successfully" | |
def ph_on_value(): | |
ph_on_value = request.args.get('value') | |
globs.ph_on_set = ph_on_value | |
globs.eep_set = 2 | |
return "EC value set successfully" | |
def set_EC_value(): | |
ec_value = request.args.get('value') | |
globs.ec_set = ec_value | |
globs.eep_set = 3 | |
return "EC value set successfully" | |
def ec_A_setValue(): | |
ec_A_setValue = request.args.get('value') | |
globs.ec_A_set = ec_A_setValue | |
globs.eep_set = 4 | |
return "EC value set successfully" | |
def ec_B_setValue(): | |
ec_B_setValue = request.args.get('value') | |
globs.ec_B_set = ec_B_setValue | |
globs.eep_set = 5 | |
return "EC value set successfully" | |
def ec_C_setValue(): | |
ec_C_setValue = request.args.get('value') | |
globs.ec_C_set = ec_C_setValue | |
globs.eep_set = 6 | |
return "EC value set successfully" | |
def l_ON_set(): | |
globs.l_ON_h_set = request.args.get('l_ON_h_set') | |
globs.l_ON_m_set = request.args.get('l_ON_m_set') | |
globs.eep_set = 7 | |
return "EC value set successfully" | |
def l_OFF_set(): | |
globs.l_OFF_h_set = request.args.get('l_OFF_h_set') | |
globs.l_OFF_m_set = request.args.get('l_OFF_m_set') | |
globs.eep_set = 8 | |
return "EC value set successfully" | |
def t_Voz_eep_set(): | |
t_Voz_eep_set = request.args.get('value') | |
globs.t_Voz_set = t_Voz_eep_set | |
globs.eep_set = 9 | |
return "EC value set successfully" | |
def but_start(): | |
globs.eep_set = 10 | |
return jsonify(value_set="start") | |
def but_stop(): | |
globs.eep_set = 11 | |
return jsonify(value_set="stop") | |
def but_res(): | |
globs.eep_set = 12 | |
return jsonify(value_set="res") | |
def but_sliv(): | |
globs.eep_set = 13 | |
return jsonify(value_set="sliv") | |
def handle_api(): | |
response = api() | |
return response | |
def handle_save_db(): | |
response = save_db() | |
return response | |
def set_res(): | |
globs.eep_set = 0 | |
return jsonify(value_set="reset") | |
if __name__ == '__main__': | |
# Запускаем асинхронно установку webhook | |
loop = asyncio.get_event_loop() | |
loop.run_until_complete(set_webhook()) | |
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860))) | |