Skip to content

Commit

Permalink
Introduce abstract class for serial devices, fix Enttec Open USB
Browse files Browse the repository at this point in the history
Should fix node-dmx#93
References node-dmx#99
  • Loading branch information
Granjow committed Mar 25, 2021
1 parent 912eb43 commit fa220f7
Show file tree
Hide file tree
Showing 19 changed files with 581 additions and 622 deletions.
317 changes: 184 additions & 133 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
],
"dependencies": {
"sacn": "^3.2.1",
"serialport": "^8.0.5",
"serialport": "^9.0.7",
"socket.io": "^2.3.0"
},
"devDependencies": {
Expand Down
4 changes: 3 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ DMX-512 controller library for node.js

## Install

npm install dmx
```bash
npm install dmx
```

## Library API
```javascript
Expand Down
80 changes: 46 additions & 34 deletions spec/anim.spec.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,60 @@
import {DMX, Animation} from '../src';
import { NullDriver } from '../src/drivers/null';
import {Animation, DMX} from '../src';
import {NullDriver} from '../src/drivers/null';
import {IUniverseDriver} from '../src/models/IUniverseDriver';

const dmx = new DMX();
const universe = dmx.addUniverse('test', new NullDriver());
describe('Animations', () => {

const updateMock = jest.fn();
let dmx: DMX;
let universeDriver: IUniverseDriver;

universe.update = updateMock;
universe.update({ 1: 255 });
beforeEach(async () => {
dmx = new DMX();
universeDriver = new NullDriver();
await dmx.addUniverse('test', universeDriver);
});

const ANIM_PRECISION = 50;
const ANIM_PRECISION = 50;

test('fake timers', () => {
jest.useFakeTimers();
test('fake timers', () => {
const updateMock = jest.fn();

new Animation().add({
1: 255,
}, 100).add({
1: 0,
}, 100).run(universe);
universeDriver.update = updateMock;
universeDriver.update({1: 255});

jest.runAllTimers();
jest.useFakeTimers();

expect(updateMock).toHaveBeenCalledWith({ 1: 255 }, { origin: 'animation' });
expect(updateMock).toHaveBeenCalledWith({ 1: 0 }, { origin: 'animation' });
});
new Animation().add({
1: 255,
}, 100).add({
1: 0,
}, 100).run(universeDriver);

test('real timers', done => {
jest.useRealTimers();
jest.runAllTimers();

const startAt = Date.now();
expect(updateMock).toHaveBeenCalledWith({1: 255}, {origin: 'animation'});
expect(updateMock).toHaveBeenCalledWith({1: 0}, {origin: 'animation'});
});

new Animation().add({
1: 255,
}, 250).add({
1: 0,
}, 250).run(universe, async () => {
await universe.stop();
await universe.close();
const timeTook = Date.now() - startAt;
test('real timers', done => {
universeDriver.update = jest.fn();
universeDriver.update({1: 255});

expect(timeTook).toBeGreaterThanOrEqual(500 - ANIM_PRECISION);
expect(timeTook).toBeLessThanOrEqual(500 + ANIM_PRECISION);
done();
});
jest.useRealTimers();

const startAt = Date.now();

new Animation().add({
1: 255,
}, 250).add({
1: 0,
}, 250).run(universeDriver, async () => {
await universeDriver.close();
const timeTook = Date.now() - startAt;

expect(timeTook).toBeGreaterThanOrEqual(500 - ANIM_PRECISION);
expect(timeTook).toBeLessThanOrEqual(500 + ANIM_PRECISION);
done();
});

});
});
13 changes: 10 additions & 3 deletions src/DMX.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export class DMX extends EventEmitter {
this._devices = Object.assign({}, PredefinedDevices, devices);
}

addUniverse(name: string, universe: IUniverseDriver): IUniverseDriver {
async addUniverse(name: string, universe: IUniverseDriver): Promise<IUniverseDriver> {
await universe.init();

universe.on(Events.update, (channels, extraData) => {
this.emit(Events.update, name, channels, extraData);
});
Expand All @@ -27,8 +29,12 @@ export class DMX extends EventEmitter {
return universe;
}

update(universe: string, channels: {[key: number]: number}, extraData?: any): void {
this._universesByName.get(universe)?.update(channels, extraData || {});
update(universeName: string, channels: {[key: number]: number}, extraData?: any): void {
const universe = this._universesByName.get( universeName );
if ( universe === undefined ) {
throw new Error( `Universe ${universe} does not exist` );
}
universe.update( channels, extraData || {} );
}

updateAll(universe: string, value: number): void {
Expand All @@ -51,5 +57,6 @@ export class DMX extends EventEmitter {
for (const uni of this._universesByName.values()) {
await uni.close();
}
this.removeAllListeners();
}
}
129 changes: 50 additions & 79 deletions src/demo/demo.ts
Original file line number Diff line number Diff line change
@@ -1,86 +1,57 @@
import { Animation } from '../Animation';
import { NullDriver } from '../drivers/null';
import { DMX } from '../';
import { IUniverseDriver, UniverseData } from '../models/IUniverseDriver';

const dmx = new DMX();

// 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')
// const universe = dmx.addUniverse('demo', 'socketio', null, {port: 17809, debug: true});
const universe = dmx.addUniverse('demo', new NullDriver());

universe.update({1: 1, 2: 0});
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});

function greenWater(universe: IUniverseDriver, channels: UniverseData, duration: number): void {
const colors = [
[160, 230, 20],
[255, 255, 0],
[110, 255, 10],
];

for (const c in channels) {
const r = Math.floor((Math.random() * colors.length));
const u: UniverseData = {};

for (let i = 0; i < 3; i++) {
u[channels[c] + i] = colors[r][i];
import {Animation} from '../Animation';
import {NullDriver} from '../drivers/null';
import {DMX} from '../';
import {IUniverseDriver, UniverseData} from '../models/IUniverseDriver';

const run = async () => {

const dmx = new DMX();

// 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')
// const universe = dmx.addUniverse('demo', 'socketio', null, {port: 17809, debug: true});
const universe = await dmx.addUniverse('demo', new NullDriver());

universe.update({1: 1, 2: 0});
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});

function greenWater(universe: IUniverseDriver, channels: UniverseData, duration: number): void {
const colors = [
[160, 230, 20],
[255, 255, 0],
[110, 255, 10],
];

for (const c in channels) {
const r = Math.floor((Math.random() * colors.length));
const u: UniverseData = {};

for (let i = 0; i < 3; i++) {
u[channels[c] + i] = colors[r][i];
}
new Animation().add(u, duration).run(universe);
}
new Animation().add(u, duration).run(universe);
setTimeout(() => greenWater(universe, channels, duration), duration * 2);
}
setTimeout(() => greenWater(universe, channels, duration), duration * 2);
}

function warp(universe: IUniverseDriver, channel: number, min: number, max: number, duration: number): void {
const a: UniverseData = {};
const b: UniverseData = {};
function warp(universe: IUniverseDriver, channel: number, min: number, max: number, duration: number): void {
const a: UniverseData = {};
const b: UniverseData = {};

a[channel] = min;
b[channel] = max;
new Animation().add(a, duration).add(b, duration).run(universe, function () {
warp(universe, channel, min, max, duration);
});
}

warp(universe, 1, 200, 220, 360);
warp(universe, 1 + 15, 200, 255, 240);
greenWater(universe, [3, 6, 9], 4000);
greenWater(universe, [3 + 15, 6 + 15, 9 + 15], 4000);
a[channel] = min;
b[channel] = max;
new Animation().add(a, duration).add(b, duration).run(universe, function () {
warp(universe, channel, min, max, duration);
});
}

// function done() { console.log('DONE'); }
//
// const x = new A()
// .add({1: 255, 6: 110, 7: 255, 8: 10}, 1200)
// .delay(1000)
// .add({1: 0}, 600)
// .add({1: 255}, 600)
// .add({5: 255, 6: 128}, 1000)
// .add({1: 0}, 100)
// .add({1: 255}, 100)
// .add({1: 0}, 200)
// .add({1: 255}, 200)
// .add({1: 0}, 100)
// .add({1: 255}, 100)
// .add({1: 0})
// .delay(50)
// .add({1: 255})
// .delay(50)
// .add({1: 0})
// .delay(50)
// .add({1: 255})
// .delay(50)
// .add({1: 0})
// .delay(50)
// .add({1: 255})
// .delay(50)
// .add({2: 255}, 6000)
// .delay(200)
// .add({2: 0});
warp(universe, 1, 200, 220, 360);
warp(universe, 1 + 15, 200, 255, 240);
greenWater(universe, [3, 6, 9], 4000);
greenWater(universe, [3 + 15, 6 + 15, 9 + 15], 4000);

// const y = new A()
// .add({9: 255}, 10000);
};

// x.run(universe, done);
// y.run(universe, done);
run()
.catch((err) => console.error(err));
33 changes: 19 additions & 14 deletions src/demo/demo_simple.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import { NullDriver } from '../drivers/null';
import {NullDriver} from '../drivers/null';
import {DMX} from '../index';

const dmx = new DMX();

// var universe = dmx.addUniverse('demo', 'enttec-open-usb-dmx', '/dev/cu.usbserial-6AVNHXS8')
// const universe = dmx.addUniverse('demo', 'socketio', null, {port: 17809, debug: true});
const universe = dmx.addUniverse('demo', new NullDriver());
const run = async () => {
const universe = await dmx.addUniverse('demo', new NullDriver());

let on = false;
let on = false;

setInterval(() => {
if (on) {
on = false;
universe.updateAll(0);
console.log('off');
} else {
on = true;
universe.updateAll(250);
console.log('on');
}
}, 1000);
setInterval(() => {
if (on) {
on = false;
universe.updateAll(0);
console.log('off');
} else {
on = true;
universe.updateAll(250);
console.log('on');
}
}, 1000);
};

run()
.catch((err) => console.error(err));
Loading

0 comments on commit fa220f7

Please sign in to comment.