Files
ems/db/migration/V006__vehicles.sql
Dusan Vojacek 8b4af663d8 Initial commit
Made-with: Cursor
2026-03-20 13:27:44 +01:00

120 lines
6.5 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =============================================================
-- 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';