ControlSvc.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Linq;
  5. using System.Threading;
  6. using EntityDataSet;
  7. using IntelligentControlForsx.Service.WindturbineControl.Domain.Cmd;
  8. namespace IntelligentControlForsx.Service.WindturbineControl.IntPtrSvc
  9. {
  10. public class ControlSvc
  11. {
  12. private static ControlSvc svc = new ControlSvc();
  13. private ControlSvc()
  14. {
  15. }
  16. public static ControlSvc GetControlSvc()
  17. {
  18. return svc;
  19. }
  20. /// <summary>
  21. /// 发送控制指令--1.5MW机型
  22. /// </summary>
  23. /// <param name="intPtr">控制句柄</param>
  24. /// <param name="cmdList">控制信息集合</param>
  25. /// <param name="faultSendList">发送失败的集合</param>
  26. /// <returns>发送成功的风机Id集合</returns>
  27. public static IList<string> SendCmd_Up82(IntPtr intPtr, IList<WindturbineCmdInfo> cmdList, out IList<string> faultSendList)
  28. {
  29. byte[] typeArr = cmdList.Select(s => (byte)s.ControlType).ToArray();
  30. uint[] addressArr = cmdList.Select(s => (uint)s.CmdId).ToArray();
  31. float[] valueArr = cmdList.Select(s => s.CmdValue).ToArray();
  32. int count = CmdSendService.gycp_control(intPtr, typeArr, addressArr, valueArr, (uint)addressArr.Length);
  33. //获取发送失败的风机Id集合
  34. faultSendList = GetSendFaultWindtrubineIds();
  35. //收集并返回发送成功的风机Id集合
  36. IList<string> fault = faultSendList;
  37. return cmdList.Where(s => !fault.Contains(s.WindturbineId)).Select(k => k.WindturbineId).ToList();
  38. }
  39. /// <summary>
  40. /// 发送控制指令2MW机型
  41. /// </summary>
  42. /// <param name="intPtr">控制句柄</param>
  43. /// <param name="cmdList">控制信息集合</param>
  44. /// <param name="faultSendList">发送失败的集合</param>
  45. /// <returns>送成功的风机Id集合</returns>
  46. public static IList<string> SendCmd_Up105(IntPtr intPtr, IList<WindturbineCmdInfo> cmdList, out IList<string> faultSendList)
  47. {
  48. /*
  49. * 停机操作:停机地址发送1,停机地址发送0
  50. * 启动操作:复位地址发送1,复位地址发送0
  51. */
  52. byte[] typeArr = cmdList.Select(s => (byte)s.ControlType).ToArray();
  53. uint[] addressArr = cmdList.Select(s => (uint)s.CmdId).ToArray();
  54. float[] valueArr1 = cmdList.Select(s => s.CmdValue).ToArray();
  55. float[] valueArr0 = cmdList.Select(s => s.CmdValue).ToArray();
  56. int count1 = CmdSendService.gycp_control(intPtr, typeArr, addressArr, valueArr1, (uint)addressArr.Length);
  57. IList<string> faultSend1 = GetSendFaultWindtrubineIds();
  58. Thread.Sleep(800);
  59. int count0 = CmdSendService.gycp_control(intPtr, typeArr, addressArr, valueArr0, (uint)addressArr.Length);
  60. IList<string> faultSend0 = GetSendFaultWindtrubineIds();
  61. //将两次发送的命令失败集合合并(并集)并去重
  62. faultSendList = faultSend1.Union(faultSend0).ToList().Distinct().ToList();
  63. //收集并返回发送成功的风机Id集合
  64. IList<string> fault = faultSendList;
  65. return cmdList.Where(s => !fault.Contains(s.WindturbineId)).Select(k => k.WindturbineId).ToList();
  66. }
  67. /// <summary>
  68. /// 根据风机编号及其操作类型发送操作指令
  69. /// </summary>
  70. /// <param name="windturbinList">风机编号集合</param>
  71. /// <param name="stationId">风场编号</param>
  72. /// <param name="cmdType">操作类型</param>
  73. /// <param name="faultSendList">指令发送失败的风机集合</param>
  74. /// <param name="description">控制描述(手动,执行推荐)</param>
  75. /// <param name="user">操作人</param>
  76. /// <returns>控制指令是否全部发送成功</returns>
  77. public bool SendCmdByWindturbineIdList(IList<string> windturbinList, string stationId, CmdType cmdType, out IList<string> faultSendList, string description, user user)
  78. {
  79. faultSendList = new List<string>();
  80. using (wisdom_cs_entity ctx = new wisdom_cs_entity())
  81. {
  82. IList<windturbine> list =
  83. ctx.windturbine.Where(s => windturbinList.Contains(s.ID) && s.WINDPOWERSTATIONID == stationId)
  84. .ToList();
  85. IList<control_info> controlInfoListUp82 = new List<control_info>();
  86. IList<WindturbineCmdInfo> cmdInfoListUp82 = new List<WindturbineCmdInfo>();
  87. IList<control_info> controlInfoListUp105 = new List<control_info>();
  88. IList<WindturbineCmdInfo> cmdInfoListUp105 = new List<WindturbineCmdInfo>();
  89. for (int i = 0; i < list.Count; i++)
  90. {
  91. if (list[i].MODELID != "UP105-2000-S")
  92. {
  93. #region 操控记录实体
  94. control_info info = new control_info();
  95. info.control_description = description;
  96. info.user_id = user.id;
  97. info.time = DateTime.Now;
  98. info.success_time = null;
  99. info.windturbine_id = list[i].ID;
  100. info.type = (int)cmdType;
  101. controlInfoListUp82.Add(info);
  102. #endregion
  103. #region 风机命令实体
  104. WindturbineCmdInfo cmdInfo = new WindturbineCmdInfo();
  105. if (list[i].GYCP_ID.HasValue)
  106. cmdInfo.CmdIntPtr = ControlIntPtr.dic[list[i].PROJECTID];
  107. cmdInfo.WindturbineId = list[i].ID;
  108. cmdInfo.CmdType = cmdType;
  109. cmdInfo.ControlType = CmdSendService.GYCP_TYPE_YK;
  110. int controlType = 0;
  111. if (cmdInfo.CmdType == CmdType.Start)
  112. controlType = 1; //启动
  113. else if (cmdInfo.CmdType == CmdType.Stop)
  114. controlType = 2; //停机
  115. else if (cmdInfo.CmdType == CmdType.Maintain)
  116. controlType = 3; //维护
  117. else if (cmdInfo.CmdType == CmdType.UnMaintain)
  118. controlType = 4; //取消维护
  119. else if (cmdInfo.CmdType == CmdType.Reset)
  120. controlType = 5; //复位
  121. //获取控制点
  122. string windturbineId = list[i].ID;
  123. gycp_cmd_info gycpCmdInfo =
  124. ctx.gycp_cmd_info.Where(
  125. s => s.type == controlType && s.windturbine_id == windturbineId)
  126. .FirstOrDefault();
  127. //获取控制地址
  128. gycp_address address = null;
  129. if (list[i].GYCP_ID.HasValue)
  130. {
  131. int gycpId = list[i].GYCP_ID.Value;
  132. address = ctx.gycp_address.Where(s => s.id == gycpId).FirstOrDefault();
  133. }
  134. if (address != null && gycpCmdInfo != null)
  135. {
  136. cmdInfo.CmdId = gycpCmdInfo.cmd_id;
  137. if (gycpCmdInfo.cmd_value.HasValue)
  138. cmdInfo.CmdValue = gycpCmdInfo.cmd_value.Value;
  139. }
  140. cmdInfo.UserId = user.id;
  141. cmdInfo.Time = DateTime.Now;
  142. cmdInfo.IsSuccessSend = false;
  143. cmdInfoListUp82.Add(cmdInfo);
  144. #endregion
  145. }
  146. else
  147. {
  148. #region 操控记录实体
  149. control_info info = new control_info();
  150. info.control_description = description;
  151. info.user_id = user.id;
  152. info.time = DateTime.Now;
  153. info.success_time = null;
  154. info.windturbine_id = list[i].ID;
  155. info.type = (int)cmdType;
  156. controlInfoListUp105.Add(info);
  157. #endregion
  158. #region 风机命令实体
  159. WindturbineCmdInfo cmdInfo = new WindturbineCmdInfo();
  160. if (list[i].GYCP_ID.HasValue)
  161. cmdInfo.CmdIntPtr = ControlIntPtr.dic[list[i].PROJECTID];
  162. cmdInfo.WindturbineId = list[i].ID;
  163. cmdInfo.CmdType = cmdType;
  164. cmdInfo.ControlType = CmdSendService.GYCP_TYPE_YK;
  165. int controlType = 0;
  166. if (cmdInfo.CmdType == CmdType.Start)
  167. controlType = 5; //启动
  168. else if (cmdInfo.CmdType == CmdType.Stop)
  169. controlType = 1; //停机
  170. //获取控制点
  171. string windturbineId = list[i].ID;
  172. gycp_cmd_info gycpCmdInfo =
  173. ctx.gycp_cmd_info.Where(
  174. s => s.type == controlType && s.windturbine_id == windturbineId)
  175. .FirstOrDefault();
  176. //获取控制地址
  177. gycp_address address = null;
  178. if (list[i].GYCP_ID.HasValue)
  179. {
  180. int gycpId = list[i].GYCP_ID.Value;
  181. address = ctx.gycp_address.Where(s => s.id == gycpId).FirstOrDefault();
  182. }
  183. if (address != null && gycpCmdInfo != null)
  184. {
  185. cmdInfo.CmdId = gycpCmdInfo.cmd_id;
  186. if (gycpCmdInfo.cmd_value.HasValue)
  187. cmdInfo.CmdValue = gycpCmdInfo.cmd_value.Value;
  188. }
  189. cmdInfo.UserId = user.id;
  190. cmdInfo.Time = DateTime.Now;
  191. cmdInfo.IsSuccessSend = false;
  192. cmdInfoListUp105.Add(cmdInfo);
  193. #endregion
  194. }
  195. }
  196. var groupResultUp82 = cmdInfoListUp82.GroupBy(x => x.CmdIntPtr);
  197. foreach (var info in groupResultUp82)
  198. {
  199. IList<string> falutList = new List<string>();
  200. List<WindturbineCmdInfo> itemList = info.ToList();
  201. IList<string> successWindturbineIdList = SendCmd_Up82(itemList[0].CmdIntPtr, itemList, out falutList);
  202. #region 保存命令执行成功的记录
  203. IList<control_info> successList =
  204. controlInfoListUp82.Where(s => successWindturbineIdList.Contains(s.windturbine_id)).ToList();
  205. for (int i = 0; i < successList.Count; i++)
  206. {
  207. ctx.Entry(successList[i]).State = EntityState.Added;
  208. ctx.SaveChanges();
  209. }
  210. #endregion
  211. faultSendList = faultSendList.Union(falutList).ToList();//收集命令发送失败的风机集合
  212. }
  213. var groupResultUp105 = cmdInfoListUp105.GroupBy(x => x.CmdIntPtr);
  214. foreach (var info in groupResultUp105)
  215. {
  216. IList<string> falutList = new List<string>();
  217. List<WindturbineCmdInfo> itemList = info.ToList();
  218. IList<string> successWindturbineIdList = SendCmd_Up105(itemList[0].CmdIntPtr, itemList, out falutList);
  219. #region 保存命令执行成功的记录
  220. IList<control_info> successList =
  221. controlInfoListUp105.Where(s => successWindturbineIdList.Contains(s.windturbine_id)).ToList();
  222. for (int i = 0; i < successList.Count; i++)
  223. {
  224. ctx.Entry(successList[i]).State = EntityState.Added;
  225. ctx.SaveChanges();
  226. }
  227. #endregion
  228. faultSendList = faultSendList.Union(falutList).ToList();//收集命令发送失败的风机集合
  229. }
  230. if (faultSendList.Count <= 0)
  231. return true;
  232. else
  233. return false;
  234. }
  235. }
  236. /// <summary>
  237. /// 根据回调函数返回的数据得到命令发送失败的风机Id集合
  238. /// </summary>
  239. /// <returns></returns>
  240. public static IList<String> GetSendFaultWindtrubineIds()
  241. {
  242. IList<String> list = new List<string>();
  243. ControlResult result = ControlIntPtr.result;
  244. if (result != null)
  245. {
  246. for (int i = 0; i < result.Errors.Length; i++)
  247. {
  248. //错误值为1时代表发送失败
  249. if (result.Errors[i] == 1)
  250. {
  251. using (wisdom_cs_entity ctx = new wisdom_cs_entity())
  252. {
  253. gycp_cmd_info info =
  254. ctx.gycp_cmd_info.Where(s => s.cmd_id == result.Addresses[i]).FirstOrDefault();
  255. if (info != null)
  256. list.Add(info.windturbine_id);
  257. }
  258. }
  259. }
  260. ControlIntPtr.result = new ControlResult();
  261. }
  262. return list;
  263. }
  264. }
  265. }