Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mwittig committed Apr 26, 2015
1 parent 0ea4c28 commit 995ec86
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 1 deletion.
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
# node-milight-promise
A node module to control Milight Bulb also under various OEM brands such as Rocket LED Limitless LED Applamp, Easybulb, s`luce, iLight, iBulb, Kreuzer

A node module to control Milight LED bulbs and OEM equivalents auch as Rocket LED, Limitless LED Applamp,
Easybulb, s`luce, iLight, iBulb, and Kreuzer

NOTE: This is work in progress.

## Usage Example

var Milight = require('../src/index').MilightController;
var commands = require('../src/index').commands;


var light = new Milight({
ip: "255.255.255.255"
}),
zone = 1;

light.sendCommands(commands.rgbw.on(zone), commands.rgbw.brightness(100));
for (var x=0; x<256; x++) {
light.sendCommands( commands.rgbw.on(zone), commands.rgbw.hue(x));
}
light.pause(1000);
light.sendCommands(commands.rgbw.on(zone), commands.rgbw.whiteMode(zone));

light.close();
18 changes: 18 additions & 0 deletions example/example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var Milight = require('../src/index').MilightController;
var commands = require('../src/index').commands;


var light = new Milight({
ip: "255.255.255.255"
}),
zone = 1;

light.sendCommands(commands.rgbw.on(zone), commands.rgbw.brightness(100));
for (var x=0; x<256; x++) {
light.sendCommands( commands.rgbw.on(zone), commands.rgbw.hue(x));
}
light.pause(1000);
light.sendCommands(commands.rgbw.on(zone), commands.rgbw.whiteMode(zone));

light.close();

28 changes: 28 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "node-milight-promise",
"version": "0.0.1",
"description": "A node module to control Milight LED bulbs and OEM equivalents auch as Rocket LED, Limitless LED Applamp, Easybulb, s`luce, iLight, iBulb, and Kreuzer",
"author": {
"name": "Marcus Wittig",
"url": "https://github.com/mwittig/node-milight-promise"
},
"main": "src/index",
"homepage": "https://github.com/mwittig/node-milight-promise",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/mwittig/node-milight-promise"
},
"bugs": {
"url": "https://github.com/mwittig/node-milight-promise/issues"
},
"keywords": [
"SmartHome",
"Milight",
"WifiLight",
"LED"
],
"dependencies": {
"bluebird": ">=2.9.24"
}
}
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
MilightController : require('./milight'),

commands: require('./commands')
};
190 changes: 190 additions & 0 deletions src/milight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
var Promise = require('bluebird'),
dgram = require('dgram'),
debug = process.env.hasOwnProperty('MILIGHT_DEBUG') ? consoleDebug : function () {
};

const
DEFAULT_IP = '255.255.255.255',
DEFAULT_PORT = 8899,
DEFAULT_SEND_MESSAGE_DELAY = 100,
DEFAULT_COMMAND_DELAY = 1;

//
// Local helper functions
//

function buffer2hex(buffer) {
result = [];
for (var i = 0; i < buffer.length ; i++) {
result.push('0x' + buffer[i].toString(16))
}
return result;
}


function consoleDebug() {
console.log.apply(this, arguments)
}

//
// Class MilightController
//

/**
*
* @param options
* @constructor
*/
var MilightController = function (options) {
options = options || {};

this.ip = options.ip || DEFAULT_IP;
this._broadcastMode = this.ip === DEFAULT_IP;
this.port = options.port || DEFAULT_PORT;
this._delayBetweenMessages = options.delayBetweenMessages || DEFAULT_SEND_MESSAGE_DELAY;
this._delayBetweenCommands = options.delayBetweenCommands || DEFAULT_COMMAND_DELAY;
this._socketInit = Promise.resolve();
this._lastRequest = this._createSocket();
};

//
// Private member functions
//

MilightController.prototype._createSocket = function () {
var self = this;

return Promise.settle([self._socketInit]).then(function () {

return self._socketInit = new Promise(function (resolve, reject) {
if (self.clientSocket) {
return resolve();
}
else {
debug("Initializing Socket");
var socket = dgram.createSocket('udp4');

if (self._broadcastMode) {
socket.bind(function() {
socket.setBroadcast(true);
self.clientSocket = socket;
debug("Milight: Initializing Socket (broadcast mode) completed");
return resolve();
});
}
else {
self.clientSocket = socket;
debug("Milight: Initializing Socket done");
return resolve();
}
}
});
});
};


MilightController.prototype._sendThreeByteArray = function (threeByteArray) {
if (!threeByteArray instanceof Array) {
return Promise.reject(new Error("Array argument required"));
}
var buffer = new Buffer(threeByteArray),
self = this;

return new Promise(function (resolve, reject) {
self._createSocket().then(function() {
self.clientSocket.send(buffer
, 0
, buffer.length
, self.port
, self.ip
, function (err, bytes) {
if (err) {
debug("UDP socket error:" + err);
return reject(err);
}
else {
debug('Milight: bytesSent=' + bytes +', buffer=[' + buffer2hex(buffer) + ']');
Promise.delay(self._delayBetweenCommands).then(function () {
return resolve();
});
}
}
);
}).catch(function(error) {
reject(error);
})
})
};

//
// Public member functions
//

/**
*
* @param varArgArray
* @returns {*}
*/
MilightController.prototype.sendCommands = function (varArgArray) {
var stackedCommands = [],
varArgs = arguments,
self = this;

return self._lastRequest = Promise.settle([self._lastRequest]).then(function () {

for (var i = 0; i < varArgs.length; i++) {
if (!varArgs[i] instanceof Array) {
return Promise.reject(new Error("Array arguments required"));
}
else {
var arg = varArgs[i];
if (((arg.length) > 0) && (arg[0] instanceof Array)) {
for (var j = 0; j < arg.length; j++) {
stackedCommands.push(self._sendThreeByteArray(arg[j]));
}
}
else {
stackedCommands.push(self._sendThreeByteArray(arg));
}
}
}
return Promise.settle(stackedCommands).then(function () {
return Promise.delay(self._delayBetweenMessages);
});
});
};


/**
*
* @param ms
* @returns {*}
*/
MilightController.prototype.pause = function (ms) {
var self = this;
ms = ms || 100;

return self._lastRequest = Promise.settle([self._lastRequest]).then(function () {
return Promise.delay(ms);
})
};


/**
*
* @returns {*}
*/
MilightController.prototype.close = function () {
var self = this;

return self._lastRequest = Promise.settle([self._lastRequest]).then(function () {
if (self.clientSocket) {
self.clientSocket.close();
delete self.clientSocket;
}
return Promise.resolve();
})
};


module.exports = MilightController;

0 comments on commit 995ec86

Please sign in to comment.