mcpField
P
puda-edge

puda-edge

github.com/pudap开发199 次安装2 周前更新
代码仓库

关于 puda-edge

puda-edge 是用于构建 PUDA 边缘服务的 Python 技能,可封装机器硬件并通过 NATS 暴露类型化命令。它涵盖 SDK/API 与 GUI 实现,以及配置、安全上下文和验证流程。

主要功能

  1. 01SDK/API 与 GUI 边缘服务指南
  2. 02类型化且有文档的机器命令
  3. 03命令安全提示元数据
  4. 04配置与遥测指南
  5. 05离线及硬件验证步骤

适用场景

  1. 01为仪器 SDK 构建 Python 封装
  2. 02通过 NATS 暴露 GUI 机器工作流
  3. 03为 Agent 记录安全机器操作

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pudap/skills --skill puda-edge

安装后在 Claude Code 中输入/puda-edge确认已加载。

附带文件references/gui-edge.md

详细介绍

Puda Edge

帮助编写 Python 边缘服务:连接到 NATS 并公开机器命令的轻量级硬件封装。

构建边缘服务

条件合适时,使用现有的机器 SDK/API。对于通过桌面软件操作的仪器,构建 GUI 边缘服务:AI 使用手册或屏幕截图及任务说明,编写针对特定机器的 Python 工作流,再由 PUDA 通过 NATS 公开这些工作流。

有关 GUI 工作,请阅读 references/gui-edge.md。从 GitHub 克隆 PUDAP/edge-python-gui-template 作为脚手架,并参考 PUDAP/opentrons-gui-edge 作为完整示例。本指南介绍如何将任务说明转换为确定性的 GUI 命令并对其进行验证。有厂商 PDF 手册时,请使用手册。没有手册时,展示点击位置、输入内容和预期结果的屏幕截图也可作为原子命令的有效上下文。如果条件允许,可通过实时截图补充上述任一来源。

对于 SDK/API 和 GUI 边缘服务:

  • 在搭建脚手架之前,检查所选模板的依赖项和 SDK 契约。GUI 示例使用 from puda import EdgeNatsClient, EdgeRunner, command。
  • 机器命令应具有类型、与 JSON 兼容,并记录参数、单位、默认值、前置条件、返回的证据和失败情况。使用 @command 公开预期工作流。对于 GUI 边缘服务,capture_screenshot 是唯一的底层远程命令;使用继承的 GUI 助手函数在内部实现高级工作流。
  • 通过设置和 .env.example 配置机器标识、NATS 服务以及连接/窗口详情。保留模板的生命周期和清理逻辑。不要从其他机器复制凭据或可用的 .env。
  • 在桌面或硬件验证之前,先离线验证命令。分别报告已实现的内容、使用固定数据测试的内容、在桌面上观察到的情况,以及在硬件上实际运行的内容。

按照 Integrating a New Machine 了解仓库布局、main.py 配置、遥测和多机器 PC。对于 SDK/API 边缘服务,使用 edge-python-template 搭建脚手架;对于 GUI 边缘服务,使用上面的 GUI 模板。仓库命名为 puda-<machine_id>-edge。

仅使用 Python。有关主机/NATS/硬件的调试配置,请使用 puda-deployment。命令正常工作后,使用 puda 安装 CLI。

搭建脚手架

  1. 从模板创建仓库。解决所有 TODO。
  2. 在 .env 中设置唯一的、小写并以连字符分隔的 MACHINE_ID,以及 NATS_SERVERS。
  3. 实现 driver.py,然后在 main.py 中接入配置和驱动程序。
  4. 将助手函数设为私有(_name)。只有 @command 方法会被公开。

边缘服务连接后,使用 puda machine commands <machine_id> 进行验证。

同一台 PC 上的多台仪器可以共用一个 uv 工作区;每个子目录都应有自己的 MACHINE_ID、driver.py 和 main.py。请参阅文档和 PUDAP/ViPSA。

驱动程序

driver.py 是硬件 API 的轻量封装。方法名、文档字符串、参数和返回注解构成 Agent 看到的命令接口。在 Driver 类的文档字符串中添加一句话摘要;EdgeRunner 会在 puda machine list 和 puda machine ping 中展示第一段内容,这样 Agent 无需运行 puda machine commands 就能了解机器的用途。

  • 使用 @command 装饰每个可远程调用的方法。未装饰的公共方法不会通过 NATS 发布或调用。没有任何 @command 方法的驱动程序会在启动时失败。
  • 保持命令的原子性:每个方法只执行一项硬件操作。
  • 参数必须是基本类型(str、int、float、bool)或由基本类型组成的简单列表/字典。
  • 在每个公共方法的文档字符串中说明参数、返回值和引发的错误;这些内容会为 Agent 提供上下文。
  • 失败时抛出异常,并包含命令、目标和硬件响应。返回 False 仍会被视为 PUDA 调用成功({"result": false})。
  • shutdown、home 和 reset 均为可选方法。边缘端停止前会运行 shutdown。运行 puda machine home 会触发 home。puda machine reset 总会清除活动的 run_id,然后在存在 reset 方法时调用它。
from puda import command, safety

class Driver:
    """Software-only PUDA test machine. Commands are simulated in memory; no hardware is required."""

    @command
    def shutdown(self) -> bool:
        """Release hardware resources. If defined, called before the edge stops."""
        ...

    @command
    def home(self) -> bool:
        """Home the machine. If defined, triggered by `puda machine home <machine_id>`."""
        ...

    @command
    def reset(self) -> bool:
        """Software reset. Optional. `puda machine reset` clears the run first, then calls this if present."""
        ...

    @command
    def move_to(self, x_mm: float, y_mm: float, z_mm: float) -> bool:
        """
        Move the machine head to an absolute position.

        Args:
            x_mm: Target X position in millimeters.
            y_mm: Target Y position in millimeters.
            z_mm: Target Z position in millimeters.

        Raises:
            RuntimeError: If the hardware rejects the move.
        """
        result = self._hardware.move_to(x_mm=x_mm, y_mm=y_mm, z_mm=z_mm)
        if not result.ok:
            raise RuntimeError(
                "Failed to move machine head "
                f"to x={x_mm}, y={y_mm}, z={z_mm}: {result.error}"
            )
        return True

@safety

将 @safety 附加到 @command 方法,以便在命令目录中发布提示性上下文。它不会阻止边缘端分发命令。不带 @command 的 @safety 会被忽略。

这五个字段都必须仅作为关键字参数传入。不要添加其他字段。

字段必填作用
summary是风险概述
hazards否简短标签,例如 collision、thermal
requires否前置条件;Agent 会插入前置步骤或先询问
forbidden_when否不得使用该命令的情形
confirm否操作者输入 yes 的确认门槛。默认为 false。设为 true 即启用

不要在多个字段中重复同一句话。summary 说明风险;requires 指明前置条件;forbidden_when 说明禁止条件;confirm=True 表示需要确认。不要在 summary 中写“confirm…”。

@command
@safety(
    summary="Collision risk from unhomed motion or an occupied workspace.",
    hazards=["collision"],
    requires="Machine must just have been homed.",
    forbidden_when="Do not move if the workspace is occupied or human movement is detected.",
    confirm=True,
)
def move_to(self, x: float, y: float, z: float) -> dict:
    ...

对于只读或无害的命令(get_position、echo),不要添加 @safety。对于运动、化学品混合、加热、加压或其他不可逆的硬件操作,请使用 confirm=True。

配置

在 .env 中保留 MACHINE_ID 和 NATS_SERVERS。在 main.py 的 Config 中添加带类型的硬件字段,以便缺少值时能在启动时失败。将这些字段传入 Driver(...)。

遥测数据必须可序列化为 JSON。发布心跳,以及机器实际具备的位置信息、健康状况和状态。字段名应与硬件相符(如关节、柱塞、焦点),不要使用笛卡尔模板。

远程更新

puda machine update

使用前,请运行 puda machine update --help,查看已安装 CLI 的目标指定和更新选项。

评论

支持 Markdown