dsh-breadboard

DSH PLUGIN文档与办公

仓库 Noob-stupid/dsh-breadboard

文档与办公 L5 · 运行验证通过 安全审查:低风险 可信度:金 可安装插件
安装这个插件

DSH 嵌入式硬件沙盒插件:3D 装配协作感知 + 项目级硬件在环仿真

一句话选型结论

按资料字段整理

dsh-breadboard 是文档与办公类的 DSH 可安装插件,验证等级 L5 · 运行验证通过,安全审查为低风险,有可直接复制的安装命令。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类文档与办公 收录类型可安装插件 验证等级L5 · 运行验证通过 安全审查低风险
验证等级 L5 L5 · 运行验证通过
GitHub 星标 2 复刻 未标注 · 未关闭 issue 未标注
最近更新 2026-10-17 创建于 未标注
README 26.8 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add @noob-stupid/dsh-breadboard@0.6.0
  1. 1
    确认版本与运行环境

    仓库没有标注兼容版本与 Node.js 要求,先确认你的 DSH 版本能装,再继续。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本未标注版本不匹配时安装会报错
Node.js 要求未标注来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名未发布到 npm可用 npm view 查看包信息

能做什么

文档与办公
字段来自项目仓库与公开索引,中文说明由本站标注

适用场景

内容创作

验证等级与安全审查

L5 · 运行验证通过
自动化流程结论,不是人工审核
验证等级L5 · 运行验证通过在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来
安全审查低风险静态分析结论,未标注不代表已通过审查
仓库健康度活跃按仓库活跃度与最近更新时间给出
可信度金综合仓库活跃度与验证结果

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 验证等级 L5:安装和运行都在沙盒里跑通过,装完能直接用的概率高。
  • 静态安全审查为低风险,没有发现明显可疑行为。
  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有声明 Node.js 版本要求,版本不匹配可能装不上。
  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在文档与办公场景里给 DSH 补能力的人。
  • 想装完就能用、不想自己排依赖的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
dsh-breadboard当前 L5 · 运行验证通过 低风险 2 未标注 有
reactive-resume L3 · 安装规范通过 低风险 4.4 万 未标注 有
webnovel-writer L4 · 沙盒安装通过 低风险 7,742 未标注 有
answer-me-with-html L4 · 沙盒安装通过 低风险 4,782 未标注 有
univer-workspace L4 · 沙盒安装通过 低风险 2,258 未标注 有
last30days-skill-cn L4 · 沙盒安装通过 低风险 1,880 未标注 有

仓库档案

文档与办公
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方Noob-stupid仓库 dsh-breadboard · 默认分支 未标注
分类文档与办公creator
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言未标注仓库主语言
许可证BSD-3-Clause商用或二次分发前请确认条款原文
星标 / 复刻 / issue2 / 未标注 / 未标注收录时的数值,非实时
创建 / 更新未标注 · 2026-10-17最后推送 未标注
本站收录2026-10-30首次进入本站目录的时间

README 全文

26.8 KB
作者原文,中文版优先;只做安全转义,不改内容

Web profile 插件 —— 宿主半 + 浏览器半。

> English: README.md | 中文: README.zh.md


DSH 硬件沙盒

给 DSH 的 3D 硬件沙盒:把装配摆出来、接上线,然后让你自己项目的代码跑在虚拟硬件上。

<!-- 收录徽章位:awesome-dsh-plugin / DSH 社区列表 / dsh.so / dsh-plugin.org / …(收录通过后逐个补上官方徽章;徽章图片本身不自制) -->

安装(从 GitHub 源码装;本包未发布到 npm)

dsh plugin --profile web add github:Noob-stupid/dsh-breadboard

装完刷新页面即可。沙盒注册进 main 槽(3D 视图)与 sidebar.panellist 槽(各面板);
skill/SKILL.md 随插件一起注册,装了这个插件的 agent 已经知道该怎么用它。

喜欢的话:在插件管理里打开这个插件的详情页,内容最下方靠右有一行小字,可以到
GitHub 点个 Star。它就是透明的一行字
—— 没有底色、没有边框、没有阴影,也只在本插件自己的页面上出现。

这一行能生效靠三件事,三件都在本仓库里:

要求 位置 说明
仓库 topic dsh-plugin GitHub 仓库 topics 社区列表据此发现本仓库
dsh.bundle 清单 package.json → &quot;dsh&quot;: { &quot;bundle&quot;: { &quot;patch&quot;: &quot;./cordis.patch.yml&quot; } } 没有它 dsh plugin add 装不进任何东西 —— 而且界面上的症状极具误导性:插件列表说「没有声明组合包」,真正被挡住的却是装配本身,于是所有 /api/* 返回 404,面板干脆不出现
导出 apply(ctx) src/index.ts(宿主半)/ src/client/index.ts(浏览器半) 宿主半注册路由、工具与仿真引擎;浏览器半注册上面那两个槽

这是什么 / 解决什么问题

一个软硬件项目里,只有真机能试的那几段,是接线本身、传感器在寄存器层的语义、以及出错时的处理。
本插件把它们搬进一个真能跑起来的虚拟场景:

  • 3D 装配 —— 从内置模型库放器件(ESP32、树莓派 4B、BME280、HC-SR501 PIR、LED 模块、
    MPL3115A2、面包板),按端口逐个连线,得到一份活的 SSOT(唯一真相)装配状态,带拓扑与电气校验。
  • 项目级硬件在环 —— 一个真实 Python 进程跑你自己项目的代码。Python shim 拦截它的
    smbus/I2C 访问,由虚拟设备应答,所以被测项目读到的是寄存器级的值
    (例如它自己拿虚拟芯片的数据做真正的 BME280 补偿计算)。
  • 联网设备模拟(并列的第二类虚拟硬件)—— 一台按真实节拍主动向你的外部 HTTP 后端
    上报的设备:注册 → 拉配置 → 周期上报。已在真实的智能选座系统上全链路验证
    (设备 → HTTP → 服务端状态机 → 数据库)。
  • 故障注入 —— 拔线、返回 NACK、强制读数、让设备掉线,然后看项目的异常处理到底抓没抓住。
  • 项目级便利 —— 扫描一个真实项目文件夹,得出它需要哪些硬件;再一键换掉整套硬件。

依赖 DSH 的 web profile 与 webServer、tools、subprocess 三个服务。宿主半把它们声明为
硬 inject 依赖(刻意如此):缺任何一个,插件根本不激活,而不是"激活了但工具没注册 /
界面空白 / 仿真起不来"。

没有真实项目也想看效果

examples/zhizuo-virtual-esp32/ 是虚拟 ESP32 座位传感器的独立脚本版。
hw_list_projects 会列出内置演示项目(zhizuo-seat-node)以及它当前是否软硬件连通;
hw_import_project 一次把它的器件、连线与联网绑定摆好。

界面导览

界面目前只有中文,下表用的就是屏幕上那行字。

面板 作用
③ 项目(一键换整套硬件) 主工作流。每个项目本体显示:文件数(采样跳过时为「N 个文件(采样时跳过 M 个)」)、扫描需求、删除;底部还有:+ 导入项目本体(选文件夹)、⤓ 导出建模组(存成一个 .json)、+ 导入建模组(选 .json)、+ 添加型号定义(选 .json)、✎ 让 agent 帮我写
① 添加器件 点一下型号键,把它放进场景。只列有真几何的型号(默认收起)
② 换装模型 搜模型 / 导入文件,给某个型号换装;没有几何的型号渲染为占位盒。外部(数据驱动)型号带「[数据驱动]」标记(默认收起)
④ 真机观察 显示真实硬件的状态(只读),并能从界面开始/停止观察(默认收起)
统计 渲染统计(绘制次数 / 三角形数 / 帧率)—— 纯读取,默认关
中央 3D 视图 已放置器件(带世界变换)、端口之间的蓝色连线、在带 warn/error 告警的器件上就地面出的告警框、变换手柄 / 右键菜单(钉住、删除)、端口悬浮提示
面板浮层输入框 不离开面板就能给当前会话发消息;宿主没提供 agents 服务时该输入框直接隐藏(capabilities.chat 缺省)

其中两条要点名:

  • 「扫描需求」只是界面按钮。 它没有对应的 agent 工具 —— agent 侧没有这一步。agent 能做的是
    它后面的事:摆器件、连线、建项目图纸、跑仿真。
  • 删除项目只删掉项目定义(那一份 JSON)。它不动场景,所以删项目永远不会把你眼前的硬件清掉。

快速上手:三步

  1. 导入项目本体 —— 点 + 导入项目本体(选文件夹),选一个完整的项目文件夹
    (前后端 + 硬件代码)。它不带建模;宿主读它来判断需要哪些硬件。
  2. 扫描需要哪些硬件 —— ③ 面板里的 扫描需求 按钮(界面专属,见上)。报告会列出每个候选
    型号键,并给出证据(在哪几个文件里看到的),让你自己判断对不对;扫描时如果做了采样,
    它会说出来,而不会让你以为整个项目都扫过了。
  3. 导入建模组 —— 点 + 导入建模组(选文件夹),布局是 &lt;型号键&gt;/model.glb。
    没补的型号继续渲染为占位盒。

或者干脆跳过 1–3:把系统用话讲给 agent,让它用 hw_save_project 写成图纸,
再用 hw_import_project 一次把器件、连线、联网绑定全部摆好。

Agent 工具:16 个 hw_*

以下是实际注册的清单(未增未删)。「什么时候用」这一列才是表格的意义 —— 这些工具并不通用互换。

项目

工具 作用 什么时候用
hw_list_projects 列内置软硬件项目:器件、接线、联网配置,以及当前是否软硬件连通 在手工摆器件之前先用它 —— 一张图纸是一次调用;手工摆是四步,少一步就不通且不报错
hw_import_project 导入项目:先清空当前装配,再摆器件、连线、挂绑定 换掉整套硬件时用;注意它是替换,不是往上加
hw_save_project 新建或覆盖项目图纸(存进 $DSH_HOME/dsh-hardware-sandbox/projects/) 用户用话描述了一个系统 —— 先写成图纸,再导入

装配

工具 作用 什么时候用
hw_get_assembly 读 SSOT 摘要:revision、组件、连线、告警(连 message 一起给,不只是码)、供电、虚拟设备 每次改动前都先读 —— 你需要真实的端口 id;端口 id 是引脚身份(E4),不是丝印名(GPIO23)
hw_edit_assembly 一个工具覆盖契约里的 ClientAction 联合:放器件 / 移动 / 旋转 / 连线 / 拔线 / 删除 / 钉住 任何对场景的修改。它收一个 action 对象,先读工具描述里的样例

仿真

工具 作用 什么时候用
hw_run_simulation 在虚拟硬件上运行真实的 Python 项目;duration 是虚拟秒数;返回项目输出与虚拟/真实耗时 真正的硬件在环那一跑。accelerated(默认)远快于真实时间;realtime 按真实节拍限速,便于观察
hw_get_sim_log 读最近一次(或进行中)那跑的项目输出,可只取 tail 行 当 hw_run_simulation 的输出被截断时
hw_inject_fault 对设备 id 或 型号:地址 目标注入 disconnect / nack / busy / set_reading / clear 验证项目的异常处理真的看到了故障(例如断线后的 OSError),而不是假定它会看到

联网设备

工具 作用 什么时候用
hw_network_add 添加一台联网设备(协议适配器 + endpoint + 设备自报身份)。它不会启动 第一次把设备模拟器接上你的后端
hw_network_devices 列设备:协议、外部系统地址、在线状态、上报/失败次数、当前读数、服务端下发的配置 确认设备到底连上没有、有没有在真的上报 —— 否则"已添加但停着"看起来也很正常
hw_network_control start / stop / disconnect(掉线故障)/ clear 只有 start 会让请求真的发出去 —— 这是刻意的,默认不该有外部副作用;disconnect 用来验对面能否识别离线
hw_network_set_reading 设置物理读数(如 { ir_front: true, ir_back: true },true = 被遮挡) 单独验协议层对不对,与硬件通路无关。电平由协议按配置(如 ir_active_high)翻译,极性搞反的责任留在协议侧,不在调用方
hw_set_occlusion 遮挡 / 移开装配里的某个器件,并沿实际接线把影响传导到联网设备的读数上 验硬件通路:PIR 没接上、或接错了脚,就什么都不会发生 —— 真机就是这样

型号定义(数据驱动)

工具 作用 什么时候用
hw_scan_board_pins 从本机 PlatformIO 的权威文件推导引脚表草稿:boards/.json → build.variant → variants//pins_arduino.h(编译器实际用的那份映射)。list:true 列出本机能找到的板子 要加一块新板子时先跑它。★★ 它给的是草稿 + 缺口清单(缺:物理排布 / 电气语义 / 丝印),不是成品 —— 缺口按数据手册补齐后再用 hw_save_model_definition
hw_save_model_definition 保存一条型号定义(引脚表:portId/丝印/协议/电压/方向 + 尺寸 + 排布)。校验通过才落盘,落盘后立即生效 需要一块插件还不认识的板子时。引脚表必须有权威来源(厂商数据手册 / PlatformIO 的 variant 文件 / 项目自己的工程文件);找不到就问用户,不要凭记忆编

真机在环(只读观察)

工具 作用 什么时候用
hw_watch_device 观察一台真机:定时只读查询外部系统(智座用 GET /api/admin/sensor/devices),把真机状态映射到场景器件上。action = start / stop / status 想知道"真机现在到底连没连上"。⚠️ 它与 hw_network_add 方向相反:那个是我们冒充设备发请求,这个是我们去问真机(只读、无对外副作用)

原因码与对策

装配操作的失败都带原因码(契约的 WarningCode,共 12 项,见 src/contracts/assembly.ts)。

照着码改对应的那件事。不要盲试。

原因码 含义 该做什么
bad_params 动作参数不可用(如旋转角里带 NaN / Infinity) 改数值 —— 问题在值上,不在组件 id 上
direction_conflict 两端电流方向冲突(输出对输出 / 两个供电接在一起) 按电流方向重排:至少一端要变成输入
protocol_mismatch 两端口信号种类不同 用匹配的端口对;确认那个脚到底支持哪种信号
port_occupied 这个端口被别的线占了 拔掉那根线(用它的 cableId 做 disconnect),或换脚
voltage_mismatch 端口电压不兼容 接电压兼容的端口,或加电平转换
power_exceeded 装配的供电需求超出供给预算 增加供电或减小功耗
i2c_address_conflict 总线上两个器件地址撞了 改其中一个的地址(SDO/AD0 脚)
i2c_pullup_missing I2C 总线缺上拉 给 SDA/SCL 加上拉
unconnected_port 有端口一根线都没接 按需连接 —— 并检查是不是忘了成对的那一根
unknown_hardware_model 找不到这个型号键 用 hw_get_assembly 看现有组件里的真实键
component_pinned 组件被钉住了,移动被明确拒绝 先解开钉住(右键菜单,或 set_pinned: false)
already_connected 就是这一对端口已经连了 别去找一根不存在的线;想换线先拔这一根

三条值得留下的说明:

  • port_occupied 与 already_connected 是刻意分开的两个码。 合成一个,用户会去找一根不存在的线。
  • 多个不同端口接到同一个端口是合法的(那是 I2C 总线),不报 already_connected。
  • ok: true 不等于效果发生了。 每次写入之后都应该再读一次装配确认。

型号定义:让插件认识一块新硬件

先说清两件不同的事(这是最容易混的一处):

给的是 从哪来
建模组(.glb) 外观 —— 场景里长得像真板子 模型库(step.parts / GrabCAD / SnapEDA…,大部分板子有)或你自己导入
型号定义(.json) 引脚数据 —— 有几个脚、每个脚是什么 模型库里没有:连 SnapEDA 的符号库都"不含总线协议与电压",而语义正是我们要校验的东西

⇒ 外观来自库;引脚数据靠型号定义。 没有定义,插件不认识这块板子(摆上去也只是占位方块)。

一条定义里写什么

{
&quot;key&quot;: &quot;stm32f103c8t6&quot;,          // 型号键(小写字母/数字/连字符);不能与内置型号同名
&quot;label&quot;: &quot;STM32F103C8T6(Blue Pill)&quot;,
&quot;size&quot;: { &quot;x&quot;: 0.0533, &quot;y&quot;: 0.011, &quot;z&quot;: 0.0229 },   // 包围盒,单位【米】
&quot;powerDrawW&quot;: 0, &quot;powerSupplyW&quot;: 0,
&quot;ports&quot;: [
// portId = 身份(连线用它,必须唯一);name = 丝印(人看的那行字,可重复)
{ &quot;portId&quot;: &quot;P1&quot;, &quot;name&quot;: &quot;VBAT&quot;,   &quot;protocol&quot;: &quot;power&quot;, &quot;voltage&quot;: 3.3, &quot;direction&quot;: &quot;in&quot; },
{ &quot;portId&quot;: &quot;P2&quot;, &quot;name&quot;: &quot;PC13&quot;,   &quot;protocol&quot;: &quot;gpio&quot;,  &quot;voltage&quot;: 3.3, &quot;direction&quot;: &quot;io&quot; }
],
// 排布:贴哪条边、间距、几排(双排排针用 rows/rowPitch)
&quot;portLayout&quot;: { &quot;edge&quot;: &quot;+z&quot;, &quot;pitch&quot;: 0.00254, &quot;count&quot;: 40, &quot;inset&quot;: 0.001, &quot;rows&quot;: 2, &quot;rowPitch&quot;: 0.02292 }
}

三条容易踩的:
1. portId 是身份、name 是丝印 —— 一块板有多个 GND,用功能名当身份会撞号,而撞号的后果是静默的(两根线分不清)。
2. voltage: 0 是合法的 —— 那是 GND 的电压,不是"没填"。
3. 端口要么每个给 position、要么给 portLayout —— 两者都缺会被拒绝(不是给个默认值假装能用)。

三条获取路径(按可靠性排序)

路径 怎么做 说明
① 扫描/推导(主路径) 从工程文件推:platformio.ini 的 board = 认出型号;framework 的 variants//pins_arduino.h(编译器实际用的那份映射)拿到引脚;固件源码 #define IR_SENSOR_A_PIN 23 看出本项目实际用了哪些脚;STM32 的 .ioc 有完整外设→引脚分配 覆盖大部分;推不出电气语义(3.3V/5V、I2C、上拉)与物理尺寸 —— 那部分要手册
② AI 一键写 ③ 面板里填型号名 → ✎ 让 agent 帮我写(或让 agent 直接调 hw_save_model_definition) agent 会先找权威来源;找不到就来问你,不许凭记忆编
③ 手动/用户提供 ③ 面板 + 添加型号定义(选 .json) 你自己有手册/接线表时最快

★★ 一条纪律(写进工具描述里的)

引脚表必须有权威来源(厂商数据手册 / PlatformIO variant / CubeMX 数据库 / 项目自己的工程文件)。
手打错的引脚表比没有更坏 —— 它会产出"看起来对但接错脚"的校验,而没人能发现。
⇒ 所以插件宁可拒绝、宁可让你补来源,也不给一个"看起来合理"的默认值。

内置型号不可被覆盖:撞名会被拒绝并说明原因 —— 否则别人发一个 rpi-4b 定义就能悄悄改掉所有用户的引脚表。

真机观察:把真机状态读进场景

让场景里的器件反映真实硬件的状态:真机 → 服务端 → 插件(只读)。

hw_watch_device({ action:&#x27;start&#x27;, componentId:&#x27;c1&#x27;, deviceId:&#x27;AA:BB:CC:11:22:33&#x27;,
endpoint:&#x27;http://127.0.0.1:5800&#x27;, intervalMs:5000, cookie:&#x27;…&#x27; })
hw_watch_device({ action:&#x27;status&#x27; })     // 看现在是什么状态
hw_watch_device({ action:&#x27;stop&#x27;, componentId:&#x27;c1&#x27; })

界面上对应 ④ 真机观察 面板(填器件 / 真机标识 / 地址 / 间隔 → 开始观察(只读))。

★★ 五种状态分开(这是这一层最重要的设计)

状态 含义 该去查什么
ok 查到了,数据是新的 ——
stale 查到了,但数据很旧 真机确实离线 → 查硬件(供电/网络)
error 我们查不到(网络/鉴权/解析失败) 地址与鉴权,与硬件无关
not_found 服务端答得好好的,但没有这台设备 deviceId 是否写错;或它还没上过线
idle 还没查过 ——

⚠️ 把 error 说成"设备离线"是本项目最怕的那种错:结论看起来合理、实际完全错误,还会让人去拔插硬件,而真正的问题在我们这边(地址写错 / 没登录)。

两条硬约束

  1. 轮询走墙钟(真机按真实时间走,不能加速),间隔下限 2 秒 —— 这是保护对方服务器的硬约束,不是建议值。
  2. 只有宿主在轮询:界面只读宿主的缓存(不会把对方服务器打两遍,也不会出现两份不一致的状态)。

⚠️ 一个真实的陷阱(源码里挖出来的)

不要用 GET /api/sensor/device_config 做观察 —— 智座那条路由会把 last_seen 刷成当前时间(它本来是给设备拉配置用的)。
用它做观察 = 我们一查,离线设备就变在线 ⇒ 得出"设备在线"而设备根本没插电。

⇒ 观察只用 /api/admin/sensor/devices(只读),这条有断言钉死。

建模组格式

交给 + 导入建模组 的文件夹(也是导出与导入往返的同一套布局)是:

&lt;型号键&gt;/
model.glb      模型本体
meta.json      可选元信息
  • 渲染只加载 GLB / GLTF。 导入侧的格式判定认内容不认扩展名,接受
    glb / gltf / stl / obj / ply / 3mf / dae / fbx / wrl;但 STEP / IGES 会被明确拒绝,而不是静默存下 ——
    three.js 没有对应 loader,存下来的 STEP 永远渲染不出来。
  • 内部每个模型是一个目录 &lt;型号键&gt;/{model.bin, meta.json},model.bin 装几何字节
    (meta.json 记 format / nodes / bytes / generator)。用中性文件名存字节是刻意的:
    布局里没有扩展名歧义,meta 与它的字节绑在一起。导出的建模组用上面的
    &lt;型号键&gt;/model.glb 形式,所以导出与导入是同一套布局。
  • 随包分发(启动时补进用户模型目录,只补缺的键 —— 你自己导入过的模型绝不会被覆盖):
型号键 来源 在包里 为什么
bme280 自产 有 寄存器级设备模型 + 演示装配要用
led-5v 自产 有 最简单的输出器件
hc-sr501 自产 有 演示装配要用两个(PIR)
esp32-seat-sensor 自产 有 联网设备演示要用
rpi-4b 从 step.parts 导入(第三方) 没有 第三方几何 —— 本插件不分发;需要时从界面上自己导入
mpl3115a2 从 step.parts 导入(第三方) 没有 同上
breadboard 自产(无端口、无源) 无几何 渲染为按契约尺寸生成的占位盒

为什么这么分:四个自产模型是我们的,可以随包发,所以插件开箱即用
(演示装配就是 esp32-seat-sensor + 2 × hc-sr501,全在包里)。第三方模型是别人的资产、有它自己的条款,
所以插件不分发它们 —— 界面给搜索入口,文件你自己导。端口语义(I2C 地址、协议、电压、方向)
一律自产,因为没有哪个模型库卖这个 —— 详见 docs/05。

墙钟陷阱:联网设备为什么不用虚拟时间

虚拟时钟是加速的:advance(60) 会把 60 个虚拟秒在几十毫秒内跑完。被动等被读的总线设备挂上去没问题
(确定性、纯同步);联网设备不行 —— 它是主动周期上报的,一次快进会朝别人的后端打出几十次
真实 HTTP 请求,把对方打爆。

所以联网设备一律按墙钟(真实节拍)走,与虚拟时钟解耦;它的快照里带 wallClockDriven: true,
加速模式对它们没有意义。两个推论:

  • 加速模式对联网设备不适用。 它们始终按真实间隔上报。
  • 设备被添加后停在 idle,必须显式 start —— 默认完全不产生外部副作用。
    这是本插件的一条结构性纪律:默认行为不许伸到机器外面去。

构建与开发

# 1. 安装(同时链接构建所需的框架 peer)
npm install

# 2. 构建:src/ -&gt; lib/(需要 bash 与一份 DSH 源码 checkout)
$env:DSH_CHECKOUT=&#x27;D:\dsh\deepseek-harness&#x27;; bash scripts/build.sh

# 3. 测试与类型检查(2026-10-11 实测)
npm test                  # node --test,308 项,0 失败
npm run typecheck         # tsc -p tsconfig.json --noEmit          -&gt; exit 0
npm run typecheck:client  # tsc -p tsconfig.client.json --noEmit   -&gt; exit 0

scripts/build.sh 除了编译还做三件事:链接构建依赖(scripts/link-deps.mjs,同时挂在 postinstall 上,
因为 npm install 会清掉它不认识的 junction)、把 project-shim/ 复制进 lib/project-shim/、
写出 lib/build-stamp.json。那次复制是功能性步骤,不是打包细节 ——
SimEngine 把 Python 进程的 PYTHONPATH 指向 shim(smbus + RPi.GPIO + sitecustomize),
而 package.json 的 files 只发 lib,不做这一步就等于发布一个跑不起来的包。

scripts/prepare.mjs 让 git 装法也能用:lib/ 被 gitignore,所以 git 装出来会没有入口。
它只在 lib/index.js 缺失时才构建,而且构建失败只警告(exit 0) ——
构建失败大概率是这台机器缺 bash 或缺 devDependencies,让整个 install 失败只会把锅甩给 npm。

发布产物:npm pack → 一个 .tgz,内含 lib、cordis.patch.yml、skill、docs、models、scripts。

活体自检:线上跑的是你以为的那次构建吗?

curl http://127.0.0.1:&lt;端口&gt;/@noob-stupid/dsh-breadboard/api/capabilities

所有界面与 API 都挂在路由前缀 /@noob-stupid/dsh-breadboard/ 下。GET …/api/capabilities
返回 build(当前活着的那份代码的构建时间戳)与 simTools(实际注册成功的工具名)。
觉得哪里不对就先看它:工具注册失败是完全静默的 —— 模型只会说"我没这个能力",界面上看不出任何异常;
而热重载可能报成功、实际还是旧模块在服务。

已知限制

诚实清单;下面没有一条被"看着像默认值"的东西掩盖。

  • 本包未发布到 npm。 从 GitHub 装。有一个预构建的 tgz 作为发布产物,但没有 npm install 这一行可给。
  • 界面只有中文。 面板里今天没有语言切换,也没有英文界面文案可以承诺。
  • 项目 Python 代码读 GPIO 尚未实现。 hw_set_occlusion 会把遮挡沿实际接线传导进联网设备的读数,
    但反方向 —— 项目代码经 shim 调 RPi.GPIO.input() —— 会抛 NotImplementedError,
    桥接层的 gpio_read / gpio_write 在契约里已声明、行为未实现("已定义协议但行为模型尚未实现")。
    所以"固件轮询引脚再上报"这条路今天还走不通;"固件直接 HTTP 上报"这条路可以。
  • 联网设备还没画进 3D 场景。 它们已在 SSOT 里(transport: &#x27;network&#x27;)、工具也完全能驱动,
    但前端还没渲染它们。
  • 只声称验证过的路径。 联网设备那条链在真实后端上验证过;I2C 形态的真实项目还没有适配过 ——
    I2C 那一半目前由本仓库自带的测试项目验证。
  • 模型尺寸 vs 几何保真是待决的二选一(见 docs/06 §6):把导入模型缩放到声明的真板 size
    会让它轻微变形。今天的做法是保留真机尺寸、端口按变形后的间距对齐。
  • hw_set_occlusion 只够得着联网设备。 若被遮挡的器件接到的对端不是带 pinMap 的联网设备,
    什么都传导不过去 —— 这时工具会在 reason 里说出来,而不是静默成功。
  • 部分导入模型的端口数还在收敛(例如树莓派排针有几个脚落在 PCB 上而非引脚 mesh 上)。
    端口可用,但少数锚点有零点几毫米的偏差。

文档

文件 内容
docs/00-宿主API核实.md 宿主 API 核实(slot 树、路由注册、坑位)
docs/01-项目定位.md 项目定位、锁定范围
docs/02-步骤①-虚拟时钟内核.md 虚拟时钟内核
docs/03-模型库可行性验证.md 模型库可行性验证(为什么不做采集器)
docs/04-失败族-看起来正常实际全错.md 失败族「看起来正常、实际全错」(20 例)
docs/05-模型来源与导入方案.md 模型来源与导入方案决策
docs/06-状态与交接.md 状态与交接(一页纸)
docs/07-联网设备-第二类虚拟硬件.md 联网设备,第二类虚拟硬件

这些文档是中文的工作文档(翻译它们会多出一份需要同步的副本)。本文件与 README.md 是成对维护的。

许可证

BSD-3-Clause。


dsh-breadboard

常见问题

6 问
答案由本站依据条目字段整理,不引用上游原文
dsh-breadboard 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add @noob-stupid/dsh-breadboard@0.6.0` 即可。

dsh-breadboard 的验证等级是什么意思?

L5 · 运行验证通过。在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来

dsh-breadboard 安全吗?

低风险。

dsh-breadboard 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

dsh-breadboard 用的是什么许可证?

上游标注为 BSD-3-Clause。商用或二次分发前请到仓库确认许可证原文。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

文档与办公
按星标排序,可作替代方案

webnovel-writer

webnovel-writer

基于 Claude Code 的长篇网文辅助创作系统,解决 AI 写作中的「遗忘」和「幻觉」问题,支持 200 万字量级 连载创作。

L4 · 沙盒安装通过 7,742 星

answer-me-with-html

answer-me-with-html

Answer me with HTML — an agent skill that answers hard questions with

L4 · 沙盒安装通过 4,782 星

last30days-skill-cn

last30days-skill-cn

last30days-cn 是一个 AI Agent 技能(Skill),能够自动搜索中国互联网 8 大主流平台最近 30 天的内容,综合分

L4 · 沙盒安装通过 1,880 星

dsh-bili-scroll

dsh-bili-scroll

DSH 插件:每天替你刷一轮 B站,读字幕挑出值得的、写一份日报,值得的 @ 你

L5 · 运行验证通过 1,025 星

Noob-stupid 的其它插件

3 个

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 —。