use of com.fr3ts0n.ecu.EcuDataPv in project AndrOBD by fr3ts0n.
the class CanProt 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
*/
@SuppressWarnings("rawtypes")
@Override
public int handleTelegram(char[] buffer) {
int retValue = 0;
try {
Integer msgId = (Integer) getParamValue(ID_CAN_SVC, buffer);
Vector params = canMsgMap.get(msgId);
if (params != null) {
Iterator it = params.iterator();
while (it.hasNext()) {
Integer parId = (Integer) it.next();
float value = getMsgValue(parId.intValue(), buffer);
EcuDataPv pv = (EcuDataPv) CanPvs.get(parId);
if (pv != null) {
// now store all changes to PV
pv.put(EcuDataPv.FIELDS[EcuDataPv.FID_VALUE], new Float(value));
}
}
retValue = params.size();
}
} catch (Exception e) {
log.log(Level.SEVERE, e.toString(), e);
}
return retValue;
}
use of com.fr3ts0n.ecu.EcuDataPv 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.EcuDataPv 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.EcuDataPv in project AndrOBD by fr3ts0n.
the class ObdItemTableRenderer method getTableCellRendererComponent.
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
String fmtText = null;
// if we don't know the parent table yet, set visual parameters
if (parentTable == null)
setParentTable(table);
// background is dependent on selection status
setBackground(isSelected ? selColor : bgColor);
// if row is valid ...
if (value != null) {
// get column value
Object colVal = ((EcuDataPv) value).get(column);
if (colVal != null) {
try {
// formatting is based on column ...
switch(column) {
case EcuDataPv.FID_PID:
setHorizontalAlignment(RIGHT);
fmtText = String.format("%02X", colVal);
break;
case EcuDataPv.FID_OFS:
setHorizontalAlignment(RIGHT);
fmtText = String.valueOf(colVal);
break;
case EcuDataPv.FID_VALUE:
case EcuDataPv.FID_UNITS:
EcuDataPv currPv = (EcuDataPv) value;
Object cnvObj = currPv.get(EcuDataPv.FID_CNVID);
if (cnvObj != null && cnvObj instanceof Conversion[] && ((Conversion[]) cnvObj)[EcuDataItem.cnvSystem] != null) {
Conversion cnv;
cnv = ((Conversion[]) cnvObj)[EcuDataItem.cnvSystem];
if (column == EcuDataPv.FID_VALUE) {
setHorizontalAlignment(RIGHT);
// formated data
fmtText = cnv.physToPhysFmtString((Number) colVal, (String) currPv.get(EcuDataPv.FID_FORMAT));
} else {
setHorizontalAlignment(LEFT);
// formated units
fmtText = cnv.getUnits();
}
} else {
fmtText = String.valueOf(colVal);
}
break;
default:
setHorizontalAlignment(LEFT);
fmtText = String.valueOf(colVal);
break;
}
} catch (Exception ex) {
fmtText = String.valueOf(colVal);
}
}
}
setText(fmtText);
return this;
}
use of com.fr3ts0n.ecu.EcuDataPv in project AndrOBD by fr3ts0n.
the class ObdGaugeAdapter method getView.
/* (non-Javadoc)
* @see android.widget.ArrayAdapter#getView(int, android.view.View, android.view.ViewGroup)
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
EcuDataPv currPv = getItem(position);
int pid = currPv.getAsInt(EcuDataPv.FID_PID);
// if no recycled convertView delivered, then create a new one
if (convertView == null) {
convertView = mInflater.inflate(resourceId, parent, false);
holder = new ViewHolder();
// get all views into view holder
holder.gauge = (FrameLayout) convertView.findViewById(R.id.gauge);
holder.tvDescr = (TextView) convertView.findViewById(R.id.label);
// remember this view holder
convertView.setTag(holder);
} else {
// recall previous holder
holder = (ViewHolder) convertView.getTag();
}
convertView.getLayoutParams().width = minWidth;
convertView.getLayoutParams().height = minHeight;
// if no rendering component is registered with PV, then create and register new one
DialChart chartView = (DialChart) currPv.getRenderingComponent();
if (chartView == null) {
CategorySeries category = (CategorySeries) currPv.get(FID_GAUGE_SERIES);
Number minValue = (Number) currPv.get(EcuDataPv.FID_MIN);
Number maxValue = (Number) currPv.get(EcuDataPv.FID_MAX);
if (minValue == null)
minValue = 0f;
if (maxValue == null)
maxValue = 255f;
DialRenderer renderer = new DialRenderer();
renderer.setScale(1.25f);
// dial background
renderer.setPanEnabled(false);
renderer.setShowLegend(false);
renderer.setShowLabels(true);
renderer.setLabelsTextSize(mDisplayMetrics.densityDpi / 10);
renderer.setLabelsColor(Color.WHITE);
renderer.setShowLabels(true);
renderer.setVisualTypes(new DialRenderer.Type[] { DialRenderer.Type.NEEDLE });
renderer.setMinValue(minValue.doubleValue());
renderer.setMaxValue(maxValue.doubleValue());
renderer.setChartTitle(currPv.getUnits());
renderer.setChartTitleTextSize(mDisplayMetrics.densityDpi / 10);
SimpleSeriesRenderer r = new SimpleSeriesRenderer();
r.setColor(ChartActivity.getItemColor(pid));
try {
r.setChartValuesFormat(labelFormat);
} catch (Exception e) {
// ignore
}
renderer.addSeriesRenderer(0, r);
// create chart view and register with PV
chartView = new DialChart(category, renderer);
currPv.setRenderingComponent(chartView);
}
convertView.setBackgroundColor(ChartActivity.getItemColor(pid) & 0x08FFFFFF);
// set new values for display
holder.tvDescr.setTextColor(ChartActivity.getItemColor(pid));
holder.tvDescr.setText(String.valueOf(currPv.get(EcuDataPv.FID_DESCRIPT)));
// replace DialChart if needed
holder.gauge.removeViewAt(0);
holder.gauge.addView(new GraphicalView(getContext(), chartView), 0);
return convertView;
}
Aggregations