Pass profile timezone through DashboardData so the frontend can compute the current hour and highlight it on the heatmap (white ring + orange triangle marker). Only activates when the dashboard date matches today in the profile timezone. In cold weather (peak < 22°C, risk low), the risk card now shows a teal "Comfortable" presentation with a checkmark icon instead of the generic green "Low" shield.
180 lines
6.2 KiB
Go
180 lines
6.2 KiB
Go
package compute
|
|
|
|
import "time"
|
|
|
|
// Profile holds location profile data sent from the client.
|
|
type Profile struct {
|
|
ID int64 `json:"id"`
|
|
Name string `json:"name"`
|
|
Latitude float64 `json:"latitude"`
|
|
Longitude float64 `json:"longitude"`
|
|
Timezone string `json:"timezone"`
|
|
}
|
|
|
|
// Room holds room parameters sent from the client.
|
|
type Room struct {
|
|
ID int64 `json:"id"`
|
|
ProfileID int64 `json:"profileId"`
|
|
Name string `json:"name"`
|
|
AreaSqm float64 `json:"areaSqm"`
|
|
CeilingHeightM float64 `json:"ceilingHeightM"`
|
|
Floor int `json:"floor"`
|
|
Orientation string `json:"orientation"`
|
|
ShadingType string `json:"shadingType"`
|
|
ShadingFactor float64 `json:"shadingFactor"`
|
|
Ventilation string `json:"ventilation"`
|
|
VentilationACH float64 `json:"ventilationAch"`
|
|
WindowFraction float64 `json:"windowFraction"`
|
|
SHGC float64 `json:"shgc"`
|
|
Insulation string `json:"insulation"`
|
|
IndoorTempC float64 `json:"indoorTempC"`
|
|
IndoorHumidityPct *float64 `json:"indoorHumidityPct,omitempty"`
|
|
}
|
|
|
|
// Device holds device data sent from the client.
|
|
type Device struct {
|
|
ID int64 `json:"id"`
|
|
RoomID int64 `json:"roomId"`
|
|
Name string `json:"name"`
|
|
DeviceType string `json:"deviceType"`
|
|
WattsIdle float64 `json:"wattsIdle"`
|
|
WattsTypical float64 `json:"wattsTypical"`
|
|
WattsPeak float64 `json:"wattsPeak"`
|
|
DutyCycle float64 `json:"dutyCycle"`
|
|
}
|
|
|
|
// Occupant holds occupant data sent from the client.
|
|
type Occupant struct {
|
|
ID int64 `json:"id"`
|
|
RoomID int64 `json:"roomId"`
|
|
Count int `json:"count"`
|
|
ActivityLevel string `json:"activityLevel"`
|
|
Vulnerable bool `json:"vulnerable"`
|
|
}
|
|
|
|
// ACUnit holds AC unit data sent from the client.
|
|
type ACUnit struct {
|
|
ID int64 `json:"id"`
|
|
ProfileID int64 `json:"profileId"`
|
|
Name string `json:"name"`
|
|
ACType string `json:"acType"`
|
|
CapacityBTU float64 `json:"capacityBtu"`
|
|
HasDehumidify bool `json:"hasDehumidify"`
|
|
EfficiencyEER float64 `json:"efficiencyEer"`
|
|
}
|
|
|
|
// ACAssignment maps an AC unit to a room.
|
|
type ACAssignment struct {
|
|
ACID int64 `json:"acId"`
|
|
RoomID int64 `json:"roomId"`
|
|
}
|
|
|
|
// Forecast holds hourly forecast data sent from the client.
|
|
type Forecast struct {
|
|
Timestamp time.Time `json:"timestamp"`
|
|
TemperatureC *float64 `json:"temperatureC"`
|
|
HumidityPct *float64 `json:"humidityPct"`
|
|
CloudCoverPct *float64 `json:"cloudCoverPct"`
|
|
SunshineMin *float64 `json:"sunshineMin"`
|
|
ApparentTempC *float64 `json:"apparentTempC"`
|
|
PressureHpa *float64 `json:"pressureHpa"`
|
|
}
|
|
|
|
// Warning holds a weather warning sent from the client.
|
|
type Warning struct {
|
|
Headline string `json:"headline"`
|
|
Severity string `json:"severity"`
|
|
Description string `json:"description"`
|
|
Instruction string `json:"instruction"`
|
|
Onset string `json:"onset"`
|
|
Expires string `json:"expires"`
|
|
}
|
|
|
|
// ComputeRequest holds all data needed to compute a dashboard.
|
|
type ComputeRequest struct {
|
|
Profile Profile `json:"profile"`
|
|
Rooms []Room `json:"rooms"`
|
|
Devices []Device `json:"devices"`
|
|
Occupants []Occupant `json:"occupants"`
|
|
ACUnits []ACUnit `json:"acUnits"`
|
|
ACAssignments []ACAssignment `json:"acAssignments"`
|
|
Toggles map[string]bool `json:"toggles"`
|
|
Forecasts []Forecast `json:"forecasts"`
|
|
Warnings []Warning `json:"warnings"`
|
|
Date string `json:"date"`
|
|
}
|
|
|
|
// DashboardData holds all computed data for the dashboard response.
|
|
type DashboardData struct {
|
|
GeneratedAt time.Time `json:"generatedAt"`
|
|
ProfileName string `json:"profileName"`
|
|
Date string `json:"date"`
|
|
Timezone string `json:"timezone"`
|
|
RiskLevel string `json:"riskLevel"`
|
|
PeakTempC float64 `json:"peakTempC"`
|
|
MinNightTempC float64 `json:"minNightTempC"`
|
|
PoorNightCool bool `json:"poorNightCool"`
|
|
IndoorTempC float64 `json:"indoorTempC"`
|
|
IndoorHumidityPct float64 `json:"indoorHumidityPct"`
|
|
Warnings []WarningData `json:"warnings"`
|
|
RiskWindows []RiskWindowData `json:"riskWindows"`
|
|
Timeline []TimelineSlotData `json:"timeline"`
|
|
RoomBudgets []RoomBudgetData `json:"roomBudgets"`
|
|
CareChecklist []string `json:"careChecklist"`
|
|
}
|
|
|
|
// WarningData holds a weather warning for display.
|
|
type WarningData struct {
|
|
Headline string `json:"headline"`
|
|
Severity string `json:"severity"`
|
|
Description string `json:"description"`
|
|
Instruction string `json:"instruction"`
|
|
Onset string `json:"onset"`
|
|
Expires string `json:"expires"`
|
|
}
|
|
|
|
// RiskWindowData holds a risk window for display.
|
|
type RiskWindowData struct {
|
|
StartHour int `json:"startHour"`
|
|
EndHour int `json:"endHour"`
|
|
PeakTempC float64 `json:"peakTempC"`
|
|
Level string `json:"level"`
|
|
Reason string `json:"reason"`
|
|
}
|
|
|
|
// TimelineSlotData holds one hour's data for the timeline.
|
|
type TimelineSlotData struct {
|
|
Hour int `json:"hour"`
|
|
HourStr string `json:"hourStr"`
|
|
TempC float64 `json:"tempC"`
|
|
HumidityPct float64 `json:"humidityPct"`
|
|
PressureHpa float64 `json:"pressureHpa"`
|
|
RiskLevel string `json:"riskLevel"`
|
|
BudgetStatus string `json:"budgetStatus"`
|
|
IndoorTempC float64 `json:"indoorTempC"`
|
|
CoolMode string `json:"coolMode"`
|
|
Actions []ActionData `json:"actions"`
|
|
}
|
|
|
|
// ActionData holds a single action for display.
|
|
type ActionData struct {
|
|
Name string `json:"name"`
|
|
Category string `json:"category"`
|
|
Effort string `json:"effort"`
|
|
Impact string `json:"impact"`
|
|
Description string `json:"description"`
|
|
}
|
|
|
|
// RoomBudgetData holds a room's heat budget for display.
|
|
type RoomBudgetData struct {
|
|
RoomName string `json:"roomName"`
|
|
InternalGainsW float64 `json:"internalGainsW"`
|
|
SolarGainW float64 `json:"solarGainW"`
|
|
VentGainW float64 `json:"ventGainW"`
|
|
TotalGainW float64 `json:"totalGainW"`
|
|
TotalGainBTUH float64 `json:"totalGainBtuh"`
|
|
ACCapacityBTUH float64 `json:"acCapacityBtuh"`
|
|
HeadroomBTUH float64 `json:"headroomBtuh"`
|
|
Status string `json:"status"`
|
|
}
|