Files
nonye/back/blueprints/chou1.py

199 lines
7.1 KiB
Python
Raw Normal View History

2025-07-17 23:13:04 +08:00
from flask import Blueprint, jsonify, request, g, current_app
from werkzeug.exceptions import HTTPException
import sqlite3
import datetime
import logging
from collections import defaultdict
import random
import numpy as np
import os
# 配置日志
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('chou1_api')
logger.setLevel(logging.DEBUG)
# 创建蓝图
bp = Blueprint('chou1', __name__, url_prefix='/api')
# 预测模型路径
PREDICTION_MODEL_PATH = "DIY_gccpu_96_96/real_prediction.npy"
prediction_data = None
def load_prediction_model():
"""加载预测模型数据"""
global prediction_data
try:
if os.path.exists(PREDICTION_MODEL_PATH):
prediction_data = np.load(PREDICTION_MODEL_PATH)
logger.info(f"预测模型加载成功,数据形状: {prediction_data.shape}")
else:
logger.warning(f"预测模型文件不存在: {PREDICTION_MODEL_PATH}")
# 生成更符合时间序列的模拟数据4个时间点
prediction_data = np.random.rand(100, 4) * 5 + 20 # 模拟温度数据(20-25°C)
except Exception as e:
logger.error(f"加载预测模型失败: {str(e)}")
prediction_data = np.random.rand(100, 4) * 5 + 20 # 模拟温度数据(20-25°C)
def get_db():
"""获取数据库连接"""
if 'db' not in g:
db_path = current_app.config.get('DATABASE', 'agriculture.db')
logger.info(f"连接数据库: {db_path}")
try:
g.db = sqlite3.connect(
db_path,
check_same_thread=False,
detect_types=sqlite3.PARSE_DECLTYPES
)
g.db.row_factory = sqlite3.Row
logger.info("数据库连接成功")
except Exception as e:
logger.error(f"数据库连接失败: {str(e)}")
raise HTTPException(status_code=500, detail=f"数据库连接失败: {str(e)}")
return g.db
def close_db(e=None):
"""关闭数据库连接"""
db = g.pop('db', None)
if db is not None:
db.close()
logger.info("数据库连接已关闭")
@bp.teardown_app_request
def teardown_request(exception):
"""请求结束时关闭数据库连接"""
close_db()
@bp.route('/chou1/devices', methods=['GET'])
def get_devices():
"""获取所有设备列表(包含设备名称)"""
try:
logger.info("获取设备列表请求")
db = get_db()
cursor = db.execute("SELECT id, device_name FROM device")
devices = cursor.fetchall()
device_dict = {str(device['id']): device['device_name'] for device in devices}
logger.info(f"返回设备列表: {len(devices)} 个设备")
return jsonify({
"code": 200,
"message": "Success",
"data": device_dict
})
except Exception as e:
logger.error(f"获取设备列表失败: {str(e)}", exc_info=True)
return jsonify({
"code": 500,
"message": f"服务器错误: {str(e)}"
}), 500
@bp.route('/sensor/device/<int:device_id>/latest', methods=['GET'])
def get_latest_sensor_data(device_id):
"""获取传感器数据(所有设备返回相同数据)"""
try:
logger.info(f"获取传感器数据请求忽略设备ID: {device_id}")
# 生成模拟数据(所有设备相同)
now = datetime.datetime.now()
current_time = now.strftime('%H:%M')
current_temp = 25 + random.uniform(-2, 2) # 23-27°C之间的随机值
logger.info(f"返回模拟数据: {current_time}, {current_temp}")
return jsonify({
"code": 200,
"message": "Success",
"data": {
"time": current_time,
"temperature": current_temp
}
})
except Exception as e:
logger.error(f"获取传感器数据失败: {str(e)}", exc_info=True)
# 生成模拟数据
now = datetime.datetime.now()
current_time = now.strftime('%H:%M')
current_temp = 25 + random.uniform(-2, 2)
return jsonify({
"code": 200,
"message": f"获取数据时发生警告: {str(e)}",
"data": {
"time": current_time,
"temperature": current_temp
}
})
@bp.route('/prediction/temperature/latest', methods=['GET'])
def get_latest_temperature_prediction():
"""获取最新的温度预测数据(只返回一个点)"""
try:
global prediction_data
current_temp = float(request.args.get('current_temp', 25.0)) if 'current_temp' in request.args else None
if prediction_data is None:
load_prediction_model()
if prediction_data is not None:
# 确保获取标量值
random_index = random.randint(0, prediction_data.shape[0] - 1)
# 处理不同维度的数据
if prediction_data.ndim == 1: # 一维数组
prediction = prediction_data[random_index]
elif prediction_data.ndim == 2: # 二维数组 (samples, timesteps)
random_col = random.randint(0, prediction_data.shape[1] - 1)
prediction = prediction_data[random_index, random_col]
elif prediction_data.ndim == 3: # 三维数组 (samples, timesteps, features)
random_col = random.randint(0, prediction_data.shape[1] - 1)
prediction = prediction_data[random_index, random_col, 0] # 取第一个特征
else:
prediction = prediction_data.flat[random_index] # 其他情况取扁平化值
prediction = float(prediction) # 确保转换为浮点数
# 调整预测值范围
prediction = current_temp + (prediction - 25) * 0.5 if current_temp else prediction
# 确保预测值与当前温度不同(如果提供了当前温度)
if current_temp and abs(prediction - current_temp) < 0.5:
prediction = current_temp + (0.5 if random.random() > 0.5 else -0.5)
return jsonify({
"code": 200,
"message": "Success",
"data": prediction
})
else:
# 生成模拟预测数据
prediction = 25 + random.uniform(-2, 2)
if current_temp and abs(prediction - current_temp) < 0.5:
prediction = current_temp + (0.5 if random.random() > 0.5 else -0.5)
return jsonify({
"code": 200,
"message": "Success",
"data": prediction
})
except Exception as e:
logger.error(f"获取温度预测数据失败: {str(e)}", exc_info=True)
# 生成模拟预测数据
prediction = 25 + random.uniform(-2, 2)
if 'current_temp' in request.args:
current_temp = float(request.args['current_temp'])
if abs(prediction - current_temp) < 0.5:
prediction = current_temp + (0.5 if random.random() > 0.5 else -0.5)
return jsonify({
"code": 200,
"message": f"获取预测数据时发生警告: {str(e)}",
"data": prediction
})