Playing with the lights
CC Attribution 2.0 Belgium:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Opter, Louis
In this talk we'll take a close look at a one of the "smart" (WiFi-connected)light-bulbs available on the market today. The bulbs expose a small API overUDP that I used to run an interface on a programmable buttons array. We willsee how topics like reverse engineering, security, licensing, "self-hosting"and user experience came into play. monolight is an user interface to control LIFX WiFi-enabled light bulbs.monolight runs on a programmable button array; it is written in Python 3.6 (tohave type annotations and asyncio), and it interfaces with the bulbs through amore complex daemon written in C: lightsd. This talk will start with a live demo of the button grid remotely controllingthe light bulbs. We will then explore how it works and some of the motivationsbehind it (network isolation, trying to not depend on the "cloud",reliability, user-experience). Finally, we will look into what kind ofopportunities even more open IoT products could bring, and open leave theplace to Q&A and discussion.
 My name is Louis, Louis Upton. I'm a decent software engineer. Doesn't really matter where I am. I don't really know anything about hardware. And I think that's an important part of this talk. It is I'm playing with hardware devices. I'm playing with IoT. And I don't really know anything about this. I'm really just a software engineer. So if we're going to slide number three, agenda. So this talk is going to talk about two related projects. One is monolight, which is an UI for devices like this one, which is basically like a mattress of buttons, like this. To control light bulbs. Light bulbs like this guy here. A guy, girl, I don't know actually. This bulb. So that's monolight. It runs an interface on this button array. And then lightsd, which is a demand to control the light bulbs. So this demand talks to the light bulbs, exposes a high level API, and I can control the light bulbs this way. I'm going to first talk about monolight. So I control the bulbs through this button array. I'm going to give you some details about the project. And then I'm going to talk about lightsd, which was actually most of the work, which is a demand to talk to the bulbs. And then we're going to have maybe some time for the discussion. So if you go on slide number four, you have this high level architecture diagram. So you can see that monolight talks to both lightsd on the button array. And that's how I control the bulbs. If you go next, you see that part one is going to be monolight, part two is going to be a lightd. Then on slide number five, title monolight. So I just talked about what I said. 100 to the 8 buttons. Each button has like 16 levels of brightness. This is how I can make up a new eye by playing with the brightness levels. It's connected to the verserial. Then next slide. I was controlling this smart bulb, which is made by this brand called Lifeix. It's about 1,000 lumens bulb. So it's pretty high brightness. It's like a 70 watt light bulb. It has nice colors. It can do all the colors. It has a nice range of whites from like 2,500 Kelvin to like 9,000 Kelvin. And both side bulbs are connected over Wi-Fi, 2.4 gigahertz. So next slide. Let's have a look at the controlling light. So you have the grid. So you have like this side should be just show a grid. OK. And then next slide, you see that the Brahm row has got some functions. So Brahm row is dedicated to functions. So for example, you'll see you have like on, I can like off other functions actually later. So yeah, next slide that shows you some of the functions were like they're mapped. Like how it works. You know, I could like add more things to this balance. Like for example, control like you know, NPD control other things. And then I have like split the array into like four control pads. Right. So this is like one control pad here. Here. Right. And like there is like four sliders. And I have like some functions, other functions at the top. Right. So if you go to the next slide, you see like what its title is. OK. Awesome. So can I make it like full screen though? Yeah. Let's do for the next talk. Maybe it is very, very long. I don't know how to put it full screen. Oh yeah, perfect. So just use it here. OK. So here. OK. So like that most slider is like you know the here and then saturation brightness, temperature. So that's the HSBK you know color model HSB and then we add the temperature. So like you know can increment, decrement. So for example, I can show this here. So I turn this guy off again. I'm going to bring up the brightness which is here. I'm going to change the color which is here. Can do those two things at the same time. OK. And so on, so on. Can I make it like less saturated? So right. So you can always see like a change color. All right. So like that was kind of the demo like see. OK. Other things. All right. Like other things. I think this is like it's like like this. I can just move functions. What's interesting to see is that I'm going to make a smoother one. That's white. That's blue. I'm going to. So like what's interesting is like the board shows like the, the side of the bar been like with low latency right. That's sort of like a feature of what I did. It's like it shows really like what the status of the bar is. It's not like you know predicted or something intact. The real status of the light bulbs is shown on the board. So for example, if I make it like you know transition. We can see that the starters are moving by themselves right. And that's the program. It's just like showing the real status of the light bulbs. Right. OK. One more thing I like to show is like cool like the interface is like defined, which I think is like pretty interesting. So I'm going to go back and get up. There is no internet. OK. Wait a minute. I can put it on. Yeah. So actually I love to do this. If you can like do this. It would be awesome. So like because so like the way all this is implemented is in Python. So like the program that controls the grid is in Python. And the API and manage only are pretty high level. And the way you like set your UI element on the grid is I think pretty interesting. It's pretty high level. And that's about it for like monolight on the implementation details, which you'll find on the slides. So this is Python. I've been using Python 3.5 and 3.6 with top annotations, which are awesome. So you basically like you know do type Python. I really encourage you to look into this if you do Python or not. And then I use a CKL. So everything is in synchronous. Awesome. Thank you so much. So I'm going to go on my profile. So there we go. You'll even know like the repository architecture by the end. That's pretty awesome. So it's going to be UI. So what I'm using, no. No. OK. Yeah. So see it's how the UI is defined, right? So I can do, OK, I have like a root layer on 949. And then I can insert some balance, the balance of different actions in line. So see for example like the other, you know, the pink graph, which is the effect I did, which was moving slowly. There is the other, which is the flashing I did. So see I just like define some balance, say where they are, define the actions. It's very like declarative. That's pretty cool. OK. Coming back to the presentation itself. OK. One or two actual, maybe one more thing that's interesting on the, with Monolite, something I'd like to do next is like, I'm just going to show it on the sides. So imagine we have two functions, like timer and alert. So we could say like press the timer button and then, you know, you have this at shop, which is like a timer picker, right? It's like the time you want on your timer and then press the target once you have selected the time. Press and effect like alert, which is the one I played and flashed the bulb with. And then I would like run automatically, right? So like one thing I do with my nightbugs a lot is I use them as a kitchen timer. I have like bulbs over the house. The kitchen timer thing is pretty nice. You know, it doesn't like blow your like head runs. OK. I'm going to skip this. I talk about it already. I use, oh, I'm just going to talk about like art and pop-ups. I'm using his library to talk to the Belongrid. It's GPI with free. What else do I have to do? OK. I'm going to skip like lightsd. I'm going to skip this demo. But basically like this is how I will actually do the same thing, but come in line. So show you how to talk to lightsd, the demon that controls the light bulbs, which runs directly on the Wi-Fi access point here. Like it has very high level API in Python. Like, you know, I will show you an example in Python again. You can just, you know, do a decompression. You get like, you know, a one-liner, you get the set of the bulbs. Another one-liner, you can set, you know, turn them off on, do some effects. Very simple, no discovery delay, very high level. OK. That's the current project actually. Like, you know, what I should do so far on the grid is be like a small amount of the work. Most of the work was in lightsd, the other project. It's in C, once everywhere, details here. The original idea behind lightsd, were to remove like discovery delays, glitches, that comes with what the LFX manufacturer delivered to you with the light bulbs. Basically like the, like the bulbs are nice, but the software stack is sort of like not so good. It got a lot better in like three years, but like at the beginning it was really, really bad, and that's why I started the project. So original idea is like, reduce like issues, improve the user experience. Also, I like security in mind, right? I don't want to have light bulbs on my, like, you know, home network. I want light bulbs to be on a separate, dedicated, closed network. I don't want them to have access to internet. I don't want them to access anything, really, right? And lightsd by acting as a proxy allows you to do this, right? You can isolate the bubble in the network and use that as a gateway to the bulbs, right? So no cloud, no internet required, no nothing. Again, GPW3. And like something I have in mind with this project is also like to make it accessible to people, right? This is a personal project. I'm not doing this for like profit. I'm not doing this as part of my company and not doing it entirely personal. And I want it to make it accessible. So like have good code, show good practices. You know, I did like Python 3.6, like, you know, bleeding edge stuff. So like, you know, that's an opportunity to do this, right? Good docs. On the information details for lightsd, it uses a life fix as two APIs. One is HTTP. It goes over the cloud. And one is like on the local network, it's HTTP. It's much faster, so much harder to use. So I put all the communications to the bulbs, you know, I do sampling to keep track of the bulbs, right? Everything is like the bulbs themselves, you can like ask their state, set their state. But like, you know, the protocol is completely stateless, right? I need to like do sampling to like know what the state of the bulbs are, right? So I just like pull them all the time, right? And that's how I get to have low latency. You can talk to my high level API over TCP, unique sockets. Basically, like my API offers you like the same kind of functionality you have with your code API, except there is no cloud, right? It's all on your local network. On this project, I have like some fun parts and some like, you know, more like headbanging parts. One part I like to talk about especially is like what I call like stack position, right? Light Z is actually like, like, something in the middle in the stack, right? On the left, it's what I call like in lower level stuff, which are like the bulb. It's hardware, it's embedded. On the right, you have like monolight, which is a user interface. It's in Python, it's high level, it's a GUI. It's like, you know, there is not much, you know, system level programming stuff. Light Z is in the middle, it's in C. I find it's pretty interesting because it opens up to like a wide range of topics, right? And like, I didn't know it would go this way when I said working on Light Z, but like, it really opened up to a lot of things. I can like either go really deep down and start doing reverse engineering, start writing like few more bits and like underlight bulbs and like do like more hardware related things, or I can go very high level and start like writing GUIs and like very high level code, right? And I found this pretty interesting. Some of the Light Z bulbs I wanted to share with you. If you like, if you want to get them, get them on sale. They're pretty expensive. I think this you have the best brightness and colors on the market as of today and the bit, like, you know, there are competitors in this. You have to keep in mind there's standby power consumption, which is still pretty high. I'm pretty pissed at like, you know, the bulbs like saying like here on the box, it's activated A when the thing like, you know, consumes two watts and standby. I mean, if you have like, you know, like 10 light bulbs, you have like, it's like if you had always one fully, fully turned on. They have a cool NAPI and I think they are the only vendor to do this. And it's pretty cool. Like, I hope they keep it. It's pretty nice. They're not super mega hop on about it, but they're not really close about it either, right? And one thing though is only the first generation of bulbs doesn't crash for me. Right. Everything they made after this and they're in generation three basically crashes, right? They have like, I could go into the details of this. But under some lifetime conditions, which always happened to me, which always happened for me, the bulb crashes, unfortunately. So really, what I wanted to say about this is that binary blobs suck. Really, I love to be able to get access to the firmware source code and like be able to like have something more up under so I could like debug and eventually fix what's going on. Like, fix debug, add the opportunity to action on this, right? Or replace their stuff with my own stuff like this, right? So really, again, like, you know, free software convention, binary blobs suck. Still the case. Yeah. Thank you. Other things I want to do on this project, you know, do time based release, improve my CI automation, do what I call set enforcement. So basically like in my in lights, the maintain two version of the light bulbs, one which is the reality and one which is what I want. And because it's like all very janky, you know, lights you will like always try to make what's supposed to be the reality, right? So like I have two views and I apply one on top of each other. And then with this, be able to do a real cool like effects API, add effects plugin. They're like really reliable, right? And stuff like this. Other things I like to do, but I'm, you know, I will never do enough time. But however, like, if other people want to, like, you know, feel like something I love to do is like be able to like debug the film wars and have access to the film wars. Just make it easier for me to like reverse engineer the API stuff like this. That would be awesome. Yeah, it's about it. We have like a minute left for discussion and questions. So like, please go ahead. Don't be shy. Otherwise, I have like a side. Okay. One question here. Have you been in contact with supplier? Yes, I've been in contact with the supplier. Can you repeat the question? Yes. So I've been in contact with the supplier about my project. Yes. Actually, yes. And then we cognize that, for example, the crashes and they say it only affects a small amount of people. But it certainly affects me. They've been pretty nice. I think you're about the project because I'm doing something which is like completely different from like their product, right? Their product is cloud. It works in like mobile. I'm doing a demand and see that you have to install somewhere, right? I make it as easy as possible. But at some point, you're going to have to run an app get or you're going to have to like use appendability and like you put it somewhere in a Raspberry Pi, whatever you want. But you'll have to open a HOOT and type some comments, right? So they're not something that I'm really interested, right? I believe. And like I totally understand this. They're not interested to open the firmware? No, they're not interested. I also have this question. They're clearly not interested in opening their firmware. Any other question? No. Okay. Well, thank you so much. Thanks so much. Thank you.
 My name is Louis, Louis Upton.  I'm a decent software engineer.  Doesn't really matter where I am.  I don't really know anything about hardware.  And I think that's an important part of this talk.  It is I'm playing with hardware devices.  I'm playing with IoT.  And I don't really know anything about this.  I'm really just a software engineer.  So if we're going to slide number three, agenda.  So this talk is going to talk about two related projects.  One is monolight, which is an UI for devices like this one,  which is basically like a mattress of buttons, like this.  To control light bulbs.  Light bulbs like this guy here.  A guy, girl, I don't know actually.  This bulb.  So that's monolight.  It runs an interface on this button array.  And then lightsd, which is a demand to control the light bulbs.  So this demand talks to the light bulbs,  exposes a high level API, and I can control the light bulbs  this way.  I'm going to first talk about monolight.  So I control the bulbs through this button array.  I'm going to give you some details about the project.  And then I'm going to talk about lightsd, which was actually  most of the work, which is a demand to talk to the bulbs.  And then we're going to have maybe some time for the discussion.  So if you go on slide number four, you have this high level  architecture diagram.  So you can see that monolight talks to both lightsd on the button array.  And that's how I control the bulbs.  If you go next, you see that part one is going to be monolight,  part two is going to be a lightd.  Then on slide number five, title monolight.  So I just talked about what I said.  100 to the 8 buttons.  Each button has like 16 levels of brightness.  This is how I can make up a new eye by playing with the brightness levels.  It's connected to the verserial.  Then next slide.  I was controlling this smart bulb, which is made by this brand called  Lifeix.  It's about 1,000 lumens bulb.  So it's pretty high brightness.  It's like a 70 watt light bulb.  It has nice colors.  It can do all the colors.  It has a nice range of whites from like 2,500 Kelvin to like 9,000 Kelvin.  And both side bulbs are connected over Wi-Fi, 2.4 gigahertz.  So next slide.  Let's have a look at the controlling light.  So you have the grid.  So you have like this side should be just show a grid.  OK.  And then next slide, you see that the Brahm row  has got some functions.  So Brahm row is dedicated to functions.  So for example, you'll see you have like on, I can like off other functions  actually later.  So yeah, next slide that shows you some of the functions were like they're mapped.  Like how it works.  You know, I could like add more things to this balance.  Like for example, control like you know, NPD control other things.  And then I have like split the array into like four control pads.  Right.  So this is like one control pad here.  Here.  Right.  And like there is like four sliders.  And I have like some functions, other functions at the top.  Right.  So if you go to the next slide, you see like what its title is.  OK.  Awesome.  So can I make it like full screen though?  Yeah.  Let's do for the next talk.  Maybe it is very, very long.  I don't know how to put it full screen.  Oh yeah, perfect.  So just use it here.  OK.  So here.  OK.  So like that most slider is like you know the here and then saturation brightness, temperature.  So that's the HSBK you know color model HSB and then we add the temperature.  So like you know can increment, decrement.  So for example, I can show this here.  So I turn this guy off again.  I'm going to bring up the brightness which is here.  I'm going to change the color which is here.  Can do those two things at the same time.  OK.  And so on, so on.  Can I make it like less saturated?  So right.  So you can always see like a change color.  All right.  So like that was kind of the demo like see.  OK.  Other things.  All right.  Like other things.  I think this is like it's like like this.  I can just move functions.  What's interesting to see is that I'm going to make a smoother one.  That's white.  That's blue.  I'm going to.  So like what's interesting is like the board shows like the,  the side of the bar been like with low latency right.  That's sort of like a feature of what I did.  It's like it shows really like what the status of the bar is.  It's not like you know predicted or something intact.  The real status of the light bulbs is shown on the board.  So for example, if I make it like you know transition.  We can see that the starters are moving by themselves right.  And that's the program.  It's just like showing the real status of the light bulbs.  Right.  OK.  One more thing I like to show is like cool like the interface is like defined,  which I think is like pretty interesting.  So I'm going to go back and get up.  There is no internet.  OK.  Wait a minute.  I can put it on.  Yeah.  So actually I love to do this.  If you can like do this.  It would be awesome.  So like because so like the way all this is implemented is in Python.  So like the program that controls the grid is in Python.  And the API and manage only are pretty high level.  And the way you like set your UI element on the grid is I think pretty interesting.  It's pretty high level.  And that's about it for like monolight on the implementation details,  which you'll find on the slides.  So this is Python.  I've been using Python 3.5 and 3.6 with top annotations, which are awesome.  So you basically like you know do type Python.  I really encourage you to look into this if you do Python or not.  And then I use a CKL.  So everything is in synchronous.  Awesome.  Thank you so much.  So I'm going to go on my profile.  So there we go.  You'll even know like the repository architecture by the end.  That's pretty awesome.  So it's going to be UI.  So what I'm using, no.  No.  OK.  Yeah.  So see it's how the UI is defined, right?  So I can do, OK, I have like a root layer on 949.  And then I can insert some balance, the balance of different actions in line.  So see for example like the other, you know, the pink graph, which is the effect I did,  which was moving slowly.  There is the other, which is the flashing I did.  So see I just like define some balance, say where they are, define the actions.  It's very like declarative.  That's pretty cool.  OK.  Coming back to the presentation itself.  OK.  One or two actual, maybe one more thing that's interesting on the, with Monolite,  something I'd like to do next is like, I'm just going to show it on the sides.  So imagine we have two functions, like timer and alert.  So we could say like press the timer button and then, you know, you have this at shop,  which is like a timer picker, right?  It's like the time you want on your timer and then press the target once you have selected the time.  Press and effect like alert, which is the one I played and flashed the bulb with.  And then I would like run automatically, right?  So like one thing I do with my nightbugs a lot is I use them as a kitchen timer.  I have like bulbs over the house.  The kitchen timer thing is pretty nice.  You know, it doesn't like blow your like head runs.  OK.  I'm going to skip this.  I talk about it already.  I use, oh, I'm just going to talk about like art and pop-ups.  I'm using his library to talk to the Belongrid.  It's GPI with free.  What else do I have to do?  OK.  I'm going to skip like lightsd.  I'm going to skip this demo.  But basically like this is how I will actually do the same thing, but come in line.  So show you how to talk to lightsd, the demon that controls the light bulbs,  which runs directly on the Wi-Fi access point here.  Like it has very high level API in Python.  Like, you know, I will show you an example in Python again.  You can just, you know, do a decompression.  You get like, you know, a one-liner, you get the set of the bulbs.  Another one-liner, you can set, you know, turn them off on, do some effects.  Very simple, no discovery delay, very high level.  OK.  That's the current project actually.  Like, you know, what I should do so far on the grid is be like a small amount of the work.  Most of the work was in lightsd, the other project.  It's in C, once everywhere, details here.  The original idea behind lightsd, were to remove like discovery delays, glitches,  that comes with what the LFX manufacturer delivered to you with the light bulbs.  Basically like the, like the bulbs are nice, but the software stack is sort of like not so good.  It got a lot better in like three years, but like at the beginning it was really, really bad,  and that's why I started the project.  So original idea is like, reduce like issues, improve the user experience.  Also, I like security in mind, right?  I don't want to have light bulbs on my, like, you know, home network.  I want light bulbs to be on a separate, dedicated, closed network.  I don't want them to have access to internet.  I don't want them to access anything, really, right?  And lightsd by acting as a proxy allows you to do this, right?  You can isolate the bubble in the network and use that as a gateway to the bulbs, right?  So no cloud, no internet required, no nothing.  Again, GPW3.  And like something I have in mind with this project is also like to make it accessible to people, right?  This is a personal project.  I'm not doing this for like profit.  I'm not doing this as part of my company and not doing it entirely personal.  And I want it to make it accessible.  So like have good code, show good practices.  You know, I did like Python 3.6, like, you know, bleeding edge stuff.  So like, you know, that's an opportunity to do this, right?  Good docs.  On the information details for lightsd, it uses a life fix as two APIs.  One is HTTP.  It goes over the cloud.  And one is like on the local network, it's HTTP.  It's much faster, so much harder to use.  So I put all the communications to the bulbs, you know, I do sampling to keep track of the bulbs, right?  Everything is like the bulbs themselves, you can like ask their state, set their state.  But like, you know, the protocol is completely stateless, right?  I need to like do sampling to like know what the state of the bulbs are, right?  So I just like pull them all the time, right?  And that's how I get to have low latency.  You can talk to my high level API over TCP, unique sockets.  Basically, like my API offers you like the same kind of functionality you have with your code API, except there is no cloud, right?  It's all on your local network.  On this project, I have like some fun parts and some like, you know, more like headbanging parts.  One part I like to talk about especially is like what I call like stack position, right?  Light Z is actually like, like, something in the middle in the stack, right?  On the left, it's what I call like in lower level stuff, which are like the bulb.  It's hardware, it's embedded.  On the right, you have like monolight, which is a user interface.  It's in Python, it's high level, it's a GUI.  It's like, you know, there is not much, you know, system level programming stuff.  Light Z is in the middle, it's in C.  I find it's pretty interesting because it opens up to like a wide range of topics, right?  And like, I didn't know it would go this way when I said working on Light Z, but like, it really opened up to a lot of things.  I can like either go really deep down and start doing reverse engineering, start writing like few more bits and like underlight bulbs and like do like more hardware related things,  or I can go very high level and start like writing GUIs and like very high level code, right?  And I found this pretty interesting.  Some of the Light Z bulbs I wanted to share with you.  If you like, if you want to get them, get them on sale.  They're pretty expensive.  I think this you have the best brightness and colors on the market as of today and the bit, like, you know, there are competitors in this.  You have to keep in mind there's standby power consumption, which is still pretty high.  I'm pretty pissed at like, you know, the bulbs like saying like here on the box, it's activated A when the thing like, you know, consumes two watts  and standby.  I mean, if you have like, you know, like 10 light bulbs, you have like, it's like if you had always one fully, fully turned on.  They have a cool NAPI and I think they are the only vendor to do this.  And it's pretty cool.  Like, I hope they keep it.  It's pretty nice.  They're not super mega hop on about it, but they're not really close about it either, right?  And one thing though is only the first generation of bulbs doesn't crash for me.  Right.  Everything they made after this and they're in generation three basically crashes, right?  They have like, I could go into the details of this.  But under some lifetime conditions, which always happened to me, which always happened for me, the bulb crashes, unfortunately.  So really, what I wanted to say about this is that binary blobs suck.  Really, I love to be able to get access to the firmware source code and like be able to like have something more up under so I could like debug and eventually fix what's going on.  Like, fix debug, add the opportunity to action on this, right?  Or replace their stuff with my own stuff like this, right?  So really, again, like, you know, free software convention, binary blobs suck.  Still the case.  Yeah.  Thank you.  Other things I want to do on this project, you know, do time based release, improve my CI automation, do what I call set enforcement.  So basically like in my in lights, the maintain two version of the light bulbs, one which is the reality and one which is what I want.  And because it's like all very janky, you know, lights you will like always try to make what's supposed to be the reality, right?  So like I have two views and I apply one on top of each other.  And then with this, be able to do a real cool like effects API, add effects plugin.  They're like really reliable, right?  And stuff like this.  Other things I like to do, but I'm, you know, I will never do enough time.  But however, like, if other people want to, like, you know, feel like something I love to do is like be able to like debug the film wars and have access to the film wars.  Just make it easier for me to like reverse engineer the API stuff like this.  That would be awesome.  Yeah, it's about it.  We have like a minute left for discussion and questions.  So like, please go ahead.  Don't be shy.  Otherwise, I have like a side.  Okay.  One question here.  Have you been in contact with supplier?  Yes, I've been in contact with the supplier.  Can you repeat the question?  Yes.  So I've been in contact with the supplier about my project.  Yes.  Actually, yes.  And then we cognize that, for example, the crashes and they say it only affects a small amount of people.  But it certainly affects me.  They've been pretty nice.  I think you're about the project because I'm doing something which is like completely different from like their product, right?  Their product is cloud.  It works in like mobile.  I'm doing a demand and see that you have to install somewhere, right?  I make it as easy as possible.  But at some point, you're going to have to run an app get or you're going to have to like use appendability and like you put it somewhere in a Raspberry Pi, whatever you want.  But you'll have to open a HOOT and type some comments, right?  So they're not something that I'm really interested, right?  I believe. And like I totally understand this.  They're not interested to open the firmware?  No, they're not interested.  I also have this question.  They're clearly not interested in opening their firmware.  Any other question?  No.  Okay.  Well, thank you so much.  Thanks so much.  Thank you.
Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_0_71.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_72_131.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_132_767.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_768_1031.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_1032_2579.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_2580_3071.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_3072_4991.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_4992_5255.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_5256_8711.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_8712_12803.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_12804_14339.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_14340_16127.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_16128_16511.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_16512_21647.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_21648_22403.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_22404_23303.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_23304_24839.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_24840_25607.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_25608_26495.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_26496_27143.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_27144_27779.png Playing_with_the_lights_Control_LIFX_WiFienabled_light_bulbs_27780_27896.png