Merge pull request #70 from Fensterbank/feature/library

Modernize code and enforcing eslint rules
This commit is contained in:
Frédéric Bolvin 2018-12-29 16:19:03 +01:00 committed by GitHub
commit 65f24c5031
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 1192 additions and 987 deletions

12
.editorconfig Normal file
View file

@ -0,0 +1,12 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = LF
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

179
.eslintrc Normal file
View file

@ -0,0 +1,179 @@
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"globals": {
"document": false,
"escape": false,
"navigator": false,
"unescape": false,
"window": false,
"describe": true,
"before": true,
"it": true,
"expect": true,
"sinon": true
},
"parser": "babel-eslint",
"plugins": [
],
"rules": {
"block-scoped-var": 2,
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
"camelcase": [2, { "properties": "always" }],
"comma-dangle": [2, "always-multiline"],
"comma-spacing": [2, { "before": false, "after": true }],
"comma-style": [2, "last"],
"complexity": 0,
"consistent-return": 2,
"consistent-this": 0,
"curly": [2, "multi-line"],
"default-case": 0,
"dot-location": [2, "property"],
"dot-notation": 0,
"eol-last": 2,
"eqeqeq": [2, "allow-null"],
"func-names": 0,
"func-style": 0,
"generator-star-spacing": [2, "both"],
"guard-for-in": 0,
"handle-callback-err": [0, "^(err|error|anySpecificError)$" ],
"indent": [2, 2, { "SwitchCase": 1 }],
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
"keyword-spacing": [2, {"before": true, "after": true}],
"linebreak-style": 0,
"max-depth": 0,
"max-len": [2, 120, 4],
"max-nested-callbacks": 0,
"max-params": 0,
"max-statements": 0,
"new-cap": [2, { "newIsCap": true, "capIsNew": false }],
"newline-after-var": [2, "always"],
"new-parens": 2,
"no-alert": 0,
"no-array-constructor": 2,
"no-bitwise": 0,
"no-caller": 2,
"no-catch-shadow": 0,
"no-cond-assign": 2,
"no-console": 0,
"no-constant-condition": 0,
"no-continue": 0,
"no-control-regex": 2,
"no-debugger": 2,
"no-delete-var": 2,
"no-div-regex": 0,
"no-dupe-args": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-else-return": 2,
"no-empty": 0,
"no-empty-character-class": 2,
"no-eq-null": 0,
"no-eval": 2,
"no-ex-assign": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-boolean-cast": 2,
"no-extra-parens": 0,
"no-extra-semi": 0,
"no-extra-strict": 0,
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-func-assign": 2,
"no-implied-eval": 2,
"no-inline-comments": 0,
"no-inner-declarations": [2, "functions"],
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": 2,
"no-lone-blocks": 0,
"no-lonely-if": 0,
"no-loop-func": 0,
"no-mixed-requires": 0,
"no-mixed-spaces-and-tabs": [2, false],
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-multiple-empty-lines": [2, { "max": 1 }],
"no-native-reassign": 2,
"no-negated-in-lhs": 2,
"no-nested-ternary": 0,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-require": 2,
"no-new-wrappers": 2,
"no-obj-calls": 2,
"no-octal": 2,
"no-octal-escape": 2,
"no-path-concat": 0,
"no-plusplus": 0,
"no-process-env": 0,
"no-process-exit": 0,
"no-proto": 2,
"no-redeclare": 2,
"no-regex-spaces": 2,
"no-reserved-keys": 0,
"no-restricted-modules": 0,
"no-return-assign": 2,
"no-script-url": 0,
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow": 0,
"no-shadow-restricted-names": 2,
"no-spaced-func": 2,
"no-sparse-arrays": 2,
"no-sync": 0,
"no-ternary": 0,
"no-throw-literal": 2,
"no-trailing-spaces": 2,
"no-undef": 2,
"no-undef-init": 2,
"no-undefined": 0,
"no-underscore-dangle": 0,
"no-unneeded-ternary": 2,
"no-unreachable": 1,
"no-unused-expressions": 0,
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
"no-use-before-define": 2,
"no-var": 2,
"no-void": 0,
"no-warning-comments": 0,
"no-with": 2,
"one-var": 0,
"operator-assignment": 0,
"operator-linebreak": [2, "after"],
"padded-blocks": 0,
"prefer-const": 2,
"quote-props": 0,
"quotes": [2, "single", "avoid-escape"],
"radix": 2,
"semi": [2, "always"],
"semi-spacing": 0,
"sort-vars": 0,
"space-before-blocks": [2, "always"],
"space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
"space-in-brackets": 0,
"space-in-parens": [2, "never"],
"space-infix-ops": 2,
"space-unary-ops": [2, { "words": true, "nonwords": false }],
"spaced-comment": [2, "always"],
"strict": 2,
"use-isnan": 2,
"valid-jsdoc": 0,
"valid-typeof": 2,
"vars-on-top": 0,
"wrap-iife": [2, "any"],
"wrap-regex": 0,
"yoda": [2, "never"]
}
}

6
.gitignore vendored
View file

@ -15,3 +15,9 @@ results
node_modules node_modules
.project .project
.com.greenworldsoft.syncfolderspro .com.greenworldsoft.syncfolderspro
# Remove some common IDE working directories
.idea
.vscode
.DS_Store

156
anim.js
View file

@ -1,81 +1,83 @@
"use strict" const ease = require('./easing.js').ease;
const resolution = 25;
var ease = require('./easing.js').ease class Anim {
var resolution = 25 constructor() {
this.fxStack = [];
this.interval = null;
}
function Anim() { add(to, duration = resolution, options = {}) {
this.fx_stack = [] options.easing = options.easing || 'linear';
this.interval = null
this.fxStack.push({ 'to': to, 'duration': duration, 'options': options });
return this;
}
delay(duration) {
this.add({}, duration);
return this;
}
stop() {
if (this.interval) {
clearInterval(this.interval);
}
this.fxStack = [];
}
run(universe, onFinish) {
let config = {};
let ticks = 0;
let duration = 0;
let animationStep;
let iid = null;
const stack = [ ...this.fxStack ];
const aniSetup = () => {
animationStep = stack.shift();
ticks = 0;
duration = animationStep.duration;
config = {};
for (const k in animationStep.to) {
config[k] = {
'start': universe.get(k),
'end': animationStep.to[k],
'options': animationStep.options,
};
}
};
const aniStep = () => {
const newValues = {};
for (const k in config) {
const entry = config[k];
const easing = ease[entry.options.easing];
newValues[k] = Math.round(entry.start + easing(ticks, 0, 1, duration) * (entry.end - entry.start));
}
ticks = ticks + resolution;
universe.update(newValues);
if (ticks > duration) {
if (stack.length > 0) {
aniSetup();
} else {
clearInterval(iid);
if (onFinish) {
onFinish();
}
}
}
};
aniSetup();
iid = this.interval = setInterval(aniStep, resolution);
return this;
}
} }
Anim.prototype.add = function(to, duration, options) { module.exports = Anim;
var options = options || {}
var duration = duration || resolution
options.easing = options.easing || 'linear';
this.fx_stack.push({'to': to, 'duration': duration, 'options': options})
return this
}
Anim.prototype.delay = function(duration) {
return this.add({}, duration)
}
Anim.prototype.stop = function () {
if(this.interval) {
clearInterval(this.interval)
}
this.fx_stack = []
}
Anim.prototype.run = function(universe, onFinish) {
var config = {}
var ticks = 0
var duration = 0
var animationStep
var fx_stack = this.fx_stack;
var ani_setup = function() {
animationStep = fx_stack.shift()
ticks = 0
duration = animationStep.duration
config = {}
for (var k in animationStep.to) {
config[k] = {
'start': universe.get(k),
'end': animationStep.to[k],
'options': animationStep.options
}
}
}
var ani_step = function() {
var newValues = {}
for (var k in config) {
var entry = config[k]
var easing = ease[entry.options.easing]
newValues[k] = Math.round(entry.start + easing(ticks, 0, 1, duration) * (entry.end - entry.start))
}
ticks = ticks + resolution
universe.update(newValues)
if (ticks > duration) {
if (fx_stack.length > 0) {
ani_setup()
} else {
clearInterval(iid)
if(onFinish) {
onFinish()
}
}
}
}
ani_setup()
var iid = this.interval = setInterval(ani_step, resolution)
return this
}
module.exports = Anim

133
demo.js
View file

@ -1,85 +1,84 @@
"use strict" const DMX = require('./dmx');
var DMX = require('./dmx') const dmx = new DMX();
const A = dmx.animation;
var dmx = new DMX();
var A = dmx.animation;
// var universe = dmx.addUniverse('demo', 'enttec-usb-dmx-pro', '/dev/cu.usbserial-6AVNHXS8') // var universe = dmx.addUniverse('demo', 'enttec-usb-dmx-pro', '/dev/cu.usbserial-6AVNHXS8')
// var universe = dmx.addUniverse('demo', 'enttec-open-usb-dmx', '/dev/cu.usbserial-6AVNHXS8') // var universe = dmx.addUniverse('demo', 'enttec-open-usb-dmx', '/dev/cu.usbserial-6AVNHXS8')
var universe = dmx.addUniverse('demo', 'null') const universe = dmx.addUniverse('demo', 'null');
universe.update({1: 1, 2: 0}) universe.update({1: 1, 2: 0});
universe.update({16: 1, 17: 255}) universe.update({16: 1, 17: 255});
universe.update({1: 255, 3: 120, 4: 230, 5: 30, 6: 110, 7: 255, 8: 10, 9: 255, 10: 255, 11: 0}) universe.update({1: 255, 3: 120, 4: 230, 5: 30, 6: 110, 7: 255, 8: 10, 9: 255, 10: 255, 11: 0});
function done() {console.log('DONE')} function done() {console.log('DONE');}
function green_water(universe, channels, duration) { function greenWater(universe, channels, duration) {
var colors = [ const colors = [
[160, 230, 20], [160, 230, 20],
[255, 255, 0], [255, 255, 0],
[110, 255, 10] [110, 255, 10],
] ];
for(var c in channels) { for (const c in channels) {
var r = Math.floor((Math.random()*colors.length)) const r = Math.floor((Math.random() * colors.length));
var u = {} const u = {};
for(var i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
u[channels[c] + i] = colors[r][i] u[channels[c] + i] = colors[r][i];
} }
new A().add(u, duration).run(universe) new A().add(u, duration).run(universe);
} }
setTimeout(function() {green_water(universe, channels, duration);}, duration * 2) setTimeout(function () {greenWater(universe, channels, duration);}, duration * 2);
} }
function warp(universe, channel, min, max, duration) { function warp(universe, channel, min, max, duration) {
var a = {}, b = {} const a = {}, b = {};
a[channel] = min;
b[channel] = max; a[channel] = min;
new A().add(a, duration).add(b, duration).run(universe, function() { b[channel] = max;
warp(universe, channel, min, max, duration) new A().add(a, duration).add(b, duration).run(universe, function () {
}) warp(universe, channel, min, max, duration);
});
} }
warp(universe, 1, 200, 220, 360) warp(universe, 1, 200, 220, 360);
warp(universe, 1+15, 200, 255, 240) warp(universe, 1 + 15, 200, 255, 240);
green_water(universe, [3, 6, 9], 4000) greenWater(universe, [3, 6, 9], 4000);
green_water(universe, [3+15, 6+15, 9+15], 4000) greenWater(universe, [3 + 15, 6 + 15, 9 + 15], 4000);
return return;
var x = new A() const x = new A()
.add({1: 255, 6: 110, 7: 255, 8: 10}, 1200) .add({1: 255, 6: 110, 7: 255, 8: 10}, 1200)
.delay(1000) .delay(1000)
.add({1: 0}, 600) .add({1: 0}, 600)
.add({1: 255}, 600) .add({1: 255}, 600)
.add({5: 255, 6: 128}, 1000) .add({5: 255, 6: 128}, 1000)
.add({1: 0}, 100) .add({1: 0}, 100)
.add({1: 255}, 100) .add({1: 255}, 100)
.add({1: 0}, 200) .add({1: 0}, 200)
.add({1: 255}, 200) .add({1: 255}, 200)
.add({1: 0}, 100) .add({1: 0}, 100)
.add({1: 255}, 100) .add({1: 255}, 100)
.add({1: 0}) .add({1: 0})
.delay(50) .delay(50)
.add({1: 255}) .add({1: 255})
.delay(50) .delay(50)
.add({1: 0}) .add({1: 0})
.delay(50) .delay(50)
.add({1: 255}) .add({1: 255})
.delay(50) .delay(50)
.add({1: 0}) .add({1: 0})
.delay(50) .delay(50)
.add({1: 255}) .add({1: 255})
.delay(50) .delay(50)
.add({2: 255}, 6000) .add({2: 255}, 6000)
.delay(200) .delay(200)
.add({2: 0}) .add({2: 0});
var y = new A() const y = new A()
.add({9: 255}, 10000) .add({9: 255}, 10000);
x.run(universe, done) x.run(universe, done);
y.run(universe, done) y.run(universe, done);

View file

@ -1,22 +1,20 @@
"use strict" const DMX = require('./dmx');
var DMX = require('./dmx'); const dmx = new DMX();
var dmx = new DMX();
var A = dmx.animation;
// var universe = dmx.addUniverse('demo', 'enttec-open-usb-dmx', '/dev/cu.usbserial-6AVNHXS8') // var universe = dmx.addUniverse('demo', 'enttec-open-usb-dmx', '/dev/cu.usbserial-6AVNHXS8')
var universe = dmx.addUniverse('demo', 'null') const universe = dmx.addUniverse('demo', 'null');
var on = false; let on = false;
setInterval(function(){
if(on){ setInterval(() => {
if (on) {
on = false; on = false;
universe.updateAll(0); universe.updateAll(0);
console.log("off"); console.log('off');
}else{ } else {
on = true; on = true;
universe.updateAll(250); universe.updateAll(250);
console.log("on"); console.log('on');
} }
}, 1000); }, 1000);

View file

@ -1,116 +1,129 @@
module.exports = { module.exports = {
'generic': { 'generic': {
channels: ['dimmer'] channels: ['dimmer'],
}, },
'generic-rgb': { 'generic-rgb': {
channels: ['red', 'green', 'blue'] channels: ['red', 'green', 'blue'],
}, },
'showtec-multidim2': { 'showtec-multidim2': {
channels: ['1', '2', '3', '4'] 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: [
ranges: { 'ctrl',
'ctrl': { 'dimmer',
'type': 'option', 'strobe',
'options': [ 'red0',
{'value': 0, 'label': 'Black Out'}, 'green0',
{'value': 1, 'label': 'Dimmer 1'}, 'blue0',
{'value': 16, 'label': 'Dimmer 2'}, 'red1',
{'value': 32, 'label': 'Red'}, 'green1',
{'value': 48, 'label': 'Green'}, 'blue1',
{'value': 64, 'label': 'Blue'}, 'red2',
{'value': 80, 'label': 'Purple'}, 'green2',
{'value': 96, 'label': 'Yellow'}, 'blue2',
{'value': 112, 'label': 'Cyan'}, ],
{'value': 128, 'label': 'White'}, ranges: {
{'value': 144, 'label': 'Color change'}, 'ctrl': {
{'value': 160, 'label': 'Color flow'}, 'type': 'option',
{'value': 176, 'label': 'Color dream'}, 'options': [
{'value': 192, 'label': 'Multi flow'}, { 'value': 0, 'label': 'Black Out' },
{'value': 208, 'label': 'Dream flow'}, { 'value': 1, 'label': 'Dimmer 1' },
{'value': 224, 'label': 'Two color flow'}, { 'value': 16, 'label': 'Dimmer 2' },
{'value': 240, 'label': 'Sound activity'} { 'value': 32, 'label': 'Red' },
] { 'value': 48, 'label': 'Green' },
}, { 'value': 64, 'label': 'Blue' },
'dimmer': { { 'value': 80, 'label': 'Purple' },
'type': 'slider', { 'value': 96, 'label': 'Yellow' },
'min': 0, { 'value': 112, 'label': 'Cyan' },
'max': 255 { 'value': 128, 'label': 'White' },
} { 'value': 144, 'label': 'Color change' },
} { 'value': 160, 'label': 'Color flow' },
}, { 'value': 176, 'label': 'Color dream' },
'stairville-led-par-56': { { 'value': 192, 'label': 'Multi flow' },
channels: ['ctrl', 'red', 'green', 'blue', 'speed'], { 'value': 208, 'label': 'Dream flow' },
ranges: { { 'value': 224, 'label': 'Two color flow' },
'ctrl': { { 'value': 240, 'label': 'Sound activity' },
'type': 'option', ],
'options': [ },
{'value': 0, 'label': 'RGB Control'}, 'dimmer': {
{'value': 64, 'label': '7 color fade'}, 'type': 'slider',
{'value': 128, 'label': '7 color change'}, 'min': 0,
{'value': 192, 'label': '3 color change'} 'max': 255,
] },
} },
} },
}, 'stairville-led-par-56': {
'ultra-pro-24ch-rdm': { channels: ['ctrl', 'red', 'green', 'blue', 'speed'],
channels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24' ] ranges: {
}, 'ctrl': {
'ultra-pro-6rgbch-rdm': { 'type': 'option',
channels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24' ], 'options': [
channelgroups: ['1', '2', '3', '4', '5', '6'] { 'value': 0, 'label': 'RGB Control' },
}, { 'value': 64, 'label': '7 color fade' },
'oppsk-cob-uv-par': { { 'value': 128, 'label': '7 color change' },
channels: ['dimmer', 'strobe', 'program-speed', 'sound-activity'] { 'value': 192, 'label': '3 color change' },
}, ],
'lixda-par12-led': { },
channels: ['ctrl', 'static-color', 'speed', 'dimmer', 'red', 'green', 'blue', 'white'], },
ranges: { },
'ctrl': { 'ultra-pro-24ch-rdm': {
'type': 'option', channels: [...Array(25).keys()].slice(1),
'options': [ },
{'value': 0, 'label': 'Off'}, 'ultra-pro-6rgbch-rdm': {
{'value': 11, 'label': 'Static Color'}, channels: [...Array(25).keys()].slice(1),
{'value': 51, 'label': 'Jump'}, channelgroups: ['1', '2', '3', '4', '5', '6'],
{'value': 101, 'label': 'Gradual'}, },
{'value': 151, 'label': 'Sound Activate'}, 'oppsk-cob-uv-par': {
{'value': 200, 'label': 'Strobe'} channels: ['dimmer', 'strobe', 'program-speed', 'sound-activity'],
] },
}, 'lixda-par12-led': {
'static-color': { channels: ['ctrl', 'static-color', 'speed', 'dimmer', 'red', 'green', 'blue', 'white'],
'type': 'option', ranges: {
'options': [ 'ctrl': {
{'value': 0, 'label': 'All Color'}, 'type': 'option',
{'value': 40, 'label': 'Red'}, 'options': [
{'value': 50, 'label': 'Green'}, { 'value': 0, 'label': 'Off' },
{'value': 60, 'label': 'Blue'}, { 'value': 11, 'label': 'Static Color' },
{'value': 70, 'label': 'Yellow'}, { 'value': 51, 'label': 'Jump' },
{'value': 80, 'label': 'Cyan'}, { 'value': 101, 'label': 'Gradual' },
{'value': 90, 'label': 'Purple'}, { 'value': 151, 'label': 'Sound Activate' },
{'value': 100, 'label': 'White'}, { 'value': 200, 'label': 'Strobe' },
{'value': 110, 'label': 'Red + Green'}, ],
{'value': 120, 'label': 'Red + Blue'}, },
{'value': 130, 'label': 'Red + White'}, 'static-color': {
{'value': 140, 'label': 'Green + Blue'}, 'type': 'option',
{'value': 150, 'label': 'Green + White'}, 'options': [
{'value': 160, 'label': 'Blue + White'}, { 'value': 0, 'label': 'All Color' },
{'value': 170, 'label': 'Red + Green + White'}, { 'value': 40, 'label': 'Red' },
{'value': 180, 'label': 'Red + Blue + White'}, { 'value': 50, 'label': 'Green' },
{'value': 190, 'label': 'Green + Blue + White'}, { 'value': 60, 'label': 'Blue' },
{'value': 200, 'label': 'Red + Green + Blue'}, { 'value': 70, 'label': 'Yellow' },
{'value': 210, 'label': 'Red + Green + Blue + White'} { 'value': 80, 'label': 'Cyan' },
] { 'value': 90, 'label': 'Purple' },
} { 'value': 100, 'label': 'White' },
} { 'value': 110, 'label': 'Red + Green' },
}, { 'value': 120, 'label': 'Red + Blue' },
'eurolite-led-tha-120PC': { { 'value': 130, 'label': 'Red + White' },
channels: ['red', 'green', 'blue', 'white', 'dimmer', 'strobe', 'effect'] { 'value': 140, 'label': 'Green + Blue' },
}, { 'value': 150, 'label': 'Green + White' },
'briteq-bt-theatre-60FC': { { 'value': 160, 'label': 'Blue + White' },
channels: ['dimmer', 'strobe', 'effect', 'red', 'green', 'blue', 'white'] { 'value': 170, 'label': 'Red + Green + White' },
}, { 'value': 180, 'label': 'Red + Blue + White' },
'lalucenatz-led-4ch': { { 'value': 190, 'label': 'Green + Blue + White' },
channels: ['master', 'red', 'green', 'blue'] { 'value': 200, 'label': 'Red + Green + Blue' },
}, { 'value': 210, 'label': 'Red + Green + Blue + White' },
} ],
},
},
},
'eurolite-led-tha-120PC': {
channels: ['red', 'green', 'blue', 'white', 'dimmer', 'strobe', 'effect'],
},
'briteq-bt-theatre-60FC': {
channels: ['dimmer', 'strobe', 'effect', 'red', 'green', 'blue', 'white'],
},
'lalucenatz-led-4ch': {
channels: ['master', 'red', 'green', 'blue'],
},
};

View file

@ -1,129 +1,128 @@
#!/usr/bin/env node #!/usr/bin/env node
"use strict" const fs = require('fs');
const http = require('http');
var fs = require('fs') const body = require('body-parser');
var http = require('http') const express = require('express');
var body = require('body-parser') const socketio = require('socket.io');
var express = require('express') const program = require('commander');
var socketio = require('socket.io') const DMX = require('./dmx');
var program = require('commander') const A = DMX.Animation;
var DMX = require('./dmx')
var A = DMX.Animation
program program
.version("0.0.1") .version('0.0.1')
.option('-c, --config <file>', 'Read config from file [/etc/dmx-web.json]', '/etc/dmx-web.json') .option('-c, --config <file>', 'Read config from file [/etc/dmx-web.json]', '/etc/dmx-web.json')
.parse(process.argv) .parse(process.argv);
const config = JSON.parse(fs.readFileSync(program.config, 'utf8'));
var config = JSON.parse(fs.readFileSync(program.config, 'utf8'))
function DMXWeb() { function DMXWeb() {
var app = express() const app = express();
var server = http.createServer(app) const server = http.createServer(app);
var io = socketio.listen(server) const io = socketio.listen(server);
var dmx = new DMX(config) const dmx = new DMX(config);
for(var universe in config.universes) { for (const universe in config.universes) {
dmx.addUniverse( dmx.addUniverse(
universe, universe,
config.universes[universe].output.driver, config.universes[universe].output.driver,
config.universes[universe].output.device, config.universes[universe].output.device,
config.universes[universe].output.options config.universes[universe].output.options
) );
} }
var listen_port = config.server.listen_port || 8080 const listenPort = config.server.listen_port || 8080;
var listen_host = config.server.listen_host || '::' const listenHost = config.server.listen_host || '::';
server.listen(listen_port, listen_host, null, function() { server.listen(listenPort, listenHost, null, () => {
if(config.server.uid && config.server.gid) { if (config.server.uid && config.server.gid) {
try { try {
process.setuid(config.server.uid) process.setuid(config.server.uid);
process.setgid(config.server.gid) process.setgid(config.server.gid);
} catch (err) { } catch (err) {
console.log(err) console.log(err);
process.exit(1) process.exit(1);
} }
} }
}) });
app.use(body.json()) app.use(body.json());
app.get('/', function(req, res) { app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html') res.sendFile(__dirname + '/index.html');
}) });
app.get('/config', function(req, res) { app.get('/config', (req, res) => {
var response = {"devices": dmx.devices, "universes": {}} const response = {'devices': dmx.devices, 'universes': {}};
Object.keys(config.universes).forEach(function(key) {
response.universes[key] = config.universes[key].devices
})
res.json(response) Object.keys(config.universes).forEach(key => {
}) response.universes[key] = config.universes[key].devices;
});
app.get('/state/:universe', function(req, res) { res.json(response);
if(!(req.params.universe in dmx.universes)) { });
res.status(404).json({"error": "universe not found"})
return
}
res.json({"state": dmx.universeToObject(req.params.universe)}) app.get('/state/:universe', (req, res) => {
}) if (!(req.params.universe in dmx.universes)) {
res.status(404).json({'error': 'universe not found'});
return;
}
app.post('/state/:universe', function(req, res) { res.json({'state': dmx.universeToObject(req.params.universe)});
if(!(req.params.universe in dmx.universes)) { });
res.status(404).json({"error": "universe not found"})
return
}
dmx.update(req.params.universe, req.body) app.post('/state/:universe', (req, res) => {
res.json({"state": dmx.universeToObject(req.params.universe)}) if (!(req.params.universe in dmx.universes)) {
}) res.status(404).json({'error': 'universe not found'});
return;
}
app.post('/animation/:universe', function(req, res) { dmx.update(req.params.universe, req.body);
try { res.json({'state': dmx.universeToObject(req.params.universe)});
var universe = dmx.universes[req.params.universe] });
// preserve old states app.post('/animation/:universe', (req, res) => {
var old = dmx.universeToObject(req.params.universe) try {
const universe = dmx.universes[req.params.universe];
var animation = new A() // preserve old states
for(var step in req.body) { const old = dmx.universeToObject(req.params.universe);
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) { const animation = new A();
socket.emit('init', {'devices': dmx.devices, 'setup': config})
socket.on('request_refresh', function() { for (const step in req.body) {
for(var universe in config.universes) { animation.add(
socket.emit('update', universe, dmx.universeToObject(universe)) 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)});
}
});
socket.on('update', function(universe, update) { io.sockets.on('connection', socket => {
dmx.update(universe, update) socket.emit('init', {'devices': dmx.devices, 'setup': config});
})
dmx.on('update', function(universe, update) { socket.on('request_refresh', () => {
socket.emit('update', universe, update) for (const universe in config.universes) {
}) socket.emit('update', universe, dmx.universeToObject(universe));
}) }
});
socket.on('update', (universe, update) => {
dmx.update(universe, update);
});
dmx.on('update', (universe, update) => {
socket.emit('update', universe, update);
});
});
} }
DMXWeb() DMXWeb();

99
dmx.js
View file

@ -1,55 +1,58 @@
"use strict" const util = require('util');
const EventEmitter = require('events').EventEmitter;
var util = require('util') class DMX {
var EventEmitter = require('events').EventEmitter constructor(options) {
const opt = options || {};
const devices = opt.devices || {};
function DMX(options) { this.universes = {};
var options = options || {} this.drivers = {};
var devices = options.devices || {} this.devices = Object.assign({}, require('./devices'), devices);
this.universes = {} this.animation = require('./anim');
this.drivers = {}
this.devices = Object.assign({}, require('./devices'), devices);
this.animation = require('./anim')
this.registerDriver('null', require('./drivers/null')) this.registerDriver('null', require('./drivers/null'));
this.registerDriver('dmx4all', require('./drivers/dmx4all')) this.registerDriver('dmx4all', require('./drivers/dmx4all'));
this.registerDriver('enttec-usb-dmx-pro', require('./drivers/enttec-usb-dmx-pro')) this.registerDriver('enttec-usb-dmx-pro', require('./drivers/enttec-usb-dmx-pro'));
this.registerDriver('enttec-open-usb-dmx', require('./drivers/enttec-open-usb-dmx')) this.registerDriver('enttec-open-usb-dmx', require('./drivers/enttec-open-usb-dmx'));
this.registerDriver('dmxking-ultra-dmx-pro', require('./drivers/dmxking-ultra-dmx-pro')) this.registerDriver('dmxking-ultra-dmx-pro', require('./drivers/dmxking-ultra-dmx-pro'));
this.registerDriver('artnet', require('./drivers/artnet')) this.registerDriver('artnet', require('./drivers/artnet'));
this.registerDriver('bbdmx', require('./drivers/bbdmx')) this.registerDriver('bbdmx', require('./drivers/bbdmx'));
}
registerDriver(name, module) {
this.drivers[name] = module;
}
addUniverse(name, driver, deviceId, options) {
this.universes[name] = new this.drivers[driver](deviceId, options);
return this.universes[name];
}
update(universe, channels) {
this.universes[universe].update(channels);
this.emit('update', universe, channels);
}
updateAll(universe, value) {
this.universes[universe].updateAll(value);
this.emit('updateAll', universe, value);
}
universeToObject(universeKey) {
const universe = this.universes[universeKey];
const u = {};
for (let i = 0; i < 512; i++) {
u[i] = universe.get(i);
}
return u;
}
} }
util.inherits(DMX, EventEmitter) util.inherits(DMX, EventEmitter);
DMX.devices = require('./devices') DMX.devices = require('./devices');
DMX.Animation = require('./anim') DMX.Animation = require('./anim');
DMX.prototype.registerDriver = function(name, module) { module.exports = DMX;
this.drivers[name] = module
}
DMX.prototype.addUniverse = function(name, driver, device_id, options) {
return this.universes[name] = new this.drivers[driver](device_id, options)
}
DMX.prototype.update = function(universe, channels) {
this.universes[universe].update(channels)
this.emit('update', universe, channels)
}
DMX.prototype.updateAll = function(universe, value) {
this.universes[universe].updateAll(value)
this.emit('updateAll', universe, value)
}
DMX.prototype.universeToObject = function(universe) {
var universe = this.universes[universe]
var u = {}
for(var i = 0; i < 512; i++) {
u[i] = universe.get(i)
}
return u
}
module.exports = DMX

View file

@ -1,72 +1,67 @@
"use strict" const dgram = require('dgram');
var dgram = require('dgram') function EnttecODE(deviceId = '127.0.0.1', options = {}) {
const self = this;
function EnttecODE(device_id, options) { self.header = new Buffer([65, 114, 116, 45, 78, 101, 116, 0, 0, 80, 0, 14]);
var self = this self.sequence = new Buffer([0]);
self.physical = new Buffer([0]);
self.universeId = new Buffer([0x00, 0x00]);
self.length = new Buffer([0x02, 0x00]);
self.header = new Buffer([65, 114, 116, 45, 78, 101, 116, 0, 0, 80, 0, 14]) self.universe = new Buffer(513);
self.sequence = new Buffer([0]) self.universe.fill(0);
self.physical = new Buffer([0])
self.universe_id = new Buffer([0x00, 0x00])
self.length = new Buffer([0x02, 0x00])
self.universe = new Buffer(513) self.sleepTime = 24;
self.universe.fill(0)
self.sleepTime = 24 self.universe_id.writeInt16LE(options.universe || 0, 0);
self.host = deviceId;
options = options || {} self.port = options.port || 6454;
self.universe_id.writeInt16LE(options.universe || 0, 0) self.dev = dgram.createSocket('udp4');
self.host = device_id || '127.0.0.1' self.dev.bind(() => self.dev.setBroadcast(true));
self.port = options.port || 6454 self.start();
self.dev = dgram.createSocket('udp4')
self.dev.bind(function() {
self.dev.setBroadcast(true)
})
self.start()
} }
EnttecODE.prototype.send_universe = function() { EnttecODE.prototype.sendUniverse = function () {
var pkg = Buffer.concat([ const pkg = Buffer.concat([
this.header, this.header,
this.sequence, this.sequence,
this.physical, this.physical,
this.universe_id, this.universe_id,
this.length, this.length,
this.universe.slice(1) this.universe.slice(1),
]) ]);
this.dev.send(pkg, 0, pkg.length, this.port, this.host) this.dev.send(pkg, 0, pkg.length, this.port, this.host);
} };
EnttecODE.prototype.start = function() { EnttecODE.prototype.start = function () {
this.timeout = setInterval(this.send_universe.bind(this), this.sleepTime) this.timeout = setInterval(this.sendUniverse.bind(this), this.sleepTime);
} };
EnttecODE.prototype.stop = function() { EnttecODE.prototype.stop = function () {
clearInterval(this.timeout) clearInterval(this.timeout);
} };
EnttecODE.prototype.close = function(cb) { EnttecODE.prototype.close = function (cb) {
this.stop() this.stop();
cb(null) cb(null);
} };
EnttecODE.prototype.update = function(u) { EnttecODE.prototype.update = function (u) {
for (var c in u) { for (const c in u) {
this.universe[c] = u[c] this.universe[c] = u[c];
} }
} };
EnttecODE.prototype.updateAll = function(v) { EnttecODE.prototype.updateAll = function (v) {
for (var i = 1; i <= 512; i++) { for (const i = 1; i <= 512; i++) {
this.universe[i] = v this.universe[i] = v;
} }
} };
EnttecODE.prototype.get = function(c) { EnttecODE.prototype.get = function (c) {
return this.universe[c] return this.universe[c];
} };
module.exports = EnttecODE module.exports = EnttecODE;

View file

@ -1,59 +1,58 @@
'use strict' const dgram = require('dgram');
var dgram = require('dgram') const UNIVERSE_LEN = 512;
var UNIVERSE_LEN = 512 function BBDMX(deviceId = '127.0.0.1', options = {}) {
const self = this;
function BBDMX(device_id, options) { self.options = options;
var self = this self.universe = new Buffer(UNIVERSE_LEN + 1);
self.options = options || {} self.universe.fill(0);
self.universe = new Buffer(UNIVERSE_LEN + 1) self.host = deviceId;
self.universe.fill(0) self.port = self.options.port || 9930;
self.host = device_id || '127.0.0.1' self.dev = dgram.createSocket('udp4');
self.port = self.options.port || 9930 self.sleepTime = 24;
self.dev = dgram.createSocket('udp4') self.start();
self.sleepTime = 24
self.start()
} }
BBDMX.prototype.send_universe = function() { BBDMX.prototype.sendUniverse = function () {
var channel let channel;
var messageBuffer = new Buffer(UNIVERSE_LEN.toString()) let messageBuffer = new Buffer(UNIVERSE_LEN.toString());
for (var i = 1; i <= UNIVERSE_LEN; i++) { for (const i = 1; i <= UNIVERSE_LEN; i++) {
channel = new Buffer(' ' + this.universe[i]) channel = new Buffer(' ' + this.universe[i]);
messageBuffer = Buffer.concat([messageBuffer, channel]) messageBuffer = Buffer.concat([messageBuffer, channel]);
} }
this.dev.send(messageBuffer, 0, messageBuffer.length, this.port, this.host) this.dev.send(messageBuffer, 0, messageBuffer.length, this.port, this.host);
}
BBDMX.prototype.start = function() {
this.timeout = setInterval(this.send_universe.bind(this), this.sleepTime)
}
BBDMX.prototype.stop = function() {
clearInterval(this.timeout)
}
BBDMX.prototype.close = function(cb) {
this.stop()
cb(null)
}; };
BBDMX.prototype.update = function(u) { BBDMX.prototype.start = function () {
for (var c in u) { this.timeout = setInterval(this.sendUniverse.bind(this), this.sleepTime);
this.universe[c] = u[c] };
}
}
BBDMX.prototype.updateAll = function(v) { BBDMX.prototype.stop = function () {
for (var i = 1; i <= UNIVERSE_LEN; i++) { clearInterval(this.timeout);
this.universe[i] = v };
}
}
BBDMX.prototype.get = function(c) { BBDMX.prototype.close = function (cb) {
return this.universe[c] this.stop();
} cb(null);
};
module.exports = BBDMX BBDMX.prototype.update = function (u) {
for (const c in u) {
this.universe[c] = u[c];
}
};
BBDMX.prototype.updateAll = function (v) {
for (const i = 1; i <= UNIVERSE_LEN; i++) {
this.universe[i] = v;
}
};
BBDMX.prototype.get = function (c) {
return this.universe[c];
};
module.exports = BBDMX;

View file

@ -1,67 +1,66 @@
"use strict" const SerialPort = require('serialport');
var SerialPort = require("serialport") const UNIVERSE_LEN = 512;
var UNIVERSE_LEN = 512 function DMX4ALL(deviceId, options = {}) {
const self = this;
function DMX4ALL(device_id, options) { this.universe = new Buffer(UNIVERSE_LEN + 1);
var self = this this.universe.fill(0);
options = options || {}
this.universe = new Buffer(UNIVERSE_LEN + 1)
this.universe.fill(0)
this.dev = new SerialPort(device_id, { this.dev = new SerialPort(deviceId, {
'baudRate': 38400, 'baudRate': 38400,
'dataBits': 8, 'dataBits': 8,
'stopBits': 1, 'stopBits': 1,
'parity': 'none' 'parity': 'none',
}, function(err) { }, err => {
if(!err) { if (!err) {
self.send_universe() self.sendUniverse();
} }
}) });
this.dev.on('data', function(data) { this.dev.on('data', data => {
//process.stdout.write(data.toString('ascii')) // process.stdout.write(data.toString('ascii'))
}) });
} }
DMX4ALL.prototype.send_universe = function() { DMX4ALL.prototype.sendUniverse = function () {
if(!this.dev.writable) { if (!this.dev.writable) {
return return;
} }
var msg = Buffer(UNIVERSE_LEN * 3) const msg = Buffer(UNIVERSE_LEN * 3);
for(var i = 0; i < UNIVERSE_LEN; i++) {
msg[i * 3 + 0] = (i < 256) ? 0xE2 : 0xE3
msg[i * 3 + 1] = i
msg[i * 3 + 2] = this.universe[i + 1]
}
this.dev.write(msg)
}
DMX4ALL.prototype.start = function() {} for (let i = 0; i < UNIVERSE_LEN; i++) {
DMX4ALL.prototype.stop = function() {} msg[i * 3 + 0] = (i < 256) ? 0xE2 : 0xE3;
msg[i * 3 + 1] = i;
msg[i * 3 + 2] = this.universe[i + 1];
}
this.dev.write(msg);
};
DMX4ALL.prototype.close = function(cb) { DMX4ALL.prototype.start = () => {};
this.dev.close(cb) DMX4ALL.prototype.stop = () => {};
}
DMX4ALL.prototype.update = function(u) { DMX4ALL.prototype.close = function (cb) {
for(var c in u) { this.dev.close(cb);
this.universe[c] = u[c] };
}
this.send_universe()
}
DMX4ALL.prototype.updateAll = function(v){ DMX4ALL.prototype.update = function (u) {
for(var i = 1; i <= 512; i++) { for (const c in u) {
this.universe[i] = v this.universe[c] = u[c];
} }
this.send_universe() this.sendUniverse();
} };
DMX4ALL.prototype.get = function(c) { DMX4ALL.prototype.updateAll = function (v) {
return this.universe[c] for (let i = 1; i <= 512; i++) {
} this.universe[i] = v;
}
this.sendUniverse();
};
module.exports = DMX4ALL DMX4ALL.prototype.get = function (c) {
return this.universe[c];
};
module.exports = DMX4ALL;

View file

@ -1,83 +1,82 @@
"use strict" const SerialPort = require('serialport');
var SerialPort = require("serialport") const DMXKING_ULTRA_DMX_PRO_DMX_STARTCODE = 0x00;
const DMXKING_ULTRA_DMX_PRO_START_OF_MSG = 0x7e;
const DMXKING_ULTRA_DMX_PRO_END_OF_MSG = 0xe7;
const DMXKING_ULTRA_DMX_PRO_SEND_DMX_RQ = 0x06;
const DMXKING_ULTRA_DMX_PRO_SEND_DMX_A_RQ = 0x64;
const DMXKING_ULTRA_DMX_PRO_SEND_DMX_B_RQ = 0x65;
// var DMXKING_ULTRA_DMX_PRO_RECV_DMX_PKT = 0x05;
var DMXKING_ULTRA_DMX_PRO_DMX_STARTCODE = 0x00 function DMXKingUltraDMXPro(deviceId, options = {}) {
, DMXKING_ULTRA_DMX_PRO_START_OF_MSG = 0x7e const self = this;
, DMXKING_ULTRA_DMX_PRO_END_OF_MSG = 0xe7
, DMXKING_ULTRA_DMX_PRO_SEND_DMX_RQ = 0x06
, DMXKING_ULTRA_DMX_PRO_SEND_DMX_A_RQ = 0x64
, DMXKING_ULTRA_DMX_PRO_SEND_DMX_B_RQ = 0x65
, DMXKING_ULTRA_DMX_PRO_RECV_DMX_PKT = 0x05
;
function DMXKingUltraDMXPro(device_id, options) { this.options = options;
var self = this this.universe = Buffer.alloc(513, 0);
this.options = options || {}
this.universe = Buffer.alloc(513, 0);
this.sendDMXReq = DMXKING_ULTRA_DMX_PRO_SEND_DMX_RQ this.sendDMXReq = DMXKING_ULTRA_DMX_PRO_SEND_DMX_RQ;
if (this.options.port === "A") { if (this.options.port === 'A') {
this.sendDMXReq = DMXKING_ULTRA_DMX_PRO_SEND_DMX_A_RQ this.sendDMXReq = DMXKING_ULTRA_DMX_PRO_SEND_DMX_A_RQ;
} else if (this.options.port === "B") { } else if (this.options.port === 'B') {
this.sendDMXReq = DMXKING_ULTRA_DMX_PRO_SEND_DMX_B_RQ this.sendDMXReq = DMXKING_ULTRA_DMX_PRO_SEND_DMX_B_RQ;
} }
this.dev = new SerialPort(device_id, { this.dev = new SerialPort(deviceId, {
'baudRate': 250000, 'baudRate': 250000,
'dataBits': 8, 'dataBits': 8,
'stopBits': 2, 'stopBits': 2,
'parity': 'none' 'parity': 'none',
}, function(err) { }, err => {
if(!err) { if (!err) {
self.send_universe() self.sendUniverse();
} }
}) });
} }
DMXKingUltraDMXPro.prototype.send_universe = function() { DMXKingUltraDMXPro.prototype.sendUniverse = function () {
if(!this.dev.writable) { if (!this.dev.writable) {
return return;
} }
var hdr = Buffer.from([ const hdr = Buffer.from([
DMXKING_ULTRA_DMX_PRO_START_OF_MSG, DMXKING_ULTRA_DMX_PRO_START_OF_MSG,
this.sendDMXReq, this.sendDMXReq,
(this.universe.length) & 0xff, (this.universe.length) & 0xff,
((this.universe.length) >> 8) & 0xff, ((this.universe.length) >> 8) & 0xff,
DMXKING_ULTRA_DMX_PRO_DMX_STARTCODE DMXKING_ULTRA_DMX_PRO_DMX_STARTCODE,
]) ]);
var msg = Buffer.concat([ const msg = Buffer.concat([
hdr, hdr,
this.universe.slice(1), this.universe.slice(1),
Buffer.from([DMXKING_ULTRA_DMX_PRO_END_OF_MSG]) Buffer.from([DMXKING_ULTRA_DMX_PRO_END_OF_MSG]),
]) ]);
this.dev.write(msg)
}
DMXKingUltraDMXPro.prototype.start = function() {} this.dev.write(msg);
DMXKingUltraDMXPro.prototype.stop = function() {} };
DMXKingUltraDMXPro.prototype.close = function(cb) { DMXKingUltraDMXPro.prototype.start = () => { };
this.dev.close(cb) DMXKingUltraDMXPro.prototype.stop = () => { };
}
DMXKingUltraDMXPro.prototype.update = function(u) { DMXKingUltraDMXPro.prototype.close = function (cb) {
for(var c in u) { this.dev.close(cb);
this.universe[c] = u[c] };
}
this.send_universe()
}
DMXKingUltraDMXPro.prototype.updateAll = function(v){ DMXKingUltraDMXPro.prototype.update = function (u) {
for(var i = 1; i <= 512; i++) { for (const c in u) {
this.universe[i] = v this.universe[c] = u[c];
} }
this.send_universe() this.sendUniverse();
} };
DMXKingUltraDMXPro.prototype.get = function(c) { DMXKingUltraDMXPro.prototype.updateAll = function (v) {
return this.universe[c] for (let i = 1; i <= 512; i++) {
} this.universe[i] = v;
}
this.sendUniverse();
};
module.exports = DMXKingUltraDMXPro DMXKingUltraDMXPro.prototype.get = function (c) {
return this.universe[c];
};
module.exports = DMXKingUltraDMXPro;

View file

@ -1,75 +1,75 @@
"use strict" const SerialPort = require('serialport');
var SerialPort = require("serialport") function EnttecOpenUsbDMX(deviceId, options) {
const self = this;
function EnttecOpenUsbDMX(device_id, options) { options = options || {};
var self = this
options = options || {}
this.universe = new Buffer(513) this.universe = new Buffer(513);
this.universe.fill(0) this.universe.fill(0);
self.interval = 46 self.interval = 46;
this.dev = new SerialPort(device_id, { this.dev = new SerialPort(deviceId, {
'baudRate': 250000, 'baudRate': 250000,
'dataBits': 8, 'dataBits': 8,
'stopBits': 2, 'stopBits': 2,
'parity': 'none' 'parity': 'none',
}, function(err) { }, err => {
if(err) { if (err) {
console.log(err) console.log(err);
return return;
} }
self.start() self.start();
}) });
} }
EnttecOpenUsbDMX.prototype.send_universe = function() { EnttecOpenUsbDMX.prototype.sendUniverse = function () {
var self = this const self = this;
if(!this.dev.writable) {
return
}
// toggle break if (!this.dev.writable) {
self.dev.set({brk: true, rts: true}, function(err, r) { return;
setTimeout(function() { }
self.dev.set({brk: false, rts: true}, function(err, r) {
setTimeout(function() {
self.dev.write(Buffer.concat([Buffer([0]), self.universe.slice(1)]))
}, 1)
})
}, 1)
})
}
EnttecOpenUsbDMX.prototype.start = function() { // toggle break
this.intervalhandle = setInterval(this.send_universe.bind(this), this.interval) self.dev.set({brk: true, rts: true}, (err, r) => {
} setTimeout(() => {
self.dev.set({brk: false, rts: true}, (err, r) => {
setTimeout(() => {
self.dev.write(Buffer.concat([Buffer([0]), self.universe.slice(1)]));
}, 1);
});
}, 1);
});
};
EnttecOpenUsbDMX.prototype.stop = function() { EnttecOpenUsbDMX.prototype.start = function () {
clearInterval(this.intervalhandle) this.intervalhandle = setInterval(this.sendUniverse.bind(this), this.interval);
} };
EnttecOpenUsbDMX.prototype.close = function(cb) { EnttecOpenUsbDMX.prototype.stop = function () {
this.stop() clearInterval(this.intervalhandle);
this.dev.close(cb) };
}
EnttecOpenUsbDMX.prototype.update = function(u) { EnttecOpenUsbDMX.prototype.close = function (cb) {
for(var c in u) { this.stop();
this.universe[c] = u[c] this.dev.close(cb);
} };
}
EnttecOpenUsbDMX.prototype.updateAll = function(v) { EnttecOpenUsbDMX.prototype.update = function (u) {
for(var i = 1; i <= 512; i++) { for (const c in u) {
this.universe[i] = v this.universe[c] = u[c];
} }
} };
EnttecOpenUsbDMX.prototype.get = function(c) { EnttecOpenUsbDMX.prototype.updateAll = function (v) {
return this.universe[c] for (let i = 1; i <= 512; i++) {
} this.universe[i] = v;
}
};
module.exports = EnttecOpenUsbDMX EnttecOpenUsbDMX.prototype.get = function (c) {
return this.universe[c];
};
module.exports = EnttecOpenUsbDMX;

View file

@ -1,74 +1,72 @@
"use strict" const SerialPort = require('serialport');
var SerialPort = require("serialport") const ENTTEC_PRO_DMX_STARTCODE = 0x00;
const ENTTEC_PRO_START_OF_MSG = 0x7e;
const ENTTEC_PRO_END_OF_MSG = 0xe7;
const ENTTEC_PRO_SEND_DMX_RQ = 0x06;
// var ENTTEC_PRO_RECV_DMX_PKT = 0x05;
var ENTTEC_PRO_DMX_STARTCODE = 0x00 function EnttecUSBDMXPRO(deviceId, options = {}) {
, ENTTEC_PRO_START_OF_MSG = 0x7e const self = this;
, ENTTEC_PRO_END_OF_MSG = 0xe7
, ENTTEC_PRO_SEND_DMX_RQ = 0x06
, ENTTEC_PRO_RECV_DMX_PKT = 0x05
;
function EnttecUSBDMXPRO(device_id, options) { this.universe = Buffer.alloc(513, 0);
var self = this
options = options || {}
this.universe = Buffer.alloc(513, 0);
this.dev = new SerialPort(device_id, { this.dev = new SerialPort(deviceId, {
'baudRate': 250000, 'baudRate': 250000,
'dataBits': 8, 'dataBits': 8,
'stopBits': 2, 'stopBits': 2,
'parity': 'none' 'parity': 'none',
}, function(err) { }, err => {
if(!err) { if (!err) {
self.send_universe() self.sendUniverse();
} }
}) });
} }
EnttecUSBDMXPRO.prototype.send_universe = function() { EnttecUSBDMXPRO.prototype.sendUniverse = function () {
if(!this.dev.writable) { if (!this.dev.writable) {
return return;
} }
var hdr = Buffer.from([ const hdr = Buffer.from([
ENTTEC_PRO_START_OF_MSG, ENTTEC_PRO_START_OF_MSG,
ENTTEC_PRO_SEND_DMX_RQ, ENTTEC_PRO_SEND_DMX_RQ,
(this.universe.length) & 0xff, (this.universe.length) & 0xff,
((this.universe.length) >> 8) & 0xff, ((this.universe.length) >> 8) & 0xff,
ENTTEC_PRO_DMX_STARTCODE ENTTEC_PRO_DMX_STARTCODE,
]) ]);
var msg = Buffer.concat([ const msg = Buffer.concat([
hdr, hdr,
this.universe.slice(1), this.universe.slice(1),
Buffer.from([ENTTEC_PRO_END_OF_MSG]) Buffer.from([ENTTEC_PRO_END_OF_MSG]),
]) ]);
this.dev.write(msg)
}
EnttecUSBDMXPRO.prototype.start = function() {} this.dev.write(msg);
EnttecUSBDMXPRO.prototype.stop = function() {} };
EnttecUSBDMXPRO.prototype.close = function(cb) { EnttecUSBDMXPRO.prototype.start = () => { };
this.dev.close(cb) EnttecUSBDMXPRO.prototype.stop = () => { };
}
EnttecUSBDMXPRO.prototype.update = function(u) { EnttecUSBDMXPRO.prototype.close = function (cb) {
for(var c in u) { this.dev.close(cb);
this.universe[c] = u[c] };
}
this.send_universe()
}
EnttecUSBDMXPRO.prototype.updateAll = function(v){ EnttecUSBDMXPRO.prototype.update = function (u) {
for(var i = 1; i <= 512; i++) { for (const c in u) {
this.universe[i] = v this.universe[c] = u[c];
} }
this.send_universe() this.sendUniverse();
} };
EnttecUSBDMXPRO.prototype.get = function(c) { EnttecUSBDMXPRO.prototype.updateAll = function (v) {
return this.universe[c] for (let i = 1; i <= 512; i++) {
} this.universe[i] = v;
}
this.sendUniverse();
};
module.exports = EnttecUSBDMXPRO EnttecUSBDMXPRO.prototype.get = function (c) {
return this.universe[c];
};
module.exports = EnttecUSBDMXPRO;

View file

@ -1,42 +1,42 @@
"use strict" function Null(deviceId, options) {
const self = this;
function Null(device_id, options) { options = options || {};
var self = this this.universe = Buffer.alloc(513, 0);
options = options || {} self.start();
this.universe = Buffer.alloc(513, 0);
self.start()
} }
Null.prototype.start = function() { Null.prototype.start = function () {
var self = this const self = this;
self.timeout = setInterval(function() {
console.log(self.universe)
}, 1000)
}
Null.prototype.stop = function() { self.timeout = setInterval(() => {
clearInterval(this.timeout) console.log(self.universe);
} }, 1000);
};
Null.prototype.close = function(cb) { Null.prototype.stop = function () {
cb(null) clearInterval(this.timeout);
} };
Null.prototype.update = function(u) { Null.prototype.close = cb => {
for(var c in u) { cb(null);
this.universe[c] = u[c] };
}
console.log(this.universe.slice(1))
}
Null.prototype.updateAll = function(v){ Null.prototype.update = function (u) {
for(var i = 1; i <= 512; i++) { for (const c in u) {
this.universe[i] = v this.universe[c] = u[c];
} }
} console.log(this.universe.slice(1));
};
Null.prototype.get = function(c) { Null.prototype.updateAll = function (v) {
return this.universe[c] for (let i = 1; i <= 512; i++) {
} this.universe[i] = v;
}
};
module.exports = Null Null.prototype.get = function (c) {
return this.universe[c];
};
module.exports = Null;

239
easing.js
View file

@ -35,124 +35,127 @@
// t: current time, b: begInnIng value, c: change In value, d: duration // t: current time, b: begInnIng value, c: change In value, d: duration
exports.ease = { exports.ease = {
linear: function (t, b, c, d) { return c * t/d + b; }, linear(t, b, c, d) { return c * t / d + b; },
inQuad: function (t, b, c, d) { return c * (t/=d) * t + b; }, inQuad(t, b, c, d) { return c * (t /= d) * t + b; },
outQuad: function (t, b, c, d) { return -c * (t/=d) * (t-2) + b; }, outQuad(t, b, c, d) { return -c * (t /= d) * (t - 2) + b; },
inOutQuad: function (t, b, c, d) { inOutQuad(t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t + b; if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c/2 * ((--t)*(t-2) - 1) + b; return -c / 2 * ((--t) * (t - 2) - 1) + b;
}, },
inCubic: function (t, b, c, d) { return c*(t/=d)*t*t + b; }, inCubic(t, b, c, d) { return c * (t /= d) * t * t + b; },
outCubic: function (t, b, c, d) { return c*((t=t/d-1)*t*t + 1) + b; }, outCubic(t, b, c, d) { return c * ((t = t / d - 1) * t * t + 1) + b; },
inOutCubic: function (t, b, c, d) { inOutCubic(t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t*t + b; if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
return c/2*((t-=2)*t*t + 2) + b; return c / 2 * ((t -= 2) * t * t + 2) + b;
}, },
inQuart: function (t, b, c, d) { inQuart(t, b, c, d) {
return c*(t/=d)*t*t*t + b; return c * (t /= d) * t * t * t + b;
}, },
outQuart: function (t, b, c, d) { outQuart(t, b, c, d) {
return -c * ((t=t/d-1)*t*t*t - 1) + b; return -c * ((t = t / d - 1) * t * t * t - 1) + b;
}, },
inOutQuart: function (t, b, c, d) { inOutQuart(t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t*t*t + b; if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c/2 * ((t-=2)*t*t*t - 2) + b; return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}, },
inQuint: function (t, b, c, d) { inQuint(t, b, c, d) {
return c*(t/=d)*t*t*t*t + b; return c * (t /= d) * t * t * t * t + b;
}, },
outQuint: function (t, b, c, d) { outQuint(t, b, c, d) {
return c*((t=t/d-1)*t*t*t*t + 1) + b; return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
}, },
inOutQuint: function (t, b, c, d) { inOutQuint(t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
return c/2*((t-=2)*t*t*t*t + 2) + b; return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
}, },
inSine: function (t, b, c, d) { inSine(t, b, c, d) {
return -c * Math.cos(t/d * (Math.PI/2)) + c + b; return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
}, },
outSine: function (t, b, c, d) { outSine(t, b, c, d) {
return c * Math.sin(t/d * (Math.PI/2)) + b; return c * Math.sin(t / d * (Math.PI / 2)) + b;
}, },
inOutSine: function (t, b, c, d) { inOutSine(t, b, c, d) {
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
}, },
inExpo: function (t, b, c, d) { inExpo(t, b, c, d) {
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; return (t === 0) ? b : c * (2 ** (10 * (t / d - 1))) + b;
}, },
outExpo: function (t, b, c, d) { outExpo(t, b, c, d) {
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; return (t === d) ? b + c : c * (-(2 ** (-10 * t / d)) + 1) + b;
}, },
inOutExpo: function (t, b, c, d) { inOutExpo(t, b, c, d) {
if (t==0) return b; if (t === 0) return b;
if (t==d) return b+c; if (t === d) return b + c;
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; if ((t /= d / 2) < 1) return c / 2 * (2 ** (10 * (t - 1))) + b;
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; return c / 2 * (-(2 ** (-10 * --t)) + 2) + b;
}, },
inCirc: function (t, b, c, d) { inCirc(t, b, c, d) {
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
}, },
outCirc: function (t, b, c, d) { outCirc(t, b, c, d) {
return c * Math.sqrt(1 - (t=t/d-1)*t) + b; return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
}, },
inOutCirc: function (t, b, c, d) { inOutCirc(t, b, c, d) {
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
}, },
inElastic: function (t, b, c, d) { inElastic(t, b, c, d) {
var s=1.70158;var p=0;var a=c; let s = 1.70158; let p = 0; let a = c;
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
if (a < Math.abs(c)) { a=c; var s=p/4; } if (t === 0) return b; if ((t /= d) === 1) return b + c; if (!p) p = d * 0.3;
else var s = p/(2*Math.PI) * Math.asin (c/a); if (a < Math.abs(c)) { a = c; s = p / 4; } else s = p / (2 * Math.PI) * Math.asin(c / a);
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
}, return -(a * (2 ** (10 * (t -= 1))) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
outElastic: function (t, b, c, d) { },
var s=1.70158;var p=0;var a=c; outElastic(t, b, c, d) {
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; let s = 1.70158; let p = 0; let a = c;
if (a < Math.abs(c)) { a=c; var s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a); if (t === 0) return b; if ((t /= d) === 1) return b + c; if (!p) p = d * 0.3;
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; if (a < Math.abs(c)) { a = c; s = p / 4; } else s = p / (2 * Math.PI) * Math.asin(c / a);
},
inOutElastic: function (t, b, c, d) { return a * (2 ** (-10 * t)) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
var s=1.70158;var p=0;var a=c; },
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); inOutElastic(t, b, c, d) {
if (a < Math.abs(c)) { a=c; var s=p/4; } let s = 1.70158; let p = 0; let a = c;
else var s = p/(2*Math.PI) * Math.asin (c/a);
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; if (t === 0) return b; if ((t /= d / 2) === 2) return b + c; if (!p) p = d * (0.3 * 1.5);
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; if (a < Math.abs(c)) { a = c; s = p / 4; } else s = p / (2 * Math.PI) * Math.asin(c / a);
},
inBack: function (t, b, c, d, s) { if (t < 1) return -0.5 * (a * (2 ** (10 * (t -= 1))) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
if (s == undefined) s = 1.70158; return a * (2 ** (-10 * (t -= 1))) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + c + b;
return c*(t/=d)*t*((s+1)*t - s) + b; },
}, inBack(t, b, c, d, s) {
outBack: function (t, b, c, d, s) { if (s === undefined) s = 1.70158;
if (s == undefined) s = 1.70158; return c * (t /= d) * t * ((s + 1) * t - s) + b;
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; },
}, outBack(t, b, c, d, s) {
inOutBack: function (t, b, c, d, s) { if (s === undefined) s = 1.70158;
if (s == undefined) s = 1.70158; return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; },
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; inOutBack(t, b, c, d, s) {
}, if (s === undefined) s = 1.70158;
inBounce: function (t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
return c - exports.ease.outBounce (d-t, 0, c, d) + b; return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
}, },
outBounce: function (t, b, c, d) { inBounce(t, b, c, d) {
if ((t/=d) < (1/2.75)) { return c - exports.ease.outBounce(d - t, 0, c, d) + b;
return c*(7.5625*t*t) + b; },
} else if (t < (2/2.75)) { outBounce(t, b, c, d) {
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; if ((t /= d) < (1 / 2.75)) {
} else if (t < (2.5/2.75)) { return c * (7.5625 * t * t) + b;
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; } else if (t < (2 / 2.75)) {
} else { return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; } else if (t < (2.5 / 2.75)) {
} return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
}, }
inOutBounce: function (t, b, c, d) { return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
if (t < d/2) return exports.ease.inBounce (t*2, 0, c, d) * .5 + b;
return exports.ease.outBounce (t*2-d, 0, c, d) * .5 + c*.5 + b; },
} inOutBounce(t, b, c, d) {
} if (t < d / 2) return exports.ease.inBounce(t * 2, 0, c, d) * 0.5 + b;
return exports.ease.outBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
},
};
/* /*
* *

View file

@ -1,35 +1,36 @@
{ {
"name": "dmx", "name": "dmx",
"version": "0.1.1", "version": "0.2.0",
"author": "Sebastian Wiedenroth <wiedi@frubar.net>", "author": "Sebastian Wiedenroth <wiedi@frubar.net>",
"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", "bin": {
"bin": { "dmx-web": "./dmx.js"
"dmx-web": "./dmx-web.js" },
}, "scripts": {
"repository": { "test": "node_modules/eslint/bin/eslint.js -c .eslintrc .; exit 0"
"type": "git", },
"url": "https://github.com/wiedi/node-dmx.git" "repository": {
}, "type": "git",
"keywords": [ "url": "https://github.com/wiedi/node-dmx.git"
"DMX", },
"light control" "keywords": [
], "DMX",
"dependencies": { "light control"
"serialport": "^6.0.4", ],
"socket.io": "^2.0.4", "dependencies": {
"express": "^4.16.2", "body-parser": "^1.5.2",
"body-parser": "^1.5.2", "commander": "^2.12.2",
"commander": "^2.12.2" "express": "^4.16.2",
}, "serialport": "^6.0.4",
"licenses": [ "socket.io": "^2.0.4"
{ },
"name": "MIT", "devDependencies": {
"url": "http://www.opensource.org/licenses/mit-license.php" "babel-eslint": "^10.0.1",
} "eslint": "^5.0.1"
], },
"engines": { "license": "MIT",
"node": ">=5.1.0" "engines": {
} "node": ">=10.0.0"
}
} }