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); } } }