import flask from flask import request, jsonify import os import sqlite3 from datetime import datetime 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 ) ''') conn.commit() conn.close() # Глобальные переменные 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() # Получаем текущую дату и время current_time = datetime.now().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 ) 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'] )) 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') } # Проверяем, что все необходимые параметры переданы required_params = ['dey', 'wek', 'v_hid', 'v_min', 'ph', 'ec', 'tS', 'tA', 'hDm', 'sVen', 'onA', 'onB', 'onC'] 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': 'Данные сохранены'}) # Маршрут для вывода всех данных из таблицы @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('/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'''Таблица system_data не существует.
''' cursor.execute(''' SELECT date_time, ph, ec, dey, onA, onB, onC FROM system_data WHERE wek = ? ORDER BY date_time ''', (week_number,)) rows = cursor.fetchall() conn.close() if not rows: return f'''За {week_number}-ю неделю данных нет.
''' dates = [f"{row[0]} (d: {row[3]})" for row in rows] ph_values = [float(row[1]) for row in rows] ec_values = [float(row[2]) for row in rows] onA_values = [float(row[4]) for row in rows] onB_values = [float(row[5]) for row in rows] onC_values = [float(row[6]) for row in rows] plt.figure(figsize=(15, 18)) # Увеличил высоту для трех графиков # График pH plt.subplot(3, 1, 1) plt.plot(dates, ph_values, linestyle='-', color='b') plt.title(f'График pH за {week_number}-ю неделю', fontsize=14) plt.xlabel('Дата и день недели', fontsize=12) plt.ylabel('Значение pH', fontsize=12) plt.xticks(rotation=90, fontsize=6) plt.grid(True) # График EC plt.subplot(3, 1, 2) plt.plot(dates, ec_values, linestyle='-', color='g') plt.title(f'График EC за {week_number}-ю неделю', fontsize=14) plt.xlabel('Дата и день недели', fontsize=12) plt.ylabel('Значение EC', fontsize=12) plt.xticks(rotation=90, fontsize=6) plt.grid(True) # График насосов plt.subplot(3, 1, 3) plt.plot(dates, onA_values, linestyle='-', color='green', label='Насос A') plt.plot(dates, onB_values, linestyle='-', color='brown', label='Насос B') plt.plot(dates, onC_values, linestyle='-', color='orange', label='Насос C') plt.title(f'График работы насосов за {week_number}-ю неделю', fontsize=14) plt.xlabel('Дата и день недели', fontsize=12) plt.ylabel('Состояние насосов', fontsize=12) plt.xticks(rotation=90, fontsize=6) plt.legend() plt.grid(True) # Увеличиваем расстояние между графиками plt.subplots_adjust(hspace=1.2, bottom=0.1, top=0.95) buffer = io.BytesIO() plt.savefig(buffer, format='png') buffer.seek(0) plot_data = base64.b64encode(buffer.getvalue()).decode('utf-8') return f'''