Add server-side rendered setup UI accessible via `heatwave web`. The dashboard is now re-rendered per request and includes a nav bar linking to the new /setup page. Setup provides full CRUD for profiles, rooms, devices, occupants, AC units (with room assignment), scenario toggles, and forecast fetching — all via POST/redirect/GET forms. - Add ShowNav field to DashboardData for conditional nav bar - Extract fetchForecastForProfile() for reuse by web handler - Create setup.html.tmpl with Tailwind-styled entity sections - Create web_handlers.go with 15 route handlers and flash cookies - Switch web.go from pre-rendered to per-request dashboard rendering - Graceful dashboard fallback when no forecast data exists
63 lines
1.2 KiB
Go
63 lines
1.2 KiB
Go
package heat
|
|
|
|
import (
|
|
"math"
|
|
"testing"
|
|
)
|
|
|
|
const tolerance = 0.01
|
|
|
|
func almostEqual(a, b, tol float64) bool {
|
|
return math.Abs(a-b) < tol
|
|
}
|
|
|
|
func TestWattsToBTUH(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
watts float64
|
|
want float64
|
|
}{
|
|
{"zero", 0, 0},
|
|
{"one watt", 1, 3.41214},
|
|
{"1000 watts", 1000, 3412.14},
|
|
{"negative", -100, -341.214},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := WattsToBTUH(tt.watts)
|
|
if !almostEqual(got, tt.want, tolerance) {
|
|
t.Errorf("WattsToBTUH(%v) = %v, want %v", tt.watts, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBTUHToWatts(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
btuh float64
|
|
want float64
|
|
}{
|
|
{"zero", 0, 0},
|
|
{"one BTU/h", 1, 0.29307},
|
|
{"8000 BTU/h", 8000, 2344.57},
|
|
{"negative", -3412.14, -1000.0},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := BTUHToWatts(tt.btuh)
|
|
if !almostEqual(got, tt.want, tolerance) {
|
|
t.Errorf("BTUHToWatts(%v) = %v, want %v", tt.btuh, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRoundTrip(t *testing.T) {
|
|
original := 500.0
|
|
got := BTUHToWatts(WattsToBTUH(original))
|
|
if !almostEqual(got, original, tolerance) {
|
|
t.Errorf("round-trip failed: %v -> %v", original, got)
|
|
}
|
|
}
|