ControlIntPtr.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Data.Metadata.Edm;
  6. using System.Linq;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Threading;
  10. using EntityDataSet;
  11. using IntelligentControlForsx.Service.WindturbineControl.Domain.Cmd;
  12. using log4net;
  13. namespace IntelligentControlForsx.Service.WindturbineControl.IntPtrSvc
  14. {
  15. /// <summary>
  16. /// 创建控制句柄
  17. /// </summary>
  18. public class ControlIntPtr
  19. {
  20. private static ILog logger = LogManager.GetLogger("AppInfoLog");
  21. /// <summary>
  22. /// 句柄集合
  23. /// </summary>
  24. public static Dictionary<string, IntPtr> dic = new Dictionary<string, IntPtr>();
  25. private ArrayList servers = new ArrayList();
  26. private static ControlIntPtr controlIntPtr = new ControlIntPtr();
  27. public static ControlResult result = new ControlResult();
  28. private static CmdSendService.GycpReceive receive = null;
  29. private static AutoResetEvent resultEvent;
  30. private byte[] tmp_types;
  31. int[] tmp_addrs;
  32. private int[] tmp_errs;
  33. private ControlIntPtr()
  34. {
  35. }
  36. public static ControlIntPtr GetControlIntPtr()
  37. {
  38. return controlIntPtr;
  39. }
  40. /// <summary>
  41. /// 创建句柄
  42. /// </summary>
  43. /// <returns></returns>
  44. public bool init()
  45. {
  46. result = null;
  47. resultEvent = new AutoResetEvent(false);
  48. receive = new CmdSendService.GycpReceive(ReceiveCallback); ;
  49. using (wisdom_cs_entity ctx = new wisdom_cs_entity())
  50. {
  51. IList<gycp_address> list = ctx.gycp_address.Select(s => s).ToList();
  52. for (int i = 0; i < list.Count; i++)
  53. {
  54. GycpServer data = new GycpServer();
  55. data.Id = list[i].id;
  56. data.ProjectId = list[i].project_id;
  57. data.Ip = list[i].ip;
  58. data.Port = (ushort)list[i].port;
  59. servers.Add(data);
  60. }
  61. if (servers == null)
  62. {
  63. return false;
  64. }
  65. foreach (GycpServer server in this.servers)
  66. {
  67. try
  68. {
  69. server.Gycp = CmdSendService.gycp_create(server.Ip, server.Port, 30, 30, 20, receive, server.Gycp);
  70. // server.Gycp = CmdSendService.gycp_create("172.168.1.107", (ushort)9901, 30, 30, 20, receive, server.Gycp);
  71. //将控制句柄添加至字典
  72. dic.Add(server.ProjectId, server.Gycp);
  73. logger.Info("创建句柄成功:" + server.Ip + ":" + server.Port);
  74. }
  75. catch (Exception ex)
  76. {
  77. logger.Info("创建控制句柄失败" + server.Ip + "," + server.Port + ":" + ex);
  78. }
  79. }
  80. return true;
  81. }
  82. }
  83. /// <summary>
  84. /// 销毁句柄
  85. /// </summary>
  86. public void Destroy()
  87. {
  88. foreach (GycpServer server in this.servers)
  89. {
  90. CmdSendService.gycp_destroy(server.Gycp);
  91. }
  92. }
  93. /// <summary>
  94. /// 回调函数
  95. /// </summary>
  96. /// <param name="types">指令类型</param>
  97. /// <param name="addrs">指令地址</param>
  98. /// <param name="errors">错误码</param>
  99. /// <param name="length">指令长度</param>
  100. /// <param name="arg">句柄</param>
  101. public static void ReceiveCallback(IntPtr types, IntPtr addrs, IntPtr errors, uint length, IntPtr arg)
  102. {
  103. #region
  104. //控制命令错误码,0-发送成功,1--网络错误,2--modbus地址错误或不存在,-1无返回错误码,一般为服务错误,100为返回数据中命令地址编号找不到对应风机控制命令错误码
  105. //try
  106. //{
  107. // if (addrs != null && errors != null && length != 0)
  108. // {
  109. // byte[] tmp_types = new byte[length];
  110. // int[] tmp_addrs = new int[length];
  111. // int[] tmp_errs = new int[length];
  112. // Marshal.Copy(types, tmp_types, 0, tmp_types.Length);
  113. // Marshal.Copy(addrs, tmp_addrs, 0, tmp_addrs.Length);
  114. // Marshal.Copy(errors, tmp_errs, 0, tmp_errs.Length);
  115. // result = new ControlResult();
  116. // result.Types = tmp_types;
  117. // result.Addresses = tmp_addrs;
  118. // result.Errors = tmp_errs;
  119. // for (int i = 0; i < result.Addresses.Length; i++)
  120. // {
  121. // IList<string> keyList = TaskQueueSvc.dicTask.Keys.ToList();
  122. // for (int j = 0; j < keyList.Count; j++)
  123. // {
  124. // var task = TaskQueueSvc.dicTask[keyList[j]];
  125. // if (task.CmdId == result.Addresses[i])
  126. // {
  127. // //控制命令发送时间不为空
  128. // //重置命令发送时间为空
  129. // //控制命令错误码为空
  130. // //控制命令是否成功字段为空
  131. // //以上条件代表 控制命令 回调信息
  132. // if (task.SendControlTime.HasValue && !task.SendResetTime.HasValue && !task.SendControlErrorInfo.HasValue && !task.IsSendControlSuccess.HasValue)
  133. // {
  134. // task.SendControlErrorInfo = result.Errors[i];
  135. // if (result.Errors[i] == 0)
  136. // task.IsSendControlSuccess = true;
  137. // else
  138. // task.IsSendControlSuccess = false;
  139. // }
  140. // //控制命令发送时间不为空
  141. // //控制命令错误码不为空
  142. // //控制命令是否成功不为空
  143. // //重置命令发送时间不为空
  144. // //重置命令错误码为空
  145. // //重置命令是否成功为空
  146. // // 以上条件满足,则代表105机型重置命令 发送后的回调信息
  147. // else if (task.SendControlTime.HasValue && task.SendControlErrorInfo.HasValue && task.IsSendControlSuccess.HasValue && task.SendResetTime.HasValue && !task.SendResetlErrorInfo.HasValue && !task.IsSendResetSuccess.HasValue)
  148. // {
  149. // task.SendResetlErrorInfo = result.Errors[i];
  150. // if (result.Errors[i] == 0)
  151. // task.IsSendResetSuccess = true;
  152. // else
  153. // task.IsSendResetSuccess = false;
  154. // }
  155. // }
  156. // }
  157. // }
  158. // Console.WriteLine("回调成功" + tmp_addrs + "||" + tmp_errs + "||" + tmp_errs);
  159. // }
  160. //}
  161. //catch (Exception e)
  162. //{
  163. // Console.WriteLine("回调异常");
  164. //}
  165. #endregion
  166. #region
  167. //控制命令错误码,0-发送成功,1--网络错误,2--modbus地址错误或不存在,-1无返回错误码,一般为服务错误,100为返回数据中命令地址编号找不到对应风机控制命令错误码
  168. try
  169. {
  170. if (addrs != null && errors != null && length != 0)
  171. {
  172. byte[] tmp_types = new byte[length];
  173. int[] tmp_addrs = new int[length];
  174. int[] tmp_errs = new int[length];
  175. Marshal.Copy(types, tmp_types, 0, tmp_types.Length);
  176. Marshal.Copy(addrs, tmp_addrs, 0, tmp_addrs.Length);
  177. Marshal.Copy(errors, tmp_errs, 0, tmp_errs.Length);
  178. result = new ControlResult();
  179. result.Types = tmp_types;
  180. result.Addresses = tmp_addrs;
  181. result.Errors = tmp_errs;
  182. for (int i = 0; i < tmp_addrs.Length; i++)
  183. {
  184. Console.WriteLine("命令地址:"+tmp_addrs[i]+"错误码"+tmp_errs[i]);
  185. }
  186. for (int i = 0; i < result.Addresses.Length; i++)
  187. {
  188. IList<string> keyList = TaskQueueSvc.dicTask.Keys.ToList();
  189. for (int j = 0; j < keyList.Count; j++)
  190. {
  191. var task = TaskQueueSvc.dicTask[keyList[j]];
  192. if (task.CmdId == result.Addresses[i])
  193. {
  194. //控制命令发送时间不为空
  195. //重置命令发送时间为空
  196. //控制命令错误码为空
  197. //控制命令是否成功字段为空
  198. //以上条件代表 控制命令 回调信息
  199. if (task.SendControlTime.HasValue && !task.SendResetTime.HasValue && !task.SendControlErrorInfo.HasValue && !task.IsSendControlSuccess.HasValue)
  200. {
  201. task.SendControlErrorInfo = result.Errors[i];
  202. if (result.Errors[i] == 0)
  203. task.IsSendControlSuccess = true;
  204. else
  205. task.IsSendControlSuccess = false;
  206. using (wisdom_cs_entity ctx = new wisdom_cs_entity())
  207. {
  208. control_log log =
  209. ctx.control_log.Where(s => s.id == task.LogId).FirstOrDefault();
  210. if (log != null)
  211. {
  212. log.send_control_error_info = result.Errors[i].ToString();
  213. if (result.Errors[i] == 0)
  214. log.is_send_control_success = true;
  215. else
  216. log.is_send_control_success = false;
  217. ctx.Entry(log).State = EntityState.Modified;
  218. ctx.SaveChanges();
  219. }
  220. }
  221. }
  222. //控制命令发送时间不为空
  223. //控制命令错误码不为空
  224. //控制命令是否成功不为空
  225. //重置命令发送时间不为空
  226. //重置命令错误码为空
  227. //重置命令是否成功为空
  228. // 以上条件满足,则代表105机型重置命令 发送后的回调信息
  229. else if (task.SendControlTime.HasValue && task.SendControlErrorInfo.HasValue && task.IsSendControlSuccess.HasValue && task.SendResetTime.HasValue && !task.SendResetlErrorInfo.HasValue && !task.IsSendResetSuccess.HasValue)
  230. {
  231. task.SendResetlErrorInfo = result.Errors[i];
  232. if (result.Errors[i] == 0)
  233. task.IsSendResetSuccess = true;
  234. else
  235. task.IsSendResetSuccess = false;
  236. using (wisdom_cs_entity ctx = new wisdom_cs_entity())
  237. {
  238. control_log log =
  239. ctx.control_log.Where(s => s.id == task.LogId).FirstOrDefault();
  240. if (log != null)
  241. {
  242. log.send_reset_error_info = result.Errors[i].ToString();
  243. if (result.Errors[i] == 0)
  244. log.is_send_reset_success = true;
  245. else
  246. log.is_send_reset_success = false;
  247. ctx.Entry(log).State = EntityState.Modified;
  248. ctx.SaveChanges();
  249. }
  250. }
  251. }
  252. }
  253. }
  254. }
  255. }
  256. }
  257. catch (Exception e)
  258. {
  259. Console.WriteLine("回调异常");
  260. }
  261. #endregion
  262. }
  263. }
  264. public class GycpServer
  265. {
  266. public int Id { set; get; }
  267. public string ProjectId { set; get; }
  268. public string Ip { set; get; }
  269. public ushort Port { set; get; }
  270. public IntPtr Gycp;
  271. }
  272. }