# SPDX-FileCopyrightText: 2026 James Harton # # SPDX-License-Identifier: Apache-2.0 defmodule BB.MCP.Resources.RobotState do @moduledoc """ Current operational and safety state of a robot. Read via `bb://robots/{robot}/state`. """ use Anubis.Server.Component, type: :resource, uri_template: "bb://robots/{robot}/state", name: "robot_state" alias Anubis.Server.Response alias BB.MCP.Resources alias BB.Robot.Runtime alias BB.Safety @impl true def description, do: "Current safety and operational state of the robot" @impl true def mime_type, do: "application/json" @impl true def read(params, frame) do case Resources.fetch_robot(params) do {:ok, module} -> payload = %{ "safety_state" => Safety.state(module), "operational_state" => Runtime.operational_state(module), "executing" => Runtime.executing?(module), "executing_commands" => Enum.map(Runtime.executing_commands(module), &format_command/1) } {:reply, Response.json(Response.resource(), payload), frame} {:error, error} -> {:error, error, frame} end end defp format_command(%_{} = struct) do struct |> Map.from_struct() |> stringify_keys() end defp format_command(map) when is_map(map), do: stringify_keys(map) defp format_command(other), do: inspect(other) defp stringify_keys(map) when is_map(map) do Map.new(map, fn {k, v} -> {to_string(k), stringify_value(v)} end) end defp stringify_value(pid) when is_pid(pid), do: inspect(pid) defp stringify_value(value), do: value end