Get device info
device_infoRetrieve retained device topics and optional metadata for a JouleScope energy analyzer. Use to get device information and status.
Instructions
Return retained device topics and optional metadata for one JouleScope.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| device_path | No | ||
| include_metadata | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/joulescope_mcp/server.py:50-60 (registration)The MCP tool registration for 'device_info' using @mcp.tool decorator. Defines the tool's title, description, annotations (read_only), structured output, and parameters (device_path, include_metadata). Delegates to service.device_info().
@mcp.tool( title="Get device info", description="Return retained device topics and optional metadata for one JouleScope.", annotations=read_only, structured_output=True, ) def device_info(device_path: str | None = None, include_metadata: bool = False) -> dict[str, Any]: try: return service.device_info(device_path=device_path, include_metadata=include_metadata) except JoulescopeMcpError as exc: raise _tool_error(exc) from exc - src/joulescope_mcp/service.py:167-197 (handler)The actual handler logic for device_info in Js220Service. Opens a driver session, selects a device, subscribes to retained publications (pub_retain) and optionally metadata (metadata_rsp_retain), strips the device prefix from topic keys, and returns device_path, values dict, and optional metadata dict.
def device_info(self, device_path: str | None = None, include_metadata: bool = False) -> dict[str, Any]: values: dict[str, Any] = {} metadata: dict[str, Any] = {} def on_pub(topic: str, value: Any) -> None: values[topic] = _jsonable(value) def on_metadata(topic: str, value: Any) -> None: metadata[topic[:-1] if topic.endswith("$") else topic] = _jsonable(value) with self._driver_session() as driver: device = self._select_device(driver, device_path=device_path, require_js220=False) driver.open(device, mode="restore") try: driver.subscribe(device, "pub_retain", on_pub) driver.unsubscribe(device, on_pub) if include_metadata: driver.subscribe(device, "metadata_rsp_retain", on_metadata) driver.unsubscribe(device, on_metadata) finally: driver.close(device) def strip_prefix(items: dict[str, Any]) -> dict[str, Any]: prefix = device + "/" return {k[len(prefix) :] if k.startswith(prefix) else k: v for k, v in sorted(items.items())} return { "device_path": device, "values": strip_prefix(values), "metadata": strip_prefix(metadata) if include_metadata else None, } - Function signature showing input parameters: device_path (str | None, default None) and include_metadata (bool, default False). Return type is dict[str, Any] with keys 'device_path', 'values', and 'metadata'.
def device_info(self, device_path: str | None = None, include_metadata: bool = False) -> dict[str, Any]: values: dict[str, Any] = {} - Helper function strip_prefix used within device_info to remove the device path prefix from topic keys for cleaner output.
def strip_prefix(items: dict[str, Any]) -> dict[str, Any]: prefix = device + "/" return {k[len(prefix) :] if k.startswith(prefix) else k: v for k, v in sorted(items.items())}