use of com.fr3ts0n.ecu.EcuDataItem in project AndrOBD by fr3ts0n.
the class Kw1281Prot method initialize.
/**
* Initialize protocol
*/
public void initialize() {
// init
VidPvs.clear();
PidPvs.clear();
// init TC list with "NO codes set"
tCodes.clear();
tCodes.put(Integer.valueOf(0), knownCodes.get(Integer.valueOf(0)));
setNumCodes(0);
// initialize map of known data items
knownGrpItems.clear();
for (int i = 0; i <= 0xFF; i++) {
knownGrpItems.put(Integer.valueOf(i), new Vector<EcuDataItem>());
}
currDataGroup = selectedDataGroup = 0;
currGrpItems = knownGrpItems.get(Integer.valueOf(currDataGroup));
// notify about property change
firePropertyChange(new PropertyChangeEvent(this, "preset", null, knownGrpItems));
}
use of com.fr3ts0n.ecu.EcuDataItem in project AndrOBD by fr3ts0n.
the class Kw1281Prot method loadPreset.
/**
* load preset data
*/
protected void loadPreset() {
Thread loadThd = new Thread() {
@Override
public void run() {
EcuDataPv vid = (EcuDataPv) VidPvs.get(0);
String fileName = vid.get(EcuDataPv.FID_VALUE).toString().trim() + ".prs";
if (fileName.equals(lastPresetName)) {
log.info("Preset already loaded:" + fileName);
} else {
log.info("Load Preset: " + fileName);
try {
BufferedReader rdr = new BufferedReader(new FileReader(fileName));
knownGrpItems.clear();
PidPvs.clear();
while (rdr.ready()) {
String line = rdr.readLine();
// forget about empty, or remarked lines
if (line.trim().length() == 0 || line.startsWith("#") || line.startsWith("//"))
continue;
String[] params = line.split("\t");
Integer frmNum = Integer.valueOf(params[0], 0x10);
// List of all Items within group
Vector<EcuDataItem> grpVec = new Vector<EcuDataItem>();
// loop through all items for this group
for (int i = 1; i < params.length && params[i].length() > 0; i++) {
Vector<EcuDataItem> currVec = itms.getPidDataItems(ID_GRPINFO_DATA, Integer.parseInt(params[i], 0x10));
// add all items in list to corresponding group vector
Iterator<EcuDataItem> it = currVec.iterator();
while (it.hasNext()) {
EcuDataItem itm = (EcuDataItem) it.next().clone();
itm.pid = frmNum;
itm.ofs = i - 1;
itm.pv.put(EcuDataPv.FID_PID, Integer.valueOf(itm.pid));
itm.pv.put(EcuDataPv.FID_OFS, Integer.valueOf(itm.ofs));
grpVec.add(itm);
}
}
// make items known items
knownGrpItems.put(frmNum, grpVec);
}
log.info("Preset loaded: " + fileName);
// notify about property change
firePropertyChange(new PropertyChangeEvent(this, "preset", lastPresetName, fileName));
// remember name of preset
lastPresetName = fileName;
rdr.close();
} catch (IOException ex) {
log.warning("LoadPreset: " + ex.toString());
}
}
}
};
// MIN priority to NOT disturb communication
loadThd.setPriority(Thread.MIN_PRIORITY);
loadThd.start();
}
use of com.fr3ts0n.ecu.EcuDataItem in project AndrOBD by fr3ts0n.
the class Kw1281Prot method showGroupItems.
/**
* show all data items of selected group
* * if there are other items shown, it does not hide them.
*
* @param groupNum
*/
void showGroupItems(int groupNum) {
// get items of goup
Vector<EcuDataItem> grpItms = knownGrpItems.get(groupNum);
if (grpItms != null) {
// loop through items in group
Iterator<EcuDataItem> itItm = grpItms.iterator();
while (itItm.hasNext()) {
EcuDataItem itm = itItm.next();
PidPvs.put(itm.pv.toString(), itm.pv);
}
}
}
use of com.fr3ts0n.ecu.EcuDataItem in project AndrOBD by fr3ts0n.
the class Kw1281Prot method handleTelegram.
/**
* handle incoming protocol telegram
* default implementaion only checks telegram and notifies listeners with
* protocol payload
*
* @param buffer - telegram buffer
* @return number of listeners notified
*/
@Override
public int handleTelegram(char[] buffer) {
int cnt = 0;
log.fine("RX:" + ProtUtils.hexDumpBuffer(buffer));
// if telegram is OK
if (checkTelegram(buffer)) {
// get command
int cmd = getParamInt(FLD_ID_CMD, buffer);
// update block counter
blockCounter = (char) getParamInt(FLD_ID_BLKCNT, buffer).intValue();
// get payload
char[] payLoad = getPayLoad(buffer);
switch(cmd) {
case ID_GRPINFO_HEAD:
// field number within group
int fldId = 0;
// loop through all data items within telegram
for (int i = 0; i < payLoad.length; ) {
// get data id from group reading
int dId = (int) payLoad[i];
// get the corresponding data items for svc/pid
Vector<EcuDataItem> pidItems = itms.getPidDataItems(ID_GRPINFO_DATA, dId);
// if item was found ...
if (pidItems != null && pidItems.size() > 0) {
EcuDataItem currItm;
// if item already exists
if (currGrpItems.size() > fldId) {
// re-use existing item
currItm = currGrpItems.get(fldId);
} else {
// otherwise clone a new one
currItm = (EcuDataItem) pidItems.get(0).clone();
// set specific values for this item
currItm.pid = (int) getCurrDataGroup();
currItm.ofs += fldId;
currItm.pv.put(EcuDataPv.FID_PID, Integer.valueOf(currItm.pid));
currItm.pv.put(EcuDataPv.FID_OFS, Integer.valueOf(currItm.ofs));
// ensure there are enough elements in list
while (currGrpItems.size() <= fldId) currGrpItems.add(null);
// add item to list of group data items
currGrpItems.set(fldId, currItm);
}
// update metadata
int numTblChrs = payLoad[i + 2];
// if conversion is a VagConversion, we may adjust meta parameters
if (currItm.cnv[0] instanceof VagConversion) {
// set meta parameter for conversion
((VagConversion) currItm.cnv[0]).setMetaNw(payLoad[i + 1]);
// any following table data available?
if (numTblChrs != 0) {
// set table values for conversion
((VagConversion) currItm.cnv[0]).setMetaTblValues(String.valueOf(payLoad, i + 3, numTblChrs).toCharArray());
}
}
// increment byte index to next entry
i += 3 + numTblChrs;
// increment field number
fldId++;
}
}
showGroupItems(getCurrDataGroup());
// now request again to get real data
requestGroupData(getCurrDataGroup());
break;
case ID_GRPINFO_DATA:
if (currGrpItems == null || currGrpItems.size() < BLK_NUM_ITEMS) {
log.severe(String.format("Missing/Incomplete Metadata for GRP:%d", (int) getCurrDataGroup()));
}
{
for (int i = 0; i < Math.min(payLoad.length, currGrpItems.size()); i++) {
EcuDataItem currItm = currGrpItems.get(i);
if (currItm != null) {
// and update corresponding process var
currItm.updatePvFomBuffer(payLoad);
} else {
log.severe(String.format("Data w/o meta GRP:%d, ITM:%d", (int) getCurrDataGroup(), i));
}
}
}
// if we do group reading and desired group has not changed ...
if (service == SVC_READ_DATA_GRP && getCurrDataGroup() == getSelectedDataGroup()) {
// request same group again
requestGroupData(getCurrDataGroup());
} else {
// otherwise close this group by requesting ACK
requestACK();
}
break;
case ID_GRPREAD_DATA:
// loop through all 4 entries of group
for (int i = 0; i < payLoad.length; i += 3) {
// get data it from group reading
int dId = (int) payLoad[i];
// get the corresponding data items for svc/pid
Vector<EcuDataItem> pidItems = itms.getPidDataItems(cmd, dId);
// if item was found ...
if (pidItems != null) {
// loop through all data items for this dId
Iterator<EcuDataItem> it = pidItems.iterator();
while (it.hasNext()) {
EcuDataItem currItm = (EcuDataItem) it.next().clone();
// set specific values for this item
currItm.pid = (int) getCurrDataGroup();
currItm.ofs += i / 3;
currItm.pv.put(EcuDataPv.FID_PID, Integer.valueOf(currItm.pid));
currItm.pv.put(EcuDataPv.FID_OFS, Integer.valueOf(currItm.ofs));
// ensure there are enough elements in list
while (currGrpItems.size() < (i / 3)) currGrpItems.add(null);
// add item to list of group data items
currGrpItems.set(i / 3, currItm);
// and update corresponding process var
currItm.updatePvFomBuffer(Arrays.copyOfRange(payLoad, i + 1, i + 3));
}
} else {
log.warning("Unknown data ID:" + dId);
}
}
// if we do group reading and desired group has not changed ...
if (service == SVC_READ_DATA_GRP && getCurrDataGroup() == getSelectedDataGroup()) {
// request same group again
requestGroupData(getCurrDataGroup());
} else {
// otherwise close this group by requesting ACK
requestACK();
}
break;
case CMD_ACK:
switch(service) {
case SVC_READ_DATA_ALL:
// request next available data group
requestGroupData(getNextDataGroup());
break;
case SVC_READ_DATA_GRP:
// ensure new selection of group is updated
setCurrDataGroup(getSelectedDataGroup());
// request same group again
requestGroupData(getCurrDataGroup());
break;
case SVC_READ_DFCS:
// clear fault code list
tCodes.clear();
setNumCodes(0);
// request failure codes
requestDFCs();
break;
case SVC_CLEAR_DFCS:
// Request clearing DFCs ...
requestClearDFCs();
// ... and continue with Reading DFCc
setService(SVC_READ_DFCS);
break;
case SVC_SHUTDOWN:
requestEndComm();
// now set to Service NONE
setService(SVC_FINISHED);
break;
case SVC_NONE:
default:
requestACK();
break;
}
break;
case ID_NODATA:
log.info(String.format("NODATA: Group:%d -> remove", (int) getCurrDataGroup()));
// since data is not available, remove group from map ...
knownGrpItems.remove(Integer.valueOf(getCurrDataGroup()));
// if we finished the initial turaround, save preset data
if (currDataGroup == 0) {
savePreset();
}
// request ACK
requestACK();
break;
case ID_DFC_DATA:
int nCodes = numCodes;
// loop through all codes reported
for (int i = 0; i < payLoad.length; i += 3) {
// get code number and status
int dfcNum = getParamInt(i, 2, payLoad);
int dfcStat = getParamInt(i + 2, 1, payLoad);
// enter code into code list for visualisation
EcuCodeItem code = knownCodes.get(dfcNum);
// if code is not known ...
if (code == null) {
// create new one and add it to list of known codes
code = new EcuCodeItem(dfcNum, "Unknown Fault code");
}
code.put(EcuCodeItem.FID_STATUS, Integer.valueOf(dfcStat));
tCodes.put(dfcNum, code);
if (dfcNum != 0xFFFF) {
nCodes++;
// set the MIL status based on code status
nCodes |= dfcStat & 0x80;
}
}
// set number of codes
setNumCodes(nCodes);
// finish service since we received corresponding answer
setService(SVC_NONE);
// further DFCs may still come after ACK ...
requestACK();
break;
case ID_ASCII_DATA:
// save vehicle ID data
EcuDataPv pv = new EcuDataPv();
pv.put(EcuDataPv.FID_DESCRIPT, "ID");
pv.put(EcuDataPv.FID_VALUE, String.valueOf(payLoad));
VidPvs.put(VidPvs.size(), pv);
// if this is the first VID dataset, try to load corresponding preset
if (VidPvs.size() == 1)
loadPreset();
// send ACK
requestACK();
break;
default:
requestACK();
break;
}
cnt++;
}
return (cnt);
}
use of com.fr3ts0n.ecu.EcuDataItem in project AndrOBD by fr3ts0n.
the class ObdProt method preparePidPvs.
/**
* prepare process variables for each PID
* @param pvList list of process vars
*/
public void preparePidPvs(int obdService, PvList pvList) {
// reset fixed PIDs
resetFixedPid();
HashMap<String, EcuDataPv> newList = new HashMap<String, EcuDataPv>();
for (Integer currPid : pidSupported) {
Vector<EcuDataItem> items = dataItems.getPidDataItems(obdService, currPid);
// if no items defined, create dummy item
if (items == null) {
log.warning(String.format("unknown PID %02X", currPid));
// create new dummy item / OneToOne conversion
Conversion[] dummyCnvs = { EcuConversions.dfltCnv, EcuConversions.dfltCnv };
EcuDataItem newItem = new EcuDataItem(currPid, 0, 0, 0, 32, 0xFFFFFFFF, dummyCnvs, "%#08x", null, null, String.format("PID %02X", currPid), String.format("PID_%02X", currPid));
dataItems.appendItemToService(obdService, newItem);
// re-load data items for this PID
items = dataItems.getPidDataItems(obdService, currPid);
}
// loop through all items found ...
for (EcuDataItem pidPv : items) {
if (pidPv != null) {
newList.put(pidPv.toString(), pidPv.pv);
}
}
}
pvList.putAll(newList, PvChangeEvent.PV_ADDED, false);
}
Aggregations