You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
8.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 导入必要的模块和类
from app import create_app, db # 从app包导入Flask应用工厂函数和数据库实例
from app.models import MonitorPoint, AlarmRule, AlarmRecord # 导入数据模型类
from datetime import datetime, timedelta # 导入日期时间处理模块
import random # 导入随机数生成模块
def create_alarm_data():
"""
创建报警测试数据的主函数
这个函数会为每个监控点创建报警规则,并生成模拟的报警记录
"""
# 创建Flask应用实例
# create_app()是应用工厂函数返回配置好的Flask应用对象
app = create_app()
# 使用应用上下文来执行数据库操作
# app.app_context()确保我们在Flask应用上下文中工作这是访问数据库所必需的
with app.app_context():
# 第一步:清理现有的报警数据
# 先删除报警记录,再删除报警规则(由于外键约束,需要按顺序删除)
AlarmRecord.query.delete() # 删除所有现有的报警记录
AlarmRule.query.delete() # 删除所有现有的报警规则
# 第二步:获取所有监控点
# MonitorPoint.query.all() 查询数据库中的所有监控点
points = MonitorPoint.query.all()
# 检查是否已存在监控点数据
if not points:
print("请先创建监控点数据!")
return # 如果没有监控点,则退出函数
# 第三步:为每个监控点创建报警规则
rules = [] # 创建一个空列表来存储所有创建的报警规则对象
# 遍历每个监控点
for point in points:
# 为当前监控点创建溶解氧报警规则
rules.append(AlarmRule(
point_id=point.id, # 关联监控点ID
parameter='dissolved_oxygen', # 监控参数:溶解氧
min_value=4.0, # 最小值阈值
max_value=8.0, # 最大值阈值
level='warning', # 报警级别:警告
enabled=True # 规则启用状态
))
# 为当前监控点创建pH值报警规则
rules.append(AlarmRule(
point_id=point.id,
parameter='ph_value', # 监控参数pH值
min_value=6.5, # 最小pH值
max_value=8.5, # 最大pH值
level='danger', # 报警级别:危险
enabled=True
))
# 为当前监控点创建温度报警规则
rules.append(AlarmRule(
point_id=point.id,
parameter='temperature', # 监控参数:温度
min_value=20.0, # 最低温度
max_value=28.0, # 最高温度
level='warning',
enabled=True
))
# 为当前监控点创建氨氮报警规则
rules.append(AlarmRule(
point_id=point.id,
parameter='ammonia_nitrogen', # 监控参数:氨氮
min_value=0.1, # 最小氨氮值
max_value=0.5, # 最大氨氮值
level='danger',
enabled=True
))
# 为当前监控点创建浊度报警规则
rules.append(AlarmRule(
point_id=point.id,
parameter='turbidity', # 监控参数:浊度
min_value=10.0, # 最小浊度
max_value=30.0, # 最大浊度
level='warning',
enabled=True
))
# 第四步:保存所有报警规则到数据库
# 遍历规则列表,将每个规则对象添加到数据库会话中
for rule in rules:
db.session.add(rule) # 将规则对象添加到数据库会话
# 提交事务,将所有添加的规则实际保存到数据库
db.session.commit()
# 第五步:创建报警记录数据
now = datetime.utcnow() # 获取当前UTC时间
# 定义各参数的单位,用于生成阈值描述
parameter_units = {
'dissolved_oxygen': 'mg/L', # 溶解氧单位:毫克/升
'ph_value': '', # pH值无单位
'temperature': '', # 温度单位:摄氏度
'ammonia_nitrogen': 'mg/L', # 氨氮单位:毫克/升
'turbidity': 'NTU' # 浊度单位NTU
}
# 创建活跃报警记录状态为active的报警
for _ in range(5): # 循环5次创建5条活跃报警
rule = random.choice(rules) # 随机选择一个报警规则
# 确保规则有最小值和最大值定义
if rule.min_value is not None and rule.max_value is not None:
# 随机决定是低于最小值还是超过最大值
if random.choice([True, False]):
# 生成低于最小值的数据
value = rule.min_value - random.uniform(0.5, 2.0)
# 生成阈值描述文本
threshold_desc = f"低于最小值 {rule.min_value} {parameter_units.get(rule.parameter, '')}"
else:
# 生成超过最大值的数据
value = rule.max_value + random.uniform(0.5, 2.0)
threshold_desc = f"超过最大值 {rule.max_value} {parameter_units.get(rule.parameter, '')}"
# 创建报警记录对象
alarm = AlarmRecord(
point_id=rule.point_id, # 关联的监控点ID
rule_id=rule.id, # 触发的规则ID
parameter=rule.parameter, # 报警参数类型
current_value=round(value, 2), # 当前值保留2位小数
threshold=threshold_desc, # 阈值描述
level=rule.level, # 报警级别
status='active', # 报警状态:活跃中
created_at=now - timedelta(minutes=random.randint(5, 120)) # 创建时间5-120分钟前
)
db.session.add(alarm) # 将报警记录添加到数据库会话
# 创建已解决的报警记录状态为resolved的历史报警
for _ in range(20): # 循环20次创建20条历史报警
rule = random.choice(rules) # 随机选择一个报警规则
if rule.min_value is not None and rule.max_value is not None:
# 同样随机生成超出范围的值
if random.choice([True, False]):
value = rule.min_value - random.uniform(0.5, 2.0)
threshold_desc = f"低于最小值 {rule.min_value} {parameter_units.get(rule.parameter, '')}"
else:
value = rule.max_value + random.uniform(0.5, 2.0)
threshold_desc = f"超过最大值 {rule.max_value} {parameter_units.get(rule.parameter, '')}"
# 生成随机的创建时间1-30天前
created_time = now - timedelta(days=random.randint(1, 30))
# 创建已解决的报警记录
alarm = AlarmRecord(
point_id=rule.point_id,
rule_id=rule.id,
parameter=rule.parameter,
current_value=round(value, 2),
threshold=threshold_desc,
level=rule.level,
status='resolved', # 报警状态:已解决
created_at=created_time, # 报警创建时间
resolved_at=created_time + timedelta(minutes=random.randint(10, 120)) # 解决时间创建后10-120分钟
)
db.session.add(alarm)
# 第六步:提交所有报警记录到数据库
db.session.commit()
# 第七步:打印统计信息
rules_count = AlarmRule.query.count() # 统计报警规则总数
active_alarms = AlarmRecord.query.filter_by(status='active').count() # 统计活跃报警数
resolved_alarms = AlarmRecord.query.filter_by(status='resolved').count() # 统计已解决报警数
print('报警测试数据创建成功!')
print(f'已创建 {rules_count} 条报警规则')
print(f'已创建 {active_alarms} 条活跃报警')
print(f'已创建 {resolved_alarms} 条历史报警')
# 程序入口点
if __name__ == '__main__':
# 当直接运行此脚本时,执行创建报警数据的函数
create_alarm_data()