1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.EnttecOpenDMXUSBDevice = exports.PRODUCT_ID = exports.VENDOR_ID = void 0;
|
4 | const eventemitter3_1 = require("eventemitter3");
|
5 | const serialport_1 = require("serialport");
|
6 | exports.VENDOR_ID = "0403";
|
7 | exports.PRODUCT_ID = "6001";
|
8 | class EnttecOpenDMXUSBDevice extends eventemitter3_1.EventEmitter {
|
9 | |
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | constructor(path, startSending = true, usleep = null) {
|
16 | super();
|
17 | this.shouldBeSending = false;
|
18 | this.sendTimeout = null;
|
19 | this.buffer = Buffer.alloc(513);
|
20 | this.port = new serialport_1.SerialPort({
|
21 | path,
|
22 | baudRate: 250000,
|
23 | dataBits: 8,
|
24 | stopBits: 2,
|
25 | parity: "none",
|
26 | autoOpen: true
|
27 | });
|
28 | this.port.on("open", () => {
|
29 | this.emit("ready");
|
30 | if (startSending)
|
31 | this.startSending(0);
|
32 | });
|
33 |
|
34 | this.port.on("error", (error) => {
|
35 | this.emit("error", error);
|
36 | });
|
37 | this.usleep = usleep;
|
38 | }
|
39 | |
40 |
|
41 |
|
42 |
|
43 |
|
44 | startSending(interval = 0) {
|
45 | if (!this.port.isOpen)
|
46 | throw new Error("The device is not ready yet. Wait for the 'ready' event.");
|
47 | this.shouldBeSending = true;
|
48 |
|
49 | const send = () => {
|
50 | this._sendUniverse()
|
51 | .then(() => {
|
52 | if (this.shouldBeSending)
|
53 |
|
54 | this.sendTimeout = setTimeout(send, interval);
|
55 | })
|
56 | .catch(error => this.emit("error", error));
|
57 | };
|
58 | send();
|
59 | }
|
60 | |
61 |
|
62 |
|
63 | stopSending() {
|
64 | this.shouldBeSending = false;
|
65 | if (this.sendTimeout !== null)
|
66 | clearTimeout(this.sendTimeout);
|
67 | }
|
68 | |
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | setChannels(channels, clear = false) {
|
76 | if (clear) {
|
77 | this.buffer = Buffer.alloc(513);
|
78 | this.buffer[0] = 0;
|
79 | }
|
80 | if (Buffer.isBuffer(channels)) {
|
81 | if (channels.length > 512)
|
82 | throw new Error("The maximum size of an DMX universe is 512 channels.");
|
83 | channels.copy(this.buffer, 1);
|
84 | }
|
85 | else if (Array.isArray(channels)) {
|
86 | if (channels.length > 512)
|
87 | throw new Error("The maximum size of an DMX universe is 512 channels.");
|
88 | channels.forEach((value, index) => {
|
89 | if (value > 0xFF || value < 0)
|
90 | throw new Error("All values must be between 0 and 255.");
|
91 | this.buffer[index + 1] = value;
|
92 | });
|
93 | }
|
94 | else if (typeof channels === "object") {
|
95 | Object.entries(channels).forEach(([channel, value]) => {
|
96 | let channelNumber;
|
97 | try {
|
98 | channelNumber = Number.parseInt(channel, 10);
|
99 | }
|
100 | catch {
|
101 | throw new Error("Only channel numbers are supported.");
|
102 | }
|
103 | if (channelNumber > 512 || channelNumber < 1)
|
104 | throw new Error("All channel numbers must be between 1 and 512.");
|
105 | else if (value > 0xFF || value < 0)
|
106 | throw new Error("All values must be between 0 and 255.");
|
107 | this.buffer[channelNumber] = value;
|
108 | });
|
109 | }
|
110 | else
|
111 | throw new TypeError("data must be of type Buffer, Object or Array.");
|
112 | }
|
113 | |
114 |
|
115 |
|
116 |
|
117 | async _sendUniverse() {
|
118 | return new Promise(resolve => {
|
119 | this.port.set({ brk: true, rts: false }, () => {
|
120 | if (this.usleep === null) {
|
121 | setTimeout(() => {
|
122 | this.port.set({ brk: false, rts: false }, () => {
|
123 | setTimeout(() => {
|
124 | this.port.write(this.buffer, () => resolve());
|
125 | }, 1);
|
126 | });
|
127 | }, 1);
|
128 | }
|
129 | else {
|
130 | this.usleep(92);
|
131 | this.port.set({ brk: false, rts: false }, () => {
|
132 | this.usleep(12);
|
133 | this.port.write(this.buffer, () => resolve());
|
134 | });
|
135 | }
|
136 | });
|
137 | });
|
138 | }
|
139 | |
140 |
|
141 |
|
142 | static async listDevices() {
|
143 | const allPorts = await serialport_1.SerialPort.list();
|
144 | return allPorts
|
145 | .filter(device => device.vendorId === exports.VENDOR_ID && device.productId === exports.PRODUCT_ID)
|
146 | .map(device => device.path);
|
147 | }
|
148 | |
149 |
|
150 |
|
151 |
|
152 | static async getFirstAvailableDevice() {
|
153 | const devices = await EnttecOpenDMXUSBDevice.listDevices();
|
154 | if (devices.length === 0)
|
155 | throw new Error("No device found.");
|
156 | else
|
157 | return devices[0];
|
158 | }
|
159 | }
|
160 | exports.EnttecOpenDMXUSBDevice = EnttecOpenDMXUSBDevice;
|