构建

面向开发者的实践教程和指南。

标签:
推荐
换掉传感器,控制照旧 — 不把一座温室建两遍的办法
ITEM开发者2026/8/1

换掉传感器,控制照旧 — 不把一座温室建两遍的办法

温室控制器之所以贵,真正的原因是传感器和控制在代码里一对一咬死了。让节点自己声明自己、规则按种类而不是按型号来写,换一只温度传感器就没有代码要改。用同一个服务端、同一套规则真跑了两座不同温室的记录。

#embedded#sensors
文章列表
接到一颗芯片上,接上来的机器就成了终端 — POS、自助点单、后厨屏一次搞定ITEM开发者2026/7/30

在店里本来就有的收款终端旁边立一个服务端,把平板、PC 和后厨屏接上去。三台机器一个 App 都没做,却各自成了自助点单机、POS 和后厨显示。刷卡授权那条路一行都没碰。全部代码、运行日志,以及三块真实渲染出来的画面原样刊出。

开发板交出自己的画面 — 两块实物、两种传输、一个客户端ISSUE开发者2026/7/27

STM32H723 走 USB 串口,ESP32 用 mDNS 发现后走 Wi-Fi TCP 接上。两块板各自交出画面定义,按下按钮真的会点亮 LED。客户端代码在两种情况下一个字都不差。没有模拟器 —— 只有这一篇,没有硬件校验就会失败。

不发问的画面 — 钉在墙上的东西不该发问ITEM开发者2026/7/20

这个系列里的每一个画面都是靠问才知道的。拿在手上的画面可以这样,钉在墙上的后厨画面不行 — 它要么不停地问,要么就晚。订阅之后,三单送达期间画面调用的工具是 0 个。

重试的代价由谁来付 — 不是打电话的那一方,是接电话的那一方ITEM开发者2026/7/16

关于重试的文章大多是从调用方写的。这一篇从接收方来数。四个调用者用两种方式熬过了 700 毫秒的故障,两次最后都通过了。不同的是这期间网关被砸了多少次 — 64 次和 25 次。

两个人都收到「已预订」 — 一个 await 分开的东西ITEM开发者2026/7/13

两个人同时抢同一个时段。用话说,这两个处理器做的是完全一样的事 — 看看空不空,空就占。一个给两个人都发了确认,另一个没有。差别就是中间那一个 await。

这个谁能按 — 把按钮藏起来不是权限ITEM开发者2026/7/9

两个人打开同一个画面。撤销按钮对两人都可见。店员按下去时服务器拒绝,而拒绝被记进了台账。画面文件是同一个文件,我们把它的哈希打进了日志。

画面从服务器来 — 当客户端一个画面都不持有ITEM开发者2026/7/6

到目前为止,这个系列的每个样例都把画面文件放在应用旁边。这次的客户端一个画面都没有。它去问服务器该画什么、画出来,服务器说变了它就再问一次。不用重装、不用重启、不用构建。

第一个 MCP 服务端 — 我的代码在聊天窗里跑起来ITEM开发者2026/7/2

在 Claude Desktop 里写一句「存到笔记里」,跑起来的是我笔记本上几十行的服务端。没有商店,也没有部署,只有一行配置。我们把这趟往返从头做到尾,并让 dart test 自己来查。

一个文件,两种形状 — 不知道自己有多长的列表ITEM开发者2026/6/17

画面课程最后一讲。conditional 让画面分岔,list 在不知道数量的情况下生成行。三条线十六讲在这里接上。

这一切,皆于一个运行时之上ITEM开发者2026/6/11

二月做芯片,三月做仪器,四月做行车记录仪,五月做温室。每个都有自己的应用,互不相识。可是画屏幕的那段代码,二十七份的字节完全一样。不是同一个版本,是同一个文件。

按钮只报一个名字 — 按下去时宿主做了什么ITEM开发者2026/6/10

画面课程第 4 讲。onTap 里没有代码,只有工具名。那个名字是否真的到了宿主,图上看不出来,所以测试台亲自按下去并记下来。

数字不在文件里 — 同一个文件,两张图ITEM开发者2026/5/27

画面课程第 3 讲。一个 `{{now}}` 就把画面和值分开了。至于是否真的分开,靠把同一个文件在两种状态下各渲染一次来定。

方向与间距 — 不用坐标的排布ITEM开发者2026/5/20

画面课程第 2 讲。放多个元素看似需要坐标,但 linear 只收方向和间距。不用坐标不是口味,是条件。

各不相同的传感器,汇于一块屏幕之上ITEM开发者2026/5/14

温室上挂的传感器各不相同。有按摄氏测的、按华氏测的、按 ppm 测的。让节点自己声明自己、让规则用「种类」而不是型号说话之后,换掉传感器又加了两个节点,服务端代码和规则一个字都没改。

画面就是文件 — 四行开始的 UI 运行时ITEM开发者2026/5/13

画面课程第 1 讲。客户端课程第 4 讲里服务器送来的那团东西,究竟是什么。从一个四行的 JSON、和一个绝不往里看的宿主开始。

不去问 — 轮询比「浪费」更糟的地方ITEM开发者2026/4/24

MCP 客户端课程最后一篇。订阅、被通知、然后再读。轮询费资源只是次要的——真正的问题是:两次询问之间值变了两次,中间那一下永远看不到。

接住画面 — 客户端里一块画面都没有ITEM开发者2026/4/17

MCP 客户端课程第四篇。从服务端读回画面定义,交给运行时。这个文件里没有一行是在描述柜台长什么样——而且这一点会被检查。

行车记录仪 — 不碰一帧影像ITEM开发者2026/4/9

车队管理者在行车记录仪上要看的远不止视频。行程记录、卡余量、碰撞灵敏度。所以常见做法是做一个什么都返回的 API,只在视频前面立一道权限检查。那道检查一删就完了。这个应用没有给视频工具上锁——它压根没做。

调用并接住 — 拒绝不是异常ITEM开发者2026/4/3

MCP 客户端课程第三篇。调用工具并读回答案。结果不是一个值而是一份内容列表;而服务端拒绝时,它不会以 throw 的形式到来——所以要读,不是去捕获。

它能做什么 — 把清单写下来,客户端就只属于那一个服务端ITEM开发者2026/3/27

MCP 客户端课程第二篇。去问工具和资源的清单。两行就完了,而有没有这两行,决定了它是「那台服务端专用的客户端」还是「站到任何服务端面前都行的客户端」。

连上去 — 传输不是配置,是一条要执行的命令ITEM开发者2026/3/20

MCP 客户端课程第一篇。接到服务端上。这里要看的不是连接代码,而是传输到底是什么——不是要打开的套接字,而是要启动的命令;正因如此,以后换传输就变成了换一行命令。

只说「变了」 — 为什么不能把值带上ITEM开发者2026/3/13

MCP 服务端课程最后一篇。让画面不再每秒去问。由服务端来说,而通知里只带 uri,不带值。而且没订阅的客户端,什么都收不到。

即使仪器没有专用软件ITEM开发者2026/3/12

仪器早就会说话。问题在于三家用三种方式回答——指数写法、回车符、把单位粘在值上。把这三种揉成一个形状,放进同一块屏。而且屏上显示的是仪表说的数字,不是旋钮拨到的数字。

进程死了也留得下 — 用最不聪明的办法ITEM开发者2026/3/6

MCP 服务端课程第五篇。等待人数放在变量里,会随进程一起消失。把它写进文件,而且每次都整份重写。比局部更新慢,但不会留下写了一半的记录。

把画面做成资源 — 不是代码,是服务端交出来的文档ITEM开发者2026/2/26

MCP 服务端课程第四篇。服务端把画面当成一个文件拿着,再交出去。改了文件,下一次连接就变了,不用重编译也不用重装——前提是每次请求都去读它。

会拒绝的工具 — 模式是约定,不是保证ITEM开发者2026/2/20

MCP 服务端课程第三篇。给工具加上输入模式,再写一个不信任这个模式的处理器。直到「放 0 个人进来」和「放 99 个人进来」因为两种不同的理由被拒绝为止。

在芯片上 — 固件用 C,画面用定义ITEM开发者2026/2/12

给评估板加屏幕,通常要叠一整套图形栈再把固件重烧一遍。这次换了个做法:让开发板把自己的能力当工具、把自己的画面当资源交出来。接上桌上的 STM32H723,点亮 LED,并把开发板递过来的 656 字节画面原样渲染出来。

一个工具 — 说明文比代码更要紧ITEM开发者2026/2/6

MCP 服务端课程第二篇。注册一个工具。它由名字、说明、输入模式、处理器四块组成,其中三块不是我们读,而是调用方读。所以把说明文写好,比把处理器写好更值钱。

来处理状态吧——动值,别动画面ITEM开发者2026/1/23

两周前那块叫号屏加上了按钮。一按数字就动。可问题在于那个数字是谁拿着的。屏幕拿着,第二块面板就会显示另一个号;柜台拿着,面板拔了再插还是同一个号。

LCD 厂商三十分钟做出 HMI — 面板说出工具,画面成为定义ISSUE开发者2026/1/15

把面板的能力做成工具,把画面做成定义,把运行时当渲染器。我们把这条链条真正从头跑到尾的样例摊开来,展示这些包是怎么咬合的。画面不是画出来的,是真的渲染并截下来的。

十行代码,推出第一个画面ITEM开发者2026/1/9

做一块候诊叫号屏。画面定义只有九行,而这九行不在客户端里。服务端把它当成一个文件拿着,接进来就递过去。所谓「不用构建、不用安装」,说的就是这件事。

把服务端立起来 — 并且不往 stdout 写任何东西ITEM开发者2026/1/6

MCP 服务端课程第一篇。没有工具也没有资源,只把服务端立起来。这里要确认的只有一件事——客户端连上来,能不能拿到 initialize 的回答。以及一条现在不定下来、后面就会一直坏的规矩。