I spent a few hours the other day getting some basic control (switch on/off for now) of LIFX bulbs through the smartthings app. Here’s the relevant info:
The general setup is this:
LIFX connected through wifi to my home network.
iMac on this network running a modified version of the node.js app from magicmonkey.
A simple script listening to a virtual switch device. This script send HTTP requests to the node.js app.
smartthings hub is on the same network but this doesn’t seem to matter since it appears that the script is running in the smartthings cloud (can anyone verify this?) so I had to open up a port in my router for the script to be able to connect to the node app.
I added some basic commands to the web app example in magicmonkey’s code. I also threw in an ugly hack to control “groups” of bulbs.
app.js mostly does the web request routing for the node app. Here’s my modifications. The first part adds a route that can take a bulb id (name) or one of my fake groups and turn those on/off. The last two bits control all the bulbs at the same time.
app.get('/set/:group/:val', function(req, res, next){
group = req.params.group.toLowerCase();
val = req.params.val.toLowerCase();
console.log("set " + group + " to " + val);
if (group === "bedroom") {
toggleBulbs(bedroom, val);
} else if (group === "office") {
toggleBulbs(office, val);
} else if (group === "all") {
toggleBulbs(undefined, val);
} else {
console.log("Unknown group " + group);
}
res.end("OK");
});
function toggleBulbs(bulbs, onoff) {
if (onoff === "on") {
lx.lightsOn(bulbs);
} else if (onoff === "off") {
lx.lightsOff(bulbs);
} else {
console.log("Unknown value " + onoff);
}
}
app.get('/set/all/on', function(req, res, next){
console.log("turn all on");
lx.lightsOn();
res.end("OK");
});
app.get('/set/all/off', function(req, res, next){
console.log("turn all off");
lx.lightsOff();
res.end("OK");
});
lifx.js talk to the LIFX network. I only needed to modify one function here in order to be able to control groups (arrays) of bulbs. This is an ugly copy/paste hack because javascript is stupid
Lifx.prototype._sendToOneOrAll = function(command, bulb) {
this.gateways.forEach(function(g) {
var siteAddress = g.lifxAddress;
siteAddress.copy(command, 16);
if (typeof bulb == 'undefined') {
g.send(command);
} else if (bulb instanceof Array) {
for (i in bulb) {
// Overwrite the bulb address here
var target;
if (Buffer.isBuffer(bulb[i])) {
target = bulb[i];
} else if (typeof bulb[i].lifxAddress != 'undefined') {
target = bulb[i].lifxAddress;
} else {
throw "Unknown bulb";
}
target.copy(command, 8);
g.send(command);
}
} else {
// Overwrite the bulb address here
var target;
if (Buffer.isBuffer(bulb)) {
target = bulb;
} else if (typeof bulb.lifxAddress != 'undefined') {
target = bulb.lifxAddress;
} else {
throw "Unknown bulb";
}
target.copy(command, 8);
g.send(command);
}
});
};
Finally, here’s the ST app. Replace IP and PORT with your external IP address and the port you opened up for the node app. Also, create a new device of type On/Off Button Tile. This device will be used to turn the lights on/off.
preferences {
section("Use this switch for the bedroom..") {
input "bedroom", "capability.switch", title: "Bedroom switch?"
}
section("Use this switch for the office..") {
input "office", "capability.switch", title: "Office switch?"
}
}
def installed() {
log.trace "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
// TODO: subscribe to attributes, devices, locations, etc.
subscribe(bedroom, "switch", bedroomHandler)
subscribe(office, "switch", officeHandler)
}
def bedroomHandler(evt) {
if (evt.value == "on") {
turnLightsOn('bedroom')
} else if (evt.value == "off") {
turnLightsOff('bedroom')
}
}
def officeHandler(evt) {
log.trace evt.value
if (evt.value == "on") {
turnLightsOn('office')
} else if (evt.value == "off") {
turnLightsOff('office')
}
}
def turnLightsOn(group) {
if (group == "") {
group = "all"
}
httpGet("http://IP:PORT/set/${group}/on", {})
}
def turnLightsOff(group) {
log.trace "turnLightsOff: ${group}"
if (group == "") {
group = "all"
}
httpGet("http://IP:PORT/set/${group}/off", {})
}