functions/Read-TibberWebSocket.ps1
function Read-TibberWebSocket { <# .Synopsis Read packages on the provided WebSocket connection. .Description Calling this function will read packages on the provided WebSocket connection. .Example Read-TibberWebSocket -Connection $connection -Callback { param($Json) Write-Host "New Json document recieved: $($Json.payload.data | Out-String)" } .Example function Write-PackageToHost { param ( [Object] $Json ) Write-Host "New Json document recieved: $($Json.payload.data | Out-String)" } Read-TibberWebSocket -Connection $connection -Callback ${function:Write-PackageToHost} .Example $result = Read-TibberWebSocket -Connection $connection -Callback ${function:Write-PackageToHost} -TimeoutInSeconds 30 Write-Host "Read $($result.NumberOfPackages) package(s) in $($result.ElapsedTimeInSeconds) seconds" .Example Read-TibberWebSocket -Connection $connection -Callback ${function:Write-PackageToHost} -PackageCount 3 Write-Host "Read $($result.NumberOfPackages) package(s) in $($result.ElapsedTimeInSeconds) seconds" .Link Register-TibberLiveConsumptionSubscription .Link https://developer.tibber.com/docs/reference#livemeasurement #> param ( # Specifies the connection to use for the communication. [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName)] [Object] $Connection, # Specifies the script block called for each response. [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName)] [ScriptBlock] $Callback, # Specifies for how long in seconds we should read packages, or -1 to read indefinitely. [Parameter(ValueFromPipelineByPropertyName)] [ValidateRange(-1, [int]::MaxValue)] [Alias('Timeout')] [int] $TimeoutInSeconds = -1, # Specifies the number of packages to read, or -1 to read indefinitely. [Parameter(ValueFromPipelineByPropertyName)] [ValidateRange(-1, [int]::MaxValue)] [Alias('Count')] [int] $PackageCount = -1 ) begin { # Setup parameters $uri = $Connection.URI $webSocket = $Connection.WebSocket $cancellationToken = $Connection.CancellationTokenSource.Token $recvBuffer = $Connection.RecvBuffer } process { Write-Verbose "Read packages from $URI" # Reading packages $timer = [Diagnostics.Stopwatch]::StartNew() $packageCounter = 0 while (($TimeoutInSeconds -eq -1 -Or $timer.Elapsed.TotalSeconds -lt $TimeoutInSeconds) ` -And ($PackageCount -eq -1 -Or $packageCounter -lt $PackageCount) ` -And ($webSocket.State -eq 'Open')) { $response = "" do { $result = $webSocket.ReceiveAsync($recvBuffer, $cancellationToken) while (-Not $result.IsCompleted) { Start-Sleep -Milliseconds 10 } Write-Debug -Message "WebSocket status:" Write-Debug -Message ($webSocket | Select-Object * | Out-String) Write-Debug -Message "WebSocket operation result:" Write-Debug -Message ($result | Select-Object * | Out-String) if ($result.Result.CloseStatus) { throw "Receive failed: $($result.Result.CloseStatusDescription) [$($result.Result.CloseStatus)]" } $response += [Text.Encoding]::ASCII.GetString($recvBuffer.Array, 0, $result.Result.Count) $packageCounter++ } until ($result.Result.EndOfMessage) Invoke-Command -ScriptBlock $Callback -ArgumentList $($response | ConvertFrom-Json) } $timer.Stop() Write-Verbose "Read $packageCounter package(s) in $($timer.Elapsed.TotalSeconds) seconds" # Output result object [PSCustomObject]@{ NumberOfPackages = $packageCounter ElapsedTimeInSeconds = $timer.Elapsed.TotalSeconds } } } |