diff --git a/.gitignore b/.gitignore
index 6568e15..8232012 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,5 @@ results
.DS_Store
node_modules
+.project
+.com.greenworldsoft.syncfolderspro
diff --git a/com.dmx-web.server.example.plist b/com.dmx-web.server.example.plist
new file mode 100644
index 0000000..3be95c5
--- /dev/null
+++ b/com.dmx-web.server.example.plist
@@ -0,0 +1,27 @@
+
+
+
+
+ RunAtLoad
+
+ KeepAlive
+
+ Label
+ com.dmx-web.server
+ ProgramArguments
+
+ /usr/local/bin/dmx-web
+ -c
+ /Library/Server/DMX/dmx-web.json
+
+ StandardOutPath
+ /Library/Logs/homebridge/dmxlogfile.log
+ StandardErrorPath
+ /Library/Logs/homebridge/dmxlogfile.log
+ EnvironmentVariables
+
+ PATH
+ /usr/local/bin/:$PATH
+
+
+
diff --git a/devices.js b/devices.js
index 70fc349..99256e0 100644
--- a/devices.js
+++ b/devices.js
@@ -50,5 +50,15 @@ module.exports = {
]
}
}
+ },
+ 'ultra-pro-24ch-rdm': {
+ 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: {
+ 'dimmer': {
+ 'type': 'slider',
+ 'min': 0,
+ 'max': 255
+ }
+ }
}
}
\ No newline at end of file
diff --git a/dmx-web-example.conf b/dmx-web-example.conf
index f470862..bde5ca0 100644
--- a/dmx-web-example.conf
+++ b/dmx-web-example.conf
@@ -1,76 +1,143 @@
-module.exports = {
+{
"server": {
"listen_port": 8080,
"listen_host": "::",
- // drop privileges to:
- // "uid": "www-data",
- // "gid": "www-data"
+ "comment1": "On linux drop privileges by adding the following lines: uid: www-data and gid: www-data",
+ "comment2": "On Macos uid and gid must be set in the launchd script."
},
"presets": [
{
- label: "White",
- 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 }
+ "label": "White",
+ "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 }
}
},
{
- label: 'Natural',
- values: {
- 'office': { 0:16, 1:255, 2:0, 3:255, 4: 190, 5:140, 15:16, 16:255, 17:0, 18:255, 19: 190, 20:140 }
+ "label": "Natural",
+ "values": {
+ "office": { "0":16, "1":255, "2":0, "3":255, "4": 190, "5":140, "15":16, "16":255, "17":0, "18":255, "19": 190, "20":140 }
}
},
{
- label: 'Worklight',
- values: {
- 'office': { 0:16, 1:130, 2:0, 3:255, 4: 165, 5:0, 15: 1, 16:255, 17:0, 18:255, 19: 190, 20:140, 21:0, 22: 0, 23:0, 24:255, 25: 190, 26:140 }
+ "label": "Worklight",
+ "values": {
+ "office": { "0":16, "1":130, "2":0, "3":255, "4": 165, "5":0, "15": 1, "16":255, "17":0, "18":255, "19": 190, "20":140, "21":0, "22": 0, "23":0, "24":255, "25": 190, "26":140 }
}
},
{
- label: 'Chill',
- values: {
- 'office': { 0:16, 1:255, 2:0, 3:255, 4: 39, 5:0, 15: 1, 16:255, 17:0, 18:255, 19: 255, 20:0, 21:0, 22: 0, 23:0, 24:128, 25: 0, 26:255, 31:255, 32: 60 }
+ "label": "Chill",
+ "values": {
+ "office": { "0":16, "1":255, "2":0, "3":255, "4": 39, "5":0, "15": 1, "16":255, "17":0, "18":255, "19": 255, "20":0, "21":0, "22": 0, "23":0, "24":128, "25": 0, "26":255, "31":255, "32": 60 }
}
},
{
- label: 'Cinema',
- values: {
- 'office': { 0:16, 1:30, 2:0, 3:255, 4: 39, 5:0, 15:0, 31:255, 32:0 }
+ "label": "Cinema",
+ "values": {
+ "office": { "0":16, "1":30, "2":0, "3":255, "4": 39, "5":0, "15":0, "31":255, "32":0 }
}
- },
+ }
],
- universes: {
- 'office': {
- 'output': {
- // 'driver': 'enttec-usb-dmx-pro',
- // 'device': '/dev/cu.usbserial-6AVNHXS8'
- 'driver': 'null',
- 'device': 0
+ "universes": {
+ "office": {
+ "output": {
+ "driver": "enttec-usb-dmx-pro",
+ "device": "/dev/cu.usbserial-6A1KQK87"
},
- 'devices': [
+ "devices": [
{
- 'type': 'eurolite-led-bar',
- 'address': 0
+ "type": "eurolite-led-bar",
+ "address": 0
},
{
- 'type': 'eurolite-led-bar',
- 'address': 15
+ "type": "eurolite-led-bar",
+ "address": 15
},
{
- 'type': 'showtec-multidim2',
- 'address': 31
+ "type": "showtec-multidim2",
+ "address": 31
},
{
- 'type': 'stairville-led-par-56',
- 'address': 64
+ "type": "stairville-led-par-56",
+ "address": 64
},
{
- 'type': 'stairville-led-par-56',
- 'address': 70
+ "type": "stairville-led-par-56",
+ "address": 70
},
{
- 'type': 'stairville-led-par-56',
- 'address': 76
+ "type": "stairville-led-par-56",
+ "address": 76
+ }
+ ]
+ },
+ "bedroom": {
+ "output": {
+ "driver": "dmxking-ultra-dmx-pro",
+ "device": "/dev/cu.usbserial-6AVNHXS8",
+ "options": {
+ "port": "A"
+ }
+ },
+ "devices": [
+ {
+ "type": "eurolite-led-bar",
+ "address": 0
+ },
+ {
+ "type": "eurolite-led-bar",
+ "address": 15
+ },
+ {
+ "type": "showtec-multidim2",
+ "address": 31
+ },
+ {
+ "type": "stairville-led-par-56",
+ "address": 64
+ },
+ {
+ "type": "stairville-led-par-56",
+ "address": 70
+ },
+ {
+ "type": "stairville-led-par-56",
+ "address": 76
+ }
+ ]
+ },
+ "livingroom": {
+ "output": {
+ "driver": "dmxking-ultra-dmx-pro",
+ "device": "/dev/cu.usbserial-6AVNHXS8",
+ "options": {
+ "port": "B"
+ }
+ },
+ "devices": [
+ {
+ "type": "eurolite-led-bar",
+ "address": 0
+ },
+ {
+ "type": "eurolite-led-bar",
+ "address": 15
+ },
+ {
+ "type": "showtec-multidim2",
+ "address": 31
+ },
+ {
+ "type": "stairville-led-par-56",
+ "address": 64
+ },
+ {
+ "type": "stairville-led-par-56",
+ "address": 70
+ },
+ {
+ "type": "stairville-led-par-56",
+ "address": 76
}
]
}
diff --git a/dmx-web.js b/dmx-web.js
index 9f1dd99..06073df 100755
--- a/dmx-web.js
+++ b/dmx-web.js
@@ -28,7 +28,8 @@ function DMXWeb() {
dmx.addUniverse(
universe,
config.universes[universe].output.driver,
- config.universes[universe].output.device
+ config.universes[universe].output.device,
+ config.universes[universe].output.options
)
}
diff --git a/dmx.js b/dmx.js
index 78c937a..45d4695 100644
--- a/dmx.js
+++ b/dmx.js
@@ -9,12 +9,13 @@ function DMX(options) {
this.drivers = {}
this.devices = options.devices || require('./devices')
- this.registerDriver('null', require('./drivers/null'))
- this.registerDriver('dmx4all', require('./drivers/dmx4all'))
- 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('artnet', require('./drivers/artnet'))
- this.registerDriver('bbdmx', require('./drivers/bbdmx'))
+ this.registerDriver('null', require('./drivers/null'))
+ this.registerDriver('dmx4all', require('./drivers/dmx4all'))
+ 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('dmxking-ultra-dmx-pro', require('./drivers/dmxking-ultra-dmx-pro'))
+ this.registerDriver('artnet', require('./drivers/artnet'))
+ this.registerDriver('bbdmx', require('./drivers/bbdmx'))
}
util.inherits(DMX, EventEmitter)
@@ -26,8 +27,8 @@ DMX.prototype.registerDriver = function(name, module) {
this.drivers[name] = module
}
-DMX.prototype.addUniverse = function(name, driver, device_id) {
- return this.universes[name] = new this.drivers[driver](device_id)
+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) {
diff --git a/drivers/dmxking-ultra-dmx-pro.js b/drivers/dmxking-ultra-dmx-pro.js
new file mode 100644
index 0000000..6805bd8
--- /dev/null
+++ b/drivers/dmxking-ultra-dmx-pro.js
@@ -0,0 +1,84 @@
+"use strict"
+
+var SerialPort = require("serialport")
+
+var DMXKING_ULTRA_DMX_PRO_DMX_STARTCODE = 0x00
+ , DMXKING_ULTRA_DMX_PRO_START_OF_MSG = 0x7e
+ , 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) {
+ var self = this
+ this.options = options || {}
+ this.universe = new Buffer(512)
+ this.universe.fill(0)
+
+ this.sendDMXReq = DMXKING_ULTRA_DMX_PRO_SEND_DMX_RQ
+ if (this.options.port === "A") {
+ this.sendDMXReq = DMXKING_ULTRA_DMX_PRO_SEND_DMX_A_RQ
+ } else if (this.options.port === "B") {
+ this.sendDMXReq = DMXKING_ULTRA_DMX_PRO_SEND_DMX_B_RQ
+ }
+
+ this.dev = new SerialPort(device_id, {
+ 'baudrate': 250000,
+ 'databits': 8,
+ 'stopbits': 2,
+ 'parity': 'none'
+ }, function(err) {
+ if(!err) {
+ self.send_universe()
+ }
+ })
+}
+
+DMXKingUltraDMXPro.prototype.send_universe = function() {
+ if(!this.dev.isOpen()) {
+ return
+ }
+ var hdr = Buffer([
+ DMXKING_ULTRA_DMX_PRO_START_OF_MSG,
+ this.sendDMXReq,
+ (this.universe.length + 1) & 0xff,
+ ((this.universe.length + 1) >> 8) & 0xff,
+ DMXKING_ULTRA_DMX_PRO_DMX_STARTCODE
+ ])
+
+ var msg = Buffer.concat([
+ hdr,
+ this.universe,
+ Buffer([DMXKING_ULTRA_DMX_PRO_END_OF_MSG])
+ ])
+ this.dev.write(msg)
+}
+
+DMXKingUltraDMXPro.prototype.start = function() {}
+DMXKingUltraDMXPro.prototype.stop = function() {}
+
+DMXKingUltraDMXPro.prototype.close = function(cb) {
+ this.dev.close(cb)
+}
+
+DMXKingUltraDMXPro.prototype.update = function(u) {
+ for(var c in u) {
+ this.universe[c] = u[c]
+ }
+ this.send_universe()
+}
+
+DMXKingUltraDMXPro.prototype.updateAll = function(v){
+ for(var i = 0; i < 512; i++) {
+ this.universe[i] = v
+ }
+ this.send_universe()
+}
+
+DMXKingUltraDMXPro.prototype.get = function(c) {
+ return this.universe[c]
+}
+
+module.exports = DMXKingUltraDMXPro
\ No newline at end of file
diff --git a/readme.md b/readme.md
index d4ebf30..b33287b 100644
--- a/readme.md
+++ b/readme.md
@@ -28,6 +28,10 @@ A example configuration is in the repository by the name dmx-web-example.c
dmx-web [-c ]
+### Run as a service
+
+On MacOS you can run dmx-web as a service by adding a launch script to /Library/LaunchDaemons. See the example file.
+
### Animation HTTP API
A List of Channel Transistions can be POSTed to /animation/<universe>
. Each transistion is a JSON Object with at least the to
property present. The Value of which also has to be an Object describing the channel end-states.
@@ -70,12 +74,14 @@ These drivers are currently registered by default:
- dmx4all: driver for DMX4ALL devices like the "NanoDMX USB Interface"
- enttec-usb-dmx-pro: a driver for devices using a Enttec USB DMX Pro chip like the "DMXKing ultraDMX Micro".
- enttec-open-usb-dmx: driver for "Enttec Open DMX USB". This device is NOT recommended, there are known hardware limitations and this driver is not very stable. (If possible better obtain a device with the "pro" chip)
+- dmxking-utra-dmx-pro: driver for the DMXKing Ultra DMX pro interface. This driver support multiple universe specify the options with Port = A or B
-#### dmx.addUniverse(name, driver, device_id)
+#### dmx.addUniverse(name, driver, device_id, options)
- name
- String
- driver
- String, referring a registered driver
- device_id
- Number or Object
+- options
- Object, driver specific options
Add a new DMX Universe with a name, driver and an optional device_id used by the driver to identify the device.
For enttec-usb-dmx-pro and enttec-open-usb-dmx device_id is the path the the serial device. For artnet it is the target ip.