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
107 lines
4.0 KiB
SQL
107 lines
4.0 KiB
SQL
CREATE TABLE IF NOT EXISTS profiles (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL UNIQUE,
|
|
latitude REAL NOT NULL,
|
|
longitude REAL NOT NULL,
|
|
timezone TEXT NOT NULL DEFAULT 'Europe/Berlin',
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS rooms (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
profile_id INTEGER NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
area_sqm REAL NOT NULL,
|
|
ceiling_height_m REAL NOT NULL DEFAULT 2.5,
|
|
floor INTEGER NOT NULL DEFAULT 0,
|
|
orientation TEXT NOT NULL DEFAULT 'N',
|
|
shading_type TEXT NOT NULL DEFAULT 'none',
|
|
shading_factor REAL NOT NULL DEFAULT 1.0,
|
|
ventilation TEXT NOT NULL DEFAULT 'natural',
|
|
ventilation_ach REAL NOT NULL DEFAULT 0.5,
|
|
window_fraction REAL NOT NULL DEFAULT 0.15,
|
|
shgc REAL NOT NULL DEFAULT 0.6,
|
|
insulation TEXT NOT NULL DEFAULT 'average',
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS occupants (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
room_id INTEGER NOT NULL REFERENCES rooms(id) ON DELETE CASCADE,
|
|
count INTEGER NOT NULL DEFAULT 1,
|
|
activity_level TEXT NOT NULL DEFAULT 'sedentary',
|
|
vulnerable INTEGER NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS devices (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
room_id INTEGER NOT NULL REFERENCES rooms(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
device_type TEXT NOT NULL,
|
|
watts_idle REAL NOT NULL DEFAULT 0,
|
|
watts_typical REAL NOT NULL DEFAULT 0,
|
|
watts_peak REAL NOT NULL DEFAULT 0,
|
|
duty_cycle REAL NOT NULL DEFAULT 1.0,
|
|
schedule TEXT NOT NULL DEFAULT '{}',
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS ac_units (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
profile_id INTEGER NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
ac_type TEXT NOT NULL DEFAULT 'portable',
|
|
capacity_btu REAL NOT NULL,
|
|
has_dehumidify INTEGER NOT NULL DEFAULT 0,
|
|
efficiency_eer REAL NOT NULL DEFAULT 10.0,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS ac_room_assignments (
|
|
ac_id INTEGER NOT NULL REFERENCES ac_units(id) ON DELETE CASCADE,
|
|
room_id INTEGER NOT NULL REFERENCES rooms(id) ON DELETE CASCADE,
|
|
PRIMARY KEY (ac_id, room_id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS forecasts (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
profile_id INTEGER NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
|
|
timestamp TEXT NOT NULL,
|
|
temperature_c REAL,
|
|
humidity_pct REAL,
|
|
wind_speed_ms REAL,
|
|
cloud_cover_pct REAL,
|
|
precipitation_mm REAL,
|
|
sunshine_min REAL,
|
|
pressure_hpa REAL,
|
|
dew_point_c REAL,
|
|
apparent_temp_c REAL,
|
|
condition TEXT,
|
|
source TEXT NOT NULL,
|
|
fetched_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
UNIQUE(profile_id, timestamp, source)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS warnings (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
profile_id INTEGER NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
|
|
warning_id TEXT NOT NULL UNIQUE,
|
|
event_type TEXT,
|
|
severity TEXT,
|
|
headline TEXT,
|
|
description TEXT,
|
|
instruction TEXT,
|
|
onset TEXT,
|
|
expires TEXT,
|
|
fetched_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS toggles (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
profile_id INTEGER NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
active INTEGER NOT NULL DEFAULT 0,
|
|
activated_at TEXT
|
|
);
|