functions/public/Wait-KlippyReady.ps1
|
function Wait-KlippyReady { <# .SYNOPSIS Waits for a Klipper printer to become ready. .DESCRIPTION Monitors the printer state via WebSocket and waits until Klipper reports a "ready" state. Useful after firmware restarts or error recovery. .PARAMETER Id The unique identifier of the printer. .PARAMETER PrinterName The friendly name of the printer. .PARAMETER InputObject A printer object from pipeline input. .PARAMETER Timeout Maximum time to wait in seconds. Default is 120. .PARAMETER Quiet Suppress progress messages. .EXAMPLE Wait-KlippyReady -PrinterName "voronv2" Waits for the printer to become ready. .EXAMPLE Wait-KlippyReady -Timeout 60 Waits up to 60 seconds for the default printer to become ready. .EXAMPLE Restart-KlippyService -ServiceName "klipper" | Wait-KlippyReady Restarts Klipper and waits for it to become ready. .OUTPUTS PSCustomObject with the ready state information. #> [CmdletBinding(DefaultParameterSetName = 'Default')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true, ParameterSetName = 'ById')] [ValidateNotNullOrEmpty()] [string]$Id, [Parameter(Mandatory = $true, ParameterSetName = 'ByName', Position = 0)] [ValidateNotNullOrEmpty()] [string]$PrinterName, [Parameter(Mandatory = $true, ParameterSetName = 'ByObject', ValueFromPipeline = $true)] [PSCustomObject]$InputObject, [Parameter()] [ValidateRange(1, 3600)] [int]$Timeout = 120, [Parameter()] [switch]$Quiet ) process { # Resolve printer $resolveParams = @{} switch ($PSCmdlet.ParameterSetName) { 'ById' { $resolveParams['Id'] = $Id } 'ByName' { $resolveParams['PrinterName'] = $PrinterName } 'ByObject' { $resolveParams['InputObject'] = $InputObject } } $printer = Resolve-KlippyPrinterTarget @resolveParams # First check current state via REST try { $currentInfo = Invoke-KlippyJsonRpc -Printer $printer -Method "printer/info" if ($currentInfo.State -eq 'ready') { if (-not $Quiet) { Write-Host "[$($printer.PrinterName)] Already ready" } return [PSCustomObject]@{ PSTypeName = 'KlippyCLI.WaitResult' PrinterId = $printer.Id PrinterName = $printer.PrinterName State = 'ready' WaitTime = [TimeSpan]::Zero Success = $true } } } catch { Write-Verbose "Could not get current state, will wait via WebSocket: $_" } if (-not $Quiet) { Write-Host "[$($printer.PrinterName)] Waiting for printer to become ready..." -NoNewline } $startTime = [datetime]::UtcNow $ws = $null try { $ws = New-KlippyWebSocketClient -Printer $printer # Subscribe to webhooks for state changes $null = $ws.Subscribe(@{ webhooks = $null; print_stats = $null }) $deadline = [datetime]::UtcNow.AddSeconds($Timeout) while ([datetime]::UtcNow -lt $deadline) { $message = $ws.Receive(2000) if ($null -ne $message) { # Check for klippy state in notifications if ($message.method -eq 'notify_klippy_ready') { if (-not $Quiet) { Write-Host " Ready!" } return [PSCustomObject]@{ PSTypeName = 'KlippyCLI.WaitResult' PrinterId = $printer.Id PrinterName = $printer.PrinterName State = 'ready' WaitTime = [datetime]::UtcNow - $startTime Success = $true } } # Also check webhooks state updates if ($message.method -eq 'notify_status_update' -and $message.params) { $status = $message.params[0] if ($status.webhooks.state -eq 'ready') { if (-not $Quiet) { Write-Host " Ready!" } return [PSCustomObject]@{ PSTypeName = 'KlippyCLI.WaitResult' PrinterId = $printer.Id PrinterName = $printer.PrinterName State = 'ready' WaitTime = [datetime]::UtcNow - $startTime Success = $true } } } } if (-not $Quiet) { Write-Host "." -NoNewline } # Periodically check via REST as backup try { $currentInfo = Invoke-KlippyJsonRpc -Printer $printer -Method "printer/info" if ($currentInfo.State -eq 'ready') { if (-not $Quiet) { Write-Host " Ready!" } return [PSCustomObject]@{ PSTypeName = 'KlippyCLI.WaitResult' PrinterId = $printer.Id PrinterName = $printer.PrinterName State = 'ready' WaitTime = [datetime]::UtcNow - $startTime Success = $true } } } catch { # Ignore REST errors during wait } } # Timeout if (-not $Quiet) { Write-Host " Timeout!" } Write-Warning "[$($printer.PrinterName)] Timeout waiting for ready state after $Timeout seconds" return [PSCustomObject]@{ PSTypeName = 'KlippyCLI.WaitResult' PrinterId = $printer.Id PrinterName = $printer.PrinterName State = 'timeout' WaitTime = [datetime]::UtcNow - $startTime Success = $false } } catch { if (-not $Quiet) { Write-Host " Error!" } Write-Error "[$($printer.PrinterName)] Error waiting for ready state: $_" return [PSCustomObject]@{ PSTypeName = 'KlippyCLI.WaitResult' PrinterId = $printer.Id PrinterName = $printer.PrinterName State = 'error' WaitTime = [datetime]::UtcNow - $startTime Success = $false Error = $_.Exception.Message } } finally { if ($ws) { $ws.Close() } } } } |