feat(display): add automatic dimming & switch off to display

WIP, dims the display to 50% of the BacklightMaxBrightness after
BacklightDimAfterMS expires. Turns the display off after
BacklightOffAfterMS
This commit is contained in:
Cameron Fleming 2025-01-03 22:07:05 +00:00
parent 4fd8b1e6ff
commit cd7258efd0
1 changed files with 68 additions and 4 deletions

View File

@ -1,15 +1,17 @@
package kvm package kvm
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"time"
"os" "os"
"errors"
"strconv" "strconv"
"time"
) )
var currentScreen = "ui_Boot_Screen" var currentScreen = "ui_Boot_Screen"
var lastWakeTime = time.Now()
var backlightState = 0 // 0 - NORMAL, 1 - DIMMED, 2 - OFF
func switchToScreen(screen string) { func switchToScreen(screen string) {
_, err := CallCtrlAction("lv_scr_load", map[string]interface{}{"obj": screen}) _, err := CallCtrlAction("lv_scr_load", map[string]interface{}{"obj": screen})
@ -68,6 +70,7 @@ func requestDisplayUpdate() {
return return
} }
go func() { go func() {
wakeDisplay()
fmt.Println("display updating........................") fmt.Println("display updating........................")
//TODO: only run once regardless how many pending updates //TODO: only run once regardless how many pending updates
updateDisplay() updateDisplay()
@ -88,7 +91,7 @@ func updateStaticContents() {
// setDisplayBrightness sets /sys/class/backlight/backlight/brightness to alter // setDisplayBrightness sets /sys/class/backlight/backlight/brightness to alter
// the backlight brightness of the JetKVM hardware's display. // the backlight brightness of the JetKVM hardware's display.
func setDisplayBrightness(brightness int) (error) { func setDisplayBrightness(brightness int) error {
if brightness > 100 || brightness < 0 { if brightness > 100 || brightness < 0 {
return errors.New("brightness value out of bounds, must be between 0 and 100") return errors.New("brightness value out of bounds, must be between 0 and 100")
} }
@ -105,10 +108,58 @@ func setDisplayBrightness(brightness int) (error) {
return err return err
} }
fmt.Print("display: set brightness to %v", brightness) fmt.Printf("display: set brightness to %v", brightness)
return nil return nil
} }
// displayTimeoutTick checks the time the display was last woken, and compares that to the
// config's displayTimeout values to decide whether or not to dim/switch off the display.
func displayTimeoutTick() {
tn := time.Now()
td := tn.Sub(lastWakeTime).Milliseconds()
// fmt.Printf("display: tick: time since wake: %vms, dim after: %v, off after: %v\n", td, config.DisplayDimAfterMs, config.DisplayOffAfterMs)
if td > config.DisplayOffAfterMs && config.DisplayOffAfterMs != 0 && (backlightState == 1 || backlightState == 0) {
// Display fully off
backlightState = 2
err := setDisplayBrightness(0)
if err != nil {
fmt.Printf("display: timeout: Failed to switch off backlight: %s\n", err)
}
} else if td > config.DisplayDimAfterMs && config.DisplayDimAfterMs != 0 && backlightState == 0 {
// Display dimming
// Get 50% of max brightness, rounded up.
dimBright := config.DisplayMaxBrightness / 2
fmt.Printf("display: timeout: target dim brightness: %v\n", dimBright)
backlightState = 1
err := setDisplayBrightness(dimBright)
if err != nil {
fmt.Printf("display: timeout: Failed to dim backlight: %s\n", err)
}
}
}
// wakeDisplay sets the display brightness back to config.DisplayMaxBrightness and stores the time the display
// last woke, ready for displayTimeoutTick to put the display back in the dim/off states.
func wakeDisplay() {
if config.DisplayMaxBrightness == 0 {
config.DisplayMaxBrightness = 100
}
err := setDisplayBrightness(config.DisplayMaxBrightness)
if err != nil {
fmt.Printf("display wake failed, %s\n", err)
}
lastWakeTime = time.Now()
backlightState = 0
}
func init() { func init() {
go func() { go func() {
waitCtrlClientConnected() waitCtrlClientConnected()
@ -119,4 +170,17 @@ func init() {
fmt.Println("display inited") fmt.Println("display inited")
requestDisplayUpdate() requestDisplayUpdate()
}() }()
go func() {
// Start display auto-sleeping ticker
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
displayTimeoutTick()
}
}
}()
} }