Lightsd: a daemon with a JSON-RPC API to control your bulbs

Hello all,

I wanted to give an update on what I had planned for the end of 2015:

  • transition support for power_{off,on,toggle} (GH-5);
  • support for machines attached to multiple networks (GH-2).

I managed to do those two things plus:

  • better documentation with a new section on how to write a client for lightsd;
  • improved lightsc.py: it properly does I/O now which makes it a better foundation for an “official” Python client;
  • finally wrote a contribution guide.

It’s also interesting to note that transition support for power_{off,on,toggle} has been implemented on top of an internal effects API. This should enable interesting features in the future: delay or repeat a command or even more complicated things (e.g: following the circadian cycle).

Unfortunately, most of those features aren’t released yet and are sitting in my patch queue. Things should get released (modulo successful QA, especially on the transition code) in the next 4 to 8 weeks with a priority on the documentation.

I’m planning to be in Brussels at Fosdem at the end of the month, I’ll try to find some time to prepare a lightning talk about the project.

Any question or remark, let me know!

Best

1 Like

Just wanted to let you know that I also have lightsd running on raspberry pi using ruby to change the lights every hour based on an old article about lifx and circadian rhythm (about 18 lights).

Anyway, it’s working great, thank you!

1 Like

Nice!

How are you sending the commands to lightsd? Just using the command pipe?

The internal effects API I was talking about is kinda comparable to things like Lightbow (I actually just purchased it to check that) no idea how I’m gonna expose it yet though.

I decided to set it up using TCPIP in case I wanted to interface with it from another program, and then on the ruby side:
require 'socket’
require ‘json’

then very similar to the python client:
class LIGHTSD

def initialize(tcp, port)
@tcp = tcp
@port = port
@j = {
“jsonrpc” => “2.0”,
“method” => nil,
“params” => Array.new,
“id” => nil
}
end

def get_light_state§
@j[“method”] = “get_light_state”
@j[“params”].push§

self.call["result"]

end

x = LIGHTSD.new(‘192.168.1.40’, 8080)
r = x.get_light_state("*")
r.each { |i| p “#{i[‘label’]} is #{i[‘power’]?‘on’:‘off’}” }

1 Like

btw, my ultimate goal in all this work is to eventually have a manual override in parallel to the automation so that if someone wants a particular light setting (or dim lights up down, turn on full or off, etc…) that it can be done in a traditional manner using a wall dimmer switch or perhaps a scene controller.

I ran accross razberry, which is a daughterboard that allows messages to and from the zwave bus which can do some pretty advanced things. Has anyone used this? Or, anyone have thoughts on if this would work well as a solution?

Thanks!

Interesting so you mean something like this: the bulbs would all be following a cycle by default but someone could temporarily exclude a bulb from the cycle?

Complex cycles have to be controlled by something external to the bulbs (e.g: lightsd or your script) so you would have to communicate with that thing to exclude and then add a back a bulb from/to a cycle.

The Original 1000 and the Color 650 are the only model using a 802.15.4 radio/chip, a standard upon which zwave and zigbee are built upon, but afaik LIFX isn’t using either of them. Anyway all their newer products since the Original 1000 and Color 650 are WiFi only.

Actually, a bit less work than that. Using the razberry to intercept the zwave signals and then generate messages for lightsd to change the lights. …I can also just check the lights on the hour when my automation occurs to see if they are overridden and ignore those lights until midnight or some such.

After a bit more research I went ahead and got a razberry daughterboard and inexpensive zwave scene controller so I suppose I will soon be able to answer my own question :slight_smile:

Oh, I also wasnt real happy with the response time of the simple, yet slow Internet button however I may revisit that in a similar manner to my zwave concept and have it talk direct to lightsd. IFTTT took up to 30 seconds to react and didn’t look or feel like a common light switch at all.

1 Like

For anyone interested, I got my Razberry daughterboard going and have some Ruby code that checks the status of a Levitan single click switch and then calls light sequences based on status of the light, the day and the number of clicks.

Pretty responsive, although I suspect people will take a little to get used to the clicks since I haven’t figured out how to queue up clicks so double and triple clicks might be hinky if clicking too impatient.

Next, I’ll be rewiring so that my lights are always on and I’ll just pull power for the light switch that looks and works exactly like a real light switch (well, cause it is :slight_smile: )

Future updates include using scene controllers over switches to be more intuitive and responsive and also the JS interface is supposed to allow binding to events rather than polling like I am, but haven’t gotten that to work yet and from what I have read not sure it’s more responsive anyway.

1 Like

Ok, finally put all the pieces together…so, yeah, a $200 light switch :wink:

$35 raspberry pi (raspbian and razberry for zwave)
$60 razberry daughter board
$130 4 zone leviton VRCZ4-M0Z zwave controller
$65 leviton binary switch VRS15-1LZ
$UGH … 20 LIFX lights (over the course of 2ish years)…we got about $1500 in referral money from referring 5 people our solar panel system, so that was set aside for the lights. All original A20s.

Running Razberry and LightsD on the raspberry pi, I use my Ruby script to check for changes on the zwave devices and adjust the lights according:

  • binary switch will toggle lights (by entry), and also creates a relay on the mesh network to the razberry since the scene controller is out of range. Good for coming home if it’s dark or leaving if lights are on.
  • 4 zone controller - didn’t completely recognize with razberry, but enough so that I am able to tell if a button is pushed (even if it’s the current scene) so I make it do things like on, off, full on, scenes, etc…
  • my lights still change automatically each hour (as well as on/off at certain times and relative to sunrise and sunset) based on the circadium rhythm article published a while ago.

I had to hardwire my lights to always on and just grabbed power for the controllers.

What’s next…:

  • I cannot control the LED’s on the controllers, although I can set some zwave settings to allow better tracking of current button pushed.
  • no built-in automation…I’ll just have to program that.
  • no sync command to get the lights to change in unison
  • working on more intuitive options for the switches based on current state of lights, time of day, button sequence, etc…
  • need a way to indicate whether to automate lights or not…currently my hourly schedule will override changes I make manually (including smart phone). There is a light that can probably turn on or off that I can use as an indicator…something like that.

Any thoughts, suggestions, comments, questions?

Thanks again for the LIGHTSD work!!

1 Like

I am having issues with some bulbs not communicating with lightsd. Sometimes one or all of my bulbs do not show up in get_light_state("*")

systemctl status lightsd shows numerous log entries thus:

[WARN] lightsd: received unknown packet 0x196 from [::fffff:192.168.0.10]:56700

That error repeats for whichever bulbs are not showing up. Using the app, or Daniel Hall’s lifxsdk all bulbs can be seen and controlled while lightsd cannot.

Any hints for a beginner where to start looking?

Sorry all, I have been busy with other things lately and I kinda fell behind here. On the bright side I have been silently working on setting up my own buildbot instance which will allow me to fully automate a large part of my development/release workflow. As part of this I will also make “official” lightsd docker images along the next release.

@beanbrown amazing work!

@yeltrah If lightsd can’t control some lights I don’t really see how the official app can, they might show up in the app because each bulb is persisted in the lifx “cloud” but I doubt they can be controlled. In that regard the troubleshooting steps are the same for lightsd and the official app: try different WiFi channels, maybe give a shot to the latest firmwares (I wasn’t following but looks like that horrible QCA firmware bug might be fixed?).

The warning you’re seeing is innocuous, it just means lightsd received a packet it doesn’t know how to handle (yet), I should lower the verbosity for this message.

Let me know if you still can’t get anything to work!

@lopter,

does lightsd just listen passively?

is there any reason I should see a correlation between installing lightsd today, and having 22 of my 23 LIFX bulbs fall off the network within 6 hours? It’s pretty normal for me to have 2 or 3 of the bulbs fall off the network at any given time, but I haven’t had this many offline at the same time before, when nobody is flipping switches.

Thanks.

Hello Tim,

Thank you for giving a try to lightsd!

No, lightsd tries hard to present as up-to-date as possible information and samples the bulbs aggressively.

Yes, the reason is likely a bug in the firmware of the Qualcomm Atheros chip in the bulb that handles Wi-Fi and Alljoyn. You’ll find more information in other threads in this sub-forum.

Upgraded firmwares have been recently released, so more details on your bulb and their firmware version would be helpful (you can get that easily by executing c.get_light_state("*")["result"] in lightsc.py).

Best

Thanks, @lopter. I was in touch with support, and they sent me a new firmware to test.

I really like lightsd, and am looking forward to playing around with it more. And bonus, I’ll get to learn Python 3, at the same time.

Cheers.

1 Like

Thanks to lightsd I’ve been able to create “gesture” control for one of my lights with NodeMCU and Range sensor. If anyone is interested, here is how I’ve done it http://lab.ra100.net/control-lifx-nodemcu-and-range-sensor

2 Likes

@lopter I have been unable to build on the latest Raspbian builds, it just about finishes then fails at the end. I gave up sorry and don’t have the error written down but attempting on a new build on Pi 1 and 2 failed. I will try the 3 next but not sure when I will have time.

Oh! Can you copy/paste or attach error logs? Then I should be able to help.


@ra100, nice! I need to setup ready-to-install Debian/Ubuntu packages and/or, even better, actual repositories (which will also help @boxhead) .

I also need to add a method to adjust or set the brightness independently of the hue/saturation/temperature to make this kind of things easier. I actually wonder if such thing would be useful for another parameter than the brightness (in other words if lightsd should expose a generic method or only something for the brightness).

I’d recommend being able to change any subset of the HSBK components, while leaving the other components unchanged. (The same as what is possible in the Cloud API.)

I second that idea, I don’t think I’d use something like changing only hue right now, but it would be nice to can do that easily.

I will have to try and build again when I have some time to capture that for you. It isn’t an issue and I am not sure if anyone else has found the same problem. I will try again on the 3 as it is so much quicker.

1 Like