123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- 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
- /// <summary>
- /// 实时状态计算结果(最终计算结果,报警,状态,风速)
- /// </summary>
- public IList<AdviceModel> AdviceList { get; set; }
- /// <summary>
- /// 预测结果
- /// </summary>
- public IList<AdviceModel> PredictAdviceList { get; set; }
- /// <summary>
- /// 风机信息(包含统一编码和测点实时数据)
- /// </summary>
- ///
- public Dictionary<string, WindturbineInfo> dicWindturbineInfo;
- Dictionary<string, TagInfo> 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"]);
- /// <summary>
- /// key=风机编号,value 风机状态测点
- /// </summary>
- private Dictionary<string, string> pointDic;
- private Object AdviceListAddLock = new object();
- /// <summary>
- /// 计算结果合并
- /// </summary>
- /// <param name="list">实时计算结果</param>
- public void AdviceListAdd(IList<AdviceModel> list)
- {
- lock (AdviceListAddLock)// 多线程锁
- {
- if (AdviceList == null)
- AdviceList = new List<AdviceModel>();
- //预测结果,与当前状态,与预测时间比较后的结果
- IList<AdviceModel> allowList = new List<AdviceModel>();
- if (pointDic == null)
- GetStatusPoint();
- if (PredictAdviceList != null)
- {
- DateTime nowTime = DateTime.Now;
- IList<AdviceModel> 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<AdviceModel> 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<string> 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
- }
- }
- /// <summary>
- /// 计算结果合并--待机状态的风机推荐维护和维护状态下的推荐取消维护
- /// </summary>
- /// <param name="list">实时计算结果</param>
- public void AddMaintainAdvice(IList<AdviceModel> list)
- {
- lock (AdviceListAddLock)// 多线程锁
- {
- if (AdviceList == null)
- AdviceList = new List<AdviceModel>();
- // 全局列表中所有建议维护的设备
- 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<string, AdviceModel>(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<string, AdviceModel>(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("全场无风 维护&取消维护 运行完成");
- }
- }
- /// <summary>
- /// 获取风机状态测点
- /// </summary>
- private void GetStatusPoint()
- {
- if (pointDic == null)
- pointDic = new Dictionary<string, string>();
- using (GDNXFDDbContext ctx = new GDNXFDDbContext())
- {
- IList<WindTurbineTestingPointAI> 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<string, WindturbineInfo>();
- using (GDNXFDDbContext ctx = new GDNXFDDbContext())
- {
- IList<WindTurbine> 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<WindTurbineTestingPointAI> aiList = ctx.WindTurbineTestingPointAI.Where(s => s.WindturbineId == windturbineId && arr.Contains(s.UniformCode)).ToList();
- if (dicTag == null)
- dicTag = new Dictionary<string, TagInfo>();
- 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<string, TsData> 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<AdviceModel>();
- 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);
- }
- /// <summary>
- /// 添加计算流水表信息
- /// </summary>
- /// <param name="model">更新数据</param>
- /// <param name="typeString">更新类型:1=未执行,2=用户执行,3=用户取消,4=系统取消</param>
- /// <param name="userName">操作人姓名</param>
- /// <param name="userId">操作人用户编号,系统用户编号为0</param>
- 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<AdviceHistoryModel> list = new List<AdviceHistoryModel>();
- list.Add(hisModel);
- AdviceHistoryModelRepository.InsertHistory(list);
- }
- /// <summary>
- /// 更新计算流水信息
- /// </summary>
- /// <param name="windturbineId">风机编号</param>
- /// <param name="actionType">更新类型:1=未执行,2=用户执行,3=用户取消,4=系统取消<</param>
- /// <param name="userName">操作人姓名</param>
- /// <param name="userId">操作人用户编号,系统用户编号为0</param>
- public void UpdateAdviceModelHistory(string windturbineId, int actionType, string userName, string userId)
- {
- AdviceHistoryModelRepository.UpdateHistory(windturbineId, userId, userName, actionType);
- }
- }
- }
|