Improve reactor controls, reactions, and maintenance UI
This commit is contained in:
@@ -9,6 +9,7 @@ from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from . import constants
|
||||
from .commands import ReactorCommand
|
||||
from .reactor import Reactor
|
||||
from .simulation import ReactorSimulation
|
||||
@@ -50,8 +51,12 @@ class ReactorDashboard:
|
||||
DashboardKey("o", "Toggle secondary pump"),
|
||||
DashboardKey("t", "Toggle turbine"),
|
||||
DashboardKey("1/2/3", "Toggle turbine units 1-3"),
|
||||
DashboardKey("y/u/i", "Maintain turbine 1/2/3"),
|
||||
DashboardKey("c", "Toggle consumer"),
|
||||
DashboardKey("r", "Reset & clear state"),
|
||||
DashboardKey("m", "Maintain primary pump"),
|
||||
DashboardKey("n", "Maintain secondary pump"),
|
||||
DashboardKey("k", "Maintain core (requires shutdown)"),
|
||||
DashboardKey("+/-", "Withdraw/insert rods"),
|
||||
DashboardKey("[/]", "Adjust consumer demand −/+50 MW"),
|
||||
DashboardKey("s", "Setpoint −250 MW"),
|
||||
@@ -142,6 +147,18 @@ class ReactorDashboard:
|
||||
self._queue_command(ReactorCommand(power_setpoint=self.reactor.control.setpoint_mw + 250.0))
|
||||
elif ch in (ord("a"), ord("A")):
|
||||
self._queue_command(ReactorCommand(rod_manual=not self.reactor.control.manual_control))
|
||||
elif ch in (ord("m"), ord("M")):
|
||||
self._queue_command(ReactorCommand.maintain("primary_pump"))
|
||||
elif ch in (ord("n"), ord("N")):
|
||||
self._queue_command(ReactorCommand.maintain("secondary_pump"))
|
||||
elif ch in (ord("k"), ord("K")):
|
||||
self._queue_command(ReactorCommand.maintain("core"))
|
||||
elif ch in (ord("y"), ord("Y")):
|
||||
self._queue_command(ReactorCommand.maintain("turbine_1"))
|
||||
elif ch in (ord("u"), ord("U")):
|
||||
self._queue_command(ReactorCommand.maintain("turbine_2"))
|
||||
elif ch in (ord("i"), ord("I")):
|
||||
self._queue_command(ReactorCommand.maintain("turbine_3"))
|
||||
|
||||
def _queue_command(self, command: ReactorCommand) -> None:
|
||||
if self.pending_command is None:
|
||||
@@ -240,10 +257,12 @@ class ReactorDashboard:
|
||||
("Core Power", f"{state.core.power_output_mw:8.1f} MW"),
|
||||
("Neutron Flux", f"{state.core.neutron_flux:10.2e}"),
|
||||
("Rods", f"{self.reactor.control.rod_fraction:.3f}"),
|
||||
("Rod Mode", "AUTO" if not self.reactor.control.manual_control else "MANUAL"),
|
||||
("Setpoint", f"{self.reactor.control.setpoint_mw:7.0f} MW"),
|
||||
("Reactivity", f"{state.core.reactivity_margin:+.4f}"),
|
||||
],
|
||||
)
|
||||
y = self._draw_section(win, y, "Key Poisons / Emitters", self._poison_lines(state))
|
||||
y = self._draw_section(
|
||||
win,
|
||||
y,
|
||||
@@ -300,6 +319,7 @@ class ReactorDashboard:
|
||||
"Start pumps before withdrawing rods.",
|
||||
"Bring turbine and consumer online after thermal stabilization.",
|
||||
"Toggle turbine units (1/2/3) for staggered maintenance.",
|
||||
"Use m/n/k/y/u/i to request maintenance (stop equipment first).",
|
||||
"Press 'r' to reset/clear state if you want a cold start.",
|
||||
"Watch component health to avoid automatic trips.",
|
||||
]
|
||||
@@ -370,6 +390,24 @@ class ReactorDashboard:
|
||||
def _total_load_demand(self, state: PlantState) -> float:
|
||||
return sum(t.load_demand_mw for t in state.turbines)
|
||||
|
||||
def _poison_lines(self, state: PlantState) -> list[tuple[str, str]]:
|
||||
inventory = state.core.fission_product_inventory or {}
|
||||
particles = state.core.emitted_particles or {}
|
||||
lines: list[tuple[str, str]] = []
|
||||
def fmt(symbol: str, label: str) -> tuple[str, str]:
|
||||
qty = inventory.get(symbol, 0.0)
|
||||
threshold = constants.KEY_POISON_THRESHOLDS.get(symbol)
|
||||
flag = " !" if threshold is not None and qty >= threshold else ""
|
||||
return (f"{label}{flag}", f"{qty:9.2e}")
|
||||
|
||||
lines.append(fmt("Xe", "Xe (xenon)"))
|
||||
lines.append(fmt("Sm", "Sm (samarium)"))
|
||||
lines.append(fmt("I", "I (iodine)"))
|
||||
lines.append(("Neutrons (src)", f"{particles.get('n', 0.0):9.2e}"))
|
||||
lines.append(("Gammas", f"{particles.get('gamma', 0.0):9.2e}"))
|
||||
lines.append(("Alphas", f"{particles.get('alpha', 0.0):9.2e}"))
|
||||
return lines
|
||||
|
||||
def _draw_health_bar(self, win: "curses._CursesWindow", start_y: int) -> None:
|
||||
height, width = win.getmaxyx()
|
||||
if start_y >= height - 2:
|
||||
|
||||
Reference in New Issue
Block a user