Basic control of LIFX bulbs

Home Forums Developers Basic control of LIFX bulbs

Tagged: 

This topic contains 9 replies, has 3 voices, and was last updated by Avatar of Eran Eran 2 months, 2 weeks ago.

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #9335
    Avatar of Eran
    Eran
    Participant

    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", {})
    }
    
    #9336
    Avatar of Eran
    Eran
    Participant

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

    #9843
    Avatar of Eran
    Eran
    Participant

    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

    #10244
    Avatar of ymilord
    ymilord
    Participant

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

    #10377
    Avatar of Eran
    Eran
    Participant

    @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.

    #10382
    Avatar of ymilord
    ymilord
    Participant

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

    #10432
    Avatar of Eran
    Eran
    Participant

    @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.

    #10639
    Avatar of Eran
    Eran
    Participant

    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

    #10683
    Avatar of Richard Lee
    Richard Lee
    Participant

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

    #10816
    Avatar of Eran
    Eran
    Participant

    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.

Viewing 10 posts - 1 through 10 (of 10 total)

You must be logged in to reply to this topic.