Skip to content

2026-08-14 ER Midea Bridge:不在家里运行服务器的美的空调控制桥

  • 目标空调:美的 KFR-26GW/BP2DN8Y-DH400(3),不带 M
  • 长期部署目标:ESP-01S,1 MiB Flash,配合现有 ESP-01 Adapter 5V 转换底座
  • 验证平台:经典 ESP32,承担 RX-only、全双工协议探测、离线命令闭环和云端集成验证
  • 云端路径:EMQX Serverless + Cloudflare Worker / Durable Object / Worker Static Assets / Access
  • 产品原则:家中不运行 HASS、MQTT Broker、数据库或其他常驻服务器,设备只建立主动出站连接
  • 固件更新:ESP8266 目标 A/C 与 ESP32 目标 B 分别走同目标、人工确认的 OTA,设备不主动检查更新
  • HomeKit 边界:独立 ESP32/S2/S3 Bridge 在局域网提供 HAP,空调节点不监听局域网控制端口

我们实现了一套什么系统

ER Midea Bridge 把一台没有现代联网能力的美的空调变成可远程观察、控制和定时的设备。ESP 通过室内机 UART 读取主板状态,使用 MQTT/TLS 主动连接托管 Broker;浏览器控制页、状态历史、命令协调和定时任务全部运行在云端。家中无需公网 IP,也无需常驻树莓派、NAS 容器或 Home Assistant 主机。当前架构已从单一遥控链扩展到分目标 OTA 和独立 HomeKit Bridge,但这些能力仍共享“主板回读才是当前状态”的同一条权威边界。

除了远程遥控页面,项目还把“网页已经提交”“Broker 已经接收”“ESP 已经接受”“空调主板已经执行”拆成四个不同状态。只有主板后续报告与目标设定匹配时,命令才进入 applied。HTTP 202、MQTT publish 成功和页面动画只表示链路中的一个阶段,不代替主板执行证据。

代码基线 0b7b6f5 将四个产品版本分开管理:Worker 0.3.0,ESP8266 固件 0.2.0.2+A/C.<UTC>,ESP32 固件 0.2.1.5+B.<UTC>,HomeKit Bridge 0.1.0.1。版本号反映构建与发布边界;硬件支持等级仍以实际目标的分层验收为准。

能力当前实现
状态读取统一状态模型覆盖电源、模式、目标温度、风速、摆风、预设,以及室内/室外温度、湿度和功率的可空字段
远程控制命令携带 boot_idrequest_id 和有效期,经过严格字段、类型、组合与能力校验后才进入 UART
最终确认accepted → applied / rejected / timeout 与主板回读关联;applied 携带对应 state_seq
浏览器控制Vue 3 + Element Plus 的响应式 PWA,展示 reported state、短暂 desired overlay、运行反馈、历史图表与设备信息
云端定时每设备 Durable Object 保存最多五项一次性任务,通过 Alarm 进入同一命令串行协调器
固件更新Worker 只在操作者确认后下发同目标、短有效期、非 retained 的 OTA 命令;ESP8266 与 ESP32 均有 trial/回滚路径
HomeKit独立 Bridge 通过 LAN HAP 服务 Home App/Siri,直连 EMQX 读状态并发复合命令,不连接空调 UART
安全边界每设备独立 MQTT 凭据和主题 ACL;控制页与设备 API 由 Cloudflare Access 保护;空调节点没有入站 Web、Telnet 或 AP 配网入口
故障恢复网络异常不改变空调状态;ESP8266 在持续离线且资源退化、UART 安全、启动时间与 RTC 重启预算同时满足时才受控重启
可观测性RSSI、堆与连续块低水位、连续栈、最大 tick 间隔、会话/发布/确认/恢复计数随 telemetry 上报

当前技术架构

ESP-01S 固件只关心四件事:持续服务 UART、维持 Wi-Fi 与 MQTT/TLS、执行严格命令合同、上报状态与健康数据。EMQX 负责设备与 Bridge 连接、ACL、retained 状态和消息转发;Worker 验证 webhook 与操作者身份;每台设备的 Durable Object 保存状态、历史、命令意图和定时任务。Vue 控制台已合并为同一 Worker 的 Static Assets,网页不保存 Broker 密钥。

空调节点始终只建立出站连接。云端发生故障时,ESP 继续处理主板 UART 和原装遥控器状态,空调不会因控制服务离线而自动改变设置。HomeKit Bridge 是唯一在家庭 LAN 监听 HAP 的组件,它不连接空调 UART,也不改变节点的网络信任边界。

路线如何一步步收敛

项目没有从一开始就写出当前架构。每一阶段先解决一个未知数,再删除已经失去价值的过渡实现。

阶段路线当时解决的问题后续处理
Phase 0–1ESP-01S + ESPHome/HASS 临时探测快速生成 climate 实体、观察传感器、准备 RX-only 与双向 UART 抓取只定位为实机探针,不进入正式系统;后来由 ESP32 原生探测栈取代
Phase 2–3自研 C++ 核心 + ESP8266 MQTT 固件固定命令 schema、主板回读确认、故障隔离和 1 MiB 构建边界成为两种 MCU 共用的长期核心
Phase 4–9Mosquitto + 轻量 Go HTTPS 服务用单文件静态服务验证完整自托管闭环,建立 API、控制页和跨语言合同测试证明路线可行,但仍需管理 VPS、证书、容器与另一套状态实现
Phase 10–15引入 ESP32 / ESP-IDF用更安全、可观察的平台完成 RX-only、全双工、离线命令和云端 compositionESP32 固定为验证平台,ESP8266 保持长期部署目标
Phase 20–26生产/探针拆分与代码收敛移除 ESP8266 探针、ESPHome/HASS 资料和重复诊断;统一 C++/Go/前端合同探针只在 ESP32,生产固件只保留必要路径
Phase 27–32EMQX Serverless + Cloudflare将 Broker、状态、API、实时通信和前端迁入托管服务完成线上 mock 双向 E2E、Durable Object 状态层与单 Worker 控制面
2026-08-07–08Worker Static Assets + HomeKit mainline删除独立 Pages 部署;把 HomeKit 作为独立 ESP-IDF Bridge 产品网页/API 同源;Bridge 直连 EMQX,Worker 退出实时 HomeKit 关键路径
2026-08-09–10ESP32 OTA + ESP8266 RTOS SDK v3.4建立分目标发布合同,将 ESP8266 生产路径迁入原生 UART/Wi-Fi/NVS/mbedTLS/ESP-MQTTESP32 保留 IDF 双分区回滚;ESP8266 形成 1 MiB 可链接基线
2026-08-11–13ESP8266 真 A/B OTA + 项目自有协议模块将双槽构建、trial/confirm/回滚和固定内存 Midea 协议纳入同一验收链软件/目标构建已通过;断电、WDT、双槽往返和长期运行仍待实机

这段迭代留下了三条稳定边界:美的协议与命令规则在共享 C++ core;UART、Wi-Fi、TLS、MQTT、boot 和构建差异留在 ESP8266/ESP32 adapter;云端与 HomeKit Bridge 只消费公开 MQTT 合同。服务端语言、前端框架或 MCU 可以继续变化,accepted/applied、启动绑定、期限、去重和主板回读语义不需要跟着重写。

为什么没有采用 ESPHome + HASS 作为正式路线

ESPHome 很适合项目最早期的未知数。几段 YAML 就能得到 UART、Midea climate 实体、加密 Native API 和 Home Assistant 页面;短期探测不需要先完成 MQTT 合同、控制 API和前端。项目 Phase 1 因此准备了 RX-only、正常控制与原始抓帧三种固件,以及只绑定本机回环地址的临时 HASS 容器。

正式产品的运行目标与这套组合不一致。典型 ESPHome + HASS 路线由 Home Assistant 通过 Native API 连接设备;ESPHome Native API 官方文档列出的主要客户端也包括 Home Assistant。这样做意味着家中需要一台长期在线的 HASS 主机,并承担存储、升级、备份、网络发现和故障恢复。我们的目标是通过手机或浏览器随时控制空调,同时不在家里维护服务器,因此没有把 HASS 纳入生产依赖。

还有一层更重要的产品语义。HASS climate 实体擅长表达目标状态,ER Midea Bridge 还需要表达一次命令从云端到主板的证据链、当前启动身份、短期有效期、重复请求、主板回读匹配和控制授权新鲜度。这些规则放在自有协议与控制面中更直接,也可以针对准确型号逐项收紧能力,而不把 YAML 中出现的实体自动视为主板已经支持。

ESPHome 不用 HASS:路线成立,为什么仍未选择

ESPHome MQTT 官方文档明确支持设备直接连接 MQTT Broker。关闭 Native API,或把其离线重启时间设为零,就可以在没有 HASS 的情况下运行;设备也可以通过自定义 topic 与外部服务交互。它确实满足“家中不运行 Home Assistant”这一条约束。

这条候选路线可以做成:

text
空调主板 → ESPHome Midea 组件 → MQTT/TLS → EMQX → Worker / Static Assets

它的优势很清楚:UART、Wi-Fi、日志、配置生成和 Midea climate 组件已有框架支持,常见实体接入速度快;如果目标只是把标准 climate 状态发布到 Broker,再由通用平台消费,ESPHome 会减少大量固件工作。

ER Midea Bridge 的自定义部分已经超过框架能直接复用的部分。项目仍需在 ESPHome lambda、自定义组件或外部服务中实现以下内容:

  • 与当前 Worker 完全一致的严格命令 schema、字段类型和组合限制;
  • boot_id 启动绑定、可信时间、命令期限和有界 request_id 去重;
  • accepted/applied/rejected/timeout 及主板后续报告匹配;
  • retained 状态只作为缓存、实时 state/telemetry 才能恢复 control_ready 的新鲜度规则;
  • 命令期间优先 UART、推迟阻塞式 TLS 重连,以及 ESP8266 的堆、连续块、连续栈与受控恢复策略;
  • ESP32 RX-only、全双工原始帧观察和离线命令会话;
  • ESP8266 与 ESP32 共用的协议 fixture、主机单元测试和 sanitizer 门禁。
比较项ESPHome + HASSESPHome + 直接 MQTT当前自研固件 + Serverless
家中常驻服务器需要 HASS不需要不需要
首次做出 climate 实体最快较慢
自定义命令生命周期需要额外实现需要额外实现已是 core 合同
ESP32 原始探针与离线闭环另建专用路径另建专用路径与生产 core 共用
ESP8266 1 MiB 资源策略受框架 composition 约束受框架 composition 约束固定存储与热路径可逐项控制
云端 UI 与状态协调HASS 提供仍需自建Worker / DO / Static Assets 已完成
主板能力证据实体易快速出现,仍需另做验证同左能力矩阵与命令 policy 直接相连

ESPHome 可以直接连接 MQTT。选择自研固件,是因为项目已经需要维护自己的云端、命令合同、硬件探针和验收体系;继续使用 ESPHome 会同时维护框架模型与自有模型,减少的主要是外围初始化代码。当前路线把复杂度集中在少量深模块里,ESP32 和 ESP8266 直接运行相同业务核心,长期边界更清晰。

从 Go 自托管服务转向纯 Serverless

Go 路线完成了什么

Phase 4 的 Go 控制服务是一条刻意保持简单的自托管路径:Mosquitto 负责 MQTT/TLS,约 7 MiB 的静态 Go 二进制在 scratch 容器中提供 HTTPS API 与嵌入式中文控制页;最新状态放在内存,服务重启后由 Broker retained state 恢复。它没有数据库、反向代理或 HASS,软件 E2E 已经证明 MQTT/TLS 上报、HTTPS 读取和 QoS 1 非 retained 命令可以闭环。

这条路线的优点是完全可控、依赖少、部署行为容易理解。代价也同样具体:需要一台持续在线的 VPS,维护 Mosquitto、容器、DNS、防火墙、私有 PKI、叶证书轮换、数据备份和服务升级;控制页与 API 跟随同一个二进制发布;复杂状态、历史、实时连接与定时任务会逐步把“轻量服务”扩展成长期运维对象。

迁移早期,Go 与 Cloudflare 两套控制面曾经并存并共享 MQTT 合同。这种双实现适合迁移验证,不适合作为长期基线:命令字段变化需要同步 C++、Go、Worker 和页面;线上问题还要先判断设备连接了哪一个 Broker、请求进入哪一个控制面。Serverless 链路完成真实 mock E2E 与 Access 迁移后,Go 服务在提交 e3ad589 中删除,自建 Mosquitto 缩回 TLS/ACL 冒烟工具。

Serverless 路线怎样分担状态

这里的“纯 Serverless”表示没有需要自行管理的家庭服务器或 VPS,生产链仍由两套托管服务组成:EMQX Cloud 管 MQTT,Cloudflare 管 HTTP、状态和页面。EMQX Serverless 官方文档提供托管 MQTT/TLS 入口;Cloudflare Durable Objects为每台设备提供单点协调、持久状态、WebSocket 和 Alarm。

层次当前责任从 Go/VPS 路线移走的工作
EMQX ServerlessMQTT/TLS、设备认证、ACL、retained 状态、规则与 HTTP 动作Mosquitto 容器、Broker 端口和生产私有 PKI 运维
WorkerAccess JWT 复验、webhook schema、设备 API、EMQX 发布Go HTTPS 进程、TLS listener、Bearer token API
Durable Object每设备串行命令、reported/desired、历史、WebSocket、SQLite 与 Alarm内存状态扩展、数据库选型、调度器和并发协调
Worker Static Assets与 API 同源的 Vue 控制台、PWA、响应式布局、图表与瞬时操作反馈独立 Pages 项目和嵌入 Go 二进制的静态页面
Cloudflare Access登录身份与 API 会话自管登录入口与控制 token 生命周期

Serverless 带来的关键变化是发布与故障边界。前端、状态协调和固件保持独立版本,但控制台与 API 从同一 Worker 域名交付;浏览器不接触 EMQX 密钥;每台设备最多一个命令在途,手动操作和定时任务进入同一串行出口。投递结果未知或确认超时时,协调器停止当前意图及后续队列,不自动重放一条可能已经生效的空调命令。

HomeKit 接入为什么是独立 Bridge

HomeKit 要求家庭 LAN 内有一个常驻 HAP 端点,这与空调节点“只建立出站 TLS、不监听入站端口”的约束相冲。项目因此把 homekit-bridge-idf/ 作为独立产品:ESP32、ESP32-S2 或 ESP32-S3 运行 HAP 和 mDNS,空调节点继续保持原有固件和 UART 边界。

Bridge 使用自己的 MQTT/TLS 身份直连 EMQX,订阅已绑定设备的实时状态,并把 Home App 在 100 ms 窗口内的多字段写入合并为一条复合命令。Worker 只异步发布 retained 目录与绑定、镜像设备事件,不中转 HomeKit 实时操作。这样可以在 Worker 暂时不可用时保留 LAN 到 EMQX 的实时路径,同时仍由设备端执行 boot_id、过期、去重和单命令顺序规则。

Bridge 当前版本为 0.1.0.1,三个芯片目标只完成 build-supported 证据。Home App 配对、Siri、真实复合命令、断网恢复、资源峰值和长期运行必须按 ESP32/S2/S3 分别验收,不能由链接成功代替。

为什么先用 ESP32 验证,再转向 ESP8266

两块芯片承担不同角色:ESP32 提供观测和试错空间,ESP-01S 提供最终安装形态,因此从 ESP32 转向 ESP-01S 属于验证平台与部署平台的切换。

ESP32 适合把未知数逐个拆开

经典 ESP32 开发板有独立 USB 调试口、更多 GPIO、多个硬件 UART、4 MiB Flash 和更充足的内存。项目默认用 UART2 的 GPIO16/GPIO17 连接空调侧,同时保留 USB 串口输出结构化探针日志。验证过程可以严格分级:

  1. probe-rx 在软件中解除 TX 路由,实物上继续物理断开 TX,只观察主板数据;
  2. 电平、共地、波特率和帧完整性稳定后进入 probe-duplex,先查询能力;
  3. 通过 USB 控制台运行与 MQTT 相同的命令 JSON,离线完成 accepted → applied 闭环;
  4. 最后使用 ESP32 production composition 验证 Wi-Fi、SNTP、MQTT/TLS 与云端全链路。

这套顺序把 UART、电气、协议、命令和云端拆成可单独观察的阶段。ESP32 的结果证明共享协议与业务路径,无法替代 ESP8266 的 mbedTLS 内存峰值、GPIO1 启动输出、1 MiB Flash、供电和长时间运行验收。

ESP-01S 对应真正的部署约束

最终设备只需要一个 UART、2.4 GHz Wi-Fi 和主动 MQTT/TLS。ESP-01S 尺寸小,现有库存与已经购入的 ESP-01 Adapter 5V 转换底座也使空调内部的紧凑安装更现实。选型围绕手头物料、安装形态和角色匹配展开,价格差异没有主导这次决定。

1 MiB 预算反过来约束了软件组成:固件没有文件系统、Web Server、HASS Native API、Telnet 或生产抓包日志;热路径使用固定容量帧、请求池与内联回调;TLS 重连受当前堆、最大连续块和连续栈门槛约束;协议抓包只留在 ESP32。当前 checkout 保留的两份 ESP-01S 槽专用 production 镜像均为 430,944 bytes,低于每槽 458,751 bytes 硬上限,并已链入 UART、Wi-Fi、mbedTLS、ESP-MQTT、OTA 与 trial 确认路径。这仍是构建证据,不是 ESP-01S 电气、断电或长期运行证据。

转换底座属于最终硬件验收的一部分。商品名称提供了 5V 输入和 ESP-01 插座这一设计线索;实际安装仍以测量为准,记录外部输入、ESP 插座 3.3V、两侧 UART 高电平、Wi-Fi/TLS 峰值期间电压和复位原因。它是否同时完成双向电平适配,也由实物电路与波形确认。

角色ESP32ESP-01S / ESP8266
项目定位协议探针与完整云端验证平台长期部署目标
串口UART2 接空调,USB 串口独立调试UART0 同时承担生产通信与早期配置
验证模式RX-only、probe-duplex、offline command、productionproduction
资源目标保持可观察性和集成覆盖固定 1 MiB、双 448 KiB 应用槽、无文件系统、控制热路径固定容量
共同部分C++ core、MideaController、CommandPolicy、CloudProtocol、MqttContract同左
OTAIDF ota_0/ota_1 + pending verify/回滚,目标 B项目 bootloader + 无复制 A/B trial/confirm/回滚,目标 A/C
独立验收GPIO、电平、ESP-IDF 网络栈与选定开发板Adapter 供电、GPIO1 启动输出、mbedTLS/OTA 峰值与 14 天耐久

1 MiB ESP8266 怎样完成真 A/B OTA

最早的 CopyOTA 思路会把新镜像下载到临时区,重启前再复制到固定运行位置。它有两个存储区域,但没有独立的 trial 启动、确认和自动回滚语义。当前实现在 1 MiB Flash 上固定两个 0x70000 应用槽:ota_00x10000 开始,ota_10x80000 开始。每个版本分别按所属 IROM 地址链接两份镜像,新固件直接在 inactive slot 运行,不做第二次 Flash 复制。

text
STABLE(old)
  → 下载并校验 inactive slot
  → PENDING(old, new)
  → bootloader 先持久化 TRIAL_STARTED,再启动 new
     → 本地自检通过:CONFIRMED(new)
     → 确认前复位、panic、WDT 或掉电:ROLLED_BACK(old)

boot-control 使用两个 4 KiB 扇区保存带 generation 与 CRC32 的冗余记录,更新 metadata 时不先擦除唯一有效副本。trial 固件运行至少 15 秒,在 30 秒窗口内确认 Midea/Cloud task、堆、最大连续块、栈余量与 recovery watchdog 都处于本地可接受状态,才提交新槽。这个确认不等待 Wi-Fi、MQTT、NTP、Cloudflare 或空调应答,普通网络故障不会被当成坏固件。

ESP-01S 目标 A 与调试板目标 C 共享 ESP8266 修订号,但使用独立 stable channel,不能交叉升级。发布清单同时引用两份 slot-specific 制品;Worker 只向设备投影当次目标槽的固定下载路径。设备校验 target、version、长度、镜像格式和流式 SHA-256;项目依赖 R2/Worker 写权限、Cloudflare Access 与 TLS 建立来源信任,当前没有独立固件签名、Secure Boot 或 Flash 加密。

这条链目前已完成状态机、双槽构建、双制品发布、Worker 路由和回滚展示的软件/目标构建验证。仍需在 A/C 实板上分别做双槽启动、下载/写 Flash/首启三个断电窗口、panic/WDT、多次往返、UART/TLS 资源峰值和回滚 ACK 验收。软件门禁通过不等于这些实机门槛已完成。

我们怎样找到显示板上的飞线点位

CN22 接上适配器后,最早遇到的现象是两个候选信号脚都收不到数据。交换 RX/TX、改变监听方向也没有改变结果,适配器自身回环却能正常收发。这组现象只能说明串口工具和适配器具备基本收发能力,问题范围仍包括主板没有主动发帧、逻辑电平不匹配、CN22 没有接入实际 UART 网络,以及板型选配导致走线被断开。

点位来自一条逐段收敛的证据链:“串口现象缩小范围 → 观察空焊位 → 断电测通断 → 对比同系列板型 → 沿两条信号链继续追踪”。参考板照片负责解释空焊位对应的板型选配,万用表结果负责确定当前板子上的实际路径。

第一步:从“没有数据”转向检查 PCB 选配网络

最初的 RX-only 监听没有字节,交换信号脚后仍然如此。排查先确认适配器回环、9600 8N1 和候选输出电平,再观察显示板上与 CN22 相邻的器件位,暂时保留固件、针脚定义和 PCB 路由三类可能。此时发现 RJX1RJX2RJX3 都没有安装 0Ω 电阻或锡桥。

这组空焊位改变了排查方向:CN22 插座虽然存在,信号脚可能只到达选配焊盘的一侧,没有继续接入 IC02 周边的 UART 网络。三处焊盘的用途当时仍不清楚,可能分别属于 TX、RX、电源、使能或另一种模块选配,因此没有把三处一起短接。

第二步:用断电通断测量建立第一段路径

断开空调供电、ESP32 USB 和串口工具后,分别测量 CN22 第 2、3、4 脚到 RJX1/2/3 两端。为了避免“左、右”随着照片方向变化,现场把每个焊盘分成“靠 CN22/板边的一侧”和“靠 IC02/数码管的一侧”。

我们逐项记录的测量结果把两条信号线锁定为:

text
CN22 2脚 → RJX1 的 CN22 侧
CN22 3脚 → RJX2 的 CN22 侧

当时 RJX1RJX2 本身开路,所以两根线都在焊盘处终止。这可以解释为什么适配器连接正确、串口参数也合理,主板侧仍然没有形成完整收发路径。RJX3 没有进入这两条实测链路,因此继续保持空置。

第三步:用同系列板照片识别“板型选配”,不靠照片猜网络

随后对比了多个同系列美的显示/接收板照片。带外接 CN22 的参考板在 RJX1RJX2 位置安装了 0Ω 链路,RJX3 保持空置;另一类板载 Wi-Fi 版本在同一区域使用不同的电阻选配。高分辨率板图还能看到 R9B1R9B2R9B4R9B5CN303CN305IC02 等丝印。

照片提供的是板型差异:同一 PCB 通过不同的 0Ω/电阻组合,把 UART 路由到外接 CN22 或板载 Wi-Fi 模块。它没有单独决定飞线位置;位置仍需回到当前板子的通断测量。

第四步:补上 RJX 与 IC02 之间缺失的 R9B 段

只恢复 RJX1/RJX2 仍不足以构成完整链路,因为我们继续发现参考板上的 R9B1/R9B2 在当前板上也没有安装。于是测量从 RJX 的 IC02 侧继续向 R9B1/R9B2 两端推进。

现场结果为:

text
R9B1 一侧 → RJX2 的 IC02 侧:导通
R9B2 一侧 → RJX1 的 IC02 侧:导通

两次测量修正了最初按编号顺序配对的猜测。最终形成的两条候选信号路径是交叉编号:

text
CN22 2脚 → RJX1 → R9B2 → IC02
CN22 3脚 → RJX2 → R9B1 → IC02

这也是飞线点位的来源。最终方案沿 PCB 已经预留的外接 CN22 选配链施工:补通 RJX1RJX2R9B1R9B2 四个空焊位,保留 RJX3 开路;无需从 CN22 拉两根长线直接焊到 IC02 引脚。现成焊盘让两条路径可以分别测量、返工和检查,也保留了原板的布线方向。

现场线索当时得到的结论下一步动作
两个候选脚监听都无数据,适配器回环正常交换 RX/TX 仍不足以解释现象检查电平和 CN22 后方 PCB 路由
RJX1/2/3 均为空焊位CN22 可能是同板不同配置留下的接口断电测 CN22 到每个 RJX 两侧的通断
CN22-2 → RJX1CN22-3 → RJX2两条 UART 候选线在 RJX 处被截断对比外接 CN22 参考板,同时保持 RJX3 不动
参考板还有 R9B1/R9B2,当前板同样缺件只补 RJX 可能仍到不了 IC02继续测 RJX 到 R9B 两侧
RJX1 → R9B2RJX2 → R9B1得到两条交叉编号的完整候选路径使用四个现成焊位恢复外接 CN22 选配链

飞线方案形成后,断电检查项目也随路径确定:CN22-2 应越过 RJX1 到达 R9B2 另一侧,CN22-3 应越过 RJX2 到达 R9B1 另一侧;第 2、3 脚之间保持不导通,5V 与 GND 保持不导通,两根信号也不应短接到电源或地。完成这些静态检查后,才恢复 CN22 3 → HW-580 RXCN22 2 → HW-580 TX 并重新观察串口。

这次找点的关键经验是先找 PCB 自己留下的选配边界。相似板照片能揭示 BOM 变体,万用表能确认当前板的铜线实际去了哪里;两者相交后,飞线从“猜一对串口脚”变成“恢复原设计中的四段可测链路”。

固件内部如何同时服务两种芯片

共享层采用无平台依赖的 C++ core 保存稳定规则,硬件与网络实现通过窄 interface 接入,避免用大量 #ifdef 把两块芯片揉在一起。

模块负责内容平台边界
midea_protocol / MideaController固定容量帧、状态映射、命令发送与主板回读共享有界 ByteStream;ESP8266 与 ESP32 分别提供原生 UART adapter
CommandPolicy模式、温度、风速、预设组合与主板状态匹配纯 C++,主机单测直接覆盖
CloudProtocolMQTT 命令 JSON、期限、启动身份、状态/确认/遥测编码不建立网络连接
MqttContracttopic、发布顺序、有界确认队列、状态与遥测生命周期两个平台的 ESP-MQTT adapter 只实现 publication sink
DeviceRuntimeUART 优先级、在途命令、网络重连时机不解析 Midea 帧,也不手写 JSON
RuntimeHealth / RecoveryWatchdog资源门、长期遥测与受控恢复判定ESP8266 adapter 执行 RTC 预算和实际重启
OtaContract / boot adapter共享 manifest、版本、SHA-256 与命令边界ESP8266 项目 boot-control;ESP32 使用 ESP-IDF OTA/回滚 API
MideaFrameProbe / OfflineCommandSession原始帧观察与无云端命令闭环只进入 ESP32 探针 composition

美的协议实现已从外部子模块和构建期 overlay 迁入项目自有的 lib/midea_protocol。上游来源和最新审阅 commit 记录在 PROVENANCE.md,后续同步采用显式审阅和选择性移植,不再导入 Arduino/IDF 兼容层。完整帧固定 96 字节,一个在途请求与八个排队请求使用对象池,回调、定时器和状态监听也使用固定容量。动态帧字符串、通用 logger 和重复日志从 ESP8266 热路径移除,原始帧诊断集中到 ESP32 probe。

一条命令怎样到达空调主板

retained availability=online 只用于恢复上一次已知状态,不能单独开放控制。Worker 还要求 120 秒内出现相同 boot_id 的实时 state 或 telemetry。ESP 重启、命令过期、请求重复或设备只剩 Broker 缓存时,旧命令都无法再次执行。

下一步验收已经从“能否构建”转向实物故障注入

当前软件基线、已部署控制链路和一台真实目标的基本命令/回读闭环已有分层证据,经典 ESP32 production 也已在真实开发板烧录。剩余风险集中在每个实际目标的电气、更新恢复和长期运行,应按以下顺序继续:

  1. 在 ESP-01S 上记录实际芯片/Flash 身份、镜像 SHA-256、Adapter 输入与 3.3V 低水位、两侧 UART 高电平和 GPIO1 启动输出影响。
  2. 在目标 A/C 上分别完成 ota_0 ↔ ota_1 往返,对下载、写 Flash、boot-control、trial 首启和确认前掉电注入故障,并核对 Worker rolled_back 与同 release 抑制。
  3. 分别中断 Wi-Fi、DNS、NTP、MQTT、Worker 和空调,确认 UART 仍可服务且旧命令不重放;随后启动 ESP-01S 14 天耐久窗口。
  4. HomeKit Bridge 按 ESP32、S2、S3 分别完成配对、Siri、复合命令、断网恢复、资源余量和长期运行,三个 target 不互相代替。

实物验收会回答三个仍然开放的问题:ESP-01 Adapter 是否真正完成所需的供电与双向电平转换;trial 阶段的 WDT 是否能覆盖所有永久卡死类型;HomeKit Bridge 在三种无 PSRAM 目标上的 TLS/HAP 峰值是否仍保留足够堆、连续块和栈余量。这三项都需测量,无法从构建产物推导。

这条路线最终得到什么

ER Midea Bridge 的收敛方向可以概括为四次职责转移:ESPHome/HASS 把协议探索速度交给成熟框架;ESP32 把真实硬件未知数放到更安全的验证平台;Serverless 把服务器运维交给托管基础设施;独立 HomeKit Bridge 把 LAN HAP 入站能力与空调节点的出站安全模型分开。ESP-01S 上最终留下主板通信、可靠命令语义、受控出站云连接和可回滚更新。

Go 路线和 ESPHome 路线都完成了各自的任务。前者证明完整自托管闭环可以很小,后者证明 Midea 实体与探测流程可以快速建立;当前架构吸收了两者的结果,同时删除双控制面、独立 Pages 项目、家庭常驻服务器和生产探针。现有 ESP-01S 与 5V 转换底座让最终安装有了明确物料基础,ESP32 继续承担探测与云端验证责任,HomeKit Bridge 承担局域网入口,三者之间由同一套领域语义和 MQTT 合同连接。