using GDNXFD.Data;
using GDNXFD.Data.Model;
using GDNXFD.Data.Repositories;
using GDNXFD.WcfService.RealtimeState;
using GDNXFD.WcfService.RealtimeState.Domain;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WisdomClient.data;
namespace GDNXFD.WcfService
{
public class AdviceCache
{
#region 单例方法
public static AdviceCache Instance
{
get { return SingletonCreator.instance; }
}
class SingletonCreator
{
internal static readonly AdviceCache instance = new AdviceCache();
}
#endregion
///
/// 实时状态计算结果(最终计算结果,报警,状态,风速)
///
public IList AdviceList { get; set; }
///
/// 预测结果
///
public IList PredictAdviceList { get; set; }
///
/// 风机信息(包含统一编码和测点实时数据)
///
///
public Dictionary dicWindturbineInfo;
Dictionary dicTag;
private static string windSpeedCode_Up82 = ConfigurationManager.AppSettings["WindSpeed_Up82"];
private static string windSpeedCode_Up105 = ConfigurationManager.AppSettings["WindSpeed_Up105"];
private static string windSpeedCode_FiveMin = ConfigurationManager.AppSettings["WindSpeedCode_FiveMin"];
//用户取消后的有效时间(毫秒)
private static int UserCancelTime = Convert.ToInt32(ConfigurationManager.AppSettings["UserCancelTime"]);
///
/// key=风机编号,value 风机状态测点
///
private Dictionary pointDic;
private Object AdviceListAddLock = new object();
///
/// 计算结果合并
///
/// 实时计算结果
public void AdviceListAdd(IList list)
{
lock (AdviceListAddLock)// 多线程锁
{
if (AdviceList == null)
AdviceList = new List();
//预测结果,与当前状态,与预测时间比较后的结果
IList allowList = new List();
if (pointDic == null)
GetStatusPoint();
if (PredictAdviceList != null)
{
DateTime nowTime = DateTime.Now;
IList alist = PredictAdviceList.Where(s => s.AdviceExecuteTime < nowTime).ToList();
for (int i = 0; i < alist.Count; i++)
{
double? statusValue = null;
double? hungTypeValue = null;
if (dicWindturbineInfo[alist[i].WindturbineId].StatusCode.TagData.doubleValue.HasValue)
statusValue = dicWindturbineInfo[alist[i].WindturbineId].StatusCode.TagData.doubleValue.Value;
if (dicWindturbineInfo[alist[i].WindturbineId].LockCode.TagData.doubleValue.HasValue)
hungTypeValue = dicWindturbineInfo[alist[i].WindturbineId].LockCode.TagData.doubleValue.Value;
if (statusValue.HasValue && hungTypeValue.HasValue)
{
WStatus status = HelpperMethod.GetWindturbineStatus(statusValue.Value);
HungType hungType = HelpperMethod.GetHungType(hungTypeValue.Value);
//如果建议启动,风机未挂牌,且风机当前状态为待机,
if (alist[i].AdviseOperation == OperateStyle.Start && status == WStatus.Standby && hungType == HungType.UnLock)
{
allowList.Add(alist[i]);
}
WStatus[] statusArr = { WStatus.Online, WStatus.OnPower, WStatus.Start };
//如果建议停机,风机未挂牌,且当前风机状态为 并网、上电、启动中的一种
if (alist[i].AdviseOperation == OperateStyle.Stop && statusArr.Contains(status) && hungType == HungType.UnLock)
{
allowList.Add(alist[i]);
}
}
}
}
//最终合并结果
IList finalList = list;
for (int i = 0; i < allowList.Count; i++)
{
string windturbineId = allowList[i].WindturbineId;
int count = finalList.Where(s => s.WindturbineId == windturbineId).ToList().Count;
if (count == 0)
finalList.Add(allowList[i]);
}
for (int i = 0; i < finalList.Count; i++)
{
string windturbineId = finalList[i].WindturbineId;
AdviceModel m = AdviceList.Where(s => s.WindturbineId == windturbineId).FirstOrDefault();
if (m == null)
{
AdviceList.Add(finalList[i]);
//添加计算流水表数据
InsertAdviceModelHistory(finalList[i]);
}
else
{
//如果m的状态为用户取消
if (m.Status == 3)
{
TimeSpan sp = DateTime.Now - m.ExecuteTime.Value;
//如果m的取消时间已经失效,则继续将计算结果合并到AdviceList中
if (sp.TotalMilliseconds > UserCancelTime)
{
m.AdviseOperation = finalList[i].AdviseOperation;
m.AdviceType = finalList[i].AdviceType;
m.LastUpdateTime = finalList[i].LastUpdateTime;
m.AdviceExecuteTime = finalList[i].AdviceExecuteTime;
m.ExecuteTime = finalList[i].ExecuteTime;
m.ExecuteOperation = finalList[i].ExecuteOperation;
m.Operater = finalList[i].Operater;
m.Status = finalList[i].Status;
m.Notes = finalList[i].Notes;
//添加新的计算流水表信息
InsertAdviceModelHistory(finalList[i]);
}
}
//如果m的状态为未执行
else if (m.Status == 1)
{
//如果本次推荐和上次推荐结果不一致,则更新推荐结果,
if (m.AdviseOperation != finalList[i].AdviseOperation)
{
m.AdviseOperation = finalList[i].AdviseOperation;
m.AdviceType = finalList[i].AdviceType;
m.LastUpdateTime = finalList[i].LastUpdateTime;
m.AdviceExecuteTime = finalList[i].AdviceExecuteTime;
m.ExecuteTime = finalList[i].ExecuteTime;
m.ExecuteOperation = finalList[i].ExecuteOperation;
m.Operater = finalList[i].Operater;
m.Status = finalList[i].Status;
m.Notes = finalList[i].Notes;
//将上一次的流水信息更新
UpdateAdviceModelHistory(finalList[i].WindturbineId, 4, "系统", "0");
//添加新的计算流水表信息
InsertAdviceModelHistory(finalList[i]);
}
}
//如果m的状态为用户执行
else if (m.Status == 2)
{
//如果本次推荐和上次推荐结果不一致,则更新推荐结果,
if (m.AdviseOperation != finalList[i].AdviseOperation)
{
m.AdviseOperation = finalList[i].AdviseOperation;
m.AdviceType = finalList[i].AdviceType;
m.LastUpdateTime = finalList[i].LastUpdateTime;
m.AdviceExecuteTime = finalList[i].AdviceExecuteTime;
m.ExecuteTime = finalList[i].ExecuteTime;
m.ExecuteOperation = finalList[i].ExecuteOperation;
m.Operater = finalList[i].Operater;
m.Status = finalList[i].Status;
m.Notes = finalList[i].Notes;
//添加新的计算流水表信息
InsertAdviceModelHistory(finalList[i]);
}
}
//如果m的状态为系统取消
else
{
//如果本次推荐和上次推荐结果不一致,则更新推荐结果,
if (m.AdviseOperation != finalList[i].AdviseOperation)
{
m.AdviseOperation = finalList[i].AdviseOperation;
m.AdviceType = finalList[i].AdviceType;
m.LastUpdateTime = finalList[i].LastUpdateTime;
m.AdviceExecuteTime = finalList[i].AdviceExecuteTime;
m.ExecuteTime = finalList[i].ExecuteTime;
m.ExecuteOperation = finalList[i].ExecuteOperation;
m.Operater = finalList[i].Operater;
m.Status = finalList[i].Status;
m.Notes = finalList[i].Notes;
//添加新的计算流水表信息
InsertAdviceModelHistory(finalList[i]);
}
}
}
}
//排除已失效的计算结果, 如果finalList没有的风机,但AdviceList有的风机,说明上次风机的计算结果已失效,其中失效包括 用户已执行,和系统取消
IList finalWindturbineIdList = finalList.Select(s => s.WindturbineId).ToList();
for (int i = 0; i < AdviceList.Count; i++)
{
if (!finalWindturbineIdList.Contains(AdviceList[i].WindturbineId))
{
if (AdviceList[i].Status == 1&& (AdviceList[i].AdviseOperation==OperateStyle.Start|| AdviceList[i].AdviseOperation == OperateStyle.Stop))
{
AdviceList[i].Status = 4;
UpdateAdviceModelHistory(AdviceList[i].WindturbineId, 4, "系统", "0");
}
}
}
#region 运行结果打印
//Console.WriteLine("*********************************************");
//for (int i = 0; i < AdviceList.Count; i++)
//{
// string infoString = "";
// infoString = infoString + "风机当前状态为" + HelpperMethod.GetWindturbineStatus(dicWindturbineInfo[AdviceList[i].WindturbineId].StatusCode.TagData.doubleValue.Value).ToString();
// infoString = infoString + "风机当前风速为" + dicWindturbineInfo[AdviceList[i].WindturbineId].WindSpeedCode.TagData.doubleValue.Value.ToString("f2") + "m/s";
// //获取切入风
// double putSpeed = CalcStateSvc.Instance.inputSpeedDic[AdviceList[i].WindturbineId];
// string s = "是否失效" + AdviceList[i].Status + "-" + AdviceList[i].WindturbineId + "--推荐动作:" + AdviceList[i].AdviseOperation.ToString() + "----" + infoString + "切入风:" + putSpeed.ToString("");
// Console.WriteLine(s);
//}
//Console.WriteLine("*********************************************");
#endregion
}
}
///
/// 计算结果合并--待机状态的风机推荐维护和维护状态下的推荐取消维护
///
/// 实时计算结果
public void AddMaintainAdvice(IList list)
{
lock (AdviceListAddLock)// 多线程锁
{
if (AdviceList == null)
AdviceList = new List();
// 全局列表中所有建议维护的设备
var tmpMaintainCopy = AdviceList.Where(a => a.AdviseOperation == OperateStyle.Maintain).ToArray();
AdviceModel[] copyTmpMaintain = new AdviceModel[tmpMaintainCopy.Length];
tmpMaintainCopy.CopyTo(copyTmpMaintain, 0);
// 以风机编号为key,风机信息为Value
var tmpMaintainDictionary = copyTmpMaintain.Select(c => new KeyValuePair(c.WindturbineId, c)).ToDictionary(k => k.Key, v => v.Value);
// 全局列表中所有建议取消维护的设备
var tmpCancelMaintainCopy = AdviceList.Where(a => a.AdviseOperation == OperateStyle.UnMaintain).ToArray();
AdviceModel[] copyTmpCancelMaintain = new AdviceModel[tmpCancelMaintainCopy.Length];
tmpCancelMaintainCopy.CopyTo(copyTmpCancelMaintain, 0);
// 以风机编号为key,风机信息为Value
var tmpCancelMaintainDictionary = copyTmpCancelMaintain.Select(c => new KeyValuePair(c.WindturbineId, c)).ToDictionary(k => k.Key, v => v.Value);
foreach (var l in list)
{
// 上次要维护,这次也维护 ---> 不做操作
if (tmpMaintainDictionary.ContainsKey(l.WindturbineId) && l.AdviseOperation == OperateStyle.Maintain)
{
//
tmpMaintainDictionary.Remove(l.WindturbineId);//移除
//
}
// 上次要维护,这次却取消维护--->
else if (tmpMaintainDictionary.ContainsKey(l.WindturbineId) && l.AdviseOperation == OperateStyle.UnMaintain)
{
// 查看上次取消维护中有没有这个记录,如果有,上次取消维护就不做更改 ----> 对应的,删除推荐维护的记录,并将流水变更掉
// 如果没有,添加上这个维护记录,添加流水 ----> 对应的,删除推荐维护记录,并将流水变更掉
if (!tmpCancelMaintainDictionary.ContainsKey(l.WindturbineId))
{
AdviceList.Add(l);
//添加计算流水表数据
InsertAdviceModelHistory(l);
}
}
// 上次要取消维护,这次也取消维护
else if (tmpCancelMaintainDictionary.ContainsKey(l.WindturbineId) && l.AdviseOperation == OperateStyle.UnMaintain)
{
tmpCancelMaintainDictionary.Remove(l.WindturbineId);
}
// 上次要取消维护,这次却要维护
else if (tmpCancelMaintainDictionary.ContainsKey(l.WindturbineId) && l.AdviseOperation == OperateStyle.Maintain)
{
//
if (tmpMaintainDictionary.ContainsKey(l.WindturbineId))
{
AdviceList.Add(l);
//添加计算流水表数据
InsertAdviceModelHistory(l);
}
}
// 上次没有维护 ---> ADD 加流水
else
{
AdviceList.Add(l);
//添加计算流水表数据
InsertAdviceModelHistory(l);
//
}
}
// 上次有维护,这次没有维护 ---> 删除没有老记录,流水变更为系统取消
// cancelMaintainArray 剩下的就是老记录了 需要取消推荐并移除
foreach (var v in tmpMaintainDictionary.Values)
{
//将上一次的流水信息更新
UpdateAdviceModelHistory(v.WindturbineId, 4, "系统", "0");
AdviceList.Remove(v);
}
// 上次有取消维护,这次没有取消维护 -->删除老记录,流水变更为系统取消
foreach (var v in tmpCancelMaintainDictionary.Values)
{
//将上一次的流水信息更新
UpdateAdviceModelHistory(v.WindturbineId, 4, "系统", "0");
AdviceList.Remove(v);
}
Console.WriteLine("全场无风 维护&取消维护 运行完成");
}
}
///
/// 获取风机状态测点
///
private void GetStatusPoint()
{
if (pointDic == null)
pointDic = new Dictionary();
using (GDNXFDDbContext ctx = new GDNXFDDbContext())
{
IList pointList = ctx.WindTurbineTestingPointAI.Where(s => s.UniformCode == "FJZT8").ToList();
for (int i = 0; i < pointList.Count; i++)
{
if (!pointDic.ContainsKey(pointList[i].WindturbineId))
{
pointDic.Add(pointList[i].WindturbineId, pointList[i].Id);
}
}
}
}
public void GetWindturbinInfo()
{
if (dicWindturbineInfo == null)
{
dicWindturbineInfo = new Dictionary();
using (GDNXFDDbContext ctx = new GDNXFDDbContext())
{
IList list = ctx.WindTurbine.Where(s => s.WindPowerStationId.Contains("_FDC") && s.WindPowerStationId != "QS_FDC").ToList().ToList();
for (int i = 0; i < list.Count; i++)
{
WindturbineInfo d = new WindturbineInfo();
d.Windturbine = list[i];
d.WindturbineId = list[i].Id;
d.StatusCode = new TagInfo();
d.StatusCode.UniformCode = "FJZT8";
d.BoxTemperature = new TagInfo();
d.BoxTemperature.UniformCode = "AI057";
d.WindturbinePower = new TagInfo();
d.WindturbinePower.UniformCode = "AI130";
d.WindSpeedCode = new TagInfo();
d.WindSpeedCodeFiveMin = new TagInfo();
if (list[i].ModelId == "UP105-2000-S")
d.WindSpeedCode.UniformCode = windSpeedCode_Up105;
else
d.WindSpeedCode.UniformCode = windSpeedCode_Up82;
d.LockCode = new TagInfo();
d.LockCode.UniformCode = "XDSL";
d.WindSpeedCodeFiveMin.UniformCode = windSpeedCode_FiveMin;
d.WindDirectionCode = new TagInfo();
string[] stationIdArr = { "SBQ_FDC", "MHS_FDC" };
if (stationIdArr.Contains(list[i].WindPowerStationId) && list[i].ModelId == "UP105-2000-S")
d.WindDirectionCode.UniformCode = "AI010";
else
d.WindDirectionCode.UniformCode = "AI008";
if (!dicWindturbineInfo.ContainsKey(list[i].Id))
dicWindturbineInfo.Add(d.WindturbineId, d);
string[] arr = { d.StatusCode.UniformCode, d.WindSpeedCode.UniformCode, d.WindDirectionCode.UniformCode, d.LockCode.UniformCode,d.WindSpeedCodeFiveMin.UniformCode,d.BoxTemperature.UniformCode,d.WindturbinePower.UniformCode };
string windturbineId = list[i].Id;
IList aiList = ctx.WindTurbineTestingPointAI.Where(s => s.WindturbineId == windturbineId && arr.Contains(s.UniformCode)).ToList();
if (dicTag == null)
dicTag = new Dictionary();
for (int j = 0; j < aiList.Count; j++)
{
if (!dicTag.ContainsKey(aiList[j].Id))
{
if (aiList[j].UniformCode == d.WindSpeedCode.UniformCode)
dicTag.Add(aiList[j].Id, d.WindSpeedCode);
if (aiList[j].UniformCode == d.WindDirectionCode.UniformCode)
dicTag.Add(aiList[j].Id, d.WindDirectionCode);
if (aiList[j].UniformCode == d.StatusCode.UniformCode)
dicTag.Add(aiList[j].Id, d.StatusCode);
if (aiList[j].UniformCode == d.LockCode.UniformCode)
dicTag.Add(aiList[j].Id, d.LockCode);
if (aiList[j].UniformCode == d.WindSpeedCodeFiveMin.UniformCode)
dicTag.Add(aiList[j].Id, d.WindSpeedCodeFiveMin);
if (aiList[j].UniformCode == d.BoxTemperature.UniformCode)// 机舱温度
{
dicTag.Add(aiList[j].Id, d.BoxTemperature);
}
if (aiList[j].UniformCode == d.WindturbinePower.UniformCode)// 机舱温度
{
dicTag.Add(aiList[j].Id, d.WindturbinePower);
}
}
}
}
}
}
Dictionary resultDic = WisdomClient.RestfulClient.findLatestByTagNames(dicTag.Keys.ToArray());
foreach (var item in resultDic)
{
if (dicTag.ContainsKey(item.Key))
dicTag[item.Key].TagData = item.Value;
}
Console.WriteLine(" [|]");
}
public void GetPredictAdviceModel(WindTurbine wt)
{
if (PredictAdviceList == null)
PredictAdviceList = new List();
foreach (var am in PredictAdviceList)
{
if (am.WindturbineId == wt.Id)
{
am.LastUpdateTime = DateTime.Now;
am.Status = 1;
am.AdviseOperation = OperateStyle.Start;
am.AdviceExecuteTime = DateTime.Now;
return;
}
}
AdviceModel adm = new AdviceModel();
adm.AdviceExecuteTime = DateTime.Now;
adm.AdviceType = CalculationOriginType.PowerForecast;
adm.AdviseOperation = OperateStyle.Start;
adm.LastUpdateTime = DateTime.Now;
adm.ModelId = wt.ModelId;
adm.StationId = wt.WindPowerStationId;
adm.Status = 1;
adm.WindturbineId = wt.Id;
PredictAdviceList.Add(adm);
}
///
/// 添加计算流水表信息
///
/// 更新数据
/// 更新类型:1=未执行,2=用户执行,3=用户取消,4=系统取消
/// 操作人姓名
/// 操作人用户编号,系统用户编号为0
public void InsertAdviceModelHistory(AdviceModel model)
{
AdviceHistoryModel hisModel = new AdviceHistoryModel();
hisModel.Id = Guid.NewGuid().ToString();
hisModel.WindturbineId = model.WindturbineId;
hisModel.StationId = model.StationId;
hisModel.ModelId = model.ModelId;
hisModel.AdviseOperation = model.AdviseOperation;
hisModel.AdviceType = model.AdviceType;
hisModel.LastUpdateTime = model.LastUpdateTime;
hisModel.AdviceExecuteTime = model.AdviceExecuteTime;
hisModel.ExecuteTime = model.ExecuteTime;
hisModel.ExecuteOperation = model.ExecuteOperation;
hisModel.Status = model.Status;
IList list = new List();
list.Add(hisModel);
AdviceHistoryModelRepository.InsertHistory(list);
}
///
/// 更新计算流水信息
///
/// 风机编号
/// 更新类型:1=未执行,2=用户执行,3=用户取消,4=系统取消<
/// 操作人姓名
/// 操作人用户编号,系统用户编号为0
public void UpdateAdviceModelHistory(string windturbineId, int actionType, string userName, string userId)
{
AdviceHistoryModelRepository.UpdateHistory(windturbineId, userId, userName, actionType);
}
}
}