找回密码
 立即注册

微信扫码登录

搜索
查看: 921|回复: 9

[技术探讨] 北汽新能源极狐汽车ArcFox接入homeassistant

[复制链接]

9

主题

69

回帖

653

积分

高级会员

积分
653
金钱
570
HASS币
20
发表于 2026-7-11 21:36:35 | 显示全部楼层 |阅读模式
Arcfox Home Assistant Integration
这是一个用于将北汽极狐(ARCFOX)电动车接入 Home Assistant 的自定义集成骨架,适合通过 HACS 或手动复制到 custom_components/arcfox 使用。
当前仓库已经包含:
  • UI 配置流
  • DataUpdateCoordinator 轮询架构
  • 车辆传感器
  • 车辆锁实体
  • 空调/方向盘加热/除霜开关实体
  • 空调温度设定
  • 座椅加热/通风档位选择
  • 车辆定位实体
  • 唤醒、后备箱、闪灯鸣笛与手动刷新按钮
  • 独立的 transport 层,方便后面替换成 MQTT/BCTP
  • BCTP/MQTT 的 envelope 和 topic 骨架
  • BCTP publish-only transport scaffold
  • 原生 async MQTT publisher,支持可选 broker 配置
  • 仓库级 logo.png 和集成级 custom_components/arcfox/icon.png,用于展示图标
  • 配置流已支持直接导入 app 会话的 access token,不再强制要求短信验证码

当前状态
Home Assistant 这一层已经是完整结构,当前重点已经转到 app 会话和 BCTP 远控协议。
原因很直接:极狐车联网接口没有公开官方开发文档,真实接入通常需要从官方 App 抓包、反编译或已有民间 SDK 中整理登录、车辆列表、状态查询、远程控制等接口。
也就是说:
  • 这个仓库现在可以作为正式开发起点
  • Home Assistant 架构已经搭好
  • 真正决定能否连上车辆的是 api.py 中的接口地址、鉴权字段和响应结构映射

目录结构custom_components/
  arcfox/
    __init__.py
    api.py
    bctp.py
    binary_sensor.py
    button.py
    config_flow.py
    const.py
    coordinator.py
    device_tracker.py
    entity.py
    lock.py
    manifest.json
    models.py
    sensor.py
    strings.json
    switch.py
    translations/
      en.json
      zh-Hans.json
hacs.json开发重点
你后续主要需要改这几个位置:
  • custom_components/arcfox/api.py
  • custom_components/arcfox/models.py
  • 如果返回字段变化较大,再补对应实体平台

需要补齐的接口
  • 登录
  • 刷新 token
  • 查询账号车辆列表
  • 查询单车状态
  • 远程锁车 / 解锁
  • 远程开启 / 关闭空调
  • 唤醒车辆

安装手动安装
复制 custom_components/arcfox 到你的 Home Assistant 配置目录:
config/custom_components/arcfox
然后重启 Home Assistant,在“设备与服务”中添加 ARCFOX.
HACS
仓库已经包含 hacs.json,可以作为自定义仓库导入。
已实现的实体
  • sensor
    • 电池电量
    • 续航里程
    • 总里程
    • 车内温度
    • 车外温度

  • binary_sensor
    • 充电中
    • 已插枪

  • lock
    • 车辆门锁

  • switch
    • 空调开关
    • 方向盘加热
    • 前除霜
    • 后除霜

  • number
    • 空调设定温度

  • select
    • 四个座椅的加热/通风档位

  • device_tracker
    • 车辆位置

  • button
    • 唤醒车辆
    • 打开/关闭车窗
    • 打开/关闭天窗
    • 打开后备箱
    • 闪灯鸣笛
    • 立即刷新


cmd=7 现状
当前代码里已经把 cmd=7 这组 body-control 命令整理成统一封装,按目前静态证据映射为:
  • window
  • defrost
  • door
  • trunk
  • flashHonk
  • sunroof

其中已接入 Home Assistant 的是:
  • 前除霜
  • 打开/关闭车窗
  • 打开/关闭天窗
  • 打开后备箱
  • 闪灯鸣笛

cmd=6 现状
100601010001 / 100601010002 -> group=10 cmd=6 目前按“座椅舒适总开关”处理,后续等实车报文再最终确认具体业务对象。
协议归一化
当前已经整理出来的高置信映射如下:
命令簇
用途
备注

cmd=2空调设温p1 为温度
cmd=6座椅舒适总开关先按总开关处理
cmd=7车身动作车窗、门、后备箱、闪灯鸣笛、天窗
cmd=8座椅加热/通风四席位,按档位控制,代码层拆成 seat_heat / seat_wind
cmd=16方向盘加热两态控制
cmd=33空调主控开关和复合参数
cmd=38前/后除霜p1 区分前后
对应到 Home Assistant 目前暴露的控制项:
  • 空调开关
  • 空调温度
  • 方向盘加热
  • 前后除霜
  • 座椅加热 / 通风
  • 车窗 / 天窗 / 后备箱 / 闪灯鸣笛

代码里已经把这些动作抽成统一的 command spec,集中放在 custom_components/arcfox/protocol.py,api.py 只负责调用规格表并交给 transport.py。
custom_components/arcfox/bctp.py 里已经补了 BCTP 的 header、envelope 和 topic 构造骨架。
custom_components/arcfox/transport.py 已经定义好底层传输契约,并补了一个可挂 MQTT 发布器的 BCTP command transport scaffold。api.py 现在会在可识别的命令上优先走这个命令通道,没挂 transport 时则回退到现有 HTTP 占位实现。座椅命令已经拆成 seat_heat 和 seat_wind 两个显式动作。
当前默认 API base URL 是 APK 配置里出现的 https://hbt-app-rsa.bjev.com.cn。认证优先支持当前 App 的 B2C 链路:导入已登录 App 的 JWT access token 后,集成会立即校验 /vcam/v1/accounts/base 并读取 /vcam/v1/accounts/vehicles;也可以提供短期 app token 和 App 密码走 /vcam/v1/auth/accounts/login。app token 必须从当前 App 会话取得,不能将私有客户端凭据写入集成源码。
旧版车控 SDK 的 /auth/signin、/auth/signinsms 和 /auth/refreshtoken 仅保留为兼容路径。手机号直接配合该短信接口不是当前极狐 App 的认证方式,不能作为默认配置方案。
配置里已经可以选择 http 或 mqtt 命令通道。mqtt 模式下会使用本仓库内置的原生 MQTT publisher 直连 broker,再发布 BCTP envelope。
注意当前 mqtt 仍然不是开箱即用:
  • 静态分析和实测都表明,极狐 MQTT broker 不只校验 username/password
  • app 还会加载客户端证书
  • 该证书是在手机 app 登录后动态申请,再写入 AndroidKeyStore 或内部 files/
  • 所以只填 access_token、mqtt_host、mqtt_username、mqtt_password 还不足以完成真实 MQTT 建链

调试时建议把 custom_components.arcfox 的日志级别开到 debug,这样会直接打印命令走的是 MQTT 还是 HTTP,以及 BCTP publish request 的完整结构。
更详细的未决问题和后续待办放在 ARCFOX_协议问题记录.md
Logo
当前仓库使用的 ARCFOX logo 来源于用户提供的图样,并保留了一个参考来源:
  • https://favpng.com/png_view/arcfox-logo-png/7MCDBLCk


参考
  • Home Assistant integration file structure:https://developers.home-assistant.io/docs/creating_integration_file_structure/
  • Home Assistant config flow:https://developers.home-assistant.io/docs/core/integration/config_flow/
  • Home Assistant data fetching:https://developers.home-assistant.io/docs/integration_fetching_data/


评分

参与人数 1金钱 +20 HASS币 +20 收起 理由
admin + 20 + 20 牛而逼之!

查看全部评分

[url=https://www.ha-box.xyz]HA BOX[/url]
回复

使用道具 举报

9

主题

69

回帖

653

积分

高级会员

积分
653
金钱
570
HASS币
20
 楼主| 发表于 2026-7-11 21:40:28 | 显示全部楼层
ARCFOX 协议问题记录
这是当前对极狐 ARCFOX 接入 Home Assistant 的协议整理和未决问题记录。
已确认
  • cmd=2
    • 空调设温
    • p1 是温度

  • cmd=6
    • 当前按“座椅舒适总开关”处理
    • 仍需实车报文确认最终语义

  • cmd=7
    • 车身动作簇
    • 覆盖车窗、门、后备箱、闪灯鸣笛、天窗

  • cmd=8
    • 座椅加热/通风
    • 四席位、档位控制
    • 代码层已拆成 seat_heat / seat_wind

  • cmd=16
    • 方向盘加热

  • cmd=33
    • 空调主控

  • cmd=38
    • 前/后除霜


认证链路
  • 早先抓到的 sdkserver-be12.bjev.com.cn/api 这条车控 SDK 链路,登录相关接口是:
    • POST /auth/signinsms
    • POST /auth/signin
    • POST /auth/refreshtoken

  • 这条链路里,SDK 代码显示登录请求会带:
    • userId
    • vin
    • smsCode
    • 某些分支还会带 p10 / 证书内容

  • 但最新手机抓包说明,App 的 UI 登录实际先走的是 B2C 层:
    • 图形验证码资源来自 captcha.alicaptcha.com
    • 会话和账号中心请求落到 warden.op-newmall.arcfox.cn
    • 登录态相关请求还会访问 a1-019443ef.easemob.com 和 huanxin.arcfox.cn

  • B2C SDK 里可以确认:
    • /protocol/login/service 被注册成 InnerLoginImpl
    • InnerLoginImpl.getUserToken() 返回 arcFoxToken
    • InnerLoginImpl.getUserPin() 返回 pin
    • LoginInterceptor 会附加 cookie third-login-from=21;mfs_jh_session=<token>;

  • 目前还没有抓到真正的车控后端请求,尤其是:
    • sdkserver-be12.bjev.com.cn
    • findBindUserList
    • findUserCarBind
    • carState/query
    • bluetoothRemoteKey

  • 结论:
    • App 登录成功不等于我们已经拿到车控 SDK 的完整认证串
    • 下一步要补的是“进入车辆主页后”的车控请求抓包,而不是继续猜登录字段





车控链路
  • 进入“我的AT”后,App 会启动 BQMqttService
  • MQTT 服务器按车型选择:
    • ssl://emqx-be12.bjev.com.cn:8883
    • ssl://emqx-be12-pub.bjev.com.cn:8883
    • ssl://emqx-n5.bjev.com.cn:8883
    • ssl://emqx-test.bjev.com.cn:8883

  • MQTT 连接参数:
    • CLIENTID = vin-userId-imei
    • username = MOBILE_<userId>
    • password = accessToken

  • MQTT 订阅 topic 形如:
    • bctp/<model>/standard/server/<vin>/topic/20/05
    • bctp/<model>/standard/appsdk/<vin>/topic/21
    • bctp/<model>/standard/server/<vin>/topic/20/04
    • bctp/<model>/standard/server/<vin>/topic/20/03

  • 车控成功前的本地依赖:
    • SPHelper.saveUserInfo(...) 保存 userId / accessToken / refreshToken / vin
    • rcKey、rcKeyCks 需要落到 SPHelper
    • BQMqttService 会优先读取本地证书,再回退 AndroidKeyStore

  • 这意味着:
    • 手机 App 的“网络连接不畅”更像是 MQTT/证书层失败
    • 不是普通 HTTP 登录失败
    • 代理里看不到 sdkserver-be12 并不奇怪,因为控制页主要在走 MQTT


已确认的命令串
BaicTelematicsSDK.sendCommand(...) 里已经确认的常用命令串如下:
  • 10070101000101
    • group=7
    • cmd=1
    • c=1
    • p3=1

  • 10070102000104
    • group=7
    • cmd=1
    • c=2
    • p3=4

  • 10070101000801
    • group=7
    • cmd=1
    • c=1
    • p10=1

  • 10070102000804
    • group=7
    • cmd=1
    • c=2
    • p10=4

  • 10070101001601
    • group=7
    • cmd=1
    • c=1
    • p11=1

  • 10070102001604
    • group=7
    • cmd=1
    • c=2
    • p11=4

  • 10070101003201
    • group=7
    • cmd=1
    • c=1
    • p12=1

  • 10070102003204
    • group=7
    • cmd=1
    • c=2
    • p12=4


说明:
  • p3、p10、p11、p12 对应的是 body-control 里的不同动作槽位
  • c=1 / c=2 基本可视作开 / 关两态
  • 我们现在的 Home Assistant 动作层已经能映射这些槽位,但 BCTP protobuf 还没完全复刻,所以控制发送还差最后一层编码

BCTP 报文结构顶层协议头
BctpProtoEntity 的核心字段已经坐实:
  • protocolName
  • frameworkProtocolVersion = 1
  • vin
  • deviceNumber = 3123
  • terminalBarcode
  • qos = 1
  • type
  • compressFlag
  • sendTime
  • businessProtocolDatauUnitType = 2
  • messageNumber
  • serviceProtocolVersion = 1
  • businessProtocolDataUnitLength
  • bctpEntity

编码规则
BctpParseUtils.encode(...) 的流程是:
  • 先把业务 protobuf 对象 toByteArray()
  • 再把上面的顶层协议头拼起来
  • type 用十六进制字符串转字节
  • 时间字段是 10 字节结构
  • 如 compressFlag == 2,解码时会走 Snappy

控制包
BctpControlCmdEntity 结构是:
  • header
  • body
  • Cyber

其中 Cyber 字段包含:
  • userID
  • keyID
  • CMAC

计算逻辑:
  • keyID 来自 SPHelper.getRckeyIsCloudCks(...)
  • CMAC 用 rckey 对整个 JSON 做校验

远程启动/透明传输
另一条分支会走:
  • ElectricRtmTransparentTransmission

里面的内容包含:
  • token = SDKREMOTESTART<随机数>
  • content = BctpRemoteStartCmdEntity 的 JSON

这说明:
  • 现在仓库里的 MQTT scaffold 还只是把 topic 和头部框架搭起来
  • 真正能下发控制,还差业务 protobuf 类和 BctpParseUtils.encode(...) 的完整替换

topic 路由
App 里实际 topic 前缀和车型强相关,已确认:
  • BE12 -> bctp/BE12/standard/terminal/<VIN>/topic/21
  • N5 / N50AB / N51AB / N50AS / N51AS -> bctp/N5/standard/terminal/<VIN>/topic/21
  • N80KS -> bctp2/N80KS/standard/terminal/<VIN>/topic/21
  • B31CS -> bctp2/B31CS/standard/terminal/<VIN>/topic/21
  • N60 -> bctp2/N60AS/standard/terminal/<VIN>/topic/21

这也是为什么当前集成里不能死写 N5。
当前代码状态
  • Home Assistant 实体已经接入
  • switch
    • 空调
    • 方向盘加热
    • 前除霜
    • 后除霜
    • 座椅舒适总开关

  • number
    • 空调设定温度

  • select
    • 四个座椅的加热/通风档位

  • button
    • 唤醒
    • 车窗
    • 天窗
    • 后备箱
    • 闪灯鸣笛
    • 刷新

  • transport.py
    • 已定义底层传输契约
    • 当前仍是 HTTP 占位实现
    • 已补一个 BCTP command transport scaffold

  • mqtt_client.py
    • 已补原生 async MQTT publisher
    • 支持可选 broker 配置
    • 命令发布可直接打 debug 日志

  • const.py
    • 默认 API base URL 已切到 https://sdkserver-be12.bjev.com.cn/api

  • 认证字段已切到 user_id / vin / sms_code / refresh_token
  • protocol.py
    • 已整理 command spec
    • api.py 通过规格表调用动作

  • bctp.py
    • 已补 BCTP header / envelope / topic 构造骨架
    • 命令层可直接生成 publish request

  • cmd=8 动作
    • 已接到 async_set_seat_option
    • 现在能走统一命令通道

  • 实体层
    • 命令调用现在优先传完整 vehicle 对象,方便后续命中 VIN topic


仍需确认
  • cmd=6 的最终业务对象
  • cmd=8 中 heat / wind 的真实协议分界
  • cmd=7 六个槽位是否需要进一步细分到车门/除霜等具体动作
  • 实车返回体的成功/失败码
  • 车辆状态回读字段是否存在更稳定的官方字段名
  • 继续补齐 lock / wake_up 等未映射命令的 BCTP 头字段,减少 HTTP 回退

风险点
  • 目前 api.py 仍然保留占位 HTTP 路径
  • cmd=6、cmd=8 仍然带有推断色彩
  • 如果后续抓到真实 MQTT / protobuf 报文,协议层大概率还要再收一轮
  • 车辆列表查询目前按单 VIN 拉取,若一个账号多车,后面需要再补列表接口


[url=https://www.ha-box.xyz]HA BOX[/url]
回复

使用道具 举报

9

主题

69

回帖

653

积分

高级会员

积分
653
金钱
570
HASS币
20
 楼主| 发表于 2026-7-11 21:44:11 | 显示全部楼层
这是 ARCFOX App 检测到了 PCAPdroid 的 VPN/代理环境,不是账号问题。

  先这样处理:

  1. 停止 PCAPdroid 捕获。
  2. 关闭 HTTPS 解密。
  3. 关闭 PCAPdroid 的 VPN。
  4. 确认 ARCFOX App 恢复正常联网。

  ARCFOX 很可能同时做了代理检测和证书固定,所以普通无 Root 抓包无法拿到登录 token。不要继续尝试绕过它,也不要安装所谓“SSL 解锁”工具。

  剩下的可靠方案是:

  - 使用 Root/测试环境做运行时提取;
  - 或继续做“手机会话桥接”,让 HA 不直接保存 token。

  目前你的手机无需再操作车控。


› 手机会话桥接 这是什么意思?


• “手机会话桥接”就是让手机继续作为 ARCFOX App 客户端:

  Home Assistant
        ↓ 局域网请求
  手机上的桥接服务
        ↓ 使用 App 当前登录会话
  ARCFOX 官方服务器
        ↓
  车辆

  这样:

  - accessToken 和 refreshToken 不需要填入 HA
  - 安全码也可以只保留在手机端
  - 手机负责调用官方 App 的车辆状态和远控接口
  - HA 只调用手机局域网地址

  但它不是安装一个普通 App 就能完成。需要让桥接服务复用 ARCFOX App 的登录会话,通常要做成:

  1. 修改/注入 ARCFOX App;
  2. Root + 运行时调试;
  3. 或开发一个能与 ARCFOX App 协作的 Android companion service。

  当前这部手机被 ARCFOX 的代理检测和加密存储保护,最稳妥的下一步是研究“在 App 内部挂接一个本地 HTTP 服务”,而不是继续尝试导出 token。
[url=https://www.ha-box.xyz]HA BOX[/url]
回复

使用道具 举报

28

主题

342

回帖

2069

积分

论坛技术达人

积分
2069
金钱
1694
HASS币
20
发表于 2026-7-11 21:54:22 | 显示全部楼层
我看到是,国内的新能源车厂鉴权一个比一个变态。态度就是宁愿车子变成砖头,也不要你个外人来搬砖。
回复

使用道具 举报

9

主题

69

回帖

653

积分

高级会员

积分
653
金钱
570
HASS币
20
 楼主| 发表于 2026-7-12 18:31:51 | 显示全部楼层
duanyudan123 发表于 2026-7-11 21:54
我看到是,国内的新能源车厂鉴权一个比一个变态。态度就是宁愿车子变成砖头,也不要你个外人来搬砖。 ...

是,用codex搞了好几天,搞不定认证这块。基本上放弃了
[url=https://www.ha-box.xyz]HA BOX[/url]
回复

使用道具 举报

9

主题

69

回帖

653

积分

高级会员

积分
653
金钱
570
HASS币
20
 楼主| 发表于 2026-7-12 18:39:06 | 显示全部楼层
另外,这么搞会不会收到律师函之类的?
[url=https://www.ha-box.xyz]HA BOX[/url]
回复

使用道具 举报

9

主题

69

回帖

653

积分

高级会员

积分
653
金钱
570
HASS币
20
 楼主| 发表于 2026-7-12 18:45:47 | 显示全部楼层
github地址
https://github.com/arcfox-project/arcfox

有能力的大佬可以在此基础上搞。
[url=https://www.ha-box.xyz]HA BOX[/url]
回复

使用道具 举报

3

主题

179

回帖

1437

积分

管理员

积分
1437
金钱
1255
HASS币
0
发表于 2026-7-13 08:35:00 | 显示全部楼层
lazycn 发表于 2026-7-12 18:39
另外,这么搞会不会收到律师函之类的?

不跟他要广告费不错了!!
回复

使用道具 举报

3

主题

179

回帖

1437

积分

管理员

积分
1437
金钱
1255
HASS币
0
发表于 2026-7-13 08:35:44 | 显示全部楼层
admin 发表于 2026-7-13 08:35
不跟他要广告费不错了!!

以后的以后,接不进HA的车,还能卖出去吗
回复

使用道具 举报

0

主题

22

回帖

222

积分

中级会员

积分
222
金钱
200
HASS币
0
发表于 2026-7-22 09:14:47 | 显示全部楼层
我目前是星途汽车,app签名验证也很麻烦,所以我现在的方案是使用限制手机或者nas安装app+macrodroid 识别app内容,通过macrodroid发布mqtt来实现状态回显到ha
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian ( 晋ICP备17001384号-1 )|网站地图

GMT+8, 2026-8-10 13:33 , Processed in 0.018604 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表