GunPanel.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. package com.mes.component;
  2. import com.mes.ui.MesClient;
  3. import com.mes.ui.YgslUtil;
  4. import com.mes.util.JdbcUtils;
  5. import com.mes.ygsl.YgslClient;
  6. import com.mes.ygsl.YgslConfig;
  7. import com.mes.ygsl.YgslParam;
  8. import javax.swing.*;
  9. import java.awt.*;
  10. import java.util.List;
  11. import java.util.Timer;
  12. import java.util.TimerTask;
  13. public class GunPanel extends JPanel {
  14. private YgslConfig config;
  15. private int gunIndex;
  16. private int currentCount = 0;
  17. private int taskCount = 0;
  18. private boolean isOnline = false;
  19. private boolean isConnected = false;
  20. private YgslClient gunClient;
  21. private Timer heartBeatTimer;
  22. private List<String> tighteningIds;
  23. private JLabel nameLabel;
  24. private JLabel statusLabel;
  25. private JLabel scheduleLabel;
  26. private JLabel torqueLabel;
  27. private JLabel angleLabel;
  28. private OnTighteningDataListener dataListener;
  29. private OnTaskCompletedListener taskCompletedListener;
  30. private OnStatusChangeListener statusChangeListener;
  31. public interface OnTighteningDataListener {
  32. void onTighteningData(GunPanel panel, String tighteningStatus, String torque, String angle,
  33. String tighteningID, String jobID, String pos);
  34. }
  35. public interface OnTaskCompletedListener {
  36. void onTaskCompleted(GunPanel panel);
  37. }
  38. public interface OnStatusChangeListener {
  39. void onStatusChanged(GunPanel panel, boolean isOnline);
  40. }
  41. public GunPanel(YgslConfig config) {
  42. this.config = config;
  43. this.gunIndex = config.getGunIndex();
  44. // 颗数由扫码规则在开工前动态设定,配置中的 task_count 仅作占位
  45. this.taskCount = 0;
  46. this.tighteningIds = new java.util.ArrayList<>();
  47. initUI();
  48. }
  49. private void initUI() {
  50. setLayout(null);
  51. setPreferredSize(new Dimension(230, 140));
  52. setOpaque(false);
  53. JLabel titleLabel = new JLabel(config.getGunName());
  54. titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
  55. titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
  56. titleLabel.setForeground(Color.BLACK);
  57. titleLabel.setBounds(0, 5, 160, 28);
  58. add(titleLabel);
  59. statusLabel = new JLabel("离线");
  60. statusLabel.setHorizontalAlignment(SwingConstants.CENTER);
  61. statusLabel.setFont(new Font("微软雅黑", Font.BOLD, 14));
  62. statusLabel.setBounds(165, 8, 60, 22);
  63. statusLabel.setForeground(Color.RED);
  64. add(statusLabel);
  65. JLabel scheduleTitleLabel = new JLabel("进度:");
  66. scheduleTitleLabel.setHorizontalAlignment(SwingConstants.RIGHT);
  67. scheduleTitleLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18));
  68. scheduleTitleLabel.setForeground(Color.BLACK);
  69. scheduleTitleLabel.setBounds(10, 40, 60, 25);
  70. add(scheduleTitleLabel);
  71. scheduleLabel = new JLabel("0/" + taskCount);
  72. scheduleLabel.setHorizontalAlignment(SwingConstants.LEFT);
  73. scheduleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
  74. scheduleLabel.setForeground(Color.BLACK);
  75. scheduleLabel.setBounds(75, 40, 90, 25);
  76. add(scheduleLabel);
  77. JLabel torqueTitleLabel = new JLabel("扭矩:");
  78. torqueTitleLabel.setHorizontalAlignment(SwingConstants.RIGHT);
  79. torqueTitleLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18));
  80. torqueTitleLabel.setForeground(Color.BLACK);
  81. torqueTitleLabel.setBounds(10, 75, 60, 25);
  82. add(torqueTitleLabel);
  83. torqueLabel = new JLabel("");
  84. torqueLabel.setHorizontalAlignment(SwingConstants.LEFT);
  85. torqueLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
  86. torqueLabel.setForeground(Color.BLACK);
  87. torqueLabel.setBounds(75, 75, 100, 25);
  88. add(torqueLabel);
  89. JLabel angleTitleLabel = new JLabel("角度:");
  90. angleTitleLabel.setHorizontalAlignment(SwingConstants.RIGHT);
  91. angleTitleLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18));
  92. angleTitleLabel.setForeground(Color.BLACK);
  93. angleTitleLabel.setBounds(10, 110, 60, 25);
  94. add(angleTitleLabel);
  95. angleLabel = new JLabel("");
  96. angleLabel.setHorizontalAlignment(SwingConstants.LEFT);
  97. angleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
  98. angleLabel.setForeground(Color.BLACK);
  99. angleLabel.setBounds(75, 110, 100, 25);
  100. add(angleLabel);
  101. }
  102. public void connect() {
  103. if (gunClient != null) {
  104. return;
  105. }
  106. gunClient = new YgslClient(config.getIpAddress(), config.getPort(), gunIndex);
  107. gunClient.setGunPanel(this);
  108. try {
  109. gunClient.run();
  110. isConnected = true;
  111. startHeartBeatTimer();
  112. } catch (Exception e) {
  113. e.printStackTrace();
  114. isConnected = false;
  115. scheduleReconnect();
  116. }
  117. }
  118. public void disconnect() {
  119. stopHeartBeatTimer();
  120. if (gunClient != null) {
  121. gunClient.close();
  122. gunClient = null;
  123. }
  124. isConnected = false;
  125. isOnline = false;
  126. updateStatusUI();
  127. }
  128. private void scheduleReconnect() {
  129. Timer reconnectTimer = new Timer();
  130. reconnectTimer.schedule(new TimerTask() {
  131. @Override
  132. public void run() {
  133. if (!isConnected) {
  134. connect();
  135. }
  136. }
  137. }, 3000);
  138. }
  139. private void startHeartBeatTimer() {
  140. stopHeartBeatTimer();
  141. heartBeatTimer = new Timer();
  142. heartBeatTimer.schedule(new TimerTask() {
  143. @Override
  144. public void run() {
  145. if (gunClient != null && isConnected) {
  146. if (isOnline) {
  147. YgslUtil.comHeart(gunClient);
  148. } else {
  149. scheduleReconnect();
  150. }
  151. }
  152. updateStatusUI();
  153. }
  154. }, 1000, 3000);
  155. }
  156. private void stopHeartBeatTimer() {
  157. if (heartBeatTimer != null) {
  158. heartBeatTimer.cancel();
  159. heartBeatTimer = null;
  160. }
  161. }
  162. public void setOnline(boolean online) {
  163. this.isOnline = online;
  164. updateStatusUI();
  165. if (statusChangeListener != null) {
  166. statusChangeListener.onStatusChanged(this, online);
  167. }
  168. }
  169. private void updateStatusUI() {
  170. SwingUtilities.invokeLater(() -> {
  171. if (isOnline) {
  172. statusLabel.setText("在线");
  173. statusLabel.setForeground(Color.GREEN);
  174. } else {
  175. statusLabel.setText("离线");
  176. statusLabel.setForeground(Color.RED);
  177. }
  178. });
  179. }
  180. public void processTighteningData(String content) {
  181. if (MesClient.work_status != 1) {
  182. YgslUtil.lastTighteningResultDataAcknowledge(gunClient);
  183. return;
  184. }
  185. String tighteningStatus = com.mes.ygsl.YgslParam.getTighteningStatus(content);
  186. String torqueStatus = com.mes.ygsl.YgslParam.getTorqueStatus(content);
  187. String angleStatus = com.mes.ygsl.YgslParam.getAngleStatus(content);
  188. String torque = com.mes.ygsl.YgslParam.getTorque(content);
  189. String angle = com.mes.ygsl.YgslParam.getAngle(content);
  190. String tighteningID = com.mes.ygsl.YgslParam.getTighteningID(content);
  191. String jobID = com.mes.ygsl.YgslParam.getJobID(content);
  192. String torqueMin = YgslParam.getTorqueMinLimit(content);
  193. String torqueMax = YgslParam.getTorqueMaxLimit(content);
  194. String torqueFinal = YgslParam.getTorqueFinalTarget(content);
  195. String angleMin = YgslParam.getAngleMin(content);
  196. String angleMax = YgslParam.getAngleMax(content);
  197. String angleFinal = YgslParam.getFinalAngleTarget(content);
  198. if (tighteningID.isEmpty() || tighteningIds.contains(tighteningID)) {
  199. YgslUtil.lastTighteningResultDataAcknowledge(gunClient);
  200. return;
  201. }
  202. tighteningIds.add(tighteningID);
  203. String pos = String.valueOf(gunIndex);
  204. Boolean checkRet = JdbcUtils.checkTighteningById(tighteningID, pos, jobID);
  205. if (!checkRet) {
  206. if (tighteningStatus.equals("0")) {
  207. if (torqueStatus.equals("1")) {
  208. torqueLabel.setForeground(Color.BLACK);
  209. } else {
  210. torqueLabel.setForeground(Color.RED);
  211. }
  212. if (angleStatus.equals("1")) {
  213. angleLabel.setForeground(Color.BLACK);
  214. } else {
  215. angleLabel.setForeground(Color.RED);
  216. }
  217. } else {
  218. torqueLabel.setForeground(Color.BLACK);
  219. angleLabel.setForeground(Color.BLACK);
  220. if (tighteningStatus.equals("1")) {
  221. currentCount++;
  222. }
  223. }
  224. final int displayCount = tighteningStatus.equals("1") ? currentCount : currentCount + 1;
  225. SwingUtilities.invokeLater(() -> {
  226. torqueLabel.setText(torque);
  227. angleLabel.setText(angle);
  228. scheduleLabel.setText(displayCount + "/" + taskCount);
  229. });
  230. JdbcUtils.insertTighteningData(
  231. MesClient.mes_gw,MesClient.mes_line_sn,MesClient.product_sn.getText(),
  232. tighteningStatus,torqueStatus,angleStatus,torqueMin,torqueMax,torqueFinal,torque,
  233. angleMin,angleMax,angleFinal,angle,tighteningID,jobID,"",
  234. pos,MesClient.user_menu.getText()
  235. );
  236. if (currentCount >= taskCount) {
  237. disableTool();
  238. if (taskCompletedListener != null) {
  239. taskCompletedListener.onTaskCompleted(this);
  240. }
  241. }
  242. }
  243. YgslUtil.lastTighteningResultDataAcknowledge(gunClient);
  244. if (dataListener != null) {
  245. dataListener.onTighteningData(this, tighteningStatus, torque, angle, tighteningID, jobID, pos);
  246. }
  247. }
  248. public void enableTool() {
  249. if (gunClient != null && isOnline) {
  250. YgslUtil.enableTool(gunClient);
  251. }
  252. }
  253. public void disableTool() {
  254. if (gunClient != null && isOnline) {
  255. YgslUtil.disableTool(gunClient);
  256. }
  257. }
  258. public void pSet() {
  259. System.out.println("GunPanel[" + gunIndex + "] pSet called, isOnline=" + isOnline + ", gunClient=" + (gunClient != null));
  260. if (gunClient != null && isOnline) {
  261. YgslUtil.pSet(gunClient);
  262. } else {
  263. System.err.println("GunPanel[" + gunIndex + "] pSet skipped - not online!");
  264. }
  265. }
  266. public void startJob() {
  267. System.out.println("GunPanel[" + gunIndex + "] startJob called, isOnline=" + isOnline + ", gunClient=" + (gunClient != null));
  268. if (gunClient != null && isOnline) {
  269. YgslUtil.selectJob(gunClient);
  270. } else {
  271. System.err.println("GunPanel[" + gunIndex + "] startJob skipped - not online!");
  272. }
  273. }
  274. public void reset() {
  275. currentCount = 0;
  276. taskCount = 0; // 下一件由扫码规则重新设定
  277. tighteningIds.clear();
  278. SwingUtilities.invokeLater(() -> {
  279. torqueLabel.setText("");
  280. angleLabel.setText("");
  281. scheduleLabel.setText("0/0");
  282. torqueLabel.setForeground(Color.BLACK);
  283. angleLabel.setForeground(Color.BLACK);
  284. });
  285. }
  286. public boolean isTaskCompleted() {
  287. return taskCount > 0 && currentCount >= taskCount;
  288. }
  289. public int getCurrentCount() {
  290. return currentCount;
  291. }
  292. public int getTaskCount() {
  293. return taskCount;
  294. }
  295. /** 按扫码规则动态设定本枪拧紧颗数 */
  296. public void setTaskCount(int taskCount) {
  297. this.taskCount = taskCount;
  298. SwingUtilities.invokeLater(() -> {
  299. scheduleLabel.setText(currentCount + "/" + taskCount);
  300. });
  301. }
  302. public boolean isOnline() {
  303. return isOnline;
  304. }
  305. public YgslConfig getConfig() {
  306. return config;
  307. }
  308. public int getGunIndex() {
  309. return gunIndex;
  310. }
  311. public YgslClient getGunClient() {
  312. return gunClient;
  313. }
  314. public int getAutoSubmit() {
  315. return config.getAutoSubmit();
  316. }
  317. public void setDataListener(OnTighteningDataListener listener) {
  318. this.dataListener = listener;
  319. }
  320. public void setTaskCompletedListener(OnTaskCompletedListener listener) {
  321. this.taskCompletedListener = listener;
  322. }
  323. public void setStatusChangeListener(OnStatusChangeListener listener) {
  324. this.statusChangeListener = listener;
  325. }
  326. public void destroy() {
  327. disconnect();
  328. }
  329. public void updateConfig(YgslConfig newConfig) {
  330. this.config = newConfig;
  331. this.taskCount = newConfig.getTaskCount();
  332. SwingUtilities.invokeLater(() -> {
  333. scheduleLabel.setText(currentCount + "/" + taskCount);
  334. });
  335. }
  336. }