functions/public/Get-KlippyWebcam.ps1

function Get-KlippyWebcam {
    <#
    .SYNOPSIS
        Gets webcam information from a Klipper printer.

    .DESCRIPTION
        Retrieves configured webcams and their settings including
        stream URLs, snapshot URLs, and rotation settings.

    .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 Name
        Filter by specific webcam name.

    .EXAMPLE
        Get-KlippyWebcam
        Gets all webcams from the default printer.

    .EXAMPLE
        Get-KlippyWebcam -Name "main_camera"
        Gets a specific webcam by name.

    .EXAMPLE
        Get-KlippyPrinter | Get-KlippyWebcam
        Gets webcams from all registered printers.

    .OUTPUTS
        KlippyCLI.Webcam objects.
    #>

    [CmdletBinding(DefaultParameterSetName = 'Default')]
    [OutputType([PSCustomObject])]
    param(
        [Parameter(ParameterSetName = 'ById')]
        [ValidateNotNullOrEmpty()]
        [string]$Id,

        [Parameter(ParameterSetName = 'ByName', Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string]$PrinterName,

        [Parameter(ParameterSetName = 'ByObject', ValueFromPipeline = $true)]
        [PSCustomObject]$InputObject,

        [Parameter()]
        [string]$Name
    )

    process {
        # Resolve printer
        $resolveParams = @{}
        switch ($PSCmdlet.ParameterSetName) {
            'ById' { $resolveParams['Id'] = $Id }
            'ByName' { $resolveParams['PrinterName'] = $PrinterName }
            'ByObject' { $resolveParams['InputObject'] = $InputObject }
        }

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        try {
            $response = Invoke-KlippyJsonRpc -Printer $printer -Method "server/webcams/list" -NoNormalize

            if (-not $response -or -not $response.webcams) {
                Write-Verbose "No webcams found on '$($printer.PrinterName)'."
                return
            }

            foreach ($webcam in $response.webcams) {
                # Filter by name if specified
                if ($Name -and $webcam.name -ne $Name) {
                    continue
                }

                # Build full URLs from relative paths if needed
                $baseUrl = $printer.Uri.TrimEnd('/')
                $streamUrl = $webcam.stream_url
                $snapshotUrl = $webcam.snapshot_url

                if ($streamUrl -and $streamUrl.StartsWith('/')) {
                    $streamUrl = "$baseUrl$streamUrl"
                }
                if ($snapshotUrl -and $snapshotUrl.StartsWith('/')) {
                    $snapshotUrl = "$baseUrl$snapshotUrl"
                }

                [PSCustomObject]@{
                    PSTypeName    = 'KlippyCLI.Webcam'
                    PrinterId     = $printer.Id
                    PrinterName   = $printer.PrinterName
                    Name          = $webcam.name
                    Location      = $webcam.location
                    Service       = $webcam.service
                    Enabled       = $webcam.enabled
                    StreamUrl     = $streamUrl
                    SnapshotUrl   = $snapshotUrl
                    FlipHorizontal = $webcam.flip_horizontal
                    FlipVertical  = $webcam.flip_vertical
                    Rotation      = $webcam.rotation
                    AspectRatio   = $webcam.aspect_ratio
                    TargetFps     = $webcam.target_fps
                    TargetFpsIdle = $webcam.target_fps_idle
                }
            }
        }
        catch {
            Write-Error "Failed to get webcams from '$($printer.PrinterName)': $_"
        }
    }
}