Compare commits

..

No commits in common. "a6eab94e0da6bdb26fd9abbbc1c7ccf4be8a3e94" and "79bac39b6b40f8e4ac72bd7aea0880366fe3a799" have entirely different histories.

4 changed files with 54 additions and 148 deletions

View File

@ -23,8 +23,8 @@ type Config struct {
LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration
WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"` WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"`
DisplayMaxBrightness int `json:"display_max_brightness"` DisplayMaxBrightness int `json:"display_max_brightness"`
DisplayDimAfterSec int `json:"display_dim_after_sec"` DisplayDimAfterMs int64 `json:"display_dim_after_ms"`
DisplayOffAfterSec int `json:"display_off_after_sec"` DisplayOffAfterMs int64 `json:"display_off_after_ms"`
} }
const configPath = "/userdata/kvm_config.json" const configPath = "/userdata/kvm_config.json"
@ -33,8 +33,8 @@ var defaultConfig = &Config{
CloudURL: "https://api.jetkvm.com", CloudURL: "https://api.jetkvm.com",
AutoUpdateEnabled: true, // Set a default value AutoUpdateEnabled: true, // Set a default value
DisplayMaxBrightness: 64, DisplayMaxBrightness: 64,
DisplayDimAfterSec: 120, // 2 minutes DisplayDimAfterMs: 120000, // 2 minutes
DisplayOffAfterSec: 1800, // 30 minutes DisplayOffAfterMs: 1800000, // 30 minutes
} }
var config *Config var config *Config

View File

@ -77,7 +77,7 @@ func requestDisplayUpdate() {
return return
} }
go func() { go func() {
wakeDisplay(false) 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()
@ -149,28 +149,22 @@ func tick_displayOff() {
// wakeDisplay sets the display brightness back to config.DisplayMaxBrightness and stores the time the display // 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. // last woke, ready for displayTimeoutTick to put the display back in the dim/off states.
// Set force to true to skip the backlight state check, this should be done if altering the tickers. func wakeDisplay() {
func wakeDisplay(force bool) { if backlightState == 0 {
if backlightState == 0 && !force {
return return
} }
if config.DisplayMaxBrightness == 0 {
config.DisplayMaxBrightness = 100
}
err := setDisplayBrightness(config.DisplayMaxBrightness) err := setDisplayBrightness(config.DisplayMaxBrightness)
if err != nil { if err != nil {
fmt.Printf("display wake failed, %s\n", err) fmt.Printf("display wake failed, %s\n", err)
} }
if config.DisplayDimAfterSec == 0 { dim_ticker.Reset(time.Duration(config.DisplayDimAfterMs) * time.Millisecond)
dim_ticker.Stop() off_ticker.Reset(time.Duration(config.DisplayOffAfterMs) * time.Millisecond)
} else {
dim_ticker.Reset(time.Duration(config.DisplayDimAfterSec) * time.Second)
}
if config.DisplayOffAfterSec == 0 {
off_ticker.Stop()
} else {
off_ticker.Reset(time.Duration(config.DisplayOffAfterSec) * time.Second)
}
backlightState = 0 backlightState = 0
} }
@ -198,43 +192,7 @@ func watchTsEvents() {
return return
} }
wakeDisplay(false) wakeDisplay()
}
}
// startBacklightTickers starts the two tickers for dimming and switching off the display
// if they're not already set. This is done separately to the init routine as the "never dim"
// option has the value set to zero, but time.NewTicker only accept positive values.
func startBacklightTickers() {
LoadConfig()
if dim_ticker == nil && config.DisplayDimAfterSec != 0 {
fmt.Printf("display: dim_ticker has started.")
dim_ticker = time.NewTicker(time.Duration(config.DisplayDimAfterSec) * time.Second)
defer dim_ticker.Stop()
go func() {
for {
select {
case <-dim_ticker.C:
tick_displayDim()
}
}
}()
}
if off_ticker == nil && config.DisplayOffAfterSec != 0 {
fmt.Printf("display: off_ticker has started.")
off_ticker = time.NewTicker(time.Duration(config.DisplayOffAfterSec) * time.Second)
defer off_ticker.Stop()
go func() {
for {
select {
case <-off_ticker.C:
tick_displayOff()
}
}
}()
} }
} }
@ -246,11 +204,28 @@ func init() {
updateStaticContents() updateStaticContents()
displayInited = true displayInited = true
fmt.Println("display inited") fmt.Println("display inited")
wakeDisplay(false) wakeDisplay()
requestDisplayUpdate() requestDisplayUpdate()
}() }()
startBacklightTickers() go func() {
LoadConfig()
// Start display auto-sleeping tickers
dim_ticker = time.NewTicker(time.Duration(config.DisplayDimAfterMs) * time.Millisecond)
defer dim_ticker.Stop()
off_ticker = time.NewTicker(time.Duration(config.DisplayOffAfterMs) * time.Millisecond)
defer off_ticker.Stop()
for {
select {
case <-dim_ticker.C:
tick_displayDim()
case <-off_ticker.C:
tick_displayOff()
}
}
}()
go watchTsEvents() go watchTsEvents()
} }

View File

@ -225,14 +225,13 @@ func rpcTryUpdate() error {
return nil return nil
} }
func rpcSetBacklightSettings(params BacklightSettings) error { func rpcSetBacklightSettings(data *BacklightSettings) error {
LoadConfig() LoadConfig()
blConfig := params blConfig := *data
// NOTE: by default, the frontend limits the brightness to 64, as that's what the device originally shipped with. if blConfig.MaxBrightness > 100 || blConfig.MaxBrightness < 0 {
if blConfig.MaxBrightness > 255 || blConfig.MaxBrightness < 0 { return fmt.Errorf("maxBrightness must be between 0 and 100")
return fmt.Errorf("maxBrightness must be between 0 and 255")
} }
if blConfig.DimAfter < 0 { if blConfig.DimAfter < 0 {
@ -244,24 +243,12 @@ func rpcSetBacklightSettings(params BacklightSettings) error {
} }
config.DisplayMaxBrightness = blConfig.MaxBrightness config.DisplayMaxBrightness = blConfig.MaxBrightness
config.DisplayDimAfterSec = blConfig.DimAfter config.DisplayDimAfterMs = int64(blConfig.DimAfter)
config.DisplayOffAfterSec = blConfig.OffAfter config.DisplayOffAfterMs = int64(blConfig.OffAfter)
if err := SaveConfig(); err != nil { if err := SaveConfig(); err != nil {
return fmt.Errorf("failed to save config: %w", err) return fmt.Errorf("failed to save config: %w", err)
} }
log.Printf("rpc: display: settings applied, max_brightness: %d, dim after: %ds, off after: %ds", config.DisplayMaxBrightness, config.DisplayDimAfterSec, config.DisplayOffAfterSec)
// If the device started up with auto-dim and/or auto-off set to zero, the display init
// method will not have started the tickers. So in case that has changed, attempt to start the tickers now.
startBacklightTickers()
// Wake the display after the settings are altered, this ensures the tickers
// are reset to the new settings, and will bring the display up to maxBrightness.
// Calling with force set to true, to ignore the current state of the display, and force
// it to reset the tickers.
wakeDisplay(true)
return nil return nil
} }
@ -270,8 +257,8 @@ func rpcGetBacklightSettings() (*BacklightSettings, error) {
return &BacklightSettings{ return &BacklightSettings{
MaxBrightness: config.DisplayMaxBrightness, MaxBrightness: config.DisplayMaxBrightness,
DimAfter: int(config.DisplayDimAfterSec), DimAfter: int(config.DisplayDimAfterMs),
OffAfter: int(config.DisplayOffAfterSec), OffAfter: int(config.DisplayOffAfterMs),
}, nil }, nil
} }
@ -435,7 +422,7 @@ func callRPCHandler(handler RPCHandler, params map[string]interface{}) (interfac
} }
args[i] = reflect.ValueOf(newStruct).Elem() args[i] = reflect.ValueOf(newStruct).Elem()
} else { } else {
return nil, fmt.Errorf("invalid parameter type for: %s, type: %s", paramName, paramType.Kind()) return nil, fmt.Errorf("invalid parameter type for: %s", paramName)
} }
} else { } else {
args[i] = convertedValue.Convert(paramType) args[i] = convertedValue.Convert(paramType)
@ -610,6 +597,6 @@ var rpcHandlers = map[string]RPCHandler{
"getWakeOnLanDevices": {Func: rpcGetWakeOnLanDevices}, "getWakeOnLanDevices": {Func: rpcGetWakeOnLanDevices},
"setWakeOnLanDevices": {Func: rpcSetWakeOnLanDevices, Params: []string{"params"}}, "setWakeOnLanDevices": {Func: rpcSetWakeOnLanDevices, Params: []string{"params"}},
"resetConfig": {Func: rpcResetConfig}, "resetConfig": {Func: rpcResetConfig},
"setBacklightSettings": {Func: rpcSetBacklightSettings, Params: []string{"params"}}, "setBacklightSettings": {Func: rpcSetBacklightSettings, Params: []string{"settings"}},
"getBacklightSettings": {Func: rpcGetBacklightSettings}, "getBacklightSettings": {Func: rpcGetBacklightSettings},
} }

View File

@ -230,18 +230,8 @@ export default function SettingsSidebar() {
[send, setDeveloperMode], [send, setDeveloperMode],
); );
const handleBacklightSettingsChange = (settings: BacklightSettings) => { const handleBacklightSettingChange = useCallback((settings: BacklightSettings) => {
// If the user has set the display to dim after it turns off, set the dim_after send("setBacklightSettings", { settings }, resp => {
// value to never.
if (settings.dim_after > settings.off_after && settings.off_after != 0) {
settings.dim_after = 0;
}
setBacklightSettings(settings);
}
const handleBacklightSettingsSave = () => {
send("setBacklightSettings", { params: settings.backlightSettings }, resp => {
if ("error" in resp) { if ("error" in resp) {
notifications.error( notifications.error(
`Failed to set backlight settings: ${resp.error.data || "Unknown error"}`, `Failed to set backlight settings: ${resp.error.data || "Unknown error"}`,
@ -250,7 +240,7 @@ export default function SettingsSidebar() {
} }
notifications.success("Backlight settings updated successfully"); notifications.success("Backlight settings updated successfully");
}); });
}; }, [send]);
const handleUpdateSSHKey = useCallback(() => { const handleUpdateSSHKey = useCallback(() => {
send("setSSHKeyState", { sshKey }, resp => { send("setSSHKeyState", { sshKey }, resp => {
@ -839,6 +829,7 @@ export default function SettingsSidebar() {
/> />
</div> </div>
<SettingsItem title="Display Brightness" description="Set the brightness of the display"> <SettingsItem title="Display Brightness" description="Set the brightness of the display">
{/* TODO: Allow the user to pick any value between 0 and 100 */}
<SelectMenuBasic <SelectMenuBasic
size="SM" size="SM"
label="" label=""
@ -846,65 +837,18 @@ export default function SettingsSidebar() {
options={[ options={[
{ value: "0", label: "Off" }, { value: "0", label: "Off" },
{ value: "10", label: "Low" }, { value: "10", label: "Low" },
{ value: "35", label: "Medium" }, { value: "50", label: "Medium" },
{ value: "64", label: "High" }, { value: "100", label: "High" },
]} ]}
onChange={e => { onChange={e => {
settings.backlightSettings.max_brightness = parseInt(e.target.value) handleBacklightSettingChange({
handleBacklightSettingsChange(settings.backlightSettings); max_brightness: parseInt(e.target.value),
dim_after: settings.backlightSettings.dim_after,
off_after: settings.backlightSettings.off_after,
});
}} }}
/> />
</SettingsItem> </SettingsItem>
{settings.backlightSettings.max_brightness != 0 && (
<>
<SettingsItem title="Dim Display After" description="Set how long to wait before dimming the display">
<SelectMenuBasic
size="SM"
label=""
value={settings.backlightSettings.dim_after.toString()}
options={[
{ value: "0", label: "Never" },
{ value: "60", label: "1 Minute" },
{ value: "300", label: "5 Minutes" },
{ value: "600", label: "10 Minutes" },
{ value: "1800", label: "30 Minutes" },
{ value: "3600", label: "1 Hour" },
]}
onChange={e => {
settings.backlightSettings.dim_after = parseInt(e.target.value)
handleBacklightSettingsChange(settings.backlightSettings);
}}
/>
</SettingsItem>
<SettingsItem title="Turn off Display After" description="Set how long to wait before turning off the display">
<SelectMenuBasic
size="SM"
label=""
value={settings.backlightSettings.off_after.toString()}
options={[
{ value: "0", label: "Never" },
{ value: "300", label: "5 Minutes" },
{ value: "600", label: "10 Minutes" },
{ value: "1800", label: "30 Minutes" },
{ value: "3600", label: "1 Hour" },
]}
onChange={e => {
settings.backlightSettings.off_after = parseInt(e.target.value)
handleBacklightSettingsChange(settings.backlightSettings);
}}
/>
</SettingsItem>
</>
)}
<p className="text-xs text-slate-600 dark:text-slate-400">
The display will wake up when the connection state changes, or when touched.
</p>
<Button
size="SM"
theme="primary"
text="Save Display Settings"
onClick={handleBacklightSettingsSave}
/>
<div className="h-[1px] w-full bg-slate-800/10 dark:bg-slate-300/20" /> <div className="h-[1px] w-full bg-slate-800/10 dark:bg-slate-300/20" />
<div className="pb-2 space-y-4"> <div className="pb-2 space-y-4">
<SectionHeader <SectionHeader