functions/public/Get-KlippyServiceStatus.ps1

function Get-KlippyServiceStatus {
    <#
    .SYNOPSIS
        Gets service status from a Klipper printer's host machine.

    .DESCRIPTION
        Retrieves the status of system services running on the printer's
        host machine including Klipper, Moonraker, and other related services.

    .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 ServiceName
        Filter to specific service(s). Supports wildcards.

    .EXAMPLE
        Get-KlippyServiceStatus
        Gets all service statuses from the default printer.

    .EXAMPLE
        Get-KlippyServiceStatus -PrinterName "voronv2" -ServiceName "klipper"
        Gets Klipper service status.

    .EXAMPLE
        Get-KlippyServiceStatus -ServiceName "*"
        Gets all available services.

    .EXAMPLE
        Get-KlippyPrinter | Get-KlippyServiceStatus | Where-Object ActiveState -ne 'active'
        Finds services that aren't running on all printers.

    .OUTPUTS
        PSCustomObject[] with service status information.
    #>

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

        [Parameter(Mandatory = $true, ParameterSetName = 'ByName')]
        [ValidateNotNullOrEmpty()]
        [string]$PrinterName,

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

        [Parameter(Position = 0)]
        [string]$ServiceName
    )

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

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        try {
            Write-Verbose "[$($printer.PrinterName)] Fetching service status..."

            $sysInfo = Invoke-KlippyJsonRpc -Printer $printer -Method "machine/system_info"
            $services = $sysInfo.SystemInfo.ServiceState

            if (-not $services) {
                Write-Warning "[$($printer.PrinterName)] No service information available"
                return
            }

            # Convert hashtable to service objects
            $results = foreach ($svcName in $services.PSObject.Properties.Name) {
                $svc = $services.$svcName

                [PSCustomObject]@{
                    PSTypeName   = 'KlippyCLI.ServiceStatus'
                    PrinterId    = $printer.Id
                    PrinterName  = $printer.PrinterName
                    ServiceName  = $svcName
                    ActiveState  = $svc.ActiveState
                    SubState     = $svc.SubState
                }
            }

            # Filter by service name if specified
            if ($ServiceName) {
                $hasWildcard = $ServiceName -match '[\*\?\[\]]'
                if ($hasWildcard) {
                    $results = $results | Where-Object { $_.ServiceName -like $ServiceName }
                }
                else {
                    $results = $results | Where-Object { $_.ServiceName -ieq $ServiceName }
                }
            }

            return $results
        }
        catch {
            Write-Error "[$($printer.PrinterName)] Failed to get service status: $_"
        }
    }
}