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
31 lines
817 B
Go
31 lines
817 B
Go
package action
|
|
|
|
import (
|
|
"github.com/cnachtigall/heatwave-autopilot/internal/heat"
|
|
"github.com/cnachtigall/heatwave-autopilot/internal/risk"
|
|
)
|
|
|
|
// TimelineSlot represents one hour in a 24-hour plan.
|
|
type TimelineSlot struct {
|
|
Hour int
|
|
Actions []Action
|
|
TempC float64
|
|
RiskLevel risk.RiskLevel
|
|
BudgetStatus heat.BudgetStatus
|
|
}
|
|
|
|
// BuildTimeline creates a 24-slot timeline from hourly contexts and available actions.
|
|
func BuildTimeline(contexts []HourContext, actions []Action) []TimelineSlot {
|
|
slots := make([]TimelineSlot, len(contexts))
|
|
for i, ctx := range contexts {
|
|
slots[i] = TimelineSlot{
|
|
Hour: ctx.Hour,
|
|
TempC: ctx.TempC,
|
|
RiskLevel: ctx.RiskLevel,
|
|
BudgetStatus: ctx.BudgetStatus,
|
|
Actions: SelectActions(actions, ctx),
|
|
}
|
|
}
|
|
return slots
|
|
}
|