> For the complete documentation index, see [llms.txt](https://docs.launchboard.app/cxd/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.launchboard.app/cxd/internet-of-things-project/iot-project-outline/1-5-build-smart-lightbulb.md).

# 1-5 Build Smart Lightbulb

The [Philips Hue](http://www2.meethue.com/en-us/) smart lightbulb was introduced in 2012, and now several companies offer smart lightbulbs. Smart lightbulbs can be controlled remotely using a mobile app and offer features like setting automatic on-off schedules, dimming lights, changing the light color, syncing lights to music, etc.

**VIDEO:** [Philips Hue Smart Lighting](https://www.youtube.com/watch?v=tgGlYsUlCbI)

![](https://576155698-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LDgX-RdB-DPZBPuXzJ1%2F-LDgX75Qrx69yS4tZ2_Z%2F-LDgXC78kskkKaJTb-i1%2Fphilips-hue-lightbulb.png?generation=1527608056019501\&alt=media)

### YOUR TASK

As an introduction to building and programming IoT devices using your Photon kit, your team will create a **prototype** of a smart lightbulb that can be controlled by a web app.

Your team will build its prototype of a smart lightbulb in four versions (or iterations) that keep getting closer to the end result. Each time you will modify your existing Photon device and your existing Photon code.

1. **Prototype Version 1:** Connect LED light to Photon device, and have Photon code turn light on and off in repeating cycle.
2. **Prototype Version 2:** Add push button to Photon device, and have Photon code turn on light when button is pressed.
3. **Prototype Version 3:** Modify Photon code so button switches light on or off with each push, like a regular light switch.
4. **Prototype Version 4:** Modify Photon code so it interacts with a web app by sending and receiving data through Internet. Create web app that shows current status of light and allows user to switch light on or off remotely.

Since this is practice, the instructions provided below will tell you which parts are needed, show you how to connect them, and even provide the code needed.

Your focus should be on:

* understanding how to connect the parts to form circuits that power the parts and transfer data
* understanding how the Photon code controls the parts and processes data
* understanding how the Photon code and a web app can interact by sending and receiving data through the Internet

## BACKGROUND

Each part (such as LED, etc.) that you connect to your Photon device must have a complete electrical circuit. The jumper wires and breadboard are used to help make a circuit for each part.

If this is your first time using an electronics kit, then read this helpful background about [circuits and the breadboard](/cxd/internet-of-things-project/references-for-wiring-and-coding/creating-circuits.md).

## PROTOTYPE VERSION 1

**GOAL: Connect LED light to Photon device, and have Photon code turn light on and off in repeating cycle.**

Complete [Experiment 1](https://learn.sparkfun.com/tutorials/sparkfun-inventors-kit-for-photon-experiment-guide/experiment-1-hello-world-blink-an-led) of the online SparkFun Photon Experiment Guide. *Only complete the first part – skip Part 2.*

**For the Photon code, just modify (or copy) your existing** [**Hello World app**](/cxd/internet-of-things-project/references-for-wiring-and-coding/hello-world-app-for-photon.md)**.** That code is identical to the code for Experiment 1, except for the pin being used for the LED. In Hello World, you used pin D7 (built-in LED). In Experiment 1, you are instructed to connect an LED light bulb to pin D0. So just change this one line of code as shown below:

```java
// global variables
int led = D0;
```

**NOTE:** LED lights need to be connected correctly. They are polarized (meaning they have a positive end and a negative end), and they need to be connected through a resistor (to limit the current that flows through the bulb). Pay attention to the diagrams and instructions in the experiment.

## PROTOTYPE VERSION 2

**GOAL: Add push button to Photon device, and have Photon code turn light on when button is pressed.**

Complete [Experiment 2](https://learn.sparkfun.com/tutorials/sparkfun-inventors-kit-for-photon-experiment-guide/experiment-2-with-the-touch-of-a-button) of the online SparkFun Photon Experiment Guide. *Only complete the first part – skip Part 2.*

**For the Photon code, modify your existing code from the previous step.** The complete code for Experiment 2 is shown below.

```java
// global variables
int led = D0;
int pushButton = D2;

void setup() {
    pinMode(pushButton, INPUT_PULLUP);
    pinMode(led, OUTPUT);
}

void loop() {
    int pushButtonState = digitalRead(pushButton);

    // LOW means button is being pushed
    if(pushButtonState == LOW) {
        digitalWrite(led, HIGH);
    } else {
        digitalWrite(led, LOW);
    }
}
```

The push buttons included in your kit are classified as **momentary** switches, meaning they are only active ("on") when they are being pushed. Everyday examples of momentary switches are doorbell switches and the keys on a computer keyboard.

## PROTOTYPE VERSION 3

**GOAL: Modify Photon code so button switches light on or off with each push.**

You will modify your existing Photon code to make the push button act similar to a **maintained** switch, which maintain their current state (on or off) until pushed again. This is how most light switches operate.

To do this, you need to create a global variable in the Photon code to keep track of the light's current state (on or off), so the light can be switched to the opposite state when the button is pushed again. Let's name this variable as: `ledStatus`

There are several possible data types that could be used for this variable, but we have to select only one to use:

```java
// DON'T copy and paste this

// possible data types for variable - can only use one
int ledStatus = 0; // 0 represents off, 1 represents on
boolean ledStatus = false; // false represents off, true represents on
String ledStatus = "off"; // use "off" or "on"
```

Although any of those data types above would work, the code might be easier to understand if we use a String variable to track `ledStatus` as "off" or "on" by changing the variable's value whenever the button is pushed.

Since we still need global variables for the LED pin and the push button pin, our final list of global variables will be:

```java
// global variables
int led = D0;
int pushButton = D2;
String ledStatus = "off";
```

Let's make sure the light is actually off when the device first starts (so it matches the initial `ledStatus` assigned in the global variables). To do this, add a statement within the `setup()` function.

```java
void setup() {
    pinMode(pushButton, INPUT_PULLUP);
    pinMode(led, OUTPUT);

    // make sure light is off at start
    digitalWrite(led, LOW);
}
```

Let's add a custom function at the end of the Photon code that will toggle the light on or off based on the current `ledStatus`. Let's name this function as: `ledToggle()`

```java
void ledToggle(){
    if (ledStatus == "off") {
        digitalWrite(led, HIGH);
        ledStatus = "on";
    } else {
        digitalWrite(led, LOW);
        ledStatus = "off";
    }
}
```

Now you can "call" (run) this custom function within the `loop()` whenever the button is pushed:

```java
void loop() {
    int pushButtonState = digitalRead(pushButton);

    if(pushButtonState == LOW) {
        ledToggle();
    }

    // wait before reading button again
    delay(200);
}
```

Notice that a slight delay was included before reading the button again. (The delay command uses milliseconds, so 1000 milliseconds = 1 second.)

Without a delay (or if the delay is too short), the code loops so fast that it toggles the light on and off multiple times with each button press, making the device seem unpredictable. If the delay is too long, the device feels unresponsive because you have to hold down the button longer to have the code detect the press.

Remember to flash the modified app to your Photon device to test it out.

## PROTOTYPE VERSION 4

**GOAL: Modify Photon code so it interacts with a web app by sending and receiving data through Internet. Create a web app that shows current status of light and allows user to switch light on or off remotely.**

You will modify your existing Photon code to send and receive data through the Particle Cloud service. Then you will create a web app that uses the Particle JavaScript library to send and receive data through the Particle Cloud.

Particle has built-in functions to share data through the Particle Cloud service. This is how your Photon device can interact with other apps (or even with other Photon devices).

### Modify Photon Code

We want to share the `ledStatus` variable with our web app, so we can display the current status of the light. We can share the current value of a variable by adding one line of code to the `setup()` function:

```java
Particle.variable("ledStatus", ledStatus);
```

We need to first tell it what name to call the variable in Particle Cloud (name can be up to 12 characters) and then identify the name of the variable in the Photon code. Usually, these two will have the same name (but they don't have to).

Next, we want to be able to receive data from our web app, so we can run the function to toggle the light on or off when the user clicks a button in the web app. Again, we can do this by adding one line of code to the the `setup()` function:

```java
Particle.function("led", ledToggle);
```

We need to first tell it what name to call the function in Particle Cloud (name can be up to 12 characters) and then identify the name of the function in the Photon code to run. These can have the same name or be different.

We will also need to modify our `ledToggle()` function. If we want to use the Particle Cloud to call a function in our Photon code, then the function in the Photon code **must** return a `int` value (instead of `void` or some other data type) – and the function **must** accept a `String` value from the Particle Cloud (the string is the data that our web app sends to the Photon device).

However, you do *not* necessarily have to do any with the function's return value or even with the String value – they just need to be present in the code for it to communicate properly with Particle Cloud.

The modified `ledToggle()` function is as follows:

```java
int ledToggle(String data){
    if (ledStatus == "off") {
        digitalWrite(led, HIGH);
        ledStatus = "on";
        return 1;
    } else {
        digitalWrite(led, LOW);
        ledStatus = "off";
        return 0;
    }
}
```

Now we have to also modify the line of Photon code in the loop that calls this function when the user pushes the button on the device. We **must** pass a string value to the function (even though we decided to not actually use this string for anything inside the function).

The modified `loop()` function is as follows (only change is adding `"toggle"`):

```java
void loop() {
    int pushButtonState = digitalRead(pushButton);

    if(pushButtonState == LOW) {
        ledToggle("toggle");
    }

    // wait before reading button again
    delay(200);
}
```

That takes care of the changes in the Photon code. Remember to flash the modified app to your Photon device.

### Create Web App

Create a new HTML file (**index.html**), CSS file (**style.css**), and JavaScript file (**code.js**) using a code editor (such as Editey in Google Drive, etc.). Make sure the files are blank.

Copy and paste the HTML code below into **index.html**

#### HTML for index.html

```markup
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Smart Lightbulb</title>
        <script src="//cdn.jsdelivr.net/jquery/3.1.1/jquery.min.js" type="text/javascript"></script>
        <script src="//cdn.jsdelivr.net/particle-api-js/6.4.2/particle.min.js" type="text/javascript"></script>
        <script src="code.js" type="text/javascript"></script>        
        <link href="style.css" rel="stylesheet" type="text/css">
    </head>
    <body>
        <h1>My Smart Light</h1>
        <div id="light" class="card">
            <h2 id="light-name" contenteditable="true">Light 1</h2>
            <h2 id="light-status">Connecting...</h2>
            <button id="light-button" onclick="toggleLight();">Wait</button>
        </div>
    </body>
</html>
```

Notice that the HTML `<head>` section loads 3 JavaScript files:

1. **jQuery** which is a JavaScript library that makes it easier to do things like change HTML or CSS in your web app
2. **Particle API JS** which is a JavaScript library that contains functions that allows your web app do things like share data through Particle Cloud
3. **code.js** which is your own JavaScript file that will get data from your Photon device, send data to your Photon device, and update your web app to show the current status of your Photon device.

Notice that we've assigned unique id names to several elements within the `<body>` section. This will allow us to use jQuery functions to change these elements.

Finally, notice that we added an onclick event to the `<button>` that will run a JavaScript function called `toggleLight()` which will be in your **code.js** file.

Next, copy and paste the CSS code below into **style.css**

#### CSS for style.css

```css
body {
    font-family:  Helvetica, Arial, sans-serif;
    font-size: 1em;
    text-align: center;
}
h1 {
    color: red;
}
.card {
    width: 250px;
    height: 200px;
    padding: 10px;
    margin: 0 auto 20px;
    border: 1px solid #888;
    border-radius: 5px;
    box-shadow: 2px 2px 2px #ccc;
    background-color: #bbb;
    text-align: center;
}
.light-on {
    background-color: #ffff99; /* yellow */
}
button {
    padding: 10px;
    width: 100px;
    border-radius: 10px;
    font-size: 1em;
    color: #444;
    background-color: white;
}
```

The CSS will make our web app look nicer. The `<div>` in the HTML is styled to look like a card. The background color will be gray when the light is off but will be changed to yellow when the light is on.

We will change this background color by using jQuery to add the class of `.light-on` to the `<div>` if the data from the Particle Cloud tells us the light is on. When the light is turned off, we will use jQuery to remove that class (making the card gray again).

Finally, copy and paste the JavaScript code below into **code.js**

#### JavaScript for code.js

```javascript
var myDevice = "000000000000000000000000"; // insert your Photon device ID
var myToken = "abcdefghijklmnopqrstuvwxyz1234567890"; // insert your Photon access token
var particle = new Particle();

window.setInterval(checkLight, 200);

function checkLight(){
    particle.getVariable({ deviceId: myDevice, name: "ledStatus", auth: myToken }).then(function(data) {
            if (data.body.result == "on") {
                $("#light").addClass("light-on");
                $("#light-status").html("ON");
                $("#light-button").html("Turn Off")
            } else if (data.body.result == "off") {
                $("#light").removeClass("light-on");
                $("#light-status").html("OFF");
                $("#light-button").html("Turn On")
            }
    }, function(err) {
            console.log("An error occurred retrieving data:", err);
    });
}

function toggleLight() {
    particle.callFunction({ deviceId: myDevice, name: "led", argument: "toggle", auth: myToken });
}
```

Notice that the first two lines of JavaScript are supposed to list your Photon **device ID** and your Photon **access token**, which must be copied and pasted from your Particle Build account.

**IMPORTANT:** *If you don't update these first two lines of JS code, your web app will **not** work properly.*

* Your Photon **device ID** is listed in the "Devices" section of your Particle Build account. Click the arrow to the right of your Photon device name to reveal the device ID. This device ID acts like a username to access your device's data in the Particle Cloud service.
* Your Photon **access token** is listed in the "Settings" section of your Particle Build account. This access token acts as a password to access your device's data in the Particle Cloud service. (*If you reset your access token at some future point, you would have to update your web app to use the new token*.)

Next notice that we include a JavaScript statement that tells the webpage (window) to run the `checkLight` function at an interval of once every 200 milliseconds. This lets the web app stay updated on the current status of the light.

Next, we list our `checkLight()` function that we already told the web app to run every 200 milliseconds. Inside this function, it checks the current value of the `ledStatus` variable that is being shared to the Particle Cloud by your Photon device.

Here's how `particle.getVariable` in the web app matches up with `Particle.variable` in the Photon code. Notice that what links them is the name `"ledStatus"` – this is the variable in the Photon code that is being sharing through Particle Cloud.

```java
// Just a comparison - DON'T copy and paste these again

// WEB APP 
function checkLight(){
    particle.getVariable({ deviceId: myDevice, name: "ledStatus", auth: myToken }).then(function(data) {
            if (data.body.result == "on") {
                $("#light").addClass("light-on");
                $("#light-status").html("ON");
                $("#light-button").html("Turn Off")
            } else if (data.body.result == "off") {
                $("#light").removeClass("light-on");
                $("#light-status").html("OFF");
                $("#light-button").html("Turn On")
            }
    }, function(err) {
            console.log("An error occurred retrieving data:", err);
    });
}


// PHOTON CODE
Particle.variable("ledStatus", ledStatus);
```

Once we get the data result for the `"ledStatus"` variable, we use jQuery statements to add or remove the class `light-on` to switch the card background to yellow or gray and to update the text in two HTML elements.

Finally, the last thing in our JavaScript is the `toggleLight()` function that will run whenever the user clicks the on-screen button. Inside this function, it calls the `"led"` function through Particle Cloud and sends it data (the String argument, which we assigned a value of "toggle").

Here's how `particle.callFunction` in the web app matches up with `Particle.function` in the Photon code. Notice that what links them is the name `"led"` – this is the function that the web app calls through Particle Cloud. When the Photon code receives this call, the Photon code runs the custom function called `ledToggle` and passes it the String data sent by the the web app.

```java
// Just a comparison - DON'T copy and paste these again

// WEB APP 
function toggleLight() {
    particle.callFunction({ deviceId: myDevice, name: "led", argument: "toggle", auth: myToken });
}

// PHOTON CODE
Particle.function("led", ledToggle);

int ledToggle(String data){
    if (ledStatus == "off") {
        digitalWrite(led1, HIGH);
        ledStatus = "on";
        return 1;
    } else {
        digitalWrite(led1, LOW);
        ledStatus = "off";
        return 0;
    }
}
```

Be sure to refresh your web app, and it should now be able to interact with your Photon device. You should be able to push the physical button on the Photon device to switch the light on or off – and see that your web app shows the updated light status relatively quickly.

You should also be able to do the reverse: click the on-screen button in your web app to see that it toggles the light on your Photon device and then updates the light status on the web app.

**NOTE:** There may be a slight delay of about 0.5 second for the device and web app to sync up. Keep in mind that the web app was told to only run `checkLight()` once every 0.2 seconds. We also told the Photon code to add its own delay of 0.2 seconds because of the push button. Also, the data is traveling from an app on one device through the Internet to Particle Cloud and then back again through the Internet to the other app on a different device. (Remember data is **not** being transferred through the USB cable – it only provides power.)

### You've just created your first IoT device!

### GOING FURTHER

If you have time, you could think about ways to modify the smart lightbulb and its apps. *Can you further customize the appearance of the web app? Can you add a second LED light and second button to your Photon device – and then modify your Photon app and web app to control each light separately? What are some other features that you could try to add to the smart lightbulb web app (dimming lights, setting on-off schedule, etc.)?*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.launchboard.app/cxd/internet-of-things-project/iot-project-outline/1-5-build-smart-lightbulb.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
