import flask from flask import request, jsonify 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 flask import render_template from api_logic import api 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 ) ''') 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.Flask(__name__, template_folder="./") app.config['DEBUG'] = True # Функция сохранения в базу 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 # Маршрут сохранения в базу @app.route('/sav_db_api', methods=['GET']) 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'}) # Проверка входа на страницы @app.route('/page_key', methods=['GET']) 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 # Тестовый запрос с установки @app.route('/test_server', methods=['GET']) 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) # Маршрут для вывода всех данных из таблицы @app.route('/get_all_data', methods=['GET']) 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 # Удаление базы @app.route('/delite_db', methods=['GET']) 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 @app.route('/plot_ph', methods=['GET']) def plot_ph(): try: # Получаем параметры из URL (если они есть) start_date = request.args.get('start_date') end_date = request.args.get('end_date') # Если параметры есть, проверяем их корректность if start_date and end_date: try: # Преобразуем даты в формат datetime start_date = datetime.strptime(start_date, '%Y-%m-%dT%H:%M') end_date = datetime.strptime(end_date, '%Y-%m-%dT%H:%M') # Проверяем, что дата начала раньше даты окончания if start_date >= end_date: return '''
Дата начала должна быть раньше даты окончания.
''' except ValueError: return '''Формат даты должен быть YYYY-MM-DDTHH:MM.
''' # Подключаемся к базе данных 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: return '''Таблица system_data не существует. Обновите базу данных.
''' # Выполняем запрос для получения данных в заданном диапазоне cursor.execute(''' SELECT date_time, ph, dey, wek FROM system_data WHERE date_time BETWEEN ? AND ? ORDER BY date_time ''', (start_date, end_date)) rows = cursor.fetchall() conn.close() # Проверяем, есть ли данные if not rows: return '''Для выбранного диапазона дат данные не найдены.
''' # Разделяем данные на дату и время, а также добавляем значения из столбцов dey и wek dates = [f"{row[0]} d: {row[2]} w: {row[3]}" for row in rows] # Дата и время + dey + wek ph_values = [float(row[1]) for row in rows] # Значения pH # Создаем график plt.figure(figsize=(15, 6)) # Увеличиваем ширину графика plt.plot(dates, ph_values, marker='o', linestyle='-', color='b') # Точки соединены линией plt.title('График значений pH') plt.xlabel('Дата и время') plt.ylabel('Значение pH') plt.xticks(rotation=90) # Поворачиваем подписи оси X вертикально plt.grid(True) plt.gcf().subplots_adjust(bottom=0.4) # Увеличиваем пространство снизу для надписей # Сохраняем график в буфер buffer = io.BytesIO() plt.savefig(buffer, format='png') buffer.seek(0) # Кодируем график в base64 plot_data = base64.b64encode(buffer.getvalue()).decode('utf-8') # Возвращаем график в формате HTML с кнопками "Новые данные" и "Обновить данные" return f'''