rxjs-obd
Version:
RxJS Implementation for OBD (On Board Diagnostics) of vehicles via ELM 327 connections.
92 lines • 3.27 kB
JavaScript
import { Subscriber } from 'rxjs';
var OBD_OUTPUT_MESSAGE_TYPES;
(function (OBD_OUTPUT_MESSAGE_TYPES) {
OBD_OUTPUT_MESSAGE_TYPES["MODE_01"] = "41";
OBD_OUTPUT_MESSAGE_TYPES["MODE_09"] = "09";
})(OBD_OUTPUT_MESSAGE_TYPES || (OBD_OUTPUT_MESSAGE_TYPES = {}));
const OBD_NO_DATA = 'NO DATA';
const OBD_PROMPT = '>';
export function obdReader() {
return function (source) {
return source.lift(new OBDReaderOperator());
};
}
class OBDReaderOperator {
call(subscriber, source) {
return source.subscribe(new OBDReaderSubscriber(subscriber));
}
}
class OBDReaderSubscriber extends Subscriber {
constructor(destination) {
super(destination);
/**
* Internal buffer of bytes received from OBD.
*/
this.memento = [];
/**
* Internal buffer of the entire output for debug propose.
*/
this.buffer = '';
}
_next(data) {
this.buffer += data;
if (OBDReaderSubscriber.hasPrompt(data)) {
const bytes = this.memento;
if (OBDReaderSubscriber.isOutput(bytes, OBD_OUTPUT_MESSAGE_TYPES.MODE_01)) {
this.destination.next(bytes);
}
else if (bytes && bytes.length && bytes[0] === OBD_NO_DATA) {
this.destination.next(bytes);
}
else if (this.buffer.indexOf(OBD_OUTPUT_MESSAGE_TYPES.MODE_09) === 0) {
this.destination.next([this.buffer]);
}
else {
this.destination.error(`Prompt received without data. Last call ${JSON.stringify(data)} and the entire output was ${this.buffer}`);
}
//clear buffers
this.memento = [];
this.buffer = '';
}
else if (data) {
if (OBD_NO_DATA === data) {
this.memento = [data];
}
else {
const bytes = OBDReaderSubscriber.getByteGroupings(data);
if (OBDReaderSubscriber.isOutput(bytes, OBD_OUTPUT_MESSAGE_TYPES.MODE_01)) {
this.memento = bytes;
}
}
}
}
/**
* Determines if the passed buffer/string has a prompt.
* that indicates it has been completed.
* @param data the returned data.
* @return flag indicating if the data has a prompt.
*/
static hasPrompt(data) {
// Basically, we check that the a newline has started
return data.indexOf(OBD_PROMPT) !== -1;
}
/**
* Determines if the passed buffer is an output of desired mode.
* @param bytes the buffer returned by OBD
* @param mode the desired mode.
* @returns Flag indicating that is a valid result.
*/
static isOutput(bytes, mode) {
return bytes && bytes.length && bytes[0] === mode;
}
/**
* Convert the returned bytes into their pairs if possible, or return null.
* @param str the returned bytes.
* @return the returned bytes into their pairs if possible, or return null.
*/
static getByteGroupings(str) {
// Remove white space (if any exists) and get byte groups as pairs
return str.replace(/ /g, '').match(/.{1,2}/g);
}
}
//# sourceMappingURL=obdReader.js.map