/// /// /// /// /// /// /// import _dtc = require("./core/dtc"); import _pid = require("./core/pid"); import _obd = require("./core/obd"); import _ticker = require("./core/ticker"); import _device = require("./device/index"); import _serial = require("./serial/index"); const DTC = _dtc.OBD2.Core.DTC; const PID = _pid.OBD2.Core.PID; const OBD = _obd.OBD2.Core.OBD; const Ticker = _ticker.OBD2.Core.Ticker; const Device = _device.OBD2.Device.Main; const Serial = _serial.OBD2.Serial.Main; import events = require("events"); const debug : debug.IDebug = require( "debug" )( "OBD2.Main" ); export namespace OBD2 { export class Main extends events.EventEmitter { public DTC : _dtc.OBD2.Core.DTC; public PID : _pid.OBD2.Core.PID; public OBD : _obd.OBD2.Core.OBD; public Ticker : _ticker.OBD2.Core.Ticker; public Device : _device.OBD2.Device.Main; public Serial : obd2.OBD2_SerialInterface; private _options : obd2.OBD2_IOptions; public constructor( options : any ) { super(); debug( "Initializing" ); this._options = options; this.DTC = new DTC(); this.PID = new PID(); this.OBD = new OBD( this.PID.getListPID() ); this.Ticker = new Ticker( this._options.delay ); this.Device = new Device( this._options.device ); this.Serial = new Serial( this._options.serial, this._options.port, { baudrate : this._options.baud }); debug( "Ready" ); } public start( callBack : any ) { this.Serial.on( "data", ( data ) => { this.OBD.parseDataStream( data, ( type, mess ) => { this.emit( type, mess, data ); this.emit( "dataParsed", type, mess, data ); } ); this.emit( "dataReceived", data ); } ); this.Serial.connect( () => { this.Device.connect( this, () => { /*this.Serial.getSerial().on("data", ( data ) => { console.log("data2", data); });*/ callBack(); } ); } ); } public sendAT( atCommand : string ) { //atCommand = atCommand.replace(/" "/g, ""); //atCommand = String(atCommand).replace(" ", ""); this.Ticker.addItem( "AT", atCommand, false, ( next ) => { this.Serial.drain( atCommand + "\r" ); this.once( "dataReceived", ( data ) => { // Wait a bit setTimeout( next, 100 ); } ); } ); } public listPID( callBack : any ) : void { let pidSupportList = [ "00", "20", "40", "60", "80", "A0", "C0" ]; if ( this.PID.getList().length > 0 ) { callBack( this.PID.getList() ); } else { this._tickListPID( pidSupportList, ( a ) => { callBack( this.PID.getList() ); } ); } } /** * Writing PID * * @param replies * @param loop * @param pidNumber * @param pidMode * @param callBack */ public writePID( replies : string, loop : boolean, pidNumber : string, pidMode? : string, callBack? : any ) : void { // Arguments if ( typeof pidMode === "function" ) { callBack = pidMode; pidMode = "01"; } else { pidMode = !pidMode ? "01" : pidMode; } // Vars let pidData : any = this.PID.getByPid( pidNumber, pidMode ); let sendData : string = ""; replies = !replies ? "" : replies; // PID defined? if ( pidData ) { // MODE + PID + (send/read) if ( pidData.pid !== "undefined" ) { sendData = pidData.mode + pidData.pid + replies + "\r"; } // Only mode send ( ex. DTC ) else { sendData = pidData.mode + replies + "\r"; } } // Undefined PID else { sendData = pidMode + pidNumber + replies + "\r"; } // Add Ticker this.Ticker.addItem( "PID", sendData, !!loop, ( next, elem ) => { // Timeout let for auto cleaning let itemSkip : any; // Send data if ( elem.fail % 20 === 0 ) { this.Serial.drain( sendData ); } // Detected parsed PID data this.once( "pid", ( mess, data ) => { if ( typeof callBack === "function" ) { callBack( mess, data ); } clearTimeout( itemSkip ); itemSkip = undefined; next(); } ); // Timeout timer itemSkip = setTimeout( () => { // Fail to remove elem.fail++; // Auto remover, 60 loop wait, 4 sending try if ( this._options.cleaner && elem.fail > 60 ) { this.Ticker.delItem( "PID", sendData ); } next(); }, this._options.delay ); /* // Direct callBack if ( typeof callBack === "function" ) { // Detected parsed PID data this.once("pid", ( mess, data ) => { callBack( mess, data ); clearTimeout( itemSkip ); delete itemSkip; next(); }); } // Without direct callback else { // Auto remover, 100 loop wait if ( this._options.cleaner ) { // Timeout timer itemSkip = setTimeout(()=> { // Fail to remove elem.fail++; console.log(elem.data, elem.fail); if ( elem.fail === 100 ) { this.Ticker.delItem( "PID", sendData ); } next(); }, this._options.delay ); } // Next Tick next(); } */ } ); }; /** * Sending PID code * * @param pidNumber * @param pidMode * @param callBack */ public sendPID( pidNumber : string, pidMode? : string, callBack? : any ) : void { this.writePID( undefined, false, pidNumber, pidMode, callBack ); } /** * Reading PID code * * @param pidNumber * @param pidMode * @param callBack */ public readPID( pidNumber : string, pidMode? : string, callBack? : any ) : void { this.writePID( "1", true, pidNumber, pidMode, callBack ); } private _tickListPID( pidList : any, callBack : any ) : void { if ( pidList.length <= 0 ) { callBack(); } let cmdPid = pidList.shift(); if ( this.PID.getListECU().length > 0 && this.PID.getListECU().indexOf( cmdPid ) < 0 ) { callBack(); } this.sendPID( cmdPid, "01", ( mess, data ) => { if ( this.PID._loadPidEcuList( mess.name, mess.value ) ) { this._tickListPID( pidList, callBack ); } else { callBack(); } } ); } } }