Hi @prohand, great job, I looked at the branch code and the result is consistent with what the core does. You can push, the mechanics are good. Three points though, two of which deserve a fix before or just after going into production.
1. The parent is a counter that resets to zero, not an index
You publish « Energy today » in energy-sensor / energy, which Gladys documents as « cumulative energy consumption » and treats as an index. The calculateConsumptionFromIndex job does index(t) − index(t−1) and discards negative deltas (« counter reset detected »). So nothing is counted twice — that’s why your daily total is accurate — but everything consumed between the last poll before midnight and the first poll after is lost, every night. With 900 s of polling, that’s the last quarter of an hour of the day; and if Daikin doesn’t fill its 22h–24h bucket until after midnight, it’s two hours that disappear.
The clean fix: have the integration keep its own cumulative total (in its store, total += max(0, today − previous_today)) and publish a true energy-sensor / index that is monotonic. The core then derives exactly, and the midnight case disappears.
2. The 2-hour buckets distort the cost in HP/HC and Tempo
Daikin only exposes 12 2-hour slots. Your 30-minute series will therefore look like 0, 0, 0, 1.8 kWh, 0, 0, 0, …. The daily total is correct (hence the match with the Onecta app), but the distribution throughout the day is not. Yet calculateCostFrom bills each 30-minute window at the price of that window: on a Base contract it’s inconsequential, on peak/off-peak or Tempo the cost can be seriously wrong, depending on the time the poll was taken.
Two options: clearly document it (« reliable cost in Base, indicative in HP/HC »), or better — saveStates accepts a created_at, so you can publish the index states timestamped at the boundaries of the Daikin buckets rather than at the poll time. Consumption then falls into the correct half-hours.
3. Deriving your own UUIDs is my problem, not yours
Choosing the ids of the features to be able to point energy_parent_id before the lines exist works (the device.create inserts the features then resolves the links in a second pass), and your safeguard — only naming features that Gladys doesn’t know yet — is the right one. But publishing an id in the discovery payload is not in the spec for external integrations: it works today because nothing validates it, and I don’t want it to become an implicit contract.
I will therefore wire addEnergyFeatures() (the one from Zigbee2mqtt/Tasmota) to external integrations, in getDiscoveredDevices: any integration that publishes an index will automatically get the 30-minute pair, with ids and links managed by the core. Keep your code well isolated (featureUuid.js + the block in buildDevice) so you can remove it in one block when it’s available.
The request:
And two details:
- The
energylevel of your capabilities scale serves no purpose:energy_parent_idarrived in Gladys in August 2025, well before external integrations. Any instance capable of running your container already has energy tracking. - « Energy this month » and « Energy this year » must stay at level 0, it’s normal and you should not link them at all: they are also typed
energy, so they appear as possible parents in Settings → Energy Tracking, and a user who wires them would count the same kWh multiple times. A line in the documentation saying « only link the day’s consumption » will avoid the question.
In short: go for production, and I’ll take care of point 3 on the core side.