functions/public/Save-KlippyWebcamSnapshot.ps1
|
function Save-KlippyWebcamSnapshot { <# .SYNOPSIS Saves a webcam snapshot from a Klipper printer. .DESCRIPTION Downloads a snapshot image from a configured webcam and saves it to a file. .PARAMETER Id The unique identifier of the printer. .PARAMETER PrinterName The friendly name of the printer. .PARAMETER InputObject A webcam object from pipeline input. .PARAMETER WebcamName The name of the webcam to capture from. .PARAMETER Path The file path to save the snapshot. If not specified, saves to current directory with a timestamp-based filename. .PARAMETER Force Overwrite existing file without prompting. .EXAMPLE Save-KlippyWebcamSnapshot Saves a snapshot from the first webcam to the current directory. .EXAMPLE Save-KlippyWebcamSnapshot -WebcamName "main_camera" -Path "C:\snapshots\print.jpg" Saves a snapshot from a specific webcam to a specific path. .EXAMPLE Get-KlippyWebcam | Save-KlippyWebcamSnapshot -Path "C:\snapshots" Saves snapshots from all webcams to a folder. .OUTPUTS System.IO.FileInfo object for the saved file. #> [CmdletBinding(SupportsShouldProcess)] [OutputType([System.IO.FileInfo])] param( [Parameter(ParameterSetName = 'ById')] [ValidateNotNullOrEmpty()] [string]$Id, [Parameter(ParameterSetName = 'ByName')] [ValidateNotNullOrEmpty()] [string]$PrinterName, [Parameter(ParameterSetName = 'ByObject', ValueFromPipeline = $true)] [PSCustomObject]$InputObject, [Parameter(ParameterSetName = 'ById')] [Parameter(ParameterSetName = 'ByName')] [string]$WebcamName, [Parameter()] [string]$Path, [Parameter()] [switch]$Force ) process { $webcam = $null $printer = $null # Handle webcam object from pipeline if ($InputObject -and $InputObject.PSTypeName -eq 'KlippyCLI.Webcam') { $webcam = $InputObject $printer = [PSCustomObject]@{ Id = $InputObject.PrinterId PrinterName = $InputObject.PrinterName } } else { # Resolve printer $resolveParams = @{} if ($Id) { $resolveParams['Id'] = $Id } elseif ($PrinterName) { $resolveParams['PrinterName'] = $PrinterName } elseif ($InputObject) { $resolveParams['InputObject'] = $InputObject } $printer = Resolve-KlippyPrinterTarget @resolveParams # Get webcams $webcams = Get-KlippyWebcam -Id $printer.Id if (-not $webcams) { Write-Error "No webcams found on '$($printer.PrinterName)'." return } if ($WebcamName) { $webcam = $webcams | Where-Object { $_.Name -eq $WebcamName } if (-not $webcam) { Write-Error "Webcam '$WebcamName' not found on '$($printer.PrinterName)'." return } } else { # Use the first enabled webcam $webcam = $webcams | Where-Object { $_.Enabled } | Select-Object -First 1 if (-not $webcam) { $webcam = $webcams | Select-Object -First 1 } } } if (-not $webcam.SnapshotUrl) { Write-Error "Webcam '$($webcam.Name)' does not have a snapshot URL configured." return } try { # Determine output path $outputPath = $Path if (-not $outputPath) { $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $outputPath = Join-Path (Get-Location) "$($printer.PrinterName)_$($webcam.Name)_$timestamp.jpg" } elseif (Test-Path $outputPath -PathType Container) { # Path is a directory, generate filename $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $outputPath = Join-Path $outputPath "$($printer.PrinterName)_$($webcam.Name)_$timestamp.jpg" } # Check if file exists if ((Test-Path $outputPath) -and -not $Force) { if (-not $PSCmdlet.ShouldProcess($outputPath, "Overwrite existing file")) { return } } $action = "Save snapshot from '$($webcam.Name)'" if ($PSCmdlet.ShouldProcess($printer.PrinterName, $action)) { Write-Verbose "Downloading snapshot from: $($webcam.SnapshotUrl)" # Download the snapshot $webClient = [System.Net.WebClient]::new() try { $webClient.DownloadFile($webcam.SnapshotUrl, $outputPath) } finally { $webClient.Dispose() } $fileInfo = Get-Item $outputPath Write-Host "Saved snapshot to: $outputPath ($([math]::Round($fileInfo.Length / 1KB, 1)) KB)" -ForegroundColor Green Write-Output $fileInfo } } catch { Write-Error "Failed to save webcam snapshot from '$($printer.PrinterName)': $_" } } } |