家里的电表早已联网,但 Home Assistant 里一直看不到电费。每次想知道本月用了多少电、账户还有多少钱,都得单独打开“网上国网”查一遍。

前段时间我把这个缺口补上了。现在余额、本月电费、历史欠费、日用电量、月度账单都在同一个 HA 看板里。安装本身不复杂,真正花时间的是后来发现的自动刷新问题。这篇文章按我的实际配置过程记录,供同样使用国家电网和 HA 的朋友参考。

实际电费看板

▲ 最后做成的电费看板,金额和用电量分开显示

先说清楚用的是什么

我用的是社区集成 state_grid,不是国家电网官方插件。它通过网上国网的网页和 App 接口读取数据,可以拿到:

  • 账户余额、本月电费、历史欠费;
  • 最近一天的用电量;
  • 当月、上月和年度累计用电量;
  • 上月电费、年度累计电费;
  • 峰、谷、平、尖等分时数据(取决于当地账户是否提供)。

它适合已经在“网上国网”里绑定了电费户号的人,不需要额外购买硬件,也不要求家里的电表必须支持某种 HA 协议。

项目地址:

https://github.com/tiejiang29/state_grid

state_grid 项目主页

▲ 我这次使用的社区项目,最初安装版本为 v0.9.15

需要提醒一句:这类接口不是公开开发接口,上游网站或 App 一改,集成也可能跟着失效。重要提醒和自动化不要只依赖它。

安装集成

如果已经在用 HACS,可以在 HACS 的“集成”里添加自定义仓库:

https://github.com/tiejiang29/state_grid

类别选择“集成”,下载后重启 Home Assistant。

也可以手动安装。把仓库中的整个目录:

custom_components/state_grid/

复制到 HA 配置目录的同名位置,最后应形成:

/config/custom_components/state_grid/

然后删除旧的 __pycache__,重启 HA。

我的 HA 跑在 Docker 里,配置目录挂载在宿主机上。无论是 Docker、HA OS 还是其他部署方式,关键都是把组件放进实际的 /config/custom_components/,而不是随便找一个目录解压。

登录网上国网

重启后进入:

设置 → 设备与服务 → 添加集成 → 国家电网

image-20261109194323235

按页面提示填写网上国网的登录手机号和密码。

我第一次添加时碰到了“新设备安全验证”,服务端返回 4006,随后手机收到短信验证码。在配置页输入验证码后,账号就添加成功了。这个过程与平时在新手机上登录网上国网差不多,不是密码错误。

如果账号下绑定了多个户号,集成会把它们分别建成设备。我的账号下有 3 个户号,每个户号生成了 26 个实体,所以后面做看板时又按户号筛了一遍,没有把几个地址的数据混在一起。

国网集成

▲ 添加成功后,国网账号下的户号会分别显示为设备

这里也提醒一下:不要把登录密码、短信验证码或 .storage 里的会话文件发给别人。HA 备份同样包含敏感信息,公开分享前要先检查。

做一个单独的电费看板

集成自带的实体已经够用了,但我更习惯把金额和用电量整理到一个独立页面,而不是在实体列表里翻。

我在 configuration.yaml 中注册了一个 YAML 看板:

lovelace:
  dashboards:
    utilities-dashboard:
      mode: yaml
      title: 公共事业
      icon: mdi:home-lightning-bolt
      show_in_sidebar: true
      filename: dashboards/utilities.yaml

然后新建 /config/dashboards/utilities.yaml。下面是精简后的配置,把 YOUR_ELECTRIC_ACCOUNT_ID 换成自己的户号即可:

title: 公共事业
views:
  - title: 公共事业
    path: utilities
    icon: mdi:home-lightning-bolt
    cards:
      - type: entities
        title: 电费账单
        icon: mdi:cash
        entities:
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_balance
            name: 账户余额
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_esti_amt
            name: 本月已产生电费
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_history_owe
            name: 历史欠费
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_last_month_ele_cost
            name: 上月电费
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_refresh_time
            name: 数据更新时间
      - type: entities
        title: 用电情况
        icon: mdi:lightning-bolt
        entities:
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_daily_ele_num
            name: 最近出数日用电
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_daily_lasted_date
            name: 日用电数据日期
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_month_ele_num
            name: 当月累计用电
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_last_month_ele_num
            name: 上月用电
          - entity: sensor.state_grid_YOUR_ELECTRIC_ACCOUNT_ID_year_ele_num
            name: 年度累计用电

保存后重启 HA,侧边栏就会出现“公共事业”。

金额单位“元”没有显示成空白,这一点也让我检查过一遍。这个项目目前的金额实体没有强行标记为 monetary,而是直接以“元”为单位显示,避免了部分前端卡片把“元”当作 ISO 货币代码处理的问题。

最麻烦的反而在后面:数据不自动更新

刚接上的那几天,我以为已经大功告成。后来翻历史记录才发现,目标户号从 11 月 5 日到 11 月 9 日都没有写入新状态。手动重新加载集成后,数据立刻更新了,说明账号、密码和国网接口本身没有问题。

我先排除了两个方向:

  1. 不是定时器没运行。 临时加日志后,协调器确实每 5 分钟执行一次。
  2. 不是国网还没出账。 手动取数时能拿到新的日用电和账单。

最后定位到调度逻辑:App 已经取回新数据,但协调器没有重新读取 push_pending,仍然按照 force_refresh=False 跳过新载荷。表现就是“定时器一直在跑,实体却一直不更新”。

这里很容易和集成设置里的“刷新间隔”混淆。设置项决定多久向国网请求一次数据,默认 12 小时,可以调到 12~48 小时;协调器则每 5 分钟检查一次当前状态。取回数据以后,是否真正解析并写入实体,是另一段逻辑。

我这次修改的是 /config/custom_components/state_grid/coordinator.py 里的 _async_update_data(),并不是去改设置里的刷新间隔。把 12 小时调短也解决不了这个问题,只会增加国网请求次数。

修复的关键只有几行:在 App 取数结束后,重新检查是否有待消费的数据,再决定是否执行解析。

await app_supply.async_fill_cache(self.hass, client)

# App 取数可能刚刚产生了新的待消费载荷,必须重新读取。
push_pending = bool(getattr(client, "push_pending", False))
has_cached_data = bool(client.powerUserList)
force_refresh = not has_cached_data or push_pending
await client.refresh_data(force_refresh=force_refresh)

修完后,完整刷新能正常写入,余额、本月电费和最新日用电都随之更新,我也把临时调试日志全部撤掉了。

这段经历给我的教训很直接:看到“最近刷新时间”还不够,最好再看一眼这个值对应的实际状态有没有变化。 有些故障不会报错,只是安静地留着旧数据。

如果你准备照做,不必直接照抄这段补丁。先检查所用版本的调度代码;上游可能已经改动。另一方面,HACS 的“重新下载”会覆盖本地修改,自己打过补丁的文件要先留好差异,别点完升级才发现修复被覆盖了。

日常使用时的几个细节

数据不是实时的。 国网通常按天发布用电量,今天看到的“最近出数日”是昨天很正常。默认每 12 小时真正取一次数已经够用,没必要把请求频率调得很高。

几个金额不要混着看。 我会同时保留“账户余额”“本月已产生电费”和“历史欠费”。本月电费是在累计的账单金额,账户余额是账户里还剩多少钱,是否欠费则看历史欠费,它们不是同一个概念。

会话和备份要保管好。 集成会保存会话信息。换设备画像、删除相关存储文件,可能重新触发新设备验证;HA 备份也不适合直接公开。

接受它偶尔会失效。 这是社区维护的非官方接口适配器。出问题先看数据日期和 HA 日志,不要一上来就反复登录,避免触发国网风控。

现在打开公共事业看板,就能看到账户余额、当月电费和最近一天的用电情况,少了一个需要单独打开的 App。至于水费和燃气费,各地的查询渠道差异更大,等真正跑通后再另写一篇记录。

Q.E.D.


寻门而入,破门而出