| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- package com.mes.component;
- import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
- import com.mes.ui.MesClient;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.swing.*;
- import java.awt.*;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * PLC信号监控组件
- * 可复用的信号监控面板,支持显示PLC信号状态和详细对话框
- */
- public class PlcSignalMonitor {
-
- private static final Logger log = LoggerFactory.getLogger(PlcSignalMonitor.class);
-
- private S7PLC s7PLC;
- private String plcDb;
- private String stationName;
- private JFrame parentFrame;
-
- // 信号标签(用于对话框中的实时更新)
- private JLabel signal_feeding;
- private JLabel signal_blanking;
- private JLabel signal_running;
- private JLabel signal_deviceStatus;
- private JLabel signal_allowFeeding;
- private JLabel signal_allowBlanking;
- private JLabel signal_heart;
- private JLabel signal_toDevice;
- private JLabel signal_toTransfer;
- private JLabel signal_transferToDevice;
-
- /**
- * 构造函数
- * @param s7PLC PLC连接对象
- * @param plcDb DB块名称(如 DB7000)
- * @param stationName 工位名称(如 OP040A)
- * @param parentFrame 父窗口
- */
- public PlcSignalMonitor(S7PLC s7PLC, String plcDb, String stationName, JFrame parentFrame) {
- this.s7PLC = s7PLC;
- this.plcDb = plcDb;
- this.stationName = stationName;
- this.parentFrame = parentFrame;
- }
-
- /**
- * 创建信号监控按钮(放在工位面板中)
- * @return 信号监控按钮
- */
- public JButton createSignalButton() {
- JButton signalBtn = new JButton("PLC信号");
- signalBtn.setFont(new Font("微软雅黑", Font.PLAIN, 12));
- signalBtn.setForeground(new Color(0, 102, 204));
- signalBtn.setToolTipText("点击查看PLC信号详情");
- signalBtn.addActionListener(e -> showSignalDialog());
- return signalBtn;
- }
-
- /**
- * 创建信号标签
- */
- private JLabel createSignalLabel(String text, boolean active) {
- JLabel label = new JLabel(text);
- label.setOpaque(true);
- label.setFont(new Font("微软雅黑", Font.PLAIN, 11));
- label.setHorizontalAlignment(SwingConstants.CENTER);
- label.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
- label.setPreferredSize(new Dimension(50, 18));
- updateSignalLabel(label, active);
- return label;
- }
-
- /**
- * 更新信号标签状态
- */
- private void updateSignalLabel(JLabel label, boolean active) {
- if (active) {
- label.setBackground(new Color(0, 200, 0));
- label.setForeground(Color.WHITE);
- } else {
- label.setBackground(new Color(200, 200, 200));
- label.setForeground(Color.DARK_GRAY);
- }
- }
-
- /**
- * 显示信号监控对话框
- */
- public void showSignalDialog() {
- JDialog dialog = new JDialog(parentFrame, stationName + " - PLC信号监控", false);
- dialog.setSize(550, 400);
- dialog.setLocationRelativeTo(parentFrame);
-
- JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
- panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
-
- // 标题
- JLabel title = new JLabel("PLC信号实时监控");
- title.setFont(new Font("微软雅黑", Font.BOLD, 16));
- title.setAlignmentX(Component.CENTER_ALIGNMENT);
- panel.add(title);
- panel.add(Box.createVerticalStrut(10));
-
- // 工位信息
- JLabel stationInfo = new JLabel("工位: " + stationName + " | DB块: " + plcDb);
- stationInfo.setFont(new Font("微软雅黑", Font.PLAIN, 12));
- stationInfo.setForeground(Color.GRAY);
- stationInfo.setAlignmentX(Component.CENTER_ALIGNMENT);
- panel.add(stationInfo);
- panel.add(Box.createVerticalStrut(15));
-
- // 信号详情面板
- JPanel signalPanel = createSignalDetailPanel();
- panel.add(signalPanel);
-
- panel.add(Box.createVerticalStrut(15));
-
- // 刷新按钮
- JButton refreshBtn = new JButton("刷新信号");
- refreshBtn.setFont(new Font("微软雅黑", Font.PLAIN, 12));
- refreshBtn.setAlignmentX(Component.CENTER_ALIGNMENT);
- refreshBtn.addActionListener(e -> updateSignalDisplay());
- panel.add(refreshBtn);
-
- dialog.add(panel);
-
- // 首次显示时更新信号
- updateSignalDisplay();
-
- dialog.setVisible(true);
- }
-
- /**
- * 创建信号详情面板
- */
- private JPanel createSignalDetailPanel() {
- List<String[]> signalList = new ArrayList<>();
- signalList.add(new String[]{"请求上料", plcDb + ".0.0", "PLC→MES"});
- signalList.add(new String[]{"下料信号", plcDb + ".0.1", "PLC→MES"});
- signalList.add(new String[]{"设备运行", plcDb + ".0.2", "PLC→MES"});
- signalList.add(new String[]{"设备通讯", plcDb + ".0.3", "PLC状态"});
- signalList.add(new String[]{"MES允许上料", plcDb + ".0.4", "MES→PLC"});
- signalList.add(new String[]{"MES允许下料", plcDb + ".0.5", "MES→PLC"});
- signalList.add(new String[]{"心跳信号", plcDb + ".0.6", "MES→PLC"});
- signalList.add(new String[]{"上料到设备", plcDb + ".0.7", "PLC→MES"});
- if (MesClient.transferEnabled) {
- signalList.add(new String[]{"上料到中转车", plcDb + ".1.0", "PLC→MES"});
- signalList.add(new String[]{"中转车上料到设备", plcDb + ".1.1", "PLC→MES"});
- }
- JPanel panel = new JPanel(new GridLayout(signalList.size() + 1, 4, 5, 5));
- panel.setBorder(BorderFactory.createTitledBorder(stationName + " 信号状态"));
-
- // 表头
- panel.add(createHeaderLabel("信号名称"));
- panel.add(createHeaderLabel("地址"));
- panel.add(createHeaderLabel("方向"));
- panel.add(createHeaderLabel("状态"));
-
- // 初始化信号标签
- signal_feeding = createStatusLabel();
- signal_blanking = createStatusLabel();
- signal_running = createStatusLabel();
- signal_deviceStatus = createStatusLabel();
- signal_allowFeeding = createStatusLabel();
- signal_allowBlanking = createStatusLabel();
- signal_heart = createStatusLabel();
- signal_toDevice = createStatusLabel();
- signal_toTransfer = createStatusLabel();
- signal_transferToDevice = createStatusLabel();
-
- List<JLabel> statusLabels = new ArrayList<>();
- statusLabels.add(signal_feeding);
- statusLabels.add(signal_blanking);
- statusLabels.add(signal_running);
- statusLabels.add(signal_deviceStatus);
- statusLabels.add(signal_allowFeeding);
- statusLabels.add(signal_allowBlanking);
- statusLabels.add(signal_heart);
- statusLabels.add(signal_toDevice);
- if (MesClient.transferEnabled) {
- statusLabels.add(signal_toTransfer);
- statusLabels.add(signal_transferToDevice);
- }
-
- // 添加信号行
- for (int i = 0; i < signalList.size(); i++) {
- String[] signals = signalList.get(i);
- panel.add(new JLabel(signals[0], SwingConstants.CENTER));
- panel.add(new JLabel(signals[1], SwingConstants.CENTER));
- panel.add(new JLabel(signals[2], SwingConstants.CENTER));
- panel.add(statusLabels.get(i));
- }
-
- return panel;
- }
-
- /**
- * 创建表头标签
- */
- private JLabel createHeaderLabel(String text) {
- JLabel label = new JLabel(text, SwingConstants.CENTER);
- label.setFont(new Font("微软雅黑", Font.BOLD, 12));
- return label;
- }
-
- /**
- * 创建状态标签
- */
- private JLabel createStatusLabel() {
- JLabel label = new JLabel("--", SwingConstants.CENTER);
- label.setOpaque(true);
- label.setBackground(Color.LIGHT_GRAY);
- label.setFont(new Font("微软雅黑", Font.PLAIN, 11));
- return label;
- }
-
- /**
- * 更新信号显示
- */
- private void updateSignalDisplay() {
- try {
- if (s7PLC == null) {
- log.warn("[{}] PLC连接为空,无法读取信号", stationName);
- showConnectionError();
- return;
- }
-
- // 读取所有信号
- boolean feeding = s7PLC.readBoolean(plcDb + ".0.0");
- boolean blanking = s7PLC.readBoolean(plcDb + ".0.1");
- boolean running = s7PLC.readBoolean(plcDb + ".0.2");
- boolean deviceStatus = s7PLC.readBoolean(plcDb + ".0.3");
- boolean allowFeeding = s7PLC.readBoolean(plcDb + ".0.4");
- boolean allowBlanking = s7PLC.readBoolean(plcDb + ".0.5");
- boolean heart = s7PLC.readBoolean(plcDb + ".0.6");
- boolean toDevice = s7PLC.readBoolean(plcDb + ".0.7");
- boolean toTransfer = MesClient.transferEnabled && s7PLC.readBoolean(plcDb + ".1.0");
- boolean transferToDevice = MesClient.transferEnabled && s7PLC.readBoolean(plcDb + ".1.1");
-
- // 在EDT线程中更新UI
- SwingUtilities.invokeLater(() -> {
- updateStatusLabel(signal_feeding, feeding);
- updateStatusLabel(signal_blanking, blanking);
- updateStatusLabel(signal_running, running);
- updateStatusLabel(signal_deviceStatus, deviceStatus);
- updateStatusLabel(signal_allowFeeding, allowFeeding);
- updateStatusLabel(signal_allowBlanking, allowBlanking);
- updateStatusLabel(signal_heart, heart);
- updateStatusLabel(signal_toDevice, toDevice);
- if (MesClient.transferEnabled) {
- updateStatusLabel(signal_toTransfer, toTransfer);
- updateStatusLabel(signal_transferToDevice, transferToDevice);
- }
- });
-
- } catch (Exception e) {
- String errorMsg = e.getMessage();
- if (errorMsg != null && errorMsg.contains("connect timed out")) {
- log.warn("[{}] PLC连接超时,请检查网络连接", stationName);
- } else {
- log.error("[{}] 读取PLC信号异常: {}", stationName, errorMsg);
- }
- // 在UI上显示错误提示
- SwingUtilities.invokeLater(this::showConnectionError);
- }
- }
-
- /**
- * 显示连接错误提示
- */
- private void showConnectionError() {
- JLabel[] labels = {
- signal_feeding, signal_blanking, signal_running, signal_deviceStatus,
- signal_allowFeeding, signal_allowBlanking, signal_heart,
- signal_toDevice, signal_toTransfer, signal_transferToDevice
- };
-
- for (JLabel label : labels) {
- if (label != null && label.getParent() != null) {
- label.setText("ERR");
- label.setBackground(Color.ORANGE);
- label.setForeground(Color.WHITE);
- }
- }
- }
-
- /**
- * 更新状态标签
- */
- private void updateStatusLabel(JLabel label, boolean active) {
- if (label != null) {
- if (active) {
- label.setText("1");
- label.setBackground(new Color(0, 200, 0));
- label.setForeground(Color.WHITE);
- } else {
- label.setText("0");
- label.setBackground(new Color(200, 200, 200));
- label.setForeground(Color.DARK_GRAY);
- }
- }
- }
- }
|