Skip to content

Instantly share code, notes, and snippets.

@EinPinsel
Created December 4, 2016 15:10
Show Gist options
  • Save EinPinsel/2069da59c545373e8fd47a6c15ad7bc5 to your computer and use it in GitHub Desktop.
Save EinPinsel/2069da59c545373e8fd47a6c15ad7bc5 to your computer and use it in GitHub Desktop.
#------------------------------------------------------------------------------
# THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED “AS IS” WITHOUT
# WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
# LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS
# FOR A PARTICULAR PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR
# RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#------------------------------------------------------------------------------
$global:access_token = $null
$global:refresh_token = $null
#Netatmo Details. Client ID and secret from creating the App, and a username and password that has access to the api.
$global:client_id='xxxxxxxxxxxxxxxxxxxxxxxxxxx'
$global:client_secret='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
$global:Netatmo_username='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
$global:Netatmo_password='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
#OMS Workspace Variables
$global:CustomerId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" #Workspace ID
$global:SharedKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$global:LogType = "Netatmo_WeatherStation" #Create a Log Type name
#Function to send data to OMS workspace
function WriteOMSEvent($SensorID, $SensorName, $MeasurementName, $MeasurementValue){
#Specify a time in the format YYYY-MM-DDThh:mm:ssZ to specify a created datetime for the records.
$TimeStampField = [DateTime]::UtcNow.ToString("r")
#Create json record
$json = @"
[{ "Sensor_id": "$SensorID",
"Sensor_name": "$SensorName",
"Measurement_name": "$MeasurementName",
"Value": $MeasurementValue
}]
"@
#Output the json to console so that we can see the results.
$json
# Function to create the authorization signature.
Function Build-Signature ($customerId, $SharedKey, $date, $contentLength, $method, $contentType, $resource)
{
$xHeaders = "x-ms-date:" + $date
$stringToHash = $method + "`n" + $contentLength + "`n" + $contentType + "`n" + $xHeaders + "`n" + $resource
$bytesToHash = [Text.Encoding]::UTF8.GetBytes($stringToHash)
$keyBytes = [Convert]::FromBase64String($SharedKey)
$sha256 = New-Object System.Security.Cryptography.HMACSHA256
$sha256.Key = $keyBytes
$calculatedHash = $sha256.ComputeHash($bytesToHash)
$encodedHash = [Convert]::ToBase64String($calculatedHash)
$authorization = 'SharedKey {0}:{1}' -f $customerId,$encodedHash
return $authorization
}
# Function doing the post to the OMS Workspace.
Function Post-OMSData($customerId, $SharedKey, $body, $LogType)
{
$method = "POST"
$contentType = "application/json"
$resource = "/api/logs"
$rfc1123date = [DateTime]::UtcNow.ToString("r")
$contentLength = $body.Length
$signature = Build-Signature `
-customerId $customerId `
-sharedKey $SharedKey `
-date $rfc1123date `
-contentLength $contentLength `
-fileName $fileName `
-method $method `
-contentType $contentType `
-resource $resource
$uri = "https://" + $customerId + ".ods.opinsights.azure.com" + $resource + "?api-version=2016-04-01"
$headers = @{
"Authorization" = $signature;
"Log-Type" = $LogType;
"x-ms-date" = $rfc1123date;
"time-generated-field" = $TimeStampField;
}
$response = Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Headers $headers -Body $body -UseBasicParsing
return $response.StatusCode
}
# The only function after creating the json document that's doing the work.
Post-OMSData -customerId $customerId -sharedKey $SharedKey -body ([System.Text.Encoding]::UTF8.GetBytes($json)) -logType $LogType
}
#End of Function WriteOMSEvent
#Authenticate to the Netatmo API and get an access token.
function Netatmo-DoAuth {
$postParams = @{
grant_type='password';
client_id=$client_id;
client_secret=$client_secret;
username=$Netatmo_username;
password=$Netatmo_password
}
$Request = Invoke-WebRequest -Uri https://api.netatmo.com/oauth2/token -Method POST -Body $postParams -UseBasicParsing
if ($Request.StatusCode -eq 200) {
$ResponseJson = $Request.Content | ConvertFrom-Json
$global:access_token = $ResponseJson.access_token
$global:refresh_token = $ResponseJson.refresh_token
}
ELSE
{
write-error -message $Request.StatusDescription -ErrorId $Request.StatusCode
}
}
#Read the Netatmo API for Sensor data, convert into an object, and post to OMS.
function ReadSensorData{$SensorpostParams = @{access_token=$access_token}
#Request Sensor data from Netatmo
$SensorRequest = Invoke-WebRequest -Uri https://api.netatmo.com/api/getstationsdata -Method POST -Body $SensorpostParams -UseBasicParsing
if ($SensorRequest.StatusCode -eq 200) {
#Convert to object.
$SensorContent = $SensorRequest.Content | ConvertFrom-Json
#Indoor unit sensors
$MainUnit_id = $SensorContent.body.devices[0]._id
$MainUnit_module_name = $SensorContent.body.devices[0].module_name
$MainUnit_wifi_status = $SensorContent.body.devices[0].wifi_status
$MainUnit_Pressure = $SensorContent.body.devices[0].dashboard_data.Pressure
$MainUnit_pressure_trend = $SensorContent.body.devices[0].dashboard_data.pressure_trend
$MainUnit_Temperature = $SensorContent.body.devices[0].dashboard_data.Temperature
$MainUnit_temp_trend = $SensorContent.body.devices[0].dashboard_data.temp_trend
$MainUnit_Humidity = $SensorContent.body.devices[0].dashboard_data.Humidity
$MainUnit_CO2 = $SensorContent.body.devices[0].dashboard_data.CO2
WriteOMSEvent -SensorID $MainUnit_id -SensorName $MainUnit_module_name -MeasurementName "Pressure" -MeasurementValue $MainUnit_Pressure
WriteOMSEvent -SensorID $MainUnit_id -SensorName $MainUnit_module_name -MeasurementName "Wifi Signal" -MeasurementValue $MainUnit_wifi_status
WriteOMSEvent -SensorID $MainUnit_id -SensorName $MainUnit_module_name -MeasurementName "Temperature" -MeasurementValue $MainUnit_Temperature
WriteOMSEvent -SensorID $MainUnit_id -SensorName $MainUnit_module_name -MeasurementName "Humidity" -MeasurementValue $MainUnit_Humidity
WriteOMSEvent -SensorID $MainUnit_id -SensorName $MainUnit_module_name -MeasurementName "CO2" -MeasurementValue $MainUnit_CO2
#Outdoor Unit Sensors
$OutdoorUnit_id = $SensorContent.body.devices[0].modules[0]._id
$OutdoorUnit_module_name = $SensorContent.body.devices[0].modules[0].module_name
$OutdoorUnit_Temperature = $SensorContent.body.devices[0].modules[0].dashboard_data.Temperature -as [double]
$OutdoorUnit_temp_trend = $SensorContent.body.devices[0].modules[0].dashboard_data.temp_trend
$OutdoorUnit_Humidity = $SensorContent.body.devices[0].modules[0].dashboard_data.Humidity -as [double]
WriteOMSEvent -SensorID $OutdoorUnit_id -SensorName $OutdoorUnit_module_name -MeasurementName "Temperature" -MeasurementValue $OutdoorUnit_Temperature
WriteOMSEvent -SensorID $OutdoorUnit_id -SensorName $OutdoorUnit_module_name -MeasurementName "Humidity" -MeasurementValue $OutdoorUnit_Humidity
}
ELSE
{
if ($SensorRequest.StatusCode -eq 403) {
write-error -message "Netatmo Unauthorized, refreshing access token"
Netatmo-DoAuth
ReadSensorData
}
write-error -message $Request.StatusDescription -ErrorId $Request.StatusCode
}
}
#Call the two main functions to do the work
Netatmo-DoAuth
ReadSensorData
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment