-- ============================================================= -- V006__vehicles.sql -- EMS Platform – vozidla a EV session tracking -- ============================================================= -- ============================================================ -- Vozidla -- ============================================================ CREATE TABLE ems.asset_vehicle ( id SERIAL PRIMARY KEY, site_id INT NOT NULL REFERENCES ems.site(id), code TEXT NOT NULL, name TEXT, make TEXT, -- 'Tesla', 'Renault' model TEXT, -- 'Model Y', 'Zoe R135' battery_capacity_kwh NUMERIC(6,2) NOT NULL, -- kapacita trakční baterie max_charge_power_w INT NOT NULL, -- max přijímaný AC výkon vozidla default_charger_id INT REFERENCES ems.asset_ev_charger(id), api_type TEXT NOT NULL DEFAULT 'none', -- 'tesla', 'none' api_reference TEXT, -- klíč do env/secrets pro API default_target_soc_pct NUMERIC(5,2) NOT NULL DEFAULT 80, default_deadline_hour INT NOT NULL DEFAULT 7, -- hodina rána active BOOLEAN NOT NULL DEFAULT true, UNIQUE (site_id, code) ); COMMENT ON TABLE ems.asset_vehicle IS 'Vozidla registrovaná v EMS. Každé vozidlo má výchozí cílový SoC a deadline pro plánování nabíjení.'; COMMENT ON COLUMN ems.asset_vehicle.battery_capacity_kwh IS 'Celková kapacita trakční baterie vozidla v kWh. Tesla Model Y ~75 kWh, Renault Zoe R135 ~52 kWh.'; COMMENT ON COLUMN ems.asset_vehicle.max_charge_power_w IS 'Maximální výkon který vozidlo přijme přes AC nabíjení. Může být nižší než výkon WB. Tesla MY ~11 000 W, Zoe R135 ~7 400 W.'; COMMENT ON COLUMN ems.asset_vehicle.api_type IS 'Typ API pro čtení stavu vozidla. tesla = Tesla API (Tessie nebo přímé), none = žádné API.'; COMMENT ON COLUMN ems.asset_vehicle.api_reference IS 'Název env proměnné nebo klíče v secrets kde je uložen API token/přihlášení. Např. TESLA_MY_TOKEN.'; COMMENT ON COLUMN ems.asset_vehicle.default_target_soc_pct IS 'Výchozí cílový SoC pro deadline charging. Uživatel může přepsat v UI před odjezdem.'; COMMENT ON COLUMN ems.asset_vehicle.default_deadline_hour IS 'Výchozí hodina rána do které musí být dosažen target SoC. 7 = 07:00.'; -- ============================================================ -- EV session tracking -- ============================================================ CREATE TABLE ems.ev_session ( id SERIAL PRIMARY KEY, site_id INT NOT NULL REFERENCES ems.site(id), charger_id INT NOT NULL REFERENCES ems.asset_ev_charger(id), vehicle_id INT REFERENCES ems.asset_vehicle(id), -- NULL pokud neznámé vozidlo session_start TIMESTAMPTZ NOT NULL DEFAULT now(), session_end TIMESTAMPTZ, -- Stav při připojení (pokud znám) soc_at_connect_pct NUMERIC(5,2), -- Deadline požadavek target_soc_pct NUMERIC(5,2), target_deadline TIMESTAMPTZ, -- Průběžný stav (aktualizován z telemetrie) energy_delivered_wh NUMERIC(12,3) NOT NULL DEFAULT 0, last_power_w INT, -- Výsledek při odpojení soc_at_disconnect_pct NUMERIC(5,2), total_cost_czk NUMERIC(10,4), deadline_met BOOLEAN, -- byl deadline splněn? -- Metadata created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); COMMENT ON TABLE ems.ev_session IS 'Záznamy jednotlivých nabíjecích sessions EV. Session začíná připojením (status != available na WB) a končí odpojením.'; COMMENT ON COLUMN ems.ev_session.vehicle_id IS 'Identifikace vozidla. Může být NULL pokud EMS neví které auto je připojeno (Zoe nemá API).'; COMMENT ON COLUMN ems.ev_session.soc_at_connect_pct IS 'SoC baterie vozidla při připojení. Pro Tesla čteno z API, pro Zoe NULL (neznáme).'; COMMENT ON COLUMN ems.ev_session.target_soc_pct IS 'Cílový SoC pro tuto session. Výchozí z asset_vehicle.default_target_soc_pct, uživatel může změnit v UI.'; COMMENT ON COLUMN ems.ev_session.target_deadline IS 'Deadline pro dosažení target_soc_pct. Výchozí = dnešní/zítřejší default_deadline_hour.'; COMMENT ON COLUMN ems.ev_session.energy_delivered_wh IS 'Kumulativní energie dodaná v této session v Wh. Čteno z WB Modbus (kWh counter). Slouží i pro odhad SoC u Zoe.'; COMMENT ON COLUMN ems.ev_session.deadline_met IS 'True pokud byl target_soc_pct dosažen před target_deadline. NULL pokud session ještě probíhá.'; -- Hypertable pro session log (sessions jsou časová série) -- Poznámka: ev_session není hypertable – sessions jsou krátké záznamy, ne telemetrie. -- Index pro rychlé dotazy na aktivní session CREATE INDEX idx_ev_session_active ON ems.ev_session (charger_id, session_end) WHERE session_end IS NULL; CREATE INDEX idx_ev_session_site_time ON ems.ev_session (site_id, session_start DESC); -- ============================================================ -- Seed – vozidla home-01 -- ============================================================ INSERT INTO ems.asset_vehicle (site_id, code, name, make, model, battery_capacity_kwh, max_charge_power_w, default_charger_id, api_type, default_target_soc_pct, default_deadline_hour) SELECT s.id, 'tesla-my', 'Tesla Model Y', 'Tesla', 'Model Y', 75.0, 11000, -- Tesla MY AC max ~11kW (3fáze × 16A × 230V) ch1.id, 'none', -- Tesla API fáze 2, zatím none 80, -- 80% výchozí target – Tesla má velkou baterii 7 -- do 7:00 ráno FROM ems.site s JOIN ems.asset_ev_charger ch1 ON ch1.site_id = s.id AND ch1.code = 'ev-charger-1' WHERE s.code = 'home-01'; INSERT INTO ems.asset_vehicle (site_id, code, name, make, model, battery_capacity_kwh, max_charge_power_w, default_charger_id, api_type, default_target_soc_pct, default_deadline_hour) SELECT s.id, 'zoe-r135', 'Renault Zoe R135', 'Renault', 'Zoe R135', 52.0, 7400, -- Zoe R135 max 7.4kW AC (jednofáze 32A nebo 3fáze nižší) ch2.id, 'none', -- Zoe nemá API 90, -- 90% výchozí target – Zoe má menší baterii, kritičtější 7 FROM ems.site s JOIN ems.asset_ev_charger ch2 ON ch2.site_id = s.id AND ch2.code = 'ev-charger-2' WHERE s.code = 'home-01';