MXComponent_FEM02.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. using ProjectBase.Data.BaseDAL;
  2. using ProjectBase.Data.Logs;
  3. using ProjectBase.Data.Redis;
  4. using ProjectBase.Util;
  5. using SIMDP.BLL;
  6. using SIMDP.Device;
  7. using SIMDP.Model;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Text;
  11. using System.Windows.Forms;
  12. namespace SIMDP.Project
  13. {
  14. public class MXComponent_FEM02 : PlcMXComponent
  15. {
  16. #region 设备空间 寄存器定义&继承成员
  17. private static string ip1 = "";
  18. private static int port1 = 0;
  19. private static string ip2 = "";
  20. private static int port2 = 0;
  21. private void InitScannerParams()
  22. {
  23. bool res1 = BLLFactory<BlPlcInfo>.Instance.GetScannerParams("Cammer1", out ip1, out port1);
  24. bool res2 = BLLFactory<BlPlcInfo>.Instance.GetScannerParams("Cammer2", out ip2, out port2);
  25. if (!res1 || !res2)
  26. {
  27. DevExpress.XtraEditors.XtraMessageBox.Show("当前扫码相机未配置,无法通信", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  28. }
  29. }
  30. public static bool SkipHeadScan = false;
  31. public static bool SkipFEMScan = false;
  32. public MXComponent_FEM02()
  33. {
  34. InitScannerParams();//初始化相机参数;
  35. FormCurrentTask.manualForceMatchSuccess += new FormCurrentTask.delegateResetVertify2(ManualForceMatchSuccess);
  36. FormCurrentTask.manualForceReleaseEmpty += new FormCurrentTask.delegateResetVertify2(ManualForceReleaseEmpty);
  37. FormCurrentTask.manualForceWrite2Tighting += new FormCurrentTask.delegateResetVertify3(ManualForceWrite2Tighting);
  38. }
  39. public override void actionConnected()
  40. {
  41. //复位PLC写入PLC的信号
  42. Write("SRS数据传输异常信号", false);
  43. Write("读取FEM二维码成功", false);
  44. Write("读取FEM二维码失败", false);
  45. Write("读取车头纸二维码成功", false);
  46. Write("读取车头纸二维码失败", false);
  47. Write("拧紧工位数据写入成功", false);
  48. Write("VIN匹配失败信号", false);
  49. Write("读取拧紧结果完成", false);
  50. }
  51. private bool pcHeartBeat = false;
  52. public override void actionTimer()
  53. {
  54. try
  55. {
  56. pcHeartBeat = !pcHeartBeat;
  57. if (!Write("PC心跳", pcHeartBeat))
  58. {
  59. isConnect = false;
  60. return;
  61. }
  62. //SRS报警
  63. if (SysEnvironment.warn_AS400)
  64. {
  65. Write("SRS数据传输异常信号", true);
  66. SysEnvironment.warn_AS400 = false;
  67. }
  68. foreach (MXComponentDataPointInfo p in monitorPoints)
  69. {
  70. if (!Read(p, out object value))
  71. {
  72. isConnect = false;
  73. return;
  74. }
  75. if (!value.Equals(p.value))
  76. {
  77. p.value = value;
  78. if (p.proc != null)
  79. p.proc.Invoke(this, new object[] { value });
  80. }
  81. }
  82. redis.Publish(SysEnvironment.OpcDataChannel, "");
  83. }
  84. catch (Exception ex)
  85. {
  86. isConnect = false;
  87. LogHelper.log.Error($"actionTimer()异常,即将重连PLC: {ex.Message}");
  88. }
  89. }
  90. internal class ProductionData
  91. {
  92. internal List<string> keys = new List<string>();
  93. internal Dictionary<string, string> dict = new Dictionary<string, string>();
  94. internal MoProductData model = new MoProductData();
  95. internal ProductionData()
  96. {
  97. model.RuleId = BLLFactory<BLL.BlRule>.Instance.GetRuleIdByName("FEM");
  98. keys.Add("型号");
  99. keys.Add("颜色");
  100. keys.Add("VIN");
  101. keys.Add("FEM");
  102. keys.Add("VIN2");
  103. keys.Add("力矩1");
  104. keys.Add("角度1");
  105. keys.Add("状态1");
  106. keys.Add("力矩2");
  107. keys.Add("角度2");
  108. keys.Add("状态2");
  109. keys.Add("力矩3");
  110. keys.Add("角度3");
  111. keys.Add("状态3");
  112. keys.Add("力矩4");
  113. keys.Add("角度4");
  114. keys.Add("状态4");
  115. keys.Add("生产完成");
  116. foreach (var key in keys)
  117. {
  118. dict.Add(key, "");
  119. }
  120. }
  121. internal string Dict2String()
  122. {
  123. StringBuilder builder = new StringBuilder();
  124. foreach (var d in dict)
  125. {
  126. if (builder.Length > 0)
  127. builder.Append(",");
  128. builder.Append(d.Value);
  129. }
  130. return builder.ToString();
  131. }
  132. internal MoProductData toModel()
  133. {
  134. model.DataValue = this.Dict2String();
  135. return model;
  136. }
  137. internal void LoadData(MoProductData data)
  138. {
  139. model.DataId = data.DataId;
  140. model.DataValue = data.DataValue;
  141. model.RuleId = data.RuleId;
  142. model.RuleTime = data.RuleTime;
  143. model.Batchid = data.Batchid;
  144. string[] values = model.DataValue.Split(',');
  145. if (values.Length > keys.Count)
  146. return;
  147. for (int i = 0; i < keys.Count; i++)
  148. {
  149. dict[keys[i]] = values[i];
  150. }
  151. }
  152. }
  153. public static class SuperQueueScanner
  154. {
  155. internal static RedisHelper redis = new RedisHelper(0);
  156. internal static Queue<string> HeadScanQueue = new Queue<string>(HeadScanQueueLength);
  157. internal static Queue<string> FEMScanQueue = new Queue<string>(FEMScanQueueLength);
  158. //1:匹配成功 0:不匹配 -1:空车架 -2:匹配中(两车间隙、未扫完) -3 未连锁 不匹配
  159. internal static int Scanning_Match_Result { get; set; } = -3;
  160. internal static int HeadScanQueueLength { get; } = 1;
  161. internal static int FEMScanQueueLength { get; } = 1;
  162. internal static int HeadScanCount { get { return HeadScanQueue.Count; } }
  163. internal static int FEMScanCount { get { return FEMScanQueue.Count; } }
  164. internal static void ClrearQueue()
  165. {
  166. HeadScanQueue.Clear();
  167. FEMScanQueue.Clear();
  168. }
  169. internal static string HeadScanEnqueue(string forceEnqueue = "")
  170. {
  171. if (forceEnqueue == "")
  172. forceEnqueue = Scanner.CameraScanner(ip2, port2, 3).Trim();
  173. //压入扫码站
  174. HeadScanQueue.Enqueue(forceEnqueue);
  175. redis.Publish(SysEnvironment.redis_Scanning_HeadCode, forceEnqueue);
  176. SysEnvironment.Global_Scanning_HeadCode = forceEnqueue;
  177. //缓存容量限制
  178. string dequeue = "";
  179. while (HeadScanQueue.Count > HeadScanQueueLength)
  180. {
  181. dequeue = HeadScanQueue.Dequeue();
  182. }
  183. return forceEnqueue;
  184. }
  185. internal static string HeadScanDequeue()
  186. {
  187. string dequeueStr = "";
  188. try
  189. {
  190. dequeueStr = HeadScanQueue.Dequeue();
  191. }
  192. catch { }
  193. return dequeueStr;
  194. }
  195. internal static string FEMScanEnqueue(string forceEnqueue = "")
  196. {
  197. if (forceEnqueue == "")
  198. forceEnqueue = Scanner.CameraScanner(ip1, port1, 3).Trim();
  199. FEMScanQueue.Enqueue(forceEnqueue);
  200. redis.Publish(SysEnvironment.redis_Scanning_FEMCode, forceEnqueue);
  201. SysEnvironment.Global_Scanning_FEMCode = forceEnqueue;
  202. //缓存容量限制
  203. string dequeue = "";
  204. while (FEMScanQueue.Count > FEMScanQueueLength)
  205. {
  206. dequeue = FEMScanQueue.Dequeue();
  207. }
  208. return forceEnqueue;
  209. }
  210. internal static string FEMScanDequeue()
  211. {
  212. string dequeueStr = "";
  213. try
  214. {
  215. dequeueStr = FEMScanQueue.Dequeue();
  216. }
  217. catch { }
  218. return dequeueStr;
  219. }
  220. /// <summary>
  221. /// 如果生成了匹配结果(匹配结果不为-3),则返回true;
  222. /// </summary>
  223. /// <returns></returns>
  224. internal static bool GenMatchResult()
  225. {
  226. LogHelper.log.Info($"匹配逻辑开始,车头扫码SkipHeadScan = {SkipHeadScan},FEM扫码SkipFEMScan = {SkipFEMScan}");
  227. if (SkipHeadScan && SkipFEMScan)
  228. {
  229. SuperQueueScanner.Scanning_Match_Result = -3;
  230. return false;
  231. }
  232. else if (SkipHeadScan && !SkipFEMScan)
  233. {
  234. if (FEMScanQueue.Count < 1)
  235. {
  236. SuperQueueScanner.Scanning_Match_Result = -3;
  237. return false;
  238. }
  239. string str2 = FEMScanQueue.Dequeue();
  240. if (!SysEnvironment.CheckVINRule(str2))
  241. {
  242. SuperQueueScanner.Scanning_Match_Result = 0;
  243. return true;
  244. }
  245. if (!string.Equals(str2, SysEnvironment.Global_Scanning_Pointer))
  246. {
  247. SuperQueueScanner.Scanning_Match_Result = 0;
  248. return true;
  249. }
  250. }
  251. else if (!SkipHeadScan && SkipFEMScan)
  252. {
  253. if (HeadScanQueue.Count < 1)
  254. {
  255. SuperQueueScanner.Scanning_Match_Result = -3;
  256. return false;
  257. }
  258. string str1 = HeadScanQueue.Dequeue();
  259. if (!SysEnvironment.CheckVINRule(str1))
  260. {
  261. SuperQueueScanner.Scanning_Match_Result = 0;
  262. return true;
  263. }
  264. if (!string.Equals(str1, SysEnvironment.Global_Scanning_Pointer))
  265. {
  266. SuperQueueScanner.Scanning_Match_Result = 0;
  267. return true;
  268. }
  269. }
  270. else
  271. {
  272. if (FEMScanQueue.Count < 1 && HeadScanQueue.Count < 1)
  273. {
  274. SuperQueueScanner.Scanning_Match_Result = -3;
  275. return false;
  276. }
  277. else if (FEMScanQueue.Count < 1)
  278. {
  279. SuperQueueScanner.Scanning_Match_Result = -2;//匹配中
  280. return false;//此处要注意
  281. }
  282. else if (HeadScanQueue.Count < 1)
  283. {
  284. SuperQueueScanner.Scanning_Match_Result = -2;//匹配中
  285. return true;
  286. }
  287. string str1 = HeadScanQueue.Dequeue();
  288. string str2 = FEMScanQueue.Dequeue();
  289. if (!SysEnvironment.CheckVINRule(str1) || !SysEnvironment.CheckVINRule(str2))
  290. {
  291. SuperQueueScanner.Scanning_Match_Result = 0;
  292. return true;
  293. }
  294. if (!string.Equals(str1, str2))
  295. {
  296. SuperQueueScanner.Scanning_Match_Result = 0;
  297. return true;
  298. }
  299. if (!string.Equals(str1, SysEnvironment.Global_Scanning_Pointer))
  300. {
  301. SuperQueueScanner.Scanning_Match_Result = 0;
  302. return true;
  303. }
  304. }
  305. //匹配成功,写入数据库扫码结果
  306. SuperQueueScanner.Scanning_Match_Result = 1;
  307. StoreScanningResult();
  308. return true;
  309. }
  310. }
  311. private static void StoreScanningResult()
  312. {
  313. try
  314. {
  315. MoMtocData task = BLLFactory<BlMtocData>.Instance.FindPointerModel(SysEnvironment.Global_Scanning_Pointer);
  316. if (task == null)
  317. {
  318. //不用报警
  319. LogHelper.log.Error($"存储车号 {SysEnvironment.Global_Scanning_Pointer}扫码数据异常:找不到车号的MTOC数据 ");
  320. return;
  321. }
  322. ProductionData data = new ProductionData();
  323. data.dict["型号"] = task.Model.ToString();
  324. data.dict["颜色"] = task.Color.ToString();
  325. data.dict["VIN"] = task.Vin;
  326. data.dict["VIN2"] = task.Vin;
  327. data.dict["FEM"] = task.Vin;
  328. data.model.Batchid = task.Vin;
  329. data.model.RuleTime = DateTime.Now;
  330. BLLFactory<BlProductData>.Instance.Insert(data.toModel());
  331. LogHelper.log.Info($"存储车号 {SysEnvironment.Global_Scanning_Pointer}扫码数据成功");
  332. }
  333. catch (Exception ex)
  334. {
  335. //不用报警
  336. LogHelper.log.Error($"存储车号 {SysEnvironment.Global_Scanning_Pointer}扫码数据异常: {ex.Message} ");
  337. }
  338. }
  339. #endregion
  340. #region PLC信号响应函数
  341. public void 联机模式(object value)
  342. {
  343. bool signal = Convert.ToBoolean(value);
  344. LogHelper.log.Info($"signal = {signal}");
  345. if (signal)
  346. {
  347. // SysEnvironment.sign_OnlineMode = true;
  348. //221104 重新联机后,强制复位PLC请求和PC状态
  349. actionConnected();
  350. }
  351. else
  352. {
  353. // SysEnvironment.sign_OnlineMode = false;
  354. SuperQueueScanner.ClrearQueue();
  355. }
  356. }
  357. public void 连锁信号(object value)
  358. {
  359. bool signal = Convert.ToBoolean(value);
  360. LogHelper.log.Info($"signal = {signal}");
  361. if (signal)
  362. {
  363. //////连锁第一时间进行匹配并处理结果
  364. //if (SuperQueueScanner.GenMatchResult()) SysEnvironment.Global_ScannerBlock = true;
  365. //redis.Publish(SysEnvironment.redis_ScannerBlock, SysEnvironment.Global_ScannerBlock);
  366. //TackleMatchResult();
  367. }
  368. else
  369. {
  370. //切除时,清空写入过的车型
  371. List<MoMtocData> list = new List<MoMtocData>();
  372. MoMtocData model = new MoMtocData() { Vin = "", Model = 0, Color = 0, };
  373. for (int i = 0; i < 10; i++)
  374. {
  375. list.Add(model);
  376. }
  377. if (WriteFromD4001(list))
  378. {
  379. redis.Publish(SysEnvironment.redis_Tighting_Pointer, "");
  380. redis.Publish(SysEnvironment.redis_Tighting_Model, "");
  381. redis.Publish(SysEnvironment.redis_Tighting_Color, "");
  382. }
  383. }
  384. }
  385. /// <summary>
  386. /// 这个函数永远都在 刚刚给出匹配结果的时侯后调用
  387. /// </summary>
  388. private void TackleMatchResult()
  389. {
  390. redis.Publish(SysEnvironment.redis_ScanningMatchRes, SuperQueueScanner.Scanning_Match_Result);
  391. if (SuperQueueScanner.Scanning_Match_Result == 0)
  392. Write("VIN匹配失败信号", true);
  393. else if (SuperQueueScanner.Scanning_Match_Result == -2)
  394. Write("VIN匹配失败信号", true);
  395. else if (SuperQueueScanner.Scanning_Match_Result == -1)
  396. Write("VIN匹配失败信号", false);
  397. else if (SuperQueueScanner.Scanning_Match_Result == 1)
  398. Write("VIN匹配失败信号", false);
  399. Read("请求拧紧工位数据写入", out bool delayWrite);
  400. if (delayWrite) 请求拧紧工位数据写入(true);
  401. }
  402. public void 手自动模式切换(object value)
  403. {
  404. bool signal = Convert.ToBoolean(value);
  405. LogHelper.log.Info($"signal = {signal}");
  406. //if (signal)
  407. //{
  408. // // SysEnvironment.sign_AutoMode = true;
  409. //}
  410. //else
  411. //{
  412. // // SysEnvironment.sign_AutoMode = false;
  413. // redis.Publish(SysEnvironment.redis_Tighting_Pointer, "");
  414. // redis.Publish(SysEnvironment.redis_Tighting_Model, "");
  415. // redis.Publish(SysEnvironment.redis_Tighting_Color, "");
  416. //}
  417. }
  418. public void 预约停止状态切换(object value)
  419. {
  420. bool signal = Convert.ToBoolean(value);
  421. LogHelper.log.Info($"signal = {signal}");
  422. //if (signal)
  423. //{
  424. // SysEnvironment.sign_OrderStop = true;
  425. // LogHelper.log.Debug("预约停止状态已设置!");
  426. //}
  427. //else
  428. //{
  429. // SysEnvironment.sign_OrderStop = false;
  430. // LogHelper.log.Debug("预约停止状态已取消");
  431. //}
  432. }
  433. public void 扫描车头纸二维码请求(object value)
  434. {
  435. bool signal = Convert.ToBoolean(value);
  436. LogHelper.log.Info($"signal = {signal}");
  437. if (!signal)
  438. {
  439. Write("读取车头纸二维码成功", false);
  440. Write("读取车头纸二维码失败", false);
  441. return;
  442. }
  443. //if (SysEnvironment.Global_ScannerBlock) return;///没写入之前不扫新的
  444. string HeadBarcode = SuperQueueScanner.HeadScanEnqueue();
  445. LogHelper.log.Info($"触发车头纸扫码:{HeadBarcode}");
  446. Write("读取车头纸二维码成功", true);
  447. Read("连锁信号", out bool bChain);
  448. if (bChain)
  449. {
  450. if (SuperQueueScanner.GenMatchResult()) SysEnvironment.Global_ScannerBlock = true;
  451. redis.Publish(SysEnvironment.redis_ScannerBlock, SysEnvironment.Global_ScannerBlock);
  452. TackleMatchResult();
  453. }
  454. else
  455. {
  456. //切除状态下,扫码跳指针
  457. MoMtocData model2Scan = BLLFactory<BlMtocData>.Instance.FindPointerNextModel(SysEnvironment.Global_Scanning_Pointer);
  458. SysEnvironment.Global_Scanning_Pointer = model2Scan == null ? "" : model2Scan.Vin;
  459. redis.Publish(SysEnvironment.redis_Scanning_Pointer, SysEnvironment.Global_Scanning_Pointer);
  460. LogHelper.log.Info($"切除状态,强制跳指针到:{SysEnvironment.Global_Scanning_Pointer}");
  461. SuperQueueScanner.Scanning_Match_Result = -3;
  462. redis.Publish(SysEnvironment.redis_ScanningMatchRes, SuperQueueScanner.Scanning_Match_Result);
  463. }
  464. }
  465. public void 扫描FEM二维码请求(object value)
  466. {
  467. bool signal = Convert.ToBoolean(value);
  468. LogHelper.log.Info($"signal = {signal}");
  469. if (!signal)
  470. {
  471. Write("读取FEM二维码成功", false);
  472. Write("读取FEM二维码失败", false);
  473. return;
  474. }
  475. if (SysEnvironment.Global_ScannerBlock) return;///没写入之前不扫新的
  476. string FEMBarcode = SuperQueueScanner.FEMScanEnqueue();
  477. LogHelper.log.Info($"触发FEM扫码:{FEMBarcode}");
  478. Write("读取FEM二维码成功", true);
  479. Read("连锁信号", out bool bChain);//其实不连锁也不会触发扫码
  480. if (bChain)
  481. {
  482. if (SuperQueueScanner.GenMatchResult()) SysEnvironment.Global_ScannerBlock = true;
  483. redis.Publish(SysEnvironment.redis_ScannerBlock, SysEnvironment.Global_ScannerBlock);
  484. TackleMatchResult();
  485. }
  486. }
  487. public void ManualForceMatchSuccess()
  488. {
  489. SuperQueueScanner.Scanning_Match_Result = 1;
  490. TackleMatchResult();
  491. }
  492. public void ManualForceReleaseEmpty()
  493. {
  494. //SuperQueueScanner.Scanning_Match_Result = -1;
  495. //TackleMatchResult();
  496. }
  497. public void ManualForceWrite2Tighting(short model, short color, string vin)
  498. {
  499. if (WriteD4001(model, color, vin))
  500. {
  501. Write("拧紧工位数据写入成功", true);
  502. SysEnvironment.Global_ScannerBlock = false;
  503. redis.Publish(SysEnvironment.redis_ScannerBlock, SysEnvironment.Global_ScannerBlock);
  504. ///车型已写入,可以进入下一轮扫码,先扫车身的(因为不会阻塞)
  505. Read("扫描车头纸二维码请求", out bool bscanHead);
  506. if (bscanHead) 扫描车头纸二维码请求(true);
  507. Read("扫描FEM二维码请求", out bool bscanFEM);
  508. if (bscanFEM) 扫描FEM二维码请求(true);
  509. SysEnvironment.Global_Tighting_Pointer = vin;
  510. SysEnvironment.Global_Tighting_Model = model;
  511. SysEnvironment.Global_Tighting_Color = color;
  512. redis.Publish(SysEnvironment.redis_Tighting_Pointer, vin);
  513. redis.Publish(SysEnvironment.redis_Tighting_Model, model);
  514. redis.Publish(SysEnvironment.redis_Tighting_Color, color);
  515. }
  516. //保险复位一下
  517. Read("请求拧紧工位数据写入", out bool res);
  518. if (!res)
  519. {
  520. Write("拧紧工位数据写入成功", false);
  521. }
  522. }
  523. /// <summary>
  524. /// 主链发车,PLC要车型,此信号发出前,PC应保证匹配已经结束,如果未匹配完成则应将M1128持续置1
  525. /// 如果接收此信号时,匹配结果<1,将直接返回(设计上只有第一台车允许这样)。
  526. /// </summary>
  527. /// <param name="value"></param>
  528. public void 请求拧紧工位数据写入(object value)
  529. {
  530. bool signal = Convert.ToBoolean(value);
  531. LogHelper.log.Info($"signal = {signal}");
  532. if (!signal)
  533. {
  534. Write("拧紧工位数据写入成功", false);
  535. return;
  536. }
  537. //非连锁禁止触发
  538. Read("连锁信号", out bool bChain);
  539. if (!bChain) return;
  540. //清空拧紧工位所有的信息,包括 PLC PC UI
  541. SysEnvironment.Global_Tighting_Pointer = "";
  542. SysEnvironment.Global_Tighting_Model = 0;
  543. SysEnvironment.Global_Tighting_Color = 0;
  544. redis.Publish(SysEnvironment.redis_Tighting_Pointer, "");
  545. redis.Publish(SysEnvironment.redis_Tighting_Model, "");
  546. redis.Publish(SysEnvironment.redis_Tighting_Color, "");
  547. //只要PLC要数据,就先给置成0
  548. if (!WriteD4001(0, 0, "")) return;
  549. ////空车架/插车 -1
  550. //if (SuperQueueScanner.Scanning_Match_Result == -1)
  551. //{
  552. // ///此处UI更新不完善,但不再更改,因为后续弃用空车架逻辑
  553. // Write("拧紧工位数据写入成功", true);
  554. // bWritten = true;
  555. // redis.Publish(SysEnvironment.redis_Tighting_Pointer, "空车架/插车");
  556. // redis.Publish(SysEnvironment.redis_Tighting_Model, "0");
  557. // redis.Publish(SysEnvironment.redis_Tighting_Color, "0");
  558. // return;
  559. //}
  560. //匹配失败0、没匹配完-2 切除状态不匹配 -3
  561. else if (SuperQueueScanner.Scanning_Match_Result < 1)
  562. {
  563. ///设计上不允许出现的情况!!只有第一台车有这个可能
  564. LogHelper.log.Error($"非正常情况!发车时(M1118触发时),匹配结果为 {SuperQueueScanner.Scanning_Match_Result} !!");
  565. return;
  566. }
  567. // == 1 进入匹配成功逻辑
  568. LogHelper.log.Info($"进入匹配成功逻辑:当前指针 {SysEnvironment.Global_Scanning_Pointer}");
  569. List<MoMtocData> listMtoc = BLLFactory<BlMtocData>.Instance.FindFromThis(SysEnvironment.Global_Scanning_Pointer, 10);
  570. if (listMtoc == null || listMtoc.Count < 1)
  571. {
  572. LogHelper.log.Error($"找不到指针所指车型信息!!");
  573. return;
  574. }
  575. ///清空所有扫码工位信息
  576. SysEnvironment.Global_Scanning_HeadCode = "";
  577. SysEnvironment.Global_Scanning_FEMCode = "";
  578. SuperQueueScanner.Scanning_Match_Result = -3;
  579. redis.Publish(SysEnvironment.redis_Scanning_HeadCode, SysEnvironment.Global_Scanning_HeadCode);
  580. redis.Publish(SysEnvironment.redis_Scanning_FEMCode, SysEnvironment.Global_Scanning_FEMCode);
  581. redis.Publish(SysEnvironment.redis_ScanningMatchRes, SuperQueueScanner.Scanning_Match_Result);
  582. if (WriteFromD4001(listMtoc))
  583. {
  584. Write("拧紧工位数据写入成功", true);
  585. SysEnvironment.Global_ScannerBlock = false;
  586. redis.Publish(SysEnvironment.redis_ScannerBlock, SysEnvironment.Global_ScannerBlock);
  587. ///车型已写入,可以进入下一轮扫码,先扫车身的(因为不会阻塞)
  588. Read("扫描车头纸二维码请求", out bool bscanHead);
  589. if (bscanHead) 扫描车头纸二维码请求(true);
  590. Read("扫描FEM二维码请求", out bool bscanFEM);
  591. if (bscanFEM) 扫描FEM二维码请求(true);
  592. }
  593. UpdateTightingInfo(listMtoc[0]);
  594. MoveScanningPointer();
  595. }
  596. private bool WriteFromD4001(List<MoMtocData> list)
  597. {
  598. int length = list.Count;
  599. string startDevice_Type = "D4001";
  600. string startDevice_Color = "D6001";
  601. string startDevice_VIN = "D8010";
  602. short[] data1 = new short[length];
  603. short[] data2 = new short[length];
  604. short[] data3 = new short[length * 10];
  605. for (int i = 0; i < list.Count; i++)
  606. {
  607. data1[i] = Convert.ToInt16(list[i].Model);
  608. data2[i] = Convert.ToInt16(list[i].Color);
  609. int tmpCount = 0;
  610. short[] tmpShorts = String2Shorts(list[i].Vin);
  611. for (int j = i * 10; j < i * 10 + 10; j++)
  612. {
  613. data3[j] = tmpShorts[tmpCount];
  614. tmpCount++;
  615. }
  616. }
  617. int res1 = actEasyIF.WriteDeviceBlock2(startDevice_Type, length, ref data1[0]);
  618. int res2 = actEasyIF.WriteDeviceBlock2(startDevice_Color, length, ref data2[0]);
  619. int res3 = actEasyIF.WriteDeviceBlock2(startDevice_VIN, length * 10, ref data3[0]);
  620. return res1 == 0 && res2 == 0 && res3 == 0;
  621. }
  622. private bool WriteD4001(short model, short color, string vin)
  623. {
  624. string startDevice_Type = "D4001";
  625. string startDevice_Color = "D6001";
  626. string startDevice_VIN = "D8010";
  627. short[] data1 = new short[1] { model };
  628. short[] data2 = new short[1] { color };
  629. short[] data3 = new short[10];
  630. short[] tmpShorts = String2Shorts(vin);
  631. for (int i = 0; i < 10; i++)
  632. {
  633. data3[i] = tmpShorts[i];
  634. }
  635. int res1 = actEasyIF.WriteDeviceBlock2(startDevice_Type, 1, ref data1[0]);
  636. int res2 = actEasyIF.WriteDeviceBlock2(startDevice_Color, 1, ref data2[0]);
  637. int res3 = actEasyIF.WriteDeviceBlock2(startDevice_VIN, 10, ref data3[0]);
  638. return res1 == 0 && res2 == 0 && res3 == 0;
  639. }
  640. /// <summary>
  641. /// 更新本地拧紧工位信息
  642. /// </summary>
  643. /// <param name="modelScanned"></param>
  644. public void UpdateTightingInfo(MoMtocData modelScanned)
  645. {
  646. LogHelper.log.Info($"【更新本地拧紧工位数据】");
  647. //拧紧工位数据变更
  648. SysEnvironment.Global_Tighting_Pointer = modelScanned.Vin;
  649. SysEnvironment.Global_Tighting_Model = modelScanned.Model;
  650. SysEnvironment.Global_Tighting_Color = modelScanned.Color;
  651. redis.Publish(SysEnvironment.redis_Tighting_Pointer, modelScanned.Vin);
  652. redis.Publish(SysEnvironment.redis_Tighting_Model, modelScanned.Model);
  653. redis.Publish(SysEnvironment.redis_Tighting_Color, modelScanned.Color);
  654. }
  655. public void MoveScanningPointer()
  656. {
  657. LogHelper.log.Info($"【跳扫码工位指针】");
  658. //扫码工位指针变更
  659. MoMtocData model2Scan = BLLFactory<BlMtocData>.Instance.FindPointerNextModel(SysEnvironment.Global_Scanning_Pointer);
  660. SysEnvironment.Global_Scanning_Pointer = model2Scan == null ? "" : model2Scan.Vin;
  661. redis.Publish(SysEnvironment.redis_Scanning_Pointer, SysEnvironment.Global_Scanning_Pointer);
  662. LogHelper.log.Info($"扫码工位跳指针到 {SysEnvironment.Global_Scanning_Pointer}");
  663. }
  664. public void 读取拧紧结果请求(object value)
  665. {
  666. bool signal = Convert.ToBoolean(value);
  667. LogHelper.log.Info($"signal = {signal}");
  668. if (!signal)
  669. {
  670. Write("读取拧紧结果完成", false);
  671. return;
  672. }
  673. Read("拧紧结果1", out short itightRes1);
  674. Read("拧紧结果2", out short itightRes2);
  675. Read("拧紧结果3", out short itightRes3);
  676. Read("拧紧结果4", out short itightRes4);
  677. Read("拧紧力矩1", out float moment1);
  678. Read("拧紧力矩2", out float moment2);
  679. Read("拧紧力矩3", out float moment3);
  680. Read("拧紧力矩4", out float moment4);
  681. Read("拧紧角度1", out float angle1);
  682. Read("拧紧角度2", out float angle2);
  683. Read("拧紧角度3", out float angle3);
  684. Read("拧紧角度4", out float angle4);
  685. try
  686. {
  687. string curerntVIN = SysEnvironment.Global_Tighting_Pointer;
  688. int currentModel = SysEnvironment.Global_Tighting_Model;
  689. int curerntColor = SysEnvironment.Global_Tighting_Color;
  690. MoProductData model_data = BLLFactory<BlProductData>.Instance.Find2Bind(curerntVIN);
  691. if (model_data == null)
  692. {
  693. ProductionData data = new ProductionData();
  694. data.dict["型号"] = currentModel.ToString();
  695. data.dict["颜色"] = curerntColor.ToString();
  696. data.dict["VIN"] = curerntVIN;
  697. data.dict["FEM"] = curerntVIN;
  698. data.dict["VIN2"] = curerntVIN;
  699. data.dict["状态1"] = GetTightResult(itightRes1);
  700. data.dict["状态2"] = GetTightResult(itightRes2);
  701. data.dict["状态3"] = GetTightResult(itightRes3);
  702. data.dict["状态4"] = GetTightResult(itightRes4);
  703. data.dict["力矩1"] = moment1.ToString();
  704. data.dict["力矩2"] = moment2.ToString();
  705. data.dict["力矩3"] = moment3.ToString();
  706. data.dict["力矩4"] = moment4.ToString();
  707. data.dict["角度1"] = angle1.ToString();
  708. data.dict["角度2"] = angle2.ToString();
  709. data.dict["角度3"] = angle3.ToString();
  710. data.dict["角度4"] = angle4.ToString();
  711. data.dict["生产完成"] = "1";
  712. data.model.Batchid = curerntVIN;
  713. data.model.RuleTime = DateTime.Now;
  714. BLLFactory<BlProductData>.Instance.Insert(data.toModel());
  715. Write("读取拧紧结果完成", true);
  716. }
  717. else
  718. {
  719. ProductionData data = new ProductionData();
  720. data.LoadData(model_data);
  721. data.dict["状态1"] = GetTightResult(itightRes1);
  722. data.dict["状态2"] = GetTightResult(itightRes2);
  723. data.dict["状态3"] = GetTightResult(itightRes3);
  724. data.dict["状态4"] = GetTightResult(itightRes4);
  725. data.dict["力矩1"] = moment1.ToString();
  726. data.dict["力矩2"] = moment2.ToString();
  727. data.dict["力矩3"] = moment3.ToString();
  728. data.dict["力矩4"] = moment4.ToString();
  729. data.dict["角度1"] = angle1.ToString();
  730. data.dict["角度2"] = angle2.ToString();
  731. data.dict["角度3"] = angle3.ToString();
  732. data.dict["角度4"] = angle4.ToString();
  733. data.dict["生产完成"] = "1";
  734. data.model.RuleTime = DateTime.Now;
  735. BLLFactory<BlProductData>.Instance.Update(data.toModel(), data.model.DataId);
  736. Write("读取拧紧结果完成", true);
  737. }
  738. }
  739. catch (Exception ex)
  740. {
  741. //报警!!
  742. LogHelper.log.Error($"存储拧紧数据异常: {ex.Message} ");
  743. return;
  744. }
  745. }
  746. #endregion
  747. #region 私有方法
  748. private bool WriteDevice(List<MoMtocData> list, int length, bool writeD8000 = false)
  749. {
  750. string startDevice_Type = "D4001";
  751. string startDevice_Color = "D6001";
  752. string startDevice_VIN = "D8010";
  753. if (writeD8000)
  754. {
  755. startDevice_Type = "D4000";
  756. startDevice_Color = "D6000";
  757. startDevice_VIN = "D8000";
  758. }
  759. short[] data1 = new short[length];
  760. short[] data2 = new short[length];
  761. short[] data3 = new short[length * 10];
  762. for (int i = 0; i < list.Count; i++)
  763. {
  764. data1[i] = Convert.ToInt16(list[i].Model);
  765. data2[i] = Convert.ToInt16(list[i].Color);
  766. int tmpCount = 0;
  767. short[] tmpShorts = String2Shorts(list[i].Vin);
  768. for (int j = i * 10; j < i * 10 + 10; j++)
  769. {
  770. data3[j] = tmpShorts[tmpCount];
  771. tmpCount++;
  772. }
  773. }
  774. int res1 = actEasyIF.WriteDeviceBlock2(startDevice_Type, length, ref data1[0]);
  775. int res2 = actEasyIF.WriteDeviceBlock2(startDevice_Color, length, ref data2[0]);
  776. int res3 = actEasyIF.WriteDeviceBlock2(startDevice_VIN, length * 10, ref data3[0]);
  777. return res1 == 0 && res2 == 0 && res3 == 0;
  778. }
  779. private short[] String2Shorts(string ss, int minimumLength = 10)
  780. {
  781. char[] cc = ss.ToCharArray();
  782. short[] ii = new short[cc.Length];
  783. if (cc.Length < minimumLength)
  784. ii = new short[minimumLength];
  785. for (int i = 0; i < cc.Length; i += 2)
  786. {
  787. if (i + 1 == cc.Length)
  788. ii[i / 2] = (short)cc[i];
  789. else
  790. ii[i / 2] = (short)(cc[i + 1] * 256 + cc[i]);
  791. }
  792. return ii;
  793. }
  794. /// <summary>
  795. /// 清空PLC数据展示地址数据
  796. /// </summary>
  797. private void ClearPLC()
  798. {
  799. try
  800. {
  801. int length = 12;
  802. string startDevice_Type = "D4000";
  803. short[] data1 = new short[length];
  804. int res1 = actEasyIF.WriteDeviceBlock2(startDevice_Type, length, ref data1[0]);
  805. string startDevice_Color = "D6000";
  806. short[] data2 = new short[length];
  807. int res2 = actEasyIF.WriteDeviceBlock2(startDevice_Color, length, ref data2[0]);
  808. string startDevice_VIN = "D8000";
  809. //short[] data3 = Enumerable.Repeat<short>(Convert.ToInt16( '\0'), length).ToArray();;
  810. //int res3 = actEasyIF.WriteDeviceBlock2(startDevice_VIN, length, ref data3[0]);//多此一举
  811. short[] data3 = new short[length * 10];
  812. int res3 = actEasyIF.WriteDeviceBlock2(startDevice_VIN, length * 10, ref data3[0]);
  813. // SysEnvironment.SignTrrigerScanPLCData = res1 == 0 && res2 == 0 && res3 == 0;//用于监控节点界面刷新显示
  814. }
  815. catch (Exception ex)
  816. {
  817. LogHelper.log.Error($"ClearPLC()出错: {ex.Message}");
  818. }
  819. }
  820. private string GetTightResult(int ires)
  821. {
  822. switch (ires)
  823. {
  824. case 1:
  825. return "OK";
  826. case 2:
  827. return "NG";
  828. case 0:
  829. return "未拧紧";
  830. default:
  831. return ires.ToString();
  832. }
  833. }
  834. #endregion
  835. }
  836. }