EV arrival hold: po detekci píchnutí okamžitě 0 A — nabíjení spouští až plán
TeltoCharge po připojení kabelu sám rozjede nabíjení svým defaultem; EMS ho dosud dohnal až exportem setpointů (do 15 min). _on_ev_arrival nyní před replanem zapíše přes journal telto_amps_to_use=0 (write_ev_arrival_hold), replan+export vzápětí nastaví plánované ampéry. Watchdog (300 s → failsafe 8 A) zachován — výpadek EMS auto nenechá na 0 A. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -128,6 +128,56 @@ async def write_ev_setpoints(
|
||||
return f"OK EV: {written}/{len(rows)} charger(s) written"
|
||||
|
||||
|
||||
async def write_ev_arrival_hold(
|
||||
site_id: int, charger_code: str, db: asyncpg.Connection
|
||||
) -> bool:
|
||||
"""Okamžitě po DETEKCI příjezdu zapsat 0 A na daný wallbox (přes journal).
|
||||
|
||||
TeltoCharge po připojení kabelu sám rozjede nabíjení svým defaultem —
|
||||
nabíjet smí až PLÁN (replan + export běží hned poté v _on_ev_arrival,
|
||||
takže držení trvá sekundy až ~1 min). Watchdog registry se zapíší spolu
|
||||
s 0 A (drop-unchanged je po prvním verified stejně přeskočí).
|
||||
"""
|
||||
from services.control.modbus_journal import (
|
||||
create_modbus_commands,
|
||||
execute_modbus_commands,
|
||||
)
|
||||
|
||||
row = await db.fetchrow(
|
||||
"""
|
||||
SELECT ec.id AS asset_id, ec.code, se.host, se.port, se.unit_id
|
||||
FROM ems.asset_ev_charger ec
|
||||
JOIN ems.site_endpoint se ON se.id = ec.endpoint_id
|
||||
WHERE ec.site_id = $1
|
||||
AND ec.code = $2
|
||||
AND ec.schedulable = true
|
||||
AND se.enabled = true
|
||||
AND se.endpoint_type = 'modbus_tcp'
|
||||
""",
|
||||
site_id,
|
||||
charger_code,
|
||||
)
|
||||
if row is None:
|
||||
return False
|
||||
cmd_ids = await create_modbus_commands(
|
||||
site_id,
|
||||
None,
|
||||
"ev_charger",
|
||||
int(row["asset_id"]),
|
||||
str(row["code"]),
|
||||
str(row["host"]),
|
||||
int(row["port"] or 502),
|
||||
int(row["unit_id"] if row["unit_id"] is not None else 1),
|
||||
_telto_setpoint_registers(0),
|
||||
db,
|
||||
)
|
||||
ok = await execute_modbus_commands(cmd_ids, db)
|
||||
logger.info(
|
||||
"EV arrival hold [%s]: 0 A %s", charger_code, "written" if ok else "FAILED"
|
||||
)
|
||||
return bool(ok)
|
||||
|
||||
|
||||
async def write_heat_pump_setpoint(
|
||||
site_id: int, setpoints: ControlSetpoints, db: asyncpg.Connection
|
||||
) -> str:
|
||||
|
||||
@@ -87,6 +87,17 @@ async def _on_ev_arrival(site_id: int, charger_code: str) -> None:
|
||||
from services.planning_engine import run_rolling_replan
|
||||
|
||||
async with _BG_POOL.acquire() as conn:
|
||||
# Wallbox po píchnutí sám rozjíždí nabíjení svým defaultem — držet
|
||||
# 0 A, dokud nerozhodne plán (export běží hned po replanu níže).
|
||||
try:
|
||||
from services.control.outputs import write_ev_arrival_hold
|
||||
|
||||
await write_ev_arrival_hold(site_id, charger_code, conn)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"EV arrival hold failed (site=%s, %s) — WB pojede defaultem do exportu",
|
||||
site_id, charger_code,
|
||||
)
|
||||
# Tesla: skutečné SoC do session PŘED replanem (selhání nesmí blokovat plán)
|
||||
try:
|
||||
await _patch_session_from_tesla(site_id, charger_code, conn)
|
||||
|
||||
Reference in New Issue
Block a user