diff --git a/firmata/firmata-tests.ts b/firmata/firmata-tests.ts new file mode 100644 index 0000000000..93cbb7d8db --- /dev/null +++ b/firmata/firmata-tests.ts @@ -0,0 +1,46 @@ +// Tests for firmata.d.ts +// Project: https://github.com/firmata/firmata.js +// Definitions by: Troy W. + +import * as Board from 'firmata' + +function test_basic_board() +{ + let board = new Board(''); +} + +function test_board_with_callback() +{ + let board = new Board('', (error:any) => + { + board.pinMode(13, board.MODES.OUTPUT); + board.pinMode(12, Board.PIN_MODES.OUTPUT); + }); +} + +function test_board_with_listener() +{ + let board = new Board(''); + + board.on('ready', () => + { + board.pinMode(13, board.MODES.OUTPUT); + board.pinMode(12, Board.PIN_MODES.OUTPUT); + }); +} + +function test_class_extension() +{ + class MyBoard extends Board + { + Disconnect() + { + this.transport.close((error:any) => {}); + } + } + + let myBoard:MyBoard = new MyBoard('', () => + { + myBoard.Disconnect(); + }); +} \ No newline at end of file diff --git a/firmata/firmata.d.ts b/firmata/firmata.d.ts new file mode 100644 index 0000000000..a732f01339 --- /dev/null +++ b/firmata/firmata.d.ts @@ -0,0 +1,274 @@ +// Type definitions for firmata.js v0.15.0 +// Project: https://github.com/firmata/firmata.js +// Definitions by: Troy W. + +declare module 'firmata' +{ + import * as SerialPort from 'serialport' + import { EventEmitter } from 'events' + + /** + * Most of these are generated by observing https://github.com/firmata/firmata.js/blob/master/lib/firmata.js + * items not exported are intentionally so, they exist only to inform intelligent completion and should not be exported + * without good reasoning. + * + * Also, this is a starting point that appeared to work fine for months within a project of my company, but I give no + * guarantee that it cannot be improved. + */ + class Board extends EventEmitter + { + constructor(serialPort:string, callback?:(error:any) => void) + + public MODES:Board.IPinModes; + public STEPPER:Board.IStepperConstants; + public I2C_MODES:Board.II2cModes; + public SERIAL_MODES:Board.ISerialModes; + public SERIAL_PORT_IDs:Board.ISerialPortIds; + public SERIAL_PIN_TYPES:Board.ISerialPinTypes; + public HIGH:Board.PIN_STATE; + public LOW:Board.PIN_STATE; + public pins:Board.IPins[]; + public ports:number[]; + public analogPins:number[]; + public version:Board.IVersion; + public firmware:Board.IFirmware; + public settings:Board.ISettings; + + public reportVersion(callback:() => void):void + public queryFirmware(callback:() => void):void + public analogRead(pin:number, callback:(value:number) => void):void + public analogWrite(pin:number, value:number):void + public pwmWrite(pin:number, value:number):void + public servoConfig(pin:number, min:number, max:number):void + public servoWrite(pin:number, value:number):void + public pinMode(pin:number, mode:Board.PIN_MODES):void + public digitalWrite(pin:number, val:Board.PIN_STATE):void + public digitalRead(pin:number, callback:(val:Board.PIN_STATE) => void):void + public queryCapabilities(callback:() => void):void + public queryAnalogMapping(callback:() => void):void + public queryPinState(pin:number, callback:() => void):void + public sendString(str):void // TODO untested/incomplete --- TWW + public sendI2CConfig(delay):void // TODO untested/incomplete --- TWW + public i2cConfig(options):void // TODO untested/incomplete --- TWW + public sendI2CWriteRequest(slaveAddress, bytes):void // TODO untested/incomplete --- TWW + public i2cWrite(address, registerOrData, inBytes):void // TODO untested/incomplete --- TWW + public i2cWriteReg(address, register, byte):void // TODO untested/incomplete --- TWW + public sendI2CReadRequest(address, numBytes, callback):void // TODO untested/incomplete --- TWW + public i2cRead(address, register, bytesToRead, callback):void // TODO untested/incomplete --- TWW + public i2cStop(options):void // TODO untested/incomplete --- TWW + public i2cReadOnce(address, register, bytesToRead, callback):void // TODO untested/incomplete --- TWW + public sendOneWireConfig(pin, enableParasiticPower):void // TODO untested/incomplete --- TWW + public sendOneWireSearch(pin, callback):void // TODO untested/incomplete --- TWW + public sendOneWireAlarmsSearch(pin, callback):void // TODO untested/incomplete --- TWW + public sendOneWireRead(pin, device, numBytesToRead, callback):void // TODO untested/incomplete --- TWW + public sendOneWireReset(pin):void // TODO untested/incomplete --- TWW + public sendOneWireWrite(pin, device, data):void // TODO untested/incomplete --- TWW + public sendOneWireDelay(pin, delay):void // TODO untested/incomplete --- TWW + public sendOneWireWriteAndRead(pin, device, data, numBytesToRead, callback):void // TODO untested/incomplete --- TWW + public setSamplingInterval(interval:number):void + public getSamplingInterval():number // TODO untested/incomplete --- TWW + public reportAnalogPin(pin:number, value:Board.REPORTING):void + public reportDigitalPin(pin:number, value:Board.REPORTING):void + public pingRead(opts, callback):void // TODO untested/incomplete --- TWW + public stepperConfig(deviceNum:number, type:number, stepsPerRev:number, dirOrMotor1Pin:number, + stepOrMotor2Pin:number, + motor3Pin?:number, motor4Pin?:number):void + public stepperStep(deviceNum:number, direction:number, steps:number, speed:number, accel:number, decel:number, + callback:(bool?:boolean) => void):void + public serialConfig(options):void // TODO untested/incomplete --- TWW + public serialWrite(portId, inBytes):void // TODO untested/incomplete --- TWW + public serialRead(portId, maxBytesToRead, callback):void // TODO untested/incomplete --- TWW + public serialStop(portId):void // TODO untested/incomplete --- TWW + public serialClose(portId):void // TODO untested/incomplete --- TWW + public serialFlush(portId):void // TODO untested/incomplete --- TWW + public serialListen(portId):void // TODO untested/incomplete --- TWW + public sysexResponse(commandByte, handler):void // TODO untested/incomplete --- TWW + public sysexCommand(message):void // TODO untested/incomplete --- TWW + public reset():void + public static isAcceptablePort(port:Board.IPort):boolean // TODO untested/incomplete --- TWW + public static requestPort(callback:(error:any, port:Board.IPort) => any):void // TODO untested/incomplete --- TWW + public static encode(data:number[]):number[] // TODO untested/incomplete --- TWW + public static decode(data:number[]):number[] // TODO untested/incomplete --- TWW + + protected transport:SerialPort; + + protected _sendOneWireSearch(type, event, pin, callback):void // TODO untested/incomplete --- TWW + protected _sendOneWireRequest(pin, subcommand, device, numBytesToRead, correlationId, delay, dataToWrite, event, + callback):void // TODO untested/incomplete --- TWW + } + + namespace Board + { + export interface IPinModes + { + INPUT:PIN_MODES, OUTPUT:PIN_MODES, ANALOG:PIN_MODES, PWM:PIN_MODES, SERVO:PIN_MODES, + SHIFT:PIN_MODES, I2C:PIN_MODES, ONEWIRE:PIN_MODES, STEPPER:PIN_MODES, SERIAL:PIN_MODES, + PULLUP:PIN_MODES, IGNORE:PIN_MODES, PING_READ:PIN_MODES, UNKOWN:PIN_MODES + } + + export interface IStepperConstants + { + TYPE:{ DRIVER:STEPPER_TYPES, TWO_WIRE:STEPPER_TYPES, FOUR_WIRE:STEPPER_TYPES }, + RUNSTATE:{ + STOP:STEPPER_RUN_STATES, ACCEL:STEPPER_RUN_STATES, DECEL:STEPPER_RUN_STATES, RUN:STEPPER_RUN_STATES + }, + DIRECTION:{ CCW:STEPPER_DIRECTIONS, CW:STEPPER_DIRECTIONS } + } + + export interface II2cModes + { + WRITE:I2C_MODES, READ:I2C_MODES, CONTINUOUS_READ:I2C_MODES, STOP_READING:I2C_MODES + } + + export interface ISerialModes + { + CONTINUOUS_READ:SERIAL_MODES, STOP_READING:SERIAL_MODES + } + + export interface ISerialPortIds + { + HW_SERIAL0:SERIAL_PORT_IDs, HW_SERIAL1:SERIAL_PORT_IDs, HW_SERIAL2:SERIAL_PORT_IDs, HW_SERIAL3:SERIAL_PORT_IDs, + SW_SERIAL0:SERIAL_PORT_IDs, SW_SERIAL1:SERIAL_PORT_IDs,SW_SERIAL2:SERIAL_PORT_IDs, SW_SERIAL3:SERIAL_PORT_IDs, + DEFAULT:SERIAL_PORT_IDs, + } + + export interface ISerialPinTypes + { + RES_RX0:SERIAL_PIN_TYPES, RES_TX0:SERIAL_PIN_TYPES, RES_RX1:SERIAL_PIN_TYPES, RES_TX1:SERIAL_PIN_TYPES, + RES_RX2:SERIAL_PIN_TYPES, RES_TX2:SERIAL_PIN_TYPES, RES_RX3:SERIAL_PIN_TYPES, RES_TX3:SERIAL_PIN_TYPES, + } + + export interface IPins + { + mode:PIN_MODES, + value:PIN_STATE|number, + supportedModes:PIN_MODES[], + analogChannel:number, + report:REPORTING, + state:PIN_STATE|PULLUP_STATE, // TODO not sure if this exists anymore... --- TWW + } + + export interface IFirmware + { + name:string, + version:IVersion, + } + + export interface ISettings + { + reportVersionTimeout:number, + samplingInterval:number, + serialport:{ + baudRate:number, + bufferSize:number + } + } + + export interface IPort + { + comName:string, + } + + export interface IVersion + { + major:number, + minor:number + } + + // TODO these enums could actually be non-const in the future (provides some benefits) --- TWW + // https://github.com/firmata/firmata.js/blob/master/lib/firmata.js#L431 + export const enum PIN_MODES { + INPUT = 0x00, + OUTPUT = 0x01, + ANALOG = 0x02, + PWM = 0x03, + SERVO = 0x04, + SHIFT = 0x05, + I2C = 0x06, + ONEWIRE = 0x07, + STEPPER = 0x08, + SERIAL = 0x0A, + PULLUP = 0x0B, + IGNORE = 0x7F, + PING_READ = 0x75, + UNKNOWN = 0x10, + } + + export const enum PIN_STATE { + LOW = 0, + HIGH = 1, + } + + export const enum REPORTING { + ON = 1, + OFF = 0, + } + + export const enum PULLUP_STATE { + ENABLED = 1, + DISABLED = 0, + } + + // https://github.com/firmata/firmata.js/blob/master/lib/firmata.js#L456 + export const enum STEPPER_TYPES { + DRIVER = 1, + TWO_WIRE = 2, + FOUR_WIRE = 4, + } + + // https://github.com/firmata/firmata.js/blob/master/lib/firmata.js#L461 + export const enum STEPPER_RUN_STATES { + STOP = 0, + ACCEL = 1, + DECEL = 2, + RUN = 3, + } + + // https://github.com/firmata/firmata.js/blob/master/lib/firmata.js#L467 + export const enum STEPPER_DIRECTIONS { + CCW = 0, + CW = 1, + } + + // https://github.com/firmata/firmata.js/blob/master/lib/firmata.js#L448 + export const enum I2C_MODES { + WRITE = 0, + READ = 1, + CONTINUOUS_READ = 2, + STOP_READING = 3 + } + + // https://github.com/firmata/firmata.js/blob/master/lib/firmata.js#L473 + export const enum SERIAL_MODES { + CONTINUOUS_READ = 0x00, + STOP_READING = 0x01, + } + + // https://github.com/firmata/firmata.js/blob/master/lib/firmata.js#L479 + export const enum SERIAL_PORT_IDs { + HW_SERIAL0 = 0x00, + HW_SERIAL1 = 0x01, + HW_SERIAL2 = 0x02, + HW_SERIAL3 = 0x03, + SW_SERIAL0 = 0x08, + SW_SERIAL1 = 0x09, + SW_SERIAL2 = 0x10, + SW_SERIAL3 = 0x11, + DEFAULT = 0x08, + } + + // https://github.com/firmata/firmata.js/blob/master/lib/firmata.js#L497 + export const enum SERIAL_PIN_TYPES { + RES_RX0 = 0x00, + RES_TX0 = 0x01, + RES_RX1 = 0x02, + RES_TX1 = 0x03, + RES_RX2 = 0x04, + RES_TX2 = 0x05, + RES_RX3 = 0x06, + RES_TX3 = 0x07, + } + } + + export = Board; +} \ No newline at end of file diff --git a/firmata/readme.md b/firmata/readme.md new file mode 100644 index 0000000000..32bb7df11f --- /dev/null +++ b/firmata/readme.md @@ -0,0 +1,46 @@ +# Usage + +For typescript projects, instead of + +```js +var Board = require('firmata'); +``` + +you should use + +```typescript +import * as Board from 'firmata' +``` + +You will find that `const enums` are exported under the namespace `Board` for ease of comparison or +use with other libraries before any boards are actually instantiated. + +It's also important to note that if you want to extend the `Board` class in typescript, the +following will work (as long as you turn on `--noImplicitUseStrict` when compiling); here's +an example: + +```typescript +// store as script.ts and compile with `tsc --noImplicitUseStrict script.ts` +// then run `node script.js` + +import * as Board from 'firmata' + +let portString = 'port string'; + +class MyBoard extends Board +{ + Disconnect() + { + this.transport.close(() => + { + console.log('extended board closed'); + }); + } +} + +let myBoard:MyBoard = new MyBoard(portString, () => +{ + console.log('extended board ready'); + myBoard.Disconnect(); +}); +``` \ No newline at end of file diff --git a/firmata/tsconfig.json b/firmata/tsconfig.json new file mode 100644 index 0000000000..c1b83e40b5 --- /dev/null +++ b/firmata/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": false, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "firmata.d.ts", + "firmata-tests.ts" + ] +} \ No newline at end of file