functions/public/Set-KlippyPowerDevice.ps1

function Set-KlippyPowerDevice {
    <#
    .SYNOPSIS
        Controls a power device on a Klipper printer.

    .DESCRIPTION
        Turns power devices (smart plugs, relays, GPIO) on, off, or toggles them.

    .PARAMETER Id
        The unique identifier of the printer.

    .PARAMETER PrinterName
        The friendly name of the printer.

    .PARAMETER InputObject
        A power device object from pipeline input.

    .PARAMETER DeviceName
        The name of the power device to control.

    .PARAMETER Action
        The action to perform: On, Off, or Toggle.

    .EXAMPLE
        Set-KlippyPowerDevice -DeviceName "printer_power" -Action On
        Turns on the printer power device.

    .EXAMPLE
        Set-KlippyPowerDevice -DeviceName "led_strip" -Action Toggle
        Toggles the LED strip.

    .EXAMPLE
        Get-KlippyPowerDevice -DeviceName "printer_power" | Set-KlippyPowerDevice -Action Off
        Turns off a device via pipeline.

    .OUTPUTS
        KlippyCLI.PowerDevice object with updated state.
    #>

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

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

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

        [Parameter(Mandatory = $true, ParameterSetName = 'ById')]
        [Parameter(Mandatory = $true, ParameterSetName = 'ByName')]
        [Parameter(ParameterSetName = 'ByObject', ValueFromPipelineByPropertyName = $true)]
        [string]$DeviceName,

        [Parameter(Mandatory = $true)]
        [ValidateSet('On', 'Off', 'Toggle')]
        [string]$Action
    )

    process {
        # Resolve printer and device name
        $resolveParams = @{}
        $targetDevice = $DeviceName

        if ($Id) { $resolveParams['Id'] = $Id }
        elseif ($PrinterName) { $resolveParams['PrinterName'] = $PrinterName }
        elseif ($InputObject) {
            if ($InputObject.PSTypeName -eq 'KlippyCLI.PowerDevice') {
                $resolveParams['Id'] = $InputObject.PrinterId
                if (-not $targetDevice) {
                    $targetDevice = $InputObject.DeviceName
                }
            }
            else {
                $resolveParams['InputObject'] = $InputObject
            }
        }

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        if (-not $targetDevice) {
            Write-Error "No device name specified."
            return
        }

        try {
            $actionVerb = switch ($Action) {
                'On' { 'on' }
                'Off' { 'off' }
                'Toggle' { 'toggle' }
            }

            $actionDescription = "Turn $Action device '$targetDevice'"
            if ($PSCmdlet.ShouldProcess($printer.PrinterName, $actionDescription)) {
                $encodedDevice = [System.Uri]::EscapeDataString($targetDevice)
                $endpoint = "machine/device_power/$actionVerb`?device=$encodedDevice"

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

                if ($response -and $response.$targetDevice) {
                    $newStatus = $response.$targetDevice
                    Write-Host "Device '$targetDevice' is now $newStatus on '$($printer.PrinterName)'." -ForegroundColor Green

                    # Return updated device info
                    [PSCustomObject]@{
                        PSTypeName  = 'KlippyCLI.PowerDevice'
                        PrinterId   = $printer.Id
                        PrinterName = $printer.PrinterName
                        DeviceName  = $targetDevice
                        Status      = $newStatus
                        IsOn        = $newStatus -eq 'on'
                    }
                }
            }
        }
        catch {
            Write-Error "Failed to control power device '$targetDevice' on '$($printer.PrinterName)': $_"
        }
    }
}