This is a template ability that reports live telemetry from an OpenHome DevKit by voice — CPU, memory, temperature, uptime, Wi-Fi, disk, overall health, or a full snapshot. You ask in plain language; the LLM routes your request to exactly one telemetry function, the DevKit reads the metric locally, and the agent speaks a concise answer.
The cloud side (main.py) handles intent routing and the conversation loop; the device side (devkit_functions.py) runs on the DevKit and reads real system values from /proc, /sys, and standard tools. The two sides talk through send_devkit_capability_action().
⚠️ Local abilities cannot be tested in the Live Editor. They run on a connected DevKit device.
- Voice system monitor — "what's my CPU?", "how hot is it?"
- Health check assistant — "is anything wrong?" → flags high temp, low memory, full disk
- Uptime / status reporter — "how long has it been running?"
- Network status check — "am I on Wi-Fi?" / "what network am I on?"
- One-shot snapshot — "give me everything" → a spoken summary of all key metrics
- Foundation for hardware dashboards — extend the registry with your own metrics
| Function | Reports |
|---|---|
get_cpu |
CPU usage (used / free percent) |
get_memory |
Memory used / total / available (GB) |
get_temperature |
Device temperature (°C) and a status word |
get_uptime |
How long the device has been running |
get_wifi |
Wi-Fi connection and SSID |
get_disk |
Disk used percent and free space |
get_health |
Overall health — flags high temp, low memory, full disk |
get_all_stats |
A spoken snapshot of all key metrics |
- An OpenHome DevKit (Linux device) running the device-side bridge.
- A Linux environment exposing
/proc/stat,/proc/meminfo,/proc/uptime, and/sys/class/thermal/thermal_zone0/temp. iwgetidavailable for Wi-Fi SSID lookup (optional — degrades gracefully).- No API keys and no external services — everything is read locally on the device.
- Get the template from the OpenHome dashboard or GitHub and add it to your agent.
- Configure trigger words in the dashboard.
- Power on the DevKit, connect it to your agent, and say a trigger word.
This template uses generic triggers — customize these for your ability:
- "device stats" / "system status" / "check the DevKit"
- Configure your own trigger words in the OpenHome dashboard.
- User asks about device status
- The LLM routes the request to one telemetry function (or
none/exit) - On the first turn, an unmatched request defaults to
get_all_stats - The DevKit reads the metric and returns a structured result
- The agent speaks the result, then asks if you want anything else
- The loop continues until you say an exit phrase ("stop", "done", "thanks", "bye", …)
- The conversation runs in a loop; the first turn uses
wait_for_complete_transcription(), later turns useuser_response() _route_to_devkit_function()callstext_to_text_response()with a strict routingSYSTEM_PROMPTthat returns a single JSON object:{"function_name": "<name | none | exit>"}- The chosen function is dispatched to the device:
result = await self.capability_worker.send_devkit_capability_action(
function_name=function_name,
args=[],
timeout=8,
)_spoken_response_from_result()validates the result and returns the device'sspoken_response- Unsupported requests get a helpful prompt; the loop ends cleanly on
exit
Each function reads a real metric and emits a structured JSON payload on stdout:
{ "success": true, "metric": "cpu", "spoken_response": "CPU is 12 percent used and 88 percent free.", "data": { ... }, "error": null }- CPU — samples
/proc/stattwice and computes usage over the interval - Memory — parses
MemTotal/MemAvailablefrom/proc/meminfo - Temperature — reads
/sys/class/thermal/thermal_zone0/tempand maps it to a status word - Uptime — reads
/proc/uptimeand formats days/hours/minutes - Wi-Fi — runs
iwgetid -rfor the SSID - Disk — uses
shutil.disk_usage("/") - Health — combines temp, memory, and disk into a list of issues
- All stats — gathers everything into one spoken snapshot
A central dispatcher (main() + FUNCTION_REGISTRY) routes the function name and emits a structured error for missing/unknown functions, bad arguments, or unexpected failures.
Dispatches a telemetry function name (with empty args) to the device and waits up to 8 seconds for the JSON result.
Maps each metric name to its reader function. This is the extension point — add a new reader and register it here, then add it to AVAILABLE_STATS and the routing rules in main.py.
User: "what's my CPU at?" → AI: "CPU is 12 percent used and 88 percent free."
User: "how hot is it?" → AI: "DevKit temperature is 47.2 degrees Celsius and running cool."
User: "is anything wrong?" → AI: "The DevKit looks healthy."
User: "give me everything" → AI: "DevKit snapshot: temperature is 47.2 degrees Celsius, CPU is 12 percent used, memory has 5.1 gigabytes available, disk is 38 percent used, Wi-Fi is connected to HomeNet."
User: "that's all, thanks" → AI: "Exiting DevKit stats." (ability exits)
Write a reader in devkit_functions.py that calls _emit_success / _emit_error, register it in FUNCTION_REGISTRY, then add it to AVAILABLE_STATS and the routing rules in SYSTEM_PROMPT.
Edit _temperature_status() bands and the health checks in get_health() (temperature ≥ 75 °C, memory < 200 MB, disk ≥ 90%).
Adjust SYSTEM_PROMPT routing rules, the conversation history window ([-12:]), or the send_devkit_capability_action timeout.
- Keep spoken responses short — each function returns a one-line
spoken_responsebuilt for voice. - Degrade gracefully — readers return structured errors instead of crashing when a value is unavailable.
- Route by intent, not keywords alone — the LLM prompt maps natural phrasing to one function.
- Always call
resume_normal_flow()— thefinallyblock guarantees control returns to the Agent.
The device call returned no dict / failed — confirm the DevKit is connected and the bridge is running.
The underlying file or command couldn't be read on this device (e.g. no iwgetid, or a different thermal zone path). Check the device logs for the metric's error code.
Refine the routing rules in SYSTEM_PROMPT and add the failing phrasing to the relevant rule.