USB Missile Launcher controlled w/ Node.js and AngularJS
@TimPietrusky
Part #1
The Journey
Why are we here?
Hauke
Christmas
Nerd stuff
USB Missile Launcher
Facts
- Real name is "Thunder Missile Launcher"
-
Produced by Dream Cheeky
- Includes 4 foam missiles
- Costs 34,95 € on getDigital
Arrival
Runs on Windows
Let's go on GitHub
Alternatives
No fucking way
I want
- an awesome UIX
- to write my frontend- and backend in JavaScript
- that the application runs on as many systems as possible
I want to learn
Part #2
The Talking
Use
Find
Find USB devices
// https://github.com/node-hid/node-hid
var HID = require('node-hid'),
// Get all devices connected to the computer
devices = HID.devices();
// Show all devices
console.log(devices);
Output
// Informations about the connected device
[{ vendorId: 8483,
productId: 4112,
path: '0003:0006:00',
manufacturer: 'Syntek',
product: 'USB Missile Launcher',
release: 1,
interface: 0 }]
Important
vendorId + productId = unique
path = system specific
Connect
Connect to a USB device
// Options
var options = { vendorID : 8483, productID : 4112 };
// Iterate over all USB devices
devices.forEach(function(device, index) {
// Get a specific device
if (device.vendorId == options.vendorID
&& device.productId == options.productID) {
// Open a connection to the device
console.log(new HID.HID(device.path));
}
}, this);
Output
// The handler for the device
{ domain: null,
_events: { newListener: [Function] },
_maxListeners: 10,
_raw: {},
read: [Function],
write: [Function],
getFeatureReport: [Function],
sendFeatureReport: [Function],
setNonBlocking: [Function],
_paused: true }
Read
Read from a USB device
// Open the device
var connectedDevice = new HID.HID(device.path);
// Read from device
connectedDevice.on("data", function(data) {
console.log(data);
});
Write
Write to a USB device
var command = {
left : [2, 4, 0, 0, 0, 0, 0, 0],
right : [2, 8, 0, 0, 0, 0, 0, 0],
stop : [2, 32, 0, 0, 0, 0, 0, 0] }
connectedDevice.write(command.left); // Turn left
setTimeout(function() {
connectedDevice.write(command.right); // Turn right
setTimeout(function() {
connectedDevice.write(command.stop); // Stop
}, 500);
}, 500);
= thunder-connector
Part #3
The Controlling
Express
Express
- Web application framework for Node.js
- Routing
- Handler
- Views
Create a webserver
var express = require('express'),
ThunderConnector = require('thunder-connector');
// Initialize Express
var app = express();
// Handle the default route
app.get('/', function(request, response) {
// Handle request and send a response
});
// Listen on port x for a connection
app.listen(1337);
Handle request & send response
// Display the frontend if no action is given
if (!request.param('action')) {
response.sendfile('app/app.html');
} else {
var result = {
// Send 'action' as a command to the device
'result' : ThunderConnector.command(request.param('action')),
'action' : request.param('action')
};
// Send the result back to the client
response.json(result);
}
User Interface
Sketch
100 coffees later...
- SASS
- Grunt
Frontend
AngularJS
AngularJS
- Model-View-Controller framework from Google
- Single page web applications
- Custom tag attributes
- Data-binding
Basic markup
<!-- Root element of the application -->
<html ng-app="ThunderCommander">
<body
<!-- Attach controller class to view -->
ng-controller="CommandCenterController"
<!-- Listen to keyDown/keyUp events -->
ng-keydown="sendKey($event)"
ng-keyup="sendKey($event)"
<!-- Change class based on the connection status -->
ng-class="{'connected': connected, 'not-connected': !connected}"
>
Controller
// Container of the application
var ThunderCommander = angular.module('ThunderCommander', []);
// Controller to manipulate the client scope
ThunderCommander.controller('CommandCenterController',
['$scope', '$http', function($scope, $http) {
// Application logic
}]);
Application logic
// Send a command based on the pressed key
$scope.sendKey = function(event) {
switch (event.keyCode) {
// Left arrow
case 37 : $scope.sendCommand('left'); break;
}
}
// Send a command to the server
$scope.sendCommand = function(command) {
// Send an HTTP request to the server
$http.get('/?action='+command).success(function(data) {
// Do something with the result
});
};
Result
The End?
#1
Thank you all!
#2
@TimPietrusky
slid.es/timpietrusky/frankfurtjs-20140319
FrankfurtJS 20140319
By Tim Pietrusky
FrankfurtJS 20140319
- 3,740