diff --git a/README.md b/README.md index c09731d..77acc30 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,53 @@ # artnet-node ## Art-Net Library for NodeJS -##### BrianMMcClain \ No newline at end of file + +Using es6 syntax and newer version of NodeJS (6.9.1). + + +### Usage example + + + +Server: +``` +const Server = require('../main').Server + +Server.listen(6454, (msg, peer) => { + console.log('-----------------') + console.log('Sequence: ' + msg.sequence) + console.log('Physical: ' + msg.physical) + console.log('Universe: ' + msg.universe) + console.log('Length: ' + msg.length) + console.log('Data length: ' + msg.data.length) +}) +``` + +Client: +``` +const Client = require('../main').Client +const client = new Client('192.168.1.213', 6454) + +client.send(26, createBuffer(1)) +setTimeout(() => client.send(0, createBuffer(3)), 500) +setTimeout(() => client.send(15, createBuffer(50)), 1000) +setTimeout(() => client.close(), 1500) + +function createBuffer (length) { + // each led will receive and RGB so 3 values per led. + length *= 3 + console.log('creating buffer with length:', length) + const data = new Uint8Array(length) + for (let i = 0; i < length; i += 3) { + data[i] = Math.round(Math.random() * 255) // Red + data[i + 1] = Math.round(Math.random() * 255) // Green + data[i + 2] = Math.round(Math.random() * 255) // Blue + } + return data +} +``` + +Client tested on [Enttec Pixelator](http://www.enttec.com/index.php?main_menu=Products&pn=70060) + +![Pixelator Enntec test](./image.jpg?raw=true) + +Forked from [https://github.com/BrianMMcClain/artnet-node](https://github.com/BrianMMcClain/artnet-node) diff --git a/image.jpg b/image.jpg new file mode 100644 index 0000000..649f527 Binary files /dev/null and b/image.jpg differ diff --git a/lib/artnet_client.js b/lib/artnet_client.js index 1c3f280..6a621f0 100644 --- a/lib/artnet_client.js +++ b/lib/artnet_client.js @@ -1,32 +1,38 @@ -var dgram = require('dgram'); -var Buffer = require('buffer').Buffer; +const dgram = require('dgram') +const Buffer = require('buffer').Buffer -function ArtNetClient(host, port) { - this._host = host; - this._port = port; - this._socket = dgram.createSocket("udp4"); - this.HEADER = [65, 114, 116, 45, 78, 101, 116, 0, 0, 80, 0, 14]; // 0 - 11 - this.SEQUENCE = [0]; // 12 - this.PHYSICAL = [0]; // 13 - this.UNIVERSE = [0, 0]; // 14 - 15 - //this.LENGTH = [0, 13]; // 16 - 17 -} -exports.ArtNetClient = ArtNetClient; +class ArtNetClient { + constructor (host, port) { + this._host = host + this._port = port + this._socket = dgram.createSocket('udp4') + this.HEADER = new Uint8Array([65, 114, 116, 45, 78, 101, 116, 0, 0, 80, 0, 14, 0, 0, 0, 0, 0, 0]) + } -exports.createClient = function(host, port) { - return new ArtNetClient(host, port); -} + send (universe, data) { + // Calcualte the length + const lengthUpper = (data.length >> 8) & 0xff + const lengthLower = data.length & 0xff + // Calcualte the universe + const universeUpper = (universe >> 8) & 0xff + const universeLower = universe & 0xff + // set LENGTH + this.HEADER.set([lengthUpper, lengthLower], 16) + // universe + this.HEADER.set([universeUpper, universeLower], 14) + + let buf = Buffer.concat([ + Buffer.from(this.HEADER.buffer), + Buffer.from(data.buffer) + ], data.length + this.HEADER.length) + + // send the ART-NET buffer + this._socket.send(buf, 0, buf.length, this._port, this._host, () => {}) + } -ArtNetClient.prototype.send = function(data) { - // Calcualte the length - var length_upper = Math.floor(data.length / 256); - var length_lower = data.length % 256; - - var data = this.HEADER.concat(this.SEQUENCE).concat(this.PHYSICAL).concat(this.UNIVERSE).concat([length_upper, length_lower]).concat(data); - var buf = Buffer(data); - this._socket.send(buf, 0, buf.length, this._port, this._host, function(){}); + close () { + this._socket.close() + } } -ArtNetClient.prototype.close = function(){ - this._socket.close(); -}; +module.exports = ArtNetClient diff --git a/lib/artnet_server.js b/lib/artnet_server.js index 785d9ec..2b3425b 100644 --- a/lib/artnet_server.js +++ b/lib/artnet_server.js @@ -1,35 +1,21 @@ -var util = require('util'); -var events = require('events'); -var dgram = require('dgram'); +const dgram = require('dgram') // ArtNet server class -exports.listen = function(port, cb) { - this.port = port; - events.EventEmitter.call(this); - - // Set up the socket - var sock = dgram.createSocket("udp4", function (msg, peer) { - - var sequence = msg.readUInt8(12,true); - var physical = msg.readUInt8(13,true); - var universe = msg.readUInt8(14,true); - var offset = msg.readUInt8(16,true); - var length = msg.readUInt8(17,true); - - var rawData = []; - - for( i = 18; i < 18 + length; i++ ){ - rawData.push( msg.readUInt8(i) ); - } - - var retData = {sequence: sequence, physical: physical, universe: universe, length: length, data: rawData}; - - // And call the callback passing the deseralized data - cb(retData, peer); - }); - sock.bind(port); +exports.listen = (port, cb) => { + this.port = port + // Set up the socket + // msg is a buffer which is a Uint8Array + const sock = dgram.createSocket('udp4', function (msg, peer) { + // Deseralize the data - magic numbers are as per the Art-Net protocol + var sequence = msg[12] + var physical = msg[13] + var universe = (msg[14] * 256) + msg[15] + var length = (msg[16] * 256) + msg[17] + var rawData = msg.slice(18, msg.length) + // Build the associative array to return + var retData = {sequence: sequence, physical: physical, universe: universe, length: length, data: rawData} + // And call the callback passing the deseralized data + cb(retData, peer) + }) + sock.bind(port) } - -// Setup EventEmitter for the ArtNetServer -util.inherits(this, events.EventEmitter); - diff --git a/test/client.js b/test/client.js new file mode 100644 index 0000000..56f051e --- /dev/null +++ b/test/client.js @@ -0,0 +1,20 @@ +const Client = require('../main').Client +const client = new Client('192.168.1.213', 6454) + +client.send(26, createBuffer(1)) +setTimeout(() => client.send(0, createBuffer(3)), 500) +setTimeout(() => client.send(15, createBuffer(50)), 1000) +setTimeout(() => client.close(), 1500) + +function createBuffer (length) { + // each led will receive and RGB so 3 values per led. + length *= 3 + console.log('creating buffer with length:', length) + const data = new Uint8Array(length) + for (let i = 0; i < length; i += 3) { + data[i] = Math.round(Math.random() * 255) // Red + data[i + 1] = Math.round(Math.random() * 255) // Green + data[i + 2] = Math.round(Math.random() * 255) // Blue + } + return data +} diff --git a/test/server.js b/test/server.js new file mode 100644 index 0000000..673a227 --- /dev/null +++ b/test/server.js @@ -0,0 +1,12 @@ +const Server = require('../main').Server + +Server.listen(6454, (msg, peer) => { + console.log('-----------------') + console.log('Sequence: ' + msg.sequence) + console.log('Physical: ' + msg.physical) + console.log('Universe: ' + msg.universe) + console.log('Length: ' + msg.length) + console.log('Data length: ' + msg.data.length) +}) + +console.log('Server Started.') diff --git a/test/test-client.js b/test/test-client.js deleted file mode 100644 index 44221c2..0000000 --- a/test/test-client.js +++ /dev/null @@ -1,6 +0,0 @@ -var artnetclient = require('../lib/artnet_client'); - -var data = [255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]; - -var client = artnetclient.createClient('127.0.0.1', 6454); -client.send(data); \ No newline at end of file diff --git a/test/test-server.js b/test/test-server.js deleted file mode 100644 index ae76bec..0000000 --- a/test/test-server.js +++ /dev/null @@ -1,11 +0,0 @@ -var artnetsrv = require('../lib/artnet_server'); - -var srv = artnetsrv.listen(6454, function(msg, peer) { - console.log("-----------------"); - console.log("Sequence: " + msg.sequence); - console.log("Physical: " + msg.physical); - console.log("Universe: " + msg.universe); - console.log("Length: " + msg.length); - console.log("Data: " + msg.data); - console.log("-----------------"); -});