LightwaveRF Energy Data

Those unlucky enough to be invited over to the General's base will know that I am a fan of LightwaveRFs products. My Father-in-law recently got a hold of a Link plus and energy monitor to keep tabs on his consumption but the app interface is a bit simple and only shows you the last few days in a graph. Even then it's hard to find if you don't know to flip your phone on its side...

 

Cue the need for a data API and, as if by magic, here it is: https://api.lightwaverf.com/ Or maybe not. Certainly this api is quite useful if you're probing locally but since we're all supposed to be embracing the cloud...

Here's the one we're looking for: https://support.lightwaverf.com/hc/en-us/articles/360020665652-Link-Plus-Smart-Series-API- convenitently hidden away in a dark article on their support site.

Now we have the API docs it should take no time at all to find the sections we need. Drill down to device and historical data and it shows us the url we need to build:

GET https://publicapi.lightwaverf.com/v1/data/:deviceId/:featureId?

Which helpfully tells us we'll need a deviceId and featureId. Also if clicked you can see a helpful query parameter of start and end times. We'll use those too.

Getting started on the script then we'll first need to authenticate. Lightwave have been pretty secure doing this, opting for a basic and refresh token to be exchanged for an authentication bearer. Luckily working with APIs at the office means I already have some lines for the authentication stage.

$Headers = (@{'authorization' = ('Basic ' + $BasicToken)})
$Body = (@{'grant_type' = 'refresh_token'; 'refresh_token' = $RefreshToken})
$AuthResponse = Invoke-WebRequest -Method Post -Uri 'https://auth.lightwaverf.com/token' -Headers $Headers -Body ($Body | ConvertTo-Json) -ContentType 'application/json'
$AccessToken = ($AuthResponse.Content | ConvertFrom-Json).access_token
$Headers = (@{'Authorization' = ('Bearer ' + $AccessToken)})

We'll need to ask users for their refresh token for almost every authentication as it expires very quickly. See https://lwtokens.docs.apiary.io/# for details.
It's also worth noting that the token page on the webapp doesn't generate a new refresh token unless the button is clicked and password entered. This can make for a painful experience so I'll be looking for a more automatic way to do this.

 

Next we need to get the device and feature IDs. This can be done via the structures API:

GET https://publicapi.lightwaverf.com/v1/structures
GET https://publicapi.lightwaverf.com/v1/structure/{structureId}?

These allow you to see all structures and one specifically. Translate that into powershell and we have the devices listable:

$Response = Invoke-WebRequest -Method Get -Uri 'https://publicapi.lightwaverf.com/v1/structures' -Headers $Headers
$Structure = ($Response.Content | ConvertFrom-Json).structures

$Response = Invoke-WebRequest -Method Get -Uri ('https://publicapi.lightwaverf.com/v1/structure/' + $Structure) -Headers $Headers
$AllDevices = ($Response.Content | ConvertFrom-Json).devices

From here on out it's quite straight forward to grab the device we need. Assuming you only have one energy monitor you can filter for the device model like so:

$EnergyMonitorProductID = 'LW600'
$EnergyMonitorDevice = $AllDevices | Where-Object {$_.product -eq $EnergyMonitorProductID}

 

And then finally the data pull. Pick the feature we want, either energy for total consumption since last counter reset or power for current draw, and download then save the data (of course you can just | ogv it too)

$EnergyMonitorFeature = $EnergyMonitorDevice.featureSets.features | Where-Object {$_.type -eq $MonitorType.ToLower()}
$Response = Invoke-WebRequest -Method Get -Uri ('https://publicapi.lightwaverf.com/v1/data/' + $EnergyMonitorDevice.deviceId + '/' + $EnergyMonitorFeature.featureId + '?start=' + (Get-Date $StartDate -Format 'yyyy-MM-ddTHH:mm:ss.000Z') + '&end=' + (Get-Date $EndDate -Format 'yyyy-MM-ddTHH:mm:ss.000Z')) -Headers $Headers
($Response.Content | ConvertFrom-Json).data | Select-Object @{name='Date';expression={$_.date.replace('T',' ').replace('Z','')}},value | ConvertTo-Csv -NoTypeInformation | Out-File -FilePath ($UserDesktopLocation + '\LightwaveEnergyData.csv')

and presto you have a CSV with your data between two dates.

All it needs is a bit of tidying and it can be sent to the father-in-law.

Here's the finished article:

Get-LightwaveRFEnergyData.ps1 (4.35 kb)

Admittedly a little rough but not bad for an hours scanning around the internet to make life easier.

 

From the CSV we've imported the data into excel and created nice graphs by splitting fields etc. giving you very granular readouts quickly.

o7