functions/private/Invoke-KlippyWebSocketWait.ps1
|
function Invoke-KlippyWebSocketWait { <# .SYNOPSIS Waits for a condition using WebSocket subscriptions. .DESCRIPTION Connects via WebSocket, subscribes to printer objects, and waits for a condition to be met based on status updates. .PARAMETER Printer The printer object. .PARAMETER Objects Hashtable of objects to subscribe to. Format: @{ object_name = $null } or @{ object_name = @("attr1", "attr2") } .PARAMETER Condition ScriptBlock that receives status updates and returns $true when condition is met. Receives the status hashtable as $args[0]. .PARAMETER TimeoutSeconds Maximum time to wait. Default is 300 (5 minutes). .PARAMETER ProgressMessage Optional message for progress output. .PARAMETER OnProgress Optional ScriptBlock called on each status update for progress reporting. .EXAMPLE Invoke-KlippyWebSocketWait -Printer $printer -Objects @{print_stats=$null} ` -Condition { $args[0].print_stats.state -eq 'complete' } .OUTPUTS The final status that matched the condition. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [PSCustomObject]$Printer, [Parameter(Mandatory = $true)] [hashtable]$Objects, [Parameter(Mandatory = $true)] [scriptblock]$Condition, [Parameter()] [ValidateRange(1, 3600)] [int]$TimeoutSeconds = 300, [Parameter()] [string]$ProgressMessage, [Parameter()] [scriptblock]$OnProgress ) $ws = $null try { # Connect WebSocket $ws = New-KlippyWebSocketClient -Printer $Printer # Subscribe to objects Write-Verbose "Subscribing to: $($Objects.Keys -join ', ')" $initialStatus = $ws.Subscribe($Objects) # Check if condition is already met from initial status if ($initialStatus.status) { $normalized = ConvertTo-KlippyPascalCaseObject -InputObject $initialStatus.status if (& $Condition $initialStatus.status) { Write-Verbose "Condition already met from initial status" return $normalized } } # Wait for condition if ($ProgressMessage) { Write-Host $ProgressMessage -NoNewline } # Build progress callback $progressCallback = { param($status) if ($OnProgress) { & $OnProgress $status } if ($ProgressMessage) { Write-Host "." -NoNewline } } # Call WaitForMessage with positional parameters (ScriptMethods don't support named params) $result = $ws.WaitForMessage($Condition, $TimeoutSeconds, $progressCallback) if ($ProgressMessage) { Write-Host " Done" } return ConvertTo-KlippyPascalCaseObject -InputObject $result } finally { if ($ws) { $ws.Close() } } } |