fix: params page cfg=None + hot-reload config chaque jour
dashboard/app.py:
load_sim_config() retourne None (pas {}) quand le fichier est absent
— {} est falsy en Python, masquait le formulaire même quand la config
était chargeable mais vide. None est explicitement distinguable.
load_all_modes() charge toujours depuis sim_001.json (référence 5 modes)
— sim_002 n'a qu'un seul mode dans son bloc 'modes', le tableau comparatif
était vide pour S2.
{% if cfg is not none %} dans le template au lieu de {% if cfg %}
Message d'avertissement sous le bouton save : prise en compte au prochain jour
Message d'erreur précis si fichier introuvable (path + hint mount Docker)
/params/save: vérification if cfg is None
run.py:
Hot-reload config à chaque tick==0 (frontière de jour) :
cfg.load(config_path, session_id=SESSION_ID)
effective_mode mis à jour depuis la config rechargée
tick_sleep recalculé (TICK_SLEEP_SEC env var prime toujours)
→ Changer mode/drain/encounter via dashboard prend effet le jour suivant
sans redémarrer le process
This commit is contained in:
+25
-8
@@ -47,13 +47,21 @@ def execute(sql, params=None):
|
|||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
def load_sim_config(session_id: int) -> dict:
|
_REFERENCE_CONFIG_ID = 1 # sim_001.json = référence pour la liste des modes
|
||||||
|
|
||||||
|
def load_sim_config(session_id: int) -> dict | None:
|
||||||
|
"""Retourne le cfg JSON ou None si introuvable (None est falsy ET distinguable de {})."""
|
||||||
path = os.path.join(SIM_CONFIGS_DIR, f"sim_{session_id:03d}.json")
|
path = os.path.join(SIM_CONFIGS_DIR, f"sim_{session_id:03d}.json")
|
||||||
try:
|
try:
|
||||||
with open(path) as f:
|
with open(path) as f:
|
||||||
return json.load(f)
|
return json.load(f)
|
||||||
except Exception:
|
except Exception as e:
|
||||||
return {}
|
return None
|
||||||
|
|
||||||
|
def load_all_modes() -> dict:
|
||||||
|
"""Charge les modes depuis sim_001.json (référence complète des 5 modes)."""
|
||||||
|
cfg = load_sim_config(_REFERENCE_CONFIG_ID) or {}
|
||||||
|
return cfg.get("modes", {})
|
||||||
|
|
||||||
def save_sim_config(session_id: int, cfg: dict):
|
def save_sim_config(session_id: int, cfg: dict):
|
||||||
path = os.path.join(SIM_CONFIGS_DIR, f"sim_{session_id:03d}.json")
|
path = os.path.join(SIM_CONFIGS_DIR, f"sim_{session_id:03d}.json")
|
||||||
@@ -407,7 +415,7 @@ if (el) {
|
|||||||
<div class="panel">
|
<div class="panel">
|
||||||
<h2>⚙ CONFIG SIM_{{ '%03d' % current_sid }}.JSON</h2>
|
<h2>⚙ CONFIG SIM_{{ '%03d' % current_sid }}.JSON</h2>
|
||||||
<form method="POST" action="/params/save?sid={{ current_sid }}">
|
<form method="POST" action="/params/save?sid={{ current_sid }}">
|
||||||
{% if cfg %}
|
{% if cfg is not none %}
|
||||||
|
|
||||||
<div class="cfg-block">
|
<div class="cfg-block">
|
||||||
<h3>GÉNÉRAL</h3>
|
<h3>GÉNÉRAL</h3>
|
||||||
@@ -466,8 +474,17 @@ if (el) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-green">💾 SAUVEGARDER CONFIG</button>
|
<button type="submit" class="btn btn-green">💾 SAUVEGARDER CONFIG</button>
|
||||||
|
<p style="margin-top:6px;font-size:10px;color:#555">
|
||||||
|
⚠ Prise en compte au prochain jour (J{{ (session.current_day or 0) + 1 }}).
|
||||||
|
Pour effet immédiat : STOP → relancer via terminal.
|
||||||
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p style="color:#ff4444;font-size:11px">Fichier sim_{{ '%03d' % current_sid }}.json introuvable dans {{ sim_configs_dir }}</p>
|
<p style="color:#ff4444;font-size:11px">
|
||||||
|
Fichier <code>sim_{{ '%03d' % current_sid }}.json</code> introuvable dans <code>{{ sim_configs_dir }}</code>
|
||||||
|
</p>
|
||||||
|
<p style="color:#555;font-size:10px;margin-top:4px">
|
||||||
|
Vérifier le mount Docker : /home/ubuntu/fallout-venice/src/config → /app/src/config
|
||||||
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -673,7 +690,7 @@ def params():
|
|||||||
sid = int(request.args.get("sid", all_sessions[-1]["id"] if all_sessions else 1))
|
sid = int(request.args.get("sid", all_sessions[-1]["id"] if all_sessions else 1))
|
||||||
session = query_one("SELECT * FROM sessions WHERE id = %s", (sid,))
|
session = query_one("SELECT * FROM sessions WHERE id = %s", (sid,))
|
||||||
cfg = load_sim_config(sid)
|
cfg = load_sim_config(sid)
|
||||||
modes = cfg.get("modes", {})
|
modes = load_all_modes() # toujours les 5 modes depuis sim_001 (référence)
|
||||||
flash_msg = request.args.get("msg")
|
flash_msg = request.args.get("msg")
|
||||||
flash_ok = request.args.get("ok", "1") == "1"
|
flash_ok = request.args.get("ok", "1") == "1"
|
||||||
return render_template_string(TEMPLATE,
|
return render_template_string(TEMPLATE,
|
||||||
@@ -697,8 +714,8 @@ def params():
|
|||||||
def params_save():
|
def params_save():
|
||||||
sid = int(request.args.get("sid", 1))
|
sid = int(request.args.get("sid", 1))
|
||||||
cfg = load_sim_config(sid)
|
cfg = load_sim_config(sid)
|
||||||
if not cfg:
|
if cfg is None:
|
||||||
return redirect(url_for("params", sid=sid, msg="Fichier config introuvable", ok=0))
|
return redirect(url_for("params", sid=sid, msg=f"Fichier sim_{sid:03d}.json introuvable dans {SIM_CONFIGS_DIR}", ok=0))
|
||||||
|
|
||||||
f = request.form
|
f = request.form
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -77,8 +77,12 @@ def run(config_path: str | None = None):
|
|||||||
|
|
||||||
day, current_tick = tick_engine.next_tick(day, current_tick)
|
day, current_tick = tick_engine.next_tick(day, current_tick)
|
||||||
|
|
||||||
# Réinit world_state au début de chaque nouveau jour
|
# Début d'un nouveau jour : hot-reload config depuis le JSON (permet les changements dashboard)
|
||||||
if current_tick == 0:
|
if current_tick == 0:
|
||||||
|
cfg.load(config_path, session_id=SESSION_ID)
|
||||||
|
effective_mode = cfg.mode() or db_mode
|
||||||
|
tick_sleep = float(os.getenv("TICK_SLEEP_SEC",
|
||||||
|
cfg.get("tick", {}).get("tick_sleep_sec", tick_sleep)))
|
||||||
_init_world_state(SESSION_ID, day)
|
_init_world_state(SESSION_ID, day)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|||||||
Reference in New Issue
Block a user