{# Capabilities: functions #} {% set caps = device.capabilities or {} %}

Functions (RPCs)

{% if caps.functions %}
{% for fn in caps.functions %}
{{ fn.name }}({% for pname, pspec in (fn.parameters.properties or {}).items() %}{{ pname }}{% if pspec.default is defined %}={{ pspec.default | tojson }}{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}) {% if fn.description %}

{{ fn.description }}

{% endif %}
{% endfor %}
{% else %}

No RPC functions registered

{% endif %}
{# Capabilities: events #}

Events

{% if caps.events %}
{% for ev in caps.events %}
{{ ev.name }} {% if ev.description %}

{{ ev.description }}

{% endif %}
{% endfor %}
{% else %}

No events registered

{% endif %}
{# Identity #} {% set ident = device._raw.identity or {} if device._raw else {} %}

Identity

{% for key in ['manufacturer', 'model', 'firmware_version', 'serial_number', 'arch'] %} {% if ident.get(key) %}
{{ key | replace('_', ' ') | title }}
{{ ident[key] }}
{% endif %} {% endfor %}
{# Invoke panel (shown by Try button) #} {# Event log panel (shown by Live log button). Lives inside the detail row so the log appears next to the device it's streaming from — important UX at 100s of devices. Safe to keep here because the JSON-poll architecture leaves the detail slot untouched on every 10s tick; the only way the slot gets re-fetched is a capability hash change, at which point the client closes any open stream before the refetch (the events list might have changed too). #} {# Collapsible raw JSON #}
Raw registration data
{{ device._raw | tojson_pretty }}