import yaml from fastapi import APIRouter, HTTPException from pydantic import BaseModel from typing import List, Tuple import matplotlib.pyplot as plt from matplotlib import cm from mpl_toolkits.mplot3d import Axes3D import io import base64 from db.crud import * from db.models import LoadParameters from db.repositories import get_exp_parameters_by_category, get_exp_parameters_by_exp_hash from macros_generator import load_calculation, recycling_calculation from network.routes.ch_experimentdb_experiment_data_router import get_ch_experimentdb_experiment_data_by_file_id from network.schemas import ExperimentParametersBody, ExperimentParametersPlot router = APIRouter() @router.post('/create') async def create_experiment_parameters(body: ExperimentParametersBody): try: await create(ExperimentParameters, outer_blades_count=body.outer_blades_count, outer_blades_length=body.outer_blades_length, outer_blades_angle=body.outer_blades_angle, middle_blades_count=body.middle_blades_count, load_id=body.load_id, recycling_id=body.recycling_id, experiment_hash=body.experiment_hash ) return {"message": "Новая запись успешно добавлена"} except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") @router.post('/plot') async def create_plot(body: ExperimentParametersPlot): try: exp_data = await get_ch_experimentdb_experiment_data_by_file_id(body.file_id) if not exp_data: raise HTTPException(status_code=404, detail="Данные не найдены для указанного file_id") filtered_data = [ record for record in exp_data if body.range[0] <= getattr(record, body.additional_dimension, None) <= body.range[1] ] if not filtered_data: return {"message": "Нет данных для отображения в заданном диапазоне"} x = [record.x for record in filtered_data] y = [record.y for record in filtered_data] z = [record.z for record in filtered_data] color_values = [getattr(record, body.additional_dimension, None) for record in filtered_data] fig = plt.figure(figsize=(10, 8)) ax = fig.add_subplot(111, projection='3d') scatter = ax.scatter(x, y, z, c=color_values, cmap=cm.viridis, marker='o') cbar = fig.colorbar(scatter, ax=ax) cbar.set_label(body.additional_dimension) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.title(f"3D график с измерением: {body.additional_dimension}") buf = io.BytesIO() plt.savefig(buf, format='png') buf.seek(0) image_base64 = base64.b64encode(buf.getvalue()).decode('utf-8') buf.close() plt.close(fig) return {"message": "График построен успешно", "plot": image_base64} except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") @router.get('/all') async def get_all_experiment_parameters(): try: result = await get_all(ExperimentParameters) if result is not None: return result else: return {"message": "Нет записей в "} except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") @router.get('/{id}') async def get_by_id_experiment_parameters(id: int): try: result = await get_by_id(ExperimentParameters, id) if result is not None: return result else: return {"message": "Запись не найдена"} except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") @router.get('/by_category/{id}') async def get_experiment_parameters_by_exp_category(id: int): try: result = await get_exp_parameters_by_category(id) if result is not None: return result else: return {"message": f' с идентификатором категории - {id} - не найдены'} except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") @router.get('/by_exp_hash/{hash}') async def get_experiment_parameters_by_exp_category(hash: str): try: result = await get_exp_parameters_by_exp_hash(hash) if result is not None: return result else: return {"message": f' с experiment_hash = {id} - не найдены'} except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") @router.delete('/{id}/delete') async def delete_experiment_parameters(id: int): try: is_deleted = await delete(ExperimentParameters, id) if is_deleted: return {"message": "Запись успешно удалена"} else: return {"message": "Запись не найдена"} except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") # @router.post('/process_and_save/{id}') было нужно для проверки async def process_and_save_experiment_data(id: int, load: float, recycling_level: float) -> dict: try: experiment = await get_by_id(ExperimentParameters, id) if experiment is None: raise HTTPException(status_code=404, detail=f"ExperimentParameters с id {id} не найден.") yaml_file_path = "config.yaml" with open(yaml_file_path, "r", encoding="utf-8") as file: data = yaml.safe_load(file) diameters = data["parameters"]["diameters"] dict_load = load_calculation(load, diameters, None) primary_air_consumption = dict_load["primary_air_consumption"] secondary_air_consumption = dict_load["secondary_air_consumption"] gas_inlet_consumption = dict_load["gas_inlet_consumption"] alpha = dict_load["alpha"] gas_consumption = dict_load["gas_consumption"] air_consumption = dict_load["air_consumption"] dict_recycling = recycling_calculation(alpha, gas_consumption, air_consumption, recycling_level) co2 = dict_recycling["CO2"] n2 = dict_recycling["N2"] h2o = dict_recycling["H2O"] o2 = dict_recycling["O2"] load_params = await create( LoadParameters, load=int(load), primary_air_consumption=primary_air_consumption, secondary_air_consumption=secondary_air_consumption, gas_inlet_consumption=gas_inlet_consumption ) recycling_params = await create( RecyclingParameters, load_id=load_params.id, recycling_level=int(recycling_level), co2=co2, n2=n2, h2o=h2o, o2=o2 ) await update_exp( ExperimentParameters, id=experiment.id, updated_data={ "load_id": load_params.id, "recycling_id": recycling_params.id } ) return { "message": "Данные успешно обработаны и сохранены.", "load_parameters": load_params, "recycling_parameters": recycling_params } except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}")