Skip to content

Rex0519/ele

Repository files navigation

电力数据仿真系统

基于真实电力数据的仿真系统,支持自动生成符合实际用电规律的模拟数据,提供 REST API 和 MCP Server 供 AI 查询,并具备智能告警和飞书通知能力。通过 FlowiseAI 平台提供自然语言对话界面,供管理层直接查询用电数据。

功能特性

  • 自然语言查询:通过 FlowiseAI Agent 对话界面,用自然语言查询用电数据和告警信息
  • 数据仿真:基于历史数据统计特征,按时段规律(夜间低谷、早晚高峰)自动生成仿真电力数据
  • 智能告警:支持阈值告警、趋势异常检测(同比激增/骤降)、设备离线检测
  • 短信通知:检测到高级别告警时自动发送短信通知(支持接入第三方短信平台)
  • REST API:完整的设备管理、电力数据查询、告警管理接口
  • MCP Server:支持 stdio 和 Streamable HTTP 双传输模式,供 Claude Desktop 和 FlowiseAI 等 AI 平台调用
  • 定时调度:每小时自动生成仿真数据并执行告警检测
  • CSV 离线导出:每日自动导出数据到 CSV 文件,供 OpenClaw 等 AI Agent 通过 pandas 做离线分析

系统架构

管理层用户 ──自然语言对话──→ FlowiseAI Agent ──MCP/HTTP──→ FastAPI + MCP Server ──→ PostgreSQL
                                                            ↑
                                        APScheduler ──告警检测──→ 飞书 Webhook
                                                   └──CSV导出──→ data_export/ ──→ OpenClaw Agent

技术栈

组件 技术
数据库 PostgreSQL 16 + TimescaleDB
后端框架 FastAPI
ORM SQLAlchemy 2.0
调度器 APScheduler
AI 集成 MCP SDK (stdio + Streamable HTTP)
AI 前端 FlowiseAI (Docker)
部署 Docker Compose

快速开始

环境要求

  • Python 3.12+
  • Docker & Docker Compose
  • uv(Python 包管理器)

1. 安装依赖

# 克隆项目后进入目录
cd ele

# 安装依赖
uv sync

2. 准备数据

确保 data_extracted/ 目录包含以下 Excel 文件(从 data.zip 解压):

data_extracted/
├── ene_config_area.xls    # 区域配置
├── ene_config_item.xls    # 项目配置
├── ene_config_device.xls  # 设备-配置关联
├── devicenfo.xls          # 设备信息
└── electric.xls           # 历史电力数据

解压命令:

unzip data.zip -d data_extracted

3. 启动服务

# 启动数据库
docker-compose up -d db

# 等待数据库就绪(约 10 秒)
docker-compose ps  # 确认状态为 healthy

# 启动应用
uv run python -m src.main

应用启动时会自动:

  1. 导入 Excel 数据到数据库
  2. 提取设备特征用于仿真
  3. 生成告警阈值配置(首次启动,477 条)
  4. 回补数据空洞(检测 30 天内所有缺失小时并补全)
  5. 清理 30 天前的过期告警
  6. 启动定时调度器(每小时整点执行)

4. 配置 FlowiseAI

FlowiseAI 已集成到 docker-compose,启动全部服务:

docker-compose up -d

访问 http://localhost:13000 进入 FlowiseAI,然后:

  1. 创建 Agentflow → 添加 Custom MCP Tool
    • URL: http://app:8000/mcp
    • 点击 Refresh Actions 加载工具列表
  2. 配置 System Message → 粘贴系统提示词(见 docs/system-prompt.md
  3. 保存并测试对话

5. 访问服务

服务 地址
FlowiseAI http://localhost:13000
API 文档 http://localhost:8000/docs
MCP 端点 http://localhost:8000/mcp
健康检查 http://localhost:8000/health

数据库连接

参数
Host localhost
Port 5432
Database electric
User admin
Password password

命令行连接:

docker exec -it ele-db-1 psql -U admin -d electric

API 接口

设备管理

方法 路径 说明
GET /api/devices 获取设备列表
GET /api/devices/{device_id} 获取设备详情
GET /api/devices/{device_id}/data 获取设备历史电力数据

电力数据

方法 路径 说明
GET /api/electric/realtime 获取实时电力数据
GET /api/electric/areas/{area_id}/summary 获取区域用电汇总
GET /api/electric/statistics 获取统计分析数据

告警管理

方法 路径 说明
GET /api/alerts 获取告警列表
GET /api/alerts/active 获取未解决告警
POST /api/alerts/{alert_id}/resolve 标记告警已解决
GET /api/alerts/thresholds 获取阈值配置
PUT /api/alerts/thresholds/{device_id} 更新设备阈值

示例请求

# 获取设备列表
curl http://localhost:8000/api/devices

# 获取实时数据
curl http://localhost:8000/api/electric/realtime?limit=10

# 获取统计数据(按天/周/月)
curl "http://localhost:8000/api/electric/statistics?period=day"

# 获取未解决告警
curl http://localhost:8000/api/alerts/active

# 设置设备告警阈值
curl -X PUT http://localhost:8000/api/alerts/thresholds/123456 \
  -H "Content-Type: application/json" \
  -d '{"min_value": 0, "max_value": 100, "severity": "WARNING"}'

MCP Server

系统提供 MCP Server,支持 stdio 和 Streamable HTTP 双传输模式。

可用工具

工具名 说明
list_areas 列出所有区域
list_devices 列出设备,可按区域或类型过滤
query_electric_data 查询指定设备的电力数据(支持名称模糊匹配)
get_area_summary 获取区域用电汇总(支持名称模糊匹配)
compare_usage 对比用电量(日/周/区域排名)
list_active_alerts 列出当前未解决告警
analyze_anomaly 分析设备异常情况(支持名称模糊匹配)

Streamable HTTP 模式(FlowiseAI 等 AI 平台)

应用启动后 MCP 端点自动可用:http://localhost:8000/mcp

stdio 模式(Claude Desktop)

claude_desktop_config.json 中添加:

{
  "mcpServers": {
    "electric-simulation": {
      "command": "uv",
      "args": ["run", "python", "-c", "import asyncio; from src.mcp.server import run_mcp_server; asyncio.run(run_mcp_server())"],
      "cwd": "/path/to/ele",
      "env": {
        "DATABASE_URL": "postgresql+psycopg://admin:password@localhost:5432/electric"
      }
    }
  }
}

短信通知

系统在检测到 HIGH 或 CRITICAL 级别告警时自动发送短信通知。

配置

通过环境变量或 .env 文件配置:

SMS_ENABLED=true
SMS_PHONES='["13800138000","13900139000"]'

当前使用占位实现(DummySmsSender),仅打印日志。接入真实短信平台时,继承 SmsSender 基类实现 send 方法即可。

数据仿真原理

时段系数

系统根据实际用电规律,为不同时段设置系数:

时段 系数 说明
0:00 - 6:00 0.5 夜间低谷
7:00 - 9:00 1.3 早高峰
10:00 - 17:00 1.0 工作时段
18:00 - 21:00 1.4 晚高峰
22:00 - 23:00 0.7 夜间过渡

生成算法

基础值 = 历史均值 × 时段系数
正常增量 = max(0, 基础值 + 随机波动)      # 97% 概率
异常增量 = 基础值 × 2.5~4.0(激增)       # 1.5% 概率
         | 基础值 × 0.02~0.15(骤降)     # 1.5% 概率
累计值 = 上次累计值 + 增量

正常波动服从正态分布 N(0, std × 0.3)。异常数据约占 3%,确保告警系统有足够的触发场景用于演示。

业务口径补充

设备点位与命名规则

  • 点位编号(point_id):根据解析出的区域与设备类型生成 区域缩写-设备类型缩写-序号(例如 XBL-KT-01)。
  • 显示名称区域-设备类型-序号号(例如 西北-空调-01号)。
  • 区域解析:优先匹配设备名中的楼层与方位缩写(如 F-WSF-WN 等),其次匹配 243/238/249 等层号,未命中则归为"其他"。
  • 设备类型解析:通过设备名内置关键字或缩写(如 ktfjsy 等)映射成业务分类;未命中则归为"其他"。

设备画像生成口径

系统启动导入 Excel 数据后,会基于 devicenfo.xls 生成设备画像(device_profile):

  • 默认均值 mean_value = 10.0、标准差 std_value = 2.0、最小值 min_value = 0.0、最大值 max_value = 50.0
  • 累计值初始为 last_value = 0,用于后续仿真累加。
  • 设备画像是仿真数据的基础,当前版本不依赖历史电力表中的统计特征。

仿真数据生成口径

每小时任务遍历全部设备画像,按"时段系数 + 随机扰动"计算增量:

  • 97% 正常数据:增量 = max(0, mean_value × 时段系数 + noise),其中 noise = N(0, std_value × 0.3)
  • 3% 异常数据:增量 = 基础值 × [2.5, 4.0](激增)或 基础值 × [0.02, 0.15](骤降)。
  • value = last_value + 增量,并回写到 device_profile.last_value
  • 每条仿真数据的 device_idhash(point_id) % 10^18 作为稳定标识。

告警检测口径

  • 阈值告警:基于最新一条电力增量 incr 与阈值配置(threshold_config)判断是否越界。默认阈值范围 [2.0, 18.0],正常数据约 514,异常数据可达 0.152。
  • 趋势告警:取"最近一小时内的最新值"对比"昨日同时间段(前后 1 小时窗口)"的增量,超过 1.5 倍或低于 0.3 倍触发。
  • 离线告警:设备 2 小时内无数据上报触发 HIGH 告警,且未解决告警不会重复生成。
  • 短信通知:仅对 HIGH/CRITICAL 告警发送,最多展示前 5 条信息。

数据维护

  • 自动回补:启动时检测 30 天内所有小时级数据空洞,逐小时回补。容器重启导致的数据中断会自动修复。
  • 过期清理:自动清理 30 天前的告警记录。
  • 数据保留:TimescaleDB 自动删除 30 天前的 electric_data(retention policy)。

告警规则

1. 阈值告警

当电力增量超出配置的阈值范围时触发。系统启动时自动为所有设备生成默认阈值配置(min=2.0, max=18.0, severity=WARNING),可通过 API 调整。

-- 查看当前阈值配置
SELECT point_id, min_value, max_value, severity FROM threshold_config LIMIT 5;

-- 手动调整某设备阈值
UPDATE threshold_config SET max_value = 15.0, severity = 'HIGH' WHERE point_id = 'XBL-KT-01';

2. 趋势异常

  • 同比激增:当前增量 > 昨日同时段 × 1.5
  • 同比骤降:当前增量 < 昨日同时段 × 0.3

3. 设备离线

设备超过 2 小时无数据上报时触发 HIGH 级别告警。

数据库结构

核心表

表名 说明
config_area 区域配置
config_item 项目配置(充电桩、照明、空调等)
device 设备信息
config_device 设备-配置关联
electric_data 电力时序数据(TimescaleDB hypertable)
alert 告警记录
threshold_config 阈值配置
device_profile 设备特征(用于仿真)

查询示例

-- 查看设备数量
SELECT count(*) FROM device;

-- 查看最近的电力数据
SELECT * FROM electric_data ORDER BY time DESC LIMIT 10;

-- 查看异常数据(超出阈值范围)
SELECT point_id, time, incr FROM electric_data WHERE incr > 18 OR incr < 2 ORDER BY time DESC LIMIT 20;

-- 查看未解决的告警
SELECT * FROM alert WHERE resolved_at IS NULL;

-- 查看告警统计
SELECT alert_type, severity, count(*) FROM alert GROUP BY alert_type, severity;

-- 查看设备特征
SELECT point_id, mean_value, std_value FROM device_profile LIMIT 10;

-- 查看阈值配置
SELECT point_id, min_value, max_value, severity FROM threshold_config LIMIT 10;

-- 检查数据连续性(最近48小时)
SELECT time_bucket('1 hour', time) AS hour, count(*) FROM electric_data
GROUP BY hour ORDER BY hour DESC LIMIT 48;

项目结构

ele/
├── docker-compose.yml      # Docker 编排(含 FlowiseAI)
├── Dockerfile              # 应用镜像
├── pyproject.toml          # 项目依赖
├── README.md               # 本文档
│
├── scripts/
│   └── init_db.sql         # 数据库初始化
│
├── src/
│   ├── main.py             # 应用入口
│   ├── config.py           # 配置管理
│   ├── scheduler.py        # 定时调度
│   │
│   ├── db/                 # 数据库层
│   │   ├── models.py       # ORM 模型
│   │   ├── connection.py   # 连接管理
│   │   ├── init_data.py    # 数据导入
│   │   ├── maintenance.py  # 数据维护(回补/清理)
│   │   └── device_parser.py # 设备名称解析器
│   │
│   ├── api/                # REST API
│   │   ├── devices.py      # 设备接口
│   │   ├── electric.py     # 电力数据接口
│   │   └── alerts.py       # 告警接口
│   │
│   ├── simulator/          # 仿真引擎
│   │   ├── generator.py    # 数据生成器
│   │   └── profiles.py     # 时段系数
│   │
│   ├── alert/              # 告警系统
│   │   ├── detector.py     # 告警检测器
│   │   ├── rules.py        # 告警规则
│   │   └── sms.py          # 短信发送(抽象层)
│   │
│   ├── mcp/                # MCP Server
│   │   └── server.py       # AI 工具服务(stdio + Streamable HTTP)
│   │
│   └── export/             # CSV 离线导出
│       └── csv_exporter.py # 数据导出器
│
├── tests/                  # 测试用例
│
├── data_extracted/         # Excel 数据(需解压)
├── data_export/            # CSV 导出目录(自动生成,已 gitignore)
│
├── docs/
│   ├── system-prompt.md    # Agent 系统提示词
│   └── plans/              # 设计文档

CSV 离线导出与 OpenClaw 集成

系统每天凌晨 02:00 自动将数据库数据导出为 CSV 文件到 data_export/ 目录(通过 Docker volume 映射到宿主机)。

导出文件

文件 说明
areas.csv 区域配置
devices.csv 设备列表(含区域、类型、测点)
electric_data.csv 近 30 天逐小时用电数据
alerts.csv 告警记录
_metadata.json 导出元信息、表关系、字段说明

手动触发导出

from src.db import get_db
from src.export import CsvExporter

db = next(get_db())
CsvExporter(db).export_all()
db.close()

OpenClaw Skill

安装 electric-analysis skill 后,OpenClaw agent 可自动分析导出的电力数据:

# skill 文件位置
~/.openclaw/skills/electric-analysis/SKILL.md

支持的分析场景:区域用电排名、日环比对比、设备类型分布、异常设备检测、时段用电模式。也支持自定义查询(agent 根据 schema 自行生成 pandas 代码)。

开发

运行测试

uv run pytest tests/ -v

手动触发仿真

from src.db import get_db
from src.simulator import SimulationGenerator
from src.alert import AlertDetector

db = next(get_db())

# 生成仿真数据
generator = SimulationGenerator(db)
records = generator.generate_hourly_data()
print(f"Generated {len(records)} records")

# 执行告警检测
detector = AlertDetector(db)
alerts = detector.detect_all()
print(f"Detected {len(alerts)} alerts")

db.close()

停止服务

# 停止应用(Ctrl+C)

# 停止所有 Docker 服务
docker-compose down

# 停止并删除数据库数据
docker-compose down -v

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors