How to Control Philips Wiz Bulb Using Go
Tags: iot, homeautomation, philipswiz
Published: 2023-02-17 18:30:00

## Introduction

I have always been conscious about privacy and it was the sole reason I wasn't early adapter of smart home devices. This changed when I bought Raspberry Pi. I learned that I can make my Pi hub to all the smart devices at my home.

And this is how I bought 9W Philips Wiz light; the cheapest one I could get in the Indian market.

To use this product, you at least need to have a home network (a wifi router will work). The router does not need to have internet connection.

## Control Philips Wiz using App

The most common way to control the Wiz light is using the mobile app. It is available for both [Android](https://play.google.com/store/apps/details?id=com.tao.wiz&hl=en_IN&gl=US&pli=1) and [iOS](https://apps.apple.com/us/app/wiz-connected/id1497247770).

I don't want to cover how to operate the bulb using the app. I would leave it upto you. I want you to explore the app completely before proceeding towards the next section.

As we are going to control the bulb using code, I want you to practice doing these actions:

- Turn on/off
- Set colors
- Set brightness
- Set temperature
- Set modes

## Control Philips Wiz using Go

While there are libraries available to interact with the bulb, I wanted to show you guys what happens internally with the bulb. In a home automation scenario, you'd mostly be using such libraries.

### Find the bulb IP

Before we write any piece of code, it is crucial to find out the IP of your bulb. In most latest routers, they show what clients are connected to the router, the device name should appear as `wiz_xxxxxx` where `xxxxxx` is the starting mac address of the bulb.

If somehow your router does not supports showing the IP of connected devices, you'll have to do some hit and trial.

- Get the IP of your PC/Laptop. You can run `ip a` if you are on Linux. My PC's IP is `192.168.0.100`.
- Turn off the light from the app and send the *Hello Philips Wiz* code described in next section to each of the IPs near to your PCs IP. 

So I'd send following message to 192.168.0.95-105. How many machines you have to try depends on how many devices you have on your network.

We need the IP because we are going to communicate with bulb by sending and receiving UDP messages.

### Hello Philips Wiz using UDP

```go
package main

import "net"

var wizIP = "192.168.0.101"  // this is address on my bulb in my network
const wizPort = "38899"

func main() {
	c, err := net.Dial("udp", fmt.Sprintf("%s:%s", wizIp, wizPort)
	if err != nil {
		panic("could not connect to wiz light")
	}

	c.Write([]byte(`{"method": "setPilot", "params":{"state": true}}`))
}
```

Starting at line 5, first we have to define the IP of the bulb. It is `192.168.0.101` in my case.

Next we have to define the port on which Wiz light listens on. This port ID is constant and won't change unlike the `wizIP`.

Line 14 is the most important. The message is actually a JSON. Let's beautify it before discussing about it.

```json
{
  "method": "setPilot",
  "params": {
    "state": true
  }
}
```

1. "method": The first key in the JSON object is `method`. This is either `getPilot` or `setPilot` depending on whether you want to get the state of the bulb, or set a state to the bulb. In our case, we are going to set some state. I have never really used the `getPilot` method, yet.
2. "params": Next in the JSON object is parameters we are sending; it is denoted by `params` in the JSON body. This is going to complement the `method`.

Now depending on what we are trying to do with the bulb, the params are going to change. In above code, we are just saying to set the `state` to `true`, which literally means to start the bulb.

If your bulb was off, it would have turned on after running the above code.

Similarly, if you want to turn it off, change the state to `false` and send the message again.

### Set custom colors

Wiz accepts RGB colors values. If you don't know what that means, go to google and type in "rgb color picker", then choose a color and then note the RGB value. For example, value for pure **red** would be 255, 0, 0. Here 255 is the value of red, and 0 is for both green and blue.

To set Wiz to red color, this message can be sent:

```json
{
  "method": "setPilot",
  "params": {
    "r": 255,
    "g": 0,
    "b": 0
  }
}
```

You have already seen how to send that message.

### Set brightness

In the app UI, you must have seen the brightness slider? If not, consider the following screenshot.

<img src="https://d2kbulfv42d43j.cloudfront.net/2023/Q1/philips-wiz-app-controls.jpg" caption="App showing temperature and brightness slider" alt="App showing temperature and brightness slider" position="center" />

First of all, I have warm white light selected. The top slider is for temperature, which we are going to talk about in next section.

The lowest value for brightness is 10, and max is 100. You guessed it right, lowest is not 0 because at 0, the bulb will be off.

You can club brightness setting with scene settings as well as any color setting. In following message, I'm setting the color to green and brightness to 50%.

```json
{
  "method": "setPilot",
  "params": {
    "r": 255,
    "g": 0,
    "b": 0,
    "dimming": 50,
  }
}
```

### Set temperature

Setting temperature is similarly easy. There is a params called `temp`. The range is between 2200 to 6200.

To the best of my knowledge, temperature can only be clubbed with brightness.

Here I'm presenting you an example payload for the message demonstrating 2200 kelvin temperate with a intensity of 20%.

```json
{
  "method": "setPilot",
  "params": {
    "temp": 2200
    "dimming": 20,
  }
}
```

## Conclusion

When I bought my Philips Wiz, I had no intention of controlling it programatically. It would such an overkill.

But shortly after this buy, I also [bought a Raspberry Pi](/posts/2023/first-month-with-my-raspberry-pi/). I became aware that this programatic access can be integrated by home automation.

Libraries already exist in Python. One of them is [pywizlight](https://github.com/sbidy/pywizlight), which seems to be most mature. But there are many more.

Maybe we could write some similar library in Go.