Skip to main content
Glama
adrighem

Domoticz MCP Server

by adrighem

get_battery_levels

Check battery levels of smart home devices and get a list of those at or below a specified threshold to identify low batteries.

Instructions

Get a list of devices with battery levels at or below the specified threshold.

Args: threshold: Battery percentage threshold (default: 20).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
thresholdNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function for the 'get_battery_levels' tool. Fetches all devices, filters by battery level (ignoring 255 which means mains/no battery), and returns devices at or below the threshold, sorted ascending.
    @mcp.tool()
    async def get_battery_levels(threshold: int = 20) -> str:
        """Get a list of devices with battery levels at or below the specified threshold.
        
        Args:
            threshold: Battery percentage threshold (default: 20).
        """
        async with create_client() as client:
            devices = await _get_cached_data(client, _device_cache, f"{DOMOTICZ_API_URL}?type=command¶m=getdevices&filter=all&used=true")
            results = []
            for dev in devices:
                battery = dev.get("BatteryLevel", 255)
                # BatteryLevel 255 often means no battery or not reporting
                if battery != 255 and battery <= threshold:
                    results.append({
                        "idx": dev.get("idx"),
                        "Name": dev.get("Name"),
                        "BatteryLevel": battery,
                        "HardwareName": dev.get("HardwareName"),
                        "LastUpdate": dev.get("LastUpdate")
                    })
            # Sort by battery level ascending
            results.sort(key=lambda x: x["BatteryLevel"])
            return json.dumps({"status": "OK", "result": results})
  • The tool is registered via the @mcp.tool() decorator on the get_battery_levels function, using the FastMCP instance created at line 70.
    @mcp.tool()
    async def get_battery_levels(threshold: int = 20) -> str:
        """Get a list of devices with battery levels at or below the specified threshold.
        
        Args:
            threshold: Battery percentage threshold (default: 20).
        """
        async with create_client() as client:
            devices = await _get_cached_data(client, _device_cache, f"{DOMOTICZ_API_URL}?type=command¶m=getdevices&filter=all&used=true")
            results = []
            for dev in devices:
                battery = dev.get("BatteryLevel", 255)
                # BatteryLevel 255 often means no battery or not reporting
                if battery != 255 and battery <= threshold:
                    results.append({
                        "idx": dev.get("idx"),
                        "Name": dev.get("Name"),
                        "BatteryLevel": battery,
                        "HardwareName": dev.get("HardwareName"),
                        "LastUpdate": dev.get("LastUpdate")
                    })
            # Sort by battery level ascending
            results.sort(key=lambda x: x["BatteryLevel"])
            return json.dumps({"status": "OK", "result": results})
  • The schema/type definition is the function signature: threshold is an int with default 20. Returns a JSON string with status and result array.
    @mcp.tool()
    async def get_battery_levels(threshold: int = 20) -> str:
        """Get a list of devices with battery levels at or below the specified threshold.
        
        Args:
            threshold: Battery percentage threshold (default: 20).
        """
        async with create_client() as client:
            devices = await _get_cached_data(client, _device_cache, f"{DOMOTICZ_API_URL}?type=command¶m=getdevices&filter=all&used=true")
            results = []
            for dev in devices:
                battery = dev.get("BatteryLevel", 255)
                # BatteryLevel 255 often means no battery or not reporting
                if battery != 255 and battery <= threshold:
                    results.append({
                        "idx": dev.get("idx"),
                        "Name": dev.get("Name"),
                        "BatteryLevel": battery,
                        "HardwareName": dev.get("HardwareName"),
                        "LastUpdate": dev.get("LastUpdate")
                    })
            # Sort by battery level ascending
            results.sort(key=lambda x: x["BatteryLevel"])
            return json.dumps({"status": "OK", "result": results})
  • The _get_cached_data helper is used internally to fetch and cache device data from the Domoticz API.
    async def _get_cached_data(client: "httpx.AsyncClient", cache_obj: Dict[str, Any], api_url: str, key_path: str = "result") -> List[Dict[str, Any]]:
        now = time.time()
        if cache_obj["data"] is None or (now - cache_obj["timestamp"]) > CACHE_TTL:
            response = await _do_request(client, "GET", api_url)
            cache_obj["data"] = response.json().get(key_path, [])
            cache_obj["timestamp"] = now
        return cache_obj["data"]
    
    async def _resolve_idx(
        client: "httpx.AsyncClient",
  • The audit_batteries prompt references get_battery_levels to guide the AI agent in battery auditing.
    @mcp.prompt()
    def audit_batteries(threshold: int = 20) -> str:
        """Prompt to audit battery levels across all sensors."""
        return f"Please check the battery levels of all my smart home devices. Use the `get_battery_levels` tool with a threshold of {threshold}% to identify any sensors that need attention soon. Provide a clear list of these devices, including their current battery percentage and which room they are in (if known)."
    
    @mcp.prompt()
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, the description carries the full burden. It accurately describes the read operation but lacks details on side effects, permissions, or output structure. The behavior is minimally transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two clear sentences with no extraneous information. The first states the action, the second documents the parameter. Highly efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter tool with an output schema, the description is nearly complete. It could mention that it returns only devices meeting the condition, but that is already clear from the purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides no description for the threshold parameter, only type and default. The description adds crucial meaning: 'Battery percentage threshold (default: 20)' fully clarifies the parameter's purpose and default value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Get') and resource ('a list of devices with battery levels'), and specifies the filtering condition (at or below threshold). It distinguishes from siblings like get_all_devices which likely returns all devices, and get_device which returns a single device.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for retrieving devices with low battery levels, but it does not explicitly state when to use it versus alternatives or when not to use it. No exclusions or alternative recommendations are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/adrighem/domoticz-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server