-- Modbus command journal + cut-off switch audit (EMS)

CREATE TABLE ems.modbus_command (
    id              SERIAL PRIMARY KEY,
    site_id         INT  NOT NULL REFERENCES ems.site(id),
    asset_type      TEXT NOT NULL,  -- 'inverter', 'ev_charger', 'heat_pump', 'cutoff'
    asset_id        INT  NOT NULL,  -- ID v příslušné asset tabulce
    asset_code      TEXT NOT NULL,  -- např. 'deye-main' (denorm. pro čitelnost)
    device_host     TEXT NOT NULL,
    device_port     INT  NOT NULL,
    device_unit_id  INT  NOT NULL,
    register        INT  NOT NULL,  -- číslo registru (decimal)
    register_name   TEXT,           -- 'export_limit', 'charge_limit' (pro čitelnost)
    value_to_write  INT  NOT NULL,
    value_written   INT,            -- skutečně zapsaná hodnota (NULL = nezapsáno)
    value_verified  INT,            -- přečtená hodnota po verifikaci (NULL = neověřeno)
    status          TEXT NOT NULL DEFAULT 'pending',
                    -- 'pending', 'written', 'verified', 'failed', 'mismatch', 'retrying'
    planning_run_id INT REFERENCES ems.planning_run(id),
    attempt_count   INT NOT NULL DEFAULT 0,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    written_at      TIMESTAMPTZ,
    verified_at     TIMESTAMPTZ,
    error_msg       TEXT
);

COMMENT ON TABLE ems.modbus_command IS
'Command journal pro Modbus zápisy do zařízení.
Každý zápis = jeden řádek. Verifikační job ověří value_verified == value_to_write.
Při mismatch: retry max 3× → přepnout na SELF_SUSTAIN + Discord alert.
asset_type+asset_id odkazuje na příslušnou asset tabulku (inverter/ev_charger/...).';

CREATE INDEX idx_modbus_command_status
    ON ems.modbus_command (site_id, status, created_at DESC);

CREATE INDEX idx_modbus_command_pending
    ON ems.modbus_command (status, created_at)
    WHERE status IN ('pending', 'retrying');

CREATE TABLE ems.cutoff_switch_log (
    id           SERIAL PRIMARY KEY,
    site_id      INT  NOT NULL REFERENCES ems.site(id),
    asset_code   TEXT NOT NULL,      -- 'cutoff-pv-b', 'cutoff-microinverter'
    switched_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    new_state    BOOLEAN NOT NULL,   -- true=zapnuto/připojeno, false=odpojeno
    previous_state BOOLEAN,
    reason       TEXT NOT NULL,      -- 'negative_sell_price', 'manual', 'auto_restore'
    sell_price_czk NUMERIC(10,6),    -- spotová cena v době přepnutí
    triggered_by TEXT                -- 'control_exporter', 'user:jan', 'system'
);

COMMENT ON TABLE ems.cutoff_switch_log IS
'Log přepnutí cut-off přepínačů. Loguje se jen při změně stavu (edge trigger).
Používá se pro mikroinvertory na GEN portu při záporných prodejních cenách.';
