一、个人介绍
大家好,我是 Roy,社区 ID 是 4682B4,这个 ID 是一个十六进制的颜色码,也是我之前写前端最爱用的颜色。
我目前是在一家数据库公司做商业化运营和开源相关的工作,本职工作其实和编程关系不大,但我最近两年一直在关注 AI IDE 相关的内容,希望能借助 AI Coding ,用「最小闭环」来验证和助力工作流。
从今年3月3号 TRAE 中文社区正式上线开始,我也陆续在社区输出了许多内容:
用Vibe Coding开发微信小程序,30天狂揽3w+用户[谁输谁洗碗-猜数字游戏]
【Skill 创作】一个让大家都能写出小红书千赞笔记的 Skill
【More Than Coding】Code+MTC双模式混用复刻 SBTI,25 种 TRAE 社区人格等你来认领
公众号投稿:
https://mp.weixin.qq.com/s/Br4u2HQXF4pOL-3jXlPI6w
https://mp.weixin.qq.com/s/LXqoK-BHZQoNUYu6b1DWeQ
作为社区用户受邀参与 TRAE 官方直播:
除了工作上的提效外,带给我最多正反馈的就是今年 3 月用 TRAE 开发的《谁输谁洗碗》微信小程序,上线以来已累计 4.8w 的注册用户,这是我在除了工作之外的工具第一次正式上线的项目,在各个平台都收获了好评,甚至靠流量主的收益收回了服务器成本外还小赚了一些。
为了能帮助更多的用户了解小程序开发,我也将小程序项目开源:Github 地址
说回本次项目,虽然在复赛阶段开放了组队,但我一方面在职时间不固定,一方面这个产品的需求还是比较复杂,不太能协作开发,所以还是以个人身份参赛。从产品定义、硬件选型接线、固件烧录、后端、小程序到 Web 后台,全部一个人 + TRAE 完成。对我来说,这个作品同时是一次验证:一个非技术背景的人,在 AI 的协作下能把一个软硬件结合的产品推进到什么程度。
做「芳莲」的原因在初赛帖里讲过:芳莲是我奶奶的名字。今年过年回家,我看到我爸在给奶奶家里装摄像头。我理解他的担心——奶奶年纪大了,不大会用手机,有时候忘带手机、出门了、睡着了,家里人联系不上就揪心。经常因为奶奶忘带手机或者忘记给手机充电联系不上,我爸开车过去后发现奶奶只是在客厅看电视。但摄像头这件事让我总是感觉不舒服:人不应该像宠物一样被监看,虽然这件事的出发点是好的。所以我想做一个更温和的方案,可以把传感器设备无感的接入到老人的照常生活中,家属可以实时的接收到信息,不需要额外安装 app 就可以接收到信息。
在查看了市面上的一些类似产品之后,我发现这类需求不是没有,而且要么成本比较高,比如某宝基于 STM32 的智能家居系统,成套下来要基本要上千元,而且还需要有一定开发基础;要么就只服务于单一场景,比如智能门锁、用药提醒盒子等等,无法将事件通知汇总在一个系统内。
所以初赛我提交的是一个跑通核心链路的 demo,它包括硬件的传感器、TDengine 数据库、云服务器、微信小程序,做到了最基本的硬件烧录 ——> heartbeat/事件上报 ——> 数据库记录 + web 后台展示 ——> 微信小程序提醒。
而在复赛阶段,我把它做成了一个多场景传感器、四端闭环、可以交付给真实家庭使用的完整产品。这篇复赛帖子我就来讲讲这个「芳莲完整版」到底完整在哪里。
初赛链接:
二、产品简介
是什么
「芳莲」是一套面向独居长辈的轻量居家守护系统:无感传感器硬件 + 微信小程序 + Web 管理后台。长辈们不需要学习任何新的东西,每天照常打开冰箱、喝水、出门,传感器就将这些代表长辈行动的信号自动传到了家属的微信里。整套系统围绕一个原则设计:关心要有边界。
面向谁
- 核心用户:独居或与配偶同住的长辈,尤其是不大会用智能手机的老人,他们对电子产品零感知、零操作;
- 查看者:远方的子女、孙辈、照护者,在微信小程序里看一眼就知道老人今天的状态,如果需要的话还可以订阅关键的事件,比如开关门、用药等;
- 运营者:Web 管理后台承载设备白名单、用户、会员、关系图谱等全部运营能力,让这套系统可以被真实地商业化运营。
完整功能清单
硬件端(4 块真实在跑的板子,双芯片平台)
- 磁吸板(经典 ESP32 + KY-025):贴在药盒 / 门上,开合即上报;带配网状态指示、反馈灯做事件确认;
- 压力板(经典 ESP32 + FSR402B):垫在水杯 / 玄关地垫 / 坐垫下,拿起放下即上报;
- 按钮板(ESP32-C3 SuperMini + 微动开关):按一下报一声平安;体积极小,可以放在床头或口袋;
- BLE 免烧录配网:自定义 GATT 协议(SSID 写入 / 密码触发 / 状态通知 / Hub ID 只读四个特征值),WiFi 凭证存 NVS,换家庭换网络不用重新烧录;固件内连接失败自动重试 3 次;BOOT 键长按 5 秒清凭证复位;
- 60 秒心跳上报,设备离线可判;白名单激活机制,未激活设备上报一律 401;
- 事件语义可自定义:同一枚磁吸可以是「开门」也可以是「药盒」,同一枚压力垫可以是「杯垫」也可以是「地垫」,命名交给用户。
微信小程序「芳莲守护助手」(家属端)
- 微信授权登录:AuthGate 登录墙统一拦截,任何接口 401 自动弹登录;
- 首页「当前状态」四态,全部由真实事件派生:一切正常(绿)/ 最近较安静(黄)/ 今日暂无动态(黄)/ 设备离线(红),heartbeat(心跳)只在离线态以「最后在线」名义出现,绝不冒充「老人活跃」;
- 「今日安心」:按设备动态展示今日触发次数与最近活动时间,绑什么设备显示什么;支持弹层式编辑排序;
- 事件时间线:按日翻页回看历史(今天 / 昨天 / 任意日期),事件徽章区分磁吸 / 压力 / 按钮,优先显示设备自定义名;
- 设备页:按家庭组分组,在线呼吸灯,设备 / 家庭组均可重命名;
- 绑定向导四步流:BLE 搜索设备(含排查清单)→ 填 WiFi 密码(预填手机当前 SSID)→ 配网 → 配对码绑定 → 两步命名(这是谁的家 → 它守护什么);
- 消息订阅:按设备粒度订阅微信服务通知,事件 ≤2 秒触达(由于个人开发者身份限制,消息订阅只支持单次订阅);
- 会员体系:激活码开通(月卡 / 年卡);亲友卡邀请、分享、接受、移除全流程;亲友视角显示「由 XX 共享」;
- 分享能力:全页面支持好友分享与朋友圈分享,亲友卡通过微信原生分享卡片邀请和绑定。
Web 管理后台(运营端)
- Landing 叙事首页:品牌叙事 + 关系图谱示例 + 四组特性分镜,全局水域背景(二维波动方程 Canvas 水面,点击落涟漪,细雨维持生机);
- 设备状态:按家庭组分组、在线状态灯、搜索与状态筛选;
- 设备详情:按传感器类型动态展示今日触发次数与「上次触发 x 分钟前」;
- 事件记录:今天 / 昨天 / 近 7 天 / 近 30 天预设 + 自定义区间 + 每页 50 条分页 + 多维筛选;
- 设备白名单:激活状态、配对码(未绑定绿色可见 / 已绑定灰色标出)、已注册传感器、绑定用户与来源;
- 用户管理:称呼、会员状态(有效 / 有效·亲友共享 / 已过期 / 未开通)、亲友卡关系,绑定关系优先排序,默认隐藏未绑定用户;
- 关系图谱:见下文「设计一」;
- 激活码管理:生成、激活、撤销、延期,按状态与套餐筛选;
- 全后台统一筛选组件库(FilterBar 一族);自定义名优先 + 系统 ID 弱化的双行展示(NameWithId);openid 双击复制 + 全局轻提示。
后端与工程质量
- Next.js API Routes,双鉴权体系:设备
X-Hub-ID + X-Hub-Token(激活时动态下发),用户 / 管理员 JWT; - 设备限流(每 hub 每秒 10 次);激活 / 绑定 / 解绑 / 命名 / 订阅 / 亲友卡全套 REST 接口;
- 绑定模型:家庭组绑定与设备绑定混合,「家庭组绑定吸收设备绑定」规则在写入层、显示层、存量迁移三层落地;
- 数量约束:家庭组 ≤3 台设备、个人 ≤2 个家庭组、亲友卡一主一副;
三个我最想展开讲的设计
设计一:关系图谱 —— 运营端的「上帝视角」
随着用户、家庭组、设备、绑定关系变多,一个必然的问题是:谁在看护谁,怎么一眼看懂?
表格回答不了这个问题。所以我在 Web 管理端做了一整张可交互的关系图谱:
- 四列结构:用户 → 家庭组 → Hub → 传感器,每一条边都是一条真实的绑定关系;
- 两种绑定方式可视化:家庭组绑定(整组共享)与跨家庭组的设备直接绑定(橙色虚线流动动画标出);
- 亲友卡关系用紫色虚线单独表达,亲友节点带三态徽标:「亲友卡·有效 / 亲友卡 / 亲友卡·失效」——靠主卡供血、亲友自有会员、双方均无会员,一眼可辨;
- 完整的筛选系统:隐藏未绑定用户(默认开)、聚焦某个用户、全字段关键词搜索、设备在线状态分段,筛选变化时节点平滑重排;
- 未绑定用户收进底部独立虚线区域,不干扰主链路;
- 支持
?demo=1演示模式,内置多角色压力场景数据,方便展示和讲解。
这不只是一个「好看的可视化」,它是客服答疑、运营排查、商业化分析的共同入口。比如「这个用户为什么能看到那台设备」这类问题,图谱上顺着边看一眼就有答案。
设计二:亲友卡 —— 会员权益的传导设计
商业化做到最后都会遇到一个问题:照护老人从来不是一个人的事,是一个家庭的事。哥哥买了会员,妹妹也想收到通知、看到状态,难道要再买一份?
我参照山姆会员店的「主卡 + 亲友卡」模式做了权益传导:
- 一主一副:付费会员可邀请一位微信用户成为亲友,共享全部会员权益;
- 读共享、写私有:亲友能看到主卡家庭组的设备和事件、能订阅通知,但不能改主卡的设备、不能解绑、不能命名——可见性共享,所有权不共享;
- 权益不链式传递:亲友的会员资格只挂主卡的自有订阅,亲友自己再去分享不会继续传导,主卡到期 / 撤销 / 移除,亲友权益实时失效,续费自动恢复;
- 实时评估而非快照:会员有效性跟着账号走,每次请求实时计算,与绑定方式无关。
这个设计的关键不是「分享」本身,而是边界的清晰度:哪些能看、哪些能改、什么时候失效,全部在数据模型层定义干净。
设计三:TDengine —— 事件数据为什么该用时序数据库(开源)
芳莲的核心数据只有一种:某个时间,某台设备的某个传感器,发生了一件事。这是教科书级的时序数据场景,所以我选了我公司的开源产品 TDengine:
- 超级表 + Tag 模型:一张
sensor_events超级表承载全部事件,hub_id / sensor_id / sensor_type作为 Tag,事件字段只有时间戳和事件类型,极简; - 自动建子表:新设备第一次上报,按命名规范自动生成独立子表(如
fl_reed_a3m8n1_reed_01),不用人工维护表结构; - 查询即业务:家属端的「今日安心」(今日次数 + 最近触发)、时间线(按日 / 任意区间 + 分页 + 按类型计数)、设备详情的「上次触发 x 分钟前」,全部是一条 SQL 的事;
- 心跳与事件同库:设备在线状态也来自时序查询,60 秒心跳即最后在线时间。
当然踩过坑:TDengine 的保留关键字(metadata、value)要加反引号,超级表 Tag 数量和应用代码不匹配会直接报错,历史数据不支持 UPDATE 等等,这些都进了我的开发日志,下文会讲。
硬件产品及成本(以磁吸传感器这一套为参考)
| 设备名称 | 价格 | 数量 |
|---|---|---|
| ESP32-C3 SuperMini开发板 | 9.4 | 1 |
| KY-025 大磁簧 磁性感应模块干簧管传感器 | 1.5 | 1 |
| Type-C + 3.7V 充电锂电池 | 9.5 | 1 |
| 子母线 | 0.1 | 3 |
| Type-C 线 | 0.5 | 1 |
单套磁吸传感器 硬件成本仅为 19.5 元(因为我是单采,量大价格还会更低)
用户使用路径
开箱上电,设备进入配网模式 → 小程序搜到
FLAN- 开头的设备,填 WiFi 密码完成配网 → 设备自动联网激活,生成 8 位配对码 → 小程序输入配对码完成绑定 → 两步命名:这是谁的家、它守护什么 → 传感器贴好,老人照常生活 → 家属在小程序看「当前状态 / 今日安心 / 时间线」→ 订阅后事件微信通知 ≤2 秒触达 → 会员到期激活码续期,或用亲友卡把权益共享给家人。
功能流程图
五层流水线:感知(磁吸 / 压力 / 按钮)→ 连接(HTTPS 上报 / 心跳 / BLE 配网)→ 云端(Next.js API / TDengine / 元数据)→ 应用(小程序家属端 / Web 运营端)→ 触达(微信服务通知)。
相比初赛 Demo 的升级
| 维度 | 初赛 Demo | 复赛完整版 |
|---|---|---|
| 硬件 | 1 块板子验证心跳与单传感器上报 | 4 块板子、3 类传感器、双芯片平台(经典 ESP32 + ESP32-C3 supermini)全部在线 |
| 配网 | WiFi 凭证编译烧录进固件,换网必须重烧 | BLE 免烧录配网 + 自动重试 + BOOT 长按复位,普通用户可通过微信小程序直接完成配网 |
| 设备模型 | 单 Hub 全局凭证 | 家庭组 / Hub / 传感器三层模型,白名单激活 + 动态 Token |
| 事件语义 | 硬编码「用药 / 饮水 / 平安」 | 通用传感器描述 + 用户自定义命名,语义交给场景 |
| 小程序 | 演示页面 | 完整产品:授权登录、绑定向导、命名体系、按日时间线、消息订阅、会员与亲友卡 |
| 状态呈现 | 「在线 = 一切正常」 | 状态由事件派生,心跳与活跃语义分离,数据诚实 |
| 数据查询 | 只看今天 | 按日 / 任意区间 + 分页 + 类型计数 |
| 商业闭环 | 无 | 激活码会员体系 + 亲友卡共享 + 数量约束(3 设备 / 2 家庭组 / 1 亲友卡) |
| 运营后台 | 设备列表 + 事件列表 | Landing 页、白名单、用户管理、激活码、关系图谱、统一筛选体系 |
| 设计系统 | 绿色 demo 风格 | 暖米 + 橙的统一设计 tokens,小程序与 Web 同源 |
三、产品演示视频
[传感器事件触发演示视频已上传复赛飞书表单]
四、创作历程:从 Demo 到能交付的产品
复赛这段时间,我从 WAIC 展会回来之后才有空启动,期间记了 8 天开发日志…挑关键节点来讲一下。
7 月 28 日,先还债:统一命名与家庭组架构。 初赛遗留的混乱命名(fanglian_hub_01、medicine_reed_01……)让监控状态一团乱。这一天确立了三层命名规范——家庭组 fl_hh_xxx、Hub fl_reed_xxx、传感器 reed_01,四端统一;设备从「各自独立」改为「家庭组下的多 Hub」;后端按家庭组维护白名单,激活后动态下发 Token;传感器从硬编码改为事件上报时自动注册。看起来不性感,但这是后续一切功能的地基。当天还经历了复赛第一个事故:rsync 同步时 --delete 没排除 .env,把服务器环境变量删了(很神奇,还给我道歉不小心误删了让我发给他备份文件?),所有 JWT 失效——从那以后,部署脚本里排除敏感文件成了铁律。
7 月 29 日,绑定模型成型。 按 Hub 独立绑定 + 家庭组批量绑定的混合模式落地;配对码从「会过期」改为「长期有效、绑定即失效、解绑重新生成」,设备流转逻辑第一次闭环;Web 端新增白名单页。当天踩了微信小程序的坑:showModal 按钮文案超过 4 个汉字直接抛错。
7 月 30 日,小程序从 demo 变成产品。 设计系统推倒重来,与 Web 端统一为暖米底 + 橙色 accent;首页指标从「固定三指标」改为「绑什么设备显示什么」;自定义命名体系上线。当天最有意思的坑:Input 的 maxlength 会把中文输入法的拼音字母计入长度——想打「幸福小区」,拼音第 7 个字母就被截断,永远组不成词。改为提交时按字符校验才解决(其实我在用其他家产品力偶尔也会遇到这个问题,就是限制比如 6 个字符&汉字,但其实你输入的时候按拼音计数,比如字节跳动“zijietiaodong”,其实你在输入 “tiao” 的 “i” 的时候就已经无法输入了)。
7 月 31 日,出差深圳机场大面积延误。 微信早就回收了 getUserProfile,后端拿到的只有 openid,管理端完全分不出谁是谁。这一天没写代码,只定了方案:用户自填称呼(type="nickname" 组件一键填微信昵称)+ 三端「自定义名优先、系统 ID 弱化」+ 必须用户主动触发(合规)。后来证明这一天的设计省了很多返工。
8 月 1 日,最重要的一天:BLE 配网。 初赛最大的「不真实」在于 WiFi 凭证要烧录进固件——真实用户不可能接受。我自定义了一套 BLE GATT 配网协议(没用 BluFi,固件手写),小程序侧封装扫描、MTU 协商、UTF-8 编解码。还有个经典 bug:配网「第一次必失败、第二次必成功」——根因是 BLE 和 WiFi 共用射频,首次全信道扫描超时不够,第二次有缓存所以必成。修复是把重试收进固件(最多 3 次,保留扫描缓存),上层超时窗口放大到 55 秒,用户无感知。涉及时序的硬件交互,失败重试应收进底层,不要把「再试一次」的成本转嫁给用户。
8 月 2 日,商业闭环:会员与亲友卡。 山姆模式的亲友卡上线(见上文「设计二」),配套落地数量约束。当天还修了 Taro 的运行时崩溃:列表里动态增删带事件的节点会触发 diff 错误,第一轮改法没修对,第二轮改成弹层式排序、按钮固定渲染才根治——小程序列表交互,不给事件节点做动态增删。
8 月 3 日,Web 端不只是纯后台。 Landing 叙事页 + 全局水域背景上线;管理后台六个页面的筛选器统一成一套组件库。也砍掉了两个过度设计:会随波逐流的物理莲花、手绘素描莲花 SVG——背景装饰宁轻勿重,注重功能,首页都不需要一朵抢戏的花。
8 月 4 日,第三块板子上线,由于 demo 版本用的板子在尺寸和成本上都有问题,所以换了 ESP32-C3 SuperMini。 这块板子的故事较多,放在技术方案里专门讲。
还有一条贯穿始终的线:「最后活跃:刚刚」的语义修正。首页曾永远显示「一切正常 · 刚刚活跃」,因为取的是设备心跳——心跳每 60 秒一次,所以永远「刚刚」。但心跳只代表设备在线,不代表老人活跃。最终状态完全由事件派生,心跳只在「设备离线」时以「最后在线」的名义出现。对守护类产品来说,数据的诚实比好看的 UI 重要——家属看到的每一句「一切正常」,都必须是真的。
五、TRAE 实践过程
整个复赛全程在 TRAE IDE / TRAE Work 中完成。有几个让我印象比较刻的协作片段:
- 把模糊场景拆成协议:我说「想让设备免烧录换 WiFi」,TRAE 直接给出 GATT Service / Characteristic 划分(SSID 写入 / 密码触发 / 状态通知 / Hub ID 只读)、NVS 存储方案、BOOT 长按复位交互,连「广播名带 MAC 尾两位防多设备混淆」这种细节都想到了;
- 硬件 bug 的排查思路:在从经典 ESP32 切换到 C3 的时候遇到「BLE 写入回调里调 WiFi.begin 死机」这种问题,TRAE 一次定位到 C3 的 BLE 任务栈(BTC_TASK)比经典 ESP32 小,给出标志位 defer 到主循环的修复,省了我凌晨四点去问某宝卖家;
- 权益模型的推演:亲友卡「读共享、写私有」「权益只挂主卡自有订阅、不链式传递」这些边界,是和 TRAE 一轮轮对话推演出来的,最后落成 53 项断言的测试套件——测试用例本身也大部分是 TRAE 写的;
- 四端一致性:固件、后端、小程序、Web 并行改同一个功能(比如命名规范那次)时,TRAE 帮我保持了字段命名和协议字段的零漂移(这个很猛很关键,尤其对于跨平台的项目);
- Spec 驱动:几个大功能(用户绑定、商业化设备上架、会员订阅、命名统一)都先走了 TRAE 的 Spec 流程,spec / checklist / tasks 三件套留在仓库里,开发按任务清单推进。
TRAE 开发关键步骤截图
Session ID
- 亲友卡在小程序端显示问题优化
.86228294965995:d50429159e32cbe6eacdb17302abea2d_6a7315c48aa15ad8600b4bd6.6a731e018aa15ad8600b4fba.6a731e01d16fba37ca5e47c0:Trae CN.T(2026/8/5 19:26:57)
- 亲友卡绑定形式设计
.86228294965995:02914e61905e3f9d6fb647fc93c12fa9_6a6e1cfe8aa15ad8600b1cdb.6a70757c8aa15ad8600b36a4.6a70757c4e7f9e327d21538c:Trae CN.T(2026/8/3 19:03:24)
- 后端首页重新设计
.86228294965995:eab9b4c1646107d5c79905011b887c64_6a70b3698aa15ad8600b3fb0.6a70b7fb8aa15ad8600b3fb2.6a70b7fb4e7f9e327d215398:Trae CN.T(2026/8/3 23:47:07)
- 配网设计
.86228294965995:59563a3e02393d51c2afa4126cae8582_6a6b48b49f469db9b223b8bf.6a6d017c8aa15ad8600b07e9.6a6d017c4e7f9e327d215361:Trae CN.T(2026/8/1 04:11:40)
- 关系图谱设计
.86228294965995:2d7c11e880bf08645c099de53d589a50_6a6b406e9f469db9b223b7a3.6a6b43fd9f469db9b223b7f9.6a6b43fcf690a07150b20286:Trae CN.T(2026/7/30 20:30:53)
- ISC-V 工具链下载太慢切国内镜像
.86228294965995:153650e01fe8a74b5508d00363afaa3b_6a70ca158aa15ad8600b40fd.6a70d7d88aa15ad8600b420a.6a70d7d84e7f9e327d21539e:Trae CN.T(2026/8/4 02:03:04)
六、技术方案
整体架构
四端协同:硬件层(两类芯片、三类传感器)通过 HTTPS 把事件和心跳打到 Next.js 后端;后端设备侧走 Token 鉴权写 TDengine,用户侧走 JWT 服务小程序和管理后台;事件产生后按订阅关系走微信模板消息推送。小程序同时承担 BLE 配网通道的角色。
双芯片平台:经典 ESP32 开发板 vs ESP32-C3 SuperMini
复赛我把硬件从一种板子扩展到了两种,这是一个有意的选择(主要是成本以及大小):
| 维度 | 经典 ESP32 开发板 | ESP32-C3 SuperMini |
|---|---|---|
| 体积 | 大,引脚全引出 | 指甲盖大小,可藏进任何角落 |
| 成本 | 约 30–40 元 | 约 10 元出头 |
| GPIO | 充裕(灯环 23 / 反馈灯 25 / 复位 0) | 有限(按钮 4 / BOOT 9) |
| 架构 | Xtensa 双核 | RISC-V 单核 |
| 串口 | USB 转串口芯片,即插即调 | 原生 USB,需正确配置 |
| 供电 | 板载稳压,宽容 | 供电能力弱,挑电源 |
| BLE 栈 | 任务栈大,回调里可直接干活 | 任务栈小,回调里只能置标志位 |
产品逻辑是:交互越简单的设备,板子应该越小越便宜。对于单传感器的硬件,一颗 10 元的 C3 就够,符合项目整体追求体积成本最小化和极简的产品逻辑
但 C3 的烧录和调试,由于和经典 ESP32 开发板有很大不同,让本来准备烧录测试就睡觉的我,实打实踩了五个坑(都记录在 8 月 4 日的烧录实录里,K3 陪我烧到凌晨四点):
- 原生 USB 串口不工作:C3 走原生 USB 必须同时定义
ARDUINO_USB_CDC_ON_BOOT=1和ARDUINO_USB_MODE=1两个宏,缺后者 HWCDC 版的Serial根本不会被声明,编译直接报'Serial' was not declared in this scope; - BLE 回调里 WiFi.begin 栈溢出:经典 ESP32 栈大没事,C3 的 BLE 任务栈小,在写入回调里直接连 WiFi 必死机——必须用全局标志位 defer 到主循环执行;
- 供电不足导致配网随机失败:电脑 USB 口供电撑不住 WiFi 发射的电流尖峰,表现为「时而连上时而不行」,换手机充电器一次成功——供电是配网不稳定的高频元凶;
- 2.4GHz 硬限制:C3 只支持 2.4GHz WiFi,iPhone 热点默认 5GHz,要手动开「最大兼容性」;
- 工具链下载极慢:PlatformIO 默认源国内基本拉不动,最后走乐鑫官方镜像手动下载工具链包(约 10MB/s),解压后手写
package.json和.piopm让 pio 识别。
另外固件体积也成了问题:BLE + WiFi + HTTPS 编出来 1.73MB,超过默认 1MB 应用分区,改用 huge_app.csv 分区表才装下。最终 platformio.ini 固化两个环境:-e esp32dev(经典板)和 -e esp32-c3(按钮板),config.h 按芯片宏自动切换设备身份,新增设备只改对应分支。
固件关键设计
- BLE 配网协议:Service
6C69616E-...(“lian”),四个特征值:0001SSID 写入、0002密码写入并触发连接、0003状态通知(ok:<ip>/fail:*)、0004Hub ID 只读;广播名FLAN-XXXX带 MAC 尾两位,多台同时配网可区分; - 凭证管理:WiFi 凭证存 NVS,出厂是「干净固件」;启动时有凭证直连、无凭证进配网模式(灯环蓝色慢闪);BOOT 长按 5 秒清 NVS 复位;
- 传感器防抖:FSR402B 用 8 次滑动平均 + 200ms 稳定判断,ADC 阈值按实际安装标定,10K 下拉电阻防空置抖动;
- 配网重试:连接超时或明确失败自动重试最多 3 次,重试保留扫描缓存,全部失败才上报
fail:timeout; - HTTP 客户端自适应:按
API_BASE_URL协议自动选择WiFiClient/WiFiClientSecure,避免 SSL 握手失败重启(初赛的坑,现在成了代码里的自适应逻辑)。
后端与数据
- API 分层:设备侧(激活 / 事件 / 心跳,Token 鉴权 + 每 hub 每秒 10 次限流)、用户侧(绑定 / 命名 / 订阅 / 会员卡,JWT)、管理侧(白名单 / 用户 / 激活码,Admin JWT);
- TDengine:超级表 + Tag,子表按设备自动创建;事件、心跳同库;区间分页查询 + 按类型计数;
- 元数据:白名单、绑定关系、命名、订阅、会员、亲友卡走 JSON 持久化 + 进程内缓存,重启不丢;
- 绑定与权益模型:家庭组绑定吸收设备绑定(写入层吸收 + 显示层去重 + 存量迁移);可见性(
listVisibleHubIds,含亲友共享)与所有权(listUserHubIds,仅自有)两个入口函数分离,逐路由过归属; - 测试:4 套自包含回归脚本(自带独立后端实例),176 项断言覆盖绑定、订阅门控、时间线查询、亲友卡全生命周期与数量上限。
部署
自有服务器 + PM2 + Nginx。一键部署脚本:本地构建校验(失败即终止)→ rsync 同步(排除 .env / .env.local / node_modules / .next)→ 服务器 nohup 后台构建(避免 SSH 长连接被断)→ 检测构建日志关键词 → 成功才 PM2 重启。这套流程是被三次线上事故(误删 .env、SSH 断连、Nginx 拦截 _next/image)教育出来的。
七、社会价值与商业化思考
社会价值:照护的另一种答案
中国独居和空巢老人的规模早已破亿。「想知道爸妈今天好不好」和「不想被摄像头盯着」,是同一个家庭里同时存在的两种正当诉求。但看看现有的选项,每一个都有明显的妥协:
- 打电话 / 发微信:最直接,但本质是打扰。老人可能在休息、在楼下遛弯、手机在充电,接不到就是一轮焦虑升级;接到了,「你吃药了吗」问多了也是负担;
- 摄像头:信息最全,但对一个在自己家里生活了几十年的人来说,镜头意味着「被看着」。我可以给家里的宠物装摄像头,但对老人,这件事应该更克制;
- 换电子门锁:能知道出没出门,但一把锁几百上千元,还涉及门体改造;更重要的是很多老人不习惯——指纹识别对磨损的指纹不友好,密码记不住,最后还是揣着机械钥匙,电子锁沦为普通锁;
- 手机 App / 智能手表 / 智能家居中控台:对不大会用智能手机的老人,学习成本就是最大的门槛;手表要充电、要佩戴,坚持下来的不多,智能家具中控本身就是小一点的平板,学习成本依然非常的大。
「芳莲」的答案是把这件事反过来做:不让老人适应设备,让设备藏在老人的生活轨迹里。
- 无感:磁吸、压力、按钮都是几元到几十元的成熟传感器,贴在药盒上、垫在水杯下、放在床头,老人照常生活,什么都不用学;
- 语义可自定义:这是我认为最有价值的一点。同一枚磁吸传感器,贴在门上就是「出门 / 回家」,贴在药盒上就是「吃药」;同一枚压力垫,垫在水杯下是「喝水」,垫在玄关地垫下是「出门遛弯回来了」,垫在沙发坐垫下是「起床活动了」。硬件是通用的,意义是家庭自己定义的——每户人家关心的平安信号不一样,产品不该替他们做决定;
- 极低成本:单台设备硬件成本二十元,一个三口之「家」(磁吸 + 压感 + 按钮)全套不到一百元,近是是电子门锁的零头;
- 零学习、零安装负担:家属在微信小程序里看,不用装任何 App;老人那边做到完完全全的 0 学习成本。
这套逻辑背后是我对「科技适老」的一个判断:很多适老产品的思路是「教老人用科技」,但更正确的方向可能是「让科技适应老人」。「芳莲」不替代陪伴,它替代的是那些「你怎么不接电话」的焦虑,和「你吃药了吗」的重复追问,让关心变得有边界,让被关心的人保留尊严。
再往远一点说,这类低成本无感守护方案,对社区养老、居家养老服务机构同样有参考价值:一个护工照看几十户老人的场景里,「哪户今天还没有任何事件触发」就是最有价值的一条信息。
商业化思考
- 成本结构:硬件走成熟模块,单台物料成本二十元左右,可以接近成本价出售甚至随订阅赠送——硬件是入口,不是利润来源;
- 订阅制会员:激活码开通(月卡 / 年卡),一个家庭组最多 3 台设备、一个账号最多 2 个家庭组,约束清晰,续费路径短;
- 亲友卡裂变:一主一副的亲友卡让会员自然流向兄弟姐妹家庭(照护本来就是家庭协作),付费一个人、安心一家人,转化率与留存都会因此受益;
- 运营自给:Web 管理后台的白名单、激活码、用户管理、关系图谱,就是这套模式自营所需的全部基础设施,复赛版本已经齐备;
- 普惠价值:我相信照护科技的上限不只由付费能力决定。极低的硬件成本 + 订阅制,是为了让普通家庭、包括收入不高的家庭也用得起,「安心」这件事本身就是社会价值的一部分。同时我也会在后续开源本地部署的版本,有一定开发能力的用户可以在基础上做二开和自行烧录部署。
八、迭代规划
近期
- 用户使用手册:配网、安装、命名、订阅的图文指引,让非技术家庭能独立完成开箱全流程;
- 产品通用外壳设计(3D 打印):让三块裸板变成真正可以放进家里的产品,同时具备结构稳定性;
- 更多传感器接入:门磁、PIR 人体感应等(固件已按传感器类型宏预留扩展位);
远期
- 开源整个项目:固件、后端、小程序、Web 后台全部开放,探索「硬件开源 + 订阅服务」的可持续模式;
- 让有技术能力的用户可以本地部署、二次开发,进一步降低使用成本——照护这件事,能自己搭的人不该被挡在门外;
- 机构版看护台:面向社区养老服务机构,一个后台看护多个家庭组。
九、感谢 TRAE 帮我跨过复赛的千山万水
在初赛帖的结尾我说,ESP32 第一次上报心跳成功的那个瞬间最惊喜。
复赛阶段赶上了 Kimi-K3 发布,我的惊喜变成了更具体的内容,我有无数次和朋友感慨:“太强了,TRAE + K3 真的太强了,这要是我刚毕业那会儿肯定要花上好几天”,这其中我挑印象最深的几个:
- rsync 误删生产
.env:所有 JWT 失效。TRAE 帮我从本地配置和生产信息重建环境变量,并把部署脚本改成「排除敏感文件 + 后台构建 + 日志校验后才重启」的稳妥形态——事故变成了流程资产; - BLE 配网「第一次必失败」:我以为是代码问题,TRAE 从 BLE / WiFi 射频共存的物理特性解释清楚,把自动重试收进固件;
- Taro diff 崩溃:这个主要是想在微信小程序做事件管理的排序,其实这个功能我之前的小游戏里写过类似的,但因为场景和涉及到后端的问题,第一轮修错方向,TRAE 没有硬撑,和我一起承认误判,第二轮换「弹层式排序 + 按钮固定渲染」根治,还顺手沉淀了一条「小程序不给事件节点做动态增删」的编码规约;
- 176 项断言的测试套件:四个回归脚本大部分由 TRAE 生成,亲友卡那种「改绑新主卡 → 权益跟随 → 撤销失效」的长链路用例,手写要写到怀疑人生。
这些坑单独看都不大,但串起来就是一个作品从「能演示」到「能交付」的距离。这大概就是我在复赛里对「AI 协作开发」最真实的体会:它不只是帮我写得快,而是让我一个人也敢去接硬件、敢碰时序数据库、敢做商业闭环。
十、最后的最后
写完上一段的时候,我想起来 Mac 里一直存着之前用 TRAE 开发的文件,搜了下 TRAE CN 版本是 2025 年 3 月 3 日上线(具体忘了),我的第一个 TRAE 的项目是在 3 月 6 日创建,用 TRAE 写了一个非常简陋的贪吃蛇游戏。
2026 年 2 月底我开始写自己的第一个小程序并上线,本来只是做着自己玩,没想到后来玩的人越来越多,甚至拉了玩家群,根据用户的反馈增加了许多功能,最多的时候一天有超过 4000 人打开过我的游戏。
后续在创造力大赛之前还写过一些用于工作的、娱乐向的或者没有上线的项目:
之前有很多因为觉得学习成本太高而搁置的想法,都被我用 TRAE 逐一变成可以上线分享的产品,这也正印证了本次大赛的 slogan:「世界很大 放手去造」。
用 TRAE 的这 500 多天里,我依旧不会写代码,但是确认了一件事:很多"我不行",其实只是"没开始"。对我来说,TRAE 更像一个放大器,它放大的是每个普通人身上那点微弱却真实的闪光点。在 TRAE 的帮助下,平凡如你我,也有机会被更多人看见。



























