markobel/kkt-kolbe-homeassistant

GitHub: markobel/kkt-kolbe-homeassistant

该项目通过透明代理桥接 Hekr 云端协议,将已失去官方 App 支持的 KKT KOLBE 抽油烟机无缝接入 Home Assistant 进行 MQTT 控制。

Stars: 0 | Forks: 0

# KKT KOLBE 抽油烟机 → Home Assistant (Hekr 云端桥接) 从 **Home Assistant** 控制 **KKT KOLBE** 抽油烟机(以及可能支持其他 **Hekr / WISEN** WiFi 设备)—— **无需任何硬件修改**。 KKT 停止了 WISEN 应用,导致这些抽油烟机变成半砖状态:WiFi 仍然可用,但已经没有官方途径来控制它们了。该项目在抽油烟机和 Hekr 云端之间放置了一个小型透明代理,通过支持自动发现的 MQTT 将抽油烟机接入 Home Assistant。 ![带有 KKT KOLBE 抽油烟机控制功能的 Home Assistant 仪表盘](https://static.pigsec.cn/wp-content/uploads/repos/cas/89/8912cfccc7d6a6ede61087b4423cc73b8fd2e7a47a89662e9b2fbb9c5d2f784f.png) ## 功能 - 透明 MITM 代理:抽油烟机 ↔ **桥接** ↔ Hekr 云端 - Home Assistant **MQTT 自动发现** (switch, select, fan, sensors) - 向抽油烟机注入指令 (电源 / 灯光 / 风速) - 实时记录完整的 Hekr JSON 协议,用于进一步的逆向工程 - 交互式 REPL,用于映射未知的 command ID - 作为微型 Docker 容器运行 ## 在 Home Assistant 中暴露的实体 | 实体 | 类型 | 备注 | |---|---|---| | 电源 | `switch` | 总开关(风扇 + 灯光)— cmdId `0x02` | | 灯光 | `switch` | 仅灯光 — cmdId `0x03` | | 风速 | `select` | 0 / 1 / 2 / 3 / 4 — cmdId `0x04` | | 风扇 | `fan` | 同风速,以带百分比的风扇形式暴露 | | 连接状态 | `binary_sensor` | 在线 / 离线 | | 原始状态 | `sensor` | 最后的原始十六进制数据帧(诊断) | | 序列号 | `sensor` | 设备帧计数器(诊断) | ## 工作原理 抽油烟机内部包含一个 **基于 ESP 的 Hekr WiFi 模块**。它会向 Hekr 云端发起一个明文 TCP 连接(无 TLS),并交换以换行符分隔的 JSON: ``` device -> cloud : {"msgId":..,"action":"heartbeat"} device -> cloud : {"msgId":..,"action":"devSend","params":{... "raw":"4811..."}} cloud -> device: {"msgId":..,"action":"appSend","params":{... "raw":"4807..."}} ``` - `devSend.raw` 是抽油烟机上报的**状态**帧。 - `appSend.raw` 是云端发送给抽油烟机的**指令**。 - 每个 `raw` 都是一段简短的二进制 payload,并经过了十六进制编码。 通过将抽油烟机的云端流量重定向到此桥接(仅需在您的路由器上设置一条 DNAT 规则),桥接就可以读取每次状态更新并注入自己的 指令,同时仍会将所有数据转发给真实的云端,从而确保抽油烟机保持 正常工作。 ### 状态帧结构 (KKT KOLBE FREE) 17 字节,例如 `4811 01 23 01 01 00 01 02 00 01 FA 00 00 01 00 7E`: | 偏移量 | 含义 | |---|---| | 0 | `0x48` 魔数 | | 1 | 长度 (`0x11` = 17) | | 2 | 帧类型 | | 3 | 序列计数器 | | 6 | 灯光 (0/1) | | 7 | **风速 (0..4)** | | 9–14 | 滤网 / 计数器区块 | | 16 | 校验和 = `sum(prev bytes) & 0xFF` | ### 指令帧结构 7 字节:`48 07 02 [seq] [cmdId] [value] [chk]`,校验和 = `sum & 0xFF`。 | cmdId | 功能 | |---|---| | `0x02` | 主电源(风扇 + 灯光) | | `0x03` | 灯光开关 | | `0x04` | 风扇转速 (值 0..4) | ## 设置 ### 前置条件 - 使用 Hekr 云端(WISEN 应用)且在您的局域网中可达的抽油烟机 - 一台可以添加 **DNAT** 规则的路由器(例如:UniFi, OpenWrt, pfSense) - 一个 MQTT broker(例如 Mosquitto) - 启用了 MQTT 集成的 Home Assistant - 您网络中一台主机上的 Docker + Docker Compose ### 1. 查找您的设备标识符 您需要三样东西:**设备 IP**、**devTid** 和 **ctrlKey**。 抓取抽油烟机的流量(在路由器上运行,或在任何可以镜像流量的主机上运行): ``` tcpdump -i any -nn -s 0 -w hood.pcap 'host ' ``` 在抓包的同时,通过 WISEN 应用切换抽油烟机的状态(或重启其电源)。然后 检查 JSON(payload 是纯 ASCII 文本): ``` tshark -r hood.pcap -Y 'tcp.len > 0' -T fields -e tcp.payload \ | while read p; do printf "%b\n" "$(echo "$p" | sed 's/\(..\)/\\x\1/g')"; done ``` 您会看到类似这样的行: ``` {"action":"devSend","params":{"devTid":"ESP_2M_AABBCCDDEEFF", ...}} {"action":"appSend","params":{"devTid":"ESP_2M_AABBCCDDEEFF", "ctrlKey":"<32 hex chars>", ...}} ``` - `devTid` → `HEKR_DEV_TID` - `ctrlKey` → `HEKR_CTRL_KEY` - 设备连接的 IP (`tcp.dstport == 83`) → `HEKR_CLOUD_HOST` ### 2. 配置 ``` git clone https://github.com/markobel/kkt-kolbe-homeassistant.git cd kkt-kolbe-homeassistant cp .env.example .env # 使用你的 devTid, ctrlKey, MQTT credentials 等编辑 .env。 nano .env ``` ### 3. 将抽油烟机重定向到桥接 (DNAT) 将抽油烟机的云端流量发送到运行桥接的主机。替换 IP/端口 以匹配您的设置。 **通用 iptables(在路由器上运行):** ``` iptables -t nat -A PREROUTING \ -s -d \ -p tcp --dport 83 \ -j DNAT --to-destination :83 ``` **UniFi (UDR/UDM)** — 使用 `on_boot.d` 使其持久化 (需要 [unifios-utilities](https://github.com/unifi-utilities/unifios-utilities))。 创建 `/data/on_boot.d/15-hekr-redirect.sh`: ``` #!/bin/sh iptables -t nat -C PREROUTING -s -d \ -p tcp --dport 83 -j DNAT --to-destination :83 2>/dev/null || \ iptables -t nat -A PREROUTING -s -d \ -p tcp --dport 83 -j DNAT --to-destination :83 ``` ``` chmod +x /data/on_boot.d/15-hekr-redirect.sh /data/on_boot.d/15-hekr-redirect.sh ``` ### 4. 运行 ``` docker compose up -d --build docker compose logs -f hekr-bridge ``` 强制抽油烟机重新连接,以便它获取新的路由(重启其电源,或 在路由器上清除现有连接,例如 `conntrack -D -s `)。 您应该会看到: ``` Hekr bridge listening on 0.0.0.0:83 -> :83 MQTT: connected to ... MQTT: published 7 HA discovery entities === DEVICE CONNECT from ('', ...) === === CLOUD CONNECT to :83 ok === STATE CHG: ... ``` 该设备将出现在 Home Assistant 的 **设置 → 设备与服务 → MQTT** 下。 ## 映射更多指令 (REPL) 该容器运行一个交互式 REPL。连接到它: ``` docker attach hekr-bridge # detach with Ctrl+P then Ctrl+Q (NOT Ctrl+C) ``` 然后进行测试: ``` speed 1 speed 0 light 1 cmd 05 01 # try unknown command id 0x05 with value 1 state ``` 观察 `STATE CHG` 行以查看哪个字节发生了变化,并为您的型号映射新功能 (RGB、滤网重置、定时器等)。欢迎贡献代码! ## 注意事项与说明 - 该桥接仍然依赖于**真实的 Hekr 云端**保持可达,因为 它需要转发登录/握手过程。如果云端某日失效,所抓取到的 握手记录(`devLoginResp` → `reportDevInfoResp` → `getTimerListResp`)足以 在本地模拟该过程 — 欢迎 PR。 - 您可能会看到的 `uart timeout` 响应在这款硬件上只是表面现象: 指令已被执行,且抽油烟机仍会上报最新状态。 - 在 KKT KOLBE FREE 上观察到的是纯明文 TCP,没有 TLS,也没有证书绑定。 您的型号可能有所不同。 ## 免责声明 这是一个非官方的社区项目。不隶属于 KKT KOLBE 或 Hekr。使用风险自负。您有责任遵守您交互的任何 云服务的服务条款以及适用的法律。 ## 许可证 MIT — 查看 [LICENSE](LICENSE)。
标签:Docker, Home Assistant, 安全防御评估, 智能家居, 版权保护, 物联网, 请求拦截