Skip to content

fix: token 失效时自动刷新并自愈网关连接 - #278

Open
yangkghjh wants to merge 3 commits into
banto6:masterfrom
yangkghjh:fix/token-refresh-self-heal
Open

fix: token 失效时自动刷新并自愈网关连接#278
yangkghjh wants to merge 3 commits into
banto6:masterfrom
yangkghjh:fix/token-refresh-self-heal

Conversation

@yangkghjh

Copy link
Copy Markdown

问题

设备过一段时间后全部变为 unavailable,直到手动重新配置账户才能恢复。

根因

  1. token 有效期约 10 天expires_in=863999s)。token 失效后,海尔 WebSocket 网关拒绝连接,插件把所有实体标记为不可用。
  2. token 刷新链路脆弱token_updater 每 1 小时才检查一次,且验证 token 时若 get_user_info() 抛出非 HaierClientException 的异常(网络波动、超时等),try_update_token 直接中断,token 永远不会被刷新
  3. 网关重连使用旧 tokenHaierDeviceGateway 在初始化时固定 token,WS 断线后每 30 秒重连都使用旧 token。即使 token 已被刷新并保存到 config entry,重连依然失败,实体持续不可用。

修复

  • __init__.py
    • try_update_token 捕获所有异常(不仅是 HaierClientException),网络波动时同样尝试刷新,刷新成功会保存新 token。
    • 网关断线时通过 EVENT_TOKEN_REFRESH_REQUESTED 事件立即触发 token 刷新(带 5 分钟节流,避免断线重试风暴),不再等待下一个整点。
    • 初始 token 刷新失败不再导致集成加载失败。
  • core/device_gateway.py
    • 网关断线时 fire EVENT_TOKEN_REFRESH_REQUESTED 请求立即刷新。
    • 每次重连前从 config entry 读取最新 token(通过新增的 _get_latest_token()),并同步给 client,确保 token 刷新后重连立即生效。
  • core/client.py:新增 HaierClient.update_token() 方法。
  • core/event.py:新增 EVENT_TOKEN_REFRESH_REQUESTED 事件。

效果

token 失效后,网关断线 → 立即触发刷新 → 重连使用新 token → 设备自动恢复,无需人工干预。

测试

  • 4 个改动文件均通过 py_compile
  • 单元测试(stub HA 环境)验证:断线事件只 fire 一次、最新 token 读取、无 config_entry 回退、_connect 使用最新 token 构造 WS URL。

修复设备过一段时间后全部变为 unavailable 的问题。

根因:
- token 有效期约10天,失效后海尔 WebSocket 网关拒绝连接
- token_updater 每小时才检查一次,且 get_user_info 验证失败
  (网络波动等非 HaierClientException 异常)时直接中断刷新流程
- 网关重连永远使用初始化时的旧 token,token 已刷新也不生效

修复:
- token_updater 捕获所有验证异常,网络波动时同样尝试刷新
- 网关断线时 fire EVENT_TOKEN_REFRESH_REQUESTED,立即触发 token
  刷新(5分钟节流,避免重试风暴),不再等待整点
- 网关每次重连前从 config entry 读取最新 token 并同步给 client,
  确保 token 刷新后重连立即生效
- 新增 HaierClient.update_token() 方法
发现上一版修复的盲区:网关断线触发刷新时,try_update_token
先调用 get_user_info 验证 token 有效性。海尔 WS 网关对 token
的校验比 REST 接口更严格——token 在 REST 层仍返回 200(有效),
但 WebSocket 网关已拒绝该 token。此时验证通过 → 不刷新 →
gateway 永远用被拒的 token 重连,设备持续 unavailable。

修复:try_update_token 增加 force 参数,网关断线触发的刷新
强制跳过 token 有效性检查直接刷新。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant