This commit is contained in:
2026-01-10 04:39:21 +01:00
parent 8de9a0dd87
commit eee3f48569
6 changed files with 75 additions and 31 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -7,7 +7,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<script type="module" crossorigin src="/assets/index-DY7RBkJT.js"></script>
<script type="module" crossorigin src="/assets/index-CQrlLShx.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-PFp0U9rZ.css">
</head>
<body>

View File

@@ -27,6 +27,7 @@ type Client struct {
// Auto fan management
autoFanEnabled bool
lastFanMode string // Remember last manual mode
autoFanActive bool // Track if auto-fan is currently active (in Broadcast mode)
}
type Status struct {
@@ -190,6 +191,47 @@ func (c *Client) pollLoop() {
// Override PowerForward with display power for frontend
status.PowerForward = status.displayPower
// Auto fan management based on temperature
// Do this BEFORE merging to use the fresh temperature value
if c.autoFanEnabled {
// Use the temperature from the current status message
// If it's 0, use the last known temperature
temp := status.Temperature
if temp == 0 && c.lastStatus != nil {
temp = c.lastStatus.Temperature
}
currentMode := strings.ToUpper(status.FanMode)
if currentMode == "" && c.lastStatus != nil {
currentMode = strings.ToUpper(c.lastStatus.FanMode)
}
// Only act on valid temperature readings
if temp > 5.0 { // Ignore invalid/startup readings below 5°C
// If temp >= 60°C, switch to Broadcast
if temp >= 60.0 && currentMode != "BROADCAST" {
if !c.autoFanActive {
log.Printf("PowerGenius: Temperature %.1f°C >= 60°C, switching fan to Broadcast mode", temp)
c.autoFanActive = true
}
if err := c.setFanModeInternal("BROADCAST"); err != nil {
log.Printf("PowerGenius: Failed to set fan mode: %v", err)
}
}
// If temp <= 55°C, switch back to Contest
if temp <= 55.0 && currentMode == "BROADCAST" {
if c.autoFanActive {
log.Printf("PowerGenius: Temperature %.1f°C <= 55°C, switching fan back to Contest mode", temp)
c.autoFanActive = false
}
if err := c.setFanModeInternal("CONTEST"); err != nil {
log.Printf("PowerGenius: Failed to set fan mode: %v", err)
}
}
}
}
// Merge with existing status (spontaneous messages may only update some fields)
c.statusMu.Lock()
if c.lastStatus != nil {
@@ -216,32 +258,6 @@ func (c *Client) pollLoop() {
c.lastStatus = status
c.statusMu.Unlock()
// Auto fan management based on temperature
if c.autoFanEnabled {
temp := status.Temperature
currentMode := status.FanMode
// If temp >= 60°C, switch to Broadcast
if temp >= 60.0 && currentMode != "Broadcast" {
log.Printf("PowerGenius: Temperature %.1f°C >= 60°C, switching fan to Broadcast mode", temp)
if err := c.SetFanMode("Broadcast"); err != nil {
log.Printf("PowerGenius: Failed to set fan mode: %v", err)
}
}
// If temp <= 55°C, switch back to Contest (or last manual mode)
if temp <= 55.0 && currentMode == "Broadcast" {
targetMode := c.lastFanMode
if targetMode == "" || targetMode == "Broadcast" {
targetMode = "Contest"
}
log.Printf("PowerGenius: Temperature %.1f°C <= 55°C, switching fan back to %s mode", temp, targetMode)
if err := c.SetFanMode(targetMode); err != nil {
log.Printf("PowerGenius: Failed to set fan mode: %v", err)
}
}
}
case <-c.stopChan:
return
}
@@ -462,7 +478,12 @@ func (c *Client) SetFanMode(mode string) error {
// We store it in title case: "Standard", "Contest", "Broadcast"
c.lastFanMode = strings.Title(strings.ToLower(mode))
cmd := fmt.Sprintf("setup fanmode=%s", modeUpper)
return c.setFanModeInternal(modeUpper)
}
// setFanModeInternal sets fan mode without updating lastFanMode (for auto-fan)
func (c *Client) setFanModeInternal(mode string) error {
cmd := fmt.Sprintf("setup fanmode=%s", mode)
_, err := c.sendCommand(cmd)
return err
}

View File

@@ -102,14 +102,14 @@
<!-- Temperature Gauges -->
<div class="temp-group">
<div class="temp-item">
<div class="temp-value" style="color: {tempColor}">{temperature.toFixed(0)}°</div>
<div class="temp-value" style="color: {tempColor}">{temperature.toFixed(1)}°</div>
<div class="temp-label">PA Temp</div>
<div class="temp-mini-bar">
<div class="temp-mini-fill" style="width: {(temperature / 80) * 100}%; background: {tempColor}"></div>
</div>
</div>
<div class="temp-item">
<div class="temp-value" style="color: {tempColor}">{harmonicLoadTemp.toFixed(0)}°</div>
<div class="temp-value" style="color: {tempColor}">{harmonicLoadTemp.toFixed(1)}°</div>
<div class="temp-label">HL Temp</div>
<div class="temp-mini-bar">
<div class="temp-mini-fill" style="width: {(harmonicLoadTemp / 80) * 100}%; background: {tempColor}"></div>

View File

@@ -3,7 +3,14 @@
export let status;
$: heading = status?.heading || 0;
let heading = 0;
let connected = false;
// Update heading only if we have a valid value from status
$: if (status?.heading !== undefined && status?.heading !== null) {
heading = status.heading;
}
$: connected = status?.connected || false;
let targetHeading = 0;