using GDNXFD.Data;
using System;
using System.Collections.Generic;
namespace GDNXFD.Alert.Interpreter
{
public abstract class AlertRuleInterpreter
{
private AlertRule _alertRule;
private string[] _windturbines;
private string[] _stations;
private string[] _projects;
private string[] _lines;
private string[] _electricals;
protected IDataProvider dataProvider;
public AlertRuleInterpreter(AlertRule ar)
{
_alertRule = ar;
dataProvider = InterpreterFactory.Instance.DataProvider;
}
public string Category
{
get { return _alertRule.Category; }
}
public AlertRule AlertRule
{
get { return _alertRule; }
}
public string[] Windturbines
{
get
{
if (_windturbines == null && Category == "1" && !string.IsNullOrWhiteSpace(_alertRule.Windturbine))
{
_windturbines = _alertRule.Windturbine.Split(',');
}
return _windturbines;
}
}
public string[] Stations
{
get
{
if (_stations == null && Category == "2" && !string.IsNullOrWhiteSpace(_alertRule.Station))
{
_stations = _alertRule.Station.Split(',');
}
return _stations;
}
}
public string[] Projects
{
get
{
if (_projects == null && Category == "3" && !string.IsNullOrWhiteSpace(_alertRule.Project))
{
_projects = _alertRule.Project.Split(',');
}
return _projects;
}
}
public string[] Lines
{
get
{
if (_lines == null && Category == "4" && !string.IsNullOrWhiteSpace(_alertRule.Line))
{
_lines = _alertRule.Line.Split(',');
}
return _lines;
}
}
public string[] Electricals
{
get
{
if (_electricals == null && Category == "5" && !string.IsNullOrWhiteSpace(_alertRule.Station))
{
_electricals = _alertRule.Station.Split(',');
}
return _electricals;
}
}
protected string dataInfo;
///
/// 存放实时数据的值,带入dataProvider中进行更新
///
public string DataInfo
{
get { return dataInfo; }
set { dataInfo = value; }
}
///
/// 规则解释类
/// 在自动生成的规则解析代码中实现该方法
///
///
///
///
public abstract bool Interpret(string objectId, AlertObjectType objectType);
#region 扩展方法
///
/// 判定状态保持的方法
/// 应用场景:读取实时库某一点的历史值,时间区间为:当前时间向前追溯{duration}分钟,
/// 若时间段范围内无值或只有一个值,返回false
/// 若时间段内有若干值(大于1)且都相同,则认为该状态一直持续未变
///
/// 测点名称
/// 持续时间,单位:分钟
/// 对象ID
/// 对象类型
///
/// true:时间段内状态不变
/// false:时间段内数据不足或者状态变动过
///
protected bool StatusContinued(string testPointName, int duration, string objectId, AlertObjectType objectType)
{
testPointName = testPointName.TrimStart('S', 'T', 'R');
DateTime tEnd = DateTime.Now;
DateTime tStart = tEnd.AddMinutes(0 - duration);
double[] arr = dataProvider.FindHistoryRaw(testPointName, objectId, objectType, tStart, tEnd);
if (arr != null && arr.Length >1)
{
for (int i=1;i
/// 取测点与给定的时间之前的差值
/// 算法:读取实时库某一点当前值及给定时间前的值,返回当前值与前值的差
///
/// 测点名称
/// 时间差, 单位: 分钟
/// 对象ID
/// 对象类型
///
/// 当前值 - 前值
///
protected double DiffMinutes(string testPointName, int minutes, string objectId, AlertObjectType objectType)
{
if (minutes <= 0)
return 0;
testPointName = testPointName.TrimStart('S', 'T', 'R');
DateTime tEnd = DateTime.Now;
DateTime tStart = tEnd.AddMinutes(0 - minutes);
double[] arr = dataProvider.FindAIHistorySnap(testPointName, objectId, objectType, tStart, tEnd, minutes*60);
if (arr.Length != 2)
return 0;
else
{
return arr[1] - arr[0];
}
}
protected double DiffSeconds(string testPointName, int seconds, string objectId, AlertObjectType objectType)
{
if (seconds <= 0)
return 0;
testPointName = testPointName.TrimStart('S', 'T', 'R');
DateTime tEnd = DateTime.Now;
DateTime tStart = tEnd.AddSeconds(0 - seconds);
double[] arr = dataProvider.FindAIHistorySnap(testPointName, objectId, objectType, tStart, tEnd, seconds);
if (arr.Length != 2)
return 0;
else
{
return arr[1] - arr[0];
}
}
///
/// 判定状态突然大幅变化的方法
/// 算法:读取实时库某一点的历史值(2次),时间区间分别为
/// a) Datetime.Now —— Datetime.Now - duration
/// b)Datetime.Now - duration —— Datetime.Now - duration*2
/// 分别计算出两个时间段的平均值和方差,
/// 若均值的比率 或者方差的比率大于制定的值时,则认为是数据突变
///
/// 测点名称
/// 持续时间,单位:分钟
/// 对象ID
/// 对象类型
///
/// true:时间段内状态不变
/// false:时间段内数据不足或者状态变动过
///
protected bool SuddenChange(string testPointName, int duration, double ratio, string objectId, AlertObjectType objectType)
{
if (ratio <= 0)
return false;
double fc1, fc2, avg1, avg2, sum;
testPointName = testPointName.TrimStart('S', 'T', 'R');
DateTime tEnd = DateTime.Now;
DateTime tStart = tEnd.AddMinutes(0 - duration);
DateTime tStart1 = tStart.AddMinutes(0 - duration);
double[] arr = dataProvider.FindHistoryRaw(testPointName, objectId, objectType, tStart, tEnd);
double[] arr1 = dataProvider.FindHistoryRaw(testPointName, objectId, objectType, tStart1, tStart);
if (arr == null || arr.Length < 1)
return false;
if (arr1 == null || arr1.Length < 1)
{
fc1 = 0;
avg1 = arr[0];
}
else
{
sum = 0;
for(int i=0;i ratio || ratio2 < 1 / ratio)
return true;
sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += Math.Pow(arr[i] - avg2, 2);
}
fc2 = Math.Sqrt(sum / arr.Length);
if (fc1 == 0 && fc2 != 0)
return true;
if (fc1 == 0 && fc2 == 0)
return false;
ratio2 = fc2 / fc1;
if (ratio2 > ratio || ratio2 < 1 / ratio)
return true;
return false;
}
///
/// 获取测点最近收到数据的时间
/// 应用场景:读取实时库某一点的当前值(对应EDos的GetRtValue方法),返回改值对应的时间,
///
/// 测点名称
/// 对象ID
/// 对象类型
///
/// 时间,单位为秒(近似值)
///
protected int LastUpdateTime(string testPointName, string objectId, AlertObjectType objectType)
{
testPointName = testPointName.TrimStart('S', 'T', 'R');
int t1 = dataProvider.GetLastUpdateTime(testPointName, objectId, objectType, ref dataInfo);
return CommonMethod.ConvertDateTimeInt(DateTime.Now) - t1;
}
#endregion
}
}