# G915 TKL lighting power settings over HID++ 0x8071 (rgbEffects). # g915-lighting.ps1 read timeouts, power mode and SW-control state # g915-lighting.ps1 -Dim 65535 -Off 65535 set both idle timeouts (seconds; 65535 = never) # g915-lighting.ps1 -Mode 1 lights on now (1 = full, 2 = power save, 3 = off) # g915-lighting.ps1 -Release hand lighting back to the keyboard firmware param([int]$Dim = -1, [int]$Off = -1, [int]$Mode = 0, [switch]$Release, [string]$Rcv = 'c545', [byte]$Slot = 1) Add-Type -Path (Join-Path $PSScriptRoot 'Hidpp.cs') $rx = New-Object HidppReceiver (, [HidppReceiver]::Find("vid_046d&pid_$Rcv")) function Call([byte]$idx, [byte]$fn, [byte[]]$params) { while ($rx.Next(0)) {} $long = $params.Length -gt 3 $req = New-Object byte[] $(if ($long) { 20 } else { 7 }) $req[0] = $(if ($long) { 0x11 } else { 0x10 }); $req[1] = $Slot; $req[2] = $idx; $req[3] = ($fn -shl 4) -bor 0x0A for ($i = 0; $i -lt $params.Length; $i++) { $req[4 + $i] = $params[$i] } $rx.Send($req) $deadline = (Get-Date).AddSeconds(2) while ((Get-Date) -lt $deadline) { $r = $rx.Next(200) if ($r -and $r[1] -eq $Slot -and $r[2] -eq $idx -and $r[3] -eq $req[3]) { return ,$r } if ($r -and $r[1] -eq $Slot -and $r[2] -eq 0xFF -and $r[3] -eq $idx) { throw ("HID++ error 0x{0:X2} on fn {1}" -f $r[5], $fn) } } throw "No reply from keyboard (asleep or switched to the Mac?)" } function U16($r, $o) { ([int]$r[$o] -shl 8) -bor [int]$r[$o + 1] } function Fmt($s) { if ($s -eq 0xFFFF) { 'never' } else { "$s s" } } try { $root = Call 0 0 ([byte[]](0x80, 0x71)) # Root.getFeature(0x8071) $fi = $root[4]; if ($fi -eq 0) { throw "Keyboard has no 0x8071 feature" } if ($Dim -ge 0 -and $Off -ge 0) { $null = Call $fi 7 ([byte[]](0x01, 0x00, 0x00, ($Dim -shr 8), ($Dim -band 0xFF), ($Off -shr 8), ($Off -band 0xFF))) "Wrote timeouts: dim {0}, off {1}" -f (Fmt $Dim), (Fmt $Off) } if ($Release) { # Hand LEDs and power modes back to the keyboard firmware (onboard behaviour) $null = Call $fi 5 ([byte[]](0x01, 0x00, 0x00)) "Released SW control" } if ($Mode -ge 1) { # Only accepted while some host owns power modes (SW control flag 0x02) $null = Call $fi 8 ([byte[]](0x01, $Mode, 0x00)) "Set power mode $Mode" } $cfg = Call $fi 7 ([byte[]](0x00, 0x00, 0x00)) $sw = Call $fi 5 ([byte[]](0x00, 0x00, 0x00)) $pm = Call $fi 8 ([byte[]](0x00, 0x00, 0x00)) "0x8071 at feature index $fi" " Idle -> power save (dim): {0}" -f (Fmt (U16 $cfg 7)) " Idle -> off: {0}" -f (Fmt (U16 $cfg 9)) " Power mode: {0} (1 = full, 2 = power save, 3 = off)" -f $pm[5] " SW control flags: 0x{0:X2} (0x01 = host owns LEDs, 0x02 = host owns power modes)" -f $sw[5] " Event flags: 0x{0:X2}" -f $sw[6] " raw cfg {0}" -f [HidppReceiver]::Hex($cfg) } finally { $rx.Dispose() }