PSWattTime.psm1

$script:azLocations = Get-AzLocation

<#
    .SYNOPSIS
    Get an authentication token for the WattTime API

    .DESCRIPTION
    Get an authentication token for the WattTime API with a specified username and password

    .PARAMETER Username
    The username to use for authentication

    .PARAMETER Password
    The password to use for authentication

    .EXAMPLE
    Get-WattTimeAuthToken -Username 'username' -Password 'password'
#>

function Get-WattTimeAuthToken {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]$Username,
        [Parameter(Mandatory=$true)]
        [string]$Password
    )
    $base64UsernamePassword = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($Username):$($Password)"))
    $basicAuthValue = "Basic $base64UsernamePassword"
    $headers = @{
        'Authorization' = $basicAuthValue
    }

    $authToken = Invoke-RestMethod -Uri 'https://api2.watttime.org/v2/login' -Method Get -Headers $headers -ContentType 'application/json'
    return $authToken.token
}

<#
    .SYNOPSIS
    Query watttime.org for the current ba

    .DESCRIPTION
    Query watttime.org for the current ba on the https://api2.watttime.org/index endpoint

    .PARAMETER AuthToken
    The authentication token to use for the request

    .PARAMETER ba
    The ba to query for

    .EXAMPLE
    Get-WattTime -ba 'NL' -AuthToken $authToken
#>

function Get-WattTime {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]$ba,
        [Parameter(Mandatory=$true)]
        [string]$AuthToken
    )
    # call the WattTime API with GET request with the parameters
    $headers = @{
        'Authorization' = "Bearer $AuthToken"
    }
    $params = @{
        ba = $ba
    }
    $wattTime = Invoke-RestMethod -Uri 'https://api2.watttime.org/v2/index/' -Method Get -Headers $headers -Body $params -ContentType 'application/json'
    return $wattTime
}

<#
    .SYNOPSIS
    Get a WattTime ba for a given Azure Region

    .DESCRIPTION
    Get a WattTime ba for a given Azure Region via the https://api2.watttime.org/v2/ba-from-loc endpoint

    .PARAMETER Region
    The Azure Region to get the WattTime ba for

    .PARAMETER AuthToken
    The authentication token to use for the request

    .EXAMPLE
    ConvertFrom-AzureRegion -Region westeurope
#>

function ConvertFrom-AzureRegion {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]$Region,
        [Parameter(Mandatory=$true)]
        [string]$AuthToken
    )
    $azLocation = $azLocations | Where-Object { $_.Location -eq $Region }
    $headers = @{
        'Authorization' = "Bearer $AuthToken"
    }
    $params = @{
        latitude = $azLocation.Latitude
        longitude = $azLocation.Longitude
    }
    $wattTimeBa = Invoke-RestMethod -Uri 'https://api2.watttime.org/v2/ba-from-loc/' -Method Get -Headers $headers -Body $params -ContentType 'application/json'
    return $wattTimeBa.abbrev
}

<#
    .SYNOPSIS
    Get the current WattTime index for a given Azure Region

    .DESCRIPTION
    Get the current WattTime index for a given Azure Region

    .PARAMETER Region
    The Azure Region to get the WattTime index for

    .PARAMETER AuthToken
    The authentication token to use for the request

    .EXAMPLE
    Get-WattTimeForAzureRegion -Region westeurope -AuthToken $authToken
#>

function Get-WattTimeForAzureRegion {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]$Region,
        [Parameter(Mandatory=$true)]
        [string]$AuthToken
    )
    $wattTimeBa = ConvertFrom-AzureRegion -Region $Region -AuthToken $AuthToken
    $wattTime = Get-WattTime -ba $wattTimeBa -AuthToken $AuthToken
    $wattTime | Add-Member -MemberType NoteProperty -Name 'region' -Value $Region
    return $wattTime
}

<#
    .SYNOPSIS
    Get the Azure region with the lowest wattTime index

    .DESCRIPTION
    Get the current WattTime index for a given Azure Region

    .PARAMETER Regions
    The list of Azure Regions to get the WattTime index for

    .PARAMETER AuthToken
    The authentication token to use for the request

    .EXAMPLE
    Get-AzureRegionWithLowestWattTime -Regions westeurope,northeurope -AuthToken $authToken
#>

function Get-AzureRegionWithLowestWattTime {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string[]]$Regions,
        [Parameter(Mandatory=$true)]
        [string]$AuthToken
    )
    $wattTime = @()
    foreach ($region in $Regions) {
        $wattTime += Get-WattTimeForAzureRegion -Region $region -AuthToken $AuthToken
    }
    $wattTime | Sort-Object -Property percent | Select-Object -First 1
}

Export-ModuleMember -Function Get-WattTimeAuthToken, Get-WattTime, ConvertFrom-AzureRegion, Get-WattTimeForAzureRegion, Get-AzureRegionWithLowestWattTime