Basic control of LIFX bulbs

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 :slight_smile:

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", {})
}

PS. In case that’s not obvious to anyone, this essentially opens up remote control of your LIFX bulbs from the Internet with no authentication. Use at your own risk :slight_smile:

Here’s my fork of MagicMonkey’s project. This one contains more of the logic to control bulbs and groups of bulbs, as well as the REST API to do so. https://github.com/limbo/lifxjs

Hi, Is there a way to control the bulbs individually i.e. /set/bulb/Fan%201/on ?

@ymilord, yeah that should work. The label can apply to a group of bulbs or a single bulb. The Web app will try to figure out which one it is.

Hrmm then I must be something wrong. On the Web app it keeps saying “no group fan 1”

@ymilord, are you using the version from my github repo? That’s the latest working version and should be able to do that. The URLs have changed a little but I hope the documentation is clear enough. If you want a hand with setting it all up, email me at limbo2k@gmail.com.

Eran.

To anyone using the node.js server, check out my recent updates. Latest version has much improved stability and might actually be ready to run as a functional server instead of an experiment.

https://github.com/limbo/lifxjs

Is there a plan to merge this back into the magicmonkey master?

Not at the moment. As far as I can tell magicmonkey hasn’t updated in a while so I don’t know if that project’s still alive. Additionally, I really see this project as a stopgap until LIFX publishes an API (last updated is Q1 this year) so I’m not seeing a long future for this part of the project. Where I’d like to go is build a proper driver (similar to the Hue driver by ST) but I’m waiting for access to some arcane bits of API from ST.

Any news about LIFX integration with ST?

Should I Install magicmonkey on windows machine and try from there?
magicmonkey hasn’t been updated for a while…
Anything else/new?

I would say give up… I was able to setup something, it took me a while to accomplish a perfect setup. It work for 4month. LIFX just release a new version that broke all my setup.

However they finally build a rest API from their cloud. There is no date of when it will be open (https://github.com/chendo/lifx-http/issues/27) but once it does, it should be easier to implement but the speed will suck really bad :confused:

The new FW and release 2.0 of LIFX is actually much better. True cloud control. I’m hoping this will help us figure out how to control from Smartthings now.

J

Well their new API have serious delays, I was hopeful for 1 day.
I think I’m going to end up selling those bulbs…