forked from pathikrit/node-thunder-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdriver.js
124 lines (105 loc) · 3.34 KB
/
driver.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
(function () {
'use strict';
var DEVICE = {
ID: {
VENDOR : 0x2123,
PRODUCT: 0x1010
},
CMD: {
UP : 0x02,
DOWN : 0x01,
LEFT : 0x04,
RIGHT: 0x08,
FIRE : 0x10,
STOP : 0x20,
RESET: 'l8000,d2000'
},
MISSILES: {
NUMBER : 4,
RELOAD_DELAY_MS: 4500
}
};
var _ = require('underscore'), usb = require('node-usb/usb.js');
var launcher = usb.find_by_vid_and_pid(DEVICE.ID.VENDOR, DEVICE.ID.PRODUCT)[0];
if (!launcher) {
throw 'Launcher not found - make sure your Thunder Missile Launcher is plugged in to a USB port';
}
var launcherInterface = launcher.interfaces[0];
if (launcherInterface.isKernelDriverActive()) {
launcherInterface.detachKernelDriver();
}
launcherInterface.claim();
process.on('exit', launcherInterface.release);
function signal(cmd, duration, callback) {
launcher.controlTransfer(0x21, 0x09, 0x0, 0x0, new Buffer([0x02, cmd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
function (data) {
if (_.isNumber(duration)) {
_.delay(_.isFunction(callback) ? callback : controller.stop, duration);
}
}
);
}
function trigger(callback, p1, p2) {
return function () {
callback(p1, p2);
};
}
var controller = {};
controller.up = controller.u = function (duration, callback) {
signal(DEVICE.CMD.UP, duration, callback);
};
controller.down = controller.d = function (duration, callback) {
signal(DEVICE.CMD.DOWN, duration, callback);
};
controller.left = controller.l = function (duration, callback) {
signal(DEVICE.CMD.LEFT, duration, callback);
};
controller.right = controller.r = function (duration, callback) {
signal(DEVICE.CMD.RIGHT, duration, callback);
};
controller.stop = controller.s = function (callback) {
if (_.isFunction(callback) && callback !== controller.stop) {
signal(DEVICE.CMD.STOP, 0, callback);
} else {
signal(DEVICE.CMD.STOP);
}
};
controller.fire = controller.f = function (number, callback) {
number = _.isNumber(number) && number >= 0 && number <= DEVICE.MISSILES.NUMBER ? number : 1;
if (number === 0) {
controller.stop(callback);
} else {
signal(DEVICE.CMD.FIRE, DEVICE.MISSILES.RELOAD_DELAY_MS, trigger(controller.fire, number - 1, callback));
}
};
controller.park = controller.p = function (callback) {
controller.execute(DEVICE.CMD.RESET, callback);
};
controller.execute = function (commands, callback) {
if (_.isString(commands)) {
controller.execute(commands.split(','), callback);
} else if (commands.length === 0) {
controller.stop(callback);
} else {
var command = commands.shift(), func = command.length > 0 ? controller[command[0]] : null;
if (_.isFunction(func)) {
var next = trigger(controller.execute, commands, callback);
if (func === controller.park || func === controller.stop) {
func(next);
} else {
var number;
try {
number = parseInt(command.substring(1), 10);
} catch (ignore) {
number = null;
}
func(number, next);
}
} else {
console.warn('Ignoring bad command: ' + command);
controller.execute(commands, callback);
}
}
};
module.exports = controller;
})();