rewrite webinterface to use express and cdn hosted bootstrap

This commit is contained in:
Sebastian Wiedenroth 2013-11-17 17:45:53 +01:00
parent bf5cede0ca
commit 4003ff812a
17 changed files with 166 additions and 9064 deletions

View file

@ -39,7 +39,7 @@ Anim.prototype.run = function(universe, onFinish) {
} }
} }
var ani_step = function() { var ani_step = function() {
new_vals = {} var new_vals = {}
for(var k in config) { for(var k in config) {
new_vals[k] = Math.round(config[k].start + ease['linear'](t, 0, 1, d) * (config[k].end - config[k].start)) new_vals[k] = Math.round(config[k].start + ease['linear'](t, 0, 1, d) * (config[k].end - config[k].start))
} }

View file

@ -1,8 +0,0 @@
// webserver configuration
// listen port
exports.port = 80;
// uid and gid to drop root priv.
exports.uid = 'light';
exports.gid = 'users';

View file

@ -1,4 +1,10 @@
exports.devices = { module.exports = {
'generic': {
channels: ['dimmer']
},
'showtec-multidim2': {
channels: ['1', '2', '3', '4']
},
'eurolite-led-bar': { 'eurolite-led-bar': {
channels: ['ctrl', 'dimmer', 'strobe', 'red0', 'green0', 'blue0', 'red1', 'green1', 'blue1', 'red2', 'green2', 'blue2'], channels: ['ctrl', 'dimmer', 'strobe', 'red0', 'green0', 'blue0', 'red1', 'green1', 'blue1', 'red2', 'green2', 'blue2'],
ranges: { ranges: {
@ -31,9 +37,6 @@ exports.devices = {
} }
} }
}, },
'showtec-multidim2': {
channels: ['1', '2', '3', '4']
},
'stairville-led-par-56': { 'stairville-led-par-56': {
channels: ['ctrl', 'red', 'green', 'blue', 'speed'], channels: ['ctrl', 'red', 'green', 'blue', 'speed'],
ranges: { ranges: {

View file

@ -1,7 +1,15 @@
exports.setup = { module.exports = {
presets: [ "server": {
"listen_port": 8080,
"listen_host": "::",
// drop privileges to:
// "uid": "www-data",
// "gid": "www-data"
},
"presets": [
{ {
label: 'White', label: "White",
values: { values: {
'office': { 0:16, 1:255, 2:0, 3:255, 4: 255, 5:255, 15:16, 16:255, 17:0, 18:255, 19: 255, 20:255 } 'office': { 0:16, 1:255, 2:0, 3:255, 4: 255, 5:255, 15:16, 16:255, 17:0, 18:255, 19: 255, 20:255 }
} }
@ -34,7 +42,8 @@ exports.setup = {
universes: { universes: {
'office': { 'office': {
'output': { 'output': {
'driver': 'enttec-usb-dmx-pro', // 'driver': 'enttec-usb-dmx-pro',
'driver': 'null',
'device': 0 'device': 0
}, },
'devices': [ 'devices': [

109
dmx-web.js Executable file
View file

@ -0,0 +1,109 @@
#!/usr/bin/env node
"use strict"
var http = require('http')
var connect = require('connect')
var express = require('express')
var socketio = require('socket.io')
var program = require('commander')
var DMX = require('./dmx')
var A = DMX.Animation
program
.version("0.0.1")
.option('-c, --config <file>', 'Read config from file [/etc/dmx-web.json]', '/etc/dmx-web.json')
.parse(process.argv)
var config = require(program.config)
function DMXWeb() {
var app = express()
var server = http.createServer(app)
var io = socketio.listen(server)
var dmx = new DMX()
for(var universe in config.universes) {
dmx.addUniverse(
universe,
config.universes[universe].output.driver,
config.universes[universe].output.device
)
}
var listen_port = config.server.listen_port || 8080
var listen_host = config.server.listen_host || '::'
server.listen(listen_port, listen_host, null, function() {
if(config.server.uid && config.server.gid) {
try {
process.setuid(config.server.uid)
process.setgid(config.server.gid)
} catch (err) {
console.log(err)
process.exit(1)
}
}
})
io.set('log level', 1)
app.configure(function() {
app.use(connect.json())
})
app.get('/', function(req, res) {
res.sendfile(__dirname + '/index.html')
})
app.post('/animation/:universe', function(req, res) {
try {
var universe = dmx.universes[req.params.universe]
// preserve old states
var old = {}
for(var i = 0; i < 256; i++) {
old[i] = universe.get(i)
}
var animation = new A()
for(var step in req.body) {
animation.add(
req.body[step].to,
req.body[step].duration || 0,
req.body[step].options || {}
)
}
animation.add(old, 0)
animation.run(universe)
res.json({"success": true})
} catch(e) {
console.log(e)
res.json({"error": String(e)})
}
})
io.sockets.on('connection', function(socket) {
socket.emit('init', {'devices': DMX.devices, 'setup': config})
socket.on('request_refresh', function() {
for(var universe in config.universes) {
var u = {}
for(var i = 0; i < 256; i++) {
u[i] = dmx.universes[universe].get(i)
}
socket.emit('update', universe, u)
}
})
socket.on('update', function(universe, update) {
dmx.update(universe, update)
})
dmx.on('update', function(universe, update) {
socket.emit('update', universe, update)
})
})
}
DMXWeb()

4
dmx.js
View file

@ -6,12 +6,16 @@ var EventEmitter = require('events').EventEmitter
function DMX() { function DMX() {
this.universes = {} this.universes = {}
this.drivers = {} this.drivers = {}
this.registerDriver('null', require('./drivers/null')) this.registerDriver('null', require('./drivers/null'))
this.registerDriver('enttec-usb-dmx-pro', require('./drivers/enttec-usb-dmx-pro')) this.registerDriver('enttec-usb-dmx-pro', require('./drivers/enttec-usb-dmx-pro'))
} }
util.inherits(DMX, EventEmitter) util.inherits(DMX, EventEmitter)
DMX.devices = require('./devices')
DMX.Animation = require('./anim')
DMX.prototype.registerDriver = function(name, module) { DMX.prototype.registerDriver = function(name, module) {
this.drivers[name] = module this.drivers[name] = module
} }

View file

@ -5,8 +5,7 @@
<title>DMX Lichtschalter</title> <title>DMX Lichtschalter</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<link href="/static/bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet">
<style> <style>
body { body {
background: #222; background: #222;
@ -45,7 +44,7 @@
</style> </style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script> <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="/socket.io/socket.io.js"></script> <script src="/socket.io/socket.io.js"></script>
<script> <script>
function get_html_id(universe, channel) { function get_html_id(universe, channel) {

View file

@ -5,6 +5,9 @@
"description": "DMX library and webservice", "description": "DMX library and webservice",
"url": "https://github.com/wiedi/node-dmx", "url": "https://github.com/wiedi/node-dmx",
"main": "dmx.js", "main": "dmx.js",
"bin": {
"dmx-web": "./dmx-web.js"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/wiedi/node-dmx.git" "url": "https://github.com/wiedi/node-dmx.git"
@ -15,7 +18,10 @@
], ],
"dependencies": { "dependencies": {
"ftdi": "1.0.x", "ftdi": "1.0.x",
"socket.io": "0.9.x" "socket.io": "0.9.x",
"connect": "2.11.x",
"express": "3.4.x",
"commander": "2.0.x"
}, },
"licenses": [ "licenses": [
{ {

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

137
web.js
View file

@ -1,137 +0,0 @@
"use strict"
var http = require('http'),
path = require('path'),
io = require('socket.io'),
fs = require('fs'),
A = require('./anim.js').Anim
;
var DMX = require('./dmx')
var config = require('./config.js')
, web = require('./web.js')
, setup = require('./setup.js').setup
, devices = require('./devices.js').devices
function DMXWeb(dmx) {
function handler (request, response) {
var reqBody = '';
request.on("data", function (chunk) {
reqBody += chunk;
});
request.on("end", function () {
var urlData = require('url').parse(request.url),
urlPath = urlData.pathname.split('/');
if(urlPath.length == 3 && urlPath[1] == 'animation') {
try {
// save old states
var universe = dmx.drivers[urlPath[2]], old = {}, black = {};
for(var i = 0; i < 256; i++) {
old[i] = universe.get(i);
black[i] = 0;
}
var jsonAnim = JSON.parse(reqBody), animation = new A();
for(var step in jsonAnim) {
animation.add(jsonAnim[step].to, jsonAnim[step].duration || 0, jsonAnim[step].options || {});
}
animation.add(old, 0);
animation.run(universe);
response.write('{ "success": true }');
} catch(e) {
response.write('{ "error": "broken json" }');
}
response.end();
return;
}
var filePath = '.' + urlData.pathname;
if (filePath == './')
filePath = './index.html';
var extname = path.extname(filePath);
var contentType = 'text/html';
switch (extname) {
case '.js': contentType = 'text/javascript'; break;
case '.css': contentType = 'text/css'; break;
}
fs.exists(filePath, function(exists) {
if(!exists) {
console.log('404: ' + request.url)
response.writeHead(404);
response.end();
return;
}
fs.readFile(filePath, function(error, content) {
if (error) {
console.log('500: ' + request.url)
response.writeHead(500);
response.end();
return;
}
response.writeHead(200, { 'Content-Type': contentType });
response.end(content, 'utf-8');
});
});
});
}
var app = http.createServer(handler)
app.listen(config.port, '::', null, function() {
try {
process.setgid(config.gid);
process.setuid(config.uid);
} catch (err) {
console.log(err);
process.exit(1);
}
});
io.listen(app).sockets.on('connection', function (socket) {
socket.emit('init', {'devices': devices, 'setup': setup});
socket.on('request_refresh', function() {
for(var universe in setup.universes) {
var u = {}
for(var i = 0; i < 256; i++) {
u[i] = dmx.universes[universe].get(i);
}
console.log('sending update...')
console.log(u)
socket.emit('update', universe, u);
}
});
dmx.on('update', function(universe, update){
socket.emit('update', universe, update);
});
socket.on('update', function(universe, update) {
dmx.update(universe, update);
});
});
}
var dmx = new DMX()
for(var universe in setup.universes) {
dmx.addUniverse(
universe,
setup.universes[universe].output.driver,
setup.universes[universe].output.device
)
}
var web = new DMXWeb(dmx)