{% extends "base.html" %} {% block title %}Home{% endblock %} {% block content %}

{{ connection.name }} ({{ connection.prefix }})

{% if load_notice %}
{{ load_notice }}
{% endif %}

Active connection

Prefix
{{ connection.prefix }}
Driver
{{ connection.__class__.__module__ }}
Topics served
{{ topics|length }}
Railroad
{{ railroad }}
{# Command Station power — is the CS itself powered / talking to us? Distinct from Track Power (the DCC signal on the rails, whose full ON/OFF/IDLE control lives in the card below). This is a strict bool: On when the driver's connection is open, Off otherwise. #}
Command Station Power
{% if command_station_on %}On{% else %}Off{% endif %}

To pick a different driver at startup, open the PMRI launcher, switch to the Startup Options tab, choose the desired default connection, then restart the web service from the launcher's Service tab.

Profiles

{% if settings_root %}

Reading from {{ settings_root }}

{% endif %} {% if profile_error %}
Profile operation failed: {{ profile_error }}
{% endif %} {% if profiles %}

Active profile determines which PanelPro.xml, roster.xml, and per-loco data the server uses. Switching clears the in-memory bean tables and repopulates them from the new profile.

{# Profile CRUD. Create appends a new profile to profiles.xml + mints an empty PanelPro.xml. Delete unregisters but leaves the on-disk directory alone (so an accidental click through the UI isn't data-destructive). The active profile can't be deleted; switch first with the picker above. #}

Manage profiles

Name must be filesystem-safe (no spaces, slashes, or colons). A directory of that name is created under the settings root with an empty PanelPro.xml — populate it via the picker above or the copy-beans widget below.

{% for p in profiles %} {% endfor %}
NameId
{{ p.name }}{% if p.id == active_profile_id %} active{% endif %} {{ p.id }} {% if p.id != active_profile_id %}
{% else %} can't delete the active profile {% endif %}
{# Cross-profile bean import. Backed by the ``beanTransfer`` JSON service. Preview shows per-type counts + how many rows would be overwritten in the target; Apply performs the upsert and, when the target is the active profile, re-populates the live bean managers so the change is visible immediately. #}

Copy beans between profiles

Turnouts / sensors / lights are upserted by system name; roster entries are upserted by id. Same-named rows in the target are overwritten; unrelated rows are left alone. A roster copy into the active profile also broadcasts the new RL to any connected WiThrottle client.

{% else %}

No profiles.xml found at the settings path above. Either copy your JMRI profiles.xml + profile directories there, or set the JMRI_SETTINGS_DIR environment variable to point at where they live (e.g. JMRI_SETTINGS_DIR=/mnt/jmri) and restart the server.

{% endif %}
{% include "_fast_clock.html" %}
{% include "_power_panel.html" %}

Recent log lines

{% include "_log_tail.html" %}

Topics available on the JSON API

Click a topic to expand its help panel — summary, available methods, and a request/response example. Full class + method reference is at /docs/.

{% for t in topics %}
{{ t.topic }} {% if t.help and t.help.rewrite_extension %} rewrite {% endif %} {% if t.help %} {{ t.help.summary.split(".")[0] }}. {% else %} (no help authored yet) {% endif %} {% if t.help %}

{{ t.help.summary }}

{% if t.help.methods %} {% for m in t.help.methods %} {% endfor %}
MethodWhat it does
{{ m.name }} {{ m.description }} {% if m.example_request %}
example

request

{{ m.example_request }}
{% if m.example_response %}

response

{{ m.example_response }}
{% endif %}
{% endif %}
{% endif %} {% if t.help.source %}

Source: {{ t.help.source }}

{% endif %}
{% endif %}
{% endfor %}
{# CS-power badge. Server renders the initial state on every /home GET; the jmri-server PushManager pushes ``{type: "commandStationPower", data: {on: bool}}`` on every heartbeat-detected transition, and the JS below mirrors it into the badge without a full page reload. ``app.js`` is loaded with ``defer`` in the head — that means it runs AFTER the DOM is parsed, which is AFTER this inline {% endblock %}