001package jmri.jmrix.lenz.swing.systeminfo;
002
003import java.awt.GridLayout;
004import javax.swing.BorderFactory;
005import javax.swing.Box;
006import javax.swing.BoxLayout;
007import javax.swing.JButton;
008import javax.swing.JLabel;
009import javax.swing.JPanel;
010import javax.swing.JToggleButton;
011import jmri.jmrix.lenz.XNetConstants;
012import jmri.jmrix.lenz.XNetListener;
013import jmri.jmrix.lenz.XNetMessage;
014import jmri.jmrix.lenz.XNetReply;
015import jmri.jmrix.lenz.XNetTrafficController;
016import org.slf4j.Logger;
017import org.slf4j.LoggerFactory;
018
019/**
020 * Frame displaying Version information for XpressNet hardware.
021 * <p>
022 * This is a utility for reading the software version and type of the command
023 * station, and, the Hardware and software versions of your XpressNet Computer
024 * Interface.
025 * <p>
026 * Some of this code may be moved to facilitate automatic enabling of features
027 * that are not available on all XpressNet Command Stations (as an example, the
028 * fact that you can't program using the computer on a Commander or Compact)
029 *
030 * @author Paul Bender Copyright (C) 2003-2010
031 * @author Giorgio Terdina Copyright (C) 2007
032 */
033public class SystemInfoFrame extends jmri.util.JmriJFrame implements XNetListener {
034
035    protected XNetTrafficController tc;
036
037    public SystemInfoFrame(jmri.jmrix.lenz.XNetSystemConnectionMemo memo) {
038        super(Bundle.getMessage("MenuItemXNetSystemInformation"));
039        tc = memo.getXNetTrafficController();
040        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
041
042        JPanel infoPane = new JPanel();
043        infoPane.setBorder(BorderFactory.createEtchedBorder());
044        infoPane.setLayout(new GridLayout(6, 2));
045
046        infoPane.add(new JLabel(Bundle.getMessage("CommandStationLabel")));
047        infoPane.add(CSType);
048
049        infoPane.add(new JLabel(Bundle.getMessage("SoftwareVersionLabel")));
050        infoPane.add(CSSoftwareVersion);
051
052        infoPane.add(new JLabel(Bundle.getMessage("MakeLabel", Bundle.getMessage("StatusCol"))));
053        infoPane.add(CSStatus);
054
055        infoPane.add(new JLabel(Bundle.getMessage("InterfaceLabel")));
056        infoPane.add(LIType);
057
058        infoPane.add(new JLabel(Bundle.getMessage("HardwareVersionLabel")));
059        infoPane.add(LIHardwareVersion);
060
061        infoPane.add(new JLabel(Bundle.getMessage("SoftwareVersionLabel")));
062        infoPane.add(LISoftwareVersion);
063
064        getContentPane().add(infoPane);
065        getContentPane().add(Box.createVerticalGlue());
066
067        JPanel buttonPane = new JPanel();
068        buttonPane.add(getSystemInfoButton);
069        buttonPane.add(closeButton);
070        getContentPane().add(buttonPane);
071
072        addHelpMenu("package.jmri.jmrix.lenz.systeminfo.SystemInfoFrame", true);
073
074        // and prep for display
075        pack();
076
077        // initialize the display values with what the LenzCommandStation
078        // class already knows.
079        setCSVersionDisplay();
080
081        // Add Get SystemInfo button handler
082        getSystemInfoButton.addActionListener(a -> getSystemInfo());
083
084        // install close button handler
085        closeButton.addActionListener(a -> {
086            setVisible(false);
087            dispose();
088        });
089
090        if (tc != null) {
091            tc.addXNetListener(~0, this);
092        } else {
093            log.warn("No XpressNet connection, panel won't function");
094        }
095
096    }
097
098    boolean read = false;
099
100    final JLabel CSType = new JLabel("                ");
101    final JLabel CSSoftwareVersion = new JLabel("");
102    final JLabel CSStatus = new JLabel(Bundle.getMessage("BeanStateUnknown"));
103    final JLabel LIType = new JLabel("       ");
104    final JLabel LIHardwareVersion = new JLabel("");
105    final JLabel LISoftwareVersion = new JLabel("");
106
107    final JToggleButton getSystemInfoButton = new JToggleButton(Bundle.getMessage("GetSystemInfoButtonLabel"));
108    final JButton closeButton = new JButton(Bundle.getMessage("ButtonClose"));
109
110    /**
111     * Send Information request to LI100/LI101.
112     */
113    void getSystemInfo() {
114        /* First, we need to send a request for the Command Station
115         hardware and software version */
116        XNetMessage msg = XNetMessage.getCSVersionRequestMessage();
117        //Then send to the controller
118        tc.sendXNetMessage(msg, this);
119        /* Next, get the message to request the Computer Interface
120         Hardware/Software Version */
121        XNetMessage msg2 = XNetMessage.getLIVersionRequestMessage();
122        // Then send it to the controller
123        tc.sendXNetMessage(msg2, this);
124        /* Finally, we send a request for the Command Station Status*/
125        XNetMessage msg3 = XNetMessage.getCSStatusRequestMessage();
126        //Then send to the controller
127        tc.sendXNetMessage(msg3, this);
128    }
129
130    /**
131     * Listen for responses from the LI101.
132     */
133    @Override
134    public void message(XNetReply l) {
135
136        // Check to see if this is a response for the LI version info
137        // or the Command Station Version Info
138        if (l.getElement(0) == XNetConstants.LI_VERSION_RESPONSE) {
139            // This is an Interface response
140            LIHardwareVersion.setText("" + (l.getElementBCD(1).floatValue() / 10));
141            LISoftwareVersion.setText("" + (l.getElementBCD(2)));
142        } else if (l.getElement(0) == XNetConstants.CS_SERVICE_MODE_RESPONSE) {
143            // This is the Command Station Software Version Response
144            if (l.getElement(1) == XNetConstants.CS_SOFTWARE_VERSION) {
145                tc.getCommandStation().setCommandStationSoftwareVersion(l);
146                tc.getCommandStation().setCommandStationType(l);
147                setCSVersionDisplay();
148            }
149        } else if (l.getElement(0) == XNetConstants.CS_REQUEST_RESPONSE) {
150            if (l.getElement(1) == XNetConstants.CS_STATUS_RESPONSE) {
151                int statusByte = l.getElement(2);
152                if ((statusByte & 0x01) == 0x01) {
153                    // Command station is in Emergency Off Mode
154                    CSStatus.setText(Bundle.getMessage("XNetCSStatusEmergencyOff"));
155                } else if ((statusByte & 0x02) == 0x02) {
156                    // Command station is in Emergency Stop Mode
157                    CSStatus.setText(Bundle.getMessage("XNetCSStatusEmergencyStop"));
158                } else if ((statusByte & 0x08) == 0x08) {
159                    // Command station is in Service Mode
160                    CSStatus.setText(Bundle.getMessage("XNetCSStatusServiceMode"));
161                } else if ((statusByte & 0x40) == 0x40) {
162                    // Command station is in Power Up Mode
163                    if ((statusByte & 0x04) == 0x04) {
164                        CSStatus.setText(Bundle.getMessage("XNetCSStatusPoweringUp") + ": "
165                                + Bundle.getMessage("XNetCSStatusPowerModeAuto"));
166                    } else {
167                        CSStatus.setText(Bundle.getMessage("XNetCSStatusPoweringUp") + ": "
168                                + Bundle.getMessage("XNetCSStatusPowerModeManual"));
169                    }
170                } else if ((statusByte & 0x80) == 0x80) {
171                    // Command station has a experienced a ram check error
172                    CSStatus.setText(Bundle.getMessage("XNetCSStatusRamCheck"));
173                } else {
174                    CSStatus.setText(Bundle.getMessage("XNetCSStatusRamNormal"));
175                }
176            }
177        }
178    }
179
180    /**
181     * Listen for the messages to the LI100/LI101.
182     */
183    @Override
184    public void message(XNetMessage l) {
185    }
186
187    /**
188     * Handle a timeout notification.
189     */
190    @Override
191    public void notifyTimeout(XNetMessage msg) {
192        if (log.isDebugEnabled()) {
193            log.debug("Notified of timeout on message{}", msg.toString());
194        }
195    }
196
197    /**
198     * Display the currently known version information from the
199     * LenzCommandStation class.
200     */
201    private void setCSVersionDisplay() {
202        CSSoftwareVersion.setText("" + tc.getCommandStation()
203                .getCommandStationSoftwareVersion());
204        int cs_type = tc.getCommandStation().getCommandStationType();
205        if (cs_type == jmri.jmrix.lenz.XNetConstants.CS_TYPE_LZ100) {
206            CSType.setText(Bundle.getMessage("CSTypeLZ100"));
207        } else if (cs_type == jmri.jmrix.lenz.XNetConstants.CS_TYPE_LH200) {
208            CSType.setText(Bundle.getMessage("CSTypeLH200"));
209        } else if (cs_type == jmri.jmrix.lenz.XNetConstants.CS_TYPE_COMPACT) {
210            CSType.setText(Bundle.getMessage("CSTypeCompact"));
211        } else if (cs_type == jmri.jmrix.lenz.XNetConstants.CS_TYPE_MULTIMAUS) {
212            CSType.setText(Bundle.getMessage("CSTypeMultiMaus"));
213        } else if (cs_type == jmri.jmrix.lenz.XNetConstants.CS_TYPE_Z21) {
214            CSType.setText(Bundle.getMessage("CSTypeZ21"));
215        } else if (cs_type == jmri.jmrix.lenz.XNetConstants.CS_TYPE_LOKMAUSII) {
216            CSType.setText(Bundle.getMessage("CSTypeLokMaus"));
217        } else if (cs_type == jmri.jmrix.lenz.XNetConstants.CS_TYPE_LDH35) {
218            CSType.setText(Bundle.getMessage("CSTypeLDH35"));
219        } else {
220            CSType.setText(Bundle.getMessage("StateUnknown")); // use shared key
221        }
222    }
223
224    private static final Logger log = LoggerFactory.getLogger(SystemInfoFrame.class);
225
226}