509 lines
12 KiB
Markdown
509 lines
12 KiB
Markdown
|
|
# 二次回路巡检计算算法详细说明文档
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
本文档详细说明了二次回路巡检系统中各种计算算法的实现原理、参数配置和前端实现指南。
|
|||
|
|
|
|||
|
|
## 目录
|
|||
|
|
|
|||
|
|
1. [表达式计算系统](#表达式计算系统)
|
|||
|
|
2. [JavaScript代码执行](#javascript代码执行)
|
|||
|
|
3. [时间窗口计算器](#时间窗口计算器)
|
|||
|
|
4. [巡检算法类型](#巡检算法类型)
|
|||
|
|
5. [前端实现指南](#前端实现指南)
|
|||
|
|
6. [API接口说明](#api接口说明)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 表达式计算系统
|
|||
|
|
|
|||
|
|
### 1. 表达式语法
|
|||
|
|
|
|||
|
|
支持标准的JavaScript表达式语法,变量格式为 `{地址_类型}`:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 基本比较
|
|||
|
|
{16835_0} > 100
|
|||
|
|
|
|||
|
|
// 复合条件
|
|||
|
|
{16835_0} > 50 && {16835_1} < 200
|
|||
|
|
|
|||
|
|
// 数学运算
|
|||
|
|
abs({16835_0} - {16835_1}) > 10
|
|||
|
|
|
|||
|
|
// 逻辑运算
|
|||
|
|
{16128_0} == 1 || {16129_0} == 1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 变量代码格式
|
|||
|
|
|
|||
|
|
- **遥测数据**: `{地址_0}` - 例如 `{16835_0}` 表示地址16835的遥测值
|
|||
|
|
- **遥信数据**: `{地址_1}` - 例如 `{16128_1}` 表示地址16128的遥信状态
|
|||
|
|
|
|||
|
|
### 3. 支持的运算符
|
|||
|
|
|
|||
|
|
| 运算符类型 | 运算符 | 说明 | 示例 |
|
|||
|
|
|-----------|--------|------|------|
|
|||
|
|
| 算术运算 | `+`, `-`, `*`, `/` | 基本数学运算 | `{16835_0} + {16836_0}` |
|
|||
|
|
| 比较运算 | `>`, `<`, `>=`, `<=`, `==`, `!=` | 数值比较 | `{16835_0} > 100` |
|
|||
|
|
| 逻辑运算 | `&&`, `\|\|`, `!` | 逻辑与、或、非 | `{16835_0} > 50 && {16836_0} < 200` |
|
|||
|
|
| 数学函数 | `abs()`, `max()`, `min()` | 数学函数 | `abs({16835_0} - {16836_0})` |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## JavaScript代码执行
|
|||
|
|
|
|||
|
|
### 1. 数据格式
|
|||
|
|
|
|||
|
|
JavaScript代码可以访问全局变量 `data`,格式如下:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// data 数组格式
|
|||
|
|
[
|
|||
|
|
{"16168_0": {"value": 10.5, "time": 1758778427624}},
|
|||
|
|
{"16168_0": {"value": 11.22, "time": 1758778427674}},
|
|||
|
|
{"16128_1": {"value": 1, "time": 1758778427624}},
|
|||
|
|
// ... 更多数据点
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 标准返回格式
|
|||
|
|
|
|||
|
|
JavaScript代码应返回包含以下属性的对象:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
{
|
|||
|
|
"Flag": true, // 布尔值,表示计算结果是否正常
|
|||
|
|
"ResultDescription": "计算结果描述" // 字符串,描述计算结果
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. JavaScript代码示例
|
|||
|
|
|
|||
|
|
#### 示例1:简单阈值检查
|
|||
|
|
```javascript
|
|||
|
|
function checkThreshold() {
|
|||
|
|
let abnormalCount = 0;
|
|||
|
|
|
|||
|
|
for (let item of data) {
|
|||
|
|
for (let key in item) {
|
|||
|
|
if (item[key].value > 100) {
|
|||
|
|
abnormalCount++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
Flag: abnormalCount === 0,
|
|||
|
|
ResultDescription: abnormalCount === 0 ?
|
|||
|
|
"所有数据点正常" :
|
|||
|
|
`发现${abnormalCount}个异常数据点`
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkThreshold();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 示例2:电压一致性检查
|
|||
|
|
```javascript
|
|||
|
|
function checkVoltageConsistency() {
|
|||
|
|
let voltageValues = [];
|
|||
|
|
|
|||
|
|
// 收集所有电压值
|
|||
|
|
for (let item of data) {
|
|||
|
|
for (let key in item) {
|
|||
|
|
if (key.endsWith('_0')) { // 遥测数据
|
|||
|
|
voltageValues.push(item[key].value);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (voltageValues.length < 2) {
|
|||
|
|
return {
|
|||
|
|
Flag: false,
|
|||
|
|
ResultDescription: "电压数据点不足,无法进行一致性检查"
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 计算电压偏差
|
|||
|
|
let maxVoltage = Math.max(...voltageValues);
|
|||
|
|
let minVoltage = Math.min(...voltageValues);
|
|||
|
|
let deviation = maxVoltage - minVoltage;
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
Flag: deviation <= 5.0,
|
|||
|
|
ResultDescription: `电压偏差: ${deviation.toFixed(2)}V, ${deviation <= 5.0 ? '正常' : '异常'}`
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
checkVoltageConsistency();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 示例3:时间序列分析
|
|||
|
|
```javascript
|
|||
|
|
function analyzeTimeSeries() {
|
|||
|
|
let timeSeriesData = {};
|
|||
|
|
|
|||
|
|
// 按变量代码分组数据
|
|||
|
|
for (let item of data) {
|
|||
|
|
for (let key in item) {
|
|||
|
|
if (!timeSeriesData[key]) {
|
|||
|
|
timeSeriesData[key] = [];
|
|||
|
|
}
|
|||
|
|
timeSeriesData[key].push({
|
|||
|
|
value: item[key].value,
|
|||
|
|
time: item[key].time
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let results = [];
|
|||
|
|
|
|||
|
|
// 分析每个变量的趋势
|
|||
|
|
for (let variable in timeSeriesData) {
|
|||
|
|
let values = timeSeriesData[variable];
|
|||
|
|
if (values.length >= 2) {
|
|||
|
|
let trend = values[values.length - 1].value - values[0].value;
|
|||
|
|
results.push({
|
|||
|
|
variable: variable,
|
|||
|
|
trend: trend,
|
|||
|
|
isStable: Math.abs(trend) < 1.0
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let unstableCount = results.filter(r => !r.isStable).length;
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
Flag: unstableCount === 0,
|
|||
|
|
ResultDescription: unstableCount === 0 ?
|
|||
|
|
"所有变量趋势稳定" :
|
|||
|
|
`${unstableCount}个变量趋势不稳定`
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
analyzeTimeSeries();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 时间窗口计算器
|
|||
|
|
|
|||
|
|
### 1. 基本功能
|
|||
|
|
|
|||
|
|
时间窗口计算器提供以下功能:
|
|||
|
|
|
|||
|
|
- **实时数据获取**: 获取指定时间窗口内的遥测/遥信数据
|
|||
|
|
- **时间序列生成**: 生成带时间戳的历史数据序列
|
|||
|
|
- **JavaScript表达式计算**: 支持自定义JavaScript表达式计算
|
|||
|
|
- **数据格式转换**: 自动转换为前端需要的JSON格式
|
|||
|
|
|
|||
|
|
### 2. API方法
|
|||
|
|
|
|||
|
|
#### CalculateTimeWindowDataAsync
|
|||
|
|
```csharp
|
|||
|
|
// 获取JSON格式的时间窗口数据
|
|||
|
|
Task<string> CalculateTimeWindowDataAsync(
|
|||
|
|
Guid inspectionItemId,
|
|||
|
|
int timeWindowSeconds = 60,
|
|||
|
|
CancellationToken cancellationToken = default)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### CalculateTimeSeriesDataAsync
|
|||
|
|
```csharp
|
|||
|
|
// 获取时间序列数据
|
|||
|
|
Task<List<Dictionary<string, object>>> CalculateTimeSeriesDataAsync(
|
|||
|
|
Guid inspectionItemId,
|
|||
|
|
int timeWindowSeconds = 60,
|
|||
|
|
int sampleIntervalSeconds = 5,
|
|||
|
|
CancellationToken cancellationToken = default)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 返回数据格式
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"16835_0": 52.5,
|
|||
|
|
"16835_1": 75.3,
|
|||
|
|
"16128_1": 1
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 巡检算法类型
|
|||
|
|
|
|||
|
|
### 1. 电压采集一致性判断 (VoltageCollectionConsistency)
|
|||
|
|
|
|||
|
|
**算法原理**: 检查多个电压采集点的数值一致性
|
|||
|
|
|
|||
|
|
**参数配置**:
|
|||
|
|
- `VoltageDeviationThreshold`: 电压偏差阈值(kV)
|
|||
|
|
- `TimeWindowSeconds`: 时间窗口(秒)
|
|||
|
|
|
|||
|
|
**计算逻辑**:
|
|||
|
|
```javascript
|
|||
|
|
// 示例表达式
|
|||
|
|
abs({16835_0} - {16836_0}) <= 1.0
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 电流采集一致性判断 (CurrentCollectionConsistency)
|
|||
|
|
|
|||
|
|
**算法原理**: 检查电流采集的一致性和合理性
|
|||
|
|
|
|||
|
|
**参数配置**:
|
|||
|
|
- `CurrentDeviationThresholdPercent`: 电流偏差阈值百分比(%)
|
|||
|
|
- `TimeWindowSeconds`: 时间窗口(秒)
|
|||
|
|
|
|||
|
|
**计算逻辑**:
|
|||
|
|
```javascript
|
|||
|
|
// 示例表达式
|
|||
|
|
abs(({16837_0} - {16838_0}) / {16837_0}) * 100 <= 5.0
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 位置信号采集校验 (PositionSignalVerification)
|
|||
|
|
|
|||
|
|
**算法原理**: 校验开关位置信号的正确性
|
|||
|
|
|
|||
|
|
**参数配置**:
|
|||
|
|
- `TimeWindowSeconds`: 时间窗口(秒)
|
|||
|
|
|
|||
|
|
**计算逻辑**:
|
|||
|
|
```javascript
|
|||
|
|
// 示例表达式:检查分合闸位置信号互斥
|
|||
|
|
!({16128_1} == 1 && {16129_1} == 1)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 交流回路极性校验 (ACCircuitPolarityVerification)
|
|||
|
|
|
|||
|
|
**算法原理**: 验证交流回路的极性正确性
|
|||
|
|
|
|||
|
|
**参数配置**:
|
|||
|
|
- `PhaseAngleDifferenceThreshold`: 相角差阈值(度)
|
|||
|
|
- `TimeWindowSeconds`: 时间窗口(秒)
|
|||
|
|
|
|||
|
|
**计算逻辑**:
|
|||
|
|
```javascript
|
|||
|
|
// 示例表达式:检查相角差
|
|||
|
|
abs({16840_0} - {16841_0}) <= 10.0
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5. 通信质量分析 (CommunicationQualityAnalysis)
|
|||
|
|
|
|||
|
|
**算法原理**: 分析通信链路的质量和可靠性
|
|||
|
|
|
|||
|
|
**参数配置**:
|
|||
|
|
- `TimeWindowSeconds`: 时间窗口(秒)
|
|||
|
|
|
|||
|
|
**计算逻辑**: 基于数据可用性和通信延时进行综合评估
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 前端实现指南
|
|||
|
|
|
|||
|
|
### 1. 表达式编辑器
|
|||
|
|
|
|||
|
|
推荐使用Monaco Editor或CodeMirror实现表达式编辑器:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// Monaco Editor配置示例
|
|||
|
|
const editorConfig = {
|
|||
|
|
language: 'javascript',
|
|||
|
|
theme: 'vs-dark',
|
|||
|
|
automaticLayout: true,
|
|||
|
|
minimap: { enabled: false },
|
|||
|
|
scrollBeyondLastLine: false,
|
|||
|
|
wordWrap: 'on'
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 变量代码提示
|
|||
|
|
|
|||
|
|
实现变量代码的智能提示功能:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 变量代码提示数据
|
|||
|
|
const variableHints = [
|
|||
|
|
{ label: '{16835_0}', detail: '电压A相 (遥测)', insertText: '{16835_0}' },
|
|||
|
|
{ label: '{16836_0}', detail: '电压B相 (遥测)', insertText: '{16836_0}' },
|
|||
|
|
{ label: '{16128_1}', detail: '分闸位置 (遥信)', insertText: '{16128_1}' },
|
|||
|
|
// ... 更多提示
|
|||
|
|
];
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 表达式验证
|
|||
|
|
|
|||
|
|
前端应实现表达式语法验证:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
async function validateExpression(expression) {
|
|||
|
|
try {
|
|||
|
|
const response = await fetch('/api/secondary-circuit/validate-expression', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: { 'Content-Type': 'application/json' },
|
|||
|
|
body: JSON.stringify({ expression })
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const result = await response.json();
|
|||
|
|
return result;
|
|||
|
|
} catch (error) {
|
|||
|
|
return { isValid: false, errors: [error.message] };
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 实时数据预览
|
|||
|
|
|
|||
|
|
提供实时数据预览功能:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
async function previewCalculation(inspectionItemId, expression) {
|
|||
|
|
try {
|
|||
|
|
const response = await fetch('/api/secondary-circuit/test-expression', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: { 'Content-Type': 'application/json' },
|
|||
|
|
body: JSON.stringify({
|
|||
|
|
inspectionItemId,
|
|||
|
|
expression,
|
|||
|
|
timeWindowSeconds: 60
|
|||
|
|
})
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const result = await response.json();
|
|||
|
|
return result;
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('预览计算失败:', error);
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## API接口说明
|
|||
|
|
|
|||
|
|
### 1. 表达式验证接口
|
|||
|
|
|
|||
|
|
**URL**: `POST /api/secondary-circuit/validate-expression`
|
|||
|
|
|
|||
|
|
**请求参数**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"expression": "{16835_0} > 100 && {16836_0} < 200"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应格式**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"flag": true,
|
|||
|
|
"message": "表达式语法正确",
|
|||
|
|
"resultData": {
|
|||
|
|
"isValid": true,
|
|||
|
|
"errors": [],
|
|||
|
|
"warnings": [],
|
|||
|
|
"variableCodes": ["16835_0", "16836_0"]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 表达式测试接口
|
|||
|
|
|
|||
|
|
**URL**: `POST /api/secondary-circuit/test-expression`
|
|||
|
|
|
|||
|
|
**请求参数**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"expression": "{16835_0} > 100",
|
|||
|
|
"timeWindowSeconds": 60
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应格式**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"flag": true,
|
|||
|
|
"message": "表达式计算成功",
|
|||
|
|
"resultData": {
|
|||
|
|
"isSuccess": true,
|
|||
|
|
"result": true,
|
|||
|
|
"executionTimeMs": 15,
|
|||
|
|
"variableValues": {
|
|||
|
|
"16835_0": 105.5
|
|||
|
|
},
|
|||
|
|
"evaluationDetails": [
|
|||
|
|
"提取到 1 个变量: 16835_0",
|
|||
|
|
"替换后的表达式: 105.5 > 100",
|
|||
|
|
"计算结果: true"
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 时间窗口数据获取接口
|
|||
|
|
|
|||
|
|
**URL**: `GET /api/secondary-circuit/time-window-data/{inspectionItemId}`
|
|||
|
|
|
|||
|
|
**查询参数**:
|
|||
|
|
- `timeWindowSeconds`: 时间窗口(秒),默认60
|
|||
|
|
- `format`: 返回格式,可选 `json` 或 `timeseries`
|
|||
|
|
|
|||
|
|
**响应格式**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"flag": true,
|
|||
|
|
"message": "获取成功",
|
|||
|
|
"resultData": "{\"16835_0\": 52.5, \"16835_1\": 75.3}"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 最佳实践
|
|||
|
|
|
|||
|
|
### 1. 表达式设计原则
|
|||
|
|
|
|||
|
|
- **简洁明了**: 表达式应该易于理解和维护
|
|||
|
|
- **性能考虑**: 避免过于复杂的计算逻辑
|
|||
|
|
- **错误处理**: 考虑数据缺失或异常情况
|
|||
|
|
- **文档说明**: 为复杂表达式添加注释说明
|
|||
|
|
|
|||
|
|
### 2. JavaScript代码规范
|
|||
|
|
|
|||
|
|
- **函数封装**: 将复杂逻辑封装为函数
|
|||
|
|
- **错误处理**: 添加适当的错误检查
|
|||
|
|
- **性能优化**: 避免不必要的循环和计算
|
|||
|
|
- **返回格式**: 严格按照标准格式返回结果
|
|||
|
|
|
|||
|
|
### 3. 前端集成建议
|
|||
|
|
|
|||
|
|
- **用户体验**: 提供友好的编辑和调试界面
|
|||
|
|
- **实时反馈**: 实现表达式语法检查和结果预览
|
|||
|
|
- **帮助文档**: 集成在线帮助和示例代码
|
|||
|
|
- **版本管理**: 支持表达式的版本控制和回滚
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 常见问题解答
|
|||
|
|
|
|||
|
|
### Q1: 如何处理数据缺失的情况?
|
|||
|
|
|
|||
|
|
A: 系统会自动将缺失的数据设置为默认值(遥测为0,遥信为false),建议在表达式中添加数据有效性检查。
|
|||
|
|
|
|||
|
|
### Q2: JavaScript代码的执行时间限制是多少?
|
|||
|
|
|
|||
|
|
A: 默认限制为30秒,超时会自动终止执行并返回错误信息。
|
|||
|
|
|
|||
|
|
### Q3: 支持哪些JavaScript内置函数?
|
|||
|
|
|
|||
|
|
A: 支持标准的Math对象函数,如Math.abs()、Math.max()、Math.min()等,以及基本的数组和字符串操作。
|
|||
|
|
|
|||
|
|
### Q4: 如何调试复杂的JavaScript代码?
|
|||
|
|
|
|||
|
|
A: 可以使用console.log()输出调试信息,这些信息会包含在返回结果的详情中。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*本文档版本: 1.0*
|
|||
|
|
*最后更新: 2024年*
|