Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Automate Home Lights With The Fetch API
Michael Liendo
Michael Liendo

Posted on

     

Automate Home Lights With The Fetch API

Now that I've settled into being home more-so than usual, I'm looking for ways to improve my decor.

I read thatinterior lighting can boost your mood, the same way colors on a web page can. So I decided to purchase someLIFX Mini bulbs--no hub required, and can say after a couple days, it's definitely helped keep me sane during these times.

However, after a bit, my developer itch was kicking in. So in this project, we'll use thefetch web API to first list our lights, and from there, we will send a request to a particular light so that it's color changes.

🗒️ It's worth mentioning that if you don't want to take the coding route, the serviceIFTTT has many 3rd party integrations that you can take advantage of to enhance your lighting experience.


🚨 If you just want to look at the code and fill in the blanks, there is a codeSandbox down below. Just make sure to update thesuper-secret-token.js file with your keys if wanting to make it work 😉

Getting an API Key

I was pleased to find that LIFX has an API for their bulbs, and upon signing up, you can access your secret token that we'll need later on.

Admittedly, it took me longer in figuring where to find my token than it did to write the code, so to help out, here's the easy path:

  1. Head over to thecloud portal and sign inwith the same username and password that you used to sign in with on your mobile app

  2. Once you're signed it, you should be redirected to a page where you can "Generate New Token" (note that I already have a few tokens created).

Click the "Generate New Token" button and give your token a name.

generate token

That's it 🎉 Now you should see your secret token.

🗒️ As is mentioned on the site, you'll want to copy that somewhere safe because once you navigate away from the page, you won't be able to access the token again and can only generate a new one. In codeSandbox, the easiest way to do this, is to make your project private or an a minimum, unlisted

Alt Text

Reading the Docs

Now that I had an API Key, I was able tocheckout the docs and figure out what endpoints were available to me.

In particular theList Lights and theSet State endpoints are what we'll be using.

Authentication

It's worth reading over theAuthentication andRate Limits sections to understand how the API keeps us secure and prevents spamming. Here are the main points:

  • If usingBasic auth, as we are, we'll need to provide our token as the username
  • Our requests have to have theContent-Type: application/json header
  • Our token allows us to make 120 requests every 60 seconds. We can use theX-RateLimit-Remaining response header to see how many request we have left.

Setting Up Our Project

As mentioned above, if you have your secret token, feel free to plug that into thesuper-secret-token.js file'sTOKEN area and click theList Light ids button to get your lights. From there, pick and id, plug it into the other secret value, and it should Just Work™️

For those still with me, let's use the sandbox above and take a tour of the code.

Starting with theindex.html file, you'll notice it's fairly boring. It's vanilla JavaScript and we just have a couple of elements withid's assigned so that we can target them in our code. The most appealing part is that we have<input type="color" />. Giving aninput atype attribute of "color" will give us a nice color picker on both desktop and mobile!

Let's get to the star of the show.

Finally Making Our Request With Fetch

Inindex.js we kick things off by bringing in our tokens, and grabbing a few elements that we created in ourindex.html file.

Next up we add an event-listener to our button so we can trigger a request whenever a user clicks theList Light ids button.

Now on to our request.

Fetch With Basic Auth

fetch takes in an endpoint as a first argument. Which we are passing as a string

fetch(`https://api.lifx.com/v1/lights/all`
Enter fullscreen modeExit fullscreen mode

Additionally,fetch can take an object used for configuration as a second argument. This is where we can specify any required headers, as well as set the auth type.

headers:{"Content-Type":"application/json",Authorization:`Basic${btoa(TOKEN)}`}
Enter fullscreen modeExit fullscreen mode

🔥 Note the use of thebtoa function. This is the browser's built-in method for converting anormal string to a base64 encoded string. If wanting to convert the other way around, there's alsoatob().

From there, we continue as usual:

  1. Fetch returns apromise so we call.then to run code when we get a response from the server
  2. We take the response from the server and parse the data as JSON viares.json()
  3. We update the DOM to show the list of lights in the subsequent.then block.

Fetch With APut Verb and Hidden Headers

Things get even more interesting with our "change color" button.

After listening for a click event, we grab the value from the input and log it out. What this reveals is that the value is in fact a hex color:#00ffff for example.

This is great because to change a light's color to something more that just a generic "green", we'll have to pass in a hex code value.

Now within ourfetch request, we have a new endpoint. This one ends inid:${LIGHT_ID}/state where theLIGHT_ID as you may have guessed, is one of the lights that we got back from ourList Light ids button.

However, let's take a moment to dissect the second argument: the configuration object

{method:"put",headers:{"Content-Type":"application/json",Authorization:`Basic${btoa(TOKEN)}`},body:JSON.stringify({color:colorValue})
Enter fullscreen modeExit fullscreen mode

Here, we say the method isput because we aresending data. The headers are the same as before. Next up thebody is the data that we are sending. Servers typically expect JSON data to be passed to them, so we use the built-inJSON.stringify() method to convert our object to that format for us.

🎉All done🎉

That alone is enough to get the color to change! If all went well, you should see something like the below tweet


🔥Extra Credit🔥

Recall, that the API only allows us to send 120 requests per minute. So the question becomes: How can we make sure we don't go over our limit so that our application doesn't break or we get flagged for spamming?

The answer is in the final lines of our code:

.then(res=>{console.log(res.headers.get("x-ratelimit-remaining"));returnres.json();}).then(data=>console.log(data));// display to user
Enter fullscreen modeExit fullscreen mode

Normally, when usingfetch, only a small amount of headers are actually available for us to access. So sayingres.headers["x-ratelimit-remaining"] is going to give usundefined. However, using the specialres.headers.get() function, we can target the header that lets us know how many requests are remaining.

There are actually plenty of other headers to checkout as well! I included an award-winning screenshot of how to find them:

Network Tab

Top comments(5)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
delfick profile image
Stephen Moore
  • Location
    Australia
  • Work
    Software Engineer at LIFX
  • Joined

Hello,

I work in the Cloud team at LIFX

Cool article!

Just a couple notes, you can avoid needing the btoa function by telling the server to use the token as a Bearer. So you can say"Authorization: Bearer ${token}"

Also, there's multiple ways of specifying the colour as shown hereapi.developer.lifx.com/docs/colors

So, for example, if you want your lights to be a cool white you can say{"color": "kelvin:8000 saturation:0"} and that way you don't need to figure out the hex for that :)

CollapseExpand
 
focusotter profile image
Michael Liendo
Will code for tacos 🤤Lover of teaching, speaking, learning, and growing. Egghead Instructor. AWS Community Builder
  • Email
  • Location
    Midwest
  • Education
    self-paced
  • Work
    Senior Developer Advocate at AWS
  • Joined

Hey! Thanks so much for checking it out!

Yea, it's super nice to be able to use more specific colors it's just that color inputs give a hex value by default.

Would Bearer tokens be a simpler approach? I tried switching it over, but it said the token was no longer valid. I'm assuming because it's a raw token and not one given from an oAuth flow?

Thanks again for checking it out! I actually have 2 more posts coming up with fun projects around these lights, so if there's anything specific you'd like to see covered, my DM's are open on Twitter and I'd love to help out!

CollapseExpand
 
delfick profile image
Stephen Moore
  • Location
    Australia
  • Work
    Software Engineer at LIFX
  • Joined

I'm not sure why your token wouldn't work as a Bearer token. If you get your token, can you do something like this from the command line?

curl http://api.lifx.co/v1/lights -H"Authorization: Bearer c6805af2e4fa8cd15dc28a8c6e54cc1c371e9efafb87b10536341105f74087a3"

(in this example, that's not a real token, but it looks like one :p)

The token you create from cloud.lifx.com never expires. The only way they stop working is if you revoke them from that same page.

I look forward to reading your other articles :)

Thread Thread
 
focusotter profile image
Michael Liendo
Will code for tacos 🤤Lover of teaching, speaking, learning, and growing. Egghead Instructor. AWS Community Builder
  • Email
  • Location
    Midwest
  • Education
    self-paced
  • Work
    Senior Developer Advocate at AWS
  • Joined

Thanks so much, I got it to work with a Bearer token!

With Basic auth, it'stoken:, but I didn't need the colon for Bearer auth.

Thanks again, that definitely remotes some overhead!

Thread Thread
 
delfick profile image
Stephen Moore
  • Location
    Australia
  • Work
    Software Engineer at LIFX
  • Joined

Awesome! :)

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Will code for tacos 🤤Lover of teaching, speaking, learning, and growing. Egghead Instructor. AWS Community Builder
  • Location
    Midwest
  • Education
    self-paced
  • Work
    Senior Developer Advocate at AWS
  • Joined

More fromMichael Liendo

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp