Implement diagnostics code reading via SSM and results display panel.

This commit is contained in:
Dale Schultz 2013-06-01 16:35:05 -04:00
parent d8281aec8a
commit 841ba982ee
8 changed files with 536 additions and 59 deletions

View File

@ -1439,10 +1439,23 @@ public final class EcuLogger extends AbstractFrame implements MessageListener {
return resetManager.resetEcu();
}
public boolean readEcuCodes() {
public final boolean getDtcodesEmpty() {
LOGGER.info("DT codes defined: " + !dtcodes.isEmpty() +
", definition version: " + defVersion);
return dtcodes.isEmpty();
}
public final boolean isEcuInit() {
if (ecuInit == null) {
LOGGER.info("DT codes ECU Initialized: false");
return false;
}
return true;
}
public final int readEcuCodes() {
final ReadCodesManager readCodesManager =
new ReadCodesManagerImpl(
settings,
this,
dtcodes,
ecuInit.getEcuInitBytes().length);

View File

@ -1,6 +1,6 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2012 RomRaider.com
* Copyright (C) 2006-2013 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,6 +19,7 @@
package com.romraider.logger.ecu.comms.readcodes;
public interface ReadCodesManager {
boolean readCodes();
int readCodes();
}

View File

@ -1,6 +1,6 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2012 RomRaider.com
* Copyright (C) 2006-2013 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,78 +19,123 @@
package com.romraider.logger.ecu.comms.readcodes;
import static com.romraider.logger.ecu.comms.io.connection.LoggerConnectionFactory.getConnection;
import static com.romraider.util.ParamChecker.checkNotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.Logger;
import com.romraider.Settings;
import com.romraider.logger.ecu.EcuLogger;
import com.romraider.logger.ecu.comms.io.connection.LoggerConnection;
import com.romraider.logger.ecu.comms.manager.PollingStateImpl;
import com.romraider.logger.ecu.comms.query.EcuQuery;
import com.romraider.logger.ecu.comms.query.EcuQueryImpl;
import com.romraider.logger.ecu.definition.EcuData;
import com.romraider.logger.ecu.definition.EcuSwitch;
import static com.romraider.logger.ecu.comms.io.connection.LoggerConnectionFactory.getConnection;
import com.romraider.logger.ecu.ui.MessageListener;
import com.romraider.util.HexUtil;
import static com.romraider.util.ParamChecker.checkNotNull;
import org.apache.log4j.Logger;
import com.romraider.logger.ecu.ui.swing.tools.ReadCodesResultsPanel;
public final class ReadCodesManagerImpl implements ReadCodesManager {
private static final Logger LOGGER = Logger.getLogger(ReadCodesManagerImpl.class);
private final Settings settings;
private static final Logger LOGGER =
Logger.getLogger(ReadCodesManagerImpl.class);
private final MessageListener messageListener;
private final EcuLogger logger;
private final List<EcuSwitch> dtcodes;
private final int ecuInitLength;
public ReadCodesManagerImpl(Settings settings,
MessageListener messageListener,
List<EcuSwitch> dtcodes,
int ecuInitLength) {
checkNotNull(settings, messageListener);
this.settings = settings;
this.messageListener = messageListener;
public ReadCodesManagerImpl(EcuLogger logger,
List<EcuSwitch> dtcodes,
int ecuInitLength) {
checkNotNull(logger, dtcodes);
this.logger = logger;
this.messageListener = (MessageListener) logger;
this.dtcodes = dtcodes;
this.ecuInitLength = ecuInitLength;
}
public boolean readCodes() {
String target = "ECU";
public final int readCodes() {
final ArrayList<EcuQuery> queries = new ArrayList<EcuQuery>();
String lastCode = dtcodes.get(dtcodes.size() - 1).getId();
if (ecuInitLength < 104) {
lastCode = "D168";
lastCode = "D488";
}
else if (ecuInitLength < 56) {
lastCode = "D256";
}
LOGGER.debug("ECU init length:" + ecuInitLength + " Last code:" + lastCode);
LOGGER.debug(
"DT codes ECU init length: " + ecuInitLength +
", Last code: " + lastCode);
for (int i = 0; !dtcodes.get(i).getId().equals(lastCode); i++) {
queries.add(new EcuQueryImpl((EcuData) dtcodes.get(i)));
LOGGER.debug("Adding DTC:" + dtcodes.get(i).getName());
LOGGER.debug("Adding query for DTC: " + dtcodes.get(i).getName());
}
String target = "ECU";
try {
LoggerConnection connection = getConnection(Settings.getLoggerProtocol(), settings.getLoggerPort(),
settings.getLoggerConnectionProperties());
final LoggerConnection connection = getConnection(
Settings.getLoggerProtocol(),
logger.getSettings().getLoggerPort(),
logger.getSettings().getLoggerConnectionProperties());
try {
if (Settings.getDestinationId() == 0x18) target = "TCU";
messageListener.reportMessage("Sending " + target + " Read codes...");
connection.sendAddressReads((Collection<EcuQuery>)queries, Settings.getDestinationId(),
new PollingStateImpl());
messageListener.reportMessage("Sending " + target + " Read codes...complete.");
for (EcuQuery query : queries) {
LOGGER.info(query.getLoggerData().getName() + " result:" + query.getResponse());
messageListener.reportMessage(
"Reading " + target + " DTC codes...");
final Collection<EcuQuery> querySet = new ArrayList<EcuQuery>();
for (int i = 0; i < queries.size(); i += 150) {
for (int j = i; (j < i + 150) && (j < queries.size()); j++) {
querySet.add(queries.get(j));
}
connection.sendAddressReads(
querySet,
Settings.getDestinationId(),
new PollingStateImpl());
querySet.clear();
}
return true;
} finally {
messageListener.reportMessage(
"Reading " + target + " DTC codes...complete.");
double result = 0;
final ArrayList<EcuQuery> dtcSet = new ArrayList<EcuQuery>();
for (EcuQuery query : queries) {
result = query.getResponse();
if (!(result == -1 || result == 0)) {
int tmp = 0;
int mem = 0;
if (result == 1 || result == 3) tmp = 1;
if (result == 2 || result == 3) mem = 1;
LOGGER.debug("DTC: " +
query.getLoggerData().getName() +
" tmp:" + tmp + " mem:" + mem);
dtcSet.add(query);
}
}
if (dtcSet.isEmpty()) {
LOGGER.info("Success reading " + target +
" DTC codes, none set");
return -1;
}
else {
ReadCodesResultsPanel.displayResultsPane(logger, dtcSet);
}
return 1;
}
finally {
connection.close();
}
} catch (Exception e) {
messageListener.reportMessage("Unable to read " + target + " codes - check correct serial port has been selected, cable is connected and ignition is on.");
LOGGER.error("Error reading " + target + " codes", e);
return false;
}
catch (Exception e) {
messageListener.reportMessage(
"Unable to read " + target + " DTC " +
" codes - check correct serial port has been selected," +
" cable is connected and ignition is on.");
LOGGER.error("Error reading " + target + " DTC codes", e);
return 0;
}
}
}

View File

@ -0,0 +1,70 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2013 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.romraider.logger.ecu.definition;
import static com.romraider.util.ParamChecker.checkBit;
import com.romraider.logger.ecu.ui.handler.dash.GaugeMinMax;
public final class EcuDtcConvertorImpl implements EcuDataConvertor {
private static final GaugeMinMax GAUGE_MIN_MAX = new GaugeMinMax(0.0, 1.0, 1.0);
private static final String FORMAT = "0";
private final int bit;
public EcuDtcConvertorImpl(int bit) {
checkBit(bit);
this.bit = bit;
}
public double convert(byte[] bytes) {
final byte allOnes = (byte) 0xff;
double result = 0;
if (bytes[0] == allOnes && bytes[1] == allOnes) {
result = -1;
}
else {
if ((bytes[0] & (1 << bit)) > 0) result++;
if ((bytes[1] & (1 << bit)) > 0) result+=2;
}
return result;
}
public String getUnits() {
return "On/Off";
}
public GaugeMinMax getGaugeMinMax() {
return GAUGE_MIN_MAX;
}
public String getFormat() {
return FORMAT;
}
public String format(double value) {
//return value > 0 ? "On" : "Off";
return value > 0 ? "1" : "0";
}
public String toString() {
return getUnits();
}
}

View File

@ -47,6 +47,7 @@ import com.romraider.logger.ecu.definition.EcuDataConvertor;
import com.romraider.logger.ecu.definition.EcuDerivedParameterConvertor;
import com.romraider.logger.ecu.definition.EcuDerivedParameterConvertorImpl;
import com.romraider.logger.ecu.definition.EcuDerivedParameterImpl;
import com.romraider.logger.ecu.definition.EcuDtcConvertorImpl;
import com.romraider.logger.ecu.definition.EcuParameter;
import com.romraider.logger.ecu.definition.EcuParameterConvertorImpl;
import com.romraider.logger.ecu.definition.EcuParameterImpl;
@ -305,7 +306,7 @@ public final class LoggerDefinitionHandler extends DefaultHandler {
}
}
} else if (TAG_DTCODE.equals(qName)) {
final EcuDataConvertor[] convertors = new EcuDataConvertor[]{new EcuSwitchConvertorImpl(address.getBit())};
final EcuDataConvertor[] convertors = new EcuDataConvertor[]{new EcuDtcConvertorImpl(address.getBit())};
final EcuSwitch ecuSwitch = new EcuSwitchImpl(id, name, desc, address, convertors);
dtcodes.add(ecuSwitch);
ecuDataMap.put(ecuSwitch.getId(), ecuSwitch);

View File

@ -1,6 +1,6 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2012 RomRaider.com
* Copyright (C) 2006-2013 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,6 +19,7 @@
package com.romraider.logger.ecu.ui.swing.menubar.action;
import static com.romraider.Version.MIN_LOG_DEF_VERSION;
import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
import static javax.swing.JOptionPane.OK_OPTION;
@ -37,35 +38,74 @@ public final class ReadEcuCodesAction extends AbstractAction {
super(logger);
}
public void actionPerformed(ActionEvent actionEvent) {
if (showConfirmation() == OK_OPTION) {
boolean logging = logger.isLogging();
if (logging) logger.stopLogging();
readEcu();
// if (logging) logger.startLogging();
public final void actionPerformed(ActionEvent actionEvent) {
if (logger.getDtcodesEmpty()) {
final String wrongDefVersion = "To read diagnostic codes the " +
"Logger requires a logger definfition XML file of\n" +
"version " + MIN_LOG_DEF_VERSION + " or higher. " +
"Use the Help menu 'Update Logger Definition' item to\n" +
"go online and donwload the latest logger definition.\n";
showMessageDialog(logger,
wrongDefVersion,
"Definition Error", ERROR_MESSAGE);
}
else if (!logger.isEcuInit()) {
final String notInit = "To read diagnostic codes the " +
"Logger must first intialize with the\n" +
logger.getTarget() +
". Press the Restart button to connect with the Logger then\n" +
"try reading the codes again.\n";
showMessageDialog(logger,
notInit,
"Not Initialized", ERROR_MESSAGE);
}
else {
final boolean logging = logger.isLogging();
if (showConfirmation() == OK_OPTION) {
if (logging) logger.stopLogging();
readEcu();
if (logging) logger.startLogging();
}
}
}
private int showConfirmation() {
return showConfirmDialog(logger, "Do you want to read the " + logger.getTarget() + "codes?", "Read " + logger.getTarget(), YES_NO_OPTION, WARNING_MESSAGE);
private final int showConfirmation() {
return showConfirmDialog(
logger,
"Do you want to read the " + logger.getTarget() +
" diagnostic codes?",
"Read " + logger.getTarget() + " diagnostic codes",
YES_NO_OPTION, WARNING_MESSAGE);
}
private void readEcu() {
if (doRead()) {
showMessageDialog(logger, "Read Successful!",
"Reset " + logger.getTarget(), INFORMATION_MESSAGE);
} else {
showMessageDialog(logger, "Error reading " + logger.getTarget() + " codes.\nCheck the following:\n* Correct COM port selected\n" +
"* Cable is connected properly\n* Ignition is ON\n* Logger is stopped", "Read " + logger.getTarget(), ERROR_MESSAGE);
private final void readEcu() {
final int result = doRead();
if (result == -1) {
showMessageDialog(
logger,
"No diagnostic codes set.", "Read Success",
INFORMATION_MESSAGE);
}
else if (result == 0) {
showMessageDialog(
logger,
"Error reading " + logger.getTarget() + " diagnostic codes.\n" +
"Check the following:\n" +
"* Logger has successfully conencted to the ECU\n" +
"* Correct COM port is selected (if not Openport 2)\n" +
"* Cable is connected properly\n* Ignition is ON\n* " +
"Logger is stopped",
"Error Read " + logger.getTarget(), ERROR_MESSAGE);
}
}
private boolean doRead() {
private int doRead() {
try {
return logger.readEcuCodes();
} catch (Exception e) {
logger.reportError("Error performing " + logger.getTarget() + " read", e);
return false;
logger.reportError(
"Error performing " + logger.getTarget() + " codes read", e);
return 0;
}
}
}

View File

@ -0,0 +1,224 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2013 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.romraider.logger.ecu.ui.swing.tools;
import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
import static javax.swing.JOptionPane.showMessageDialog;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import com.romraider.Settings;
import com.romraider.logger.ecu.EcuLogger;
import com.romraider.logger.ecu.comms.query.EcuQuery;
public final class ReadCodesResultsPanel extends JPanel {
private static final long serialVersionUID = -3180488605471088911L;
private static final JPanel resultsPanel = new JPanel();
private static final String DT_FORMAT = "%1$tY%1$tm%1$td-%1$tH%1$tM%1$tS";
private ReadCodesResultsPanel(ArrayList<EcuQuery> dtcSet) {
super(new GridLayout(1,0));
final ReadCodesTableModel dtcModel = new ReadCodesTableModel();
dtcModel.setDtcList(dtcSet);
final JTable table = new JTable(dtcModel);
TableColumn column = null;
for (int i = 0; i < table.getColumnCount(); i++) {
column = table.getColumnModel().getColumn(i);
if (i == 0) {
column.setPreferredWidth(360);
} else {
column.setPreferredWidth(80);
}
}
table.setAutoCreateRowSorter(true);
table.getRowSorter().toggleSortOrder(0);
table.setColumnSelectionAllowed(false);
table.setRowSelectionAllowed(true);
table.getTableHeader().setReorderingAllowed(false);
resultsPanel.setLayout(new BorderLayout());
final JTableHeader th = table.getTableHeader();
final Font thFont = th.getFont();
final Font thBoldFont = new Font(
thFont.getFamily(),
Font.BOLD,
thFont.getSize());
th.setFont(thBoldFont);
resultsPanel.add(th, BorderLayout.PAGE_START);
resultsPanel.add(table, BorderLayout.CENTER);
add(resultsPanel);
}
public final static void displayResultsPane(
EcuLogger logger,
ArrayList<EcuQuery> dtcSet) {
final JDialog frame = new JDialog(logger, "Diagnostic Code Read Results");
frame.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
final JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
mainPanel.setOpaque(true);
final ReadCodesResultsPanel resultsPane =
new ReadCodesResultsPanel(dtcSet);
mainPanel.add(resultsPane);
mainPanel.add(createSaveReultsPanel(dtcSet));
frame.setContentPane(mainPanel);
final Point loggerLocation = logger.getLocation();
final Point dialogLocation = new Point();
dialogLocation.setLocation(
loggerLocation.getX() + 30,
loggerLocation.getY() + 90);
frame.setLocation(dialogLocation);
frame.setIconImage(logger.getIconImage());
frame.pack();
frame.setVisible(true);
}
private final static JPanel createSaveReultsPanel(
final ArrayList<EcuQuery> dtcSet) {
final JPanel basePanel = new JPanel(new BorderLayout());
basePanel.setBorder(BorderFactory.createTitledBorder("Save Results"));
final JLabel comment = new JLabel();
comment.setText("Click table, press Ctrl-A then Ctrl-C to copy " +
"table to clipboard, or...");
final JPanel controlPanel = new JPanel();
final JButton toFile = new JButton("Save to File");
toFile.setToolTipText("Save table to a text file");
toFile.setMnemonic(KeyEvent.VK_F);
toFile.addActionListener(new ActionListener() {
@Override
public final void actionPerformed(ActionEvent actionEvent) {
saveTableText(dtcSet);
}
});
final JButton toImage = new JButton("Save as Image");
toImage.setToolTipText("Save table as an image");
toImage.setMnemonic(KeyEvent.VK_I);
toImage.addActionListener(new ActionListener() {
@Override
public final void actionPerformed(ActionEvent actionEvent) {
saveTableImage();
}
});
controlPanel.add(toFile);
controlPanel.add(toImage);
basePanel.add(comment, BorderLayout.CENTER);
basePanel.add(controlPanel, BorderLayout.SOUTH);
return basePanel;
}
private static final void saveTableText(ArrayList<EcuQuery> dtcSet) {
final String nowStr = String.format(DT_FORMAT, System.currentTimeMillis());
final String fileName = String.format("%s%sromraiderDTC_%s.csv",
Settings.getLoggerOutputDirPath(),
File.separator,
nowStr);
try {
final File csvFile = new File(fileName);
final String eol = System.getProperty("line.separator");
final BufferedWriter bw = new BufferedWriter(
new FileWriter(csvFile));
bw.write("Diagnostic Code Name,Temporary,Memorized" + eol);
double result = 0;
for (EcuQuery query : dtcSet) {
result = query.getResponse();
String tmp = "false";
String mem = "false";
if (result == 1 || result == 3) tmp = "true";
if (result == 2 || result == 3) mem = "true";
bw.append(query.getLoggerData().getName() + "," +
tmp + "," +
mem + eol);
}
bw.close();
showMessageDialog(
null,
"Table text saved to: " + fileName,
"Save Success",
INFORMATION_MESSAGE);
}
catch (Exception e) {
showMessageDialog(
null,
"Failed to save table, check path:\n" + fileName,
"Save Failed",
ERROR_MESSAGE);
}
}
private static final void saveTableImage() {
final BufferedImage resultsImage = new BufferedImage(
resultsPanel.getWidth(),
resultsPanel.getHeight(),
BufferedImage.TYPE_INT_ARGB);
resultsPanel.paint(resultsImage.createGraphics());
final String nowStr = String.format(DT_FORMAT, System.currentTimeMillis());
final String fileName = String.format("%s%sromraiderDTC_%s.png",
Settings.getLoggerOutputDirPath(),
File.separator,
nowStr);
try {
final File imageFile = new File(fileName);
ImageIO.write(
resultsImage,
"png",
imageFile);
showMessageDialog(
null,
"Table image saved to: " + fileName,
"Save Success",
INFORMATION_MESSAGE);
}
catch (Exception e) {
showMessageDialog(
null,
"Failed to save image, check path:\n" + fileName,
"Save Failed",
ERROR_MESSAGE);
}
}
}

View File

@ -0,0 +1,83 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2013 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.romraider.logger.ecu.ui.swing.tools;
import java.util.ArrayList;
import javax.swing.table.DefaultTableModel;
import com.romraider.logger.ecu.comms.query.EcuQuery;
public final class ReadCodesTableModel extends DefaultTableModel {
private static final long serialVersionUID = -4229633011594395331L;
private ArrayList<EcuQuery> dtcSet;
public final int getColumnCount() {
return 3;
}
public final String getColumnName(int column) {
switch (column) {
case 0: return "Diagnostic Code Name";
case 1: return "Temporary";
case 2: return "Memorized";
default: return "";
}
}
public final Object getValueAt(int row, int column) {
if (dtcSet != null) {
final double result = dtcSet.get(row).getResponse();
switch (column) {
case 0:
return " " + dtcSet.get(row).getLoggerData().getName();
case 1:
return (result == 1 || result == 3)
? new Boolean(true)
: new Boolean(false);
case 2:
return (result == 2 || result == 3)
? new Boolean(true)
: new Boolean(false);
default:
return null;
}
}
else {
return null;
}
}
public final int getRowCount() {
return (dtcSet != null) ? dtcSet.size() : 0;
}
public final Class<? extends Object> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
public final boolean isCellEditable(int row, int column) {
return false;
}
public final void setDtcList(ArrayList<EcuQuery> dtcSet) {
this.dtcSet = dtcSet;
}
}