using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Threading; using EntityDataSet; using IntelligentControlForsx.Service.WindturbineControl.Domain.Cmd; namespace IntelligentControlForsx.Service.WindturbineControl.IntPtrSvc { public class ControlSvc { private static ControlSvc svc = new ControlSvc(); private ControlSvc() { } public static ControlSvc GetControlSvc() { return svc; } /// /// 发送控制指令--1.5MW机型 /// /// 控制句柄 /// 控制信息集合 /// 发送失败的集合 /// 发送成功的风机Id集合 public static IList SendCmd_Up82(IntPtr intPtr, IList cmdList, out IList faultSendList) { byte[] typeArr = cmdList.Select(s => (byte)s.ControlType).ToArray(); uint[] addressArr = cmdList.Select(s => (uint)s.CmdId).ToArray(); float[] valueArr = cmdList.Select(s => s.CmdValue).ToArray(); int count = CmdSendService.gycp_control(intPtr, typeArr, addressArr, valueArr, (uint)addressArr.Length); //获取发送失败的风机Id集合 faultSendList = GetSendFaultWindtrubineIds(); //收集并返回发送成功的风机Id集合 IList fault = faultSendList; return cmdList.Where(s => !fault.Contains(s.WindturbineId)).Select(k => k.WindturbineId).ToList(); } /// /// 发送控制指令2MW机型 /// /// 控制句柄 /// 控制信息集合 /// 发送失败的集合 /// 送成功的风机Id集合 public static IList SendCmd_Up105(IntPtr intPtr, IList cmdList, out IList faultSendList) { /* * 停机操作:停机地址发送1,停机地址发送0 * 启动操作:复位地址发送1,复位地址发送0 */ byte[] typeArr = cmdList.Select(s => (byte)s.ControlType).ToArray(); uint[] addressArr = cmdList.Select(s => (uint)s.CmdId).ToArray(); float[] valueArr1 = cmdList.Select(s => s.CmdValue).ToArray(); float[] valueArr0 = cmdList.Select(s => s.CmdValue).ToArray(); int count1 = CmdSendService.gycp_control(intPtr, typeArr, addressArr, valueArr1, (uint)addressArr.Length); IList faultSend1 = GetSendFaultWindtrubineIds(); Thread.Sleep(800); int count0 = CmdSendService.gycp_control(intPtr, typeArr, addressArr, valueArr0, (uint)addressArr.Length); IList faultSend0 = GetSendFaultWindtrubineIds(); //将两次发送的命令失败集合合并(并集)并去重 faultSendList = faultSend1.Union(faultSend0).ToList().Distinct().ToList(); //收集并返回发送成功的风机Id集合 IList fault = faultSendList; return cmdList.Where(s => !fault.Contains(s.WindturbineId)).Select(k => k.WindturbineId).ToList(); } /// /// 根据风机编号及其操作类型发送操作指令 /// /// 风机编号集合 /// 风场编号 /// 操作类型 /// 指令发送失败的风机集合 /// 控制描述(手动,执行推荐) /// 操作人 /// 控制指令是否全部发送成功 public bool SendCmdByWindturbineIdList(IList windturbinList, string stationId, CmdType cmdType, out IList faultSendList, string description, user user) { faultSendList = new List(); using (wisdom_cs_entity ctx = new wisdom_cs_entity()) { IList list = ctx.windturbine.Where(s => windturbinList.Contains(s.ID) && s.WINDPOWERSTATIONID == stationId) .ToList(); IList controlInfoListUp82 = new List(); IList cmdInfoListUp82 = new List(); IList controlInfoListUp105 = new List(); IList cmdInfoListUp105 = new List(); for (int i = 0; i < list.Count; i++) { if (list[i].MODELID != "UP105-2000-S") { #region 操控记录实体 control_info info = new control_info(); info.control_description = description; info.user_id = user.id; info.time = DateTime.Now; info.success_time = null; info.windturbine_id = list[i].ID; info.type = (int)cmdType; controlInfoListUp82.Add(info); #endregion #region 风机命令实体 WindturbineCmdInfo cmdInfo = new WindturbineCmdInfo(); if (list[i].GYCP_ID.HasValue) cmdInfo.CmdIntPtr = ControlIntPtr.dic[list[i].PROJECTID]; cmdInfo.WindturbineId = list[i].ID; cmdInfo.CmdType = cmdType; cmdInfo.ControlType = CmdSendService.GYCP_TYPE_YK; int controlType = 0; if (cmdInfo.CmdType == CmdType.Start) controlType = 1; //启动 else if (cmdInfo.CmdType == CmdType.Stop) controlType = 2; //停机 else if (cmdInfo.CmdType == CmdType.Maintain) controlType = 3; //维护 else if (cmdInfo.CmdType == CmdType.UnMaintain) controlType = 4; //取消维护 else if (cmdInfo.CmdType == CmdType.Reset) controlType = 5; //复位 //获取控制点 string windturbineId = list[i].ID; gycp_cmd_info gycpCmdInfo = ctx.gycp_cmd_info.Where( s => s.type == controlType && s.windturbine_id == windturbineId) .FirstOrDefault(); //获取控制地址 gycp_address address = null; if (list[i].GYCP_ID.HasValue) { int gycpId = list[i].GYCP_ID.Value; address = ctx.gycp_address.Where(s => s.id == gycpId).FirstOrDefault(); } if (address != null && gycpCmdInfo != null) { cmdInfo.CmdId = gycpCmdInfo.cmd_id; if (gycpCmdInfo.cmd_value.HasValue) cmdInfo.CmdValue = gycpCmdInfo.cmd_value.Value; } cmdInfo.UserId = user.id; cmdInfo.Time = DateTime.Now; cmdInfo.IsSuccessSend = false; cmdInfoListUp82.Add(cmdInfo); #endregion } else { #region 操控记录实体 control_info info = new control_info(); info.control_description = description; info.user_id = user.id; info.time = DateTime.Now; info.success_time = null; info.windturbine_id = list[i].ID; info.type = (int)cmdType; controlInfoListUp105.Add(info); #endregion #region 风机命令实体 WindturbineCmdInfo cmdInfo = new WindturbineCmdInfo(); if (list[i].GYCP_ID.HasValue) cmdInfo.CmdIntPtr = ControlIntPtr.dic[list[i].PROJECTID]; cmdInfo.WindturbineId = list[i].ID; cmdInfo.CmdType = cmdType; cmdInfo.ControlType = CmdSendService.GYCP_TYPE_YK; int controlType = 0; if (cmdInfo.CmdType == CmdType.Start) controlType = 5; //启动 else if (cmdInfo.CmdType == CmdType.Stop) controlType = 1; //停机 //获取控制点 string windturbineId = list[i].ID; gycp_cmd_info gycpCmdInfo = ctx.gycp_cmd_info.Where( s => s.type == controlType && s.windturbine_id == windturbineId) .FirstOrDefault(); //获取控制地址 gycp_address address = null; if (list[i].GYCP_ID.HasValue) { int gycpId = list[i].GYCP_ID.Value; address = ctx.gycp_address.Where(s => s.id == gycpId).FirstOrDefault(); } if (address != null && gycpCmdInfo != null) { cmdInfo.CmdId = gycpCmdInfo.cmd_id; if (gycpCmdInfo.cmd_value.HasValue) cmdInfo.CmdValue = gycpCmdInfo.cmd_value.Value; } cmdInfo.UserId = user.id; cmdInfo.Time = DateTime.Now; cmdInfo.IsSuccessSend = false; cmdInfoListUp105.Add(cmdInfo); #endregion } } var groupResultUp82 = cmdInfoListUp82.GroupBy(x => x.CmdIntPtr); foreach (var info in groupResultUp82) { IList falutList = new List(); List itemList = info.ToList(); IList successWindturbineIdList = SendCmd_Up82(itemList[0].CmdIntPtr, itemList, out falutList); #region 保存命令执行成功的记录 IList successList = controlInfoListUp82.Where(s => successWindturbineIdList.Contains(s.windturbine_id)).ToList(); for (int i = 0; i < successList.Count; i++) { ctx.Entry(successList[i]).State = EntityState.Added; ctx.SaveChanges(); } #endregion faultSendList = faultSendList.Union(falutList).ToList();//收集命令发送失败的风机集合 } var groupResultUp105 = cmdInfoListUp105.GroupBy(x => x.CmdIntPtr); foreach (var info in groupResultUp105) { IList falutList = new List(); List itemList = info.ToList(); IList successWindturbineIdList = SendCmd_Up105(itemList[0].CmdIntPtr, itemList, out falutList); #region 保存命令执行成功的记录 IList successList = controlInfoListUp105.Where(s => successWindturbineIdList.Contains(s.windturbine_id)).ToList(); for (int i = 0; i < successList.Count; i++) { ctx.Entry(successList[i]).State = EntityState.Added; ctx.SaveChanges(); } #endregion faultSendList = faultSendList.Union(falutList).ToList();//收集命令发送失败的风机集合 } if (faultSendList.Count <= 0) return true; else return false; } } /// /// 根据回调函数返回的数据得到命令发送失败的风机Id集合 /// /// public static IList GetSendFaultWindtrubineIds() { IList list = new List(); ControlResult result = ControlIntPtr.result; if (result != null) { for (int i = 0; i < result.Errors.Length; i++) { //错误值为1时代表发送失败 if (result.Errors[i] == 1) { using (wisdom_cs_entity ctx = new wisdom_cs_entity()) { gycp_cmd_info info = ctx.gycp_cmd_info.Where(s => s.cmd_id == result.Addresses[i]).FirstOrDefault(); if (info != null) list.Add(info.windturbine_id); } } } ControlIntPtr.result = new ControlResult(); } return list; } } }