functions/public/Get-KlippyObject.ps1

function Get-KlippyObject {
    <#
    .SYNOPSIS
        Queries Klipper printer objects.

    .DESCRIPTION
        Retrieves specific printer object data from Klipper.
        Can query individual objects or list all available objects.

    .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 ObjectName
        The name of the printer object to query (e.g., "extruder", "heater_bed", "toolhead").
        Supports wildcards.

    .PARAMETER Attributes
        Specific attributes to retrieve from the object.

    .PARAMETER List
        List all available printer objects.

    .EXAMPLE
        Get-KlippyObject -List
        Lists all available printer objects.

    .EXAMPLE
        Get-KlippyObject -ObjectName "extruder"
        Gets the extruder object with all attributes.

    .EXAMPLE
        Get-KlippyObject -ObjectName "heater_bed" -Attributes "temperature", "target"
        Gets specific attributes from the heater_bed object.

    .EXAMPLE
        Get-KlippyObject -ObjectName "heater*"
        Gets all objects matching the wildcard pattern.

    .OUTPUTS
        PSCustomObject with printer object data.
    #>

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

        [Parameter(ParameterSetName = 'Query', Position = 1)]
        [Parameter(ParameterSetName = 'List')]
        [ValidateNotNullOrEmpty()]
        [string]$PrinterName,

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

        [Parameter(Mandatory = $true, ParameterSetName = 'Query', Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string]$ObjectName,

        [Parameter(ParameterSetName = 'Query')]
        [string[]]$Attributes,

        [Parameter(Mandatory = $true, ParameterSetName = 'List')]
        [switch]$List
    )

    process {
        # Resolve printer
        $resolveParams = @{}
        if ($Id) { $resolveParams['Id'] = $Id }
        elseif ($PrinterName) { $resolveParams['PrinterName'] = $PrinterName }
        elseif ($InputObject) { $resolveParams['InputObject'] = $InputObject }

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        try {
            if ($List) {
                # Get list of available objects
                $response = Invoke-KlippyJsonRpc -Printer $printer -Method "printer/objects/list"

                $result = [PSCustomObject]@{
                    PSTypeName  = 'KlippyCLI.ObjectList'
                    PrinterId   = $printer.Id
                    PrinterName = $printer.PrinterName
                    Objects     = $response.Objects | Sort-Object
                }

                return $result
            }

            # Check if ObjectName contains wildcard
            if ($ObjectName -match '[\*\?\[\]]') {
                # Get all objects and filter by wildcard
                $allObjects = Invoke-KlippyJsonRpc -Printer $printer -Method "printer/objects/list"
                $matchingObjects = $allObjects.Objects | Where-Object { $_ -like $ObjectName }

                if ($matchingObjects.Count -eq 0) {
                    Write-Warning "No objects matching '$ObjectName' found."
                    return
                }

                # Query each matching object
                $results = foreach ($objName in $matchingObjects) {
                    Get-KlippyObject -PrinterName $printer.PrinterName -ObjectName $objName -Attributes $Attributes
                }

                return $results
            }

            # Build query endpoint
            $queryString = $ObjectName
            if ($Attributes -and $Attributes.Count -gt 0) {
                $queryString = "$ObjectName=$($Attributes -join ',')"
            }

            $endpoint = "printer/objects/query?$queryString"
            $response = Invoke-KlippyJsonRpc -Printer $printer -Method $endpoint

            # Extract the specific object from status
            $objectData = $response.Status.$ObjectName
            if ($null -eq $objectData) {
                # Try with PascalCase conversion
                $pascalName = ($ObjectName -split '_' | ForEach-Object { $_.Substring(0,1).ToUpper() + $_.Substring(1) }) -join ''
                $objectData = $response.Status.$pascalName
            }

            if ($null -eq $objectData) {
                Write-Error "Object '$ObjectName' not found or returned no data."
                return
            }

            # Add metadata
            $objectData | Add-Member -NotePropertyName 'PrinterId' -NotePropertyValue $printer.Id -Force
            $objectData | Add-Member -NotePropertyName 'PrinterName' -NotePropertyValue $printer.PrinterName -Force
            $objectData | Add-Member -NotePropertyName 'ObjectName' -NotePropertyValue $ObjectName -Force
            $objectData.PSObject.TypeNames.Insert(0, 'KlippyCLI.PrinterObject')

            return $objectData
        }
        catch {
            Write-Error "Failed to query object '$ObjectName' on '$($printer.PrinterName)': $_"
        }
    }
}