/* * (C) Copyright 2015 by fr3ts0n <erwin.scheuch-heilig@gmx.at> * * 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., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package com.fr3ts0n.ecu; import org.apache.log4j.Logger; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; /** * Diagnostic data conversions * * @author erwin */ public class EcuConversions extends HashMap<String, Conversion[]> { /** SerialVersion UID */ private static final long serialVersionUID = 273813879102783740L; /** conversion type IDs from CSV file */ public static final String CNV_TYPE_LINEAR = "LINEAR"; public static final String CNV_TYPE_HASH = "HASH"; public static final String CNV_TYPE_BITMAP = "BITMAP"; public static final String CNV_TYPE_CODELIST = "CODELIST"; public static final String CNV_TYPE_PCODELIST = "PCODELIST"; public static final String CNV_TYPE_VAG = "VAG"; public static final String CNV_TYPE_INT = "INTEGER"; public static final String CNV_TYPE_ASCII = "ASCII"; /** CSV field positions */ static final int FLD_NAME = 0; static final int FLD_TYPE = 1; static final int FLD_VARIANT = 2; static final int FLD_SYSTEM = 3; static final int FLD_FACTOR = 4; static final int FLD_DIVIDER = 5; static final int FLD_OFFSET = 6; static final int FLD_PHOFFSET = 7; static final int FLD_UNITS = 8; static final int FLD_DESCRIPTION = 9; static final int FLD_PARAMETERS = 10; // the data logger static Logger log = Logger.getLogger("data.cnv"); /** DEFAULT type conversion */ public static final NumericConversion dfltCnv = new IntConversion(); /** code list conversion */ public static EcuCodeList codeList = null; /** * Create conversion list from default resource file (tab delimited csv) * (prot/res/conversion.csv) */ public EcuConversions() { // add dynamic entris from csv file(s) this("prot/res/obd/conversions.csv"); } /** * Create conversion list from resource file (tab delimited csv) * * @param resource name of resource to be loaded */ public EcuConversions(String resource) { // add static conversions put("DEFAULT", new Conversion[]{dfltCnv, dfltCnv}); // add dynamic entris from csv file(s) loadFromResource(resource); } public void loadFromStream(InputStream inStr) { BufferedReader rdr; String currLine; String[] params; Conversion[] currCnvSet; Conversion newCnv; int line = 0; try { rdr = new BufferedReader(new InputStreamReader(inStr)); // loop through all lines of the file ... while ((currLine = rdr.readLine()) != null) { // ignore line 1 if (++line == 1) { continue; } // replace all optional quotes from CSV code list currLine = currLine.replaceAll("\"", ""); // split CSV line into parameters params = currLine.split("\t"); if (params[FLD_TYPE].equals(CNV_TYPE_LINEAR)) { // create linear conversion newCnv = new LinearConversion(Integer.parseInt(params[FLD_FACTOR]), Integer.parseInt(params[FLD_DIVIDER]), Integer.parseInt(params[FLD_OFFSET]), Integer.parseInt(params[FLD_PHOFFSET]), params[FLD_UNITS]); } else if (params[FLD_TYPE].equals(CNV_TYPE_HASH)) { // create HashConversion based on CSV data newCnv = new HashConversion( String.valueOf(params[FLD_PARAMETERS]).split(";") ); } else if (params[FLD_TYPE].equals(CNV_TYPE_BITMAP)) { // create BitmapConversion based on CSV parameters newCnv = new BitmapConversion( String.valueOf(params[FLD_PARAMETERS]).split(";") ); } else if (params[FLD_TYPE].equals(CNV_TYPE_CODELIST)) { // create ECU code list based on ResourceBundle codeList = new EcuCodeList( String.valueOf(params[FLD_PARAMETERS])); newCnv = codeList; } else if (params[FLD_TYPE].equals(CNV_TYPE_PCODELIST)) { // create OBD code list based on ResourceBundle codeList = new ObdCodeList( String.valueOf(params[FLD_PARAMETERS])); newCnv = codeList; } else if (params[FLD_TYPE].equals(CNV_TYPE_VAG)) { // create VAG conversion newCnv = new VagConversion(Integer.parseInt(params[FLD_VARIANT]), Double.parseDouble(params[FLD_FACTOR]) / Integer.parseInt(params[FLD_DIVIDER]), Double.parseDouble(params[FLD_OFFSET]), params[FLD_UNITS]); } else if (params[FLD_TYPE].equals(CNV_TYPE_ASCII)) { newCnv = null; } else if (params[FLD_TYPE].equals(CNV_TYPE_INT)) { newCnv = dfltCnv; } else { newCnv = dfltCnv; } // insert fault code element currCnvSet = get(params[FLD_NAME]); // if this conversion does not exist yet ... if (currCnvSet == null) { // create new set for metric and imperial currCnvSet = new Conversion[EcuDataItem.SYSTEM_TYPES]; // and initialize both systems with this data for (int i = 0; i < EcuDataItem.SYSTEM_TYPES; i++) { currCnvSet[i] = newCnv; log.trace("+" + params[FLD_NAME] + "/" + params[FLD_SYSTEM] + " - " + String.valueOf(newCnv)); } } else { // if it is known already, then only update the matching system for (int i = 0; i < EcuDataItem.SYSTEM_TYPES; i++) { if (EcuDataItem.cnvSystems[i].equals(params[FLD_SYSTEM])) { currCnvSet[i] = newCnv; log.trace("+" + params[FLD_NAME] + "/" + params[FLD_SYSTEM] + " - " + newCnv.toString()); } } } // (re-)enter the updated conversion set into map put(params[FLD_NAME], currCnvSet); } rdr.close(); } catch (IOException e) { e.printStackTrace(); } } /** * load conversion list from resource file (tab delimited) * * @param resource name of resource to be loaded */ private void loadFromResource(String resource) { try { loadFromStream(getClass().getResource(resource).openStream()); } catch(IOException ex) { ex.printStackTrace(); } } }