Home Assistant の Recorder を PostgreSQL へ変更し、Energy Dashboard の統計をほぼ正常な状態まで戻した。しかしその後、買電と売電にまた数千 kWh 単位の異常値が入った。
前回の復旧作業:
今回はstatisticsとstatistics_short_termだけでなく、集計前のstatesまで遡った。その結果、買電と売電の元センサーがほぼ同時に一度だけ急減し、約 30 秒後に正常値へ戻っていたことを確認できた。
買電: 5119.555 → 1370.486 → 5119.573
売電: 3770.158 → 992.608 → 3770.158この急減がtotal_increasingの新しいメーター周期として扱われ、正常値へ戻った際に巨大な増分がsumへ加算されたと考えられる。
今回はstatisticsだけでなく集計前のstatesまで遡り、異常が加算された時刻と元センサーの値を確認した。補正 SQL はまだ実行していない案なので、流用する場合は必ずバックアップを取得し、自分の環境のテーブル定義と対象行を確認してほしい。
環境
- インストール方法: Home Assistant Core
- Core: 2026.6.1
- フロントエンド: 20260527.4
- Recorder DB: PostgreSQL
- タイムゾーン: Asia/Tokyo
- SPW277-LP から ECHONET Lite 経由で電力量を取得
- 対象: Energy Dashboard
今回確認した主なテーブルは次のとおり。
states: Recorder が保存したエンティティの状態states_meta: エンティティ ID のメタデータstatistics_short_term: 5 分単位の短期統計statistics: 1 時間単位の長期統計statistics_meta: 統計 ID と内部 ID の対応statistics_runs: 統計処理の実行履歴
epoch で保存されている時刻は、次の式で JST へ変換した。
to_timestamp(start_ts) AT TIME ZONE 'Asia/Tokyo'調査対象のセンサーを特定する
Energy Dashboard で使っている主なセンサーは次の 3 つだった。
発電
sensor.auto_discovery_measured_cumulative_amount_of_electric_energy_generated
買電
sensor.auto_discovery_measured_cumulative_amount_of_electric_energy_normal_direction
売電
sensor.auto_discovery_measured_cumulative_amount_of_electric_energy_reverse_directionstatistics_metaから内部で使われるmetadata_idを確認する。
SELECT statistic_id, id
FROM statistics_meta
WHERE statistic_id IN (
'sensor.auto_discovery_measured_cumulative_amount_of_electric_energy_generated',
'sensor.auto_discovery_measured_cumulative_amount_of_electric_energy_normal_direction',
'sensor.auto_discovery_measured_cumulative_amount_of_electric_energy_reverse_direction'
);結果は次のとおりだった。
| 対象 | metadata_id |
|---|---|
| 売電 | 139 |
| 買電 | 140 |
| 発電 | 159 |
以降の SQL ではこの ID を利用した。ただし、metadata_idは環境固有なので、別環境で同じ値をそのまま使ってはいけない。
数千 kWh の異常値が再発した
しばらく正常に動いていたが、買電と売電に再び数千 kWh 級の異常値が入った。
statistics_short_termを広めの時間範囲で確認すると、2 時 30 分を境にsumだけが急増していた。
買電
02:25 state=5119.555 sum=358.381
02:30 state=5119.688 sum=5478.069
売電
02:25 state=3770.158 sum=51.557
02:30 state=3770.158 sum=3821.715増加量はそれぞれ、その時点のstateと一致している。
358.381 + 5119.688 = 5478.069
51.557 + 3770.158 = 3821.715statisticsにも同じジャンプが反映されていた。
買電
01:00 sum=357.820
02:00 sum=5478.594
売電
01:00 sum=51.557
02:00 sum=3821.715なお、異常値を探す SQL で期間を先に絞ってからLAG()を使うと、検索範囲の先頭行には直前値がなく、正常な値まで巨大差分に見えることがある。LAG()を計算する範囲には調査開始時刻より前の行も含める必要がある。
元の states に異常値がないか確認する
集計処理だけが壊れたのか、センサーから異常値が渡されたのかを切り分けるため、statesとstates_metaを確認した。
SELECT
sm.entity_id,
to_timestamp(s.last_updated_ts) AT TIME ZONE 'Asia/Tokyo' AS time,
s.state
FROM states s
JOIN states_meta sm
ON sm.metadata_id = s.metadata_id
WHERE sm.entity_id IN (
'sensor.auto_discovery_measured_cumulative_amount_of_electric_energy_normal_direction',
'sensor.auto_discovery_measured_cumulative_amount_of_electric_energy_reverse_direction'
)
AND s.last_updated_ts >= EXTRACT(
EPOCH FROM TIMESTAMPTZ '2026-07-22 02:20:00+09'
)
AND s.last_updated_ts < EXTRACT(
EPOCH FROM TIMESTAMPTZ '2026-07-22 02:40:00+09'
)
ORDER BY s.last_updated_ts;ここで決定的なデータが見つかった。
買電
02:29:38.087152 5119.555
02:30:08.488914 1370.486
02:30:38.786682 5119.573
売電
02:30:08.488766 992.608
02:30:38.786536 3770.158買電と売電がほぼ同時に一度だけ低い値となり、約 30 秒後には元へ戻っている。
Home Assistant のtotal_increasingは、値の減少を新しいメーター周期の開始やメーター交換として扱う。今回も急減がリセット相当と判断され、その直後に正常な累積値へ戻ったことで、買電の5119.688kWhと売電の3770.158kWhが新しい増分としてsumへ入ったと考えると、実際の統計値と一致する。
これにより、今回の直接原因は Energy Dashboard の表示キャッシュやstatisticsだけの破損ではなく、Recorder へ渡る前のセンサー値に一瞬だけ異常があったことまで確認できた。
買電と売電が同時刻に異常になっているため、SPW277-LP または ECHONET Lite 連携の共通処理が疑わしい。ただし、異常値だった1370.486と992.608の由来は分からず、応答の取り違え、別プロパティの参照、係数や桁の問題などは候補にすぎない。根本原因は未解決である。
statistics の補正案
調査時点では、異常加算された値を以後のsumから引く方針にした。
この SQL は補正案であり、実行後の結果は確認できていない。Home Assistant の停止、PostgreSQL のバックアップ、更新対象行の事前確認を行ったうえで、自分の環境に合わせて調整する必要がある。
まず更新対象と補正後の値をSELECTで確認する。
SELECT
'statistics_short_term' AS source,
metadata_id,
to_timestamp(start_ts) AT TIME ZONE 'Asia/Tokyo' AS time,
sum AS before_sum,
sum - CASE metadata_id
WHEN 140 THEN 5119.688
WHEN 139 THEN 3770.158
END AS after_sum
FROM statistics_short_term
WHERE metadata_id IN (139, 140)
AND start_ts >= EXTRACT(
EPOCH FROM TIMESTAMPTZ '2026-07-22 02:30:00+09'
)
UNION ALL
SELECT
'statistics' AS source,
metadata_id,
to_timestamp(start_ts) AT TIME ZONE 'Asia/Tokyo' AS time,
sum AS before_sum,
sum - CASE metadata_id
WHEN 140 THEN 5119.688
WHEN 139 THEN 3770.158
END AS after_sum
FROM statistics
WHERE metadata_id IN (139, 140)
AND start_ts >= EXTRACT(
EPOCH FROM TIMESTAMPTZ '2026-07-22 02:00:00+09'
)
ORDER BY source, metadata_id, time;対象が正しいことを確認できた場合の更新案は次のとおり。
BEGIN;
UPDATE statistics_short_term
SET sum = sum - 5119.688
WHERE metadata_id = 140
AND start_ts >= EXTRACT(
EPOCH FROM TIMESTAMPTZ '2026-07-22 02:30:00+09'
);
UPDATE statistics_short_term
SET sum = sum - 3770.158
WHERE metadata_id = 139
AND start_ts >= EXTRACT(
EPOCH FROM TIMESTAMPTZ '2026-07-22 02:30:00+09'
);
UPDATE statistics
SET sum = sum - 5119.688
WHERE metadata_id = 140
AND start_ts >= EXTRACT(
EPOCH FROM TIMESTAMPTZ '2026-07-22 02:00:00+09'
);
UPDATE statistics
SET sum = sum - 3770.158
WHERE metadata_id = 139
AND start_ts >= EXTRACT(
EPOCH FROM TIMESTAMPTZ '2026-07-22 02:00:00+09'
);
COMMIT;途中で件数や値に問題があれば、COMMITせずに次を実行する。
ROLLBACK;補正後に期待していた長期統計は次の値だった。
買電
01:00 357.820
02:00 358.906
03:00 360.097
04:00 360.951
売電
01:00 51.557
02:00 51.557
03:00 51.557
04:00 51.557ただし、これは計算上の期待値であり、確認済みの実行結果ではない。
再発防止について
統計を補正しても、元センサーが同じ異常値を返せば再発する。ただし、確認できたのは一度だけであり、正当なメーターリセットを誤って除外する危険もあるため、現時点ではフィルターを実装せず様子を見ることにした。
同じ問題が再発した場合は、次の対策を検討する。
- 異常発生時刻の前後に記録された Home Assistant と ECHONET Lite 連携のログを確認する
1370.486と992.608が別 EPC や別インスタンスの値と一致しないか調べる- 1 回だけの大幅な急減を Recorder へ渡さないフィルターを設ける
- 複数回連続して同じ傾向を確認してから累積値を採用する
- 連携側で ECHONET Lite の要求と応答の対応付けを確認する
ただし、正当なメーターリセットまで除外すると別の不整合を生む。単純な上限・下限だけではなく、直前値との差、連続回数、センサーのリセット仕様を含めて判断した方がよい。
調べて分かったこと
statisticsだけを見ていたときは集計処理の問題かと思っていたが、statesまで戻ると、買電と売電の元センサーがほぼ同時に一度だけ急減していた。約 30 秒後に累積値が元へ戻り、その値が巨大な増分として加算されたと考えると実際の統計と一致する。
SPW277-LP または ECHONET Lite 連携のどこで1370.486と992.608が生まれたかは分からない。正当なメーターリセットまで除外したくないので、今はフィルターを入れず、再発したら要求と応答の対応まで追うことにした。
参考
おしまい



