functions/public/Get-KlippyStepper.ps1

function Get-KlippyStepper {
    <#
    .SYNOPSIS
        Gets stepper motor and TMC driver status from a Klipper printer.

    .DESCRIPTION
        Retrieves stepper motor enable states and TMC driver information
        including temperature, current, and driver status.

    .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 stepper name. Supports wildcards.

    .PARAMETER IncludeTMC
        Include TMC driver information if available.

    .EXAMPLE
        Get-KlippyStepper
        Gets all steppers from the default printer.

    .EXAMPLE
        Get-KlippyStepper -PrinterName "voronv2" -IncludeTMC
        Gets all steppers with TMC driver info from the specified printer.

    .EXAMPLE
        Get-KlippyStepper -Name "stepper_z*"
        Gets Z-axis steppers.

    .OUTPUTS
        KlippyCLI.Stepper 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,

        [Parameter()]
        [switch]$IncludeTMC
    )

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

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        try {
            # Get list of available objects
            $allObjects = Invoke-KlippyJsonRpc -Printer $printer -Method "printer/objects/list"

            # Get stepper_enable for enable states
            $hasStepperEnable = $allObjects.Objects -contains 'stepper_enable'

            # Find TMC driver objects
            $tmcPrefixes = @('tmc2130', 'tmc2208', 'tmc2209', 'tmc2240', 'tmc2660', 'tmc5160')
            $tmcObjects = @{}

            if ($IncludeTMC) {
                foreach ($obj in $allObjects.Objects) {
                    foreach ($prefix in $tmcPrefixes) {
                        if ($obj.StartsWith("$prefix ")) {
                            $stepperName = ($obj -split ' ', 2)[1]
                            $tmcObjects[$stepperName] = $obj
                            break
                        }
                    }
                }
            }

            # Build query
            $queryObjects = @()
            if ($hasStepperEnable) {
                $queryObjects += 'stepper_enable'
            }
            if ($IncludeTMC -and $tmcObjects.Count -gt 0) {
                $queryObjects += $tmcObjects.Values
            }

            if ($queryObjects.Count -eq 0) {
                Write-Warning "No stepper information available."
                return
            }

            # Build query string
            $queryParts = $queryObjects | ForEach-Object { [System.Uri]::EscapeDataString($_) }
            $endpoint = "printer/objects/query?" + ($queryParts -join '&')

            $response = Invoke-KlippyJsonRpc -Printer $printer -Method $endpoint -NoNormalize

            # Process stepper_enable results
            if ($hasStepperEnable) {
                $stepperEnable = $response.status.stepper_enable
                if ($stepperEnable -and $stepperEnable.steppers) {
                    foreach ($stepperName in $stepperEnable.steppers.PSObject.Properties.Name) {
                        # Apply name filter
                        if ($Name -and $stepperName -notlike $Name) {
                            continue
                        }

                        $enabled = $stepperEnable.steppers.$stepperName

                        $result = [PSCustomObject]@{
                            PSTypeName  = 'KlippyCLI.Stepper'
                            PrinterId   = $printer.Id
                            PrinterName = $printer.PrinterName
                            Name        = $stepperName
                            Enabled     = $enabled
                        }

                        # Add TMC info if available
                        if ($IncludeTMC -and $tmcObjects.ContainsKey($stepperName)) {
                            $tmcObjName = $tmcObjects[$stepperName]
                            $tmcData = $response.status.$tmcObjName
                            if ($tmcData) {
                                $result | Add-Member -NotePropertyName 'TMCDriver' -NotePropertyValue ($tmcObjName -split ' ')[0] -Force
                                $result | Add-Member -NotePropertyName 'Temperature' -NotePropertyValue $tmcData.temperature -Force
                                $result | Add-Member -NotePropertyName 'RunCurrent' -NotePropertyValue $tmcData.run_current -Force
                                $result | Add-Member -NotePropertyName 'HoldCurrent' -NotePropertyValue $tmcData.hold_current -Force
                            }
                        }

                        $result
                    }
                }
            }
        }
        catch {
            Write-Error "Failed to get steppers from '$($printer.PrinterName)': $_"
        }
    }
}