{{ _('OCPP Server Monitor') }}

{{ _('Überwachen Sie den OCPP-Server (API-Port) in Echtzeit. Timeouts: %(seconds)s s pro Endpoint. Bei nicht erreichbarer API wird eine klare Fehlermeldung angezeigt.', seconds=timeout_seconds) }}

{{ _('API-Basis') }}
{{ api_base or _('Offline') }}
{% if api_error %}
{{ api_error }}
{% endif %}
{{ _('Timeout: %(seconds)s s', seconds=timeout_seconds) }} {% if window_minutes is not none %} {{ _('Log-Fenster: %(minutes)s Minuten', minutes=window_minutes) }} {% endif %} {% if liveness_threshold is not none %} {{ _('Timeout-Warnschwelle: %(seconds)s s', seconds=liveness_threshold) }} {% endif %}
{% if api_unreachable %} {% endif %}
{{ _('Verbindungen & FDs') }}
{{ _('WebSocket & FD-Metriken') }}
{% set ws_error = endpoint_results['websocket_counts']['error'] %} {{ ws_error and _('Offline') or _('Online') }}
{% if ws_error %}

{{ ws_error }}

{% else %}
{{ _('Aktive Verbindungen') }} {{ connection_metrics.get('active', 0) }}
{{ _('Verfolgte Einträge') }} {{ connection_metrics.get('tracked_entries', 0) }}
{{ _('Open FDs') }} {{ fd_metrics.get('open_fds') if fd_metrics.get('open_fds') is not none else '–' }}
{{ _('FD-Limit') }} {{ fd_metrics.get('fd_soft_limit') if fd_metrics.get('fd_soft_limit') is not none else '–' }}
{{ _('FD-Auslastung') }} {% if derived.fd_usage_ratio is not none %} {{ (derived.fd_usage_ratio * 100) | round(2) }}% {% else %} – {% endif %}
{% endif %}
{{ _('DB-Pool') }}
{{ _('Größen & freie Slots') }}
{% set db_error = endpoint_results['db_pool_status']['error'] %} {{ db_error and _('Offline') or _('Online') }}
{% if db_error %}

{{ db_error }}

{% else %}
{{ _('Pool-Typ') }} {{ db_pool_status.get('pool_type') or '–' }}
{{ _('Max Slots') }} {{ derived.db_max_slots if derived.db_max_slots is not none else '–' }}
{{ _('Belegt') }} {% if derived.db_used is not none %} {{ derived.db_used }}{% if derived.db_usage_ratio is not none %} ({{ (derived.db_usage_ratio * 100) | round(1) }}%){% endif %} {% else %}–{% endif %}
{{ _('Frei') }} {{ derived.db_free_slots if derived.db_free_slots is not none else '–' }}
{{ _('Min/Max') }} {% if db_pool_status.get('minsize') is not none or db_pool_status.get('maxsize') is not none %} {{ db_pool_status.get('minsize') or '–' }} / {{ db_pool_status.get('maxsize') or '–' }} {% else %} – / – {% endif %}
{% endif %}
{{ _('Log-Queue') }}
{{ _('Füllstand & Drops') }}
{% set log_error = endpoint_results['log_queue_metrics']['error'] %} {{ log_error and _('Offline') or _('Online') }}
{% if log_error %}

{{ log_error }}

{% else %}
{{ _('Größe') }} {{ log_queue_metrics.get('size', 0) }} / {{ log_queue_metrics.get('maxsize') or '∞' }}
{{ _('Füllgrad') }} {% if derived.log_fill_ratio is not none %} {{ (derived.log_fill_ratio * 100) | round(1) }}% {% else %}–{% endif %}
{{ _('Drops gesamt') }} {{ log_queue_metrics.get('drop_count', 0) }}
{{ _('Drops (%(minutes)s min)', minutes=(derived.log_window or log_queue_metrics.get('recent_window_minutes') or '–')) }} {{ derived.log_drop_recent if derived.log_drop_recent is not none else '–' }}
{{ _('Letzter Drop') }} {{ log_queue_metrics.get('last_drop_at') or '–' }}
{% endif %}
{{ _('Action-Metriken') }}
{{ _('Erfolgs- & Fehlerzahlen inkl. P95') }}
{% set action_error = endpoint_results['action_metrics']['error'] %} {{ action_error and _('Offline') or _('Online') }}
{% if action_error %}

{{ action_error }}

{% else %} {% if action_warnings %}
{{ _('Warnungen:') }}
    {% for warn in action_warnings %}
  • {{ warn.action }} – {{ warn.code }} ({{ warn.count }})
  • {% endfor %}
{% endif %}
{% if action_metrics %} {% for name, metric in action_metrics.items() %} {% endfor %} {% else %} {% endif %}
{{ _('Action') }} {{ _('Success') }} {{ _('Errors') }} {{ _('Avg (ms)') }} {{ _('P95 (ms)') }}
{{ name }} {{ metric.get('success', 0) }} {{ metric.get('call_errors', 0) }} {{ metric.get('avg_ms') | round(2) if metric.get('avg_ms') is not none else '–' }} {{ metric.get('p95_ms') | round(2) if metric.get('p95_ms') is not none else '–' }}
{{ _('Keine Action-Metriken verfügbar.') }}
{% endif %}
{{ _('Stations-Liveness') }}
{{ _('Risiken & verbleibende Zeit') }}
{% set live_error = endpoint_results['station_liveness']['error'] %} {{ live_error and _('Offline') or _('Online') }}
{% if live_error %}

{{ live_error }}

{% else %}
{{ _('Stations: %(count)s', count=liveness_entries | length) }} {{ _('At Risk: %(count)s', count=derived.risk_entries | length) }}
{% if liveness_entries %} {% for entry in liveness_entries %} {% endfor %} {% else %} {% endif %}
{{ _('Station') }} {{ _('Last Seen') }} {{ _('Seconds until Timeout') }}
{{ entry.station_id }} {{ entry.last_seen or '–' }} {{ entry.seconds_until_timeout if entry.seconds_until_timeout is not none else '–' }}
{{ _('Keine Live-Daten verfügbar.') }}
{% endif %}
{{ _('Station Snapshot') }}
{{ _('/api/connected_stations') }}
{% set connected_error = endpoint_results['connected_stations']['error'] %} {{ connected_error and _('Offline') or _('Online') }}
{% if connected_error %}

{{ connected_error }}

{% else %}
{% set stations = connected_snapshot.get('stations', []) %} {% if stations %} {% for station in stations %} {% endfor %} {% else %} {% endif %}
{{ _('Station') }} {{ _('Connected since') }} {{ _('Last seen') }}
{{ station.station_id }} {{ station.connected_since or '–' }} {{ station.last_seen or '–' }}
{{ _('Keine verbundenen Stationen.') }}
{% endif %}