LET THERE BE LIGHT!
This post has been updated on 5/18/17 to reflect changes made to the Lifx API!
I stumbled upon the fact that LIFX has an API you can use today. Having found that out I wanted to do it in PowerShell and see what I can do. As it turns out there's a decent amount of things you can do and their API is "limited" to around 1 call per second.
If you would like to get into even more detail, step-by-step, and behind the scenes of how this works, check out this post!
Requirements
To get started with this you'll need...
- A LIFX lightbulb.
- An API key generated from the LIFX cloud website.
- A basic understanding of LIFX's API documentation.
Getting started
Here's what I did to get started.
- Created a PowerShell script named Get-LifxApi.ps1.
- Opened the script up with basic parameters and variables to get started.
- Somewhat annoying my girlfriend with the light changing so much ❤️
Starting code
[cmdletbinding(DefaultParameterSetName='SetState')] param( [Parameter( ParameterSetName = "StateSetting" )] [ValidateSet('SetState','FlashColor','RandomColors','ListLights')] [string] $Action = 'SetState', [Parameter( ParameterSetName = "StateSetting" )] [ValidateSet('on','off')] [string] $State = 'on', [Parameter( ParameterSetName = "StateSetting" )] [ValidateSet('white','red','orange','yellow','cyan','green','blue','purple','pink')] [string] $Color = 'white', [Parameter( ParameterSetName = "StateSetting" )] [ValidateRange(0.0,1)] [double] $Brightness = '0.4', [Parameter( ParameterSetName = "Toggle" )] [Switch] $Toggle ) $apiKey = 'YourKeyGoesHere' $headers = @{Authorization=("Bearer {0}" -f $apiKey)} $allURL = 'https://api.lifx.com/v1/lights/all' $acceptHeader = 'application/json' $baseURL = 'https://api.lifx.com/v1/lights' $foregroundColor = 'white' [array]$colors = @('white','red','orange','yellow','cyan','green','blue','purple','pink')
Notes
You'll want to change the $apiKey to match your API key from the LIFX cloud.
The $allURL variable will return all your lights, and then the $baseURL variable is used later when formatting calls to change colors or do other things. $foregroundColor let's you specify a color for some of the Write-Host returns, and $colors is an array of colors currently accepted by the API (and you'll see why it is there later in this post).
Let's make our first call!
I store the results of my light(s) in the $lifxLights variable.
$lifxLights = Invoke-RestMethod -headers $headers -Uri $allURL -ContentType $acceptheader
And now to write our first function in this script.
This function will allow us to utilize the API's state setting option. I named this function Set-LightState
function Set-LightState { #Begin function Set-LightState [cmdletbinding()] param( [Parameter()] [ValidateSet('on','off')] [string] $state, [Parameter()] [string] $color, [Parameter()] [ValidateRange(0.0,1)] [double] $brightness, [string] $selector ) if ($lifxLight.Connected) { $fullURL = "$baseurl/$($lifxLight.id)/state" $payload = [PSCustomObject]@{ power = $state color = $color brightness = $brightness } $payloadJson = $payload | ConvertTo-Json Write-Host "Attempting to Change light to:" -ForegroundColor $foregroundcolor Write-Host `t"State :" $state Write-Host `t"Color :" $color Write-Host `t"Brightness:" ($brightness * 100)"%" `n $stateReturn = Invoke-RestMethod -headers $headers -uri $fullURL -Method Put -Body $payloadJson -ContentType $acceptheader Write-Host "API status:" -ForegroundColor $foregroundcolor Write-Host `t"Light :" $stateReturn.results.label Write-Host `t"Status:" $stateReturn.results.status `n } else { $lightName = $lifxLight.label Write-Host "$lightName is offline or unreachable :(" } } #End function Set-LightState
I only have one LIFX light. In the start of this function I set my 'selector' (a required field for API calls to LIFX when setting states) as the light's ID. I then use the value of light's ID to setup the URL structure for the call. $fullURL becomes the URL used when accessing the API to set the state of the light.
Let's take some action!
At the start of the script I have a parameter for action.
Below is how it is used, in conjunction with toggle.
if ($toggle) { #If we're just toggling $fullURL = "$baseurl/$($lifxLight.id)/toggle" $toggleResult = Invoke-RestMethod -Uri $fullURL -Method Post -ContentType $acceptHeader -Headers $headers if ($toggleResult.results.status -eq 'ok') { Write-Host "Light [$($toggleResult.results.label)] was toggled!" } else { Write-Host "Something went wrong: [$($toggleResult.results.status)]" } } else { #Else we perform the actions! Switch ($action) { #Begin switch for script actions 'SetState' { Set-LightState -state $state -color $color -brightness $brightness } 'ListLights' { return $lifxLight } 'RandomColors' { $originalBrightness = $lifxLight.Brightness $originalColor = $lifxLight.Color $originalState = $lifxLight.Power $colorString = "hue:" + $originalcolor.hue + " saturation:" + $originalcolor.saturation + " kelvin:" + $originalColor.Kelvin $i = 0 While ($i -le 10) { $color = Get-Random $colors [double]$brightness = "{0:n2}" -f (Get-Random -Maximum 1 -Minimum 0.00) Set-LightState -color $color -brightness $brightness -selector $selector -state $state Start-Sleep -seconds 1 $i++ } Set-LightState -state $originalState -color $colorString -brightness $originalBrightness } 'FlashColor' { $originalBrightness = $lifxLights.Brightness $originalColor = $lifxLights.Color $originalState = $lifxLights.Power $colorString = "hue:" + $originalcolor.hue + " saturation:" + $originalcolor.saturation + " kelvin:" + $originalColor.Kelvin Set-LightState -state $state -color $color -brightness $brightness Start-Sleep -Seconds 1 Set-LightState -state $originalState -color $colorString -brightness $originalBrightness Start-Sleep -Seconds 1 Set-LightState -state $state -color $color -brightness $brightness Start-Sleep -Seconds 1 Set-LightState -state $originalState -color $colorString -brightness $originalBrightness Start-Sleep -Seconds 1 Set-LightState -state $state -color $color -brightness $brightness Start-Sleep -Seconds 1 Set-LightState -state $originalState -color $colorString -brightness $originalBrightness } } #End switch for light actions }
My favorite action is the RandomColors. I have that set to use Get-Random to set the color and brightness randomly. The other action is setstate. What that will do is set the light to a state you specify. If you do not give it options it will default to turning the light on to a brightness of 40% (0.4) and the color value of white (this is defined as per the default options for the parameters at the start of this script). You can change them by supplying the arguments when you run the script.
$fullURL example contents:
https://api.lifx.com/v1/lights/az0321123abc/state
Examples
.\Get-LifxAPI.ps1 -Action setstate -State on -Color blue -Brightness 0.5
Did it work?!
(Yup)
.\Get-LifxAPI.ps1 -Action setstate
The above example is the simplest way to run it as it utilizes the default parameters. (actually, you could just run Get-LifxAPI.ps1)
Now for some fun!
.\Get-LifxAPI.ps1 -Action RandomColors
More to come!
I will be adding to this as I work on it more and clean it up. I will get adding:
- Help nodes for Get-Help (done!).
- More options to leverage different parts of the LIFX API (coming).
- And more as I think of cool things to do with this!
Use:
Get-Help .\Get-LifxAPI.ps1 -Detailed
To see the help that is included. Be sure to change Get-LifxAPI.ps1 to what you named your script to!
The Code
<# .SYNOPSIS Use this script to control your Lifx light via PowerShell! .DESCRIPTION You can use this script to turn your light on and off, as well as change the brightness and colors. .PARAMETER Action Argument: The action you'd like to take: SetState, FlashColor, RandomColors, and ListLights are valid actions. .PARAMETER State This parameter accepts the state you'd like to set: on or off. .PARAMETER Color Argument: The color you'd like to set the light to. Valid colors can be tab completed. .PARAMETER Brightness Argument: The brightness you want to set. Valid range: between 0-1 (0.5 being 50%) .PARAMETER Toggle Toggles the light .NOTES Name: Get-LifxAPI.ps1 Author: Mike Roberts aka Ginger Ninja DateCreated: 2/6/2016 Last Modified: 5/18/2017 .EXAMPLE $response = .\Get-LifxAPI.ps1 -Action ListLights --------------------------------------------------------------- 1. Get an object returned that contains the result of the API call p$[18:52:20]> $response id : nun-ya uuid : more nun-ya label : Ninja room connected : True power : on color : @{hue=249.9977111467155; saturation=0; kelvin=3400} brightness : 0.48508430609597925 group : @{id=nun-ya; name=My Room} location : @{id=nun-ya; name=My Home} product : @{name=Original 1000; identifier=lifx_original_a21; company=LIFX; capabilities=} last_seen : 2017-05-19T01:51:49Z seconds_since_seen : 32 .EXAMPLE .\Get-LifxAPI.ps1 -Action RandomColors --------------------------------------------------------------- 1. Light toggles between random colors 10 times .EXAMPLE .\Get-LifxAPI.ps1 -Toggle --------------------------------------------------------------- 1. Toggles light state (on or off respectively) .EXAMPLE .\Get-LifxAPI.ps1 -Action SetState -State on -Color blue -Brightness 0.5 --------------------------------------------------------------- 1. Turns light on 2. Changes color to blue 3. Changes brightness to 0.5 .OUTPUTS If you use ListLights as the action, the output will be an object containing the results of the api call. .LINK http://www.gngrninja.com/script-ninja/2016/2/6/powershell-control-your-lifx-light #> [cmdletbinding(DefaultParameterSetName='SetState')] param( [Parameter( ParameterSetName = "StateSetting" )] [ValidateSet('SetState','FlashColor','RandomColors','ListLights')] [string] $Action = 'SetState', [Parameter( ParameterSetName = "StateSetting" )] [ValidateSet('on','off')] [string] $State = 'on', [Parameter( ParameterSetName = "StateSetting" )] [ValidateSet('white','red','orange','yellow','cyan','green','blue','purple','pink')] [string] $Color = 'white', [Parameter( ParameterSetName = "StateSetting" )] [ValidateRange(0.0,1)] [double] $Brightness = '0.4', [Parameter( ParameterSetName = "Toggle" )] [Switch] $Toggle ) $apiKey = 'YourKeyGoesHere' $headers = @{Authorization=("Bearer {0}" -f $apiKey)} $allURL = 'https://api.lifx.com/v1/lights/all' $acceptHeader = 'application/json' $baseURL = 'https://api.lifx.com/v1/lights' $foregroundColor = 'white' [array]$colors = @('white','red','orange','yellow','cyan','green','blue','purple','pink') function Set-LightState { #Begin function Set-LightState [cmdletbinding()] param( [Parameter()] [ValidateSet('on','off')] [string] $state, [Parameter()] [string] $color, [Parameter()] [ValidateRange(0.0,1)] [double] $brightness, [string] $selector ) if ($lifxLight.Connected) { $fullURL = "$baseurl/$($lifxLight.id)/state" $payload = [PSCustomObject]@{ power = $state color = $color brightness = $brightness } $payloadJson = $payload | ConvertTo-Json Write-Host "Attempting to Change light to:" -ForegroundColor $foregroundcolor Write-Host `t"State :" $state Write-Host `t"Color :" $color Write-Host `t"Brightness:" ($brightness * 100)"%" `n $stateReturn = Invoke-RestMethod -headers $headers -uri $fullURL -Method Put -Body $payloadJson -ContentType $acceptheader Write-Host "API status:" -ForegroundColor $foregroundcolor Write-Host `t"Light :" $stateReturn.results.label Write-Host `t"Status:" $stateReturn.results.status `n } else { $lightName = $lifxLight.label Write-Host "$lightName is offline or unreachable :(" } } #End function Set-LightState #Get Lifx Lights $lifxLights = Invoke-RestMethod -headers $headers -Uri $allURL -ContentType $acceptheader if ($lifxLights.Count -gt 1) { Write-Host "Pick a light:"`n for ($i = 0;$i -le $lifxLights.Count - 1;$i++) { Write-Host "[$i] -> $($lifxLights[$i].label)" } $picked = $false Do { [int]$number = Read-Host "Which [#]?" Write-Host "$number" if (![String]::IsNullOrEmpty($number) -and ($number -le ($lifxLights.Count - 1) -and $number -gt -1)) { $picked = $true $lifxLight = $number write-Host "sup" } } While ($picked -eq $false) } else { $lifxLight = $lifxLights[0] } if ($toggle) { #If we're just toggling $fullURL = "$baseurl/$($lifxLight.id)/toggle" $toggleResult = Invoke-RestMethod -Uri $fullURL -Method Post -ContentType $acceptHeader -Headers $headers if ($toggleResult.results.status -eq 'ok') { Write-Host "Light [$($toggleResult.results.label)] was toggled!" } else { Write-Host "Something went wrong: [$($toggleResult.results.status)]" } } else { #Else we perform the actions! Switch ($action) { #Begin switch for script actions 'SetState' { Set-LightState -state $state -color $color -brightness $brightness } 'ListLights' { return $lifxLight } 'RandomColors' { $originalBrightness = $lifxLight.Brightness $originalColor = $lifxLight.Color $originalState = $lifxLight.Power $colorString = "hue:" + $originalcolor.hue + " saturation:" + $originalcolor.saturation + " kelvin:" + $originalColor.Kelvin $i = 0 While ($i -le 10) { $color = Get-Random $colors [double]$brightness = "{0:n2}" -f (Get-Random -Maximum 1 -Minimum 0.00) Set-LightState -color $color -brightness $brightness -selector $selector -state $state Start-Sleep -seconds 1 $i++ } Set-LightState -state $originalState -color $colorString -brightness $originalBrightness } 'FlashColor' { $originalBrightness = $lifxLights.Brightness $originalColor = $lifxLights.Color $originalState = $lifxLights.Power $colorString = "hue:" + $originalcolor.hue + " saturation:" + $originalcolor.saturation + " kelvin:" + $originalColor.Kelvin Set-LightState -state $state -color $color -brightness $brightness Start-Sleep -Seconds 1 Set-LightState -state $originalState -color $colorString -brightness $originalBrightness Start-Sleep -Seconds 1 Set-LightState -state $state -color $color -brightness $brightness Start-Sleep -Seconds 1 Set-LightState -state $originalState -color $colorString -brightness $originalBrightness Start-Sleep -Seconds 1 Set-LightState -state $state -color $color -brightness $brightness Start-Sleep -Seconds 1 Set-LightState -state $originalState -color $colorString -brightness $originalBrightness } } #End switch for light actions }
Leave comment if you have any ideas or feedback!
-Ginger Ninja